diff --git a/docs/docs/reference/cloud-init.md b/docs/docs/reference/cloud-init.md index 49fd9cc81..04e907ced 100644 --- a/docs/docs/reference/cloud-init.md +++ b/docs/docs/reference/cloud-init.md @@ -344,6 +344,21 @@ use the following construct in the pod annotations: VirtletCloudInitUserDataScript: "@virtlet-mount-script@" ``` +# Disabling cloud-init based network configuration + +As the network configuration is applied only upon the first startup, +it's not used when +[persistent root filesystem](../volumes/#persistent-root-filesystem) +is used, so new network configuration can be passed using DHCP to a +new pod with the same rootfs. Moreover, in some cases it may be +desirable to force Virtlet to use DHCP instead of cloud-init based +network config. To do so, you need to add the following annotation +to the pod: + +```yaml +VirtletForceDHCPNetworkConfig: "true" +``` + # Additional links These links may help to understand some basics about cloud-init: diff --git a/pkg/libvirttools/TestCloudInitGenerator__pod_with_forced_dhcp_network_config.out.yaml b/pkg/libvirttools/TestCloudInitGenerator__pod_with_forced_dhcp_network_config.out.yaml new file mode 100755 index 000000000..b38e049b4 --- /dev/null +++ b/pkg/libvirttools/TestCloudInitGenerator__pod_with_forced_dhcp_network_config.out.yaml @@ -0,0 +1,5 @@ +meta-data: + instance-id: foo.default + local-hostname: foo +network-config: null +user-data: null diff --git a/pkg/libvirttools/TestContainerLifecycle.out.yaml b/pkg/libvirttools/TestContainerLifecycle.out.yaml index 0237c5ab6..1d715eccb 100755 --- a/pkg/libvirttools/TestContainerLifecycle.out.yaml +++ b/pkg/libvirttools/TestContainerLifecycle.out.yaml @@ -115,6 +115,7 @@ CPUModel: "" CPUSetting: null DiskDriver: scsi + ForceDHCPNetworkConfig: false InjectedFiles: null MetaData: null RootVolumeSize: 0 @@ -173,6 +174,7 @@ CPUModel: "" CPUSetting: null DiskDriver: scsi + ForceDHCPNetworkConfig: false InjectedFiles: null MetaData: null RootVolumeSize: 0 @@ -226,6 +228,7 @@ CPUModel: "" CPUSetting: null DiskDriver: scsi + ForceDHCPNetworkConfig: false InjectedFiles: null MetaData: null RootVolumeSize: 0 diff --git a/pkg/libvirttools/TestDomainForcedShutdown.out.yaml b/pkg/libvirttools/TestDomainForcedShutdown.out.yaml index a8c768a6b..ee4e6e6e0 100755 --- a/pkg/libvirttools/TestDomainForcedShutdown.out.yaml +++ b/pkg/libvirttools/TestDomainForcedShutdown.out.yaml @@ -131,6 +131,7 @@ CPUModel: "" CPUSetting: null DiskDriver: scsi + ForceDHCPNetworkConfig: false InjectedFiles: null MetaData: null RootVolumeSize: 0 diff --git a/pkg/libvirttools/cloudinit.go b/pkg/libvirttools/cloudinit.go index 0c29061b0..1371c8fea 100644 --- a/pkg/libvirttools/cloudinit.go +++ b/pkg/libvirttools/cloudinit.go @@ -177,9 +177,11 @@ func (g *CloudInitGenerator) generateUserData(volumeMap diskPathMap) ([]byte, er } func (g *CloudInitGenerator) generateNetworkConfiguration() ([]byte, error) { - if g.config.RootVolumeDevice() != nil { - // We don't use network config with persistent rootfs - // for now because with some cloud-init + if g.config.ParsedAnnotations.ForceDHCPNetworkConfig || g.config.RootVolumeDevice() != nil { + // Don't use cloud-init network config if asked not + // to do so. + // Also, we don't use network config with persistent + // rootfs for now because with some cloud-init // implementations it's applied only once return nil, nil } diff --git a/pkg/libvirttools/cloudinit_test.go b/pkg/libvirttools/cloudinit_test.go index e74d5b0eb..a83473453 100644 --- a/pkg/libvirttools/cloudinit_test.go +++ b/pkg/libvirttools/cloudinit_test.go @@ -388,6 +388,18 @@ func TestCloudInitGenerator(t *testing.T) { // make sure network config is null for the persistent rootfs case verifyNetworkConfig: true, }, + { + name: "pod with forced dhcp network config", + config: &types.VMConfig{ + PodName: "foo", + PodNamespace: "default", + ParsedAnnotations: &types.VirtletAnnotations{ForceDHCPNetworkConfig: true}, + }, + verifyMetaData: true, + verifyUserData: true, + // make sure network config is null + verifyNetworkConfig: true, + }, { name: "injecting mount script into user data script", config: &types.VMConfig{ diff --git a/pkg/metadata/types/annotations.go b/pkg/metadata/types/annotations.go index 5fbc33aba..cee6a892b 100644 --- a/pkg/metadata/types/annotations.go +++ b/pkg/metadata/types/annotations.go @@ -45,6 +45,7 @@ const ( sshKeysKeyName = "VirtletSSHKeys" chown9pfsMountsKeyName = "VirtletChown9pfsMounts" systemUUIDKeyName = "VirtletSystemUUID" + forceDHCPNetworkConfigKeyName = "VirtletForceDHCPNetworkConfig" // CloudInitUserDataSourceKeyName is the name of user data source key in the pod annotations. CloudInitUserDataSourceKeyName = "VirtletCloudInitUserDataSource" // SSHKeySourceKeyName is the name of ssh key source key in the pod annotations. @@ -119,6 +120,10 @@ type VirtletAnnotations struct { // SystemUUID specifies fixed SMBIOS UUID to be used for the domain. // If not set, the SMBIOS UUID will be automatically generated from the Pod ID. SystemUUID *uuid.UUID + // ForceDHCPNetworkConfig prevents Virtlet from using Cloud-Init based network + // configuration and makes it only provide DHCP. Note that this will + // not work for multi-CNI configuration. + ForceDHCPNetworkConfig bool } // ExternalDataLoader is used to load extra pod data from @@ -318,5 +323,13 @@ func (va *VirtletAnnotations) parsePodAnnotations(ns string, podAnnotations map[ } } + if podAnnotations[chown9pfsMountsKeyName] == "true" { + va.VirtletChown9pfsMounts = true + } + + if podAnnotations[forceDHCPNetworkConfigKeyName] == "true" { + va.ForceDHCPNetworkConfig = true + } + return nil } diff --git a/pkg/metadata/types/annotations_test.go b/pkg/metadata/types/annotations_test.go index 7a50ea684..c6accb849 100644 --- a/pkg/metadata/types/annotations_test.go +++ b/pkg/metadata/types/annotations_test.go @@ -163,6 +163,18 @@ func TestVirtletAnnotations(t *testing.T) { CDImageType: "nocloud", }, }, + { + name: "force DHCP network config", + annotations: map[string]string{ + "VirtletForceDHCPNetworkConfig": "true", + }, + va: &VirtletAnnotations{ + VCPUCount: 1, + DiskDriver: "scsi", + CDImageType: "nocloud", + ForceDHCPNetworkConfig: true, + }, + }, // bad metadata items follow { name: "bad vcpu count",