feat: automatically generate a unique 'default-N' context name for new cluster (fixes #113)

This commit is contained in:
Pasha Sviderski
2025-09-08 20:35:17 +10:00
parent ec2787c99c
commit d25864e52f
2 changed files with 31 additions and 8 deletions
+1 -1
View File
@@ -89,7 +89,7 @@ func NewInitCommand() *cobra.Command {
"Version of the Uncloud daemon to install on the machine.", "Version of the Uncloud daemon to install on the machine.",
) )
cmd.Flags().StringVarP( cmd.Flags().StringVarP(
&opts.context, "context", "c", "default", &opts.context, "context", "c", cli.DefaultContextName,
"Name of the created context for the initialised cluster in the Uncloud config.", "Name of the created context for the initialised cluster in the Uncloud config.",
) )
+30 -7
View File
@@ -26,7 +26,7 @@ const (
// DefaultSSHKeyPath is the fallback location for the SSH private key when provisioning remote machines. // DefaultSSHKeyPath is the fallback location for the SSH private key when provisioning remote machines.
// Used when no key is explicitly provided and SSH agent authentication fails. // Used when no key is explicitly provided and SSH agent authentication fails.
DefaultSSHKeyPath = "~/.ssh/id_ed25519" DefaultSSHKeyPath = "~/.ssh/id_ed25519"
defaultContextName = "default" DefaultContextName = "default"
) )
type CLI struct { type CLI struct {
@@ -170,12 +170,9 @@ func (cli *CLI) InitCluster(ctx context.Context, opts InitClusterOptions) (*clie
} }
func (cli *CLI) initRemoteMachine(ctx context.Context, opts InitClusterOptions) (*client.Client, error) { func (cli *CLI) initRemoteMachine(ctx context.Context, opts InitClusterOptions) (*client.Client, error) {
contextName := opts.Context contextName, err := cli.newContextName(opts.Context)
if contextName == "" { if err != nil {
contextName = defaultContextName return nil, err
}
if _, ok := cli.Config.Contexts[contextName]; ok {
return nil, fmt.Errorf("cluster context '%s' already exists", contextName)
} }
machineClient, err := provisionRemoteMachine(ctx, opts.RemoteMachine, opts.Version) machineClient, err := provisionRemoteMachine(ctx, opts.RemoteMachine, opts.Version)
@@ -250,6 +247,32 @@ func (cli *CLI) initRemoteMachine(ctx context.Context, opts InitClusterOptions)
return machineClient, nil return machineClient, nil
} }
// newContextName returns a unique name for a new cluster context. If the provided name is not DefaultContextName,
// and it's already taken, an error is returned. If the name is not provided or is DefaultContextName, the first
// available name "default[-N]" is returned.
func (cli *CLI) newContextName(name string) (string, error) {
if name == "" {
name = DefaultContextName
}
if _, exists := cli.Config.Contexts[name]; !exists {
return name, nil
}
// If non-default context already exists, error out.
if name != DefaultContextName {
return "", fmt.Errorf("cluster context '%s' already exists", name)
}
// The default context already exists, generate a numbered suffix to make it unique.
for i := 1; ; i++ {
name = fmt.Sprintf("%s-%d", DefaultContextName, i)
if _, exists := cli.Config.Contexts[name]; !exists {
return name, nil
}
}
}
type AddMachineOptions struct { type AddMachineOptions struct {
Context string Context string
MachineName string MachineName string