Skip to content

Commit d3f5e3d

Browse files
committed
WIP answerfile generation
This process has several steps: - building of a data structure holding all of the answerfile data, from a customizable base in data.py and from tests-specific items - serialization as XML to be read by host-installer - necessary changes to the ISO for host-installer to use it This is needed so: - different tests can use different parameters without the need for provisionning every answerfile to be used - tests can dynamically add contents for their own needs, before the XML gets actualy written FIXME: - this covers boot from remastered ISO and not PXE, install on UEFI/NVMe disk (xml needs generation there too) and not BIOS/ATA (needs clever parametrization) - doc
1 parent ef0b0c4 commit d3f5e3d

File tree

4 files changed

+66
-4
lines changed

4 files changed

+66
-4
lines changed

data.py-dist

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# You need to have an SSH key into the hosts' /root/.ssh/authorized_keys.
66
HOST_DEFAULT_USER = "root"
77
HOST_DEFAULT_PASSWORD = ""
8+
HOST_DEFAULT_PASSWORD_HASH = "" # FIXME
89

910
# Public key for a private key available to the test runner
1011
TEST_SSH_PUBKEY = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKz9uQOoxq6Q0SQ0XTzQHhDolvuo/7EyrDZsYQbRELhcPJG8MT/o5u3HyJFhIP2+HqBSXXgmqRPJUkwz9wUwb2sUwf44qZm/pyPUWOoxyVtrDXzokU/uiaNKUMhbnfaXMz6Ogovtjua63qld2+ZRXnIgrVtYKtYBeu/qKGVSnf4FTOUKl1w3uKkr59IUwwAO8ay3wVnxXIHI/iJgq6JBgQNHbn3C/SpYU++nqL9G7dMyqGD36QPFuqH/cayL8TjNZ67TgAzsPX8OvmRSqjrv3KFbeSlpS/R4enHkSemhgfc8Z2f49tE7qxWZ6x4Uyp5E6ur37FsRf/tEtKIUJGMRXN XCP-ng CI"
@@ -118,3 +119,13 @@ DEFAULT_LVMOISCSI_DEVICE_CONFIG = {
118119
# 'targetIQN': 'target.example',
119120
# 'SCSIid': 'id'
120121
}
122+
123+
BASE_ANSWERFILES = dict(
124+
INSTALL={
125+
"root": {"tag": "installation"},
126+
"root-password": {"type": "hash", "text": HOST_DEFAULT_PASSWORD_HASH},
127+
"admin-interface": {"name": "eth0", "proto": "dhcp"},
128+
"timezone": {"text": "Europe/Paris"},
129+
"keymap": {"text": "us"},
130+
},
131+
)

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ markers =
2323
vm_definitions: dicts of VM defs for create_vms fixture.
2424

2525
# * installation-related markers to customize installer run
26+
answerfile: dict defining an answerfile
2627
installer_iso: key of data.ISO_IMAGES identifying an installer ISO
2728

2829
# * Test targets related to VMs

tests/install/conftest.py

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,47 @@
55

66
from lib.commands import local_cmd, scp, ssh
77

8+
@pytest.fixture(scope='function')
9+
def answerfile(request):
10+
markers = request.node.get_closest_marker("answerfile")
11+
12+
if markers is None:
13+
yield None # no answerfile to generate
14+
return
15+
16+
# construct answerfile definition from option "base", and explicit bits
17+
marker = markers.args[0]
18+
if marker["base"]:
19+
from data import BASE_ANSWERFILES
20+
answerfile_def = BASE_ANSWERFILES[marker["base"]]
21+
del marker["base"]
22+
else:
23+
answerfile_def = {}
24+
answerfile_def.update(marker)
25+
26+
# convert to a ElementTree.Element tree suitable for further
27+
# modification before we serialize it to XML
28+
import xml.etree.ElementTree as ET
29+
30+
# root element special case
31+
root_def = answerfile_def.pop("root")
32+
root_tag = root_def.pop("tag")
33+
root = ET.Element(root_tag, **root_def)
34+
35+
# contents of root element
36+
for name, defn in answerfile_def.items():
37+
text = defn.pop("text", None)
38+
element = ET.SubElement(root, name, **defn)
39+
if text:
40+
element.text = text
41+
42+
yield ET.ElementTree(root)
43+
844
@pytest.fixture(scope='function')
945
def iso_remaster(request, answerfile):
1046
marker = request.node.get_closest_marker("installer_iso")
1147
assert marker is not None, "iso_remaster fixture requires 'installer_iso' marker"
1248
iso_key = marker.args[0]
13-
ANSWERFILE_URL = "http://pxe/configs/custom/ydi/install-8.2-uefi-iso-ext.xml" # FIXME
1449

1550
from data import ISO_IMAGES, ISOSR_SRV, ISOSR_PATH, TEST_SSH_PUBKEY, TOOLS
1651
assert "iso-remaster" in TOOLS
@@ -24,6 +59,13 @@ def iso_remaster(request, answerfile):
2459
remastered_iso = os.path.join(isotmp, "image.iso")
2560
iso_patcher_script = os.path.join(isotmp, "iso-patcher")
2661
img_patcher_script = os.path.join(isotmp, "img-patcher")
62+
answerfile_xml = os.path.join(isotmp, "answerfile.xml")
63+
64+
if answerfile:
65+
logging.info("generating answerfile %s", answerfile_xml)
66+
answerfile.write(answerfile_xml)
67+
else:
68+
logging.info("no answerfile")
2769

2870
logging.info("Remastering %s to %s", SOURCE_ISO, remastered_iso)
2971

@@ -36,7 +78,8 @@ def iso_remaster(request, answerfile):
3678
mkdir -p "$INSTALLIMG/root/.ssh"
3779
echo "{TEST_SSH_PUBKEY}" > "$INSTALLIMG/root/.ssh/authorized_keys"
3880
39-
curl {ANSWERFILE_URL} -o "$INSTALLIMG/root/answerfile.xml"
81+
test ! -e "{answerfile_xml}" ||
82+
cp "{answerfile_xml}" "$INSTALLIMG/root/answerfile.xml"
4083
""",
4184
file=patcher_fd)
4285
os.chmod(patcher_fd.fileno(), 0o755)
@@ -47,8 +90,9 @@ def iso_remaster(request, answerfile):
4790
print(f"""#!/bin/bash
4891
set -ex
4992
ISODIR="$1"
50-
SED_COMMANDS=(-e "s@/vmlinuz@/vmlinuz sshpassword={passwd} atexit=shell@")
51-
SED_COMMANDS+=(-e "s@/vmlinuz@/vmlinuz install answerfile=file:///root/answerfile.xml network_device=all@")
93+
SED_COMMANDS=(-e "s@/vmlinuz@/vmlinuz sshpassword={passwd} atexit=shell network_device=all@")
94+
test ! -e "{answerfile_xml}" ||
95+
SED_COMMANDS+=(-e "s@/vmlinuz@/vmlinuz install answerfile=file:///root/answerfile.xml@")
5296
5397
sed -i "${{SED_COMMANDS[@]}}" \
5498
"$ISODIR"/*/*/grub*.cfg \

tests/install/test_install.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ class TestInstallNested:
2525
vdis=[dict(name="vm 1 system disk", size="100GiB", device="xvda", userdevice="0")],
2626
vifs=[dict(index=0, network_uuid="eabc1038-e40f-2ae5-0781-a3adbec1cae8")], # FIXME
2727
))
28+
@pytest.mark.answerfile(
29+
{
30+
"base": "INSTALL",
31+
"source": {"type": "local"},
32+
"primary-disk": {"text": "nvme0n1"},
33+
})
2834
@pytest.mark.installer_iso("xcpng-8.2.1-2023")
2935
def test_install_nested_821_uefi(self, iso_remaster, create_vms):
3036
assert len(create_vms) == 1

0 commit comments

Comments
 (0)