diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2026-06-16 01:52:00 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2026-06-16 01:52:00 +0000 |
| commit | 16a8a828163dc2344466fabbe7b2ae0383a033c2 (patch) | |
| tree | 920c6ffd8b587c6354a1edd1bd82d50b46bf9416 | |
| parent | 5129011f1e80b0243ec857abb10b15af03941b30 (diff) | |
| download | s6-frontend-16a8a828163dc2344466fabbe7b2ae0383a033c2.tar.gz | |
s6_set changes: configurable set, remove load/save, add copy
Also add a configurable set to s6_live_install
Don't unlist current in s6_repository_list
| -rw-r--r-- | doc/overview.html | 10 | ||||
| -rw-r--r-- | doc/s6_live.html | 45 | ||||
| -rw-r--r-- | doc/s6_repository.html | 6 | ||||
| -rw-r--r-- | doc/s6_set.html | 100 | ||||
| -rw-r--r-- | src/s6-frontend/live_install.c | 5 | ||||
| -rw-r--r-- | src/s6-frontend/repository_list.c | 4 | ||||
| -rw-r--r-- | src/s6-frontend/s6-frontend-internal.h | 3 | ||||
| -rw-r--r-- | src/s6-frontend/set.c | 3 | ||||
| -rw-r--r-- | src/s6-frontend/set.help.txt | 22 | ||||
| -rw-r--r-- | src/s6-frontend/set_change.c | 50 | ||||
| -rw-r--r-- | src/s6-frontend/set_check.c | 15 | ||||
| -rw-r--r-- | src/s6-frontend/set_commit.c | 7 | ||||
| -rw-r--r-- | src/s6-frontend/set_copy.c | 65 | ||||
| -rw-r--r-- | src/s6-frontend/set_delete.c | 6 | ||||
| -rw-r--r-- | src/s6-frontend/set_list.c | 15 | ||||
| -rw-r--r-- | src/s6-frontend/set_status.c | 15 |
16 files changed, 201 insertions, 170 deletions
diff --git a/doc/overview.html b/doc/overview.html index f0f45f0..cd9f338 100644 --- a/doc/overview.html +++ b/doc/overview.html @@ -226,10 +226,10 @@ dependency tree dynamically. On the other hand, s6-frontend (and, more accuratel the <a href="//skarnet.org/software/s6-rc/">s6-rc</a> service manager and its <a href="//skarnet.org/software/s6-rc/repodefs.html">repo</a> commands), separates the notion of <em>live database</em> and of <em>working set</em> -entirely. The <em>working set</em> is worked on <em>offline</em>, without +entirely. A <em>working set</em> is worked on <em>offline</em>, without impacting the current machine state. You can <em>start</em> and <em>stop</em> live services, but you can only <em>enable</em> or <em>disable</em> -— or <em>mask</em> — services on the working set. Enabling a +— or <em>mask</em> — services on a working set. Enabling a service means that <em>next time you boot on the service database you are working on</em>, that service will be automatically started. <br /> Once you have worked on a set of services you can replace the live @@ -278,17 +278,17 @@ in which case it will give detailed information on its supervised instance. </td <td> <tt>rc-status default</tt> </td> <td> <tt>s6 live status</tt> or <tt>s6 set status</tt> </td> <td> <tt>s6 live status</tt> shows the status of the current live database, -<tt>s6 set status</tt> the status of the offline working set. </td> +<tt>s6 set status</tt> the status of the <tt>current</tt> offline working set. </td> </tr> <tr> <td> <tt>rc-update add foobar</tt> </td> <td> <tt>s6 set enable foobar</tt> </td> - <td> Enable service <tt>foobar</tt> in the offline working set. </td> + <td> Enable service <tt>foobar</tt> in the <tt>current</tt> offline working set. </td> </tr> <tr> <td> <tt>rc-update del foobar</tt> </td> <td> <tt>s6 set disable foobar</tt> </td> - <td> Disable service <tt>foobar</tt> in the offline working set. </td> + <td> Disable service <tt>foobar</tt> in the <tt>current</tt> offline working set. </td> </tr> <tr> <td> <tt>rc-update show</tt> </td> diff --git a/doc/s6_live.html b/doc/s6_live.html index 53f3359..0af54c5 100644 --- a/doc/s6_live.html +++ b/doc/s6_live.html @@ -78,12 +78,12 @@ of the service from its state. </li> <h4> Options </h4> <dl> -<dt> -e, --without-essentials </dt> +<dt> <tt>-e</tt>, <tt>--without-essentials</tt> </dt> <dd> Do not list essential services, which can clutter the display with irrelevant information and are all supposed to always be up anyway. This is the default. </dd> -<dt> -E, --with-essentials </dt> +<dt> <tt>-E</tt>, <tt>--with-essentials</tt> </dt> <dd> List all services, including essential ones. </dd> </dl> @@ -104,10 +104,10 @@ as well as their dependencies. </li> <h4> Options </h4> <dl> -<dt> -n, --dry-run </dt> +<dt> <tt>-n</tt>, <tt>--dry-run</tt> </dt> <dd> Only print what would be done; do not actually start services. </dd> -<dt> -t <em>timeout</em>, --timeout=<em>timeout</em> </dt> +<dt> <tt>-t <em>timeout</em></tt>, <tt>--timeout=<em>timeout</em></tt> </dt> <dd> If the whole change still hasn't completed after <em>timeout</em> milliseconds, stop waiting and don't attempt to perform the remaining transitions. By default, <em>timeout</em> is 0, meaning infinite: the @@ -131,10 +131,10 @@ as well as services that depends on them. </li> <h4> Options </h4> <dl> -<dt> -n, --dry-run </dt> +<dt> <tt>-n</tt>, <tt>--dry-run</tt> </dt> <dd> Only print what would be done; do not actually stop services. </dd> -<dt> -t <em>timeout</em>, --timeout=<em>timeout</em> </dt> +<dt> <tt>-t <em>timeout</em></tt>, <tt>--timeout=<em>timeout</em></tt> </dt> <dd> If the whole change still hasn't completed after <em>timeout</em> milliseconds, stop waiting and don't attempt to perform the remaining transitions. By default, <em>timeout</em> is 0, meaning infinite: the @@ -162,10 +162,10 @@ back up. </li> <h4> Options </h4> <dl> -<dt> -n, --dry-run </dt> +<dt> <tt>-n</tt>, <tt>--dry-run</tt> </dt> <dd> Only print what would be done; do not actually stop or start services. </dd> -<dt> -t <em>timeout</em>, --timeout=<em>timeout</em> </dt> +<dt> <tt>-t <em>timeout</em></tt>, <tt>--timeout=<em>timeout</em></tt> </dt> <dd> If the whole restart still hasn't completed after <em>timeout</em> milliseconds, stop waiting and don't attempt to perform the remaining transitions. By default, <em>timeout</em> is 0, meaning infinite: the @@ -189,16 +189,16 @@ the bundle of services that are enabled at boot time. </li> <h4> Options </h4> <dl> -<dt> -n, --dry-run </dt> +<dt> <tt>-n</tt>, <tt>--dry-run</tt> </dt> <dd> Only print what would be done; do not actually start services. </dd> -<dt> -t <em>timeout</em>, --timeout=<em>timeout</em> </dt> +<dt> <tt>-t <em>timeout</em></tt>, <tt>--timeout=<em>timeout</em></tt> </dt> <dd> If the whole change still hasn't completed after <em>timeout</em> milliseconds, stop waiting and don't attempt to perform the remaining transitions. By default, <em>timeout</em> is 0, meaning infinite: the command can wait forever. </dd> -<dt> -D <em>bundle</em>, --default-bundle=<em>bundle</em> </dt> +<dt> <tt>-D <em>bundle</em></tt>, <tt>--default-bundle=<em>bundle</em></tt> </dt> <dd> Start the bundle of services named <em>bundle</em> instead. The default is <tt>default</tt>, possibly overridden by the <tt>--with-default-bundle</tt> build-time configure option in @@ -223,15 +223,15 @@ reboot a machine; for that, check <a href="s6_system.html"><tt>s6 system</tt></a <h4> Options </h4> <dl> -<dt> -n, --dry-run </dt> +<dt> <tt>-n</tt>, <tt>--dry-run</tt> </dt> <dd> Only print what would be done; do not actually stop services. </dd> -<dt> -e, --without-essentials </dt> +<dt> <tt>-e</tt>, <tt>--without-essentials</tt> </dt> <dd> Do not stop essential services; keep the machine in a state where it can more or less run and be interacted with, even if in a completely bare state. This is the default. </dd> -<dt> -E, --with-essentials </dt> +<dt> <tt>-E</tt>, <tt>--with-essentials</tt> </dt> <dd> Also stop essential services. After this command the machine isn't good for much except a reboot. <code>s6 live stop-everything -E</code> is the command that should be run right before a shutdown when the @@ -239,7 +239,7 @@ system is not using s6-linux-init. To that end, the line <code>::shutdown:/usr/bin/s6 live stop-everything -E</code> should be added to <tt>/etc/inittab</tt>, if that is what the init uses. </dd> -<dt> -t <em>timeout</em>, --timeout=<em>timeout</em> </dt> +<dt> <tt>-t <em>timeout</em></tt>, <tt>--timeout=<em>timeout</em></tt> </dt> <dd> If the whole change still hasn't completed after <em>timeout</em> milliseconds, stop waiting and don't attempt to perform the remaining transitions. By default, <em>timeout</em> is 0, meaning infinite: the @@ -251,11 +251,11 @@ command can wait forever. </dd> <h4> Interface </h4> <pre> - s6 live install [ -b ] [ -K ] [ -f <em>convfile</em> ] [ --init ] + s6 live install [ -b ] [ -K ] [ -f <em>convfile</em> ] [ -s <em>setname</em> ] [ --init ] </pre> <ul> - <li> <tt>s6 live install</tt> installs the <em>current working set</em> + <li> <tt>s6 live install</tt> installs the <tt>current</tt> <em>working set</em> of services, that has been crafted and committed via <a href="s6_set.html"><tt>s6 set</tt></a> commands, replacing the current live service database. </li> @@ -267,21 +267,24 @@ stopped before the live database is replaced. </li> <h4> Options </h4> <dl> -<dt> -b, --block </dt> +<dt> <tt>-b</tt>, <tt>--block</tt> </dt> <dd> Block if something is currently holding the lock on the live service database. The default is to fail with an error message instead. </dd> -<dt> -K, --keep-old </dt> +<dt> <tt>-K</tt>, <tt>--keep-old</tt> </dt> <dd> Do not automatically delete the old service database after a successful switch. Instead, print its path to stdout. </dd> -<dt> -f <em>convfile</em>, --conversion-file=<em>convfile</em> </dt> +<dt> <tt>-f <em>convfile</em></tt>, <tt>--conversion-file=<em>convfile</em></tt> </dt> <dd> Use <em>convfile</em> as a <a href="//skarnet.org/software/s6-rc/s6-rc-update.html#conversion">conversion file</a> for the underlying <a href="//skarnet.org/software/s6-rc/s6-rc-update.html">s6-rc-update</a> invocation. This option should never be necessary if the services in the stores are properly managed. </dd> -<dt> --init </dt> +<dt> <tt>-s <em>setname</em></tt>, <tt>--set=<em>setname</em></tt> </dt> +<dd> Install the compiled set named <em>setname</em>. Default is <strong><tt>current</tt></strong>. </dd> + +<dt> <tt>--init</tt> </dt> <dd> Copy the compiled database of the current working set to the place where it can be booted on, but do not call diff --git a/doc/s6_repository.html b/doc/s6_repository.html index 1d33c0b..d9cfcc9 100644 --- a/doc/s6_repository.html +++ b/doc/s6_repository.html @@ -99,9 +99,9 @@ no impact whatsoever and this option can safely be ignored. </dd> </pre> <ul> - <li> <tt>s6 repository list</tt> lists all the saved sets in the repository, -printing their names on stdout, one per line. It does not list <tt>current</tt>, -the current working set, which always exists. </li> + <li> <tt>s6 repository list</tt> lists all the sets in the repository, +printing their names on stdout, one per line. <tt>current</tt> is the +default working set and always exists. </li> <li> No options are defined. </li> </ul> diff --git a/doc/s6_set.html b/doc/s6_set.html index 8f0e969..bd74233 100644 --- a/doc/s6_set.html +++ b/doc/s6_set.html @@ -37,7 +37,7 @@ setting services in a state that remains theoretical until the user <p> <tt>s6 set</tt> commands always operate on a "working set" of services, -which is internally named <tt>current</tt>. It is not the set that is +which is by default named <tt>current</tt>. It is not the set that is currently live; it is the set that is currently worked on. </p> @@ -56,41 +56,27 @@ currently live; it is the set that is currently worked on. and usage of the <tt>s6 set</tt> command. It is not as detailed as this page. </p> -<h3 id="save"> save </h3> +<h3 id="copy"> copy </h3> <h4> Interface </h4> <pre> - s6 set save [ -f ] <em>name</em> + s6 set copy [ -f ] <em>source</em> <em>dest</em> </pre> <ul> - <li> <tt>s6 set save</tt> saves a copy of the current working set into a -set named <em>name</em>. </li> - <li> <em>name</em> can be loaded by <a href="#load"><tt>s6 set load <em>name</em></tt></a>. </li> + <li> <tt>s6 set copy</tt> copies the set named <em>source</em> to a new set +named <em>dest</em>. </li> + <li> There is always at least one set named <tt>current</tt>. This is the set being +operated on by default by every <tt>s6 set</tt> command. </li> </ul> <h4> Options </h4> <dl> <dt> -f, --force </dt> -<dd> If a set named <em>name</em> already exists, overwrite it with a copy -of the current working set. By default, the command exits with an error -instead of overwriting. </dd> - -<h3 id="load"> load </h3> - -<h4> Interface </h4> - -<pre> - s6 set load <em>name</em> -</pre> - -<ul> - <li> <tt>s6 set load</tt> replaces the current working set with the set stored -as <em>name</em>. </li> - <li> No options are defined. </li> -</ul> +<dd> If <em>dest</em> already exists, overwrite it with a copy of <em>source</em>. +By default, the command exits with an error instead of overwriting. </dd> <h3 id="delete"> delete </h3> @@ -102,6 +88,7 @@ as <em>name</em>. </li> <ul> <li> <tt>s6 set delete</tt> deletes the saved sets named <em>names...</em> </li> + <li> The set named <tt>current</tt> cannot be deleted. </li> <li> No options are defined. </li> </ul> @@ -110,11 +97,11 @@ as <em>name</em>. </li> <h4> Interface </h4> <pre> - s6 set list [ -E | -e ] + s6 set list [ -E | -e ] [ -s <em>setname</em> ] </pre> <ul> - <li> <tt>s6 set list</tt> lists all the services in the current set, + <li> <tt>s6 set list</tt> lists all the services in the <tt>current</tt> set, printing their names on stdout, one per line. </li> </ul> @@ -127,6 +114,9 @@ default. </dd> <dt> -e, --without-essentials </dt> <dd> Do not list essential services. </dd> + +<dt> <tt>-s <em>setname</em></tt>, <tt>--set=<em>setname</em></tt> </dt> +<dd> List the services in the set named <em>setname</em> rather than <tt>current</tt>. </dd> </dl> <h3 id="status"> status </h3> @@ -134,12 +124,12 @@ default. </dd> <h4> Interface </h4> <pre> - s6 set status [ -E | -e ] [ <em>names...</em> ] + s6 set status [ -E | -e ] [ -s <em>setname</em> ] [ <em>names...</em> ] </pre> <ul> <li> <tt>s6 set status</tt> lists the services named <em>names...</em> -in the working set with their current +in the <tt>current</tt> set with their current <a href="//skarnet.org/software/s6-rc/repodefs.html#rx">prescription</a>, i.e. the state that they should be in at boot time: masked, disabled (listed as <tt>usable</tt>), enabled (listed as <tt>active</tt>), or essential @@ -180,6 +170,9 @@ default. </dd> <dt> -e, --without-essentials </dt> <dd> Do not print essential services. </dd> + +<dt> <tt>-s <em>setname</em></tt>, <tt>--set=<em>setname</em></tt> </dt> +<dd> List the services in the set named <em>setname</em>, rather than <tt>current</tt>. </dd> </dl> <div id="enable"> @@ -198,7 +191,7 @@ currently running database. <h4> Interface </h4> <pre> - s6 set enable|disable|mask|unmask|make-essential [ -f ] [ -n ] [ -I fail|warn|pull ] [ <em>services...</em> ] + s6 set enable|disable|mask|unmask|make-essential [ -n ] [ -I | -i ] [ -P | -p ] [ -s <em>setname</em> ] [ <em>services...</em> ] </pre> <ul> @@ -224,28 +217,33 @@ make the set inconsistent. </li> <h4> Options </h4> <dl> -<dt> -f, --ignore-dependencies </dt> -<dd> Only change the services listed in <em>services</em>, don't compute dependencies. </dd> <dt> -n, --dry-run </dt> <dd> Do not perform the change; only show what would be done and check whether the set would be made inconsistent. </dd> -<dt> -I <em>what</em>, --if-dependencies-found=<em>what</em> </dt> -<dd> What to do when services have dependencies, or reverse dependencies, that are not -listed in <em>services...</em>. <em>what</em> can be <tt>fail</tt>, <tt>warn</tt>, -or <tt>pull</tt>. - <ul> - <li> <tt>fail</tt>: abort the operation with an error message. </li> - <li> <tt>warn</tt>: perform the operation with a warning message. The set might -be inconsistent afterwards, that can be changed by manually changing the dependencies -or by fixing the set (see below). </li> - <li> <tt>pull</tt>: resolve inconsistencies by pulling the dependencies into the -same prescription as the listed service. For <tt>enable</tt>, -service dependencies are made <em>active</em> as well. For <tt>disable</tt>, reverse -dependencies are disabled as well. For <tt>mask</tt>, reverse dependencies are -masked as well. </li> - </ul> + <dt> <tt>-I</tt>, <tt>--no-fail-on-dependencies</tt> </dt> + <dd> Do not fail if a dependency (to a service that's outside the listed ones) is found. +This is the default. Depending on the <tt>-p</tt> flag, either a warning message will be +printed and an inconsistent set will be made, or the dependency will be pulled into the change. </dd> + + <dt> <tt>-i</tt>, <tt>--fail-on-dependencies</tt> </dt> + <dd> If a dependency is found that would create an inconsistent set if the change was +applied, print an error message and exit 1. </dd> + + <dt> <tt>-P</tt>, <tt>--no-pull-dependencies</tt> </dt> + <dd> If a dependency is found that would create an inconsistent set if the change was +applied, print a warning message (if verbosity is not 0) listing the services that +also need to change prescriptions; then apply the change anyway. This is the default. </dd> + + <dt> <tt>-p</tt>, <tt>--pull-dependencies</tt> </dt> + <dd> If a dependency is found that would create an inconsistent set, automatically +extend the change to the dependencies as well so the set remain consistent. Print an +informational message (if verbosity is 2 or more) listing the services that are being +pulled into the change, then apply the change. </dd> + + <dt> <tt>-s <em>setname</em></tt>, <tt>--set=<em>setname</em></tt> </dt> + <dd> Perform the change on set <em>setname</em>. Default is <strong>current</strong> </dd> </dl> <h3 id="check"> check </h3> @@ -253,11 +251,11 @@ masked as well. </li> <h4> Interface </h4> <pre> - s6 set check [ -F ] [ -d | -u ] [ -E | -e ] + s6 set check [ -F ] [ -d | -u ] [ -E | -e ] [ -s <em>setname</em> ] </pre> <ul> - <li> <tt>s6 set check</tt> checks the current working set for + <li> <tt>s6 set check</tt> checks the <tt>current</tt> set for inconsistencies, printing anything it finds to stdout. </li> </ul> @@ -290,6 +288,9 @@ default. </dd> <dd> Fix the set by enabling or unmasking services. If service <tt>A</tt> depends on service <tt>B</tt> and <tt>A</tt> is unmasked or enabled, change <tt>B</tt> to be unmasked or enabled as well. </dd> + +<dt> <tt>-s <em>setname</em></tt>, <tt>--set=<em>setname</em></tt> </dt> +<dd> Check the set named <em>setname</em>, rather than <tt>current</tt>. </dd> </dl> <h3 id="commit"> commit </h3> @@ -297,7 +298,7 @@ change <tt>B</tt> to be unmasked or enabled as well. </dd> <h4> Interface </h4> <pre> - s6 set commit [ -f ] [ -K ] [ -D <em>defaultbundle</em> ] [ -h <em>fdhuser</em> ] + s6 set commit [ -f ] [ -K ] [ -D <em>defaultbundle</em> ] [ -h <em>fdhuser</em> ] [ -s <em>setname</em> ] </pre> <ul> @@ -337,6 +338,9 @@ to change the default, which depends on the distribution and is probably called the set. This must be a user name defined in the <tt>/etc/passwd</tt> file or whatever user database the system uses. The default is <tt>root</tt> and that is fine. </dd> + +<dt> <tt>-s <em>setname</em></tt>, <tt>--set=<em>setname</em></tt> </dt> +<dd> Commit the set named <em>setname</em>, rather than <tt>current</tt>. </dd> </dl> </body> diff --git a/src/s6-frontend/live_install.c b/src/s6-frontend/live_install.c index 6ab0780..10861f3 100644 --- a/src/s6-frontend/live_install.c +++ b/src/s6-frontend/live_install.c @@ -19,6 +19,7 @@ enum golb_e enum gola_e { GOLA_CONVFILE, + GOLA_SET, GOLA_N } ; @@ -35,12 +36,14 @@ void live_install (char const *const *argv) static gol_arg const rgola[] = { { .so = 'f', .lo = "conversion-file", .i = GOLA_CONVFILE }, + { .so = 's', .lo = "set", .i = GOLA_SET }, } ; uint64_t wgolb = 0 ; unsigned int m = 0 ; char const *wgola[GOLA_N] = { 0 } ; char const *newargv[18] ; char fmtv[UINT_FMT] ; + wgola[GOLA_SET] = "current" ; argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ; @@ -68,7 +71,7 @@ void live_install (char const *const *argv) } if (wgolb & GOLB_INIT) newargv[m++] = "--no-update" ; newargv[m++] = "--" ; - newargv[m++] = "current" ; + newargv[m++] = wgola[GOLA_SET] ; newargv[m++] = 0 ; main_exec(newargv) ; } diff --git a/src/s6-frontend/repository_list.c b/src/s6-frontend/repository_list.c index b34ac71..063b9d6 100644 --- a/src/s6-frontend/repository_list.c +++ b/src/s6-frontend/repository_list.c @@ -8,7 +8,7 @@ void repository_list (char const *const *argv) { - char const *newargv[9] ; + char const *newargv[7] ; unsigned int m = 0 ; char fmtv[UINT_FMT] ; newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-repo-list" ; @@ -20,8 +20,6 @@ void repository_list (char const *const *argv) } newargv[m++] = "-r" ; newargv[m++] = g->dirs.repo ; - newargv[m++] = "-x" ; - newargv[m++] = "current" ; newargv[m++] = "--" ; newargv[m++] = 0 ; diff --git a/src/s6-frontend/s6-frontend-internal.h b/src/s6-frontend/s6-frontend-internal.h index 843ad41..7bd1409 100644 --- a/src/s6-frontend/s6-frontend-internal.h +++ b/src/s6-frontend/s6-frontend-internal.h @@ -74,8 +74,7 @@ extern void set_help (char const *const *) gccattr_noreturn ; extern void set_list (char const *const *) gccattr_noreturn ; extern void set_status (char const *const *) gccattr_noreturn ; -extern void set_load (char const *const *) gccattr_noreturn ; -extern void set_save (char const *const *) gccattr_noreturn ; +extern void set_copy (char const *const *) gccattr_noreturn ; extern void set_delete (char const *const *) gccattr_noreturn ; extern void set_mask (char const *const *) gccattr_noreturn ; diff --git a/src/s6-frontend/set.c b/src/s6-frontend/set.c index 8123371..fe5f165 100644 --- a/src/s6-frontend/set.c +++ b/src/s6-frontend/set.c @@ -25,15 +25,14 @@ void set (char const *const *argv) { { .s = "check", .f = &set_check }, { .s = "commit", .f = &set_commit }, + { .s = "copy", .f = &set_copy }, { .s = "delete", .f = &set_delete }, { .s = "disable", .f = &set_disable }, { .s = "enable", .f = &set_enable }, { .s = "help", .f = &set_help }, { .s = "list", .f = &set_list }, - { .s = "load", .f = &set_load }, { .s = "make-essential", .f = &set_make_essential }, { .s = "mask", .f = &set_mask }, - { .s = "save", .f = &set_save }, { .s = "status", .f = &set_status }, { .s = "unmask", .f = &set_unmask }, } ; diff --git a/src/s6-frontend/set.help.txt b/src/s6-frontend/set.help.txt index 362ee9f..62b59ea 100644 --- a/src/s6-frontend/set.help.txt +++ b/src/s6-frontend/set.help.txt @@ -2,8 +2,8 @@ Usage: s6 set subcommand [ options ] [ arguments... ] Subcommands: help this message - save save the current set under a user-provided name - load load a previously saved set + copy copy a set to another name (default name is "current") + delete delete one or more sets list list services in the working set status list services in the working set with their rx enable enable services @@ -14,21 +14,27 @@ Subcommands: commit commit working set (can then be installed) -s6 set save options: +s6 set copy options: -f --force overwrite named set if existing -s6 set load options: none +s6 set delete options: none -s6 set list options: none +s6 set list options: + -s SET --set=SET show services in set SET (default: current) s6 set status options: -E --with-essentials show all services, even essential ones (default) -e --without-essentials don't show essential services + -s SET --set=SET show services in set SET (default: current) s6 set enable|disable|mask|unmask options: -f --ignore-dependencies only change listed services -n --dry-run show what would happen, don't do - -I WHAT --if-dependencies-found=WHAT WHAT=warn (default) | fail | pull (dependencies will be brought to the same rx) + -I --no-fail-on-dependencies warn or pull unlisted dependencies if found (default) + -i --fail-on-dependencies fail if unlisted dependencies are found + -P --no-pull-dependencies warn on unlisted dependencies (default) + -p --pull-dependencies apply the rx change to unlisted dependencies as well + -s SET --set=SET change services in set SET (default: current) s6 set check options: -E --no-force-essential do not allow manual changes to essential services (default) @@ -36,10 +42,12 @@ s6 set check options: -F --fix try to fix inconsistencies automatically -d --down fix by disabling or masking services if necessary (default) -u --up fix by enabling services if necessary + -s SET --set=SET check set SET (default: current) s6 set commit options: -f --force compile db even if up-to-date -K --keep-old keep old db if any, print its path to stdout -D BUN --default-bundle=BUN name of the bundle containing enabled+essential services - -h USER --fdholder-user=USER user for the s6-fdholderd process (default=root, it's fine) + -h USER --fdholder-user=USER user for the s6-fdholderd process (default: root - it's fine) + -s SET --set=SET commit set SET (default: current) diff --git a/src/s6-frontend/set_change.c b/src/s6-frontend/set_change.c index 64b6fbf..a0db9b7 100644 --- a/src/s6-frontend/set_change.c +++ b/src/s6-frontend/set_change.c @@ -11,13 +11,14 @@ enum golb_e { - GOLB_IGNORE_DEPENDENCIES = 0x02, - GOLB_DRYRUN = 0x04, + GOLB_DRYRUN = 0x02, + GOLB_FAIL_ON_DEPS = 0x04, + GOLB_PULL_DEPS = 0x08, } ; enum gola_e { - GOLA_FORCELEVEL, + GOLA_SET, GOLA_N } ; @@ -26,30 +27,28 @@ static void set_change (char const *const *argv, char const *newrx, char const * { static gol_bool const rgolb[] = { - { .so = 'f', .lo = "ignore-dependencies", .clear = 0, .set = GOLB_IGNORE_DEPENDENCIES }, - { .so = 'n', .lo = "dry-run", .clear = 0, .set = GOLB_DRYRUN } + { .so = 0, .lo = "no-dry-run", .clear = GOLB_DRYRUN, .set = 0 }, + { .so = 'n', .lo = "dry-run", .clear = 0, .set = GOLB_DRYRUN }, + { .so = 'I', .lo = "no-fail-on-dependencies", .clear = GOLB_FAIL_ON_DEPS, .set = 0 }, + { .so = 'i', .lo = "fail-on-dependencies", .clear = 0, .set = GOLB_FAIL_ON_DEPS }, + { .so = 'P', .lo = "no-pull-dependencies", .clear = GOLB_PULL_DEPS, .set = 0 }, + { .so = 'p', .lo = "pull-dependencies", .clear = 0, .set = GOLB_PULL_DEPS }, } ; static gol_arg const rgola[] = { - { .so = 'I', .lo = "if-dependencies-found", .i = GOLA_FORCELEVEL } + { .so = 's', .lo = "set", .i = GOLA_SET }, } ; uint64_t wgolb = 0 ; + char const *wgola[GOLA_N] = { [GOLA_SET] = "current" } ; unsigned int m = 0 ; + unsigned int argc ; - char const *wgola[GOLA_N] = { 0 } ; argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ; - if (!*argv) strerr_die(100, "usage: ", "s6 set ", cmd, " [ --ignore-dependencies ] [ --dry-run ] [ --if-dependencies-found=fail|warn|pull ] services...") ; - argc = env_len(argv) ; - if (wgola[GOLA_FORCELEVEL]) - { - if (strcmp(wgola[GOLA_FORCELEVEL], "fail") - && strcmp(wgola[GOLA_FORCELEVEL], "pull") - && strcmp(wgola[GOLA_FORCELEVEL], "warn")) - strerr_dief1x(100, "--if-dependencies-found= argument must be fail, warn or pull") ; - } + if (!*argv) strerr_die(100, "usage: ", "s6 set ", cmd, " [ --dry-run ] [ --fail-on-dependencies | --pull-dependencies ] [ --set=setname ] services...") ; + argc = env_len(argv) ; char fmtv[UINT_FMT] ; - char const *newargv[14 + argc] ; + char const *newargv[13 + argc] ; newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-change" ; if (g->verbosity != 1) { @@ -59,21 +58,14 @@ static void set_change (char const *const *argv, char const *newrx, char const * } newargv[m++] = "-r" ; newargv[m++] = g->dirs.repo ; - if (wgolb & GOLB_IGNORE_DEPENDENCIES) - newargv[m++] = "-f" ; - if (wgolb & GOLB_DRYRUN) - newargv[m++] = "-n" ; - if (wgola[GOLA_FORCELEVEL]) - { - newargv[m++] = "-I" ; - newargv[m++] = wgola[GOLA_FORCELEVEL] ; - } + if (wgolb & GOLB_DRYRUN) newargv[m++] = "-n" ; if (!strcmp(newrx, "always")) newargv[m++] = "-e" ; + if (wgolb & GOLB_FAIL_ON_DEPS) newargv[m++] = "-i" ; + if (wgolb & GOLB_PULL_DEPS) newargv[m++] = "-p" ; newargv[m++] = "--" ; - newargv[m++] = "current" ; + newargv[m++] = wgola[GOLA_SET] ; newargv[m++] = newrx ; - for (unsigned int i = 0 ; i < argc ; i++) - newargv[m++] = argv[i] ; + for (unsigned int i = 0 ; i < argc ; i++) newargv[m++] = argv[i] ; newargv[m++] = 0 ; main_exec(newargv) ; } diff --git a/src/s6-frontend/set_check.c b/src/s6-frontend/set_check.c index a76d538..f0cd536 100644 --- a/src/s6-frontend/set_check.c +++ b/src/s6-frontend/set_check.c @@ -18,6 +18,12 @@ enum golb_e GOLB_FIX = 0x04, } ; +enum gola_e +{ + GOLA_SET, + GOLA_N +} ; + void set_check (char const *const *argv) { static gol_bool const rgolb[] = @@ -28,12 +34,17 @@ void set_check (char const *const *argv) { .so = 'u', .lo = "up", .clear = 0, .set = GOLB_FIXUP }, { .so = 'F', .lo = "fix", .clear = 0, .set = GOLB_FIX }, } ; + static gol_arg const rgola[] = + { + { .so = 's', .lo = "set", .i = GOLA_SET }, + } ; uint64_t wgolb = 0 ; + char const *wgola[GOLA_N] = { [GOLA_SET] = "current" } ; unsigned int m = 0 ; char const *newargv[11] ; char fmtv[UINT_FMT] = " " ; - argv += gol_argv(argv, rgolb, 5, 0, 0, &wgolb, 0) ; + argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ; newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-fix" ; if (g->verbosity != 1) @@ -48,7 +59,7 @@ void set_check (char const *const *argv) newargv[m++] = wgolb & GOLB_FIXUP ? "--fix-up" : "--fix-down" ; if (!(wgolb & GOLB_FIX)) newargv[m++] = "--dry-run" ; newargv[m++] = "--" ; - newargv[m++] = "current" ; + newargv[m++] = wgola[GOLA_SET] ; newargv[m++] = 0 ; main_exec(newargv) ; diff --git a/src/s6-frontend/set_commit.c b/src/s6-frontend/set_commit.c index 887d5d9..3e0fae2 100644 --- a/src/s6-frontend/set_commit.c +++ b/src/s6-frontend/set_commit.c @@ -18,6 +18,7 @@ enum gola_e { GOLA_DEFBUNDLE, GOLA_FDHUSER, + GOLA_SET, GOLA_N } ; @@ -31,7 +32,8 @@ void set_commit (char const *const *argv) static gol_arg const rgola[] = { { .so = 'D', .lo = "default-bundle", .i = GOLA_DEFBUNDLE }, - { .so = 'h', .lo = "fdholder-user", .i = GOLA_FDHUSER } + { .so = 'h', .lo = "fdholder-user", .i = GOLA_FDHUSER }, + { .so = 's', .lo = "set", .i = GOLA_SET }, } ; uint64_t wgolb = 0 ; @@ -41,6 +43,7 @@ void set_commit (char const *const *argv) char fmtv[UINT_FMT] ; wgola[GOLA_DEFBUNDLE] = S6_FRONTEND_DEFBUNDLE ; + wgola[GOLA_SET] = "current" ; argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ; newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-commit" ; @@ -62,7 +65,7 @@ void set_commit (char const *const *argv) newargv[m++] = wgola[GOLA_FDHUSER] ; } newargv[m++] = "--" ; - newargv[m++] = "current" ; + newargv[m++] = wgola[GOLA_SET] ; newargv[m++] = 0 ; main_exec(newargv) ; } diff --git a/src/s6-frontend/set_copy.c b/src/s6-frontend/set_copy.c index 07b9e24..b9f9713 100644 --- a/src/s6-frontend/set_copy.c +++ b/src/s6-frontend/set_copy.c @@ -17,50 +17,37 @@ enum golb_e GOLB_FORCE = 0x01, } ; -static void set_copy (char const *from, char const *to, int force) gccattr_noreturn ; -static void set_copy (char const *from, char const *to, int force) +void set_copy (char const *const *argv) { - unsigned int m = 0 ; - char const *argv[10] ; - char fmtv[UINT_FMT] ; - argv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-copy" ; - if (g->verbosity != 1) - { - fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ; - argv[m++] = "-v" ; - argv[m++] = fmtv ; - } - argv[m++] = "-r" ; - argv[m++] = g->dirs.repo ; - if (force) argv[m++] = "-f" ; - argv[m++] = "--" ; - argv[m++] = from ; - argv[m++] = to ; - argv[m++] = 0 ; - main_exec(argv) ; -} - -void set_save (char const *const *argv) -{ - static gol_bool const rgolb[] = + static gol_bool const rgolb[] = { { .so = 'f', .lo = "force", .clear = 0, .set = GOLB_FORCE }, } ; uint64_t wgolb = 0 ; + unsigned int m = 0 ; + char const *newargv[10] ; + char fmtv[UINT_FMT] ; + argv += gol_argv(argv, rgolb, 1, 0, 0, &wgolb, 0) ; - if (!*argv) strerr_die(100, "usage: ", "s6 set ", "save [ --force ] name") ; - if (argv[0][0] == '.' || strchr(argv[0], '/') || strchr(argv[0], '\n') - || !strcmp(argv[0], "current")) - strerr_dief1x(100, "invalid set name") ; - set_copy("current", argv[0], !!(wgolb & GOLB_FORCE)) ; -} + if (!argv[0] || !argv[1]) strerr_die(100, "usage: ", "s6 set ", "copy [ --force ] source destination") ; + if (argv[0][0] == '.' || strchr(argv[0], '/') || strchr(argv[0], '\n')) + strerr_dief(100, "invalid ", "source", " set name") ; + if (argv[1][0] == '.' || strchr(argv[1], '/') || strchr(argv[1], '\n')) + strerr_dief(100, "invalid ", "destination", " set name") ; -void set_load (char const *const *argv) -{ - argv += gol_argv(argv, 0, 0, 0, 0, 0, 0) ; - if (!*argv) strerr_die(100, "usage: ", "s6 set ", "load name") ; - if (argv[0][0] == '.' || strchr(argv[0], '/') || strchr(argv[0], '\n') - || !strcmp(argv[0], "current")) - strerr_dief1x(100, "invalid set name") ; - set_copy(argv[0], "current", 1) ; + newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-copy" ; + if (g->verbosity != 1) + { + fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ; + newargv[m++] = "-v" ; + newargv[m++] = fmtv ; + } + newargv[m++] = "-r" ; + newargv[m++] = g->dirs.repo ; + if (wgolb & GOLB_FORCE) newargv[m++] = "-f" ; + newargv[m++] = "--" ; + newargv[m++] = argv[0] ; + newargv[m++] = argv[1] ; + newargv[m++] = 0 ; + main_exec(newargv) ; } diff --git a/src/s6-frontend/set_delete.c b/src/s6-frontend/set_delete.c index f5e5e37..9346d3b 100644 --- a/src/s6-frontend/set_delete.c +++ b/src/s6-frontend/set_delete.c @@ -17,9 +17,11 @@ void set_delete (char const *const *argv) argc = env_len(argv) ; for (unsigned int i = 0 ; i < argc ; i++) - if (argv[i][0] == '.' || strchr(argv[i], '/') || strchr(argv[i], '\n') - || !strcmp(argv[i], "current")) + { + if (argv[i][0] == '.' || strchr(argv[i], '/') || strchr(argv[i], '\n')) strerr_dief(100, "invalid set name: ", argv[i]) ; + if (!strcmp(argv[i], "current")) strerr_diefu(100, "delete current set") ; + } unsigned int m = 0 ; char const *newargv[7 + argc] ; diff --git a/src/s6-frontend/set_list.c b/src/s6-frontend/set_list.c index f5eeeb1..d1a127f 100644 --- a/src/s6-frontend/set_list.c +++ b/src/s6-frontend/set_list.c @@ -14,6 +14,12 @@ enum golb_e GOLB_IGNORE_ESSENTIALS = 0x01, } ; +enum gola_e +{ + GOLA_SET, + GOLA_N +} ; + void set_list (char const *const *argv) { static gol_bool const rgolb[] = @@ -21,11 +27,16 @@ void set_list (char const *const *argv) { .so = 'E', .lo = "with-essentials", .clear = GOLB_IGNORE_ESSENTIALS, .set = 0 }, { .so = 'e', .lo = "without-essentials", .clear = 0, .set = GOLB_IGNORE_ESSENTIALS }, } ; + static gol_arg const rgola[] = + { + { .so = 's', .lo = "set", .i = GOLA_SET }, + } ; uint64_t wgolb = 0 ; + char const *wgola[GOLA_N] = { [GOLA_SET] = "current" } ; unsigned int m = 0 ; char const *newargv[10] ; char fmtv[UINT_FMT] ; - argv += gol_argv(argv, rgolb, 2, 0, 0, &wgolb, 0) ; + argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ; newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-status" ; fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ; @@ -36,7 +47,7 @@ void set_list (char const *const *argv) newargv[m++] = "-L" ; newargv[m++] = wgolb & GOLB_IGNORE_ESSENTIALS ? "--without-essentials" : "--with-essentials" ; newargv[m++] = "--" ; - newargv[m++] = "current" ; + newargv[m++] = wgola[GOLA_SET] ; newargv[m++] = 0 ; main_exec(newargv) ; } diff --git a/src/s6-frontend/set_status.c b/src/s6-frontend/set_status.c index a5dd094..8f397b8 100644 --- a/src/s6-frontend/set_status.c +++ b/src/s6-frontend/set_status.c @@ -16,6 +16,12 @@ enum golb_e GOLB_IGNORE_ESSENTIALS = 0x01, } ; +enum gola_e +{ + GOLA_SET, + GOLA_N +} ; + void set_status (char const *const *argv) { static gol_bool const rgolb[] = @@ -23,12 +29,17 @@ void set_status (char const *const *argv) { .so = 'E', .lo = "with-essentials", .clear = GOLB_IGNORE_ESSENTIALS, .set = 0 }, { .so = 'e', .lo = "without-essentials", .clear = 0, .set = GOLB_IGNORE_ESSENTIALS }, } ; + static gol_arg const rgola[] = + { + { .so = 's', .lo = "set", .i = GOLA_SET }, + } ; uint64_t wgolb = 0 ; + char const *wgola[GOLA_N] = { [GOLA_SET] = "current" } ; unsigned int m = 0 ; unsigned int argc ; char fmtv[UINT_FMT] = " " ; - argv += gol_argv(argv, rgolb, 2, 0, 0, &wgolb, 0) ; + argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ; argc = env_len(argv) ; if (!set_check_service_names(argv, argc)) strerr_dief1x(100, "invalid service name") ; @@ -42,7 +53,7 @@ void set_status (char const *const *argv) newargv[m++] = g->dirs.repo ; newargv[m++] = wgolb & GOLB_IGNORE_ESSENTIALS ? "--without-essentials" : "--with-essentials" ; newargv[m++] = "--" ; - newargv[m++] = "current" ; + newargv[m++] = wgola[GOLA_SET] ; for (unsigned int i = 0 ; i < argc ; i++) newargv[m++] = argv[i] ; newargv[m++] = 0 ; |
