Skip to content

Commit fe829ef

Browse files
committed
refactor: embed install.sh script in uc CLI to not curl | sh and version together with CLI
1 parent cd07278 commit fe829ef

3 files changed

Lines changed: 61 additions & 42 deletions

File tree

‎internal/cli/machine.go‎

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"context"
5+
"encoding/base64"
56
"errors"
67
"fmt"
78
"os"
@@ -13,14 +14,11 @@ import (
1314
"github.com/psviderski/uncloud/internal/cli/tui"
1415
"github.com/psviderski/uncloud/internal/machine/api/pb"
1516
"github.com/psviderski/uncloud/internal/sshexec"
17+
"github.com/psviderski/uncloud/scripts"
1618
"google.golang.org/protobuf/types/known/emptypb"
1719
)
1820

19-
const (
20-
// TODO: support pinning the script version to the CLI version.
21-
installScriptURL = "https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/install.sh"
22-
rootUser = "root"
23-
)
21+
const rootUser = "root"
2422

2523
type RemoteMachine struct {
2624
User string
@@ -30,26 +28,30 @@ type RemoteMachine struct {
3028
UseSSHGo bool // Use Go's built-in SSH library instead of the system ssh CLI command.
3129
}
3230

33-
func installCmd(user string, version string) string {
31+
// installCmd returns a shell command that decodes the base64-encoded install script and pipes it
32+
// into bash, optionally via sudo and with UNCLOUD_* environment variables set.
33+
func installCmd(scriptBase64, user, version string) string {
3434
sudoPrefix := ""
3535
var env []string
3636

3737
// Add the SSH user (non-root) to the uncloud group to allow access to the Uncloud daemon unix socket.
3838
if user != rootUser {
39-
sudoPrefix = "sudo"
39+
sudoPrefix = "sudo "
4040
env = append(env, "UNCLOUD_GROUP_ADD_USER="+sshexec.Quote(user))
4141
}
4242
if version != "" {
4343
env = append(env, "UNCLOUD_VERSION="+sshexec.Quote(version))
4444
}
4545

46-
envCmd := strings.Join(env, " ")
47-
curlBashCmd := fmt.Sprintf("curl -fsSL %s | %s %s bash", sshexec.Quote(installScriptURL), sudoPrefix, envCmd)
46+
envPrefix := ""
47+
if len(env) > 0 {
48+
envPrefix = strings.Join(env, " ") + " "
49+
}
4850

49-
return curlBashCmd
51+
return fmt.Sprintf("printf '%%s' %s | base64 -d | %s%sbash", scriptBase64, sudoPrefix, envPrefix)
5052
}
5153

52-
// provisionMachine provisions the remote machine by downloading the Uncloud install script from GitHub and running it.
54+
// provisionMachine provisions the remote machine by running the Uncloud install script embedded in the uc CLI.
5355
// If version is specified, it will be passed to the install script as UNCLOUD_VERSION environment variable.
5456
func provisionMachine(ctx context.Context, exec sshexec.Executor, version string) error {
5557
user, err := exec.Run(ctx, "whoami")
@@ -88,13 +90,10 @@ func provisionMachine(ctx context.Context, exec sshexec.Executor, version string
8890
}
8991
}
9092

91-
cmd := installCmd(user, version)
92-
93-
fmt.Println("Downloading Uncloud install script:", installScriptURL)
94-
95-
cmd = sshexec.QuoteCommand("bash", "-c", "set -o pipefail; "+cmd)
93+
scriptBase64 := base64.StdEncoding.EncodeToString([]byte(scripts.InstallScript))
94+
cmd := sshexec.QuoteCommand("bash", "-c", "set -o pipefail; "+installCmd(scriptBase64, user, version))
9695
if err = exec.Stream(ctx, cmd, os.Stdout, os.Stderr); err != nil {
97-
return fmt.Errorf("download and run install script: %w", err)
96+
return fmt.Errorf("run install script: %w", err)
9897
}
9998
return nil
10099
}

‎internal/cli/machine_test.go‎

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,42 @@ import (
77
)
88

99
func TestInstallCmd(t *testing.T) {
10-
t.Run("root", func(t *testing.T) {
11-
cmd := installCmd("root", "")
12-
assert.NotContains(t, cmd, "sudo")
13-
assert.NotContains(t, cmd, "UNCLOUD_GROUP_ADD_USER")
14-
})
10+
const scriptB64 = "SCRIPT_BASE64_PLACEHOLDER"
1511

16-
// Test with version
17-
t.Run("root with version", func(t *testing.T) {
18-
cmd := installCmd("root", "v1.2.3")
19-
assert.NotContains(t, cmd, "sudo")
20-
assert.NotContains(t, cmd, "UNCLOUD_GROUP_ADD_USER")
21-
assert.Contains(t, cmd, "UNCLOUD_VERSION=v1.2.3")
22-
})
12+
tests := []struct {
13+
name string
14+
user string
15+
version string
16+
want string
17+
}{
18+
{
19+
name: "root",
20+
user: "root",
21+
want: "printf '%s' SCRIPT_BASE64_PLACEHOLDER | base64 -d | bash",
22+
},
23+
{
24+
name: "root with version",
25+
user: "root",
26+
version: "v1.2.3",
27+
want: "printf '%s' SCRIPT_BASE64_PLACEHOLDER | base64 -d | UNCLOUD_VERSION=v1.2.3 bash",
28+
},
29+
{
30+
name: "nonroot",
31+
user: "nonroot",
32+
want: "printf '%s' SCRIPT_BASE64_PLACEHOLDER | base64 -d | sudo UNCLOUD_GROUP_ADD_USER=nonroot bash",
33+
},
34+
{
35+
name: "nonroot with version",
36+
user: "nonroot",
37+
version: "v1.2.3",
38+
want: "printf '%s' SCRIPT_BASE64_PLACEHOLDER | base64 -d | " +
39+
"sudo UNCLOUD_GROUP_ADD_USER=nonroot UNCLOUD_VERSION=v1.2.3 bash",
40+
},
41+
}
2342

24-
t.Run("nonroot", func(t *testing.T) {
25-
cmd := installCmd("nonroot", "")
26-
assert.Contains(t, cmd, "sudo")
27-
assert.Contains(t, cmd, "UNCLOUD_GROUP_ADD_USER=nonroot")
28-
})
29-
30-
t.Run("nonroot with version", func(t *testing.T) {
31-
cmd := installCmd("nonroot", "v1.2.3")
32-
assert.Contains(t, cmd, "sudo")
33-
assert.Contains(t, cmd, "UNCLOUD_GROUP_ADD_USER=nonroot")
34-
assert.Contains(t, cmd, "UNCLOUD_VERSION=v1.2.3")
35-
})
36-
}
43+
for _, tt := range tests {
44+
t.Run(tt.name, func(t *testing.T) {
45+
assert.Equal(t, tt.want, installCmd(scriptB64, tt.user, tt.version))
46+
})
47+
}
48+
}

‎scripts/scripts.go‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Package scripts embeds shell scripts shipped with the uc CLI so they can be
2+
// executed on remote machines without being fetched from the network.
3+
package scripts
4+
5+
import _ "embed"
6+
7+
//go:embed install.sh
8+
var InstallScript string

0 commit comments

Comments
 (0)