From 918169663cdf73c71761b6ca14040c7e68716609 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 4 Mar 2026 09:33:25 +0100 Subject: [PATCH 01/30] feat: add support for Spot VMs and validation for provisioning options --- cli/cmd/bootstrap_gcp.go | 1 + internal/bootstrap/gcp/gcp.go | 119 +++++++++++++- internal/bootstrap/gcp/gcp_client.go | 21 +++ internal/bootstrap/gcp/gcp_test.go | 232 +++++++++++++++++++++++++-- internal/bootstrap/gcp/mocks.go | 63 ++++++++ 5 files changed, 415 insertions(+), 21 deletions(-) diff --git a/cli/cmd/bootstrap_gcp.go b/cli/cmd/bootstrap_gcp.go index b96a38a6..9855f21a 100644 --- a/cli/cmd/bootstrap_gcp.go +++ b/cli/cmd/bootstrap_gcp.go @@ -69,6 +69,7 @@ func AddBootstrapGcpCmd(parent *cobra.Command, opts *GlobalOptions) { flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.SSHPublicKeyPath, "ssh-public-key-path", "~/.ssh/id_rsa.pub", "SSH Public Key Path (default: ~/.ssh/id_rsa.pub)") flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.SSHPrivateKeyPath, "ssh-private-key-path", "~/.ssh/id_rsa", "SSH Private Key Path (default: ~/.ssh/id_rsa)") flags.BoolVar(&bootstrapGcpCmd.CodesphereEnv.Preemptible, "preemptible", false, "Use preemptible VMs for Codesphere infrastructure (default: false)") + flags.BoolVar(&bootstrapGcpCmd.CodesphereEnv.Spot, "spot", false, "Use Spot VMs for Codesphere infrastructure. Falls back to standard VMs if spot capacity unavailable (default: false)") flags.IntVar(&bootstrapGcpCmd.CodesphereEnv.DatacenterID, "datacenter-id", 1, "Datacenter ID (default: 1)") flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.CustomPgIP, "custom-pg-ip", "", "Custom PostgreSQL IP (optional)") flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.InstallConfigPath, "install-config", "config.yaml", "Path to install config file (optional)") diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 71373096..b227d7d8 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -93,6 +93,7 @@ type CodesphereEnvironment struct { InstallHash string `json:"install_hash"` InstallSkipSteps []string `json:"install_skip_steps"` Preemptible bool `json:"preemptible"` + Spot bool `json:"spot"` WriteConfig bool `json:"-"` GatewayIP string `json:"gateway_ip"` PublicGatewayIP string `json:"public_gateway_ip"` @@ -306,9 +307,22 @@ func (b *GCPBootstrapper) ValidateInput() error { return err } + err = b.validateVMProvisioningOptions() + if err != nil { + return err + } + return b.validateGithubParams() } +// validateVMProvisioningOptions checks that spot and preemptible options are not both set +func (b *GCPBootstrapper) validateVMProvisioningOptions() error { + if b.Env.Spot && b.Env.Preemptible { + return fmt.Errorf("cannot specify both --spot and --preemptible flags; use --spot for the newer spot VM model") + } + return nil +} + // validateInstallVersion checks if the specified install version exists and contains the required installer artifact func (b *GCPBootstrapper) validateInstallVersion() error { if b.Env.InstallLocal != "" { @@ -694,6 +708,43 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { wg.Add(1) go func(vm VMDef) { defer wg.Done() + + existingInstance, err := b.GCPClient.GetInstance(projectID, zone, vm.Name) + if err == nil && existingInstance != nil { + instanceStatus := existingInstance.GetStatus() + if instanceStatus == "TERMINATED" || instanceStatus == "STOPPED" || instanceStatus == "SUSPENDED" { + // Start the stopped instance + err = b.GCPClient.StartInstance(projectID, zone, vm.Name) + if err != nil { + errCh <- fmt.Errorf("failed to start stopped instance %s: %w", vm.Name, err) + return + } + // Re-fetch instance to get updated IPs after start + existingInstance, err = b.GCPClient.GetInstance(projectID, zone, vm.Name) + if err != nil { + errCh <- fmt.Errorf("failed to get instance %s after start: %w", vm.Name, err) + return + } + } + + externalIP := "" + internalIP := "" + if len(existingInstance.GetNetworkInterfaces()) > 0 { + internalIP = existingInstance.GetNetworkInterfaces()[0].GetNetworkIP() + if len(existingInstance.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 { + externalIP = existingInstance.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP() + } + } + resultCh <- vmResult{ + vmType: vm.Tags[0], + name: vm.Name, + externalIP: externalIP, + internalIP: internalIP, + } + return + } + + // Instance doesn't exist, create it disks := []*computepb.AttachedDisk{ { Boot: protoBool(true), @@ -737,9 +788,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { Tags: &computepb.Tags{ Items: vm.Tags, }, - Scheduling: &computepb.Scheduling{ - Preemptible: &b.Env.Preemptible, - }, + Scheduling: b.buildSchedulingConfig(), NetworkInterfaces: []*computepb.NetworkInterface{ { Network: protoString(network), @@ -767,9 +816,9 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { } } - err = b.GCPClient.CreateInstance(projectID, zone, instance) - if err != nil && !isAlreadyExistsError(err) { - errCh <- fmt.Errorf("failed to create instance %s: %w", vm.Name, err) + err = b.createInstanceWithFallback(projectID, zone, instance, vm.Name) + if err != nil { + errCh <- err return } @@ -843,6 +892,64 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { return nil } +// buildSchedulingConfig creates the scheduling configuration based on spot/preemptible settings +func (b *GCPBootstrapper) buildSchedulingConfig() *computepb.Scheduling { + if b.Env.Spot { + return &computepb.Scheduling{ + ProvisioningModel: protoString("SPOT"), + OnHostMaintenance: protoString("TERMINATE"), + AutomaticRestart: protoBool(false), + InstanceTerminationAction: protoString("STOP"), + } + } + if b.Env.Preemptible { + return &computepb.Scheduling{ + Preemptible: protoBool(true), + } + } + + return &computepb.Scheduling{} +} + +// createInstanceWithFallback attempts to create an instance with the configured settings. +// If spot VMs are enabled and creation fails due to capacity issues, it falls back to standard VMs. +func (b *GCPBootstrapper) createInstanceWithFallback(projectID, zone string, instance *computepb.Instance, vmName string) error { + err := b.GCPClient.CreateInstance(projectID, zone, instance) + if err == nil { + return nil + } + + if isAlreadyExistsError(err) { + return nil + } + + if b.Env.Spot && isSpotCapacityError(err) { + b.stlog.Logf("Spot capacity unavailable for %s, falling back to standard VM", vmName) + instance.Scheduling = &computepb.Scheduling{} + err = b.GCPClient.CreateInstance(projectID, zone, instance) + if err != nil && !isAlreadyExistsError(err) { + return fmt.Errorf("failed to create instance %s (fallback to standard VM): %w", vmName, err) + } + return nil + } + + return fmt.Errorf("failed to create instance %s: %w", vmName, err) +} + +// isSpotCapacityError checks if the error is related to spot VM capacity issues +func isSpotCapacityError(err error) bool { + if err == nil { + return false + } + errStr := err.Error() + return strings.Contains(errStr, "ZONE_RESOURCE_POOL_EXHAUSTED") || + strings.Contains(errStr, "UNSUPPORTED_OPERATION") || + strings.Contains(errStr, "stockout") || + strings.Contains(errStr, "does not have enough resources") || + strings.Contains(errStr, "quota") || + status.Code(err) == codes.ResourceExhausted +} + // EnsureGatewayIPAddresses reserves 2 static external IP addresses for the ingress // controllers of the cluster. func (b *GCPBootstrapper) EnsureGatewayIPAddresses() error { diff --git a/internal/bootstrap/gcp/gcp_client.go b/internal/bootstrap/gcp/gcp_client.go index b487343a..4fc8de6f 100644 --- a/internal/bootstrap/gcp/gcp_client.go +++ b/internal/bootstrap/gcp/gcp_client.go @@ -48,6 +48,7 @@ type GCPClientManager interface { CreateFirewallRule(projectID string, rule *computepb.Firewall) error CreateInstance(projectID, zone string, instance *computepb.Instance) error GetInstance(projectID, zone, instanceName string) (*computepb.Instance, error) + StartInstance(projectID, zone, instanceName string) error CreateAddress(projectID, region string, address *computepb.Address) (string, error) GetAddress(projectID, region, addressName string) (*computepb.Address, error) EnsureDNSManagedZone(projectID, zoneName, dnsName, description string) error @@ -552,6 +553,26 @@ func (c *GCPClient) GetInstance(projectID, zone, instanceName string) (*computep }) } +// StartInstance starts a stopped Compute Engine instance in the specified project and zone. +func (c *GCPClient) StartInstance(projectID, zone, instanceName string) error { + client, err := compute.NewInstancesRESTClient(c.ctx) + if err != nil { + return err + } + defer util.IgnoreError(client.Close) + + op, err := client.Start(c.ctx, &computepb.StartInstanceRequest{ + Project: projectID, + Zone: zone, + Instance: instanceName, + }) + if err != nil { + return err + } + + return op.Wait(c.ctx) +} + // CreateAddress creates a new static IP address in the specified project and region. func (c *GCPClient) CreateAddress(projectID, region string, address *computepb.Address) (string, error) { client, err := compute.NewAddressesRESTClient(c.ctx) diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index 4fe6ccea..c47e2bf1 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "strings" + "sync" "os" @@ -169,9 +170,11 @@ var _ = Describe("GCP Bootstrapper", func() { gc.EXPECT().CreateFirewallRule(projectId, mock.Anything).Return(nil).Times(5) // 11. EnsureComputeInstances - gc.EXPECT().CreateInstance(projectId, "us-central1-a", mock.Anything).Return(nil).Times(9) - // GetInstance calls to retrieve IPs + // Track GetInstance calls per VM name + instanceCalls := make(map[string]int) + var instanceMu sync.Mutex ipResp := &computepb.Instance{ + Status: protoString("RUNNING"), NetworkInterfaces: []*computepb.NetworkInterface{ { NetworkIP: protoString("10.0.0.1"), @@ -181,9 +184,19 @@ var _ = Describe("GCP Bootstrapper", func() { }, }, } - - gc.EXPECT().GetInstance(projectId, "us-central1-a", mock.Anything).Return(ipResp, nil).Times(9) + gc.EXPECT().GetInstance(projectId, "us-central1-a", mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { + instanceMu.Lock() + defer instanceMu.Unlock() + instanceCalls[name]++ + if instanceCalls[name] == 1 { + // First call, instance doesn't exist + return nil, fmt.Errorf("not found") + } + // Second call, return instance with IPs + return ipResp, nil + }).Times(18) fw.EXPECT().ReadFile(mock.Anything).Return([]byte("fake-key"), nil).Times(9) + gc.EXPECT().CreateInstance(projectId, "us-central1-a", mock.Anything).Return(nil).Times(9) // 12. EnsureGatewayIPAddresses gc.EXPECT().GetAddress(projectId, "us-central1", "gateway").Return(nil, fmt.Errorf("not found")) @@ -384,6 +397,17 @@ var _ = Describe("GCP Bootstrapper", func() { }) + Context("When both --spot and --preemptible are specified", func() { + BeforeEach(func() { + csEnv.Spot = true + csEnv.Preemptible = true + }) + It("fails with a clear error message", func() { + err := bs.ValidateInput() + Expect(err).To(MatchError(MatchRegexp("cannot specify both --spot and --preemptible"))) + }) + }) + }) Describe("EnsureInstallConfig", func() { @@ -945,14 +969,10 @@ var _ = Describe("GCP Bootstrapper", func() { }) Describe("Valid EnsureComputeInstances", func() { It("creates all instances", func() { - // Mock ReadFile for SSH key (called 9 times in parallel) - fw.EXPECT().ReadFile(csEnv.SSHPublicKeyPath).Return([]byte("ssh-rsa AAA..."), nil).Times(9) - - // Mock CreateInstance (9 times) - gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil).Times(9) - - // Mock GetInstance (9 times) + instanceCalls := make(map[string]int) + var mu sync.Mutex ipResp := &computepb.Instance{ + Status: protoString("RUNNING"), NetworkInterfaces: []*computepb.NetworkInterface{ { NetworkIP: protoString("10.0.0.x"), @@ -962,7 +982,20 @@ var _ = Describe("GCP Bootstrapper", func() { }, }, } - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(ipResp, nil).Times(9) + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { + mu.Lock() + defer mu.Unlock() + instanceCalls[name]++ + if instanceCalls[name] == 1 { + // First call, instance doesn't exist + return nil, fmt.Errorf("not found") + } + // Second call, return instance with IPs + return ipResp, nil + }).Times(18) + + fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Times(9) + gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil).Times(9) err := bs.EnsureComputeInstances() Expect(err).NotTo(HaveOccurred()) @@ -975,7 +1008,8 @@ var _ = Describe("GCP Bootstrapper", func() { Describe("Invalid cases", func() { It("fails when SSH key read fails", func() { - fw.EXPECT().ReadFile(csEnv.SSHPublicKeyPath).Return(nil, fmt.Errorf("read error")).Maybe() + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("not found")).Maybe() + fw.EXPECT().ReadFile(mock.Anything).Return(nil, fmt.Errorf("read error")).Maybe() err := bs.EnsureComputeInstances() Expect(err).To(HaveOccurred()) @@ -983,7 +1017,8 @@ var _ = Describe("GCP Bootstrapper", func() { }) It("fails when CreateInstance fails", func() { - fw.EXPECT().ReadFile(csEnv.SSHPublicKeyPath).Return([]byte("ssh-rsa AAA..."), nil).Maybe() + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("not found")).Maybe() + fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Maybe() gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(fmt.Errorf("create error")).Maybe() err := bs.EnsureComputeInstances() @@ -992,7 +1027,8 @@ var _ = Describe("GCP Bootstrapper", func() { }) It("fails when GetInstance fails", func() { - fw.EXPECT().ReadFile(csEnv.SSHPublicKeyPath).Return([]byte("ssh-rsa AAA..."), nil).Maybe() + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("not found")).Maybe() + fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Maybe() gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil).Maybe() gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("get error")).Maybe() @@ -1001,6 +1037,172 @@ var _ = Describe("GCP Bootstrapper", func() { Expect(err.Error()).To(ContainSubstring("error ensuring compute instances")) }) }) + + Describe("Spot VM functionality", func() { + It("creates spot VMs when spot flag is enabled", func() { + csEnv.Spot = true + + // Track GetInstance calls per VM name + instanceCalls := make(map[string]int) + var mu sync.Mutex + ipResp := &computepb.Instance{ + Status: protoString("RUNNING"), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString("10.0.0.x"), + AccessConfigs: []*computepb.AccessConfig{ + {NatIP: protoString("1.2.3.x")}, + }, + }, + }, + } + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { + mu.Lock() + defer mu.Unlock() + instanceCalls[name]++ + if instanceCalls[name] == 1 { + return nil, fmt.Errorf("not found") + } + return ipResp, nil + }).Times(18) + + fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Times(9) + + // Verify CreateInstance is called with SPOT provisioning model + gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.MatchedBy(func(instance *computepb.Instance) bool { + return instance.Scheduling != nil && + instance.Scheduling.ProvisioningModel != nil && + *instance.Scheduling.ProvisioningModel == "SPOT" + })).Return(nil).Times(9) + + err := bs.EnsureComputeInstances() + Expect(err).NotTo(HaveOccurred()) + }) + + It("falls back to standard VM when spot capacity is exhausted", func() { + csEnv.Spot = true + + // Track GetInstance calls per VM name + instanceCalls := make(map[string]int) + var mu sync.Mutex + ipResp := &computepb.Instance{ + Status: protoString("RUNNING"), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString("10.0.0.x"), + AccessConfigs: []*computepb.AccessConfig{ + {NatIP: protoString("1.2.3.x")}, + }, + }, + }, + } + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { + mu.Lock() + defer mu.Unlock() + instanceCalls[name]++ + if instanceCalls[name] == 1 { + return nil, fmt.Errorf("not found") + } + return ipResp, nil + }).Times(18) + + fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Times(9) + + createCalls := make(map[string]int) + gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone string, instance *computepb.Instance) error { + mu.Lock() + defer mu.Unlock() + name := *instance.Name + createCalls[name]++ + if createCalls[name] == 1 { + return fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED") + } + return nil + }).Times(18) + + err := bs.EnsureComputeInstances() + Expect(err).NotTo(HaveOccurred()) + }) + + It("restarts stopped VMs instead of creating new ones", func() { + instanceCalls := make(map[string]int) + var mu sync.Mutex + stoppedResp := &computepb.Instance{ + Status: protoString("TERMINATED"), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString("10.0.0.x"), + AccessConfigs: []*computepb.AccessConfig{ + {NatIP: protoString("1.2.3.x")}, + }, + }, + }, + } + runningResp := &computepb.Instance{ + Status: protoString("RUNNING"), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString("10.0.0.x"), + AccessConfigs: []*computepb.AccessConfig{ + {NatIP: protoString("1.2.3.x")}, + }, + }, + }, + } + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { + mu.Lock() + defer mu.Unlock() + instanceCalls[name]++ + if instanceCalls[name] == 1 { + // First call, VM exists but is stopped + return stoppedResp, nil + } + // After StartInstance, VM is running + return runningResp, nil + }).Times(18) + + gc.EXPECT().StartInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil).Times(9) + + err := bs.EnsureComputeInstances() + Expect(err).NotTo(HaveOccurred()) + }) + + It("uses existing running VMs without starting them", func() { + runningResp := &computepb.Instance{ + Status: protoString("RUNNING"), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString("10.0.0.x"), + AccessConfigs: []*computepb.AccessConfig{ + {NatIP: protoString("1.2.3.x")}, + }, + }, + }, + } + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(runningResp, nil).Times(9) + + err := bs.EnsureComputeInstances() + Expect(err).NotTo(HaveOccurred()) + }) + + It("handles VMs in intermediate states (STAGING/PROVISIONING)", func() { + provisioningResp := &computepb.Instance{ + Status: protoString("STAGING"), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString("10.0.0.x"), + AccessConfigs: []*computepb.AccessConfig{ + {NatIP: protoString("1.2.3.x")}, + }, + }, + }, + } + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(provisioningResp, nil).Times(9) + + err := bs.EnsureComputeInstances() + Expect(err).NotTo(HaveOccurred()) + }) + }) }) Describe("EnsureGatewayIPAddresses", func() { diff --git a/internal/bootstrap/gcp/mocks.go b/internal/bootstrap/gcp/mocks.go index 495ad6e3..a24742b3 100644 --- a/internal/bootstrap/gcp/mocks.go +++ b/internal/bootstrap/gcp/mocks.go @@ -1320,3 +1320,66 @@ func (_c *MockGCPClientManager_GetProjectByName_Call) RunAndReturn(run func(fold _c.Call.Return(run) return _c } + +// StartInstance provides a mock function for the type MockGCPClientManager +func (_mock *MockGCPClientManager) StartInstance(projectID string, zone string, instanceName string) error { + ret := _mock.Called(projectID, zone, instanceName) + + if len(ret) == 0 { + panic("no return value specified for StartInstance") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string, string, string) error); ok { + r0 = returnFunc(projectID, zone, instanceName) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockGCPClientManager_StartInstance_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartInstance' +type MockGCPClientManager_StartInstance_Call struct { + *mock.Call +} + +// StartInstance is a helper method to define mock.On call +// - projectID string +// - zone string +// - instanceName string +func (_e *MockGCPClientManager_Expecter) StartInstance(projectID interface{}, zone interface{}, instanceName interface{}) *MockGCPClientManager_StartInstance_Call { + return &MockGCPClientManager_StartInstance_Call{Call: _e.mock.On("StartInstance", projectID, zone, instanceName)} +} + +func (_c *MockGCPClientManager_StartInstance_Call) Run(run func(projectID string, zone string, instanceName string)) *MockGCPClientManager_StartInstance_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockGCPClientManager_StartInstance_Call) Return(err error) *MockGCPClientManager_StartInstance_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockGCPClientManager_StartInstance_Call) RunAndReturn(run func(projectID string, zone string, instanceName string) error) *MockGCPClientManager_StartInstance_Call { + _c.Call.Return(run) + return _c +} From 1ff3b6f3e8952ef03b7d7fa0bfda47b733025d53 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 5 Mar 2026 10:47:49 +0000 Subject: [PATCH 02/30] chore(docs): Auto-update docs and licenses Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> --- docs/oms_beta_bootstrap-gcp.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/oms_beta_bootstrap-gcp.md b/docs/oms_beta_bootstrap-gcp.md index 33c0fd95..1582a4e3 100644 --- a/docs/oms_beta_bootstrap-gcp.md +++ b/docs/oms_beta_bootstrap-gcp.md @@ -47,6 +47,7 @@ oms beta bootstrap-gcp [flags] --registry-user string Custom Registry username (only for GitHub registry type) (optional) --secrets-dir string Directory for secrets (default: /etc/codesphere/secrets) (default "/etc/codesphere/secrets") --secrets-file string Path to secrets files (optional) (default "prod.vault.yaml") + --spot Use Spot VMs for Codesphere infrastructure. Falls back to standard VMs if spot capacity unavailable (default: false) --ssh-private-key-path string SSH Private Key Path (default: ~/.ssh/id_rsa) (default "~/.ssh/id_rsa") --ssh-public-key-path string SSH Public Key Path (default: ~/.ssh/id_rsa.pub) (default "~/.ssh/id_rsa.pub") --ssh-quiet Suppress SSH command output (default: true) (default true) From f5cdbb3c8d6d45eab87909b40b28baee90b24707 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 5 Mar 2026 12:22:04 +0100 Subject: [PATCH 03/30] Update internal/bootstrap/gcp/gcp.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- internal/bootstrap/gcp/gcp.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index fee5d408..042a3c0a 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -710,7 +710,14 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { defer wg.Done() existingInstance, err := b.GCPClient.GetInstance(projectID, zone, vm.Name) - if err == nil && existingInstance != nil { + if err != nil { + st, ok := status.FromError(err) + if !ok || st.Code() != codes.NotFound { + errCh <- fmt.Errorf("failed to get instance %s: %w", vm.Name, err) + return + } + } + if existingInstance != nil { instanceStatus := existingInstance.GetStatus() if instanceStatus == "TERMINATED" || instanceStatus == "STOPPED" || instanceStatus == "SUSPENDED" { // Start the stopped instance From 7b78e189d09ed8ae4873034b6a87aa859a45a1ac Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 5 Mar 2026 12:27:30 +0100 Subject: [PATCH 04/30] feat: enhance instance creation logging for spot VM fallback --- internal/bootstrap/gcp/gcp.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index fee5d408..c13f59fe 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -700,6 +700,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { wg := sync.WaitGroup{} errCh := make(chan error, len(vmDefs)) resultCh := make(chan vmResult, len(vmDefs)) + logCh := make(chan string, len(vmDefs)) rootDiskSize := int64(200) if b.Env.RegistryType == RegistryTypeGitHub { rootDiskSize = 50 @@ -816,7 +817,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { } } - err = b.createInstanceWithFallback(projectID, zone, instance, vm.Name) + err = b.createInstanceWithFallback(projectID, zone, instance, vm.Name, logCh) if err != nil { errCh <- err return @@ -851,6 +852,11 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { close(errCh) close(resultCh) + close(logCh) + + for msg := range logCh { + b.stlog.Logf("%s", msg) + } var errs []error for err := range errCh { @@ -913,7 +919,7 @@ func (b *GCPBootstrapper) buildSchedulingConfig() *computepb.Scheduling { // createInstanceWithFallback attempts to create an instance with the configured settings. // If spot VMs are enabled and creation fails due to capacity issues, it falls back to standard VMs. -func (b *GCPBootstrapper) createInstanceWithFallback(projectID, zone string, instance *computepb.Instance, vmName string) error { +func (b *GCPBootstrapper) createInstanceWithFallback(projectID, zone string, instance *computepb.Instance, vmName string, logCh chan<- string) error { err := b.GCPClient.CreateInstance(projectID, zone, instance) if err == nil { return nil @@ -924,7 +930,7 @@ func (b *GCPBootstrapper) createInstanceWithFallback(projectID, zone string, ins } if b.Env.Spot && isSpotCapacityError(err) { - b.stlog.Logf("Spot capacity unavailable for %s, falling back to standard VM", vmName) + logCh <- fmt.Sprintf("Spot capacity unavailable for %s, falling back to standard VM", vmName) instance.Scheduling = &computepb.Scheduling{} err = b.GCPClient.CreateInstance(projectID, zone, instance) if err != nil && !isAlreadyExistsError(err) { From 2c6a4243063bd70e680439a21d040707eb870e08 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 5 Mar 2026 13:18:58 +0100 Subject: [PATCH 05/30] test: improve GetInstance error handling in GCPBootstrapper tests --- internal/bootstrap/gcp/gcp.go | 7 +++++-- internal/bootstrap/gcp/gcp_test.go | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 8a0836a4..ac973b49 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -712,8 +712,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { existingInstance, err := b.GCPClient.GetInstance(projectID, zone, vm.Name) if err != nil { - st, ok := status.FromError(err) - if !ok || st.Code() != codes.NotFound { + if !isNotFoundError(err) { errCh <- fmt.Errorf("failed to get instance %s: %w", vm.Name, err) return } @@ -1711,6 +1710,10 @@ func isAlreadyExistsError(err error) bool { return status.Code(err) == codes.AlreadyExists || strings.Contains(err.Error(), "already exists") } +func isNotFoundError(err error) bool { + return status.Code(err) == codes.NotFound || strings.Contains(err.Error(), "not found") +} + // readSSHKey reads an SSH key file, expanding ~ in the path func (b *GCPBootstrapper) readSSHKey(path string) (string, error) { realPath := util.ExpandPath(path) diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index 196ca03a..1d91ddb4 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -1029,10 +1029,21 @@ var _ = Describe("GCP Bootstrapper", func() { }) It("fails when GetInstance fails", func() { - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("not found")).Maybe() + instanceCalls := make(map[string]int) + var mu sync.Mutex + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn( + func(projectID, zone, name string) (*computepb.Instance, error) { + mu.Lock() + defer mu.Unlock() + instanceCalls[name]++ + if instanceCalls[name] == 1 { + return nil, fmt.Errorf("not found") + } + return nil, fmt.Errorf("get error") + }, + ).Maybe() fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Maybe() gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil).Maybe() - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("get error")).Maybe() err := bs.EnsureComputeInstances() Expect(err).To(HaveOccurred()) From e234f5f619aaf130d47a3c99b9951663f83f63d1 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 5 Mar 2026 13:49:46 +0100 Subject: [PATCH 06/30] Update internal/bootstrap/gcp/gcp.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- internal/bootstrap/gcp/gcp.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index ac973b49..2fbea36e 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -958,7 +958,6 @@ func isSpotCapacityError(err error) bool { strings.Contains(errStr, "UNSUPPORTED_OPERATION") || strings.Contains(errStr, "stockout") || strings.Contains(errStr, "does not have enough resources") || - strings.Contains(errStr, "quota") || status.Code(err) == codes.ResourceExhausted } From af02bd5753a009dc3ae045013d9c9deea69b7a1f Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 5 Mar 2026 14:46:25 +0100 Subject: [PATCH 07/30] feat: implement waitForInstanceRunning to ensure instance readiness and IP assignment --- internal/bootstrap/gcp/gcp.go | 52 +++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 2fbea36e..c99c666d 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -726,21 +726,19 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { errCh <- fmt.Errorf("failed to start stopped instance %s: %w", vm.Name, err) return } - // Re-fetch instance to get updated IPs after start - existingInstance, err = b.GCPClient.GetInstance(projectID, zone, vm.Name) - if err != nil { - errCh <- fmt.Errorf("failed to get instance %s after start: %w", vm.Name, err) - return - } + } + + // Wait until the instance is RUNNING and IPs are populated. + readyInstance, err := b.waitForInstanceRunning(projectID, zone, vm.Name, vm.ExternalIP) + if err != nil { + errCh <- fmt.Errorf("instance %s did not become ready: %w", vm.Name, err) + return } externalIP := "" - internalIP := "" - if len(existingInstance.GetNetworkInterfaces()) > 0 { - internalIP = existingInstance.GetNetworkInterfaces()[0].GetNetworkIP() - if len(existingInstance.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 { - externalIP = existingInstance.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP() - } + internalIP := readyInstance.GetNetworkInterfaces()[0].GetNetworkIP() + if len(readyInstance.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 { + externalIP = readyInstance.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP() } resultCh <- vmResult{ vmType: vm.Tags[0], @@ -948,6 +946,36 @@ func (b *GCPBootstrapper) createInstanceWithFallback(projectID, zone string, ins return fmt.Errorf("failed to create instance %s: %w", vmName, err) } +// waitForInstanceRunning polls GetInstance until the instance status is RUNNING +// and its internal IP (and external IP, when needsExternalIP is true) are populated. +// It returns the ready instance or an error if the deadline is exceeded. +func (b *GCPBootstrapper) waitForInstanceRunning(projectID, zone, name string, needsExternalIP bool) (*computepb.Instance, error) { + const ( + maxAttempts = 60 + pollInterval = 5 * time.Second + ) + for attempt := range maxAttempts { + inst, err := b.GCPClient.GetInstance(projectID, zone, name) + if err != nil { + return nil, fmt.Errorf("failed to poll instance %s: %w", name, err) + } + + if inst.GetStatus() == "RUNNING" && + len(inst.GetNetworkInterfaces()) > 0 && + inst.GetNetworkInterfaces()[0].GetNetworkIP() != "" && + (!needsExternalIP || (len(inst.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 && + inst.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP() != "")) { + return inst, nil + } + + if attempt < maxAttempts-1 { + time.Sleep(pollInterval) + } + } + return nil, fmt.Errorf("timed out waiting for instance %s to be RUNNING with IPs assigned after %s", + name, time.Duration(maxAttempts)*pollInterval) +} + // isSpotCapacityError checks if the error is related to spot VM capacity issues func isSpotCapacityError(err error) bool { if err == nil { From d1554ae5c6a2e480707c8ecfc8ef9847e1694477 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:34:03 +0100 Subject: [PATCH 08/30] ref: simplify IP extraction and enhance instance handling in EnsureComputeInstances --- internal/bootstrap/gcp/gcp.go | 36 +++++++++--------- internal/bootstrap/gcp/gcp_test.go | 61 +++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 24 deletions(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 81d6cc60..06997f04 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -742,11 +742,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { return } - externalIP := "" - internalIP := readyInstance.GetNetworkInterfaces()[0].GetNetworkIP() - if len(readyInstance.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 { - externalIP = readyInstance.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP() - } + internalIP, externalIP := extractInstanceIPs(readyInstance) resultCh <- vmResult{ vmType: vm.Tags[0], name: vm.Name, @@ -834,23 +830,14 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { return } - // Find out the IP addresses of the created instance - resp, err := b.GCPClient.GetInstance(projectID, zone, vm.Name) + // Wait for the newly created instance to be RUNNING with IPs assigned + readyInstance, err := b.waitForInstanceRunning(projectID, zone, vm.Name, vm.ExternalIP) if err != nil { - errCh <- fmt.Errorf("failed to get instance %s: %w", vm.Name, err) + errCh <- fmt.Errorf("instance %s did not become ready: %w", vm.Name, err) return } - externalIP := "" - internalIP := "" - if len(resp.GetNetworkInterfaces()) > 0 { - internalIP = resp.GetNetworkInterfaces()[0].GetNetworkIP() - if len(resp.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 { - externalIP = resp.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP() - } - } - - // Send result through channel instead of creating nodes in goroutine + internalIP, externalIP := extractInstanceIPs(readyInstance) resultCh <- vmResult{ vmType: vm.Tags[0], name: vm.Name, @@ -909,6 +896,17 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { return nil } +// extractInstanceIPs returns the internal and external IPs from a compute instance. +func extractInstanceIPs(inst *computepb.Instance) (internalIP, externalIP string) { + if len(inst.GetNetworkInterfaces()) > 0 { + internalIP = inst.GetNetworkInterfaces()[0].GetNetworkIP() + if len(inst.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 { + externalIP = inst.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP() + } + } + return +} + // buildSchedulingConfig creates the scheduling configuration based on spot/preemptible settings func (b *GCPBootstrapper) buildSchedulingConfig() *computepb.Scheduling { if b.Env.Spot { @@ -1745,7 +1743,7 @@ func isAlreadyExistsError(err error) bool { } func isNotFoundError(err error) bool { - return status.Code(err) == codes.NotFound || strings.Contains(err.Error(), "not found") + return status.Code(err) == codes.NotFound || strings.Contains(strings.ToLower(err.Error()), "not found") } // readSSHKey reads an SSH key file, expanding ~ in the path diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index d20d74cd..ff74936d 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -985,15 +985,14 @@ var _ = Describe("GCP Bootstrapper", func() { }, }, } + // First call per VM: not found (triggers creation). Second call: running with IPs. gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { mu.Lock() defer mu.Unlock() instanceCalls[name]++ if instanceCalls[name] == 1 { - // First call, instance doesn't exist return nil, fmt.Errorf("not found") } - // Second call, return instance with IPs return ipResp, nil }).Times(18) @@ -1193,14 +1192,17 @@ var _ = Describe("GCP Bootstrapper", func() { }, }, } - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(runningResp, nil).Times(9) + // 9 VMs × 2 GetInstance calls each (initial check + waitForInstanceRunning poll) + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(runningResp, nil).Times(18) err := bs.EnsureComputeInstances() Expect(err).NotTo(HaveOccurred()) }) It("handles VMs in intermediate states (STAGING/PROVISIONING)", func() { - provisioningResp := &computepb.Instance{ + instanceCalls := make(map[string]int) + var mu sync.Mutex + stagingResp := &computepb.Instance{ Status: protoString("STAGING"), NetworkInterfaces: []*computepb.NetworkInterface{ { @@ -1211,11 +1213,60 @@ var _ = Describe("GCP Bootstrapper", func() { }, }, } - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(provisioningResp, nil).Times(9) + runningResp := &computepb.Instance{ + Status: protoString("RUNNING"), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString("10.0.0.x"), + AccessConfigs: []*computepb.AccessConfig{ + {NatIP: protoString("1.2.3.x")}, + }, + }, + }, + } + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { + mu.Lock() + defer mu.Unlock() + instanceCalls[name]++ + if instanceCalls[name] == 1 { + // First call: instance exists but is still staging + return stagingResp, nil + } + // Second call via waitForInstanceRunning: now running + return runningResp, nil + }).Times(18) err := bs.EnsureComputeInstances() Expect(err).NotTo(HaveOccurred()) }) + + It("fails when StartInstance returns an error", func() { + stoppedResp := &computepb.Instance{ + Status: protoString("TERMINATED"), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString("10.0.0.x"), + AccessConfigs: []*computepb.AccessConfig{ + {NatIP: protoString("1.2.3.x")}, + }, + }, + }, + } + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(stoppedResp, nil).Maybe() + gc.EXPECT().StartInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(fmt.Errorf("start error")).Maybe() + + err := bs.EnsureComputeInstances() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("failed to start stopped instance")) + }) + + It("fails when initial GetInstance returns a non-NotFound error", func() { + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("permission denied")).Maybe() + + err := bs.EnsureComputeInstances() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("failed to get instance")) + }) }) }) From 67f88ec0849eaeca1a4659331026a5ffe2e80092 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Fri, 13 Mar 2026 11:46:48 +0000 Subject: [PATCH 09/30] chore(docs): Auto-update docs and licenses Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> --- internal/bootstrap/gcp/mocks.go | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/internal/bootstrap/gcp/mocks.go b/internal/bootstrap/gcp/mocks.go index 4fd00cb9..ea8c1aa0 100644 --- a/internal/bootstrap/gcp/mocks.go +++ b/internal/bootstrap/gcp/mocks.go @@ -1570,3 +1570,66 @@ func (_c *MockGCPClientManager_RemoveIAMRoleBinding_Call) RunAndReturn(run func( _c.Call.Return(run) return _c } + +// StartInstance provides a mock function for the type MockGCPClientManager +func (_mock *MockGCPClientManager) StartInstance(projectID string, zone string, instanceName string) error { + ret := _mock.Called(projectID, zone, instanceName) + + if len(ret) == 0 { + panic("no return value specified for StartInstance") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string, string, string) error); ok { + r0 = returnFunc(projectID, zone, instanceName) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockGCPClientManager_StartInstance_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartInstance' +type MockGCPClientManager_StartInstance_Call struct { + *mock.Call +} + +// StartInstance is a helper method to define mock.On call +// - projectID string +// - zone string +// - instanceName string +func (_e *MockGCPClientManager_Expecter) StartInstance(projectID interface{}, zone interface{}, instanceName interface{}) *MockGCPClientManager_StartInstance_Call { + return &MockGCPClientManager_StartInstance_Call{Call: _e.mock.On("StartInstance", projectID, zone, instanceName)} +} + +func (_c *MockGCPClientManager_StartInstance_Call) Run(run func(projectID string, zone string, instanceName string)) *MockGCPClientManager_StartInstance_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockGCPClientManager_StartInstance_Call) Return(err error) *MockGCPClientManager_StartInstance_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockGCPClientManager_StartInstance_Call) RunAndReturn(run func(projectID string, zone string, instanceName string) error) *MockGCPClientManager_StartInstance_Call { + _c.Call.Return(run) + return _c +} From 74b936cfdb7de88ca566cbaca30774ca9f698bbe Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Fri, 13 Mar 2026 12:49:54 +0100 Subject: [PATCH 10/30] fix: mockery --- cli/cmd/mocks.go | 24 +- internal/bootstrap/gcp/mocks.go | 557 ++++++++----------------------- internal/codesphere/mocks.go | 123 ++----- internal/installer/mocks.go | 250 +++----------- internal/installer/node/mocks.go | 82 +---- internal/portal/mocks.go | 225 +++---------- internal/system/mocks.go | 44 +-- internal/util/mocks.go | 242 +++----------- 8 files changed, 317 insertions(+), 1230 deletions(-) diff --git a/cli/cmd/mocks.go b/cli/cmd/mocks.go index 26b37df5..60357284 100644 --- a/cli/cmd/mocks.go +++ b/cli/cmd/mocks.go @@ -75,32 +75,16 @@ type MockOMSUpdater_Update_Call struct { } // Update is a helper method to define mock.On call -// - ctx context.Context -// - current string -// - repo selfupdate.Repository +// - ctx +// - current +// - repo func (_e *MockOMSUpdater_Expecter) Update(ctx interface{}, current interface{}, repo interface{}) *MockOMSUpdater_Update_Call { return &MockOMSUpdater_Update_Call{Call: _e.mock.On("Update", ctx, current, repo)} } func (_c *MockOMSUpdater_Update_Call) Run(run func(ctx context.Context, current string, repo selfupdate.Repository)) *MockOMSUpdater_Update_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 selfupdate.Repository - if args[2] != nil { - arg2 = args[2].(selfupdate.Repository) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(context.Context), args[1].(string), args[2].(selfupdate.Repository)) }) return _c } diff --git a/internal/bootstrap/gcp/mocks.go b/internal/bootstrap/gcp/mocks.go index 4fd00cb9..66ce8366 100644 --- a/internal/bootstrap/gcp/mocks.go +++ b/internal/bootstrap/gcp/mocks.go @@ -64,38 +64,17 @@ type MockGCPClientManager_AssignIAMRole_Call struct { } // AssignIAMRole is a helper method to define mock.On call -// - projectID string -// - saEmail string -// - saProjectID string -// - roles []string +// - projectID +// - saEmail +// - saProjectID +// - roles func (_e *MockGCPClientManager_Expecter) AssignIAMRole(projectID interface{}, saEmail interface{}, saProjectID interface{}, roles interface{}) *MockGCPClientManager_AssignIAMRole_Call { return &MockGCPClientManager_AssignIAMRole_Call{Call: _e.mock.On("AssignIAMRole", projectID, saEmail, saProjectID, roles)} } func (_c *MockGCPClientManager_AssignIAMRole_Call) Run(run func(projectID string, saEmail string, saProjectID string, roles []string)) *MockGCPClientManager_AssignIAMRole_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 []string - if args[3] != nil { - arg3 = args[3].([]string) - } - run( - arg0, - arg1, - arg2, - arg3, - ) + run(args[0].(string), args[1].(string), args[2].(string), args[3].([]string)) }) return _c } @@ -142,32 +121,16 @@ type MockGCPClientManager_CreateAddress_Call struct { } // CreateAddress is a helper method to define mock.On call -// - projectID string -// - region string -// - address *computepb.Address +// - projectID +// - region +// - address func (_e *MockGCPClientManager_Expecter) CreateAddress(projectID interface{}, region interface{}, address interface{}) *MockGCPClientManager_CreateAddress_Call { return &MockGCPClientManager_CreateAddress_Call{Call: _e.mock.On("CreateAddress", projectID, region, address)} } func (_c *MockGCPClientManager_CreateAddress_Call) Run(run func(projectID string, region string, address *computepb.Address)) *MockGCPClientManager_CreateAddress_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 *computepb.Address - if args[2] != nil { - arg2 = args[2].(*computepb.Address) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(*computepb.Address)) }) return _c } @@ -216,32 +179,16 @@ type MockGCPClientManager_CreateArtifactRegistry_Call struct { } // CreateArtifactRegistry is a helper method to define mock.On call -// - projectID string -// - region string -// - repoName string +// - projectID +// - region +// - repoName func (_e *MockGCPClientManager_Expecter) CreateArtifactRegistry(projectID interface{}, region interface{}, repoName interface{}) *MockGCPClientManager_CreateArtifactRegistry_Call { return &MockGCPClientManager_CreateArtifactRegistry_Call{Call: _e.mock.On("CreateArtifactRegistry", projectID, region, repoName)} } func (_c *MockGCPClientManager_CreateArtifactRegistry_Call) Run(run func(projectID string, region string, repoName string)) *MockGCPClientManager_CreateArtifactRegistry_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(string)) }) return _c } @@ -279,26 +226,15 @@ type MockGCPClientManager_CreateFirewallRule_Call struct { } // CreateFirewallRule is a helper method to define mock.On call -// - projectID string -// - rule *computepb.Firewall +// - projectID +// - rule func (_e *MockGCPClientManager_Expecter) CreateFirewallRule(projectID interface{}, rule interface{}) *MockGCPClientManager_CreateFirewallRule_Call { return &MockGCPClientManager_CreateFirewallRule_Call{Call: _e.mock.On("CreateFirewallRule", projectID, rule)} } func (_c *MockGCPClientManager_CreateFirewallRule_Call) Run(run func(projectID string, rule *computepb.Firewall)) *MockGCPClientManager_CreateFirewallRule_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 *computepb.Firewall - if args[1] != nil { - arg1 = args[1].(*computepb.Firewall) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(*computepb.Firewall)) }) return _c } @@ -336,32 +272,16 @@ type MockGCPClientManager_CreateInstance_Call struct { } // CreateInstance is a helper method to define mock.On call -// - projectID string -// - zone string -// - instance *computepb.Instance +// - projectID +// - zone +// - instance func (_e *MockGCPClientManager_Expecter) CreateInstance(projectID interface{}, zone interface{}, instance interface{}) *MockGCPClientManager_CreateInstance_Call { return &MockGCPClientManager_CreateInstance_Call{Call: _e.mock.On("CreateInstance", projectID, zone, instance)} } func (_c *MockGCPClientManager_CreateInstance_Call) Run(run func(projectID string, zone string, instance *computepb.Instance)) *MockGCPClientManager_CreateInstance_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 *computepb.Instance - if args[2] != nil { - arg2 = args[2].(*computepb.Instance) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(*computepb.Instance)) }) return _c } @@ -408,38 +328,17 @@ type MockGCPClientManager_CreateProject_Call struct { } // CreateProject is a helper method to define mock.On call -// - parent string -// - projectName string -// - displayName string -// - ttl time.Duration +// - parent +// - projectName +// - displayName +// - ttl func (_e *MockGCPClientManager_Expecter) CreateProject(parent interface{}, projectName interface{}, displayName interface{}, ttl interface{}) *MockGCPClientManager_CreateProject_Call { return &MockGCPClientManager_CreateProject_Call{Call: _e.mock.On("CreateProject", parent, projectName, displayName, ttl)} } func (_c *MockGCPClientManager_CreateProject_Call) Run(run func(parent string, projectName string, displayName string, ttl time.Duration)) *MockGCPClientManager_CreateProject_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 time.Duration - if args[3] != nil { - arg3 = args[3].(time.Duration) - } - run( - arg0, - arg1, - arg2, - arg3, - ) + run(args[0].(string), args[1].(string), args[2].(string), args[3].(time.Duration)) }) return _c } @@ -477,20 +376,14 @@ type MockGCPClientManager_CreateProjectID_Call struct { } // CreateProjectID is a helper method to define mock.On call -// - projectName string +// - projectName func (_e *MockGCPClientManager_Expecter) CreateProjectID(projectName interface{}) *MockGCPClientManager_CreateProjectID_Call { return &MockGCPClientManager_CreateProjectID_Call{Call: _e.mock.On("CreateProjectID", projectName)} } func (_c *MockGCPClientManager_CreateProjectID_Call) Run(run func(projectName string)) *MockGCPClientManager_CreateProjectID_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -543,32 +436,16 @@ type MockGCPClientManager_CreateServiceAccount_Call struct { } // CreateServiceAccount is a helper method to define mock.On call -// - projectID string -// - name string -// - displayName string +// - projectID +// - name +// - displayName func (_e *MockGCPClientManager_Expecter) CreateServiceAccount(projectID interface{}, name interface{}, displayName interface{}) *MockGCPClientManager_CreateServiceAccount_Call { return &MockGCPClientManager_CreateServiceAccount_Call{Call: _e.mock.On("CreateServiceAccount", projectID, name, displayName)} } func (_c *MockGCPClientManager_CreateServiceAccount_Call) Run(run func(projectID string, name string, displayName string)) *MockGCPClientManager_CreateServiceAccount_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(string)) }) return _c } @@ -615,26 +492,15 @@ type MockGCPClientManager_CreateServiceAccountKey_Call struct { } // CreateServiceAccountKey is a helper method to define mock.On call -// - projectID string -// - saEmail string +// - projectID +// - saEmail func (_e *MockGCPClientManager_Expecter) CreateServiceAccountKey(projectID interface{}, saEmail interface{}) *MockGCPClientManager_CreateServiceAccountKey_Call { return &MockGCPClientManager_CreateServiceAccountKey_Call{Call: _e.mock.On("CreateServiceAccountKey", projectID, saEmail)} } func (_c *MockGCPClientManager_CreateServiceAccountKey_Call) Run(run func(projectID string, saEmail string)) *MockGCPClientManager_CreateServiceAccountKey_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(string)) }) return _c } @@ -672,50 +538,19 @@ type MockGCPClientManager_CreateVPC_Call struct { } // CreateVPC is a helper method to define mock.On call -// - projectID string -// - region string -// - networkName string -// - subnetName string -// - routerName string -// - natName string +// - projectID +// - region +// - networkName +// - subnetName +// - routerName +// - natName func (_e *MockGCPClientManager_Expecter) CreateVPC(projectID interface{}, region interface{}, networkName interface{}, subnetName interface{}, routerName interface{}, natName interface{}) *MockGCPClientManager_CreateVPC_Call { return &MockGCPClientManager_CreateVPC_Call{Call: _e.mock.On("CreateVPC", projectID, region, networkName, subnetName, routerName, natName)} } func (_c *MockGCPClientManager_CreateVPC_Call) Run(run func(projectID string, region string, networkName string, subnetName string, routerName string, natName string)) *MockGCPClientManager_CreateVPC_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 string - if args[3] != nil { - arg3 = args[3].(string) - } - var arg4 string - if args[4] != nil { - arg4 = args[4].(string) - } - var arg5 string - if args[5] != nil { - arg5 = args[5].(string) - } - run( - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - ) + run(args[0].(string), args[1].(string), args[2].(string), args[3].(string), args[4].(string), args[5].(string)) }) return _c } @@ -753,32 +588,16 @@ type MockGCPClientManager_DeleteDNSRecordSets_Call struct { } // DeleteDNSRecordSets is a helper method to define mock.On call -// - projectID string -// - zoneName string -// - baseDomain string +// - projectID +// - zoneName +// - baseDomain func (_e *MockGCPClientManager_Expecter) DeleteDNSRecordSets(projectID interface{}, zoneName interface{}, baseDomain interface{}) *MockGCPClientManager_DeleteDNSRecordSets_Call { return &MockGCPClientManager_DeleteDNSRecordSets_Call{Call: _e.mock.On("DeleteDNSRecordSets", projectID, zoneName, baseDomain)} } func (_c *MockGCPClientManager_DeleteDNSRecordSets_Call) Run(run func(projectID string, zoneName string, baseDomain string)) *MockGCPClientManager_DeleteDNSRecordSets_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(string)) }) return _c } @@ -816,20 +635,14 @@ type MockGCPClientManager_DeleteProject_Call struct { } // DeleteProject is a helper method to define mock.On call -// - projectID string +// - projectID func (_e *MockGCPClientManager_Expecter) DeleteProject(projectID interface{}) *MockGCPClientManager_DeleteProject_Call { return &MockGCPClientManager_DeleteProject_Call{Call: _e.mock.On("DeleteProject", projectID)} } func (_c *MockGCPClientManager_DeleteProject_Call) Run(run func(projectID string)) *MockGCPClientManager_DeleteProject_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -867,26 +680,15 @@ type MockGCPClientManager_EnableAPIs_Call struct { } // EnableAPIs is a helper method to define mock.On call -// - projectID string -// - apis []string +// - projectID +// - apis func (_e *MockGCPClientManager_Expecter) EnableAPIs(projectID interface{}, apis interface{}) *MockGCPClientManager_EnableAPIs_Call { return &MockGCPClientManager_EnableAPIs_Call{Call: _e.mock.On("EnableAPIs", projectID, apis)} } func (_c *MockGCPClientManager_EnableAPIs_Call) Run(run func(projectID string, apis []string)) *MockGCPClientManager_EnableAPIs_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 []string - if args[1] != nil { - arg1 = args[1].([]string) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].([]string)) }) return _c } @@ -924,26 +726,15 @@ type MockGCPClientManager_EnableBilling_Call struct { } // EnableBilling is a helper method to define mock.On call -// - projectID string -// - billingAccount string +// - projectID +// - billingAccount func (_e *MockGCPClientManager_Expecter) EnableBilling(projectID interface{}, billingAccount interface{}) *MockGCPClientManager_EnableBilling_Call { return &MockGCPClientManager_EnableBilling_Call{Call: _e.mock.On("EnableBilling", projectID, billingAccount)} } func (_c *MockGCPClientManager_EnableBilling_Call) Run(run func(projectID string, billingAccount string)) *MockGCPClientManager_EnableBilling_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(string)) }) return _c } @@ -981,38 +772,17 @@ type MockGCPClientManager_EnsureDNSManagedZone_Call struct { } // EnsureDNSManagedZone is a helper method to define mock.On call -// - projectID string -// - zoneName string -// - dnsName string -// - description string +// - projectID +// - zoneName +// - dnsName +// - description func (_e *MockGCPClientManager_Expecter) EnsureDNSManagedZone(projectID interface{}, zoneName interface{}, dnsName interface{}, description interface{}) *MockGCPClientManager_EnsureDNSManagedZone_Call { return &MockGCPClientManager_EnsureDNSManagedZone_Call{Call: _e.mock.On("EnsureDNSManagedZone", projectID, zoneName, dnsName, description)} } func (_c *MockGCPClientManager_EnsureDNSManagedZone_Call) Run(run func(projectID string, zoneName string, dnsName string, description string)) *MockGCPClientManager_EnsureDNSManagedZone_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 string - if args[3] != nil { - arg3 = args[3].(string) - } - run( - arg0, - arg1, - arg2, - arg3, - ) + run(args[0].(string), args[1].(string), args[2].(string), args[3].(string)) }) return _c } @@ -1050,32 +820,16 @@ type MockGCPClientManager_EnsureDNSRecordSets_Call struct { } // EnsureDNSRecordSets is a helper method to define mock.On call -// - projectID string -// - zoneName string -// - records []*dns.ResourceRecordSet +// - projectID +// - zoneName +// - records func (_e *MockGCPClientManager_Expecter) EnsureDNSRecordSets(projectID interface{}, zoneName interface{}, records interface{}) *MockGCPClientManager_EnsureDNSRecordSets_Call { return &MockGCPClientManager_EnsureDNSRecordSets_Call{Call: _e.mock.On("EnsureDNSRecordSets", projectID, zoneName, records)} } func (_c *MockGCPClientManager_EnsureDNSRecordSets_Call) Run(run func(projectID string, zoneName string, records []*dns.ResourceRecordSet)) *MockGCPClientManager_EnsureDNSRecordSets_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 []*dns.ResourceRecordSet - if args[2] != nil { - arg2 = args[2].([]*dns.ResourceRecordSet) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].([]*dns.ResourceRecordSet)) }) return _c } @@ -1124,32 +878,16 @@ type MockGCPClientManager_GetAddress_Call struct { } // GetAddress is a helper method to define mock.On call -// - projectID string -// - region string -// - addressName string +// - projectID +// - region +// - addressName func (_e *MockGCPClientManager_Expecter) GetAddress(projectID interface{}, region interface{}, addressName interface{}) *MockGCPClientManager_GetAddress_Call { return &MockGCPClientManager_GetAddress_Call{Call: _e.mock.On("GetAddress", projectID, region, addressName)} } func (_c *MockGCPClientManager_GetAddress_Call) Run(run func(projectID string, region string, addressName string)) *MockGCPClientManager_GetAddress_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(string)) }) return _c } @@ -1198,32 +936,16 @@ type MockGCPClientManager_GetArtifactRegistry_Call struct { } // GetArtifactRegistry is a helper method to define mock.On call -// - projectID string -// - region string -// - repoName string +// - projectID +// - region +// - repoName func (_e *MockGCPClientManager_Expecter) GetArtifactRegistry(projectID interface{}, region interface{}, repoName interface{}) *MockGCPClientManager_GetArtifactRegistry_Call { return &MockGCPClientManager_GetArtifactRegistry_Call{Call: _e.mock.On("GetArtifactRegistry", projectID, region, repoName)} } func (_c *MockGCPClientManager_GetArtifactRegistry_Call) Run(run func(projectID string, region string, repoName string)) *MockGCPClientManager_GetArtifactRegistry_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(string)) }) return _c } @@ -1272,20 +994,14 @@ type MockGCPClientManager_GetBillingInfo_Call struct { } // GetBillingInfo is a helper method to define mock.On call -// - projectID string +// - projectID func (_e *MockGCPClientManager_Expecter) GetBillingInfo(projectID interface{}) *MockGCPClientManager_GetBillingInfo_Call { return &MockGCPClientManager_GetBillingInfo_Call{Call: _e.mock.On("GetBillingInfo", projectID)} } func (_c *MockGCPClientManager_GetBillingInfo_Call) Run(run func(projectID string)) *MockGCPClientManager_GetBillingInfo_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -1334,32 +1050,16 @@ type MockGCPClientManager_GetInstance_Call struct { } // GetInstance is a helper method to define mock.On call -// - projectID string -// - zone string -// - instanceName string +// - projectID +// - zone +// - instanceName func (_e *MockGCPClientManager_Expecter) GetInstance(projectID interface{}, zone interface{}, instanceName interface{}) *MockGCPClientManager_GetInstance_Call { return &MockGCPClientManager_GetInstance_Call{Call: _e.mock.On("GetInstance", projectID, zone, instanceName)} } func (_c *MockGCPClientManager_GetInstance_Call) Run(run func(projectID string, zone string, instanceName string)) *MockGCPClientManager_GetInstance_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(string)) }) return _c } @@ -1408,26 +1108,15 @@ type MockGCPClientManager_GetProjectByName_Call struct { } // GetProjectByName is a helper method to define mock.On call -// - folderID string -// - displayName string +// - folderID +// - displayName func (_e *MockGCPClientManager_Expecter) GetProjectByName(folderID interface{}, displayName interface{}) *MockGCPClientManager_GetProjectByName_Call { return &MockGCPClientManager_GetProjectByName_Call{Call: _e.mock.On("GetProjectByName", folderID, displayName)} } func (_c *MockGCPClientManager_GetProjectByName_Call) Run(run func(folderID string, displayName string)) *MockGCPClientManager_GetProjectByName_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(string)) }) return _c } @@ -1474,20 +1163,14 @@ type MockGCPClientManager_IsOMSManagedProject_Call struct { } // IsOMSManagedProject is a helper method to define mock.On call -// - projectID string +// - projectID func (_e *MockGCPClientManager_Expecter) IsOMSManagedProject(projectID interface{}) *MockGCPClientManager_IsOMSManagedProject_Call { return &MockGCPClientManager_IsOMSManagedProject_Call{Call: _e.mock.On("IsOMSManagedProject", projectID)} } func (_c *MockGCPClientManager_IsOMSManagedProject_Call) Run(run func(projectID string)) *MockGCPClientManager_IsOMSManagedProject_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -1525,38 +1208,17 @@ type MockGCPClientManager_RemoveIAMRoleBinding_Call struct { } // RemoveIAMRoleBinding is a helper method to define mock.On call -// - projectID string -// - saName string -// - saProjectID string -// - roles []string +// - projectID +// - saName +// - saProjectID +// - roles func (_e *MockGCPClientManager_Expecter) RemoveIAMRoleBinding(projectID interface{}, saName interface{}, saProjectID interface{}, roles interface{}) *MockGCPClientManager_RemoveIAMRoleBinding_Call { return &MockGCPClientManager_RemoveIAMRoleBinding_Call{Call: _e.mock.On("RemoveIAMRoleBinding", projectID, saName, saProjectID, roles)} } func (_c *MockGCPClientManager_RemoveIAMRoleBinding_Call) Run(run func(projectID string, saName string, saProjectID string, roles []string)) *MockGCPClientManager_RemoveIAMRoleBinding_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 []string - if args[3] != nil { - arg3 = args[3].([]string) - } - run( - arg0, - arg1, - arg2, - arg3, - ) + run(args[0].(string), args[1].(string), args[2].(string), args[3].([]string)) }) return _c } @@ -1570,3 +1232,50 @@ func (_c *MockGCPClientManager_RemoveIAMRoleBinding_Call) RunAndReturn(run func( _c.Call.Return(run) return _c } + +// StartInstance provides a mock function for the type MockGCPClientManager +func (_mock *MockGCPClientManager) StartInstance(projectID string, zone string, instanceName string) error { + ret := _mock.Called(projectID, zone, instanceName) + + if len(ret) == 0 { + panic("no return value specified for StartInstance") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string, string, string) error); ok { + r0 = returnFunc(projectID, zone, instanceName) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockGCPClientManager_StartInstance_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartInstance' +type MockGCPClientManager_StartInstance_Call struct { + *mock.Call +} + +// StartInstance is a helper method to define mock.On call +// - projectID +// - zone +// - instanceName +func (_e *MockGCPClientManager_Expecter) StartInstance(projectID interface{}, zone interface{}, instanceName interface{}) *MockGCPClientManager_StartInstance_Call { + return &MockGCPClientManager_StartInstance_Call{Call: _e.mock.On("StartInstance", projectID, zone, instanceName)} +} + +func (_c *MockGCPClientManager_StartInstance_Call) Run(run func(projectID string, zone string, instanceName string)) *MockGCPClientManager_StartInstance_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(string)) + }) + return _c +} + +func (_c *MockGCPClientManager_StartInstance_Call) Return(err error) *MockGCPClientManager_StartInstance_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockGCPClientManager_StartInstance_Call) RunAndReturn(run func(projectID string, zone string, instanceName string) error) *MockGCPClientManager_StartInstance_Call { + _c.Call.Return(run) + return _c +} diff --git a/internal/codesphere/mocks.go b/internal/codesphere/mocks.go index f236d994..ccd510ea 100644 --- a/internal/codesphere/mocks.go +++ b/internal/codesphere/mocks.go @@ -68,38 +68,17 @@ type MockClient_CreateWorkspace_Call struct { } // CreateWorkspace is a helper method to define mock.On call -// - teamID int -// - planID int -// - name string -// - repoURL *string +// - teamID +// - planID +// - name +// - repoURL func (_e *MockClient_Expecter) CreateWorkspace(teamID interface{}, planID interface{}, name interface{}, repoURL interface{}) *MockClient_CreateWorkspace_Call { return &MockClient_CreateWorkspace_Call{Call: _e.mock.On("CreateWorkspace", teamID, planID, name, repoURL)} } func (_c *MockClient_CreateWorkspace_Call) Run(run func(teamID int, planID int, name string, repoURL *string)) *MockClient_CreateWorkspace_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 int - if args[0] != nil { - arg0 = args[0].(int) - } - var arg1 int - if args[1] != nil { - arg1 = args[1].(int) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 *string - if args[3] != nil { - arg3 = args[3].(*string) - } - run( - arg0, - arg1, - arg2, - arg3, - ) + run(args[0].(int), args[1].(int), args[2].(string), args[3].(*string)) }) return _c } @@ -137,20 +116,14 @@ type MockClient_DeleteWorkspace_Call struct { } // DeleteWorkspace is a helper method to define mock.On call -// - workspaceID int +// - workspaceID func (_e *MockClient_Expecter) DeleteWorkspace(workspaceID interface{}) *MockClient_DeleteWorkspace_Call { return &MockClient_DeleteWorkspace_Call{Call: _e.mock.On("DeleteWorkspace", workspaceID)} } func (_c *MockClient_DeleteWorkspace_Call) Run(run func(workspaceID int)) *MockClient_DeleteWorkspace_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 int - if args[0] != nil { - arg0 = args[0].(int) - } - run( - arg0, - ) + run(args[0].(int)) }) return _c } @@ -188,26 +161,15 @@ type MockClient_ExecuteCommand_Call struct { } // ExecuteCommand is a helper method to define mock.On call -// - workspaceID int -// - command string +// - workspaceID +// - command func (_e *MockClient_Expecter) ExecuteCommand(workspaceID interface{}, command interface{}) *MockClient_ExecuteCommand_Call { return &MockClient_ExecuteCommand_Call{Call: _e.mock.On("ExecuteCommand", workspaceID, command)} } func (_c *MockClient_ExecuteCommand_Call) Run(run func(workspaceID int, command string)) *MockClient_ExecuteCommand_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 int - if args[0] != nil { - arg0 = args[0].(int) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) + run(args[0].(int), args[1].(string)) }) return _c } @@ -355,32 +317,16 @@ type MockClient_SetEnvVar_Call struct { } // SetEnvVar is a helper method to define mock.On call -// - workspaceID int -// - key string -// - value string +// - workspaceID +// - key +// - value func (_e *MockClient_Expecter) SetEnvVar(workspaceID interface{}, key interface{}, value interface{}) *MockClient_SetEnvVar_Call { return &MockClient_SetEnvVar_Call{Call: _e.mock.On("SetEnvVar", workspaceID, key, value)} } func (_c *MockClient_SetEnvVar_Call) Run(run func(workspaceID int, key string, value string)) *MockClient_SetEnvVar_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 int - if args[0] != nil { - arg0 = args[0].(int) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(int), args[1].(string), args[2].(string)) }) return _c } @@ -418,32 +364,16 @@ type MockClient_StartPipeline_Call struct { } // StartPipeline is a helper method to define mock.On call -// - workspaceID int -// - profile string -// - stage string +// - workspaceID +// - profile +// - stage func (_e *MockClient_Expecter) StartPipeline(workspaceID interface{}, profile interface{}, stage interface{}) *MockClient_StartPipeline_Call { return &MockClient_StartPipeline_Call{Call: _e.mock.On("StartPipeline", workspaceID, profile, stage)} } func (_c *MockClient_StartPipeline_Call) Run(run func(workspaceID int, profile string, stage string)) *MockClient_StartPipeline_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 int - if args[0] != nil { - arg0 = args[0].(int) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(int), args[1].(string), args[2].(string)) }) return _c } @@ -481,26 +411,15 @@ type MockClient_SyncLandscape_Call struct { } // SyncLandscape is a helper method to define mock.On call -// - workspaceID int -// - profile string +// - workspaceID +// - profile func (_e *MockClient_Expecter) SyncLandscape(workspaceID interface{}, profile interface{}) *MockClient_SyncLandscape_Call { return &MockClient_SyncLandscape_Call{Call: _e.mock.On("SyncLandscape", workspaceID, profile)} } func (_c *MockClient_SyncLandscape_Call) Run(run func(workspaceID int, profile string)) *MockClient_SyncLandscape_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 int - if args[0] != nil { - arg0 = args[0].(int) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) + run(args[0].(int), args[1].(string)) }) return _c } diff --git a/internal/installer/mocks.go b/internal/installer/mocks.go index 797f266e..a7390604 100644 --- a/internal/installer/mocks.go +++ b/internal/installer/mocks.go @@ -61,20 +61,14 @@ type MockArgoCDResources_ApplyAll_Call struct { } // ApplyAll is a helper method to define mock.On call -// - ctx context.Context +// - ctx func (_e *MockArgoCDResources_Expecter) ApplyAll(ctx interface{}) *MockArgoCDResources_ApplyAll_Call { return &MockArgoCDResources_ApplyAll_Call{Call: _e.mock.On("ApplyAll", ctx)} } func (_c *MockArgoCDResources_ApplyAll_Call) Run(run func(ctx context.Context)) *MockArgoCDResources_ApplyAll_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - run( - arg0, - ) + run(args[0].(context.Context)) }) return _c } @@ -148,20 +142,14 @@ type MockConfigManager_ParseConfigYaml_Call struct { } // ParseConfigYaml is a helper method to define mock.On call -// - configPath string +// - configPath func (_e *MockConfigManager_Expecter) ParseConfigYaml(configPath interface{}) *MockConfigManager_ParseConfigYaml_Call { return &MockConfigManager_ParseConfigYaml_Call{Call: _e.mock.On("ParseConfigYaml", configPath)} } func (_c *MockConfigManager_ParseConfigYaml_Call) Run(run func(configPath string)) *MockConfigManager_ParseConfigYaml_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -226,20 +214,14 @@ type MockInstallConfigManager_ApplyProfile_Call struct { } // ApplyProfile is a helper method to define mock.On call -// - profile string +// - profile func (_e *MockInstallConfigManager_Expecter) ApplyProfile(profile interface{}) *MockInstallConfigManager_ApplyProfile_Call { return &MockInstallConfigManager_ApplyProfile_Call{Call: _e.mock.On("ApplyProfile", profile)} } func (_c *MockInstallConfigManager_ApplyProfile_Call) Run(run func(profile string)) *MockInstallConfigManager_ApplyProfile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -457,20 +439,14 @@ type MockInstallConfigManager_LoadInstallConfigFromFile_Call struct { } // LoadInstallConfigFromFile is a helper method to define mock.On call -// - configPath string +// - configPath func (_e *MockInstallConfigManager_Expecter) LoadInstallConfigFromFile(configPath interface{}) *MockInstallConfigManager_LoadInstallConfigFromFile_Call { return &MockInstallConfigManager_LoadInstallConfigFromFile_Call{Call: _e.mock.On("LoadInstallConfigFromFile", configPath)} } func (_c *MockInstallConfigManager_LoadInstallConfigFromFile_Call) Run(run func(configPath string)) *MockInstallConfigManager_LoadInstallConfigFromFile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -508,20 +484,14 @@ type MockInstallConfigManager_LoadVaultFromFile_Call struct { } // LoadVaultFromFile is a helper method to define mock.On call -// - vaultPath string +// - vaultPath func (_e *MockInstallConfigManager_Expecter) LoadVaultFromFile(vaultPath interface{}) *MockInstallConfigManager_LoadVaultFromFile_Call { return &MockInstallConfigManager_LoadVaultFromFile_Call{Call: _e.mock.On("LoadVaultFromFile", vaultPath)} } func (_c *MockInstallConfigManager_LoadVaultFromFile_Call) Run(run func(vaultPath string)) *MockInstallConfigManager_LoadVaultFromFile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -695,26 +665,15 @@ type MockInstallConfigManager_WriteInstallConfig_Call struct { } // WriteInstallConfig is a helper method to define mock.On call -// - configPath string -// - withComments bool +// - configPath +// - withComments func (_e *MockInstallConfigManager_Expecter) WriteInstallConfig(configPath interface{}, withComments interface{}) *MockInstallConfigManager_WriteInstallConfig_Call { return &MockInstallConfigManager_WriteInstallConfig_Call{Call: _e.mock.On("WriteInstallConfig", configPath, withComments)} } func (_c *MockInstallConfigManager_WriteInstallConfig_Call) Run(run func(configPath string, withComments bool)) *MockInstallConfigManager_WriteInstallConfig_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 bool - if args[1] != nil { - arg1 = args[1].(bool) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(bool)) }) return _c } @@ -752,26 +711,15 @@ type MockInstallConfigManager_WriteVault_Call struct { } // WriteVault is a helper method to define mock.On call -// - vaultPath string -// - withComments bool +// - vaultPath +// - withComments func (_e *MockInstallConfigManager_Expecter) WriteVault(vaultPath interface{}, withComments interface{}) *MockInstallConfigManager_WriteVault_Call { return &MockInstallConfigManager_WriteVault_Call{Call: _e.mock.On("WriteVault", vaultPath, withComments)} } func (_c *MockInstallConfigManager_WriteVault_Call) Run(run func(vaultPath string, withComments bool)) *MockInstallConfigManager_WriteVault_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 bool - if args[1] != nil { - arg1 = args[1].(bool) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(bool)) }) return _c } @@ -847,20 +795,14 @@ type MockHelmClient_FindRelease_Call struct { } // FindRelease is a helper method to define mock.On call -// - releaseName string +// - releaseName func (_e *MockHelmClient_Expecter) FindRelease(releaseName interface{}) *MockHelmClient_FindRelease_Call { return &MockHelmClient_FindRelease_Call{Call: _e.mock.On("FindRelease", releaseName)} } func (_c *MockHelmClient_FindRelease_Call) Run(run func(releaseName string)) *MockHelmClient_FindRelease_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -898,26 +840,15 @@ type MockHelmClient_InstallChart_Call struct { } // InstallChart is a helper method to define mock.On call -// - ctx context.Context -// - cfg ChartConfig +// - ctx +// - cfg func (_e *MockHelmClient_Expecter) InstallChart(ctx interface{}, cfg interface{}) *MockHelmClient_InstallChart_Call { return &MockHelmClient_InstallChart_Call{Call: _e.mock.On("InstallChart", ctx, cfg)} } func (_c *MockHelmClient_InstallChart_Call) Run(run func(ctx context.Context, cfg ChartConfig)) *MockHelmClient_InstallChart_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 ChartConfig - if args[1] != nil { - arg1 = args[1].(ChartConfig) - } - run( - arg0, - arg1, - ) + run(args[0].(context.Context), args[1].(ChartConfig)) }) return _c } @@ -955,26 +886,15 @@ type MockHelmClient_UpgradeChart_Call struct { } // UpgradeChart is a helper method to define mock.On call -// - ctx context.Context -// - cfg ChartConfig +// - ctx +// - cfg func (_e *MockHelmClient_Expecter) UpgradeChart(ctx interface{}, cfg interface{}) *MockHelmClient_UpgradeChart_Call { return &MockHelmClient_UpgradeChart_Call{Call: _e.mock.On("UpgradeChart", ctx, cfg)} } func (_c *MockHelmClient_UpgradeChart_Call) Run(run func(ctx context.Context, cfg ChartConfig)) *MockHelmClient_UpgradeChart_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 ChartConfig - if args[1] != nil { - arg1 = args[1].(ChartConfig) - } - run( - arg0, - arg1, - ) + run(args[0].(context.Context), args[1].(ChartConfig)) }) return _c } @@ -1048,32 +968,16 @@ type MockK0sManager_Download_Call struct { } // Download is a helper method to define mock.On call -// - version string -// - force bool -// - quiet bool +// - version +// - force +// - quiet func (_e *MockK0sManager_Expecter) Download(version interface{}, force interface{}, quiet interface{}) *MockK0sManager_Download_Call { return &MockK0sManager_Download_Call{Call: _e.mock.On("Download", version, force, quiet)} } func (_c *MockK0sManager_Download_Call) Run(run func(version string, force bool, quiet bool)) *MockK0sManager_Download_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 bool - if args[1] != nil { - arg1 = args[1].(bool) - } - var arg2 bool - if args[2] != nil { - arg2 = args[2].(bool) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(bool), args[2].(bool)) }) return _c } @@ -1164,32 +1068,16 @@ type MockK0sManager_Install_Call struct { } // Install is a helper method to define mock.On call -// - configPath string -// - k0sPath string -// - force bool +// - configPath +// - k0sPath +// - force func (_e *MockK0sManager_Expecter) Install(configPath interface{}, k0sPath interface{}, force interface{}) *MockK0sManager_Install_Call { return &MockK0sManager_Install_Call{Call: _e.mock.On("Install", configPath, k0sPath, force)} } func (_c *MockK0sManager_Install_Call) Run(run func(configPath string, k0sPath string, force bool)) *MockK0sManager_Install_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 bool - if args[2] != nil { - arg2 = args[2].(bool) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(bool)) }) return _c } @@ -1254,20 +1142,14 @@ type MockPackageManager_Extract_Call struct { } // Extract is a helper method to define mock.On call -// - force bool +// - force func (_e *MockPackageManager_Expecter) Extract(force interface{}) *MockPackageManager_Extract_Call { return &MockPackageManager_Extract_Call{Call: _e.mock.On("Extract", force)} } func (_c *MockPackageManager_Extract_Call) Run(run func(force bool)) *MockPackageManager_Extract_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 bool - if args[0] != nil { - arg0 = args[0].(bool) - } - run( - arg0, - ) + run(args[0].(bool)) }) return _c } @@ -1305,26 +1187,15 @@ type MockPackageManager_ExtractDependency_Call struct { } // ExtractDependency is a helper method to define mock.On call -// - file string -// - force bool +// - file +// - force func (_e *MockPackageManager_Expecter) ExtractDependency(file interface{}, force interface{}) *MockPackageManager_ExtractDependency_Call { return &MockPackageManager_ExtractDependency_Call{Call: _e.mock.On("ExtractDependency", file, force)} } func (_c *MockPackageManager_ExtractDependency_Call) Run(run func(file string, force bool)) *MockPackageManager_ExtractDependency_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 bool - if args[1] != nil { - arg1 = args[1].(bool) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(bool)) }) return _c } @@ -1371,20 +1242,14 @@ type MockPackageManager_ExtractOciImageIndex_Call struct { } // ExtractOciImageIndex is a helper method to define mock.On call -// - imagefile string +// - imagefile func (_e *MockPackageManager_Expecter) ExtractOciImageIndex(imagefile interface{}) *MockPackageManager_ExtractOciImageIndex_Call { return &MockPackageManager_ExtractOciImageIndex_Call{Call: _e.mock.On("ExtractOciImageIndex", imagefile)} } func (_c *MockPackageManager_ExtractOciImageIndex_Call) Run(run func(imagefile string)) *MockPackageManager_ExtractOciImageIndex_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -1477,20 +1342,14 @@ type MockPackageManager_GetBaseimageName_Call struct { } // GetBaseimageName is a helper method to define mock.On call -// - baseimage string +// - baseimage func (_e *MockPackageManager_Expecter) GetBaseimageName(baseimage interface{}) *MockPackageManager_GetBaseimageName_Call { return &MockPackageManager_GetBaseimageName_Call{Call: _e.mock.On("GetBaseimageName", baseimage)} } func (_c *MockPackageManager_GetBaseimageName_Call) Run(run func(baseimage string)) *MockPackageManager_GetBaseimageName_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -1537,26 +1396,15 @@ type MockPackageManager_GetBaseimagePath_Call struct { } // GetBaseimagePath is a helper method to define mock.On call -// - baseimage string -// - force bool +// - baseimage +// - force func (_e *MockPackageManager_Expecter) GetBaseimagePath(baseimage interface{}, force interface{}) *MockPackageManager_GetBaseimagePath_Call { return &MockPackageManager_GetBaseimagePath_Call{Call: _e.mock.On("GetBaseimagePath", baseimage, force)} } func (_c *MockPackageManager_GetBaseimagePath_Call) Run(run func(baseimage string, force bool)) *MockPackageManager_GetBaseimagePath_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 bool - if args[1] != nil { - arg1 = args[1].(bool) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(bool)) }) return _c } @@ -1647,20 +1495,14 @@ type MockPackageManager_GetDependencyPath_Call struct { } // GetDependencyPath is a helper method to define mock.On call -// - filename string +// - filename func (_e *MockPackageManager_Expecter) GetDependencyPath(filename interface{}) *MockPackageManager_GetDependencyPath_Call { return &MockPackageManager_GetDependencyPath_Call{Call: _e.mock.On("GetDependencyPath", filename)} } func (_c *MockPackageManager_GetDependencyPath_Call) Run(run func(filename string)) *MockPackageManager_GetDependencyPath_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } diff --git a/internal/installer/node/mocks.go b/internal/installer/node/mocks.go index f88c2503..27228da4 100644 --- a/internal/installer/node/mocks.go +++ b/internal/installer/node/mocks.go @@ -59,32 +59,16 @@ type MockNodeClient_CopyFile_Call struct { } // CopyFile is a helper method to define mock.On call -// - n *Node -// - src string -// - dst string +// - n +// - src +// - dst func (_e *MockNodeClient_Expecter) CopyFile(n interface{}, src interface{}, dst interface{}) *MockNodeClient_CopyFile_Call { return &MockNodeClient_CopyFile_Call{Call: _e.mock.On("CopyFile", n, src, dst)} } func (_c *MockNodeClient_CopyFile_Call) Run(run func(n *Node, src string, dst string)) *MockNodeClient_CopyFile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 *Node - if args[0] != nil { - arg0 = args[0].(*Node) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(*Node), args[1].(string), args[2].(string)) }) return _c } @@ -122,26 +106,15 @@ type MockNodeClient_HasFile_Call struct { } // HasFile is a helper method to define mock.On call -// - n *Node -// - filePath string +// - n +// - filePath func (_e *MockNodeClient_Expecter) HasFile(n interface{}, filePath interface{}) *MockNodeClient_HasFile_Call { return &MockNodeClient_HasFile_Call{Call: _e.mock.On("HasFile", n, filePath)} } func (_c *MockNodeClient_HasFile_Call) Run(run func(n *Node, filePath string)) *MockNodeClient_HasFile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 *Node - if args[0] != nil { - arg0 = args[0].(*Node) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) + run(args[0].(*Node), args[1].(string)) }) return _c } @@ -179,32 +152,16 @@ type MockNodeClient_RunCommand_Call struct { } // RunCommand is a helper method to define mock.On call -// - n *Node -// - username string -// - command string +// - n +// - username +// - command func (_e *MockNodeClient_Expecter) RunCommand(n interface{}, username interface{}, command interface{}) *MockNodeClient_RunCommand_Call { return &MockNodeClient_RunCommand_Call{Call: _e.mock.On("RunCommand", n, username, command)} } func (_c *MockNodeClient_RunCommand_Call) Run(run func(n *Node, username string, command string)) *MockNodeClient_RunCommand_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 *Node - if args[0] != nil { - arg0 = args[0].(*Node) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(*Node), args[1].(string), args[2].(string)) }) return _c } @@ -242,26 +199,15 @@ type MockNodeClient_WaitReady_Call struct { } // WaitReady is a helper method to define mock.On call -// - n *Node -// - timeout time.Duration +// - n +// - timeout func (_e *MockNodeClient_Expecter) WaitReady(n interface{}, timeout interface{}) *MockNodeClient_WaitReady_Call { return &MockNodeClient_WaitReady_Call{Call: _e.mock.On("WaitReady", n, timeout)} } func (_c *MockNodeClient_WaitReady_Call) Run(run func(n *Node, timeout time.Duration)) *MockNodeClient_WaitReady_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 *Node - if args[0] != nil { - arg0 = args[0].(*Node) - } - var arg1 time.Duration - if args[1] != nil { - arg1 = args[1].(time.Duration) - } - run( - arg0, - arg1, - ) + run(args[0].(*Node), args[1].(time.Duration)) }) return _c } diff --git a/internal/portal/mocks.go b/internal/portal/mocks.go index c162a3ee..83372369 100644 --- a/internal/portal/mocks.go +++ b/internal/portal/mocks.go @@ -61,32 +61,16 @@ type MockHttp_Download_Call struct { } // Download is a helper method to define mock.On call -// - url string -// - file io.Writer -// - quiet bool +// - url +// - file +// - quiet func (_e *MockHttp_Expecter) Download(url interface{}, file interface{}, quiet interface{}) *MockHttp_Download_Call { return &MockHttp_Download_Call{Call: _e.mock.On("Download", url, file, quiet)} } func (_c *MockHttp_Download_Call) Run(run func(url string, file io.Writer, quiet bool)) *MockHttp_Download_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 io.Writer - if args[1] != nil { - arg1 = args[1].(io.Writer) - } - var arg2 bool - if args[2] != nil { - arg2 = args[2].(bool) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(io.Writer), args[2].(bool)) }) return _c } @@ -135,20 +119,14 @@ type MockHttp_Get_Call struct { } // Get is a helper method to define mock.On call -// - url string +// - url func (_e *MockHttp_Expecter) Get(url interface{}) *MockHttp_Get_Call { return &MockHttp_Get_Call{Call: _e.mock.On("Get", url)} } func (_c *MockHttp_Get_Call) Run(run func(url string)) *MockHttp_Get_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -197,32 +175,16 @@ type MockHttp_Request_Call struct { } // Request is a helper method to define mock.On call -// - url string -// - method string -// - body io.Reader +// - url +// - method +// - body func (_e *MockHttp_Expecter) Request(url interface{}, method interface{}, body interface{}) *MockHttp_Request_Call { return &MockHttp_Request_Call{Call: _e.mock.On("Request", url, method, body)} } func (_c *MockHttp_Request_Call) Run(run func(url string, method string, body io.Reader)) *MockHttp_Request_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 io.Reader - if args[2] != nil { - arg2 = args[2].(io.Reader) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(io.Reader)) }) return _c } @@ -287,44 +249,18 @@ type MockPortal_DownloadBuildArtifact_Call struct { } // DownloadBuildArtifact is a helper method to define mock.On call -// - product Product -// - build Build -// - file io.Writer -// - startByte int -// - quiet bool +// - product +// - build +// - file +// - startByte +// - quiet func (_e *MockPortal_Expecter) DownloadBuildArtifact(product interface{}, build interface{}, file interface{}, startByte interface{}, quiet interface{}) *MockPortal_DownloadBuildArtifact_Call { return &MockPortal_DownloadBuildArtifact_Call{Call: _e.mock.On("DownloadBuildArtifact", product, build, file, startByte, quiet)} } func (_c *MockPortal_DownloadBuildArtifact_Call) Run(run func(product Product, build Build, file io.Writer, startByte int, quiet bool)) *MockPortal_DownloadBuildArtifact_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 Product - if args[0] != nil { - arg0 = args[0].(Product) - } - var arg1 Build - if args[1] != nil { - arg1 = args[1].(Build) - } - var arg2 io.Writer - if args[2] != nil { - arg2 = args[2].(io.Writer) - } - var arg3 int - if args[3] != nil { - arg3 = args[3].(int) - } - var arg4 bool - if args[4] != nil { - arg4 = args[4].(bool) - } - run( - arg0, - arg1, - arg2, - arg3, - arg4, - ) + run(args[0].(Product), args[1].(Build), args[2].(io.Writer), args[3].(int), args[4].(bool)) }) return _c } @@ -371,20 +307,14 @@ type MockPortal_GetApiKeyId_Call struct { } // GetApiKeyId is a helper method to define mock.On call -// - oldKey string +// - oldKey func (_e *MockPortal_Expecter) GetApiKeyId(oldKey interface{}) *MockPortal_GetApiKeyId_Call { return &MockPortal_GetApiKeyId_Call{Call: _e.mock.On("GetApiKeyId", oldKey)} } func (_c *MockPortal_GetApiKeyId_Call) Run(run func(oldKey string)) *MockPortal_GetApiKeyId_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -431,32 +361,16 @@ type MockPortal_GetBuild_Call struct { } // GetBuild is a helper method to define mock.On call -// - product Product -// - version string -// - hash string +// - product +// - version +// - hash func (_e *MockPortal_Expecter) GetBuild(product interface{}, version interface{}, hash interface{}) *MockPortal_GetBuild_Call { return &MockPortal_GetBuild_Call{Call: _e.mock.On("GetBuild", product, version, hash)} } func (_c *MockPortal_GetBuild_Call) Run(run func(product Product, version string, hash string)) *MockPortal_GetBuild_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 Product - if args[0] != nil { - arg0 = args[0].(Product) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(Product), args[1].(string), args[2].(string)) }) return _c } @@ -558,20 +472,14 @@ type MockPortal_ListBuilds_Call struct { } // ListBuilds is a helper method to define mock.On call -// - product Product +// - product func (_e *MockPortal_Expecter) ListBuilds(product interface{}) *MockPortal_ListBuilds_Call { return &MockPortal_ListBuilds_Call{Call: _e.mock.On("ListBuilds", product)} } func (_c *MockPortal_ListBuilds_Call) Run(run func(product Product)) *MockPortal_ListBuilds_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 Product - if args[0] != nil { - arg0 = args[0].(Product) - } - run( - arg0, - ) + run(args[0].(Product)) }) return _c } @@ -620,38 +528,17 @@ type MockPortal_RegisterAPIKey_Call struct { } // RegisterAPIKey is a helper method to define mock.On call -// - owner string -// - organization string -// - role string -// - expiresAt time.Time +// - owner +// - organization +// - role +// - expiresAt func (_e *MockPortal_Expecter) RegisterAPIKey(owner interface{}, organization interface{}, role interface{}, expiresAt interface{}) *MockPortal_RegisterAPIKey_Call { return &MockPortal_RegisterAPIKey_Call{Call: _e.mock.On("RegisterAPIKey", owner, organization, role, expiresAt)} } func (_c *MockPortal_RegisterAPIKey_Call) Run(run func(owner string, organization string, role string, expiresAt time.Time)) *MockPortal_RegisterAPIKey_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 time.Time - if args[3] != nil { - arg3 = args[3].(time.Time) - } - run( - arg0, - arg1, - arg2, - arg3, - ) + run(args[0].(string), args[1].(string), args[2].(string), args[3].(time.Time)) }) return _c } @@ -689,20 +576,14 @@ type MockPortal_RevokeAPIKey_Call struct { } // RevokeAPIKey is a helper method to define mock.On call -// - key string +// - key func (_e *MockPortal_Expecter) RevokeAPIKey(key interface{}) *MockPortal_RevokeAPIKey_Call { return &MockPortal_RevokeAPIKey_Call{Call: _e.mock.On("RevokeAPIKey", key)} } func (_c *MockPortal_RevokeAPIKey_Call) Run(run func(key string)) *MockPortal_RevokeAPIKey_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -740,26 +621,15 @@ type MockPortal_UpdateAPIKey_Call struct { } // UpdateAPIKey is a helper method to define mock.On call -// - key string -// - expiresAt time.Time +// - key +// - expiresAt func (_e *MockPortal_Expecter) UpdateAPIKey(key interface{}, expiresAt interface{}) *MockPortal_UpdateAPIKey_Call { return &MockPortal_UpdateAPIKey_Call{Call: _e.mock.On("UpdateAPIKey", key, expiresAt)} } func (_c *MockPortal_UpdateAPIKey_Call) Run(run func(key string, expiresAt time.Time)) *MockPortal_UpdateAPIKey_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 time.Time - if args[1] != nil { - arg1 = args[1].(time.Time) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(time.Time)) }) return _c } @@ -797,26 +667,15 @@ type MockPortal_VerifyBuildArtifactDownload_Call struct { } // VerifyBuildArtifactDownload is a helper method to define mock.On call -// - file io.Reader -// - download Build +// - file +// - download func (_e *MockPortal_Expecter) VerifyBuildArtifactDownload(file interface{}, download interface{}) *MockPortal_VerifyBuildArtifactDownload_Call { return &MockPortal_VerifyBuildArtifactDownload_Call{Call: _e.mock.On("VerifyBuildArtifactDownload", file, download)} } func (_c *MockPortal_VerifyBuildArtifactDownload_Call) Run(run func(file io.Reader, download Build)) *MockPortal_VerifyBuildArtifactDownload_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 io.Reader - if args[0] != nil { - arg0 = args[0].(io.Reader) - } - var arg1 Build - if args[1] != nil { - arg1 = args[1].(Build) - } - run( - arg0, - arg1, - ) + run(args[0].(io.Reader), args[1].(Build)) }) return _c } @@ -892,20 +751,14 @@ type MockHttpClient_Do_Call struct { } // Do is a helper method to define mock.On call -// - request *http.Request +// - request func (_e *MockHttpClient_Expecter) Do(request interface{}) *MockHttpClient_Do_Call { return &MockHttpClient_Do_Call{Call: _e.mock.On("Do", request)} } func (_c *MockHttpClient_Do_Call) Run(run func(request *http.Request)) *MockHttpClient_Do_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 *http.Request - if args[0] != nil { - arg0 = args[0].(*http.Request) - } - run( - arg0, - ) + run(args[0].(*http.Request)) }) return _c } diff --git a/internal/system/mocks.go b/internal/system/mocks.go index ee80bc69..cf8e9292 100644 --- a/internal/system/mocks.go +++ b/internal/system/mocks.go @@ -58,32 +58,16 @@ type MockImageManager_BuildImage_Call struct { } // BuildImage is a helper method to define mock.On call -// - dockerfile string -// - tag string -// - buildContext string +// - dockerfile +// - tag +// - buildContext func (_e *MockImageManager_Expecter) BuildImage(dockerfile interface{}, tag interface{}, buildContext interface{}) *MockImageManager_BuildImage_Call { return &MockImageManager_BuildImage_Call{Call: _e.mock.On("BuildImage", dockerfile, tag, buildContext)} } func (_c *MockImageManager_BuildImage_Call) Run(run func(dockerfile string, tag string, buildContext string)) *MockImageManager_BuildImage_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(string), args[2].(string)) }) return _c } @@ -121,20 +105,14 @@ type MockImageManager_LoadImage_Call struct { } // LoadImage is a helper method to define mock.On call -// - imageTarPath string +// - imageTarPath func (_e *MockImageManager_Expecter) LoadImage(imageTarPath interface{}) *MockImageManager_LoadImage_Call { return &MockImageManager_LoadImage_Call{Call: _e.mock.On("LoadImage", imageTarPath)} } func (_c *MockImageManager_LoadImage_Call) Run(run func(imageTarPath string)) *MockImageManager_LoadImage_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -172,20 +150,14 @@ type MockImageManager_PushImage_Call struct { } // PushImage is a helper method to define mock.On call -// - tag string +// - tag func (_e *MockImageManager_Expecter) PushImage(tag interface{}) *MockImageManager_PushImage_Call { return &MockImageManager_PushImage_Call{Call: _e.mock.On("PushImage", tag)} } func (_c *MockImageManager_PushImage_Call) Run(run func(tag string)) *MockImageManager_PushImage_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } diff --git a/internal/util/mocks.go b/internal/util/mocks.go index 2912e9d3..a002ef16 100644 --- a/internal/util/mocks.go +++ b/internal/util/mocks.go @@ -71,26 +71,15 @@ type MockDockerfileManager_UpdateFromStatement_Call struct { } // UpdateFromStatement is a helper method to define mock.On call -// - dockerfile io.Reader -// - baseImage string +// - dockerfile +// - baseImage func (_e *MockDockerfileManager_Expecter) UpdateFromStatement(dockerfile interface{}, baseImage interface{}) *MockDockerfileManager_UpdateFromStatement_Call { return &MockDockerfileManager_UpdateFromStatement_Call{Call: _e.mock.On("UpdateFromStatement", dockerfile, baseImage)} } func (_c *MockDockerfileManager_UpdateFromStatement_Call) Run(run func(dockerfile io.Reader, baseImage string)) *MockDockerfileManager_UpdateFromStatement_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 io.Reader - if args[0] != nil { - arg0 = args[0].(io.Reader) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) + run(args[0].(io.Reader), args[1].(string)) }) return _c } @@ -166,20 +155,14 @@ type MockFileIO_Create_Call struct { } // Create is a helper method to define mock.On call -// - filename string +// - filename func (_e *MockFileIO_Expecter) Create(filename interface{}) *MockFileIO_Create_Call { return &MockFileIO_Create_Call{Call: _e.mock.On("Create", filename)} } func (_c *MockFileIO_Create_Call) Run(run func(filename string)) *MockFileIO_Create_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -217,32 +200,16 @@ type MockFileIO_CreateAndWrite_Call struct { } // CreateAndWrite is a helper method to define mock.On call -// - filePath string -// - data []byte -// - fileType string +// - filePath +// - data +// - fileType func (_e *MockFileIO_Expecter) CreateAndWrite(filePath interface{}, data interface{}, fileType interface{}) *MockFileIO_CreateAndWrite_Call { return &MockFileIO_CreateAndWrite_Call{Call: _e.mock.On("CreateAndWrite", filePath, data, fileType)} } func (_c *MockFileIO_CreateAndWrite_Call) Run(run func(filePath string, data []byte, fileType string)) *MockFileIO_CreateAndWrite_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 []byte - if args[1] != nil { - arg1 = args[1].([]byte) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].([]byte), args[2].(string)) }) return _c } @@ -280,20 +247,14 @@ type MockFileIO_Exists_Call struct { } // Exists is a helper method to define mock.On call -// - filename string +// - filename func (_e *MockFileIO_Expecter) Exists(filename interface{}) *MockFileIO_Exists_Call { return &MockFileIO_Exists_Call{Call: _e.mock.On("Exists", filename)} } func (_c *MockFileIO_Exists_Call) Run(run func(filename string)) *MockFileIO_Exists_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -340,20 +301,14 @@ type MockFileIO_IsDirectory_Call struct { } // IsDirectory is a helper method to define mock.On call -// - filename string +// - filename func (_e *MockFileIO_Expecter) IsDirectory(filename interface{}) *MockFileIO_IsDirectory_Call { return &MockFileIO_IsDirectory_Call{Call: _e.mock.On("IsDirectory", filename)} } func (_c *MockFileIO_IsDirectory_Call) Run(run func(filename string)) *MockFileIO_IsDirectory_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -391,26 +346,15 @@ type MockFileIO_MkdirAll_Call struct { } // MkdirAll is a helper method to define mock.On call -// - path string -// - perm os.FileMode +// - path +// - perm func (_e *MockFileIO_Expecter) MkdirAll(path interface{}, perm interface{}) *MockFileIO_MkdirAll_Call { return &MockFileIO_MkdirAll_Call{Call: _e.mock.On("MkdirAll", path, perm)} } func (_c *MockFileIO_MkdirAll_Call) Run(run func(path string, perm os.FileMode)) *MockFileIO_MkdirAll_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 os.FileMode - if args[1] != nil { - arg1 = args[1].(os.FileMode) - } - run( - arg0, - arg1, - ) + run(args[0].(string), args[1].(os.FileMode)) }) return _c } @@ -459,20 +403,14 @@ type MockFileIO_Open_Call struct { } // Open is a helper method to define mock.On call -// - filename string +// - filename func (_e *MockFileIO_Expecter) Open(filename interface{}) *MockFileIO_Open_Call { return &MockFileIO_Open_Call{Call: _e.mock.On("Open", filename)} } func (_c *MockFileIO_Open_Call) Run(run func(filename string)) *MockFileIO_Open_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -521,20 +459,14 @@ type MockFileIO_OpenAppend_Call struct { } // OpenAppend is a helper method to define mock.On call -// - filename string +// - filename func (_e *MockFileIO_Expecter) OpenAppend(filename interface{}) *MockFileIO_OpenAppend_Call { return &MockFileIO_OpenAppend_Call{Call: _e.mock.On("OpenAppend", filename)} } func (_c *MockFileIO_OpenAppend_Call) Run(run func(filename string)) *MockFileIO_OpenAppend_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -583,32 +515,16 @@ type MockFileIO_OpenFile_Call struct { } // OpenFile is a helper method to define mock.On call -// - name string -// - flag int -// - perm os.FileMode +// - name +// - flag +// - perm func (_e *MockFileIO_Expecter) OpenFile(name interface{}, flag interface{}, perm interface{}) *MockFileIO_OpenFile_Call { return &MockFileIO_OpenFile_Call{Call: _e.mock.On("OpenFile", name, flag, perm)} } func (_c *MockFileIO_OpenFile_Call) Run(run func(name string, flag int, perm os.FileMode)) *MockFileIO_OpenFile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 int - if args[1] != nil { - arg1 = args[1].(int) - } - var arg2 os.FileMode - if args[2] != nil { - arg2 = args[2].(os.FileMode) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].(int), args[2].(os.FileMode)) }) return _c } @@ -657,20 +573,14 @@ type MockFileIO_ReadDir_Call struct { } // ReadDir is a helper method to define mock.On call -// - dirname string +// - dirname func (_e *MockFileIO_Expecter) ReadDir(dirname interface{}) *MockFileIO_ReadDir_Call { return &MockFileIO_ReadDir_Call{Call: _e.mock.On("ReadDir", dirname)} } func (_c *MockFileIO_ReadDir_Call) Run(run func(dirname string)) *MockFileIO_ReadDir_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -719,20 +629,14 @@ type MockFileIO_ReadFile_Call struct { } // ReadFile is a helper method to define mock.On call -// - filename string +// - filename func (_e *MockFileIO_Expecter) ReadFile(filename interface{}) *MockFileIO_ReadFile_Call { return &MockFileIO_ReadFile_Call{Call: _e.mock.On("ReadFile", filename)} } func (_c *MockFileIO_ReadFile_Call) Run(run func(filename string)) *MockFileIO_ReadFile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -770,20 +674,14 @@ type MockFileIO_Remove_Call struct { } // Remove is a helper method to define mock.On call -// - path string +// - path func (_e *MockFileIO_Expecter) Remove(path interface{}) *MockFileIO_Remove_Call { return &MockFileIO_Remove_Call{Call: _e.mock.On("Remove", path)} } func (_c *MockFileIO_Remove_Call) Run(run func(path string)) *MockFileIO_Remove_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) + run(args[0].(string)) }) return _c } @@ -821,32 +719,16 @@ type MockFileIO_WriteFile_Call struct { } // WriteFile is a helper method to define mock.On call -// - filename string -// - data []byte -// - perm os.FileMode +// - filename +// - data +// - perm func (_e *MockFileIO_Expecter) WriteFile(filename interface{}, data interface{}, perm interface{}) *MockFileIO_WriteFile_Call { return &MockFileIO_WriteFile_Call{Call: _e.mock.On("WriteFile", filename, data, perm)} } func (_c *MockFileIO_WriteFile_Call) Run(run func(filename string, data []byte, perm os.FileMode)) *MockFileIO_WriteFile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 []byte - if args[1] != nil { - arg1 = args[1].([]byte) - } - var arg2 os.FileMode - if args[2] != nil { - arg2 = args[2].(os.FileMode) - } - run( - arg0, - arg1, - arg2, - ) + run(args[0].(string), args[1].([]byte), args[2].(os.FileMode)) }) return _c } @@ -976,8 +858,8 @@ type MockTableWriter_AppendHeader_Call struct { } // AppendHeader is a helper method to define mock.On call -// - row table.Row -// - configs ...table.RowConfig +// - row +// - configs func (_e *MockTableWriter_Expecter) AppendHeader(row interface{}, configs ...interface{}) *MockTableWriter_AppendHeader_Call { return &MockTableWriter_AppendHeader_Call{Call: _e.mock.On("AppendHeader", append([]interface{}{row}, configs...)...)} @@ -985,20 +867,13 @@ func (_e *MockTableWriter_Expecter) AppendHeader(row interface{}, configs ...int func (_c *MockTableWriter_AppendHeader_Call) Run(run func(row table.Row, configs ...table.RowConfig)) *MockTableWriter_AppendHeader_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 table.Row - if args[0] != nil { - arg0 = args[0].(table.Row) + variadicArgs := make([]table.RowConfig, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(table.RowConfig) + } } - var arg1 []table.RowConfig - var variadicArgs []table.RowConfig - if len(args) > 1 { - variadicArgs = args[1].([]table.RowConfig) - } - arg1 = variadicArgs - run( - arg0, - arg1..., - ) + run(args[0].(table.Row), variadicArgs...) }) return _c } @@ -1030,8 +905,8 @@ type MockTableWriter_AppendRow_Call struct { } // AppendRow is a helper method to define mock.On call -// - row table.Row -// - configs ...table.RowConfig +// - row +// - configs func (_e *MockTableWriter_Expecter) AppendRow(row interface{}, configs ...interface{}) *MockTableWriter_AppendRow_Call { return &MockTableWriter_AppendRow_Call{Call: _e.mock.On("AppendRow", append([]interface{}{row}, configs...)...)} @@ -1039,20 +914,13 @@ func (_e *MockTableWriter_Expecter) AppendRow(row interface{}, configs ...interf func (_c *MockTableWriter_AppendRow_Call) Run(run func(row table.Row, configs ...table.RowConfig)) *MockTableWriter_AppendRow_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 table.Row - if args[0] != nil { - arg0 = args[0].(table.Row) - } - var arg1 []table.RowConfig - var variadicArgs []table.RowConfig - if len(args) > 1 { - variadicArgs = args[1].([]table.RowConfig) + variadicArgs := make([]table.RowConfig, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(table.RowConfig) + } } - arg1 = variadicArgs - run( - arg0, - arg1..., - ) + run(args[0].(table.Row), variadicArgs...) }) return _c } @@ -1194,20 +1062,14 @@ type MockTime_Sleep_Call struct { } // Sleep is a helper method to define mock.On call -// - duration time.Duration +// - duration func (_e *MockTime_Expecter) Sleep(duration interface{}) *MockTime_Sleep_Call { return &MockTime_Sleep_Call{Call: _e.mock.On("Sleep", duration)} } func (_c *MockTime_Sleep_Call) Run(run func(duration time.Duration)) *MockTime_Sleep_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 time.Duration - if args[0] != nil { - arg0 = args[0].(time.Duration) - } - run( - arg0, - ) + run(args[0].(time.Duration)) }) return _c } From df5efc33f3bf28827c0c411a85e8bf337c5a004d Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Fri, 13 Mar 2026 11:51:41 +0000 Subject: [PATCH 11/30] chore(docs): Auto-update docs and licenses Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> --- cli/cmd/mocks.go | 24 +- internal/bootstrap/gcp/mocks.go | 537 +++++++++++++++++++++++++------ internal/codesphere/mocks.go | 123 +++++-- internal/installer/mocks.go | 250 +++++++++++--- internal/installer/node/mocks.go | 82 ++++- internal/portal/mocks.go | 225 ++++++++++--- internal/system/mocks.go | 44 ++- internal/util/mocks.go | 242 +++++++++++--- 8 files changed, 1251 insertions(+), 276 deletions(-) diff --git a/cli/cmd/mocks.go b/cli/cmd/mocks.go index 60357284..26b37df5 100644 --- a/cli/cmd/mocks.go +++ b/cli/cmd/mocks.go @@ -75,16 +75,32 @@ type MockOMSUpdater_Update_Call struct { } // Update is a helper method to define mock.On call -// - ctx -// - current -// - repo +// - ctx context.Context +// - current string +// - repo selfupdate.Repository func (_e *MockOMSUpdater_Expecter) Update(ctx interface{}, current interface{}, repo interface{}) *MockOMSUpdater_Update_Call { return &MockOMSUpdater_Update_Call{Call: _e.mock.On("Update", ctx, current, repo)} } func (_c *MockOMSUpdater_Update_Call) Run(run func(ctx context.Context, current string, repo selfupdate.Repository)) *MockOMSUpdater_Update_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(selfupdate.Repository)) + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 selfupdate.Repository + if args[2] != nil { + arg2 = args[2].(selfupdate.Repository) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } diff --git a/internal/bootstrap/gcp/mocks.go b/internal/bootstrap/gcp/mocks.go index 9a6b87e5..ea8c1aa0 100644 --- a/internal/bootstrap/gcp/mocks.go +++ b/internal/bootstrap/gcp/mocks.go @@ -5,14 +5,13 @@ package gcp import ( - "time" - "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" "cloud.google.com/go/compute/apiv1/computepb" "cloud.google.com/go/resourcemanager/apiv3/resourcemanagerpb" mock "github.com/stretchr/testify/mock" "google.golang.org/api/cloudbilling/v1" "google.golang.org/api/dns/v1" + "time" ) // NewMockGCPClientManager creates a new instance of MockGCPClientManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. @@ -65,17 +64,38 @@ type MockGCPClientManager_AssignIAMRole_Call struct { } // AssignIAMRole is a helper method to define mock.On call -// - projectID -// - saEmail -// - saProjectID -// - roles +// - projectID string +// - saEmail string +// - saProjectID string +// - roles []string func (_e *MockGCPClientManager_Expecter) AssignIAMRole(projectID interface{}, saEmail interface{}, saProjectID interface{}, roles interface{}) *MockGCPClientManager_AssignIAMRole_Call { return &MockGCPClientManager_AssignIAMRole_Call{Call: _e.mock.On("AssignIAMRole", projectID, saEmail, saProjectID, roles)} } func (_c *MockGCPClientManager_AssignIAMRole_Call) Run(run func(projectID string, saEmail string, saProjectID string, roles []string)) *MockGCPClientManager_AssignIAMRole_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string), args[3].([]string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 []string + if args[3] != nil { + arg3 = args[3].([]string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) }) return _c } @@ -122,16 +142,32 @@ type MockGCPClientManager_CreateAddress_Call struct { } // CreateAddress is a helper method to define mock.On call -// - projectID -// - region -// - address +// - projectID string +// - region string +// - address *computepb.Address func (_e *MockGCPClientManager_Expecter) CreateAddress(projectID interface{}, region interface{}, address interface{}) *MockGCPClientManager_CreateAddress_Call { return &MockGCPClientManager_CreateAddress_Call{Call: _e.mock.On("CreateAddress", projectID, region, address)} } func (_c *MockGCPClientManager_CreateAddress_Call) Run(run func(projectID string, region string, address *computepb.Address)) *MockGCPClientManager_CreateAddress_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(*computepb.Address)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 *computepb.Address + if args[2] != nil { + arg2 = args[2].(*computepb.Address) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -180,16 +216,32 @@ type MockGCPClientManager_CreateArtifactRegistry_Call struct { } // CreateArtifactRegistry is a helper method to define mock.On call -// - projectID -// - region -// - repoName +// - projectID string +// - region string +// - repoName string func (_e *MockGCPClientManager_Expecter) CreateArtifactRegistry(projectID interface{}, region interface{}, repoName interface{}) *MockGCPClientManager_CreateArtifactRegistry_Call { return &MockGCPClientManager_CreateArtifactRegistry_Call{Call: _e.mock.On("CreateArtifactRegistry", projectID, region, repoName)} } func (_c *MockGCPClientManager_CreateArtifactRegistry_Call) Run(run func(projectID string, region string, repoName string)) *MockGCPClientManager_CreateArtifactRegistry_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -227,15 +279,26 @@ type MockGCPClientManager_CreateFirewallRule_Call struct { } // CreateFirewallRule is a helper method to define mock.On call -// - projectID -// - rule +// - projectID string +// - rule *computepb.Firewall func (_e *MockGCPClientManager_Expecter) CreateFirewallRule(projectID interface{}, rule interface{}) *MockGCPClientManager_CreateFirewallRule_Call { return &MockGCPClientManager_CreateFirewallRule_Call{Call: _e.mock.On("CreateFirewallRule", projectID, rule)} } func (_c *MockGCPClientManager_CreateFirewallRule_Call) Run(run func(projectID string, rule *computepb.Firewall)) *MockGCPClientManager_CreateFirewallRule_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(*computepb.Firewall)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 *computepb.Firewall + if args[1] != nil { + arg1 = args[1].(*computepb.Firewall) + } + run( + arg0, + arg1, + ) }) return _c } @@ -273,16 +336,32 @@ type MockGCPClientManager_CreateInstance_Call struct { } // CreateInstance is a helper method to define mock.On call -// - projectID -// - zone -// - instance +// - projectID string +// - zone string +// - instance *computepb.Instance func (_e *MockGCPClientManager_Expecter) CreateInstance(projectID interface{}, zone interface{}, instance interface{}) *MockGCPClientManager_CreateInstance_Call { return &MockGCPClientManager_CreateInstance_Call{Call: _e.mock.On("CreateInstance", projectID, zone, instance)} } func (_c *MockGCPClientManager_CreateInstance_Call) Run(run func(projectID string, zone string, instance *computepb.Instance)) *MockGCPClientManager_CreateInstance_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(*computepb.Instance)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 *computepb.Instance + if args[2] != nil { + arg2 = args[2].(*computepb.Instance) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -329,17 +408,38 @@ type MockGCPClientManager_CreateProject_Call struct { } // CreateProject is a helper method to define mock.On call -// - parent -// - projectName -// - displayName -// - ttl +// - parent string +// - projectName string +// - displayName string +// - ttl time.Duration func (_e *MockGCPClientManager_Expecter) CreateProject(parent interface{}, projectName interface{}, displayName interface{}, ttl interface{}) *MockGCPClientManager_CreateProject_Call { return &MockGCPClientManager_CreateProject_Call{Call: _e.mock.On("CreateProject", parent, projectName, displayName, ttl)} } func (_c *MockGCPClientManager_CreateProject_Call) Run(run func(parent string, projectName string, displayName string, ttl time.Duration)) *MockGCPClientManager_CreateProject_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string), args[3].(time.Duration)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 time.Duration + if args[3] != nil { + arg3 = args[3].(time.Duration) + } + run( + arg0, + arg1, + arg2, + arg3, + ) }) return _c } @@ -377,14 +477,20 @@ type MockGCPClientManager_CreateProjectID_Call struct { } // CreateProjectID is a helper method to define mock.On call -// - projectName +// - projectName string func (_e *MockGCPClientManager_Expecter) CreateProjectID(projectName interface{}) *MockGCPClientManager_CreateProjectID_Call { return &MockGCPClientManager_CreateProjectID_Call{Call: _e.mock.On("CreateProjectID", projectName)} } func (_c *MockGCPClientManager_CreateProjectID_Call) Run(run func(projectName string)) *MockGCPClientManager_CreateProjectID_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -437,16 +543,32 @@ type MockGCPClientManager_CreateServiceAccount_Call struct { } // CreateServiceAccount is a helper method to define mock.On call -// - projectID -// - name -// - displayName +// - projectID string +// - name string +// - displayName string func (_e *MockGCPClientManager_Expecter) CreateServiceAccount(projectID interface{}, name interface{}, displayName interface{}) *MockGCPClientManager_CreateServiceAccount_Call { return &MockGCPClientManager_CreateServiceAccount_Call{Call: _e.mock.On("CreateServiceAccount", projectID, name, displayName)} } func (_c *MockGCPClientManager_CreateServiceAccount_Call) Run(run func(projectID string, name string, displayName string)) *MockGCPClientManager_CreateServiceAccount_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -493,15 +615,26 @@ type MockGCPClientManager_CreateServiceAccountKey_Call struct { } // CreateServiceAccountKey is a helper method to define mock.On call -// - projectID -// - saEmail +// - projectID string +// - saEmail string func (_e *MockGCPClientManager_Expecter) CreateServiceAccountKey(projectID interface{}, saEmail interface{}) *MockGCPClientManager_CreateServiceAccountKey_Call { return &MockGCPClientManager_CreateServiceAccountKey_Call{Call: _e.mock.On("CreateServiceAccountKey", projectID, saEmail)} } func (_c *MockGCPClientManager_CreateServiceAccountKey_Call) Run(run func(projectID string, saEmail string)) *MockGCPClientManager_CreateServiceAccountKey_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) }) return _c } @@ -539,19 +672,50 @@ type MockGCPClientManager_CreateVPC_Call struct { } // CreateVPC is a helper method to define mock.On call -// - projectID -// - region -// - networkName -// - subnetName -// - routerName -// - natName +// - projectID string +// - region string +// - networkName string +// - subnetName string +// - routerName string +// - natName string func (_e *MockGCPClientManager_Expecter) CreateVPC(projectID interface{}, region interface{}, networkName interface{}, subnetName interface{}, routerName interface{}, natName interface{}) *MockGCPClientManager_CreateVPC_Call { return &MockGCPClientManager_CreateVPC_Call{Call: _e.mock.On("CreateVPC", projectID, region, networkName, subnetName, routerName, natName)} } func (_c *MockGCPClientManager_CreateVPC_Call) Run(run func(projectID string, region string, networkName string, subnetName string, routerName string, natName string)) *MockGCPClientManager_CreateVPC_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string), args[3].(string), args[4].(string), args[5].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 string + if args[3] != nil { + arg3 = args[3].(string) + } + var arg4 string + if args[4] != nil { + arg4 = args[4].(string) + } + var arg5 string + if args[5] != nil { + arg5 = args[5].(string) + } + run( + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + ) }) return _c } @@ -589,16 +753,32 @@ type MockGCPClientManager_DeleteDNSRecordSets_Call struct { } // DeleteDNSRecordSets is a helper method to define mock.On call -// - projectID -// - zoneName -// - baseDomain +// - projectID string +// - zoneName string +// - baseDomain string func (_e *MockGCPClientManager_Expecter) DeleteDNSRecordSets(projectID interface{}, zoneName interface{}, baseDomain interface{}) *MockGCPClientManager_DeleteDNSRecordSets_Call { return &MockGCPClientManager_DeleteDNSRecordSets_Call{Call: _e.mock.On("DeleteDNSRecordSets", projectID, zoneName, baseDomain)} } func (_c *MockGCPClientManager_DeleteDNSRecordSets_Call) Run(run func(projectID string, zoneName string, baseDomain string)) *MockGCPClientManager_DeleteDNSRecordSets_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -636,14 +816,20 @@ type MockGCPClientManager_DeleteProject_Call struct { } // DeleteProject is a helper method to define mock.On call -// - projectID +// - projectID string func (_e *MockGCPClientManager_Expecter) DeleteProject(projectID interface{}) *MockGCPClientManager_DeleteProject_Call { return &MockGCPClientManager_DeleteProject_Call{Call: _e.mock.On("DeleteProject", projectID)} } func (_c *MockGCPClientManager_DeleteProject_Call) Run(run func(projectID string)) *MockGCPClientManager_DeleteProject_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -681,15 +867,26 @@ type MockGCPClientManager_EnableAPIs_Call struct { } // EnableAPIs is a helper method to define mock.On call -// - projectID -// - apis +// - projectID string +// - apis []string func (_e *MockGCPClientManager_Expecter) EnableAPIs(projectID interface{}, apis interface{}) *MockGCPClientManager_EnableAPIs_Call { return &MockGCPClientManager_EnableAPIs_Call{Call: _e.mock.On("EnableAPIs", projectID, apis)} } func (_c *MockGCPClientManager_EnableAPIs_Call) Run(run func(projectID string, apis []string)) *MockGCPClientManager_EnableAPIs_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].([]string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 []string + if args[1] != nil { + arg1 = args[1].([]string) + } + run( + arg0, + arg1, + ) }) return _c } @@ -727,15 +924,26 @@ type MockGCPClientManager_EnableBilling_Call struct { } // EnableBilling is a helper method to define mock.On call -// - projectID -// - billingAccount +// - projectID string +// - billingAccount string func (_e *MockGCPClientManager_Expecter) EnableBilling(projectID interface{}, billingAccount interface{}) *MockGCPClientManager_EnableBilling_Call { return &MockGCPClientManager_EnableBilling_Call{Call: _e.mock.On("EnableBilling", projectID, billingAccount)} } func (_c *MockGCPClientManager_EnableBilling_Call) Run(run func(projectID string, billingAccount string)) *MockGCPClientManager_EnableBilling_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) }) return _c } @@ -773,17 +981,38 @@ type MockGCPClientManager_EnsureDNSManagedZone_Call struct { } // EnsureDNSManagedZone is a helper method to define mock.On call -// - projectID -// - zoneName -// - dnsName -// - description +// - projectID string +// - zoneName string +// - dnsName string +// - description string func (_e *MockGCPClientManager_Expecter) EnsureDNSManagedZone(projectID interface{}, zoneName interface{}, dnsName interface{}, description interface{}) *MockGCPClientManager_EnsureDNSManagedZone_Call { return &MockGCPClientManager_EnsureDNSManagedZone_Call{Call: _e.mock.On("EnsureDNSManagedZone", projectID, zoneName, dnsName, description)} } func (_c *MockGCPClientManager_EnsureDNSManagedZone_Call) Run(run func(projectID string, zoneName string, dnsName string, description string)) *MockGCPClientManager_EnsureDNSManagedZone_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string), args[3].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 string + if args[3] != nil { + arg3 = args[3].(string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) }) return _c } @@ -821,16 +1050,32 @@ type MockGCPClientManager_EnsureDNSRecordSets_Call struct { } // EnsureDNSRecordSets is a helper method to define mock.On call -// - projectID -// - zoneName -// - records +// - projectID string +// - zoneName string +// - records []*dns.ResourceRecordSet func (_e *MockGCPClientManager_Expecter) EnsureDNSRecordSets(projectID interface{}, zoneName interface{}, records interface{}) *MockGCPClientManager_EnsureDNSRecordSets_Call { return &MockGCPClientManager_EnsureDNSRecordSets_Call{Call: _e.mock.On("EnsureDNSRecordSets", projectID, zoneName, records)} } func (_c *MockGCPClientManager_EnsureDNSRecordSets_Call) Run(run func(projectID string, zoneName string, records []*dns.ResourceRecordSet)) *MockGCPClientManager_EnsureDNSRecordSets_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].([]*dns.ResourceRecordSet)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 []*dns.ResourceRecordSet + if args[2] != nil { + arg2 = args[2].([]*dns.ResourceRecordSet) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -879,16 +1124,32 @@ type MockGCPClientManager_GetAddress_Call struct { } // GetAddress is a helper method to define mock.On call -// - projectID -// - region -// - addressName +// - projectID string +// - region string +// - addressName string func (_e *MockGCPClientManager_Expecter) GetAddress(projectID interface{}, region interface{}, addressName interface{}) *MockGCPClientManager_GetAddress_Call { return &MockGCPClientManager_GetAddress_Call{Call: _e.mock.On("GetAddress", projectID, region, addressName)} } func (_c *MockGCPClientManager_GetAddress_Call) Run(run func(projectID string, region string, addressName string)) *MockGCPClientManager_GetAddress_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -937,16 +1198,32 @@ type MockGCPClientManager_GetArtifactRegistry_Call struct { } // GetArtifactRegistry is a helper method to define mock.On call -// - projectID -// - region -// - repoName +// - projectID string +// - region string +// - repoName string func (_e *MockGCPClientManager_Expecter) GetArtifactRegistry(projectID interface{}, region interface{}, repoName interface{}) *MockGCPClientManager_GetArtifactRegistry_Call { return &MockGCPClientManager_GetArtifactRegistry_Call{Call: _e.mock.On("GetArtifactRegistry", projectID, region, repoName)} } func (_c *MockGCPClientManager_GetArtifactRegistry_Call) Run(run func(projectID string, region string, repoName string)) *MockGCPClientManager_GetArtifactRegistry_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -995,14 +1272,20 @@ type MockGCPClientManager_GetBillingInfo_Call struct { } // GetBillingInfo is a helper method to define mock.On call -// - projectID +// - projectID string func (_e *MockGCPClientManager_Expecter) GetBillingInfo(projectID interface{}) *MockGCPClientManager_GetBillingInfo_Call { return &MockGCPClientManager_GetBillingInfo_Call{Call: _e.mock.On("GetBillingInfo", projectID)} } func (_c *MockGCPClientManager_GetBillingInfo_Call) Run(run func(projectID string)) *MockGCPClientManager_GetBillingInfo_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -1051,16 +1334,32 @@ type MockGCPClientManager_GetInstance_Call struct { } // GetInstance is a helper method to define mock.On call -// - projectID -// - zone -// - instanceName +// - projectID string +// - zone string +// - instanceName string func (_e *MockGCPClientManager_Expecter) GetInstance(projectID interface{}, zone interface{}, instanceName interface{}) *MockGCPClientManager_GetInstance_Call { return &MockGCPClientManager_GetInstance_Call{Call: _e.mock.On("GetInstance", projectID, zone, instanceName)} } func (_c *MockGCPClientManager_GetInstance_Call) Run(run func(projectID string, zone string, instanceName string)) *MockGCPClientManager_GetInstance_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -1109,15 +1408,26 @@ type MockGCPClientManager_GetProjectByName_Call struct { } // GetProjectByName is a helper method to define mock.On call -// - folderID -// - displayName +// - folderID string +// - displayName string func (_e *MockGCPClientManager_Expecter) GetProjectByName(folderID interface{}, displayName interface{}) *MockGCPClientManager_GetProjectByName_Call { return &MockGCPClientManager_GetProjectByName_Call{Call: _e.mock.On("GetProjectByName", folderID, displayName)} } func (_c *MockGCPClientManager_GetProjectByName_Call) Run(run func(folderID string, displayName string)) *MockGCPClientManager_GetProjectByName_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) }) return _c } @@ -1164,14 +1474,20 @@ type MockGCPClientManager_IsOMSManagedProject_Call struct { } // IsOMSManagedProject is a helper method to define mock.On call -// - projectID +// - projectID string func (_e *MockGCPClientManager_Expecter) IsOMSManagedProject(projectID interface{}) *MockGCPClientManager_IsOMSManagedProject_Call { return &MockGCPClientManager_IsOMSManagedProject_Call{Call: _e.mock.On("IsOMSManagedProject", projectID)} } func (_c *MockGCPClientManager_IsOMSManagedProject_Call) Run(run func(projectID string)) *MockGCPClientManager_IsOMSManagedProject_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -1209,17 +1525,38 @@ type MockGCPClientManager_RemoveIAMRoleBinding_Call struct { } // RemoveIAMRoleBinding is a helper method to define mock.On call -// - projectID -// - saName -// - saProjectID -// - roles +// - projectID string +// - saName string +// - saProjectID string +// - roles []string func (_e *MockGCPClientManager_Expecter) RemoveIAMRoleBinding(projectID interface{}, saName interface{}, saProjectID interface{}, roles interface{}) *MockGCPClientManager_RemoveIAMRoleBinding_Call { return &MockGCPClientManager_RemoveIAMRoleBinding_Call{Call: _e.mock.On("RemoveIAMRoleBinding", projectID, saName, saProjectID, roles)} } func (_c *MockGCPClientManager_RemoveIAMRoleBinding_Call) Run(run func(projectID string, saName string, saProjectID string, roles []string)) *MockGCPClientManager_RemoveIAMRoleBinding_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string), args[3].([]string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 []string + if args[3] != nil { + arg3 = args[3].([]string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) }) return _c } @@ -1257,16 +1594,32 @@ type MockGCPClientManager_StartInstance_Call struct { } // StartInstance is a helper method to define mock.On call -// - projectID -// - zone -// - instanceName +// - projectID string +// - zone string +// - instanceName string func (_e *MockGCPClientManager_Expecter) StartInstance(projectID interface{}, zone interface{}, instanceName interface{}) *MockGCPClientManager_StartInstance_Call { return &MockGCPClientManager_StartInstance_Call{Call: _e.mock.On("StartInstance", projectID, zone, instanceName)} } func (_c *MockGCPClientManager_StartInstance_Call) Run(run func(projectID string, zone string, instanceName string)) *MockGCPClientManager_StartInstance_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } diff --git a/internal/codesphere/mocks.go b/internal/codesphere/mocks.go index ccd510ea..f236d994 100644 --- a/internal/codesphere/mocks.go +++ b/internal/codesphere/mocks.go @@ -68,17 +68,38 @@ type MockClient_CreateWorkspace_Call struct { } // CreateWorkspace is a helper method to define mock.On call -// - teamID -// - planID -// - name -// - repoURL +// - teamID int +// - planID int +// - name string +// - repoURL *string func (_e *MockClient_Expecter) CreateWorkspace(teamID interface{}, planID interface{}, name interface{}, repoURL interface{}) *MockClient_CreateWorkspace_Call { return &MockClient_CreateWorkspace_Call{Call: _e.mock.On("CreateWorkspace", teamID, planID, name, repoURL)} } func (_c *MockClient_CreateWorkspace_Call) Run(run func(teamID int, planID int, name string, repoURL *string)) *MockClient_CreateWorkspace_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int), args[1].(int), args[2].(string), args[3].(*string)) + var arg0 int + if args[0] != nil { + arg0 = args[0].(int) + } + var arg1 int + if args[1] != nil { + arg1 = args[1].(int) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 *string + if args[3] != nil { + arg3 = args[3].(*string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) }) return _c } @@ -116,14 +137,20 @@ type MockClient_DeleteWorkspace_Call struct { } // DeleteWorkspace is a helper method to define mock.On call -// - workspaceID +// - workspaceID int func (_e *MockClient_Expecter) DeleteWorkspace(workspaceID interface{}) *MockClient_DeleteWorkspace_Call { return &MockClient_DeleteWorkspace_Call{Call: _e.mock.On("DeleteWorkspace", workspaceID)} } func (_c *MockClient_DeleteWorkspace_Call) Run(run func(workspaceID int)) *MockClient_DeleteWorkspace_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) + var arg0 int + if args[0] != nil { + arg0 = args[0].(int) + } + run( + arg0, + ) }) return _c } @@ -161,15 +188,26 @@ type MockClient_ExecuteCommand_Call struct { } // ExecuteCommand is a helper method to define mock.On call -// - workspaceID -// - command +// - workspaceID int +// - command string func (_e *MockClient_Expecter) ExecuteCommand(workspaceID interface{}, command interface{}) *MockClient_ExecuteCommand_Call { return &MockClient_ExecuteCommand_Call{Call: _e.mock.On("ExecuteCommand", workspaceID, command)} } func (_c *MockClient_ExecuteCommand_Call) Run(run func(workspaceID int, command string)) *MockClient_ExecuteCommand_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int), args[1].(string)) + var arg0 int + if args[0] != nil { + arg0 = args[0].(int) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) }) return _c } @@ -317,16 +355,32 @@ type MockClient_SetEnvVar_Call struct { } // SetEnvVar is a helper method to define mock.On call -// - workspaceID -// - key -// - value +// - workspaceID int +// - key string +// - value string func (_e *MockClient_Expecter) SetEnvVar(workspaceID interface{}, key interface{}, value interface{}) *MockClient_SetEnvVar_Call { return &MockClient_SetEnvVar_Call{Call: _e.mock.On("SetEnvVar", workspaceID, key, value)} } func (_c *MockClient_SetEnvVar_Call) Run(run func(workspaceID int, key string, value string)) *MockClient_SetEnvVar_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int), args[1].(string), args[2].(string)) + var arg0 int + if args[0] != nil { + arg0 = args[0].(int) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -364,16 +418,32 @@ type MockClient_StartPipeline_Call struct { } // StartPipeline is a helper method to define mock.On call -// - workspaceID -// - profile -// - stage +// - workspaceID int +// - profile string +// - stage string func (_e *MockClient_Expecter) StartPipeline(workspaceID interface{}, profile interface{}, stage interface{}) *MockClient_StartPipeline_Call { return &MockClient_StartPipeline_Call{Call: _e.mock.On("StartPipeline", workspaceID, profile, stage)} } func (_c *MockClient_StartPipeline_Call) Run(run func(workspaceID int, profile string, stage string)) *MockClient_StartPipeline_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int), args[1].(string), args[2].(string)) + var arg0 int + if args[0] != nil { + arg0 = args[0].(int) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -411,15 +481,26 @@ type MockClient_SyncLandscape_Call struct { } // SyncLandscape is a helper method to define mock.On call -// - workspaceID -// - profile +// - workspaceID int +// - profile string func (_e *MockClient_Expecter) SyncLandscape(workspaceID interface{}, profile interface{}) *MockClient_SyncLandscape_Call { return &MockClient_SyncLandscape_Call{Call: _e.mock.On("SyncLandscape", workspaceID, profile)} } func (_c *MockClient_SyncLandscape_Call) Run(run func(workspaceID int, profile string)) *MockClient_SyncLandscape_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int), args[1].(string)) + var arg0 int + if args[0] != nil { + arg0 = args[0].(int) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) }) return _c } diff --git a/internal/installer/mocks.go b/internal/installer/mocks.go index a7390604..797f266e 100644 --- a/internal/installer/mocks.go +++ b/internal/installer/mocks.go @@ -61,14 +61,20 @@ type MockArgoCDResources_ApplyAll_Call struct { } // ApplyAll is a helper method to define mock.On call -// - ctx +// - ctx context.Context func (_e *MockArgoCDResources_Expecter) ApplyAll(ctx interface{}) *MockArgoCDResources_ApplyAll_Call { return &MockArgoCDResources_ApplyAll_Call{Call: _e.mock.On("ApplyAll", ctx)} } func (_c *MockArgoCDResources_ApplyAll_Call) Run(run func(ctx context.Context)) *MockArgoCDResources_ApplyAll_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) }) return _c } @@ -142,14 +148,20 @@ type MockConfigManager_ParseConfigYaml_Call struct { } // ParseConfigYaml is a helper method to define mock.On call -// - configPath +// - configPath string func (_e *MockConfigManager_Expecter) ParseConfigYaml(configPath interface{}) *MockConfigManager_ParseConfigYaml_Call { return &MockConfigManager_ParseConfigYaml_Call{Call: _e.mock.On("ParseConfigYaml", configPath)} } func (_c *MockConfigManager_ParseConfigYaml_Call) Run(run func(configPath string)) *MockConfigManager_ParseConfigYaml_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -214,14 +226,20 @@ type MockInstallConfigManager_ApplyProfile_Call struct { } // ApplyProfile is a helper method to define mock.On call -// - profile +// - profile string func (_e *MockInstallConfigManager_Expecter) ApplyProfile(profile interface{}) *MockInstallConfigManager_ApplyProfile_Call { return &MockInstallConfigManager_ApplyProfile_Call{Call: _e.mock.On("ApplyProfile", profile)} } func (_c *MockInstallConfigManager_ApplyProfile_Call) Run(run func(profile string)) *MockInstallConfigManager_ApplyProfile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -439,14 +457,20 @@ type MockInstallConfigManager_LoadInstallConfigFromFile_Call struct { } // LoadInstallConfigFromFile is a helper method to define mock.On call -// - configPath +// - configPath string func (_e *MockInstallConfigManager_Expecter) LoadInstallConfigFromFile(configPath interface{}) *MockInstallConfigManager_LoadInstallConfigFromFile_Call { return &MockInstallConfigManager_LoadInstallConfigFromFile_Call{Call: _e.mock.On("LoadInstallConfigFromFile", configPath)} } func (_c *MockInstallConfigManager_LoadInstallConfigFromFile_Call) Run(run func(configPath string)) *MockInstallConfigManager_LoadInstallConfigFromFile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -484,14 +508,20 @@ type MockInstallConfigManager_LoadVaultFromFile_Call struct { } // LoadVaultFromFile is a helper method to define mock.On call -// - vaultPath +// - vaultPath string func (_e *MockInstallConfigManager_Expecter) LoadVaultFromFile(vaultPath interface{}) *MockInstallConfigManager_LoadVaultFromFile_Call { return &MockInstallConfigManager_LoadVaultFromFile_Call{Call: _e.mock.On("LoadVaultFromFile", vaultPath)} } func (_c *MockInstallConfigManager_LoadVaultFromFile_Call) Run(run func(vaultPath string)) *MockInstallConfigManager_LoadVaultFromFile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -665,15 +695,26 @@ type MockInstallConfigManager_WriteInstallConfig_Call struct { } // WriteInstallConfig is a helper method to define mock.On call -// - configPath -// - withComments +// - configPath string +// - withComments bool func (_e *MockInstallConfigManager_Expecter) WriteInstallConfig(configPath interface{}, withComments interface{}) *MockInstallConfigManager_WriteInstallConfig_Call { return &MockInstallConfigManager_WriteInstallConfig_Call{Call: _e.mock.On("WriteInstallConfig", configPath, withComments)} } func (_c *MockInstallConfigManager_WriteInstallConfig_Call) Run(run func(configPath string, withComments bool)) *MockInstallConfigManager_WriteInstallConfig_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 bool + if args[1] != nil { + arg1 = args[1].(bool) + } + run( + arg0, + arg1, + ) }) return _c } @@ -711,15 +752,26 @@ type MockInstallConfigManager_WriteVault_Call struct { } // WriteVault is a helper method to define mock.On call -// - vaultPath -// - withComments +// - vaultPath string +// - withComments bool func (_e *MockInstallConfigManager_Expecter) WriteVault(vaultPath interface{}, withComments interface{}) *MockInstallConfigManager_WriteVault_Call { return &MockInstallConfigManager_WriteVault_Call{Call: _e.mock.On("WriteVault", vaultPath, withComments)} } func (_c *MockInstallConfigManager_WriteVault_Call) Run(run func(vaultPath string, withComments bool)) *MockInstallConfigManager_WriteVault_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 bool + if args[1] != nil { + arg1 = args[1].(bool) + } + run( + arg0, + arg1, + ) }) return _c } @@ -795,14 +847,20 @@ type MockHelmClient_FindRelease_Call struct { } // FindRelease is a helper method to define mock.On call -// - releaseName +// - releaseName string func (_e *MockHelmClient_Expecter) FindRelease(releaseName interface{}) *MockHelmClient_FindRelease_Call { return &MockHelmClient_FindRelease_Call{Call: _e.mock.On("FindRelease", releaseName)} } func (_c *MockHelmClient_FindRelease_Call) Run(run func(releaseName string)) *MockHelmClient_FindRelease_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -840,15 +898,26 @@ type MockHelmClient_InstallChart_Call struct { } // InstallChart is a helper method to define mock.On call -// - ctx -// - cfg +// - ctx context.Context +// - cfg ChartConfig func (_e *MockHelmClient_Expecter) InstallChart(ctx interface{}, cfg interface{}) *MockHelmClient_InstallChart_Call { return &MockHelmClient_InstallChart_Call{Call: _e.mock.On("InstallChart", ctx, cfg)} } func (_c *MockHelmClient_InstallChart_Call) Run(run func(ctx context.Context, cfg ChartConfig)) *MockHelmClient_InstallChart_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(ChartConfig)) + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 ChartConfig + if args[1] != nil { + arg1 = args[1].(ChartConfig) + } + run( + arg0, + arg1, + ) }) return _c } @@ -886,15 +955,26 @@ type MockHelmClient_UpgradeChart_Call struct { } // UpgradeChart is a helper method to define mock.On call -// - ctx -// - cfg +// - ctx context.Context +// - cfg ChartConfig func (_e *MockHelmClient_Expecter) UpgradeChart(ctx interface{}, cfg interface{}) *MockHelmClient_UpgradeChart_Call { return &MockHelmClient_UpgradeChart_Call{Call: _e.mock.On("UpgradeChart", ctx, cfg)} } func (_c *MockHelmClient_UpgradeChart_Call) Run(run func(ctx context.Context, cfg ChartConfig)) *MockHelmClient_UpgradeChart_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(ChartConfig)) + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 ChartConfig + if args[1] != nil { + arg1 = args[1].(ChartConfig) + } + run( + arg0, + arg1, + ) }) return _c } @@ -968,16 +1048,32 @@ type MockK0sManager_Download_Call struct { } // Download is a helper method to define mock.On call -// - version -// - force -// - quiet +// - version string +// - force bool +// - quiet bool func (_e *MockK0sManager_Expecter) Download(version interface{}, force interface{}, quiet interface{}) *MockK0sManager_Download_Call { return &MockK0sManager_Download_Call{Call: _e.mock.On("Download", version, force, quiet)} } func (_c *MockK0sManager_Download_Call) Run(run func(version string, force bool, quiet bool)) *MockK0sManager_Download_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool), args[2].(bool)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 bool + if args[1] != nil { + arg1 = args[1].(bool) + } + var arg2 bool + if args[2] != nil { + arg2 = args[2].(bool) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -1068,16 +1164,32 @@ type MockK0sManager_Install_Call struct { } // Install is a helper method to define mock.On call -// - configPath -// - k0sPath -// - force +// - configPath string +// - k0sPath string +// - force bool func (_e *MockK0sManager_Expecter) Install(configPath interface{}, k0sPath interface{}, force interface{}) *MockK0sManager_Install_Call { return &MockK0sManager_Install_Call{Call: _e.mock.On("Install", configPath, k0sPath, force)} } func (_c *MockK0sManager_Install_Call) Run(run func(configPath string, k0sPath string, force bool)) *MockK0sManager_Install_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(bool)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 bool + if args[2] != nil { + arg2 = args[2].(bool) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -1142,14 +1254,20 @@ type MockPackageManager_Extract_Call struct { } // Extract is a helper method to define mock.On call -// - force +// - force bool func (_e *MockPackageManager_Expecter) Extract(force interface{}) *MockPackageManager_Extract_Call { return &MockPackageManager_Extract_Call{Call: _e.mock.On("Extract", force)} } func (_c *MockPackageManager_Extract_Call) Run(run func(force bool)) *MockPackageManager_Extract_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(bool)) + var arg0 bool + if args[0] != nil { + arg0 = args[0].(bool) + } + run( + arg0, + ) }) return _c } @@ -1187,15 +1305,26 @@ type MockPackageManager_ExtractDependency_Call struct { } // ExtractDependency is a helper method to define mock.On call -// - file -// - force +// - file string +// - force bool func (_e *MockPackageManager_Expecter) ExtractDependency(file interface{}, force interface{}) *MockPackageManager_ExtractDependency_Call { return &MockPackageManager_ExtractDependency_Call{Call: _e.mock.On("ExtractDependency", file, force)} } func (_c *MockPackageManager_ExtractDependency_Call) Run(run func(file string, force bool)) *MockPackageManager_ExtractDependency_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 bool + if args[1] != nil { + arg1 = args[1].(bool) + } + run( + arg0, + arg1, + ) }) return _c } @@ -1242,14 +1371,20 @@ type MockPackageManager_ExtractOciImageIndex_Call struct { } // ExtractOciImageIndex is a helper method to define mock.On call -// - imagefile +// - imagefile string func (_e *MockPackageManager_Expecter) ExtractOciImageIndex(imagefile interface{}) *MockPackageManager_ExtractOciImageIndex_Call { return &MockPackageManager_ExtractOciImageIndex_Call{Call: _e.mock.On("ExtractOciImageIndex", imagefile)} } func (_c *MockPackageManager_ExtractOciImageIndex_Call) Run(run func(imagefile string)) *MockPackageManager_ExtractOciImageIndex_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -1342,14 +1477,20 @@ type MockPackageManager_GetBaseimageName_Call struct { } // GetBaseimageName is a helper method to define mock.On call -// - baseimage +// - baseimage string func (_e *MockPackageManager_Expecter) GetBaseimageName(baseimage interface{}) *MockPackageManager_GetBaseimageName_Call { return &MockPackageManager_GetBaseimageName_Call{Call: _e.mock.On("GetBaseimageName", baseimage)} } func (_c *MockPackageManager_GetBaseimageName_Call) Run(run func(baseimage string)) *MockPackageManager_GetBaseimageName_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -1396,15 +1537,26 @@ type MockPackageManager_GetBaseimagePath_Call struct { } // GetBaseimagePath is a helper method to define mock.On call -// - baseimage -// - force +// - baseimage string +// - force bool func (_e *MockPackageManager_Expecter) GetBaseimagePath(baseimage interface{}, force interface{}) *MockPackageManager_GetBaseimagePath_Call { return &MockPackageManager_GetBaseimagePath_Call{Call: _e.mock.On("GetBaseimagePath", baseimage, force)} } func (_c *MockPackageManager_GetBaseimagePath_Call) Run(run func(baseimage string, force bool)) *MockPackageManager_GetBaseimagePath_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 bool + if args[1] != nil { + arg1 = args[1].(bool) + } + run( + arg0, + arg1, + ) }) return _c } @@ -1495,14 +1647,20 @@ type MockPackageManager_GetDependencyPath_Call struct { } // GetDependencyPath is a helper method to define mock.On call -// - filename +// - filename string func (_e *MockPackageManager_Expecter) GetDependencyPath(filename interface{}) *MockPackageManager_GetDependencyPath_Call { return &MockPackageManager_GetDependencyPath_Call{Call: _e.mock.On("GetDependencyPath", filename)} } func (_c *MockPackageManager_GetDependencyPath_Call) Run(run func(filename string)) *MockPackageManager_GetDependencyPath_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } diff --git a/internal/installer/node/mocks.go b/internal/installer/node/mocks.go index 27228da4..f88c2503 100644 --- a/internal/installer/node/mocks.go +++ b/internal/installer/node/mocks.go @@ -59,16 +59,32 @@ type MockNodeClient_CopyFile_Call struct { } // CopyFile is a helper method to define mock.On call -// - n -// - src -// - dst +// - n *Node +// - src string +// - dst string func (_e *MockNodeClient_Expecter) CopyFile(n interface{}, src interface{}, dst interface{}) *MockNodeClient_CopyFile_Call { return &MockNodeClient_CopyFile_Call{Call: _e.mock.On("CopyFile", n, src, dst)} } func (_c *MockNodeClient_CopyFile_Call) Run(run func(n *Node, src string, dst string)) *MockNodeClient_CopyFile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*Node), args[1].(string), args[2].(string)) + var arg0 *Node + if args[0] != nil { + arg0 = args[0].(*Node) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -106,15 +122,26 @@ type MockNodeClient_HasFile_Call struct { } // HasFile is a helper method to define mock.On call -// - n -// - filePath +// - n *Node +// - filePath string func (_e *MockNodeClient_Expecter) HasFile(n interface{}, filePath interface{}) *MockNodeClient_HasFile_Call { return &MockNodeClient_HasFile_Call{Call: _e.mock.On("HasFile", n, filePath)} } func (_c *MockNodeClient_HasFile_Call) Run(run func(n *Node, filePath string)) *MockNodeClient_HasFile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*Node), args[1].(string)) + var arg0 *Node + if args[0] != nil { + arg0 = args[0].(*Node) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) }) return _c } @@ -152,16 +179,32 @@ type MockNodeClient_RunCommand_Call struct { } // RunCommand is a helper method to define mock.On call -// - n -// - username -// - command +// - n *Node +// - username string +// - command string func (_e *MockNodeClient_Expecter) RunCommand(n interface{}, username interface{}, command interface{}) *MockNodeClient_RunCommand_Call { return &MockNodeClient_RunCommand_Call{Call: _e.mock.On("RunCommand", n, username, command)} } func (_c *MockNodeClient_RunCommand_Call) Run(run func(n *Node, username string, command string)) *MockNodeClient_RunCommand_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*Node), args[1].(string), args[2].(string)) + var arg0 *Node + if args[0] != nil { + arg0 = args[0].(*Node) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -199,15 +242,26 @@ type MockNodeClient_WaitReady_Call struct { } // WaitReady is a helper method to define mock.On call -// - n -// - timeout +// - n *Node +// - timeout time.Duration func (_e *MockNodeClient_Expecter) WaitReady(n interface{}, timeout interface{}) *MockNodeClient_WaitReady_Call { return &MockNodeClient_WaitReady_Call{Call: _e.mock.On("WaitReady", n, timeout)} } func (_c *MockNodeClient_WaitReady_Call) Run(run func(n *Node, timeout time.Duration)) *MockNodeClient_WaitReady_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*Node), args[1].(time.Duration)) + var arg0 *Node + if args[0] != nil { + arg0 = args[0].(*Node) + } + var arg1 time.Duration + if args[1] != nil { + arg1 = args[1].(time.Duration) + } + run( + arg0, + arg1, + ) }) return _c } diff --git a/internal/portal/mocks.go b/internal/portal/mocks.go index 83372369..c162a3ee 100644 --- a/internal/portal/mocks.go +++ b/internal/portal/mocks.go @@ -61,16 +61,32 @@ type MockHttp_Download_Call struct { } // Download is a helper method to define mock.On call -// - url -// - file -// - quiet +// - url string +// - file io.Writer +// - quiet bool func (_e *MockHttp_Expecter) Download(url interface{}, file interface{}, quiet interface{}) *MockHttp_Download_Call { return &MockHttp_Download_Call{Call: _e.mock.On("Download", url, file, quiet)} } func (_c *MockHttp_Download_Call) Run(run func(url string, file io.Writer, quiet bool)) *MockHttp_Download_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(io.Writer), args[2].(bool)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 io.Writer + if args[1] != nil { + arg1 = args[1].(io.Writer) + } + var arg2 bool + if args[2] != nil { + arg2 = args[2].(bool) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -119,14 +135,20 @@ type MockHttp_Get_Call struct { } // Get is a helper method to define mock.On call -// - url +// - url string func (_e *MockHttp_Expecter) Get(url interface{}) *MockHttp_Get_Call { return &MockHttp_Get_Call{Call: _e.mock.On("Get", url)} } func (_c *MockHttp_Get_Call) Run(run func(url string)) *MockHttp_Get_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -175,16 +197,32 @@ type MockHttp_Request_Call struct { } // Request is a helper method to define mock.On call -// - url -// - method -// - body +// - url string +// - method string +// - body io.Reader func (_e *MockHttp_Expecter) Request(url interface{}, method interface{}, body interface{}) *MockHttp_Request_Call { return &MockHttp_Request_Call{Call: _e.mock.On("Request", url, method, body)} } func (_c *MockHttp_Request_Call) Run(run func(url string, method string, body io.Reader)) *MockHttp_Request_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(io.Reader)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 io.Reader + if args[2] != nil { + arg2 = args[2].(io.Reader) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -249,18 +287,44 @@ type MockPortal_DownloadBuildArtifact_Call struct { } // DownloadBuildArtifact is a helper method to define mock.On call -// - product -// - build -// - file -// - startByte -// - quiet +// - product Product +// - build Build +// - file io.Writer +// - startByte int +// - quiet bool func (_e *MockPortal_Expecter) DownloadBuildArtifact(product interface{}, build interface{}, file interface{}, startByte interface{}, quiet interface{}) *MockPortal_DownloadBuildArtifact_Call { return &MockPortal_DownloadBuildArtifact_Call{Call: _e.mock.On("DownloadBuildArtifact", product, build, file, startByte, quiet)} } func (_c *MockPortal_DownloadBuildArtifact_Call) Run(run func(product Product, build Build, file io.Writer, startByte int, quiet bool)) *MockPortal_DownloadBuildArtifact_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(Product), args[1].(Build), args[2].(io.Writer), args[3].(int), args[4].(bool)) + var arg0 Product + if args[0] != nil { + arg0 = args[0].(Product) + } + var arg1 Build + if args[1] != nil { + arg1 = args[1].(Build) + } + var arg2 io.Writer + if args[2] != nil { + arg2 = args[2].(io.Writer) + } + var arg3 int + if args[3] != nil { + arg3 = args[3].(int) + } + var arg4 bool + if args[4] != nil { + arg4 = args[4].(bool) + } + run( + arg0, + arg1, + arg2, + arg3, + arg4, + ) }) return _c } @@ -307,14 +371,20 @@ type MockPortal_GetApiKeyId_Call struct { } // GetApiKeyId is a helper method to define mock.On call -// - oldKey +// - oldKey string func (_e *MockPortal_Expecter) GetApiKeyId(oldKey interface{}) *MockPortal_GetApiKeyId_Call { return &MockPortal_GetApiKeyId_Call{Call: _e.mock.On("GetApiKeyId", oldKey)} } func (_c *MockPortal_GetApiKeyId_Call) Run(run func(oldKey string)) *MockPortal_GetApiKeyId_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -361,16 +431,32 @@ type MockPortal_GetBuild_Call struct { } // GetBuild is a helper method to define mock.On call -// - product -// - version -// - hash +// - product Product +// - version string +// - hash string func (_e *MockPortal_Expecter) GetBuild(product interface{}, version interface{}, hash interface{}) *MockPortal_GetBuild_Call { return &MockPortal_GetBuild_Call{Call: _e.mock.On("GetBuild", product, version, hash)} } func (_c *MockPortal_GetBuild_Call) Run(run func(product Product, version string, hash string)) *MockPortal_GetBuild_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(Product), args[1].(string), args[2].(string)) + var arg0 Product + if args[0] != nil { + arg0 = args[0].(Product) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -472,14 +558,20 @@ type MockPortal_ListBuilds_Call struct { } // ListBuilds is a helper method to define mock.On call -// - product +// - product Product func (_e *MockPortal_Expecter) ListBuilds(product interface{}) *MockPortal_ListBuilds_Call { return &MockPortal_ListBuilds_Call{Call: _e.mock.On("ListBuilds", product)} } func (_c *MockPortal_ListBuilds_Call) Run(run func(product Product)) *MockPortal_ListBuilds_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(Product)) + var arg0 Product + if args[0] != nil { + arg0 = args[0].(Product) + } + run( + arg0, + ) }) return _c } @@ -528,17 +620,38 @@ type MockPortal_RegisterAPIKey_Call struct { } // RegisterAPIKey is a helper method to define mock.On call -// - owner -// - organization -// - role -// - expiresAt +// - owner string +// - organization string +// - role string +// - expiresAt time.Time func (_e *MockPortal_Expecter) RegisterAPIKey(owner interface{}, organization interface{}, role interface{}, expiresAt interface{}) *MockPortal_RegisterAPIKey_Call { return &MockPortal_RegisterAPIKey_Call{Call: _e.mock.On("RegisterAPIKey", owner, organization, role, expiresAt)} } func (_c *MockPortal_RegisterAPIKey_Call) Run(run func(owner string, organization string, role string, expiresAt time.Time)) *MockPortal_RegisterAPIKey_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string), args[3].(time.Time)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 time.Time + if args[3] != nil { + arg3 = args[3].(time.Time) + } + run( + arg0, + arg1, + arg2, + arg3, + ) }) return _c } @@ -576,14 +689,20 @@ type MockPortal_RevokeAPIKey_Call struct { } // RevokeAPIKey is a helper method to define mock.On call -// - key +// - key string func (_e *MockPortal_Expecter) RevokeAPIKey(key interface{}) *MockPortal_RevokeAPIKey_Call { return &MockPortal_RevokeAPIKey_Call{Call: _e.mock.On("RevokeAPIKey", key)} } func (_c *MockPortal_RevokeAPIKey_Call) Run(run func(key string)) *MockPortal_RevokeAPIKey_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -621,15 +740,26 @@ type MockPortal_UpdateAPIKey_Call struct { } // UpdateAPIKey is a helper method to define mock.On call -// - key -// - expiresAt +// - key string +// - expiresAt time.Time func (_e *MockPortal_Expecter) UpdateAPIKey(key interface{}, expiresAt interface{}) *MockPortal_UpdateAPIKey_Call { return &MockPortal_UpdateAPIKey_Call{Call: _e.mock.On("UpdateAPIKey", key, expiresAt)} } func (_c *MockPortal_UpdateAPIKey_Call) Run(run func(key string, expiresAt time.Time)) *MockPortal_UpdateAPIKey_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(time.Time)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 time.Time + if args[1] != nil { + arg1 = args[1].(time.Time) + } + run( + arg0, + arg1, + ) }) return _c } @@ -667,15 +797,26 @@ type MockPortal_VerifyBuildArtifactDownload_Call struct { } // VerifyBuildArtifactDownload is a helper method to define mock.On call -// - file -// - download +// - file io.Reader +// - download Build func (_e *MockPortal_Expecter) VerifyBuildArtifactDownload(file interface{}, download interface{}) *MockPortal_VerifyBuildArtifactDownload_Call { return &MockPortal_VerifyBuildArtifactDownload_Call{Call: _e.mock.On("VerifyBuildArtifactDownload", file, download)} } func (_c *MockPortal_VerifyBuildArtifactDownload_Call) Run(run func(file io.Reader, download Build)) *MockPortal_VerifyBuildArtifactDownload_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(io.Reader), args[1].(Build)) + var arg0 io.Reader + if args[0] != nil { + arg0 = args[0].(io.Reader) + } + var arg1 Build + if args[1] != nil { + arg1 = args[1].(Build) + } + run( + arg0, + arg1, + ) }) return _c } @@ -751,14 +892,20 @@ type MockHttpClient_Do_Call struct { } // Do is a helper method to define mock.On call -// - request +// - request *http.Request func (_e *MockHttpClient_Expecter) Do(request interface{}) *MockHttpClient_Do_Call { return &MockHttpClient_Do_Call{Call: _e.mock.On("Do", request)} } func (_c *MockHttpClient_Do_Call) Run(run func(request *http.Request)) *MockHttpClient_Do_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*http.Request)) + var arg0 *http.Request + if args[0] != nil { + arg0 = args[0].(*http.Request) + } + run( + arg0, + ) }) return _c } diff --git a/internal/system/mocks.go b/internal/system/mocks.go index cf8e9292..ee80bc69 100644 --- a/internal/system/mocks.go +++ b/internal/system/mocks.go @@ -58,16 +58,32 @@ type MockImageManager_BuildImage_Call struct { } // BuildImage is a helper method to define mock.On call -// - dockerfile -// - tag -// - buildContext +// - dockerfile string +// - tag string +// - buildContext string func (_e *MockImageManager_Expecter) BuildImage(dockerfile interface{}, tag interface{}, buildContext interface{}) *MockImageManager_BuildImage_Call { return &MockImageManager_BuildImage_Call{Call: _e.mock.On("BuildImage", dockerfile, tag, buildContext)} } func (_c *MockImageManager_BuildImage_Call) Run(run func(dockerfile string, tag string, buildContext string)) *MockImageManager_BuildImage_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -105,14 +121,20 @@ type MockImageManager_LoadImage_Call struct { } // LoadImage is a helper method to define mock.On call -// - imageTarPath +// - imageTarPath string func (_e *MockImageManager_Expecter) LoadImage(imageTarPath interface{}) *MockImageManager_LoadImage_Call { return &MockImageManager_LoadImage_Call{Call: _e.mock.On("LoadImage", imageTarPath)} } func (_c *MockImageManager_LoadImage_Call) Run(run func(imageTarPath string)) *MockImageManager_LoadImage_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -150,14 +172,20 @@ type MockImageManager_PushImage_Call struct { } // PushImage is a helper method to define mock.On call -// - tag +// - tag string func (_e *MockImageManager_Expecter) PushImage(tag interface{}) *MockImageManager_PushImage_Call { return &MockImageManager_PushImage_Call{Call: _e.mock.On("PushImage", tag)} } func (_c *MockImageManager_PushImage_Call) Run(run func(tag string)) *MockImageManager_PushImage_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } diff --git a/internal/util/mocks.go b/internal/util/mocks.go index a002ef16..2912e9d3 100644 --- a/internal/util/mocks.go +++ b/internal/util/mocks.go @@ -71,15 +71,26 @@ type MockDockerfileManager_UpdateFromStatement_Call struct { } // UpdateFromStatement is a helper method to define mock.On call -// - dockerfile -// - baseImage +// - dockerfile io.Reader +// - baseImage string func (_e *MockDockerfileManager_Expecter) UpdateFromStatement(dockerfile interface{}, baseImage interface{}) *MockDockerfileManager_UpdateFromStatement_Call { return &MockDockerfileManager_UpdateFromStatement_Call{Call: _e.mock.On("UpdateFromStatement", dockerfile, baseImage)} } func (_c *MockDockerfileManager_UpdateFromStatement_Call) Run(run func(dockerfile io.Reader, baseImage string)) *MockDockerfileManager_UpdateFromStatement_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(io.Reader), args[1].(string)) + var arg0 io.Reader + if args[0] != nil { + arg0 = args[0].(io.Reader) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) }) return _c } @@ -155,14 +166,20 @@ type MockFileIO_Create_Call struct { } // Create is a helper method to define mock.On call -// - filename +// - filename string func (_e *MockFileIO_Expecter) Create(filename interface{}) *MockFileIO_Create_Call { return &MockFileIO_Create_Call{Call: _e.mock.On("Create", filename)} } func (_c *MockFileIO_Create_Call) Run(run func(filename string)) *MockFileIO_Create_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -200,16 +217,32 @@ type MockFileIO_CreateAndWrite_Call struct { } // CreateAndWrite is a helper method to define mock.On call -// - filePath -// - data -// - fileType +// - filePath string +// - data []byte +// - fileType string func (_e *MockFileIO_Expecter) CreateAndWrite(filePath interface{}, data interface{}, fileType interface{}) *MockFileIO_CreateAndWrite_Call { return &MockFileIO_CreateAndWrite_Call{Call: _e.mock.On("CreateAndWrite", filePath, data, fileType)} } func (_c *MockFileIO_CreateAndWrite_Call) Run(run func(filePath string, data []byte, fileType string)) *MockFileIO_CreateAndWrite_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].([]byte), args[2].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 []byte + if args[1] != nil { + arg1 = args[1].([]byte) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -247,14 +280,20 @@ type MockFileIO_Exists_Call struct { } // Exists is a helper method to define mock.On call -// - filename +// - filename string func (_e *MockFileIO_Expecter) Exists(filename interface{}) *MockFileIO_Exists_Call { return &MockFileIO_Exists_Call{Call: _e.mock.On("Exists", filename)} } func (_c *MockFileIO_Exists_Call) Run(run func(filename string)) *MockFileIO_Exists_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -301,14 +340,20 @@ type MockFileIO_IsDirectory_Call struct { } // IsDirectory is a helper method to define mock.On call -// - filename +// - filename string func (_e *MockFileIO_Expecter) IsDirectory(filename interface{}) *MockFileIO_IsDirectory_Call { return &MockFileIO_IsDirectory_Call{Call: _e.mock.On("IsDirectory", filename)} } func (_c *MockFileIO_IsDirectory_Call) Run(run func(filename string)) *MockFileIO_IsDirectory_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -346,15 +391,26 @@ type MockFileIO_MkdirAll_Call struct { } // MkdirAll is a helper method to define mock.On call -// - path -// - perm +// - path string +// - perm os.FileMode func (_e *MockFileIO_Expecter) MkdirAll(path interface{}, perm interface{}) *MockFileIO_MkdirAll_Call { return &MockFileIO_MkdirAll_Call{Call: _e.mock.On("MkdirAll", path, perm)} } func (_c *MockFileIO_MkdirAll_Call) Run(run func(path string, perm os.FileMode)) *MockFileIO_MkdirAll_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(os.FileMode)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 os.FileMode + if args[1] != nil { + arg1 = args[1].(os.FileMode) + } + run( + arg0, + arg1, + ) }) return _c } @@ -403,14 +459,20 @@ type MockFileIO_Open_Call struct { } // Open is a helper method to define mock.On call -// - filename +// - filename string func (_e *MockFileIO_Expecter) Open(filename interface{}) *MockFileIO_Open_Call { return &MockFileIO_Open_Call{Call: _e.mock.On("Open", filename)} } func (_c *MockFileIO_Open_Call) Run(run func(filename string)) *MockFileIO_Open_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -459,14 +521,20 @@ type MockFileIO_OpenAppend_Call struct { } // OpenAppend is a helper method to define mock.On call -// - filename +// - filename string func (_e *MockFileIO_Expecter) OpenAppend(filename interface{}) *MockFileIO_OpenAppend_Call { return &MockFileIO_OpenAppend_Call{Call: _e.mock.On("OpenAppend", filename)} } func (_c *MockFileIO_OpenAppend_Call) Run(run func(filename string)) *MockFileIO_OpenAppend_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -515,16 +583,32 @@ type MockFileIO_OpenFile_Call struct { } // OpenFile is a helper method to define mock.On call -// - name -// - flag -// - perm +// - name string +// - flag int +// - perm os.FileMode func (_e *MockFileIO_Expecter) OpenFile(name interface{}, flag interface{}, perm interface{}) *MockFileIO_OpenFile_Call { return &MockFileIO_OpenFile_Call{Call: _e.mock.On("OpenFile", name, flag, perm)} } func (_c *MockFileIO_OpenFile_Call) Run(run func(name string, flag int, perm os.FileMode)) *MockFileIO_OpenFile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(int), args[2].(os.FileMode)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 int + if args[1] != nil { + arg1 = args[1].(int) + } + var arg2 os.FileMode + if args[2] != nil { + arg2 = args[2].(os.FileMode) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -573,14 +657,20 @@ type MockFileIO_ReadDir_Call struct { } // ReadDir is a helper method to define mock.On call -// - dirname +// - dirname string func (_e *MockFileIO_Expecter) ReadDir(dirname interface{}) *MockFileIO_ReadDir_Call { return &MockFileIO_ReadDir_Call{Call: _e.mock.On("ReadDir", dirname)} } func (_c *MockFileIO_ReadDir_Call) Run(run func(dirname string)) *MockFileIO_ReadDir_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -629,14 +719,20 @@ type MockFileIO_ReadFile_Call struct { } // ReadFile is a helper method to define mock.On call -// - filename +// - filename string func (_e *MockFileIO_Expecter) ReadFile(filename interface{}) *MockFileIO_ReadFile_Call { return &MockFileIO_ReadFile_Call{Call: _e.mock.On("ReadFile", filename)} } func (_c *MockFileIO_ReadFile_Call) Run(run func(filename string)) *MockFileIO_ReadFile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -674,14 +770,20 @@ type MockFileIO_Remove_Call struct { } // Remove is a helper method to define mock.On call -// - path +// - path string func (_e *MockFileIO_Expecter) Remove(path interface{}) *MockFileIO_Remove_Call { return &MockFileIO_Remove_Call{Call: _e.mock.On("Remove", path)} } func (_c *MockFileIO_Remove_Call) Run(run func(path string)) *MockFileIO_Remove_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) }) return _c } @@ -719,16 +821,32 @@ type MockFileIO_WriteFile_Call struct { } // WriteFile is a helper method to define mock.On call -// - filename -// - data -// - perm +// - filename string +// - data []byte +// - perm os.FileMode func (_e *MockFileIO_Expecter) WriteFile(filename interface{}, data interface{}, perm interface{}) *MockFileIO_WriteFile_Call { return &MockFileIO_WriteFile_Call{Call: _e.mock.On("WriteFile", filename, data, perm)} } func (_c *MockFileIO_WriteFile_Call) Run(run func(filename string, data []byte, perm os.FileMode)) *MockFileIO_WriteFile_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].([]byte), args[2].(os.FileMode)) + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 []byte + if args[1] != nil { + arg1 = args[1].([]byte) + } + var arg2 os.FileMode + if args[2] != nil { + arg2 = args[2].(os.FileMode) + } + run( + arg0, + arg1, + arg2, + ) }) return _c } @@ -858,8 +976,8 @@ type MockTableWriter_AppendHeader_Call struct { } // AppendHeader is a helper method to define mock.On call -// - row -// - configs +// - row table.Row +// - configs ...table.RowConfig func (_e *MockTableWriter_Expecter) AppendHeader(row interface{}, configs ...interface{}) *MockTableWriter_AppendHeader_Call { return &MockTableWriter_AppendHeader_Call{Call: _e.mock.On("AppendHeader", append([]interface{}{row}, configs...)...)} @@ -867,13 +985,20 @@ func (_e *MockTableWriter_Expecter) AppendHeader(row interface{}, configs ...int func (_c *MockTableWriter_AppendHeader_Call) Run(run func(row table.Row, configs ...table.RowConfig)) *MockTableWriter_AppendHeader_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]table.RowConfig, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(table.RowConfig) - } + var arg0 table.Row + if args[0] != nil { + arg0 = args[0].(table.Row) } - run(args[0].(table.Row), variadicArgs...) + var arg1 []table.RowConfig + var variadicArgs []table.RowConfig + if len(args) > 1 { + variadicArgs = args[1].([]table.RowConfig) + } + arg1 = variadicArgs + run( + arg0, + arg1..., + ) }) return _c } @@ -905,8 +1030,8 @@ type MockTableWriter_AppendRow_Call struct { } // AppendRow is a helper method to define mock.On call -// - row -// - configs +// - row table.Row +// - configs ...table.RowConfig func (_e *MockTableWriter_Expecter) AppendRow(row interface{}, configs ...interface{}) *MockTableWriter_AppendRow_Call { return &MockTableWriter_AppendRow_Call{Call: _e.mock.On("AppendRow", append([]interface{}{row}, configs...)...)} @@ -914,13 +1039,20 @@ func (_e *MockTableWriter_Expecter) AppendRow(row interface{}, configs ...interf func (_c *MockTableWriter_AppendRow_Call) Run(run func(row table.Row, configs ...table.RowConfig)) *MockTableWriter_AppendRow_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]table.RowConfig, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(table.RowConfig) - } + var arg0 table.Row + if args[0] != nil { + arg0 = args[0].(table.Row) + } + var arg1 []table.RowConfig + var variadicArgs []table.RowConfig + if len(args) > 1 { + variadicArgs = args[1].([]table.RowConfig) } - run(args[0].(table.Row), variadicArgs...) + arg1 = variadicArgs + run( + arg0, + arg1..., + ) }) return _c } @@ -1062,14 +1194,20 @@ type MockTime_Sleep_Call struct { } // Sleep is a helper method to define mock.On call -// - duration +// - duration time.Duration func (_e *MockTime_Expecter) Sleep(duration interface{}) *MockTime_Sleep_Call { return &MockTime_Sleep_Call{Call: _e.mock.On("Sleep", duration)} } func (_c *MockTime_Sleep_Call) Run(run func(duration time.Duration)) *MockTime_Sleep_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(time.Duration)) + var arg0 time.Duration + if args[0] != nil { + arg0 = args[0].(time.Duration) + } + run( + arg0, + ) }) return _c } From 482fdbd25517f194d8f73a5e3fc9e844df158da5 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Fri, 13 Mar 2026 13:00:21 +0100 Subject: [PATCH 12/30] fix: update install profile from 'dev' to 'minimal' in GCP Bootstrapper tests --- internal/bootstrap/gcp/gcp_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index 0c50d84d..a10b60a7 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -136,11 +136,11 @@ var _ = Describe("GCP Bootstrapper", func() { // 1. EnsureInstallConfig fw.EXPECT().Exists("fake-config-file").Return(false) - icg.EXPECT().ApplyProfile("dev").Return(nil) + icg.EXPECT().ApplyProfile("minimal").Return(nil) // Returning a real install config to avoid nil pointer dereferences later icg.EXPECT().GetInstallConfig().RunAndReturn(func() *files.RootConfig { realIcm := installer.NewInstallConfigManager() - _ = realIcm.ApplyProfile("dev") + _ = realIcm.ApplyProfile("minimal") return realIcm.GetInstallConfig() }) @@ -440,7 +440,7 @@ var _ = Describe("GCP Bootstrapper", func() { It("creates install config when missing", func() { fw.EXPECT().Exists(csEnv.InstallConfigPath).Return(false) - icg.EXPECT().ApplyProfile("dev").Return(nil) + icg.EXPECT().ApplyProfile("minimal").Return(nil) icg.EXPECT().GetInstallConfig().Return(&files.RootConfig{}) err := bs.EnsureInstallConfig() @@ -462,7 +462,7 @@ var _ = Describe("GCP Bootstrapper", func() { It("returns error when config file missing and applying profile fails", func() { fw.EXPECT().Exists(csEnv.InstallConfigPath).Return(false) - icg.EXPECT().ApplyProfile("dev").Return(fmt.Errorf("profile error")) + icg.EXPECT().ApplyProfile("minimal").Return(fmt.Errorf("profile error")) err := bs.EnsureInstallConfig() Expect(err).To(HaveOccurred()) From 6d1d398b9255bdf224491d2f2147f57e9b0972dd Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Mon, 16 Mar 2026 12:00:58 +0100 Subject: [PATCH 13/30] test: add test for spot vm --- internal/bootstrap/gcp/gcp.go | 18 +- internal/bootstrap/gcp/spot_vm_test.go | 372 +++++++++++++++++++++++++ 2 files changed, 381 insertions(+), 9 deletions(-) create mode 100644 internal/bootstrap/gcp/spot_vm_test.go diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index f76ec779..169942a6 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -864,7 +864,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { Tags: &computepb.Tags{ Items: vm.Tags, }, - Scheduling: b.buildSchedulingConfig(), + Scheduling: b.BuildSchedulingConfig(), NetworkInterfaces: []*computepb.NetworkInterface{ { Network: protoString(network), @@ -892,7 +892,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { } } - err = b.createInstanceWithFallback(projectID, zone, instance, vm.Name, logCh) + err = b.CreateInstanceWithFallback(projectID, zone, instance, vm.Name, logCh) if err != nil { errCh <- err return @@ -975,8 +975,8 @@ func extractInstanceIPs(inst *computepb.Instance) (internalIP, externalIP string return } -// buildSchedulingConfig creates the scheduling configuration based on spot/preemptible settings -func (b *GCPBootstrapper) buildSchedulingConfig() *computepb.Scheduling { +// BuildSchedulingConfig creates the scheduling configuration based on spot/preemptible settings +func (b *GCPBootstrapper) BuildSchedulingConfig() *computepb.Scheduling { if b.Env.Spot { return &computepb.Scheduling{ ProvisioningModel: protoString("SPOT"), @@ -994,9 +994,9 @@ func (b *GCPBootstrapper) buildSchedulingConfig() *computepb.Scheduling { return &computepb.Scheduling{} } -// createInstanceWithFallback attempts to create an instance with the configured settings. +// CreateInstanceWithFallback attempts to create an instance with the configured settings. // If spot VMs are enabled and creation fails due to capacity issues, it falls back to standard VMs. -func (b *GCPBootstrapper) createInstanceWithFallback(projectID, zone string, instance *computepb.Instance, vmName string, logCh chan<- string) error { +func (b *GCPBootstrapper) CreateInstanceWithFallback(projectID, zone string, instance *computepb.Instance, vmName string, logCh chan<- string) error { err := b.GCPClient.CreateInstance(projectID, zone, instance) if err == nil { return nil @@ -1006,7 +1006,7 @@ func (b *GCPBootstrapper) createInstanceWithFallback(projectID, zone string, ins return nil } - if b.Env.Spot && isSpotCapacityError(err) { + if b.Env.Spot && IsSpotCapacityError(err) { logCh <- fmt.Sprintf("Spot capacity unavailable for %s, falling back to standard VM", vmName) instance.Scheduling = &computepb.Scheduling{} err = b.GCPClient.CreateInstance(projectID, zone, instance) @@ -1049,8 +1049,8 @@ func (b *GCPBootstrapper) waitForInstanceRunning(projectID, zone, name string, n name, time.Duration(maxAttempts)*pollInterval) } -// isSpotCapacityError checks if the error is related to spot VM capacity issues -func isSpotCapacityError(err error) bool { +// IsSpotCapacityError checks if the error is related to spot VM capacity issues +func IsSpotCapacityError(err error) bool { if err == nil { return false } diff --git a/internal/bootstrap/gcp/spot_vm_test.go b/internal/bootstrap/gcp/spot_vm_test.go new file mode 100644 index 00000000..dcd808e7 --- /dev/null +++ b/internal/bootstrap/gcp/spot_vm_test.go @@ -0,0 +1,372 @@ +// Copyright (c) Codesphere Inc. +// SPDX-License-Identifier: Apache-2.0 + +package gcp_test + +import ( + "context" + "fmt" + + "cloud.google.com/go/compute/apiv1/computepb" + "github.com/codesphere-cloud/oms/internal/bootstrap" + "github.com/codesphere-cloud/oms/internal/bootstrap/gcp" + "github.com/codesphere-cloud/oms/internal/env" + "github.com/codesphere-cloud/oms/internal/installer" + "github.com/codesphere-cloud/oms/internal/installer/node" + "github.com/codesphere-cloud/oms/internal/portal" + "github.com/codesphere-cloud/oms/internal/util" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +var _ = Describe("Spot VM", func() { + + Describe("isSpotCapacityError", func() { + It("returns false for nil error", func() { + Expect(gcp.IsSpotCapacityError(nil)).To(BeFalse()) + }) + + It("detects gRPC ResourceExhausted status", func() { + err := status.Errorf(codes.ResourceExhausted, "resource exhausted") + Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) + }) + + It("does not match non-ResourceExhausted gRPC codes", func() { + Expect(gcp.IsSpotCapacityError(status.Errorf(codes.NotFound, "not found"))).To(BeFalse()) + Expect(gcp.IsSpotCapacityError(status.Errorf(codes.PermissionDenied, "denied"))).To(BeFalse()) + Expect(gcp.IsSpotCapacityError(status.Errorf(codes.Internal, "internal"))).To(BeFalse()) + }) + }) + + Describe("buildSchedulingConfig", func() { + var ( + bs *gcp.GCPBootstrapper + csEnv *gcp.CodesphereEnvironment + ) + + BeforeEach(func() { + csEnv = &gcp.CodesphereEnvironment{ + ProjectName: "test", + Region: "us-central1", + Zone: "us-central1-a", + BaseDomain: "example.com", + DNSProjectID: "dns-project", + DNSZoneName: "test-zone", + SecretsDir: "/etc/codesphere/secrets", + DatacenterID: 1, + Experiments: gcp.DefaultExperiments, + } + + var err error + bs, err = gcp.NewGCPBootstrapper( + context.Background(), + env.NewEnv(), + bootstrap.NewStepLogger(false), + csEnv, + installer.NewMockInstallConfigManager(GinkgoT()), + gcp.NewMockGCPClientManager(GinkgoT()), + util.NewMockFileIO(GinkgoT()), + node.NewMockNodeClient(GinkgoT()), + portal.NewMockPortal(GinkgoT()), + util.NewFakeTime(), + ) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("when spot is enabled", func() { + BeforeEach(func() { + csEnv.Spot = true + csEnv.Preemptible = false + }) + + It("sets SPOT provisioning model", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.ProvisioningModel).NotTo(BeNil()) + Expect(*sched.ProvisioningModel).To(Equal("SPOT")) + }) + + It("sets OnHostMaintenance to TERMINATE", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.OnHostMaintenance).NotTo(BeNil()) + Expect(*sched.OnHostMaintenance).To(Equal("TERMINATE")) + }) + + It("sets AutomaticRestart to false", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.AutomaticRestart).NotTo(BeNil()) + Expect(*sched.AutomaticRestart).To(BeFalse()) + }) + + It("sets InstanceTerminationAction to STOP", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.InstanceTerminationAction).NotTo(BeNil()) + Expect(*sched.InstanceTerminationAction).To(Equal("STOP")) + }) + }) + + Context("when preemptible is enabled", func() { + BeforeEach(func() { + csEnv.Spot = false + csEnv.Preemptible = true + }) + + It("sets Preemptible to true", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.Preemptible).NotTo(BeNil()) + Expect(*sched.Preemptible).To(BeTrue()) + }) + + It("does not set SPOT provisioning model", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.ProvisioningModel).To(BeNil()) + }) + }) + + Context("when neither spot nor preemptible is enabled", func() { + BeforeEach(func() { + csEnv.Spot = false + csEnv.Preemptible = false + }) + + It("returns empty scheduling config", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.ProvisioningModel).To(BeNil()) + Expect(sched.Preemptible).To(BeNil()) + Expect(sched.OnHostMaintenance).To(BeNil()) + Expect(sched.AutomaticRestart).To(BeNil()) + Expect(sched.InstanceTerminationAction).To(BeNil()) + }) + }) + }) + + Describe("validateVMProvisioningOptions", func() { + var csEnv *gcp.CodesphereEnvironment + + BeforeEach(func() { + csEnv = &gcp.CodesphereEnvironment{ + ProjectName: "test", + Region: "us-central1", + Zone: "us-central1-a", + BaseDomain: "example.com", + DNSProjectID: "dns-project", + DNSZoneName: "test-zone", + SecretsDir: "/etc/codesphere/secrets", + DatacenterID: 1, + Experiments: gcp.DefaultExperiments, + InstallConfigPath: "fake-config", + SecretsFilePath: "fake-secrets", + GitHubAppName: "fake-app", + GithubAppClientID: "fake-id", + GithubAppClientSecret: "fake-secret", + } + }) + + newBootstrapper := func() *gcp.GCPBootstrapper { + bs, err := gcp.NewGCPBootstrapper( + context.Background(), + env.NewEnv(), + bootstrap.NewStepLogger(false), + csEnv, + installer.NewMockInstallConfigManager(GinkgoT()), + gcp.NewMockGCPClientManager(GinkgoT()), + util.NewMockFileIO(GinkgoT()), + node.NewMockNodeClient(GinkgoT()), + portal.NewMockPortal(GinkgoT()), + util.NewFakeTime(), + ) + Expect(err).NotTo(HaveOccurred()) + return bs + } + + It("succeeds when only spot is set", func() { + csEnv.Spot = true + csEnv.Preemptible = false + bs := newBootstrapper() + err := bs.ValidateInput() + Expect(err).NotTo(HaveOccurred()) + }) + + It("succeeds when only preemptible is set", func() { + csEnv.Spot = false + csEnv.Preemptible = true + bs := newBootstrapper() + err := bs.ValidateInput() + Expect(err).NotTo(HaveOccurred()) + }) + + It("succeeds when neither is set", func() { + csEnv.Spot = false + csEnv.Preemptible = false + bs := newBootstrapper() + err := bs.ValidateInput() + Expect(err).NotTo(HaveOccurred()) + }) + + It("fails when both spot and preemptible are set", func() { + csEnv.Spot = true + csEnv.Preemptible = true + bs := newBootstrapper() + err := bs.ValidateInput() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("cannot specify both --spot and --preemptible")) + }) + }) + + Describe("createInstanceWithFallback", func() { + var ( + bs *gcp.GCPBootstrapper + csEnv *gcp.CodesphereEnvironment + gc *gcp.MockGCPClientManager + logCh chan string + ) + + BeforeEach(func() { + gc = gcp.NewMockGCPClientManager(GinkgoT()) + csEnv = &gcp.CodesphereEnvironment{ + ProjectName: "test", + ProjectID: "test-pid", + Region: "us-central1", + Zone: "us-central1-a", + BaseDomain: "example.com", + DNSProjectID: "dns-project", + DNSZoneName: "test-zone", + SecretsDir: "/etc/codesphere/secrets", + DatacenterID: 1, + Experiments: gcp.DefaultExperiments, + } + logCh = make(chan string, 10) + + var err error + bs, err = gcp.NewGCPBootstrapper( + context.Background(), + env.NewEnv(), + bootstrap.NewStepLogger(false), + csEnv, + installer.NewMockInstallConfigManager(GinkgoT()), + gc, + util.NewMockFileIO(GinkgoT()), + node.NewMockNodeClient(GinkgoT()), + portal.NewMockPortal(GinkgoT()), + util.NewFakeTime(), + ) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("when creation succeeds on first attempt", func() { + It("returns nil", func() { + instance := &computepb.Instance{Name: protoString("test-vm")} + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance).Return(nil) + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).NotTo(HaveOccurred()) + }) + }) + + Context("when the instance already exists", func() { + It("returns nil (treats as success)", func() { + instance := &computepb.Instance{Name: protoString("test-vm")} + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). + Return(status.Errorf(codes.AlreadyExists, "already exists")) + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).NotTo(HaveOccurred()) + }) + }) + + Context("when spot is enabled", func() { + BeforeEach(func() { + csEnv.Spot = true + }) + + DescribeTable("falls back to standard VM on capacity errors", + func(capacityErr error) { + instance := &computepb.Instance{ + Name: protoString("test-vm"), + Scheduling: &computepb.Scheduling{ + ProvisioningModel: protoString("SPOT"), + }, + } + + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(capacityErr).Once() + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(nil).Once() + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).NotTo(HaveOccurred()) + + Expect(logCh).To(Receive(ContainSubstring("falling back to standard VM"))) + }, + Entry("gRPC ResourceExhausted", status.Errorf(codes.ResourceExhausted, "exhausted")), + ) + + It("clears scheduling config on fallback", func() { + instance := &computepb.Instance{ + Name: protoString("test-vm"), + Scheduling: &computepb.Scheduling{ + ProvisioningModel: protoString("SPOT"), + }, + } + + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")).Once() + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.MatchedBy(func(inst *computepb.Instance) bool { + return inst.Scheduling != nil && + inst.Scheduling.ProvisioningModel == nil && + inst.Scheduling.Preemptible == nil + })).Return(nil).Once() + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).NotTo(HaveOccurred()) + }) + + It("returns error when fallback also fails", func() { + instance := &computepb.Instance{ + Name: protoString("test-vm"), + Scheduling: &computepb.Scheduling{ + ProvisioningModel: protoString("SPOT"), + }, + } + + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")).Once() + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(fmt.Errorf("quota exceeded")).Once() + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("fallback to standard VM")) + }) + }) + + Context("when spot is disabled", func() { + BeforeEach(func() { + csEnv.Spot = false + }) + + It("does not fall back on capacity errors", func() { + instance := &computepb.Instance{Name: protoString("test-vm")} + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). + Return(fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")) + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("failed to create instance test-vm")) + }) + + It("propagates non-capacity errors", func() { + instance := &computepb.Instance{Name: protoString("test-vm")} + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). + Return(fmt.Errorf("permission denied")) + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("failed to create instance test-vm")) + Expect(err.Error()).To(ContainSubstring("permission denied")) + }) + }) + }) +}) From 8461787fecf9100962f4ae01d2f3b27a117dd9aa Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Mon, 16 Mar 2026 12:54:53 +0100 Subject: [PATCH 14/30] test: update spot vm tests --- internal/bootstrap/gcp/spot_vm_test.go | 219 +++++++++++++++++++++++++ 1 file changed, 219 insertions(+) diff --git a/internal/bootstrap/gcp/spot_vm_test.go b/internal/bootstrap/gcp/spot_vm_test.go index dcd808e7..ed007a18 100644 --- a/internal/bootstrap/gcp/spot_vm_test.go +++ b/internal/bootstrap/gcp/spot_vm_test.go @@ -39,6 +39,43 @@ var _ = Describe("Spot VM", func() { Expect(gcp.IsSpotCapacityError(status.Errorf(codes.PermissionDenied, "denied"))).To(BeFalse()) Expect(gcp.IsSpotCapacityError(status.Errorf(codes.Internal, "internal"))).To(BeFalse()) }) + + It("detects ZONE_RESOURCE_POOL_EXHAUSTED error string", func() { + err := fmt.Errorf("googleapi: Error 403: ZONE_RESOURCE_POOL_EXHAUSTED - the zone does not have enough resources") + Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) + }) + + It("detects UNSUPPORTED_OPERATION error string", func() { + err := fmt.Errorf("UNSUPPORTED_OPERATION: spot VMs not available in this zone") + Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) + }) + + It("detects stockout error string", func() { + err := fmt.Errorf("stockout in zone us-central1-a") + Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) + }) + + It("detects does not have enough resources error string", func() { + err := fmt.Errorf("the zone 'us-central1-a' does not have enough resources available to fulfill the request") + Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) + }) + + It("does not match unrelated error strings", func() { + Expect(gcp.IsSpotCapacityError(fmt.Errorf("permission denied"))).To(BeFalse()) + Expect(gcp.IsSpotCapacityError(fmt.Errorf("invalid argument"))).To(BeFalse()) + Expect(gcp.IsSpotCapacityError(fmt.Errorf("quota exceeded"))).To(BeFalse()) + Expect(gcp.IsSpotCapacityError(fmt.Errorf("network error"))).To(BeFalse()) + }) + + It("detects gRPC ResourceExhausted with additional message text", func() { + err := status.Errorf(codes.ResourceExhausted, "spot VM pool exhausted in us-central1-a") + Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) + }) + + It("does not match gRPC Unavailable status", func() { + err := status.Errorf(codes.Unavailable, "service unavailable") + Expect(gcp.IsSpotCapacityError(err)).To(BeFalse()) + }) }) Describe("buildSchedulingConfig", func() { @@ -105,6 +142,20 @@ var _ = Describe("Spot VM", func() { Expect(sched.InstanceTerminationAction).NotTo(BeNil()) Expect(*sched.InstanceTerminationAction).To(Equal("STOP")) }) + + It("returns a complete scheduling config with all four fields set", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched).NotTo(BeNil()) + Expect(*sched.ProvisioningModel).To(Equal("SPOT")) + Expect(*sched.OnHostMaintenance).To(Equal("TERMINATE")) + Expect(*sched.AutomaticRestart).To(BeFalse()) + Expect(*sched.InstanceTerminationAction).To(Equal("STOP")) + }) + + It("does not set Preemptible field", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.Preemptible).To(BeNil()) + }) }) Context("when preemptible is enabled", func() { @@ -123,6 +174,21 @@ var _ = Describe("Spot VM", func() { sched := bs.BuildSchedulingConfig() Expect(sched.ProvisioningModel).To(BeNil()) }) + + It("does not set OnHostMaintenance", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.OnHostMaintenance).To(BeNil()) + }) + + It("does not set AutomaticRestart", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.AutomaticRestart).To(BeNil()) + }) + + It("does not set InstanceTerminationAction", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.InstanceTerminationAction).To(BeNil()) + }) }) Context("when neither spot nor preemptible is enabled", func() { @@ -213,6 +279,45 @@ var _ = Describe("Spot VM", func() { Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("cannot specify both --spot and --preemptible")) }) + + It("error message suggests using --spot over --preemptible", func() { + csEnv.Spot = true + csEnv.Preemptible = true + bs := newBootstrapper() + err := bs.ValidateInput() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("use --spot for the newer spot VM model")) + }) + + It("spot does not interfere with other validation (install version)", func() { + csEnv.Spot = true + csEnv.InstallVersion = "v1.0.0" + csEnv.InstallHash = "abc123" + csEnv.RegistryType = gcp.RegistryTypeGitHub + + mockPortal := portal.NewMockPortal(GinkgoT()) + mockPortal.EXPECT().GetBuild(portal.CodesphereProduct, "v1.0.0", "abc123").Return(portal.Build{ + Artifacts: []portal.Artifact{{Filename: "installer-lite.tar.gz"}}, + Hash: "abc123", + Version: "v1.0.0", + }, nil) + + bs, err := gcp.NewGCPBootstrapper( + context.Background(), + env.NewEnv(), + bootstrap.NewStepLogger(false), + csEnv, + installer.NewMockInstallConfigManager(GinkgoT()), + gcp.NewMockGCPClientManager(GinkgoT()), + util.NewMockFileIO(GinkgoT()), + node.NewMockNodeClient(GinkgoT()), + mockPortal, + util.NewFakeTime(), + ) + Expect(err).NotTo(HaveOccurred()) + err = bs.ValidateInput() + Expect(err).NotTo(HaveOccurred()) + }) }) Describe("createInstanceWithFallback", func() { @@ -301,6 +406,10 @@ var _ = Describe("Spot VM", func() { Expect(logCh).To(Receive(ContainSubstring("falling back to standard VM"))) }, Entry("gRPC ResourceExhausted", status.Errorf(codes.ResourceExhausted, "exhausted")), + Entry("ZONE_RESOURCE_POOL_EXHAUSTED string", fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")), + Entry("UNSUPPORTED_OPERATION string", fmt.Errorf("UNSUPPORTED_OPERATION")), + Entry("stockout string", fmt.Errorf("stockout in zone")), + Entry("does not have enough resources string", fmt.Errorf("zone does not have enough resources")), ) It("clears scheduling config on fallback", func() { @@ -340,6 +449,83 @@ var _ = Describe("Spot VM", func() { Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fallback to standard VM")) }) + + It("does NOT fall back when error is not capacity-related", func() { + instance := &computepb.Instance{ + Name: protoString("test-vm"), + Scheduling: &computepb.Scheduling{ + ProvisioningModel: protoString("SPOT"), + }, + } + + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(fmt.Errorf("permission denied")).Once() + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("failed to create instance test-vm")) + Expect(err.Error()).To(ContainSubstring("permission denied")) + Expect(logCh).To(BeEmpty()) + }) + + It("succeeds when fallback retry returns AlreadyExists", func() { + instance := &computepb.Instance{ + Name: protoString("test-vm"), + Scheduling: &computepb.Scheduling{ + ProvisioningModel: protoString("SPOT"), + }, + } + + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(status.Errorf(codes.ResourceExhausted, "exhausted")).Once() + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(status.Errorf(codes.AlreadyExists, "already exists")).Once() + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).NotTo(HaveOccurred()) + + Expect(logCh).To(Receive(ContainSubstring("falling back to standard VM"))) + }) + + It("logs the correct VM name in the fallback message", func() { + instance := &computepb.Instance{ + Name: protoString("ceph-3"), + Scheduling: &computepb.Scheduling{ + ProvisioningModel: protoString("SPOT"), + }, + } + + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")).Once() + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(nil).Once() + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "ceph-3", logCh) + Expect(err).NotTo(HaveOccurred()) + + var msg string + Expect(logCh).To(Receive(&msg)) + Expect(msg).To(ContainSubstring("ceph-3")) + }) + + It("wraps the original error when fallback fails", func() { + instance := &computepb.Instance{ + Name: protoString("test-vm"), + Scheduling: &computepb.Scheduling{ + ProvisioningModel: protoString("SPOT"), + }, + } + + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(fmt.Errorf("stockout in zone")).Once() + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). + Return(fmt.Errorf("insufficient quota")).Once() + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("fallback to standard VM")) + Expect(err.Error()).To(ContainSubstring("insufficient quota")) + }) }) Context("when spot is disabled", func() { @@ -367,6 +553,39 @@ var _ = Describe("Spot VM", func() { Expect(err.Error()).To(ContainSubstring("failed to create instance test-vm")) Expect(err.Error()).To(ContainSubstring("permission denied")) }) + + It("returns nil for string-based already exists error", func() { + instance := &computepb.Instance{Name: protoString("test-vm")} + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). + Return(fmt.Errorf("The resource 'test-vm' already exists")) + + err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) + Expect(err).NotTo(HaveOccurred()) + }) + }) + }) + + Describe("CodesphereEnvironment Spot/Preemptible fields", func() { + It("defaults Spot to false", func() { + csEnv := &gcp.CodesphereEnvironment{} + Expect(csEnv.Spot).To(BeFalse()) + }) + + It("defaults Preemptible to false", func() { + csEnv := &gcp.CodesphereEnvironment{} + Expect(csEnv.Preemptible).To(BeFalse()) + }) + + It("can set Spot independently", func() { + csEnv := &gcp.CodesphereEnvironment{Spot: true} + Expect(csEnv.Spot).To(BeTrue()) + Expect(csEnv.Preemptible).To(BeFalse()) + }) + + It("can set Preemptible independently", func() { + csEnv := &gcp.CodesphereEnvironment{Preemptible: true} + Expect(csEnv.Preemptible).To(BeTrue()) + Expect(csEnv.Spot).To(BeFalse()) }) }) }) From b0de0d8200ec26a6decaf6a995a0569495e7ff7b Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Mon, 16 Mar 2026 13:30:41 +0100 Subject: [PATCH 15/30] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- internal/bootstrap/gcp/gcp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 169942a6..9518d540 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -1042,7 +1042,7 @@ func (b *GCPBootstrapper) waitForInstanceRunning(projectID, zone, name string, n } if attempt < maxAttempts-1 { - time.Sleep(pollInterval) + b.Time.Sleep(pollInterval) } } return nil, fmt.Errorf("timed out waiting for instance %s to be RUNNING with IPs assigned after %s", From d47f56dca2562c4f84ac49f9260753169562add6 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Mon, 16 Mar 2026 13:31:16 +0100 Subject: [PATCH 16/30] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- internal/bootstrap/gcp/gcp.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 9518d540..3b7b48a4 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -1811,6 +1811,16 @@ func isAlreadyExistsError(err error) bool { } func isNotFoundError(err error) bool { + if err == nil { + return false + } + + // Delegate to the exported helper for Google API 404 handling + if IsNotFoundError(err) { + return true + } + + // Preserve existing gRPC and string-based "not found" detection return status.Code(err) == codes.NotFound || strings.Contains(strings.ToLower(err.Error()), "not found") } From 3101c024cc3c3092242a70a32c3776f1d1bb9fe8 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Mon, 16 Mar 2026 13:33:18 +0100 Subject: [PATCH 17/30] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- internal/bootstrap/gcp/gcp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 3b7b48a4..56e93881 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -794,7 +794,7 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { } if existingInstance != nil { instanceStatus := existingInstance.GetStatus() - if instanceStatus == "TERMINATED" || instanceStatus == "STOPPED" || instanceStatus == "SUSPENDED" { + if instanceStatus == "TERMINATED" || instanceStatus == "STOPPED" { // Start the stopped instance err = b.GCPClient.StartInstance(projectID, zone, vm.Name) if err != nil { From b102983470107d05c970d84f8440607493da47d0 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:19:07 +0100 Subject: [PATCH 18/30] ref: streamline VM management and enhance error handling in GCPBootstrapper --- internal/bootstrap/gcp/gcp.go | 311 ++++++++++---------- internal/bootstrap/gcp/gcp_test.go | 162 +--------- internal/bootstrap/gcp/test_helpers_test.go | 60 ++++ 3 files changed, 228 insertions(+), 305 deletions(-) create mode 100644 internal/bootstrap/gcp/test_helpers_test.go diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 56e93881..788cc4e3 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -67,7 +67,7 @@ func GetDNSRecordNames(baseDomain string) []struct { } } -// IsNotFoundError checks if the error is a Google API "not found" error (HTTP 404). +// IsNotFoundError checks if the error indicates a "not found" condition. func IsNotFoundError(err error) bool { if err == nil { return false @@ -77,7 +77,12 @@ func IsNotFoundError(err error) bool { if errors.As(err, &googleErr) { return googleErr.Code == 404 } - return false + + if status.Code(err) == codes.NotFound { + return true + } + + return strings.Contains(strings.ToLower(err.Error()), "not found") } type VMDef struct { @@ -763,155 +768,26 @@ type vmResult struct { } func (b *GCPBootstrapper) EnsureComputeInstances() error { - projectID := b.Env.ProjectID - region := b.Env.Region - zone := b.Env.Zone - - network := fmt.Sprintf("projects/%s/global/networks/%s-vpc", projectID, projectID) - subnetwork := fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s-%s-subnet", projectID, region, projectID, region) - diskType := fmt.Sprintf("projects/%s/zones/%s/diskTypes/pd-ssd", projectID, zone) + rootDiskSize := int64(200) + if b.Env.RegistryType == RegistryTypeGitHub { + rootDiskSize = 50 + } - // Create VMs in parallel wg := sync.WaitGroup{} errCh := make(chan error, len(vmDefs)) resultCh := make(chan vmResult, len(vmDefs)) logCh := make(chan string, len(vmDefs)) - rootDiskSize := int64(200) - if b.Env.RegistryType == RegistryTypeGitHub { - rootDiskSize = 50 - } + for _, vm := range vmDefs { wg.Add(1) go func(vm VMDef) { defer wg.Done() - - existingInstance, err := b.GCPClient.GetInstance(projectID, zone, vm.Name) - if err != nil { - if !isNotFoundError(err) { - errCh <- fmt.Errorf("failed to get instance %s: %w", vm.Name, err) - return - } - } - if existingInstance != nil { - instanceStatus := existingInstance.GetStatus() - if instanceStatus == "TERMINATED" || instanceStatus == "STOPPED" { - // Start the stopped instance - err = b.GCPClient.StartInstance(projectID, zone, vm.Name) - if err != nil { - errCh <- fmt.Errorf("failed to start stopped instance %s: %w", vm.Name, err) - return - } - } - - // Wait until the instance is RUNNING and IPs are populated. - readyInstance, err := b.waitForInstanceRunning(projectID, zone, vm.Name, vm.ExternalIP) - if err != nil { - errCh <- fmt.Errorf("instance %s did not become ready: %w", vm.Name, err) - return - } - - internalIP, externalIP := extractInstanceIPs(readyInstance) - resultCh <- vmResult{ - vmType: vm.Tags[0], - name: vm.Name, - externalIP: externalIP, - internalIP: internalIP, - } - return - } - - // Instance doesn't exist, create it - disks := []*computepb.AttachedDisk{ - { - Boot: protoBool(true), - AutoDelete: protoBool(true), - Type: protoString("PERSISTENT"), - InitializeParams: &computepb.AttachedDiskInitializeParams{ - DiskType: &diskType, - DiskSizeGb: protoInt64(rootDiskSize), - SourceImage: protoString("projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts"), - }, - }, - } - for _, diskSize := range vm.AdditionalDisks { - disks = append(disks, &computepb.AttachedDisk{ - Boot: protoBool(false), - AutoDelete: protoBool(true), - Type: protoString("PERSISTENT"), - InitializeParams: &computepb.AttachedDiskInitializeParams{ - DiskSizeGb: protoInt64(diskSize), - DiskType: &diskType, - }, - }) - } - - pubKey, err := b.readSSHKey(b.Env.SSHPublicKeyPath) - if err != nil { - errCh <- fmt.Errorf("failed to read SSH public key: %w", err) - return - } - - serviceAccount := fmt.Sprintf("cloud-controller@%s.iam.gserviceaccount.com", projectID) - instance := &computepb.Instance{ - Name: protoString(vm.Name), - ServiceAccounts: []*computepb.ServiceAccount{ - { - Email: protoString(serviceAccount), - Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, - }, - }, - MachineType: protoString(fmt.Sprintf("zones/%s/machineTypes/%s", zone, vm.MachineType)), - Tags: &computepb.Tags{ - Items: vm.Tags, - }, - Scheduling: b.BuildSchedulingConfig(), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - Network: protoString(network), - Subnetwork: protoString(subnetwork), - }, - }, - Disks: disks, - Metadata: &computepb.Metadata{ - Items: []*computepb.Items{ - { - Key: protoString("ssh-keys"), - Value: protoString(fmt.Sprintf("root:%s\nubuntu:%s", pubKey+"root", pubKey+"ubuntu")), - }, - }, - }, - } - - // Configure external IP if needed - if vm.ExternalIP { - instance.NetworkInterfaces[0].AccessConfigs = []*computepb.AccessConfig{ - { - Name: protoString("External NAT"), - Type: protoString("ONE_TO_ONE_NAT"), - }, - } - } - - err = b.CreateInstanceWithFallback(projectID, zone, instance, vm.Name, logCh) + result, err := b.ensureVM(vm, rootDiskSize, logCh) if err != nil { errCh <- err return } - - // Wait for the newly created instance to be RUNNING with IPs assigned - readyInstance, err := b.waitForInstanceRunning(projectID, zone, vm.Name, vm.ExternalIP) - if err != nil { - errCh <- fmt.Errorf("instance %s did not become ready: %w", vm.Name, err) - return - } - - internalIP, externalIP := extractInstanceIPs(readyInstance) - resultCh <- vmResult{ - vmType: vm.Tags[0], - name: vm.Name, - externalIP: externalIP, - internalIP: internalIP, - } + resultCh <- result }(vm) } wg.Wait() @@ -964,6 +840,129 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error { return nil } +// ensureVM handles the full lifecycle of a single VM: check existence, restart if stopped, +// or create a new instance with spot fallback. Returns the VM result with assigned IPs. +func (b *GCPBootstrapper) ensureVM(vm VMDef, rootDiskSize int64, logCh chan<- string) (vmResult, error) { + projectID := b.Env.ProjectID + zone := b.Env.Zone + + existingInstance, err := b.GCPClient.GetInstance(projectID, zone, vm.Name) + if err != nil && !IsNotFoundError(err) { + return vmResult{}, fmt.Errorf("failed to get instance %s: %w", vm.Name, err) + } + + if existingInstance != nil { + if s := existingInstance.GetStatus(); s == "TERMINATED" || s == "STOPPED" { + if err := b.GCPClient.StartInstance(projectID, zone, vm.Name); err != nil { + return vmResult{}, fmt.Errorf("failed to start stopped instance %s: %w", vm.Name, err) + } + } + } else { + instance, err := b.buildInstanceSpec(vm, rootDiskSize) + if err != nil { + return vmResult{}, err + } + if err := b.CreateInstanceWithFallback(projectID, zone, instance, vm.Name, logCh); err != nil { + return vmResult{}, err + } + } + + readyInstance, err := b.waitForInstanceRunning(projectID, zone, vm.Name, vm.ExternalIP) + if err != nil { + return vmResult{}, fmt.Errorf("instance %s did not become ready: %w", vm.Name, err) + } + + internalIP, externalIP := extractInstanceIPs(readyInstance) + return vmResult{ + vmType: vm.Tags[0], + name: vm.Name, + externalIP: externalIP, + internalIP: internalIP, + }, nil +} + +// buildInstanceSpec constructs the full compute instance specification for a VM. +func (b *GCPBootstrapper) buildInstanceSpec(vm VMDef, rootDiskSize int64) (*computepb.Instance, error) { + projectID := b.Env.ProjectID + region := b.Env.Region + zone := b.Env.Zone + + network := fmt.Sprintf("projects/%s/global/networks/%s-vpc", projectID, projectID) + subnetwork := fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s-%s-subnet", projectID, region, projectID, region) + diskType := fmt.Sprintf("projects/%s/zones/%s/diskTypes/pd-ssd", projectID, zone) + + disks := []*computepb.AttachedDisk{ + { + Boot: protoBool(true), + AutoDelete: protoBool(true), + Type: protoString("PERSISTENT"), + InitializeParams: &computepb.AttachedDiskInitializeParams{ + DiskType: &diskType, + DiskSizeGb: protoInt64(rootDiskSize), + SourceImage: protoString("projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts"), + }, + }, + } + for _, diskSize := range vm.AdditionalDisks { + disks = append(disks, &computepb.AttachedDisk{ + Boot: protoBool(false), + AutoDelete: protoBool(true), + Type: protoString("PERSISTENT"), + InitializeParams: &computepb.AttachedDiskInitializeParams{ + DiskSizeGb: protoInt64(diskSize), + DiskType: &diskType, + }, + }) + } + + pubKey, err := b.readSSHKey(b.Env.SSHPublicKeyPath) + if err != nil { + return nil, fmt.Errorf("failed to read SSH public key: %w", err) + } + + serviceAccount := fmt.Sprintf("cloud-controller@%s.iam.gserviceaccount.com", projectID) + instance := &computepb.Instance{ + Name: protoString(vm.Name), + ServiceAccounts: []*computepb.ServiceAccount{ + { + Email: protoString(serviceAccount), + Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, + }, + }, + MachineType: protoString(fmt.Sprintf("zones/%s/machineTypes/%s", zone, vm.MachineType)), + Tags: &computepb.Tags{ + Items: vm.Tags, + }, + Scheduling: b.BuildSchedulingConfig(), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + Network: protoString(network), + Subnetwork: protoString(subnetwork), + }, + }, + Disks: disks, + Metadata: &computepb.Metadata{ + Items: []*computepb.Items{ + { + Key: protoString("ssh-keys"), + Value: protoString(fmt.Sprintf("root:%s\nubuntu:%s", pubKey+"root", pubKey+"ubuntu")), + }, + }, + }, + } + + if vm.ExternalIP { + instance.NetworkInterfaces[0].AccessConfigs = []*computepb.AccessConfig{ + { + Name: protoString("External NAT"), + Type: protoString("ONE_TO_ONE_NAT"), + }, + } + } + + return instance, nil +} + // extractInstanceIPs returns the internal and external IPs from a compute instance. func extractInstanceIPs(inst *computepb.Instance) (internalIP, externalIP string) { if len(inst.GetNetworkInterfaces()) > 0 { @@ -975,6 +974,22 @@ func extractInstanceIPs(inst *computepb.Instance) (internalIP, externalIP string return } +// isInstanceReady checks if an instance is RUNNING with its internal IP assigned, +// and optionally its external IP as well. +func isInstanceReady(inst *computepb.Instance, needsExternalIP bool) bool { + if inst.GetStatus() != "RUNNING" || len(inst.GetNetworkInterfaces()) == 0 { + return false + } + ni := inst.GetNetworkInterfaces()[0] + if ni.GetNetworkIP() == "" { + return false + } + if needsExternalIP && (len(ni.GetAccessConfigs()) == 0 || ni.GetAccessConfigs()[0].GetNatIP() == "") { + return false + } + return true +} + // BuildSchedulingConfig creates the scheduling configuration based on spot/preemptible settings func (b *GCPBootstrapper) BuildSchedulingConfig() *computepb.Scheduling { if b.Env.Spot { @@ -1033,11 +1048,7 @@ func (b *GCPBootstrapper) waitForInstanceRunning(projectID, zone, name string, n return nil, fmt.Errorf("failed to poll instance %s: %w", name, err) } - if inst.GetStatus() == "RUNNING" && - len(inst.GetNetworkInterfaces()) > 0 && - inst.GetNetworkInterfaces()[0].GetNetworkIP() != "" && - (!needsExternalIP || (len(inst.GetNetworkInterfaces()[0].GetAccessConfigs()) > 0 && - inst.GetNetworkInterfaces()[0].GetAccessConfigs()[0].GetNatIP() != "")) { + if isInstanceReady(inst, needsExternalIP) { return inst, nil } @@ -1810,20 +1821,6 @@ func isAlreadyExistsError(err error) bool { return status.Code(err) == codes.AlreadyExists || strings.Contains(err.Error(), "already exists") } -func isNotFoundError(err error) bool { - if err == nil { - return false - } - - // Delegate to the exported helper for Google API 404 handling - if IsNotFoundError(err) { - return true - } - - // Preserve existing gRPC and string-based "not found" detection - return status.Code(err) == codes.NotFound || strings.Contains(strings.ToLower(err.Error()), "not found") -} - // readSSHKey reads an SSH key file, expanding ~ in the path func (b *GCPBootstrapper) readSSHKey(path string) (string, error) { realPath := util.ExpandPath(path) diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index a10b60a7..80cd3dd2 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -30,8 +30,6 @@ import ( "google.golang.org/api/dns/v1" ) -func protoString(s string) *string { return &s } - func jumpbboxMatcher(node *node.Node) bool { return node.GetName() == "jumpbox" } @@ -186,17 +184,7 @@ var _ = Describe("GCP Bootstrapper", func() { // Track GetInstance calls per VM name instanceCalls := make(map[string]int) var instanceMu sync.Mutex - ipResp := &computepb.Instance{ - Status: protoString("RUNNING"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.1"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.4")}, - }, - }, - }, - } + ipResp := makeRunningInstance("10.0.0.1", "1.2.3.4") gc.EXPECT().GetInstance(projectId, "us-central1-a", mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { instanceMu.Lock() defer instanceMu.Unlock() @@ -984,29 +972,8 @@ var _ = Describe("GCP Bootstrapper", func() { }) Describe("Valid EnsureComputeInstances", func() { It("creates all instances", func() { - instanceCalls := make(map[string]int) - var mu sync.Mutex - ipResp := &computepb.Instance{ - Status: protoString("RUNNING"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } - // First call per VM: not found (triggers creation). Second call: running with IPs. - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { - mu.Lock() - defer mu.Unlock() - instanceCalls[name]++ - if instanceCalls[name] == 1 { - return nil, fmt.Errorf("not found") - } - return ipResp, nil - }).Times(18) + ipResp := makeRunningInstance("10.0.0.x", "1.2.3.x") + mockGetInstanceNotFoundThenRunning(gc, csEnv.ProjectID, csEnv.Zone, ipResp, 9) fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Times(9) gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil).Times(9) @@ -1067,29 +1034,8 @@ var _ = Describe("GCP Bootstrapper", func() { It("creates spot VMs when spot flag is enabled", func() { csEnv.Spot = true - // Track GetInstance calls per VM name - instanceCalls := make(map[string]int) - var mu sync.Mutex - ipResp := &computepb.Instance{ - Status: protoString("RUNNING"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { - mu.Lock() - defer mu.Unlock() - instanceCalls[name]++ - if instanceCalls[name] == 1 { - return nil, fmt.Errorf("not found") - } - return ipResp, nil - }).Times(18) + ipResp := makeRunningInstance("10.0.0.x", "1.2.3.x") + mockGetInstanceNotFoundThenRunning(gc, csEnv.ProjectID, csEnv.Zone, ipResp, 9) fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Times(9) @@ -1107,33 +1053,13 @@ var _ = Describe("GCP Bootstrapper", func() { It("falls back to standard VM when spot capacity is exhausted", func() { csEnv.Spot = true - // Track GetInstance calls per VM name - instanceCalls := make(map[string]int) - var mu sync.Mutex - ipResp := &computepb.Instance{ - Status: protoString("RUNNING"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { - mu.Lock() - defer mu.Unlock() - instanceCalls[name]++ - if instanceCalls[name] == 1 { - return nil, fmt.Errorf("not found") - } - return ipResp, nil - }).Times(18) + ipResp := makeRunningInstance("10.0.0.x", "1.2.3.x") + mockGetInstanceNotFoundThenRunning(gc, csEnv.ProjectID, csEnv.Zone, ipResp, 9) fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Times(9) createCalls := make(map[string]int) + var mu sync.Mutex gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone string, instance *computepb.Instance) error { mu.Lock() defer mu.Unlock() @@ -1152,28 +1078,8 @@ var _ = Describe("GCP Bootstrapper", func() { It("restarts stopped VMs instead of creating new ones", func() { instanceCalls := make(map[string]int) var mu sync.Mutex - stoppedResp := &computepb.Instance{ - Status: protoString("TERMINATED"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } - runningResp := &computepb.Instance{ - Status: protoString("RUNNING"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } + stoppedResp := makeStoppedInstance("10.0.0.x", "1.2.3.x") + runningResp := makeRunningInstance("10.0.0.x", "1.2.3.x") gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { mu.Lock() defer mu.Unlock() @@ -1193,17 +1099,7 @@ var _ = Describe("GCP Bootstrapper", func() { }) It("uses existing running VMs without starting them", func() { - runningResp := &computepb.Instance{ - Status: protoString("RUNNING"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } + runningResp := makeRunningInstance("10.0.0.x", "1.2.3.x") // 9 VMs × 2 GetInstance calls each (initial check + waitForInstanceRunning poll) gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(runningResp, nil).Times(18) @@ -1214,28 +1110,8 @@ var _ = Describe("GCP Bootstrapper", func() { It("handles VMs in intermediate states (STAGING/PROVISIONING)", func() { instanceCalls := make(map[string]int) var mu sync.Mutex - stagingResp := &computepb.Instance{ - Status: protoString("STAGING"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } - runningResp := &computepb.Instance{ - Status: protoString("RUNNING"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } + stagingResp := makeInstance("STAGING", "10.0.0.x", "1.2.3.x") + runningResp := makeRunningInstance("10.0.0.x", "1.2.3.x") gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { mu.Lock() defer mu.Unlock() @@ -1253,17 +1129,7 @@ var _ = Describe("GCP Bootstrapper", func() { }) It("fails when StartInstance returns an error", func() { - stoppedResp := &computepb.Instance{ - Status: protoString("TERMINATED"), - NetworkInterfaces: []*computepb.NetworkInterface{ - { - NetworkIP: protoString("10.0.0.x"), - AccessConfigs: []*computepb.AccessConfig{ - {NatIP: protoString("1.2.3.x")}, - }, - }, - }, - } + stoppedResp := makeStoppedInstance("10.0.0.x", "1.2.3.x") gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(stoppedResp, nil).Maybe() gc.EXPECT().StartInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(fmt.Errorf("start error")).Maybe() diff --git a/internal/bootstrap/gcp/test_helpers_test.go b/internal/bootstrap/gcp/test_helpers_test.go new file mode 100644 index 00000000..b0b6462e --- /dev/null +++ b/internal/bootstrap/gcp/test_helpers_test.go @@ -0,0 +1,60 @@ +// Copyright (c) Codesphere Inc. +// SPDX-License-Identifier: Apache-2.0 + +package gcp_test + +import ( + "fmt" + "sync" + + "cloud.google.com/go/compute/apiv1/computepb" + "github.com/codesphere-cloud/oms/internal/bootstrap/gcp" + "github.com/stretchr/testify/mock" +) + +func protoString(s string) *string { return &s } + +// makeInstance creates a computepb.Instance with the given status and IPs. +func makeInstance(status, internalIP, externalIP string) *computepb.Instance { + inst := &computepb.Instance{ + Status: protoString(status), + NetworkInterfaces: []*computepb.NetworkInterface{ + { + NetworkIP: protoString(internalIP), + }, + }, + } + if externalIP != "" { + inst.NetworkInterfaces[0].AccessConfigs = []*computepb.AccessConfig{ + {NatIP: protoString(externalIP)}, + } + } + return inst +} + +// makeRunningInstance creates a RUNNING instance with both IPs assigned. +func makeRunningInstance(internalIP, externalIP string) *computepb.Instance { + return makeInstance("RUNNING", internalIP, externalIP) +} + +// makeStoppedInstance creates a TERMINATED instance with IPs from its last run. +func makeStoppedInstance(internalIP, externalIP string) *computepb.Instance { + return makeInstance("TERMINATED", internalIP, externalIP) +} + +// mockGetInstanceNotFoundThenRunning sets up a GetInstance mock where the first call per VM +// returns "not found" and subsequent calls return the given running instance. +// Returns the expected total call count (2 × numVMs). +func mockGetInstanceNotFoundThenRunning(gc *gcp.MockGCPClientManager, projectID, zone string, runningResp *computepb.Instance, numVMs int) { + instanceCalls := make(map[string]int) + var mu sync.Mutex + gc.EXPECT().GetInstance(projectID, zone, mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { + mu.Lock() + defer mu.Unlock() + instanceCalls[name]++ + if instanceCalls[name] == 1 { + return nil, fmt.Errorf("not found") + } + return runningResp, nil + }).Times(numVMs * 2) +} From 22966a27e468c37c3bca11d1cb61497f52898279 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:37:38 +0100 Subject: [PATCH 19/30] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- internal/bootstrap/gcp/gcp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 788cc4e3..25a7a967 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -1042,7 +1042,7 @@ func (b *GCPBootstrapper) waitForInstanceRunning(projectID, zone, name string, n maxAttempts = 60 pollInterval = 5 * time.Second ) - for attempt := range maxAttempts { + for attempt := 0; attempt < maxAttempts; attempt++ { inst, err := b.GCPClient.GetInstance(projectID, zone, name) if err != nil { return nil, fmt.Errorf("failed to poll instance %s: %w", name, err) From f5c65293cb86e70db08cc68999549a134a02e752 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:40:31 +0100 Subject: [PATCH 20/30] ref: update GCP bootstrap command flags to clarify VM options and exclusivity --- cli/cmd/bootstrap_gcp.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/cmd/bootstrap_gcp.go b/cli/cmd/bootstrap_gcp.go index a4184031..b4aa2efe 100644 --- a/cli/cmd/bootstrap_gcp.go +++ b/cli/cmd/bootstrap_gcp.go @@ -69,8 +69,8 @@ func AddBootstrapGcpCmd(parent *cobra.Command, opts *GlobalOptions) { flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.FolderID, "folder-id", "", "GCP Folder ID (optional)") flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.SSHPublicKeyPath, "ssh-public-key-path", "~/.ssh/id_rsa.pub", "SSH Public Key Path (default: ~/.ssh/id_rsa.pub)") flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.SSHPrivateKeyPath, "ssh-private-key-path", "~/.ssh/id_rsa", "SSH Private Key Path (default: ~/.ssh/id_rsa)") - flags.BoolVar(&bootstrapGcpCmd.CodesphereEnv.Preemptible, "preemptible", false, "Use preemptible VMs for Codesphere infrastructure (default: false)") - flags.BoolVar(&bootstrapGcpCmd.CodesphereEnv.Spot, "spot", false, "Use Spot VMs for Codesphere infrastructure. Falls back to standard VMs if spot capacity unavailable (default: false)") + flags.BoolVar(&bootstrapGcpCmd.CodesphereEnv.Preemptible, "preemptible", false, "Use preemptible VMs for Codesphere infrastructure. Mutually exclusive with --spot (default: false)") + flags.BoolVar(&bootstrapGcpCmd.CodesphereEnv.Spot, "spot", false, "Use Spot VMs for Codesphere infrastructure. Falls back to standard VMs if spot capacity unavailable. Mutually exclusive with --preemptible (default: false)") flags.IntVar(&bootstrapGcpCmd.CodesphereEnv.DatacenterID, "datacenter-id", 1, "Datacenter ID (default: 1)") flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.CustomPgIP, "custom-pg-ip", "", "Custom PostgreSQL IP (optional)") flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.InstallConfigPath, "install-config", "config.yaml", "Path to install config file (optional)") From e6edb9083ea7247d52483e866c6df2e439af828a Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 09:41:33 +0000 Subject: [PATCH 21/30] chore(docs): Auto-update docs and licenses Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> --- docs/oms_beta_bootstrap-gcp.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/oms_beta_bootstrap-gcp.md b/docs/oms_beta_bootstrap-gcp.md index 3a7af479..e95ab53f 100644 --- a/docs/oms_beta_bootstrap-gcp.md +++ b/docs/oms_beta_bootstrap-gcp.md @@ -40,7 +40,7 @@ oms beta bootstrap-gcp [flags] --openbao-password string OpenBao password (optional) --openbao-uri string URI for OpenBao (optional) --openbao-user string OpenBao username (optional) (default "admin") - --preemptible Use preemptible VMs for Codesphere infrastructure (default: false) + --preemptible Use preemptible VMs for Codesphere infrastructure. Mutually exclusive with --spot (default: false) --project-name string Unique GCP Project Name (required) --project-ttl string Time to live for the GCP project. Cleanup workflows will remove it afterwards. (default: 2 hours) (default "2h") --region string GCP Region (default: europe-west4) (default "europe-west4") @@ -48,7 +48,7 @@ oms beta bootstrap-gcp [flags] --registry-user string Custom Registry username (only for GitHub registry type) (optional) --secrets-dir string Directory for secrets (default: /etc/codesphere/secrets) (default "/etc/codesphere/secrets") --secrets-file string Path to secrets files (optional) (default "prod.vault.yaml") - --spot Use Spot VMs for Codesphere infrastructure. Falls back to standard VMs if spot capacity unavailable (default: false) + --spot Use Spot VMs for Codesphere infrastructure. Falls back to standard VMs if spot capacity unavailable. Mutually exclusive with --preemptible (default: false) --ssh-private-key-path string SSH Private Key Path (default: ~/.ssh/id_rsa) (default "~/.ssh/id_rsa") --ssh-public-key-path string SSH Public Key Path (default: ~/.ssh/id_rsa.pub) (default "~/.ssh/id_rsa.pub") --ssh-quiet Suppress SSH command output (default: false) From a88d43608e634ce961d4c6c0716d1685a28cce1f Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:51:43 +0100 Subject: [PATCH 22/30] fix: handle not found error in instance polling with retry logic --- internal/bootstrap/gcp/gcp.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 25a7a967..dcf7ce11 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -1045,6 +1045,12 @@ func (b *GCPBootstrapper) waitForInstanceRunning(projectID, zone, name string, n for attempt := 0; attempt < maxAttempts; attempt++ { inst, err := b.GCPClient.GetInstance(projectID, zone, name) if err != nil { + if IsNotFoundError(err) { + if attempt < maxAttempts-1 { + b.Time.Sleep(pollInterval) + } + continue + } return nil, fmt.Errorf("failed to poll instance %s: %w", name, err) } From b947458662bf735e5c821280a72642257967580b Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:53:26 +0100 Subject: [PATCH 23/30] fix: update IsNotFoundError function to always return false and improve test helper comment clarity --- internal/bootstrap/gcp/gcp.go | 2 +- internal/bootstrap/gcp/test_helpers_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index dcf7ce11..46389b1b 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -82,7 +82,7 @@ func IsNotFoundError(err error) bool { return true } - return strings.Contains(strings.ToLower(err.Error()), "not found") + return false } type VMDef struct { diff --git a/internal/bootstrap/gcp/test_helpers_test.go b/internal/bootstrap/gcp/test_helpers_test.go index b0b6462e..def3e54b 100644 --- a/internal/bootstrap/gcp/test_helpers_test.go +++ b/internal/bootstrap/gcp/test_helpers_test.go @@ -44,7 +44,7 @@ func makeStoppedInstance(internalIP, externalIP string) *computepb.Instance { // mockGetInstanceNotFoundThenRunning sets up a GetInstance mock where the first call per VM // returns "not found" and subsequent calls return the given running instance. -// Returns the expected total call count (2 × numVMs). +// It sets the expected total call count to 2 × numVMs. func mockGetInstanceNotFoundThenRunning(gc *gcp.MockGCPClientManager, projectID, zone string, runningResp *computepb.Instance, numVMs int) { instanceCalls := make(map[string]int) var mu sync.Mutex From a83bd6d1e66b2ff1590d89264b8e49590450a629 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 11:05:27 +0100 Subject: [PATCH 24/30] fix: update mockGetInstanceNotFoundThenRunning to return a googleapi.Error for not found cases --- internal/bootstrap/gcp/test_helpers_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/bootstrap/gcp/test_helpers_test.go b/internal/bootstrap/gcp/test_helpers_test.go index def3e54b..5d9c210c 100644 --- a/internal/bootstrap/gcp/test_helpers_test.go +++ b/internal/bootstrap/gcp/test_helpers_test.go @@ -4,12 +4,12 @@ package gcp_test import ( - "fmt" "sync" "cloud.google.com/go/compute/apiv1/computepb" "github.com/codesphere-cloud/oms/internal/bootstrap/gcp" "github.com/stretchr/testify/mock" + "google.golang.org/api/googleapi" ) func protoString(s string) *string { return &s } @@ -53,7 +53,7 @@ func mockGetInstanceNotFoundThenRunning(gc *gcp.MockGCPClientManager, projectID, defer mu.Unlock() instanceCalls[name]++ if instanceCalls[name] == 1 { - return nil, fmt.Errorf("not found") + return nil, &googleapi.Error{Code: 404, Message: "not found"} } return runningResp, nil }).Times(numVMs * 2) From 31e115f4697dd1894cf9c0e503d03bb5655a12d3 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 11:17:17 +0100 Subject: [PATCH 25/30] fix: simplify instance retrieval logic in GCP Bootstrapper tests --- internal/bootstrap/gcp/gcp_test.go | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index 80cd3dd2..7e0b38b7 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -181,21 +181,8 @@ var _ = Describe("GCP Bootstrapper", func() { gc.EXPECT().CreateFirewallRule(projectId, mock.Anything).Return(nil).Times(5) // 11. EnsureComputeInstances - // Track GetInstance calls per VM name - instanceCalls := make(map[string]int) - var instanceMu sync.Mutex ipResp := makeRunningInstance("10.0.0.1", "1.2.3.4") - gc.EXPECT().GetInstance(projectId, "us-central1-a", mock.Anything).RunAndReturn(func(projectID, zone, name string) (*computepb.Instance, error) { - instanceMu.Lock() - defer instanceMu.Unlock() - instanceCalls[name]++ - if instanceCalls[name] == 1 { - // First call, instance doesn't exist - return nil, fmt.Errorf("not found") - } - // Second call, return instance with IPs - return ipResp, nil - }).Times(18) + mockGetInstanceNotFoundThenRunning(gc, projectId, "us-central1-a", ipResp, 9) fw.EXPECT().ReadFile(mock.Anything).Return([]byte("fake-key"), nil).Times(9) gc.EXPECT().CreateInstance(projectId, "us-central1-a", mock.Anything).Return(nil).Times(9) From 661109694fdb6804b6797c90e3b9d0ac384d710f Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 11:47:13 +0100 Subject: [PATCH 26/30] ref: fix comments in GCP Bootstrapper tests for clarity --- internal/bootstrap/gcp/gcp_test.go | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index 7e0b38b7..1718afff 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -132,7 +132,7 @@ var _ = Describe("GCP Bootstrapper", func() { bs.Env.RegistryType = gcp.RegistryTypeArtifactRegistry bs.Env.WriteConfig = true - // 1. EnsureInstallConfig + // EnsureInstallConfig fw.EXPECT().Exists("fake-config-file").Return(false) icg.EXPECT().ApplyProfile("minimal").Return(nil) // Returning a real install config to avoid nil pointer dereferences later @@ -144,49 +144,49 @@ var _ = Describe("GCP Bootstrapper", func() { projectId := "test-project-12345" - // 2. EnsureSecrets + // EnsureSecrets fw.EXPECT().Exists("fake-secret").Return(false) icg.EXPECT().GetVault().Return(&files.InstallVault{}) - // 3. EnsureProject + // EnsureProject gc.EXPECT().GetProjectByName(mock.Anything, "test-project").Return(nil, fmt.Errorf("project not found: test-project")) gc.EXPECT().CreateProjectID("test-project").Return(projectId) gc.EXPECT().CreateProject(mock.Anything, mock.Anything, "test-project", time.Hour).Return(mock.Anything, nil) - // 4. EnsureBilling + // EnsureBilling gc.EXPECT().GetBillingInfo(projectId).Return(&cloudbilling.ProjectBillingInfo{BillingEnabled: false}, nil) gc.EXPECT().EnableBilling(projectId, "test-billing-account").Return(nil) - // 5. EnsureAPIsEnabled + // EnsureAPIsEnabled gc.EXPECT().EnableAPIs(projectId, mock.Anything).Return(nil) - // 6. EnsureArtifactRegistry + // EnsureArtifactRegistry gc.EXPECT().GetArtifactRegistry(projectId, "us-central1", "codesphere-registry").Return(nil, fmt.Errorf("not found")) gc.EXPECT().CreateArtifactRegistry(projectId, "us-central1", "codesphere-registry").Return(&artifactregistrypb.Repository{Name: "codesphere-registry"}, nil) - // 7. EnsureServiceAccounts + // EnsureServiceAccounts gc.EXPECT().CreateServiceAccount(projectId, "cloud-controller", "cloud-controller").Return("cloud-controller@p.iam.gserviceaccount.com", false, nil) gc.EXPECT().CreateServiceAccount(projectId, "artifact-registry-writer", "artifact-registry-writer").Return("writer@p.iam.gserviceaccount.com", true, nil) gc.EXPECT().CreateServiceAccountKey(projectId, "writer@p.iam.gserviceaccount.com").Return("fake-key", nil) - // 8. EnsureIAMRoles + // EnsureIAMRoles gc.EXPECT().AssignIAMRole(projectId, "artifact-registry-writer", projectId, []string{"roles/artifactregistry.writer"}).Return(nil) gc.EXPECT().AssignIAMRole(projectId, "cloud-controller", projectId, []string{"roles/compute.admin"}).Return(nil) gc.EXPECT().AssignIAMRole(csEnv.DNSProjectID, "cloud-controller", projectId, []string{"roles/dns.admin"}).Return(nil) - // 9. EnsureVPC + // EnsureVPC gc.EXPECT().CreateVPC(projectId, "us-central1", projectId+"-vpc", projectId+"-us-central1-subnet", projectId+"-router", projectId+"-nat-gateway").Return(nil) - // 10. EnsureFirewallRules (5 times) + // EnsureFirewallRules (5 times) gc.EXPECT().CreateFirewallRule(projectId, mock.Anything).Return(nil).Times(5) - // 11. EnsureComputeInstances + // EnsureComputeInstances ipResp := makeRunningInstance("10.0.0.1", "1.2.3.4") mockGetInstanceNotFoundThenRunning(gc, projectId, "us-central1-a", ipResp, 9) fw.EXPECT().ReadFile(mock.Anything).Return([]byte("fake-key"), nil).Times(9) gc.EXPECT().CreateInstance(projectId, "us-central1-a", mock.Anything).Return(nil).Times(9) - // 12. EnsureGatewayIPAddresses + // EnsureGatewayIPAddresses gc.EXPECT().GetAddress(projectId, "us-central1", "gateway").Return(nil, fmt.Errorf("not found")) gc.EXPECT().CreateAddress(projectId, "us-central1", mock.MatchedBy(func(addr *computepb.Address) bool { return *addr.Name == "gateway" })).Return("1.1.1.1", nil) gc.EXPECT().GetAddress(projectId, "us-central1", "gateway").Return(nil, fmt.Errorf("not found")) @@ -194,7 +194,7 @@ var _ = Describe("GCP Bootstrapper", func() { gc.EXPECT().CreateAddress(projectId, "us-central1", mock.MatchedBy(func(addr *computepb.Address) bool { return *addr.Name == "public-gateway" })).Return("2.2.2.2", nil) gc.EXPECT().GetAddress(projectId, "us-central1", "public-gateway").Return(&computepb.Address{Address: protoString("2.2.2.2")}, nil) - // 16. UpdateInstallConfig + // UpdateInstallConfig icg.EXPECT().GenerateSecrets().Return(nil) icg.EXPECT().WriteInstallConfig("fake-config-file", true).Return(nil) nodeClient.EXPECT().CopyFile(mock.Anything, "fake-config-file", "/etc/codesphere/config.yaml").Return(nil) @@ -205,23 +205,23 @@ var _ = Describe("GCP Bootstrapper", func() { nodeClient.EXPECT().WaitReady(mock.Anything, mock.Anything).Return(nil).Return(nil) nodeClient.EXPECT().RunCommand(mock.Anything, mock.Anything, mock.Anything).Return(nil) - // 17. EnsureAgeKey + // EnsureAgeKey nodeClient.EXPECT().RunCommand(mock.MatchedBy(jumpbboxMatcher), "root", "mkdir -p /etc/codesphere/secrets; age-keygen -o /etc/codesphere/secrets/age_key.txt").Return(nil) nodeClient.EXPECT().HasFile(mock.MatchedBy(jumpbboxMatcher), "/etc/codesphere/secrets/age_key.txt").Return(false) - // 18. EncryptVault + // EncryptVault nodeClient.EXPECT().RunCommand(mock.MatchedBy(jumpbboxMatcher), "root", "cp /etc/codesphere/secrets/prod.vault.yaml{,.bak}").Return(nil) nodeClient.EXPECT().RunCommand(mock.MatchedBy(jumpbboxMatcher), "root", mock.MatchedBy(func(cmd string) bool { return strings.Contains(cmd, "sops --encrypt") })).Return(nil) - // 19. EnsureDNSRecords + // EnsureDNSRecords gc.EXPECT().EnsureDNSManagedZone(csEnv.DNSProjectID, "test-zone", "example.com.", mock.Anything).Return(nil) gc.EXPECT().EnsureDNSRecordSets(csEnv.DNSProjectID, "test-zone", mock.MatchedBy(func(records []*dns.ResourceRecordSet) bool { return len(records) == 4 })).Return(nil) - // 20. GenerateK0sConfigScript + // GenerateK0sConfigScript fw.EXPECT().WriteFile("configure-k0s.sh", mock.Anything, os.FileMode(0755)).Return(nil) nodeClient.EXPECT().CopyFile(mock.Anything, "configure-k0s.sh", "/root/configure-k0s.sh").Return(nil) nodeClient.EXPECT().RunCommand(mock.Anything, "root", "chmod +x /root/configure-k0s.sh").Return(nil) From 7d2a1540a4ce719280de4fea6421f6eb87db6c12 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Wed, 18 Mar 2026 16:59:04 +0100 Subject: [PATCH 27/30] fix: enhance GCP instance management and testing for spot VMs --- internal/bootstrap/gcp/gcp.go | 24 +- internal/bootstrap/gcp/gcp_test.go | 22 +- internal/bootstrap/gcp/spot_vm_test.go | 501 ++++---------------- internal/bootstrap/gcp/test_helpers_test.go | 33 +- 4 files changed, 152 insertions(+), 428 deletions(-) diff --git a/internal/bootstrap/gcp/gcp.go b/internal/bootstrap/gcp/gcp.go index 46389b1b..d654337e 100644 --- a/internal/bootstrap/gcp/gcp.go +++ b/internal/bootstrap/gcp/gcp.go @@ -852,10 +852,13 @@ func (b *GCPBootstrapper) ensureVM(vm VMDef, rootDiskSize int64, logCh chan<- st } if existingInstance != nil { - if s := existingInstance.GetStatus(); s == "TERMINATED" || s == "STOPPED" { + switch s := existingInstance.GetStatus(); s { + case "TERMINATED", "STOPPED": if err := b.GCPClient.StartInstance(projectID, zone, vm.Name); err != nil { return vmResult{}, fmt.Errorf("failed to start stopped instance %s: %w", vm.Name, err) } + case "SUSPENDED": + return vmResult{}, fmt.Errorf("instance %s is SUSPENDED; manual resume is required", vm.Name) } } else { instance, err := b.buildInstanceSpec(vm, rootDiskSize) @@ -1063,20 +1066,22 @@ func (b *GCPBootstrapper) waitForInstanceRunning(projectID, zone, name string, n } } return nil, fmt.Errorf("timed out waiting for instance %s to be RUNNING with IPs assigned after %s", - name, time.Duration(maxAttempts)*pollInterval) + name, pollInterval*time.Duration(maxAttempts)) } -// IsSpotCapacityError checks if the error is related to spot VM capacity issues +// IsSpotCapacityError checks if the error is related to spot VM capacity issues. func IsSpotCapacityError(err error) bool { if err == nil { return false } - errStr := err.Error() - return strings.Contains(errStr, "ZONE_RESOURCE_POOL_EXHAUSTED") || - strings.Contains(errStr, "UNSUPPORTED_OPERATION") || + if status.Code(err) == codes.ResourceExhausted { + return true + } + errStr := strings.ToLower(err.Error()) + return strings.Contains(errStr, "zone_resource_pool_exhausted") || + strings.Contains(errStr, "unsupported_operation") || strings.Contains(errStr, "stockout") || - strings.Contains(errStr, "does not have enough resources") || - status.Code(err) == codes.ResourceExhausted + strings.Contains(errStr, "does not have enough resources") } // EnsureGatewayIPAddresses reserves 2 static external IP addresses for the ingress @@ -1824,6 +1829,9 @@ func (b *GCPBootstrapper) RunK0sConfigScript() error { // Helper functions func isAlreadyExistsError(err error) bool { + if err == nil { + return false + } return status.Code(err) == codes.AlreadyExists || strings.Contains(err.Error(), "already exists") } diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index 1718afff..1309c83f 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/mock" "google.golang.org/api/cloudbilling/v1" "google.golang.org/api/dns/v1" + "google.golang.org/api/googleapi" ) func jumpbboxMatcher(node *node.Node) bool { @@ -387,17 +388,6 @@ var _ = Describe("GCP Bootstrapper", func() { }) - Context("When both --spot and --preemptible are specified", func() { - BeforeEach(func() { - csEnv.Spot = true - csEnv.Preemptible = true - }) - It("fails with a clear error message", func() { - err := bs.ValidateInput() - Expect(err).To(MatchError(MatchRegexp("cannot specify both --spot and --preemptible"))) - }) - }) - }) Describe("EnsureInstallConfig", func() { @@ -975,8 +965,10 @@ var _ = Describe("GCP Bootstrapper", func() { }) Describe("Invalid cases", func() { + notFoundErr := &googleapi.Error{Code: 404, Message: "not found"} + It("fails when SSH key read fails", func() { - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("not found")).Maybe() + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, notFoundErr).Maybe() fw.EXPECT().ReadFile(mock.Anything).Return(nil, fmt.Errorf("read error")).Maybe() err := bs.EnsureComputeInstances() @@ -985,7 +977,7 @@ var _ = Describe("GCP Bootstrapper", func() { }) It("fails when CreateInstance fails", func() { - gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, fmt.Errorf("not found")).Maybe() + gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(nil, notFoundErr).Maybe() fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Maybe() gc.EXPECT().CreateInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).Return(fmt.Errorf("create error")).Maybe() @@ -994,7 +986,7 @@ var _ = Describe("GCP Bootstrapper", func() { Expect(err.Error()).To(ContainSubstring("error ensuring compute instances")) }) - It("fails when GetInstance fails", func() { + It("fails when GetInstance fails after creation", func() { instanceCalls := make(map[string]int) var mu sync.Mutex gc.EXPECT().GetInstance(csEnv.ProjectID, csEnv.Zone, mock.Anything).RunAndReturn( @@ -1003,7 +995,7 @@ var _ = Describe("GCP Bootstrapper", func() { defer mu.Unlock() instanceCalls[name]++ if instanceCalls[name] == 1 { - return nil, fmt.Errorf("not found") + return nil, notFoundErr } return nil, fmt.Errorf("get error") }, diff --git a/internal/bootstrap/gcp/spot_vm_test.go b/internal/bootstrap/gcp/spot_vm_test.go index ed007a18..ce7b6c72 100644 --- a/internal/bootstrap/gcp/spot_vm_test.go +++ b/internal/bootstrap/gcp/spot_vm_test.go @@ -4,17 +4,10 @@ package gcp_test import ( - "context" "fmt" "cloud.google.com/go/compute/apiv1/computepb" - "github.com/codesphere-cloud/oms/internal/bootstrap" "github.com/codesphere-cloud/oms/internal/bootstrap/gcp" - "github.com/codesphere-cloud/oms/internal/env" - "github.com/codesphere-cloud/oms/internal/installer" - "github.com/codesphere-cloud/oms/internal/installer/node" - "github.com/codesphere-cloud/oms/internal/portal" - "github.com/codesphere-cloud/oms/internal/util" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/stretchr/testify/mock" @@ -24,61 +17,35 @@ import ( var _ = Describe("Spot VM", func() { - Describe("isSpotCapacityError", func() { + Describe("IsSpotCapacityError", func() { It("returns false for nil error", func() { Expect(gcp.IsSpotCapacityError(nil)).To(BeFalse()) }) - It("detects gRPC ResourceExhausted status", func() { - err := status.Errorf(codes.ResourceExhausted, "resource exhausted") - Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) - }) - - It("does not match non-ResourceExhausted gRPC codes", func() { - Expect(gcp.IsSpotCapacityError(status.Errorf(codes.NotFound, "not found"))).To(BeFalse()) - Expect(gcp.IsSpotCapacityError(status.Errorf(codes.PermissionDenied, "denied"))).To(BeFalse()) - Expect(gcp.IsSpotCapacityError(status.Errorf(codes.Internal, "internal"))).To(BeFalse()) - }) - - It("detects ZONE_RESOURCE_POOL_EXHAUSTED error string", func() { - err := fmt.Errorf("googleapi: Error 403: ZONE_RESOURCE_POOL_EXHAUSTED - the zone does not have enough resources") - Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) - }) - - It("detects UNSUPPORTED_OPERATION error string", func() { - err := fmt.Errorf("UNSUPPORTED_OPERATION: spot VMs not available in this zone") - Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) - }) - - It("detects stockout error string", func() { - err := fmt.Errorf("stockout in zone us-central1-a") - Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) - }) - - It("detects does not have enough resources error string", func() { - err := fmt.Errorf("the zone 'us-central1-a' does not have enough resources available to fulfill the request") - Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) - }) - - It("does not match unrelated error strings", func() { - Expect(gcp.IsSpotCapacityError(fmt.Errorf("permission denied"))).To(BeFalse()) - Expect(gcp.IsSpotCapacityError(fmt.Errorf("invalid argument"))).To(BeFalse()) - Expect(gcp.IsSpotCapacityError(fmt.Errorf("quota exceeded"))).To(BeFalse()) - Expect(gcp.IsSpotCapacityError(fmt.Errorf("network error"))).To(BeFalse()) - }) - - It("detects gRPC ResourceExhausted with additional message text", func() { - err := status.Errorf(codes.ResourceExhausted, "spot VM pool exhausted in us-central1-a") - Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) - }) + DescribeTable("detects known capacity errors", + func(err error) { Expect(gcp.IsSpotCapacityError(err)).To(BeTrue()) }, + Entry("gRPC ResourceExhausted", status.Errorf(codes.ResourceExhausted, "resource exhausted")), + Entry("gRPC ResourceExhausted with detail", status.Errorf(codes.ResourceExhausted, "spot VM pool exhausted in us-central1-a")), + Entry("ZONE_RESOURCE_POOL_EXHAUSTED", fmt.Errorf("googleapi: Error 403: ZONE_RESOURCE_POOL_EXHAUSTED - the zone does not have enough resources")), + Entry("UNSUPPORTED_OPERATION", fmt.Errorf("UNSUPPORTED_OPERATION: spot VMs not available in this zone")), + Entry("stockout", fmt.Errorf("stockout in zone us-central1-a")), + Entry("does not have enough resources", fmt.Errorf("the zone 'us-central1-a' does not have enough resources available to fulfill the request")), + ) - It("does not match gRPC Unavailable status", func() { - err := status.Errorf(codes.Unavailable, "service unavailable") - Expect(gcp.IsSpotCapacityError(err)).To(BeFalse()) - }) + DescribeTable("rejects non-capacity errors", + func(err error) { Expect(gcp.IsSpotCapacityError(err)).To(BeFalse()) }, + Entry("NotFound", status.Errorf(codes.NotFound, "not found")), + Entry("PermissionDenied", status.Errorf(codes.PermissionDenied, "denied")), + Entry("Internal", status.Errorf(codes.Internal, "internal")), + Entry("Unavailable", status.Errorf(codes.Unavailable, "service unavailable")), + Entry("permission denied string", fmt.Errorf("permission denied")), + Entry("invalid argument string", fmt.Errorf("invalid argument")), + Entry("quota exceeded string", fmt.Errorf("quota exceeded")), + Entry("network error string", fmt.Errorf("network error")), + ) }) - Describe("buildSchedulingConfig", func() { + Describe("BuildSchedulingConfig", func() { var ( bs *gcp.GCPBootstrapper csEnv *gcp.CodesphereEnvironment @@ -96,115 +63,37 @@ var _ = Describe("Spot VM", func() { DatacenterID: 1, Experiments: gcp.DefaultExperiments, } - - var err error - bs, err = gcp.NewGCPBootstrapper( - context.Background(), - env.NewEnv(), - bootstrap.NewStepLogger(false), - csEnv, - installer.NewMockInstallConfigManager(GinkgoT()), - gcp.NewMockGCPClientManager(GinkgoT()), - util.NewMockFileIO(GinkgoT()), - node.NewMockNodeClient(GinkgoT()), - portal.NewMockPortal(GinkgoT()), - util.NewFakeTime(), - ) - Expect(err).NotTo(HaveOccurred()) + gc := gcp.NewMockGCPClientManager(GinkgoT()) + bs = newTestBootstrapper(csEnv, gc) }) - Context("when spot is enabled", func() { - BeforeEach(func() { - csEnv.Spot = true - csEnv.Preemptible = false - }) - - It("sets SPOT provisioning model", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.ProvisioningModel).NotTo(BeNil()) - Expect(*sched.ProvisioningModel).To(Equal("SPOT")) - }) - - It("sets OnHostMaintenance to TERMINATE", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.OnHostMaintenance).NotTo(BeNil()) - Expect(*sched.OnHostMaintenance).To(Equal("TERMINATE")) - }) - - It("sets AutomaticRestart to false", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.AutomaticRestart).NotTo(BeNil()) - Expect(*sched.AutomaticRestart).To(BeFalse()) - }) - - It("sets InstanceTerminationAction to STOP", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.InstanceTerminationAction).NotTo(BeNil()) - Expect(*sched.InstanceTerminationAction).To(Equal("STOP")) - }) - - It("returns a complete scheduling config with all four fields set", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched).NotTo(BeNil()) - Expect(*sched.ProvisioningModel).To(Equal("SPOT")) - Expect(*sched.OnHostMaintenance).To(Equal("TERMINATE")) - Expect(*sched.AutomaticRestart).To(BeFalse()) - Expect(*sched.InstanceTerminationAction).To(Equal("STOP")) - }) - - It("does not set Preemptible field", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.Preemptible).To(BeNil()) - }) + It("returns spot scheduling when spot is enabled", func() { + csEnv.Spot = true + sched := bs.BuildSchedulingConfig() + Expect(*sched.ProvisioningModel).To(Equal("SPOT")) + Expect(*sched.OnHostMaintenance).To(Equal("TERMINATE")) + Expect(*sched.AutomaticRestart).To(BeFalse()) + Expect(*sched.InstanceTerminationAction).To(Equal("STOP")) + Expect(sched.Preemptible).To(BeNil()) }) - Context("when preemptible is enabled", func() { - BeforeEach(func() { - csEnv.Spot = false - csEnv.Preemptible = true - }) - - It("sets Preemptible to true", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.Preemptible).NotTo(BeNil()) - Expect(*sched.Preemptible).To(BeTrue()) - }) - - It("does not set SPOT provisioning model", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.ProvisioningModel).To(BeNil()) - }) - - It("does not set OnHostMaintenance", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.OnHostMaintenance).To(BeNil()) - }) - - It("does not set AutomaticRestart", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.AutomaticRestart).To(BeNil()) - }) - - It("does not set InstanceTerminationAction", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.InstanceTerminationAction).To(BeNil()) - }) + It("returns preemptible scheduling when preemptible is enabled", func() { + csEnv.Preemptible = true + sched := bs.BuildSchedulingConfig() + Expect(*sched.Preemptible).To(BeTrue()) + Expect(sched.ProvisioningModel).To(BeNil()) + Expect(sched.OnHostMaintenance).To(BeNil()) + Expect(sched.AutomaticRestart).To(BeNil()) + Expect(sched.InstanceTerminationAction).To(BeNil()) }) - Context("when neither spot nor preemptible is enabled", func() { - BeforeEach(func() { - csEnv.Spot = false - csEnv.Preemptible = false - }) - - It("returns empty scheduling config", func() { - sched := bs.BuildSchedulingConfig() - Expect(sched.ProvisioningModel).To(BeNil()) - Expect(sched.Preemptible).To(BeNil()) - Expect(sched.OnHostMaintenance).To(BeNil()) - Expect(sched.AutomaticRestart).To(BeNil()) - Expect(sched.InstanceTerminationAction).To(BeNil()) - }) + It("returns empty scheduling when neither is enabled", func() { + sched := bs.BuildSchedulingConfig() + Expect(sched.ProvisioningModel).To(BeNil()) + Expect(sched.Preemptible).To(BeNil()) + Expect(sched.OnHostMaintenance).To(BeNil()) + Expect(sched.AutomaticRestart).To(BeNil()) + Expect(sched.InstanceTerminationAction).To(BeNil()) }) }) @@ -230,97 +119,32 @@ var _ = Describe("Spot VM", func() { } }) - newBootstrapper := func() *gcp.GCPBootstrapper { - bs, err := gcp.NewGCPBootstrapper( - context.Background(), - env.NewEnv(), - bootstrap.NewStepLogger(false), - csEnv, - installer.NewMockInstallConfigManager(GinkgoT()), - gcp.NewMockGCPClientManager(GinkgoT()), - util.NewMockFileIO(GinkgoT()), - node.NewMockNodeClient(GinkgoT()), - portal.NewMockPortal(GinkgoT()), - util.NewFakeTime(), - ) - Expect(err).NotTo(HaveOccurred()) - return bs - } - - It("succeeds when only spot is set", func() { - csEnv.Spot = true - csEnv.Preemptible = false - bs := newBootstrapper() - err := bs.ValidateInput() - Expect(err).NotTo(HaveOccurred()) - }) - - It("succeeds when only preemptible is set", func() { - csEnv.Spot = false - csEnv.Preemptible = true - bs := newBootstrapper() - err := bs.ValidateInput() - Expect(err).NotTo(HaveOccurred()) - }) - - It("succeeds when neither is set", func() { - csEnv.Spot = false - csEnv.Preemptible = false - bs := newBootstrapper() - err := bs.ValidateInput() - Expect(err).NotTo(HaveOccurred()) - }) + DescribeTable("succeeds for valid combinations", + func(spot, preemptible bool) { + csEnv.Spot = spot + csEnv.Preemptible = preemptible + gc := gcp.NewMockGCPClientManager(GinkgoT()) + bs := newTestBootstrapper(csEnv, gc) + Expect(bs.ValidateInput()).NotTo(HaveOccurred()) + }, + Entry("only spot", true, false), + Entry("only preemptible", false, true), + Entry("neither", false, false), + ) It("fails when both spot and preemptible are set", func() { csEnv.Spot = true csEnv.Preemptible = true - bs := newBootstrapper() + gc := gcp.NewMockGCPClientManager(GinkgoT()) + bs := newTestBootstrapper(csEnv, gc) err := bs.ValidateInput() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("cannot specify both --spot and --preemptible")) - }) - - It("error message suggests using --spot over --preemptible", func() { - csEnv.Spot = true - csEnv.Preemptible = true - bs := newBootstrapper() - err := bs.ValidateInput() - Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("use --spot for the newer spot VM model")) }) - - It("spot does not interfere with other validation (install version)", func() { - csEnv.Spot = true - csEnv.InstallVersion = "v1.0.0" - csEnv.InstallHash = "abc123" - csEnv.RegistryType = gcp.RegistryTypeGitHub - - mockPortal := portal.NewMockPortal(GinkgoT()) - mockPortal.EXPECT().GetBuild(portal.CodesphereProduct, "v1.0.0", "abc123").Return(portal.Build{ - Artifacts: []portal.Artifact{{Filename: "installer-lite.tar.gz"}}, - Hash: "abc123", - Version: "v1.0.0", - }, nil) - - bs, err := gcp.NewGCPBootstrapper( - context.Background(), - env.NewEnv(), - bootstrap.NewStepLogger(false), - csEnv, - installer.NewMockInstallConfigManager(GinkgoT()), - gcp.NewMockGCPClientManager(GinkgoT()), - util.NewMockFileIO(GinkgoT()), - node.NewMockNodeClient(GinkgoT()), - mockPortal, - util.NewFakeTime(), - ) - Expect(err).NotTo(HaveOccurred()) - err = bs.ValidateInput() - Expect(err).NotTo(HaveOccurred()) - }) }) - Describe("createInstanceWithFallback", func() { + Describe("CreateInstanceWithFallback", func() { var ( bs *gcp.GCPBootstrapper csEnv *gcp.CodesphereEnvironment @@ -343,42 +167,22 @@ var _ = Describe("Spot VM", func() { Experiments: gcp.DefaultExperiments, } logCh = make(chan string, 10) - - var err error - bs, err = gcp.NewGCPBootstrapper( - context.Background(), - env.NewEnv(), - bootstrap.NewStepLogger(false), - csEnv, - installer.NewMockInstallConfigManager(GinkgoT()), - gc, - util.NewMockFileIO(GinkgoT()), - node.NewMockNodeClient(GinkgoT()), - portal.NewMockPortal(GinkgoT()), - util.NewFakeTime(), - ) - Expect(err).NotTo(HaveOccurred()) + bs = newTestBootstrapper(csEnv, gc) }) - Context("when creation succeeds on first attempt", func() { - It("returns nil", func() { - instance := &computepb.Instance{Name: protoString("test-vm")} - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance).Return(nil) + It("succeeds on first attempt", func() { + instance := &computepb.Instance{Name: protoString("test-vm")} + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance).Return(nil) - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) - Expect(err).NotTo(HaveOccurred()) - }) + Expect(bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh)).To(Succeed()) }) - Context("when the instance already exists", func() { - It("returns nil (treats as success)", func() { - instance := &computepb.Instance{Name: protoString("test-vm")} - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). - Return(status.Errorf(codes.AlreadyExists, "already exists")) + It("treats AlreadyExists as success", func() { + instance := &computepb.Instance{Name: protoString("test-vm")} + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). + Return(status.Errorf(codes.AlreadyExists, "already exists")) - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) - Expect(err).NotTo(HaveOccurred()) - }) + Expect(bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh)).To(Succeed()) }) Context("when spot is enabled", func() { @@ -386,40 +190,31 @@ var _ = Describe("Spot VM", func() { csEnv.Spot = true }) + spotInstance := func(name string) *computepb.Instance { + return &computepb.Instance{ + Name: protoString(name), + Scheduling: &computepb.Scheduling{ProvisioningModel: protoString("SPOT")}, + } + } + DescribeTable("falls back to standard VM on capacity errors", func(capacityErr error) { - instance := &computepb.Instance{ - Name: protoString("test-vm"), - Scheduling: &computepb.Scheduling{ - ProvisioningModel: protoString("SPOT"), - }, - } - - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). - Return(capacityErr).Once() - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). - Return(nil).Once() - - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) - Expect(err).NotTo(HaveOccurred()) + instance := spotInstance("test-vm") + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything).Return(capacityErr).Once() + gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything).Return(nil).Once() + Expect(bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh)).To(Succeed()) Expect(logCh).To(Receive(ContainSubstring("falling back to standard VM"))) }, Entry("gRPC ResourceExhausted", status.Errorf(codes.ResourceExhausted, "exhausted")), - Entry("ZONE_RESOURCE_POOL_EXHAUSTED string", fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")), - Entry("UNSUPPORTED_OPERATION string", fmt.Errorf("UNSUPPORTED_OPERATION")), - Entry("stockout string", fmt.Errorf("stockout in zone")), - Entry("does not have enough resources string", fmt.Errorf("zone does not have enough resources")), + Entry("ZONE_RESOURCE_POOL_EXHAUSTED", fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")), + Entry("UNSUPPORTED_OPERATION", fmt.Errorf("UNSUPPORTED_OPERATION")), + Entry("stockout", fmt.Errorf("stockout in zone")), + Entry("does not have enough resources", fmt.Errorf("zone does not have enough resources")), ) It("clears scheduling config on fallback", func() { - instance := &computepb.Instance{ - Name: protoString("test-vm"), - Scheduling: &computepb.Scheduling{ - ProvisioningModel: protoString("SPOT"), - }, - } - + instance := spotInstance("test-vm") gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). Return(fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")).Once() gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.MatchedBy(func(inst *computepb.Instance) bool { @@ -428,36 +223,24 @@ var _ = Describe("Spot VM", func() { inst.Scheduling.Preemptible == nil })).Return(nil).Once() - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) - Expect(err).NotTo(HaveOccurred()) + Expect(bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh)).To(Succeed()) }) - It("returns error when fallback also fails", func() { - instance := &computepb.Instance{ - Name: protoString("test-vm"), - Scheduling: &computepb.Scheduling{ - ProvisioningModel: protoString("SPOT"), - }, - } - + It("returns error with context when fallback also fails", func() { + instance := spotInstance("test-vm") gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). Return(fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")).Once() gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). - Return(fmt.Errorf("quota exceeded")).Once() + Return(fmt.Errorf("insufficient quota")).Once() err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fallback to standard VM")) + Expect(err.Error()).To(ContainSubstring("insufficient quota")) }) - It("does NOT fall back when error is not capacity-related", func() { - instance := &computepb.Instance{ - Name: protoString("test-vm"), - Scheduling: &computepb.Scheduling{ - ProvisioningModel: protoString("SPOT"), - }, - } - + It("does NOT fall back on non-capacity errors", func() { + instance := spotInstance("test-vm") gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). Return(fmt.Errorf("permission denied")).Once() @@ -469,70 +252,18 @@ var _ = Describe("Spot VM", func() { }) It("succeeds when fallback retry returns AlreadyExists", func() { - instance := &computepb.Instance{ - Name: protoString("test-vm"), - Scheduling: &computepb.Scheduling{ - ProvisioningModel: protoString("SPOT"), - }, - } - + instance := spotInstance("test-vm") gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). Return(status.Errorf(codes.ResourceExhausted, "exhausted")).Once() gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). Return(status.Errorf(codes.AlreadyExists, "already exists")).Once() - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) - Expect(err).NotTo(HaveOccurred()) - + Expect(bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh)).To(Succeed()) Expect(logCh).To(Receive(ContainSubstring("falling back to standard VM"))) }) - - It("logs the correct VM name in the fallback message", func() { - instance := &computepb.Instance{ - Name: protoString("ceph-3"), - Scheduling: &computepb.Scheduling{ - ProvisioningModel: protoString("SPOT"), - }, - } - - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). - Return(fmt.Errorf("ZONE_RESOURCE_POOL_EXHAUSTED")).Once() - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). - Return(nil).Once() - - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "ceph-3", logCh) - Expect(err).NotTo(HaveOccurred()) - - var msg string - Expect(logCh).To(Receive(&msg)) - Expect(msg).To(ContainSubstring("ceph-3")) - }) - - It("wraps the original error when fallback fails", func() { - instance := &computepb.Instance{ - Name: protoString("test-vm"), - Scheduling: &computepb.Scheduling{ - ProvisioningModel: protoString("SPOT"), - }, - } - - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). - Return(fmt.Errorf("stockout in zone")).Once() - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", mock.Anything). - Return(fmt.Errorf("insufficient quota")).Once() - - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("fallback to standard VM")) - Expect(err.Error()).To(ContainSubstring("insufficient quota")) - }) }) Context("when spot is disabled", func() { - BeforeEach(func() { - csEnv.Spot = false - }) - It("does not fall back on capacity errors", func() { instance := &computepb.Instance{Name: protoString("test-vm")} gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). @@ -543,49 +274,13 @@ var _ = Describe("Spot VM", func() { Expect(err.Error()).To(ContainSubstring("failed to create instance test-vm")) }) - It("propagates non-capacity errors", func() { - instance := &computepb.Instance{Name: protoString("test-vm")} - gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). - Return(fmt.Errorf("permission denied")) - - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("failed to create instance test-vm")) - Expect(err.Error()).To(ContainSubstring("permission denied")) - }) - It("returns nil for string-based already exists error", func() { instance := &computepb.Instance{Name: protoString("test-vm")} gc.EXPECT().CreateInstance("test-pid", "us-central1-a", instance). Return(fmt.Errorf("The resource 'test-vm' already exists")) - err := bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh) - Expect(err).NotTo(HaveOccurred()) + Expect(bs.CreateInstanceWithFallback("test-pid", "us-central1-a", instance, "test-vm", logCh)).To(Succeed()) }) }) }) - - Describe("CodesphereEnvironment Spot/Preemptible fields", func() { - It("defaults Spot to false", func() { - csEnv := &gcp.CodesphereEnvironment{} - Expect(csEnv.Spot).To(BeFalse()) - }) - - It("defaults Preemptible to false", func() { - csEnv := &gcp.CodesphereEnvironment{} - Expect(csEnv.Preemptible).To(BeFalse()) - }) - - It("can set Spot independently", func() { - csEnv := &gcp.CodesphereEnvironment{Spot: true} - Expect(csEnv.Spot).To(BeTrue()) - Expect(csEnv.Preemptible).To(BeFalse()) - }) - - It("can set Preemptible independently", func() { - csEnv := &gcp.CodesphereEnvironment{Preemptible: true} - Expect(csEnv.Preemptible).To(BeTrue()) - Expect(csEnv.Spot).To(BeFalse()) - }) - }) }) diff --git a/internal/bootstrap/gcp/test_helpers_test.go b/internal/bootstrap/gcp/test_helpers_test.go index 5d9c210c..c1afe878 100644 --- a/internal/bootstrap/gcp/test_helpers_test.go +++ b/internal/bootstrap/gcp/test_helpers_test.go @@ -4,10 +4,18 @@ package gcp_test import ( + "context" "sync" "cloud.google.com/go/compute/apiv1/computepb" + "github.com/codesphere-cloud/oms/internal/bootstrap" "github.com/codesphere-cloud/oms/internal/bootstrap/gcp" + "github.com/codesphere-cloud/oms/internal/env" + "github.com/codesphere-cloud/oms/internal/installer" + "github.com/codesphere-cloud/oms/internal/installer/node" + "github.com/codesphere-cloud/oms/internal/portal" + "github.com/codesphere-cloud/oms/internal/util" + . "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/mock" "google.golang.org/api/googleapi" ) @@ -43,8 +51,8 @@ func makeStoppedInstance(internalIP, externalIP string) *computepb.Instance { } // mockGetInstanceNotFoundThenRunning sets up a GetInstance mock where the first call per VM -// returns "not found" and subsequent calls return the given running instance. -// It sets the expected total call count to 2 × numVMs. +// returns a 404 "not found" error and subsequent calls return the given running instance. +// The expected total call count is 2 × numVMs. func mockGetInstanceNotFoundThenRunning(gc *gcp.MockGCPClientManager, projectID, zone string, runningResp *computepb.Instance, numVMs int) { instanceCalls := make(map[string]int) var mu sync.Mutex @@ -58,3 +66,24 @@ func mockGetInstanceNotFoundThenRunning(gc *gcp.MockGCPClientManager, projectID, return runningResp, nil }).Times(numVMs * 2) } + +// newTestBootstrapper creates a GCPBootstrapper with the given environment and GCP client mock. +// All other dependencies use fresh mocks. +func newTestBootstrapper(csEnv *gcp.CodesphereEnvironment, gc gcp.GCPClientManager) *gcp.GCPBootstrapper { + bs, err := gcp.NewGCPBootstrapper( + context.Background(), + env.NewEnv(), + bootstrap.NewStepLogger(false), + csEnv, + installer.NewMockInstallConfigManager(GinkgoT()), + gc, + util.NewMockFileIO(GinkgoT()), + node.NewMockNodeClient(GinkgoT()), + portal.NewMockPortal(GinkgoT()), + util.NewFakeTime(), + ) + if err != nil { + panic("newTestBootstrapper: " + err.Error()) + } + return bs +} From 051249f02c383381e20cf82623f720a6351872b4 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 19 Mar 2026 11:33:36 +0000 Subject: [PATCH 28/30] chore(docs): Auto-update docs and licenses Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> --- NOTICE | 40 ++++++++++++++++++++-------------------- internal/tmpl/NOTICE | 40 ++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/NOTICE b/NOTICE index 6d4dba00..2607ce1a 100644 --- a/NOTICE +++ b/NOTICE @@ -23,9 +23,9 @@ License URL: https://github.com/googleapis/google-cloud-go/blob/auth/oauth2adapt ---------- Module: cloud.google.com/go/compute -Version: v1.56.0 +Version: v1.57.0 License: Apache-2.0 -License URL: https://github.com/googleapis/google-cloud-go/blob/compute/v1.56.0/compute/LICENSE +License URL: https://github.com/googleapis/google-cloud-go/blob/compute/v1.57.0/compute/LICENSE ---------- Module: cloud.google.com/go/compute/metadata @@ -155,9 +155,9 @@ License URL: https://github.com/cloudflare/circl/blob/v1.6.3/LICENSE ---------- Module: github.com/codesphere-cloud/cs-go -Version: v0.19.4 +Version: v0.21.1 License: Apache-2.0 -License URL: https://github.com/codesphere-cloud/cs-go/blob/v0.19.4/LICENSE +License URL: https://github.com/codesphere-cloud/cs-go/blob/v0.21.1/LICENSE ---------- Module: github.com/codesphere-cloud/oms/internal/tmpl @@ -419,9 +419,9 @@ License URL: https://github.com/googleapis/enterprise-certificate-proxy/blob/v0. ---------- Module: github.com/googleapis/gax-go/v2 -Version: v2.17.0 +Version: v2.18.0 License: BSD-3-Clause -License URL: https://github.com/googleapis/gax-go/blob/v2.17.0/v2/LICENSE +License URL: https://github.com/googleapis/gax-go/blob/v2.18.0/v2/LICENSE ---------- Module: github.com/gosuri/uitable @@ -815,9 +815,9 @@ License URL: https://cs.opensource.google/go/x/crypto/+/v0.49.0:LICENSE ---------- Module: golang.org/x/net -Version: v0.51.0 +Version: v0.52.0 License: BSD-3-Clause -License URL: https://cs.opensource.google/go/x/net/+/v0.51.0:LICENSE +License URL: https://cs.opensource.google/go/x/net/+/v0.52.0:LICENSE ---------- Module: golang.org/x/oauth2 @@ -857,39 +857,39 @@ License URL: https://cs.opensource.google/go/x/time/+/v0.15.0:LICENSE ---------- Module: google.golang.org/api -Version: v0.271.0 +Version: v0.272.0 License: BSD-3-Clause -License URL: https://github.com/googleapis/google-api-go-client/blob/v0.271.0/LICENSE +License URL: https://github.com/googleapis/google-api-go-client/blob/v0.272.0/LICENSE ---------- Module: google.golang.org/api/internal/third_party/uritemplates -Version: v0.271.0 +Version: v0.272.0 License: BSD-3-Clause -License URL: https://github.com/googleapis/google-api-go-client/blob/v0.271.0/internal/third_party/uritemplates/LICENSE +License URL: https://github.com/googleapis/google-api-go-client/blob/v0.272.0/internal/third_party/uritemplates/LICENSE ---------- Module: google.golang.org/genproto/googleapis -Version: v0.0.0-20260128011058-8636f8732409 +Version: v0.0.0-20260217215200-42d3e9bedb6d License: Apache-2.0 -License URL: https://github.com/googleapis/go-genproto/blob/8636f8732409/LICENSE +License URL: https://github.com/googleapis/go-genproto/blob/42d3e9bedb6d/LICENSE ---------- Module: google.golang.org/genproto/googleapis/api -Version: v0.0.0-20260203192932-546029d2fa20 +Version: v0.0.0-20260226221140-a57be14db171 License: Apache-2.0 -License URL: https://github.com/googleapis/go-genproto/blob/546029d2fa20/googleapis/api/LICENSE +License URL: https://github.com/googleapis/go-genproto/blob/a57be14db171/googleapis/api/LICENSE ---------- Module: google.golang.org/genproto/googleapis/rpc -Version: v0.0.0-20260226221140-a57be14db171 +Version: v0.0.0-20260311181403-84a4fc48630c License: Apache-2.0 -License URL: https://github.com/googleapis/go-genproto/blob/a57be14db171/googleapis/rpc/LICENSE +License URL: https://github.com/googleapis/go-genproto/blob/84a4fc48630c/googleapis/rpc/LICENSE ---------- Module: google.golang.org/grpc -Version: v1.79.2 +Version: v1.79.3 License: Apache-2.0 -License URL: https://github.com/grpc/grpc-go/blob/v1.79.2/LICENSE +License URL: https://github.com/grpc/grpc-go/blob/v1.79.3/LICENSE ---------- Module: google.golang.org/protobuf diff --git a/internal/tmpl/NOTICE b/internal/tmpl/NOTICE index 6d4dba00..2607ce1a 100644 --- a/internal/tmpl/NOTICE +++ b/internal/tmpl/NOTICE @@ -23,9 +23,9 @@ License URL: https://github.com/googleapis/google-cloud-go/blob/auth/oauth2adapt ---------- Module: cloud.google.com/go/compute -Version: v1.56.0 +Version: v1.57.0 License: Apache-2.0 -License URL: https://github.com/googleapis/google-cloud-go/blob/compute/v1.56.0/compute/LICENSE +License URL: https://github.com/googleapis/google-cloud-go/blob/compute/v1.57.0/compute/LICENSE ---------- Module: cloud.google.com/go/compute/metadata @@ -155,9 +155,9 @@ License URL: https://github.com/cloudflare/circl/blob/v1.6.3/LICENSE ---------- Module: github.com/codesphere-cloud/cs-go -Version: v0.19.4 +Version: v0.21.1 License: Apache-2.0 -License URL: https://github.com/codesphere-cloud/cs-go/blob/v0.19.4/LICENSE +License URL: https://github.com/codesphere-cloud/cs-go/blob/v0.21.1/LICENSE ---------- Module: github.com/codesphere-cloud/oms/internal/tmpl @@ -419,9 +419,9 @@ License URL: https://github.com/googleapis/enterprise-certificate-proxy/blob/v0. ---------- Module: github.com/googleapis/gax-go/v2 -Version: v2.17.0 +Version: v2.18.0 License: BSD-3-Clause -License URL: https://github.com/googleapis/gax-go/blob/v2.17.0/v2/LICENSE +License URL: https://github.com/googleapis/gax-go/blob/v2.18.0/v2/LICENSE ---------- Module: github.com/gosuri/uitable @@ -815,9 +815,9 @@ License URL: https://cs.opensource.google/go/x/crypto/+/v0.49.0:LICENSE ---------- Module: golang.org/x/net -Version: v0.51.0 +Version: v0.52.0 License: BSD-3-Clause -License URL: https://cs.opensource.google/go/x/net/+/v0.51.0:LICENSE +License URL: https://cs.opensource.google/go/x/net/+/v0.52.0:LICENSE ---------- Module: golang.org/x/oauth2 @@ -857,39 +857,39 @@ License URL: https://cs.opensource.google/go/x/time/+/v0.15.0:LICENSE ---------- Module: google.golang.org/api -Version: v0.271.0 +Version: v0.272.0 License: BSD-3-Clause -License URL: https://github.com/googleapis/google-api-go-client/blob/v0.271.0/LICENSE +License URL: https://github.com/googleapis/google-api-go-client/blob/v0.272.0/LICENSE ---------- Module: google.golang.org/api/internal/third_party/uritemplates -Version: v0.271.0 +Version: v0.272.0 License: BSD-3-Clause -License URL: https://github.com/googleapis/google-api-go-client/blob/v0.271.0/internal/third_party/uritemplates/LICENSE +License URL: https://github.com/googleapis/google-api-go-client/blob/v0.272.0/internal/third_party/uritemplates/LICENSE ---------- Module: google.golang.org/genproto/googleapis -Version: v0.0.0-20260128011058-8636f8732409 +Version: v0.0.0-20260217215200-42d3e9bedb6d License: Apache-2.0 -License URL: https://github.com/googleapis/go-genproto/blob/8636f8732409/LICENSE +License URL: https://github.com/googleapis/go-genproto/blob/42d3e9bedb6d/LICENSE ---------- Module: google.golang.org/genproto/googleapis/api -Version: v0.0.0-20260203192932-546029d2fa20 +Version: v0.0.0-20260226221140-a57be14db171 License: Apache-2.0 -License URL: https://github.com/googleapis/go-genproto/blob/546029d2fa20/googleapis/api/LICENSE +License URL: https://github.com/googleapis/go-genproto/blob/a57be14db171/googleapis/api/LICENSE ---------- Module: google.golang.org/genproto/googleapis/rpc -Version: v0.0.0-20260226221140-a57be14db171 +Version: v0.0.0-20260311181403-84a4fc48630c License: Apache-2.0 -License URL: https://github.com/googleapis/go-genproto/blob/a57be14db171/googleapis/rpc/LICENSE +License URL: https://github.com/googleapis/go-genproto/blob/84a4fc48630c/googleapis/rpc/LICENSE ---------- Module: google.golang.org/grpc -Version: v1.79.2 +Version: v1.79.3 License: Apache-2.0 -License URL: https://github.com/grpc/grpc-go/blob/v1.79.2/LICENSE +License URL: https://github.com/grpc/grpc-go/blob/v1.79.3/LICENSE ---------- Module: google.golang.org/protobuf From ba12703dc2e6785787824ac2cca51ae1582e34b4 Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 19 Mar 2026 15:34:55 +0100 Subject: [PATCH 29/30] fix: Correct indentation in EnsureComputeInstances test case --- internal/bootstrap/gcp/gcp_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/bootstrap/gcp/gcp_test.go b/internal/bootstrap/gcp/gcp_test.go index 4f84498f..03771180 100644 --- a/internal/bootstrap/gcp/gcp_test.go +++ b/internal/bootstrap/gcp/gcp_test.go @@ -989,7 +989,7 @@ var _ = Describe("GCP Bootstrapper", func() { }) Describe("Valid EnsureComputeInstances", func() { It("creates all instances", func() { - ipResp := makeRunningInstance("10.0.0.x", "1.2.3.x") + ipResp := makeRunningInstance("10.0.0.x", "1.2.3.x") mockGetInstanceNotFoundThenRunning(gc, csEnv.ProjectID, csEnv.Zone, ipResp, 9) fw.EXPECT().ReadFile(mock.Anything).Return([]byte("ssh-rsa AAA..."), nil).Times(9) From eca66d74ac64b09cc79dd0bf4abae20a90686aaf Mon Sep 17 00:00:00 2001 From: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:36:05 +0000 Subject: [PATCH 30/30] chore(docs): Auto-update docs and licenses Signed-off-by: OliverTrautvetter <66372584+OliverTrautvetter@users.noreply.github.com> --- NOTICE | 20 ++++++++++---------- internal/tmpl/NOTICE | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/NOTICE b/NOTICE index 2607ce1a..e1b54f8c 100644 --- a/NOTICE +++ b/NOTICE @@ -929,9 +929,9 @@ License URL: https://github.com/helm/helm/blob/v4.1.3/LICENSE ---------- Module: k8s.io/api -Version: v0.35.2 +Version: v0.35.3 License: Apache-2.0 -License URL: https://github.com/kubernetes/api/blob/v0.35.2/LICENSE +License URL: https://github.com/kubernetes/api/blob/v0.35.3/LICENSE ---------- Module: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions @@ -941,15 +941,15 @@ License URL: https://github.com/kubernetes/apiextensions-apiserver/blob/v0.35.1/ ---------- Module: k8s.io/apimachinery/pkg -Version: v0.35.2 +Version: v0.35.3 License: Apache-2.0 -License URL: https://github.com/kubernetes/apimachinery/blob/v0.35.2/LICENSE +License URL: https://github.com/kubernetes/apimachinery/blob/v0.35.3/LICENSE ---------- Module: k8s.io/apimachinery/third_party/forked/golang -Version: v0.35.2 +Version: v0.35.3 License: BSD-3-Clause -License URL: https://github.com/kubernetes/apimachinery/blob/v0.35.2/third_party/forked/golang/LICENSE +License URL: https://github.com/kubernetes/apimachinery/blob/v0.35.3/third_party/forked/golang/LICENSE ---------- Module: k8s.io/apiserver/pkg/endpoints/deprecation @@ -965,15 +965,15 @@ License URL: https://github.com/kubernetes/cli-runtime/blob/v0.35.2/LICENSE ---------- Module: k8s.io/client-go -Version: v0.35.2 +Version: v0.35.3 License: Apache-2.0 -License URL: https://github.com/kubernetes/client-go/blob/v0.35.2/LICENSE +License URL: https://github.com/kubernetes/client-go/blob/v0.35.3/LICENSE ---------- Module: k8s.io/client-go/third_party/forked/golang/template -Version: v0.35.2 +Version: v0.35.3 License: BSD-3-Clause -License URL: https://github.com/kubernetes/client-go/blob/v0.35.2/third_party/forked/golang/LICENSE +License URL: https://github.com/kubernetes/client-go/blob/v0.35.3/third_party/forked/golang/LICENSE ---------- Module: k8s.io/component-base/version diff --git a/internal/tmpl/NOTICE b/internal/tmpl/NOTICE index 2607ce1a..e1b54f8c 100644 --- a/internal/tmpl/NOTICE +++ b/internal/tmpl/NOTICE @@ -929,9 +929,9 @@ License URL: https://github.com/helm/helm/blob/v4.1.3/LICENSE ---------- Module: k8s.io/api -Version: v0.35.2 +Version: v0.35.3 License: Apache-2.0 -License URL: https://github.com/kubernetes/api/blob/v0.35.2/LICENSE +License URL: https://github.com/kubernetes/api/blob/v0.35.3/LICENSE ---------- Module: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions @@ -941,15 +941,15 @@ License URL: https://github.com/kubernetes/apiextensions-apiserver/blob/v0.35.1/ ---------- Module: k8s.io/apimachinery/pkg -Version: v0.35.2 +Version: v0.35.3 License: Apache-2.0 -License URL: https://github.com/kubernetes/apimachinery/blob/v0.35.2/LICENSE +License URL: https://github.com/kubernetes/apimachinery/blob/v0.35.3/LICENSE ---------- Module: k8s.io/apimachinery/third_party/forked/golang -Version: v0.35.2 +Version: v0.35.3 License: BSD-3-Clause -License URL: https://github.com/kubernetes/apimachinery/blob/v0.35.2/third_party/forked/golang/LICENSE +License URL: https://github.com/kubernetes/apimachinery/blob/v0.35.3/third_party/forked/golang/LICENSE ---------- Module: k8s.io/apiserver/pkg/endpoints/deprecation @@ -965,15 +965,15 @@ License URL: https://github.com/kubernetes/cli-runtime/blob/v0.35.2/LICENSE ---------- Module: k8s.io/client-go -Version: v0.35.2 +Version: v0.35.3 License: Apache-2.0 -License URL: https://github.com/kubernetes/client-go/blob/v0.35.2/LICENSE +License URL: https://github.com/kubernetes/client-go/blob/v0.35.3/LICENSE ---------- Module: k8s.io/client-go/third_party/forked/golang/template -Version: v0.35.2 +Version: v0.35.3 License: BSD-3-Clause -License URL: https://github.com/kubernetes/client-go/blob/v0.35.2/third_party/forked/golang/LICENSE +License URL: https://github.com/kubernetes/client-go/blob/v0.35.3/third_party/forked/golang/LICENSE ---------- Module: k8s.io/component-base/version