Skip to content

Commit 813c7d4

Browse files
committed
Add Disabled field to VM bootstrap
Add Disabled field to the VirtualMachineBootstrapSpec to allow skipping bootstrap customization. When true, the VM will not be bootstrapped even if a provider (CloudInit, LinuxPrep, Sysprep, VAppConfig) is specified. This is useful for either disabling the implicit LinuxPrep customization we do on Linux images for historical reasons, or deferring bootstrap when the guest is already configured.
1 parent 95bfd85 commit 813c7d4

File tree

11 files changed

+210
-33
lines changed

11 files changed

+210
-33
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: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ var (
7373
ErrBootstrapCustomize = pkgerr.NoRequeueNoErr("bootstrap customized vm")
7474
)
7575

76-
func DoBootstrap(
76+
func DoBootstrap( //nolint:gocyclo
7777
vmCtx pkgctx.VirtualMachineContext,
7878
vcVM *object.VirtualMachine,
7979
config *vimtypes.VirtualMachineConfigInfo,
@@ -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)