=head1 NAME

aa-enable - Enable services, i.e. copy servicedirs to repodir

=head1 SYNOPSIS

B<aa-enable> [B<-D>] [B<-r> I<REPODIR>] [B<-c> I<CRASH>] [B<-f> I<FINISH>]
[B<-k> I<SERVICE>] [B<-S> I<SOURCEDIR>] [B<-s> I<SOURCEDIR>] [B<-l> I<LISTDIR>]
[B<-N>] [B<-W>] [B<-u>] [B<-a>] [B<--no-supervise>] [B<-q>] [I<SERVICE...>]

=head1 OPTIONS

=over

=item B<-a, --alarm-s6>

Alarms I<s6-svscan> as last step; This obviously assumes there is a running
instance of I<s6-svscan> running on I<REPODIR/.scandir>; Also note that it will
do it regardless of whether longruns where added or not.

"Alarm" means I<s6-svscan> will immediately perform a scan of its scandir to
check for (new) services. This is equivalent to manually running
C<s6-svscan -a REPODIR/.scandir> afterwards.

=item B<-c, --set-crash> I<CRASH>

Create a symlink I<REPODIR/.scandir/.s6-svscan/crash> that points to I<CRASH>.
This is what B<s6-svscan> will exec into if it crashes.

=item B<-D, --double-output>

Enable double-output mode. Instead of using stdout for regular output, and
stderr for warnings and errors, everything is sent both to stdout and stderr.
This is intended to redirect stderr to a log file, so full output can be both
shown on console and logged.

=item B<-f, --set-finish> I<FINISH>

Create a symlink I<REPODIR/.scandir/.s6-svscan/finish> that points to I<FINISH>.
This is what B<s6-svscan> will exec into when it's done. This would usually
point to B<aa-stage3>(1).

=item B<-h, --help>

Show help screen and exit.

=item B<-k, --skip-down> I<SERVICE>

When (if) enabling I<SERVICE> do not create a file I<down> even it there's none
and it is a longrun service. This is intended to be used during stage 1, for
the catch-all logger service, which needs to be started automatically by
B<s6-svscan> (to unblock & trigger stage 2).

=item B<-l, --listdir> I<LISTDIR>

Use I<LISTDIR> to list services to enable. Only one can be set, if specified
more than once the last one will be used.

The directory will be read, and names of files/directories within be used as
service name to enable. For directories, their content will be merged/copied
into the servicedir; See below for more.

If I<LISTDIR> doesn't start with a slash or dot, it will be prefixed with
I</etc/anopa/listdirs/>

=item B<-N, --no-needs>

Don't auto-enable any services listed under directory I<needs> of a service
being (auto-)enabled.

=item B<-q, --quiet>

Don't print enabled service names.

=item B<-r, --repodir> I<REPODIR>

Use I<REPODIR> as repository directory. This is where all servicedirs will be
created/copied to.

=item B<-S, --reset-source> I<SOURCEDIR>

Reset the list of source directories to I<SOURCEDIR>. You can add more with
B<--source>. This is useful to unset the defaults.

=item B<-s, --source> I<SOURCEDIR>

Add I<SOURCEDIR> as new source. Can be specified multiple times; Source
directories will be processed in the order they were added.

=item B<-u, --upgrade>

Upgrade servicedirs instead of creating them. See below for implications.

=item B<--no-supervise>

Disable creation of I<supervise> folders for longrun services. By default,
B<aa-enable>(1) will create a folder I<supervise> with permissions 0711 for
every longrun service (including loggers).

This is meant to ensure one can read the s6 status file (which is
world-readable by default) without the need to be root. This allows for example
to use B<aa-status>(1) as a user properly.

If you were to disable this, the I<supervise> folders would likely be created by
B<s6-supervise> with 0700 permissions, and when trying to read s6 status as a
user a "Permission denied" error would occur.

=item B<-V, --version>

Show version information and exit.

=item B<-W, --no-wants>

Don't auto-enable any services listed under directory I<wants> of a service
being (auto-)enabled.

=back

=head1 DESCRIPTION

With B<anopa>, you usually create your service repository early on boot (during
stage 1) into tmpfs (I</run/services>). This ensures that no previous
state/files from an earlier boot will interfere with the current one, leaving
your main filesystem untouched (it could even be read-only).

By default the repository directory used is I</run/services> and source
directories are, in order, I</etc/anopa/services> and I</usr/lib/services>

Also note that by default B<aa-enable>(1) will auto-enable any service whose
name was found in a directory I<need> or I<wants> of a created servicedir. This
can be turned off via B<--no-needs> and/or B<--no-wants> if needed.

You can use B<-> as service name to read actual service names from stdin, where
there must be one name per line.

=head2 Enabling a service / Creating a servicedir

Instead of simply creating the repository ahead of time, and copying it all on
boot, the copying process is done through B<aa-enable>(1) which works as such:

- The given I<LISTDIR> is read. It contains either empty regular files, or
directories, whose name is the name of a service to enable.

- Source directories are tried, in order, to find the corresponding servicedir,
which is then copied over to the runtime repository (I<REPODIR>). During this
copy, B<aa-enable>(1) notes whether or not a file I<run> exists, i.e. whether
this is a long-run or one-shot service.

- If the service name came from a directory in I<LISTDIR>, its content is then
merged/copied over into the servicedir. This allows to specify service-specific
configuration, or could possibly be used to overwrite an actual script. See
below for how to remove/append to files.

- If the service is a long-run, an empty regular file I<down> is created (unless
it already existed, or the service was specified to B<--skip-down>) to ensure
the service won't be auto-started by B<s6-svscan>, and a symlink is added to the
servicedir into the I<.scandir> sub-directory of I<REPODIR> (even if the service
was specified to B<--skip-down>).
And, unless option B<--no-supervise> was specified, a folder I<supervise> is
created with 0711 permissions.

- As last step, B<aa-enable>(1) will check if a regular file I<log/run-args>
exists in the newly created servicedir, and if so its content will be appended
to I<log/run>

=head2 Special case: Instances

Service names cannot start nor end with a @ character, but can contain one.
servicedirs in source directories shall not contain a @ character, unless it is
the last character in their name.

The idea is to use the notion of "instances." Imagine a service that starts a
getty on a tty. Instead of needing to write as many servicedirs as you want
gettys on ttys, you simply write one, named I<getty@>

Then, you can enable I<getty@tty1> and I<getty@tty2>. For the service name
I<getty@tty1>, we say the service used in I<getty> for instance I<tty1>. The way
it works in B<aa-enable>(1) is that it will look for a servicedir I<getty@> in
source directories, but will copy it as I<getty@tty1> into the repository.

Then, in your run/finish/start/stop script(s), you can e.g. use B<aa-service>(1)
to get the service & instance names and use them as needed.

Additionally, whenever copying content of the directories I<needs>, I<wants>,
I<after> and I<before>, B<aa-enable>(1) will automatically rename any file whose
name ends with a @ to append the current instance name.

Therefore, if servicedir I<getty@> contained a file named I<set-numlock@> into
one of those, it would be copied as e.g. I<set-numock@tty1> into the created
servicedir I<getty@tty1>.

=head2 Special case: service logger

Long-run services are likely to be logged, and to do so you need to provide a
servicedir I<log> inside the servicedir of the service.

To simplify things, if a regular file or directory I<log> is found in a
servicedir (in a source directory), B<aa-enable>(1) will copy the servicedir
I<log>, taken from source directories as usual, into the servicedir of the
service. And in case of a directory, its content will then be merged/copied
over.

This allows you to use the service/servicedir I<log> as logger for a service by
simply putting an empty regular file I<log> into the original servicedir (in a
source directory); Or use a directory to simply specify/add configuration files.

Note that you can also still provide files from the configuration directory in
listdir, since it is copied last (and that this always includes providing a new
I<run> file).

The servicedir of the logger is treated as such, meaning dependencies ("needs"
and "wants") will be auto-enabled as needed, you can remove/append to files
from the configuration directory as described below, and a file I<down> will be
created, as well as a folder I<supervise> (unless B<--no-supervise> was
specified).

Lastly, B<aa-enable>(1)'s last step when creating a servicedir is to check for a
regular file I<log/run-args> in the newly created servicedir, and if found to
append its content to I<log/run>

The idea is to allow to easily use the default logger, and yet be able to add
e.g. directives to B<s6-log>'s loggin script. This could be particularly useful
e.g. if the default logger does connect its stdout to a fifo, allowing you to
select lines to write there (or to the logger's stderr).

Note that since you can remove or append to files from configuration (directory
in I<LISTDIR>; See below), you can either remove, rewrite or append to
I<log/run-args> as needed before it is processed.

=head2 Removing/appending to files

When copying files from the "configuration directory" (directory in I<LISTDIR>)
regular files starting with either a dash ( - ) or plus sign ( + ) are processed
in a special manner:

- A file I<-foobar> will have B<aa-enable>(1) remove file I<foobar> from the
destination servicedir, if it exists.

- A file I<+foobar> will have its content be appended to I<foobar> in the
destination servicedir.

=head2 Upgrading servicedirs

You can upgrade servicedirs using the B<--upgrade> option. This is meant to
apply changes (from source directories and/or configuration) into existing
servicedirs.

When used, B<aa-enable>(1) will behave as usual with the following changes:

- The repodir (and the contained scandir) must already exist;

- Each servicedir must already exist as well. Before copying anything, all its
  content will be recursively removed except for regular file I<status.anopa>,
  regular file I<down>, folder I<supervise> and folder I<event> (and their
  content);

- For longruns, no I<down> file will be created, nor will a symlink be added
  into the scandir or I<supervise> folder be created;

- If used, options B<--set-finish> and B<--set-crash> are ignored.

Services auto-added from I<needs> or I<wants> will also be processed differently
that those specified:

- If servicedir already exists in repodir, nothing is done

- Else, they are enabled as usual (i.e. as if without the B<--upgrade> option)
