feat: make connection method using system 'ssh' the default (add ssh+go:// fallback)

This commit is contained in:
Pasha Sviderski
2026-03-27 20:27:36 +10:00
parent 0a9a1db815
commit 06c2bc55f2
60 changed files with 206 additions and 152 deletions
+10 -9
View File
@@ -40,17 +40,18 @@ func NewAddCommand() *cobra.Command {
Long: `Add a new machine to an existing Uncloud cluster.
Connection methods:
ssh://user@host - Use built-in SSH library (default, no prefix required)
ssh+cli://user@host - Use system SSH command (supports ProxyJump, SSH config)`,
[ssh://]user@host - Use system 'ssh' command with full SSH config support (default, no prefix required)
ssh+go://user@host - Use Go's built-in SSH library`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cli.BindEnvToFlag(cmd, "yes", "UNCLOUD_AUTO_CONFIRM")
uncli := cmd.Context().Value("cli").(*cli.CLI)
// Determine if SSH CLI needs to be used and strip scheme
// Determine connection mode and strip scheme.
destination := args[0]
useSSHCLI := strings.HasPrefix(destination, "ssh+cli://")
useSSHGo := strings.HasPrefix(destination, "ssh+go://")
destination = strings.TrimPrefix(destination, "ssh+go://")
destination = strings.TrimPrefix(destination, "ssh+cli://")
destination = strings.TrimPrefix(destination, "ssh://")
@@ -59,11 +60,11 @@ Connection methods:
return fmt.Errorf("parse remote machine: %w", err)
}
remoteMachine := &cli.RemoteMachine{
User: user,
Host: host,
Port: port,
KeyPath: opts.sshKey,
UseSSHCLI: useSSHCLI,
User: user,
Host: host,
Port: port,
KeyPath: opts.sshKey,
UseSSHGo: useSSHGo,
}
return add(cmd.Context(), uncli, remoteMachine, opts)
+10 -9
View File
@@ -45,8 +45,8 @@ func NewInitCommand() *cobra.Command {
This command creates a new context in your Uncloud config to manage the cluster.
Connection methods:
ssh://user@host - Use built-in SSH library (default, no prefix required)
ssh+cli://user@host - Use system SSH command (supports ProxyJump, SSH config)`,
[ssh://]user@host - Use system 'ssh' command with full SSH config support (default, no prefix required)
ssh+go://user@host - Use Go's built-in SSH library`,
Example: ` # Initialise a new cluster with default settings.
uc machine init root@<your-server-ip>
@@ -68,9 +68,10 @@ Connection methods:
var remoteMachine *cli.RemoteMachine
if len(args) > 0 {
// Determine if SSH CLI is requested and strip scheme
// Determine connection mode and strip scheme.
destination := args[0]
useSSHCLI := strings.HasPrefix(destination, "ssh+cli://")
useSSHGo := strings.HasPrefix(destination, "ssh+go://")
destination = strings.TrimPrefix(destination, "ssh+go://")
destination = strings.TrimPrefix(destination, "ssh+cli://")
destination = strings.TrimPrefix(destination, "ssh://")
@@ -79,11 +80,11 @@ Connection methods:
return fmt.Errorf("parse remote machine: %w", err)
}
remoteMachine = &cli.RemoteMachine{
User: user,
Host: host,
Port: port,
KeyPath: opts.sshKey,
UseSSHCLI: useSSHCLI,
User: user,
Host: host,
Port: port,
KeyPath: opts.sshKey,
UseSSHGo: useSSHGo,
}
}
+12 -5
View File
@@ -47,23 +47,30 @@ func main() {
var conn *config.MachineConnection
if opts.connect != "" {
if strings.HasPrefix(opts.connect, "tcp://") {
addrPort, err := netip.ParseAddrPort(opts.connect[len("tcp://"):])
addrPort, err := netip.ParseAddrPort(strings.TrimPrefix(opts.connect, "tcp://"))
if err != nil {
return fmt.Errorf("parse TCP address: %w", err)
}
conn = &config.MachineConnection{
TCP: &addrPort,
}
} else if strings.HasPrefix(opts.connect, "ssh+cli://") {
dest := opts.connect[len("ssh+cli://"):]
} else if strings.HasPrefix(opts.connect, "ssh+go://") {
dest := strings.TrimPrefix(opts.connect, "ssh+go://")
conn = &config.MachineConnection{
SSHCLI: config.SSHDestination(dest),
SSHGo: config.SSHDestination(dest),
}
} else if strings.HasPrefix(opts.connect, "ssh+cli://") {
// Backward-compatible alias for ssh://.
dest := strings.TrimPrefix(opts.connect, "ssh+cli://")
conn = &config.MachineConnection{
SSH: config.SSHDestination(dest),
}
} else if strings.HasPrefix(opts.connect, "unix://") {
conn = &config.MachineConnection{
Unix: opts.connect[len("unix://"):],
}
} else {
// Default: system ssh CLI command (no prefix or ssh:// prefix).
dest := strings.TrimPrefix(opts.connect, "ssh://")
conn = &config.MachineConnection{
SSH: config.SSHDestination(dest),
@@ -83,7 +90,7 @@ func main() {
cmd.PersistentFlags().StringVar(&opts.connect, "connect", "",
"Connect to a remote cluster machine without using the Uncloud configuration file. [$UNCLOUD_CONNECT]\n"+
"Format: [ssh://]user@host[:port], ssh+cli://user@host[:port], tcp://host:port, or unix:///path/to/uncloud.sock")
"Format: [ssh://]user@host[:port], ssh+go://user@host[:port], tcp://host:port, or unix:///path/to/uncloud.sock")
cmd.PersistentFlags().StringVar(&opts.configPath, "uncloud-config", "~/.config/uncloud/config.yaml",
"Path to the Uncloud configuration file. [$UNCLOUD_CONFIG]")
_ = cmd.MarkPersistentFlagFilename("uncloud-config", "yaml", "yml")