forked from LaconicNetwork/kompose
Merge branch 'main' into feature-1635-with-labels
This commit is contained in:
commit
a589f1d6e9
@ -211,6 +211,9 @@ The currently supported options are:
|
|||||||
| kompose.cronjob.schedule | kubernetes cronjob schedule (for example: '1 * * * *') |
|
| kompose.cronjob.schedule | kubernetes cronjob schedule (for example: '1 * * * *') |
|
||||||
| kompose.cronjob.concurrency_policy | 'Forbid' / 'Allow' / 'Never' / '' |
|
| kompose.cronjob.concurrency_policy | 'Forbid' / 'Allow' / 'Never' / '' |
|
||||||
| kompose.cronjob.backoff_limit | kubernetes cronjob backoff limit (for example: '6') |
|
| 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.
|
**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:
|
labels:
|
||||||
kompose.volume.sub-path: pg-data
|
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
|
## 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.
|
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
10
go.mod
@ -19,7 +19,7 @@ require (
|
|||||||
github.com/spf13/cobra v1.8.0
|
github.com/spf13/cobra v1.8.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/spf13/viper v1.16.0
|
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
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gotest.tools/v3 v3.5.1
|
gotest.tools/v3 v3.5.1
|
||||||
k8s.io/api v0.28.4
|
k8s.io/api v0.28.4
|
||||||
@ -62,10 +62,10 @@ require (
|
|||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/mod v0.16.0 // indirect
|
||||||
golang.org/x/net v0.19.0 // indirect
|
golang.org/x/net v0.22.0 // indirect
|
||||||
golang.org/x/sync v0.5.0 // indirect
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
golang.org/x/sys v0.15.0 // indirect
|
golang.org/x/sys v0.18.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
|||||||
22
go.sum
22
go.sum
@ -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.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.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.1/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.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
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-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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
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.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
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-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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/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-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-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.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.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
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-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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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-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-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.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
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.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.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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/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.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
|
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||||
golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
|
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-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
@ -144,6 +144,7 @@ type ServiceConfig struct {
|
|||||||
ExposeService string `compose:"kompose.service.expose"`
|
ExposeService string `compose:"kompose.service.expose"`
|
||||||
ExposeServicePath string `compose:"kompose.service.expose.path"`
|
ExposeServicePath string `compose:"kompose.service.expose.path"`
|
||||||
BuildLabels map[string]string `compose:"build-labels"`
|
BuildLabels map[string]string `compose:"build-labels"`
|
||||||
|
BuildTarget string `compose:""`
|
||||||
ExposeServiceTLS string `compose:"kompose.service.expose.tls-secret"`
|
ExposeServiceTLS string `compose:"kompose.service.expose.tls-secret"`
|
||||||
ExposeServiceIngressClassName string `compose:"kompose.service.expose.ingress-class-name"`
|
ExposeServiceIngressClassName string `compose:"kompose.service.expose.ingress-class-name"`
|
||||||
ImagePullSecret string `compose:"kompose.image-pull-secret"`
|
ImagePullSecret string `compose:"kompose.image-pull-secret"`
|
||||||
|
|||||||
@ -559,6 +559,7 @@ func dockerComposeToKomposeMapping(composeObject *types.Project) (kobject.Kompos
|
|||||||
serviceConfig.Dockerfile = composeServiceConfig.Build.Dockerfile
|
serviceConfig.Dockerfile = composeServiceConfig.Build.Dockerfile
|
||||||
serviceConfig.BuildArgs = composeServiceConfig.Build.Args
|
serviceConfig.BuildArgs = composeServiceConfig.Build.Args
|
||||||
serviceConfig.BuildLabels = composeServiceConfig.Build.Labels
|
serviceConfig.BuildLabels = composeServiceConfig.Build.Labels
|
||||||
|
serviceConfig.BuildTarget = composeServiceConfig.Build.Target
|
||||||
}
|
}
|
||||||
|
|
||||||
// env
|
// env
|
||||||
|
|||||||
@ -88,6 +88,12 @@ const (
|
|||||||
LabelCronJobConcurrencyPolicy = "kompose.cronjob.concurrency_policy"
|
LabelCronJobConcurrencyPolicy = "kompose.cronjob.concurrency_policy"
|
||||||
// LabelCronJobBackoffLimit defines the job backoff limit
|
// LabelCronJobBackoffLimit defines the job backoff limit
|
||||||
LabelCronJobBackoffLimit = "kompose.cronjob.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 defines the override resource name
|
||||||
LabelNameOverride = "kompose.service.name_override"
|
LabelNameOverride = "kompose.service.name_override"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -654,7 +654,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
|
|||||||
if serviceAccountName, ok := service.Labels[compose.LabelServiceAccountName]; ok {
|
if serviceAccountName, ok := service.Labels[compose.LabelServiceAccountName]; ok {
|
||||||
template.Spec.ServiceAccountName = serviceAccountName
|
template.Spec.ServiceAccountName = serviceAccountName
|
||||||
}
|
}
|
||||||
|
fillInitContainers(template, service)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -985,3 +985,48 @@ func reformatSecretConfigUnderscoreWithDash(secretConfig types.ServiceSecretConf
|
|||||||
|
|
||||||
return newSecretConfig
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/kubernetes/kompose/pkg/testutils"
|
"github.com/kubernetes/kompose/pkg/testutils"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
|
api "k8s.io/api/core/v1"
|
||||||
corev1 "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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -396,7 +396,7 @@ func BuildDockerImage(service kobject.ServiceConfig, name string) error {
|
|||||||
// Use the build struct function to build the image
|
// Use the build struct function to build the image
|
||||||
// Build the image!
|
// Build the image!
|
||||||
build := docker.Build{Client: *client}
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -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
|
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))
|
log.Infof("Building image '%s' from directory '%s'", image, path.Base(source))
|
||||||
|
|
||||||
outputBuffer := bytes.NewBuffer(nil)
|
outputBuffer := bytes.NewBuffer(nil)
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if usecli, _ := strconv.ParseBool(os.Getenv("DOCKER_BUILDKIT")); usecli {
|
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 {
|
} 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)
|
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
|
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
|
// Create a temporary file for tarball image packaging
|
||||||
tmpFile, err := os.CreateTemp(os.TempDir(), "kompose-image-build-")
|
tmpFile, err := os.CreateTemp(os.TempDir(), "kompose-image-build-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -93,13 +93,14 @@ func (c *Build) buildDockerClient(source string, image string, dockerfile string
|
|||||||
OutputStream: outputBuffer,
|
OutputStream: outputBuffer,
|
||||||
Dockerfile: dockerfile,
|
Dockerfile: dockerfile,
|
||||||
BuildArgs: buildargs,
|
BuildArgs: buildargs,
|
||||||
|
Target: buildTarget,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build it!
|
// Build it!
|
||||||
return c.Client.BuildImage(opts)
|
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}
|
args := []string{"build", "-t", image}
|
||||||
|
|
||||||
if dockerfile != "" {
|
if dockerfile != "" {
|
||||||
@ -111,6 +112,9 @@ func buildDockerCli(source string, image string, dockerfile string, buildargs []
|
|||||||
}
|
}
|
||||||
|
|
||||||
args = append(args, source)
|
args = append(args, source)
|
||||||
|
if buildTarget != "" {
|
||||||
|
args = append(args, fmt.Sprintf("--target=%s", buildTarget))
|
||||||
|
}
|
||||||
|
|
||||||
cmd := exec.Command("docker", args...)
|
cmd := exec.Command("docker", args...)
|
||||||
cmd.Stdout = outputBuffer
|
cmd.Stdout = outputBuffer
|
||||||
|
|||||||
@ -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"
|
os_output="$KOMPOSE_ROOT/script/test/fixtures/resources-lowercase/output-os.yaml"
|
||||||
convert::expect_success "$k8s_cmd" "$k8s_output" || exit 1
|
convert::expect_success "$k8s_cmd" "$k8s_output" || exit 1
|
||||||
convert::expect_success "$os_cmd" "$os_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
|
||||||
|
|||||||
8
script/test/fixtures/initcontainer/compose.yaml
vendored
Normal file
8
script/test/fixtures/initcontainer/compose.yaml
vendored
Normal 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"]'
|
||||||
29
script/test/fixtures/initcontainer/output-k8s.yaml
vendored
Normal file
29
script/test/fixtures/initcontainer/output-k8s.yaml
vendored
Normal 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
|
||||||
Loading…
Reference in New Issue
Block a user