fix: cloud-init datasource_list must be one-line

Ensure datasource_list configuration from subiquity is a single
line: datasource_list: [None] to support ds-identify limitation
in parsing single-line datasource_list values.

cloud-init's ds-identify doesn't actually support multi-line YAML
and never has.

We can see this behavior in /run/cloud-init/ds-identify.log which
opts to use a default datsource_list and logs:

  /etcloud/cloud.cfg.d/99-installer.cfg set datasource_list:
  no datasource_list found, using default: ....

This issue doesn't affect subiquity in practice because
it also places /etc/cloud/ds-identify.cfg containing `policy: enabled`.
Which means cloud-init will be enabled regardless of whether
ds-identify finds a valid datasource.

We see this in /run/cloud-init/ds-identify.log with the following:

  DSNAME=
  ...
  mode=enabled returning 0

Once cloud-init python code runs and merges system configuration in
/etc/cloud/cloud.cfg.d with a proper YAML parser, it correctly parses
multi-line YAML config and successfully limits the merged
datasource_list: [ None ] provided in
/etc/cloud/cloud.cfg.d/99-installer.yaml.

If subiquity were to drop the /etc/cloud/ds-identify.cfg file in the
future, cloud-init would actually be disabled on first boot because it
never detected a viable datasource during systemd generator timeframe
and ds-identify policy doesn't mandate being enabled by default.
This commit is contained in:
Chad Smith 2024-05-21 15:36:01 -06:00
parent dea2ca2379
commit 197c3f743d
2 changed files with 10 additions and 3 deletions

View File

@ -435,7 +435,10 @@ class SubiquityModel:
"metadata": metadata,
},
},
}
},
# ds-identify does not support multi-line YAML datasource_list.
# Turn off default_flow_style forcing datasource_list: [None].
default_flow_style=None,
)
grub_dpkg = yaml.dump({"grub_dpkg": {"enabled": False}})
files = [

View File

@ -285,7 +285,8 @@ grub_dpkg:
enabled: false
""",
"etc/cloud/cloud.cfg.d/99-installer.cfg": re.compile(
"datasource:\n None:\n metadata:\n instance-id: .*\n userdata_raw: \"#cloud-config\\\\ngrowpart:\\\\n mode: \\'off\\'\\\\npreserve_hostname: true\\\\n\\\\\n" # noqa
"datasource:\n None:\n metadata: {instance-id: .*}\n userdata_raw: \"#cloud-config\\\\ngrowpart:\\\\n mode: \\'off\\'\\\\npreserve_hostname: true\\\\n\\\\\n.*datasource_list: \[None\]", # noqa
re.DOTALL,
),
"etc/hostname": "somehost\n",
"etc/cloud/ds-identify.cfg": "policy: enabled\n",
@ -320,7 +321,10 @@ grub_dpkg:
):
for cpath, content, perms in model._cloud_init_files():
if isinstance(expected_files[cpath], re.Pattern):
self.assertIsNotNone(expected_files[cpath].match(content))
self.assertIsNotNone(
expected_files[cpath].match(content),
f"Missing expected file match {cpath}: {content}"
)
else:
self.assertEqual(expected_files[cpath], content)