mirror of
https://github.com/systemd/systemd.git
synced 2025-02-24 17:57:34 +03:00
bootctl: add --install-source=auto|image|host
When using --root=/--image= the binaries to install/update will be picked from the directory/image. Add an option to let the caller choose. By default (auto) the image is tried first, and if nothing is found then the host. The other options allow to strictly try the image or host and ignore the other.
This commit is contained in:
parent
80a2381d5c
commit
02d06ba180
@ -258,6 +258,16 @@
|
|||||||
switch of the same name.</para></listitem>
|
switch of the same name.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--install-source=</option></term>
|
||||||
|
<listitem><para>When installing binaries with <option>--root=</option> or
|
||||||
|
<option>--image=</option>, selects where to source them from. Takes one of <literal>auto</literal>
|
||||||
|
(the default), <literal>image</literal> or <literal>host</literal>. With <literal>auto</literal>
|
||||||
|
binaries will be picked from the specified directory or image, and if not found they will be picked
|
||||||
|
from the host. With <literal>image</literal> or <literal>host</literal> no fallback search will be
|
||||||
|
performed if the binaries are not found in the selected source.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-p</option></term>
|
<term><option>-p</option></term>
|
||||||
<term><option>--print-esp-path</option></term>
|
<term><option>--print-esp-path</option></term>
|
||||||
|
@ -32,7 +32,7 @@ _bootctl() {
|
|||||||
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||||
local -A OPTS=(
|
local -A OPTS=(
|
||||||
[STANDALONE]='-h --help -p --print-esp-path -x --print-boot-path --version --no-variables --no-pager --graceful'
|
[STANDALONE]='-h --help -p --print-esp-path -x --print-boot-path --version --no-variables --no-pager --graceful'
|
||||||
[ARG]='--esp-path --boot-path --make-machine-id-directory --root --image'
|
[ARG]='--esp-path --boot-path --make-machine-id-directory --root --image --install-source'
|
||||||
)
|
)
|
||||||
|
|
||||||
if __contains_word "$prev" ${OPTS[ARG]}; then
|
if __contains_word "$prev" ${OPTS[ARG]}; then
|
||||||
@ -52,6 +52,9 @@ _bootctl() {
|
|||||||
compopt -o nospace
|
compopt -o nospace
|
||||||
comps=$( compgen -A file -- "$cur" )
|
comps=$( compgen -A file -- "$cur" )
|
||||||
;;
|
;;
|
||||||
|
--install-source)
|
||||||
|
comps="image host auto"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
||||||
return 0
|
return 0
|
||||||
|
@ -75,4 +75,5 @@ _arguments \
|
|||||||
'--graceful[Do not fail when locating ESP or writing fails]' \
|
'--graceful[Do not fail when locating ESP or writing fails]' \
|
||||||
'--root=[Operate under the specified directory]:PATH' \
|
'--root=[Operate under the specified directory]:PATH' \
|
||||||
'--image=[Operate on the specified image]:PATH' \
|
'--image=[Operate on the specified image]:PATH' \
|
||||||
|
'--install-source[Where to pick files when using --root=/--image=]:options:(image host auto)' \
|
||||||
'*::bootctl command:_bootctl_commands'
|
'*::bootctl command:_bootctl_commands'
|
||||||
|
@ -80,6 +80,11 @@ static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
|||||||
static bool arg_arch_all = false;
|
static bool arg_arch_all = false;
|
||||||
static char *arg_root = NULL;
|
static char *arg_root = NULL;
|
||||||
static char *arg_image = NULL;
|
static char *arg_image = NULL;
|
||||||
|
static enum {
|
||||||
|
ARG_INSTALL_SOURCE_IMAGE,
|
||||||
|
ARG_INSTALL_SOURCE_HOST,
|
||||||
|
ARG_INSTALL_SOURCE_AUTO,
|
||||||
|
} arg_install_source = ARG_INSTALL_SOURCE_AUTO;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
|
||||||
@ -843,6 +848,7 @@ static int create_subdirs(const char *root, const char * const *subdirs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int copy_one_file(const char *esp_path, const char *name, bool force) {
|
static int copy_one_file(const char *esp_path, const char *name, bool force) {
|
||||||
|
char *root = IN_SET(arg_install_source, ARG_INSTALL_SOURCE_AUTO, ARG_INSTALL_SOURCE_IMAGE) ? arg_root : NULL;
|
||||||
_cleanup_free_ char *source_path = NULL, *dest_path = NULL, *p = NULL, *q = NULL;
|
_cleanup_free_ char *source_path = NULL, *dest_path = NULL, *p = NULL, *q = NULL;
|
||||||
const char *e;
|
const char *e;
|
||||||
char *dest_name, *s;
|
char *dest_name, *s;
|
||||||
@ -857,13 +863,16 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
|
|||||||
if (!p)
|
if (!p)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = chase_symlinks(p, arg_root, CHASE_PREFIX_ROOT, &source_path, NULL);
|
r = chase_symlinks(p, root, CHASE_PREFIX_ROOT, &source_path, NULL);
|
||||||
|
/* If we had a root directory to try, we didn't find it and we are in auto mode, retry on the host */
|
||||||
|
if (r == -ENOENT && root && arg_install_source == ARG_INSTALL_SOURCE_AUTO)
|
||||||
|
r = chase_symlinks(p, NULL, CHASE_PREFIX_ROOT, &source_path, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r,
|
return log_error_errno(r,
|
||||||
"Failed to resolve path %s%s%s: %m",
|
"Failed to resolve path %s%s%s: %m",
|
||||||
p,
|
p,
|
||||||
arg_root ? " under directory " : "",
|
root ? " under directory " : "",
|
||||||
arg_root ? arg_root : "");
|
root ?: "");
|
||||||
|
|
||||||
q = path_join("/EFI/systemd/", dest_name);
|
q = path_join("/EFI/systemd/", dest_name);
|
||||||
if (!q)
|
if (!q)
|
||||||
@ -899,13 +908,17 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int install_binaries(const char *esp_path, const char *arch, bool force) {
|
static int install_binaries(const char *esp_path, const char *arch, bool force) {
|
||||||
|
char *root = IN_SET(arg_install_source, ARG_INSTALL_SOURCE_AUTO, ARG_INSTALL_SOURCE_IMAGE) ? arg_root : NULL;
|
||||||
_cleanup_closedir_ DIR *d = NULL;
|
_cleanup_closedir_ DIR *d = NULL;
|
||||||
_cleanup_free_ char *path = NULL;
|
_cleanup_free_ char *path = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = chase_symlinks_and_opendir(BOOTLIBDIR, arg_root, CHASE_PREFIX_ROOT, &path, &d);
|
r = chase_symlinks_and_opendir(BOOTLIBDIR, root, CHASE_PREFIX_ROOT, &path, &d);
|
||||||
|
/* If we had a root directory to try, we didn't find it and we are in auto mode, retry on the host */
|
||||||
|
if (r == -ENOENT && root && arg_install_source == ARG_INSTALL_SOURCE_AUTO)
|
||||||
|
r = chase_symlinks_and_opendir(BOOTLIBDIR, NULL, CHASE_PREFIX_ROOT, &path, &d);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to open boot loader directory %s: %m", BOOTLIBDIR);
|
return log_error_errno(r, "Failed to open boot loader directory %s%s: %m", root ?: "", BOOTLIBDIR);
|
||||||
|
|
||||||
const char *suffix = strjoina(arch, ".efi");
|
const char *suffix = strjoina(arch, ".efi");
|
||||||
const char *suffix_signed = strjoina(arch, ".efi.signed");
|
const char *suffix_signed = strjoina(arch, ".efi.signed");
|
||||||
@ -1394,6 +1407,8 @@ static int help(int argc, char *argv[], void *userdata) {
|
|||||||
" --boot-path=PATH Path to the $BOOT partition\n"
|
" --boot-path=PATH Path to the $BOOT partition\n"
|
||||||
" --root=PATH Operate on an alternate filesystem root\n"
|
" --root=PATH Operate on an alternate filesystem root\n"
|
||||||
" --image=PATH Operate on disk image as filesystem root\n"
|
" --image=PATH Operate on disk image as filesystem root\n"
|
||||||
|
" --install-source=auto|image|host\n"
|
||||||
|
" Where to pick files when using --root=/--image=\n"
|
||||||
" -p --print-esp-path Print path to the EFI System Partition\n"
|
" -p --print-esp-path Print path to the EFI System Partition\n"
|
||||||
" -x --print-boot-path Print path to the $BOOT partition\n"
|
" -x --print-boot-path Print path to the $BOOT partition\n"
|
||||||
" --no-variables Don't touch EFI variables\n"
|
" --no-variables Don't touch EFI variables\n"
|
||||||
@ -1426,6 +1441,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_BOOT_PATH,
|
ARG_BOOT_PATH,
|
||||||
ARG_ROOT,
|
ARG_ROOT,
|
||||||
ARG_IMAGE,
|
ARG_IMAGE,
|
||||||
|
ARG_INSTALL_SOURCE,
|
||||||
ARG_VERSION,
|
ARG_VERSION,
|
||||||
ARG_NO_VARIABLES,
|
ARG_NO_VARIABLES,
|
||||||
ARG_NO_PAGER,
|
ARG_NO_PAGER,
|
||||||
@ -1444,6 +1460,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "boot-path", required_argument, NULL, ARG_BOOT_PATH },
|
{ "boot-path", required_argument, NULL, ARG_BOOT_PATH },
|
||||||
{ "root", required_argument, NULL, ARG_ROOT },
|
{ "root", required_argument, NULL, ARG_ROOT },
|
||||||
{ "image", required_argument, NULL, ARG_IMAGE },
|
{ "image", required_argument, NULL, ARG_IMAGE },
|
||||||
|
{ "install-source", required_argument, NULL, ARG_INSTALL_SOURCE },
|
||||||
{ "print-esp-path", no_argument, NULL, 'p' },
|
{ "print-esp-path", no_argument, NULL, 'p' },
|
||||||
{ "print-path", no_argument, NULL, 'p' }, /* Compatibility alias */
|
{ "print-path", no_argument, NULL, 'p' }, /* Compatibility alias */
|
||||||
{ "print-boot-path", no_argument, NULL, 'x' },
|
{ "print-boot-path", no_argument, NULL, 'x' },
|
||||||
@ -1499,6 +1516,19 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_INSTALL_SOURCE:
|
||||||
|
if (streq(optarg, "auto"))
|
||||||
|
arg_install_source = ARG_INSTALL_SOURCE_AUTO;
|
||||||
|
else if (streq(optarg, "image"))
|
||||||
|
arg_install_source = ARG_INSTALL_SOURCE_IMAGE;
|
||||||
|
else if (streq(optarg, "host"))
|
||||||
|
arg_install_source = ARG_INSTALL_SOURCE_HOST;
|
||||||
|
else
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Unexpected parameter for --install-source=: %s", optarg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
if (arg_print_dollar_boot_path)
|
if (arg_print_dollar_boot_path)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
@ -1592,6 +1622,9 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
if (arg_root && arg_image)
|
if (arg_root && arg_image)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
|
||||||
|
|
||||||
|
if (arg_install_source != ARG_INSTALL_SOURCE_AUTO && !arg_root && !arg_image)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--install-from-host is only supported with --root= or --image=.");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user