Skip to content

Commit

Permalink
generate contents for ovf-env.xml when provisioning via IMDS (canonic…
Browse files Browse the repository at this point in the history
…al#959)

Azure Linux Agent (WaLinuxAgent) waits for the ovf-env.xml file 
to be written by cloud-init when cloud-init provisions the VM. This 
file is written whenever cloud-init reads its contents from the 
provisioning ISO. 
With this change, when there is no provisioning ISO, 
DataSourceAzure will generate the ovf-env.xml file based on the 
metadata obtained from Azure IMDS.
  • Loading branch information
anhvoms authored and TheRealFalcon committed Aug 10, 2021
1 parent 693f2b7 commit 675fc31
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
15 changes: 14 additions & 1 deletion cloudinit/sources/DataSourceAzure.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
is_byte_swapped,
dhcp_log_cb,
push_log_to_kvp,
report_failure_to_fabric)
report_failure_to_fabric,
build_minimal_ovf)

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -540,6 +541,18 @@ def crawl_metadata(self):
)
crawled_data['metadata']['disable_password'] = imds_disable_password # noqa: E501

if metadata_source == 'IMDS' and not crawled_data['files']:
try:
contents = build_minimal_ovf(
username=imds_username,
hostname=imds_hostname,
disableSshPwd=imds_disable_password)
crawled_data['files'] = {'ovf-env.xml': contents}
except Exception as e:
report_diagnostic_event(
"Failed to construct OVF from IMDS data %s" % e,
logger_func=LOG.debug)

# only use userdata from imds if OVF did not provide custom data
# userdata provided by IMDS is always base64 encoded
if not userdata_raw:
Expand Down
34 changes: 34 additions & 0 deletions cloudinit/sources/helpers/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,40 @@ def http_with_retries(url, **kwargs) -> str:
raise exc


def build_minimal_ovf(
username: str,
hostname: str,
disableSshPwd: str) -> bytes:
OVF_ENV_TEMPLATE = textwrap.dedent('''\
<ns0:Environment xmlns:ns0="http://schemas.dmtf.org/ovf/environment/1"
xmlns:ns1="http://schemas.microsoft.com/windowsazure"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:ProvisioningSection>
<ns1:Version>1.0</ns1:Version>
<ns1:LinuxProvisioningConfigurationSet>
<ns1:ConfigurationSetType>LinuxProvisioningConfiguration
</ns1:ConfigurationSetType>
<ns1:UserName>{username}</ns1:UserName>
<ns1:DisableSshPasswordAuthentication>{disableSshPwd}
</ns1:DisableSshPasswordAuthentication>
<ns1:HostName>{hostname}</ns1:HostName>
</ns1:LinuxProvisioningConfigurationSet>
</ns1:ProvisioningSection>
<ns1:PlatformSettingsSection>
<ns1:Version>1.0</ns1:Version>
<ns1:PlatformSettings>
<ns1:ProvisionGuestAgent>true</ns1:ProvisionGuestAgent>
</ns1:PlatformSettings>
</ns1:PlatformSettingsSection>
</ns0:Environment>
''')
ret = OVF_ENV_TEMPLATE.format(
username=username,
hostname=hostname,
disableSshPwd=disableSshPwd)
return ret.encode('utf-8')


class AzureEndpointHttpClient:

headers = {
Expand Down

0 comments on commit 675fc31

Please sign in to comment.