Skip to content

Commit 20bb340

Browse files
committed
fix: allow SSH to be enabled and disabled via variable
Fixes #2693 Fixes ENG-1886 Signed-off-by: Russell Centanni <russell.centanni@gmail.com>
1 parent 7c8b944 commit 20bb340

9 files changed

Lines changed: 151 additions & 26 deletions

File tree

cmd/init.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strconv"
1111
"strings"
1212

13+
"github.com/loft-sh/devspace/pkg/util/ptr"
1314
"mvdan.cc/sh/v3/expand"
1415

1516
"github.com/loft-sh/devspace/pkg/devspace/compose"
@@ -759,7 +760,7 @@ func (cmd *InitCmd) addDevConfig(config *latest.Config, imageName, image string,
759760
devConfig.DevImage = devImage
760761

761762
devConfig.SSH = &latest.SSH{
762-
Enabled: true,
763+
Enabled: ptr.Bool(true),
763764
}
764765

765766
if devConfig.ProxyCommands == nil {

e2e/tests/ssh/ssh.go

Lines changed: 112 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package ssh
22

33
import (
44
"context"
5-
"github.com/onsi/ginkgo/v2"
65
"os"
76
"os/exec"
87
"time"
@@ -12,7 +11,8 @@ import (
1211
"github.com/loft-sh/devspace/e2e/framework"
1312
"github.com/loft-sh/devspace/e2e/kube"
1413
"github.com/loft-sh/devspace/pkg/util/factory"
15-
"k8s.io/apimachinery/pkg/util/wait"
14+
"github.com/onsi/ginkgo/v2"
15+
"github.com/onsi/gomega"
1616
)
1717

1818
var _ = DevSpaceDescribe("ssh", func() {
@@ -34,19 +34,19 @@ var _ = DevSpaceDescribe("ssh", func() {
3434
framework.ExpectNoError(err)
3535
})
3636

37-
ginkgo.It("devspace dev should start an SSH service", func() {
37+
ginkgo.It("devspace dev should start an SSH service", func(ctx context.Context) {
3838
tempDir, err := framework.CopyToTempDir("tests/ssh/testdata/ssh-simple")
3939
framework.ExpectNoError(err)
40-
defer framework.CleanupTempDir(initialDir, tempDir)
40+
ginkgo.DeferCleanup(framework.CleanupTempDir, initialDir, tempDir)
4141

4242
ns, err := kubeClient.CreateNamespace("ssh")
4343
framework.ExpectNoError(err)
44-
defer framework.ExpectDeleteNamespace(kubeClient, ns)
44+
ginkgo.DeferCleanup(framework.ExpectDeleteNamespace, kubeClient, ns)
4545

4646
// create a new dev command and start it
4747
done := make(chan error)
4848
cancelCtx, cancel := context.WithCancel(context.Background())
49-
defer cancel()
49+
ginkgo.DeferCleanup(cancel)
5050

5151
go func() {
5252
defer ginkgo.GinkgoRecover()
@@ -64,20 +64,118 @@ var _ = DevSpaceDescribe("ssh", func() {
6464
}()
6565

6666
// connect to the SSH server
67-
err = wait.PollImmediate(time.Second, time.Minute*2, func() (bool, error) {
67+
gomega.Eventually(func(g gomega.Gomega) {
6868
cmd := exec.Command("ssh", "test.ssh-simple.devspace", "ls")
6969
err := cmd.Run()
70-
if err != nil {
71-
return false, nil
72-
}
70+
g.Expect(err).NotTo(gomega.HaveOccurred())
71+
72+
cancel()
73+
}).
74+
WithPolling(time.Second).
75+
WithTimeout(time.Second * 60).
76+
Should(gomega.Succeed())
7377

74-
return true, nil
75-
})
78+
err = <-done
7679
framework.ExpectNoError(err)
80+
})
7781

78-
cancel()
82+
ginkgo.It("devspace dev should NOT start an SSH service when disabled with a variable", func(ctx context.Context) {
83+
tempDir, err := framework.CopyToTempDir("tests/ssh/testdata/ssh-variable")
84+
framework.ExpectNoError(err)
85+
ginkgo.DeferCleanup(framework.CleanupTempDir, initialDir, tempDir)
7986

80-
err = <-done
87+
ns, err := kubeClient.CreateNamespace("ssh")
8188
framework.ExpectNoError(err)
89+
ginkgo.DeferCleanup(framework.ExpectDeleteNamespace, kubeClient, ns)
90+
91+
// create a new dev command and start it
92+
done := make(chan error)
93+
cancelCtx, cancel := context.WithCancel(context.Background())
94+
ginkgo.DeferCleanup(cancel)
95+
96+
go func() {
97+
defer ginkgo.GinkgoRecover()
98+
99+
devCmd := &cmd.RunPipelineCmd{
100+
GlobalFlags: &flags.GlobalFlags{
101+
NoWarn: true,
102+
Debug: true,
103+
Namespace: ns,
104+
Vars: []string{"SSH=false"},
105+
},
106+
Pipeline: "dev",
107+
Ctx: cancelCtx,
108+
}
109+
110+
done <- devCmd.RunDefault(f)
111+
}()
112+
113+
gomega.Eventually(func(g gomega.Gomega) {
114+
cmd := exec.Command("ssh", "test.ssh-variable.devspace", "ls")
115+
out, err := cmd.CombinedOutput()
116+
output := string(out)
117+
g.Expect(err).To(gomega.HaveOccurred())
118+
g.Expect(output).To(
119+
gomega.Or(
120+
gomega.ContainSubstring("Could not resolve hostname test.ssh-variable.devspace"),
121+
gomega.ContainSubstring("ssh: connect to host localhost port 10023"),
122+
),
123+
)
124+
125+
cancel()
126+
}).
127+
WithPolling(time.Second).
128+
WithTimeout(time.Second * 60).
129+
Should(gomega.Succeed())
130+
131+
cmdErr := <-done
132+
framework.ExpectNoError(cmdErr)
133+
})
134+
135+
ginkgo.It("devspace dev should start an SSH service when enabled with a variable", func(ctx context.Context) {
136+
tempDir, err := framework.CopyToTempDir("tests/ssh/testdata/ssh-variable")
137+
framework.ExpectNoError(err)
138+
ginkgo.DeferCleanup(framework.CleanupTempDir, initialDir, tempDir)
139+
140+
ns, err := kubeClient.CreateNamespace("ssh")
141+
framework.ExpectNoError(err)
142+
ginkgo.DeferCleanup(framework.ExpectDeleteNamespace, kubeClient, ns)
143+
144+
// create a new dev command and start it
145+
done := make(chan error)
146+
cancelCtx, cancel := context.WithCancel(context.Background())
147+
ginkgo.DeferCleanup(cancel)
148+
149+
go func() {
150+
defer ginkgo.GinkgoRecover()
151+
152+
devCmd := &cmd.RunPipelineCmd{
153+
GlobalFlags: &flags.GlobalFlags{
154+
NoWarn: true,
155+
Debug: true,
156+
Namespace: ns,
157+
Vars: []string{"SSH=true"},
158+
},
159+
Pipeline: "dev",
160+
Ctx: cancelCtx,
161+
}
162+
163+
done <- devCmd.RunDefault(f)
164+
}()
165+
166+
// connect to the SSH server
167+
gomega.Eventually(func(g gomega.Gomega) {
168+
cmd := exec.Command("ssh", "test.ssh-variable.devspace", "ls")
169+
err := cmd.Run()
170+
g.Expect(err).NotTo(gomega.HaveOccurred())
171+
172+
cancel()
173+
}).
174+
WithPolling(time.Second).
175+
WithTimeout(time.Second * 60).
176+
Should(gomega.Succeed())
177+
178+
cmdErr := <-done
179+
framework.ExpectNoError(cmdErr)
82180
})
83181
})

e2e/tests/ssh/testdata/ssh-simple/devspace.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
version: v2beta1
2+
name: ssh-simple
23
vars:
34
IMAGE: alpine
45
deployments:
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
version: v2beta1
2+
name: ssh-variable
3+
vars:
4+
IMAGE: alpine
5+
SSH:
6+
value: true
7+
deployments:
8+
test:
9+
helm:
10+
chart:
11+
name: component-chart
12+
repo: https://charts.devspace.sh
13+
values:
14+
containers:
15+
- image: ${IMAGE}
16+
command: ["sleep"]
17+
args: ["999999999999"]
18+
dev:
19+
test:
20+
imageSelector: ${IMAGE}
21+
ssh:
22+
enabled: ${SSH}
23+
localHostname: test.ssh-variable.devspace
24+
localPort: 10023
25+
remoteAddress: 0.0.0.0:8023

pkg/devspace/config/versions/latest/schema.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,7 @@ type SSH struct {
10081008
// Enabled can be used to enable the ssh server within the container. By default,
10091009
// DevSpace will generate the required keys and create an entry in your ~/.ssh/config
10101010
// for this container that can be used via `ssh dev-config-name.dev-project-name.devspace`
1011-
Enabled bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
1011+
Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
10121012

10131013
// LocalHostname is the local ssh host to write to the ~/.ssh/config
10141014
LocalHostname string `yaml:"localHostname,omitempty" json:"localHostname,omitempty"`

pkg/devspace/helm/v3/client.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,15 @@ import (
77
"strconv"
88
"strings"
99

10+
"github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
1011
devspacecontext "github.com/loft-sh/devspace/pkg/devspace/context"
1112
dependencyutil "github.com/loft-sh/devspace/pkg/devspace/dependency/util"
12-
"github.com/pkg/errors"
13-
"github.com/sirupsen/logrus"
14-
15-
"github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
1613
"github.com/loft-sh/devspace/pkg/devspace/helm/generic"
1714
"github.com/loft-sh/devspace/pkg/devspace/helm/types"
1815
"github.com/loft-sh/devspace/pkg/util/log"
1916
"github.com/loft-sh/utils/pkg/downloader/commands"
17+
"github.com/pkg/errors"
18+
"github.com/sirupsen/logrus"
2019
"sigs.k8s.io/yaml"
2120
)
2221

pkg/devspace/pipeline/engine/basichandler/handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package basichandler
33
import (
44
"context"
55
"fmt"
6-
"github.com/loft-sh/devspace/pkg/devspace/config/constants"
76
"os"
87
"time"
98

9+
"github.com/loft-sh/devspace/pkg/devspace/config/constants"
1010
enginecommands "github.com/loft-sh/devspace/pkg/devspace/pipeline/engine/basichandler/commands"
1111
"github.com/loft-sh/devspace/pkg/devspace/pipeline/engine/types"
1212
"github.com/loft-sh/devspace/pkg/util/log"

pkg/devspace/services/ssh/ssh.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package ssh
33
import (
44
"bytes"
55
"fmt"
6-
"github.com/mgutz/ansi"
7-
"github.com/mitchellh/go-homedir"
86
"io"
97
"path/filepath"
108
"strconv"
@@ -21,6 +19,8 @@ import (
2119
"github.com/loft-sh/devspace/pkg/devspace/services/targetselector"
2220
"github.com/loft-sh/devspace/pkg/devspace/services/terminal"
2321
"github.com/loft-sh/devspace/pkg/util/tomb"
22+
"github.com/mgutz/ansi"
23+
"github.com/mitchellh/go-homedir"
2424
"github.com/pkg/errors"
2525
"github.com/sirupsen/logrus"
2626
kubectlExec "k8s.io/client-go/util/exec"
@@ -35,7 +35,7 @@ func StartSSH(ctx devspacecontext.Context, devPod *latest.DevPod, selector targe
3535
// init done array is used to track when sync was initialized
3636
initDoneArray := []chan struct{}{}
3737
loader.EachDevContainer(devPod, func(devContainer *latest.DevContainer) bool {
38-
if devContainer.SSH == nil {
38+
if devContainer.SSH == nil || (devContainer.SSH.Enabled != nil && !*devContainer.SSH.Enabled) {
3939
return true
4040
}
4141

pkg/util/log/logger.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package log
22

33
import (
4+
"io"
5+
46
"github.com/loft-sh/devspace/pkg/util/survey"
5-
log "github.com/loft-sh/utils/pkg/log"
7+
"github.com/loft-sh/utils/pkg/log"
68
"github.com/sirupsen/logrus"
7-
"io"
89
)
910

1011
// logFunctionType type

0 commit comments

Comments
 (0)