Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions hotfix/hotfix_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
SCRIPTS_BEGIN = "# ---- hotfix-scripts: auto-generated ----"
SCRIPTS_END = "# ---- end hotfix-scripts ----"

# Map from source file paths (relative to artifacts/) to the GetVariableProperty
# keys used in nodecustomdata.yml. Only scripts that appear as write_files entries
# Map from source file paths (relative to artifacts/) to the template variable
# keys used in nodecustomdata.yml. Only files that appear as write_files entries
# in the traditional section are included.
SOURCE_TO_VARKEY = {
# CSE helpers — base (non-distro)
Expand Down Expand Up @@ -380,7 +380,9 @@ def parse_write_files_blocks(traditional_lines):
"""Parse write_files blocks from the traditional section.

Each block is either a simple '- path:' entry or an entire conditional
block (e.g., {{if IsAzlOSGuard}}...{{end}}) treated as a single unit.
block (e.g., {{if IsAzlOSGuard}}...{{end}}) treated as a single unit. File
keys may use either the legacy GetVariableProperty form or the literal-file
GetCloudInitFileProperties form.

Returns a list of (varkeys_set, lines_list) tuples.
"""
Expand Down Expand Up @@ -421,9 +423,17 @@ def parse_write_files_blocks(traditional_lines):

if in_block:
current_block.append(line)
match = re.search(r'GetVariableProperty\s+"cloudInitData"\s+"(\w+)"', stripped)
if match:
current_varkeys.add(match.group(1))
matches = (
re.search(
r'GetVariableProperty\s+"cloudInitData"\s+"(\w+)"',
stripped,
),
re.search(r'GetCloudInitFileProperties\s+"(\w+)"', stripped),
)
for match in matches:
if match:
current_varkeys.add(match.group(1))
break

if current_block and current_varkeys:
blocks.append((current_varkeys.copy(), list(current_block)))
Expand Down
95 changes: 94 additions & 1 deletion hotfix/hotfix_generate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@
{{end}}
"""

MIXED_ENCODING_TEMPLATE = """- path: /literal.sh
owner: root
{{GetCloudInitFileProperties "literalFile"}}
- path: /legacy.sh
owner: root
encoding: gzip
content: !!binary |
{{GetVariableProperty "cloudInitData" "legacyFile"}}
"""


class HotfixGenerateTests(unittest.TestCase):
def test_production_renderer_omits_empty_platform_payloads(self):
Expand Down Expand Up @@ -161,7 +171,10 @@ def test_config_modules_are_independently_hotfixable(self):
self.assertEqual({variable}, blocks[0][0])
self.assertIn(f"- path: {{{{{path_function}}}}}", template)
self.assertIn('permissions: "0744"', template)
self.assertIn("encoding: gzip", template)
self.assertTrue(
f'GetCloudInitFileProperties "{variable}"' in template
or f'GetVariableProperty "cloudInitData" "{variable}"' in template
)
self.assertNotIn("{{if", template)

def test_mariner_package_update_is_not_embedded_in_custom_data(self):
Expand Down Expand Up @@ -234,6 +247,86 @@ def test_parse_write_files_blocks_keeps_distro_chain_together(self):
blocks[1][0],
)

def test_parse_write_files_blocks_accepts_literal_and_legacy_syntax(self):
blocks = hotfix_generate.parse_write_files_blocks(
MIXED_ENCODING_TEMPLATE.splitlines(keepends=True)
)

self.assertEqual(
[
({"literalFile"}, [
"- path: /literal.sh\n",
" owner: root\n",
'{{GetCloudInitFileProperties "literalFile"}}\n',
]),
({"legacyFile"}, [
"- path: /legacy.sh\n",
" owner: root\n",
" encoding: gzip\n",
" content: !!binary |\n",
' {{GetVariableProperty "cloudInitData" "legacyFile"}}\n',
]),
],
blocks,
)

def test_current_template_literal_entries_are_injected_and_rendered(self):
repository = Path(__file__).resolve().parents[1]
template_lines = (repository / hotfix_generate.TEMPLATE).read_text().splitlines(
keepends=True
)
_, outer_else, end = hotfix_generate.find_block_boundaries(template_lines)
self.assertIsNotNone(outer_else)
self.assertIsNotNone(end)
traditional = template_lines[outer_else + 1:end]
available = set().union(
*(keys for keys, _ in hotfix_generate.parse_write_files_blocks(traditional))
)
selected = {"provisionConfigsGPU"}
self.assertIn("provisionConfigsGPU", available)

hotfix_template = hotfix_generate.build_hotfix_template(selected, traditional)
self.assertIn(
'{{GetCloudInitFileProperties "provisionConfigsGPU"}}',
hotfix_template,
)

with tempfile.TemporaryDirectory() as temp_dir:
injected_template = Path(temp_dir) / "nodecustomdata.yml"
injected_template.write_text("".join(template_lines))
generated_dir = Path(temp_dir) / "generated"
with mock.patch.object(
hotfix_generate, "TEMPLATE", str(injected_template)
), mock.patch.object(
hotfix_generate, "GENERATED_DIR", str(generated_dir)
):
hotfix_generate.update_nodecustomdata(selected)
injected = injected_template.read_text()
marked_block = injected.split(hotfix_generate.SCRIPTS_BEGIN, 1)[1].split(
hotfix_generate.SCRIPTS_END, 1
)[0]
self.assertIn(
'{{GetCloudInitFileProperties "provisionConfigsGPU"}}',
marked_block,
)

hotfix_generate.write_rendered_payload(selected, traditional)

for platform in ("ubuntu", "mariner"):
rendered = (
generated_dir / f"rendered_nodecustomdata_{platform}.yml"
).read_text()
self.assertIn(
"- path: /opt/azure/containers/provision_configs_gpu.sh",
rendered,
)
self.assertIn('permissions: "0744"', rendered)
self.assertIn(r'content: "#!/bin/bash\n', rendered)
self.assertIn("configGPUDrivers() {", rendered)
self.assertNotIn("GetCloudInitFileProperties", rendered)
self.assertNotIn("{{", rendered)
self.assertNotIn("encoding: gzip", rendered)

def test_build_hotfix_template_selects_only_requested_blocks(self):
rendered = hotfix_generate.build_hotfix_template(
{"provisionSource"},
Expand Down
108 changes: 27 additions & 81 deletions parts/linux/cloud-init/nodecustomdata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,201 +28,147 @@ write_files:
{{if IsAKSCustomCloud}}
- path: {{GetInitAKSCloudFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "initAKSCloud"}}
{{GetCloudInitFileProperties "initAKSCloud"}}
{{end}}

{{- else }}
- path: {{GetCSEHelpersScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionSource"}}
{{GetCloudInitFileProperties "provisionSource"}}


{{if IsACL }}
- path: {{GetCSEHelpersScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionSourceACL"}}
{{GetCloudInitFileProperties "provisionSourceACL"}}
{{- else if IsAzlOSGuard}}
- path: {{GetCSEHelpersScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionSourceAzlOSGuard"}}
{{GetCloudInitFileProperties "provisionSourceAzlOSGuard"}}
{{- else if IsMariner}}
- path: {{GetCSEHelpersScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionSourceMariner"}}
{{GetCloudInitFileProperties "provisionSourceMariner"}}
{{- else if IsFlatcar }}
- path: {{GetCSEHelpersScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionSourceFlatcar"}}
{{GetCloudInitFileProperties "provisionSourceFlatcar"}}
{{- else }}
- path: {{GetCSEHelpersScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionSourceUbuntu"}}
{{GetCloudInitFileProperties "provisionSourceUbuntu"}}
{{end}}

{{ if not IsCustomImage -}}
- path: /opt/azure/containers/provision_start.sh
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionStartScript"}}
{{GetCloudInitFileProperties "provisionStartScript"}}
{{- end }}

- path: /opt/azure/containers/provision.sh
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionScript"}}
{{GetCloudInitFileProperties "provisionScript"}}

- path: {{GetCSEInstallScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionInstalls"}}
{{GetCloudInitFileProperties "provisionInstalls"}}

{{if IsACL }}
- path: {{GetCSEInstallScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionInstallsACL"}}
{{GetCloudInitFileProperties "provisionInstallsACL"}}
{{- else if IsAzlOSGuard}}
- path: {{GetCSEInstallScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionInstallsAzlOSGuard"}}
{{GetCloudInitFileProperties "provisionInstallsAzlOSGuard"}}
{{- else if IsMariner}}
- path: {{GetCSEInstallScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionInstallsMariner"}}
{{GetCloudInitFileProperties "provisionInstallsMariner"}}
{{- else if IsFlatcar }}
- path: {{GetCSEInstallScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionInstallsFlatcar"}}
{{GetCloudInitFileProperties "provisionInstallsFlatcar"}}
{{- else }}
- path: {{GetCSEInstallScriptDistroFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionInstallsUbuntu"}}
{{GetCloudInitFileProperties "provisionInstallsUbuntu"}}
{{end}}

- path: {{GetCSEConfigScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionConfigs"}}
{{GetCloudInitFileProperties "provisionConfigs"}}

- path: {{GetCSEConfigGPUScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionConfigsGPU"}}
{{GetCloudInitFileProperties "provisionConfigsGPU"}}

- path: {{GetCSEConfigLocalDNSScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionConfigsLocalDNS"}}
{{GetCloudInitFileProperties "provisionConfigsLocalDNS"}}

- path: {{GetCSEConfigKubeletScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionConfigsKubelet"}}
{{GetCloudInitFileProperties "provisionConfigsKubelet"}}

- path: {{GetCSEConfigNetworkScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionConfigsNetwork"}}
{{GetCloudInitFileProperties "provisionConfigsNetwork"}}

- path: {{GetCSEConfigAddonsScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionConfigsAddons"}}
{{GetCloudInitFileProperties "provisionConfigsAddons"}}

- path: {{GetCSEConfigChronyScriptFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "provisionConfigsChrony"}}
{{GetCloudInitFileProperties "provisionConfigsChrony"}}

{{if IsAKSCustomCloud}}
- path: {{GetInitAKSCloudFilepath}}
permissions: "0744"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "initAKSCloud"}}
{{GetCloudInitFileProperties "initAKSCloud"}}
{{end}}

- path: /etc/systemd/system/reconcile-private-hosts.service
permissions: "0644"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "reconcilePrivateHostsService"}}
{{GetCloudInitFileProperties "reconcilePrivateHostsService"}}

- path: /etc/systemd/system/kubelet.service
permissions: "0600"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "kubeletSystemdService"}}
{{GetCloudInitFileProperties "kubeletSystemdService"}}

- path: /opt/azure-network/configure-azure-network.sh
permissions: "0755"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "configureAzureNetworkScript"}}
{{GetCloudInitFileProperties "configureAzureNetworkScript"}}

- path: /etc/udev/rules.d/99-azure-network.rules
permissions: "0644"
encoding: gzip
owner: root
content: !!binary |
{{GetVariableProperty "cloudInitData" "azureNetworkUdevRule"}}
{{GetCloudInitFileProperties "azureNetworkUdevRule"}}
{{- end }}
Loading
Loading