diff --git a/go.mod b/go.mod index f591003..43b31c1 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,9 @@ require ( github.com/google/go-containerregistry v0.20.7 github.com/gorilla/websocket v1.5.3 github.com/itchyny/json2yaml v0.1.4 - github.com/kernel/hypeman-go v0.11.0 + github.com/kernel/hypeman-go v0.13.0 github.com/knadh/koanf/parsers/yaml v1.1.0 + github.com/knadh/koanf/providers/env v1.1.0 github.com/knadh/koanf/providers/file v1.2.1 github.com/knadh/koanf/v2 v2.3.2 github.com/muesli/reflow v0.3.0 @@ -52,7 +53,6 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/klauspost/compress v1.18.1 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect - github.com/knadh/koanf/providers/env v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect diff --git a/go.sum b/go.sum index 9c04859..d8bb6c4 100644 --- a/go.sum +++ b/go.sum @@ -76,8 +76,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnV github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/itchyny/json2yaml v0.1.4 h1:/pErVOXGG5iTyXHi/QKR4y3uzhLjGTEmmJIy97YT+k8= github.com/itchyny/json2yaml v0.1.4/go.mod h1:6iudhBZdarpjLFRNj+clWLAkGft+9uCcjAZYXUH9eGI= -github.com/kernel/hypeman-go v0.11.0 h1:hCXNUHtrhGKswJapzyWyozBOXhKK/oreKvm0AXHuE6c= -github.com/kernel/hypeman-go v0.11.0/go.mod h1:guRrhyP9QW/ebUS1UcZ0uZLLJeGAAhDNzSi68U4M9hI= +github.com/kernel/hypeman-go v0.13.0 h1:5GIeSkQ9BIkL+wEJnhsPmsJzuKof6zZmqcTWK67+Kcc= +github.com/kernel/hypeman-go v0.13.0/go.mod h1:guRrhyP9QW/ebUS1UcZ0uZLLJeGAAhDNzSi68U4M9hI= github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= diff --git a/pkg/cmd/build.go b/pkg/cmd/build.go index 21deedb..a4c8c88 100644 --- a/pkg/cmd/build.go +++ b/pkg/cmd/build.go @@ -77,6 +77,14 @@ Examples: Name: "image-name", Usage: `Custom image name for the build output (pushed to {registry}/{image_name} instead of {registry}/builds/{id})`, }, + &cli.IntFlag{ + Name: "cpus", + Usage: "Number of vCPUs for builder VM (default 2)", + }, + &cli.IntFlag{ + Name: "memory", + Usage: "Memory limit for builder VM in MB (default 2048)", + }, }, Commands: []*cli.Command{ &buildListCmd, @@ -172,6 +180,12 @@ func handleBuild(ctx context.Context, cmd *cli.Command) error { if v := cmd.String("image-name"); v != "" { params.ImageName = hypeman.Opt(v) } + if cmd.IsSet("cpus") { + params.CPUs = hypeman.Opt(int64(cmd.Int("cpus"))) + } + if cmd.IsSet("memory") { + params.MemoryMB = hypeman.Opt(int64(cmd.Int("memory"))) + } // Start build build, err := client.Builds.New(ctx, params, opts...) diff --git a/pkg/cmd/format.go b/pkg/cmd/format.go index 3aa3048..9716caa 100644 --- a/pkg/cmd/format.go +++ b/pkg/cmd/format.go @@ -261,7 +261,7 @@ func randomSuffix(n int) string { // Returns an error if the identifier is ambiguous or not found. func ResolveInstance(ctx context.Context, client *hypeman.Client, identifier string) (string, error) { // List all instances - instances, err := client.Instances.List(ctx) + instances, err := client.Instances.List(ctx, hypeman.InstanceListParams{}) if err != nil { return "", fmt.Errorf("failed to list instances: %w", err) } diff --git a/pkg/cmd/ps.go b/pkg/cmd/ps.go index 2a957f2..ce18050 100644 --- a/pkg/cmd/ps.go +++ b/pkg/cmd/ps.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "strings" "github.com/kernel/hypeman-go" "github.com/kernel/hypeman-go/option" @@ -24,6 +25,14 @@ var psCmd = cli.Command{ Aliases: []string{"q"}, Usage: "Only display instance IDs", }, + &cli.StringFlag{ + Name: "state", + Usage: "Filter instances by state (e.g., Running, Stopped, Standby)", + }, + &cli.StringSliceFlag{ + Name: "metadata", + Usage: "Filter by metadata key-value pair (KEY=VALUE, can be repeated)", + }, }, Action: handlePs, HideHelpCommand: true, @@ -37,8 +46,26 @@ func handlePs(ctx context.Context, cmd *cli.Command) error { opts = append(opts, debugMiddlewareOption) } + params := hypeman.InstanceListParams{} + + if state := cmd.String("state"); state != "" { + params.State = hypeman.InstanceListParamsState(state) + } + + if metadataSpecs := cmd.StringSlice("metadata"); len(metadataSpecs) > 0 { + metadata := make(map[string]string) + for _, m := range metadataSpecs { + parts := strings.SplitN(m, "=", 2) + if len(parts) == 2 { + metadata[parts[0]] = parts[1] + } + } + params.Metadata = metadata + } + instances, err := client.Instances.List( ctx, + params, opts..., ) if err != nil { @@ -47,11 +74,12 @@ func handlePs(ctx context.Context, cmd *cli.Command) error { showAll := cmd.Bool("all") quietMode := cmd.Bool("quiet") + stateFilter := cmd.String("state") - // Filter instances + // Filter instances client-side only when no server-side filter is active var filtered []hypeman.Instance for _, inst := range *instances { - if showAll || inst.State == "Running" { + if showAll || stateFilter != "" || inst.State == "Running" { filtered = append(filtered, inst) } } diff --git a/pkg/cmd/rm.go b/pkg/cmd/rm.go index 4d7884a..3066978 100644 --- a/pkg/cmd/rm.go +++ b/pkg/cmd/rm.go @@ -42,7 +42,7 @@ func handleRm(ctx context.Context, cmd *cli.Command) error { // If --all, get all instance IDs var identifiers []string if all { - instances, err := client.Instances.List(ctx) + instances, err := client.Instances.List(ctx, hypeman.InstanceListParams{}) if err != nil { return fmt.Errorf("failed to list instances: %w", err) }