Compare commits
22 Commits
ecc20d8a49
...
583e509c4c
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | 583e509c4c | |
Daan De Meyer | 0e44a351ea | |
Luca Boccassi | 94eacb9329 | |
Daan De Meyer | f458a60391 | |
Daan De Meyer | ceca7c5005 | |
Daan De Meyer | 4f969b20b0 | |
Daan De Meyer | d6047d9fb5 | |
Daan De Meyer | a2aacbfad5 | |
Daan De Meyer | 6d2fd490cf | |
Daan De Meyer | c859b310ed | |
Daan De Meyer | 51cd3dec2a | |
Daan De Meyer | fdc4706850 | |
Daan De Meyer | 506403f561 | |
Daan De Meyer | 6fd5df6005 | |
Daan De Meyer | a197604af4 | |
Vito Caputo | 4f3df8c1bb | |
白一百 | 8c18851e7e | |
Yu Watanabe | 5b2926d941 | |
Ani Sinha | 4b356c90dc | |
Léane GRASSER | f28e16d14e | |
Zbigniew Jędrzejewski-Szmek | 0e54562082 | |
Zbigniew Jędrzejewski-Szmek | 03af199aaf |
|
@ -37,7 +37,7 @@ jobs:
|
|||
VALIDATE_GITHUB_ACTIONS: true
|
||||
|
||||
- name: Check that tabs are not used in Python code
|
||||
run: sh -c '! git grep -P "\\t" -- src/ukify/ukify.py'
|
||||
run: sh -c '! git grep -P "\\t" -- src/ukify/ukify.py test/integration-test-wrapper.py'
|
||||
|
||||
- name: Install ruff and mypy
|
||||
run: |
|
||||
|
@ -47,14 +47,14 @@ jobs:
|
|||
- name: Run mypy
|
||||
run: |
|
||||
python3 -m mypy --version
|
||||
python3 -m mypy src/ukify/ukify.py
|
||||
python3 -m mypy src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
|
||||
- name: Run ruff check
|
||||
run: |
|
||||
ruff --version
|
||||
ruff check src/ukify/ukify.py
|
||||
ruff check src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
|
||||
- name: Run ruff format
|
||||
run: |
|
||||
ruff --version
|
||||
ruff format --check src/ukify/ukify.py
|
||||
ruff format --check src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
|
|
|
@ -105,7 +105,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
- uses: systemd/mkosi@8976a0abb19221e65300222f2d33067970cca0f1
|
||||
- uses: systemd/mkosi@0825cca8084674ec8fa27502134b1bc601f79e0c
|
||||
|
||||
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
|
||||
# immediately, we remove the files in the background. However, we first move them to a different location
|
||||
|
|
3
NEWS
3
NEWS
|
@ -764,6 +764,9 @@ CHANGES WITH 257 in spe:
|
|||
other cases EnterNamespace= might be an suitable approach to acquire
|
||||
symbolized backtraces.)
|
||||
|
||||
Special thanks to Nick Owens for bringing attention to and testing
|
||||
fixes for issue #34516.
|
||||
|
||||
Contributions from: 12paper, A. Wilcox, Abderrahim Kitouni,
|
||||
Adrian Vovk, Alain Greppin, Allison Karlitskaya, Alyssa Ross,
|
||||
Anders Jonsson, Andika Triwidada, Andres Beltran, Anouk Ceyssens,
|
||||
|
|
|
@ -295,6 +295,10 @@ sensor:modalias:acpi:MXC6655*:dmi:*:svnCHUWIInnovationAndTechnology*:pnHi10X:*
|
|||
sensor:modalias:acpi:KIOX000A*:dmi:*:svnCHUWIInnovationAndTechnology*:pnHi10X:*
|
||||
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
|
||||
|
||||
# Chuwi Hi10 X1
|
||||
sensor:modalias:acpi:NSA2513*:dmi:*:svnCHUWIInnovationAndTechnology*:pnHi10X1:*
|
||||
ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1
|
||||
|
||||
# Chuwi Hi10 Go
|
||||
sensor:modalias:acpi:MXC6655*:dmi:*:svnCHUWIINNOVATIONLIMITED:pnHi10Go:*
|
||||
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0,-1, 0; 0, 0, 1
|
||||
|
|
10
mkosi.clangd
10
mkosi.clangd
|
@ -1,12 +1,18 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
MKOSI_CONFIG="$(mkosi --json summary | jq -r .Images[-1])"
|
||||
if command -v flatpak-spawn >/dev/null; then
|
||||
SPAWN=(flatpak-spawn --host)
|
||||
else
|
||||
SPAWN=()
|
||||
fi
|
||||
|
||||
MKOSI_CONFIG="$("${SPAWN[@]}" --host mkosi --json summary | jq -r .Images[-1])"
|
||||
DISTRIBUTION="$(jq -r .Distribution <<< "$MKOSI_CONFIG")"
|
||||
RELEASE="$(jq -r .Release <<< "$MKOSI_CONFIG")"
|
||||
ARCH="$(jq -r .Architecture <<< "$MKOSI_CONFIG")"
|
||||
|
||||
exec mkosi \
|
||||
exec "${SPAWN[@]}" mkosi \
|
||||
--incremental=strict \
|
||||
--build-sources-ephemeral=no \
|
||||
--format=none \
|
||||
|
|
|
@ -6,10 +6,12 @@ ToolsTreeDistribution=arch
|
|||
[Build]
|
||||
ToolsTreePackages=
|
||||
cryptsetup
|
||||
github-cli
|
||||
libcap
|
||||
libmicrohttpd
|
||||
python-jinja
|
||||
python-pytest
|
||||
ruff
|
||||
shellcheck
|
||||
tpm2-tss
|
||||
util-linux-libs
|
||||
|
|
|
@ -16,3 +16,4 @@ ToolsTreePackages=
|
|||
tpm2-tss-devel
|
||||
python3-jinja2
|
||||
python3-pytest
|
||||
shellcheck
|
||||
|
|
|
@ -6,6 +6,7 @@ ToolsTreeDistribution=|ubuntu
|
|||
|
||||
[Build]
|
||||
ToolsTreePackages=
|
||||
gh
|
||||
libblkid-dev
|
||||
libcap-dev
|
||||
libcryptsetup-dev
|
||||
|
@ -16,3 +17,4 @@ ToolsTreePackages=
|
|||
libtss2-dev
|
||||
python3-jinja2
|
||||
python3-pytest
|
||||
shellcheck
|
||||
|
|
|
@ -5,4 +5,5 @@ ToolsTreeDistribution=fedora
|
|||
|
||||
[Build]
|
||||
ToolsTreePackages=
|
||||
gh
|
||||
ruff
|
||||
|
|
|
@ -5,6 +5,7 @@ ToolsTreeDistribution=opensuse
|
|||
|
||||
[Build]
|
||||
ToolsTreePackages=
|
||||
gh
|
||||
pkgconfig(blkid)
|
||||
pkgconfig(libcap)
|
||||
pkgconfig(libcryptsetup)
|
||||
|
@ -16,3 +17,4 @@ ToolsTreePackages=
|
|||
tss2-devel
|
||||
python3-jinja2
|
||||
python3-pytest
|
||||
ShellCheck
|
||||
|
|
|
@ -13,6 +13,7 @@ Environment=
|
|||
|
||||
[Content]
|
||||
Packages=
|
||||
clang-devel
|
||||
compiler-rt
|
||||
gdb
|
||||
git-core
|
||||
|
|
|
@ -15,6 +15,7 @@ Environment=
|
|||
[Content]
|
||||
Packages=
|
||||
apt
|
||||
clangd
|
||||
erofs-utils
|
||||
git-core
|
||||
libclang-rt-dev
|
||||
|
|
|
@ -12,6 +12,7 @@ Environment=
|
|||
|
||||
[Content]
|
||||
Packages=
|
||||
clang
|
||||
diffutils
|
||||
erofs-utils
|
||||
gcc-c++
|
||||
|
|
|
@ -57,6 +57,8 @@ wrap=(
|
|||
delv
|
||||
dhcpd
|
||||
dig
|
||||
dnf
|
||||
dnf5
|
||||
dmsetup
|
||||
dnsmasq
|
||||
findmnt
|
||||
|
@ -93,7 +95,7 @@ wrap=(
|
|||
)
|
||||
|
||||
for bin in "${wrap[@]}"; do
|
||||
if ! mkosi-chroot command -v "$bin" >/dev/null; then
|
||||
if ! mkosi-chroot bash -c "command -v $bin" >/dev/null; then
|
||||
continue
|
||||
fi
|
||||
|
||||
|
@ -103,7 +105,7 @@ for bin in "${wrap[@]}"; do
|
|||
enable_lsan=0
|
||||
fi
|
||||
|
||||
target="$(mkosi-chroot command -v "$bin")"
|
||||
target="$(mkosi-chroot bash -c "command -v $bin")"
|
||||
|
||||
mv "$BUILDROOT/$target" "$BUILDROOT/$target.orig"
|
||||
|
||||
|
|
4
po/fr.po
4
po/fr.po
|
@ -12,7 +12,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-11-06 14:42+0000\n"
|
||||
"PO-Revision-Date: 2024-11-20 19:13+0000\n"
|
||||
"PO-Revision-Date: 2024-11-23 10:38+0000\n"
|
||||
"Last-Translator: Léane GRASSER <leane.grasser@proton.me>\n"
|
||||
"Language-Team: French <https://translate.fedoraproject.org/projects/systemd/"
|
||||
"main/fr/>\n"
|
||||
|
@ -1258,7 +1258,7 @@ msgstr ""
|
|||
|
||||
#: src/sysupdate/org.freedesktop.sysupdate1.policy:75
|
||||
msgid "Manage optional features"
|
||||
msgstr "Gérer les fonctionnalités en option"
|
||||
msgstr "Gérer les fonctionnalités facultatives"
|
||||
|
||||
#: src/sysupdate/org.freedesktop.sysupdate1.policy:76
|
||||
msgid "Authentication is required to manage optional features"
|
||||
|
|
|
@ -75,6 +75,10 @@ static int curl_glue_socket_callback(CURL *curl, curl_socket_t s, int action, vo
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Don't configure io event source anymore when the event loop is dead already. */
|
||||
if (g->event && sd_event_get_state(g->event) == SD_EVENT_FINISHED)
|
||||
return 0;
|
||||
|
||||
r = hashmap_ensure_allocated(&g->ios, &trivial_hash_ops);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
|
|
|
@ -234,7 +234,7 @@ static int handle_action_execute(
|
|||
/* If the actual operation is inhibited, warn and fail */
|
||||
if (inhibit_what_is_valid(inhibit_operation) &&
|
||||
!ignore_inhibited &&
|
||||
manager_is_inhibited(m, inhibit_operation, /* block= */ true, NULL, false, false, 0, &offending)) {
|
||||
manager_is_inhibited(m, inhibit_operation, NULL, /* flags= */ 0, UID_INVALID, &offending)) {
|
||||
_cleanup_free_ char *comm = NULL, *u = NULL;
|
||||
|
||||
(void) pidref_get_comm(&offending->pid, &comm);
|
||||
|
@ -372,7 +372,7 @@ int manager_handle_action(
|
|||
|
||||
/* If the key handling is inhibited, don't do anything */
|
||||
if (inhibit_key > 0) {
|
||||
if (manager_is_inhibited(m, inhibit_key, /* block= */ true, NULL, true, false, 0, NULL)) {
|
||||
if (manager_is_inhibited(m, inhibit_key, NULL, MANAGER_IS_INHIBITED_IGNORE_INACTIVE, UID_INVALID, NULL)) {
|
||||
log_debug("Refusing %s operation, %s is inhibited.",
|
||||
handle_action_to_string(handle),
|
||||
inhibit_what_to_string(inhibit_key));
|
||||
|
|
|
@ -411,7 +411,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
|
|||
|
||||
assert(m);
|
||||
|
||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, /* block= */ true, t, false, false, 0, NULL);
|
||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, t, /* flags= */ 0, UID_INVALID, NULL);
|
||||
|
||||
HASHMAP_FOREACH(s, m->sessions) {
|
||||
dual_timestamp k;
|
||||
|
|
|
@ -1931,7 +1931,12 @@ int manager_dispatch_delayed(Manager *manager, bool timeout) {
|
|||
if (!manager->delayed_action || manager->action_job)
|
||||
return 0;
|
||||
|
||||
if (manager_is_inhibited(manager, manager->delayed_action->inhibit_what, /* block= */ false, NULL, false, false, 0, &offending)) {
|
||||
if (manager_is_inhibited(manager,
|
||||
manager->delayed_action->inhibit_what,
|
||||
NULL,
|
||||
MANAGER_IS_INHIBITED_CHECK_DELAY,
|
||||
UID_INVALID,
|
||||
&offending)) {
|
||||
_cleanup_free_ char *comm = NULL, *u = NULL;
|
||||
|
||||
if (!timeout)
|
||||
|
@ -2033,7 +2038,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(
|
|||
|
||||
delayed =
|
||||
m->inhibit_delay_max > 0 &&
|
||||
manager_is_inhibited(m, a->inhibit_what, /* block= */ false, NULL, false, false, 0, NULL);
|
||||
manager_is_inhibited(m, a->inhibit_what, NULL, MANAGER_IS_INHIBITED_CHECK_DELAY, UID_INVALID, NULL);
|
||||
|
||||
if (delayed)
|
||||
/* Shutdown is delayed, keep in mind what we
|
||||
|
@ -2077,7 +2082,7 @@ static int verify_shutdown_creds(
|
|||
return r;
|
||||
|
||||
multiple_sessions = r > 0;
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, /* block= */ true, NULL, false, true, uid, &offending);
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, NULL, /* flags= */ 0, uid, &offending);
|
||||
interactive = flags & SD_LOGIND_INTERACTIVE;
|
||||
|
||||
if (multiple_sessions) {
|
||||
|
@ -2820,7 +2825,7 @@ static int method_can_shutdown_or_sleep(
|
|||
return r;
|
||||
|
||||
multiple_sessions = r > 0;
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, /* block= */ true, NULL, false, true, uid, NULL);
|
||||
blocked = manager_is_inhibited(m, a->inhibit_what, NULL, /* flags= */ 0, uid, NULL);
|
||||
|
||||
if (check_unit_state && a->target) {
|
||||
_cleanup_free_ char *load_state = NULL;
|
||||
|
|
|
@ -399,11 +399,9 @@ static int pidref_is_active_session(Manager *m, const PidRef *pid) {
|
|||
bool manager_is_inhibited(
|
||||
Manager *m,
|
||||
InhibitWhat w,
|
||||
bool block,
|
||||
dual_timestamp *since,
|
||||
bool ignore_inactive,
|
||||
bool ignore_uid,
|
||||
uid_t uid,
|
||||
ManagerIsInhibitedFlags flags,
|
||||
uid_t uid_to_ignore,
|
||||
Inhibitor **ret_offending) {
|
||||
|
||||
Inhibitor *i, *offending = NULL;
|
||||
|
@ -421,18 +419,19 @@ bool manager_is_inhibited(
|
|||
if (!(i->what & w))
|
||||
continue;
|
||||
|
||||
if ((block && !IN_SET(i->mode, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK)) ||
|
||||
(!block && i->mode != INHIBIT_DELAY))
|
||||
if ((flags & MANAGER_IS_INHIBITED_CHECK_DELAY) != (i->mode == INHIBIT_DELAY))
|
||||
continue;
|
||||
|
||||
if (ignore_inactive && pidref_is_active_session(m, &i->pid) <= 0)
|
||||
if ((flags & MANAGER_IS_INHIBITED_IGNORE_INACTIVE) &&
|
||||
pidref_is_active_session(m, &i->pid) <= 0)
|
||||
continue;
|
||||
|
||||
if (i->mode == INHIBIT_BLOCK_WEAK && ignore_uid && i->uid == uid)
|
||||
if (i->mode == INHIBIT_BLOCK_WEAK &&
|
||||
uid_is_valid(uid_to_ignore) &&
|
||||
uid_to_ignore == i->uid)
|
||||
continue;
|
||||
|
||||
if (!inhibited ||
|
||||
i->since.monotonic < ts.monotonic)
|
||||
if (!inhibited || i->since.monotonic < ts.monotonic)
|
||||
ts = i->since;
|
||||
|
||||
inhibited = true;
|
||||
|
|
|
@ -67,7 +67,20 @@ int inhibitor_create_fifo(Inhibitor *i);
|
|||
bool inhibitor_is_orphan(Inhibitor *i);
|
||||
|
||||
InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mode);
|
||||
bool manager_is_inhibited(Manager *m, InhibitWhat w, bool block, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid, Inhibitor **offending);
|
||||
|
||||
typedef enum ManagerIsInhibitedFlags {
|
||||
MANAGER_IS_INHIBITED_CHECK_DELAY = 1 << 0, /* When set, we only check delay inhibitors.
|
||||
* Otherwise, we only check block inhibitors. */
|
||||
MANAGER_IS_INHIBITED_IGNORE_INACTIVE = 1 << 1, /* When set, ignore inactive sessions. */
|
||||
} ManagerIsInhibitedFlags;
|
||||
|
||||
bool manager_is_inhibited(
|
||||
Manager *m,
|
||||
InhibitWhat w,
|
||||
dual_timestamp *since,
|
||||
ManagerIsInhibitedFlags flags,
|
||||
uid_t uid_to_ignore,
|
||||
Inhibitor **ret_offending);
|
||||
|
||||
static inline bool inhibit_what_is_valid(InhibitWhat w) {
|
||||
return w > 0 && w < _INHIBIT_WHAT_MAX;
|
||||
|
|
|
@ -101,18 +101,19 @@ static int help(int argc, char *argv[], void *userdata) {
|
|||
" -j Same as --json=pretty on tty, --json=short otherwise\n"
|
||||
" --append=PATH Load specified JSON signature, and append new signature to it\n"
|
||||
"\n%3$sUKI PE Section Options:%4$s %3$sUKI PE Section%4$s\n"
|
||||
" --linux=PATH Path to Linux kernel image file %7$s .linux\n"
|
||||
" --osrel=PATH Path to os-release file %7$s .osrel\n"
|
||||
" --cmdline=PATH Path to file with kernel command line %7$s .cmdline\n"
|
||||
" --initrd=PATH Path to initrd image file %7$s .initrd\n"
|
||||
" --ucode=PATH Path to microcode image file %7$s .ucode\n"
|
||||
" --splash=PATH Path to splash bitmap file %7$s .splash\n"
|
||||
" --dtb=PATH Path to DeviceTree file %7$s .dtb\n"
|
||||
" --uname=PATH Path to 'uname -r' file %7$s .uname\n"
|
||||
" --sbat=PATH Path to SBAT file %7$s .sbat\n"
|
||||
" --pcrpkey=PATH Path to public key for PCR signatures %7$s .pcrpkey\n"
|
||||
" --profile=PATH Path to profile file %7$s .profile\n"
|
||||
" --hwids=PATH Path to HWIDs file %7$s .hwids\n"
|
||||
" --linux=PATH Path to Linux kernel image file %7$s .linux\n"
|
||||
" --osrel=PATH Path to os-release file %7$s .osrel\n"
|
||||
" --cmdline=PATH Path to file with kernel command line %7$s .cmdline\n"
|
||||
" --initrd=PATH Path to initrd image file %7$s .initrd\n"
|
||||
" --ucode=PATH Path to microcode image file %7$s .ucode\n"
|
||||
" --splash=PATH Path to splash bitmap file %7$s .splash\n"
|
||||
" --dtb=PATH Path to DeviceTree file %7$s .dtb\n"
|
||||
" --dtbauto=PATH Path to DeviceTree file for auto selection %7$s .dtbauto\n"
|
||||
" --uname=PATH Path to 'uname -r' file %7$s .uname\n"
|
||||
" --sbat=PATH Path to SBAT file %7$s .sbat\n"
|
||||
" --pcrpkey=PATH Path to public key for PCR signatures %7$s .pcrpkey\n"
|
||||
" --profile=PATH Path to profile file %7$s .profile\n"
|
||||
" --hwids=PATH Path to HWIDs file %7$s .hwids\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
program_invocation_short_name,
|
||||
link,
|
||||
|
|
|
@ -467,7 +467,7 @@ class SignTool:
|
|||
raise NotImplementedError()
|
||||
|
||||
@staticmethod
|
||||
def from_string(name) -> type['SignTool']:
|
||||
def from_string(name: str) -> type['SignTool']:
|
||||
if name == 'pesign':
|
||||
return PeSign
|
||||
elif name == 'sbsign':
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
'''Test wrapper command for driving integration tests.
|
||||
'''
|
||||
"""Test wrapper command for driving integration tests."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
|
@ -13,7 +12,6 @@ import sys
|
|||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
EMERGENCY_EXIT_DROPIN = """\
|
||||
[Unit]
|
||||
Wants=emergency-exit.service
|
||||
|
@ -34,7 +32,7 @@ ExecStart=false
|
|||
"""
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--mkosi', required=True)
|
||||
parser.add_argument('--meson-source-dir', required=True, type=Path)
|
||||
|
@ -46,34 +44,43 @@ def main():
|
|||
parser.add_argument('--slow', action=argparse.BooleanOptionalAction)
|
||||
parser.add_argument('--vm', action=argparse.BooleanOptionalAction)
|
||||
parser.add_argument('--exit-code', required=True, type=int)
|
||||
parser.add_argument('mkosi_args', nargs="*")
|
||||
parser.add_argument('mkosi_args', nargs='*')
|
||||
args = parser.parse_args()
|
||||
|
||||
if not bool(int(os.getenv("SYSTEMD_INTEGRATION_TESTS", "0"))):
|
||||
print(f"SYSTEMD_INTEGRATION_TESTS=1 not found in environment, skipping {args.name}", file=sys.stderr)
|
||||
if not bool(int(os.getenv('SYSTEMD_INTEGRATION_TESTS', '0'))):
|
||||
print(
|
||||
f'SYSTEMD_INTEGRATION_TESTS=1 not found in environment, skipping {args.name}',
|
||||
file=sys.stderr,
|
||||
)
|
||||
exit(77)
|
||||
|
||||
if args.slow and not bool(int(os.getenv("SYSTEMD_SLOW_TESTS", "0"))):
|
||||
print(f"SYSTEMD_SLOW_TESTS=1 not found in environment, skipping {args.name}", file=sys.stderr)
|
||||
if args.slow and not bool(int(os.getenv('SYSTEMD_SLOW_TESTS', '0'))):
|
||||
print(
|
||||
f'SYSTEMD_SLOW_TESTS=1 not found in environment, skipping {args.name}',
|
||||
file=sys.stderr,
|
||||
)
|
||||
exit(77)
|
||||
|
||||
if args.vm and bool(int(os.getenv("TEST_NO_QEMU", "0"))):
|
||||
print(f"TEST_NO_QEMU=1, skipping {args.name}", file=sys.stderr)
|
||||
if args.vm and bool(int(os.getenv('TEST_NO_QEMU', '0'))):
|
||||
print(f'TEST_NO_QEMU=1, skipping {args.name}', file=sys.stderr)
|
||||
exit(77)
|
||||
|
||||
for s in os.getenv("TEST_SKIP", "").split():
|
||||
for s in os.getenv('TEST_SKIP', '').split():
|
||||
if s in args.name:
|
||||
print(f"Skipping {args.name} due to TEST_SKIP", file=sys.stderr)
|
||||
print(f'Skipping {args.name} due to TEST_SKIP', file=sys.stderr)
|
||||
exit(77)
|
||||
|
||||
keep_journal = os.getenv("TEST_SAVE_JOURNAL", "fail")
|
||||
shell = bool(int(os.getenv("TEST_SHELL", "0")))
|
||||
keep_journal = os.getenv('TEST_SAVE_JOURNAL', 'fail')
|
||||
shell = bool(int(os.getenv('TEST_SHELL', '0')))
|
||||
|
||||
if shell and not sys.stderr.isatty():
|
||||
print(f"--interactive must be passed to meson test to use TEST_SHELL=1", file=sys.stderr)
|
||||
print(
|
||||
'--interactive must be passed to meson test to use TEST_SHELL=1',
|
||||
file=sys.stderr,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
name = args.name + (f"-{i}" if (i := os.getenv("MESON_TEST_ITERATION")) else "")
|
||||
name = args.name + (f'-{i}' if (i := os.getenv('MESON_TEST_ITERATION')) else '')
|
||||
|
||||
dropin = textwrap.dedent(
|
||||
"""\
|
||||
|
@ -84,14 +91,14 @@ def main():
|
|||
|
||||
if not shell:
|
||||
dropin += textwrap.dedent(
|
||||
f"""
|
||||
"""
|
||||
[Unit]
|
||||
SuccessAction=exit
|
||||
SuccessActionExitStatus=123
|
||||
"""
|
||||
)
|
||||
|
||||
if os.getenv("TEST_MATCH_SUBTEST"):
|
||||
if os.getenv('TEST_MATCH_SUBTEST'):
|
||||
dropin += textwrap.dedent(
|
||||
f"""
|
||||
[Service]
|
||||
|
@ -99,7 +106,7 @@ def main():
|
|||
"""
|
||||
)
|
||||
|
||||
if os.getenv("TEST_MATCH_TESTCASE"):
|
||||
if os.getenv('TEST_MATCH_TESTCASE'):
|
||||
dropin += textwrap.dedent(
|
||||
f"""
|
||||
[Service]
|
||||
|
@ -116,7 +123,7 @@ def main():
|
|||
"""
|
||||
)
|
||||
|
||||
journal_file = (args.meson_build_dir / (f"test/journal/{name}.journal")).absolute()
|
||||
journal_file = (args.meson_build_dir / (f'test/journal/{name}.journal')).absolute()
|
||||
journal_file.unlink(missing_ok=True)
|
||||
elif not shell:
|
||||
dropin += textwrap.dedent(
|
||||
|
@ -136,54 +143,60 @@ def main():
|
|||
*(['--forward-journal', journal_file] if journal_file else []),
|
||||
*(
|
||||
[
|
||||
'--credential',
|
||||
f"systemd.extra-unit.emergency-exit.service={shlex.quote(EMERGENCY_EXIT_SERVICE)}",
|
||||
'--credential',
|
||||
f"systemd.unit-dropin.emergency.target={shlex.quote(EMERGENCY_EXIT_DROPIN)}",
|
||||
'--credential', f'systemd.extra-unit.emergency-exit.service={shlex.quote(EMERGENCY_EXIT_SERVICE)}', # noqa: E501
|
||||
'--credential', f'systemd.unit-dropin.emergency.target={shlex.quote(EMERGENCY_EXIT_DROPIN)}',
|
||||
]
|
||||
if not sys.stderr.isatty()
|
||||
else []
|
||||
),
|
||||
'--credential',
|
||||
f"systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}",
|
||||
'--credential', f'systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}',
|
||||
'--runtime-network=none',
|
||||
'--runtime-scratch=no',
|
||||
*args.mkosi_args,
|
||||
'--qemu-firmware', args.firmware,
|
||||
*(['--qemu-kvm', 'no'] if int(os.getenv("TEST_NO_KVM", "0")) else []),
|
||||
'--qemu-firmware',
|
||||
args.firmware,
|
||||
*(['--qemu-kvm', 'no'] if int(os.getenv('TEST_NO_KVM', '0')) else []),
|
||||
'--kernel-command-line-extra',
|
||||
' '.join([
|
||||
'systemd.hostname=H',
|
||||
f"SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/{args.name}.units:/usr/lib/systemd/tests/testdata/units:",
|
||||
*([f"systemd.unit={args.unit}"] if not shell else []),
|
||||
'systemd.mask=systemd-networkd-wait-online.service',
|
||||
*(
|
||||
[
|
||||
"systemd.mask=serial-getty@.service",
|
||||
"systemd.show_status=error",
|
||||
"systemd.crash_shell=0",
|
||||
"systemd.crash_action=poweroff",
|
||||
]
|
||||
if not sys.stderr.isatty()
|
||||
else []
|
||||
),
|
||||
]),
|
||||
' '.join(
|
||||
[
|
||||
'systemd.hostname=H',
|
||||
f'SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/{args.name}.units:/usr/lib/systemd/tests/testdata/units:',
|
||||
*([f'systemd.unit={args.unit}'] if not shell else []),
|
||||
'systemd.mask=systemd-networkd-wait-online.service',
|
||||
*(
|
||||
[
|
||||
'systemd.mask=serial-getty@.service',
|
||||
'systemd.show_status=error',
|
||||
'systemd.crash_shell=0',
|
||||
'systemd.crash_action=poweroff',
|
||||
]
|
||||
if not sys.stderr.isatty()
|
||||
else []
|
||||
),
|
||||
]
|
||||
),
|
||||
'--credential', f"journal.storage={'persistent' if sys.stderr.isatty() else args.storage}",
|
||||
*(['--runtime-build-sources=no'] if not sys.stderr.isatty() else []),
|
||||
'qemu' if args.vm or os.getuid() != 0 else 'boot',
|
||||
]
|
||||
] # fmt: skip
|
||||
|
||||
result = subprocess.run(cmd)
|
||||
|
||||
# On Debian/Ubuntu we get a lot of random QEMU crashes. Retry once, and then skip if it fails again.
|
||||
if args.vm and result.returncode == 247 and args.exit_code != 247:
|
||||
journal_file.unlink(missing_ok=True)
|
||||
if journal_file:
|
||||
journal_file.unlink(missing_ok=True)
|
||||
result = subprocess.run(cmd)
|
||||
if args.vm and result.returncode == 247 and args.exit_code != 247:
|
||||
print(f"Test {args.name} failed due to QEMU crash (error 247), ignoring", file=sys.stderr)
|
||||
print(
|
||||
f'Test {args.name} failed due to QEMU crash (error 247), ignoring',
|
||||
file=sys.stderr,
|
||||
)
|
||||
exit(77)
|
||||
|
||||
if journal_file and (keep_journal == "0" or (result.returncode in (args.exit_code, 77) and keep_journal == "fail")):
|
||||
if journal_file and (
|
||||
keep_journal == '0' or (result.returncode in (args.exit_code, 77) and keep_journal == 'fail')
|
||||
):
|
||||
journal_file.unlink(missing_ok=True)
|
||||
|
||||
if shell or result.returncode in (args.exit_code, 77):
|
||||
|
@ -192,31 +205,33 @@ def main():
|
|||
if journal_file:
|
||||
ops = []
|
||||
|
||||
if os.getenv("GITHUB_ACTIONS"):
|
||||
id = os.environ["GITHUB_RUN_ID"]
|
||||
iteration = os.environ["GITHUB_RUN_ATTEMPT"]
|
||||
if os.getenv('GITHUB_ACTIONS'):
|
||||
id = os.environ['GITHUB_RUN_ID']
|
||||
iteration = os.environ['GITHUB_RUN_ATTEMPT']
|
||||
j = json.loads(
|
||||
subprocess.run(
|
||||
[
|
||||
args.mkosi,
|
||||
"--directory", os.fspath(args.meson_source_dir),
|
||||
"--json",
|
||||
"summary",
|
||||
'--directory', os.fspath(args.meson_source_dir),
|
||||
'--json',
|
||||
'summary',
|
||||
],
|
||||
stdout=subprocess.PIPE,
|
||||
text=True,
|
||||
).stdout
|
||||
)
|
||||
distribution = j["Images"][-1]["Distribution"]
|
||||
release = j["Images"][-1]["Release"]
|
||||
artifact = f"ci-mkosi-{id}-{iteration}-{distribution}-{release}-failed-test-journals"
|
||||
ops += [f"gh run download {id} --name {artifact} -D ci/{artifact}"]
|
||||
journal_file = Path(f"ci/{artifact}/test/journal/{name}.journal")
|
||||
) # fmt: skip
|
||||
distribution = j['Images'][-1]['Distribution']
|
||||
release = j['Images'][-1]['Release']
|
||||
artifact = f'ci-mkosi-{id}-{iteration}-{distribution}-{release}-failed-test-journals'
|
||||
ops += [f'gh run download {id} --name {artifact} -D ci/{artifact}']
|
||||
journal_file = Path(f'ci/{artifact}/test/journal/{name}.journal')
|
||||
|
||||
ops += [f"journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info"]
|
||||
ops += [f'journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info']
|
||||
|
||||
print("Test failed, relevant logs can be viewed with: \n\n"
|
||||
f"{(' && '.join(ops))}\n", file=sys.stderr)
|
||||
print(
|
||||
"Test failed, relevant logs can be viewed with: \n\n" f"{(' && '.join(ops))}\n",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
# 0 also means we failed so translate that to a non-zero exit code to mark the test as failed.
|
||||
exit(result.returncode or 1)
|
||||
|
|
Loading…
Reference in New Issue