mstevens pushed to rpms/mbedtls (epel9). "Update to 2.28.1"
by notificationsï¼ fedoraproject.org
Notification time stamped 2022-10-22 20:46:55 UTC
From 817d432422ebf9bab4dda39b4e70392566dced52 Mon Sep 17 00:00:00 2001
From: Morten Stevens <mstevens(a)fedoraproject.org>
Date: Oct 22 2022 20:45:09 +0000
Subject: Update to 2.28.1
---
diff --git a/.gitignore b/.gitignore
index 764c6fb..bb7bc0e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@
/mbedtls-2.16.11.tar.gz
/mbedtls-2.16.12.tar.gz
/mbedtls-2.28.0.tar.gz
+/mbedtls-2.28.1.tar.gz
diff --git a/mbedtls.spec b/mbedtls.spec
index 9ac2097..b92e23c 100644
--- a/mbedtls.spec
+++ b/mbedtls.spec
@@ -3,8 +3,8 @@
%endif
Name: mbedtls
-Version: 2.28.0
-Release: 3%{?dist}
+Version: 2.28.1
+Release: 1%{?dist}
Summary: Light-weight cryptographic and SSL/TLS library
License: ASL 2.0
URL: https://tls.mbed.org/
@@ -95,6 +95,9 @@ chmod 755 %{buildroot}%{_libdir}/*.so.*
%doc apidoc/*
%changelog
+* Sat Oct 22 2022 Morten Stevens <mstevens(a)fedoraproject.org> - 2.28.1-1
+- Update to 2.28.1
+
* Thu Jul 21 2022 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.28.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
diff --git a/sources b/sources
index 701a8dd..a2bb94e 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (mbedtls-2.28.0.tar.gz) = 907867edf532ba3b099f4fb7ce31f5773ceceb072a8d067b1d830e879d541f92f401d64f13bbe6b4eb0845e58bb765d7d28896be414bb0fc7ac5b3876066be5f
+SHA512 (mbedtls-2.28.1.tar.gz) = b71d052acfb83daff11e0182f32b0ad0af7c59d2b74bd19f270531a3da9ed3ce1d3adcaf756e161bf05a10fe1b6b7753e360e9dbb5b7b123f09201b1202ef689
https://src.fedoraproject.org/rpms/mbedtls/c/817d432422ebf9bab4dda39b4e70...
1Â year, 5Â months
mstevens pushed to rpms/mbedtls (f36). "Update to 2.28.1"
by notificationsï¼ fedoraproject.org
Notification time stamped 2022-10-22 20:46:35 UTC
From 817d432422ebf9bab4dda39b4e70392566dced52 Mon Sep 17 00:00:00 2001
From: Morten Stevens <mstevens(a)fedoraproject.org>
Date: Oct 22 2022 20:45:09 +0000
Subject: Update to 2.28.1
---
diff --git a/.gitignore b/.gitignore
index 764c6fb..bb7bc0e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@
/mbedtls-2.16.11.tar.gz
/mbedtls-2.16.12.tar.gz
/mbedtls-2.28.0.tar.gz
+/mbedtls-2.28.1.tar.gz
diff --git a/mbedtls.spec b/mbedtls.spec
index 9ac2097..b92e23c 100644
--- a/mbedtls.spec
+++ b/mbedtls.spec
@@ -3,8 +3,8 @@
%endif
Name: mbedtls
-Version: 2.28.0
-Release: 3%{?dist}
+Version: 2.28.1
+Release: 1%{?dist}
Summary: Light-weight cryptographic and SSL/TLS library
License: ASL 2.0
URL: https://tls.mbed.org/
@@ -95,6 +95,9 @@ chmod 755 %{buildroot}%{_libdir}/*.so.*
%doc apidoc/*
%changelog
+* Sat Oct 22 2022 Morten Stevens <mstevens(a)fedoraproject.org> - 2.28.1-1
+- Update to 2.28.1
+
* Thu Jul 21 2022 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.28.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
diff --git a/sources b/sources
index 701a8dd..a2bb94e 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (mbedtls-2.28.0.tar.gz) = 907867edf532ba3b099f4fb7ce31f5773ceceb072a8d067b1d830e879d541f92f401d64f13bbe6b4eb0845e58bb765d7d28896be414bb0fc7ac5b3876066be5f
+SHA512 (mbedtls-2.28.1.tar.gz) = b71d052acfb83daff11e0182f32b0ad0af7c59d2b74bd19f270531a3da9ed3ce1d3adcaf756e161bf05a10fe1b6b7753e360e9dbb5b7b123f09201b1202ef689
https://src.fedoraproject.org/rpms/mbedtls/c/817d432422ebf9bab4dda39b4e70...
1Â year, 5Â months
mstevens pushed to rpms/mbedtls (rawhide). "Update to 2.28.1"
by notificationsï¼ fedoraproject.org
Notification time stamped 2022-10-22 20:45:18 UTC
From 817d432422ebf9bab4dda39b4e70392566dced52 Mon Sep 17 00:00:00 2001
From: Morten Stevens <mstevens(a)fedoraproject.org>
Date: Oct 22 2022 20:45:09 +0000
Subject: Update to 2.28.1
---
diff --git a/.gitignore b/.gitignore
index 764c6fb..bb7bc0e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@
/mbedtls-2.16.11.tar.gz
/mbedtls-2.16.12.tar.gz
/mbedtls-2.28.0.tar.gz
+/mbedtls-2.28.1.tar.gz
diff --git a/mbedtls.spec b/mbedtls.spec
index 9ac2097..b92e23c 100644
--- a/mbedtls.spec
+++ b/mbedtls.spec
@@ -3,8 +3,8 @@
%endif
Name: mbedtls
-Version: 2.28.0
-Release: 3%{?dist}
+Version: 2.28.1
+Release: 1%{?dist}
Summary: Light-weight cryptographic and SSL/TLS library
License: ASL 2.0
URL: https://tls.mbed.org/
@@ -95,6 +95,9 @@ chmod 755 %{buildroot}%{_libdir}/*.so.*
%doc apidoc/*
%changelog
+* Sat Oct 22 2022 Morten Stevens <mstevens(a)fedoraproject.org> - 2.28.1-1
+- Update to 2.28.1
+
* Thu Jul 21 2022 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.28.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
diff --git a/sources b/sources
index 701a8dd..a2bb94e 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (mbedtls-2.28.0.tar.gz) = 907867edf532ba3b099f4fb7ce31f5773ceceb072a8d067b1d830e879d541f92f401d64f13bbe6b4eb0845e58bb765d7d28896be414bb0fc7ac5b3876066be5f
+SHA512 (mbedtls-2.28.1.tar.gz) = b71d052acfb83daff11e0182f32b0ad0af7c59d2b74bd19f270531a3da9ed3ce1d3adcaf756e161bf05a10fe1b6b7753e360e9dbb5b7b123f09201b1202ef689
https://src.fedoraproject.org/rpms/mbedtls/c/817d432422ebf9bab4dda39b4e70...
1Â year, 5Â months
mstevens pushed to rpms/mbedtls (f37). "Update to 2.28.1"
by notificationsï¼ fedoraproject.org
Notification time stamped 2022-10-22 20:45:39 UTC
From 817d432422ebf9bab4dda39b4e70392566dced52 Mon Sep 17 00:00:00 2001
From: Morten Stevens <mstevens(a)fedoraproject.org>
Date: Oct 22 2022 20:45:09 +0000
Subject: Update to 2.28.1
---
diff --git a/.gitignore b/.gitignore
index 764c6fb..bb7bc0e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@
/mbedtls-2.16.11.tar.gz
/mbedtls-2.16.12.tar.gz
/mbedtls-2.28.0.tar.gz
+/mbedtls-2.28.1.tar.gz
diff --git a/mbedtls.spec b/mbedtls.spec
index 9ac2097..b92e23c 100644
--- a/mbedtls.spec
+++ b/mbedtls.spec
@@ -3,8 +3,8 @@
%endif
Name: mbedtls
-Version: 2.28.0
-Release: 3%{?dist}
+Version: 2.28.1
+Release: 1%{?dist}
Summary: Light-weight cryptographic and SSL/TLS library
License: ASL 2.0
URL: https://tls.mbed.org/
@@ -95,6 +95,9 @@ chmod 755 %{buildroot}%{_libdir}/*.so.*
%doc apidoc/*
%changelog
+* Sat Oct 22 2022 Morten Stevens <mstevens(a)fedoraproject.org> - 2.28.1-1
+- Update to 2.28.1
+
* Thu Jul 21 2022 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.28.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
diff --git a/sources b/sources
index 701a8dd..a2bb94e 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (mbedtls-2.28.0.tar.gz) = 907867edf532ba3b099f4fb7ce31f5773ceceb072a8d067b1d830e879d541f92f401d64f13bbe6b4eb0845e58bb765d7d28896be414bb0fc7ac5b3876066be5f
+SHA512 (mbedtls-2.28.1.tar.gz) = b71d052acfb83daff11e0182f32b0ad0af7c59d2b74bd19f270531a3da9ed3ce1d3adcaf756e161bf05a10fe1b6b7753e360e9dbb5b7b123f09201b1202ef689
https://src.fedoraproject.org/rpms/mbedtls/c/817d432422ebf9bab4dda39b4e70...
1Â year, 5Â months
eneville pushed to rpms/rust-pleaser (epel9). "bump 0.5.3"
by notificationsï¼ fedoraproject.org
Notification time stamped 2022-10-22 20:46:09 UTC
From 369076802f080d1d627edba4b4e831adf3edfe20 Mon Sep 17 00:00:00 2001
From: ed neville <ed(a)s5h.net>
Date: Oct 22 2022 20:45:49 +0000
Subject: bump 0.5.3
---
diff --git a/pleaser-fix-metadata.diff b/pleaser-fix-metadata.diff
deleted file mode 100644
index 5d4edb8..0000000
--- a/pleaser-fix-metadata.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- pleaser-0.5.0/Cargo.toml 2021-11-09T22:42:53+00:00
-+++ pleaser-0.5.0/Cargo.toml 2021-11-17T21:59:33.164308+00:00
-@@ -33,7 +33,7 @@
- version = "0.2"
-
- [dependencies.nix]
--version = ">= 0.23"
-+version = ">= 0.19"
-
- [dependencies.pam]
- version = "0.7"
diff --git a/rust-pleaser.spec b/rust-pleaser.spec
index f07a745..25e92e5 100644
--- a/rust-pleaser.spec
+++ b/rust-pleaser.spec
@@ -14,8 +14,8 @@
%endif
Name: rust-%{crate}
-Version: 0.5.0
-Release: 1%{?dist}
+Version: 0.5.3
+Release: 0%{?dist}
Summary: Please, a polite regex-first sudo alternative
# Upstream license specification: GPL-3.0-or-later
https://src.fedoraproject.org/rpms/rust-pleaser/c/369076802f080d1d627edba...
1Â year, 5Â months
eclipseo pushed to rpms/golang-github-docker-cli (rawhide). "Update
to to 22.06~beta.0 (..more)"
by notificationsï¼ fedoraproject.org
Notification time stamped 2022-10-22 19:58:12 UTC
From e1e997eca7dabc5a27c67ce1933cffe428091abb Mon Sep 17 00:00:00 2001
From: Robert-André Mauchin <zebob.m(a)gmail.com>
Date: Oct 22 2022 19:57:48 +0000
Subject: Update to to 22.06~beta.0
Close: rhbz#1990103, rhbz#2113287
---
diff --git a/.gitignore b/.gitignore
index da7f9f2..659773b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
/cli-20.10.5.tar.gz
/cli-20.10.6.tar.gz
/cli-20.10.7.tar.gz
+/cli-22.06.0-beta.0.tar.gz
diff --git a/0001-Drop-obsolete-compose-on-kubernetes.patch b/0001-Drop-obsolete-compose-on-kubernetes.patch
deleted file mode 100644
index d408ba0..0000000
--- a/0001-Drop-obsolete-compose-on-kubernetes.patch
+++ /dev/null
@@ -1,5233 +0,0 @@
-From 6077685887953717815823e22ef0553b64a1509c Mon Sep 17 00:00:00 2001
-From: Nicolas De Loof <nicolas.deloof(a)gmail.com>
-Date: Wed, 16 Jun 2021 09:08:42 +0200
-Subject: [PATCH] Drop support for (archived) Compose-on-Kubernetes
-
-Signed-off-by: Nicolas De Loof <nicolas.deloof(a)gmail.com>
----
- cli/command/stack/cmd.go | 12 +-
- cli/command/stack/common.go | 19 -
- cli/command/stack/deploy.go | 6 +-
- cli/command/stack/formatter/formatter.go | 11 -
- cli/command/stack/formatter/formatter_test.go | 12 +-
- cli/command/stack/kubernetes/cli.go | 144 -
- cli/command/stack/kubernetes/client.go | 105 -
- cli/command/stack/kubernetes/conversion.go | 269 -
- .../stack/kubernetes/conversion_test.go | 185 -
- cli/command/stack/kubernetes/convert.go | 578 -
- cli/command/stack/kubernetes/convert_test.go | 349 -
- cli/command/stack/kubernetes/deploy.go | 171 -
- cli/command/stack/kubernetes/deploy_test.go | 299 -
- cli/command/stack/kubernetes/list.go | 136 -
- cli/command/stack/kubernetes/ps.go | 112 -
- cli/command/stack/kubernetes/remove.go | 27 -
- cli/command/stack/kubernetes/services.go | 140 -
- cli/command/stack/kubernetes/services_test.go | 138 -
- cli/command/stack/kubernetes/stack.go | 161 -
- cli/command/stack/kubernetes/stackclient.go | 274 -
- .../stack/kubernetes/stackclient_test.go | 60 -
- .../testdata/compose-with-expose.yml | 9 -
- .../testdata/compose-with-pull-policy.yml | 6 -
- .../testdata/compose-with-pull-secret.yml | 6 -
- cli/command/stack/kubernetes/testdata/config | 1 -
- cli/command/stack/kubernetes/testdata/secret | 1 -
- .../stack/kubernetes/testdata/warnings.golden | 31 -
- cli/command/stack/kubernetes/warnings.go | 145 -
- cli/command/stack/kubernetes/warnings_test.go | 78 -
- cli/command/stack/kubernetes/watcher.go | 262 -
- cli/command/stack/kubernetes/watcher_test.go | 220 -
- cli/command/stack/list.go | 26 +-
- cli/command/stack/options/opts.go | 1 -
- cli/command/stack/ps.go | 6 +-
- cli/command/stack/remove.go | 7 +-
- cli/command/stack/services.go | 15 +-
- cli/context/kubernetes/constants.go | 6 -
- cli/context/kubernetes/endpoint_test.go | 224 -
- cli/context/kubernetes/load.go | 146 -
- cli/context/kubernetes/load_test.go | 25 -
- cli/context/kubernetes/save.go | 69 -
- .../kubernetes/testdata/eks-kubeconfig | 23 -
- .../kubernetes/testdata/gke-kubeconfig | 23 -
- .../kubernetes/testdata/k3s-kubeconfig | 20 -
- .../kubernetes/testdata/test-kubeconfig | 20 -
- cli/context/store/doc.go | 2 +-
- e2e/stack/deploy_test.go | 9 -
- e2e/stack/help_test.go | 3 -
- e2e/stack/remove_test.go | 6 -
- .../stack-deploy-help-kubernetes.golden | 14 -
- .../testdata/stack-deploy-help-swarm.golden | 2 +-
- .../stack-deploy-with-names-kubernetes.golden | 7 -
- .../stack-remove-kubernetes-success.golden | 1 -
- \
- 3633 files changed, 12 insertions(+), 1137760 deletions(-)
- delete mode 100644 cli/command/stack/kubernetes/cli.go
- delete mode 100644 cli/command/stack/kubernetes/client.go
- delete mode 100644 cli/command/stack/kubernetes/conversion.go
- delete mode 100644 cli/command/stack/kubernetes/conversion_test.go
- delete mode 100644 cli/command/stack/kubernetes/convert.go
- delete mode 100644 cli/command/stack/kubernetes/convert_test.go
- delete mode 100644 cli/command/stack/kubernetes/deploy.go
- delete mode 100644 cli/command/stack/kubernetes/deploy_test.go
- delete mode 100644 cli/command/stack/kubernetes/list.go
- delete mode 100644 cli/command/stack/kubernetes/ps.go
- delete mode 100644 cli/command/stack/kubernetes/remove.go
- delete mode 100644 cli/command/stack/kubernetes/services.go
- delete mode 100644 cli/command/stack/kubernetes/services_test.go
- delete mode 100644 cli/command/stack/kubernetes/stack.go
- delete mode 100644 cli/command/stack/kubernetes/stackclient.go
- delete mode 100644 cli/command/stack/kubernetes/stackclient_test.go
- delete mode 100644 cli/command/stack/kubernetes/testdata/compose-with-expose.yml
- delete mode 100644 cli/command/stack/kubernetes/testdata/compose-with-pull-policy.yml
- delete mode 100644 cli/command/stack/kubernetes/testdata/compose-with-pull-secret.yml
- delete mode 100644 cli/command/stack/kubernetes/testdata/config
- delete mode 100644 cli/command/stack/kubernetes/testdata/secret
- delete mode 100644 cli/command/stack/kubernetes/testdata/warnings.golden
- delete mode 100644 cli/command/stack/kubernetes/warnings.go
- delete mode 100644 cli/command/stack/kubernetes/warnings_test.go
- delete mode 100644 cli/command/stack/kubernetes/watcher.go
- delete mode 100644 cli/command/stack/kubernetes/watcher_test.go
- delete mode 100644 cli/context/kubernetes/constants.go
- delete mode 100644 cli/context/kubernetes/endpoint_test.go
- delete mode 100644 cli/context/kubernetes/load.go
- delete mode 100644 cli/context/kubernetes/load_test.go
- delete mode 100644 cli/context/kubernetes/save.go
- delete mode 100644 cli/context/kubernetes/testdata/eks-kubeconfig
- delete mode 100644 cli/context/kubernetes/testdata/gke-kubeconfig
- delete mode 100644 cli/context/kubernetes/testdata/k3s-kubeconfig
- delete mode 100644 cli/context/kubernetes/testdata/test-kubeconfig
- delete mode 100644 e2e/stack/testdata/stack-deploy-help-kubernetes.golden
- delete mode 100644 e2e/stack/testdata/stack-deploy-with-names-kubernetes.golden
- delete mode 100644 e2e/stack/testdata/stack-remove-kubernetes-success.golden
-
-diff --git a/cli/command/stack/cmd.go b/cli/command/stack/cmd.go
-index f4ded771693..60c0cf21b80 100644
---- a/cli/command/stack/cmd.go
-+++ b/cli/command/stack/cmd.go
-@@ -11,8 +11,6 @@ import (
- "github.com/spf13/pflag"
- )
-
--var errUnsupportedAllOrchestrator = fmt.Errorf(`no orchestrator specified: use either "kubernetes" or "swarm"`)
--
- type commonOptions struct {
- orchestrator command.Orchestrator
- }
-@@ -67,9 +65,7 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command {
- newServicesCommand(dockerCli, &opts),
- )
- flags := cmd.PersistentFlags()
-- flags.String("kubeconfig", "", "Kubernetes config file")
-- flags.SetAnnotation("kubeconfig", "kubernetes", nil)
-- flags.String("orchestrator", "", "Orchestrator to use (swarm|kubernetes|all)")
-+ flags.String("orchestrator", "", "Orchestrator to use (swarm|all)")
- return cmd
- }
-
-@@ -83,9 +79,6 @@ func getOrchestrator(dockerCli command.Cli, cmd *cobra.Command) (command.Orchest
-
- func hideOrchestrationFlags(cmd *cobra.Command, orchestrator command.Orchestrator) {
- cmd.Flags().VisitAll(func(f *pflag.Flag) {
-- if _, ok := f.Annotations["kubernetes"]; ok && !orchestrator.HasKubernetes() {
-- f.Hidden = true
-- }
- if _, ok := f.Annotations["swarm"]; ok && !orchestrator.HasSwarm() {
- f.Hidden = true
- }
-@@ -101,9 +94,6 @@ func checkSupportedFlag(cmd *cobra.Command, orchestrator command.Orchestrator) e
- if !f.Changed {
- return
- }
-- if _, ok := f.Annotations["kubernetes"]; ok && !orchestrator.HasKubernetes() {
-- errs = append(errs, fmt.Sprintf(`"--%s" is only supported on a Docker cli with kubernetes features enabled`, f.Name))
-- }
- if _, ok := f.Annotations["swarm"]; ok && !orchestrator.HasSwarm() {
- errs = append(errs, fmt.Sprintf(`"--%s" is only supported on a Docker cli with swarm features enabled`, f.Name))
- }
-diff --git a/cli/command/stack/common.go b/cli/command/stack/common.go
-index 2a89cfad2ef..6de410da84c 100644
---- a/cli/command/stack/common.go
-+++ b/cli/command/stack/common.go
-@@ -4,10 +4,6 @@ import (
- "fmt"
- "strings"
- "unicode"
--
-- "github.com/docker/cli/cli/command"
-- "github.com/docker/cli/cli/command/stack/kubernetes"
-- "github.com/spf13/pflag"
- )
-
- // validateStackName checks if the provided string is a valid stack name (namespace).
-@@ -33,18 +29,3 @@ func validateStackNames(namespaces []string) error {
- func quotesOrWhitespace(r rune) bool {
- return unicode.IsSpace(r) || r == '"' || r == '\''
- }
--
--func runOrchestratedCommand(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, swarmCmd func() error, kubernetesCmd func(*kubernetes.KubeCli) error) error {
-- switch {
-- case commonOrchestrator.HasAll():
-- return errUnsupportedAllOrchestrator
-- case commonOrchestrator.HasKubernetes():
-- kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(flags, commonOrchestrator))
-- if err != nil {
-- return err
-- }
-- return kubernetesCmd(kli)
-- default:
-- return swarmCmd()
-- }
--}
-diff --git a/cli/command/stack/deploy.go b/cli/command/stack/deploy.go
-index 8dd31f41937..a25ce0cc68f 100644
---- a/cli/command/stack/deploy.go
-+++ b/cli/command/stack/deploy.go
-@@ -3,7 +3,6 @@ package stack
- import (
- "github.com/docker/cli/cli"
- "github.com/docker/cli/cli/command"
-- "github.com/docker/cli/cli/command/stack/kubernetes"
- "github.com/docker/cli/cli/command/stack/loader"
- "github.com/docker/cli/cli/command/stack/options"
- "github.com/docker/cli/cli/command/stack/swarm"
-@@ -45,13 +44,10 @@ func newDeployCommand(dockerCli command.Cli, common *commonOptions) *cobra.Comma
- `Query the registry to resolve image digest and supported platforms ("`+swarm.ResolveImageAlways+`"|"`+swarm.ResolveImageChanged+`"|"`+swarm.ResolveImageNever+`")`)
- flags.SetAnnotation("resolve-image", "version", []string{"1.30"})
- flags.SetAnnotation("resolve-image", "swarm", nil)
-- kubernetes.AddNamespaceFlag(flags)
- return cmd
- }
-
- // RunDeploy performs a stack deploy against the specified orchestrator
- func RunDeploy(dockerCli command.Cli, flags *pflag.FlagSet, config *composetypes.Config, commonOrchestrator command.Orchestrator, opts options.Deploy) error {
-- return runOrchestratedCommand(dockerCli, flags, commonOrchestrator,
-- func() error { return swarm.RunDeploy(dockerCli, opts, config) },
-- func(kli *kubernetes.KubeCli) error { return kubernetes.RunDeploy(kli, opts, config) })
-+ return swarm.RunDeploy(dockerCli, opts, config)
- }
-diff --git a/cli/command/stack/formatter/formatter.go b/cli/command/stack/formatter/formatter.go
-index c52d9309c8e..6bc6bf03f30 100644
---- a/cli/command/stack/formatter/formatter.go
-+++ b/cli/command/stack/formatter/formatter.go
-@@ -7,15 +7,11 @@ import (
- )
-
- const (
-- // KubernetesStackTableFormat is the default Kubernetes stack format
-- KubernetesStackTableFormat formatter.Format = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}\t{{.Namespace}}"
--
- // SwarmStackTableFormat is the default Swarm stack format
- SwarmStackTableFormat formatter.Format = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}"
-
- stackServicesHeader = "SERVICES"
- stackOrchestrastorHeader = "ORCHESTRATOR"
-- stackNamespaceHeader = "NAMESPACE"
-
- // TableFormatKey is an alias for formatter.TableFormatKey
- TableFormatKey = formatter.TableFormatKey
-@@ -35,8 +31,6 @@ type Stack struct {
- Services int
- // Orchestrator is the platform where the stack is deployed
- Orchestrator string
-- // Namespace is the Kubernetes namespace assigned to the stack
-- Namespace string
- }
-
- // StackWrite writes formatted stacks using the Context
-@@ -63,7 +57,6 @@ func newStackContext() *stackContext {
- "Name": formatter.NameHeader,
- "Services": stackServicesHeader,
- "Orchestrator": stackOrchestrastorHeader,
-- "Namespace": stackNamespaceHeader,
- }
- return &stackCtx
- }
-@@ -83,7 +76,3 @@ func (s *stackContext) Services() string {
- func (s *stackContext) Orchestrator() string {
- return s.s.Orchestrator
- }
--
--func (s *stackContext) Namespace() string {
-- return s.s.Namespace
--}
-diff --git a/cli/command/stack/formatter/formatter_test.go b/cli/command/stack/formatter/formatter_test.go
-index dd25bca7d2b..3dc439634f8 100644
---- a/cli/command/stack/formatter/formatter_test.go
-+++ b/cli/command/stack/formatter/formatter_test.go
-@@ -30,14 +30,6 @@ func TestStackContextWrite(t *testing.T) {
- `NAME SERVICES ORCHESTRATOR
- baz 2 orchestrator1
- bar 1 orchestrator2
--`,
-- },
-- // Kubernetes table format adds Namespace column
-- {
-- formatter.Context{Format: KubernetesStackTableFormat},
-- `NAME SERVICES ORCHESTRATOR NAMESPACE
--baz 2 orchestrator1 namespace1
--bar 1 orchestrator2 namespace2
- `,
- },
- {
-@@ -57,8 +49,8 @@ bar
- }
-
- stacks := []*Stack{
-- {Name: "baz", Services: 2, Orchestrator: "orchestrator1", Namespace: "namespace1"},
-- {Name: "bar", Services: 1, Orchestrator: "orchestrator2", Namespace: "namespace2"},
-+ {Name: "baz", Services: 2, Orchestrator: "orchestrator1"},
-+ {Name: "bar", Services: 1, Orchestrator: "orchestrator2"},
- }
- for _, tc := range cases {
- tc := tc
-diff --git a/cli/command/stack/kubernetes/cli.go b/cli/command/stack/kubernetes/cli.go
-deleted file mode 100644
-index a531846809c..00000000000
---- a/cli/command/stack/kubernetes/cli.go
-+++ /dev/null
-@@ -1,144 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
-- "net"
-- "net/url"
-- "os"
--
-- "github.com/docker/cli/cli/command"
-- kubecontext "github.com/docker/cli/cli/context/kubernetes"
-- kubernetes "github.com/docker/compose-on-kubernetes/api"
-- cliv1beta1 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compos..."
-- "github.com/pkg/errors"
-- flag "github.com/spf13/pflag"
-- kubeclient "k8s.io/client-go/kubernetes"
-- restclient "k8s.io/client-go/rest"
-- "k8s.io/client-go/tools/clientcmd"
--)
--
--// KubeCli holds kubernetes specifics (client, namespace) with the command.Cli
--type KubeCli struct {
-- command.Cli
-- kubeConfig *restclient.Config
-- kubeNamespace string
-- clientSet *kubeclient.Clientset
--}
--
--// Options contains resolved parameters to initialize kubernetes clients
--type Options struct {
-- Namespace string
-- Config string
-- Orchestrator command.Orchestrator
--}
--
--// NewOptions returns an Options initialized with command line flags
--func NewOptions(flags *flag.FlagSet, orchestrator command.Orchestrator) Options {
-- opts := Options{
-- Orchestrator: orchestrator,
-- }
-- if namespace, err := flags.GetString("namespace"); err == nil {
-- opts.Namespace = namespace
-- }
-- if kubeConfig, err := flags.GetString("kubeconfig"); err == nil {
-- opts.Config = kubeConfig
-- }
-- return opts
--}
--
--// AddNamespaceFlag adds the namespace flag to the given flag set
--func AddNamespaceFlag(flags *flag.FlagSet) {
-- flags.String("namespace", "", "Kubernetes namespace to use")
-- flags.SetAnnotation("namespace", "kubernetes", nil)
--}
--
--// WrapCli wraps command.Cli with kubernetes specifics
--func WrapCli(dockerCli command.Cli, opts Options) (*KubeCli, error) {
-- cli := &KubeCli{
-- Cli: dockerCli,
-- }
-- var (
-- clientConfig clientcmd.ClientConfig
-- err error
-- )
-- if dockerCli.CurrentContext() == "" {
-- clientConfig = kubernetes.NewKubernetesConfig(opts.Config)
-- } else {
-- clientConfig, err = kubecontext.ConfigFromContext(dockerCli.CurrentContext(), dockerCli.ContextStore())
-- }
-- if err != nil {
-- return nil, err
-- }
--
-- cli.kubeNamespace = opts.Namespace
-- if opts.Namespace == "" {
-- configNamespace, _, err := clientConfig.Namespace()
-- switch {
-- case os.IsNotExist(err), os.IsPermission(err):
-- return nil, errors.Wrap(err, "unable to load configuration file")
-- case err != nil:
-- return nil, err
-- }
-- cli.kubeNamespace = configNamespace
-- }
--
-- config, err := clientConfig.ClientConfig()
-- if err != nil {
-- return nil, err
-- }
-- cli.kubeConfig = config
--
-- clientSet, err := kubeclient.NewForConfig(config)
-- if err != nil {
-- return nil, err
-- }
-- cli.clientSet = clientSet
--
-- if opts.Orchestrator.HasAll() {
-- if err := cli.checkHostsMatch(); err != nil {
-- return nil, err
-- }
-- }
-- return cli, nil
--}
--
--func (c *KubeCli) composeClient() (*Factory, error) {
-- return NewFactory(c.kubeNamespace, c.kubeConfig, c.clientSet)
--}
--
--func (c *KubeCli) checkHostsMatch() error {
-- daemonEndpoint, err := url.Parse(c.Client().DaemonHost())
-- if err != nil {
-- return err
-- }
-- kubeEndpoint, err := url.Parse(c.kubeConfig.Host)
-- if err != nil {
-- return err
-- }
-- if daemonEndpoint.Hostname() == kubeEndpoint.Hostname() {
-- return nil
-- }
-- // The daemon can be local in Docker for Desktop, e.g. "npipe", "unix", ...
-- if daemonEndpoint.Scheme != "tcp" {
-- ips, err := net.LookupIP(kubeEndpoint.Hostname())
-- if err != nil {
-- return err
-- }
-- for _, ip := range ips {
-- if ip.IsLoopback() {
-- return nil
-- }
-- }
-- }
-- fmt.Fprintf(c.Err(), "WARNING: Swarm and Kubernetes hosts do not match (docker host=%s, kubernetes host=%s).\n"+
-- " Update $DOCKER_HOST (or pass -H), or use 'kubectl config use-context' to match.\n", daemonEndpoint.Hostname(), kubeEndpoint.Hostname())
-- return nil
--}
--
--func (c *KubeCli) stacksv1beta1() (cliv1beta1.StackInterface, error) {
-- raw, err := newStackV1Beta1(c.kubeConfig, c.kubeNamespace)
-- if err != nil {
-- return nil, err
-- }
-- return raw.stacks, nil
--}
-diff --git a/cli/command/stack/kubernetes/client.go b/cli/command/stack/kubernetes/client.go
-deleted file mode 100644
-index 9a7dc7e3eeb..00000000000
---- a/cli/command/stack/kubernetes/client.go
-+++ /dev/null
-@@ -1,105 +0,0 @@
--package kubernetes
--
--import (
-- "github.com/docker/cli/kubernetes"
-- "github.com/pkg/errors"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- kubeclient "k8s.io/client-go/kubernetes"
-- appsv1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2"
-- typesappsv1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2"
-- corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
-- restclient "k8s.io/client-go/rest"
--)
--
--// Factory is the kubernetes client factory
--type Factory struct {
-- namespace string
-- config *restclient.Config
-- coreClientSet corev1.CoreV1Interface
-- appsClientSet appsv1beta2.AppsV1beta2Interface
-- clientSet *kubeclient.Clientset
--}
--
--// NewFactory creates a kubernetes client factory
--func NewFactory(namespace string, config *restclient.Config, clientSet *kubeclient.Clientset) (*Factory, error) {
-- coreClientSet, err := corev1.NewForConfig(config)
-- if err != nil {
-- return nil, err
-- }
--
-- appsClientSet, err := appsv1beta2.NewForConfig(config)
-- if err != nil {
-- return nil, err
-- }
--
-- return &Factory{
-- namespace: namespace,
-- config: config,
-- coreClientSet: coreClientSet,
-- appsClientSet: appsClientSet,
-- clientSet: clientSet,
-- }, nil
--}
--
--// ConfigMaps returns a client for kubernetes's config maps
--func (s *Factory) ConfigMaps() corev1.ConfigMapInterface {
-- return s.coreClientSet.ConfigMaps(s.namespace)
--}
--
--// Secrets returns a client for kubernetes's secrets
--func (s *Factory) Secrets() corev1.SecretInterface {
-- return s.coreClientSet.Secrets(s.namespace)
--}
--
--// Services returns a client for kubernetes's secrets
--func (s *Factory) Services() corev1.ServiceInterface {
-- return s.coreClientSet.Services(s.namespace)
--}
--
--// Pods returns a client for kubernetes's pods
--func (s *Factory) Pods() corev1.PodInterface {
-- return s.coreClientSet.Pods(s.namespace)
--}
--
--// Nodes returns a client for kubernetes's nodes
--func (s *Factory) Nodes() corev1.NodeInterface {
-- return s.coreClientSet.Nodes()
--}
--
--// ReplicationControllers returns a client for kubernetes replication controllers
--func (s *Factory) ReplicationControllers() corev1.ReplicationControllerInterface {
-- return s.coreClientSet.ReplicationControllers(s.namespace)
--}
--
--// ReplicaSets returns a client for kubernetes replace sets
--func (s *Factory) ReplicaSets() typesappsv1beta2.ReplicaSetInterface {
-- return s.appsClientSet.ReplicaSets(s.namespace)
--}
--
--// DaemonSets returns a client for kubernetes daemon sets
--func (s *Factory) DaemonSets() typesappsv1beta2.DaemonSetInterface {
-- return s.appsClientSet.DaemonSets(s.namespace)
--}
--
--// Stacks returns a client for Docker's Stack on Kubernetes
--func (s *Factory) Stacks(allNamespaces bool) (StackClient, error) {
-- version, err := kubernetes.GetStackAPIVersion(s.clientSet.Discovery())
-- if err != nil {
-- return nil, err
-- }
-- namespace := s.namespace
-- if allNamespaces {
-- namespace = metav1.NamespaceAll
-- }
--
-- switch version {
-- case kubernetes.StackAPIV1Beta1:
-- return newStackV1Beta1(s.config, namespace)
-- case kubernetes.StackAPIV1Beta2:
-- return newStackV1Beta2(s.config, namespace)
-- case kubernetes.StackAPIV1Alpha3:
-- return newStackV1Alpha3(s.config, namespace)
-- default:
-- return nil, errors.Errorf("unsupported stack API version: %q", version)
-- }
--}
-diff --git a/cli/command/stack/kubernetes/conversion.go b/cli/command/stack/kubernetes/conversion.go
-deleted file mode 100644
-index 14797b081d3..00000000000
---- a/cli/command/stack/kubernetes/conversion.go
-+++ /dev/null
-@@ -1,269 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
-- "sort"
-- "strings"
-- "time"
--
-- "github.com/docker/compose-on-kubernetes/api/labels"
-- "github.com/docker/docker/api/types/filters"
-- "github.com/docker/docker/api/types/swarm"
-- appsv1beta2 "k8s.io/api/apps/v1beta2"
-- apiv1 "k8s.io/api/core/v1"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
--)
--
--// Pod conversion
--func podToTask(pod apiv1.Pod) swarm.Task {
-- var startTime time.Time
-- if pod.Status.StartTime != nil {
-- startTime = (*pod.Status.StartTime).Time
-- }
-- task := swarm.Task{
-- ID: string(pod.UID),
-- NodeID: pod.Spec.NodeName,
-- Spec: swarm.TaskSpec{
-- ContainerSpec: &swarm.ContainerSpec{
-- Image: getContainerImage(pod.Spec.Containers),
-- },
-- },
-- DesiredState: podPhaseToState(pod.Status.Phase),
-- Status: swarm.TaskStatus{
-- State: podPhaseToState(pod.Status.Phase),
-- Timestamp: startTime,
-- PortStatus: swarm.PortStatus{
-- Ports: getPorts(pod.Spec.Containers),
-- },
-- },
-- }
--
-- return task
--}
--
--func podPhaseToState(phase apiv1.PodPhase) swarm.TaskState {
-- switch phase {
-- case apiv1.PodPending:
-- return swarm.TaskStatePending
-- case apiv1.PodRunning:
-- return swarm.TaskStateRunning
-- case apiv1.PodSucceeded:
-- return swarm.TaskStateComplete
-- case apiv1.PodFailed:
-- return swarm.TaskStateFailed
-- default:
-- return swarm.TaskState("unknown")
-- }
--}
--
--func toSwarmProtocol(protocol apiv1.Protocol) swarm.PortConfigProtocol {
-- switch protocol {
-- case apiv1.ProtocolTCP:
-- return swarm.PortConfigProtocolTCP
-- case apiv1.ProtocolUDP:
-- return swarm.PortConfigProtocolUDP
-- }
-- return swarm.PortConfigProtocol("unknown")
--}
--
--func fetchPods(stackName string, pods corev1.PodInterface, f filters.Args) ([]apiv1.Pod, error) {
-- services := f.Get("service")
-- // for existing script compatibility, support either <servicename> or <stackname>_<servicename> format
-- stackNamePrefix := stackName + "_"
-- for _, s := range services {
-- if strings.HasPrefix(s, stackNamePrefix) {
-- services = append(services, strings.TrimPrefix(s, stackNamePrefix))
-- }
-- }
-- listOpts := metav1.ListOptions{LabelSelector: labels.SelectorForStack(stackName, services...)}
-- var result []apiv1.Pod
-- podsList, err := pods.List(listOpts)
-- if err != nil {
-- return nil, err
-- }
-- nodes := f.Get("node")
-- for _, pod := range podsList.Items {
-- if filterPod(pod, nodes) &&
-- // name filter is done client side for matching partials
-- f.FuzzyMatch("name", stackNamePrefix+pod.Name) {
--
-- result = append(result, pod)
-- }
-- }
-- return result, nil
--}
--
--func filterPod(pod apiv1.Pod, nodes []string) bool {
-- if len(nodes) == 0 {
-- return true
-- }
-- for _, name := range nodes {
-- if pod.Spec.NodeName == name {
-- return true
-- }
-- }
-- return false
--}
--
--func getContainerImage(containers []apiv1.Container) string {
-- if len(containers) == 0 {
-- return ""
-- }
-- return containers[0].Image
--}
--
--func getPorts(containers []apiv1.Container) []swarm.PortConfig {
-- if len(containers) == 0 || len(containers[0].Ports) == 0 {
-- return nil
-- }
-- ports := make([]swarm.PortConfig, len(containers[0].Ports))
-- for i, port := range containers[0].Ports {
-- ports[i] = swarm.PortConfig{
-- PublishedPort: uint32(port.HostPort),
-- TargetPort: uint32(port.ContainerPort),
-- Protocol: toSwarmProtocol(port.Protocol),
-- }
-- }
-- return ports
--}
--
--type tasksBySlot []swarm.Task
--
--func (t tasksBySlot) Len() int {
-- return len(t)
--}
--
--func (t tasksBySlot) Swap(i, j int) {
-- t[i], t[j] = t[j], t[i]
--}
--
--func (t tasksBySlot) Less(i, j int) bool {
-- // Sort by slot.
-- if t[i].Slot != t[j].Slot {
-- return t[i].Slot < t[j].Slot
-- }
--
-- // If same slot, sort by most recent.
-- return t[j].Meta.CreatedAt.Before(t[i].CreatedAt)
--}
--
--const (
-- publishedServiceSuffix = "-published"
-- publishedOnRandomPortSuffix = "-random-ports"
--)
--
--func convertToServices(replicas *appsv1beta2.ReplicaSetList, daemons *appsv1beta2.DaemonSetList, services *apiv1.ServiceList) ([]swarm.Service, error) {
-- result := make([]swarm.Service, len(replicas.Items))
--
-- for i, r := range replicas.Items {
-- s, err := replicatedService(r, services)
-- if err != nil {
-- return nil, err
-- }
-- result[i] = *s
-- }
-- for _, d := range daemons.Items {
-- s, err := globalService(d, services)
-- if err != nil {
-- return nil, err
-- }
-- result = append(result, *s)
-- }
-- sort.Slice(result, func(i, j int) bool {
-- return result[i].ID < result[j].ID
-- })
-- return result, nil
--}
--
--func uint64ptr(i int32) *uint64 {
-- var o uint64
-- if i > 0 {
-- o = uint64(i)
-- }
-- return &o
--}
--
--func replicatedService(r appsv1beta2.ReplicaSet, services *apiv1.ServiceList) (*swarm.Service, error) {
-- s, err := convertToService(r.Labels[labels.ForServiceName], services, r.Spec.Template.Spec.Containers)
-- if err != nil {
-- return nil, err
-- }
-- s.Spec.Mode = swarm.ServiceMode{
-- Replicated: &swarm.ReplicatedService{Replicas: uint64ptr(r.Status.Replicas)},
-- }
-- s.ServiceStatus = &swarm.ServiceStatus{
-- RunningTasks: uint64(r.Status.AvailableReplicas),
-- DesiredTasks: uint64(r.Status.Replicas),
-- }
-- return s, nil
--}
--
--func globalService(d appsv1beta2.DaemonSet, services *apiv1.ServiceList) (*swarm.Service, error) {
-- s, err := convertToService(d.Labels[labels.ForServiceName], services, d.Spec.Template.Spec.Containers)
-- if err != nil {
-- return nil, err
-- }
-- s.Spec.Mode = swarm.ServiceMode{
-- Global: &swarm.GlobalService{},
-- }
-- s.ServiceStatus = &swarm.ServiceStatus{
-- RunningTasks: uint64(d.Status.NumberReady),
-- DesiredTasks: uint64(d.Status.DesiredNumberScheduled),
-- }
-- return s, nil
--}
--
--func convertToService(serviceName string, services *apiv1.ServiceList, containers []apiv1.Container) (*swarm.Service, error) {
-- serviceHeadless, err := findService(services, serviceName)
-- if err != nil {
-- return nil, err
-- }
-- stack, ok := serviceHeadless.Labels[labels.ForStackName]
-- if ok {
-- stack += "_"
-- }
-- uid := string(serviceHeadless.UID)
-- s := &swarm.Service{
-- ID: uid,
-- Spec: swarm.ServiceSpec{
-- Annotations: swarm.Annotations{
-- Name: stack + serviceHeadless.Name,
-- },
-- TaskTemplate: swarm.TaskSpec{
-- ContainerSpec: &swarm.ContainerSpec{
-- Image: getContainerImage(containers),
-- },
-- },
-- },
-- }
-- if serviceNodePort, err := findService(services, serviceName+publishedOnRandomPortSuffix); err == nil && serviceNodePort.Spec.Type == apiv1.ServiceTypeNodePort {
-- s.Endpoint = serviceEndpoint(serviceNodePort, swarm.PortConfigPublishModeHost)
-- }
-- if serviceLoadBalancer, err := findService(services, serviceName+publishedServiceSuffix); err == nil && serviceLoadBalancer.Spec.Type == apiv1.ServiceTypeLoadBalancer {
-- s.Endpoint = serviceEndpoint(serviceLoadBalancer, swarm.PortConfigPublishModeIngress)
-- }
-- return s, nil
--}
--
--func findService(services *apiv1.ServiceList, name string) (apiv1.Service, error) {
-- for _, s := range services.Items {
-- if s.Name == name {
-- return s, nil
-- }
-- }
-- return apiv1.Service{}, fmt.Errorf("could not find service '%s'", name)
--}
--
--func serviceEndpoint(service apiv1.Service, publishMode swarm.PortConfigPublishMode) swarm.Endpoint {
-- configs := make([]swarm.PortConfig, len(service.Spec.Ports))
-- for i, p := range service.Spec.Ports {
-- configs[i] = swarm.PortConfig{
-- PublishMode: publishMode,
-- PublishedPort: uint32(p.Port),
-- TargetPort: uint32(p.TargetPort.IntValue()),
-- Protocol: toSwarmProtocol(p.Protocol),
-- }
-- }
-- return swarm.Endpoint{Ports: configs}
--}
-diff --git a/cli/command/stack/kubernetes/conversion_test.go b/cli/command/stack/kubernetes/conversion_test.go
-deleted file mode 100644
-index cad49d39746..00000000000
---- a/cli/command/stack/kubernetes/conversion_test.go
-+++ /dev/null
-@@ -1,185 +0,0 @@
--package kubernetes
--
--import (
-- "testing"
--
-- . "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
-- "github.com/docker/compose-on-kubernetes/api/labels"
-- "github.com/docker/docker/api/types/swarm"
-- "gotest.tools/v3/assert"
-- appsv1beta2 "k8s.io/api/apps/v1beta2"
-- apiv1 "k8s.io/api/core/v1"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- apimachineryTypes "k8s.io/apimachinery/pkg/types"
-- apimachineryUtil "k8s.io/apimachinery/pkg/util/intstr"
--)
--
--func TestReplicasConversionNeedsAService(t *testing.T) {
-- replicas := appsv1beta2.ReplicaSetList{
-- Items: []appsv1beta2.ReplicaSet{makeReplicaSet("unknown", 0, 0)},
-- }
-- services := apiv1.ServiceList{}
-- _, err := convertToServices(&replicas, &appsv1beta2.DaemonSetList{}, &services)
-- assert.ErrorContains(t, err, "could not find service")
--}
--
--func TestKubernetesServiceToSwarmServiceConversion(t *testing.T) {
-- testCases := []struct {
-- doc string
-- replicas *appsv1beta2.ReplicaSetList
-- services *apiv1.ServiceList
-- expectedServices []swarm.Service
-- }{
-- {
-- doc: "Match replicas with headless stack services",
-- replicas: &appsv1beta2.ReplicaSetList{
-- Items: []appsv1beta2.ReplicaSet{
-- makeReplicaSet("service1", 2, 5),
-- makeReplicaSet("service2", 3, 3),
-- },
-- },
-- services: &apiv1.ServiceList{
-- Items: []apiv1.Service{
-- makeKubeService("service1", "stack", "uid1", apiv1.ServiceTypeClusterIP, nil),
-- makeKubeService("service2", "stack", "uid2", apiv1.ServiceTypeClusterIP, nil),
-- makeKubeService("service3", "other-stack", "uid2", apiv1.ServiceTypeClusterIP, nil),
-- },
-- },
-- expectedServices: []swarm.Service{
-- makeSwarmService(t, "stack_service1", "uid1", ReplicatedService(5), ServiceStatus(5, 2)),
-- makeSwarmService(t, "stack_service2", "uid2", ReplicatedService(3), ServiceStatus(3, 3)),
-- },
-- },
-- {
-- doc: "Headless service and LoadBalancer Service are tied to the same Swarm service",
-- replicas: &appsv1beta2.ReplicaSetList{
-- Items: []appsv1beta2.ReplicaSet{
-- makeReplicaSet("service", 1, 1),
-- },
-- },
-- services: &apiv1.ServiceList{
-- Items: []apiv1.Service{
-- makeKubeService("service", "stack", "uid1", apiv1.ServiceTypeClusterIP, nil),
-- makeKubeService("service-published", "stack", "uid2", apiv1.ServiceTypeLoadBalancer, []apiv1.ServicePort{
-- {
-- Port: 80,
-- TargetPort: apimachineryUtil.FromInt(80),
-- Protocol: apiv1.ProtocolTCP,
-- },
-- }),
-- },
-- },
-- expectedServices: []swarm.Service{
-- makeSwarmService(t, "stack_service", "uid1",
-- ReplicatedService(1),
-- ServiceStatus(1, 1),
-- withPort(swarm.PortConfig{
-- PublishMode: swarm.PortConfigPublishModeIngress,
-- PublishedPort: 80,
-- TargetPort: 80,
-- Protocol: swarm.PortConfigProtocolTCP,
-- }),
-- ),
-- },
-- },
-- {
-- doc: "Headless service and NodePort Service are tied to the same Swarm service",
-- replicas: &appsv1beta2.ReplicaSetList{
-- Items: []appsv1beta2.ReplicaSet{
-- makeReplicaSet("service", 1, 1),
-- },
-- },
-- services: &apiv1.ServiceList{
-- Items: []apiv1.Service{
-- makeKubeService("service", "stack", "uid1", apiv1.ServiceTypeClusterIP, nil),
-- makeKubeService("service-random-ports", "stack", "uid2", apiv1.ServiceTypeNodePort, []apiv1.ServicePort{
-- {
-- Port: 35666,
-- TargetPort: apimachineryUtil.FromInt(80),
-- Protocol: apiv1.ProtocolTCP,
-- },
-- }),
-- },
-- },
-- expectedServices: []swarm.Service{
-- makeSwarmService(t, "stack_service", "uid1",
-- ReplicatedService(1),
-- ServiceStatus(1, 1),
-- withPort(swarm.PortConfig{
-- PublishMode: swarm.PortConfigPublishModeHost,
-- PublishedPort: 35666,
-- TargetPort: 80,
-- Protocol: swarm.PortConfigProtocolTCP,
-- }),
-- ),
-- },
-- },
-- }
--
-- for _, tc := range testCases {
-- tc := tc
-- t.Run(tc.doc, func(t *testing.T) {
-- swarmServices, err := convertToServices(tc.replicas, &appsv1beta2.DaemonSetList{}, tc.services)
-- assert.NilError(t, err)
-- assert.DeepEqual(t, tc.expectedServices, swarmServices)
-- })
-- }
--}
--
--func makeReplicaSet(service string, available, replicas int32) appsv1beta2.ReplicaSet {
-- return appsv1beta2.ReplicaSet{
-- ObjectMeta: metav1.ObjectMeta{
-- Labels: map[string]string{
-- labels.ForServiceName: service,
-- },
-- },
-- Spec: appsv1beta2.ReplicaSetSpec{
-- Template: apiv1.PodTemplateSpec{
-- Spec: apiv1.PodSpec{
-- Containers: []apiv1.Container{
-- {
-- Image: "image",
-- },
-- },
-- },
-- },
-- },
-- Status: appsv1beta2.ReplicaSetStatus{
-- AvailableReplicas: available,
-- Replicas: replicas,
-- },
-- }
--}
--
--func makeKubeService(service, stack, uid string, serviceType apiv1.ServiceType, ports []apiv1.ServicePort) apiv1.Service {
-- return apiv1.Service{
-- ObjectMeta: metav1.ObjectMeta{
-- Labels: map[string]string{
-- labels.ForStackName: stack,
-- },
-- Name: service,
-- UID: apimachineryTypes.UID(uid),
-- },
-- Spec: apiv1.ServiceSpec{
-- Type: serviceType,
-- Ports: ports,
-- },
-- }
--}
--
--// TODO convertToServices currently doesn't set swarm.EndpointSpec.Ports
--func withPort(port swarm.PortConfig) func(*swarm.Service) {
-- return func(service *swarm.Service) {
-- if service.Endpoint.Ports == nil {
-- service.Endpoint.Ports = make([]swarm.PortConfig, 0)
-- }
-- service.Endpoint.Ports = append(service.Endpoint.Ports, port)
-- }
--}
--
--func makeSwarmService(t *testing.T, name, id string, opts ...func(*swarm.Service)) swarm.Service {
-- t.Helper()
-- options := []func(*swarm.Service){ServiceID(id), ServiceName(name), ServiceImage("image")}
-- options = append(options, opts...)
-- return *Service(options...)
--}
-diff --git a/cli/command/stack/kubernetes/convert.go b/cli/command/stack/kubernetes/convert.go
-deleted file mode 100644
-index 60c2c884472..00000000000
---- a/cli/command/stack/kubernetes/convert.go
-+++ /dev/null
-@@ -1,578 +0,0 @@
--package kubernetes
--
--import (
-- "io"
-- "io/ioutil"
-- "regexp"
-- "strconv"
-- "strings"
--
-- "github.com/docker/cli/cli/compose/loader"
-- "github.com/docker/cli/cli/compose/schema"
-- composeTypes "github.com/docker/cli/cli/compose/types"
-- composetypes "github.com/docker/cli/cli/compose/types"
-- latest "github.com/docker/compose-on-kubernetes/api/compose/v1alpha3"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1beta1"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1beta2"
-- "github.com/docker/go-connections/nat"
-- "github.com/mitchellh/mapstructure"
-- "github.com/pkg/errors"
-- yaml "gopkg.in/yaml.v2"
-- v1 "k8s.io/api/core/v1"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
--)
--
--const (
-- // kubernatesExtraField is an extra field on ServiceConfigs containing kubernetes-specific extensions to compose format
-- kubernatesExtraField = "x-kubernetes"
--)
--
--// NewStackConverter returns a converter from types.Config (compose) to the specified
--// stack version or error out if the version is not supported or existent.
--func NewStackConverter(version string) (StackConverter, error) {
-- switch version {
-- case "v1beta1":
-- return stackV1Beta1Converter{}, nil
-- case "v1beta2":
-- return stackV1Beta2Converter{}, nil
-- case "v1alpha3":
-- return stackV1Alpha3Converter{}, nil
-- default:
-- return nil, errors.Errorf("stack version %s unsupported", version)
-- }
--}
--
--// StackConverter converts a compose types.Config to a Stack
--type StackConverter interface {
-- FromCompose(stderr io.Writer, name string, cfg *composetypes.Config) (Stack, error)
--}
--
--type stackV1Beta1Converter struct{}
--
--func (s stackV1Beta1Converter) FromCompose(stderr io.Writer, name string, cfg *composetypes.Config) (Stack, error) {
-- cfg.Version = v1beta1.MaxComposeVersion
-- st, err := fromCompose(stderr, name, cfg, v1beta1Capabilities)
-- if err != nil {
-- return Stack{}, err
-- }
-- res, err := yaml.Marshal(cfg)
-- if err != nil {
-- return Stack{}, err
-- }
-- // reload the result to check that it produced a valid 3.5 compose file
-- resparsedConfig, err := loader.ParseYAML(res)
-- if err != nil {
-- return Stack{}, err
-- }
-- if err = schema.Validate(resparsedConfig, v1beta1.MaxComposeVersion); err != nil {
-- return Stack{}, errors.Wrapf(err, "the compose yaml file is invalid with v%s", v1beta1.MaxComposeVersion)
-- }
--
-- st.ComposeFile = string(res)
-- return st, nil
--}
--
--type stackV1Beta2Converter struct{}
--
--func (s stackV1Beta2Converter) FromCompose(stderr io.Writer, name string, cfg *composetypes.Config) (Stack, error) {
-- return fromCompose(stderr, name, cfg, v1beta2Capabilities)
--}
--
--type stackV1Alpha3Converter struct{}
--
--func (s stackV1Alpha3Converter) FromCompose(stderr io.Writer, name string, cfg *composetypes.Config) (Stack, error) {
-- return fromCompose(stderr, name, cfg, v1alpha3Capabilities)
--}
--
--func fromCompose(stderr io.Writer, name string, cfg *composetypes.Config, capabilities composeCapabilities) (Stack, error) {
-- spec, err := fromComposeConfig(stderr, cfg, capabilities)
-- if err != nil {
-- return Stack{}, err
-- }
-- return Stack{
-- Name: name,
-- Spec: spec,
-- }, nil
--}
--
--func loadStackData(composefile string) (*composetypes.Config, error) {
-- parsed, err := loader.ParseYAML([]byte(composefile))
-- if err != nil {
-- return nil, err
-- }
-- return loader.Load(composetypes.ConfigDetails{
-- ConfigFiles: []composetypes.ConfigFile{
-- {
-- Config: parsed,
-- },
-- },
-- })
--}
--
--// Conversions from internal stack to different stack compose component versions.
--func stackFromV1beta1(in *v1beta1.Stack) (Stack, error) {
-- cfg, err := loadStackData(in.Spec.ComposeFile)
-- if err != nil {
-- return Stack{}, err
-- }
-- spec, err := fromComposeConfig(ioutil.Discard, cfg, v1beta1Capabilities)
-- if err != nil {
-- return Stack{}, err
-- }
-- return Stack{
-- Name: in.ObjectMeta.Name,
-- Namespace: in.ObjectMeta.Namespace,
-- ComposeFile: in.Spec.ComposeFile,
-- Spec: spec,
-- }, nil
--}
--
--func stackToV1beta1(s Stack) *v1beta1.Stack {
-- return &v1beta1.Stack{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: s.Name,
-- },
-- Spec: v1beta1.StackSpec{
-- ComposeFile: s.ComposeFile,
-- },
-- }
--}
--
--func stackFromV1beta2(in *v1beta2.Stack) (Stack, error) {
-- var spec *latest.StackSpec
-- if in.Spec != nil {
-- spec = &latest.StackSpec{}
-- if err := latest.Convert_v1beta2_StackSpec_To_v1alpha3_StackSpec(in.Spec, spec, nil); err != nil {
-- return Stack{}, err
-- }
-- }
-- return Stack{
-- Name: in.ObjectMeta.Name,
-- Namespace: in.ObjectMeta.Namespace,
-- Spec: spec,
-- }, nil
--}
--
--func stackToV1beta2(s Stack) (*v1beta2.Stack, error) {
-- var spec *v1beta2.StackSpec
-- if s.Spec != nil {
-- spec = &v1beta2.StackSpec{}
-- if err := latest.Convert_v1alpha3_StackSpec_To_v1beta2_StackSpec(s.Spec, spec, nil); err != nil {
-- return nil, err
-- }
-- }
-- return &v1beta2.Stack{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: s.Name,
-- },
-- Spec: spec,
-- }, nil
--}
--
--func stackFromV1alpha3(in *latest.Stack) Stack {
-- return Stack{
-- Name: in.ObjectMeta.Name,
-- Namespace: in.ObjectMeta.Namespace,
-- Spec: in.Spec,
-- }
--}
--
--func stackToV1alpha3(s Stack) *latest.Stack {
-- return &latest.Stack{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: s.Name,
-- },
-- Spec: s.Spec,
-- }
--}
--
--func fromComposeConfig(stderr io.Writer, c *composeTypes.Config, capabilities composeCapabilities) (*latest.StackSpec, error) {
-- if c == nil {
-- return nil, nil
-- }
-- warnUnsupportedFeatures(stderr, c)
-- serviceConfigs := make([]latest.ServiceConfig, len(c.Services))
-- for i, s := range c.Services {
-- svc, err := fromComposeServiceConfig(s, capabilities)
-- if err != nil {
-- return nil, err
-- }
-- serviceConfigs[i] = svc
-- }
-- return &latest.StackSpec{
-- Services: serviceConfigs,
-- Secrets: fromComposeSecrets(c.Secrets),
-- Configs: fromComposeConfigs(c.Configs),
-- }, nil
--}
--
--func fromComposeSecrets(s map[string]composeTypes.SecretConfig) map[string]latest.SecretConfig {
-- if s == nil {
-- return nil
-- }
-- m := map[string]latest.SecretConfig{}
-- for key, value := range s {
-- m[key] = latest.SecretConfig{
-- Name: value.Name,
-- File: value.File,
-- External: latest.External{
-- Name: value.External.Name,
-- External: value.External.External,
-- },
-- Labels: value.Labels,
-- }
-- }
-- return m
--}
--
--func fromComposeConfigs(s map[string]composeTypes.ConfigObjConfig) map[string]latest.ConfigObjConfig {
-- if s == nil {
-- return nil
-- }
-- m := map[string]latest.ConfigObjConfig{}
-- for key, value := range s {
-- m[key] = latest.ConfigObjConfig{
-- Name: value.Name,
-- File: value.File,
-- External: latest.External{
-- Name: value.External.Name,
-- External: value.External.External,
-- },
-- Labels: value.Labels,
-- }
-- }
-- return m
--}
--
--func fromComposeServiceConfig(s composeTypes.ServiceConfig, capabilities composeCapabilities) (latest.ServiceConfig, error) {
-- var (
-- userID *int64
-- err error
-- )
-- if s.User != "" {
-- numerical, err := strconv.Atoi(s.User)
-- if err == nil {
-- unixUserID := int64(numerical)
-- userID = &unixUserID
-- }
-- }
-- kubeExtra, err := resolveServiceExtra(s)
-- if err != nil {
-- return latest.ServiceConfig{}, err
-- }
-- if kubeExtra.PullSecret != "" && !capabilities.hasPullSecrets {
-- return latest.ServiceConfig{}, errors.Errorf(`stack API version %s does not support pull secrets (field "x-kubernetes.pull_secret"), please use version v1alpha3 or higher`, capabilities.apiVersion)
-- }
-- if kubeExtra.PullPolicy != "" && !capabilities.hasPullPolicies {
-- return latest.ServiceConfig{}, errors.Errorf(`stack API version %s does not support pull policies (field "x-kubernetes.pull_policy"), please use version v1alpha3 or higher`, capabilities.apiVersion)
-- }
--
-- internalPorts, err := setupIntraStackNetworking(s, kubeExtra, capabilities)
-- if err != nil {
-- return latest.ServiceConfig{}, err
-- }
--
-- return latest.ServiceConfig{
-- Name: s.Name,
-- CapAdd: s.CapAdd,
-- CapDrop: s.CapDrop,
-- Command: s.Command,
-- Configs: fromComposeServiceConfigs(s.Configs),
-- Deploy: latest.DeployConfig{
-- Mode: s.Deploy.Mode,
-- Replicas: s.Deploy.Replicas,
-- Labels: s.Deploy.Labels,
-- UpdateConfig: fromComposeUpdateConfig(s.Deploy.UpdateConfig),
-- Resources: fromComposeResources(s.Deploy.Resources),
-- RestartPolicy: fromComposeRestartPolicy(s.Deploy.RestartPolicy),
-- Placement: fromComposePlacement(s.Deploy.Placement),
-- },
-- Entrypoint: s.Entrypoint,
-- Environment: s.Environment,
-- ExtraHosts: s.ExtraHosts,
-- Hostname: s.Hostname,
-- HealthCheck: fromComposeHealthcheck(s.HealthCheck),
-- Image: s.Image,
-- Ipc: s.Ipc,
-- Labels: s.Labels,
-- Pid: s.Pid,
-- Ports: fromComposePorts(s.Ports),
-- Privileged: s.Privileged,
-- ReadOnly: s.ReadOnly,
-- Secrets: fromComposeServiceSecrets(s.Secrets),
-- StdinOpen: s.StdinOpen,
-- StopGracePeriod: composetypes.ConvertDurationPtr(s.StopGracePeriod),
-- Tmpfs: s.Tmpfs,
-- Tty: s.Tty,
-- User: userID,
-- Volumes: fromComposeServiceVolumeConfig(s.Volumes),
-- WorkingDir: s.WorkingDir,
-- PullSecret: kubeExtra.PullSecret,
-- PullPolicy: kubeExtra.PullPolicy,
-- InternalServiceType: kubeExtra.InternalServiceType,
-- InternalPorts: internalPorts,
-- }, nil
--}
--
--func setupIntraStackNetworking(s composeTypes.ServiceConfig, kubeExtra kubernetesExtra, capabilities composeCapabilities) ([]latest.InternalPort, error) {
-- if kubeExtra.InternalServiceType != latest.InternalServiceTypeAuto && !capabilities.hasIntraStackLoadBalancing {
-- return nil,
-- errors.Errorf(`stack API version %s does not support intra-stack load balancing (field "x-kubernetes.internal_service_type"), please use version v1alpha3 or higher`,
-- capabilities.apiVersion)
-- }
-- if !capabilities.hasIntraStackLoadBalancing {
-- return nil, nil
-- }
-- if err := validateInternalServiceType(kubeExtra.InternalServiceType); err != nil {
-- return nil, err
-- }
-- internalPorts, err := toInternalPorts(s.Expose)
-- if err != nil {
-- return nil, err
-- }
-- return internalPorts, nil
--}
--
--func validateInternalServiceType(internalServiceType latest.InternalServiceType) error {
-- switch internalServiceType {
-- case latest.InternalServiceTypeAuto, latest.InternalServiceTypeClusterIP, latest.InternalServiceTypeHeadless:
-- default:
-- return errors.Errorf(`invalid value %q for field "x-kubernetes.internal_service_type", valid values are %q or %q`, internalServiceType,
-- latest.InternalServiceTypeClusterIP,
-- latest.InternalServiceTypeHeadless)
-- }
-- return nil
--}
--
--func toInternalPorts(expose []string) ([]latest.InternalPort, error) {
-- var internalPorts []latest.InternalPort
-- for _, sourcePort := range expose {
-- proto, port := nat.SplitProtoPort(sourcePort)
-- start, end, err := nat.ParsePortRange(port)
-- if err != nil {
-- return nil, errors.Errorf("invalid format for expose: %q, error: %s", sourcePort, err)
-- }
-- for i := start; i <= end; i++ {
-- k8sProto := v1.Protocol(strings.ToUpper(proto))
-- switch k8sProto {
-- case v1.ProtocolSCTP, v1.ProtocolTCP, v1.ProtocolUDP:
-- default:
-- return nil, errors.Errorf("invalid protocol for expose: %q, supported values are %q, %q and %q", sourcePort, v1.ProtocolSCTP, v1.ProtocolTCP, v1.ProtocolUDP)
-- }
-- internalPorts = append(internalPorts, latest.InternalPort{
-- Port: int32(i),
-- Protocol: k8sProto,
-- })
-- }
-- }
-- return internalPorts, nil
--}
--
--func resolveServiceExtra(s composeTypes.ServiceConfig) (kubernetesExtra, error) {
-- if iface, ok := s.Extras[kubernatesExtraField]; ok {
-- var result kubernetesExtra
-- if err := mapstructure.Decode(iface, &result); err != nil {
-- return kubernetesExtra{}, err
-- }
-- return result, nil
-- }
-- return kubernetesExtra{}, nil
--}
--
--func fromComposePorts(ports []composeTypes.ServicePortConfig) []latest.ServicePortConfig {
-- if ports == nil {
-- return nil
-- }
-- p := make([]latest.ServicePortConfig, len(ports))
-- for i, port := range ports {
-- p[i] = latest.ServicePortConfig{
-- Mode: port.Mode,
-- Target: port.Target,
-- Published: port.Published,
-- Protocol: port.Protocol,
-- }
-- }
-- return p
--}
--
--func fromComposeServiceSecrets(secrets []composeTypes.ServiceSecretConfig) []latest.ServiceSecretConfig {
-- if secrets == nil {
-- return nil
-- }
-- c := make([]latest.ServiceSecretConfig, len(secrets))
-- for i, secret := range secrets {
-- c[i] = latest.ServiceSecretConfig{
-- Source: secret.Source,
-- Target: secret.Target,
-- UID: secret.UID,
-- Mode: secret.Mode,
-- }
-- }
-- return c
--}
--
--func fromComposeServiceConfigs(configs []composeTypes.ServiceConfigObjConfig) []latest.ServiceConfigObjConfig {
-- if configs == nil {
-- return nil
-- }
-- c := make([]latest.ServiceConfigObjConfig, len(configs))
-- for i, config := range configs {
-- c[i] = latest.ServiceConfigObjConfig{
-- Source: config.Source,
-- Target: config.Target,
-- UID: config.UID,
-- Mode: config.Mode,
-- }
-- }
-- return c
--}
--
--func fromComposeHealthcheck(h *composeTypes.HealthCheckConfig) *latest.HealthCheckConfig {
-- if h == nil {
-- return nil
-- }
-- return &latest.HealthCheckConfig{
-- Test: h.Test,
-- Timeout: composetypes.ConvertDurationPtr(h.Timeout),
-- Interval: composetypes.ConvertDurationPtr(h.Interval),
-- Retries: h.Retries,
-- }
--}
--
--func fromComposePlacement(p composeTypes.Placement) latest.Placement {
-- return latest.Placement{
-- Constraints: fromComposeConstraints(p.Constraints),
-- }
--}
--
--var constraintEquals = regexp.MustCompile(`([\w\.]*)\W*(==|!=)\W*([\w\.]*)`)
--
--const (
-- swarmOs = "node.platform.os"
-- swarmArch = "node.platform.arch"
-- swarmHostname = "node.hostname"
-- swarmLabelPrefix = "node.labels."
--)
--
--func fromComposeConstraints(s []string) *latest.Constraints {
-- if len(s) == 0 {
-- return nil
-- }
-- constraints := &latest.Constraints{}
-- for _, constraint := range s {
-- matches := constraintEquals.FindStringSubmatch(constraint)
-- if len(matches) == 4 {
-- key := matches[1]
-- operator := matches[2]
-- value := matches[3]
-- constraint := &latest.Constraint{
-- Operator: operator,
-- Value: value,
-- }
-- switch {
-- case key == swarmOs:
-- constraints.OperatingSystem = constraint
-- case key == swarmArch:
-- constraints.Architecture = constraint
-- case key == swarmHostname:
-- constraints.Hostname = constraint
-- case strings.HasPrefix(key, swarmLabelPrefix):
-- if constraints.MatchLabels == nil {
-- constraints.MatchLabels = map[string]latest.Constraint{}
-- }
-- constraints.MatchLabels[strings.TrimPrefix(key, swarmLabelPrefix)] = *constraint
-- }
-- }
-- }
-- return constraints
--}
--
--func fromComposeResources(r composeTypes.Resources) latest.Resources {
-- return latest.Resources{
-- Limits: fromComposeResourcesResourceLimit(r.Limits),
-- Reservations: fromComposeResourcesResource(r.Reservations),
-- }
--}
--
--// TODO create ResourceLimit type and support for limiting Pids on k8s
--func fromComposeResourcesResourceLimit(r *composeTypes.ResourceLimit) *latest.Resource {
-- if r == nil {
-- return nil
-- }
-- return &latest.Resource{
-- MemoryBytes: int64(r.MemoryBytes),
-- NanoCPUs: r.NanoCPUs,
-- }
--}
--
--func fromComposeResourcesResource(r *composeTypes.Resource) *latest.Resource {
-- if r == nil {
-- return nil
-- }
-- return &latest.Resource{
-- MemoryBytes: int64(r.MemoryBytes),
-- NanoCPUs: r.NanoCPUs,
-- }
--}
--
--func fromComposeUpdateConfig(u *composeTypes.UpdateConfig) *latest.UpdateConfig {
-- if u == nil {
-- return nil
-- }
-- return &latest.UpdateConfig{
-- Parallelism: u.Parallelism,
-- }
--}
--
--func fromComposeRestartPolicy(r *composeTypes.RestartPolicy) *latest.RestartPolicy {
-- if r == nil {
-- return nil
-- }
-- return &latest.RestartPolicy{
-- Condition: r.Condition,
-- }
--}
--
--func fromComposeServiceVolumeConfig(vs []composeTypes.ServiceVolumeConfig) []latest.ServiceVolumeConfig {
-- if vs == nil {
-- return nil
-- }
-- volumes := []latest.ServiceVolumeConfig{}
-- for _, v := range vs {
-- volumes = append(volumes, latest.ServiceVolumeConfig{
-- Type: v.Type,
-- Source: v.Source,
-- Target: v.Target,
-- ReadOnly: v.ReadOnly,
-- })
-- }
-- return volumes
--}
--
--var (
-- v1beta1Capabilities = composeCapabilities{
-- apiVersion: "v1beta1",
-- }
-- v1beta2Capabilities = composeCapabilities{
-- apiVersion: "v1beta2",
-- }
-- v1alpha3Capabilities = composeCapabilities{
-- apiVersion: "v1alpha3",
-- hasPullSecrets: true,
-- hasPullPolicies: true,
-- hasIntraStackLoadBalancing: true,
-- }
--)
--
--type composeCapabilities struct {
-- apiVersion string
-- hasPullSecrets bool
-- hasPullPolicies bool
-- hasIntraStackLoadBalancing bool
--}
--
--type kubernetesExtra struct {
-- PullSecret string `mapstructure:"pull_secret"`
-- PullPolicy string `mapstructure:"pull_policy"`
-- InternalServiceType latest.InternalServiceType `mapstructure:"internal_service_type"`
--}
-diff --git a/cli/command/stack/kubernetes/convert_test.go b/cli/command/stack/kubernetes/convert_test.go
-deleted file mode 100644
-index aaab4eb8124..00000000000
---- a/cli/command/stack/kubernetes/convert_test.go
-+++ /dev/null
-@@ -1,349 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
-- "io/ioutil"
-- "path/filepath"
-- "testing"
--
-- "github.com/docker/cli/cli/compose/loader"
-- composetypes "github.com/docker/cli/cli/compose/types"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1alpha3"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1beta1"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1beta2"
-- "gotest.tools/v3/assert"
-- is "gotest.tools/v3/assert/cmp"
-- v1 "k8s.io/api/core/v1"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
--)
--
--func TestNewStackConverter(t *testing.T) {
-- _, err := NewStackConverter("v1alpha1")
-- assert.Check(t, is.ErrorContains(err, "stack version v1alpha1 unsupported"))
--
-- _, err = NewStackConverter("v1beta1")
-- assert.NilError(t, err)
-- _, err = NewStackConverter("v1beta2")
-- assert.NilError(t, err)
-- _, err = NewStackConverter("v1alpha3")
-- assert.NilError(t, err)
--}
--
--func TestConvertFromToV1beta1(t *testing.T) {
-- composefile := `version: "3.3"
--services:
-- test:
-- image: nginx
--secrets:
-- test:
-- file: testdata/secret
--configs:
-- test:
-- file: testdata/config
--`
-- stackv1beta1 := &v1beta1.Stack{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: "test",
-- },
-- Spec: v1beta1.StackSpec{
-- ComposeFile: composefile,
-- },
-- }
--
-- result, err := stackFromV1beta1(stackv1beta1)
-- assert.NilError(t, err)
-- expected := Stack{
-- Name: "test",
-- ComposeFile: composefile,
-- Spec: &v1alpha3.StackSpec{
-- Services: []v1alpha3.ServiceConfig{
-- {
-- Name: "test",
-- Image: "nginx",
-- Environment: make(map[string]*string),
-- },
-- },
-- Secrets: map[string]v1alpha3.SecretConfig{
-- "test": {File: filepath.FromSlash("testdata/secret")},
-- },
-- Configs: map[string]v1alpha3.ConfigObjConfig{
-- "test": {File: filepath.FromSlash("testdata/config")},
-- },
-- },
-- }
-- assert.DeepEqual(t, expected, result)
-- assert.DeepEqual(t, stackv1beta1, stackToV1beta1(result))
--}
--
--func TestConvertFromToV1beta2(t *testing.T) {
-- stackv1beta2 := &v1beta2.Stack{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: "test",
-- },
-- Spec: &v1beta2.StackSpec{
-- Services: []v1beta2.ServiceConfig{
-- {
-- Name: "test",
-- Image: "nginx",
-- Environment: make(map[string]*string),
-- },
-- },
-- Secrets: map[string]v1beta2.SecretConfig{
-- "test": {File: filepath.FromSlash("testdata/secret")},
-- },
-- Configs: map[string]v1beta2.ConfigObjConfig{
-- "test": {File: filepath.FromSlash("testdata/config")},
-- },
-- },
-- }
-- expected := Stack{
-- Name: "test",
-- Spec: &v1alpha3.StackSpec{
-- Services: []v1alpha3.ServiceConfig{
-- {
-- Name: "test",
-- Image: "nginx",
-- Environment: make(map[string]*string),
-- },
-- },
-- Secrets: map[string]v1alpha3.SecretConfig{
-- "test": {File: filepath.FromSlash("testdata/secret")},
-- },
-- Configs: map[string]v1alpha3.ConfigObjConfig{
-- "test": {File: filepath.FromSlash("testdata/config")},
-- },
-- },
-- }
-- result, err := stackFromV1beta2(stackv1beta2)
-- assert.NilError(t, err)
-- assert.DeepEqual(t, expected, result)
-- gotBack, err := stackToV1beta2(result)
-- assert.NilError(t, err)
-- assert.DeepEqual(t, stackv1beta2, gotBack)
--}
--
--func TestConvertFromToV1alpha3(t *testing.T) {
-- stackv1alpha3 := &v1alpha3.Stack{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: "test",
-- },
-- Spec: &v1alpha3.StackSpec{
-- Services: []v1alpha3.ServiceConfig{
-- {
-- Name: "test",
-- Image: "nginx",
-- Environment: make(map[string]*string),
-- },
-- },
-- Secrets: map[string]v1alpha3.SecretConfig{
-- "test": {File: filepath.FromSlash("testdata/secret")},
-- },
-- Configs: map[string]v1alpha3.ConfigObjConfig{
-- "test": {File: filepath.FromSlash("testdata/config")},
-- },
-- },
-- }
-- expected := Stack{
-- Name: "test",
-- Spec: &v1alpha3.StackSpec{
-- Services: []v1alpha3.ServiceConfig{
-- {
-- Name: "test",
-- Image: "nginx",
-- Environment: make(map[string]*string),
-- },
-- },
-- Secrets: map[string]v1alpha3.SecretConfig{
-- "test": {File: filepath.FromSlash("testdata/secret")},
-- },
-- Configs: map[string]v1alpha3.ConfigObjConfig{
-- "test": {File: filepath.FromSlash("testdata/config")},
-- },
-- },
-- }
-- result := stackFromV1alpha3(stackv1alpha3)
-- assert.DeepEqual(t, expected, result)
-- gotBack := stackToV1alpha3(result)
-- assert.DeepEqual(t, stackv1alpha3, gotBack)
--}
--
--func loadTestStackWith(t *testing.T, with string) *composetypes.Config {
-- t.Helper()
-- filePath := fmt.Sprintf("testdata/compose-with-%s.yml", with)
-- data, err := ioutil.ReadFile(filePath)
-- assert.NilError(t, err)
-- yamlData, err := loader.ParseYAML(data)
-- assert.NilError(t, err)
-- cfg, err := loader.Load(composetypes.ConfigDetails{
-- ConfigFiles: []composetypes.ConfigFile{
-- {Config: yamlData, Filename: filePath},
-- },
-- })
-- assert.NilError(t, err)
-- return cfg
--}
--
--func TestHandlePullSecret(t *testing.T) {
-- testData := loadTestStackWith(t, "pull-secret")
-- cases := []struct {
-- version string
-- err string
-- }{
-- {version: "v1beta1", err: `stack API version v1beta1 does not support pull secrets (field "x-kubernetes.pull_secret"), please use version v1alpha3 or higher`},
-- {version: "v1beta2", err: `stack API version v1beta2 does not support pull secrets (field "x-kubernetes.pull_secret"), please use version v1alpha3 or higher`},
-- {version: "v1alpha3"},
-- }
--
-- for _, c := range cases {
-- c := c
-- t.Run(c.version, func(t *testing.T) {
-- conv, err := NewStackConverter(c.version)
-- assert.NilError(t, err)
-- s, err := conv.FromCompose(ioutil.Discard, "test", testData)
-- if c.err != "" {
-- assert.Error(t, err, c.err)
--
-- } else {
-- assert.NilError(t, err)
-- assert.Equal(t, s.Spec.Services[0].PullSecret, "some-secret")
-- }
-- })
-- }
--}
--
--func TestHandlePullPolicy(t *testing.T) {
-- testData := loadTestStackWith(t, "pull-policy")
-- cases := []struct {
-- version string
-- err string
-- }{
-- {version: "v1beta1", err: `stack API version v1beta1 does not support pull policies (field "x-kubernetes.pull_policy"), please use version v1alpha3 or higher`},
-- {version: "v1beta2", err: `stack API version v1beta2 does not support pull policies (field "x-kubernetes.pull_policy"), please use version v1alpha3 or higher`},
-- {version: "v1alpha3"},
-- }
--
-- for _, c := range cases {
-- c := c
-- t.Run(c.version, func(t *testing.T) {
-- conv, err := NewStackConverter(c.version)
-- assert.NilError(t, err)
-- s, err := conv.FromCompose(ioutil.Discard, "test", testData)
-- if c.err != "" {
-- assert.Error(t, err, c.err)
--
-- } else {
-- assert.NilError(t, err)
-- assert.Equal(t, s.Spec.Services[0].PullPolicy, "Never")
-- }
-- })
-- }
--}
--
--func TestHandleInternalServiceType(t *testing.T) {
-- cases := []struct {
-- name string
-- value string
-- caps composeCapabilities
-- err string
-- expected v1alpha3.InternalServiceType
-- }{
-- {
-- name: "v1beta1",
-- value: "ClusterIP",
-- caps: v1beta1Capabilities,
-- err: `stack API version v1beta1 does not support intra-stack load balancing (field "x-kubernetes.internal_service_type"), please use version v1alpha3 or higher`,
-- },
-- {
-- name: "v1beta2",
-- value: "ClusterIP",
-- caps: v1beta2Capabilities,
-- err: `stack API version v1beta2 does not support intra-stack load balancing (field "x-kubernetes.internal_service_type"), please use version v1alpha3 or higher`,
-- },
-- {
-- name: "v1alpha3",
-- value: "ClusterIP",
-- caps: v1alpha3Capabilities,
-- expected: v1alpha3.InternalServiceTypeClusterIP,
-- },
-- {
-- name: "v1alpha3-invalid",
-- value: "invalid",
-- caps: v1alpha3Capabilities,
-- err: `invalid value "invalid" for field "x-kubernetes.internal_service_type", valid values are "ClusterIP" or "Headless"`,
-- },
-- }
-- for _, c := range cases {
-- c := c
-- t.Run(c.name, func(t *testing.T) {
-- res, err := fromComposeServiceConfig(composetypes.ServiceConfig{
-- Name: "test",
-- Image: "test",
-- Extras: map[string]interface{}{
-- "x-kubernetes": map[string]interface{}{
-- "internal_service_type": c.value,
-- },
-- },
-- }, c.caps)
-- if c.err == "" {
-- assert.NilError(t, err)
-- assert.Equal(t, res.InternalServiceType, c.expected)
-- } else {
-- assert.ErrorContains(t, err, c.err)
-- }
-- })
-- }
--}
--
--func TestIgnoreExpose(t *testing.T) {
-- testData := loadTestStackWith(t, "expose")
-- for _, version := range []string{"v1beta1", "v1beta2"} {
-- conv, err := NewStackConverter(version)
-- assert.NilError(t, err)
-- s, err := conv.FromCompose(ioutil.Discard, "test", testData)
-- assert.NilError(t, err)
-- assert.Equal(t, len(s.Spec.Services[0].InternalPorts), 0)
-- }
--}
--
--func TestParseExpose(t *testing.T) {
-- testData := loadTestStackWith(t, "expose")
-- conv, err := NewStackConverter("v1alpha3")
-- assert.NilError(t, err)
-- s, err := conv.FromCompose(ioutil.Discard, "test", testData)
-- assert.NilError(t, err)
-- expected := []v1alpha3.InternalPort{
-- {
-- Port: 1,
-- Protocol: v1.ProtocolTCP,
-- },
-- {
-- Port: 2,
-- Protocol: v1.ProtocolTCP,
-- },
-- {
-- Port: 3,
-- Protocol: v1.ProtocolTCP,
-- },
-- {
-- Port: 4,
-- Protocol: v1.ProtocolTCP,
-- },
-- {
-- Port: 5,
-- Protocol: v1.ProtocolUDP,
-- },
-- {
-- Port: 6,
-- Protocol: v1.ProtocolUDP,
-- },
-- {
-- Port: 7,
-- Protocol: v1.ProtocolUDP,
-- },
-- {
-- Port: 8,
-- Protocol: v1.ProtocolUDP,
-- },
-- }
-- assert.DeepEqual(t, s.Spec.Services[0].InternalPorts, expected)
--}
-diff --git a/cli/command/stack/kubernetes/deploy.go b/cli/command/stack/kubernetes/deploy.go
-deleted file mode 100644
-index 84fdc638c2e..00000000000
---- a/cli/command/stack/kubernetes/deploy.go
-+++ /dev/null
-@@ -1,171 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
-- "io"
--
-- "github.com/docker/cli/cli/command/stack/options"
-- composetypes "github.com/docker/cli/cli/compose/types"
-- "github.com/docker/cli/cli/streams"
-- "github.com/morikuni/aec"
-- corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
--)
--
--// RunDeploy is the kubernetes implementation of docker stack deploy
--func RunDeploy(dockerCli *KubeCli, opts options.Deploy, cfg *composetypes.Config) error {
-- cmdOut := dockerCli.Out()
--
-- // Initialize clients
-- composeClient, err := dockerCli.composeClient()
-- if err != nil {
-- return err
-- }
-- stacks, err := composeClient.Stacks(false)
-- if err != nil {
-- return err
-- }
--
-- stack, err := stacks.FromCompose(dockerCli.Err(), opts.Namespace, cfg)
-- if err != nil {
-- return err
-- }
--
-- configMaps := composeClient.ConfigMaps()
-- secrets := composeClient.Secrets()
-- services := composeClient.Services()
--
-- if err := stacks.IsColliding(services, stack); err != nil {
-- return err
-- }
--
-- if err := createResources(stack, stacks, configMaps, secrets); err != nil {
-- return err
-- }
--
-- fmt.Fprintln(cmdOut, "Waiting for the stack to be stable and running...")
-- v1beta1Cli, err := dockerCli.stacksv1beta1()
-- if err != nil {
-- return err
-- }
--
-- pods := composeClient.Pods()
-- watcher := &deployWatcher{
-- stacks: v1beta1Cli,
-- pods: pods,
-- }
-- statusUpdates := make(chan serviceStatus)
-- displayDone := make(chan struct{})
-- go func() {
-- defer close(displayDone)
-- display := newStatusDisplay(dockerCli.Out())
-- for status := range statusUpdates {
-- display.OnStatus(status)
-- }
-- }()
--
-- err = watcher.Watch(stack.Name, stack.getServices(), statusUpdates)
-- close(statusUpdates)
-- <-displayDone
-- if err != nil {
-- return err
-- }
-- fmt.Fprintf(cmdOut, "\nStack %s is stable and running\n\n", stack.Name)
-- return nil
--
--}
--
--func createResources(stack Stack, stacks StackClient, configMaps corev1.ConfigMapInterface, secrets corev1.SecretInterface) error {
-- var childResources []childResource
--
-- cr, err := stack.createFileBasedConfigMaps(configMaps)
-- childResources = append(childResources, cr...) // make sure we collect childresources already created in case of failure
-- if err != nil {
-- deleteChildResources(childResources)
-- return err
-- }
--
-- cr, err = stack.createFileBasedSecrets(secrets)
-- childResources = append(childResources, cr...) // make sure we collect childresources already created in case of failure
-- if err != nil {
-- deleteChildResources(childResources)
-- return err
-- }
--
-- return stacks.CreateOrUpdate(stack, childResources)
--}
--
--type statusDisplay interface {
-- OnStatus(serviceStatus)
--}
--type metaServiceState string
--
--const (
-- metaServiceStateReady = metaServiceState("Ready")
-- metaServiceStatePending = metaServiceState("Pending")
-- metaServiceStateFailed = metaServiceState("Failed")
--)
--
--func metaStateFromStatus(status serviceStatus) metaServiceState {
-- switch {
-- case status.podsReady > 0:
-- return metaServiceStateReady
-- case status.podsPending > 0:
-- return metaServiceStatePending
-- default:
-- return metaServiceStateFailed
-- }
--}
--
--type forwardOnlyStatusDisplay struct {
-- o *streams.Out
-- states map[string]metaServiceState
--}
--
--func (d *forwardOnlyStatusDisplay) OnStatus(status serviceStatus) {
-- state := metaStateFromStatus(status)
-- if d.states[status.name] != state {
-- d.states[status.name] = state
-- fmt.Fprintf(d.o, "%s: %s\n", status.name, state)
-- }
--}
--
--type interactiveStatusDisplay struct {
-- o *streams.Out
-- statuses []serviceStatus
--}
--
--func (d *interactiveStatusDisplay) OnStatus(status serviceStatus) {
-- b := aec.EmptyBuilder
-- for ix := 0; ix < len(d.statuses); ix++ {
-- b = b.Up(1).EraseLine(aec.EraseModes.All)
-- }
-- b = b.Column(0)
-- fmt.Fprint(d.o, b.ANSI)
-- updated := false
-- for ix, s := range d.statuses {
-- if s.name == status.name {
-- d.statuses[ix] = status
-- s = status
-- updated = true
-- }
-- displayInteractiveServiceStatus(s, d.o)
-- }
-- if !updated {
-- d.statuses = append(d.statuses, status)
-- displayInteractiveServiceStatus(status, d.o)
-- }
--}
--
--func displayInteractiveServiceStatus(status serviceStatus, o io.Writer) {
-- state := metaStateFromStatus(status)
-- totalFailed := status.podsFailed + status.podsSucceeded + status.podsUnknown
-- fmt.Fprintf(o, "%[1]s: %[2]s\t\t[pod status: %[3]d/%[6]d ready, %[4]d/%[6]d pending, %[5]d/%[6]d failed]\n", status.name, state,
-- status.podsReady, status.podsPending, totalFailed, status.podsTotal)
--}
--
--func newStatusDisplay(o *streams.Out) statusDisplay {
-- if !o.IsTerminal() {
-- return &forwardOnlyStatusDisplay{o: o, states: map[string]metaServiceState{}}
-- }
-- return &interactiveStatusDisplay{o: o}
--}
-diff --git a/cli/command/stack/kubernetes/deploy_test.go b/cli/command/stack/kubernetes/deploy_test.go
-deleted file mode 100644
-index cee1089cc9e..00000000000
---- a/cli/command/stack/kubernetes/deploy_test.go
-+++ /dev/null
-@@ -1,299 +0,0 @@
--package kubernetes
--
--import (
-- "errors"
-- "testing"
--
-- composev1alpha3 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compos..."
-- composev1beta1 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compos..."
-- composev1beta2 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compos..."
-- "github.com/docker/compose-on-kubernetes/api/compose/v1alpha3"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1beta1"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1beta2"
-- "gotest.tools/v3/assert"
-- kerrors "k8s.io/apimachinery/pkg/api/errors"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- types "k8s.io/apimachinery/pkg/types"
-- watch "k8s.io/apimachinery/pkg/watch"
-- "k8s.io/client-go/kubernetes/fake"
--)
--
--func testStack() Stack {
-- return Stack{
-- Name: "test",
-- Namespace: "test",
-- ComposeFile: `version: "3.3"
--services:
-- test:
-- image: nginx
--secrets:
-- test:
-- file: testdata/secret
--configs:
-- test:
-- file: testdata/config
--`,
-- Spec: &v1alpha3.StackSpec{
-- Configs: map[string]v1alpha3.ConfigObjConfig{
-- "test": {Name: "test", File: "testdata/config"},
-- },
-- Secrets: map[string]v1alpha3.SecretConfig{
-- "test": {Name: "test", File: "testdata/secret"},
-- },
-- },
-- }
--}
--
--func TestCreateChildResourcesV1Beta1(t *testing.T) {
-- k8sclientSet := fake.NewSimpleClientset()
-- stack := testStack()
-- configs := k8sclientSet.CoreV1().ConfigMaps("test")
-- secrets := k8sclientSet.CoreV1().Secrets("test")
-- assert.NilError(t, createResources(
-- stack,
-- &stackV1Beta1{stacks: &fakeV1beta1Client{}},
-- configs,
-- secrets))
-- c, err := configs.Get("test", metav1.GetOptions{})
-- assert.NilError(t, err)
-- checkOwnerReferences(t, c.ObjectMeta, v1beta1.SchemeGroupVersion.String())
-- s, err := secrets.Get("test", metav1.GetOptions{})
-- assert.NilError(t, err)
-- checkOwnerReferences(t, s.ObjectMeta, v1beta1.SchemeGroupVersion.String())
--}
--
--func checkOwnerReferences(t *testing.T, objMeta metav1.ObjectMeta, stackVersion string) {
-- t.Helper()
-- assert.Equal(t, len(objMeta.OwnerReferences), 1)
-- assert.Equal(t, objMeta.OwnerReferences[0].Name, "test")
-- assert.Equal(t, objMeta.OwnerReferences[0].Kind, "Stack")
-- assert.Equal(t, objMeta.OwnerReferences[0].APIVersion, stackVersion)
--}
--
--func TestCreateChildResourcesV1Beta2(t *testing.T) {
-- k8sclientSet := fake.NewSimpleClientset()
-- stack := testStack()
-- configs := k8sclientSet.CoreV1().ConfigMaps("test")
-- secrets := k8sclientSet.CoreV1().Secrets("test")
-- assert.NilError(t, createResources(
-- stack,
-- &stackV1Beta2{stacks: &fakeV1beta2Client{}},
-- configs,
-- secrets))
-- c, err := configs.Get("test", metav1.GetOptions{})
-- assert.NilError(t, err)
-- checkOwnerReferences(t, c.ObjectMeta, v1beta2.SchemeGroupVersion.String())
-- s, err := secrets.Get("test", metav1.GetOptions{})
-- assert.NilError(t, err)
-- checkOwnerReferences(t, s.ObjectMeta, v1beta2.SchemeGroupVersion.String())
--}
--
--func TestCreateChildResourcesV1Alpha3(t *testing.T) {
-- k8sclientSet := fake.NewSimpleClientset()
-- stack := testStack()
-- configs := k8sclientSet.CoreV1().ConfigMaps("test")
-- secrets := k8sclientSet.CoreV1().Secrets("test")
-- assert.NilError(t, createResources(
-- stack,
-- &stackV1Alpha3{stacks: &fakeV1alpha3Client{}},
-- configs,
-- secrets))
-- c, err := configs.Get("test", metav1.GetOptions{})
-- assert.NilError(t, err)
-- checkOwnerReferences(t, c.ObjectMeta, v1alpha3.SchemeGroupVersion.String())
-- s, err := secrets.Get("test", metav1.GetOptions{})
-- assert.NilError(t, err)
-- checkOwnerReferences(t, s.ObjectMeta, v1alpha3.SchemeGroupVersion.String())
--}
--
--func TestCreateChildResourcesWithStackCreationErrorV1Beta1(t *testing.T) {
-- k8sclientSet := fake.NewSimpleClientset()
-- stack := testStack()
-- configs := k8sclientSet.CoreV1().ConfigMaps("test")
-- secrets := k8sclientSet.CoreV1().Secrets("test")
-- err := createResources(
-- stack,
-- &stackV1Beta1{stacks: &fakeV1beta1Client{errorOnCreate: true}},
-- configs,
-- secrets)
-- assert.Error(t, err, "some error")
-- _, err = configs.Get("test", metav1.GetOptions{})
-- assert.Check(t, kerrors.IsNotFound(err))
-- _, err = secrets.Get("test", metav1.GetOptions{})
-- assert.Check(t, kerrors.IsNotFound(err))
--}
--
--func TestCreateChildResourcesWithStackCreationErrorV1Beta2(t *testing.T) {
-- k8sclientSet := fake.NewSimpleClientset()
-- stack := testStack()
-- configs := k8sclientSet.CoreV1().ConfigMaps("test")
-- secrets := k8sclientSet.CoreV1().Secrets("test")
-- err := createResources(
-- stack,
-- &stackV1Beta2{stacks: &fakeV1beta2Client{errorOnCreate: true}},
-- configs,
-- secrets)
-- assert.Error(t, err, "some error")
-- _, err = configs.Get("test", metav1.GetOptions{})
-- assert.Check(t, kerrors.IsNotFound(err))
-- _, err = secrets.Get("test", metav1.GetOptions{})
-- assert.Check(t, kerrors.IsNotFound(err))
--}
--
--func TestCreateChildResourcesWithStackCreationErrorV1Alpha3(t *testing.T) {
-- k8sclientSet := fake.NewSimpleClientset()
-- stack := testStack()
-- configs := k8sclientSet.CoreV1().ConfigMaps("test")
-- secrets := k8sclientSet.CoreV1().Secrets("test")
-- err := createResources(
-- stack,
-- &stackV1Alpha3{stacks: &fakeV1alpha3Client{errorOnCreate: true}},
-- configs,
-- secrets)
-- assert.Error(t, err, "some error")
-- _, err = configs.Get("test", metav1.GetOptions{})
-- assert.Check(t, kerrors.IsNotFound(err))
-- _, err = secrets.Get("test", metav1.GetOptions{})
-- assert.Check(t, kerrors.IsNotFound(err))
--}
--
--type fakeV1beta1Client struct {
-- errorOnCreate bool
--}
--
--func (c *fakeV1beta1Client) Create(s *v1beta1.Stack) (*v1beta1.Stack, error) {
-- if c.errorOnCreate {
-- return nil, errors.New("some error")
-- }
-- return s, nil
--}
--
--func (c *fakeV1beta1Client) Update(*v1beta1.Stack) (*v1beta1.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta1Client) UpdateStatus(*v1beta1.Stack) (*v1beta1.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta1Client) Delete(name string, options *metav1.DeleteOptions) error {
-- return nil
--}
--
--func (c *fakeV1beta1Client) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
-- return nil
--}
--
--func (c *fakeV1beta1Client) Get(name string, options metav1.GetOptions) (*v1beta1.Stack, error) {
-- return nil, kerrors.NewNotFound(v1beta1.SchemeGroupVersion.WithResource("stacks").GroupResource(), name)
--}
--
--func (c *fakeV1beta1Client) List(opts metav1.ListOptions) (*v1beta1.StackList, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta1Client) Watch(opts metav1.ListOptions) (watch.Interface, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta1Client) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*v1beta1.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta1Client) WithSkipValidation() composev1beta1.StackInterface {
-- return c
--}
--
--type fakeV1beta2Client struct {
-- errorOnCreate bool
--}
--
--func (c *fakeV1beta2Client) Create(s *v1beta2.Stack) (*v1beta2.Stack, error) {
-- if c.errorOnCreate {
-- return nil, errors.New("some error")
-- }
-- return s, nil
--}
--
--func (c *fakeV1beta2Client) Update(*v1beta2.Stack) (*v1beta2.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta2Client) UpdateStatus(*v1beta2.Stack) (*v1beta2.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta2Client) Delete(name string, options *metav1.DeleteOptions) error {
-- return nil
--}
--
--func (c *fakeV1beta2Client) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
-- return nil
--}
--
--func (c *fakeV1beta2Client) Get(name string, options metav1.GetOptions) (*v1beta2.Stack, error) {
-- return nil, kerrors.NewNotFound(v1beta1.SchemeGroupVersion.WithResource("stacks").GroupResource(), name)
--}
--
--func (c *fakeV1beta2Client) List(opts metav1.ListOptions) (*v1beta2.StackList, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta2Client) Watch(opts metav1.ListOptions) (watch.Interface, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta2Client) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*v1beta2.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1beta2Client) WithSkipValidation() composev1beta2.StackInterface {
-- return c
--}
--
--type fakeV1alpha3Client struct {
-- errorOnCreate bool
--}
--
--func (c *fakeV1alpha3Client) Create(s *v1alpha3.Stack) (*v1alpha3.Stack, error) {
-- if c.errorOnCreate {
-- return nil, errors.New("some error")
-- }
-- return s, nil
--}
--
--func (c *fakeV1alpha3Client) Update(*v1alpha3.Stack) (*v1alpha3.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1alpha3Client) UpdateStatus(*v1alpha3.Stack) (*v1alpha3.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1alpha3Client) Delete(name string, options *metav1.DeleteOptions) error {
-- return nil
--}
--
--func (c *fakeV1alpha3Client) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
-- return nil
--}
--
--func (c *fakeV1alpha3Client) Get(name string, options metav1.GetOptions) (*v1alpha3.Stack, error) {
-- return nil, kerrors.NewNotFound(v1beta1.SchemeGroupVersion.WithResource("stacks").GroupResource(), name)
--}
--
--func (c *fakeV1alpha3Client) List(opts metav1.ListOptions) (*v1alpha3.StackList, error) {
-- return nil, nil
--}
--
--func (c *fakeV1alpha3Client) Watch(opts metav1.ListOptions) (watch.Interface, error) {
-- return nil, nil
--}
--
--func (c *fakeV1alpha3Client) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*v1alpha3.Stack, error) {
-- return nil, nil
--}
--
--func (c *fakeV1alpha3Client) WithSkipValidation() composev1alpha3.StackInterface {
-- return c
--}
-diff --git a/cli/command/stack/kubernetes/list.go b/cli/command/stack/kubernetes/list.go
-deleted file mode 100644
-index facd401bb99..00000000000
---- a/cli/command/stack/kubernetes/list.go
-+++ /dev/null
-@@ -1,136 +0,0 @@
--package kubernetes
--
--import (
-- "encoding/json"
-- "fmt"
-- "io/ioutil"
-- "net/http"
-- "net/url"
--
-- "github.com/docker/cli/cli/command"
-- "github.com/docker/cli/cli/command/stack/formatter"
-- "github.com/docker/cli/cli/command/stack/options"
-- "github.com/docker/cli/cli/config/configfile"
-- "github.com/pkg/errors"
-- core_v1 "k8s.io/api/core/v1"
-- apierrs "k8s.io/apimachinery/pkg/api/errors"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
--)
--
--// GetStacks lists the kubernetes stacks
--func GetStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
-- if opts.AllNamespaces || len(opts.Namespaces) == 0 {
-- if isAllNamespacesDisabled(kubeCli.ConfigFile().Kubernetes) {
-- opts.AllNamespaces = true
-- }
-- return getStacksWithAllNamespaces(kubeCli, opts)
-- }
-- return getStacksWithNamespaces(kubeCli, opts, removeDuplicates(opts.Namespaces))
--}
--
--func isAllNamespacesDisabled(kubeCliConfig *configfile.KubernetesConfig) bool {
-- return kubeCliConfig == nil || kubeCliConfig.AllNamespaces != "disabled"
--}
--
--func getStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
-- composeClient, err := kubeCli.composeClient()
-- if err != nil {
-- return nil, err
-- }
-- stackSvc, err := composeClient.Stacks(opts.AllNamespaces)
-- if err != nil {
-- return nil, err
-- }
-- stacks, err := stackSvc.List(metav1.ListOptions{})
-- if err != nil {
-- return nil, err
-- }
-- var formattedStacks []*formatter.Stack
-- for _, stack := range stacks {
-- formattedStacks = append(formattedStacks, &formatter.Stack{
-- Name: stack.Name,
-- Services: len(stack.getServices()),
-- Orchestrator: "Kubernetes",
-- Namespace: stack.Namespace,
-- })
-- }
-- return formattedStacks, nil
--}
--
--func getStacksWithAllNamespaces(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
-- stacks, err := getStacks(kubeCli, opts)
-- if !apierrs.IsForbidden(err) {
-- return stacks, err
-- }
-- namespaces, err2 := getUserVisibleNamespaces(*kubeCli)
-- if err2 != nil {
-- return nil, errors.Wrap(err2, "failed to query user visible namespaces")
-- }
-- if namespaces == nil {
-- // UCP API not present, fall back to Kubernetes error
-- return nil, err
-- }
-- opts.AllNamespaces = false
-- return getStacksWithNamespaces(kubeCli, opts, namespaces)
--}
--
--func getUserVisibleNamespaces(dockerCli command.Cli) ([]string, error) {
-- host := dockerCli.Client().DaemonHost()
-- endpoint, err := url.Parse(host)
-- if err != nil {
-- return nil, err
-- }
-- endpoint.Scheme = "https"
-- endpoint.Path = "/kubernetesNamespaces"
-- resp, err := dockerCli.Client().HTTPClient().Get(endpoint.String())
-- if err != nil {
-- return nil, err
-- }
-- defer resp.Body.Close()
-- body, err := ioutil.ReadAll(resp.Body)
-- if err != nil {
-- return nil, errors.Wrapf(err, "received %d status and unable to read response", resp.StatusCode)
-- }
-- switch resp.StatusCode {
-- case http.StatusOK:
-- nms := &core_v1.NamespaceList{}
-- if err := json.Unmarshal(body, nms); err != nil {
-- return nil, errors.Wrapf(err, "unmarshal failed: %s", string(body))
-- }
-- namespaces := make([]string, len(nms.Items))
-- for i, namespace := range nms.Items {
-- namespaces[i] = namespace.Name
-- }
-- return namespaces, nil
-- case http.StatusNotFound:
-- // UCP API not present
-- return nil, nil
-- default:
-- return nil, fmt.Errorf("received %d status while retrieving namespaces: %s", resp.StatusCode, string(body))
-- }
--}
--
--func getStacksWithNamespaces(kubeCli *KubeCli, opts options.List, namespaces []string) ([]*formatter.Stack, error) {
-- stacks := []*formatter.Stack{}
-- for _, namespace := range namespaces {
-- kubeCli.kubeNamespace = namespace
-- ss, err := getStacks(kubeCli, opts)
-- if err != nil {
-- return nil, err
-- }
-- stacks = append(stacks, ss...)
-- }
-- return stacks, nil
--}
--
--func removeDuplicates(namespaces []string) []string {
-- found := make(map[string]bool)
-- results := namespaces[:0]
-- for _, n := range namespaces {
-- if !found[n] {
-- results = append(results, n)
-- found[n] = true
-- }
-- }
-- return results
--}
-diff --git a/cli/command/stack/kubernetes/ps.go b/cli/command/stack/kubernetes/ps.go
-deleted file mode 100644
-index c8a0600d649..00000000000
---- a/cli/command/stack/kubernetes/ps.go
-+++ /dev/null
-@@ -1,112 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
-- "sort"
--
-- "github.com/docker/cli/cli/command"
-- "github.com/docker/cli/cli/command/stack/formatter"
-- "github.com/docker/cli/cli/command/stack/options"
-- "github.com/docker/cli/cli/command/task"
-- "github.com/docker/docker/api/types/swarm"
-- apiv1 "k8s.io/api/core/v1"
-- apierrs "k8s.io/apimachinery/pkg/api/errors"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
--)
--
--var supportedPSFilters = map[string]bool{
-- "name": true,
-- "service": true,
-- "node": true,
--}
--
--// RunPS is the kubernetes implementation of docker stack ps
--func RunPS(dockerCli *KubeCli, options options.PS) error {
-- filters := options.Filter.Value()
-- if err := filters.Validate(supportedPSFilters); err != nil {
-- return err
-- }
-- client, err := dockerCli.composeClient()
-- if err != nil {
-- return err
-- }
-- stacks, err := client.Stacks(false)
-- if err != nil {
-- return err
-- }
-- stackName := options.Namespace
-- _, err = stacks.Get(stackName)
-- if apierrs.IsNotFound(err) {
-- return fmt.Errorf("nothing found in stack: %s", stackName)
-- }
-- if err != nil {
-- return err
-- }
-- pods, err := fetchPods(stackName, client.Pods(), filters)
-- if err != nil {
-- return err
-- }
-- if len(pods) == 0 {
-- return fmt.Errorf("nothing found in stack: %s", stackName)
-- }
-- return printTasks(dockerCli, options, stackName, client, pods)
--}
--
--func printTasks(dockerCli command.Cli, options options.PS, namespace string, client corev1.NodesGetter, pods []apiv1.Pod) error {
-- format := options.Format
-- if format == "" {
-- format = task.DefaultFormat(dockerCli.ConfigFile(), options.Quiet)
-- }
--
-- tasks := make([]swarm.Task, len(pods))
-- for i, pod := range pods {
-- tasks[i] = podToTask(pod)
-- }
-- sort.Stable(tasksBySlot(tasks))
--
-- names := map[string]string{}
-- nodes := map[string]string{}
--
-- n, err := listNodes(client, options.NoResolve)
-- if err != nil {
-- return err
-- }
-- for i, task := range tasks {
-- nodeValue, err := resolveNode(pods[i].Spec.NodeName, n, options.NoResolve)
-- if err != nil {
-- return err
-- }
-- names[task.ID] = fmt.Sprintf("%s_%s", namespace, pods[i].Name)
-- nodes[task.ID] = nodeValue
-- }
--
-- tasksCtx := formatter.Context{
-- Output: dockerCli.Out(),
-- Format: task.NewTaskFormat(format, options.Quiet),
-- Trunc: !options.NoTrunc,
-- }
--
-- return task.FormatWrite(tasksCtx, tasks, names, nodes)
--}
--
--func resolveNode(name string, nodes *apiv1.NodeList, noResolve bool) (string, error) {
-- // Here we have a name and we need to resolve its identifier. To mimic swarm behavior
-- // we need to resolve to the id when noResolve is set, otherwise we return the name.
-- if noResolve {
-- for _, node := range nodes.Items {
-- if node.Name == name {
-- return string(node.UID), nil
-- }
-- }
-- return "", fmt.Errorf("could not find node '%s'", name)
-- }
-- return name, nil
--}
--
--func listNodes(client corev1.NodesGetter, noResolve bool) (*apiv1.NodeList, error) {
-- if noResolve {
-- return client.Nodes().List(metav1.ListOptions{})
-- }
-- return nil, nil
--}
-diff --git a/cli/command/stack/kubernetes/remove.go b/cli/command/stack/kubernetes/remove.go
-deleted file mode 100644
-index 311c7597af6..00000000000
---- a/cli/command/stack/kubernetes/remove.go
-+++ /dev/null
-@@ -1,27 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
--
-- "github.com/docker/cli/cli/command/stack/options"
-- "github.com/pkg/errors"
--)
--
--// RunRemove is the kubernetes implementation of docker stack remove
--func RunRemove(dockerCli *KubeCli, opts options.Remove) error {
-- composeClient, err := dockerCli.composeClient()
-- if err != nil {
-- return err
-- }
-- stacks, err := composeClient.Stacks(false)
-- if err != nil {
-- return err
-- }
-- for _, stack := range opts.Namespaces {
-- fmt.Fprintf(dockerCli.Out(), "Removing stack: %s\n", stack)
-- if err := stacks.Delete(stack); err != nil {
-- return errors.Wrapf(err, "Failed to remove stack %s", stack)
-- }
-- }
-- return nil
--}
-diff --git a/cli/command/stack/kubernetes/services.go b/cli/command/stack/kubernetes/services.go
-deleted file mode 100644
-index 3a3bb63c34d..00000000000
---- a/cli/command/stack/kubernetes/services.go
-+++ /dev/null
-@@ -1,140 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
-- "strings"
--
-- "github.com/docker/cli/cli/command/stack/options"
-- "github.com/docker/compose-on-kubernetes/api/labels"
-- "github.com/docker/docker/api/types/filters"
-- "github.com/docker/docker/api/types/swarm"
-- appsv1beta2 "k8s.io/api/apps/v1beta2"
-- corev1 "k8s.io/api/core/v1"
-- apierrs "k8s.io/apimachinery/pkg/api/errors"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
--)
--
--var supportedServicesFilters = map[string]bool{
-- "mode": true,
-- "name": true,
-- "label": true,
--}
--
--func generateSelector(labels map[string][]string) []string {
-- var result []string
-- for k, v := range labels {
-- for _, val := range v {
-- result = append(result, fmt.Sprintf("%s=%s", k, val))
-- }
-- if len(v) == 0 {
-- result = append(result, k)
-- }
-- }
-- return result
--}
--
--func parseLabelFilters(rawFilters []string) map[string][]string {
-- labels := map[string][]string{}
-- for _, rawLabel := range rawFilters {
-- v := strings.SplitN(rawLabel, "=", 2)
-- key := v[0]
-- if len(v) > 1 {
-- labels[key] = append(labels[key], v[1])
-- } else if _, ok := labels[key]; !ok {
-- labels[key] = []string{}
-- }
-- }
-- return labels
--}
--
--func generateLabelSelector(f filters.Args, stackName string) string {
-- selectors := append(generateSelector(parseLabelFilters(f.Get("label"))), labels.SelectorForStack(stackName))
-- return strings.Join(selectors, ",")
--}
--
--func getResourcesForServiceList(dockerCli *KubeCli, filters filters.Args, labelSelector string) (*appsv1beta2.ReplicaSetList, *appsv1beta2.DaemonSetList, *corev1.ServiceList, error) {
-- client, err := dockerCli.composeClient()
-- if err != nil {
-- return nil, nil, nil, err
-- }
-- modes := filters.Get("mode")
-- replicas := &appsv1beta2.ReplicaSetList{}
-- if len(modes) == 0 || filters.ExactMatch("mode", "replicated") {
-- if replicas, err = client.ReplicaSets().List(metav1.ListOptions{LabelSelector: labelSelector}); err != nil {
-- return nil, nil, nil, err
-- }
-- }
-- daemons := &appsv1beta2.DaemonSetList{}
-- if len(modes) == 0 || filters.ExactMatch("mode", "global") {
-- if daemons, err = client.DaemonSets().List(metav1.ListOptions{LabelSelector: labelSelector}); err != nil {
-- return nil, nil, nil, err
-- }
-- }
-- services, err := client.Services().List(metav1.ListOptions{LabelSelector: labelSelector})
-- if err != nil {
-- return nil, nil, nil, err
-- }
-- return replicas, daemons, services, nil
--}
--
--// GetServices is the kubernetes implementation of listing stack services
--func GetServices(dockerCli *KubeCli, opts options.Services) ([]swarm.Service, error) {
-- filters := opts.Filter.Value()
-- if err := filters.Validate(supportedServicesFilters); err != nil {
-- return nil, err
-- }
-- client, err := dockerCli.composeClient()
-- if err != nil {
-- return nil, err
-- }
-- stacks, err := client.Stacks(false)
-- if err != nil {
-- return nil, err
-- }
-- stackName := opts.Namespace
-- _, err = stacks.Get(stackName)
-- if apierrs.IsNotFound(err) {
-- return []swarm.Service{}, nil
-- }
-- if err != nil {
-- return nil, err
-- }
--
-- labelSelector := generateLabelSelector(filters, stackName)
-- replicasList, daemonsList, servicesList, err := getResourcesForServiceList(dockerCli, filters, labelSelector)
-- if err != nil {
-- return nil, err
-- }
--
-- // Convert Replicas sets and kubernetes services to swarm services and formatter information
-- services, err := convertToServices(replicasList, daemonsList, servicesList)
-- if err != nil {
-- return nil, err
-- }
-- services = filterServicesByName(services, filters.Get("name"), stackName)
--
-- return services, nil
--}
--
--func filterServicesByName(services []swarm.Service, names []string, stackName string) []swarm.Service {
-- if len(names) == 0 {
-- return services
-- }
-- prefix := stackName + "_"
-- // Accepts unprefixed service name (for compatibility with existing swarm scripts where service names are prefixed by stack names)
-- for i, n := range names {
-- if !strings.HasPrefix(n, prefix) {
-- names[i] = stackName + "_" + n
-- }
-- }
-- // Filter services
-- result := []swarm.Service{}
-- for _, s := range services {
-- for _, n := range names {
-- if strings.HasPrefix(s.Spec.Name, n) {
-- result = append(result, s)
-- }
-- }
-- }
-- return result
--}
-diff --git a/cli/command/stack/kubernetes/services_test.go b/cli/command/stack/kubernetes/services_test.go
-deleted file mode 100644
-index 14337ab8e4b..00000000000
---- a/cli/command/stack/kubernetes/services_test.go
-+++ /dev/null
-@@ -1,138 +0,0 @@
--package kubernetes
--
--import (
-- "testing"
--
-- "github.com/docker/docker/api/types/filters"
-- "github.com/docker/docker/api/types/swarm"
-- "gotest.tools/v3/assert"
-- "gotest.tools/v3/assert/cmp"
--)
--
--func TestServiceFiltersLabelSelectorGen(t *testing.T) {
-- cases := []struct {
-- name string
-- stackName string
-- filters filters.Args
-- expectedSelectorParts []string
-- }{
-- {
-- name: "no-filter",
-- stackName: "test",
-- filters: filters.NewArgs(),
-- expectedSelectorParts: []string{
-- "com.docker.stack.namespace=test",
-- },
-- },
-- {
-- name: "label present filter",
-- stackName: "test",
-- filters: filters.NewArgs(
-- filters.KeyValuePair{Key: "label", Value: "label-is-present"},
-- ),
-- expectedSelectorParts: []string{
-- "com.docker.stack.namespace=test",
-- "label-is-present",
-- },
-- },
-- {
-- name: "single value label filter",
-- stackName: "test",
-- filters: filters.NewArgs(
-- filters.KeyValuePair{Key: "label", Value: "label1=test"},
-- ),
-- expectedSelectorParts: []string{
-- "com.docker.stack.namespace=test",
-- "label1=test",
-- },
-- },
-- {
-- name: "multi value label filter",
-- stackName: "test",
-- filters: filters.NewArgs(
-- filters.KeyValuePair{Key: "label", Value: "label1=test"},
-- filters.KeyValuePair{Key: "label", Value: "label1=test2"},
-- ),
-- expectedSelectorParts: []string{
-- "com.docker.stack.namespace=test",
-- "label1=test",
-- "label1=test2",
-- },
-- },
-- {
-- name: "2 different labels filter",
-- stackName: "test",
-- filters: filters.NewArgs(
-- filters.KeyValuePair{Key: "label", Value: "label1=test"},
-- filters.KeyValuePair{Key: "label", Value: "label2=test2"},
-- ),
-- expectedSelectorParts: []string{
-- "com.docker.stack.namespace=test",
-- "label1=test",
-- "label2=test2",
-- },
-- },
-- }
--
-- for _, c := range cases {
-- t.Run(c.name, func(t *testing.T) {
-- result := generateLabelSelector(c.filters, c.stackName)
-- for _, toFind := range c.expectedSelectorParts {
-- assert.Assert(t, cmp.Contains(result, toFind))
-- }
-- })
-- }
--}
--func TestServiceFiltersServiceByName(t *testing.T) {
-- cases := []struct {
-- name string
-- filters []string
-- services []swarm.Service
-- expectedServices []swarm.Service
-- }{
-- {
-- name: "no filter",
-- filters: []string{},
-- services: makeServices("s1", "s2"),
-- expectedServices: makeServices("s1", "s2"),
-- },
-- {
-- name: "single-name filter",
-- filters: []string{"s1"},
-- services: makeServices("s1", "s2"),
-- expectedServices: makeServices("s1"),
-- },
-- {
-- name: "filter by prefix",
-- filters: []string{"prefix"},
-- services: makeServices("prefix-s1", "prefix-s2", "s2"),
-- expectedServices: makeServices("prefix-s1", "prefix-s2"),
-- },
-- {
-- name: "multi-name filter",
-- filters: []string{"s1", "s2"},
-- services: makeServices("s1", "s2", "s3"),
-- expectedServices: makeServices("s1", "s2"),
-- },
-- {
-- name: "stack name prefix is valid",
-- filters: []string{"stack_s1"},
-- services: makeServices("s1", "s11", "s2"),
-- expectedServices: makeServices("s1", "s11"),
-- },
-- }
-- for _, c := range cases {
-- t.Run(c.name, func(t *testing.T) {
-- result := filterServicesByName(c.services, c.filters, "stack")
-- assert.DeepEqual(t, c.expectedServices, result)
-- })
-- }
--}
--
--func makeServices(names ...string) []swarm.Service {
-- result := make([]swarm.Service, len(names))
-- for i, n := range names {
-- result[i] = swarm.Service{Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: "stack_" + n}}}
-- }
-- return result
--}
-diff --git a/cli/command/stack/kubernetes/stack.go b/cli/command/stack/kubernetes/stack.go
-deleted file mode 100644
-index e368d718de9..00000000000
---- a/cli/command/stack/kubernetes/stack.go
-+++ /dev/null
-@@ -1,161 +0,0 @@
--package kubernetes
--
--import (
-- "io/ioutil"
-- "path/filepath"
-- "sort"
--
-- latest "github.com/docker/compose-on-kubernetes/api/compose/v1alpha3"
-- "github.com/docker/compose-on-kubernetes/api/labels"
-- apiv1 "k8s.io/api/core/v1"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
--)
--
--// Stack is the main type used by stack commands so they remain independent from kubernetes compose component version.
--type Stack struct {
-- Name string
-- Namespace string
-- ComposeFile string
-- Spec *latest.StackSpec
--}
--
--type childResource interface {
-- setOwner(metav1.OwnerReference) error
-- delete() // does not report error, as if a deletion failed, we want to continue deleting other child resources
--}
--
--func deleteChildResources(childResources []childResource) {
-- for _, cr := range childResources {
-- cr.delete()
-- }
--}
--
--func setChildResourcesOwner(childResources []childResource, owner metav1.OwnerReference) error {
-- for _, cr := range childResources {
-- if err := cr.setOwner(owner); err != nil {
-- return err
-- }
-- }
-- return nil
--}
--
--// getServices returns all the stack service names, sorted lexicographically
--func (s *Stack) getServices() []string {
-- services := make([]string, len(s.Spec.Services))
-- for i, service := range s.Spec.Services {
-- services[i] = service.Name
-- }
-- sort.Strings(services)
-- return services
--}
--
--// createFileBasedConfigMaps creates a Kubernetes ConfigMap for each Compose global file-based config.
--func (s *Stack) createFileBasedConfigMaps(configMaps corev1.ConfigMapInterface) ([]childResource, error) {
-- var resources []childResource
-- for name, config := range s.Spec.Configs {
-- if config.File == "" {
-- continue
-- }
--
-- fileName := filepath.Base(config.File)
-- content, err := ioutil.ReadFile(config.File)
-- if err != nil {
-- return resources, err
-- }
--
-- configMap, err := configMaps.Create(toConfigMap(s.Name, name, fileName, content))
-- if err != nil {
-- return resources, err
-- }
-- resources = append(resources, &configMapChildResource{client: configMaps, configMap: configMap})
-- }
-- return resources, nil
--}
--
--type configMapChildResource struct {
-- client corev1.ConfigMapInterface
-- configMap *apiv1.ConfigMap
--}
--
--func (r *configMapChildResource) setOwner(ref metav1.OwnerReference) error {
-- r.configMap.OwnerReferences = append(r.configMap.OwnerReferences, ref)
-- _, err := r.client.Update(r.configMap)
-- return err
--}
--
--func (r *configMapChildResource) delete() {
-- r.client.Delete(r.configMap.Name, nil)
--}
--
--// toConfigMap converts a Compose Config to a Kube ConfigMap.
--func toConfigMap(stackName, name, key string, content []byte) *apiv1.ConfigMap {
-- return &apiv1.ConfigMap{
-- TypeMeta: metav1.TypeMeta{
-- Kind: "ConfigMap",
-- APIVersion: "v1",
-- },
-- ObjectMeta: metav1.ObjectMeta{
-- Name: name,
-- Labels: map[string]string{
-- labels.ForStackName: stackName,
-- },
-- },
-- Data: map[string]string{
-- key: string(content),
-- },
-- }
--}
--
--// createFileBasedSecrets creates a Kubernetes Secret for each Compose global file-based secret.
--func (s *Stack) createFileBasedSecrets(secrets corev1.SecretInterface) ([]childResource, error) {
-- var resources []childResource
-- for name, secret := range s.Spec.Secrets {
-- if secret.File == "" {
-- continue
-- }
--
-- fileName := filepath.Base(secret.File)
-- content, err := ioutil.ReadFile(secret.File)
-- if err != nil {
-- return resources, err
-- }
--
-- secret, err := secrets.Create(toSecret(s.Name, name, fileName, content))
-- if err != nil {
-- return resources, err
-- }
-- resources = append(resources, &secretChildResource{client: secrets, secret: secret})
-- }
-- return resources, nil
--}
--
--type secretChildResource struct {
-- client corev1.SecretInterface
-- secret *apiv1.Secret
--}
--
--func (r *secretChildResource) setOwner(ref metav1.OwnerReference) error {
-- r.secret.OwnerReferences = append(r.secret.OwnerReferences, ref)
-- _, err := r.client.Update(r.secret)
-- return err
--}
--
--func (r *secretChildResource) delete() {
-- r.client.Delete(r.secret.Name, nil)
--}
--
--// toSecret converts a Compose Secret to a Kube Secret.
--func toSecret(stackName, name, key string, content []byte) *apiv1.Secret {
-- return &apiv1.Secret{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: name,
-- Labels: map[string]string{
-- labels.ForStackName: stackName,
-- },
-- },
-- Data: map[string][]byte{
-- key: content,
-- },
-- }
--}
-diff --git a/cli/command/stack/kubernetes/stackclient.go b/cli/command/stack/kubernetes/stackclient.go
-deleted file mode 100644
-index 5ce4480ebb0..00000000000
---- a/cli/command/stack/kubernetes/stackclient.go
-+++ /dev/null
-@@ -1,274 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
--
-- composev1alpha3 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compos..."
-- composev1beta1 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compos..."
-- composev1beta2 "github.com/docker/compose-on-kubernetes/api/client/clientset/typed/compos..."
-- "github.com/docker/compose-on-kubernetes/api/compose/v1alpha3"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1beta1"
-- "github.com/docker/compose-on-kubernetes/api/compose/v1beta2"
-- "github.com/docker/compose-on-kubernetes/api/labels"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
-- "k8s.io/client-go/rest"
--)
--
--// StackClient talks to a kubernetes compose component.
--type StackClient interface {
-- StackConverter
-- CreateOrUpdate(s Stack, childResources []childResource) error
-- Delete(name string) error
-- Get(name string) (Stack, error)
-- List(opts metav1.ListOptions) ([]Stack, error)
-- IsColliding(servicesClient corev1.ServiceInterface, s Stack) error
--}
--
--// stackV1Beta1 implements stackClient interface and talks to compose component v1beta1.
--type stackV1Beta1 struct {
-- stackV1Beta1Converter
-- stacks composev1beta1.StackInterface
--}
--
--func newStackV1Beta1(config *rest.Config, namespace string) (*stackV1Beta1, error) {
-- client, err := composev1beta1.NewForConfig(config)
-- if err != nil {
-- return nil, err
-- }
-- return &stackV1Beta1{stacks: client.Stacks(namespace)}, nil
--}
--
--func (s *stackV1Beta1) CreateOrUpdate(internalStack Stack, childResources []childResource) error {
-- // If it already exists, update the stack
-- var (
-- stack *v1beta1.Stack
-- err error
-- )
-- if stack, err = s.stacks.Get(internalStack.Name, metav1.GetOptions{}); err == nil {
-- stack.Spec.ComposeFile = internalStack.ComposeFile
-- stack, err = s.stacks.Update(stack)
-- } else {
-- // Or create it
-- stack, err = s.stacks.Create(stackToV1beta1(internalStack))
-- }
-- if err != nil {
-- deleteChildResources(childResources)
-- return err
-- }
-- blockOwnerDeletion := true
-- isController := true
-- return setChildResourcesOwner(childResources, metav1.OwnerReference{
-- APIVersion: v1beta1.SchemeGroupVersion.String(),
-- Kind: "Stack",
-- Name: stack.Name,
-- UID: stack.UID,
-- BlockOwnerDeletion: &blockOwnerDeletion,
-- Controller: &isController,
-- })
--}
--
--func (s *stackV1Beta1) Delete(name string) error {
-- return s.stacks.Delete(name, &metav1.DeleteOptions{})
--}
--
--func (s *stackV1Beta1) Get(name string) (Stack, error) {
-- stackBeta1, err := s.stacks.Get(name, metav1.GetOptions{})
-- if err != nil {
-- return Stack{}, err
-- }
-- return stackFromV1beta1(stackBeta1)
--}
--
--func (s *stackV1Beta1) List(opts metav1.ListOptions) ([]Stack, error) {
-- list, err := s.stacks.List(opts)
-- if err != nil {
-- return nil, err
-- }
-- stacks := make([]Stack, len(list.Items))
-- for i := range list.Items {
-- stack, err := stackFromV1beta1(&list.Items[i])
-- if err != nil {
-- return nil, err
-- }
-- stacks[i] = stack
-- }
-- return stacks, nil
--}
--
--// IsColliding verifies that services defined in the stack collides with already deployed services
--func (s *stackV1Beta1) IsColliding(servicesClient corev1.ServiceInterface, st Stack) error {
-- for _, srv := range st.getServices() {
-- if err := verify(servicesClient, st.Name, srv); err != nil {
-- return err
-- }
-- }
-- return nil
--}
--
--// verify checks whether the service is already present in kubernetes.
--// If we find the service by name but it doesn't have our label or it has a different value
--// than the stack name for the label, we fail (i.e. it will collide)
--func verify(services corev1.ServiceInterface, stackName string, service string) error {
-- svc, err := services.Get(service, metav1.GetOptions{})
-- if err == nil {
-- if key, ok := svc.ObjectMeta.Labels[labels.ForStackName]; ok {
-- if key != stackName {
-- return fmt.Errorf("service %s already present in stack named %s", service, key)
-- }
-- return nil
-- }
-- return fmt.Errorf("service %s already present in the cluster", service)
-- }
-- return nil
--}
--
--// stackV1Beta2 implements stackClient interface and talks to compose component v1beta2.
--type stackV1Beta2 struct {
-- stackV1Beta2Converter
-- stacks composev1beta2.StackInterface
--}
--
--func newStackV1Beta2(config *rest.Config, namespace string) (*stackV1Beta2, error) {
-- client, err := composev1beta2.NewForConfig(config)
-- if err != nil {
-- return nil, err
-- }
-- return &stackV1Beta2{stacks: client.Stacks(namespace)}, nil
--}
--
--func (s *stackV1Beta2) CreateOrUpdate(internalStack Stack, childResources []childResource) error {
-- var (
-- stack *v1beta2.Stack
-- err error
-- )
-- resolved, err := stackToV1beta2(internalStack)
-- if err != nil {
-- deleteChildResources(childResources)
-- return err
-- }
-- if stack, err = s.stacks.Get(internalStack.Name, metav1.GetOptions{}); err == nil {
-- stack.Spec = resolved.Spec
-- stack, err = s.stacks.Update(stack)
-- } else {
-- // Or create it
-- stack, err = s.stacks.Create(resolved)
-- }
-- if err != nil {
-- deleteChildResources(childResources)
-- return err
-- }
-- blockOwnerDeletion := true
-- isController := true
-- return setChildResourcesOwner(childResources, metav1.OwnerReference{
-- APIVersion: v1beta2.SchemeGroupVersion.String(),
-- Kind: "Stack",
-- Name: stack.Name,
-- UID: stack.UID,
-- BlockOwnerDeletion: &blockOwnerDeletion,
-- Controller: &isController,
-- })
--}
--
--func (s *stackV1Beta2) Delete(name string) error {
-- return s.stacks.Delete(name, &metav1.DeleteOptions{})
--}
--
--func (s *stackV1Beta2) Get(name string) (Stack, error) {
-- stackBeta2, err := s.stacks.Get(name, metav1.GetOptions{})
-- if err != nil {
-- return Stack{}, err
-- }
-- return stackFromV1beta2(stackBeta2)
--}
--
--func (s *stackV1Beta2) List(opts metav1.ListOptions) ([]Stack, error) {
-- list, err := s.stacks.List(opts)
-- if err != nil {
-- return nil, err
-- }
-- stacks := make([]Stack, len(list.Items))
-- for i := range list.Items {
-- if stacks[i], err = stackFromV1beta2(&list.Items[i]); err != nil {
-- return nil, err
-- }
-- }
-- return stacks, nil
--}
--
--// IsColliding is handle server side with the compose api v1beta2, so nothing to do here
--func (s *stackV1Beta2) IsColliding(servicesClient corev1.ServiceInterface, st Stack) error {
-- return nil
--}
--
--// stackV1Beta2 implements stackClient interface and talks to compose component v1beta2.
--type stackV1Alpha3 struct {
-- stackV1Alpha3Converter
-- stacks composev1alpha3.StackInterface
--}
--
--func newStackV1Alpha3(config *rest.Config, namespace string) (*stackV1Alpha3, error) {
-- client, err := composev1alpha3.NewForConfig(config)
-- if err != nil {
-- return nil, err
-- }
-- return &stackV1Alpha3{stacks: client.Stacks(namespace)}, nil
--}
--
--func (s *stackV1Alpha3) CreateOrUpdate(internalStack Stack, childResources []childResource) error {
-- var (
-- stack *v1alpha3.Stack
-- err error
-- )
-- resolved := stackToV1alpha3(internalStack)
-- if stack, err = s.stacks.Get(internalStack.Name, metav1.GetOptions{}); err == nil {
-- stack.Spec = resolved.Spec
-- stack, err = s.stacks.Update(stack)
-- } else {
-- // Or create it
-- stack, err = s.stacks.Create(resolved)
-- }
-- if err != nil {
-- deleteChildResources(childResources)
-- return err
-- }
-- blockOwnerDeletion := true
-- isController := true
-- return setChildResourcesOwner(childResources, metav1.OwnerReference{
-- APIVersion: v1alpha3.SchemeGroupVersion.String(),
-- Kind: "Stack",
-- Name: stack.Name,
-- UID: stack.UID,
-- BlockOwnerDeletion: &blockOwnerDeletion,
-- Controller: &isController,
-- })
--}
--
--func (s *stackV1Alpha3) Delete(name string) error {
-- return s.stacks.Delete(name, &metav1.DeleteOptions{})
--}
--
--func (s *stackV1Alpha3) Get(name string) (Stack, error) {
-- stackAlpha3, err := s.stacks.Get(name, metav1.GetOptions{})
-- if err != nil {
-- return Stack{}, err
-- }
-- return stackFromV1alpha3(stackAlpha3), nil
--}
--
--func (s *stackV1Alpha3) List(opts metav1.ListOptions) ([]Stack, error) {
-- list, err := s.stacks.List(opts)
-- if err != nil {
-- return nil, err
-- }
-- stacks := make([]Stack, len(list.Items))
-- for i := range list.Items {
-- stacks[i] = stackFromV1alpha3(&list.Items[i])
-- }
-- return stacks, nil
--}
--
--// IsColliding is handle server side with the compose api v1beta2, so nothing to do here
--func (s *stackV1Alpha3) IsColliding(servicesClient corev1.ServiceInterface, st Stack) error {
-- return nil
--}
-diff --git a/cli/command/stack/kubernetes/stackclient_test.go b/cli/command/stack/kubernetes/stackclient_test.go
-deleted file mode 100644
-index 354d8c38977..00000000000
---- a/cli/command/stack/kubernetes/stackclient_test.go
-+++ /dev/null
-@@ -1,60 +0,0 @@
--package kubernetes
--
--import (
-- "io/ioutil"
-- "testing"
--
-- composetypes "github.com/docker/cli/cli/compose/types"
-- "gotest.tools/v3/assert"
--)
--
--func TestFromCompose(t *testing.T) {
-- stackClient := &stackV1Beta1{}
-- s, err := stackClient.FromCompose(ioutil.Discard, "foo", &composetypes.Config{
-- Version: "3.1",
-- Filename: "banana",
-- Services: []composetypes.ServiceConfig{
-- {
-- Name: "foo",
-- Image: "foo",
-- },
-- {
-- Name: "bar",
-- Image: "bar",
-- },
-- },
-- })
-- assert.NilError(t, err)
-- assert.Equal(t, "foo", s.Name)
-- assert.Equal(t, string(`version: "3.5"
--services:
-- bar:
-- image: bar
-- foo:
-- image: foo
--`), s.ComposeFile)
--}
--
--func TestFromComposeUnsupportedVersion(t *testing.T) {
-- stackClient := &stackV1Beta1{}
-- _, err := stackClient.FromCompose(ioutil.Discard, "foo", &composetypes.Config{
-- Version: "3.6",
-- Filename: "banana",
-- Services: []composetypes.ServiceConfig{
-- {
-- Name: "foo",
-- Image: "foo",
-- Volumes: []composetypes.ServiceVolumeConfig{
-- {
-- Type: "tmpfs",
-- Target: "/app",
-- Tmpfs: &composetypes.ServiceVolumeTmpfs{
-- Size: 10000,
-- },
-- },
-- },
-- },
-- },
-- })
-- assert.ErrorContains(t, err, "the compose yaml file is invalid with v3.5: services.foo.volumes.0 Additional property tmpfs is not allowed")
--}
-diff --git a/cli/command/stack/kubernetes/testdata/compose-with-expose.yml b/cli/command/stack/kubernetes/testdata/compose-with-expose.yml
-deleted file mode 100644
-index 4d0b6f7e7a2..00000000000
---- a/cli/command/stack/kubernetes/testdata/compose-with-expose.yml
-+++ /dev/null
-@@ -1,9 +0,0 @@
--version: "3.7"
--services:
-- test:
-- image: "some-image"
-- expose:
-- - "1" # default protocol, single port
-- - "2-4" # default protocol, port range
-- - "5/udp" # specific protocol, single port
-- - "6-8/udp" # specific protocol, port range
-\ No newline at end of file
-diff --git a/cli/command/stack/kubernetes/testdata/compose-with-pull-policy.yml b/cli/command/stack/kubernetes/testdata/compose-with-pull-policy.yml
-deleted file mode 100644
-index 471988f574b..00000000000
---- a/cli/command/stack/kubernetes/testdata/compose-with-pull-policy.yml
-+++ /dev/null
-@@ -1,6 +0,0 @@
--version: "3.7"
--services:
-- test:
-- image: "some-image"
-- x-kubernetes:
-- pull_policy: "Never"
-\ No newline at end of file
-diff --git a/cli/command/stack/kubernetes/testdata/compose-with-pull-secret.yml b/cli/command/stack/kubernetes/testdata/compose-with-pull-secret.yml
-deleted file mode 100644
-index 8c2653787d1..00000000000
---- a/cli/command/stack/kubernetes/testdata/compose-with-pull-secret.yml
-+++ /dev/null
-@@ -1,6 +0,0 @@
--version: "3.7"
--services:
-- test:
-- image: "some-private-image"
-- x-kubernetes:
-- pull_secret: "some-secret"
-\ No newline at end of file
-diff --git a/cli/command/stack/kubernetes/testdata/config b/cli/command/stack/kubernetes/testdata/config
-deleted file mode 100644
-index 6ce433f2998..00000000000
---- a/cli/command/stack/kubernetes/testdata/config
-+++ /dev/null
-@@ -1 +0,0 @@
--this is a config
-\ No newline at end of file
-diff --git a/cli/command/stack/kubernetes/testdata/secret b/cli/command/stack/kubernetes/testdata/secret
-deleted file mode 100644
-index 51ed8039237..00000000000
---- a/cli/command/stack/kubernetes/testdata/secret
-+++ /dev/null
-@@ -1 +0,0 @@
--this is a secret
-\ No newline at end of file
-diff --git a/cli/command/stack/kubernetes/testdata/warnings.golden b/cli/command/stack/kubernetes/testdata/warnings.golden
-deleted file mode 100644
-index 1ee14b0fc92..00000000000
---- a/cli/command/stack/kubernetes/testdata/warnings.golden
-+++ /dev/null
-@@ -1,31 +0,0 @@
--top-level network "global" is ignored
--service "front": network "private" is ignored
--service "front": update_config.delay is not supported
--service "front": update_config.failure_action is not supported
--service "front": update_config.monitor is not supported
--service "front": update_config.max_failure_ratio is not supported
--service "front": restart_policy.delay is ignored
--service "front": restart_policy.max_attempts is ignored
--service "front": restart_policy.window is ignored
--service "front": container_name is deprecated
--service "front": expose is deprecated
--service "front": build is ignored
--service "front": cgroup_parent is ignored
--service "front": devices are ignored
--service "front": domainname is ignored
--service "front": external_links are ignored
--service "front": links are ignored
--service "front": mac_address is ignored
--service "front": network_mode is ignored
--service "front": restart is ignored
--service "front": security_opt are ignored
--service "front": ulimits are ignored
--service "front": depends_on are ignored
--service "front": credential_spec is ignored
--service "front": dns are ignored
--service "front": dns_search are ignored
--service "front": env_file are ignored
--service "front": stop_signal is ignored
--service "front": logging is ignored
--service "front": volume.propagation is ignored
--service "front": volume.nocopy is ignored
-diff --git a/cli/command/stack/kubernetes/warnings.go b/cli/command/stack/kubernetes/warnings.go
-deleted file mode 100644
-index eb4598db45d..00000000000
---- a/cli/command/stack/kubernetes/warnings.go
-+++ /dev/null
-@@ -1,145 +0,0 @@
--package kubernetes
--
--import (
-- "fmt"
-- "io"
--
-- composetypes "github.com/docker/cli/cli/compose/types"
--)
--
--func warnUnsupportedFeatures(stderr io.Writer, cfg *composetypes.Config) {
-- warnForGlobalNetworks(stderr, cfg)
-- for _, s := range cfg.Services {
-- warnForServiceNetworks(stderr, s)
-- warnForUnsupportedDeploymentStrategy(stderr, s)
-- warnForUnsupportedRestartPolicy(stderr, s)
-- warnForDeprecatedProperties(stderr, s)
-- warnForUnsupportedProperties(stderr, s)
-- }
--}
--
--func warnForGlobalNetworks(stderr io.Writer, config *composetypes.Config) {
-- for network := range config.Networks {
-- fmt.Fprintf(stderr, "top-level network %q is ignored\n", network)
-- }
--}
--
--func warnServicef(stderr io.Writer, service, format string, args ...interface{}) {
-- fmt.Fprintf(stderr, "service \"%s\": %s\n", service, fmt.Sprintf(format, args...))
--}
--
--func warnForServiceNetworks(stderr io.Writer, s composetypes.ServiceConfig) {
-- for network := range s.Networks {
-- warnServicef(stderr, s.Name, "network %q is ignored", network)
-- }
--}
--
--func warnForDeprecatedProperties(stderr io.Writer, s composetypes.ServiceConfig) {
-- if s.ContainerName != "" {
-- warnServicef(stderr, s.Name, "container_name is deprecated")
-- }
-- if len(s.Expose) > 0 {
-- warnServicef(stderr, s.Name, "expose is deprecated")
-- }
--}
--
--func warnForUnsupportedDeploymentStrategy(stderr io.Writer, s composetypes.ServiceConfig) {
-- config := s.Deploy.UpdateConfig
-- if config == nil {
-- return
-- }
-- if config.Delay != 0 {
-- warnServicef(stderr, s.Name, "update_config.delay is not supported")
-- }
-- if config.FailureAction != "" {
-- warnServicef(stderr, s.Name, "update_config.failure_action is not supported")
-- }
-- if config.Monitor != 0 {
-- warnServicef(stderr, s.Name, "update_config.monitor is not supported")
-- }
-- if config.MaxFailureRatio != 0 {
-- warnServicef(stderr, s.Name, "update_config.max_failure_ratio is not supported")
-- }
--}
--
--func warnForUnsupportedRestartPolicy(stderr io.Writer, s composetypes.ServiceConfig) {
-- policy := s.Deploy.RestartPolicy
-- if policy == nil {
-- return
-- }
--
-- if policy.Delay != nil {
-- warnServicef(stderr, s.Name, "restart_policy.delay is ignored")
-- }
-- if policy.MaxAttempts != nil {
-- warnServicef(stderr, s.Name, "restart_policy.max_attempts is ignored")
-- }
-- if policy.Window != nil {
-- warnServicef(stderr, s.Name, "restart_policy.window is ignored")
-- }
--}
--
--func warnForUnsupportedProperties(stderr io.Writer, s composetypes.ServiceConfig) { // nolint: gocyclo
-- if build := s.Build; build.Context != "" || build.Dockerfile != "" || len(build.Args) > 0 || len(build.Labels) > 0 || len(build.CacheFrom) > 0 || build.Network != "" || build.Target != "" {
-- warnServicef(stderr, s.Name, "build is ignored")
-- }
-- if s.CgroupParent != "" {
-- warnServicef(stderr, s.Name, "cgroup_parent is ignored")
-- }
-- if len(s.Devices) > 0 {
-- warnServicef(stderr, s.Name, "devices are ignored")
-- }
-- if s.DomainName != "" {
-- warnServicef(stderr, s.Name, "domainname is ignored")
-- }
-- if len(s.ExternalLinks) > 0 {
-- warnServicef(stderr, s.Name, "external_links are ignored")
-- }
-- if len(s.Links) > 0 {
-- warnServicef(stderr, s.Name, "links are ignored")
-- }
-- if s.MacAddress != "" {
-- warnServicef(stderr, s.Name, "mac_address is ignored")
-- }
-- if s.NetworkMode != "" {
-- warnServicef(stderr, s.Name, "network_mode is ignored")
-- }
-- if s.Restart != "" {
-- warnServicef(stderr, s.Name, "restart is ignored")
-- }
-- if len(s.SecurityOpt) > 0 {
-- warnServicef(stderr, s.Name, "security_opt are ignored")
-- }
-- if len(s.Ulimits) > 0 {
-- warnServicef(stderr, s.Name, "ulimits are ignored")
-- }
-- if len(s.DependsOn) > 0 {
-- warnServicef(stderr, s.Name, "depends_on are ignored")
-- }
-- if s.CredentialSpec.File != "" {
-- warnServicef(stderr, s.Name, "credential_spec is ignored")
-- }
-- if len(s.DNS) > 0 {
-- warnServicef(stderr, s.Name, "dns are ignored")
-- }
-- if len(s.DNSSearch) > 0 {
-- warnServicef(stderr, s.Name, "dns_search are ignored")
-- }
-- if len(s.EnvFile) > 0 {
-- warnServicef(stderr, s.Name, "env_file are ignored")
-- }
-- if s.StopSignal != "" {
-- warnServicef(stderr, s.Name, "stop_signal is ignored")
-- }
-- if s.Logging != nil {
-- warnServicef(stderr, s.Name, "logging is ignored")
-- }
-- for _, m := range s.Volumes {
-- if m.Volume != nil && m.Volume.NoCopy {
-- warnServicef(stderr, s.Name, "volume.nocopy is ignored")
-- }
-- if m.Bind != nil && m.Bind.Propagation != "" {
-- warnServicef(stderr, s.Name, "volume.propagation is ignored")
-- }
-- }
--}
-diff --git a/cli/command/stack/kubernetes/warnings_test.go b/cli/command/stack/kubernetes/warnings_test.go
-deleted file mode 100644
-index 755f4e6d6a7..00000000000
---- a/cli/command/stack/kubernetes/warnings_test.go
-+++ /dev/null
-@@ -1,78 +0,0 @@
--package kubernetes
--
--import (
-- "bytes"
-- "testing"
-- "time"
--
-- composetypes "github.com/docker/cli/cli/compose/types"
-- "gotest.tools/v3/golden"
--)
--
--func TestWarnings(t *testing.T) {
-- duration := composetypes.Duration(5 * time.Second)
-- attempts := uint64(3)
-- config := &composetypes.Config{
-- Version: "3.4",
-- Services: []composetypes.ServiceConfig{
-- {
-- Name: "front",
-- Build: composetypes.BuildConfig{
-- Context: "ignored",
-- },
-- ContainerName: "ignored",
-- CgroupParent: "ignored",
-- CredentialSpec: composetypes.CredentialSpecConfig{File: "ignored"},
-- DependsOn: []string{"ignored"},
-- Deploy: composetypes.DeployConfig{
-- UpdateConfig: &composetypes.UpdateConfig{
-- Delay: composetypes.Duration(5 * time.Second),
-- FailureAction: "rollback",
-- Monitor: composetypes.Duration(10 * time.Second),
-- MaxFailureRatio: 0.5,
-- },
-- RestartPolicy: &composetypes.RestartPolicy{
-- Delay: &duration,
-- MaxAttempts: &attempts,
-- Window: &duration,
-- },
-- },
-- Devices: []string{"ignored"},
-- DNSSearch: []string{"ignored"},
-- DNS: []string{"ignored"},
-- DomainName: "ignored",
-- EnvFile: []string{"ignored"},
-- Expose: []string{"80"},
-- ExternalLinks: []string{"ignored"},
-- Image: "dockerdemos/front",
-- Links: []string{"ignored"},
-- Logging: &composetypes.LoggingConfig{Driver: "syslog"},
-- MacAddress: "ignored",
-- Networks: map[string]*composetypes.ServiceNetworkConfig{"private": {}},
-- NetworkMode: "ignored",
-- Restart: "ignored",
-- SecurityOpt: []string{"ignored"},
-- StopSignal: "ignored",
-- Ulimits: map[string]*composetypes.UlimitsConfig{"nproc": {Hard: 65535}},
-- User: "ignored",
-- Volumes: []composetypes.ServiceVolumeConfig{
-- {
-- Type: "bind",
-- Bind: &composetypes.ServiceVolumeBind{Propagation: "ignored"},
-- },
-- {
-- Type: "volume",
-- Volume: &composetypes.ServiceVolumeVolume{NoCopy: true},
-- },
-- },
-- },
-- },
-- Networks: map[string]composetypes.NetworkConfig{
-- "global": {},
-- },
-- }
-- var buf bytes.Buffer
-- warnUnsupportedFeatures(&buf, config)
-- warnings := buf.String()
-- golden.Assert(t, warnings, "warnings.golden")
--}
-diff --git a/cli/command/stack/kubernetes/watcher.go b/cli/command/stack/kubernetes/watcher.go
-deleted file mode 100644
-index 4e73287d5c3..00000000000
---- a/cli/command/stack/kubernetes/watcher.go
-+++ /dev/null
-@@ -1,262 +0,0 @@
--package kubernetes
--
--import (
-- "context"
-- "sync"
-- "time"
--
-- apiv1beta1 "github.com/docker/compose-on-kubernetes/api/compose/v1beta1"
-- "github.com/docker/compose-on-kubernetes/api/labels"
-- "github.com/pkg/errors"
-- apiv1 "k8s.io/api/core/v1"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- "k8s.io/apimachinery/pkg/fields"
-- "k8s.io/apimachinery/pkg/runtime"
-- runtimeutil "k8s.io/apimachinery/pkg/util/runtime"
-- "k8s.io/apimachinery/pkg/watch"
-- cache "k8s.io/client-go/tools/cache"
--)
--
--type stackListWatch interface {
-- List(opts metav1.ListOptions) (*apiv1beta1.StackList, error)
-- Watch(opts metav1.ListOptions) (watch.Interface, error)
--}
--
--type podListWatch interface {
-- List(opts metav1.ListOptions) (*apiv1.PodList, error)
-- Watch(opts metav1.ListOptions) (watch.Interface, error)
--}
--
--// DeployWatcher watches a stack deployement
--type deployWatcher struct {
-- pods podListWatch
-- stacks stackListWatch
--}
--
--// Watch watches a stuck deployement and return a chan that will holds the state of the stack
--func (w *deployWatcher) Watch(name string, serviceNames []string, statusUpdates chan serviceStatus) error {
-- errC := make(chan error, 1)
-- defer close(errC)
--
-- handlers := runtimeutil.ErrorHandlers
--
-- // informer errors are reported using global error handlers
-- runtimeutil.ErrorHandlers = append(handlers, func(err error) {
-- errC <- err
-- })
-- defer func() {
-- runtimeutil.ErrorHandlers = handlers
-- }()
--
-- ctx, cancel := context.WithCancel(context.Background())
-- wg := sync.WaitGroup{}
-- defer func() {
-- cancel()
-- wg.Wait()
-- }()
-- wg.Add(2)
-- go func() {
-- defer wg.Done()
-- w.watchStackStatus(ctx, name, errC)
-- }()
-- go func() {
-- defer wg.Done()
-- w.waitForPods(ctx, name, serviceNames, errC, statusUpdates)
-- }()
--
-- return <-errC
--}
--
--type stackWatcher struct {
-- resultChan chan error
-- stackName string
--}
--
--var _ cache.ResourceEventHandler = &stackWatcher{}
--
--func (sw *stackWatcher) OnAdd(obj interface{}) {
-- stack, ok := obj.(*apiv1beta1.Stack)
-- switch {
-- case !ok:
-- sw.resultChan <- errors.Errorf("stack %s has incorrect type", sw.stackName)
-- case stack.Status.Phase == apiv1beta1.StackFailure:
-- sw.resultChan <- errors.Errorf("stack %s failed with status %s: %s", sw.stackName, stack.Status.Phase, stack.Status.Message)
-- }
--}
--
--func (sw *stackWatcher) OnUpdate(oldObj, newObj interface{}) {
-- sw.OnAdd(newObj)
--}
--
--func (sw *stackWatcher) OnDelete(obj interface{}) {
--}
--
--func (w *deployWatcher) watchStackStatus(ctx context.Context, stackname string, e chan error) {
-- informer := newStackInformer(w.stacks, stackname)
-- sw := &stackWatcher{
-- resultChan: e,
-- }
-- informer.AddEventHandler(sw)
-- informer.Run(ctx.Done())
--}
--
--type serviceStatus struct {
-- name string
-- podsPending int
-- podsRunning int
-- podsSucceeded int
-- podsFailed int
-- podsUnknown int
-- podsReady int
-- podsTotal int
--}
--
--type podWatcher struct {
-- stackName string
-- services map[string]serviceStatus
-- resultChan chan error
-- starts map[string]int32
-- indexer cache.Indexer
-- statusUpdates chan serviceStatus
--}
--
--var _ cache.ResourceEventHandler = &podWatcher{}
--
--func (pw *podWatcher) handlePod(obj interface{}) {
-- pod, ok := obj.(*apiv1.Pod)
-- if !ok {
-- pw.resultChan <- errors.Errorf("Pod has incorrect type in stack %s", pw.stackName)
-- return
-- }
-- serviceName := pod.Labels[labels.ForServiceName]
-- pw.updateServiceStatus(serviceName)
-- if pw.allReady() {
-- select {
-- case pw.resultChan <- nil:
-- default:
-- // result has already been reported, just don't block
-- }
-- }
--}
--
--func (pw *podWatcher) updateServiceStatus(serviceName string) {
-- pods, _ := pw.indexer.ByIndex("byservice", serviceName)
-- status := serviceStatus{name: serviceName}
-- for _, obj := range pods {
-- if pod, ok := obj.(*apiv1.Pod); ok {
-- switch pod.Status.Phase {
-- case apiv1.PodPending:
-- status.podsPending++
-- case apiv1.PodRunning:
-- status.podsRunning++
-- case apiv1.PodSucceeded:
-- status.podsSucceeded++
-- case apiv1.PodFailed:
-- status.podsFailed++
-- case apiv1.PodUnknown:
-- status.podsUnknown++
-- }
-- if pw.isPodReady(pod) {
-- status.podsReady++
-- }
-- }
-- }
-- status.podsTotal = len(pods)
-- oldStatus := pw.services[serviceName]
-- if oldStatus != status {
-- pw.statusUpdates <- status
-- }
-- pw.services[serviceName] = status
--}
--
--func (pw *podWatcher) isPodReady(pod *apiv1.Pod) bool {
-- for _, condition := range pod.Status.Conditions {
-- if condition.Status == apiv1.ConditionTrue && condition.Type == apiv1.PodReady {
-- return true
-- }
-- }
-- return false
--}
--
--func (pw *podWatcher) allReady() bool {
-- for _, status := range pw.services {
-- if status.podsReady == 0 {
-- return false
-- }
-- }
-- return true
--}
--
--func (pw *podWatcher) OnAdd(obj interface{}) {
-- pw.handlePod(obj)
--}
--
--func (pw *podWatcher) OnUpdate(oldObj, newObj interface{}) {
-- pw.handlePod(newObj)
--}
--
--func (pw *podWatcher) OnDelete(obj interface{}) {
-- pw.handlePod(obj)
--}
--
--func (w *deployWatcher) waitForPods(ctx context.Context, stackName string, serviceNames []string, e chan error, statusUpdates chan serviceStatus) {
-- informer := newPodInformer(w.pods, stackName, cache.Indexers{
-- "byservice": func(obj interface{}) ([]string, error) {
-- pod, ok := obj.(*apiv1.Pod)
-- if !ok {
-- return nil, errors.Errorf("Pod has incorrect type in stack %s", stackName)
-- }
-- return []string{pod.Labels[labels.ForServiceName]}, nil
-- }})
-- services := map[string]serviceStatus{}
-- for _, name := range serviceNames {
-- services[name] = serviceStatus{name: name}
-- }
-- pw := &podWatcher{
-- stackName: stackName,
-- services: services,
-- resultChan: e,
-- starts: map[string]int32{},
-- indexer: informer.GetIndexer(),
-- statusUpdates: statusUpdates,
-- }
-- informer.AddEventHandler(pw)
-- informer.Run(ctx.Done())
--}
--
--func newPodInformer(podsClient podListWatch, stackName string, indexers cache.Indexers) cache.SharedIndexInformer {
-- return cache.NewSharedIndexInformer(
-- &cache.ListWatch{
-- ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
-- options.LabelSelector = labels.SelectorForStack(stackName)
-- return podsClient.List(options)
-- },
--
-- WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
-- options.LabelSelector = labels.SelectorForStack(stackName)
-- return podsClient.Watch(options)
-- },
-- },
-- &apiv1.Pod{},
-- time.Second*5,
-- indexers,
-- )
--}
--
--func newStackInformer(stacksClient stackListWatch, stackName string) cache.SharedInformer {
-- return cache.NewSharedInformer(
-- &cache.ListWatch{
-- ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
-- options.FieldSelector = fields.OneTermEqualSelector("metadata.name", stackName).String()
-- return stacksClient.List(options)
-- },
--
-- WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
-- options.FieldSelector = fields.OneTermEqualSelector("metadata.name", stackName).String()
-- return stacksClient.Watch(options)
-- },
-- },
-- &apiv1beta1.Stack{},
-- time.Second*5,
-- )
--}
-diff --git a/cli/command/stack/kubernetes/watcher_test.go b/cli/command/stack/kubernetes/watcher_test.go
-deleted file mode 100644
-index 71ba7e44d51..00000000000
---- a/cli/command/stack/kubernetes/watcher_test.go
-+++ /dev/null
-@@ -1,220 +0,0 @@
--package kubernetes
--
--import (
-- "testing"
--
-- apiv1beta1 "github.com/docker/compose-on-kubernetes/api/compose/v1beta1"
-- composelabels "github.com/docker/compose-on-kubernetes/api/labels"
-- "gotest.tools/v3/assert"
-- apiv1 "k8s.io/api/core/v1"
-- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-- "k8s.io/apimachinery/pkg/labels"
-- "k8s.io/apimachinery/pkg/runtime"
-- "k8s.io/apimachinery/pkg/runtime/schema"
-- "k8s.io/apimachinery/pkg/runtime/serializer"
-- "k8s.io/apimachinery/pkg/watch"
-- k8stesting "k8s.io/client-go/testing"
--)
--
--var podsResource = apiv1.SchemeGroupVersion.WithResource("pods")
--var podKind = apiv1.SchemeGroupVersion.WithKind("Pod")
--var stacksResource = apiv1beta1.SchemeGroupVersion.WithResource("stacks")
--var stackKind = apiv1beta1.SchemeGroupVersion.WithKind("Stack")
--
--type testPodAndStackRepository struct {
-- fake *k8stesting.Fake
--}
--
--func (r *testPodAndStackRepository) stackListWatchForNamespace(ns string) *testStackListWatch {
-- return &testStackListWatch{fake: r.fake, ns: ns}
--}
--func (r *testPodAndStackRepository) podListWatchForNamespace(ns string) *testPodListWatch {
-- return &testPodListWatch{fake: r.fake, ns: ns}
--}
--
--func newTestPodAndStackRepository(initialPods []apiv1.Pod, initialStacks []apiv1beta1.Stack, podWatchHandler, stackWatchHandler k8stesting.WatchReactionFunc) *testPodAndStackRepository {
-- var scheme = runtime.NewScheme()
-- var codecs = serializer.NewCodecFactory(scheme)
-- metav1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
-- apiv1.AddToScheme(scheme)
-- apiv1beta1.AddToScheme(scheme)
--
-- o := k8stesting.NewObjectTracker(scheme, codecs.UniversalDecoder())
-- for _, obj := range initialPods {
-- obj := obj
-- if err := o.Add(&obj); err != nil {
-- panic(err)
-- }
-- }
-- for _, obj := range initialStacks {
-- obj := obj
-- if err := o.Add(&obj); err != nil {
-- panic(err)
-- }
-- }
-- fakePtr := &k8stesting.Fake{}
-- fakePtr.AddReactor("*", "*", k8stesting.ObjectReaction(o))
-- if podWatchHandler != nil {
-- fakePtr.AddWatchReactor(podsResource.Resource, podWatchHandler)
-- }
-- if stackWatchHandler != nil {
-- fakePtr.AddWatchReactor(stacksResource.Resource, stackWatchHandler)
-- }
-- fakePtr.AddWatchReactor("*", k8stesting.DefaultWatchReactor(watch.NewFake(), nil))
-- return &testPodAndStackRepository{fake: fakePtr}
--}
--
--type testStackListWatch struct {
-- fake *k8stesting.Fake
-- ns string
--}
--
--func (s *testStackListWatch) List(opts metav1.ListOptions) (*apiv1beta1.StackList, error) {
-- obj, err := s.fake.Invokes(k8stesting.NewListAction(stacksResource, stackKind, s.ns, opts), &apiv1beta1.StackList{})
--
-- if obj == nil {
-- return nil, err
-- }
--
-- label, _, _ := k8stesting.ExtractFromListOptions(opts)
-- if label == nil {
-- label = labels.Everything()
-- }
-- list := &apiv1beta1.StackList{}
-- for _, item := range obj.(*apiv1beta1.StackList).Items {
-- if label.Matches(labels.Set(item.Labels)) {
-- list.Items = append(list.Items, item)
-- }
-- }
-- return list, err
--}
--func (s *testStackListWatch) Watch(opts metav1.ListOptions) (watch.Interface, error) {
-- return s.fake.InvokesWatch(k8stesting.NewWatchAction(stacksResource, s.ns, opts))
--}
--
--type testPodListWatch struct {
-- fake *k8stesting.Fake
-- ns string
--}
--
--func (p *testPodListWatch) List(opts metav1.ListOptions) (*apiv1.PodList, error) {
-- obj, err := p.fake.Invokes(k8stesting.NewListAction(podsResource, podKind, p.ns, opts), &apiv1.PodList{})
--
-- if obj == nil {
-- return nil, err
-- }
--
-- label, _, _ := k8stesting.ExtractFromListOptions(opts)
-- if label == nil {
-- label = labels.Everything()
-- }
-- list := &apiv1.PodList{}
-- for _, item := range obj.(*apiv1.PodList).Items {
-- if label.Matches(labels.Set(item.Labels)) {
-- list.Items = append(list.Items, item)
-- }
-- }
-- return list, err
--
--}
--func (p *testPodListWatch) Watch(opts metav1.ListOptions) (watch.Interface, error) {
-- return p.fake.InvokesWatch(k8stesting.NewWatchAction(podsResource, p.ns, opts))
--}
--
--func TestDeployWatchOk(t *testing.T) {
-- stack := apiv1beta1.Stack{
-- ObjectMeta: metav1.ObjectMeta{Name: "test-stack", Namespace: "test-ns"},
-- }
--
-- serviceNames := []string{"svc1", "svc2"}
-- testRepo := newTestPodAndStackRepository(nil, []apiv1beta1.Stack{stack}, func(action k8stesting.Action) (handled bool, ret watch.Interface, err error) {
-- res := watch.NewFake()
-- go func() {
-- pod1 := &apiv1.Pod{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: "test1",
-- Namespace: "test-ns",
-- Labels: composelabels.ForService("test-stack", "svc1"),
-- },
-- Status: apiv1.PodStatus{
-- Phase: apiv1.PodRunning,
-- Conditions: []apiv1.PodCondition{
-- {
-- Type: apiv1.PodReady,
-- Status: apiv1.ConditionTrue,
-- },
-- },
-- },
-- }
-- pod2 := &apiv1.Pod{
-- ObjectMeta: metav1.ObjectMeta{
-- Name: "test2",
-- Namespace: "test-ns",
-- Labels: composelabels.ForService("test-stack", "svc2"),
-- },
-- Status: apiv1.PodStatus{
-- Phase: apiv1.PodRunning,
-- Conditions: []apiv1.PodCondition{
-- {
-- Type: apiv1.PodReady,
-- Status: apiv1.ConditionTrue,
-- },
-- },
-- },
-- }
-- res.Add(pod1)
-- res.Add(pod2)
-- }()
--
-- return true, res, nil
-- }, nil)
--
-- testee := &deployWatcher{
-- stacks: testRepo.stackListWatchForNamespace("test-ns"),
-- pods: testRepo.podListWatchForNamespace("test-ns"),
-- }
--
-- statusUpdates := make(chan serviceStatus)
-- go func() {
-- for range statusUpdates {
-- }
-- }()
-- defer close(statusUpdates)
-- err := testee.Watch(stack.Name, serviceNames, statusUpdates)
-- assert.NilError(t, err)
--}
--
--func TestDeployReconcileFailure(t *testing.T) {
-- stack := apiv1beta1.Stack{
-- ObjectMeta: metav1.ObjectMeta{Name: "test-stack", Namespace: "test-ns"},
-- }
--
-- serviceNames := []string{"svc1", "svc2"}
-- testRepo := newTestPodAndStackRepository(nil, []apiv1beta1.Stack{stack}, nil, func(action k8stesting.Action) (handled bool, ret watch.Interface, err error) {
-- res := watch.NewFake()
-- go func() {
-- sfailed := stack
-- sfailed.Status = apiv1beta1.StackStatus{
-- Phase: apiv1beta1.StackFailure,
-- Message: "test error",
-- }
-- res.Modify(&sfailed)
-- }()
--
-- return true, res, nil
-- })
--
-- testee := &deployWatcher{
-- stacks: testRepo.stackListWatchForNamespace("test-ns"),
-- pods: testRepo.podListWatchForNamespace("test-ns"),
-- }
--
-- statusUpdates := make(chan serviceStatus)
-- go func() {
-- for range statusUpdates {
-- }
-- }()
-- defer close(statusUpdates)
-- err := testee.Watch(stack.Name, serviceNames, statusUpdates)
-- assert.ErrorContains(t, err, "Failure: test error")
--}
-diff --git a/cli/command/stack/list.go b/cli/command/stack/list.go
-index 5175ea371c8..861ae1be2fb 100644
---- a/cli/command/stack/list.go
-+++ b/cli/command/stack/list.go
-@@ -6,7 +6,6 @@ import (
- "github.com/docker/cli/cli"
- "github.com/docker/cli/cli/command"
- "github.com/docker/cli/cli/command/stack/formatter"
-- "github.com/docker/cli/cli/command/stack/kubernetes"
- "github.com/docker/cli/cli/command/stack/options"
- "github.com/docker/cli/cli/command/stack/swarm"
- "github.com/fvbommel/sortorder"
-@@ -28,10 +27,6 @@ func newListCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command
-
- flags := cmd.Flags()
- flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template")
-- flags.StringSliceVar(&opts.Namespaces, "namespace", []string{}, "Kubernetes namespaces to use")
-- flags.SetAnnotation("namespace", "kubernetes", nil)
-- flags.BoolVarP(&opts.AllNamespaces, "all-namespaces", "", false, "List stacks from all Kubernetes namespaces")
-- flags.SetAnnotation("all-namespaces", "kubernetes", nil)
- return cmd
- }
-
-@@ -45,27 +40,13 @@ func RunList(cmd *cobra.Command, dockerCli command.Cli, opts options.List, orche
- }
- stacks = append(stacks, ss...)
- }
-- if orchestrator.HasKubernetes() {
-- kubeCli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags(), orchestrator))
-- if err != nil {
-- return err
-- }
-- ss, err := kubernetes.GetStacks(kubeCli, opts)
-- if err != nil {
-- return err
-- }
-- stacks = append(stacks, ss...)
-- }
-- return format(dockerCli, opts, orchestrator, stacks)
-+ return format(dockerCli, opts, stacks)
- }
-
--func format(dockerCli command.Cli, opts options.List, orchestrator command.Orchestrator, stacks []*formatter.Stack) error {
-+func format(dockerCli command.Cli, opts options.List, stacks []*formatter.Stack) error {
- format := formatter.Format(opts.Format)
- if format == "" || format == formatter.TableFormatKey {
- format = formatter.SwarmStackTableFormat
-- if orchestrator.HasKubernetes() {
-- format = formatter.KubernetesStackTableFormat
-- }
- }
- stackCtx := formatter.Context{
- Output: dockerCli.Out(),
-@@ -73,8 +54,7 @@ func format(dockerCli command.Cli, opts options.List, orchestrator command.Orche
- }
- sort.Slice(stacks, func(i, j int) bool {
- return sortorder.NaturalLess(stacks[i].Name, stacks[j].Name) ||
-- !sortorder.NaturalLess(stacks[j].Name, stacks[i].Name) &&
-- sortorder.NaturalLess(stacks[j].Namespace, stacks[i].Namespace)
-+ !sortorder.NaturalLess(stacks[j].Name, stacks[i].Name)
- })
- return formatter.StackWrite(stackCtx, stacks)
- }
-diff --git a/cli/command/stack/options/opts.go b/cli/command/stack/options/opts.go
-index fb45dc45580..9842b4995c0 100644
---- a/cli/command/stack/options/opts.go
-+++ b/cli/command/stack/options/opts.go
-@@ -15,7 +15,6 @@ type Deploy struct {
- type List struct {
- Format string
- AllNamespaces bool
-- Namespaces []string
- }
-
- // PS holds docker stack ps options
-diff --git a/cli/command/stack/ps.go b/cli/command/stack/ps.go
-index ae692d4e13c..6d77d9f0065 100644
---- a/cli/command/stack/ps.go
-+++ b/cli/command/stack/ps.go
-@@ -3,7 +3,6 @@ package stack
- import (
- "github.com/docker/cli/cli"
- "github.com/docker/cli/cli/command"
-- "github.com/docker/cli/cli/command/stack/kubernetes"
- "github.com/docker/cli/cli/command/stack/options"
- "github.com/docker/cli/cli/command/stack/swarm"
- cliopts "github.com/docker/cli/opts"
-@@ -32,13 +31,10 @@ func newPsCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
- flags.VarP(&opts.Filter, "filter", "f", "Filter output based on conditions provided")
- flags.BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display task IDs")
- flags.StringVar(&opts.Format, "format", "", "Pretty-print tasks using a Go template")
-- kubernetes.AddNamespaceFlag(flags)
- return cmd
- }
-
- // RunPs performs a stack ps against the specified orchestrator
- func RunPs(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.PS) error {
-- return runOrchestratedCommand(dockerCli, flags, commonOrchestrator,
-- func() error { return swarm.RunPS(dockerCli, opts) },
-- func(kli *kubernetes.KubeCli) error { return kubernetes.RunPS(kli, opts) })
-+ return swarm.RunPS(dockerCli, opts)
- }
-diff --git a/cli/command/stack/remove.go b/cli/command/stack/remove.go
-index a8dceff2bb3..4ffe73ec249 100644
---- a/cli/command/stack/remove.go
-+++ b/cli/command/stack/remove.go
-@@ -3,7 +3,6 @@ package stack
- import (
- "github.com/docker/cli/cli"
- "github.com/docker/cli/cli/command"
-- "github.com/docker/cli/cli/command/stack/kubernetes"
- "github.com/docker/cli/cli/command/stack/options"
- "github.com/docker/cli/cli/command/stack/swarm"
- "github.com/spf13/cobra"
-@@ -26,14 +25,10 @@ func newRemoveCommand(dockerCli command.Cli, common *commonOptions) *cobra.Comma
- return RunRemove(dockerCli, cmd.Flags(), common.Orchestrator(), opts)
- },
- }
-- flags := cmd.Flags()
-- kubernetes.AddNamespaceFlag(flags)
- return cmd
- }
-
- // RunRemove performs a stack remove against the specified orchestrator
- func RunRemove(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.Remove) error {
-- return runOrchestratedCommand(dockerCli, flags, commonOrchestrator,
-- func() error { return swarm.RunRemove(dockerCli, opts) },
-- func(kli *kubernetes.KubeCli) error { return kubernetes.RunRemove(kli, opts) })
-+ return swarm.RunRemove(dockerCli, opts)
- }
-diff --git a/cli/command/stack/services.go b/cli/command/stack/services.go
-index 24ad3688871..a1e97b9f2e2 100644
---- a/cli/command/stack/services.go
-+++ b/cli/command/stack/services.go
-@@ -8,7 +8,6 @@ import (
- "github.com/docker/cli/cli/command"
- "github.com/docker/cli/cli/command/service"
- "github.com/docker/cli/cli/command/stack/formatter"
-- "github.com/docker/cli/cli/command/stack/kubernetes"
- "github.com/docker/cli/cli/command/stack/options"
- "github.com/docker/cli/cli/command/stack/swarm"
- cliopts "github.com/docker/cli/opts"
-@@ -37,7 +36,6 @@ func newServicesCommand(dockerCli command.Cli, common *commonOptions) *cobra.Com
- flags.BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs")
- flags.StringVar(&opts.Format, "format", "", "Pretty-print services using a Go template")
- flags.VarP(&opts.Filter, "filter", "f", "Filter output based on conditions provided")
-- kubernetes.AddNamespaceFlag(flags)
- return cmd
- }
-
-@@ -52,18 +50,7 @@ func RunServices(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator
-
- // GetServices returns the services for the specified orchestrator
- func GetServices(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.Services) ([]swarmtypes.Service, error) {
-- switch {
-- case commonOrchestrator.HasAll():
-- return nil, errUnsupportedAllOrchestrator
-- case commonOrchestrator.HasKubernetes():
-- kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(flags, commonOrchestrator))
-- if err != nil {
-- return nil, err
-- }
-- return kubernetes.GetServices(kli, opts)
-- default:
-- return swarm.GetServices(dockerCli, opts)
-- }
-+ return swarm.GetServices(dockerCli, opts)
- }
-
- func formatWrite(dockerCli command.Cli, services []swarmtypes.Service, opts options.Services) error {
-diff --git a/cli/context/kubernetes/constants.go b/cli/context/kubernetes/constants.go
-deleted file mode 100644
-index 8998de989af..00000000000
---- a/cli/context/kubernetes/constants.go
-+++ /dev/null
-@@ -1,6 +0,0 @@
--package kubernetes
--
--const (
-- // KubernetesEndpoint is the kubernetes endpoint name in a stored context
-- KubernetesEndpoint = "kubernetes"
--)
-diff --git a/cli/context/kubernetes/endpoint_test.go b/cli/context/kubernetes/endpoint_test.go
-deleted file mode 100644
-index 89eeb9d61c5..00000000000
---- a/cli/context/kubernetes/endpoint_test.go
-+++ /dev/null
-@@ -1,224 +0,0 @@
--package kubernetes
--
--import (
-- "io/ioutil"
-- "os"
-- "testing"
--
-- "github.com/docker/cli/cli/context"
-- "github.com/docker/cli/cli/context/store"
-- "gotest.tools/v3/assert"
-- "k8s.io/client-go/tools/clientcmd"
-- clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
--)
--
--func testEndpoint(server, defaultNamespace string, ca, cert, key []byte, skipTLSVerify bool) Endpoint {
-- var tlsData *context.TLSData
-- if ca != nil || cert != nil || key != nil {
-- tlsData = &context.TLSData{
-- CA: ca,
-- Cert: cert,
-- Key: key,
-- }
-- }
-- return Endpoint{
-- EndpointMeta: EndpointMeta{
-- EndpointMetaBase: context.EndpointMetaBase{
-- Host: server,
-- SkipTLSVerify: skipTLSVerify,
-- },
-- DefaultNamespace: defaultNamespace,
-- },
-- TLSData: tlsData,
-- }
--}
--
--var testStoreCfg = store.NewConfig(
-- func() interface{} {
-- return &map[string]interface{}{}
-- },
-- store.EndpointTypeGetter(KubernetesEndpoint, func() interface{} { return &EndpointMeta{} }),
--)
--
--func TestSaveLoadContexts(t *testing.T) {
-- storeDir, err := ioutil.TempDir("", "test-load-save-k8-context")
-- assert.NilError(t, err)
-- defer os.RemoveAll(storeDir)
-- store := store.New(storeDir, testStoreCfg)
-- assert.NilError(t, save(store, testEndpoint("https://test", "test", nil, nil, nil, false), "raw-notls"))
-- assert.NilError(t, save(store, testEndpoint("https://test", "test", nil, nil, nil, true), "raw-notls-skip"))
-- assert.NilError(t, save(store, testEndpoint("https://test", "test", []byte("ca"), []byte("cert"), []byte("key"), true), "raw-tls"))
--
-- kcFile, err := ioutil.TempFile(os.TempDir(), "test-load-save-k8-context")
-- assert.NilError(t, err)
-- defer os.Remove(kcFile.Name())
-- defer kcFile.Close()
-- cfg := clientcmdapi.NewConfig()
-- cfg.AuthInfos["user"] = clientcmdapi.NewAuthInfo()
-- cfg.Contexts["context1"] = clientcmdapi.NewContext()
-- cfg.Clusters["cluster1"] = clientcmdapi.NewCluster()
-- cfg.Contexts["context2"] = clientcmdapi.NewContext()
-- cfg.Clusters["cluster2"] = clientcmdapi.NewCluster()
-- cfg.AuthInfos["user"].ClientCertificateData = []byte("cert")
-- cfg.AuthInfos["user"].ClientKeyData = []byte("key")
-- cfg.Clusters["cluster1"].Server = "https://server1"
-- cfg.Clusters["cluster1"].InsecureSkipTLSVerify = true
-- cfg.Clusters["cluster2"].Server = "https://server2"
-- cfg.Clusters["cluster2"].CertificateAuthorityData = []byte("ca")
-- cfg.Contexts["context1"].AuthInfo = "user"
-- cfg.Contexts["context1"].Cluster = "cluster1"
-- cfg.Contexts["context1"].Namespace = "namespace1"
-- cfg.Contexts["context2"].AuthInfo = "user"
-- cfg.Contexts["context2"].Cluster = "cluster2"
-- cfg.Contexts["context2"].Namespace = "namespace2"
-- cfg.CurrentContext = "context1"
-- cfgData, err := clientcmd.Write(*cfg)
-- assert.NilError(t, err)
-- _, err = kcFile.Write(cfgData)
-- assert.NilError(t, err)
-- kcFile.Close()
--
-- epDefault, err := FromKubeConfig(kcFile.Name(), "", "")
-- assert.NilError(t, err)
-- epContext2, err := FromKubeConfig(kcFile.Name(), "context2", "namespace-override")
-- assert.NilError(t, err)
-- assert.NilError(t, save(store, epDefault, "embed-default-context"))
-- assert.NilError(t, save(store, epContext2, "embed-context2"))
--
-- rawNoTLSMeta, err := store.GetMetadata("raw-notls")
-- assert.NilError(t, err)
-- rawNoTLSSkipMeta, err := store.GetMetadata("raw-notls-skip")
-- assert.NilError(t, err)
-- rawTLSMeta, err := store.GetMetadata("raw-tls")
-- assert.NilError(t, err)
-- embededDefaultMeta, err := store.GetMetadata("embed-default-context")
-- assert.NilError(t, err)
-- embededContext2Meta, err := store.GetMetadata("embed-context2")
-- assert.NilError(t, err)
--
-- rawNoTLS := EndpointFromContext(rawNoTLSMeta)
-- rawNoTLSSkip := EndpointFromContext(rawNoTLSSkipMeta)
-- rawTLS := EndpointFromContext(rawTLSMeta)
-- embededDefault := EndpointFromContext(embededDefaultMeta)
-- embededContext2 := EndpointFromContext(embededContext2Meta)
--
-- rawNoTLSEP, err := rawNoTLS.WithTLSData(store, "raw-notls")
-- assert.NilError(t, err)
-- checkClientConfig(t, rawNoTLSEP, "https://test", "test", nil, nil, nil, false)
-- rawNoTLSSkipEP, err := rawNoTLSSkip.WithTLSData(store, "raw-notls-skip")
-- assert.NilError(t, err)
-- checkClientConfig(t, rawNoTLSSkipEP, "https://test", "test", nil, nil, nil, true)
-- rawTLSEP, err := rawTLS.WithTLSData(store, "raw-tls")
-- assert.NilError(t, err)
-- checkClientConfig(t, rawTLSEP, "https://test", "test", []byte("ca"), []byte("cert"), []byte("key"), true)
-- embededDefaultEP, err := embededDefault.WithTLSData(store, "embed-default-context")
-- assert.NilError(t, err)
-- checkClientConfig(t, embededDefaultEP, "https://server1", "namespace1", nil, []byte("cert"), []byte("key"), true)
-- embededContext2EP, err := embededContext2.WithTLSData(store, "embed-context2")
-- assert.NilError(t, err)
-- checkClientConfig(t, embededContext2EP, "https://server2", "namespace-override", []byte("ca"), []byte("cert"), []byte("key"), false)
--}
--
--func checkClientConfig(t *testing.T, ep Endpoint, server, namespace string, ca, cert, key []byte, skipTLSVerify bool) {
-- config := ep.KubernetesConfig()
-- cfg, err := config.ClientConfig()
-- assert.NilError(t, err)
-- ns, _, _ := config.Namespace()
-- assert.Equal(t, server, cfg.Host)
-- assert.Equal(t, namespace, ns)
-- assert.DeepEqual(t, ca, cfg.CAData)
-- assert.DeepEqual(t, cert, cfg.CertData)
-- assert.DeepEqual(t, key, cfg.KeyData)
-- assert.Equal(t, skipTLSVerify, cfg.Insecure)
--}
--
--func save(s store.Writer, ep Endpoint, name string) error {
-- meta := store.Metadata{
-- Endpoints: map[string]interface{}{
-- KubernetesEndpoint: ep.EndpointMeta,
-- },
-- Name: name,
-- }
-- if err := s.CreateOrUpdate(meta); err != nil {
-- return err
-- }
-- return s.ResetEndpointTLSMaterial(name, KubernetesEndpoint, ep.TLSData.ToStoreTLSData())
--}
--
--func TestSaveLoadGKEConfig(t *testing.T) {
-- storeDir, err := ioutil.TempDir("", t.Name())
-- assert.NilError(t, err)
-- defer os.RemoveAll(storeDir)
-- store := store.New(storeDir, testStoreCfg)
-- cfg, err := clientcmd.LoadFromFile("testdata/gke-kubeconfig")
-- assert.NilError(t, err)
-- clientCfg := clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
-- expectedCfg, err := clientCfg.ClientConfig()
-- assert.NilError(t, err)
-- ep, err := FromKubeConfig("testdata/gke-kubeconfig", "", "")
-- assert.NilError(t, err)
-- assert.NilError(t, save(store, ep, "gke-context"))
-- persistedMetadata, err := store.GetMetadata("gke-context")
-- assert.NilError(t, err)
-- persistedEPMeta := EndpointFromContext(persistedMetadata)
-- assert.Check(t, persistedEPMeta != nil)
-- persistedEP, err := persistedEPMeta.WithTLSData(store, "gke-context")
-- assert.NilError(t, err)
-- persistedCfg := persistedEP.KubernetesConfig()
-- actualCfg, err := persistedCfg.ClientConfig()
-- assert.NilError(t, err)
-- assert.DeepEqual(t, expectedCfg.AuthProvider, actualCfg.AuthProvider)
--}
--
--func TestSaveLoadEKSConfig(t *testing.T) {
-- storeDir, err := ioutil.TempDir("", t.Name())
-- assert.NilError(t, err)
-- defer os.RemoveAll(storeDir)
-- store := store.New(storeDir, testStoreCfg)
-- cfg, err := clientcmd.LoadFromFile("testdata/eks-kubeconfig")
-- assert.NilError(t, err)
-- clientCfg := clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
-- expectedCfg, err := clientCfg.ClientConfig()
-- assert.NilError(t, err)
-- ep, err := FromKubeConfig("testdata/eks-kubeconfig", "", "")
-- assert.NilError(t, err)
-- assert.NilError(t, save(store, ep, "eks-context"))
-- persistedMetadata, err := store.GetMetadata("eks-context")
-- assert.NilError(t, err)
-- persistedEPMeta := EndpointFromContext(persistedMetadata)
-- assert.Check(t, persistedEPMeta != nil)
-- persistedEP, err := persistedEPMeta.WithTLSData(store, "eks-context")
-- assert.NilError(t, err)
-- persistedCfg := persistedEP.KubernetesConfig()
-- actualCfg, err := persistedCfg.ClientConfig()
-- assert.NilError(t, err)
-- assert.DeepEqual(t, expectedCfg.ExecProvider, actualCfg.ExecProvider)
--}
--
--func TestSaveLoadK3SConfig(t *testing.T) {
-- storeDir, err := ioutil.TempDir("", t.Name())
-- assert.NilError(t, err)
-- defer os.RemoveAll(storeDir)
-- store := store.New(storeDir, testStoreCfg)
-- cfg, err := clientcmd.LoadFromFile("testdata/k3s-kubeconfig")
-- assert.NilError(t, err)
-- clientCfg := clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
-- expectedCfg, err := clientCfg.ClientConfig()
-- assert.NilError(t, err)
-- ep, err := FromKubeConfig("testdata/k3s-kubeconfig", "", "")
-- assert.NilError(t, err)
-- assert.NilError(t, save(store, ep, "k3s-context"))
-- persistedMetadata, err := store.GetMetadata("k3s-context")
-- assert.NilError(t, err)
-- persistedEPMeta := EndpointFromContext(persistedMetadata)
-- assert.Check(t, persistedEPMeta != nil)
-- persistedEP, err := persistedEPMeta.WithTLSData(store, "k3s-context")
-- assert.NilError(t, err)
-- persistedCfg := persistedEP.KubernetesConfig()
-- actualCfg, err := persistedCfg.ClientConfig()
-- assert.NilError(t, err)
-- assert.Check(t, len(actualCfg.Username) > 0)
-- assert.Check(t, len(actualCfg.Password) > 0)
-- assert.Equal(t, expectedCfg.Username, actualCfg.Username)
-- assert.Equal(t, expectedCfg.Password, actualCfg.Password)
--}
-diff --git a/cli/context/kubernetes/load.go b/cli/context/kubernetes/load.go
-deleted file mode 100644
-index 99f2a00ea0c..00000000000
---- a/cli/context/kubernetes/load.go
-+++ /dev/null
-@@ -1,146 +0,0 @@
--package kubernetes
--
--import (
-- "os"
-- "path/filepath"
--
-- "github.com/docker/cli/cli/command"
-- "github.com/docker/cli/cli/context"
-- "github.com/docker/cli/cli/context/store"
-- api "github.com/docker/compose-on-kubernetes/api"
-- "github.com/docker/docker/pkg/homedir"
-- "github.com/pkg/errors"
-- "k8s.io/client-go/tools/clientcmd"
-- clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
--)
--
--// EndpointMeta is a typed wrapper around a context-store generic endpoint describing
--// a Kubernetes endpoint, without TLS data
--type EndpointMeta struct {
-- context.EndpointMetaBase
-- DefaultNamespace string `json:",omitempty"`
-- AuthProvider *clientcmdapi.AuthProviderConfig `json:",omitempty"`
-- Exec *clientcmdapi.ExecConfig `json:",omitempty"`
-- UsernamePassword *UsernamePassword `json:"usernamePassword,omitempty"`
--}
--
--// UsernamePassword contains username/password auth info
--type UsernamePassword struct {
-- Username string `json:"username,omitempty"`
-- Password string `json:"password,omitempty"`
--}
--
--var _ command.EndpointDefaultResolver = &EndpointMeta{}
--
--// Endpoint is a typed wrapper around a context-store generic endpoint describing
--// a Kubernetes endpoint, with TLS data
--type Endpoint struct {
-- EndpointMeta
-- TLSData *context.TLSData
--}
--
--func init() {
-- command.RegisterDefaultStoreEndpoints(
-- store.EndpointTypeGetter(KubernetesEndpoint, func() interface{} { return &EndpointMeta{} }),
-- )
--}
--
--// WithTLSData loads TLS materials for the endpoint
--func (c *EndpointMeta) WithTLSData(s store.Reader, contextName string) (Endpoint, error) {
-- tlsData, err := context.LoadTLSData(s, contextName, KubernetesEndpoint)
-- if err != nil {
-- return Endpoint{}, err
-- }
-- return Endpoint{
-- EndpointMeta: *c,
-- TLSData: tlsData,
-- }, nil
--}
--
--// KubernetesConfig creates the kubernetes client config from the endpoint
--func (c *Endpoint) KubernetesConfig() clientcmd.ClientConfig {
-- cfg := clientcmdapi.NewConfig()
-- cluster := clientcmdapi.NewCluster()
-- cluster.Server = c.Host
-- cluster.InsecureSkipTLSVerify = c.SkipTLSVerify
-- authInfo := clientcmdapi.NewAuthInfo()
-- if c.TLSData != nil {
-- cluster.CertificateAuthorityData = c.TLSData.CA
-- authInfo.ClientCertificateData = c.TLSData.Cert
-- authInfo.ClientKeyData = c.TLSData.Key
-- }
-- if c.UsernamePassword != nil {
-- authInfo.Username = c.UsernamePassword.Username
-- authInfo.Password = c.UsernamePassword.Password
-- }
-- authInfo.AuthProvider = c.AuthProvider
-- authInfo.Exec = c.Exec
-- cfg.Clusters["cluster"] = cluster
-- cfg.AuthInfos["authInfo"] = authInfo
-- ctx := clientcmdapi.NewContext()
-- ctx.AuthInfo = "authInfo"
-- ctx.Cluster = "cluster"
-- ctx.Namespace = c.DefaultNamespace
-- cfg.Contexts["context"] = ctx
-- cfg.CurrentContext = "context"
-- return clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
--}
--
--// ResolveDefault returns endpoint metadata for the default Kubernetes
--// endpoint, which is derived from the env-based kubeconfig.
--func (c *EndpointMeta) ResolveDefault(stackOrchestrator command.Orchestrator) (interface{}, *store.EndpointTLSData, error) {
-- kubeconfig := os.Getenv("KUBECONFIG")
-- if kubeconfig == "" {
-- kubeconfig = filepath.Join(homedir.Get(), ".kube/config")
-- }
-- kubeEP, err := FromKubeConfig(kubeconfig, "", "")
-- if err != nil {
-- if stackOrchestrator == command.OrchestratorKubernetes || stackOrchestrator == command.OrchestratorAll {
-- return nil, nil, errors.Wrapf(err, "default orchestrator is %s but unable to resolve kubernetes endpoint", stackOrchestrator)
-- }
--
-- // We deliberately quash the error here, returning nil
-- // for the first argument is sufficient to indicate we weren't able to
-- // provide a default
-- return nil, nil, nil
-- }
--
-- var tls *store.EndpointTLSData
-- if kubeEP.TLSData != nil {
-- tls = kubeEP.TLSData.ToStoreTLSData()
-- }
-- return kubeEP.EndpointMeta, tls, nil
--}
--
--// EndpointFromContext extracts kubernetes endpoint info from current context
--func EndpointFromContext(metadata store.Metadata) *EndpointMeta {
-- ep, ok := metadata.Endpoints[KubernetesEndpoint]
-- if !ok {
-- return nil
-- }
-- typed, ok := ep.(EndpointMeta)
-- if !ok {
-- return nil
-- }
-- return &typed
--}
--
--// ConfigFromContext resolves a kubernetes client config for the specified context.
--// If kubeconfigOverride is specified, use this config file instead of the context defaults.ConfigFromContext
--// if command.ContextDockerHost is specified as the context name, fallsback to the default user's kubeconfig file
--func ConfigFromContext(name string, s store.Reader) (clientcmd.ClientConfig, error) {
-- ctxMeta, err := s.GetMetadata(name)
-- if err != nil {
-- return nil, err
-- }
-- epMeta := EndpointFromContext(ctxMeta)
-- if epMeta != nil {
-- ep, err := epMeta.WithTLSData(s, name)
-- if err != nil {
-- return nil, err
-- }
-- return ep.KubernetesConfig(), nil
-- }
-- // context has no kubernetes endpoint
-- return api.NewKubernetesConfig(""), nil
--}
-diff --git a/cli/context/kubernetes/load_test.go b/cli/context/kubernetes/load_test.go
-deleted file mode 100644
-index a35276fcc4c..00000000000
---- a/cli/context/kubernetes/load_test.go
-+++ /dev/null
-@@ -1,25 +0,0 @@
--package kubernetes
--
--import (
-- "testing"
--
-- "github.com/docker/cli/cli/command"
-- "github.com/docker/cli/cli/config/configfile"
-- cliflags "github.com/docker/cli/cli/flags"
-- "gotest.tools/v3/assert"
-- "gotest.tools/v3/env"
--)
--
--func TestDefaultContextInitializer(t *testing.T) {
-- cli, err := command.NewDockerCli()
-- assert.NilError(t, err)
-- defer env.Patch(t, "KUBECONFIG", "./testdata/test-kubeconfig")()
-- configFile := &configfile.ConfigFile{
-- StackOrchestrator: "all",
-- }
-- ctx, err := command.ResolveDefaultContext(&cliflags.CommonOptions{}, configFile, command.DefaultContextStoreConfig(), cli.Err())
-- assert.NilError(t, err)
-- assert.Equal(t, "default", ctx.Meta.Name)
-- assert.Equal(t, command.OrchestratorAll, ctx.Meta.Metadata.(command.DockerContext).StackOrchestrator)
-- assert.DeepEqual(t, "zoinx", ctx.Meta.Endpoints[KubernetesEndpoint].(EndpointMeta).DefaultNamespace)
--}
-diff --git a/cli/context/kubernetes/save.go b/cli/context/kubernetes/save.go
-deleted file mode 100644
-index 032a01d46ab..00000000000
---- a/cli/context/kubernetes/save.go
-+++ /dev/null
-@@ -1,69 +0,0 @@
--package kubernetes
--
--import (
-- "io/ioutil"
--
-- "github.com/docker/cli/cli/context"
-- "k8s.io/client-go/tools/clientcmd"
-- clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
--)
--
--// FromKubeConfig creates a Kubernetes endpoint from a Kubeconfig file
--func FromKubeConfig(kubeconfig, kubeContext, namespaceOverride string) (Endpoint, error) {
-- cfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
-- &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig},
-- &clientcmd.ConfigOverrides{CurrentContext: kubeContext, Context: clientcmdapi.Context{Namespace: namespaceOverride}})
-- ns, _, err := cfg.Namespace()
-- if err != nil {
-- return Endpoint{}, err
-- }
-- clientcfg, err := cfg.ClientConfig()
-- if err != nil {
-- return Endpoint{}, err
-- }
-- var ca, key, cert []byte
-- if ca, err = readFileOrDefault(clientcfg.CAFile, clientcfg.CAData); err != nil {
-- return Endpoint{}, err
-- }
-- if key, err = readFileOrDefault(clientcfg.KeyFile, clientcfg.KeyData); err != nil {
-- return Endpoint{}, err
-- }
-- if cert, err = readFileOrDefault(clientcfg.CertFile, clientcfg.CertData); err != nil {
-- return Endpoint{}, err
-- }
-- var tlsData *context.TLSData
-- if ca != nil || cert != nil || key != nil {
-- tlsData = &context.TLSData{
-- CA: ca,
-- Cert: cert,
-- Key: key,
-- }
-- }
-- var usernamePassword *UsernamePassword
-- if clientcfg.Username != "" || clientcfg.Password != "" {
-- usernamePassword = &UsernamePassword{
-- Username: clientcfg.Username,
-- Password: clientcfg.Password,
-- }
-- }
-- return Endpoint{
-- EndpointMeta: EndpointMeta{
-- EndpointMetaBase: context.EndpointMetaBase{
-- Host: clientcfg.Host,
-- SkipTLSVerify: clientcfg.Insecure,
-- },
-- DefaultNamespace: ns,
-- AuthProvider: clientcfg.AuthProvider,
-- Exec: clientcfg.ExecProvider,
-- UsernamePassword: usernamePassword,
-- },
-- TLSData: tlsData,
-- }, nil
--}
--
--func readFileOrDefault(path string, defaultValue []byte) ([]byte, error) {
-- if path != "" {
-- return ioutil.ReadFile(path)
-- }
-- return defaultValue, nil
--}
-diff --git a/cli/context/kubernetes/testdata/gke-kubeconfig b/cli/context/kubernetes/testdata/gke-kubeconfig
-deleted file mode 100644
-index 5a6384cbae9..00000000000
---- a/cli/context/kubernetes/testdata/gke-kubeconfig
-+++ /dev/null
-@@ -1,23 +0,0 @@
--apiVersion: v1
--clusters:
--- cluster:
-- server: https://some-server
-- name: gke_sample
--contexts:
--- context:
-- cluster: gke_sample
-- user: gke_sample
-- name: gke_sample
--current-context: gke_sample
--kind: Config
--preferences: {}
--users:
--- name: gke_sample
-- user:
-- auth-provider:
-- config:
-- cmd-args: config config-helper --format=json
-- cmd-path: /google/google-cloud-sdk/bin/gcloud
-- expiry-key: '{.credential.token_expiry}'
-- token-key: '{.credential.access_token}'
-- name: gcp
-diff --git a/cli/context/kubernetes/testdata/k3s-kubeconfig b/cli/context/kubernetes/testdata/k3s-kubeconfig
-deleted file mode 100644
-index 7bb48863f0c..00000000000
---- a/cli/context/kubernetes/testdata/k3s-kubeconfig
-+++ /dev/null
-@@ -1,20 +0,0 @@
--apiVersion: v1
--clusters:
--- cluster:
-- certificate-authority-data: dGhlLWNh
-- server: https://someserver
-- name: test-cluster
--contexts:
--- context:
-- cluster: test-cluster
-- user: test-user
-- namespace: zoinx
-- name: test
--current-context: test
--kind: Config
--preferences: {}
--users:
--- name: test-user
-- user:
-- username: admin
-- password: testpwd
-diff --git a/cli/context/kubernetes/testdata/test-kubeconfig b/cli/context/kubernetes/testdata/test-kubeconfig
-deleted file mode 100644
-index e96df74a508..00000000000
---- a/cli/context/kubernetes/testdata/test-kubeconfig
-+++ /dev/null
-@@ -1,20 +0,0 @@
--apiVersion: v1
--clusters:
--- cluster:
-- certificate-authority-data: dGhlLWNh
-- server: https://someserver
-- name: test-cluster
--contexts:
--- context:
-- cluster: test-cluster
-- user: test-user
-- namespace: zoinx
-- name: test
--current-context: test
--kind: Config
--preferences: {}
--users:
--- name: test-user
-- user:
-- client-certificate-data: dGhlLWNlcnQ=
-- client-key-data: dGhlLWtleQ==
-diff --git a/cli/context/store/doc.go b/cli/context/store/doc.go
-index 5626a64d912..d5304b1d98d 100644
---- a/cli/context/store/doc.go
-+++ b/cli/context/store/doc.go
-@@ -12,7 +12,7 @@
- // - tls/
- // - <context id>/endpoint1/: directory containing TLS data for the endpoint1 in the corresponding context
- //
--// The context store itself has absolutely no knowledge about what a docker or a kubernetes endpoint should contain in term of metadata or TLS config.
-+// The context store itself has absolutely no knowledge about what a docker endpoint should contain in term of metadata or TLS config.
- // Client code is responsible for generating and parsing endpoint metadata and TLS files.
- // The multi-endpoints approach of this package allows to combine many different endpoints in the same "context" (e.g., the Docker CLI
- // is able for a single context to define both a docker endpoint and a Kubernetes endpoint for the same cluster, and also specify which
-diff --git a/e2e/stack/deploy_test.go b/e2e/stack/deploy_test.go
-index 2b797aeab59..94275c57e7c 100644
---- a/e2e/stack/deploy_test.go
-+++ b/e2e/stack/deploy_test.go
-@@ -6,24 +6,15 @@ import (
- "strings"
- "testing"
-
-- "github.com/docker/cli/internal/test/environment"
- "gotest.tools/v3/assert"
- "gotest.tools/v3/golden"
- "gotest.tools/v3/icmd"
-- "gotest.tools/v3/skip"
- )
-
- func TestDeployWithNamedResources(t *testing.T) {
- t.Run("Swarm", func(t *testing.T) {
- testDeployWithNamedResources(t, "swarm")
- })
-- t.Run("Kubernetes", func(t *testing.T) {
-- // FIXME(chris-crone): currently does not work with compose for kubernetes.
-- t.Skip("FIXME(chris-crone): currently does not work with compose for kubernetes.")
-- skip.If(t, !environment.KubernetesEnabled())
--
-- testDeployWithNamedResources(t, "kubernetes")
-- })
- }
-
- func testDeployWithNamedResources(t *testing.T, orchestrator string) {
-diff --git a/e2e/stack/help_test.go b/e2e/stack/help_test.go
-index e7f55c0cc0c..1235eef8d1e 100644
---- a/e2e/stack/help_test.go
-+++ b/e2e/stack/help_test.go
-@@ -12,9 +12,6 @@ func TestStackDeployHelp(t *testing.T) {
- t.Run("Swarm", func(t *testing.T) {
- testStackDeployHelp(t, "swarm")
- })
-- t.Run("Kubernetes", func(t *testing.T) {
-- testStackDeployHelp(t, "kubernetes")
-- })
- }
-
- func testStackDeployHelp(t *testing.T, orchestrator string) {
-diff --git a/e2e/stack/remove_test.go b/e2e/stack/remove_test.go
-index f6222000d62..8469786acb5 100644
---- a/e2e/stack/remove_test.go
-+++ b/e2e/stack/remove_test.go
-@@ -9,7 +9,6 @@ import (
- "gotest.tools/v3/golden"
- "gotest.tools/v3/icmd"
- "gotest.tools/v3/poll"
-- "gotest.tools/v3/skip"
- )
-
- var pollSettings = environment.DefaultPollSettings
-@@ -18,11 +17,6 @@ func TestRemove(t *testing.T) {
- t.Run("Swarm", func(t *testing.T) {
- testRemove(t, "swarm")
- })
-- t.Run("Kubernetes", func(t *testing.T) {
-- skip.If(t, !environment.KubernetesEnabled())
--
-- testRemove(t, "kubernetes")
-- })
- }
-
- func testRemove(t *testing.T, orchestrator string) {
-diff --git a/e2e/stack/testdata/stack-deploy-help-kubernetes.golden b/e2e/stack/testdata/stack-deploy-help-kubernetes.golden
-deleted file mode 100644
-index e3f8e30f561..00000000000
---- a/e2e/stack/testdata/stack-deploy-help-kubernetes.golden
-+++ /dev/null
-@@ -1,14 +0,0 @@
--
--Usage: docker stack deploy [OPTIONS] STACK
--
--Deploy a new stack or update an existing stack
--
--Aliases:
-- deploy, up
--
--Options:
-- -c, --compose-file strings Path to a Compose file, or "-" to read
-- from stdin
-- --kubeconfig string Kubernetes config file
-- --namespace string Kubernetes namespace to use
-- --orchestrator string Orchestrator to use (swarm|kubernetes|all)
-diff --git a/e2e/stack/testdata/stack-deploy-help-swarm.golden b/e2e/stack/testdata/stack-deploy-help-swarm.golden
-index f21c5d316e4..5f8ed3de7b2 100644
---- a/e2e/stack/testdata/stack-deploy-help-swarm.golden
-+++ b/e2e/stack/testdata/stack-deploy-help-swarm.golden
-@@ -9,7 +9,7 @@ Aliases:
- Options:
- -c, --compose-file strings Path to a Compose file, or "-" to read
- from stdin
-- --orchestrator string Orchestrator to use (swarm|kubernetes|all)
-+ --orchestrator string Orchestrator to use (swarm|all)
- --prune Prune services that are no longer referenced
- --resolve-image string Query the registry to resolve image digest
- and supported platforms
-diff --git a/e2e/stack/testdata/stack-deploy-with-names-kubernetes.golden b/e2e/stack/testdata/stack-deploy-with-names-kubernetes.golden
-deleted file mode 100644
-index f97dd682cf6..00000000000
---- a/e2e/stack/testdata/stack-deploy-with-names-kubernetes.golden
-+++ /dev/null
-@@ -1,7 +0,0 @@
--Creating network test-stack-deploy-with-names_network2
--Creating network named-network
--Creating secret named-secret
--Creating secret test-stack-deploy-with-names_secret2
--Creating config test-stack-deploy-with-names_config2
--Creating config named-config
--Creating service test-stack-deploy-with-names_web
-diff --git a/e2e/stack/testdata/stack-remove-kubernetes-success.golden b/e2e/stack/testdata/stack-remove-kubernetes-success.golden
-deleted file mode 100644
-index 3c136713983..00000000000
---- a/e2e/stack/testdata/stack-remove-kubernetes-success.golden
-+++ /dev/null
-@@ -1 +0,0 @@
--Removing stack: test-stack-remove-kubernetes
diff --git a/0001-Revert-vendor-github.com-docker-docker.patch b/0001-Revert-vendor-github.com-docker-docker.patch
new file mode 100644
index 0000000..61a8443
--- /dev/null
+++ b/0001-Revert-vendor-github.com-docker-docker.patch
@@ -0,0 +1,195 @@
+From 14a11f4bbc396dfa99e5755d24d3854eb6070cda Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Robert-Andr=C3=A9=20Mauchin?= <zebob.m(a)gmail.com>
+Date: Sun, 9 Oct 2022 18:31:59 +0200
+Subject: [PATCH] Revert "vendor: github.com/docker/docker
+
+This reverts commit 7aa0b273e545182abddacceb79ea7e6c7dcc03fb.
+---
+ cli/command/container/restart.go | 28 +++++++++++----------------
+ cli/command/container/stop.go | 18 +++++++----------
+ docs/reference/commandline/restart.md | 4 ++--
+ docs/reference/commandline/stop.md | 4 ++--
+ 4 files changed, 22 insertions(+), 32 deletions(-)
+
+diff --git a/cli/command/container/restart.go b/cli/command/container/restart.go
+index b86b822e1c..e710daac8a 100644
+--- a/cli/command/container/restart.go
++++ b/cli/command/container/restart.go
+@@ -4,19 +4,18 @@ import (
+ "context"
+ "fmt"
+ "strings"
++ "time"
+
+ "github.com/docker/cli/cli"
+ "github.com/docker/cli/cli/command"
+ "github.com/docker/cli/cli/command/completion"
+- "github.com/docker/docker/api/types/container"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+ )
+
+ type restartOptions struct {
+- signal string
+- timeout int
+- timeoutChanged bool
++ nSeconds int
++ nSecondsChanged bool
+
+ containers []string
+ }
+@@ -31,35 +30,31 @@ func NewRestartCommand(dockerCli command
+ Args: cli.RequiresMinArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ opts.containers = args
+- opts.timeoutChanged = cmd.Flags().Changed("time")
++ opts.nSecondsChanged = cmd.Flags().Changed("time")
+ return runRestart(dockerCli, &opts)
+ },
+ ValidArgsFunction: completion.ContainerNames(dockerCli, true),
+ }
+
+ flags := cmd.Flags()
+- flags.StringVarP(&opts.signal, "signal", "s", "", "Signal to send to the container")
+- flags.IntVarP(&opts.timeout, "time", "t", 0, "Seconds to wait before killing the container")
++ flags.IntVarP(&opts.nSeconds, "time", "t", 10, "Seconds to wait for stop before killing the container")
+ return cmd
+ }
+
+ func runRestart(dockerCli command.Cli, opts *restartOptions) error {
+ ctx := context.Background()
+ var errs []string
+- var timeout *int
+- if opts.timeoutChanged {
+- timeout = &opts.timeout
++ var timeout *time.Duration
++ if opts.nSecondsChanged {
++ timeoutValue := time.Duration(opts.nSeconds) * time.Second
++ timeout = &timeoutValue
+ }
+ for _, name := range opts.containers {
+- err := dockerCli.Client().ContainerRestart(ctx, name, container.StopOptions{
+- Signal: opts.signal,
+- Timeout: timeout,
+- })
+- if err != nil {
++ if err := dockerCli.Client().ContainerRestart(ctx, name, timeout); err != nil {
+ errs = append(errs, err.Error())
+ continue
+ }
+- _, _ = fmt.Fprintln(dockerCli.Out(), name)
++ fmt.Fprintln(dockerCli.Out(), name)
+ }
+ if len(errs) > 0 {
+ return errors.New(strings.Join(errs, "\n"))
+diff --git a/cli/command/container/stop.go b/cli/command/container/stop.go
+index e5664617b1..aceb6e2a0d 100644
+--- a/cli/command/container/stop.go
++++ b/cli/command/container/stop.go
+@@ -4,19 +4,18 @@ import (
+ "context"
+ "fmt"
+ "strings"
++ "time"
+
+ "github.com/docker/cli/cli"
+ "github.com/docker/cli/cli/command"
+ "github.com/docker/cli/cli/command/completion"
+- "github.com/docker/docker/api/types/container"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+ )
+
+ type stopOptions struct {
+- signal string
+- timeout int
+- timeoutChanged bool
++ time int
++ timeChanged bool
+
+ containers []string
+ }
+@@ -31,37 +31,36 @@ func NewStopCommand(dockerCli command.Cl
+ Args: cli.RequiresMinArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ opts.containers = args
+- opts.timeoutChanged = cmd.Flags().Changed("time")
++ opts.timeChanged = cmd.Flags().Changed("time")
+ return runStop(dockerCli, &opts)
+ },
+ ValidArgsFunction: completion.ContainerNames(dockerCli, false),
+ }
+
+ flags := cmd.Flags()
+- flags.StringVarP(&opts.signal, "signal", "s", "", "Signal to send to the container")
+- flags.IntVarP(&opts.timeout, "time", "t", 0, "Seconds to wait before killing the container")
++ flags.IntVarP(&opts.time, "time", "t", 10, "Seconds to wait for stop before killing it")
+ return cmd
+ }
+
+ func runStop(dockerCli command.Cli, opts *stopOptions) error {
+- var timeout *int
+- if opts.timeoutChanged {
+- timeout = &opts.timeout
++ ctx := context.Background()
++
++ var timeout *time.Duration
++ if opts.timeChanged {
++ timeoutValue := time.Duration(opts.time) * time.Second
++ timeout = &timeoutValue
+ }
+
+- errChan := parallelOperation(context.Background(), opts.containers, func(ctx context.Context, id string) error {
+- return dockerCli.Client().ContainerStop(ctx, id, container.StopOptions{
+- Signal: opts.signal,
+- Timeout: timeout,
+- })
+- })
+ var errs []string
+- for _, ctr := range opts.containers {
++ errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, id string) error {
++ return dockerCli.Client().ContainerStop(ctx, id, timeout)
++ })
++ for _, container := range opts.containers {
+ if err := <-errChan; err != nil {
+ errs = append(errs, err.Error())
+ continue
+ }
+- _, _ = fmt.Fprintln(dockerCli.Out(), ctr)
++ fmt.Fprintln(dockerCli.Out(), container)
+ }
+ if len(errs) > 0 {
+ return errors.New(strings.Join(errs, "\n"))
+diff --git a/docs/reference/commandline/restart.md b/docs/reference/commandline/restart.md
+index 30cd15812b..aa64257d86 100644
+--- a/docs/reference/commandline/restart.md
++++ b/docs/reference/commandline/restart.md
+@@ -12,8 +12,8 @@ Usage: docker restart [OPTIONS] CONTAINER [CONTAINER...]
+ Restart one or more containers
+
+ Options:
+- -s, --signal string Signal to send to the container
+- -t, --time int Seconds to wait before killing the container
++ --help Print usage
++ -t, --time int Seconds to wait for stop before killing the container (default 10)
+ ```
+
+ ## Examples
+diff --git a/docs/reference/commandline/stop.md b/docs/reference/commandline/stop.md
+index 04df574a03..fdc7d0ae72 100644
+--- a/docs/reference/commandline/stop.md
++++ b/docs/reference/commandline/stop.md
+@@ -12,8 +12,8 @@ Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
+ Stop one or more running containers
+
+ Options:
+- -s, --signal string Signal to send to the container
+- -t, --time int Seconds to wait before killing the container
++ --help Print usage
++ -t, --time int Seconds to wait for stop before killing it (default 10)
+ ```
+
+ ## Description
+--
+2.37.3
+
diff --git a/0002-Remove-kubeapi-from-version.patch b/0002-Remove-kubeapi-from-version.patch
deleted file mode 100644
index 81a42a0..0000000
--- a/0002-Remove-kubeapi-from-version.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-diff -up cli-20.10.7/cli/command/system/version.go.orig cli-20.10.7/cli/command/system/version.go
---- cli-20.10.7/cli/command/system/version.go.orig 2021-05-31 11:40:07.000000000 +0200
-+++ cli-20.10.7/cli/command/system/version.go 2021-08-03 12:49:14.080765782 +0200
-@@ -15,7 +15,6 @@ import (
- "github.com/docker/cli/cli/version"
- "github.com/docker/cli/kubernetes"
- "github.com/docker/cli/templates"
-- kubeapi "github.com/docker/compose-on-kubernetes/api"
- "github.com/docker/docker/api/types"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-@@ -255,9 +254,7 @@ func getKubernetesVersion(dockerCli comm
- clientConfig clientcmd.ClientConfig
- err error
- )
-- if dockerCli.CurrentContext() == "" {
-- clientConfig = kubeapi.NewKubernetesConfig(kubeConfig)
-- } else {
-+ if dockerCli.CurrentContext() != "" {
- clientConfig, err = kubecontext.ConfigFromContext(dockerCli.CurrentContext(), dockerCli.ContextStore())
- }
- if err != nil {
diff --git a/golang-github-docker-cli.spec b/golang-github-docker-cli.spec
index 327243d..5cee025 100644
--- a/golang-github-docker-cli.spec
+++ b/golang-github-docker-cli.spec
@@ -1,23 +1,14 @@
-# Generated by go2rpm 1.5.0
+# Generated by go2rpm 1.8.2
%bcond_without check
-%bcond_with bootstrap
-%if %{with bootstrap}
-%global __requires_exclude %{?__requires_exclude:%{__requires_exclude}|}^golang\\(.*\\)$
-%endif
+%global debug_package %{nil}
# https://github.com/docker/cli
%global goipath github.com/docker/cli
-Version: 20.10.7
+Version: 22.06.0~beta.0
+%global tag v22.06.0-beta.0
%gometa
-%global goipaths0 github.com/docker/cli
-%global goipathsex0 github.com/docker/cli/cli/command/image
-
-%if %{without bootstrap}
-%global goipaths1 github.com/docker/cli/cli/command/image
-%endif
-
%global common_description %{expand:
The docker CLI.}
@@ -28,138 +19,24 @@ Name: %{goname}
Release: %autorelease
Summary: The docker CLI
-# Upstream license specification: Apache-2.0
-License: ASL 2.0
+License: Apache-2.0
URL: %{gourl}
-Source0: %{gosource}
-# https://github.com/docker/cli/issues/2967
-Patch0: 0001-Drop-obsolete-compose-on-kubernetes.patch
-Patch1: 0002-Remove-kubeapi-from-version.patch
-
-%if %{without bootstrap}
-BuildRequires: golang(github.com/containerd/console)
-BuildRequires: golang(github.com/containerd/containerd/platforms)
-BuildRequires: golang(github.com/docker/distribution)
-BuildRequires: golang(github.com/docker/distribution/manifest/manifestlist)
-BuildRequires: golang(github.com/docker/distribution/manifest/schema2)
-BuildRequires: golang(github.com/docker/distribution/reference)
-BuildRequires: golang(github.com/docker/distribution/registry/api/errcode)
-BuildRequires: golang(github.com/docker/distribution/registry/api/v2)
-BuildRequires: golang(github.com/docker/distribution/registry/client)
-BuildRequires: golang(github.com/docker/distribution/registry/client/auth)
-BuildRequires: golang(github.com/docker/distribution/registry/client/auth/challenge)
-BuildRequires: golang(github.com/docker/distribution/registry/client/transport)
-BuildRequires: golang(github.com/docker/docker-credential-helpers/client)
-BuildRequires: golang(github.com/docker/docker-credential-helpers/credentials)
-BuildRequires: golang(github.com/docker/docker/api)
-BuildRequires: golang(github.com/docker/docker/api/types)
-BuildRequires: golang(github.com/docker/docker/api/types/blkiodev)
-BuildRequires: golang(github.com/docker/docker/api/types/container)
-BuildRequires: golang(github.com/docker/docker/api/types/events)
-BuildRequires: golang(github.com/docker/docker/api/types/filters)
-BuildRequires: golang(github.com/docker/docker/api/types/image)
-BuildRequires: golang(github.com/docker/docker/api/types/mount)
-BuildRequires: golang(github.com/docker/docker/api/types/network)
-BuildRequires: golang(github.com/docker/docker/api/types/registry)
-BuildRequires: golang(github.com/docker/docker/api/types/strslice)
-BuildRequires: golang(github.com/docker/docker/api/types/swarm)
-BuildRequires: golang(github.com/docker/docker/api/types/versions)
-BuildRequires: golang(github.com/docker/docker/api/types/volume)
-BuildRequires: golang(github.com/docker/docker/builder/remotecontext/git)
-BuildRequires: golang(github.com/docker/docker/client)
-BuildRequires: golang(github.com/docker/docker/errdefs)
-BuildRequires: golang(github.com/docker/docker/pkg/archive)
-BuildRequires: golang(github.com/docker/docker/pkg/fileutils)
-BuildRequires: golang(github.com/docker/docker/pkg/homedir)
-BuildRequires: golang(github.com/docker/docker/pkg/idtools)
-BuildRequires: golang(github.com/docker/docker/pkg/ioutils)
-BuildRequires: golang(github.com/docker/docker/pkg/jsonmessage)
-BuildRequires: golang(github.com/docker/docker/pkg/pools)
-BuildRequires: golang(github.com/docker/docker/pkg/progress)
-BuildRequires: golang(github.com/docker/docker/pkg/signal)
-BuildRequires: golang(github.com/docker/docker/pkg/stdcopy)
-BuildRequires: golang(github.com/docker/docker/pkg/streamformatter)
-BuildRequires: golang(github.com/docker/docker/pkg/stringid)
-BuildRequires: golang(github.com/docker/docker/pkg/system)
-BuildRequires: golang(github.com/docker/docker/pkg/urlutil)
-BuildRequires: golang(github.com/docker/docker/registry)
-BuildRequires: golang(github.com/docker/go-connections/nat)
-BuildRequires: golang(github.com/docker/go-connections/tlsconfig)
-BuildRequires: golang(github.com/docker/go-units)
-BuildRequires: golang(github.com/docker/swarmkit/api)
-BuildRequires: golang(github.com/docker/swarmkit/api/defaults)
-BuildRequires: golang(github.com/docker/swarmkit/api/genericresource)
-BuildRequires: golang(github.com/fvbommel/sortorder)
-BuildRequires: golang(github.com/gogo/protobuf/types)
-BuildRequires: golang(github.com/google/shlex)
-BuildRequires: golang(github.com/imdario/mergo)
-BuildRequires: golang(github.com/mitchellh/mapstructure)
-BuildRequires: golang(github.com/moby/buildkit/api/services/control)
-BuildRequires: golang(github.com/moby/buildkit/client)
-BuildRequires: golang(github.com/moby/buildkit/frontend/dockerfile/dockerignore)
-BuildRequires: golang(github.com/moby/buildkit/session)
-BuildRequires: golang(github.com/moby/buildkit/session/auth/authprovider)
-BuildRequires: golang(github.com/moby/buildkit/session/filesync)
-BuildRequires: golang(github.com/moby/buildkit/session/secrets/secretsprovider)
-BuildRequires: golang(github.com/moby/buildkit/session/sshforward/sshprovider)
-BuildRequires: golang(github.com/moby/buildkit/util/appcontext)
-BuildRequires: golang(github.com/moby/buildkit/util/progress/progressui)
-BuildRequires: golang(github.com/moby/buildkit/util/progress/progresswriter)
-BuildRequires: golang(github.com/moby/term)
-BuildRequires: golang(github.com/morikuni/aec)
-BuildRequires: golang(github.com/opencontainers/go-digest)
-BuildRequires: golang(github.com/opencontainers/image-spec/specs-go/v1)
-BuildRequires: golang(github.com/pkg/errors)
-BuildRequires: golang(github.com/sirupsen/logrus)
-BuildRequires: golang(github.com/spf13/cobra)
-BuildRequires: golang(github.com/spf13/cobra/doc)
-BuildRequires: golang(github.com/spf13/pflag)
-BuildRequires: golang(github.com/theupdateframework/notary)
-BuildRequires: golang(github.com/theupdateframework/notary/client)
-BuildRequires: golang(github.com/theupdateframework/notary/client/changelist)
-BuildRequires: golang(github.com/theupdateframework/notary/cryptoservice)
-BuildRequires: golang(github.com/theupdateframework/notary/passphrase)
-BuildRequires: golang(github.com/theupdateframework/notary/storage)
-BuildRequires: golang(github.com/theupdateframework/notary/trustmanager)
-BuildRequires: golang(github.com/theupdateframework/notary/trustpinning)
-BuildRequires: golang(github.com/theupdateframework/notary/tuf/data)
-BuildRequires: golang(github.com/theupdateframework/notary/tuf/signed)
-BuildRequires: golang(github.com/theupdateframework/notary/tuf/utils)
-BuildRequires: golang(github.com/tonistiigi/fsutil/types)
-BuildRequires: golang(github.com/tonistiigi/go-rosetta)
-BuildRequires: golang(github.com/xeipuuv/gojsonschema)
-BuildRequires: golang(golang.org/x/sync/errgroup)
-BuildRequires: golang(golang.org/x/sys/execabs)
-BuildRequires: golang(golang.org/x/sys/unix)
-BuildRequires: golang(golang.org/x/term)
-BuildRequires: golang(golang.org/x/text/width)
-BuildRequires: golang(gopkg.in/yaml.v2)
-BuildRequires: golang(gotest.tools/v3/assert)
-BuildRequires: golang(gotest.tools/v3/assert/cmp)
-BuildRequires: golang(gotest.tools/v3/fs)
-BuildRequires: golang(gotest.tools/v3/icmd)
-BuildRequires: golang(gotest.tools/v3/poll)
-BuildRequires: golang(gotest.tools/v3/skip)
-
-%if %{with check}
-# Tests
-BuildRequires: golang(github.com/google/go-cmp/cmp)
-BuildRequires: golang(github.com/google/go-cmp/cmp/cmpopts)
-BuildRequires: golang(gotest.tools/v3/env)
-BuildRequires: golang(gotest.tools/v3/golden)
-%endif
-%endif
+Source: %{gosource}
+# For compatibility with current Swarmkit
+# https://github.com/moby/swarmkit/issues/3081
+Patch0: 0001-Revert-vendor-github.com-docker-docker.patch
-%description
-%{common_description}
+%description %{common_description}
%gopkg
%prep
%goprep
-%autopatch -p1
-# Dropping the rest of k8s
-rm -rfv kubernetes
+%patch0 -p1
+sed -i "s|github.com/docker/distribution|github.com/distribution/distribution/v3|" $(find . -iname "*.go" -type f)
+
+%generate_buildrequires
+%go_generate_buildrequires
# %%build
# for cmd in cmd/* ; do
@@ -173,11 +50,7 @@ rm -rfv kubernetes
%%if %{with check}
%check
-%gocheck -t cmd \
- -t cli/command \
- -t cli/context \
- -d internal/containerizedengine \
- -t kubernetes
+%gocheck -t cli
%endif
# %%files
diff --git a/sources b/sources
index 8d233e5..7f896d4 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (cli-20.10.7.tar.gz) = 4523ae70cb27d848da119070171af2eb84e974ac39d70be4feee105e37c949487c7f72a9bc30c32ce71bffb0787e27b7b9194ce5a8aeae57bdfeb3f2d730010f
+SHA512 (cli-22.06.0-beta.0.tar.gz) = 69e7b7d7df099344f1b7f4bb5f65258e2fdc1abdd9d7051d3e1dade478f0b38d66d2f3762adf45d8649168de0d25150e44182de15ad51858141a5267c650f652
https://src.fedoraproject.org/rpms/golang-github-docker-cli/c/e1e997eca7d...
1Â year, 5Â months