mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-10 01:17:44 +03:00
systemd-analyze: add --root option for 'verify' verb and allow path parsing
------------------------------------------------------------------------------- Example Run: foobar.service created below is a service unit file that has a non-existing key-value pairing (foo = bar) and is thus, syntactically invalid. maanya-goenka@debian:~/systemd (img-support)$ cat <<EOF>img/usr/lib/systemd/system/foobar.service > [Unit] > foo = bar > > [Service] > ExecStart = /opt/script0.sh > EOF The failure to create foobar.service because of the recursive dependency searching and verification has been addressed in a different PR: systemd-analyze: add option to return an error value when unit verification fails #20233 maanya-goenka@debian:~/systemd (img-support)$ sudo build/systemd-analyze verify --root=img/ foobar.service /home/maanya-goenka/systemd/img/usr/lib/systemd/system/foobar.service:2: Unknown key name 'foo' in section 'Unit', ignoring. foobar.service: Failed to create foobar.service/start: Unit sysinit.target not found.
This commit is contained in:
parent
782671bc8f
commit
2a7cf953e1
@ -747,8 +747,8 @@ Service b@0.service not loaded, b.socket cannot be started.
|
||||
<varlistentry>
|
||||
<term><option>--root=<replaceable>PATH</replaceable></option></term>
|
||||
|
||||
<listitem><para>With <command>cat-files</command>, show config files underneath
|
||||
the specified root path <replaceable>PATH</replaceable>.</para></listitem>
|
||||
<listitem><para>With <command>cat-files</command> and <command>verify</command>,
|
||||
operate on files underneath the specified root path <replaceable>PATH</replaceable>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -125,7 +125,7 @@ _systemd_analyze() {
|
||||
|
||||
elif __contains_word "$verb" ${VERBS[VERIFY]}; then
|
||||
if [[ $cur = -* ]]; then
|
||||
comps='--help --version --system --user --global --man=no --generators=yes'
|
||||
comps='--help --version --system --user --global --man=no --generators=yes --root'
|
||||
else
|
||||
comps=$( compgen -A file -- "$cur" )
|
||||
compopt -o filenames
|
||||
|
@ -87,6 +87,7 @@ _arguments \
|
||||
'--system[Operate on system systemd instance]' \
|
||||
'--user[Operate on user systemd instance]' \
|
||||
'--global[Show global user instance config]' \
|
||||
'--root=[Add support for root argument]:PATH' \
|
||||
'--no-pager[Do not pipe output into a pager]' \
|
||||
'--man=[Do (not) check for existence of man pages]:boolean:(1 0)' \
|
||||
'--order[When generating graph for dot, show only order]' \
|
||||
|
@ -83,7 +83,7 @@ int verify_conditions(char **lines, UnitFileScope scope) {
|
||||
return log_error_errno(r, "Failed to initialize manager: %m");
|
||||
|
||||
log_debug("Starting manager...");
|
||||
r = manager_startup(m, NULL, NULL);
|
||||
r = manager_startup(m, /* serialization= */ NULL, /* fds= */ NULL, /* root= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -218,7 +218,7 @@ static int verify_unit(Unit *u, bool check_man) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators) {
|
||||
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root) {
|
||||
const ManagerTestRunFlags flags =
|
||||
MANAGER_TEST_RUN_MINIMAL |
|
||||
MANAGER_TEST_RUN_ENV_GENERATORS |
|
||||
@ -246,7 +246,7 @@ int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run
|
||||
|
||||
log_debug("Starting manager...");
|
||||
|
||||
r = manager_startup(m, NULL, NULL);
|
||||
r = manager_startup(m, /* serialization= */ NULL, /* fds= */ NULL, root);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -7,4 +7,4 @@
|
||||
#include "path-lookup.h"
|
||||
|
||||
int verify_executable(Unit *u, const ExecCommand *exec);
|
||||
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators);
|
||||
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root);
|
||||
|
@ -2142,7 +2142,7 @@ static int do_condition(int argc, char *argv[], void *userdata) {
|
||||
}
|
||||
|
||||
static int do_verify(int argc, char *argv[], void *userdata) {
|
||||
return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators);
|
||||
return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_root);
|
||||
}
|
||||
|
||||
static int do_security(int argc, char *argv[], void *userdata) {
|
||||
@ -2381,9 +2381,9 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Option --user is not supported for cat-config right now.");
|
||||
|
||||
if (arg_root && !streq_ptr(argv[optind], "cat-config"))
|
||||
if (arg_root && !STRPTR_IN_SET(argv[optind], "cat-config", "verify"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Option --root is only supported for cat-config right now.");
|
||||
"Option --root is only supported for cat-config and verify right now.");
|
||||
|
||||
return 1; /* work to do */
|
||||
}
|
||||
|
@ -2908,7 +2908,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
before_startup = now(CLOCK_MONOTONIC);
|
||||
|
||||
r = manager_startup(m, arg_serialization, fds);
|
||||
r = manager_startup(m, arg_serialization, fds, /* root= */ NULL);
|
||||
if (r < 0) {
|
||||
error_message = "Failed to start up manager";
|
||||
goto finish;
|
||||
|
@ -1727,7 +1727,7 @@ void manager_reloading_stopp(Manager **m) {
|
||||
}
|
||||
}
|
||||
|
||||
int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
||||
int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *root) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -1736,7 +1736,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
||||
* but we should not touch the real generator directories. */
|
||||
r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope,
|
||||
MANAGER_IS_TEST_RUN(m) ? LOOKUP_PATHS_TEMPORARY_GENERATED : 0,
|
||||
NULL);
|
||||
root);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to initialize path lookup table: %m");
|
||||
|
||||
|
@ -470,7 +470,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
|
||||
Manager* manager_free(Manager *m);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||
|
||||
int manager_startup(Manager *m, FILE *serialization, FDSet *fds);
|
||||
int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *root);
|
||||
|
||||
Job *manager_get_job(Manager *m, uint32_t id);
|
||||
Unit *manager_get_unit(Manager *m, const char *name);
|
||||
|
@ -97,7 +97,7 @@ int main(int argc, char *argv[]) {
|
||||
/* The simple tests succeeded. Now let's try full unit-based use-case. */
|
||||
|
||||
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
assert_se(u = unit_new(m, sizeof(Service)));
|
||||
assert_se(unit_add_name(u, "foo.service") == 0);
|
||||
|
@ -304,7 +304,7 @@ int main(int argc, char *argv[]) {
|
||||
assert_se(runtime_dir = setup_fake_runtime_dir());
|
||||
|
||||
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
assert_se(test_bpf_cgroup_programs(m,
|
||||
"single_prog.service", single_prog, ELEMENTSOF(single_prog)) >= 0);
|
||||
|
@ -60,7 +60,7 @@ static int test_cgroup_mask(void) {
|
||||
m->default_tasks_accounting = false;
|
||||
m->default_tasks_max = TASKS_MAX_UNSET;
|
||||
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
/* Load units and verify hierarchy. */
|
||||
assert_se(manager_load_startable_unit_or_warn(m, "parent.slice", NULL, &parent) >= 0);
|
||||
|
@ -33,7 +33,7 @@ static int test_default_memory_low(void) {
|
||||
}
|
||||
|
||||
assert_se(r >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
/* dml.slice has DefaultMemoryLow=50. Beyond that, individual subhierarchies look like this:
|
||||
*
|
||||
|
@ -95,7 +95,7 @@ int main(int argc, char *argv[]) {
|
||||
if (manager_errno_skip_test(r))
|
||||
return log_tests_skipped_errno(r, "manager_new");
|
||||
assert_se(r >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
printf("Load1:\n");
|
||||
assert_se(manager_load_startable_unit_or_warn(m, "a.service", NULL, &a) >= 0);
|
||||
|
@ -844,7 +844,7 @@ static int run_tests(UnitFileScope scope, const test_entry tests[], char **patte
|
||||
if (manager_errno_skip_test(r))
|
||||
return log_tests_skipped_errno(r, "manager_new");
|
||||
assert_se(r >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
for (const test_entry *test = tests; test->f; test++)
|
||||
if (strv_fnmatch_or_empty(patterns, test->name, FNM_NOESCAPE))
|
||||
|
@ -104,7 +104,7 @@ static void test_config_parse_exec(void) {
|
||||
}
|
||||
|
||||
assert_se(r >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
assert_se(u = unit_new(m, sizeof(Service)));
|
||||
|
||||
@ -448,7 +448,7 @@ static void test_config_parse_log_extra_fields(void) {
|
||||
}
|
||||
|
||||
assert_se(r >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
assert_se(u = unit_new(m, sizeof(Service)));
|
||||
|
||||
|
@ -38,7 +38,7 @@ static int setup_test(Manager **m) {
|
||||
if (manager_errno_skip_test(r))
|
||||
return log_tests_skipped_errno(r, "manager_new");
|
||||
assert_se(r >= 0);
|
||||
assert_se(manager_startup(tmp, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(tmp, NULL, NULL, NULL) >= 0);
|
||||
|
||||
STRV_FOREACH(test_path, tests_path) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
@ -34,7 +34,7 @@ int main(int argc, char *argv[]) {
|
||||
if (manager_errno_skip_test(r))
|
||||
return log_tests_skipped_errno(r, "manager_new");
|
||||
assert_se(r >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
/* load idle ok */
|
||||
assert_se(manager_load_startable_unit_or_warn(m, "sched_idle_ok.service", NULL, &idle_ok) >= 0);
|
||||
|
@ -138,7 +138,7 @@ int main(int argc, char *argv[]) {
|
||||
assert_se(runtime_dir = setup_fake_runtime_dir());
|
||||
|
||||
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "2000", STRV_MAKE("2000"), STRV_MAKE("any")) >= 0);
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "2000", STRV_MAKE("ipv6:2001-2002"), STRV_MAKE("any")) >= 0);
|
||||
|
@ -27,7 +27,7 @@ int main(int argc, char *argv[]) {
|
||||
assert_se(runtime_dir = setup_fake_runtime_dir());
|
||||
|
||||
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
|
||||
assert_se(a = unit_new(m, sizeof(Service)));
|
||||
assert_se(unit_add_name(a, "a.service") >= 0);
|
||||
|
Loading…
Reference in New Issue
Block a user