@@ -23,6 +23,7 @@ import (
2323 "strings"
2424 "time"
2525
26+ "github.com/spectrocloud/maas-client-go/maasclient"
2627 "k8s.io/apimachinery/pkg/runtime"
2728
2829 "github.com/go-logr/logr"
@@ -225,6 +226,32 @@ func (r *MaasMachineReconciler) reconcileDelete(_ context.Context, machineScope
225226 // If MAAS requires VM host removal first, attempt best-effort unregister and retry once
226227 if isVMHostRemovalRequiredError (err ) {
227228 api := clusterScope .GetMaasClientIdentity ()
229+
230+ // For control-plane BM that backs an LXD VM host, force-delete guest VMs to unblock release
231+ if clusterScope .IsLXDHostEnabled () && machineScope .IsControlPlane () {
232+ ctx := context .Background ()
233+ client := maasclient .NewAuthenticatedClientSet (api .URL , api .Token )
234+ if hosts , herr := client .VMHosts ().List (ctx , nil ); herr == nil {
235+ for _ , h := range hosts {
236+ if h .HostSystemID () == m .ID {
237+ if guests , gerr := h .Machines ().List (ctx ); gerr == nil {
238+ for _ , g := range guests {
239+ gid := g .SystemID ()
240+ if gid == "" {
241+ continue
242+ }
243+ // Fetch details to confirm and delete
244+ if gm , ge := client .Machines ().Machine (gid ).Get (ctx ); ge == nil {
245+ _ = client .Machines ().Machine (gm .SystemID ()).Delete (ctx )
246+ }
247+ }
248+ }
249+ break
250+ }
251+ }
252+ }
253+ }
254+
228255 // choose ExternalIP first, then InternalIP
229256 nodeIP := getNodeIP (m .Addresses )
230257 if nodeIP != "" {
0 commit comments