Skip to content

Commit 038f604

Browse files
committed
Add Disabled field to VM bootstrap
Add a new Disabled field to the VirtualMachineBootstrapSpec to allow skipping bootstrap customization. When set to true, the VM will not be bootstrapped even if a provider (CloudInit, LinuxPrep, Sysprep, VAppConfig) is specified. This is useful for deferring bootstrap or when the guest is already configured.
1 parent 95bfd85 commit 038f604

File tree

11 files changed

+209
-32
lines changed

11 files changed

+209
-32
lines changed

api/test/v1alpha1/virtualmachine_conversion_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,36 @@ func TestVirtualMachineConversion(t *testing.T) {
730730
hubSpokeHub(g, &hub, &vmopv1a1.VirtualMachine{})
731731
})
732732

733+
t.Run("VirtualMachine hub-spoke-hub with bootstrap disabled", func(t *testing.T) {
734+
g := NewWithT(t)
735+
hub := vmopv1.VirtualMachine{
736+
Spec: vmopv1.VirtualMachineSpec{
737+
Bootstrap: &vmopv1.VirtualMachineBootstrapSpec{
738+
Disabled: true,
739+
},
740+
},
741+
}
742+
hubSpokeHub(g, &hub, &vmopv1a1.VirtualMachine{})
743+
})
744+
745+
t.Run("VirtualMachine hub-spoke-hub with CloudInit and bootstrap disabled ", func(t *testing.T) {
746+
g := NewWithT(t)
747+
hub := vmopv1.VirtualMachine{
748+
Spec: vmopv1.VirtualMachineSpec{
749+
Bootstrap: &vmopv1.VirtualMachineBootstrapSpec{
750+
CloudInit: &vmopv1.VirtualMachineBootstrapCloudInitSpec{
751+
RawCloudConfig: &vmopv1common.SecretKeySelector{
752+
Name: "my-secret",
753+
Key: "user-data",
754+
},
755+
},
756+
Disabled: true,
757+
},
758+
},
759+
}
760+
hubSpokeHub(g, &hub, &vmopv1a1.VirtualMachine{})
761+
})
762+
733763
t.Run("VirtualMachine hub-spoke Status", func(t *testing.T) {
734764
g := NewWithT(t)
735765

api/test/v1alpha2/virtualmachine_conversion_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,36 @@ func TestVirtualMachineConversion(t *testing.T) {
679679
hubSpokeHub(g, &hub2, &vmopv1.VirtualMachine{}, &vmopv1a2.VirtualMachine{})
680680
})
681681

682+
t.Run("VirtualMachine hub-spoke-hub with bootstrap disabled", func(t *testing.T) {
683+
g := NewWithT(t)
684+
hub := vmopv1.VirtualMachine{
685+
Spec: vmopv1.VirtualMachineSpec{
686+
Bootstrap: &vmopv1.VirtualMachineBootstrapSpec{
687+
Disabled: true,
688+
},
689+
},
690+
}
691+
hubSpokeHub(g, &hub, &vmopv1.VirtualMachine{}, &vmopv1a2.VirtualMachine{})
692+
})
693+
694+
t.Run("VirtualMachine hub-spoke-hub with CloudInit and bootstrap disabled ", func(t *testing.T) {
695+
g := NewWithT(t)
696+
hub := vmopv1.VirtualMachine{
697+
Spec: vmopv1.VirtualMachineSpec{
698+
Bootstrap: &vmopv1.VirtualMachineBootstrapSpec{
699+
CloudInit: &vmopv1.VirtualMachineBootstrapCloudInitSpec{
700+
RawCloudConfig: &vmopv1common.SecretKeySelector{
701+
Name: "my-secret",
702+
Key: "user-data",
703+
},
704+
},
705+
Disabled: true,
706+
},
707+
},
708+
}
709+
hubSpokeHub(g, &hub, &vmopv1.VirtualMachine{}, &vmopv1a2.VirtualMachine{})
710+
})
711+
682712
t.Run("VirtualMachine and spec.network.domainName", func(t *testing.T) {
683713

684714
const (

api/test/v1alpha3/virtualmachine_conversion_test.go

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ func TestVirtualMachineConversion(t *testing.T) {
120120
},
121121
RawProperties: "my-secret",
122122
},
123+
Disabled: true,
123124
},
124125
Network: &vmopv1.VirtualMachineNetworkSpec{
125126
DomainName: "my-domain.com",
@@ -382,22 +383,24 @@ func TestVirtualMachineConversion(t *testing.T) {
382383
},
383384
},
384385
{
385-
name: "spec.bootstrap.cloudInit.waitOnNetwork4",
386+
name: "spec.bootstrap.disabled",
386387
hub: &vmopv1.VirtualMachine{
387388
Spec: vmopv1.VirtualMachineSpec{
388389
Bootstrap: &vmopv1.VirtualMachineBootstrapSpec{
389-
CloudInit: &vmopv1.VirtualMachineBootstrapCloudInitSpec{
390-
WaitOnNetwork4: ptrOf(true),
391-
},
390+
Disabled: true,
392391
},
393392
},
394393
},
395394
},
396395
{
397-
name: "spec.groupName",
396+
name: "spec.bootstrap.cloudInit.waitOnNetwork4",
398397
hub: &vmopv1.VirtualMachine{
399398
Spec: vmopv1.VirtualMachineSpec{
400-
GroupName: "my-group",
399+
Bootstrap: &vmopv1.VirtualMachineBootstrapSpec{
400+
CloudInit: &vmopv1.VirtualMachineBootstrapCloudInitSpec{
401+
WaitOnNetwork4: ptrOf(true),
402+
},
403+
},
401404
},
402405
},
403406
},
@@ -410,28 +413,21 @@ func TestVirtualMachineConversion(t *testing.T) {
410413
WaitOnNetwork6: ptrOf(true),
411414
},
412415
},
413-
PromoteDisksMode: vmopv1.VirtualMachinePromoteDisksModeOffline,
414-
BootOptions: &vmopv1.VirtualMachineBootOptions{
415-
Firmware: vmopv1.VirtualMachineBootOptionsFirmwareTypeEFI,
416-
BootDelay: &metav1.Duration{Duration: time.Second * 10},
417-
BootOrder: []vmopv1.VirtualMachineBootOptionsBootableDevice{
418-
{
419-
Type: vmopv1.VirtualMachineBootOptionsBootableDiskDevice,
420-
Name: "disk-0",
421-
},
422-
{
423-
Type: vmopv1.VirtualMachineBootOptionsBootableNetworkDevice,
424-
Name: "eth0",
425-
},
426-
{
427-
Type: vmopv1.VirtualMachineBootOptionsBootableCDRomDevice,
428-
},
429-
},
430-
BootRetry: vmopv1.VirtualMachineBootOptionsBootRetryDisabled,
431-
BootRetryDelay: &metav1.Duration{Duration: time.Second * 10},
432-
EFISecureBoot: vmopv1.VirtualMachineBootOptionsEFISecureBootDisabled,
433-
NetworkBootProtocol: vmopv1.VirtualMachineBootOptionsNetworkBootProtocolIP4,
434-
},
416+
},
417+
},
418+
},
419+
{
420+
name: "spec.groupName",
421+
hub: &vmopv1.VirtualMachine{
422+
Spec: vmopv1.VirtualMachineSpec{
423+
GroupName: "my-group",
424+
},
425+
},
426+
},
427+
{
428+
name: "spec.affinity",
429+
hub: &vmopv1.VirtualMachine{
430+
Spec: vmopv1.VirtualMachineSpec{
435431
Affinity: &vmopv1.AffinitySpec{
436432
VMAffinity: &vmopv1.VMAffinitySpec{
437433
RequiredDuringSchedulingPreferredDuringExecution: []vmopv1.VMAffinityTerm{

api/test/v1alpha4/virtualmachine_conversion_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ func TestVirtualMachineConversion(t *testing.T) {
120120
},
121121
RawProperties: "my-secret",
122122
},
123+
Disabled: true,
123124
},
124125
Network: &vmopv1.VirtualMachineNetworkSpec{
125126
DomainName: "my-domain.com",
@@ -327,6 +328,16 @@ func TestVirtualMachineConversion(t *testing.T) {
327328
},
328329
},
329330
},
331+
{
332+
name: "spec.bootstrap.disabled",
333+
hub: &vmopv1.VirtualMachine{
334+
Spec: vmopv1.VirtualMachineSpec{
335+
Bootstrap: &vmopv1.VirtualMachineBootstrapSpec{
336+
Disabled: true,
337+
},
338+
},
339+
},
340+
},
330341
{
331342
name: "spec.affinity",
332343
hub: &vmopv1.VirtualMachine{

api/v1alpha1/virtualmachine_conversion.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -842,12 +842,13 @@ func restore_v1alpha5_VirtualMachineBootstrapSpec(
842842

843843
dstBootstrap := dst.Spec.Bootstrap
844844
if dstBootstrap == nil {
845-
// v1a1 doesn't have a way to represent standalone LinuxPrep. If we didn't do a
846-
// conversion in convert_v1alpha1_VmMetadata_To_v1alpha5_BootstrapSpec() but we
847-
// saved a LinuxPrep in the conversion annotation, restore that here.
848-
if srcBootstrap.LinuxPrep != nil {
845+
// v1a1 doesn't have a way to represent standalone LinuxPrep or Disabled.
846+
// If we didn't do a conversion in convert_v1alpha1_VmMetadata_To_v1alpha5_BootstrapSpec()
847+
// but we saved a LinuxPrep or Disabled in the conversion annotation, restore that here.
848+
if srcBootstrap.LinuxPrep != nil || srcBootstrap.Disabled {
849849
dst.Spec.Bootstrap = &vmopv1.VirtualMachineBootstrapSpec{
850850
LinuxPrep: srcBootstrap.LinuxPrep,
851+
Disabled: srcBootstrap.Disabled,
851852
}
852853
}
853854
return
@@ -907,6 +908,8 @@ func restore_v1alpha5_VirtualMachineBootstrapSpec(
907908
dstVAppConfig.RawProperties = srcVAppConfig.RawProperties
908909
}
909910
}
911+
912+
dstBootstrap.Disabled = srcBootstrap.Disabled
910913
}
911914

912915
func restore_v1alpha5_VirtualMachineNetworkSpec(

api/v1alpha2/virtualmachine_conversion.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,17 @@ func restore_v1alpha5_VirtualMachineBootstrapSysprep(dst, src *vmopv1.VirtualMac
347347
}
348348
}
349349

350+
func restore_v1alpha5_VirtualMachineBootstrapDisabled(dst, src *vmopv1.VirtualMachine) {
351+
if bs := src.Spec.Bootstrap; bs != nil {
352+
if bs.Disabled {
353+
if dst.Spec.Bootstrap == nil {
354+
dst.Spec.Bootstrap = &vmopv1.VirtualMachineBootstrapSpec{}
355+
}
356+
dst.Spec.Bootstrap.Disabled = true
357+
}
358+
}
359+
}
360+
350361
func restore_v1alpha5_VirtualMachineGuestID(dst, src *vmopv1.VirtualMachine) {
351362
dst.Spec.GuestID = src.Spec.GuestID
352363
}
@@ -427,6 +438,7 @@ func (src *VirtualMachine) ConvertTo(dstRaw ctrlconversion.Hub) error {
427438
restore_v1alpha5_VirtualMachineBootstrapCloudInitWaitOnNetwork(dst, restored)
428439
restore_v1alpha5_VirtualMachineBootstrapLinuxPrep(dst, restored)
429440
restore_v1alpha5_VirtualMachineBootstrapSysprep(dst, restored)
441+
restore_v1alpha5_VirtualMachineBootstrapDisabled(dst, restored)
430442
restore_v1alpha5_VirtualMachineSpecNetworkDomainName(dst, restored)
431443
restore_v1alpha5_VirtualMachineGuestID(dst, restored)
432444
restore_v1alpha5_VirtualMachinePromoteDisksMode(dst, restored)

api/v1alpha3/virtualmachine_conversion.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,17 @@ func restore_v1alpha5_VirtualMachineBootstrapSysprep(dst, src *vmopv1.VirtualMac
325325
}
326326
}
327327

328+
func restore_v1alpha5_VirtualMachineBootstrapDisabled(dst, src *vmopv1.VirtualMachine) {
329+
if bs := src.Spec.Bootstrap; bs != nil {
330+
if bs.Disabled {
331+
if dst.Spec.Bootstrap == nil {
332+
dst.Spec.Bootstrap = &vmopv1.VirtualMachineBootstrapSpec{}
333+
}
334+
dst.Spec.Bootstrap.Disabled = true
335+
}
336+
}
337+
}
338+
328339
func restore_v1alpha5_VirtualMachinePolicies(dst, src *vmopv1.VirtualMachine) {
329340
dst.Spec.Policies = slices.Clone(src.Spec.Policies)
330341
}
@@ -361,6 +372,7 @@ func (src *VirtualMachine) ConvertTo(dstRaw ctrlconversion.Hub) error {
361372
restore_v1alpha5_VirtualMachineBootstrapCloudInitWaitOnNetwork(dst, restored)
362373
restore_v1alpha5_VirtualMachineBootstrapLinuxPrep(dst, restored)
363374
restore_v1alpha5_VirtualMachineBootstrapSysprep(dst, restored)
375+
restore_v1alpha5_VirtualMachineBootstrapDisabled(dst, restored)
364376
restore_v1alpha5_VirtualMachinePromoteDisksMode(dst, restored)
365377
restore_v1alpha5_VirtualMachineBootOptions(dst, restored)
366378
restore_v1alpha5_VirtualMachineVolumes(dst, restored)

api/v1alpha4/virtualmachine_conversion.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,17 @@ func restore_v1alpha5_VirtualMachineBootstrapSysprep(dst, src *vmopv1.VirtualMac
269269
}
270270
}
271271

272+
func restore_v1alpha5_VirtualMachineBootstrapDisabled(dst, src *vmopv1.VirtualMachine) {
273+
if bs := src.Spec.Bootstrap; bs != nil {
274+
if bs.Disabled {
275+
if dst.Spec.Bootstrap == nil {
276+
dst.Spec.Bootstrap = &vmopv1.VirtualMachineBootstrapSpec{}
277+
}
278+
dst.Spec.Bootstrap.Disabled = true
279+
}
280+
}
281+
}
282+
272283
func restore_v1alpha5_VirtualMachineAffinity(dst, src *vmopv1.VirtualMachine) {
273284
if src.Spec.Affinity == nil {
274285
dst.Spec.Affinity = nil
@@ -319,6 +330,7 @@ func (src *VirtualMachine) ConvertTo(dstRaw ctrlconversion.Hub) error {
319330
restore_v1alpha5_VirtualMachineBootstrapCloudInitWaitOnNetwork(dst, restored)
320331
restore_v1alpha5_VirtualMachineBootstrapLinuxPrep(dst, restored)
321332
restore_v1alpha5_VirtualMachineBootstrapSysprep(dst, restored)
333+
restore_v1alpha5_VirtualMachineBootstrapDisabled(dst, restored)
322334
restore_v1alpha5_VirtualMachineAffinity(dst, restored)
323335
restore_v1alpha5_VirtualMachineVolumes(dst, restored)
324336

api/v1alpha5/virtualmachine_bootstrap_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ type VirtualMachineBootstrapSpec struct {
8181
// This bootstrap provider may not be used in conjunction with the CloudInit
8282
// bootstrap provider.
8383
VAppConfig *VirtualMachineBootstrapVAppConfigSpec `json:"vAppConfig,omitempty"`
84+
85+
// +optional
86+
87+
// Disabled is a flag that indicates whether or not to disable bootstrap
88+
// for this VM.
89+
//
90+
// When set to true, the bootstrap customization is not applied to the VM,
91+
// even if a bootstrap provider such as CloudInit, LinuxPrep, Sysprep, or
92+
// VAppConfig is specified.
93+
Disabled bool `json:"disabled,omitempty"`
8494
}
8595

8696
// VirtualMachineBootstrapCloudInitSpec describes the CloudInit configuration

pkg/providers/vsphere/vmlifecycle/bootstrap.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ func DoBootstrap(
105105
}
106106
}
107107

108+
if bootstrap.Disabled {
109+
vmCtx.Logger.Info("Skipping bootstrap since disabled")
110+
return nil
111+
}
112+
108113
var (
109114
cloudInit = bootstrap.CloudInit
110115
linuxPrep = bootstrap.LinuxPrep

0 commit comments

Comments
 (0)