forked from LaconicNetwork/kompose
feat: migrate from libcompose to compose-go (#1547)
* feat: migrate from libcompose to compose-go libcompose has been deprecated since summer 2021 in favor of https://github.com/compose-spec/compose-go. Kompose should now be able to load all versions of compose. * chore: replace golint with staticcheck golint has been deprecated. Recommended replacement is staticcheck.
This commit is contained in:
parent
7304bb6013
commit
2ad5745d58
11
.github/workflows/go.yml
vendored
11
.github/workflows/go.yml
vendored
@ -17,19 +17,20 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ^1.16
|
||||
go-version: ^1.19
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build
|
||||
run: make bin
|
||||
|
||||
|
||||
- name: Upload a Build Artifact
|
||||
uses: actions/upload-artifact@v2.1.4
|
||||
with:
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "kompose"
|
||||
path: "kompose"
|
||||
|
||||
21
.github/workflows/golangci-lint.yml
vendored
21
.github/workflows/golangci-lint.yml
vendored
@ -1,21 +0,0 @@
|
||||
name: golangci-lint
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
golangci:
|
||||
strategy:
|
||||
matrix:
|
||||
go: [1.16, 1.17]
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
- uses: actions/checkout@v2
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||
version: v1.29
|
||||
args: --timeout 5m
|
||||
26
.github/workflows/lint.yml
vendored
Normal file
26
.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
name: lint
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
lint:
|
||||
strategy:
|
||||
matrix:
|
||||
go: [1.18, 1.19]
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v3
|
||||
- name: "Install golang"
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
- name: "Run go vet"
|
||||
run: "go vet ./pkg/..."
|
||||
- name: "Run staticcheck"
|
||||
uses: dominikh/staticcheck-action@v1
|
||||
with:
|
||||
cache-key: "${{ matrix.go }}"
|
||||
install-go: false
|
||||
version: "latest"
|
||||
working-directory: "pkg"
|
||||
16
.github/workflows/test.yml
vendored
16
.github/workflows/test.yml
vendored
@ -10,14 +10,14 @@ env:
|
||||
jobs:
|
||||
test:
|
||||
name: Test with ${{ matrix.go }} and CROSS_COMPILE=${{ matrix.cross_compile }}
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go: [1.16, 1.17]
|
||||
go: [1.18, 1.19]
|
||||
cross_compile: [true, false]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
- name: Run tests
|
||||
@ -27,13 +27,13 @@ jobs:
|
||||
run: make cross
|
||||
docs:
|
||||
name: Build docs and Coveralls integration
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: test
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.16
|
||||
go-version: 1.19
|
||||
- name: Create .coverprofile for each targeted directory by re:running tests
|
||||
run: make test
|
||||
- name: Collect all .coverprofile files and save it to one file gover.coverprofile
|
||||
|
||||
@ -12,7 +12,7 @@ linters:
|
||||
# - errcheck
|
||||
# - goconst
|
||||
- goimports
|
||||
# - golint
|
||||
# - staticcheck
|
||||
- goprintffuncname
|
||||
# - gosimple
|
||||
- govet
|
||||
|
||||
10
Makefile
10
Makefile
@ -91,15 +91,15 @@ gen-cmd:
|
||||
|
||||
# run all validation tests
|
||||
.PHONY: validate
|
||||
validate: gofmt vet lint
|
||||
validate: gofmt vet staticcheck
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
go vet ./pkg/...
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
golint ./pkg/...
|
||||
.PHONY: staticcheck
|
||||
staticcheck:
|
||||
staticcheck ./pkg/...
|
||||
|
||||
.PHONY: gofmt
|
||||
gofmt:
|
||||
@ -114,7 +114,7 @@ test: bin test-dep validate test-unit-cover install test-cmd
|
||||
test-dep:
|
||||
go install github.com/mattn/goveralls@latest
|
||||
go install github.com/modocache/gover@latest
|
||||
go install golang.org/x/lint/golint@latest
|
||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
go install github.com/mitchellh/gox@latest
|
||||
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ func init() {
|
||||
}
|
||||
|
||||
/*
|
||||
Fish shell auto-completion support
|
||||
Fish shell auto-completion support
|
||||
*/
|
||||
func runCompletionFish(out io.Writer, kompose *cobra.Command) error {
|
||||
kompose.GenFishCompletion(out, true)
|
||||
@ -79,9 +79,9 @@ complete -c kompose -n "__fish_seen_subcommand_from completion" -a "bash zsh fis
|
||||
}
|
||||
|
||||
/*
|
||||
This is copied from
|
||||
https://github.com/kubernetes/kubernetes/blob/ea18d5c32ee7c320fe96dda6b0c757476908e696/pkg/kubectl/cmd/completion.go
|
||||
in order to generate ZSH completion support.
|
||||
This is copied from
|
||||
https://github.com/kubernetes/kubernetes/blob/ea18d5c32ee7c320fe96dda6b0c757476908e696/pkg/kubectl/cmd/completion.go
|
||||
in order to generate ZSH completion support.
|
||||
*/
|
||||
func runCompletionZsh(out io.Writer, kompose *cobra.Command) error {
|
||||
zshInitialization := `
|
||||
|
||||
@ -14,26 +14,10 @@ redirect_from:
|
||||
|
||||
This document outlines all possible conversion details regarding `docker-compose.yaml` values to Kubernetes / OpenShift artifacts.
|
||||
|
||||
## Version Table
|
||||
## Version Support
|
||||
|
||||
| Supported | Compose Version | Docker Engine Version |
|
||||
|------------|-----------------|-----------------------|
|
||||
| N | 3.8 | 19.03.0+ |
|
||||
| N | 3.7 | 18.06.0+ |
|
||||
| N | 3.6 | 18.02.0+ |
|
||||
| N | 3.5 | 17.12.0+ |
|
||||
| N | 3.4 | 17.09.0+ |
|
||||
| Y | 3.3 | 17.06.0+ |
|
||||
| Y | 3.2 | 17.04.0+ |
|
||||
| Y | 3.1 | 1.13.1+ |
|
||||
| Y | 3.0 | 1.13.0+ |
|
||||
| Y | 2.4 | 17.12.0+ |
|
||||
| Y | 2.3 | 17.06.0+ |
|
||||
| Y | 2.2 | 1.13.0+ |
|
||||
| Y | 2.1 | 1.12.0+ |
|
||||
| Y | 2.0 | 1.10.0+ |
|
||||
|
||||
**Note:** We don't support anything 3.4 and above at the moment. It is reccomended to specify `version: "3.3"` in your `docker-compose.yaml` and converting. We use a library called [libcompose](https://github.com/docker/libcompose) that supports up to version `3.3`. If you are interested in adding additional support, please open up a PR!
|
||||
Under the hood, we're using [compose-go](https://github.com/compose-spec/compose-go), the reference library for parsing Compose files. We should be able to load all versions of Compose files.
|
||||
We're doing our best to keep it up to date as soon as possible in our releases to be compatible with the latest features defined in the [Compose specification](https://github.com/compose-spec/compose-spec/blob/master/spec.md). If you absolutely need a feature we don't support yet, please open a PR!
|
||||
|
||||
## Conversion Table
|
||||
|
||||
|
||||
13
go.mod
13
go.mod
@ -4,8 +4,6 @@ go 1.13
|
||||
|
||||
replace github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.8.1
|
||||
|
||||
replace github.com/docker/libcompose => github.com/docker/libcompose v0.4.1-0.20190808084053-143e0f3f1ab9
|
||||
|
||||
replace github.com/docker/cli => github.com/docker/cli v20.10.16+incompatible
|
||||
|
||||
replace github.com/xeipuuv/gojsonschema => github.com/xeipuuv/gojsonschema v1.2.1-0.20201027075954-b076d39a02e5
|
||||
@ -31,28 +29,25 @@ replace github.com/emicklei/go-restful => github.com/emicklei/go-restful v2.16.0
|
||||
replace golang.org/x/crypto => golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d
|
||||
|
||||
require (
|
||||
github.com/compose-spec/compose-go v1.8.2
|
||||
github.com/containerd/containerd v1.6.4 // indirect
|
||||
github.com/deckarep/golang-set v1.7.1
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/libcompose v0.4.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/fsouza/go-dockerclient v1.6.6
|
||||
github.com/google/go-cmp v0.5.8
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/novln/docker-parser v1.0.0
|
||||
github.com/openshift/api v0.0.0-20200803131051-87466835fcc0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cast v1.3.1
|
||||
github.com/spf13/cobra v1.1.3
|
||||
github.com/spf13/viper v1.7.1
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect
|
||||
golang.org/x/text v0.3.8 // indirect
|
||||
golang.org/x/tools v0.1.12
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.22.5
|
||||
k8s.io/apimachinery v0.22.5
|
||||
)
|
||||
|
||||
88
go.sum
88
go.sum
@ -35,27 +35,29 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
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/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
|
||||
github.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
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/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||
github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Microsoft/go-winio v0.3.8/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20200113171025-3fe6c5262873/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
||||
github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
|
||||
github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
|
||||
@ -68,6 +70,7 @@ github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@ -80,14 +83,20 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-sdk-go v1.43.16/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
@ -113,6 +122,8 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||
github.com/compose-spec/compose-go v1.8.2 h1:sUQvDxnPgpcOyoxC/lz7mFTrTlHeZ6LWyuASYetkOqw=
|
||||
github.com/compose-spec/compose-go v1.8.2/go.mod h1:Tb5Ae2PsYN3GTqYqzl2IRbTPiJtPZZjMw8UKUvmehFk=
|
||||
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||
@ -174,24 +185,24 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
|
||||
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/cli v20.10.16+incompatible h1:aLQ8XowgKpR3/IysPj8qZQJBVQ+Qws61icFuZl6iKYs=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20221103125252-ebfa2a0ac0a9 h1:doprs/RuXCuN864IfxC3h2qocrt158wGv3A5mcqSZQw=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20221103125252-ebfa2a0ac0a9/go.mod h1:6rIc5NMSjXjjnwzWWy3HAm9gDBu+X7aCzL8VrHIKgxM=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v20.10.16+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v20.10.0-beta1.0.20201030232932-c2cc352355d4+incompatible h1:7Wcl0zstnDmC7woif4M/PWN8kql0+m1h38WhF/raC4E=
|
||||
github.com/docker/docker v20.10.0-beta1.0.20201030232932-c2cc352355d4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libcompose v0.4.1-0.20190808084053-143e0f3f1ab9 h1:Z+aRYtQXR6iFSAnoaAq/dUTcZvL1ph8uWlsrmfIP8Bs=
|
||||
github.com/docker/libcompose v0.4.1-0.20190808084053-143e0f3f1ab9/go.mod h1:YZ/h8H7gZ7/SOoviPEvSYgHomvbB82iyHvGXLVTNFwQ=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
@ -212,8 +223,6 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
@ -263,6 +272,7 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
@ -270,6 +280,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -303,6 +315,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
@ -318,8 +331,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@ -348,8 +361,7 @@ github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2c
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v0.0.0-20160317213430-0eeaf8392f5b/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
@ -377,6 +389,7 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
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/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
@ -387,11 +400,14 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
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.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
|
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
@ -424,7 +440,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v0.0.0-20150511174710-5cf931ef8f76/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
@ -442,6 +457,7 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
@ -456,8 +472,10 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
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/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/sys/mount v0.1.0 h1:Ytx78EatgFKtrqZ0BvJ0UtJE472ZvawVmil6pIfuCCU=
|
||||
@ -477,7 +495,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
@ -486,6 +503,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/networkplumbing/go-nft v0.2.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/novln/docker-parser v1.0.0 h1:PjEBd9QnKixcWczNGyEdfUrP6GR0YUilAqG7Wksg3uc=
|
||||
@ -512,12 +530,10 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v0.0.0-20170515205857-f03dbe35d449/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
|
||||
@ -555,6 +571,7 @@ github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQ
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@ -566,6 +583,7 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
@ -593,8 +611,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
@ -628,13 +647,18 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
@ -644,7 +668,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
@ -667,6 +690,9 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
@ -796,6 +822,7 @@ golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo=
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
@ -817,8 +844,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
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-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@ -899,6 +927,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
@ -933,6 +962,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@ -974,7 +1004,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
@ -1039,13 +1068,16 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
|
||||
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@ -21,8 +21,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
dockerCliTypes "github.com/docker/cli/cli/compose/types"
|
||||
"github.com/docker/libcompose/yaml"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
deployapi "github.com/openshift/api/apps/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cast"
|
||||
@ -38,7 +37,7 @@ type KomposeObject struct {
|
||||
// as they can have different names. For example environment variables are called environment in compose but Env in bundle.
|
||||
LoadedFrom string
|
||||
|
||||
Secrets map[string]dockerCliTypes.SecretConfig
|
||||
Secrets types.Secrets
|
||||
}
|
||||
|
||||
// ConvertOptions holds all options that controls transformation process
|
||||
@ -99,64 +98,64 @@ type ServiceConfigGroup []ServiceConfig
|
||||
type ServiceConfig struct {
|
||||
Name string
|
||||
ContainerName string
|
||||
Image string `compose:"image"`
|
||||
Environment []EnvVar `compose:"environment"`
|
||||
EnvFile []string `compose:"env_file"`
|
||||
Port []Ports `compose:"ports"`
|
||||
Command []string `compose:"command"`
|
||||
WorkingDir string `compose:""`
|
||||
DomainName string `compose:"domainname"`
|
||||
HostName string `compose:"hostname"`
|
||||
Args []string `compose:"args"`
|
||||
VolList []string `compose:"volumes"`
|
||||
Network []string `compose:"network"`
|
||||
Labels map[string]string `compose:"labels"`
|
||||
Annotations map[string]string `compose:""`
|
||||
CPUSet string `compose:"cpuset"`
|
||||
CPUShares int64 `compose:"cpu_shares"`
|
||||
CPUQuota int64 `compose:"cpu_quota"`
|
||||
CPULimit int64 `compose:""`
|
||||
CPUReservation int64 `compose:""`
|
||||
CapAdd []string `compose:"cap_add"`
|
||||
CapDrop []string `compose:"cap_drop"`
|
||||
Expose []string `compose:"expose"`
|
||||
ImagePullPolicy string `compose:"kompose.image-pull-policy"`
|
||||
Pid string `compose:"pid"`
|
||||
Privileged bool `compose:"privileged"`
|
||||
Restart string `compose:"restart"`
|
||||
User string `compose:"user"`
|
||||
VolumesFrom []string `compose:"volumes_from"`
|
||||
ServiceType string `compose:"kompose.service.type"`
|
||||
NodePortPort int32 `compose:"kompose.service.nodeport.port"`
|
||||
StopGracePeriod string `compose:"stop_grace_period"`
|
||||
Build string `compose:"build"`
|
||||
BuildArgs map[string]*string `compose:"build-args"`
|
||||
ExposeService string `compose:"kompose.service.expose"`
|
||||
ExposeServicePath string `compose:"kompose.service.expose.path"`
|
||||
BuildLabels map[string]string `compose:"build-labels"`
|
||||
ExposeServiceTLS string `compose:"kompose.service.expose.tls-secret"`
|
||||
ExposeServiceIngressClassName string `compose:"kompose.service.expose.ingress-class-name"`
|
||||
ImagePullSecret string `compose:"kompose.image-pull-secret"`
|
||||
Stdin bool `compose:"stdin_open"`
|
||||
Tty bool `compose:"tty"`
|
||||
MemLimit yaml.MemStringorInt `compose:"mem_limit"`
|
||||
MemReservation yaml.MemStringorInt `compose:""`
|
||||
DeployMode string `compose:""`
|
||||
Image string `compose:"image"`
|
||||
Environment []EnvVar `compose:"environment"`
|
||||
EnvFile []string `compose:"env_file"`
|
||||
Port []Ports `compose:"ports"`
|
||||
Command []string `compose:"command"`
|
||||
WorkingDir string `compose:""`
|
||||
DomainName string `compose:"domainname"`
|
||||
HostName string `compose:"hostname"`
|
||||
Args []string `compose:"args"`
|
||||
VolList []string `compose:"volumes"`
|
||||
Network []string `compose:"network"`
|
||||
Labels map[string]string `compose:"labels"`
|
||||
Annotations map[string]string `compose:""`
|
||||
CPUSet string `compose:"cpuset"`
|
||||
CPUShares int64 `compose:"cpu_shares"`
|
||||
CPUQuota int64 `compose:"cpu_quota"`
|
||||
CPULimit int64 `compose:""`
|
||||
CPUReservation int64 `compose:""`
|
||||
CapAdd []string `compose:"cap_add"`
|
||||
CapDrop []string `compose:"cap_drop"`
|
||||
Expose []string `compose:"expose"`
|
||||
ImagePullPolicy string `compose:"kompose.image-pull-policy"`
|
||||
Pid string `compose:"pid"`
|
||||
Privileged bool `compose:"privileged"`
|
||||
Restart string `compose:"restart"`
|
||||
User string `compose:"user"`
|
||||
VolumesFrom []string `compose:"volumes_from"`
|
||||
ServiceType string `compose:"kompose.service.type"`
|
||||
NodePortPort int32 `compose:"kompose.service.nodeport.port"`
|
||||
StopGracePeriod string `compose:"stop_grace_period"`
|
||||
Build string `compose:"build"`
|
||||
BuildArgs map[string]*string `compose:"build-args"`
|
||||
ExposeService string `compose:"kompose.service.expose"`
|
||||
ExposeServicePath string `compose:"kompose.service.expose.path"`
|
||||
BuildLabels map[string]string `compose:"build-labels"`
|
||||
ExposeServiceTLS string `compose:"kompose.service.expose.tls-secret"`
|
||||
ExposeServiceIngressClassName string `compose:"kompose.service.expose.ingress-class-name"`
|
||||
ImagePullSecret string `compose:"kompose.image-pull-secret"`
|
||||
Stdin bool `compose:"stdin_open"`
|
||||
Tty bool `compose:"tty"`
|
||||
MemLimit types.UnitBytes `compose:"mem_limit"`
|
||||
MemReservation types.UnitBytes `compose:""`
|
||||
DeployMode string `compose:""`
|
||||
// DeployLabels mapping to kubernetes labels
|
||||
DeployLabels map[string]string `compose:""`
|
||||
DeployUpdateConfig dockerCliTypes.UpdateConfig `compose:""`
|
||||
TmpFs []string `compose:"tmpfs"`
|
||||
Dockerfile string `compose:"dockerfile"`
|
||||
Replicas int `compose:"replicas"`
|
||||
GroupAdd []int64 `compose:"group_add"`
|
||||
Volumes []Volumes `compose:""`
|
||||
Secrets []dockerCliTypes.ServiceSecretConfig
|
||||
DeployLabels map[string]string `compose:""`
|
||||
DeployUpdateConfig types.UpdateConfig `compose:""`
|
||||
TmpFs []string `compose:"tmpfs"`
|
||||
Dockerfile string `compose:"dockerfile"`
|
||||
Replicas int `compose:"replicas"`
|
||||
GroupAdd []int64 `compose:"group_add"`
|
||||
Volumes []Volumes `compose:""`
|
||||
Secrets []types.ServiceSecretConfig
|
||||
HealthChecks HealthChecks `compose:""`
|
||||
Placement Placement `compose:""`
|
||||
//This is for long LONG SYNTAX link(https://docs.docker.com/compose/compose-file/#long-syntax)
|
||||
Configs []dockerCliTypes.ServiceConfigObjConfig `compose:""`
|
||||
Configs []types.ServiceConfigObjConfig `compose:""`
|
||||
//This is for SHORT SYNTAX link(https://docs.docker.com/compose/compose-file/#configs)
|
||||
ConfigsMetaData map[string]dockerCliTypes.ConfigObjConfig `compose:""`
|
||||
ConfigsMetaData types.Configs `compose:""`
|
||||
|
||||
WithKomposeAnnotation bool `compose:""`
|
||||
InGroup bool
|
||||
|
||||
@ -18,30 +18,36 @@ package compose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/google/shlex"
|
||||
"github.com/kubernetes/kompose/pkg/kobject"
|
||||
"github.com/kubernetes/kompose/pkg/transformer"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cast"
|
||||
api "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
//StdinData is data bytes read from stdin
|
||||
// StdinData is data bytes read from stdin
|
||||
var StdinData []byte
|
||||
|
||||
// Compose is docker compose file loader, implements Loader interface
|
||||
type Compose struct {
|
||||
}
|
||||
|
||||
// checkUnsupportedKey checks if libcompose project contains
|
||||
// checkUnsupportedKey checks if compose-go project contains
|
||||
// keys that are not supported by this loader.
|
||||
// list of all unsupported keys are stored in unsupportedKey variable
|
||||
// returns list of unsupported YAML keys from docker-compose
|
||||
func checkUnsupportedKey(composeProject *project.Project) []string {
|
||||
func checkUnsupportedKey(composeProject *types.Project) []string {
|
||||
// list of all unsupported keys for this loader
|
||||
// this is map to make searching for keys easier
|
||||
// to make sure that unsupported key is not going to be reported twice
|
||||
@ -79,18 +85,18 @@ func checkUnsupportedKey(composeProject *project.Project) []string {
|
||||
|
||||
// Root level keys are not yet supported except Network
|
||||
// Check to see if the default network is available and length is only equal to one.
|
||||
if _, ok := composeProject.NetworkConfigs["default"]; ok && len(composeProject.NetworkConfigs) == 1 {
|
||||
if _, ok := composeProject.Networks["default"]; ok && len(composeProject.Networks) == 1 {
|
||||
log.Debug("Default network found")
|
||||
}
|
||||
|
||||
// Root level volumes are not yet supported
|
||||
if len(composeProject.VolumeConfigs) > 0 {
|
||||
if len(composeProject.Volumes) > 0 {
|
||||
keysFound = append(keysFound, "root level volumes")
|
||||
}
|
||||
|
||||
for _, serviceConfig := range composeProject.ServiceConfigs.All() {
|
||||
for _, serviceConfig := range composeProject.AllServices() {
|
||||
// this reflection is used in check for empty arrays
|
||||
val := reflect.ValueOf(serviceConfig).Elem()
|
||||
val := reflect.ValueOf(serviceConfig)
|
||||
s := structs.New(serviceConfig)
|
||||
|
||||
for _, f := range s.Fields() {
|
||||
@ -109,7 +115,7 @@ func checkUnsupportedKey(composeProject *project.Project) []string {
|
||||
yamlTagName := strings.Split(f.Tag("yaml"), ",")[0]
|
||||
if f.Name() == "Networks" {
|
||||
// networks always contains one default element, even it isn't declared in compose v2.
|
||||
if len(serviceConfig.Networks.Networks) == 1 && serviceConfig.Networks.Networks[0].Name == "default" {
|
||||
if len(serviceConfig.Networks) == 1 && serviceConfig.NetworksByPriority()[0] == "default" {
|
||||
// this is empty Network definition, skip it
|
||||
continue
|
||||
}
|
||||
@ -144,61 +150,733 @@ func checkUnsupportedKey(composeProject *project.Project) []string {
|
||||
|
||||
// LoadFile loads a compose file into KomposeObject
|
||||
func (c *Compose) LoadFile(files []string) (kobject.KomposeObject, error) {
|
||||
// Load the json / yaml file in order to get the version value
|
||||
var version string
|
||||
|
||||
for _, file := range files {
|
||||
composeVersion, err := getVersionFromFile(file)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to load yaml/json file for version parsing")
|
||||
}
|
||||
|
||||
// Check that the previous file loaded matches.
|
||||
if len(files) > 0 && version != "" && version != composeVersion {
|
||||
return kobject.KomposeObject{}, errors.New("All Docker Compose files must be of the same version")
|
||||
}
|
||||
version = composeVersion
|
||||
// Gather the working directory
|
||||
workingDir, err := getComposeFileDir(files)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
}
|
||||
|
||||
log.Debugf("Docker Compose version: %s", version)
|
||||
projectOptions, err := cli.NewProjectOptions(files, cli.WithOsEnv, cli.WithWorkingDirectory(workingDir), cli.WithInterpolation(false))
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to create compose options")
|
||||
}
|
||||
|
||||
// Convert based on version
|
||||
switch version {
|
||||
// Use libcompose for 1 or 2
|
||||
// If blank, it's assumed it's 1 or 2
|
||||
case "", "1", "1.0", "2", "2.0", "2.1", "2.2":
|
||||
komposeObject, err := parseV1V2(files)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
project, err := cli.ProjectFromOptions(projectOptions)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to load files")
|
||||
}
|
||||
|
||||
komposeObject, err := dockerComposeToKomposeMapping(project)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
}
|
||||
return komposeObject, nil
|
||||
}
|
||||
|
||||
func loadPlacement(placement types.Placement) kobject.Placement {
|
||||
komposePlacement := kobject.Placement{
|
||||
PositiveConstraints: make(map[string]string),
|
||||
NegativeConstraints: make(map[string]string),
|
||||
Preferences: make([]string, 0, len(placement.Preferences)),
|
||||
}
|
||||
|
||||
// Convert constraints
|
||||
equal, notEqual := " == ", " != "
|
||||
for _, j := range placement.Constraints {
|
||||
operator := equal
|
||||
if strings.Contains(j, notEqual) {
|
||||
operator = notEqual
|
||||
}
|
||||
return komposeObject, nil
|
||||
// Use docker/cli for 3
|
||||
case "3", "3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8":
|
||||
komposeObject, err := parseV3(files)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
p := strings.Split(j, operator)
|
||||
if len(p) < 2 {
|
||||
log.Warnf("Failed to parse placement constraints %s, the correct format is 'label == xxx'", j)
|
||||
continue
|
||||
}
|
||||
return komposeObject, nil
|
||||
|
||||
key, err := convertDockerLabel(p[0])
|
||||
if err != nil {
|
||||
log.Warn("Ignore placement constraints: ", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if operator == equal {
|
||||
komposePlacement.PositiveConstraints[key] = p[1]
|
||||
} else if operator == notEqual {
|
||||
komposePlacement.NegativeConstraints[key] = p[1]
|
||||
}
|
||||
}
|
||||
|
||||
// Convert preferences
|
||||
for _, p := range placement.Preferences {
|
||||
// Spread is the only supported strategy currently
|
||||
label, err := convertDockerLabel(p.Spread)
|
||||
if err != nil {
|
||||
log.Warn("Ignore placement preferences: ", err.Error())
|
||||
continue
|
||||
}
|
||||
komposePlacement.Preferences = append(komposePlacement.Preferences, label)
|
||||
}
|
||||
return komposePlacement
|
||||
}
|
||||
|
||||
// Convert docker label to k8s label
|
||||
func convertDockerLabel(dockerLabel string) (string, error) {
|
||||
switch dockerLabel {
|
||||
case "node.hostname":
|
||||
return "kubernetes.io/hostname", nil
|
||||
case "engine.labels.operatingsystem":
|
||||
return "kubernetes.io/os", nil
|
||||
default:
|
||||
return kobject.KomposeObject{}, fmt.Errorf("version %s of Docker Compose is not supported. Please use version 1, 2 or 3", version)
|
||||
if strings.HasPrefix(dockerLabel, "node.labels.") {
|
||||
return strings.TrimPrefix(dockerLabel, "node.labels."), nil
|
||||
}
|
||||
}
|
||||
errMsg := fmt.Sprint(dockerLabel, " is not supported, only 'node.hostname', 'engine.labels.operatingsystem' and 'node.labels.xxx' (ex: node.labels.something == anything) is supported")
|
||||
return "", errors.New(errMsg)
|
||||
}
|
||||
|
||||
// Convert the Docker Compose volumes to []string (the old way)
|
||||
// TODO: Check to see if it's a "bind" or "volume". Ignore for now.
|
||||
// TODO: Refactor it similar to loadPorts
|
||||
// See: https://docs.docker.com/compose/compose-file/#long-syntax-3
|
||||
func loadVolumes(volumes []types.ServiceVolumeConfig) []string {
|
||||
var volArray []string
|
||||
for _, vol := range volumes {
|
||||
// There will *always* be Source when parsing
|
||||
v := vol.Source
|
||||
|
||||
if vol.Target != "" {
|
||||
v = v + ":" + vol.Target
|
||||
}
|
||||
|
||||
if vol.ReadOnly {
|
||||
v = v + ":ro"
|
||||
}
|
||||
|
||||
volArray = append(volArray, v)
|
||||
}
|
||||
return volArray
|
||||
}
|
||||
|
||||
// Convert Docker Compose ports to kobject.Ports
|
||||
// expose ports will be treated as TCP ports
|
||||
func loadPorts(ports []types.ServicePortConfig, expose []string) []kobject.Ports {
|
||||
komposePorts := []kobject.Ports{}
|
||||
exist := map[string]bool{}
|
||||
|
||||
for _, port := range ports {
|
||||
// Convert to a kobject struct with ports
|
||||
komposePorts = append(komposePorts, kobject.Ports{
|
||||
HostPort: cast.ToInt32(port.Published),
|
||||
ContainerPort: int32(port.Target),
|
||||
HostIP: port.HostIP,
|
||||
Protocol: strings.ToUpper(port.Protocol),
|
||||
})
|
||||
exist[cast.ToString(port.Target)+port.Protocol] = true
|
||||
}
|
||||
|
||||
for _, port := range expose {
|
||||
portValue := port
|
||||
protocol := string(api.ProtocolTCP)
|
||||
if strings.Contains(portValue, "/") {
|
||||
splits := strings.Split(port, "/")
|
||||
portValue = splits[0]
|
||||
protocol = splits[1]
|
||||
}
|
||||
|
||||
if exist[portValue+protocol] {
|
||||
continue
|
||||
}
|
||||
komposePorts = append(komposePorts, kobject.Ports{
|
||||
HostPort: cast.ToInt32(portValue),
|
||||
ContainerPort: cast.ToInt32(portValue),
|
||||
HostIP: "",
|
||||
Protocol: strings.ToUpper(protocol),
|
||||
})
|
||||
}
|
||||
|
||||
return komposePorts
|
||||
}
|
||||
|
||||
/*
|
||||
Convert the HealthCheckConfig as designed by Docker to
|
||||
|
||||
a Kubernetes-compatible format.
|
||||
*/
|
||||
func parseHealthCheckReadiness(labels types.Labels) (kobject.HealthCheck, error) {
|
||||
var test []string
|
||||
var httpPath string
|
||||
var httpPort, tcpPort, timeout, interval, retries, startPeriod int32
|
||||
var disable bool
|
||||
|
||||
for key, value := range labels {
|
||||
switch key {
|
||||
case HealthCheckReadinessDisable:
|
||||
disable = cast.ToBool(value)
|
||||
case HealthCheckReadinessTest:
|
||||
if len(value) > 0 {
|
||||
test, _ = shlex.Split(value)
|
||||
}
|
||||
case HealthCheckReadinessHTTPGetPath:
|
||||
httpPath = value
|
||||
case HealthCheckReadinessHTTPGetPort:
|
||||
httpPort = cast.ToInt32(value)
|
||||
case HealthCheckReadinessTCPPort:
|
||||
tcpPort = cast.ToInt32(value)
|
||||
case HealthCheckReadinessInterval:
|
||||
parse, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check interval variable")
|
||||
}
|
||||
interval = int32(parse.Seconds())
|
||||
case HealthCheckReadinessTimeout:
|
||||
parse, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check timeout variable")
|
||||
}
|
||||
timeout = int32(parse.Seconds())
|
||||
case HealthCheckReadinessRetries:
|
||||
retries = cast.ToInt32(value)
|
||||
case HealthCheckReadinessStartPeriod:
|
||||
parse, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check startPeriod variable")
|
||||
}
|
||||
startPeriod = int32(parse.Seconds())
|
||||
}
|
||||
}
|
||||
|
||||
if len(test) > 0 {
|
||||
if test[0] == "NONE" {
|
||||
disable = true
|
||||
test = test[1:]
|
||||
}
|
||||
// Due to docker/cli adding "CMD-SHELL" to the struct, we remove the first element of composeHealthCheck.Test
|
||||
if test[0] == "CMD" || test[0] == "CMD-SHELL" {
|
||||
test = test[1:]
|
||||
}
|
||||
}
|
||||
|
||||
return kobject.HealthCheck{
|
||||
Test: test,
|
||||
HTTPPath: httpPath,
|
||||
HTTPPort: httpPort,
|
||||
TCPPort: tcpPort,
|
||||
Timeout: timeout,
|
||||
Interval: interval,
|
||||
Retries: retries,
|
||||
StartPeriod: startPeriod,
|
||||
Disable: disable,
|
||||
}, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Convert the HealthCheckConfig as designed by Docker to
|
||||
|
||||
a Kubernetes-compatible format.
|
||||
*/
|
||||
func parseHealthCheck(composeHealthCheck types.HealthCheckConfig, labels types.Labels) (kobject.HealthCheck, error) {
|
||||
var httpPort, tcpPort, timeout, interval, retries, startPeriod int32
|
||||
var test []string
|
||||
var httpPath string
|
||||
|
||||
// Here we convert the timeout from 1h30s (example) to 36030 seconds.
|
||||
if composeHealthCheck.Timeout != nil {
|
||||
parse, err := time.ParseDuration(composeHealthCheck.Timeout.String())
|
||||
if err != nil {
|
||||
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check timeout variable")
|
||||
}
|
||||
timeout = int32(parse.Seconds())
|
||||
}
|
||||
|
||||
if composeHealthCheck.Interval != nil {
|
||||
parse, err := time.ParseDuration(composeHealthCheck.Interval.String())
|
||||
if err != nil {
|
||||
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check interval variable")
|
||||
}
|
||||
interval = int32(parse.Seconds())
|
||||
}
|
||||
|
||||
if composeHealthCheck.Retries != nil {
|
||||
retries = int32(*composeHealthCheck.Retries)
|
||||
}
|
||||
|
||||
if composeHealthCheck.StartPeriod != nil {
|
||||
parse, err := time.ParseDuration(composeHealthCheck.StartPeriod.String())
|
||||
if err != nil {
|
||||
return kobject.HealthCheck{}, errors.Wrap(err, "unable to parse health check startPeriod variable")
|
||||
}
|
||||
startPeriod = int32(parse.Seconds())
|
||||
}
|
||||
|
||||
if composeHealthCheck.Test != nil {
|
||||
test = composeHealthCheck.Test[1:]
|
||||
}
|
||||
|
||||
for key, value := range labels {
|
||||
switch key {
|
||||
case HealthCheckLivenessHTTPGetPath:
|
||||
httpPath = value
|
||||
case HealthCheckLivenessHTTPGetPort:
|
||||
httpPort = cast.ToInt32(value)
|
||||
case HealthCheckLivenessTCPPort:
|
||||
tcpPort = cast.ToInt32(value)
|
||||
}
|
||||
}
|
||||
|
||||
// Due to docker/cli adding "CMD-SHELL" to the struct, we remove the first element of composeHealthCheck.Test
|
||||
return kobject.HealthCheck{
|
||||
Test: test,
|
||||
TCPPort: tcpPort,
|
||||
HTTPPath: httpPath,
|
||||
HTTPPort: httpPort,
|
||||
Timeout: timeout,
|
||||
Interval: interval,
|
||||
Retries: retries,
|
||||
StartPeriod: startPeriod,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func dockerComposeToKomposeMapping(composeObject *types.Project) (kobject.KomposeObject, error) {
|
||||
// Step 1. Initialize what's going to be returned
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: make(map[string]kobject.ServiceConfig),
|
||||
LoadedFrom: "compose",
|
||||
Secrets: composeObject.Secrets,
|
||||
}
|
||||
|
||||
// Step 2. Parse through the object and convert it to kobject.KomposeObject!
|
||||
// Here we "clean up" the service configuration so we return something that includes
|
||||
// all relevant information as well as avoid the unsupported keys as well.
|
||||
for _, composeServiceConfig := range composeObject.Services {
|
||||
// Standard import
|
||||
// No need to modify before importation
|
||||
name := composeServiceConfig.Name
|
||||
serviceConfig := kobject.ServiceConfig{}
|
||||
serviceConfig.Name = name
|
||||
serviceConfig.Image = composeServiceConfig.Image
|
||||
serviceConfig.WorkingDir = composeServiceConfig.WorkingDir
|
||||
serviceConfig.Annotations = composeServiceConfig.Labels
|
||||
serviceConfig.CapAdd = composeServiceConfig.CapAdd
|
||||
serviceConfig.CapDrop = composeServiceConfig.CapDrop
|
||||
serviceConfig.Expose = composeServiceConfig.Expose
|
||||
serviceConfig.Privileged = composeServiceConfig.Privileged
|
||||
serviceConfig.User = composeServiceConfig.User
|
||||
serviceConfig.Stdin = composeServiceConfig.StdinOpen
|
||||
serviceConfig.Tty = composeServiceConfig.Tty
|
||||
serviceConfig.TmpFs = composeServiceConfig.Tmpfs
|
||||
serviceConfig.ContainerName = normalizeContainerNames(composeServiceConfig.ContainerName)
|
||||
serviceConfig.Command = composeServiceConfig.Entrypoint
|
||||
serviceConfig.Args = composeServiceConfig.Command
|
||||
serviceConfig.Labels = composeServiceConfig.Labels
|
||||
serviceConfig.HostName = composeServiceConfig.Hostname
|
||||
serviceConfig.DomainName = composeServiceConfig.DomainName
|
||||
serviceConfig.Secrets = composeServiceConfig.Secrets
|
||||
|
||||
if composeServiceConfig.StopGracePeriod != nil {
|
||||
serviceConfig.StopGracePeriod = composeServiceConfig.StopGracePeriod.String()
|
||||
}
|
||||
|
||||
if err := parseNetwork(&composeServiceConfig, &serviceConfig, composeObject); err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
}
|
||||
|
||||
if err := parseResources(&composeServiceConfig, &serviceConfig); err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
}
|
||||
|
||||
serviceConfig.Restart = composeServiceConfig.Restart
|
||||
|
||||
if composeServiceConfig.Deploy != nil {
|
||||
// Deploy keys
|
||||
// mode:
|
||||
serviceConfig.DeployMode = composeServiceConfig.Deploy.Mode
|
||||
// labels
|
||||
serviceConfig.DeployLabels = composeServiceConfig.Deploy.Labels
|
||||
|
||||
// restart-policy: deploy.restart_policy.condition will rewrite restart option
|
||||
// see: https://docs.docker.com/compose/compose-file/#restart_policy
|
||||
if composeServiceConfig.Deploy.RestartPolicy != nil {
|
||||
serviceConfig.Restart = composeServiceConfig.Deploy.RestartPolicy.Condition
|
||||
}
|
||||
|
||||
// replicas:
|
||||
if composeServiceConfig.Deploy.Replicas != nil {
|
||||
serviceConfig.Replicas = int(*composeServiceConfig.Deploy.Replicas)
|
||||
}
|
||||
|
||||
// placement:
|
||||
serviceConfig.Placement = loadPlacement(composeServiceConfig.Deploy.Placement)
|
||||
|
||||
if composeServiceConfig.Deploy.UpdateConfig != nil {
|
||||
serviceConfig.DeployUpdateConfig = *composeServiceConfig.Deploy.UpdateConfig
|
||||
}
|
||||
|
||||
if composeServiceConfig.Deploy.EndpointMode == "vip" {
|
||||
serviceConfig.ServiceType = string(api.ServiceTypeNodePort)
|
||||
}
|
||||
}
|
||||
|
||||
// HealthCheck Liveness
|
||||
if composeServiceConfig.HealthCheck != nil && !composeServiceConfig.HealthCheck.Disable {
|
||||
var err error
|
||||
serviceConfig.HealthChecks.Liveness, err = parseHealthCheck(*composeServiceConfig.HealthCheck, composeServiceConfig.Labels)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to parse health check")
|
||||
}
|
||||
}
|
||||
|
||||
// HealthCheck Readiness
|
||||
var readiness, errReadiness = parseHealthCheckReadiness(composeServiceConfig.Labels)
|
||||
if !readiness.Disable {
|
||||
serviceConfig.HealthChecks.Readiness = readiness
|
||||
if errReadiness != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(errReadiness, "Unable to parse health check")
|
||||
}
|
||||
}
|
||||
|
||||
if serviceConfig.Restart == "unless-stopped" {
|
||||
log.Warnf("Restart policy 'unless-stopped' in service %s is not supported, convert it to 'always'", name)
|
||||
serviceConfig.Restart = "always"
|
||||
}
|
||||
|
||||
if composeServiceConfig.Build != nil {
|
||||
serviceConfig.Build = composeServiceConfig.Build.Context
|
||||
serviceConfig.Dockerfile = composeServiceConfig.Build.Dockerfile
|
||||
serviceConfig.BuildArgs = composeServiceConfig.Build.Args
|
||||
serviceConfig.BuildLabels = composeServiceConfig.Build.Labels
|
||||
}
|
||||
|
||||
// env
|
||||
parseEnvironment(&composeServiceConfig, &serviceConfig)
|
||||
|
||||
// Get env_file
|
||||
serviceConfig.EnvFile = composeServiceConfig.EnvFile
|
||||
|
||||
// Parse the ports
|
||||
// v3 uses a new format called "long syntax" starting in 3.2
|
||||
// https://docs.docker.com/compose/compose-file/#ports
|
||||
|
||||
// here we will translate `expose` too, they basically means the same thing in kubernetes
|
||||
serviceConfig.Port = loadPorts(composeServiceConfig.Ports, serviceConfig.Expose)
|
||||
|
||||
// Parse the volumes
|
||||
// Again, in v3, we use the "long syntax" for volumes in terms of parsing
|
||||
// https://docs.docker.com/compose/compose-file/#long-syntax-3
|
||||
serviceConfig.VolList = loadVolumes(composeServiceConfig.Volumes)
|
||||
if err := parseKomposeLabels(composeServiceConfig.Labels, &serviceConfig); err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
}
|
||||
|
||||
// Log if the name will been changed
|
||||
if normalizeServiceNames(name) != name {
|
||||
log.Infof("Service name in docker-compose has been changed from %q to %q", name, normalizeServiceNames(name))
|
||||
}
|
||||
|
||||
serviceConfig.Configs = composeServiceConfig.Configs
|
||||
serviceConfig.ConfigsMetaData = composeObject.Configs
|
||||
|
||||
// Get GroupAdd, group should be mentioned in gid format but not the group name
|
||||
groupAdd, err := getGroupAdd(composeServiceConfig.GroupAdd)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "GroupAdd should be mentioned in gid format, not a group name")
|
||||
}
|
||||
serviceConfig.GroupAdd = groupAdd
|
||||
|
||||
// Final step, add to the array!
|
||||
komposeObject.ServiceConfigs[normalizeServiceNames(name)] = serviceConfig
|
||||
}
|
||||
|
||||
handleVolume(&komposeObject, &composeObject.Volumes)
|
||||
return komposeObject, nil
|
||||
}
|
||||
|
||||
func parseNetwork(composeServiceConfig *types.ServiceConfig, serviceConfig *kobject.ServiceConfig, composeObject *types.Project) error {
|
||||
if len(composeServiceConfig.Networks) == 0 {
|
||||
if defaultNetwork, ok := composeObject.Networks["default"]; ok {
|
||||
normalizedNetworkName, err := normalizeNetworkNames(defaultNetwork.Name)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to normalize network name")
|
||||
}
|
||||
serviceConfig.Network = append(serviceConfig.Network, normalizedNetworkName)
|
||||
}
|
||||
} else {
|
||||
var alias = ""
|
||||
for key := range composeServiceConfig.Networks {
|
||||
alias = key
|
||||
netName := composeObject.Networks[alias].Name
|
||||
|
||||
// if Network Name Field is empty in the docker-compose definition
|
||||
// we will use the alias name defined in service config file
|
||||
if netName == "" {
|
||||
netName = alias
|
||||
}
|
||||
|
||||
normalizedNetworkName, err := normalizeNetworkNames(netName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to normalize network name")
|
||||
}
|
||||
|
||||
serviceConfig.Network = append(serviceConfig.Network, normalizedNetworkName)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseResources(composeServiceConfig *types.ServiceConfig, serviceConfig *kobject.ServiceConfig) error {
|
||||
serviceConfig.MemLimit = composeServiceConfig.MemLimit
|
||||
|
||||
if composeServiceConfig.Deploy != nil {
|
||||
// memory:
|
||||
// See: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
|
||||
// "The expression 0.1 is equivalent to the expression 100m, which can be read as “one hundred millicpu”."
|
||||
|
||||
// Since Deploy.Resources.Limits does not initialize, we must check type Resources before continuing
|
||||
if composeServiceConfig.Deploy.Resources.Limits != nil {
|
||||
serviceConfig.MemLimit = composeServiceConfig.Deploy.Resources.Limits.MemoryBytes
|
||||
|
||||
if composeServiceConfig.Deploy.Resources.Limits.NanoCPUs != "" {
|
||||
cpuLimit, err := strconv.ParseFloat(composeServiceConfig.Deploy.Resources.Limits.NanoCPUs, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to convert cpu limits resources value")
|
||||
}
|
||||
serviceConfig.CPULimit = int64(cpuLimit * 1000)
|
||||
}
|
||||
}
|
||||
if composeServiceConfig.Deploy.Resources.Reservations != nil {
|
||||
serviceConfig.MemReservation = composeServiceConfig.Deploy.Resources.Reservations.MemoryBytes
|
||||
|
||||
if composeServiceConfig.Deploy.Resources.Reservations.NanoCPUs != "" {
|
||||
cpuReservation, err := strconv.ParseFloat(composeServiceConfig.Deploy.Resources.Reservations.NanoCPUs, 64)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to convert cpu limits reservation value")
|
||||
}
|
||||
serviceConfig.CPUReservation = int64(cpuReservation * 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseEnvironment(composeServiceConfig *types.ServiceConfig, serviceConfig *kobject.ServiceConfig) {
|
||||
// Gather the environment values
|
||||
// DockerCompose uses map[string]*string while we use []string
|
||||
// So let's convert that using this hack
|
||||
// Note: unset env pick up the env value on host if exist
|
||||
for name, value := range composeServiceConfig.Environment {
|
||||
var env kobject.EnvVar
|
||||
if value != nil {
|
||||
env = kobject.EnvVar{Name: name, Value: *value}
|
||||
} else {
|
||||
result, ok := os.LookupEnv(name)
|
||||
if ok {
|
||||
env = kobject.EnvVar{Name: name, Value: result}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
serviceConfig.Environment = append(serviceConfig.Environment, env)
|
||||
}
|
||||
}
|
||||
|
||||
func getVersionFromFile(file string) (string, error) {
|
||||
type ComposeVersion struct {
|
||||
Version string `json:"version"` // This affects YAML as well
|
||||
}
|
||||
var version ComposeVersion
|
||||
loadedFile, err := ReadFile(file)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
// parseKomposeLabels parse kompose labels, also do some validation
|
||||
func parseKomposeLabels(labels map[string]string, serviceConfig *kobject.ServiceConfig) error {
|
||||
// Label handler
|
||||
// Labels used to influence conversion of kompose will be handled
|
||||
// from here for docker-compose. Each loader will have such handler.
|
||||
if serviceConfig.Labels == nil {
|
||||
serviceConfig.Labels = make(map[string]string)
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(loadedFile, &version)
|
||||
if err != nil {
|
||||
return "", err
|
||||
for key, value := range labels {
|
||||
switch key {
|
||||
case LabelServiceType:
|
||||
serviceType, err := handleServiceType(value)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "handleServiceType failed")
|
||||
}
|
||||
|
||||
serviceConfig.ServiceType = serviceType
|
||||
case LabelServiceExpose:
|
||||
serviceConfig.ExposeService = strings.Trim(strings.ToLower(value), " ,")
|
||||
case LabelNodePortPort:
|
||||
serviceConfig.NodePortPort = cast.ToInt32(value)
|
||||
case LabelServiceExposeTLSSecret:
|
||||
serviceConfig.ExposeServiceTLS = value
|
||||
case LabelServiceExposeIngressClassName:
|
||||
serviceConfig.ExposeServiceIngressClassName = value
|
||||
case LabelImagePullSecret:
|
||||
serviceConfig.ImagePullSecret = value
|
||||
case LabelImagePullPolicy:
|
||||
serviceConfig.ImagePullPolicy = value
|
||||
default:
|
||||
serviceConfig.Labels[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return version.Version, nil
|
||||
if serviceConfig.ExposeService == "" && serviceConfig.ExposeServiceTLS != "" {
|
||||
return errors.New("kompose.service.expose.tls-secret was specified without kompose.service.expose")
|
||||
}
|
||||
|
||||
if serviceConfig.ExposeService == "" && serviceConfig.ExposeServiceIngressClassName != "" {
|
||||
return errors.New("kompose.service.expose.ingress-class-name was specified without kompose.service.expose")
|
||||
}
|
||||
|
||||
if serviceConfig.ServiceType != string(api.ServiceTypeNodePort) && serviceConfig.NodePortPort != 0 {
|
||||
return errors.New("kompose.service.type must be nodeport when assign node port value")
|
||||
}
|
||||
|
||||
if len(serviceConfig.Port) > 1 && serviceConfig.NodePortPort != 0 {
|
||||
return errors.New("cannot set kompose.service.nodeport.port when service has multiple ports")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleVolume(komposeObject *kobject.KomposeObject, volumes *types.Volumes) {
|
||||
for name := range komposeObject.ServiceConfigs {
|
||||
// retrieve volumes of service
|
||||
vols, err := retrieveVolume(name, *komposeObject)
|
||||
if err != nil {
|
||||
errors.Wrap(err, "could not retrieve vvolume")
|
||||
}
|
||||
for volName, vol := range vols {
|
||||
size, selector := getVolumeLabels(vol.VolumeName, volumes)
|
||||
if len(size) > 0 || len(selector) > 0 {
|
||||
// We can't assign value to struct field in map while iterating over it, so temporary variable `temp` is used here
|
||||
var temp = vols[volName]
|
||||
temp.PVCSize = size
|
||||
temp.SelectorValue = selector
|
||||
vols[volName] = temp
|
||||
}
|
||||
}
|
||||
// We can't assign value to struct field in map while iterating over it, so temporary variable `temp` is used here
|
||||
var temp = komposeObject.ServiceConfigs[name]
|
||||
temp.Volumes = vols
|
||||
komposeObject.ServiceConfigs[name] = temp
|
||||
}
|
||||
}
|
||||
|
||||
// returns all volumes associated with service, if `volumes_from` key is used, we have to retrieve volumes from the services which are mentioned there. Hence, recursive function is used here.
|
||||
func retrieveVolume(svcName string, komposeObject kobject.KomposeObject) (volume []kobject.Volumes, err error) {
|
||||
// if volumes-from key is present
|
||||
if komposeObject.ServiceConfigs[svcName].VolumesFrom != nil {
|
||||
// iterating over services from `volumes-from`
|
||||
for _, depSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
|
||||
// recursive call for retrieving volumes of services from `volumes-from`
|
||||
dVols, err := retrieveVolume(depSvc, komposeObject)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not retrieve the volume")
|
||||
}
|
||||
var cVols []kobject.Volumes
|
||||
cVols, err = ParseVols(komposeObject.ServiceConfigs[svcName].VolList, svcName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error generating current volumes")
|
||||
}
|
||||
|
||||
for _, cv := range cVols {
|
||||
// check whether volumes of current service is same or not as that of dependent volumes coming from `volumes-from`
|
||||
ok, dv := getVol(cv, dVols)
|
||||
if ok {
|
||||
// change current volumes service name to dependent service name
|
||||
if dv.VFrom == "" {
|
||||
cv.VFrom = dv.SvcName
|
||||
cv.SvcName = dv.SvcName
|
||||
} else {
|
||||
cv.VFrom = dv.VFrom
|
||||
cv.SvcName = dv.SvcName
|
||||
}
|
||||
cv.PVCName = dv.PVCName
|
||||
}
|
||||
volume = append(volume, cv)
|
||||
}
|
||||
// iterating over dependent volumes
|
||||
for _, dv := range dVols {
|
||||
// check whether dependent volume is already present or not
|
||||
if checkVolDependent(dv, volume) {
|
||||
// if found, add service name to `VFrom`
|
||||
dv.VFrom = dv.SvcName
|
||||
volume = append(volume, dv)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if `volumes-from` is not present
|
||||
volume, err = ParseVols(komposeObject.ServiceConfigs[svcName].VolList, svcName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error generating current volumes")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// checkVolDependent returns false if dependent volume is present
|
||||
func checkVolDependent(dv kobject.Volumes, volume []kobject.Volumes) bool {
|
||||
for _, vol := range volume {
|
||||
if vol.PVCName == dv.PVCName {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ParseVols parse volumes
|
||||
func ParseVols(volNames []string, svcName string) ([]kobject.Volumes, error) {
|
||||
var volumes []kobject.Volumes
|
||||
var err error
|
||||
|
||||
for i, vn := range volNames {
|
||||
var v kobject.Volumes
|
||||
v.VolumeName, v.Host, v.Container, v.Mode, err = transformer.ParseVolume(vn)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not parse volume %q: %v", vn, err)
|
||||
}
|
||||
v.VolumeName = normalizeVolumes(v.VolumeName)
|
||||
v.SvcName = svcName
|
||||
v.MountPath = fmt.Sprintf("%s:%s", v.Host, v.Container)
|
||||
v.PVCName = fmt.Sprintf("%s-claim%d", v.SvcName, i)
|
||||
volumes = append(volumes, v)
|
||||
}
|
||||
|
||||
return volumes, nil
|
||||
}
|
||||
|
||||
// for dependent volumes, returns true and the respective volume if mountpath are same
|
||||
func getVol(toFind kobject.Volumes, Vols []kobject.Volumes) (bool, kobject.Volumes) {
|
||||
for _, dv := range Vols {
|
||||
if toFind.MountPath == dv.MountPath {
|
||||
return true, dv
|
||||
}
|
||||
}
|
||||
return false, kobject.Volumes{}
|
||||
}
|
||||
|
||||
func getVolumeLabels(name string, volumes *types.Volumes) (string, string) {
|
||||
size, selector := "", ""
|
||||
|
||||
if volume, ok := (*volumes)[name]; ok {
|
||||
for key, value := range volume.Labels {
|
||||
if key == "kompose.volume.size" {
|
||||
size = value
|
||||
} else if key == "kompose.volume.selector" {
|
||||
selector = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return size, selector
|
||||
}
|
||||
|
||||
// getGroupAdd will return group in int64 format
|
||||
func getGroupAdd(group []string) ([]int64, error) {
|
||||
var groupAdd []int64
|
||||
for _, i := range group {
|
||||
j, err := strconv.Atoi(i)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to get group_add key")
|
||||
}
|
||||
groupAdd = append(groupAdd, int64(j))
|
||||
}
|
||||
return groupAdd, nil
|
||||
}
|
||||
|
||||
@ -24,10 +24,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/cli/cli/compose/types"
|
||||
"github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/docker/libcompose/yaml"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/kubernetes/kompose/pkg/kobject"
|
||||
"github.com/pkg/errors"
|
||||
@ -203,7 +200,7 @@ func TestLoadV3Volumes(t *testing.T) {
|
||||
ReadOnly: true,
|
||||
}
|
||||
volumes := []types.ServiceVolumeConfig{vol}
|
||||
output := loadV3Volumes(volumes)
|
||||
output := loadVolumes(volumes)
|
||||
expected := "/tmp/foobar:/tmp/foobar:ro"
|
||||
|
||||
if output[0] != expected {
|
||||
@ -220,7 +217,7 @@ func TestLoadV3Ports(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "ports with expose",
|
||||
ports: []types.ServicePortConfig{{Target: 80, Published: 80, Protocol: string(api.ProtocolTCP)}},
|
||||
ports: []types.ServicePortConfig{{Target: 80, Published: "80", Protocol: string(api.ProtocolTCP)}},
|
||||
expose: []string{"80", "8080"},
|
||||
want: []kobject.Ports{
|
||||
{HostPort: 80, ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
@ -229,7 +226,7 @@ func TestLoadV3Ports(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "exposed port including /protocol",
|
||||
ports: []types.ServicePortConfig{{Target: 80, Published: 80, Protocol: string(api.ProtocolTCP)}},
|
||||
ports: []types.ServicePortConfig{{Target: 80, Published: "80", Protocol: string(api.ProtocolTCP)}},
|
||||
expose: []string{"80/udp"},
|
||||
want: []kobject.Ports{
|
||||
{HostPort: 80, ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
@ -238,7 +235,7 @@ func TestLoadV3Ports(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
got := loadV3Ports(tt.ports, tt.expose)
|
||||
got := loadPorts(tt.ports, tt.expose)
|
||||
if diff := cmp.Diff(tt.want, got); diff != "" {
|
||||
t.Errorf("loadV3Ports() mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
@ -275,92 +272,90 @@ func TestHandleServiceType(t *testing.T) {
|
||||
|
||||
// Test loading of ports
|
||||
func TestLoadPorts(t *testing.T) {
|
||||
portWithIPAddress, _ := types.ParsePortConfig("127.0.0.1:80:80/tcp")
|
||||
portWithoutIPAddress, _ := types.ParsePortConfig("80:80/tcp")
|
||||
portWithoutProtocol, _ := types.ParsePortConfig("80:80")
|
||||
singlePort, _ := types.ParsePortConfig("80")
|
||||
singlePortsRange, _ := types.ParsePortConfig("3000-3002")
|
||||
targetAndContainerPortsRange, _ := types.ParsePortConfig("3000-3002:5000-5002")
|
||||
targetAndContainerPortsRangeWithIPAddress, _ := types.ParsePortConfig("127.0.0.1:3000-3002:5000-5002")
|
||||
port3000, _ := types.ParsePortConfig("3000")
|
||||
|
||||
tests := []struct {
|
||||
ports []string
|
||||
ports []types.ServicePortConfig
|
||||
expose []string
|
||||
want []kobject.Ports
|
||||
}{
|
||||
{
|
||||
ports: []string{"127.0.0.1:80:80/tcp"},
|
||||
ports: portWithIPAddress,
|
||||
want: []kobject.Ports{
|
||||
{HostIP: "127.0.0.1", HostPort: 80, ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
{
|
||||
ports: []string{"80:80/tcp"},
|
||||
ports: portWithoutIPAddress,
|
||||
want: []kobject.Ports{
|
||||
{HostPort: 80, ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
{
|
||||
ports: []string{"80:80"},
|
||||
ports: portWithoutProtocol,
|
||||
want: []kobject.Ports{
|
||||
{HostPort: 80, ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
{
|
||||
ports: []string{"80"},
|
||||
ports: singlePort,
|
||||
want: []kobject.Ports{
|
||||
{ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
{
|
||||
ports: []string{"3000-3005"},
|
||||
ports: singlePortsRange,
|
||||
want: []kobject.Ports{
|
||||
{ContainerPort: 3000, Protocol: string(api.ProtocolTCP)},
|
||||
{ContainerPort: 3001, Protocol: string(api.ProtocolTCP)},
|
||||
{ContainerPort: 3002, Protocol: string(api.ProtocolTCP)},
|
||||
{ContainerPort: 3003, Protocol: string(api.ProtocolTCP)},
|
||||
{ContainerPort: 3004, Protocol: string(api.ProtocolTCP)},
|
||||
{ContainerPort: 3005, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
{
|
||||
ports: []string{"3000-3005:5000-5005"},
|
||||
ports: targetAndContainerPortsRange,
|
||||
want: []kobject.Ports{
|
||||
{HostPort: 3000, ContainerPort: 5000, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 3001, ContainerPort: 5001, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 3002, ContainerPort: 5002, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 3003, ContainerPort: 5003, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 3004, ContainerPort: 5004, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 3005, ContainerPort: 5005, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
{
|
||||
ports: []string{"127.0.0.1:3000-3005:5000-5005"},
|
||||
ports: targetAndContainerPortsRangeWithIPAddress,
|
||||
want: []kobject.Ports{
|
||||
{HostIP: "127.0.0.1", HostPort: 3000, ContainerPort: 5000, Protocol: string(api.ProtocolTCP)},
|
||||
{HostIP: "127.0.0.1", HostPort: 3001, ContainerPort: 5001, Protocol: string(api.ProtocolTCP)},
|
||||
{HostIP: "127.0.0.1", HostPort: 3002, ContainerPort: 5002, Protocol: string(api.ProtocolTCP)},
|
||||
{HostIP: "127.0.0.1", HostPort: 3003, ContainerPort: 5003, Protocol: string(api.ProtocolTCP)},
|
||||
{HostIP: "127.0.0.1", HostPort: 3004, ContainerPort: 5004, Protocol: string(api.ProtocolTCP)},
|
||||
{HostIP: "127.0.0.1", HostPort: 3005, ContainerPort: 5005, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
{
|
||||
ports: []string{"80", "3000"},
|
||||
ports: append(append([]types.ServicePortConfig{}, singlePort...), port3000...),
|
||||
want: []kobject.Ports{
|
||||
{HostPort: 0, ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 0, ContainerPort: 3000, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
{
|
||||
ports: []string{"80", "3000"},
|
||||
ports: append(append([]types.ServicePortConfig{}, singlePort...), port3000...),
|
||||
expose: []string{"80", "8080"},
|
||||
want: []kobject.Ports{
|
||||
{HostPort: 0, ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 0, ContainerPort: 3000, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 0, ContainerPort: 8080, Protocol: string(api.ProtocolTCP)},
|
||||
{ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
{ContainerPort: 3000, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 80, ContainerPort: 80, Protocol: string(api.ProtocolTCP)},
|
||||
{HostPort: 8080, ContainerPort: 8080, Protocol: string(api.ProtocolTCP)},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(fmt.Sprintf("port=%q,expose=%q", tt.ports, tt.expose), func(t *testing.T) {
|
||||
got, err := loadPorts(tt.ports, tt.expose)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error with loading ports %v", err)
|
||||
}
|
||||
got := loadPorts(tt.ports, tt.expose)
|
||||
if diff := cmp.Diff(tt.want, got); diff != "" {
|
||||
t.Errorf("loadPorts() mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
@ -438,71 +433,60 @@ func TestLoadEnvVar(t *testing.T) {
|
||||
// docker-compose projects
|
||||
func TestUnsupportedKeys(t *testing.T) {
|
||||
// create project that will be used in test cases
|
||||
projectWithNetworks := project.NewProject(&project.Context{}, nil, nil)
|
||||
projectWithNetworks.ServiceConfigs = config.NewServiceConfigs()
|
||||
projectWithNetworks.ServiceConfigs.Add("foo", &config.ServiceConfig{
|
||||
Image: "foo/bar",
|
||||
Build: yaml.Build{
|
||||
Context: "./build",
|
||||
projectWithNetworks := &types.Project{
|
||||
Networks: types.Networks{
|
||||
"foo": types.NetworkConfig{
|
||||
Name: "foo",
|
||||
Driver: "bridge",
|
||||
},
|
||||
},
|
||||
Hostname: "localhost",
|
||||
Ports: []string{}, // test empty array
|
||||
Networks: &yaml.Networks{
|
||||
Networks: []*yaml.Network{
|
||||
{
|
||||
Name: "net1",
|
||||
Services: types.Services{
|
||||
types.ServiceConfig{
|
||||
Name: "foo",
|
||||
Image: "foo/bar",
|
||||
Build: &types.BuildConfig{
|
||||
Context: "./build",
|
||||
},
|
||||
Hostname: "localhost",
|
||||
Ports: []types.ServicePortConfig{}, // test empty array
|
||||
Networks: map[string]*types.ServiceNetworkConfig{
|
||||
"net1": {},
|
||||
},
|
||||
},
|
||||
types.ServiceConfig{
|
||||
Name: "bar",
|
||||
Image: "bar/foo",
|
||||
Build: &types.BuildConfig{
|
||||
Context: "./build",
|
||||
},
|
||||
Hostname: "localhost",
|
||||
Ports: []types.ServicePortConfig{}, // test empty array
|
||||
Networks: map[string]*types.ServiceNetworkConfig{
|
||||
"net1": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
projectWithNetworks.ServiceConfigs.Add("bar", &config.ServiceConfig{
|
||||
Image: "bar/foo",
|
||||
Build: yaml.Build{
|
||||
Context: "./build",
|
||||
},
|
||||
Hostname: "localhost",
|
||||
Ports: []string{}, // test empty array
|
||||
Networks: &yaml.Networks{
|
||||
Networks: []*yaml.Network{
|
||||
{
|
||||
Name: "net1",
|
||||
},
|
||||
Volumes: types.Volumes{
|
||||
"foo": types.VolumeConfig{
|
||||
Name: "foo",
|
||||
Driver: "storage",
|
||||
},
|
||||
},
|
||||
})
|
||||
projectWithNetworks.VolumeConfigs = map[string]*config.VolumeConfig{
|
||||
"foo": {
|
||||
Driver: "storage",
|
||||
},
|
||||
}
|
||||
projectWithNetworks.NetworkConfigs = map[string]*config.NetworkConfig{
|
||||
"foo": {
|
||||
Driver: "bridge",
|
||||
},
|
||||
}
|
||||
|
||||
projectWithEmptyNetwork := project.NewProject(&project.Context{}, nil, nil)
|
||||
projectWithEmptyNetwork.ServiceConfigs = config.NewServiceConfigs()
|
||||
projectWithEmptyNetwork.ServiceConfigs.Add("foo", &config.ServiceConfig{
|
||||
Networks: &yaml.Networks{},
|
||||
})
|
||||
|
||||
projectWithDefaultNetwork := project.NewProject(&project.Context{}, nil, nil)
|
||||
projectWithDefaultNetwork.ServiceConfigs = config.NewServiceConfigs()
|
||||
|
||||
projectWithDefaultNetwork.ServiceConfigs.Add("foo", &config.ServiceConfig{
|
||||
Networks: &yaml.Networks{
|
||||
Networks: []*yaml.Network{
|
||||
{
|
||||
Name: "default",
|
||||
projectWithDefaultNetwork := &types.Project{
|
||||
Services: types.Services{
|
||||
types.ServiceConfig{
|
||||
Networks: map[string]*types.ServiceNetworkConfig{
|
||||
"default": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// define all test cases for checkUnsupportedKey function
|
||||
testCases := map[string]struct {
|
||||
composeProject *project.Project
|
||||
composeProject *types.Project
|
||||
expectedUnsupportedKeys []string
|
||||
}{
|
||||
"With Networks (service and root level)": {
|
||||
@ -567,28 +551,6 @@ func TestNormalizeNetworkNames(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckLabelsPorts(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
noOfPort int
|
||||
labels string
|
||||
svcName string
|
||||
expectError bool
|
||||
}{
|
||||
{"ports is defined", 1, "NodePort", "foo", false},
|
||||
{"ports is not defined", 0, "NodePort", "foo", true},
|
||||
}
|
||||
|
||||
var err error
|
||||
for _, testcase := range testCases {
|
||||
t.Log(testcase.name)
|
||||
err = checkLabelsPorts(testcase.noOfPort, testcase.labels, testcase.svcName)
|
||||
if testcase.expectError && err == nil {
|
||||
t.Log("Expected error, got ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckPlacementCustomLabels(t *testing.T) {
|
||||
placement := types.Placement{
|
||||
Constraints: []string{
|
||||
@ -601,7 +563,7 @@ func TestCheckPlacementCustomLabels(t *testing.T) {
|
||||
{Spread: "node.labels.ssd"},
|
||||
},
|
||||
}
|
||||
output := loadV3Placement(placement)
|
||||
output := loadPlacement(placement)
|
||||
|
||||
expected := kobject.Placement{
|
||||
PositiveConstraints: map[string]string{
|
||||
|
||||
@ -1,417 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/lookup"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/kubernetes/kompose/pkg/kobject"
|
||||
"github.com/kubernetes/kompose/pkg/transformer"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cast"
|
||||
api "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// Parse Docker Compose with libcompose (only supports v1 and v2). Eventually we will
|
||||
// switch to using only libcompose once v3 is supported.
|
||||
func parseV1V2(files []string) (kobject.KomposeObject, error) {
|
||||
// Gather the appropriate context for parsing
|
||||
context := &project.Context{}
|
||||
context.ComposeFiles = files
|
||||
|
||||
if context.ResourceLookup == nil {
|
||||
context.ResourceLookup = &lookup.FileResourceLookup{}
|
||||
}
|
||||
|
||||
if context.EnvironmentLookup == nil {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, nil
|
||||
}
|
||||
context.EnvironmentLookup = &lookup.ComposableEnvLookup{
|
||||
Lookups: []config.EnvironmentLookup{
|
||||
&lookup.EnvfileLookup{
|
||||
Path: filepath.Join(cwd, ".env"),
|
||||
},
|
||||
&lookup.OsEnvLookup{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Load the context and let's start parsing
|
||||
composeObject := project.NewProject(context, nil, nil)
|
||||
err := composeObject.Parse()
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "composeObject.Parse() failed, Failed to load compose file")
|
||||
}
|
||||
|
||||
noSupKeys := checkUnsupportedKey(composeObject)
|
||||
for _, keyName := range noSupKeys {
|
||||
log.Warningf("Unsupported %s key - ignoring", keyName)
|
||||
}
|
||||
|
||||
// Map the parsed struct to a struct we understand (kobject)
|
||||
komposeObject, err := libComposeToKomposeMapping(composeObject)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
}
|
||||
|
||||
return komposeObject, nil
|
||||
}
|
||||
|
||||
// Load ports from compose file
|
||||
// also load `expose` here
|
||||
func loadPorts(composePorts []string, expose []string) ([]kobject.Ports, error) {
|
||||
kp := []kobject.Ports{}
|
||||
exist := map[string]bool{}
|
||||
for _, cp := range composePorts {
|
||||
var hostIP string
|
||||
|
||||
if parts := strings.Split(cp, ":"); len(parts) == 3 {
|
||||
if ip := net.ParseIP(parts[0]); ip.To4() == nil && ip.To16() == nil {
|
||||
return nil, fmt.Errorf("%q contains an invalid IPv4 or IPv6 IP address", parts[0])
|
||||
}
|
||||
hostIP = parts[0]
|
||||
}
|
||||
|
||||
np, pbs, err := nat.ParsePortSpecs([]string{cp})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid port, error = %v", err)
|
||||
}
|
||||
// Force HostIP value to avoid warning raised by github.com/docker/cli/opts
|
||||
// The opts package will warn if the bindings contains host IP except
|
||||
// 0.0.0.0. However, the message is not useful in this case since the value
|
||||
// should be handled by kompose properly.
|
||||
for _, pb := range pbs {
|
||||
for i, p := range pb {
|
||||
p.HostIP = ""
|
||||
pb[i] = p
|
||||
}
|
||||
}
|
||||
|
||||
var ports []string
|
||||
for p := range np {
|
||||
ports = append(ports, string(p))
|
||||
}
|
||||
sort.Strings(ports)
|
||||
|
||||
for _, p := range ports {
|
||||
pc, err := opts.ConvertPortToPortConfig(nat.Port(p), pbs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid port, error = %v", err)
|
||||
}
|
||||
for _, cfg := range pc {
|
||||
kp = append(kp, kobject.Ports{
|
||||
HostPort: int32(cfg.PublishedPort),
|
||||
ContainerPort: int32(cfg.TargetPort),
|
||||
HostIP: hostIP,
|
||||
Protocol: strings.ToUpper(string(cfg.Protocol)),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load remain expose ports
|
||||
for _, p := range kp {
|
||||
// must use cast...
|
||||
exist[cast.ToString(p.ContainerPort)+p.Protocol] = true
|
||||
}
|
||||
|
||||
if expose != nil {
|
||||
for _, port := range expose {
|
||||
portValue := port
|
||||
protocol := string(api.ProtocolTCP)
|
||||
if strings.Contains(portValue, "/") {
|
||||
splits := strings.Split(port, "/")
|
||||
portValue = splits[0]
|
||||
protocol = splits[1]
|
||||
}
|
||||
|
||||
if !exist[portValue+protocol] {
|
||||
kp = append(kp, kobject.Ports{
|
||||
ContainerPort: cast.ToInt32(portValue),
|
||||
Protocol: strings.ToUpper(protocol),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kp, nil
|
||||
}
|
||||
|
||||
// Uses libcompose's APIProject type and converts it to a Kompose object for us to understand
|
||||
func libComposeToKomposeMapping(composeObject *project.Project) (kobject.KomposeObject, error) {
|
||||
// Initialize what's going to be returned
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: make(map[string]kobject.ServiceConfig),
|
||||
LoadedFrom: "compose",
|
||||
}
|
||||
|
||||
// Here we "clean up" the service configuration so we return something that includes
|
||||
// all relevant information as well as avoid the unsupported keys as well.
|
||||
for name, composeServiceConfig := range composeObject.ServiceConfigs.All() {
|
||||
serviceConfig := kobject.ServiceConfig{}
|
||||
serviceConfig.Name = name
|
||||
serviceConfig.Image = composeServiceConfig.Image
|
||||
serviceConfig.Build = composeServiceConfig.Build.Context
|
||||
newName := normalizeContainerNames(composeServiceConfig.ContainerName)
|
||||
serviceConfig.ContainerName = newName
|
||||
if newName != composeServiceConfig.ContainerName {
|
||||
log.Infof("Container name in service %q has been changed from %q to %q", name, composeServiceConfig.ContainerName, newName)
|
||||
}
|
||||
serviceConfig.Command = composeServiceConfig.Entrypoint
|
||||
serviceConfig.HostName = composeServiceConfig.Hostname
|
||||
serviceConfig.DomainName = composeServiceConfig.DomainName
|
||||
serviceConfig.Args = composeServiceConfig.Command
|
||||
serviceConfig.Dockerfile = composeServiceConfig.Build.Dockerfile
|
||||
serviceConfig.BuildArgs = composeServiceConfig.Build.Args
|
||||
serviceConfig.Expose = composeServiceConfig.Expose
|
||||
|
||||
envs := loadEnvVars(composeServiceConfig.Environment)
|
||||
serviceConfig.Environment = envs
|
||||
|
||||
// Validate dockerfile path
|
||||
if filepath.IsAbs(serviceConfig.Dockerfile) {
|
||||
log.Fatalf("%q defined in service %q is an absolute path, it must be a relative path.", serviceConfig.Dockerfile, name)
|
||||
}
|
||||
|
||||
// load ports, same as v3, we also load `expose`
|
||||
ports, err := loadPorts(composeServiceConfig.Ports, serviceConfig.Expose)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "loadPorts failed. "+name+" failed to load ports from compose file")
|
||||
}
|
||||
serviceConfig.Port = ports
|
||||
|
||||
serviceConfig.WorkingDir = composeServiceConfig.WorkingDir
|
||||
|
||||
if composeServiceConfig.Volumes != nil {
|
||||
for _, volume := range composeServiceConfig.Volumes.Volumes {
|
||||
v := volume.String()
|
||||
serviceConfig.VolList = append(serviceConfig.VolList, v)
|
||||
}
|
||||
}
|
||||
|
||||
// canonical "Custom Labels" handler
|
||||
// Labels used to influence conversion of kompose will be handled
|
||||
// from here for docker-compose. Each loader will have such handler.
|
||||
if err := parseKomposeLabels(composeServiceConfig.Labels, &serviceConfig); err != nil {
|
||||
return kobject.KomposeObject{}, err
|
||||
}
|
||||
|
||||
err = checkLabelsPorts(len(serviceConfig.Port), composeServiceConfig.Labels[LabelServiceType], name)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "kompose.service.type can't be set if service doesn't expose any ports.")
|
||||
}
|
||||
|
||||
// convert compose labels to annotations
|
||||
serviceConfig.Annotations = composeServiceConfig.Labels
|
||||
serviceConfig.CPUQuota = int64(composeServiceConfig.CPUQuota)
|
||||
serviceConfig.CapAdd = composeServiceConfig.CapAdd
|
||||
serviceConfig.CapDrop = composeServiceConfig.CapDrop
|
||||
serviceConfig.Pid = composeServiceConfig.Pid
|
||||
|
||||
serviceConfig.Privileged = composeServiceConfig.Privileged
|
||||
serviceConfig.User = composeServiceConfig.User
|
||||
serviceConfig.VolumesFrom = composeServiceConfig.VolumesFrom
|
||||
serviceConfig.Stdin = composeServiceConfig.StdinOpen
|
||||
serviceConfig.Tty = composeServiceConfig.Tty
|
||||
serviceConfig.MemLimit = composeServiceConfig.MemLimit
|
||||
serviceConfig.TmpFs = composeServiceConfig.Tmpfs
|
||||
serviceConfig.StopGracePeriod = composeServiceConfig.StopGracePeriod
|
||||
|
||||
// pretty much same as v3
|
||||
serviceConfig.Restart = composeServiceConfig.Restart
|
||||
if serviceConfig.Restart == "unless-stopped" {
|
||||
log.Warnf("Restart policy 'unless-stopped' in service %s is not supported, convert it to 'always'", name)
|
||||
serviceConfig.Restart = "always"
|
||||
}
|
||||
|
||||
if composeServiceConfig.Networks != nil {
|
||||
if len(composeServiceConfig.Networks.Networks) > 0 {
|
||||
for _, value := range composeServiceConfig.Networks.Networks {
|
||||
if value.Name != "default" {
|
||||
nomalizedNetworkName, err := normalizeNetworkNames(value.RealName)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "Error trying to normalize network names")
|
||||
}
|
||||
if nomalizedNetworkName != value.RealName {
|
||||
log.Warnf("Network name in docker-compose has been changed from %q to %q", value.RealName, nomalizedNetworkName)
|
||||
}
|
||||
serviceConfig.Network = append(serviceConfig.Network, nomalizedNetworkName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get GroupAdd, group should be mentioned in gid format but not the group name
|
||||
groupAdd, err := getGroupAdd(composeServiceConfig.GroupAdd)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "GroupAdd should be mentioned in gid format, not a group name")
|
||||
}
|
||||
serviceConfig.GroupAdd = groupAdd
|
||||
|
||||
komposeObject.ServiceConfigs[normalizeServiceNames(name)] = serviceConfig
|
||||
if normalizeServiceNames(name) != name {
|
||||
log.Infof("Service name in docker-compose has been changed from %q to %q", name, normalizeServiceNames(name))
|
||||
}
|
||||
}
|
||||
|
||||
// This will handle volume at earlier stage itself, it will resolves problems occurred due to `volumes_from` key
|
||||
handleVolume(&komposeObject)
|
||||
|
||||
return komposeObject, nil
|
||||
}
|
||||
|
||||
// This function will retrieve volumes for each service, as well as it will parse volume information and store it in Volumes struct
|
||||
func handleVolume(komposeObject *kobject.KomposeObject) {
|
||||
for name := range komposeObject.ServiceConfigs {
|
||||
// retrieve volumes of service
|
||||
vols, err := retrieveVolume(name, *komposeObject)
|
||||
if err != nil {
|
||||
errors.Wrap(err, "could not retrieve volume")
|
||||
}
|
||||
// We can't assign value to struct field in map while iterating over it, so temporary variable `temp` is used here
|
||||
var temp = komposeObject.ServiceConfigs[name]
|
||||
temp.Volumes = vols
|
||||
komposeObject.ServiceConfigs[name] = temp
|
||||
}
|
||||
}
|
||||
|
||||
func checkLabelsPorts(noOfPort int, labels string, svcName string) error {
|
||||
if noOfPort == 0 && (labels == "NodePort" || labels == "LoadBalancer") {
|
||||
return errors.Errorf("%s defined in service %s with no ports present. Issues may occur when bringing up artifacts.", labels, svcName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// returns all volumes associated with service, if `volumes_from` key is used, we have to retrieve volumes from the services which are mentioned there. Hence, recursive function is used here.
|
||||
func retrieveVolume(svcName string, komposeObject kobject.KomposeObject) (volume []kobject.Volumes, err error) {
|
||||
// if volumes-from key is present
|
||||
if komposeObject.ServiceConfigs[svcName].VolumesFrom != nil {
|
||||
// iterating over services from `volumes-from`
|
||||
for _, depSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
|
||||
// recursive call for retrieving volumes of services from `volumes-from`
|
||||
dVols, err := retrieveVolume(depSvc, komposeObject)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not retrieve the volume")
|
||||
}
|
||||
var cVols []kobject.Volumes
|
||||
cVols, err = ParseVols(komposeObject.ServiceConfigs[svcName].VolList, svcName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error generating current volumes")
|
||||
}
|
||||
|
||||
for _, cv := range cVols {
|
||||
// check whether volumes of current service is same or not as that of dependent volumes coming from `volumes-from`
|
||||
ok, dv := getVol(cv, dVols)
|
||||
if ok {
|
||||
// change current volumes service name to dependent service name
|
||||
if dv.VFrom == "" {
|
||||
cv.VFrom = dv.SvcName
|
||||
cv.SvcName = dv.SvcName
|
||||
} else {
|
||||
cv.VFrom = dv.VFrom
|
||||
cv.SvcName = dv.SvcName
|
||||
}
|
||||
cv.PVCName = dv.PVCName
|
||||
}
|
||||
volume = append(volume, cv)
|
||||
}
|
||||
// iterating over dependent volumes
|
||||
for _, dv := range dVols {
|
||||
// check whether dependent volume is already present or not
|
||||
if checkVolDependent(dv, volume) {
|
||||
// if found, add service name to `VFrom`
|
||||
dv.VFrom = dv.SvcName
|
||||
volume = append(volume, dv)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if `volumes-from` is not present
|
||||
volume, err = ParseVols(komposeObject.ServiceConfigs[svcName].VolList, svcName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error generating current volumes")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// checkVolDependent returns false if dependent volume is present
|
||||
func checkVolDependent(dv kobject.Volumes, volume []kobject.Volumes) bool {
|
||||
for _, vol := range volume {
|
||||
if vol.PVCName == dv.PVCName {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ParseVols parse volumes
|
||||
func ParseVols(volNames []string, svcName string) ([]kobject.Volumes, error) {
|
||||
var volumes []kobject.Volumes
|
||||
var err error
|
||||
|
||||
for i, vn := range volNames {
|
||||
var v kobject.Volumes
|
||||
v.VolumeName, v.Host, v.Container, v.Mode, err = transformer.ParseVolume(vn)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not parse volume %q: %v", vn, err)
|
||||
}
|
||||
v.VolumeName = normalizeVolumes(v.VolumeName)
|
||||
v.SvcName = svcName
|
||||
v.MountPath = fmt.Sprintf("%s:%s", v.Host, v.Container)
|
||||
v.PVCName = fmt.Sprintf("%s-claim%d", v.SvcName, i)
|
||||
volumes = append(volumes, v)
|
||||
}
|
||||
|
||||
return volumes, nil
|
||||
}
|
||||
|
||||
// for dependent volumes, returns true and the respective volume if mountpath are same
|
||||
func getVol(toFind kobject.Volumes, Vols []kobject.Volumes) (bool, kobject.Volumes) {
|
||||
for _, dv := range Vols {
|
||||
if toFind.MountPath == dv.MountPath {
|
||||
return true, dv
|
||||
}
|
||||
}
|
||||
return false, kobject.Volumes{}
|
||||
}
|
||||
|
||||
// getGroupAdd will return group in int64 format
|
||||
func getGroupAdd(group []string) ([]int64, error) {
|
||||
var groupAdd []int64
|
||||
for _, i := range group {
|
||||
j, err := strconv.Atoi(i)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to get group_add key")
|
||||
}
|
||||
groupAdd = append(groupAdd, int64(j))
|
||||
}
|
||||
return groupAdd, nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -493,10 +493,8 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
|
||||
}
|
||||
}
|
||||
|
||||
if cms != nil {
|
||||
for _, c := range cms {
|
||||
*objects = append(*objects, c)
|
||||
}
|
||||
for _, c := range cms {
|
||||
*objects = append(*objects, c)
|
||||
}
|
||||
|
||||
// Configure the container ports.
|
||||
@ -724,8 +722,6 @@ func TranslatePodResource(service *kobject.ServiceConfig, template *api.PodTempl
|
||||
|
||||
template.Spec.Containers[0].Resources.Requests = resourceRequests
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetImagePullPolicy get image pull settings
|
||||
|
||||
@ -39,8 +39,8 @@ func TestCreateService(t *testing.T) {
|
||||
service := kobject.ServiceConfig{
|
||||
ContainerName: "name",
|
||||
Image: "image",
|
||||
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
@ -82,8 +82,8 @@ func TestCreateServiceWithMemLimit(t *testing.T) {
|
||||
service := kobject.ServiceConfig{
|
||||
ContainerName: "name",
|
||||
Image: "image",
|
||||
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
@ -134,8 +134,8 @@ func TestCreateServiceWithCPULimit(t *testing.T) {
|
||||
service := kobject.ServiceConfig{
|
||||
ContainerName: "name",
|
||||
Image: "image",
|
||||
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
@ -187,8 +187,8 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
|
||||
service := kobject.ServiceConfig{
|
||||
ContainerName: "name",
|
||||
Image: "image",
|
||||
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
@ -230,8 +230,8 @@ func TestTransformWithPid(t *testing.T) {
|
||||
service := kobject.ServiceConfig{
|
||||
ContainerName: "name",
|
||||
Image: "image",
|
||||
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
@ -266,8 +266,8 @@ func TestTransformWithInvalidPid(t *testing.T) {
|
||||
service := kobject.ServiceConfig{
|
||||
ContainerName: "name",
|
||||
Image: "image",
|
||||
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
|
||||
@ -29,7 +29,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/compose/types"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/kubernetes/kompose/pkg/kobject"
|
||||
"github.com/kubernetes/kompose/pkg/loader/compose"
|
||||
@ -871,7 +871,7 @@ func (k *Kubernetes) getSecretPathsLegacy(secretConfig types.ServiceSecretConfig
|
||||
}
|
||||
|
||||
// if the target isn't absolute path
|
||||
if strings.HasPrefix(secretConfig.Target, "/") == false {
|
||||
if !strings.HasPrefix(secretConfig.Target, "/") {
|
||||
// concat the default secret directory
|
||||
mountPath = "/run/secrets/" + mountPath
|
||||
}
|
||||
@ -1474,20 +1474,17 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
|
||||
SetVolumes(volumes),
|
||||
)
|
||||
|
||||
if pvc != nil {
|
||||
// Looping on the slice pvc instead of `*objects = append(*objects, pvc...)`
|
||||
// because the type of objects and pvc is different, but when doing append
|
||||
// one element at a time it gets converted to runtime.Object for objects slice
|
||||
for _, p := range pvc {
|
||||
objects = append(objects, p)
|
||||
}
|
||||
// Looping on the slice pvc instead of `*objects = append(*objects, pvc...)`
|
||||
// because the type of objects and pvc is different, but when doing append
|
||||
// one element at a time it gets converted to runtime.Object for objects slice
|
||||
for _, p := range pvc {
|
||||
objects = append(objects, p)
|
||||
}
|
||||
|
||||
if cms != nil {
|
||||
for _, c := range cms {
|
||||
objects = append(objects, c)
|
||||
}
|
||||
for _, c := range cms {
|
||||
objects = append(objects, c)
|
||||
}
|
||||
|
||||
podSpec.Append(
|
||||
SetPorts(service),
|
||||
ImagePullPolicy(name, service),
|
||||
|
||||
@ -23,7 +23,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
dockerCliTypes "github.com/docker/cli/cli/compose/types"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
|
||||
"github.com/kubernetes/kompose/pkg/kobject"
|
||||
"github.com/kubernetes/kompose/pkg/loader/compose"
|
||||
@ -43,8 +43,8 @@ func newServiceConfig() kobject.ServiceConfig {
|
||||
Name: "app",
|
||||
ContainerName: "name",
|
||||
Image: "image",
|
||||
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456}, kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: string(api.ProtocolUDP)}, kobject.Ports{HostPort: 55564, ContainerPort: 55564}, kobject.Ports{HostPort: 55563, ContainerPort: 55563}},
|
||||
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456}, {HostPort: 123, ContainerPort: 456, Protocol: string(api.ProtocolUDP)}, {HostPort: 55564, ContainerPort: 55564}, {HostPort: 55563, ContainerPort: 55563}},
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
@ -65,8 +65,8 @@ func newServiceConfig() kobject.ServiceConfig {
|
||||
Replicas: 2,
|
||||
Volumes: []kobject.Volumes{{SvcName: "app", MountPath: "/tmp/volume", PVCName: "app-claim0"}},
|
||||
GroupAdd: []int64{1003, 1005},
|
||||
Configs: []dockerCliTypes.ServiceConfigObjConfig{{Source: "config", Target: "/etc/world"}},
|
||||
ConfigsMetaData: map[string]dockerCliTypes.ConfigObjConfig{"config": dockerCliTypes.ConfigObjConfig{Name: "myconfig", File: "kubernetes_test.go"}},
|
||||
Configs: []types.ServiceConfigObjConfig{{Source: "config", Target: "/etc/world"}},
|
||||
ConfigsMetaData: types.Configs{"config": types.ConfigObjConfig{Name: "myconfig", File: "kubernetes_test.go"}},
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,7 +495,7 @@ func TestKomposeConvert(t *testing.T) {
|
||||
if (int)(dc.Spec.Replicas) != replicas {
|
||||
t.Errorf("Expected %d replicas, got %d", replicas, dc.Spec.Replicas)
|
||||
}
|
||||
if len(dc.Spec.Selector) < 0 {
|
||||
if len(dc.Spec.Selector) == 0 {
|
||||
t.Errorf("Expect selector be set, got: %#v", dc.Spec.Selector)
|
||||
}
|
||||
foundDC = true
|
||||
@ -529,8 +529,8 @@ func TestConvertRestartOptions(t *testing.T) {
|
||||
svc kobject.KomposeObject
|
||||
restartPolicy api.RestartPolicy
|
||||
}{
|
||||
"'restart' is set to 'no'": {kobject.KomposeObject{ServiceConfigs: map[string]kobject.ServiceConfig{"app": kobject.ServiceConfig{Image: "foobar", Restart: "no"}}}, api.RestartPolicyNever},
|
||||
"'restart' is set to 'on-failure'": {kobject.KomposeObject{ServiceConfigs: map[string]kobject.ServiceConfig{"app": kobject.ServiceConfig{Image: "foobar", Restart: "on-failure"}}}, api.RestartPolicyOnFailure},
|
||||
"'restart' is set to 'no'": {kobject.KomposeObject{ServiceConfigs: map[string]kobject.ServiceConfig{"app": {Image: "foobar", Restart: "no"}}}, api.RestartPolicyNever},
|
||||
"'restart' is set to 'on-failure'": {kobject.KomposeObject{ServiceConfigs: map[string]kobject.ServiceConfig{"app": {Image: "foobar", Restart: "on-failure"}}}, api.RestartPolicyOnFailure},
|
||||
}
|
||||
|
||||
for name, test := range testCases {
|
||||
|
||||
@ -190,10 +190,10 @@ func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceCon
|
||||
},
|
||||
Triggers: []deployapi.DeploymentTriggerPolicy{
|
||||
// Trigger new deploy when DeploymentConfig is created (config change)
|
||||
deployapi.DeploymentTriggerPolicy{
|
||||
{
|
||||
Type: deployapi.DeploymentTriggerOnConfigChange,
|
||||
},
|
||||
deployapi.DeploymentTriggerPolicy{
|
||||
{
|
||||
Type: deployapi.DeploymentTriggerOnImageChange,
|
||||
ImageChangeParams: &deployapi.DeploymentTriggerImageChangeParams{
|
||||
//Automatic - if new tag is detected - update image update inside the pod template
|
||||
|
||||
@ -36,8 +36,8 @@ func newServiceConfig() kobject.ServiceConfig {
|
||||
return kobject.ServiceConfig{
|
||||
ContainerName: "myfoobarname",
|
||||
Image: "image",
|
||||
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
@ -125,7 +125,7 @@ func TestKomposeConvertRoute(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
//Test getting git remote url for a directory
|
||||
// Test getting git remote url for a directory
|
||||
func TestGetGitRemote(t *testing.T) {
|
||||
var output string
|
||||
var err error
|
||||
|
||||
@ -342,7 +342,7 @@ func GetComposeFileDir(inputFiles []string) (string, error) {
|
||||
return filepath.Dir(inputFile), nil
|
||||
}
|
||||
|
||||
//BuildDockerImage builds docker image
|
||||
// BuildDockerImage builds docker image
|
||||
func BuildDockerImage(service kobject.ServiceConfig, name string) error {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
|
||||
@ -119,7 +119,7 @@ func TestParseWindowsVolumeMountLinuxContainer(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"container",
|
||||
fmt.Sprintf("%s", linuxContainer),
|
||||
linuxContainer,
|
||||
"",
|
||||
"",
|
||||
linuxContainer,
|
||||
@ -214,7 +214,7 @@ func TestParseWindowsVolumeMountWindowsContainer(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"container",
|
||||
fmt.Sprintf("%s", windowsContainer),
|
||||
windowsContainer,
|
||||
"",
|
||||
"",
|
||||
windowsContainer,
|
||||
@ -311,7 +311,7 @@ func TestParseVolume(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"container",
|
||||
fmt.Sprintf("%s", container2),
|
||||
container2,
|
||||
"",
|
||||
"",
|
||||
container2,
|
||||
|
||||
@ -82,9 +82,10 @@ func (c *Push) PushImage(image Image) error {
|
||||
// handleDockerRegistry adapt legacy docker registry address
|
||||
// After docker login to docker.io, there must be https://index.docker.io/v1/ in config.json of authentication
|
||||
// Reference: https://docs.docker.com/engine/api/v1.23/
|
||||
// > However (for legacy reasons) the “official” Docker, Inc. hosted registry
|
||||
// > must be specified with both a “https://” prefix and a “/v1/” suffix
|
||||
// > even though Docker will prefer to use the v2 registry API.
|
||||
//
|
||||
// > However (for legacy reasons) the “official” Docker, Inc. hosted registry
|
||||
// > must be specified with both a “https://” prefix and a “/v1/” suffix
|
||||
// > even though Docker will prefer to use the v2 registry API.
|
||||
func handleDockerRegistry(auth *dockerlib.AuthConfigurations) {
|
||||
const address = "docker.io"
|
||||
const legacyAddress = "https://index.docker.io/v1/"
|
||||
|
||||
@ -148,7 +148,7 @@ k8s_output="$KOMPOSE_ROOT/script/test/fixtures/change-in-volume/output-k8s-empty
|
||||
os_cmd="kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/change-in-volume/docker-compose.yml convert --with-kompose-annotation=false --stdout --volumes emptyDir"
|
||||
os_output="$KOMPOSE_ROOT/script/test/fixtures/change-in-volume/output-os-empty-vols-template.yaml"
|
||||
convert::expect_success_and_warning "$k8s_cmd" "$k8s_output"
|
||||
convert::expect_success_and_warning "$os_cmd" "$os_output"
|
||||
convert::expect_success "$os_cmd" "$os_output"
|
||||
|
||||
# Test that emptyvols works
|
||||
k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/change-in-volume/docker-compose.yml convert --with-kompose-annotation=false --stdout --emptyvols"
|
||||
@ -163,7 +163,7 @@ k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/expose/compose.yaml conve
|
||||
ocp_cmd="kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/expose/compose.yaml convert --stdout --with-kompose-annotation=false"
|
||||
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/expose/output-k8s.yaml"
|
||||
ocp_output="$KOMPOSE_ROOT/script/test/fixtures/expose/output-os.yaml"
|
||||
convert::expect_success "$k8s_cmd" "$k8s_output"
|
||||
convert::expect_success_and_warning "$k8s_cmd" "$k8s_output"
|
||||
convert::expect_success "$ocp_cmd" "$ocp_output"
|
||||
|
||||
|
||||
@ -193,7 +193,7 @@ k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/statefulset/docker-compos
|
||||
ocp_cmd="kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/statefulset/docker-compose.yaml convert --stdout --with-kompose-annotation=false --controller statefulset"
|
||||
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/statefulset/output-k8s.yaml"
|
||||
ocp_output="$KOMPOSE_ROOT/script/test/fixtures/statefulset/output-os.yaml"
|
||||
convert::expect_success "$k8s_cmd" "$k8s_output"
|
||||
convert::expect_success_and_warning "$k8s_cmd" "$k8s_output"
|
||||
convert::expect_success "$ocp_cmd" "$ocp_output"
|
||||
|
||||
# test specifying volume type using service label
|
||||
|
||||
@ -59,6 +59,7 @@ spec:
|
||||
kompose.service.type: headless
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
@ -68,6 +69,22 @@ spec:
|
||||
restartPolicy: Always
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: change-in-volume-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -87,6 +104,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
@ -106,3 +124,4 @@ spec:
|
||||
- emptyDir: {}
|
||||
name: code-volume
|
||||
status: {}
|
||||
|
||||
|
||||
@ -59,6 +59,7 @@ spec:
|
||||
kompose.service.type: headless
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
@ -68,6 +69,22 @@ spec:
|
||||
restartPolicy: Always
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: change-in-volume-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -87,6 +104,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -57,6 +57,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
@ -126,6 +127,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -57,6 +57,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
@ -126,6 +127,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/change-in-volume-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -21,6 +21,7 @@ spec:
|
||||
kompose.volume.type: configMap
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -54,6 +55,22 @@ metadata:
|
||||
io.kompose.service: db
|
||||
name: db-cm0
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: configmap-volume-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -77,6 +94,7 @@ spec:
|
||||
kompose.volume.type: configMap
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -17,6 +17,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -50,6 +51,22 @@ metadata:
|
||||
io.kompose.service: db
|
||||
name: db-cm0
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: configmap-volume-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -69,6 +86,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -19,6 +19,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -114,6 +115,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -17,6 +17,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -110,6 +111,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/configmap-volume-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -34,6 +34,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/placement-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
affinity:
|
||||
@ -75,3 +76,19 @@ spec:
|
||||
whenUnsatisfiable: ScheduleAnyway
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: placement-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/placement-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/placement-default: "true"
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/placement-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
affinity:
|
||||
|
||||
@ -16,6 +16,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/envvars-interpolation-default: "true"
|
||||
io.kompose.service: myservice
|
||||
spec:
|
||||
containers:
|
||||
@ -33,3 +34,19 @@ spec:
|
||||
restartPolicy: Always
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: envvars-interpolation-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/envvars-interpolation-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/envvars-interpolation-default: "true"
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/envvars-interpolation-default: "true"
|
||||
io.kompose.service: myservice
|
||||
spec:
|
||||
containers:
|
||||
|
||||
19
script/test/fixtures/expose/output-k8s.yaml
vendored
19
script/test/fixtures/expose/output-k8s.yaml
vendored
@ -56,6 +56,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/expose-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
@ -67,6 +68,22 @@ spec:
|
||||
restartPolicy: Always
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: expose-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/expose-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/expose-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -93,6 +110,7 @@ spec:
|
||||
kompose.service.expose.tls-secret: test-secret
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/expose-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
@ -146,3 +164,4 @@ spec:
|
||||
secretName: test-secret
|
||||
status:
|
||||
loadBalancer: {}
|
||||
|
||||
|
||||
2
script/test/fixtures/expose/output-os.yaml
vendored
2
script/test/fixtures/expose/output-os.yaml
vendored
@ -56,6 +56,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/expose-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
@ -130,6 +131,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/expose-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -1,28 +1,3 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kompose.service.group: my-group
|
||||
kompose.service.healthcheck.liveness.tcp_port: "8080"
|
||||
kompose.service.healthcheck.readiness.interval: 10s
|
||||
kompose.service.healthcheck.readiness.retries: "5"
|
||||
kompose.service.healthcheck.readiness.tcp_port: "9090"
|
||||
kompose.service.healthcheck.readiness.timeout: 1s
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.service: my-group
|
||||
name: mongo
|
||||
spec:
|
||||
ports:
|
||||
- name: "27017"
|
||||
port: 27017
|
||||
targetPort: 27017
|
||||
selector:
|
||||
io.kompose.service: my-group
|
||||
status:
|
||||
loadBalancer: {}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@ -48,6 +23,31 @@ spec:
|
||||
status:
|
||||
loadBalancer: {}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
kompose.service.group: my-group
|
||||
kompose.service.healthcheck.liveness.tcp_port: "8080"
|
||||
kompose.service.healthcheck.readiness.interval: 10s
|
||||
kompose.service.healthcheck.readiness.retries: "5"
|
||||
kompose.service.healthcheck.readiness.tcp_port: "9090"
|
||||
kompose.service.healthcheck.readiness.timeout: 1s
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.service: my-group
|
||||
name: mongo
|
||||
spec:
|
||||
ports:
|
||||
- name: "27017"
|
||||
port: 27017
|
||||
targetPort: 27017
|
||||
selector:
|
||||
io.kompose.service: my-group
|
||||
status:
|
||||
loadBalancer: {}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@ -103,11 +103,11 @@ kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
kompose.service.group: my-group
|
||||
kompose.service.healthcheck.liveness.tcp_port: "8081"
|
||||
kompose.service.healthcheck.readiness.interval: 11s
|
||||
kompose.service.healthcheck.readiness.retries: "6"
|
||||
kompose.service.healthcheck.readiness.tcp_port: "9091"
|
||||
kompose.service.healthcheck.readiness.timeout: 2s
|
||||
kompose.service.healthcheck.liveness.tcp_port: "8080"
|
||||
kompose.service.healthcheck.readiness.interval: 10s
|
||||
kompose.service.healthcheck.readiness.retries: "5"
|
||||
kompose.service.healthcheck.readiness.tcp_port: "9090"
|
||||
kompose.service.healthcheck.readiness.timeout: 1s
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.service: my-group
|
||||
@ -122,33 +122,17 @@ spec:
|
||||
metadata:
|
||||
annotations:
|
||||
kompose.service.group: my-group
|
||||
kompose.service.healthcheck.liveness.tcp_port: "8080"
|
||||
kompose.service.healthcheck.readiness.interval: 10s
|
||||
kompose.service.healthcheck.readiness.retries: "5"
|
||||
kompose.service.healthcheck.readiness.tcp_port: "9090"
|
||||
kompose.service.healthcheck.readiness.timeout: 1s
|
||||
kompose.service.healthcheck.liveness.tcp_port: "8081"
|
||||
kompose.service.healthcheck.readiness.interval: 11s
|
||||
kompose.service.healthcheck.readiness.retries: "6"
|
||||
kompose.service.healthcheck.readiness.tcp_port: "9091"
|
||||
kompose.service.healthcheck.readiness.timeout: 2s
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
io.kompose.service: my-group
|
||||
spec:
|
||||
containers:
|
||||
- image: mongo
|
||||
livenessProbe:
|
||||
failureThreshold: 5
|
||||
periodSeconds: 10
|
||||
tcpSocket:
|
||||
port: 8080
|
||||
timeoutSeconds: 1
|
||||
name: mongo
|
||||
ports:
|
||||
- containerPort: 27017
|
||||
readinessProbe:
|
||||
failureThreshold: 5
|
||||
periodSeconds: 10
|
||||
tcpSocket:
|
||||
port: 9090
|
||||
timeoutSeconds: 1
|
||||
resources: {}
|
||||
- image: mysql
|
||||
livenessProbe:
|
||||
failureThreshold: 6
|
||||
@ -166,9 +150,42 @@ spec:
|
||||
port: 9091
|
||||
timeoutSeconds: 2
|
||||
resources: {}
|
||||
- image: mongo
|
||||
livenessProbe:
|
||||
failureThreshold: 5
|
||||
periodSeconds: 10
|
||||
tcpSocket:
|
||||
port: 8080
|
||||
timeoutSeconds: 1
|
||||
name: mongo
|
||||
ports:
|
||||
- containerPort: 27017
|
||||
readinessProbe:
|
||||
failureThreshold: 5
|
||||
periodSeconds: 10
|
||||
tcpSocket:
|
||||
port: 9090
|
||||
timeoutSeconds: 1
|
||||
resources: {}
|
||||
restartPolicy: Always
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: healthcheck-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -203,6 +220,7 @@ spec:
|
||||
kompose.service.healthcheck.readiness.timeout: 1s
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
io.kompose.service: postgresql
|
||||
spec:
|
||||
containers:
|
||||
@ -256,6 +274,7 @@ spec:
|
||||
kompose.service.healthcheck.readiness.timeout: 1s
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -122,6 +122,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
io.kompose.service: mongo
|
||||
spec:
|
||||
containers:
|
||||
@ -211,6 +212,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
io.kompose.service: mysql
|
||||
spec:
|
||||
containers:
|
||||
@ -301,6 +303,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
io.kompose.service: postgresql
|
||||
spec:
|
||||
containers:
|
||||
@ -390,6 +393,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/healthcheck-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -16,6 +16,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/multiple-files-default: "true"
|
||||
io.kompose.service: bar
|
||||
spec:
|
||||
containers:
|
||||
@ -25,6 +26,22 @@ spec:
|
||||
restartPolicy: Always
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: multiple-files-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/multiple-files-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/multiple-files-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -43,6 +60,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/multiple-files-default: "true"
|
||||
io.kompose.service: foo
|
||||
spec:
|
||||
containers:
|
||||
@ -51,3 +69,4 @@ spec:
|
||||
resources: {}
|
||||
restartPolicy: Always
|
||||
status: {}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/multiple-files-default: "true"
|
||||
io.kompose.service: bar
|
||||
spec:
|
||||
containers:
|
||||
@ -84,6 +85,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/multiple-files-default: "true"
|
||||
io.kompose.service: foo
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -21,6 +21,7 @@ spec:
|
||||
kompose.volume.type: persistentVolumeClaim
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/multiple-type-volumes-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -53,6 +54,22 @@ spec:
|
||||
storage: 100Mi
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: multiple-type-volumes-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/multiple-type-volumes-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/multiple-type-volumes-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -76,6 +93,7 @@ spec:
|
||||
kompose.volume.type: configMap
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/multiple-type-volumes-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -19,6 +19,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/multiple-type-volumes-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -113,6 +114,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/multiple-type-volumes-default: "true"
|
||||
io.kompose.service: web
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
web:
|
||||
image: tuna/docker-counter23
|
||||
ports:
|
||||
- "5000:5000"
|
||||
links:
|
||||
- redis
|
||||
redis:
|
||||
image: redis:3.0
|
||||
ports:
|
||||
- "6379"
|
||||
services:
|
||||
web:
|
||||
image: tuna/docker-counter23
|
||||
ports:
|
||||
- "5000:5000"
|
||||
links:
|
||||
- redis
|
||||
redis:
|
||||
image: redis:3.0
|
||||
ports:
|
||||
- "6379"
|
||||
|
||||
@ -35,6 +35,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/service-group-default: "true"
|
||||
io.kompose.service: librenms-dispatcher
|
||||
spec:
|
||||
containers:
|
||||
@ -82,3 +83,19 @@ spec:
|
||||
storage: 100Mi
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: service-group-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/service-group-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/service-group-default: "true"
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ spec:
|
||||
kompose.service.expose.ingress-class-name: nginx
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/single-file-output-default: "true"
|
||||
io.kompose.service: front-end
|
||||
spec:
|
||||
containers:
|
||||
@ -83,3 +84,20 @@ spec:
|
||||
pathType: Prefix
|
||||
status:
|
||||
loadBalancer: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: single-file-output-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/single-file-output-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/single-file-output-default: "true"
|
||||
|
||||
|
||||
18
script/test/fixtures/statefulset/output-k8s.yaml
vendored
18
script/test/fixtures/statefulset/output-k8s.yaml
vendored
@ -56,6 +56,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/statefulset-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -94,6 +95,22 @@ spec:
|
||||
status:
|
||||
replicas: 0
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: statefulset-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/statefulset-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/statefulset-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
@ -112,6 +129,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/statefulset-default: "true"
|
||||
io.kompose.service: wordpress
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -52,6 +52,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/statefulset-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -109,6 +110,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/statefulset-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -191,6 +193,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/statefulset-default: "true"
|
||||
io.kompose.service: wordpress
|
||||
spec:
|
||||
containers:
|
||||
@ -248,6 +251,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/statefulset-default: "true"
|
||||
io.kompose.service: wordpress
|
||||
spec:
|
||||
containers:
|
||||
|
||||
18
script/test/fixtures/v2/output-k8s.yaml
vendored
18
script/test/fixtures/v2/output-k8s.yaml
vendored
@ -138,6 +138,7 @@ kind: Pod
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/v2-default: "true"
|
||||
io.kompose.service: foo
|
||||
name: foo
|
||||
spec:
|
||||
@ -194,6 +195,22 @@ spec:
|
||||
- 1234
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: v2-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/v2-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/v2-default: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@ -216,6 +233,7 @@ spec:
|
||||
kompose.service.type: loadbalancer
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/v2-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
|
||||
2
script/test/fixtures/v2/output-os.yaml
vendored
2
script/test/fixtures/v2/output-os.yaml
vendored
@ -138,6 +138,7 @@ kind: Pod
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/v2-default: "true"
|
||||
io.kompose.service: foo
|
||||
name: foo
|
||||
spec:
|
||||
@ -214,6 +215,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/v2-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
|
||||
25
script/test/fixtures/v3.0/output-k8s.yaml
vendored
25
script/test/fixtures/v3.0/output-k8s.yaml
vendored
@ -38,7 +38,7 @@ spec:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/app-network: "true"
|
||||
io.kompose.network/normalized-network: "true"
|
||||
io.kompose.network/v30-normalized-network: "true"
|
||||
io.kompose.network/web-network: "true"
|
||||
io.kompose.service: foo
|
||||
spec:
|
||||
@ -90,16 +90,16 @@ apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: normalized-network
|
||||
name: v30-normalized-network
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/normalized-network: "true"
|
||||
io.kompose.network/v30-normalized-network: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/normalized-network: "true"
|
||||
io.kompose.network/v30-normalized-network: "true"
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
@ -123,6 +123,7 @@ spec:
|
||||
kompose.service.type: headless
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/v30-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
@ -139,3 +140,19 @@ spec:
|
||||
restartPolicy: Always
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: v30-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/v30-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/v30-default: "true"
|
||||
|
||||
|
||||
3
script/test/fixtures/v3.0/output-os.yaml
vendored
3
script/test/fixtures/v3.0/output-os.yaml
vendored
@ -38,7 +38,7 @@ spec:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/app-network: "true"
|
||||
io.kompose.network/normalized-network: "true"
|
||||
io.kompose.network/v30-normalized-network: "true"
|
||||
io.kompose.network/web-network: "true"
|
||||
io.kompose.service: foo
|
||||
spec:
|
||||
@ -114,6 +114,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/v30-default: "true"
|
||||
io.kompose.service: redis
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -35,6 +35,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/windows-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
@ -69,3 +70,19 @@ spec:
|
||||
storage: 100Mi
|
||||
status: {}
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: windows-default
|
||||
spec:
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/windows-default: "true"
|
||||
podSelector:
|
||||
matchLabels:
|
||||
io.kompose.network/windows-default: "true"
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ spec:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
io.kompose.network/windows-default: "true"
|
||||
io.kompose.service: db
|
||||
spec:
|
||||
containers:
|
||||
|
||||
@ -36,7 +36,7 @@ ENV PATH="$PATH:$GOPATH/bin:$GOROOT/bin" \
|
||||
WORKDIR /tmp/go
|
||||
RUN curl https://storage.googleapis.com/golang/go$GOVERSION.linux-amd64.tar.gz | tar -xz -C /usr/local
|
||||
|
||||
RUN go get golang.org/x/lint/golint
|
||||
RUN go get honnef.co/go/tools/cmd/staticcheck@latest
|
||||
|
||||
WORKDIR $KOMPOSE_SRC
|
||||
# This image can be run as any user
|
||||
|
||||
Loading…
Reference in New Issue
Block a user