summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AGENTS.md63
-rw-r--r--Makefile8
-rw-r--r--data/defaults.toml2
-rw-r--r--data/live-build-config/archives/vyos-dev.key.chroot75
-rw-r--r--docker/vyos-dev.key75
-rwxr-xr-xscripts/check-qemu-install137
-rw-r--r--scripts/package-build/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch6
7 files changed, 205 insertions, 161 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 0620e704..5d17672d 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -35,6 +35,25 @@ make generic # builds the generic flavor
folder. Use `docker build -t vyos/vyos-build docker` from top-level dir.
- Git submodules are not in use. Prebuilt binary packages are pulled from
`https://packages.vyos.net/repositories/<train>` at build time.
+- Requires root: `sudo ./build-vyos-image generic`.
+
+### Testing a local package change
+
+Any `.deb` in `packages/` takes precedence over a package from APT repositories,
+which is how a change to
+`vyos-1x` (usually checked out at `packages/vyos-1x`) reaches an image:
+
+```bash
+cd packages/vyos-1x && dpkg-buildpackage -uc -us -tc -b # -> packages/*.deb
+cd ../.. && sudo ./build-vyos-image generic --architecture amd64
+```
+
+- Delete the previous `.deb` first. If there are two versions of the same package in
+ `packages/`, the build process is not guaranteed to pick the newest one
+ and may end up silently testing wrong code.
+- Confirm what landed rather than assuming: the version string carries the
+ git describe of the source tree, so
+ `grep <short-sha> <build-log>` shows whether the intended build went in.
## Testing instructions
@@ -50,6 +69,15 @@ make generic # builds the generic flavor
one named `test_protocols_bgp.py` can be executed by:
`make test -- --match protocols_bgp`
- Test framework must run as user `root` to spawn QEMU VMs.
+- Targets test `build/live-image-<arch>.hybrid.iso` (`ISO_PATH`), not the
+ versioned ISO next to it. After a rebuild, check the file is actually the new
+ one - an interrupted build can leave the old image in place.
+- The harness lives in this repository, so it tracks the branch, not the image.
+ Testing a feature branch's image with another branch's `check-qemu-install`
+ fails on things the image no longer does. Check out the matching branch.
+- Failures propagate: a failing testcase makes `vyos-smoketest` exit non-zero,
+ the harness raise, and `make` stop. `test-suite` runs its targets one per
+ recipe line, so it aborts at the first failure rather than running on.
## Repository layout
@@ -81,15 +109,42 @@ make generic # builds the generic flavor
## PR instructions
-- Commit/PR title must follow: `component: T1234: description`. Phorge IDs at
- https://vyos.dev. Enforced by `check-pr-message.yml` reusable workflow.
-- See also `CONTRIBUTING.md` for further hints on the commit messages.
+- Title rules are the commit message rules - see "Commit messages" below and
+ `CONTRIBUTING.md`.
+- The PR description must use `.github/PULL_REQUEST_TEMPLATE.md` as it exists in
+ the branch at the time the PR is opened. Fill the sections in, do not rewrite
+ them:
+ * Keep every heading, its order, and the HTML comments - reviewers and tooling
+ rely on them being there.
+ * Do not drop, rename, merge or reformat sections, and do not invent new ones.
+ A section with nothing to say stays in place and empty.
+ * Tick the checkboxes that apply with `[x]`; leave the rest unticked rather
+ than deleting the line.
+ * The template is not fixed forever. Read it before opening a PR instead of
+ reusing the wording from an earlier one.
- Linting: unused-imports (Pylint) and J2 lint (note: workflow file is named
`linit-j2.yml` in this repo — known cosmetic typo). Both inherited from
`vyos/.github@production`.
- PR conflicts are flagged automatically via `check-pr-conflicts.yml` (reusable
`check-pr-merge-conflict.yml` from `vyos/.github@production`).
+## Commit messages
+
+- Title: `component: T1234: description`. The Phorge Task ID is required -
+ <https://vyos.dev>. Enforced by `check-pr-message.yml`.
+- A body is highly recommended, and limited to 150 words. Say what was wrong
+ and what now happens instead; the diff shows the rest.
+- Do not name functions, methods or files unless the message is meaningless
+ without them. It reads as noise and eats the budget.
+- Use `*` or `-` for a list, and only when one is genuinely needed.
+
+## Code comments
+
+- Comment only what the code cannot say. No restating the line below.
+- Never state anything you have not verified. A confident wrong comment
+ outlives the code and misleads every later reader.
+- Keep them short. Nobody reads a novel in a source file.
+
## Notes for future contributors
- No `git submodule init` needed - packages come from the apt mirror at build
@@ -101,4 +156,4 @@ make generic # builds the generic flavor
`workflow_dispatch` into `$REMOTE_OWNER/vyos-build-packages` (REMOTE_OWNER =
the private side). The dispatcher runs as `vyosbot`.
- For new flavors, add a `data/build-flavors/<flavor>.toml` and document the
- resulting `make <flavor>` target. \ No newline at end of file
+ resulting `make <flavor>` target.
diff --git a/Makefile b/Makefile
index 4036cbff..cfc86b31 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ TEST_MEM := $(shell awk '/MemTotal/{if ($$2/1024/1024 >= 10) print 8; else print
# to their scripts via $(MAKECMDGOALS). Those extra words are also goals as
# far as make is concerned, so without this they'd fall through to the `%:`
# flavor rule below and run build-vyos-image with garbage arguments.
-TEST_TARGETS := test test-no-interfaces test-no-interfaces-no-vpp test-interfaces test-vpp testc testcvpp testraid testsb testtpm testifname test-ci-qcow2 test-image-update qemu-live test-suite test-oci
+TEST_TARGETS := test test-no-interfaces test-no-interfaces-no-vpp test-interfaces test-vpp testc testcvpp testraid test-secure-boot testtpm testifname test-ci-qcow2 test-image-update qemu-live test-suite test-oci
ifneq ($(filter $(TEST_TARGETS),$(firstword $(MAKECMDGOALS))),)
$(eval $(filter-out $(firstword $(MAKECMDGOALS)),$(MAKECMDGOALS)):;@:)
endif
@@ -78,10 +78,10 @@ testcvpp:
testraid:
scripts/check-qemu-install --debug $(UEFI_FLAG) --raid --iso $(ISO_PATH) $(filter-out $@,$(MAKECMDGOALS))
-.PHONY: testsb
+.PHONY: test-secure-boot
.ONESHELL:
-testsb:
- scripts/check-qemu-install --debug --uefi --sbtest --iso $(ISO_PATH) $(filter-out $@,$(MAKECMDGOALS))
+test-secure-boot:
+ scripts/check-qemu-install --debug --uefi --secure-boot-test --iso $(ISO_PATH) $(filter-out $@,$(MAKECMDGOALS))
.PHONY: testtpm
.ONESHELL:
diff --git a/data/defaults.toml b/data/defaults.toml
index ea181902..307039dc 100644
--- a/data/defaults.toml
+++ b/data/defaults.toml
@@ -14,7 +14,7 @@ vyos_mirror = "https://packages.vyos.net/repositories/rolling"
vyos_branch = "rolling"
release_train = "rolling"
-kernel_version = "6.18.54"
+kernel_version = "6.18.55"
kernel_flavor = "vyos"
bootloaders = "syslinux,grub-efi"
diff --git a/data/live-build-config/archives/vyos-dev.key.chroot b/data/live-build-config/archives/vyos-dev.key.chroot
index 9f306a91..a01b7486 100644
--- a/data/live-build-config/archives/vyos-dev.key.chroot
+++ b/data/live-build-config/archives/vyos-dev.key.chroot
@@ -1,5 +1,4 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v2.0.22 (GNU/Linux)
mQINBF0/MrsBEADLSj4PdgHsr4FblWqQmmZD32J3EVlXrBIwi0zT1RN6V6vA81xx
Qe8XNm6LXVB9kjH9Qv+MwIWWOkTYGCDg2oiIAKPRnJfKisDo4Ax3a1j2YOF6Ud2n
@@ -13,41 +12,41 @@ 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
-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
-FhyPysWJ4aNKtAYgVuQguPTt
-=rJUC
+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
+9Q/RplpTmdIeNjbd
+=jedA
-----END PGP PUBLIC KEY BLOCK-----
-
diff --git a/docker/vyos-dev.key b/docker/vyos-dev.key
index 9f306a91..a01b7486 100644
--- a/docker/vyos-dev.key
+++ b/docker/vyos-dev.key
@@ -1,5 +1,4 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v2.0.22 (GNU/Linux)
mQINBF0/MrsBEADLSj4PdgHsr4FblWqQmmZD32J3EVlXrBIwi0zT1RN6V6vA81xx
Qe8XNm6LXVB9kjH9Qv+MwIWWOkTYGCDg2oiIAKPRnJfKisDo4Ax3a1j2YOF6Ud2n
@@ -13,41 +12,41 @@ nekDG6H75i9szMMQGzry71+RzYMOWkUnnnQ6wjpHuce42zU7wKUdl2+Wrr+g2/cK
NKFvHRmGLVOpcabDawWi08hHr+J6Gje9PCePfY4x0p6Idjz5YW4Q1D/XSDZZ3nni
akhMO1onHLolY7jstdexhSSi7nS9bDAdnHlL7e/hJemF5G0IvLlkaXYIpQARAQAB
tDJWeU9TIG1haW50YWluZXJzIChwYWNrYWdlIHNpZ25pbmcpIDxwa2dzQHZ5b3Mu
-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
-FhyPysWJ4aNKtAYgVuQguPTt
-=rJUC
+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
+9Q/RplpTmdIeNjbd
+=jedA
-----END PGP PUBLIC KEY BLOCK-----
-
diff --git a/scripts/check-qemu-install b/scripts/check-qemu-install
index cbb2c964..49cd3d54 100755
--- a/scripts/check-qemu-install
+++ b/scripts/check-qemu-install
@@ -108,6 +108,16 @@ KEY_Y = chr(121)
mok_password = '1234'
+# Custom Secure Boot signing material (see docs.vyos.io installation/secure-boot).
+# If present, the image was signed with a custom CA and the MOK must be enrolled.
+# If absent, the image is expected to be signed by the VyOS CA and boots as-is.
+SB_CERT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data', 'certificates')
+SB_CUSTOM_KEY = os.path.join(SB_CERT_DIR, 'vyos-dev-2025-linux.key')
+SB_CUSTOM_CERT = os.path.join(SB_CERT_DIR, 'vyos-dev-2025-linux.pem')
+# Expected Linux Kernel signature certificate of a VyOS CA signed image
+SB_VYOS_ISSUER = '/CN=VyOS Networks Secure Boot CA'
+SB_VYOS_SUBJECT = '/CN=VyOS Networks Secure Boot Signer 2025 - linux'
+
# Map QEMU arch
QEMU_CONFIG = {
'amd64': {
@@ -146,7 +156,8 @@ parser.add_argument('--tpmtest', help='Execute TPM encrypted config tests',
action='store_true', default=False)
parser.add_argument('--ifnametest', help='Execute interface naming/hw-id persistence tests',
action='store_true', default=False)
-parser.add_argument('--sbtest', help='Execute Secure Boot tests',
+parser.add_argument('--secure-boot-test', help='Execute Secure Boot tests (enrolls MOK only if custom '
+ 'signing certificates exist in data/certificates)',
action='store_true', default=False)
parser.add_argument('--cloud-init', help='Execute cloud-init tests',
action='store_true', default=False)
@@ -417,20 +428,20 @@ if args.smoketest:
_primary_modes.append('--smoketest')
if args.configtest:
_primary_modes.append('--configtest')
-if args.sbtest:
- _primary_modes.append('--sbtest')
+if args.secure_boot_test:
+ _primary_modes.append('--secure-boot-test')
if len(_primary_modes) > 1:
log.error('Incompatible combination of testcase flags (%s): only one of '
'--cloud-init, --test-image-update, --tpmtest, --ifnametest, --raid, '
- '--smoketest, --configtest, --sbtest may be set.', ', '.join(_primary_modes))
+ '--smoketest, --configtest, --secure-boot-test may be set.', ', '.join(_primary_modes))
sys.exit(1)
if args.no_interfaces and not args.smoketest:
log.error('--no-interfaces requires --smoketest')
sys.exit(1)
-if args.sbtest and not args.uefi:
- log.error('--sbtest requires --uefi')
+if args.secure_boot_test and not args.uefi:
+ log.error('--secure-boot-test requires --uefi')
sys.exit(1)
if args.logfile:
@@ -466,9 +477,16 @@ if args.test_image_update and not args.iso:
OVMF_CODE = '/usr/share/OVMF/OVMF_CODE_4M.secboot.fd'
OVMF_VARS_TMP = args.disk.replace(DISK_IMAGE_EXTENSION, '.efivars')
-if args.sbtest:
+if args.secure_boot_test:
shutil.copy('/usr/share/OVMF/OVMF_VARS_4M.ms.fd', OVMF_VARS_TMP)
+sb_custom_ca = args.secure_boot_test and os.path.isfile(SB_CUSTOM_KEY) and os.path.isfile(SB_CUSTOM_CERT)
+if args.secure_boot_test:
+ if sb_custom_ca:
+ log.info('Secure Boot test: custom signing certificate found - enrolling MOK')
+ else:
+ log.info('Secure Boot test: no custom signing certificate - expecting VyOS CA signed image')
+
# Creating diskimage!!
diskname_raid = None
def gen_disk(name):
@@ -567,9 +585,10 @@ def toggleUEFISecureBoot(c):
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_RETURN)
-def BOOTLOADERchooseSerialConsole(child, live: bool, log=None) -> None:
- """ Select GRUB boot entry that uses the serial console. This differs
- between a LIVE ISO image and an already installed system. """
+def BOOTLOADERchooseSerialConsole(child, live: bool) -> None:
+ """ Select the boot entry that uses the serial console on a LIVE ISO image.
+ An already installed system boots its default entry, which already
+ uses the serial console. """
BOOTLOADER_TMO = 40
BOOTLOADER_SLEEP = 1.5
BOOTLOADER_LOAD_TMO = 5 # let GRUB screen load
@@ -616,58 +635,13 @@ def BOOTLOADERchooseSerialConsole(child, live: bool, log=None) -> None:
# Wait for GRUB
child.expect(GRUB_STRING, timeout=BOOTLOADER_TMO)
- # The installed system's top-level menu auto-boots its default
- # entry after ~BOOTLOADER_LOAD_TMO seconds, timed from when GRUB
- # itself draws the menu - not from when this script's regex match
- # on GRUB_STRING returns. Under host load the menu text can reach
- # us well after that internal countdown already started, so there
- # is no reliable amount of "send a key fast enough" that wins this
- # race every time.
- #
- # That's fine to lose: the installer always answers 'S' (serial)
- # to "What console should be used by default?", so the default
- # entry GRUB auto-boots already targets the right console.
- # waitForLogin()/loginVM(), called after this function returns,
- # already tolerate landing straight on the GRUB countdown or the
- # login prompt. So treat this submenu navigation as best-effort:
- # if we don't land in "Boot options" in time, stop navigating and
- # let the default entry (which is already auto-booting) carry on,
- # instead of raising and aborting the whole test.
- try:
- # Select GRUB serial console
- # Boot options
- child.send(KEY_DOWN)
- time.sleep(BOOTLOADER_LOAD_TMO)
- child.send(KEY_RETURN)
- time.sleep(BOOTLOADER_SLEEP)
- # GRUB submenus never time out on their own, so confirm we actually
- # landed on this submenu before navigating further - otherwise a
- # dropped keypress leaves the VM stuck here until the login wait
- # elsewhere expires
- child.expect('Select console type', timeout=BOOTLOADER_TMO)
- except pexpect.TIMEOUT:
- if log is not None:
- log.warning('GRUB auto-booted the default entry before "Boot '
- 'options" navigation completed; continuing since '
- 'the default entry already boots the serial '
- 'console selected during install')
- else:
- # We're inside the submenu, so a timeout past this point is a
- # real navigation bug, not the auto-boot race - let it propagate.
- # Select console type
- child.send(KEY_DOWN)
- time.sleep(BOOTLOADER_SLEEP)
- child.send(KEY_RETURN)
- time.sleep(BOOTLOADER_SLEEP)
- child.expect(r'ttyS \(serial\)', timeout=BOOTLOADER_TMO)
-
- # *ttyS (serial)
- child.send(KEY_DOWN)
- time.sleep(BOOTLOADER_SLEEP)
- child.send(KEY_RETURN)
- time.sleep(BOOTLOADER_SLEEP)
- # Boot
- child.send(KEY_RETURN)
+ # Do not navigate the installed system's GRUB menu. The installer
+ # already made the serial console the default (we answer 'S' to
+ # "What console should be used by default?", raw images get it from
+ # the build flavor), so the default entry boots the right console.
+ # Steering the menu with timed keypresses raced GRUB's auto-boot
+ # countdown and lost keypresses under host load (T8147, T9099,
+ # T9214). basic_cli_tests() verifies the console settings.
return None
@@ -950,7 +924,7 @@ def _image_update_cli_sequence(c, log, new_image_name, server_bind_host='127.0.0
if args.qemu_cmd:
tmp = get_qemu_cmd(qemu_name, args.uefi, args.disk, raid=diskname_raid,
- iso_img=args.iso, vnc_enabled=args.vnc, secure_boot=args.sbtest,
+ iso_img=args.iso, vnc_enabled=args.vnc, secure_boot=args.secure_boot_test,
nested_cdrom_iso=nested_payload_iso_path)
os.system(tmp)
exit(0)
@@ -1010,20 +984,26 @@ try:
log.info('Installing system')
cmd = get_qemu_cmd(qemu_name, args.uefi, args.disk, raid=diskname_raid,
tpm=args.tpmtest, iso_img=args.iso, vnc_enabled=args.vnc,
- secure_boot=args.sbtest, nested_cdrom_iso=nested_payload_iso_path)
+ secure_boot=args.secure_boot_test, nested_cdrom_iso=nested_payload_iso_path)
log.debug(f'Executing command: {cmd}')
c = pexpect.spawn(cmd, logfile=stl, timeout=60)
#################################################
# Logging into VyOS system
#################################################
- if args.sbtest:
+ if sb_custom_ca:
log.info('Disable UEFI Secure Boot for initial installation')
toggleUEFISecureBoot(c)
- BOOTLOADERchooseSerialConsole(c, live=(not args.cloud_init), log=log)
+ BOOTLOADERchooseSerialConsole(c, live=(not args.cloud_init))
loginVM(c, log)
+ if args.secure_boot_test and not sb_custom_ca:
+ log.info('Verify live system booted with UEFI Secure Boot enabled')
+ c.sendline('show secure-boot')
+ c.expect('SecureBoot enabled')
+ c.expect(op_mode_prompt)
+
#################################################
# Cloud-Init comes with a pre-assembled ISO - just boot and test it
#################################################
@@ -1120,9 +1100,11 @@ try:
c.expect('\nWhich file would you like as boot config?.*')
c.sendline('')
- c.expect(op_mode_prompt)
+ # GRUB installation and unmounting (flushing the copied squashfs to disk)
+ # can take longer than the default pexpect timeout on large images
+ c.expect(op_mode_prompt, timeout=300)
- if args.sbtest:
+ if sb_custom_ca:
c.sendline('install mok')
c.expect('input password:.*')
c.sendline(mok_password)
@@ -1136,7 +1118,7 @@ try:
#################################################
# SHIM Mok Manager
#################################################
- if args.sbtest:
+ if sb_custom_ca:
log.info('Install Secure Boot Machine Owner Key')
MOK_SLEEP = 0.5
c.expect('BdsDxe: starting Boot00.*')
@@ -1174,7 +1156,7 @@ try:
#################################################
# Re-Enable Secure Boot
#################################################
- if args.sbtest:
+ if sb_custom_ca:
log.info('Enable UEFI Secure Boot for initial installation')
toggleUEFISecureBoot(c)
@@ -1189,7 +1171,7 @@ try:
# Booting installed system
#################################################
log.info('Booting installed system')
- BOOTLOADERchooseSerialConsole(c, live=False, log=log)
+ BOOTLOADERchooseSerialConsole(c, live=False)
#################################################
# Logging into VyOS system
@@ -1804,10 +1786,19 @@ try:
c.sendline(f'sudo umount {NESTED_HTTP_MOUNT_POINT}')
c.expect(op_mode_prompt)
log.info('Nested installer ISO testcase complete')
- elif args.sbtest:
+ elif args.secure_boot_test:
c.sendline('show secure-boot')
c.expect('SecureBoot enabled')
c.expect(op_mode_prompt)
+
+ c.sendline('show secure-boot detail')
+ if sb_custom_ca:
+ c.expect('Issuer: ')
+ else:
+ log.info('Verify Linux Kernel is signed by the VyOS Secure Boot CA')
+ c.expect(re.escape(f'Issuer: {SB_VYOS_ISSUER}'))
+ c.expect(re.escape(f'Subject: {SB_VYOS_SUBJECT}'))
+ c.expect(op_mode_prompt)
else:
log.info('No testcase selected!')
@@ -1858,7 +1849,7 @@ if not args.keep:
os.remove(args.disk)
if diskname_raid:
os.remove(diskname_raid)
- if args.sbtest:
+ if args.secure_boot_test:
os.remove(OVMF_VARS_TMP)
except Exception:
log.error('Exception while removing diskimage!')
diff --git a/scripts/package-build/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch b/scripts/package-build/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch
index f493cf73..ce711365 100644
--- a/scripts/package-build/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch
+++ b/scripts/package-build/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch
@@ -135,10 +135,10 @@ index 80706368a303..d4d2be91c624 100644
.procname = "ioam6_id",
.data = &ipv6_devconf.ioam6_id,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
-index 71a38034f5ca..0ebe9fabb896 100644
+index e99b4901091a..8737bc69d9c4 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
-@@ -717,6 +717,14 @@ static inline void rt6_probe(struct fib6_nh *fib6_nh)
+@@ -718,6 +718,14 @@ static inline void rt6_probe(struct fib6_nh *fib6_nh)
}
#endif
@@ -153,7 +153,7 @@ index 71a38034f5ca..0ebe9fabb896 100644
/*
* Default Router Selection (RFC 2461 6.3.6)
*/
-@@ -758,6 +766,8 @@ static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif,
+@@ -759,6 +767,8 @@ static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif,
if (!m && (strict & RT6_LOOKUP_F_IFACE))
return RT6_NUD_FAIL_HARD;