Commit Graph
274 Commits
Author SHA1 Message Date
Daan De Meyer 74d392ed1b tree-wide: standardize header names across src/fundamental, src/basic and src/shared
Drop the -fundamental suffix from src/fundamental/ headers in favor of names
that match their src/basic/ or src/shared/ counterparts (e.g.
macro-fundamental.h -> macro.h, assert-fundamental.h -> assert-util.h,
cleanup-fundamental.h -> cleanup-util.h). Rename src/basic/{btrfs,label}.{c,h}
to use the -util suffix to match the existing shared/btrfs-util and
shared/label-util siblings. Rename src/shared/mkdir-label.{c,h} to mkdir.{c,h}
and src/shared/tmpfile-util-label.{c,h} to tmpfile-util.{c,h} to match the
corresponding src/basic names.

This saves us from having to come up with separate names for files that do
the same thing across tiers, and it makes it easier to move stuff between
src/fundamental, src/basic and src/shared: consumers just #include "foo.h"
and pick up whichever tier their -I path resolves to first, so call sites
don't need to be updated when an API moves between layers.

Where a higher-tier wrapper exists (e.g. src/basic/macro.h wrapping
src/fundamental/macro.h), the wrapper uses an explicit "../fundamental/foo.h"
or "../basic/foo.h" relative include for the lower-tier header. We can't use
GCC's #include_next directive for this — when the wrapper is reachable both
via same-dir-as-source lookup and via -I (e.g. -Isrc/shared) for the
directory it lives in, #include_next advances by exactly one slot in libcpp's
internal directory chain and lands on the same physical directory it was
already in, never reaching the lower-tier sibling (see make_cpp_dir() in
gcc/libcpp/files.cc:1986).

To make sure the right headers are always picked up, the include directories
are reordered so that e.g. src/shared always takes priority over src/basic and
similar for the other directories.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 10:33:03 +09:00
Lennart Poettering 85d47bfa92 firstboot: make clear where the full screen console wizards end
The three first boot screens are visually separated from the console
output before them via the "chome" and welcome strings and sufficient
whitespace. But so far they weren't from the output after them. This is
sometimes a big confusing. Let's add a bit of a separator between the
end and what comes next, too.

Just cosmetics, nothing else.
2026-05-21 09:09:38 +09:00
Lennart Poettering ec1f40c89d firstboot: port help() to help-util.[ch] APIs 2026-05-20 16:39:04 +02:00
Lennart Poettering 460dab3936 firstboot: prefill language prompt with firmware language if it makes
sense
2026-05-20 16:38:19 +02:00
Lennart Poettering 1d646aed65 firstboot: prefill keymap question with EFI provided info 2026-05-20 16:38:18 +02:00
Lennart Poettering a80024e96d ask-string: support prefilling a string query with an explicit string 2026-05-20 16:34:21 +02:00
Lennart Poettering 324fab7ed6 firstboot,sysinstall,hostnamed: always show FANCY_NAME=
This makes sure that whenever we want to show the OS name we can show
the fancy name. Thus this moves the escaping/validation of the fancy
name out of hostnamed into generic code, and then makes use of it in
sysinstall,firstboot,prompt-util.
2026-05-12 00:07:42 +01:00
Lennart Poettering 99ce7a0770 options: get rid of "on_error" parameter to FOREACH_OPTION
I am really not a fan of full code lines passed to macros as parameters.
Let's get rid of the 3rd parameter of FOREACH_OPTION() hence:

1. Let's return errors just as a regular value (though a negative one),
   that can be handled via a OPTION_ERROR case statement for the switch.
   This normalizes handling of the error, just like any other event
   returned by the option parser.

2. In order to avoid exploding the amount of boilerplate in each use
   (that just propagates the error on OPTION_ERROR), let's then
   introduce an explicit FOREACH_OPTION_OR_RETURN(), that returns from
   the calling function on its own (and makes that clear in the name).

Together this cleans up, normalizes the logic and shortens the code.
2026-04-30 11:12:33 +01:00
Zbigniew Jędrzejewski-Szmek 5ff0ccaf8b tree-wide: change option_parse() to return option and arg via internal state
It was requested to make the 'c', 'opt', and 'arg' params the same, i.e.
defined through the FOREACH_OPTION macro. But we can't do that easily,
because 'c' was defined in the for loop definition, and we can only
define variables of the same type in that way. Also, in some cases we
need only 'c', in other cases with need 'c' and 'arg, in some cases 'c'
and 'opt', and in other cases all three. We'd need to either
conditionalize or mark those variables with _unused_ to deal with
compiler warnings. But a different approach works quite nicely: add
state.opt and state.arg to show the current option and it's argument.
(The short names are picked on purpose to reduce verbosity since those
are used a lot.)
2026-04-27 11:33:10 +02:00
Daan De Meyer 79862d33a0 chase: add explicit root_fd parameter to chaseat() and drop CHASE_AT_RESOLVE_IN_ROOT
Split the single directory fd that chaseat() used to take into two separate
fds: a root_fd that sets the chroot boundary (symlinks may not escape it,
absolute symlinks resolve relative to it), and a dir_fd that path resolution
starts from. This makes the chroot semantics of chaseat() explicit at every
call site instead of encoding them in the CHASE_AT_RESOLVE_IN_ROOT flag,
which is removed. It also decouples the starting directory from the root
boundary, so callers can descend from any inode inside the tree without
having to reopen the root separately.

XAT_FDROOT passed as root_fd means "no containment" (host root); as dir_fd
it means "start at root_fd". For a smoother transition, AT_FDCWD is also
accepted as root_fd and treated as XAT_FDROOT. When root_fd points to a
directory that is actually the host root, it is normalized to XAT_FDROOT
up front so the existing shortcut path can kick in.

Absolute paths returned by chaseat() are now relative to root_fd, and
relative paths are relative to dir_fd. The result is absolute only when
there is no chroot boundary (root_fd is XAT_FDROOT), or when an absolute
symlink made resolution jump out of the dir_fd subtree; otherwise callers
get a relative path they can feed straight back into an openat()-style
call against dir_fd. Specifically, when dir_fd == root_fd and we're not
operating on the host's root directory, we return a relative path even if
we received an absolute path or resolved an absolute symlink to allow
passing the path directly to openat() style functions. We do this to not
have to go modify every caller of chaseat() to make sure they deal properly
with any absolute paths they might receive. Only when root_fd != dir_fd do
we have to return an absolute path to indicate that the path is relative to
root_fd and not dir_fd.

The shortcut that skips the per-component walk is reworked around a new
chase_xopenat() helper that funnels CHASE_NOFOLLOW, CHASE_MUST_BE_* and
CHASE_TRIGGER_AUTOFS through xopenat_full()'s O_NOFOLLOW, O_DIRECTORY,
XO_REGULAR, XO_SOCKET and XO_TRIGGER_AUTOMOUNT flags. As a result these
flags no longer force us off the shortcut and can be dropped from
CHASE_NO_SHORTCUT_MASK, and the old openat_opath_with_automount() helper
goes away. A CHASE_MUST_BE_ANY alias is introduced for shortcut callers
(stat/access paths) that don't go through xopenat_full() and still need
to bail on those flags locally.

All *_and_* helpers built on top of chaseat() (chase_and_openat,
chase_and_opendirat, chase_and_statat, chase_and_accessat,
chase_and_fopenat_unlocked, chase_and_unlinkat, chase_and_open_parent_at)
gain the same root_fd parameter, and every call site in the tree is
ported to the new signature.

chase_and_open() is also fixed to correctly handle CHASE_EXTRACT_FILENAME
without CHASE_PARENT.
2026-04-20 23:35:31 +02:00
Zbigniew Jędrzejewski-Szmek 086daddfdf firstboot: use parse_boolean_argument in one more place
This was pointed out in review.
2026-04-16 16:55:17 +02:00
Zbigniew Jędrzejewski-Szmek 30863f491b firstboot: use free_and_strdup_warn in parse_argv
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 16:55:15 +02:00
Zbigniew Jędrzejewski-Szmek 5a2777c93e firstboot: convert to the new option parser
The descriptions for boolean options are adjusted to work better
with BOOL as the metavar.

Description of --copy is fixed, fixup for
f649325ba7.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 16:55:14 +02:00
Zbigniew Jędrzejewski-Szmek edc8e93830 firstboot: reorder option cases to match --help output
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 16:55:12 +02:00
Lennart Poettering 4c49e864b0 firstboot: permit setting the static hostname via a system credential
For the IMDS case there's value in being able to set the static
hostname, instead of just the transient one. Let's introduce
firstboot.hostname, which only applies to first boot, and write the
static hostname. This is different from system.hostname which applies to
any boot, and writes the transient hostname.
2026-03-20 12:39:44 +01:00
Lennart Poettering 4460a4ba21 firstboot: harden credential handling a bit
Credentials are highly privileged things, but still, let's do some
validation, because we can.
2026-03-20 12:39:44 +01:00
Luca Boccassi 75cb25c0b9 firstboot/homectl: hide plymouth splashscreen when asking questions
When plymouth is enabled, the screen gets all garbled when firstboot
runs and asks questions. Disable the splash screen, but only when
actually asking questions.
2026-02-03 13:21:03 +01:00
Yu Watanabe d0b224f845 libcrypt-util: turn into dlopen() dependency
Note, this drops logging only test case for crypt_preferred_method(),
as that requires explicitly dlopen() the library. But, we should test
that make_salt() and friends automatically dlopen() it.
2026-01-02 13:06:14 +09:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Yu Watanabe 19deb47ade firstboot: drop redundant and spurious errno check
Follow-up for 2319154a6b.
2025-11-23 22:36:50 +09:00
Daan De Meyer 87fbd33372 clang-tidy: Fix all remaining misc-include-cleaner violations
- Remove unused includes
- Add common false positive headers to misc-include-cleaner.IgnoreHeaders
- Add IWYU pragma keep for uncommon false positive headers
2025-11-22 10:19:41 +01:00
Lennart Poettering 372f3159fd firstboot: don't talk about any 'new' installation
The firstboot interface might pop-up also during live mode (because it's
just very useful to have the right kbd mapping applied), and that's
hardly a "new installation". Hence use more generic terms
2025-09-26 16:40:14 +02:00
Lennart Poettering aa27bec194 firstboot: optionally, don't query for keymap unless connected to a real VT
The keymap only really matters if there's local access to a system, i.e.
if there's actually a physical kbd directly connected to it, to apply it
to. If during firstboot we are not talked to via a VT (but via SSH,
container, or hypervisor console or so instead), then it's very unlikely
we ever are. Hence, don't ask for a keymap, and let#s shortcut the
questions asked at boot.
2025-09-26 16:40:14 +02:00
Lennart Poettering bedcce1a1f firstboot: drop waiting for key when starting
We only show this blurb on the first question, but the first question is
interactive anyway, hence no need to wait for input first explicitly, we
won't progress anyway without user input.

(similar for homectl's firstboot)
2025-09-26 16:27:53 +02:00
Lennart Poettering 971637c47d firstboot: get rid of pointless strjoina() 2025-09-26 09:43:45 +02:00
Lennart Poettering 0d2cc656c8 firstboot: mute console while running on the console at boot
Fixes: #34448
2025-09-26 09:42:13 +02:00
Lennart Poettering 875a618ed3 firstboot: modernize --help output 2025-09-24 15:46:30 +02:00
Lennart Poettering 73ee723aa7 firstboot: show blue "chrome" bar at top 2025-09-24 15:46:30 +02:00
Lennart Poettering fa350969ab prompt-util: add generic prompt loop implementation
This is a generalization of the logic in systemd-firstboot. This also
ports over firstboot.c to make use of the new generalization.
2025-09-24 15:46:30 +02:00
Yu Watanabe de69562623 tree-wide: add missing '=' in short comments for function argument 2025-07-22 03:05:54 +09:00
Valentin David 0dc39dffbd Use paths specified from environment variables for /etc configuration files
Some configuration files that need updates are directly under in /etc. To
update them atomically, we need write access to /etc. For Ubuntu Core this is
an issue as /etc is not writable. Only a selection of subdirectories can be
writable. The general solution is symlinks or bind mounts to writable places.
But for atomic writes in /etc, that does not work. So Ubuntu has had a patch
for that that did not age well.

Instead we would like to introduce some environment variables for alternate
paths.

 * SYSTEMD_ETC_HOSTNAME: /etc/hostname
 * SYSTEMD_ETC_MACHINE_INFO: /etc/machine-info
 * SYSTEMD_ETC_LOCALTIME: /etc/localtime
 * SYSTEMD_ETC_LOCALE_CONF: /etc/locale.conf
 * SYSTEMD_ETC_VCONSOLE_CONF: /etc/vconsole.conf
 * SYSTEMD_ETC_ADJTIME: /etc/adjtime

While it is for now expected that there is a symlink from the standard, we
still try to read them from that alternate path. This is important for
`/etc/localtime`, which is a symlink, so we cannot have an indirect symlink or
bind mount for it.

Since machine-id is typically written only once and not updated. This commit
does not cover it. An initrd can properly create it and bind mount it.
2025-06-23 15:32:11 +02:00
Lennart Poettering 611bb28dc3 firstboot: make sure labelling is enabled
Preparation to address #37857.
2025-06-18 10:29:29 +02:00
Lennart Poettering f6e213e86a firstboot: use WRITE_STRING_FILE_LABEL more
Let's explicitly label 3 key files we generate in systemd-firstboot.

Addresses some more of #37857.
2025-06-18 10:21:26 +02:00
Lennart Poettering 3e5320e27d env-file: port write_env_file() to label_ops_pre()
Let's make more use of label_ops_pre()/label_ops_post(), and replace
write_env_file_label() by a flag to write_env_file().

This simplifies and normalizes the code.

This also makes one relevant change: it sets the new
WRITE_ENV_FILE_LABEL flag in firstboot.c when we write locale.conf,
where we previously did not (but should have). This should address one
detail of #37857.
2025-06-18 10:21:26 +02:00
Lennart Poettering 9ea5a6e7d6 fs-util: replace symlink_atomic_full_label() by a flag to symlinkat_atomic_full()
More porting work to label_ops_pre()/label_ops_post()

This also enables labelling of the /etc/localtime symlink in
systemd-firstboot, which should address one small facet of #37857
2025-06-18 10:21:25 +02:00
Daan De Meyer 86b9a3e31d tree-wide: Clean up includes
This removes more unused includes from the components already cleaned
up in #37467 and #37457.

Split out of #37344.
2025-05-21 10:49:42 +02:00
Daan De Meyer 8857aa74e5 tree-wide: Clean up includes
This commit cleans up the includes for all the small tools across
the tree.

A few cases of returning EXIT_SUCCESS are replaced with returning
0 to avoid including <stdlib.h>.

Split out of #37344.
2025-05-14 22:34:02 +02:00
Yu Watanabe 3a03b97d6f tree-wide: drop unnecessary inclusion of tmpfile-util.h 2025-04-30 05:38:48 +09:00
Daan De Meyer 8aa304d313 shared: Remove circular dependency between image-policy.h and dissect-image.h
ImagePolicy can just be a forward declaration in dissect-image.h.
2025-04-23 09:53:43 +02:00
Zbigniew Jędrzejewski-Szmek 1ae9b0cfa8 basic/glyph-util: rename "special glyph" to just "glyph"
Admittedly, some of our glyphs _are_ special, e.g. "O=" for SPECIAL_GLYPH_TOUCH ;)
But we don't need this in the name. The very long names make some invocations
very wordy, e.g. special_glyph(SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY).
Also, I want to add GLYPH_SPACE, which is not special at all.
2025-03-15 14:40:39 +01:00
Lennart Poettering d810815ed4 firstboot: welcome user with emoji in firstboot wizard 🧙 2025-03-15 05:12:12 +09:00
Lennart Poettering af9c45d5b6 hostname: support that /etc/hostname contains ??? as wildcards to be replaced by hash value from /etc/machine-id 2025-03-11 18:01:42 +01:00
Lennart Poettering 9ab703d8e1 terminal-util: change 2nd parameter of terminal_reset_defensive() to flags
let's convert the 2nd argumeng form a boolean to a proper flags
parameter. Doesn't change behaviour in anyway, but is more readable, and
prepares ground for adding more flags soon.
2025-02-27 15:13:15 +01:00
Lennart Poettering 94a2b1cd25 firstboot: add auto-completion to various fields
This adds TAB-based auto-completion to various fields we query from the
user, such as locale, keymap, timezone, group membership.

It makes it a lot easier to quickly iterate through firstboot without
typing too much.
2025-02-17 15:21:18 +01:00
Lennart Poettering b6478aa12f terminal-util: beef up show_menu()
This modernizes the function a bit, and adds some bits:

1. whether to show numbers before entries is now optional, and if they
   are shown they are displayed in grey.

2. a common prefix can now be grayed out (later useful for completion
   support)

3. some variables have been named to clarify their purpose

4. the table display dimensions can now be auto-sized (by specifying
   SIZE_MAX and number of columns and column width)
2025-02-17 15:21:13 +01:00
Lennart Poettering 8fcd85768b terminal-util: tweak any_key_to_proceed() a bit
1. Make the message a bit more visible, by adding ANSI color. This
   matters in particular during boot, where the message otherwise might
   be overprinted by other output

2. Let's turn off terminal echo so that whatever key is entered is not
   made visible on screen, and we can handle newline and other keys
   reasonably uniformly.
2025-02-17 15:07:38 +01:00
Daan De Meyer 8a008fa792 firstboot: Populate XKBLAYOUT and friends as well in vconsole.conf
Let's derive XKBLAYOUT and friends from the given keymap and populate
these as well in vconsole.conf so that if the user configures a keymap
it's also respected in display managers such as gdm.
2025-02-07 09:18:36 +09:00
Zbigniew Jędrzejewski-Szmek b66a4c157e firstboot: fix crash when hostname question is skipped 2025-01-30 19:48:43 +01:00
Lennart Poettering d66894a7a5 ask-password-api: add new "hup_fd" field to AskPasswordReq
This new field allows specification of an fd on which the password
prompt logic will look for POLLHUP events for, and if seen will abort
the query.

The usecase for this is that when we query for a pw on behalf of a
Varlink client we can abort the query automatically if the client dies.
2025-01-02 16:38:44 +01:00
Lennart Poettering c4a02a526d ask-password-api: move timeout into AskPasswordRequest structure too 2025-01-02 16:38:25 +01:00