Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions cmd/grounds/commands/cluster/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,29 @@ import (
)

func newUp() *cobra.Command {
return &cobra.Command{
Use: "up",
Short: "Resume the paused workspace",
var profile string
cmd := &cobra.Command{
Use: "up [--profile=minigame|platform]",
Short: "Spawn or resume the workspace",
Long: `Create the workspace if it doesn't exist, or resume it from a paused state.

Profiles:
minigame — namespace-scoped sandbox (default). Cheap, fast, isolated by RBAC.
platform — full per-developer vCluster with the Grounds platform chart
installed inside. Heavier (one-time ~90s spawn) but lets you
run platform plugins / agones / mc-router locally.

Profile is locked once a workspace exists. To switch, ` + "`grounds cluster delete`" + ` and re-up.`,
RunE: func(cmd *cobra.Command, _ []string) error {
if profile != "" && profile != "minigame" && profile != "platform" {
return fmt.Errorf("invalid --profile %q: must be \"minigame\" or \"platform\"", profile)
}
ctx := context.Background()
c, _, err := buildClient(ctx, cmd)
if err != nil {
return err
}
s, err := c.ClusterUp(ctx)
s, err := c.ClusterUp(ctx, profile)
if err != nil {
return err
}
Expand All @@ -28,4 +41,6 @@ func newUp() *cobra.Command {
return nil
},
}
cmd.Flags().StringVar(&profile, "profile", "", "workspace profile: minigame (default) or platform (vCluster)")
return cmd
}
13 changes: 11 additions & 2 deletions internal/api/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"net/http"
"net/url"
"time"
)

Expand Down Expand Up @@ -32,9 +33,17 @@ func (c *Client) GetCluster(ctx context.Context) (*ClusterStatus, error) {
return out, nil
}

func (c *Client) ClusterUp(ctx context.Context) (*ClusterStatus, error) {
// ClusterUp spawns or resumes the workspace. `profile` may be empty
// (forge picks the default), "minigame", or "platform". Forge enforces
// the immutable-profile rule: switching profiles on an existing
// workspace requires `grounds cluster delete` first.
func (c *Client) ClusterUp(ctx context.Context, profile string) (*ClusterStatus, error) {
path := "/v1/cluster/up"
if profile != "" {
path += "?profile=" + url.QueryEscape(profile)
}
out := &ClusterStatus{}
if err := c.doRequest(ctx, http.MethodPost, "/v1/cluster/up", nil, out); err != nil {
if err := c.doRequest(ctx, http.MethodPost, path, nil, out); err != nil {
return nil, err
}
return out, nil
Expand Down
Loading