Skip to content

Commit ce0e117

Browse files
gthvn1ydirson
authored andcommitted
Add support for netinstall
Add a new parameter to allow booting using netinstall. If an ISO only supports netinstall, it is specified it in the data.py by setting the `net-only`option to True. This option is set to False by default. Signed-off-by: Guillaume <[email protected]> Signed-off-by: Yann Dirson <[email protected]>
1 parent 22ef392 commit ce0e117

File tree

8 files changed

+107
-39
lines changed

8 files changed

+107
-39
lines changed

data.py-dist

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,33 @@ ISO_IMAGES_CACHE = "/home/user/iso"
121121
# - absolute URL
122122
# - path relative to ISO_IMAGES_BASE URL
123123
# Note the dirname part is ignored when looking in ISO_IMAGES_CACHE, abuse this
124-
# for local-only ISO with things like "locally-built/my.iso" or "xs/8.3.iso"
124+
# for local-only ISO with things like "locally-built/my.iso" or "xs/8.3.iso".
125+
# If 'net-only' is set to 'True' only source of type URL will be possible.
126+
# By default the parameter is set to False.
125127
ISO_IMAGES: Dict[str, "IsoImageDef"] = {
126128
'83nightly': {'path': os.environ.get("XCPNG83_NIGHTLY",
127129
"http://unconfigured.iso"),
128130
'unsigned': True},
129-
'83rc1': {'path': "8.3/xcp-ng-8.3.0-rc1.iso"},
130-
'83b2': {'path': "8.3/xcp-ng-8.3.0-beta2.iso"},
131-
'83b1': {'path': "8.3/xcp-ng-8.3.0-beta1.iso"},
132-
'821.1': {'path': "8.2/xcp-ng-8.2.1-20231130.iso"},
131+
# FIXME: no such symlimk + useless without 'net-url'
132+
#'83nightlynet': {'path': "http://pxe/isos/xcp-ng-8.3-ci-netinstall-latest"},
133+
# 'net-url': 'fake",
134+
# 'net-only': True},
135+
'83rc1': {'path': "8.3/xcp-ng-8.3.0-rc1.iso",
136+
#'net-url': "http://server/installers/xcp-ng/8.3-rc1",
137+
},
138+
## FIXME: only a compensation for the lack of 83nightlynet
139+
#'83rcnet': {'path': "8.3/xcp-ng-8.3.0-rc1-netinstall.iso",
140+
# 'net-url': "http://server/installers/xcp-ng/8.3-rc1",
141+
# 'net-only': True},
142+
'83b2': {'path': "8.3/xcp-ng-8.3.0-beta2.iso",
143+
#'net-url': "http://server/installers/xcp-ng/8.3-beta2",
144+
},
145+
'83b1': {'path': "8.3/xcp-ng-8.3.0-beta1.iso",
146+
#'net-url': "http://server/installers/xcp-ng/8.3-beta1",
147+
},
148+
'821.1': {'path': "8.2/xcp-ng-8.2.1-20231130.iso",
149+
#'net-url': f"http://{PXE_CONFIG_SERVER}/installers/xcp-ng/8.2.1-refreshed/",
150+
},
133151
'821': {'path': "8.2/xcp-ng-8.2.1.iso"},
134152
'820': {'path': "8.2/xcp-ng-8.2.0.iso"},
135153
'81': {'path': "8.1/xcp-ng-8.1.0-2.iso"},

lib/typing.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33

44
IsoImageDef = TypedDict('IsoImageDef',
55
{'path': str,
6+
'net-url': NotRequired[str],
7+
'net-only': NotRequired[bool],
68
'unsigned': NotRequired[bool],
79
})

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ markers =
2424

2525
# * installation-related markers to customize installer run
2626
answerfile: dict defining an answerfile
27+
package_source: source of packages during installation.
2728

2829
# * Test targets related to VMs
2930
small_vm: tests that it is enough to run just once, using the smallest possible VM.

tests/install/conftest.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,30 @@
1313
from data import (ISO_IMAGES, ISO_IMAGES_BASE, ISO_IMAGES_CACHE,
1414
PXE_CONFIG_SERVER, TEST_SSH_PUBKEY, TOOLS)
1515

16+
# Return true if the version of the ISO doesn't support the source type.
17+
# Note: this is a quick-win hack, to avoid explicit enumeration of supported
18+
# package_source values for each ISO.
19+
def skip_package_source(version, package_source):
20+
if version not in ISO_IMAGES:
21+
return True, "version of ISO {} is unknown".format(version)
22+
23+
if package_source == "iso":
24+
if ISO_IMAGES[version].get('net-only', False):
25+
return True, "ISO image is net-only while package_source is local"
26+
27+
return False, "do not skip"
28+
29+
if package_source == "net":
30+
# Net install is not valid if there is no netinstall URL
31+
# FIXME: ISO includes a default URL so we should be able to omit net-url
32+
if 'net-url' not in ISO_IMAGES[version].keys():
33+
return True, "net-url required for netinstall was not found for {}".format(version)
34+
35+
return False, "do not skip"
36+
37+
# If we don't know the source type then it is invalid
38+
return True, "unknown source type {}".format(package_source)
39+
1640
@pytest.fixture(scope='function')
1741
def answerfile(request):
1842
"""
@@ -57,6 +81,10 @@ def answerfile(request):
5781
@pytest.fixture(scope='function')
5882
def installer_iso(request):
5983
iso_key = request.getfixturevalue("iso_version")
84+
package_source = request.getfixturevalue("package_source")
85+
skip, reason = skip_package_source(iso_key, package_source)
86+
if skip:
87+
pytest.skip(reason)
6088
assert iso_key in ISO_IMAGES, f"ISO_IMAGES does not have a value for {iso_key}"
6189
iso = ISO_IMAGES[iso_key]['path']
6290
if iso.startswith("/"):
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
tests/install/test.py::TestNested::test_restore[uefi-83nightly-83nightly-83nightly-ext]
2-
tests/install/test.py::TestNested::test_boot_rst[uefi-83nightly-83nightly-83nightly-ext]
1+
tests/install/test.py::TestNested::test_restore[uefi-83nightly-83nightly-83nightly-iso-ext]
2+
tests/install/test.py::TestNested::test_boot_rst[uefi-83nightly-83nightly-83nightly-iso-ext]
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
tests/install/test.py::TestNested::test_upgrade[uefi-83nightly-83nightly-host1-ext]
2-
tests/install/test.py::TestNested::test_boot_upg[uefi-83nightly-83nightly-host1-ext]
1+
tests/install/test.py::TestNested::test_upgrade[uefi-83nightly-83nightly-host1-iso-ext]
2+
tests/install/test.py::TestNested::test_boot_upg[uefi-83nightly-83nightly-host1-iso-ext]

tests/install/test-sequences/inst.lst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
tests/install/test.py::TestNested::test_install[uefi-83nightly-ext]
2-
tests/install/test.py::TestNested::test_tune_firstboot[None-uefi-83nightly-host1-ext]
3-
tests/install/test.py::TestNested::test_boot_inst[uefi-83nightly-host1-ext]
1+
tests/install/test.py::TestNested::test_install[uefi-83nightly-iso-ext]
2+
tests/install/test.py::TestNested::test_tune_firstboot[None-uefi-83nightly-host1-iso-ext]
3+
tests/install/test.py::TestNested::test_boot_inst[uefi-83nightly-host1-iso-ext]

tests/install/test.py

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from lib.pool import Pool
1010
from lib.vdi import VDI
1111

12-
from data import NETWORKS
12+
from data import ISO_IMAGES, NETWORKS
1313
assert "MGMT" in NETWORKS
1414

1515
# Requirements:
@@ -41,8 +41,9 @@ def helper_vm_with_plugged_disk(running_vm, create_vms):
4141
@pytest.mark.dependency()
4242
class TestNested:
4343
@pytest.mark.parametrize("local_sr", ("nosr", "ext", "lvm"))
44+
@pytest.mark.parametrize("package_source", ("iso", "net"))
4445
@pytest.mark.parametrize("iso_version", (
45-
"83nightly",
46+
"83nightly", "83rcnet",
4647
"83rc1", "83b2", "83b1",
4748
"821.1",
4849
"81", "80", "76", "75",
@@ -75,24 +76,28 @@ class TestNested:
7576
vifs=[dict(index=0, network_name=NETWORKS["MGMT"])],
7677
))
7778
@pytest.mark.answerfile(
78-
lambda install_disk, local_sr: AnswerFile("INSTALL")
79+
lambda install_disk, local_sr, package_source, iso_version: AnswerFile("INSTALL")
7980
.top_setattr({} if local_sr == "nosr" else {"sr-type": local_sr})
8081
.top_append(
81-
{"TAG": "source", "type": "local"},
82+
{"TAG": "source", "type": "local"} if package_source == "iso"
83+
else {"TAG": "source", "type": "url",
84+
"CONTENTS": ISO_IMAGES[iso_version]['net-url']} if package_source == "net"
85+
else {},
8286
{"TAG": "primary-disk",
8387
"guest-storage": "no" if local_sr == "nosr" else "yes",
8488
"CONTENTS": install_disk},
8589
))
8690
def test_install(self, vm_booted_with_installer, install_disk,
87-
firmware, iso_version, local_sr):
91+
firmware, iso_version, package_source, local_sr):
8892
host_vm = vm_booted_with_installer
8993
installer.monitor_install(ip=host_vm.ip)
9094

9195
@pytest.mark.usefixtures("xcpng_chained")
9296
@pytest.mark.parametrize("local_sr", ("nosr", "ext", "lvm"))
97+
@pytest.mark.parametrize("package_source", ("iso", "net"))
9398
@pytest.mark.parametrize("machine", ("host1", "host2"))
9499
@pytest.mark.parametrize("version", (
95-
"83nightly",
100+
"83nightly", "83rcnet",
96101
"83rc1", "83b2", "83b1",
97102
"821.1",
98103
"81", "80",
@@ -102,12 +107,12 @@ def test_install(self, vm_booted_with_installer, install_disk,
102107
))
103108
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
104109
@pytest.mark.continuation_of(
105-
lambda version, firmware, local_sr: [dict(
110+
lambda version, firmware, local_sr, package_source: [dict(
106111
vm="vm1",
107-
image_test=f"TestNested::test_install[{firmware}-{version}-{local_sr}]")])
112+
image_test=f"TestNested::test_install[{firmware}-{version}-{package_source}-{local_sr}]")])
108113
@pytest.mark.small_vm
109114
def test_tune_firstboot(self, create_vms, helper_vm_with_plugged_disk,
110-
firmware, version, machine, local_sr):
115+
firmware, version, machine, local_sr, package_source):
111116
helper_vm = helper_vm_with_plugged_disk
112117

113118
helper_vm.ssh(["mount /dev/xvdb1 /mnt"])
@@ -151,6 +156,7 @@ def _test_firstboot(self, create_vms, mode, *, machine='DEFAULT', is_restore=Fal
151156
"83b1": "8.3.0",
152157
"83b2": "8.3.0",
153158
"83rc1": "8.3.0",
159+
"83rcnet": "8.3.0",
154160
"83nightly": "8.3.0",
155161
}[expected_rel_id]
156162

@@ -278,9 +284,10 @@ def _test_firstboot(self, create_vms, mode, *, machine='DEFAULT', is_restore=Fal
278284

279285
@pytest.mark.usefixtures("xcpng_chained")
280286
@pytest.mark.parametrize("local_sr", ("nosr", "ext", "lvm"))
287+
@pytest.mark.parametrize("package_source", ("iso", "net"))
281288
@pytest.mark.parametrize("machine", ("host1", "host2"))
282289
@pytest.mark.parametrize("version", (
283-
"83nightly",
290+
"83nightly", "83rcnet",
284291
"83rc1", "83b2", "83b1",
285292
"821.1",
286293
"81", "80",
@@ -290,15 +297,17 @@ def _test_firstboot(self, create_vms, mode, *, machine='DEFAULT', is_restore=Fal
290297
))
291298
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
292299
@pytest.mark.continuation_of(
293-
lambda firmware, version, machine, local_sr: [
300+
lambda firmware, version, machine, local_sr, package_source: [
294301
dict(vm="vm1",
295-
image_test=f"TestNested::test_tune_firstboot[None-{firmware}-{version}-{machine}-{local_sr}]")])
302+
image_test=("TestNested::test_tune_firstboot"
303+
f"[None-{firmware}-{version}-{machine}-{package_source}-{local_sr}]"))])
296304
def test_boot_inst(self, create_vms,
297-
firmware, version, machine, local_sr):
305+
firmware, version, machine, package_source, local_sr):
298306
self._test_firstboot(create_vms, version, machine=machine)
299307

300308
@pytest.mark.usefixtures("xcpng_chained")
301309
@pytest.mark.parametrize("local_sr", ("nosr", "ext", "lvm"))
310+
@pytest.mark.parametrize("package_source", ("iso", "net"))
302311
@pytest.mark.parametrize("machine", ("host1", "host2"))
303312
@pytest.mark.parametrize("mode", (
304313
"83nightly-83nightly",
@@ -310,19 +319,21 @@ def test_boot_inst(self, create_vms,
310319
"80-83nightly",
311320
"xs8-83nightly",
312321
"ch821.1-83nightly",
322+
"83rcnet-83rcnet",
313323
"821.1-821.1",
314324
))
315325
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
316326
@pytest.mark.continuation_of(
317-
lambda firmware, mode, machine, local_sr: [dict(
327+
lambda firmware, mode, machine, package_source, local_sr: [dict(
318328
vm="vm1",
319-
image_test=(f"TestNested::test_upgrade[{firmware}-{mode}-{machine}-{local_sr}]"))])
329+
image_test=(f"TestNested::test_upgrade[{firmware}-{mode}-{machine}-{package_source}-{local_sr}]"))])
320330
def test_boot_upg(self, create_vms,
321-
firmware, mode, machine, local_sr):
331+
firmware, mode, machine, package_source, local_sr):
322332
self._test_firstboot(create_vms, mode, machine=machine)
323333

324334
@pytest.mark.usefixtures("xcpng_chained")
325335
@pytest.mark.parametrize("local_sr", ("nosr", "ext", "lvm"))
336+
@pytest.mark.parametrize("package_source", ("iso", "net"))
326337
@pytest.mark.parametrize("mode", (
327338
"83nightly-83nightly-83nightly",
328339
"83rc1-83nightly-83nightly",
@@ -333,19 +344,21 @@ def test_boot_upg(self, create_vms,
333344
"80-83nightly-83nightly",
334345
"xs8-83nightly-83nightly",
335346
"ch821.1-83nightly-83nightly",
347+
"83rcnet-83rcnet-83rcnet", # FIXME
336348
"821.1-821.1-821.1",
337349
))
338350
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
339351
@pytest.mark.continuation_of(
340-
lambda firmware, mode, local_sr: [dict(
352+
lambda firmware, mode, package_source, local_sr: [dict(
341353
vm="vm1",
342-
image_test=(f"TestNested::test_restore[{firmware}-{mode}-{local_sr}]"))])
354+
image_test=(f"TestNested::test_restore[{firmware}-{mode}-{package_source}-{local_sr}]"))])
343355
def test_boot_rst(self, create_vms,
344-
firmware, mode, local_sr):
356+
firmware, mode, package_source, local_sr):
345357
self._test_firstboot(create_vms, mode, is_restore=True)
346358

347359
@pytest.mark.usefixtures("xcpng_chained")
348360
@pytest.mark.parametrize("local_sr", ("nosr", "ext", "lvm"))
361+
@pytest.mark.parametrize("package_source", ("iso", "net"))
349362
@pytest.mark.parametrize("machine", ("host1", "host2"))
350363
@pytest.mark.parametrize(("orig_version", "iso_version"), [
351364
("83nightly", "83nightly"),
@@ -357,26 +370,31 @@ def test_boot_rst(self, create_vms,
357370
("80", "83nightly"),
358371
("xs8", "83nightly"),
359372
("ch821.1", "83nightly"),
373+
("83rcnet", "83rcnet"), # FIXME
360374
("821.1", "821.1"),
361375
])
362376
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
363377
@pytest.mark.continuation_of(
364-
lambda firmware, orig_version, machine, local_sr: [dict(
378+
lambda firmware, orig_version, machine, package_source, local_sr: [dict(
365379
vm="vm1",
366-
image_test=f"TestNested::test_boot_inst[{firmware}-{orig_version}-{machine}-{local_sr}]")])
380+
image_test=f"TestNested::test_boot_inst[{firmware}-{orig_version}-{machine}-{package_source}-{local_sr}]")])
367381
@pytest.mark.answerfile(
368-
lambda install_disk: AnswerFile("UPGRADE").top_append(
369-
{"TAG": "source", "type": "local"},
382+
lambda install_disk, package_source, iso_version: AnswerFile("UPGRADE").top_append(
383+
{"TAG": "source", "type": "local"} if package_source == "iso"
384+
else {"TAG": "source", "type": "url",
385+
"CONTENTS": ISO_IMAGES[iso_version]['net-url']} if package_source == "net"
386+
else {},
370387
{"TAG": "existing-installation",
371388
"CONTENTS": install_disk},
372389
))
373390
def test_upgrade(self, vm_booted_with_installer, install_disk,
374-
firmware, orig_version, iso_version, machine, local_sr):
391+
firmware, orig_version, iso_version, machine, package_source, local_sr):
375392
host_vm = vm_booted_with_installer
376393
installer.monitor_upgrade(ip=host_vm.ip)
377394

378395
@pytest.mark.usefixtures("xcpng_chained")
379396
@pytest.mark.parametrize("local_sr", ("nosr", "ext", "lvm"))
397+
@pytest.mark.parametrize("package_source", ("iso", "net"))
380398
@pytest.mark.parametrize(("orig_version", "iso_version"), [
381399
("83nightly-83nightly", "83nightly"),
382400
("83rc1-83nightly", "83nightly"),
@@ -387,19 +405,20 @@ def test_upgrade(self, vm_booted_with_installer, install_disk,
387405
("80-83nightly", "83nightly"),
388406
("xs8-83nightly", "83nightly"),
389407
("ch821.1-83nightly", "83nightly"),
408+
("83rcnet-83rcnet", "83rcnet"), # FIXME
390409
("821.1-821.1", "821.1"),
391410
])
392411
@pytest.mark.parametrize("firmware", ("uefi", "bios"))
393412
@pytest.mark.continuation_of(
394-
lambda firmware, orig_version, local_sr: [dict(
413+
lambda firmware, orig_version, local_sr, package_source: [dict(
395414
vm="vm1",
396-
image_test=f"TestNested::test_boot_upg[{firmware}-{orig_version}-host1-{local_sr}]")])
415+
image_test=f"TestNested::test_boot_upg[{firmware}-{orig_version}-host1-{package_source}-{local_sr}]")])
397416
@pytest.mark.answerfile(
398417
lambda install_disk: AnswerFile("RESTORE").top_append(
399418
{"TAG": "backup-disk",
400419
"CONTENTS": install_disk},
401420
))
402421
def test_restore(self, vm_booted_with_installer, install_disk,
403-
firmware, orig_version, iso_version, local_sr):
422+
firmware, orig_version, iso_version, package_source, local_sr):
404423
host_vm = vm_booted_with_installer
405424
installer.monitor_restore(ip=host_vm.ip)

0 commit comments

Comments
 (0)