diff --git a/go.mod b/go.mod index 87fe72376..1a468ef65 100644 --- a/go.mod +++ b/go.mod @@ -82,7 +82,7 @@ require ( k8s.io/apimachinery v0.31.0 k8s.io/apiserver v0.30.3 oras.land/oras-go/v2 v2.5.0 - sdk.kraft.cloud v0.5.10-0.20240813111748-eabe84d65f02 + sdk.kraft.cloud v0.5.10-0.20240821072613-b850da091d2d sigs.k8s.io/kustomize/kyaml v0.17.2 ) diff --git a/go.sum b/go.sum index 8540ec064..3cffaee96 100644 --- a/go.sum +++ b/go.sum @@ -1792,8 +1792,8 @@ oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZH rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sdk.kraft.cloud v0.5.10-0.20240813111748-eabe84d65f02 h1:cprG5U2yYk188KvEVtr2Lho93a/xiN3XW/CVia8F7NI= -sdk.kraft.cloud v0.5.10-0.20240813111748-eabe84d65f02/go.mod h1:7Q1tBqVp8r7vtqUQhgRan26cUSx/A1uEYXhjQ/bqhiw= +sdk.kraft.cloud v0.5.10-0.20240821072613-b850da091d2d h1:WSy3+37vK/nP/BTe4XFow3oy+HE53hqitamERPHPuBs= +sdk.kraft.cloud v0.5.10-0.20240821072613-b850da091d2d/go.mod h1:7Q1tBqVp8r7vtqUQhgRan26cUSx/A1uEYXhjQ/bqhiw= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 h1:/U5vjBbQn3RChhv7P11uhYvCSm5G2GaIi5AIGBS6r4c= diff --git a/internal/cli/kraft/cloud/deploy/deploy.go b/internal/cli/kraft/cloud/deploy/deploy.go index 52cd74094..4d5237621 100644 --- a/internal/cli/kraft/cloud/deploy/deploy.go +++ b/internal/cli/kraft/cloud/deploy/deploy.go @@ -76,6 +76,7 @@ type DeployOptions struct { SubDomain []string `local:"true" long:"subdomain" short:"s" usage:"Set the names to use when provisioning subdomains"` Timeout time.Duration `local:"true" long:"timeout" usage:"Set the timeout for remote procedure calls (ms/s/m/h)" default:"60s"` Token string `noattribute:"true"` + Vcpus uint `local:"true" long:"vcpus" short:"V" usage:"Specify the number of vCPUs to allocate"` Volumes []string `long:"volume" short:"v" usage:"Specify the volume mapping(s) in the form NAME:DEST or NAME:DEST:OPTIONS"` Workdir string `local:"true" long:"workdir" short:"w" usage:"Set an alternative working directory (default is cwd)"` } diff --git a/internal/cli/kraft/cloud/deploy/deployer_image_name.go b/internal/cli/kraft/cloud/deploy/deployer_image_name.go index 805f6c5c8..29a8d54d1 100644 --- a/internal/cli/kraft/cloud/deploy/deployer_image_name.go +++ b/internal/cli/kraft/cloud/deploy/deployer_image_name.go @@ -114,6 +114,7 @@ func (deployer *deployerImageName) Deploy(ctx context.Context, opts *DeployOptio Start: !opts.NoStart, SubDomain: opts.SubDomain, Token: opts.Token, + Vcpus: opts.Vcpus, }, deployer.args...) if err != nil { return fmt.Errorf("could not create instance: %w", err) diff --git a/internal/cli/kraft/cloud/deploy/deployer_kraftfile_runtime.go b/internal/cli/kraft/cloud/deploy/deployer_kraftfile_runtime.go index 085a7a6c2..9ac9f07e8 100644 --- a/internal/cli/kraft/cloud/deploy/deployer_kraftfile_runtime.go +++ b/internal/cli/kraft/cloud/deploy/deployer_kraftfile_runtime.go @@ -142,6 +142,7 @@ func (deployer *deployerKraftfileRuntime) Deploy(ctx context.Context, opts *Depl Start: !opts.NoStart, SubDomain: opts.SubDomain, Token: opts.Token, + Vcpus: opts.Vcpus, Volumes: opts.Volumes, WaitForImage: true, WaitForImageTimeout: opts.Timeout, diff --git a/internal/cli/kraft/cloud/instance/create/create.go b/internal/cli/kraft/cloud/instance/create/create.go index 24bd14f58..61b11faa2 100644 --- a/internal/cli/kraft/cloud/instance/create/create.go +++ b/internal/cli/kraft/cloud/instance/create/create.go @@ -60,6 +60,7 @@ type CreateOptions struct { ScaleToZeroCooldown time.Duration `local:"true" long:"scale-to-zero-cooldown" usage:"Cooldown period before scaling to zero (ms/s/m/h)"` SubDomain []string `local:"true" long:"subdomain" short:"s" usage:"Set the subdomains to use when creating the service"` Token string `noattribute:"true"` + Vcpus uint `local:"true" long:"vcpus" short:"V" usage:"Specify the number of vCPUs to allocate"` Volumes []string `local:"true" long:"volume" short:"v" usage:"List of volumes to attach instance to"` WaitForImage bool `local:"true" long:"wait-for-image" short:"w" usage:"Wait for the image to be available before creating the instance"` WaitForImageTimeout time.Duration `local:"true" long:"wait-for-image-timeout" usage:"Time to wait before timing out when waiting for image (ms/s/m/h)" default:"60s"` @@ -199,6 +200,9 @@ func Create(ctx context.Context, opts *CreateOptions, args ...string) (*kcclient Image: opts.Image, RestartPolicy: opts.RestartPolicy, } + if opts.Vcpus > 0 { + req.Vcpus = ptr(int(opts.Vcpus)) + } if opts.Name != "" { req.Name = &opts.Name } diff --git a/internal/cli/kraft/cloud/utils/print.go b/internal/cli/kraft/cloud/utils/print.go index f369d3e56..40813ad65 100644 --- a/internal/cli/kraft/cloud/utils/print.go +++ b/internal/cli/kraft/cloud/utils/print.go @@ -138,6 +138,7 @@ func PrintInstances(ctx context.Context, format string, resp kcclient.ServiceRes } table.AddField("IMAGE", cs.Bold) table.AddField("MEMORY", cs.Bold) + table.AddField("VCPUS", cs.Bold) table.AddField("ARGS", cs.Bold) if format != "table" { table.AddField("ENV", cs.Bold) @@ -186,6 +187,7 @@ func PrintInstances(ctx context.Context, format string, resp kcclient.ServiceRes } table.AddField("", nil) // IMAGE table.AddField("", nil) // MEMORY + table.AddField("", nil) // VCPUS table.AddField("", nil) // ARGS if format != "table" { table.AddField("", nil) // ENV @@ -308,6 +310,7 @@ func PrintInstances(ctx context.Context, format string, resp kcclient.ServiceRes } table.AddField(instance.Image, nil) table.AddField(humanize.IBytes(uint64(instance.MemoryMB)*humanize.MiByte), nil) + table.AddField(fmt.Sprintf("%d", instance.Vcpus), nil) table.AddField(strings.Join(instance.Args, " "), nil) if format != "table" { @@ -737,6 +740,8 @@ func PrintQuotas(ctx context.Context, auth config.AuthConfig, format string, res table.AddField("ACTIVE INSTANCES", cs.Bold) table.AddField("TOTAL INSTANCES", cs.Bold) + table.AddField("ACTIVE VCPUS", cs.Bold) + table.AddField("VCPU LIMIT", cs.Bold) // Blank line on list view if format == "list" { @@ -813,9 +818,9 @@ func PrintQuotas(ctx context.Context, auth config.AuthConfig, format string, res // ACTIVE INSTANCES var activeInstances string if format == "list" { - activeInstances = printBar(cs, quota.Used.LiveInstances, quota.Hard.LiveInstances) + " " + activeInstances = printBar(cs, quota.Used.LiveInstances, quota.Hard.Instances) + " " } - activeInstances += fmt.Sprintf("%d/%d", quota.Used.LiveInstances, quota.Hard.LiveInstances) + activeInstances += fmt.Sprintf("%d/%d", quota.Used.LiveInstances, quota.Hard.Instances) table.AddField(activeInstances, nil) // TOTAL INSTANCES @@ -826,6 +831,20 @@ func PrintQuotas(ctx context.Context, auth config.AuthConfig, format string, res totalInstances += fmt.Sprintf("%d/%d", quota.Used.Instances, quota.Hard.Instances) table.AddField(totalInstances, nil) + // ACTIVE VCPUS + var activeVcpus string + if format == "list" { + activeVcpus = printBar(cs, quota.Used.LiveVcpus, quota.Hard.LiveVcpus) + " " + } + activeVcpus += fmt.Sprintf("%d/%d", quota.Used.LiveVcpus, quota.Hard.LiveVcpus) + table.AddField(activeVcpus, nil) + + // VCPU LIMIT + table.AddField(fmt.Sprintf("%d-%d", + quota.Limits.MinVcpus, + quota.Limits.MaxVcpus, + ), nil) + // Blank line on list view if format == "list" { table.AddField("", nil)