Skip to content

Commit 8cb606b

Browse files
authored
Merge pull request #5509 from willie-yao/improve-bootstrap-extension-logs
Add flag to disable bootstrap extension and improve error message
2 parents 8a1f692 + b0f3689 commit 8cb606b

File tree

9 files changed

+157
-58
lines changed

9 files changed

+157
-58
lines changed

api/v1beta1/azuremachine_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ type AzureMachineSpec struct {
137137
// +optional
138138
DisableExtensionOperations *bool `json:"disableExtensionOperations,omitempty"`
139139

140+
// DisableVMBootstrapExtension specifies whether the VM bootstrap extension should be disabled on the virtual machine.
141+
// Use this setting if you want to disable only the bootstrapping extension and not all extensions.
142+
// +optional
143+
DisableVMBootstrapExtension *bool `json:"disableVMBootstrapExtension,omitempty"`
144+
140145
// VMExtensions specifies a list of extensions to be added to the virtual machine.
141146
// +optional
142147
VMExtensions []VMExtension `json:"vmExtensions,omitempty"`

api/v1beta1/azuremachine_webhook.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,13 @@ func (mw *azureMachineWebhook) ValidateUpdate(_ context.Context, oldObj, newObj
221221
allErrs = append(allErrs, err)
222222
}
223223

224+
if err := webhookutils.ValidateImmutable(
225+
field.NewPath("spec", "disableVMBootstrapExtension"),
226+
old.Spec.DisableVMBootstrapExtension,
227+
m.Spec.DisableVMBootstrapExtension); err != nil {
228+
allErrs = append(allErrs, err)
229+
}
230+
224231
if len(allErrs) == 0 {
225232
return nil, nil
226233
}

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

azure/defaults.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ const (
111111

112112
var (
113113
// LinuxBootstrapExtensionCommand is the command the VM bootstrap extension will execute to verify Linux nodes bootstrap completes successfully.
114-
LinuxBootstrapExtensionCommand = fmt.Sprintf("for i in $(seq 1 %d); do test -f %s && break; if [ $i -eq %d ]; then exit 1; else sleep %d; fi; done", bootstrapExtensionRetries, bootstrapSentinelFile, bootstrapExtensionRetries, bootstrapExtensionSleep)
114+
LinuxBootstrapExtensionCommand = fmt.Sprintf("for i in $(seq 1 %d); do test -f %s && break; if [ $i -eq %d ]; then echo 'Error joining node to cluster: kubeadm init or join failed. To debug, check the cloud-init, kubelet, or other bootstrap logs: https://capz.sigs.k8s.io/self-managed/troubleshooting.html#checking-cloud-init-logs-ubuntu'; exit 1; else sleep %d; fi; done", bootstrapExtensionRetries, bootstrapSentinelFile, bootstrapExtensionRetries, bootstrapExtensionSleep)
115115
// WindowsBootstrapExtensionCommand is the command the VM bootstrap extension will execute to verify Windows nodes bootstrap completes successfully.
116116
WindowsBootstrapExtensionCommand = fmt.Sprintf("powershell.exe -Command \"for ($i = 0; $i -lt %d; $i++) {if (Test-Path '%s') {exit 0} else {Start-Sleep -Seconds %d}} exit -2\"",
117117
bootstrapExtensionRetries, bootstrapSentinelFile, bootstrapExtensionSleep)

azure/scope/machine.go

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -161,29 +161,30 @@ func (m *MachineScope) InitMachineCache(ctx context.Context) error {
161161
// VMSpec returns the VM spec.
162162
func (m *MachineScope) VMSpec() azure.ResourceSpecGetter {
163163
spec := &virtualmachines.VMSpec{
164-
Name: m.Name(),
165-
Location: m.Location(),
166-
ExtendedLocation: m.ExtendedLocation(),
167-
ResourceGroup: m.NodeResourceGroup(),
168-
ClusterName: m.ClusterName(),
169-
Role: m.Role(),
170-
NICIDs: m.NICIDs(),
171-
SSHKeyData: m.AzureMachine.Spec.SSHPublicKey,
172-
Size: m.AzureMachine.Spec.VMSize,
173-
OSDisk: m.AzureMachine.Spec.OSDisk,
174-
DataDisks: m.AzureMachine.Spec.DataDisks,
175-
AvailabilitySetID: m.AvailabilitySetID(),
176-
Zone: m.AvailabilityZone(),
177-
Identity: m.AzureMachine.Spec.Identity,
178-
UserAssignedIdentities: m.AzureMachine.Spec.UserAssignedIdentities,
179-
SpotVMOptions: m.AzureMachine.Spec.SpotVMOptions,
180-
SecurityProfile: m.AzureMachine.Spec.SecurityProfile,
181-
DiagnosticsProfile: m.AzureMachine.Spec.Diagnostics,
182-
DisableExtensionOperations: ptr.Deref(m.AzureMachine.Spec.DisableExtensionOperations, false),
183-
AdditionalTags: m.AdditionalTags(),
184-
AdditionalCapabilities: m.AzureMachine.Spec.AdditionalCapabilities,
185-
CapacityReservationGroupID: m.GetCapacityReservationGroupID(),
186-
ProviderID: m.ProviderID(),
164+
Name: m.Name(),
165+
Location: m.Location(),
166+
ExtendedLocation: m.ExtendedLocation(),
167+
ResourceGroup: m.NodeResourceGroup(),
168+
ClusterName: m.ClusterName(),
169+
Role: m.Role(),
170+
NICIDs: m.NICIDs(),
171+
SSHKeyData: m.AzureMachine.Spec.SSHPublicKey,
172+
Size: m.AzureMachine.Spec.VMSize,
173+
OSDisk: m.AzureMachine.Spec.OSDisk,
174+
DataDisks: m.AzureMachine.Spec.DataDisks,
175+
AvailabilitySetID: m.AvailabilitySetID(),
176+
Zone: m.AvailabilityZone(),
177+
Identity: m.AzureMachine.Spec.Identity,
178+
UserAssignedIdentities: m.AzureMachine.Spec.UserAssignedIdentities,
179+
SpotVMOptions: m.AzureMachine.Spec.SpotVMOptions,
180+
SecurityProfile: m.AzureMachine.Spec.SecurityProfile,
181+
DiagnosticsProfile: m.AzureMachine.Spec.Diagnostics,
182+
DisableExtensionOperations: ptr.Deref(m.AzureMachine.Spec.DisableExtensionOperations, false),
183+
DisableVMBootstrapExtension: ptr.Deref(m.AzureMachine.Spec.DisableVMBootstrapExtension, false),
184+
AdditionalTags: m.AdditionalTags(),
185+
AdditionalCapabilities: m.AzureMachine.Spec.AdditionalCapabilities,
186+
CapacityReservationGroupID: m.GetCapacityReservationGroupID(),
187+
ProviderID: m.ProviderID(),
187188
}
188189
if m.cache != nil {
189190
spec.SKU = m.cache.VMSKU
@@ -400,15 +401,17 @@ func (m *MachineScope) VMExtensionSpecs() []azure.ResourceSpecGetter {
400401
})
401402
}
402403

403-
cpuArchitectureType, _ := m.cache.VMSKU.GetCapability(resourceskus.CPUArchitectureType)
404-
bootstrapExtensionSpec := azure.GetBootstrappingVMExtension(m.AzureMachine.Spec.OSDisk.OSType, m.CloudEnvironment(), m.Name(), cpuArchitectureType)
404+
if !ptr.Deref(m.AzureMachine.Spec.DisableVMBootstrapExtension, false) {
405+
cpuArchitectureType, _ := m.cache.VMSKU.GetCapability(resourceskus.CPUArchitectureType)
406+
bootstrapExtensionSpec := azure.GetBootstrappingVMExtension(m.AzureMachine.Spec.OSDisk.OSType, m.CloudEnvironment(), m.Name(), cpuArchitectureType)
405407

406-
if bootstrapExtensionSpec != nil {
407-
extensionSpecs = append(extensionSpecs, &vmextensions.VMExtensionSpec{
408-
ExtensionSpec: *bootstrapExtensionSpec,
409-
ResourceGroup: m.NodeResourceGroup(),
410-
Location: m.Location(),
411-
})
408+
if bootstrapExtensionSpec != nil {
409+
extensionSpecs = append(extensionSpecs, &vmextensions.VMExtensionSpec{
410+
ExtensionSpec: *bootstrapExtensionSpec,
411+
ResourceGroup: m.NodeResourceGroup(),
412+
Location: m.Location(),
413+
})
414+
}
412415
}
413416

414417
return extensionSpecs

azure/scope/machine_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,74 @@ func TestMachineScope_VMExtensionSpecs(t *testing.T) {
917917
},
918918
},
919919
},
920+
{
921+
name: "If a custom VM extension is specified and bootstrap extension is disabled, it returns only the custom VM extension",
922+
machineScope: MachineScope{
923+
Machine: &clusterv1.Machine{},
924+
AzureMachine: &infrav1.AzureMachine{
925+
ObjectMeta: metav1.ObjectMeta{
926+
Name: "machine-name",
927+
},
928+
Spec: infrav1.AzureMachineSpec{
929+
OSDisk: infrav1.OSDisk{
930+
OSType: "Linux",
931+
},
932+
DisableVMBootstrapExtension: ptr.To(true),
933+
VMExtensions: []infrav1.VMExtension{
934+
{
935+
Name: "custom-vm-extension",
936+
Publisher: "Microsoft.Azure.Extensions",
937+
Version: "2.0",
938+
Settings: map[string]string{
939+
"timestamp": "1234567890",
940+
},
941+
ProtectedSettings: map[string]string{
942+
"commandToExecute": "echo hello world",
943+
},
944+
},
945+
},
946+
},
947+
},
948+
ClusterScoper: &ClusterScope{
949+
AzureClients: AzureClients{
950+
EnvironmentSettings: auth.EnvironmentSettings{
951+
Environment: azureautorest.Environment{
952+
Name: azureautorest.PublicCloud.Name,
953+
},
954+
},
955+
},
956+
AzureCluster: &infrav1.AzureCluster{
957+
Spec: infrav1.AzureClusterSpec{
958+
ResourceGroup: "my-rg",
959+
AzureClusterClassSpec: infrav1.AzureClusterClassSpec{
960+
Location: "westus",
961+
},
962+
},
963+
},
964+
},
965+
cache: &MachineCache{
966+
VMSKU: resourceskus.SKU{},
967+
},
968+
},
969+
want: []azure.ResourceSpecGetter{
970+
&vmextensions.VMExtensionSpec{
971+
ExtensionSpec: azure.ExtensionSpec{
972+
Name: "custom-vm-extension",
973+
VMName: "machine-name",
974+
Publisher: "Microsoft.Azure.Extensions",
975+
Version: "2.0",
976+
Settings: map[string]string{
977+
"timestamp": "1234567890",
978+
},
979+
ProtectedSettings: map[string]string{
980+
"commandToExecute": "echo hello world",
981+
},
982+
},
983+
ResourceGroup: "my-rg",
984+
Location: "westus",
985+
},
986+
},
987+
},
920988
}
921989
for _, tt := range tests {
922990
t.Run(tt.name, func(t *testing.T) {

azure/services/virtualmachines/spec.go

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,32 +34,33 @@ import (
3434

3535
// VMSpec defines the specification for a Virtual Machine.
3636
type VMSpec struct {
37-
Name string
38-
ResourceGroup string
39-
Location string
40-
ExtendedLocation *infrav1.ExtendedLocationSpec
41-
ClusterName string
42-
Role string
43-
NICIDs []string
44-
SSHKeyData string
45-
Size string
46-
AvailabilitySetID string
47-
Zone string
48-
Identity infrav1.VMIdentity
49-
OSDisk infrav1.OSDisk
50-
DataDisks []infrav1.DataDisk
51-
UserAssignedIdentities []infrav1.UserAssignedIdentity
52-
SpotVMOptions *infrav1.SpotVMOptions
53-
SecurityProfile *infrav1.SecurityProfile
54-
AdditionalTags infrav1.Tags
55-
AdditionalCapabilities *infrav1.AdditionalCapabilities
56-
DiagnosticsProfile *infrav1.Diagnostics
57-
DisableExtensionOperations bool
58-
CapacityReservationGroupID string
59-
SKU resourceskus.SKU
60-
Image *infrav1.Image
61-
BootstrapData string
62-
ProviderID string
37+
Name string
38+
ResourceGroup string
39+
Location string
40+
ExtendedLocation *infrav1.ExtendedLocationSpec
41+
ClusterName string
42+
Role string
43+
NICIDs []string
44+
SSHKeyData string
45+
Size string
46+
AvailabilitySetID string
47+
Zone string
48+
Identity infrav1.VMIdentity
49+
OSDisk infrav1.OSDisk
50+
DataDisks []infrav1.DataDisk
51+
UserAssignedIdentities []infrav1.UserAssignedIdentity
52+
SpotVMOptions *infrav1.SpotVMOptions
53+
SecurityProfile *infrav1.SecurityProfile
54+
AdditionalTags infrav1.Tags
55+
AdditionalCapabilities *infrav1.AdditionalCapabilities
56+
DiagnosticsProfile *infrav1.Diagnostics
57+
DisableExtensionOperations bool
58+
DisableVMBootstrapExtension bool
59+
CapacityReservationGroupID string
60+
SKU resourceskus.SKU
61+
Image *infrav1.Image
62+
BootstrapData string
63+
ProviderID string
6364
}
6465

6566
// ResourceName returns the name of the virtual machine.

config/crd/bases/infrastructure.cluster.x-k8s.io_azuremachines.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ spec:
248248
Use this setting only if VMExtensions are not supported by your image, as it disables CAPZ bootstrapping extension used for detecting Kubernetes bootstrap failure.
249249
This may only be set to True when no extensions are configured on the virtual machine.
250250
type: boolean
251+
disableVMBootstrapExtension:
252+
description: |-
253+
DisableVMBootstrapExtension specifies whether the VM bootstrap extension should be disabled on the virtual machine.
254+
Use this setting if you want to disable only the bootstrapping extension and not all extensions.
255+
type: boolean
251256
dnsServers:
252257
description: DNSServers adds a list of DNS Server IP addresses to
253258
the VM NICs.

config/crd/bases/infrastructure.cluster.x-k8s.io_azuremachinetemplates.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,11 @@ spec:
259259
Use this setting only if VMExtensions are not supported by your image, as it disables CAPZ bootstrapping extension used for detecting Kubernetes bootstrap failure.
260260
This may only be set to True when no extensions are configured on the virtual machine.
261261
type: boolean
262+
disableVMBootstrapExtension:
263+
description: |-
264+
DisableVMBootstrapExtension specifies whether the VM bootstrap extension should be disabled on the virtual machine.
265+
Use this setting if you want to disable only the bootstrapping extension and not all extensions.
266+
type: boolean
262267
dnsServers:
263268
description: DNSServers adds a list of DNS Server IP addresses
264269
to the VM NICs.

0 commit comments

Comments
 (0)