Merge branch 'main' into feature-1635-with-labels

This commit is contained in:
jose luis 2024-04-10 17:29:38 +02:00
commit a589f1d6e9
No known key found for this signature in database
GPG Key ID: 6D23FAD11F88081A
13 changed files with 374 additions and 23 deletions

View File

@ -211,6 +211,9 @@ The currently supported options are:
| kompose.cronjob.schedule | kubernetes cronjob schedule (for example: '1 * * * *') |
| kompose.cronjob.concurrency_policy | 'Forbid' / 'Allow' / 'Never' / '' |
| kompose.cronjob.backoff_limit | kubernetes cronjob backoff limit (for example: '6') |
| kompose.init.containers.name | kubernetes init container name |
| kompose.init.containers.image | kubernetes init container image |
| kompose.init.containers.command | kubernetes init container commands |
**Note**: `kompose.service.type` label should be defined with `ports` only (except for headless service), otherwise `kompose` will fail.
@ -467,6 +470,48 @@ services:
labels:
kompose.volume.sub-path: pg-data
```
- `kompose.init.containers.name` is used to specify the name of the Init Containers for a Pod [Init Container Name](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)
For example:
```yaml
version: '3'
services:
example-service:
image: example-image
labels:
kompose.init.containers.name: "initcontainername"
```
- `kompose.init.containers.image` defines image to use for the Init Containers [Init Container Image](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)
For example:
```yaml
version: '3'
services:
example-service:
image: example-image
labels:
kompose.init.containers.image: perl
```
- `kompose.init.containers.command` defines the command that the Init Containers will run after they are started [Init Container Command](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)
For example:
```yaml
version: '3'
services:
example-service:
image: example-image
labels:
kompose.init.containers.command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
kompose.init.containers.image: perl
```
## Restart
If you want to create normal pods without controller you can use `restart` construct of compose to define that. Follow table below to see what happens on the `restart` value.

10
go.mod
View File

@ -19,7 +19,7 @@ require (
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.16.0
golang.org/x/tools v0.16.1
golang.org/x/tools v0.19.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.5.1
k8s.io/api v0.28.4
@ -62,10 +62,10 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/mod v0.16.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect

22
go.sum
View File

@ -333,8 +333,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -367,8 +367,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -388,8 +388,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -435,10 +435,10 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -502,8 +502,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -144,6 +144,7 @@ type ServiceConfig struct {
ExposeService string `compose:"kompose.service.expose"`
ExposeServicePath string `compose:"kompose.service.expose.path"`
BuildLabels map[string]string `compose:"build-labels"`
BuildTarget string `compose:""`
ExposeServiceTLS string `compose:"kompose.service.expose.tls-secret"`
ExposeServiceIngressClassName string `compose:"kompose.service.expose.ingress-class-name"`
ImagePullSecret string `compose:"kompose.image-pull-secret"`

View File

@ -559,6 +559,7 @@ func dockerComposeToKomposeMapping(composeObject *types.Project) (kobject.Kompos
serviceConfig.Dockerfile = composeServiceConfig.Build.Dockerfile
serviceConfig.BuildArgs = composeServiceConfig.Build.Args
serviceConfig.BuildLabels = composeServiceConfig.Build.Labels
serviceConfig.BuildTarget = composeServiceConfig.Build.Target
}
// env

View File

@ -88,6 +88,12 @@ const (
LabelCronJobConcurrencyPolicy = "kompose.cronjob.concurrency_policy"
// LabelCronJobBackoffLimit defines the job backoff limit
LabelCronJobBackoffLimit = "kompose.cronjob.backoff_limit"
// LabelInitContainerName defines name resource
LabelInitContainerName = "kompose.init.containers.name"
// LabelInitContainerImage defines image to pull
LabelInitContainerImage = "kompose.init.containers.image"
// LabelInitContainerCommand defines commands
LabelInitContainerCommand = "kompose.init.containers.command"
// LabelNameOverride defines the override resource name
LabelNameOverride = "kompose.service.name_override"
)

View File

@ -654,7 +654,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
if serviceAccountName, ok := service.Labels[compose.LabelServiceAccountName]; ok {
template.Spec.ServiceAccountName = serviceAccountName
}
fillInitContainers(template, service)
return nil
}
@ -985,3 +985,48 @@ func reformatSecretConfigUnderscoreWithDash(secretConfig types.ServiceSecretConf
return newSecretConfig
}
// fillInitContainers looks for an initContainer resources and its passed as labels
// if there is no image, it does not fill the initContainer
// https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
func fillInitContainers(template *api.PodTemplateSpec, service kobject.ServiceConfig) {
resourceImage, exist := service.Labels[compose.LabelInitContainerImage]
if !exist || resourceImage == "" {
return
}
resourceName, exist := service.Labels[compose.LabelInitContainerName]
if !exist || resourceName == "" {
resourceName = "init-service"
}
template.Spec.InitContainers = append(template.Spec.InitContainers, api.Container{
Name: resourceName,
Command: parseContainerCommandsFromStr(service.Labels[compose.LabelInitContainerCommand]),
Image: resourceImage,
})
}
// parseContainerCommandsFromStr parses a string containing comma-separated commands
// returns a slice of strings or a single command
// example:
// [ "bundle", "exec", "thin", "-p", "3000" ]
//
// example:
// [ "bundle exec thin -p 3000" ]
func parseContainerCommandsFromStr(line string) []string {
if line == "" {
return []string{}
}
var commands []string
if strings.Contains(line, ",") {
line = strings.TrimSpace(strings.Trim(line, "[]"))
commands = strings.Split(line, ",")
// remove space "'
for i := range commands {
commands[i] = strings.TrimSpace(strings.Trim(commands[i], `"' `))
}
} else {
commands = append(commands, line)
}
return commands
}

View File

@ -29,6 +29,7 @@ import (
"github.com/kubernetes/kompose/pkg/testutils"
"github.com/pkg/errors"
appsv1 "k8s.io/api/apps/v1"
api "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
)
@ -738,3 +739,209 @@ func TestRemoveEmptyInterfaces(t *testing.T) {
})
}
}
func Test_parseContainerCommandsFromStr(t *testing.T) {
tests := []struct {
name string
line string
want []string
}{
{
name: "line command without spaces in between",
line: `[ "bundle", "exec", "thin", "-p", "3000" ]`,
want: []string{
"bundle", "exec", "thin", "-p", "3000",
},
},
{
name: `line command spaces inside ""`,
line: `[ " bundle ", " exec ", " thin ", " -p ", "3000" ]`,
want: []string{
"bundle", "exec", "thin", "-p", "3000",
},
},
{
name: `more use cases for line command spaces inside ""`,
line: `[ " bundle ", "exec ", " thin ", " -p ", "3000 " ]`,
want: []string{
"bundle", "exec", "thin", "-p", "3000",
},
},
{
name: `line command without [] and ""`,
line: `bundle exec thin -p 3000`,
want: []string{
"bundle exec thin -p 3000",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := parseContainerCommandsFromStr(tt.line); !reflect.DeepEqual(got, tt.want) {
t.Errorf("parseContainerCommandsFromStr() = %v, want %v", got, tt.want)
}
})
}
}
func Test_fillInitContainers(t *testing.T) {
type args struct {
template *api.PodTemplateSpec
service kobject.ServiceConfig
}
tests := []struct {
name string
args args
want []corev1.Container
}{
{
name: "Testing init container are generated from labels with ,",
args: args{
template: &api.PodTemplateSpec{},
service: kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelInitContainerName: "name",
compose.LabelInitContainerImage: "image",
compose.LabelInitContainerCommand: `[ "bundle", "exec", "thin", "-p", "3000" ]`,
},
},
},
want: []corev1.Container{
{
Name: "name",
Image: "image",
Command: []string{
"bundle", "exec", "thin", "-p", "3000",
},
},
},
},
{
name: "Testing init container are generated from labels without ,",
args: args{
template: &api.PodTemplateSpec{},
service: kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelInitContainerName: "name",
compose.LabelInitContainerImage: "image",
compose.LabelInitContainerCommand: `bundle exec thin -p 3000`,
},
},
},
want: []corev1.Container{
{
Name: "name",
Image: "image",
Command: []string{
`bundle exec thin -p 3000`,
},
},
},
},
{
name: `Testing init container with long command with vars inside and ''`,
args: args{
template: &api.PodTemplateSpec{},
service: kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelInitContainerName: "init-myservice",
compose.LabelInitContainerImage: "busybox:1.28",
compose.LabelInitContainerCommand: `['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]`,
},
},
},
want: []corev1.Container{
{
Name: "init-myservice",
Image: "busybox:1.28",
Command: []string{
"sh", "-c", `until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done`,
},
},
},
},
{
name: `without image`,
args: args{
template: &api.PodTemplateSpec{},
service: kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelInitContainerName: "init-myservice",
compose.LabelInitContainerImage: "",
compose.LabelInitContainerCommand: `['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]`,
},
},
},
want: nil,
},
{
name: `Testing init container without name`,
args: args{
template: &api.PodTemplateSpec{},
service: kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelInitContainerName: "",
compose.LabelInitContainerImage: "busybox:1.28",
compose.LabelInitContainerCommand: `['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]`,
},
},
},
want: []corev1.Container{
{
Name: "init-service",
Image: "busybox:1.28",
Command: []string{
"sh", "-c", `until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done`,
},
},
},
},
{
name: `Testing init container without command`,
args: args{
template: &api.PodTemplateSpec{},
service: kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelInitContainerName: "init-service",
compose.LabelInitContainerImage: "busybox:1.28",
compose.LabelInitContainerCommand: ``,
},
},
},
want: []corev1.Container{
{
Name: "init-service",
Image: "busybox:1.28",
Command: []string{},
},
},
},
{
name: `Testing init container without command`,
args: args{
template: &api.PodTemplateSpec{},
service: kobject.ServiceConfig{
Labels: map[string]string{
compose.LabelInitContainerName: "init-service",
compose.LabelInitContainerImage: "busybox:1.28",
},
},
},
want: []corev1.Container{
{
Name: "init-service",
Image: "busybox:1.28",
Command: []string{},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fillInitContainers(tt.args.template, tt.args.service)
if !reflect.DeepEqual(tt.args.template.Spec.InitContainers, tt.want) {
t.Errorf("Test_fillInitContainers Fail got %v, want %v", tt.args.template.Spec.InitContainers, tt.want)
}
})
}
}

View File

@ -396,7 +396,7 @@ func BuildDockerImage(service kobject.ServiceConfig, name string) error {
// Use the build struct function to build the image
// Build the image!
build := docker.Build{Client: *client}
err = build.BuildImage(imagePath, imageName, service.Dockerfile, buildargs)
err = build.BuildImage(imagePath, imageName, service.Dockerfile, buildargs, service.BuildTarget)
if err != nil {
return err

View File

@ -43,16 +43,16 @@ in order to make building easier.
if the DOCKER_BUILDKIT is '1', then we will use the docker CLI to build the image
*/
func (c *Build) BuildImage(source string, image string, dockerfile string, buildargs []dockerlib.BuildArg) error {
func (c *Build) BuildImage(source string, image string, dockerfile string, buildargs []dockerlib.BuildArg, buildTarget string) error {
log.Infof("Building image '%s' from directory '%s'", image, path.Base(source))
outputBuffer := bytes.NewBuffer(nil)
var err error
if usecli, _ := strconv.ParseBool(os.Getenv("DOCKER_BUILDKIT")); usecli {
err = buildDockerCli(source, image, dockerfile, buildargs, outputBuffer)
err = buildDockerCli(source, image, dockerfile, buildargs, outputBuffer, buildTarget)
} else {
err = c.buildDockerClient(source, image, dockerfile, buildargs, outputBuffer)
err = c.buildDockerClient(source, image, dockerfile, buildargs, outputBuffer, buildTarget)
}
log.Debugf("Image %s build output:\n%s", image, outputBuffer)
@ -66,7 +66,7 @@ func (c *Build) BuildImage(source string, image string, dockerfile string, build
return nil
}
func (c *Build) buildDockerClient(source string, image string, dockerfile string, buildargs []dockerlib.BuildArg, outputBuffer *bytes.Buffer) error {
func (c *Build) buildDockerClient(source string, image string, dockerfile string, buildargs []dockerlib.BuildArg, outputBuffer *bytes.Buffer, buildTarget string) error {
// Create a temporary file for tarball image packaging
tmpFile, err := os.CreateTemp(os.TempDir(), "kompose-image-build-")
if err != nil {
@ -93,13 +93,14 @@ func (c *Build) buildDockerClient(source string, image string, dockerfile string
OutputStream: outputBuffer,
Dockerfile: dockerfile,
BuildArgs: buildargs,
Target: buildTarget,
}
// Build it!
return c.Client.BuildImage(opts)
}
func buildDockerCli(source string, image string, dockerfile string, buildargs []dockerlib.BuildArg, outputBuffer *bytes.Buffer) error {
func buildDockerCli(source string, image string, dockerfile string, buildargs []dockerlib.BuildArg, outputBuffer *bytes.Buffer, buildTarget string) error {
args := []string{"build", "-t", image}
if dockerfile != "" {
@ -111,6 +112,9 @@ func buildDockerCli(source string, image string, dockerfile string, buildargs []
}
args = append(args, source)
if buildTarget != "" {
args = append(args, fmt.Sprintf("--target=%s", buildTarget))
}
cmd := exec.Command("docker", args...)
cmd.Stdout = outputBuffer

View File

@ -339,3 +339,8 @@ os_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/resources-lowercase/compos
os_output="$KOMPOSE_ROOT/script/test/fixtures/resources-lowercase/output-os.yaml"
convert::expect_success "$k8s_cmd" "$k8s_output" || exit 1
convert::expect_success "$os_cmd" "$os_output" || exit 1
# Test resources to generate initcontainer
k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/initcontainer/compose.yaml convert --stdout --with-kompose-annotation=false"
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/initcontainer/output-k8s.yaml"
convert::expect_success_and_warning "$k8s_cmd" "$k8s_output" || exit 1

View File

@ -0,0 +1,8 @@
version: "3"
services:
web:
image: nginx
labels:
kompose.init.containers.name: "init-myservice"
kompose.init.containers.image: "busybox:1.28"
kompose.init.containers.command: '["sh", "-c", "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]'

View File

@ -0,0 +1,29 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
io.kompose.service: web
name: web
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: web
template:
metadata:
labels:
io.kompose.network/initcontainer-default: "true"
io.kompose.service: web
spec:
containers:
- image: nginx
name: web
initContainers:
- command:
- sh
- -c
- until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done
image: busybox:1.28
name: init-myservice
restartPolicy: Always