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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ endif
# Image URL to use all building/pushing image targets
IMAGE_NAME := cluster-api-provider-maas-controller
REGISTRY ?= "us-east1-docker.pkg.dev/spectro-images/dev/${USER}/cluster-api"
SPECTRO_VERSION ?= 4.8.3-dev-12112025
SPECTRO_VERSION ?= storage-overcommit-prevention-20260506
IMG_TAG ?= v0.6.1-spectro-${SPECTRO_VERSION}
CONTROLLER_IMG ?= ${REGISTRY}/${IMAGE_NAME}

Expand Down
6 changes: 6 additions & 0 deletions api/v1beta1/maasmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ type VMConfig struct {
// +optional
Network string `json:"network,omitempty"`

// InterfaceLinkModes sets the MAAS link mode per interface (e.g. eth0, eth1, eth2).
// Keys are interface names ("eth0", "eth1", ...); values: "auto", "dhcp", "static", "link_up".
// When unset for an interface: eth0 defaults to "auto", others to "dhcp". Extensible for future interfaces.
// +optional
InterfaceLinkModes map[string]string `json:"interfaceLinkModes,omitempty"`

// AutoStart specifies whether the VM should automatically start
// +kubebuilder:default=true
// +optional
Expand Down
12 changes: 12 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions controllers/maasmachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,12 +439,14 @@ func (r *MaasMachineReconciler) reconcileNormal(ctx context.Context, machineScop
// TODO(saamalik) confirm that we'll never "recreate" a m; e.g: findMachine should always return err
// if there used to be a m
if m == nil || !(m.State == infrav1beta1.MachineStateDeployed || m.State == infrav1beta1.MachineStateDeploying) {
// If machine is in Ready state, verify network interfaces before deploying
// This ensures correct subnet assignment before deployment starts
if m != nil && m.State == infrav1beta1.MachineStateReady && machineScope.GetDynamicLXD() {
machineScope.Info("Machine is in Ready state, verifying network interfaces before deployment", "machineID", m.ID)
// If machine is in Ready or Allocated state, verify network interfaces before deploying.
// This ensures correct subnet assignment before deployment starts (avoids wrong eth0 subnet
// on 2nd VM when MAAS compose links eth0 to a different subnet than requested).
if m != nil && machineScope.GetDynamicLXD() &&
(m.State == infrav1beta1.MachineStateReady || m.State == infrav1beta1.MachineStateAllocated) {
machineScope.Info("Verifying VM network interfaces before deployment", "machineID", m.ID, "state", m.State)
if err := machineSvc.VerifyVMNetworkInterfaces(ctx, m.ID); err != nil {
machineScope.Error(err, "Failed to verify VM network interfaces in Ready state, requeuing", "machineID", m.ID)
machineScope.Error(err, "Failed to verify VM network interfaces before deploy, requeuing", "machineID", m.ID)
conditions.MarkFalse(machineScope.MaasMachine, infrav1beta1.MachineDeployedCondition, infrav1beta1.MachineDeployingReason, clusterv1.ConditionSeverityWarning, "verifying network interfaces")
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
}
Expand Down Expand Up @@ -502,14 +504,14 @@ func (r *MaasMachineReconciler) reconcileNormal(ctx context.Context, machineScop
}

switch s := m.State; {
case s == infrav1beta1.MachineStateReady:
case s == infrav1beta1.MachineStateReady, s == infrav1beta1.MachineStateAllocated:
machineScope.SetNotReady()
conditions.MarkFalse(machineScope.MaasMachine, infrav1beta1.MachineDeployedCondition, infrav1beta1.MachineDeployingReason, clusterv1.ConditionSeverityWarning, "")
// Note: Network interface verification happens before deployment is triggered (see above).
// This is a safety check in case the machine reached Ready state through a different path.
// This is a safety check in case the machine reached Ready/Allocated through a different path.
if machineScope.GetDynamicLXD() {
if err := machineSvc.VerifyVMNetworkInterfaces(ctx, m.ID); err != nil {
machineScope.Error(err, "Failed to verify VM network interfaces in Ready state (safety check)", "machineID", m.ID)
machineScope.Error(err, "Failed to verify VM network interfaces (safety check)", "machineID", m.ID, "state", s)
// Requeue to retry verification - deployment should not proceed until interfaces are correct
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
}
Expand All @@ -534,7 +536,7 @@ func (r *MaasMachineReconciler) reconcileNormal(ctx context.Context, machineScop
machineScope.SetNotReady()
machineScope.Info("Machine is powered off!")
conditions.MarkFalse(machineScope.MaasMachine, infrav1beta1.MachineDeployedCondition, infrav1beta1.MachinePoweredOffReason, clusterv1.ConditionSeverityWarning, "")
case s == infrav1beta1.MachineStateDeploying, s == infrav1beta1.MachineStateAllocated:
case s == infrav1beta1.MachineStateDeploying:
machineScope.SetNotReady()
conditions.MarkFalse(machineScope.MaasMachine, infrav1beta1.MachineDeployedCondition, infrav1beta1.MachineDeployingReason, clusterv1.ConditionSeverityWarning, "")
case s == infrav1beta1.MachineStateDeployed:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.36.3
github.com/pkg/errors v0.9.1
github.com/spectrocloud/maas-client-go v0.1.4-beta1
github.com/spectrocloud/maas-client-go v0.1.7-beta1
github.com/spf13/pflag v1.0.6
k8s.io/api v0.32.3
k8s.io/apiextensions-apiserver v0.32.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/spectrocloud/maas-client-go v0.1.4-beta1 h1:adYeve0oaYjiPuNnogMzw8LN9VenQK/iwNOO74H4lKE=
github.com/spectrocloud/maas-client-go v0.1.4-beta1/go.mod h1:LSxLlmaNCmkaldtysbp7Beq/O2wptBb6qE5iKj+Y7Lw=
github.com/spectrocloud/maas-client-go v0.1.7-beta1 h1:j5NtaNPTxoh2PxhKTJYpZUeJukWy4vC7xT2yy+1syDk=
github.com/spectrocloud/maas-client-go v0.1.7-beta1/go.mod h1:LSxLlmaNCmkaldtysbp7Beq/O2wptBb6qE5iKj+Y7Lw=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
Expand Down
224 changes: 224 additions & 0 deletions pkg/maas/client/mock/clienset_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/maas/dns/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ func (f *fakeClientSet) Users() maasclient.Users { retur
func (f *fakeClientSet) Zones() maasclient.Zones { return nil }
func (f *fakeClientSet) SSHKeys() maasclient.SSHKeys { return nil }
func (f *fakeClientSet) VMHosts() maasclient.VMHosts { return nil }
func (f *fakeClientSet) IPRanges() maasclient.IPRanges { return nil }
func (f *fakeClientSet) Subnets() maasclient.Subnets { return nil }

// fakeIPAddress satisfies maasclient.IPAddress for tests
type fakeIPAddress struct{ ip net.IP }
Expand Down
Loading