The custom help() is replaced by a COMMAND() description, and
--introspect-cli is added. The abstract is changed to use the imperative
form ("Register …" instead of "Registers …"), consistent with the other
commands. --help now goes through the pager, like other commands with
--no-pager.
The custom help() is replaced by a COMMAND() description, and
--introspect-cli is added. The abstract is changed to use the imperative
form ("Configure …" instead of "Configures …"), consistent with the
other commands.
After c9cd66ee3a and
c81b5d36b9, the comment about systemd-backlight
and systemd-veritysetup was outdated. We can test them as any other program.
Also, use an array to make list easier to extend in the future and
adjust $PATH so we don't need to care about the split between public
and non-public programs.
PID, UID, and GID are converted by sending struct ucred, however, TID
was not converted. Let's convert TID if corresponding pidfd exists, and
discards TID otherwise.
Fixes 4c7af7d9d1.
Since kernel v6.19, ioctl(PIDFD_GET_INFO) can return the set of
supported flags when PIDFD_INFO_SUPPORTED_MASK is specified.
This allows checking whether, e.g., PIDFD_INFO_COREDUMP_SIGNAL is
supported by the running kernel.
PID, UID, and GID are converted by sending struct ucred, however,
TID was not converted. Let's convert TID if corresponding pidfd exists,
and discards TID otherwise.
Fixes 4c7af7d9d1.
The connect callback is called after sd_varlink_server_add_connection()
succeeds. Do not call the disconnect callback for connections that have
not been established yet.
Previously, sd_varlink_server_add_connection_pair() did not decrement
the connection counters when json_stream_attach_fds() failed.
Set the ucred before calling json_stream_attach_fds() so that
sd_varlink_close() also decrements the counters when it fails.
This makes json_stream_attach_fds() and json_stream_connect_fd_pair()
leave the passed file descriptors with the caller on failure. Callers
should call TAKE_FD() only after a successful call.
Also make qmp_client_connect_fd() always take ownership of the passed
file descriptor, including on failure. Previously, ownership of the
passed file descriptor on failure was unclear and depended on where
the function failed.
Replace the "run_subtests; touch /testok" tail with a single wrapper
invocation. Report the test itself as skipped if every subtest is
skipped.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
Now that run_subtests() understands 77 as skipped, make the subtests
that bail out early on a missing capability or precondition exit 77
instead of exit 0. Partial skips that run after real assertions, and
exits from inside subshells, are deliberately left untouched.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
run_subtests() and run_subtests_with_signals() now treat a subtest exit
code of 77 as skipped rather than a failure, track skipped subtests
separately, and list them in the summary. Previously a subtest could
only fake a skip by exiting 0, which was indistinguishable from a real
pass.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
The vmspawn-based TEST-87 subtests each carried a near-identical
wait_for_machine() helper. Move it into util.sh so it can be shared.
The shared version is the vmspawn.sh variant, which tells missing
vhost-user-fs (nested VM) apart from any other early exit. As a result,
bin-volume and replace-storage now use that distinction too instead of
treating every early exit alike. vmspawn-drives is unaffected of this,
its --image-only console never matches the vhost-user-fs marker, so an
early exit still fails.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
Provide a Tokio-like #[tokio::main] entry point for binaries that want to run
their main function inside a fiber on a default sd_event loop.
DEFINE_MAIN_FUNCTION_FIBER(impl) mirrors DEFINE_MAIN_FUNCTION but routes impl
through a new run_main_fiber() helper. impl keeps the run() convention while
the loop's exit code keeps the exit status convention: impl's result never
becomes an exit code, an explicit exit status wins over a successful impl, and
impl's own failure wins over the exit status unless it is the -ECANCELED of a
fiber that the exit request cancelled. Signal policy stays with impl so
existing handlers such as sd_event_set_signal_exit() keep working.
The fiber is created fire-and-forget: as long as the loop reaches
SD_EVENT_FINISHED it unwinds the fiber through its exit event source, so we
never hold a reference we cannot drop because the fiber is still suspended. A
loop that fails internally never dispatches its exit sources, so the fiber may
stay suspended with no working loop left to unwind it; we leak both for now and
leave a TODO to keep the broken loop out of the default slot. Since the fiber
also refers to run_main_fiber()'s stack frame, refuse to run on a loop we don't
own, or from a fiber, as sd_fiber_new() leaves the exit event source disabled
there and nothing would unwind the fiber.
Cover argument forwarding, result propagation, explicit event exits, nested
invocations, signal-source registration, event-loop errors, and fiber stack
unwinding, and check after every run that the default event loop was released
again. Also build and run a separate test executable that expands
DEFINE_MAIN_FUNCTION_FIBER itself and verifies that a positive implementation
result maps to a successful process exit.
The getty.auto credential is a textual configuration value, but credentials
are read as raw file contents. A value written by common text-file workflows
can therefore end in a newline, causing false\n to be rejected and ignored.
Reproducer:
printf 'false\n' > "$CREDENTIALS_DIRECTORY/getty.auto"
Before: getty units could still be generated because the credential was
ignored as invalid.
Expected: false\n is parsed the same as false and disables getty
generation.
Strip the value in getty-generator before parsing it. This keeps the
credential framework byte-preserving while applying text semantics where
getty.auto is consumed.
Follow-up for: 3a883e89bc
The securebits parsing code now recognizes 'no-cap-ambient-raise' (added
in Linux 4.3), 'exec-restrict-file', and 'exec-deny-interactive' (both
added in Linux 6.14). The '-locked' variants were added too.
The `exec-restrict-file` and `exec-deny-interactive` securebits are
particularly useful in combination with `RestrictFileSystemAccess=` to
allow developers to extend the "only execute immutable files" concept to
script interpreters. Those securebits are not documented in the
[`capabilities(7)`](https://man7.org/linux/man-pages/man7/capabilities.7.html)
manpage, only in the [Executability
check](https://docs.kernel.org/userspace-api/check_exec.html) kernel
docs.
Replace opaque built-in review behavior with explicit parallel review lenses for
correctness, concurrency, security, architecture, coding style, and regression
coverage, plus bounded domain-specific reviewers and independent validation.
Prefetch pull request discussion in the setup job while letting the read-only
review job fetch and inspect the full commit history without per-commit
worktrees.
Keep GitHub writes isolated to the setup and posting jobs, pin the Claude models
and CLI, and bound execution below the AWS credential lifetime. Materialize
review instructions from the trusted base revision and scope agent writes to the
structured result directory so untrusted pull request content cannot widen the
review authority.
Treat the posting job as the authoritative trust boundary: validate all
model-selected commits, paths, lines, and thread IDs, normalize degenerate line
ranges, bound sanitized output, and surface GitHub API failures in the tracking
comment before performing writes. Retain daandemeyer/systemd in the repository
allowlist so the workflow can be exercised end to end on the personal fork.
Manual runs against fork PR #15 covered OIDC authentication, sandboxing, result
artifact handoff, tracking-comment updates, and validation of posted output.
Signed-off-by: Daan De Meyer <daan@amutable.com>
The securebits parsing code now recognizes 'no-cap-ambient-raise'
(added in Linux 4.3), 'exec-restrict-file', and 'exec-deny-interactive'
(both added in Linux 6.14). The '-locked' variants were added too.
Only trailing empty components have special meaning:
they request appending the built-in defaults.
Share the validation between normal path lookup and
systemd-analyze verify, so verify does not compose
values that path lookup later rejects.
Propagate generator path parse errors instead of
turning them into empty generator paths.
Follow-up for: cf7d80a5fe
The `restart` verb was added to machinectl as a convenience alias for
`reboot`, but its shell completions were never updated. Add it to both
the bash and zsh completions.
So far there's only one multi-line abstract. But as pointed out in the
review, it's silly to handle footer but not the abstract.
help_abstract() is not reused because it only works with one-line
abstracts. (It always prints an empty line to separate paragraphs.)
So the formatting is done anew in print_wrapped(). I think this is OK,
since it's all very simple. After everything has been converted to
COMMAND() and its helpers, help_abstract() and the sister functions will
become unused and can be dropped then.
The footer is now wrapped to min($COLUMNS, 80) when it is printed, so
CommandDescription footers do not need to be hard-wrapped in the source,
and make use of the available terminal width. Newlines embedded in the
text are preserved and each line is wrapped independently, so explicit
line breaks can still be used where needed, e.g. before the example
command line in varlinkctl.
The text is wrapped at max of 80 columns to avoid very wrong lines on
wide terminals. Such lines are hard to read.
A new helper is added for this. We already have format_strv_width in
format-table, but it requires a strv, so we'd need to conver the data,
and returns a formatted string, which we'd need to print ourselves. So
overall, it seems better to add a dedicated helper.
Before this series, many help() functions opened the pager. This got lost
in the translation. Starting the pager requires access to arg_pager_flags.
While we could pipe this through in case when command_print_help() is
called directly, but this hard in the case when verb_help_auto() or
VERB_COMMON_HELP_AUTO/VERB_COMMON_HELP_AUTO_HIDDEN are used. Let's instead
extend the (const static) CommandDescription structure with a pointer to
the arg_pager_flags variable. This restores the pager functionality in a
uniform fashion with a one-line change in the individual binaries.
Previously, the systemd-resolve compat alias was described in the same
CommandDescription structure and resolvectl. But they have different
option sets, so this doesn't really work. The alias is deprecated, so
describe it as such in the abstract, but give it a separate entry.
$ build/resolvectl --introspect-cli
{
"mediaType": "application/vnd.io.systemd.cli-introspection-0",
"commands": [
{
"names": [ "resolvconf" ],
"abstract": [
"Register DNS server and domain configuration with systemd-resolved."
],
...
},
{
"names": [ "resolvectl" ],
"abstract": [
"Send control commands to the network name resolution manager, or\nresolve domain names, IPv4 and IPv6 addresses, DNS records, and services."
],
...
},
{
"names": [ "systemd-resolve" ],
"abstract": [
"Send control commands to the network name resolution manager, or\nresolve domain names, IPv4 and IPv6 addresses, DNS records, and services.\n\nThis command is deprecated. Use resolvectl.1 instead."
],
...
}
]
}
This adds the helpers to add a hidden --introspect-cli option which
prints a machine-readable description of the program's interface and
exits. Applicable to any programs that have been converted to
VERB_COMMAND().
The output format follows the draft CLI-Introspection Specification
(https://github.com/behrmann/uapi-specifications/blob/cli-introspection/specs/cli_introspection.md):
a single JSON document with a fixed "mediaType" string and an array of
command objects, one per VERB_COMMAND() defined in the binary, so multicall
binaries are described in full. Options are taken from the command's option
namespace, so e.g. systemd-dissect does not list the mount.ddi mount-helper
options.
$ build/systemd-id128 --json=pretty --introspect-cli
{
"mediaType" : "application/vnd.io.systemd.cli-introspection-0",
"commands" : [
{
"names" : [
"systemd-id128"
],
"version" : "262~devel",
"features" : [
"-PAM",
...
],
"abstract" : [
"Generate and print 128-bit identifiers."
],
"options" : [
{
"names" : [
"-h",
"--help"
],
"argument" : "no_argument",
"help" : "Show this help"
},
...
],
"verbs" : [
{
"names" : [
"new"
],
"abstract" : [
"Generate a new ID"
],
"maxArguments" : 1
},
...
]
}
]
}
$ build/systemd-id128 --introspect-cli | jq '.commands[0].options[].names[-1]'
"--help"
"--version"
"--no-pager"
"--no-legend"
"--json"
"-j"
"--pretty"
"--value"
"--app-specific"
"--uuid"
"--introspect-cli"