Skip to content

Commit 3b6960a

Browse files
authored
[cloud] client directly calls start_devbox_server.sh <project dir> (#329)
## Summary This PR updates the cloud client to call `ssh -t <server> "bash -l -c \"start_devbox_server.sh <project-name>\""`. This informs the server about which project to start the `devbox shell` for. ## How was it tested? setup: ``` fly machines run --port 22:2222/tcp -e SSH_USER=savil --name=savil-test --region=sjc . ``` ran: ``` DEVBOX_DEBUG=1 [email protected] devbox cloud shell ``` and got a `devbox shell` and could see the project's files and execute it.
1 parent cd3565e commit 3b6960a

File tree

3 files changed

+60
-24
lines changed

3 files changed

+60
-24
lines changed

boxcli/cloud.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@ func runCloudShellCmd(flags *cloudShellCmdFlags) error {
4949
if err != nil {
5050
return errors.WithStack(err)
5151
}
52-
return cloud.Shell(box)
52+
return cloud.Shell(box.ConfigDir())
5353
}

cloud/cloud.go

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,36 @@ import (
1414

1515
"github.com/AlecAivazis/survey/v2"
1616
"github.com/fatih/color"
17-
"go.jetpack.io/devbox"
1817
"go.jetpack.io/devbox/cloud/mutagen"
1918
"go.jetpack.io/devbox/cloud/sshclient"
2019
"go.jetpack.io/devbox/cloud/sshconfig"
2120
"go.jetpack.io/devbox/cloud/stepper"
2221
"go.jetpack.io/devbox/debug"
2322
)
2423

25-
func Shell(box *devbox.Devbox) error {
24+
func Shell(configDir string) error {
2625
setupSSHConfig()
2726

2827
c := color.New(color.FgMagenta).Add(color.Bold)
2928
c.Println("Devbox Cloud")
3029
fmt.Println("Blazingly fast remote development that feels local")
3130
fmt.Print("\n")
3231

33-
username := promptUsername()
34-
s1 := stepper.Start("Creating a virtual machine on the cloud...")
35-
vmHostname := getVirtualMachine(username)
36-
s1.Success("Created virtual machine")
32+
username, vmHostname := parseVMEnvVar()
33+
if username == "" {
34+
username = promptUsername()
35+
}
36+
debug.Log("username: %s", username)
37+
38+
if vmHostname == "" {
39+
s1 := stepper.Start("Creating a virtual machine on the cloud...")
40+
vmHostname = getVirtualMachine(username)
41+
s1.Success("Created virtual machine")
42+
}
43+
debug.Log("vm_hostname: %s", vmHostname)
3744

3845
s2 := stepper.Start("Starting file syncing...")
39-
err := syncFiles(username, vmHostname, box)
46+
err := syncFiles(username, vmHostname, configDir)
4047
if err != nil {
4148
s2.Fail("Starting file syncing [FAILED]")
4249
log.Fatal(err)
@@ -46,10 +53,9 @@ func Shell(box *devbox.Devbox) error {
4653
s3 := stepper.Start("Connecting to virtual machine...")
4754
time.Sleep(1 * time.Second)
4855
s3.Stop("Connecting to virtual machine")
49-
5056
fmt.Print("\n")
5157

52-
return shell(username, vmHostname)
58+
return shell(username, vmHostname, configDir)
5359
}
5460

5561
func setupSSHConfig() {
@@ -90,6 +96,7 @@ func getVirtualMachine(username string) string {
9096
if err != nil {
9197
log.Fatal(err)
9298
}
99+
debug.Log("gateway.devbox.sh auth response: %s", string(bytes))
93100
resp := &authResponse{}
94101
err = json.Unmarshal(bytes, resp)
95102
if err != nil {
@@ -99,8 +106,8 @@ func getVirtualMachine(username string) string {
99106
return resp.VMHostname
100107
}
101108

102-
func syncFiles(username string, hostname string, box *devbox.Devbox) error {
103-
projectName := projectDirName(box.ConfigDir())
109+
func syncFiles(username, hostname, configDir string) error {
110+
projectName := projectDirName(configDir)
104111
debug.Log("Will sync files to directory: ~/code/%s", projectName)
105112

106113
// TODO: instead of id, have the server return the machine's name and use that
@@ -110,13 +117,13 @@ func syncFiles(username string, hostname string, box *devbox.Devbox) error {
110117
// If multiple projects can sync to the same machine, we need the name to also include
111118
// the project's id.
112119
Name: fmt.Sprintf("devbox-%s", id),
113-
AlphaPath: box.ConfigDir(),
120+
AlphaPath: configDir,
114121
BetaAddress: fmt.Sprintf("%s@%s", username, hostname),
115122
// It's important that the beta path is a "clean" directory that will contain *only*
116123
// the projects files. If we pick a pre-existing directories with other files, those
117124
// files will be synced back to the local directory (due to two-way-sync) and pollute
118125
// the user's local project
119-
BetaPath: "~/Code/", // TODO Use ~/code/{projectName}
126+
BetaPath: fmt.Sprintf("~/code/%s", projectName),
120127
IgnoreVCS: true,
121128
SyncMode: "two-way-resolved",
122129
})
@@ -127,15 +134,16 @@ func syncFiles(username string, hostname string, box *devbox.Devbox) error {
127134
return nil
128135
}
129136

130-
func shell(username string, hostname string) error {
137+
func shell(username, hostname, configDir string) error {
131138
client := &sshclient.Client{
132-
Username: username,
133-
Hostname: hostname,
139+
Username: username,
140+
Hostname: hostname,
141+
ProjectDirName: projectDirName(configDir),
134142
}
135143
return client.Shell()
136144
}
137145

138-
const defaultProjectDirName = "DevboxProject"
146+
const defaultProjectDirName = "devbox_project"
139147

140148
// Ideally, we'd pass in devbox.Devbox struct and call ConfigDir but it
141149
// makes it hard to wrap this in a test
@@ -146,3 +154,22 @@ func projectDirName(configDir string) string {
146154
}
147155
return name
148156
}
157+
158+
func parseVMEnvVar() (username string, vmHostname string) {
159+
vmEnvVar := os.Getenv("DEVBOX_VM")
160+
if vmEnvVar == "" {
161+
return "", ""
162+
}
163+
parts := strings.Split(vmEnvVar, "@")
164+
165+
// DEVBOX_VM = <hostname>
166+
if len(parts) == 1 {
167+
vmHostname = parts[0]
168+
return
169+
}
170+
171+
// DEVBOX_VM = <username>@<hostname>
172+
username = parts[0]
173+
vmHostname = parts[1]
174+
return
175+
}

cloud/sshclient/sshclient.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,26 @@ package sshclient
22

33
import (
44
"errors"
5+
"fmt"
56
"os"
67
"os/exec"
78
"strconv"
9+
10+
"go.jetpack.io/devbox/debug"
811
)
912

1013
type Client struct {
11-
Username string
12-
Hostname string
13-
Port int
14+
Username string
15+
Hostname string
16+
Port int
17+
ProjectDirName string
1418
}
1519

1620
func (c *Client) Shell() error {
17-
cmd := c.cmd()
21+
cmd := c.cmd("-t")
22+
remoteCmd := fmt.Sprintf(`bash -l -c "start_devbox_shell.sh \"%s\""`, c.ProjectDirName)
23+
cmd.Args = append(cmd.Args, remoteCmd)
24+
debug.Log("running command: %s", cmd)
1825

1926
// Setup stdin, stdout, stderr
2027
cmd.Stdin = os.Stdin
@@ -37,8 +44,10 @@ func (c *Client) Exec(remoteCmd string) ([]byte, error) {
3744
return bytes, err
3845
}
3946

40-
func (c *Client) cmd() *exec.Cmd {
41-
cmd := exec.Command("ssh", destination(c.Username, c.Hostname))
47+
func (c *Client) cmd(sshArgs ...string) *exec.Cmd {
48+
49+
cmd := exec.Command("ssh", sshArgs...)
50+
cmd.Args = append(cmd.Args, destination(c.Username, c.Hostname))
4251

4352
// Add any necessary flags:
4453
if c.Port != 0 {

0 commit comments

Comments
 (0)