Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strconv"
"strings"

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

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

devConfig.SSH = &latest.SSH{
Enabled: true,
Enabled: ptr.Bool(true),
}

if devConfig.ProxyCommands == nil {
Expand Down
126 changes: 112 additions & 14 deletions e2e/tests/ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package ssh

import (
"context"
"github.com/onsi/ginkgo/v2"
"os"
"os/exec"
"time"
Expand All @@ -12,7 +11,8 @@ import (
"github.com/loft-sh/devspace/e2e/framework"
"github.com/loft-sh/devspace/e2e/kube"
"github.com/loft-sh/devspace/pkg/util/factory"
"k8s.io/apimachinery/pkg/util/wait"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
)

var _ = DevSpaceDescribe("ssh", func() {
Expand All @@ -34,19 +34,19 @@ var _ = DevSpaceDescribe("ssh", func() {
framework.ExpectNoError(err)
})

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

ns, err := kubeClient.CreateNamespace("ssh")
framework.ExpectNoError(err)
defer framework.ExpectDeleteNamespace(kubeClient, ns)
ginkgo.DeferCleanup(framework.ExpectDeleteNamespace, kubeClient, ns)

// create a new dev command and start it
done := make(chan error)
cancelCtx, cancel := context.WithCancel(context.Background())
defer cancel()
ginkgo.DeferCleanup(cancel)

go func() {
defer ginkgo.GinkgoRecover()
Expand All @@ -64,20 +64,118 @@ var _ = DevSpaceDescribe("ssh", func() {
}()

// connect to the SSH server
err = wait.PollImmediate(time.Second, time.Minute*2, func() (bool, error) {
gomega.Eventually(func(g gomega.Gomega) {
cmd := exec.Command("ssh", "test.ssh-simple.devspace", "ls")
err := cmd.Run()
if err != nil {
return false, nil
}
g.Expect(err).NotTo(gomega.HaveOccurred())

cancel()
}).
WithPolling(time.Second).
WithTimeout(time.Second * 60).
Should(gomega.Succeed())

return true, nil
})
err = <-done
framework.ExpectNoError(err)
})

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

err = <-done
ns, err := kubeClient.CreateNamespace("ssh")
framework.ExpectNoError(err)
ginkgo.DeferCleanup(framework.ExpectDeleteNamespace, kubeClient, ns)

// create a new dev command and start it
done := make(chan error)
cancelCtx, cancel := context.WithCancel(context.Background())
ginkgo.DeferCleanup(cancel)

go func() {
defer ginkgo.GinkgoRecover()

devCmd := &cmd.RunPipelineCmd{
GlobalFlags: &flags.GlobalFlags{
NoWarn: true,
Debug: true,
Namespace: ns,
Vars: []string{"SSH=false"},
},
Pipeline: "dev",
Ctx: cancelCtx,
}

done <- devCmd.RunDefault(f)
}()

gomega.Eventually(func(g gomega.Gomega) {
cmd := exec.Command("ssh", "test.ssh-variable.devspace", "ls")
out, err := cmd.CombinedOutput()
output := string(out)
g.Expect(err).To(gomega.HaveOccurred())
g.Expect(output).To(
gomega.Or(
gomega.ContainSubstring("Could not resolve hostname test.ssh-variable.devspace"),
gomega.ContainSubstring("ssh: connect to host localhost port 10023"),
),
)

cancel()
}).
WithPolling(time.Second).
WithTimeout(time.Second * 60).
Should(gomega.Succeed())

cmdErr := <-done
framework.ExpectNoError(cmdErr)
})

ginkgo.It("devspace dev should start an SSH service when enabled with a variable", func(ctx context.Context) {
tempDir, err := framework.CopyToTempDir("tests/ssh/testdata/ssh-variable")
framework.ExpectNoError(err)
ginkgo.DeferCleanup(framework.CleanupTempDir, initialDir, tempDir)

ns, err := kubeClient.CreateNamespace("ssh")
framework.ExpectNoError(err)
ginkgo.DeferCleanup(framework.ExpectDeleteNamespace, kubeClient, ns)

// create a new dev command and start it
done := make(chan error)
cancelCtx, cancel := context.WithCancel(context.Background())
ginkgo.DeferCleanup(cancel)

go func() {
defer ginkgo.GinkgoRecover()

devCmd := &cmd.RunPipelineCmd{
GlobalFlags: &flags.GlobalFlags{
NoWarn: true,
Debug: true,
Namespace: ns,
Vars: []string{"SSH=true"},
},
Pipeline: "dev",
Ctx: cancelCtx,
}

done <- devCmd.RunDefault(f)
}()

// connect to the SSH server
gomega.Eventually(func(g gomega.Gomega) {
cmd := exec.Command("ssh", "test.ssh-variable.devspace", "ls")
err := cmd.Run()
g.Expect(err).NotTo(gomega.HaveOccurred())

cancel()
}).
WithPolling(time.Second).
WithTimeout(time.Second * 60).
Should(gomega.Succeed())

cmdErr := <-done
framework.ExpectNoError(cmdErr)
})
})
1 change: 1 addition & 0 deletions e2e/tests/ssh/testdata/ssh-simple/devspace.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
version: v2beta1
name: ssh-simple
vars:
IMAGE: alpine
deployments:
Expand Down
25 changes: 25 additions & 0 deletions e2e/tests/ssh/testdata/ssh-variable/devspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: v2beta1
name: ssh-variable
vars:
IMAGE: alpine
SSH:
value: true
deployments:
test:
helm:
chart:
name: component-chart
repo: https://charts.devspace.sh
values:
containers:
- image: ${IMAGE}
command: ["sleep"]
args: ["999999999999"]
dev:
test:
imageSelector: ${IMAGE}
ssh:
enabled: ${SSH}
localHostname: test.ssh-variable.devspace
localPort: 10023
remoteAddress: 0.0.0.0:8023
2 changes: 1 addition & 1 deletion pkg/devspace/config/versions/latest/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ type SSH struct {
// Enabled can be used to enable the ssh server within the container. By default,
// DevSpace will generate the required keys and create an entry in your ~/.ssh/config
// for this container that can be used via `ssh dev-config-name.dev-project-name.devspace`
Enabled bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`

// LocalHostname is the local ssh host to write to the ~/.ssh/config
LocalHostname string `yaml:"localHostname,omitempty" json:"localHostname,omitempty"`
Expand Down
7 changes: 3 additions & 4 deletions pkg/devspace/helm/v3/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ import (
"strconv"
"strings"

"github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
devspacecontext "github.com/loft-sh/devspace/pkg/devspace/context"
dependencyutil "github.com/loft-sh/devspace/pkg/devspace/dependency/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"

"github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
"github.com/loft-sh/devspace/pkg/devspace/helm/generic"
"github.com/loft-sh/devspace/pkg/devspace/helm/types"
"github.com/loft-sh/devspace/pkg/util/log"
"github.com/loft-sh/utils/pkg/downloader/commands"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"sigs.k8s.io/yaml"
)

Expand Down
2 changes: 1 addition & 1 deletion pkg/devspace/pipeline/engine/basichandler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package basichandler
import (
"context"
"fmt"
"github.com/loft-sh/devspace/pkg/devspace/config/constants"
"os"
"time"

"github.com/loft-sh/devspace/pkg/devspace/config/constants"
enginecommands "github.com/loft-sh/devspace/pkg/devspace/pipeline/engine/basichandler/commands"
"github.com/loft-sh/devspace/pkg/devspace/pipeline/engine/types"
"github.com/loft-sh/devspace/pkg/util/log"
Expand Down
6 changes: 3 additions & 3 deletions pkg/devspace/services/ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package ssh
import (
"bytes"
"fmt"
"github.com/mgutz/ansi"
"github.com/mitchellh/go-homedir"
"io"
"path/filepath"
"strconv"
Expand All @@ -21,6 +19,8 @@ import (
"github.com/loft-sh/devspace/pkg/devspace/services/targetselector"
"github.com/loft-sh/devspace/pkg/devspace/services/terminal"
"github.com/loft-sh/devspace/pkg/util/tomb"
"github.com/mgutz/ansi"
"github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
kubectlExec "k8s.io/client-go/util/exec"
Expand All @@ -35,7 +35,7 @@ func StartSSH(ctx devspacecontext.Context, devPod *latest.DevPod, selector targe
// init done array is used to track when sync was initialized
initDoneArray := []chan struct{}{}
loader.EachDevContainer(devPod, func(devContainer *latest.DevContainer) bool {
if devContainer.SSH == nil {
if devContainer.SSH == nil || (devContainer.SSH.Enabled != nil && !*devContainer.SSH.Enabled) {
return true
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/util/log/logger.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package log

import (
"io"

"github.com/loft-sh/devspace/pkg/util/survey"
log "github.com/loft-sh/utils/pkg/log"
"github.com/loft-sh/utils/pkg/log"
"github.com/sirupsen/logrus"
"io"
)

// logFunctionType type
Expand Down