command_pool

package
v0.36.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 1, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AcquireCmd = &cli.Command{
	Name:        "acquire",
	Usage:       "Acquire a pool member exclusively",
	Description: "Check out one member of a pool for exclusive use until the lease expires (or is released). Method calls and pool-name port routing skip the member while held; reach it by its own space name or by pinning calls with its space id.",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "pool",
			Usage:    "The name or ID of the pool",
			Required: true,
		},
	},
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:  "time",
			Usage: "How long to hold the member, e.g. 90s, 5m, 2h; 'none' for a lease that never expires (unlimited pools). Defaults to the pool's configured maximum.",
		},
		&cli.StringFlag{
			Name:  "wait",
			Usage: "How long to wait for a member if none is free yet (e.g. while one is being replaced or starting), e.g. 30s, 2m (max 5m). Defaults to 10s; use --wait 0s to fail immediately.",
		},
		leaseJSONFlag(),
	},
	MaxArgs: cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		poolName := cmd.GetStringArg("pool")

		duration, err := parseLeaseDuration(cmd.GetString("time"))
		if err != nil {
			return err
		}

		wait := 10
		if value := cmd.GetString("wait"); value != "" {
			wait, err = parseLeaseDuration(value)
			if err != nil {
				return fmt.Errorf("invalid --wait: %w", err)
			}
		}

		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			return fmt.Errorf("Failed to create API client: %w", err)
		}

		if !cmd.GetBool("json") {
			fmt.Printf("Acquiring a member of pool %q...\n", poolName)
		}
		lease, code, err := client.AcquirePoolLease(context.Background(), poolName, &apiclient.PoolLeaseAcquireRequest{
			DurationSeconds: duration,
			WaitSeconds:     wait,
		})
		if err != nil {
			return handleLeaseError(cmd, code, err, fmt.Sprintf("no free member available in pool %q", poolName))
		}

		if cmd.GetBool("json") {
			return printLeaseJSON(lease)
		}
		printLease(lease, "acquired")
		return nil
	},
}
View Source
var DeleteCmd = &cli.Command{
	Name:        "delete",
	Usage:       "Delete a pool",
	Description: "Delete a stopped pool and all its member spaces.",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "pool",
			Usage:    "The name or ID of the pool to delete",
			Required: true,
		},
	},
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "yes",
			Aliases: []string{"y"},
			Usage:   "Skip confirmation prompt.",
		},
	},
	MaxArgs: cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		poolName := cmd.GetStringArg("pool")

		if !cmd.GetBool("yes") {
			fmt.Printf("Delete pool %q and all its spaces? [y/N] ", poolName)
			var resp string
			fmt.Scanln(&resp)
			if resp != "y" && resp != "Y" && resp != "yes" {
				fmt.Println("Cancelled.")
				return nil
			}
		}

		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			return fmt.Errorf("Failed to create API client: %w", err)
		}

		code, err := client.DeletePool(context.Background(), poolName)
		if err != nil {
			return fmt.Errorf("Error deleting pool: %w (code %d)", err, code)
		}

		fmt.Fprintln(os.Stderr, "Pool deleted:", poolName)
		return nil
	},
}
View Source
var ExtendCmd = &cli.Command{
	Name:        "extend",
	Usage:       "Extend the lease on a pool member",
	Description: "Renew a lease: the new deadline becomes now + the given duration (or never, on unlimited pools). Bounded by the pool's maximum extension count.",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "space",
			Usage:    "The held member's name or space id — the same identifier acquire returned",
			Required: true,
		},
	},
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:  "time",
			Usage: "How long to hold the member from now, e.g. 90s, 5m, 2h; 'none' for no expiry (unlimited pools). Defaults to the pool's configured maximum.",
		},
		leaseJSONFlag(),
	},
	MaxArgs: cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		spaceArg := cmd.GetStringArg("space")

		duration, err := parseLeaseDuration(cmd.GetString("time"))
		if err != nil {
			return err
		}

		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			return fmt.Errorf("Failed to create API client: %w", err)
		}

		lease, code, err := client.ExtendSpaceLease(context.Background(), spaceArg, &apiclient.PoolLeaseExtendRequest{
			DurationSeconds: duration,
		})
		if err != nil {
			return handleLeaseError(cmd, code, err, fmt.Sprintf("lease on %s cannot be extended (limit reached or already ended)", spaceArg))
		}

		if cmd.GetBool("json") {
			return printLeaseJSON(lease)
		}
		printLease(lease, "extended")
		return nil
	},
}
View Source
var LeasesCmd = &cli.Command{
	Name:        "leases",
	Usage:       "List a pool's leases",
	Description: "Lists the pool's exclusively held leases — active plus draining (ended, waiting for in-flight work to finish).",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "pool",
			Usage:    "The name or ID of the pool",
			Required: true,
		},
	},
	Flags: []cli.Flag{
		leaseJSONFlag(),
	},
	MaxArgs: cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		poolName := cmd.GetStringArg("pool")

		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			return fmt.Errorf("Failed to create API client: %w", err)
		}

		leases, code, err := client.GetPoolLeases(context.Background(), poolName)
		if err != nil {
			return handleLeaseError(cmd, code, err, "")
		}

		if cmd.GetBool("json") {
			enc := json.NewEncoder(os.Stdout)
			enc.SetIndent("", "  ")
			return enc.Encode(leases)
		}

		if len(leases.Leases) == 0 {
			fmt.Printf("No leases held on pool %q.\n", poolName)
			return nil
		}

		w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
		fmt.Fprintln(w, "MEMBER\tSTATE\tEXPIRES\tEXTENSIONS\tHOLDER")
		for _, lease := range leases.Leases {
			fmt.Fprintf(w, "%s\t%s\t%s\t%d/%s\t%s\n",
				lease.SpaceName,
				lease.State,
				formatLeaseExpiry(lease.ExpiresAt),
				lease.ExtensionsUsed,
				formatMaxExtensions(lease.MaxExtensions),
				lease.Username,
			)
		}
		w.Flush()
		return nil
	},
}
View Source
var ListCmd = &cli.Command{
	Name:        "list",
	Usage:       "List your pools",
	Description: "Lists all pools you own with their status and member count.",
	MaxArgs:     cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			fmt.Println("Failed to create API client:", err)
			os.Exit(1)
		}

		pools, code, err := client.GetPools(context.Background())
		if err != nil {
			if code == 404 {
				fmt.Println("No pools found.")
				return nil
			}
			return fmt.Errorf("Error listing pools: %w", err)
		}

		if len(pools.Pools) == 0 {
			fmt.Println("No pools found.")
			return nil
		}

		w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
		fmt.Fprintln(w, "NAME\tSTATE\tALIVE/DESIRED\tTEMPLATE")
		for _, p := range pools.Pools {
			state := "stopped"
			if p.Active {
				state = "active"
			}
			fmt.Fprintf(w, "%s\t%s\t%d/%d\t%s\n", p.Name, state, p.AliveMembers, p.DesiredCount, p.TemplateId)
		}
		w.Flush()
		return nil
	},
}
View Source
var PoolCmd = &cli.Command{
	Name:        "pool",
	Usage:       "Manage space pools",
	Description: "Manage your space pools from the command line.",
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "server",
			Aliases: []string{"s"},
			Usage:   "The address of the remote server to manage pools on.",
			EnvVars: []string{config.CONFIG_ENV_PREFIX + "_SERVER"},
			Global:  true,
		},
		&cli.StringFlag{
			Name:    "token",
			Aliases: []string{"t"},
			Usage:   "The token to use for authentication.",
			EnvVars: []string{config.CONFIG_ENV_PREFIX + "_TOKEN"},
			Global:  true,
		},
		&cli.BoolFlag{
			Name:         "tls-skip-verify",
			Usage:        "Skip TLS verification when talking to server.",
			ConfigPath:   []string{"tls.skip_verify"},
			EnvVars:      []string{config.CONFIG_ENV_PREFIX + "_TLS_SKIP_VERIFY"},
			DefaultValue: true,
			Global:       true,
		},
		&cli.StringFlag{
			Name:         "alias",
			Aliases:      []string{"a"},
			Usage:        "The server alias to use.",
			DefaultValue: "default",
			Global:       true,
		},
	},
	Commands: []*cli.Command{
		ListCmd,
		StartCmd,
		StopCmd,
		DeleteCmd,
		SetSizeCmd,
		AcquireCmd,
		ExtendCmd,
		ReleaseCmd,
		LeasesCmd,
	},
}
View Source
var ReleaseCmd = &cli.Command{
	Name:        "release",
	Usage:       "Release a leased pool member",
	Description: "End the lease held on a pool member. The member returns to the pool once any in-flight work has finished (normally within one sweep, ~15s). With --destroy the member is deleted instead and a fresh replacement is created, so the next acquire gets a clean space.",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "space",
			Usage:    "The held member's name or space id — the same identifier acquire returned",
			Required: true,
		},
	},
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:  "destroy",
			Usage: "Destroy the member instead of returning it — a fresh replacement is created, so the next acquire gets a clean space.",
		},
		leaseJSONFlag(),
	},
	MaxArgs: cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		spaceArg := cmd.GetStringArg("space")
		destroy := cmd.GetBool("destroy")

		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			return fmt.Errorf("Failed to create API client: %w", err)
		}

		lease, code, err := client.ReleaseSpaceLease(context.Background(), spaceArg, destroy)
		if err != nil {
			return handleLeaseError(cmd, code, err, "")
		}

		if cmd.GetBool("json") {
			return printLeaseJSON(lease)
		}

		if destroy {
			fmt.Printf("Member %s destroyed; a fresh replacement is starting in pool %q.\n", spaceArg, lease.PoolName)
		} else {
			fmt.Printf("Member %s released; it returns to pool %q after in-flight work drains.\n", spaceArg, lease.PoolName)
		}
		return nil
	},
}
View Source
var SetSizeCmd = &cli.Command{
	Name:        "set-size",
	Usage:       "Set the desired space count for a pool",
	Description: "Update the target number of spaces for a pool. The sweep loop handles creating or removing members.",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "pool",
			Usage:    "The name or ID of the pool",
			Required: true,
		},
		&cli.IntArg{
			Name:     "count",
			Usage:    "The desired number of spaces (minimum 1)",
			Required: true,
		},
	},
	MaxArgs: cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		poolName := cmd.GetStringArg("pool")
		desired := cmd.GetIntArg("count")

		if desired < 1 {
			return fmt.Errorf("count must be at least 1")
		}

		fmt.Printf("Setting pool %q size to %d...\n", poolName, desired)

		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			return fmt.Errorf("Failed to create API client: %w", err)
		}

		code, err := client.SetPoolSize(context.Background(), poolName, desired)
		if err != nil {
			return fmt.Errorf("Error setting pool size: %w (code %d)", err, code)
		}

		fmt.Printf("Pool %q size set to %d.\n", poolName, desired)
		return nil
	},
}
View Source
var StartCmd = &cli.Command{
	Name:        "start",
	Usage:       "Start a pool",
	Description: "Start a stopped pool and all its member spaces.",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "pool",
			Usage:    "The name or ID of the pool to start",
			Required: true,
		},
	},
	MaxArgs: cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		poolName := cmd.GetStringArg("pool")
		fmt.Println("Starting pool:", poolName)

		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			return fmt.Errorf("Failed to create API client: %w", err)
		}

		code, err := client.StartPool(context.Background(), poolName)
		if err != nil {
			return fmt.Errorf("Error starting pool: %w (code %d)", err, code)
		}

		fmt.Println("Pool started:", poolName)
		return nil
	},
}
View Source
var StopCmd = &cli.Command{
	Name:        "stop",
	Usage:       "Stop a pool",
	Description: "Stop a running pool and all its member spaces without deleting them.",
	Arguments: []cli.Argument{
		&cli.StringArg{
			Name:     "pool",
			Usage:    "The name or ID of the pool to stop",
			Required: true,
		},
	},
	MaxArgs: cli.NoArgs,
	Run: func(ctx context.Context, cmd *cli.Command) error {
		poolName := cmd.GetStringArg("pool")
		fmt.Println("Stopping pool:", poolName)

		client, err := cmdutil.GetClient(cmd)
		if err != nil {
			return fmt.Errorf("Failed to create API client: %w", err)
		}

		code, err := client.StopPool(context.Background(), poolName)
		if err != nil {
			return fmt.Errorf("Error stopping pool: %w (code %d)", err, code)
		}

		fmt.Println("Pool stopped:", poolName)
		return nil
	},
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL