diff --git a/build_logs/darwin_amd64.log b/build_logs/darwin_amd64.log index 584516b..e69de29 100644 --- a/build_logs/darwin_amd64.log +++ b/build_logs/darwin_amd64.log @@ -1,3 +0,0 @@ -# go-compose-extractor -./main.go:31:53: undefined: types.ContainerListOptions -./main.go:67:38: container.Config undefined (type types.Container has no field or method Config) diff --git a/build_logs/darwin_arm64.log b/build_logs/darwin_arm64.log index 584516b..e69de29 100644 --- a/build_logs/darwin_arm64.log +++ b/build_logs/darwin_arm64.log @@ -1,3 +0,0 @@ -# go-compose-extractor -./main.go:31:53: undefined: types.ContainerListOptions -./main.go:67:38: container.Config undefined (type types.Container has no field or method Config) diff --git a/build_logs/error.log b/build_logs/error.log deleted file mode 100644 index 4f7d59e..0000000 --- a/build_logs/error.log +++ /dev/null @@ -1,7 +0,0 @@ -Build failed for linux/amd64 -Static build failed for linux/amd64 -Build failed for linux/arm64 -Static build failed for linux/arm64 -Build failed for darwin/amd64 -Build failed for darwin/arm64 -Build failed for windows/amd64 diff --git a/build_logs/linux_amd64.log b/build_logs/linux_amd64.log index 584516b..e69de29 100644 --- a/build_logs/linux_amd64.log +++ b/build_logs/linux_amd64.log @@ -1,3 +0,0 @@ -# go-compose-extractor -./main.go:31:53: undefined: types.ContainerListOptions -./main.go:67:38: container.Config undefined (type types.Container has no field or method Config) diff --git a/build_logs/linux_amd64_static.log b/build_logs/linux_amd64_static.log index 584516b..e69de29 100644 --- a/build_logs/linux_amd64_static.log +++ b/build_logs/linux_amd64_static.log @@ -1,3 +0,0 @@ -# go-compose-extractor -./main.go:31:53: undefined: types.ContainerListOptions -./main.go:67:38: container.Config undefined (type types.Container has no field or method Config) diff --git a/build_logs/linux_arm64.log b/build_logs/linux_arm64.log index 584516b..e69de29 100644 --- a/build_logs/linux_arm64.log +++ b/build_logs/linux_arm64.log @@ -1,3 +0,0 @@ -# go-compose-extractor -./main.go:31:53: undefined: types.ContainerListOptions -./main.go:67:38: container.Config undefined (type types.Container has no field or method Config) diff --git a/build_logs/linux_arm64_static.log b/build_logs/linux_arm64_static.log index 584516b..e69de29 100644 --- a/build_logs/linux_arm64_static.log +++ b/build_logs/linux_arm64_static.log @@ -1,3 +0,0 @@ -# go-compose-extractor -./main.go:31:53: undefined: types.ContainerListOptions -./main.go:67:38: container.Config undefined (type types.Container has no field or method Config) diff --git a/build_logs/windows_amd64.log b/build_logs/windows_amd64.log index 584516b..e69de29 100644 --- a/build_logs/windows_amd64.log +++ b/build_logs/windows_amd64.log @@ -1,3 +0,0 @@ -# go-compose-extractor -./main.go:31:53: undefined: types.ContainerListOptions -./main.go:67:38: container.Config undefined (type types.Container has no field or method Config) diff --git a/dist/go-compose-extractor_darwin_amd64 b/dist/go-compose-extractor_darwin_amd64 new file mode 100755 index 0000000..9d412ad Binary files /dev/null and b/dist/go-compose-extractor_darwin_amd64 differ diff --git a/dist/go-compose-extractor_darwin_arm64 b/dist/go-compose-extractor_darwin_arm64 new file mode 100755 index 0000000..dc33bab Binary files /dev/null and b/dist/go-compose-extractor_darwin_arm64 differ diff --git a/dist/go-compose-extractor_linux_amd64 b/dist/go-compose-extractor_linux_amd64 new file mode 100755 index 0000000..097e547 Binary files /dev/null and b/dist/go-compose-extractor_linux_amd64 differ diff --git a/dist/go-compose-extractor_linux_amd64_static b/dist/go-compose-extractor_linux_amd64_static new file mode 100755 index 0000000..848f830 Binary files /dev/null and b/dist/go-compose-extractor_linux_amd64_static differ diff --git a/dist/go-compose-extractor_linux_arm64 b/dist/go-compose-extractor_linux_arm64 new file mode 100755 index 0000000..a666242 Binary files /dev/null and b/dist/go-compose-extractor_linux_arm64 differ diff --git a/dist/go-compose-extractor_linux_arm64_static b/dist/go-compose-extractor_linux_arm64_static new file mode 100755 index 0000000..8620977 Binary files /dev/null and b/dist/go-compose-extractor_linux_arm64_static differ diff --git a/dist/go-compose-extractor_windows_amd64 b/dist/go-compose-extractor_windows_amd64 new file mode 100755 index 0000000..4409369 Binary files /dev/null and b/dist/go-compose-extractor_windows_amd64 differ diff --git a/go.mod b/go.mod index 9d9aa5d..5d41a22 100644 --- a/go.mod +++ b/go.mod @@ -2,34 +2,4 @@ module go-compose-extractor go 1.21.1 -require ( - github.com/docker/docker v27.2.0+incompatible - gopkg.in/yaml.v2 v2.4.0 -) - -require ( - github.com/Microsoft/go-winio v0.4.14 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-connections v0.5.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/term v0.5.0 // indirect - github.com/morikuni/aec v1.0.0 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/pkg/errors v0.9.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 // indirect - go.opentelemetry.io/otel/metric v1.29.0 // indirect - go.opentelemetry.io/otel/sdk v1.29.0 // indirect - go.opentelemetry.io/otel/trace v1.29.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/time v0.6.0 // indirect - gotest.tools/v3 v3.5.1 // indirect -) +require gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index ac3fdf5..dd0bc19 100644 --- a/go.sum +++ b/go.sum @@ -1,127 +1,4 @@ -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/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -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/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4= -github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -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 v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= -go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= -go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc= -go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= -go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= -go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= -go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= -go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= -go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= diff --git a/main.go b/main.go index 6aa63c7..141ee99 100644 --- a/main.go +++ b/main.go @@ -1,15 +1,15 @@ package main import ( - "context" + "bufio" + "bytes" "flag" "fmt" "log" "os" + "os/exec" "strings" - "github.com/docker/docker/api/types" - "github.com/docker/docker/client" "gopkg.in/yaml.v2" ) @@ -19,97 +19,171 @@ func main() { outputFile := flag.String("o", "docker-compose.yml", "Specify the output file for the YAML.") flag.Parse() - // Initialize Docker client - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - log.Fatalf("Error initializing Docker client: %v", err) - } - - ctx := context.Background() - - // Fetch list of all containers - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{}) + // Fetch list of all containers with their stack or project labels + containers, err := listContainers() if err != nil { log.Fatalf("Error fetching container list: %v", err) } - // Map to hold docker-compose configuration without version key - composeConfig := make(map[string]interface{}) - composeConfig["services"] = make(map[string]interface{}) + // Map to group containers by stack or project + stacks := make(map[string][]Container) - // To store available stacks/projects if no specific stack is provided - stacks := make(map[string]bool) - - // Process each container + // Group containers by Docker Compose project or Docker Swarm stack for _, container := range containers { project := container.Labels["com.docker.compose.project"] stackNamespace := container.Labels["com.docker.stack.namespace"] + stackKey := project + if stackNamespace != "" { + stackKey = stackNamespace + } - if *stackName == "" { - // Gather available stack names - if project != "" { - stacks[project] = true - } else if stackNamespace != "" { - stacks[stackNamespace] = true - } - } else { - // Export specific stack or project - if project == *stackName || stackNamespace == *stackName { - serviceName := strings.TrimPrefix(container.Names[0], "/") - image := container.Image - - // Initialize service configuration - serviceConfig := map[string]interface{}{ - "image": image, - } - - // Handle environment variables - envVars := container.Config.Env - if len(envVars) > 0 { - serviceConfig["environment"] = envVars - } - - // Handle network settings - networks := []string{} - for network := range container.NetworkSettings.Networks { - networks = append(networks, network) - } - if len(networks) > 0 { - serviceConfig["networks"] = networks - } - - // Add service configuration to compose config - composeConfig["services"].(map[string]interface{})[serviceName] = serviceConfig - } + if stackKey != "" { + stacks[stackKey] = append(stacks[stackKey], container) } } if *stackName == "" { - // Print available stacks/projects - fmt.Println("Available stacks or Docker Compose projects to export:") - for stack := range stacks { - fmt.Println("- " + stack) + // No stack specified, list available stacks + if len(stacks) == 0 { + fmt.Println("No Docker Compose projects or Docker Swarm stacks found.") + } else { + fmt.Println("Available stacks or Docker Compose projects to export:") + for stack := range stacks { + fmt.Println("- " + stack) + } } return } - // If specific stack/project is requested but not found - if len(composeConfig["services"].(map[string]interface{})) == 0 { - log.Fatalf("No services found for stack or project: %s", *stackName) + // Stack specified, check if it exists + containers, exists := stacks[*stackName] + if !exists { + log.Fatalf("Stack or project '%s' not found.", *stackName) + } + + // Export the specified stack/project to a docker-compose.yml file + err = exportStackToComposeFile(*stackName, containers, *outputFile) + if err != nil { + log.Fatalf("Error exporting stack %s: %v", *stackName, err) + } + fmt.Printf("docker-compose.yml generated successfully for stack '%s' in %s\n", *stackName, *outputFile) +} + +// Container represents basic Docker container information. +type Container struct { + ID string + Name string + Image string + Labels map[string]string + Env []string + Networks []string +} + +// listContainers runs 'docker ps' and 'docker inspect' to get a list of all containers. +func listContainers() ([]Container, error) { + cmd := exec.Command("docker", "ps", "--format", "{{.ID}} {{.Names}} {{.Image}} {{.Label \"com.docker.compose.project\"}} {{.Label \"com.docker.stack.namespace\"}}") + var out bytes.Buffer + cmd.Stdout = &out + err := cmd.Run() + if err != nil { + return nil, err + } + + scanner := bufio.NewScanner(&out) + var containers []Container + + for scanner.Scan() { + fields := strings.Fields(scanner.Text()) + if len(fields) < 3 { + continue + } + + id := fields[0] + name := fields[1] + image := fields[2] + labels := map[string]string{ + "com.docker.compose.project": fields[3], + "com.docker.stack.namespace": fields[4], + } + + // Run 'docker inspect' to get detailed container information. + env, networks, err := inspectContainer(id) + if err != nil { + return nil, err + } + + containers = append(containers, Container{ + ID: id, + Name: name, + Image: image, + Labels: labels, + Env: env, + Networks: networks, + }) + } + + return containers, scanner.Err() +} + +// inspectContainer runs 'docker inspect' and parses environment variables and networks. +func inspectContainer(containerID string) ([]string, []string, error) { + cmd := exec.Command("docker", "inspect", "--format", "{{range .Config.Env}}{{printf \"%s \" .}}{{end}} {{range $key, $value := .NetworkSettings.Networks}}{{$key}} {{end}}", containerID) + var out bytes.Buffer + cmd.Stdout = &out + err := cmd.Run() + if err != nil { + return nil, nil, err + } + + parts := strings.Split(out.String(), " ") + envVars := strings.Fields(parts[0]) + networks := strings.Fields(parts[1]) + + return envVars, networks, nil +} + +// exportStackToComposeFile generates a docker-compose.yml for a given stack or project. +func exportStackToComposeFile(stack string, containers []Container, outputFile string) error { + // Map to hold docker-compose configuration + composeConfig := make(map[string]interface{}) + composeConfig["services"] = make(map[string]interface{}) + + // Process each container in the stack + for _, container := range containers { + serviceName := container.Name + image := container.Image + + // Initialize service configuration + serviceConfig := map[string]interface{}{ + "image": image, + } + + // Handle environment variables + if len(container.Env) > 0 { + serviceConfig["environment"] = container.Env + } + + // Handle network settings + if len(container.Networks) > 0 { + serviceConfig["networks"] = container.Networks + } + + // Add service configuration to compose config + composeConfig["services"].(map[string]interface{})[serviceName] = serviceConfig } // Convert to YAML yamlData, err := yaml.Marshal(&composeConfig) if err != nil { - log.Fatalf("Error generating YAML: %v", err) + return fmt.Errorf("error generating YAML for stack %s: %v", stack, err) } - // Write YAML to specified output file - err = os.WriteFile(*outputFile, yamlData, 0644) + // Write YAML to a file + err = os.WriteFile(outputFile, yamlData, 0644) if err != nil { - log.Fatalf("Error writing to file: %v", err) + return fmt.Errorf("error writing to file %s: %v", outputFile, err) } - fmt.Printf("docker-compose.yml generated successfully in %s\n", *outputFile) + return nil }