From e563e2534c074f3d10cb1eb9e9bb4eb623590587 Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Sun, 30 Oct 2016 15:43:01 +0100 Subject: [PATCH 1/2] escape: support --unescape with --template --- man/systemd-escape.xml | 15 ++++++++----- src/escape/escape.c | 49 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/man/systemd-escape.xml b/man/systemd-escape.xml index 41014abc73..8329e5d7c4 100644 --- a/man/systemd-escape.xml +++ b/man/systemd-escape.xml @@ -76,9 +76,11 @@ Inserts the escaped strings in a unit name template. Takes a unit name template such as - foobar@.service. May not be used in - conjunction with , - or + foobar@.service. With + , expects instantiated unit names + for this template and extracts and unescapes just the instance + part. May not be used in conjunction with + or . @@ -100,8 +102,7 @@ Instead of escaping the specified strings, undo the escaping, reversing the operation. May not be used in - conjunction with , - or + conjunction with or . @@ -141,6 +142,10 @@ tmp-waldi-foobar.mount To generate instance names of three strings: $ systemd-escape --template=systemd-nspawn@.service 'My Container 1' 'containerb' 'container/III' systemd-nspawn@My\x20Container\x201.service systemd-nspawn@containerb.service systemd-nspawn@container-III.service + + To extract the instance part of an instantiated unit: + $ systemd-escape -u --template=systemd-nspawn@.service 'systemd-nspawn@My\x20Container\x201.service' +My Container 1 diff --git a/src/escape/escape.c b/src/escape/escape.c index 371ddbe02b..3cf4a20d1e 100644 --- a/src/escape/escape.c +++ b/src/escape/escape.c @@ -119,8 +119,13 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } - if ((arg_template || arg_suffix) && arg_action != ACTION_ESCAPE) { - log_error("--suffix= and --template= are not compatible with --unescape or --mangle."); + if ((arg_template || arg_suffix) && arg_action == ACTION_MANGLE) { + log_error("--suffix= and --template= are not compatible with --mangle."); + return -EINVAL; + } + + if (arg_suffix && arg_action == ACTION_UNESCAPE) { + log_error("--suffix is not compatible with --unescape."); return -EINVAL; } @@ -189,17 +194,51 @@ int main(int argc, char *argv[]) { break; - case ACTION_UNESCAPE: + case ACTION_UNESCAPE: { + _cleanup_free_ char *name = NULL; + + if (arg_template) { + _cleanup_free_ char *template = NULL; + + r = unit_name_to_instance(*i, &name); + if (r < 0) { + log_error_errno(r, "Failed to extract instance: %m"); + goto finish; + } + if (isempty(name)) { + log_error("Unit %s is missing the instance name.", *i); + r = -EINVAL; + goto finish; + } + r = unit_name_template(*i, &template); + if (r < 0) { + log_error_errno(r, "Failed to extract template: %m"); + goto finish; + } + if (!streq(arg_template, template)) { + log_error("Unit %s template %s does not match specified template %s.", *i, template, arg_template); + r = -EINVAL; + goto finish; + } + } else { + name = strdup(*i); + if (!name) { + r = log_oom(); + goto finish; + } + } + if (arg_path) - r = unit_name_path_unescape(*i, &e); + r = unit_name_path_unescape(name, &e); else - r = unit_name_unescape(*i, &e); + r = unit_name_unescape(name, &e); if (r < 0) { log_error_errno(r, "Failed to unescape string: %m"); goto finish; } break; + } case ACTION_MANGLE: r = unit_name_mangle(*i, 0, &e); From d936cddcb560c9ff9992caed850114fb957c40f4 Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Sun, 30 Oct 2016 23:49:15 +0100 Subject: [PATCH 2/2] escape: add --instance option Suggested by @keszybz in #4522. --- man/systemd-escape.xml | 20 +++++++++++++++++++- src/escape/escape.c | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/man/systemd-escape.xml b/man/systemd-escape.xml index 8329e5d7c4..f61c07ae9d 100644 --- a/man/systemd-escape.xml +++ b/man/systemd-escape.xml @@ -80,7 +80,8 @@ , expects instantiated unit names for this template and extracts and unescapes just the instance part. May not be used in conjunction with - or + , + or . @@ -118,6 +119,19 @@ . + + + + With , unescape + and print only the instance part of an instantiated unit name + template. Results in an error for an uninstantiated template + like ssh@.service or a non-template name + like ssh.service. + Must be used in conjunction with + and may not be used in conjunction with + . + + @@ -144,6 +158,10 @@ tmp-waldi-foobar.mount systemd-nspawn@My\x20Container\x201.service systemd-nspawn@containerb.service systemd-nspawn@container-III.service To extract the instance part of an instantiated unit: + $ systemd-escape -u --instance 'systemd-nspawn@My\x20Container\x201.service' +My Container 1 + + To extract the instance part of an instance of a particular template: $ systemd-escape -u --template=systemd-nspawn@.service 'systemd-nspawn@My\x20Container\x201.service' My Container 1 diff --git a/src/escape/escape.c b/src/escape/escape.c index 3cf4a20d1e..eaf0a9a7af 100644 --- a/src/escape/escape.c +++ b/src/escape/escape.c @@ -21,6 +21,7 @@ static enum { static const char *arg_suffix = NULL; static const char *arg_template = NULL; static bool arg_path = false; +static bool arg_instance = false; static void help(void) { printf("%s [OPTIONS...] [NAME...]\n\n" @@ -29,6 +30,7 @@ static void help(void) { " --version Show package version\n" " --suffix=SUFFIX Unit suffix to append to escaped strings\n" " --template=TEMPLATE Insert strings as instance into template\n" + " --instance With --unescape, show just the instance part\n" " -u --unescape Unescape strings\n" " -m --mangle Mangle strings\n" " -p --path When escaping/unescaping assume the string is a path\n" @@ -51,6 +53,7 @@ static int parse_argv(int argc, char *argv[]) { { "unescape", no_argument, NULL, 'u' }, { "mangle", no_argument, NULL, 'm' }, { "path", no_argument, NULL, 'p' }, + { "instance", no_argument, NULL, 'i' }, {} }; @@ -102,6 +105,10 @@ static int parse_argv(int argc, char *argv[]) { arg_path = true; break; + case 'i': + arg_instance = true; + break; + case '?': return -EINVAL; @@ -134,6 +141,16 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } + if (arg_instance && arg_action != ACTION_UNESCAPE) { + log_error("--instance must be used in conjunction with --unescape."); + return -EINVAL; + } + + if (arg_instance && arg_template) { + log_error("--instance may not be combined with --template."); + return -EINVAL; + } + return 1; } @@ -197,7 +214,7 @@ int main(int argc, char *argv[]) { case ACTION_UNESCAPE: { _cleanup_free_ char *name = NULL; - if (arg_template) { + if (arg_template || arg_instance) { _cleanup_free_ char *template = NULL; r = unit_name_to_instance(*i, &name); @@ -215,7 +232,7 @@ int main(int argc, char *argv[]) { log_error_errno(r, "Failed to extract template: %m"); goto finish; } - if (!streq(arg_template, template)) { + if (arg_template && !streq(arg_template, template)) { log_error("Unit %s template %s does not match specified template %s.", *i, template, arg_template); r = -EINVAL; goto finish;