Merge branch 'main' into fix-1853

Signed-off-by: jose luis <2064537+sosan@users.noreply.github.com>
This commit is contained in:
jose luis 2024-04-22 12:57:36 +02:00
commit 7713c9d43d
No known key found for this signature in database
GPG Key ID: 6D23FAD11F88081A
18 changed files with 1664 additions and 33 deletions

View File

@ -19,7 +19,7 @@ jobs:
- name: Set up Go 1.x
uses: actions/setup-go@v5
with:
go-version: ^1.19
go-version: ^1.21
id: go
- name: Check out code into the Go module directory

View File

@ -5,7 +5,7 @@ jobs:
lint:
strategy:
matrix:
go: [1.18, 1.19]
go: [1.21, 1.22]
name: lint
runs-on: ubuntu-latest
steps:
@ -16,4 +16,4 @@ jobs:
with:
go-version: ${{ matrix.go }}
- name: "Run go vet"
run: "go vet ./pkg/..."
run: "go vet ./pkg/..."

View File

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: [1.18, 1.19]
go: [1.21, 1.22]
cross_compile: [true, false]
steps:
- uses: actions/checkout@v4
@ -35,7 +35,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.19
go-version: ^1.21
- name: Install dyff
run: go install github.com/homeport/dyff/cmd/dyff@v1.5.8
- name: Create .coverprofile for each targeted directory by re:running tests

View File

@ -211,9 +211,13 @@ 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 |
| kompose.init.containers.name | kubernetes init container name |
| kompose.init.containers.image | kubernetes init container image |
| kompose.init.containers.command | kubernetes init container commands |
| kompose.hpa.replicas.min | defines Horizontal Pod Autoscaler minimum number of pod replicas |
| kompose.hpa.replicas.max | defines Horizontal Pod Autoscaler maximum number of pod replicas |
| kompose.hpa.cpu | defines Horizontal Pod Autoscaler cpu utilization trigger |
| kompose.hpa.memory | defines Horizontal Pod Autoscaler memory utilization trigger |
**Note**: `kompose.service.type` label should be defined with `ports` only (except for headless service), otherwise `kompose` will fail.
@ -512,6 +516,55 @@ services:
kompose.init.containers.image: perl
```
- `kompose.hpa.replicas.min` defines the floor for the number of replicas that the HPA can scale down to during a scaling event. Default value is set to 1. This means that, regardless of the load on the system, the HPA will always maintain at least one replica. More info: [HPA Min Replicas](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics).
For example:
```yaml
services:
pgadmin:
image: postgres
labels:
kompose.hpa.replicas.min: 1
```
- `kompose.hpa.replicas.max` defines the upper limit for the number of replicas that the HPA can create during a scaling event. Default value is set to 3. This default value serves as a safeguard, providing a conservative starting point for your HPA configuration. More info: [HPA Max Replicas](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics).
For example:
```yaml
services:
pgadmin:
image: postgres
labels:
kompose.hpa.replicas.max: 10
```
- `kompose.hpa.cpu` defines % cpu utilization that triggers to scale the number of pods. It is represented as a percentage of a resource. Default value is set to 50. This default value serves as a safeguard, providing a conservative starting point for your HPA configuration. More info: [HPA CPU Utilization](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics).
For example:
```yaml
services:
pgadmin:
image: postgres
labels:
kompose.hpa.cpu: 50
```
- `kompose.hpa.memory` defines memory utilization that triggers to scale the number of pods. It is represented as a percentage of a resource. Default value is set to 70. This default value serves as a safeguard, providing a conservative starting point for your HPA configuration. More info: [HPA Memory Utilization](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics).
For example:
```yaml
services:
pgadmin:
image: postgres
labels:
kompose.hpa.memory: 50
```
## 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.

11
go.mod
View File

@ -1,9 +1,11 @@
module github.com/kubernetes/kompose
go 1.18
go 1.21
toolchain go1.21.8
require (
github.com/compose-spec/compose-go v1.20.2
github.com/compose-spec/compose-go/v2 v2.0.0-rc.8
github.com/deckarep/golang-set v1.8.0
github.com/fatih/structs v1.1.0
github.com/fsouza/go-dockerclient v1.9.7
@ -39,12 +41,13 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/patternmatcher v0.5.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
@ -61,7 +64,7 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
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/exp v0.0.0-20240112132812-db7319d0e0e3 // 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

24
go.sum
View File

@ -37,6 +37,7 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8 h1:V8krnnfGj4pV65YLUm3C0/8bl7V5Nry2Pwvy3ru/wLc=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@ -44,6 +45,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/Microsoft/hcsshim v0.9.10 h1:TxXGNmcbQxBKVWvjvTocNb6jrPyeHlk5EiDhhgHgggs=
github.com/Microsoft/hcsshim v0.9.10/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
@ -54,8 +56,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/compose-spec/compose-go v1.20.2 h1:u/yfZHn4EaHGdidrZycWpxXgFffjYULlTbRfJ51ykjQ=
github.com/compose-spec/compose-go v1.20.2/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM=
github.com/compose-spec/compose-go/v2 v2.0.0-rc.8 h1:b7l+GqFF+2W4M4kLQUDRTGhqmTiRwT3bYd9X7xrxp5Q=
github.com/compose-spec/compose-go/v2 v2.0.0-rc.8/go.mod h1:bEPizBkIojlQ20pi2vNluBa58tevvj0Y18oUSHPyfdc=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.6.26 h1:VVfrE6ZpyisvB1fzoY8Vkiq4sy+i5oF4uk7zu03RaHs=
github.com/containerd/containerd v1.6.26/go.mod h1:I4TRdsdoo5MlKob5khDJS2EPT1l1oMNaE2MBm6FrwxM=
@ -89,6 +91,7 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/fsouza/go-dockerclient v1.9.7 h1:FlIrT71E62zwKgRvCvWGdxRD+a/pIy+miY/n3MXgfuw=
@ -172,8 +175,6 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
@ -190,15 +191,21 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
@ -237,6 +244,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
@ -269,6 +277,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@ -308,8 +317,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -439,6 +448,7 @@ 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.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
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=
@ -601,6 +611,7 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
@ -639,3 +650,4 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h6
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

View File

@ -21,7 +21,7 @@ import (
"strconv"
"time"
"github.com/compose-spec/compose-go/types"
"github.com/compose-spec/compose-go/v2/types"
deployapi "github.com/openshift/api/apps/v1"
"github.com/pkg/errors"
"github.com/spf13/cast"
@ -251,7 +251,7 @@ func (s *ServiceConfig) GetConfigMapKeyFromMeta(name string) (string, error) {
}
config := s.ConfigsMetaData[name]
if config.External.External {
if config.External {
return "", errors.Errorf("config %s is external", name)
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package compose
import (
"context"
"fmt"
"os"
"reflect"
@ -24,8 +25,8 @@ import (
"strings"
"time"
"github.com/compose-spec/compose-go/cli"
"github.com/compose-spec/compose-go/types"
"github.com/compose-spec/compose-go/v2/cli"
"github.com/compose-spec/compose-go/v2/types"
"github.com/fatih/structs"
"github.com/google/shlex"
"github.com/kubernetes/kompose/pkg/kobject"
@ -167,7 +168,7 @@ func (c *Compose) LoadFile(files []string, profiles []string) (kobject.KomposeOb
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to create compose options")
}
project, err := cli.ProjectFromOptions(projectOptions)
project, err := cli.ProjectFromOptions(context.Background(), projectOptions)
if err != nil {
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to load files")
}
@ -566,7 +567,7 @@ func dockerComposeToKomposeMapping(composeObject *types.Project) (kobject.Kompos
parseEnvironment(&composeServiceConfig, &serviceConfig)
// Get env_file
serviceConfig.EnvFile = composeServiceConfig.EnvFile
parseEnvFiles(&composeServiceConfig, &serviceConfig)
// Parse the ports
// v3 uses a new format called "long syntax" starting in 3.2
@ -695,6 +696,13 @@ func parseEnvironment(composeServiceConfig *types.ServiceConfig, serviceConfig *
}
}
func parseEnvFiles(composeServiceConfig *types.ServiceConfig, serviceConfig *kobject.ServiceConfig) {
for _, value := range composeServiceConfig.EnvFiles {
serviceConfig.EnvFile = append(serviceConfig.EnvFile, value.Path)
// value.Required is ignored
}
}
func handleCronJobConcurrencyPolicy(policy string) (batchv1.ConcurrencyPolicy, error) {
switch policy {
case "Allow":

View File

@ -24,7 +24,7 @@ import (
"testing"
"time"
"github.com/compose-spec/compose-go/types"
"github.com/compose-spec/compose-go/v2/types"
"github.com/google/go-cmp/cmp"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors"
@ -429,6 +429,52 @@ func TestLoadEnvVar(t *testing.T) {
}
}
func TestParseEnvFiles(t *testing.T) {
tests := []struct {
service types.ServiceConfig
want []string
}{
{service: types.ServiceConfig{
Name: "baz",
Image: "foo/baz",
EnvFiles: []types.EnvFile{
{
Path: "",
Required: false,
},
{
Path: "foo",
Required: false,
},
{
Path: "bar",
Required: true,
},
},
},
want: []string{"", "foo", "bar"},
},
{
service: types.ServiceConfig{
Name: "baz",
Image: "foo/baz",
EnvFiles: []types.EnvFile{},
},
want: []string{},
},
}
for _, tt := range tests {
sc := kobject.ServiceConfig{
EnvFile: []string{},
}
parseEnvFiles(&tt.service, &sc)
if !reflect.DeepEqual(sc.EnvFile, tt.want) {
t.Errorf("Expected %q, got %q", tt.want, sc.EnvFile)
}
}
}
// TestUnsupportedKeys test checkUnsupportedKey function with various
// docker-compose projects
func TestUnsupportedKeys(t *testing.T) {
@ -441,7 +487,7 @@ func TestUnsupportedKeys(t *testing.T) {
},
},
Services: types.Services{
types.ServiceConfig{
"foo": types.ServiceConfig{
Name: "foo",
Image: "foo/bar",
Build: &types.BuildConfig{
@ -453,7 +499,7 @@ func TestUnsupportedKeys(t *testing.T) {
"net1": {},
},
},
types.ServiceConfig{
"bar": types.ServiceConfig{
Name: "bar",
Image: "bar/foo",
Build: &types.BuildConfig{
@ -476,7 +522,7 @@ func TestUnsupportedKeys(t *testing.T) {
projectWithDefaultNetwork := &types.Project{
Services: types.Services{
types.ServiceConfig{
"foo": types.ServiceConfig{
Networks: map[string]*types.ServiceNetworkConfig{
"default": {},
},

View File

@ -93,6 +93,14 @@ const (
LabelInitContainerImage = "kompose.init.containers.image"
// LabelInitContainerCommand defines commands
LabelInitContainerCommand = "kompose.init.containers.command"
// LabelHpaMinReplicas defines min pod replicas
LabelHpaMinReplicas = "kompose.hpa.replicas.min"
// LabelHpaMaxReplicas defines max pod replicas
LabelHpaMaxReplicas = "kompose.hpa.replicas.max"
// LabelHpaCpu defines scaling decisions based on CPU utilization
LabelHpaCPU = "kompose.hpa.cpu"
// LabelHpaMemory defines scaling decisions based on memory utilization
LabelHpaMemory = "kompose.hpa.memory"
)
// load environment variables from compose file

View File

@ -31,7 +31,7 @@ import (
"text/template"
"time"
"github.com/compose-spec/compose-go/types"
"github.com/compose-spec/compose-go/v2/types"
"github.com/joho/godotenv"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/loader/compose"
@ -41,6 +41,7 @@ import (
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
appsv1 "k8s.io/api/apps/v1"
hpa "k8s.io/api/autoscaling/v2beta2"
api "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -48,6 +49,29 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)
// Default values for Horizontal Pod Autoscaler (HPA)
const (
DefaultMinReplicas = 1
DefaultMaxReplicas = 3
DefaultCPUUtilization = 50
DefaultMemoryUtilization = 70
)
// LabelKeys are the keys for HPA related labels in the service
var LabelKeys = []string{
compose.LabelHpaCPU,
compose.LabelHpaMemory,
compose.LabelHpaMinReplicas,
compose.LabelHpaMaxReplicas,
}
type HpaValues struct {
MinReplicas int32
MaxReplicas int32
CPUtilization int32
MemoryUtilization int32
}
/**
* Generate Helm Chart configuration
*/
@ -1030,3 +1054,122 @@ func parseContainerCommandsFromStr(line string) []string {
}
return commands
}
// searchHPAValues is useful to check if labels
// contains any labels related to Horizontal Pod Autoscaler
func searchHPAValues(labels map[string]string) bool {
for _, value := range LabelKeys {
if _, ok := labels[value]; ok {
return true
}
}
return false
}
// createHPAResources creates a HorizontalPodAutoscaler (HPA) resource
// It sets the number of replicas in the service to 0 because
// the number of replicas will be managed by the HPA
func createHPAResources(name string, service *kobject.ServiceConfig) hpa.HorizontalPodAutoscaler {
valuesHpa := getResourceHpaValues(service)
service.Replicas = 0
metrics := getHpaMetricSpec(valuesHpa)
scalerSpecs := hpa.HorizontalPodAutoscaler{
TypeMeta: metav1.TypeMeta{
Kind: "HorizontalPodAutoscaler",
APIVersion: "autoscaling/v2",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: hpa.HorizontalPodAutoscalerSpec{
ScaleTargetRef: hpa.CrossVersionObjectReference{
Kind: "Deployment",
Name: name,
APIVersion: "apps/v1",
},
MinReplicas: &valuesHpa.MinReplicas,
MaxReplicas: valuesHpa.MaxReplicas,
Metrics: metrics,
},
}
return scalerSpecs
}
// getResourceHpaValues retrieves the min/max replicas and CPU/memory utilization values
// control if maxReplicas is less than minReplicas
func getResourceHpaValues(service *kobject.ServiceConfig) HpaValues {
minReplicas := getHpaValue(service, compose.LabelHpaMinReplicas, DefaultMinReplicas)
maxReplicas := getHpaValue(service, compose.LabelHpaMaxReplicas, DefaultMaxReplicas)
if maxReplicas < minReplicas {
log.Warnf("maxReplicas %d is less than minReplicas %d. Using minReplicas value %d", maxReplicas, minReplicas, minReplicas)
maxReplicas = minReplicas
}
cpuUtilization := validatePercentageMetric(service, compose.LabelHpaCPU, DefaultCPUUtilization)
memoryUtilization := validatePercentageMetric(service, compose.LabelHpaMemory, DefaultMemoryUtilization)
return HpaValues{
MinReplicas: minReplicas,
MaxReplicas: maxReplicas,
CPUtilization: cpuUtilization,
MemoryUtilization: memoryUtilization,
}
}
// validatePercentageMetric validates the CPU or memory metrics value
// ensuring that it falls within the acceptable range [1, 100].
func validatePercentageMetric(service *kobject.ServiceConfig, metricLabel string, defaultValue int32) int32 {
metricValue := getHpaValue(service, metricLabel, defaultValue)
if metricValue > 100 || metricValue < 1 {
log.Warnf("Metric value %d is not within the acceptable range [1, 100]. Using default value %d", metricValue, defaultValue)
return defaultValue
}
return metricValue
}
// getHpaValue convert the label value to integer
// If the label is not present or the conversion fails
// it returns the provided default value
func getHpaValue(service *kobject.ServiceConfig, label string, defaultValue int32) int32 {
valueFromLabel, err := strconv.Atoi(service.Labels[label])
if err != nil || valueFromLabel < 0 {
log.Warnf("Error converting label %s. Using default value %d", label, defaultValue)
return defaultValue
}
return int32(valueFromLabel)
}
// getHpaMetricSpec returns a list of metric specs for the HPA resource
// Target type is hardcoded to hpa.UtilizationMetricType
// Each MetricSpec specifies the type metric CPU/memory and average utilization value
// to trigger scaling
func getHpaMetricSpec(hpaValues HpaValues) []hpa.MetricSpec {
var metrics []hpa.MetricSpec
if hpaValues.CPUtilization > 0 {
metrics = append(metrics, hpa.MetricSpec{
Type: hpa.ResourceMetricSourceType,
Resource: &hpa.ResourceMetricSource{
Name: api.ResourceCPU,
Target: hpa.MetricTarget{
Type: hpa.UtilizationMetricType,
AverageUtilization: &hpaValues.CPUtilization,
},
},
})
}
if hpaValues.MemoryUtilization > 0 {
metrics = append(metrics, hpa.MetricSpec{
Type: hpa.ResourceMetricSourceType,
Resource: &hpa.ResourceMetricSource{
Name: api.ResourceMemory,
Target: hpa.MetricTarget{
Type: hpa.UtilizationMetricType,
AverageUtilization: &hpaValues.MemoryUtilization,
},
},
})
}
return metrics
}

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ import (
"strconv"
"strings"
"github.com/compose-spec/compose-go/types"
"github.com/compose-spec/compose-go/v2/types"
"github.com/fatih/structs"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/loader/compose"
@ -1314,7 +1314,7 @@ func (k *Kubernetes) createConfigMapFromComposeConfig(name string, service kobje
for _, config := range service.Configs {
currentConfigName := config.Source
currentConfigObj := service.ConfigsMetaData[currentConfigName]
if currentConfigObj.External.External {
if currentConfigObj.External {
continue
}
currentFileName := currentConfigObj.File
@ -1654,6 +1654,10 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
return nil, err
}
}
err = k.configHorizontalPodScaler(name, service, opt, &objects)
if err != nil {
return nil, errors.Wrap(err, "Error creating Kubernetes HPA")
}
allobjects = append(allobjects, objects...)
}
@ -1718,3 +1722,16 @@ func (k *Kubernetes) UpdateController(obj runtime.Object, updateTemplate func(*a
}
return nil
}
// configHorizontalPodScaler create Hpa resource also append to the objects
// first checks if the service labels contain any HPA labels using the searchHPAValues
func (k *Kubernetes) configHorizontalPodScaler(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions, objects *[]runtime.Object) (err error) {
found := searchHPAValues(service.Labels)
if !found {
return nil
}
hpa := createHPAResources(name, &service)
*objects = append(*objects, &hpa)
return nil
}

View File

@ -23,7 +23,7 @@ import (
"strings"
"testing"
"github.com/compose-spec/compose-go/types"
"github.com/compose-spec/compose-go/v2/types"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/loader/compose"

View File

@ -121,7 +121,7 @@ func parseVolume(volume string) (name, host, container, mode string, err error)
return
}
// parseVolume parses window volume.
// parseWindowsVolume parses window volume.
// example: windows host mount to windows container
// volume = dataVolumeName:C:\Users\Data:D:\config:rw
// it can be parsed:

View File

@ -345,6 +345,11 @@ k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/initcontainer/compose.yam
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/initcontainer/output-k8s.yaml"
convert::expect_success_and_warning "$k8s_cmd" "$k8s_output" || exit 1
# Test HPA
k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/hpa/compose.yaml convert --stdout --with-kompose-annotation=false"
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/hpa/output-k8s.yaml"
convert::expect_success "$k8s_cmd" "$k8s_output" || exit 1
# Test env var with status
k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/envvars-with-status/compose.yaml convert --stdout --with-kompose-annotation=false"
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/envvars-with-status/output-k8s.yaml"

10
script/test/fixtures/hpa/compose.yaml vendored Normal file
View File

@ -0,0 +1,10 @@
version: "3.8"
services:
web:
image: nginx
labels:
kompose.hpa.cpu: 50
kompose.hpa.memory: 70
kompose.hpa.replicas.min: 1
kompose.hpa.replicas.max: 10

View File

@ -0,0 +1,49 @@
---
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/hpa-default: "true"
io.kompose.service: web
spec:
containers:
- image: nginx
name: web
restartPolicy: Always
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web
spec:
maxReplicas: 10
metrics:
- resource:
name: cpu
target:
averageUtilization: 50
type: Utilization
type: Resource
- resource:
name: memory
target:
averageUtilization: 70
type: Utilization
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web