Skip to content

Commit 5d0e234

Browse files
committed
feat: add ssh
1 parent d3f6962 commit 5d0e234

132 files changed

Lines changed: 9989 additions & 111 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cmd/deploy.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,10 @@ func runPipeline(ctx *devspacecontext.Context, f factory.Factory, forceLeader bo
325325
ctx.Log.Debugf("Wait for dev to finish")
326326

327327
// wait for dev
328-
pipe.WaitDev()
328+
err = pipe.WaitDev()
329+
if err != nil {
330+
return err
331+
}
329332

330333
return nil
331334
}

cmd/open.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bufio"
55
"context"
66
"fmt"
7+
"github.com/loft-sh/devspace/helper/util/port"
78
"github.com/loft-sh/devspace/pkg/devspace/config/localcache"
89
devspacecontext "github.com/loft-sh/devspace/pkg/devspace/context"
910
"github.com/loft-sh/devspace/pkg/devspace/services/portforwarding"
@@ -31,7 +32,6 @@ import (
3132
"github.com/loft-sh/devspace/pkg/util/hash"
3233
"github.com/loft-sh/devspace/pkg/util/log"
3334
"github.com/loft-sh/devspace/pkg/util/message"
34-
"github.com/loft-sh/devspace/pkg/util/port"
3535
"github.com/loft-sh/devspace/pkg/util/survey"
3636

3737
"github.com/mgutz/ansi"
@@ -298,10 +298,10 @@ func (cmd *OpenCmd) openLocal(ctx *devspacecontext.Context, domain string) error
298298
}
299299

300300
// Check if port is open
301-
portOpen, _ := port.Check(localPort)
302-
for !portOpen {
301+
portOpen, _ := port.IsAvailable(fmt.Sprintf(":%d", localPort))
302+
for i := 0; i < 10 && !portOpen; i++ {
303303
localPort++
304-
portOpen, _ = port.Check(localPort)
304+
portOpen, _ = port.IsAvailable(fmt.Sprintf(":%d", localPort))
305305
}
306306
}
307307

cmd/overwrite_command.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ import (
1616
type OverwriteCmd struct {
1717
*flags.GlobalFlags
1818

19-
Command *latest.CommandConfig
20-
Stdout io.Writer
21-
Stderr io.Writer
19+
Command *latest.CommandConfig
20+
Variables map[string]interface{}
21+
22+
Stdout io.Writer
23+
Stderr io.Writer
2224
}
2325

2426
// NewOverwriteCmd creates a new overwrite command
25-
func NewOverwriteCmd(f factory.Factory, globalFlags *flags.GlobalFlags, command *latest.CommandConfig) *cobra.Command {
27+
func NewOverwriteCmd(f factory.Factory, globalFlags *flags.GlobalFlags, command *latest.CommandConfig, variables map[string]interface{}) *cobra.Command {
2628
cmd := &OverwriteCmd{
2729
GlobalFlags: globalFlags,
2830
Command: command,
31+
Variables: variables,
2932
Stdout: os.Stdout,
3033
Stderr: os.Stderr,
3134
}
@@ -63,5 +66,5 @@ func NewOverwriteCmd(f factory.Factory, globalFlags *flags.GlobalFlags, command
6366

6467
func (cmd *OverwriteCmd) Run(f factory.Factory, args []string) error {
6568
devCtx := devspacecontext.NewContext(context.Background(), f.GetLog())
66-
return ExecuteCommand(devCtx.Context, cmd.Command, nil, args, devCtx.WorkingDir, cmd.Stdout, cmd.Stderr, os.Stdin)
69+
return ExecuteCommand(devCtx.Context, cmd.Command, cmd.Variables, args, devCtx.WorkingDir, cmd.Stdout, cmd.Stderr, os.Stdin)
6770
}

cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,11 @@ Additional run commands:
269269
}
270270

271271
func replaceCommand(command string, rawConfig *RawConfig, f factory.Factory, globalFlags *flags.GlobalFlags, fallback func(f factory.Factory, globalFlags *flags.GlobalFlags) *cobra.Command) *cobra.Command {
272-
if rawConfig != nil && rawConfig.CommandsConfig != nil && rawConfig.CommandsConfig.Commands != nil {
272+
if rawConfig != nil && rawConfig.CommandsConfig != nil && rawConfig.Resolver != nil && rawConfig.CommandsConfig.Commands != nil {
273273
// get command
274274
overwriteCommand, ok := rawConfig.CommandsConfig.Commands[command]
275275
if ok && !overwriteCommand.DisableReplace {
276-
return NewOverwriteCmd(f, globalFlags, overwriteCommand)
276+
return NewOverwriteCmd(f, globalFlags, overwriteCommand, rawConfig.Resolver.ResolvedVariables())
277277
}
278278
}
279279

cmd/ui.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"github.com/loft-sh/devspace/helper/util/port"
78
"github.com/loft-sh/devspace/pkg/devspace/config/localcache"
89
devspacecontext "github.com/loft-sh/devspace/pkg/devspace/context"
910
"github.com/loft-sh/devspace/pkg/devspace/kubectl"
@@ -20,7 +21,6 @@ import (
2021
"github.com/loft-sh/devspace/pkg/devspace/server"
2122
"github.com/loft-sh/devspace/pkg/util/factory"
2223
"github.com/loft-sh/devspace/pkg/util/log"
23-
"github.com/loft-sh/devspace/pkg/util/port"
2424
"github.com/pkg/errors"
2525
"github.com/skratchdot/open-golang/open"
2626
"github.com/spf13/cobra"
@@ -92,8 +92,8 @@ func (cmd *UICmd) RunUI(f factory.Factory) error {
9292
}
9393

9494
for i := 0; i < 20; i++ {
95-
unused, err := port.CheckHostPort(cmd.Host, checkPort)
96-
if !unused {
95+
available, _ := port.IsAvailable(fmt.Sprintf(":%d", checkPort))
96+
if !available {
9797
if i+1 == 20 {
9898
return errors.Wrap(err, "check for open port")
9999
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ require (
88
github.com/blang/semver v3.5.1+incompatible
99
github.com/bmatcuk/doublestar v1.1.1
1010
github.com/compose-spec/compose-go v1.0.1
11+
github.com/creack/pty v1.1.15
1112
github.com/docker/cli v20.10.0-beta1.0.20201029214301-1d20b15adc38+incompatible
1213
github.com/docker/distribution v2.7.1+incompatible
1314
github.com/docker/docker v20.10.5+incompatible
1415
github.com/docker/go-connections v0.4.0
1516
github.com/evanphx/json-patch v4.12.0+incompatible
1617
github.com/evanphx/json-patch/v5 v5.1.0
1718
github.com/ghodss/yaml v1.0.0
19+
github.com/gliderlabs/ssh v0.3.3
1820
github.com/google/uuid v1.1.2
1921
github.com/gorilla/websocket v1.4.2
2022
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf // indirect
@@ -34,6 +36,7 @@ require (
3436
github.com/otiai10/copy v0.0.0-20180813030456-0046ee23fdbd
3537
github.com/otiai10/mint v1.3.3 // indirect
3638
github.com/pkg/errors v0.9.1
39+
github.com/pkg/sftp v1.10.1
3740
github.com/postfinance/single v0.0.1 // indirect
3841
github.com/rhysd/go-github-selfupdate v0.0.0-20180520142321-41c1bbb0804a
3942
github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94

go.sum

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
159159
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
160160
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
161161
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
162+
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
163+
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
162164
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
163165
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
164166
github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ=
@@ -398,6 +400,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
398400
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
399401
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
400402
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
403+
github.com/gliderlabs/ssh v0.3.3 h1:mBQ8NiOgDkINJrZtoizkC3nDNYgSaWtxyem6S2XHBtA=
404+
github.com/gliderlabs/ssh v0.3.3/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914=
401405
github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g=
402406
github.com/go-critic/go-critic v0.4.3/go.mod h1:j4O3D4RoIwRqlZw5jJpx0BNfXWWbpcJoKu5cYSe4YmQ=
403407
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
@@ -727,6 +731,7 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
727731
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
728732
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
729733
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
734+
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
730735
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
731736
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
732737
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -928,6 +933,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
928933
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
929934
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
930935
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
936+
github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc=
931937
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
932938
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
933939
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -1223,6 +1229,7 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPh
12231229
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
12241230
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
12251231
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
1232+
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
12261233
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
12271234
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
12281235
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=

helper/cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func BuildRoot() *cobra.Command {
3737
rootCmd.AddCommand(NewRestartCmd())
3838
rootCmd.AddCommand(NewVersionCmd())
3939
rootCmd.AddCommand(NewTunnelCmd())
40+
rootCmd.AddCommand(NewSSHCmd())
4041
rootCmd.AddCommand(sync.NewSyncCmd())
4142

4243
return rootCmd

helper/cmd/ssh.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package cmd
2+
3+
import (
4+
"encoding/base64"
5+
"fmt"
6+
"github.com/gliderlabs/ssh"
7+
helperssh "github.com/loft-sh/devspace/helper/ssh"
8+
"github.com/loft-sh/devspace/helper/tunnel"
9+
"github.com/loft-sh/devspace/helper/util/port"
10+
"github.com/pkg/errors"
11+
"github.com/spf13/cobra"
12+
)
13+
14+
// SSHCmd holds the ssh cmd flags
15+
type SSHCmd struct {
16+
AuthorizedKeys string
17+
Address string
18+
}
19+
20+
// NewSSHCmd creates a new ssh command
21+
func NewSSHCmd() *cobra.Command {
22+
cmd := &SSHCmd{}
23+
sshCmd := &cobra.Command{
24+
Use: "ssh",
25+
Short: "Starts a new ssh server",
26+
Args: cobra.NoArgs,
27+
RunE: cmd.Run,
28+
}
29+
30+
sshCmd.Flags().StringVar(&cmd.Address, "address", fmt.Sprintf(":%d", helperssh.DefaultPort), "Address to listen to")
31+
sshCmd.Flags().StringVar(&cmd.AuthorizedKeys, "authorized-key", "", "Base64 encoded authorized keys to use")
32+
return sshCmd
33+
}
34+
35+
// Run runs the command logic
36+
func (cmd *SSHCmd) Run(cobraCmd *cobra.Command, args []string) error {
37+
var keys []ssh.PublicKey
38+
if cmd.AuthorizedKeys != "" {
39+
keyBytes, err := base64.StdEncoding.DecodeString(cmd.AuthorizedKeys)
40+
if err != nil {
41+
return fmt.Errorf("seems like the provided encoded string is not base64 encoded")
42+
}
43+
44+
for len(keyBytes) > 0 {
45+
key, _, _, rest, err := ssh.ParseAuthorizedKey(keyBytes)
46+
if err != nil {
47+
return errors.Wrap(err, "parse authorized key")
48+
}
49+
50+
keys = append(keys, key)
51+
keyBytes = rest
52+
}
53+
}
54+
55+
server, err := helperssh.NewServer(cmd.Address, keys)
56+
if err != nil {
57+
return err
58+
}
59+
60+
// check if ssh is already running at that port
61+
available, err := port.IsAvailable(cmd.Address)
62+
if !available {
63+
if err != nil {
64+
return fmt.Errorf("address %s already in use: %v", cmd.Address, err)
65+
}
66+
67+
tunnel.LogDebugf("address %s already in use", cmd.Address)
68+
return nil
69+
}
70+
71+
return server.ListenAndServe()
72+
}

0 commit comments

Comments
 (0)