package: systemd-portable

title: org.freedesktop.portable1(5)

summary: The D\-Bus interface of systemd\-portabled

text:
# org.freedesktop.portable1(5)

## NAME
org.freedesktop.portable1 - The D-Bus interface of systemd-portabled

## INTRODUCTION
systemd-portabled.service(8) is a system service that may be used to attach, detach and inspect portable services. This page describes the D-Bus interface.

## THE MANAGER OBJECT
The service exposes the following interfaces on the Manager object on the bus:

```
node /org/freedesktop/portable1 {

  interface org.freedesktop.portable1.Manager {

    methods:

      GetImage(in  s image,

               out o object);

      ListImages(out a(ssbtttso) images);

      GetImageOSRelease(in  s image,

                        out a{ss} os_release);

      GetImageMetadata(in  s image,

                       in  as matches,

                       out s image,

                       out ay os_release,

                       out a{say} units);

      GetImageMetadataWithExtensions(in  s image,

                                     in  as extensions,

                                     in  as matches,

                                     in  t flags,

                                     out s image,

                                     out ay os_release,

                                     out a{say} extensions,

                                     out a{say} units);

      GetImageState(in  s image,

                    out s state);

      GetImageStateWithExtensions(in  s image,

                                  in  as extensions,

                                  in  t flags,

                                  out s state);

      AttachImage(in  s image,

                  in  as matches,

                  in  s profile,

                  in  b runtime,

                  in  s copy_mode,

                  out a(sss) changes);

      AttachImageWithExtensions(in  s image,

                                in  as extensions,

                                in  as matches,

                                in  s profile,

                                in  s copy_mode,

                                in  t flags,

                                out a(sss) changes);

      DetachImage(in  s image,

                  in  b runtime,

                  out a(sss) changes);

      DetachImageWithExtensions(in  s image,

                                in  as extensions,

                                in  t flags,

                                out a(sss) changes);

      ReattachImage(in  s image,

                    in  as matches,

                    in  s profile,

                    in  b runtime,

                    in  s copy_mode,

                    out a(sss) changes_removed,

                    out a(sss) changes_updated);

      ReattachImageWithExtensions(in  s image,

                                  in  as extensions,

                                  in  as matches,

                                  in  s profile,

                                  in  s copy_mode,

                                  in  t flags,

                                  out a(sss) changes_removed,

                                  out a(sss) changes_updated);

      RemoveImage(in  s image);

      MarkImageReadOnly(in  s image,

                        in  b read_only);

      SetImageLimit(in  s image,

                    in  t limit);

      SetPoolLimit(in  t limit);

    properties:

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly s PoolPath = '...';

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t PoolUsage = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t PoolLimit = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly as Profiles = ['...', ...];

  };

  interface org.freedesktop.DBus.Peer { ... };

  interface org.freedesktop.DBus.Introspectable { ... };

  interface org.freedesktop.DBus.Properties { ... };
};
```

### Methods
GetImage() may be used to get the image object path of the image with the specified name.

ListImages() returns an array of all currently known images. The structures in the array consist of the following fields: image name, type, read-only flag, creation time, modification time, current disk space, usage and image object path.

GetImageOSRelease() retrieves the OS release information of an image. This method returns an array of key value pairs read from the os-release(5) file in the image and is useful to identify the operating system used in a portable service.

GetImageMetadata() retrieves metadata associated with an image. This method returns the image name, the image's os-release(5) content in the form of a (streamable) array of bytes, and a list of portable units contained in the image, in the form of a string (unit name) and an array of bytes with the content.

GetImageMetadataWithExtensions() retrieves metadata associated with an image. This method is a superset of GetImageMetadata() with the addition of a list of extensions as input parameter, which were overlaid on top of the main image via AttachImageWithExtensions(). The path of each extension and an array of bytes with the content of the respective extension-release file are returned, one such structure for each extension named in the input arguments.

GetImageState() retrieves the image state as one of the following strings:

•detached

•attached

•attached-runtime

•enabled

•enabled-runtime

•running

•running-runtime

GetImageStateWithExtensions() is a superset of GetImageState(), with additional support for a list of extensions as input parameters, which is necessary to query the state in case the image was attached in that particular way. The flag parameter is currently unused and reserved for future purposes.

AttachImage() attaches a portable image to the system. This method takes an image path or name, a list of strings that will be used to search for unit files inside the image (partial or complete matches), a string indicating which portable profile to use for the image (see Profiles property for a list of available profiles), a boolean indicating whether to attach the image only for the current boot session, and a string representing the preferred copy mode (whether to copy the image or to just symlink it) with the following possible values:

•(empty)

•copy

•symlink

•mixed

If an empty string is passed the security profile drop-ins and images will be symlinked while unit files will be copied, copy will copy, symlink will prefer linking if possible (e.g.: a unit has to be copied out of an image), and mixed will prefer linking the resources owned by the OS (e.g.: the portable profile located within the host's /usr/ tree) but will copy the resources owned by the portable image (e.g.: the unit files and the images). This method returns the list of changes applied to the system (for example, which unit was added and is now available as a system service). Each change is represented as a triplet of strings: the type of change applied, the path on which it was applied, and the source (if any). The type of change applied will be one of the following possible values:

•copy

•symlink

•write

•mkdir

Note that an image cannot be attached if a unit that it contains is already present on the system. Note that this method returns only after all the listed operations are completed, and due to the I/O involved it might take some time.

In place of the image path a ".v/" versioned directory may be specified, see systemd.v(7) for details.

In place of the directory path a ".v/" versioned directory may be specified, see systemd.v(7) for details.

AttachImageWithExtensions() attaches a portable image to the system. This method is a superset of AttachImage() with the addition of a list of extensions as input parameter, which will be overlaid on top of the main image. When this method is used, detaching must be done by passing the same arguments via the DetachImageWithExtensions() method. For more details on this functionality, see the MountImages= entry on systemd.exec(5) and systemd-sysext(8).

DetachImage() detaches a portable image from the system. This method takes an image path or name, and a boolean indicating whether the image to detach was attached only for the current boot session or persistently. This method returns the list of changes applied to the system (for example, which unit was removed and is no longer available as a system service). Each change is represented as a triplet of strings: the type of change applied, the path on which it was applied, and the source (if any). The type of change applied will be one of the following possible values:

•unlink

Note that an image cannot be detached if a unit that it contains is running. Note that this method returns only after all the listed operations are completed, and due to the I/O involved it might take some time.

DetachImageWithExtensions() detaches a portable image from the system. This method is a superset of DetachImage() with the addition of a list of extensions as input parameter, which were overlaid on top of the main image via AttachImageWithExtensions().

ReattachImage() combines the effects of the AttachImage() method and the DetachImage() method. The difference is that it is allowed to reattach an image while one or more of its units are running. The reattach operation will fail if no matching image is attached. The input parameters match the AttachImage() method, and the return parameters are the combination of the return parameters of the DetachImage() method (first array, units that were removed) and the AttachImage() method (second array, units that were updated or added).

ReattachImageWithExtensions() reattaches a portable image to the system. This method is a superset of ReattachImage() with the addition of a list of extensions as input parameter, which will be overlaid on top of the main image. For more details on this functionality, see the MountImages= entry on systemd.exec(5) and systemd-sysext(8).

RemoveImage() removes the image with the specified name.

MarkImageReadOnly() toggles the read-only flag of an image.

SetPoolLimit() sets an overall quota limit on the pool of images.

SetImageLimit() sets a per-image quota limit.

The AttachImageWithExtensions(), DetachImageWithExtensions() and ReattachImageWithExtensions() methods take in options as flags instead of booleans to allow for extendability. SD_SYSTEMD_PORTABLE_FORCE_ATTACH will bypass the safety checks that ensure the units are not running while the image is attached or detached. SD_SYSTEMD_PORTABLE_FORCE_EXTENSION will bypass the check that ensures the extension-release.NAME file in the extension image matches the image name. They are defined as follows:

```
#define SD_SYSTEMD_PORTABLE_RUNTIME            (UINT64_C(1) << 0)
#define SD_SYSTEMD_PORTABLE_FORCE_ATTACH       (UINT64_C(1) << 1)
#define SD_SYSTEMD_PORTABLE_FORCE_EXTENSION    (UINT64_C(1) << 2)
```

### Properties
PoolPath specifies the file system path where images are written to.

PoolUsage specifies the current usage size of the image pool in bytes.

PoolLimit specifies the size limit of the image pool in bytes.

Profiles specifies the available runtime profiles for portable services.

## THE IMAGE OBJECT
The service exposes the following interfaces on the Image object on the bus:

```
node /org/freedesktop/portable1 {

  interface org.freedesktop.portable1.Image {

    methods:

      GetOSRelease(out a{ss} os_release);

      GetMetadata(in  as matches,

                  out s image,

                  out ay os_release,

                  out a{say} units);

      GetMetadataWithExtensions(in  as extensions,

                                in  as matches,

                                in  t flags,

                                out s image,

                                out ay os_release,

                                out a{say} extensions,

                                out a{say} units);

      GetState(out s state);

      GetStateWithExtensions(in  as extensions,

                             in  t flags,

                             out s state);

      Attach(in  as matches,

             in  s profile,

             in  b runtime,

             in  s copy_mode,

             out a(sss) changes);

      AttachWithExtensions(in  as extensions,

                           in  as matches,

                           in  s profile,

                           in  s copy_mode,

                           in  t flags,

                           out a(sss) changes);

      Detach(in  b runtime,

             out a(sss) changes);

      DetachWithExtensions(in  as extensions,

                           in  t flags,

                           out a(sss) changes);

      Reattach(in  as matches,

               in  s profile,

               in  b runtime,

               in  s copy_mode,

               out a(sss) changes_removed,

               out a(sss) changes_updated);

      ReattachWithExtensions(in  as extensions,

                             in  as matches,

                             in  s profile,

                             in  s copy_mode,

                             in  t flags,

                             out a(sss) changes_removed,

                             out a(sss) changes_updated);

      Remove();

      MarkReadOnly(in  b read_only);

      SetLimit(in  t limit);

    properties:

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly s Name = '...';

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly s Path = '...';

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly s Type = '...';

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly b ReadOnly = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t CreationTimestamp = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t ModificationTimestamp = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t Usage = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t Limit = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t UsageExclusive = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t LimitExclusive = ...;

  };

  interface org.freedesktop.DBus.Peer { ... };

  interface org.freedesktop.DBus.Introspectable { ... };

  interface org.freedesktop.DBus.Properties { ... };
};
```

### Methods
The following methods implement the same operation as the respective methods on the Manager object (see above). However, these methods operate on the image object and hence does not take an image name parameter. Invoking the methods directly on the Manager object has the advantage of not requiring a GetImage() call to get the image object for a specific image name. Calling the methods on the Manager object is hence a round trip optimization. List of methods:

•GetOSRelease()

•GetMetadata()

•GetMetadataWithExtensions()

•GetState()

•Attach()

•AttachWithExtensions()

•Detach()

•DetachWithExtensions()

•Reattach()

•ReattachWithExtensions()

•Remove()

•MarkReadOnly()

•SetLimit()

### Properties
Name specifies the image name.

Path specifies the file system path where image is stored.

Type specifies the image type.

ReadOnly specifies whether the image is read-only.

CreationTimestamp specifies the image creation timestamp.

ModificationTimestamp specifies the image modification timestamp.

Usage specifies the image disk usage.

Limit specifies the image disk usage limit.

UsageExclusive specifies the image disk usage (exclusive).

LimitExclusive specifies the image disk usage limit (exclusive).

## VERSIONING
These D-Bus interfaces follow the usual interface versioning guidelines[1].

## HISTORY

### The Manager Object
GetImageStateWithExtensions() was added in version 251.

### The Image Object
GetStateWithExtensions() was added in version 251.

ReattachWithExtensions() was added in version 254.

## SEE ALSO
systemd(1), systemd-portabled.service(8), portablectl(1)

## NOTES
1.

the usual interface versioning guidelines

https://0pointer.de/blog/projects/versioning-dbus.html

branch: sisyphus


package: systemd-timesyncd

title: org.freedesktop.timesync1(5)

summary: The D\-Bus interface of systemd\-timesyncd

text:
# org.freedesktop.timesync1(5)

## NAME
org.freedesktop.timesync1 - The D-Bus interface of systemd-timesyncd

## INTRODUCTION
systemd-timesyncd.service(8) is a system service that may be used to synchronize the local system clock with a remote Network Time Protocol (NTP) server. This page describes the D-Bus interface.

## THE MANAGER OBJECT
The service exposes the following interfaces on the Manager object on the bus:

```
node /org/freedesktop/timesync1 {

  interface org.freedesktop.timesync1.Manager {

    methods:

      SetRuntimeNTPServers(in  as runtime_servers);

    properties:

      readonly as LinkNTPServers = ['...', ...];

      readonly as SystemNTPServers = ['...', ...];

      readonly as RuntimeNTPServers = ['...', ...];

      readonly as FallbackNTPServers = ['...', ...];

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly s ServerName = '...';

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly (iay) ServerAddress = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")

      readonly t RootDistanceMaxUSec = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")

      readonly t PollIntervalMinUSec = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")

      readonly t PollIntervalMaxUSec = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly t PollIntervalUSec = ...;

      readonly (uuuuittayttttbtt) NTPMessage = ...;

      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

      readonly x Frequency = ...;

  };

  interface org.freedesktop.DBus.Peer { ... };

  interface org.freedesktop.DBus.Introspectable { ... };

  interface org.freedesktop.DBus.Properties { ... };
};
```

Provides information about the manager.

## EXAMPLES
Example 1. Introspect org.freedesktop.timesync1.Manager on the bus

```
$ gdbus introspect --system \

  --dest org.freedesktop.timesync1 \

  --object-path /org/freedesktop/timesync1
```

## VERSIONING
These D-Bus interfaces follow the usual interface versioning guidelines[1].

## SEE ALSO
systemd(1), systemd-timesyncd.service(8)

## NOTES
1.

the usual interface versioning guidelines

https://0pointer.de/blog/projects/versioning-dbus.html


timesyncd.conf

title: timesyncd.conf(5)

text:
# timesyncd.conf(5)

## NAME
timesyncd.conf, timesyncd.conf.d - Network Time Synchronization configuration files

## SYNOPSIS
/etc/systemd/timesyncd.conf

/run/systemd/timesyncd.conf

/usr/local/lib/systemd/timesyncd.conf

/usr/lib/systemd/timesyncd.conf

/etc/systemd/timesyncd.conf.d/*.conf

/run/systemd/timesyncd.conf.d/*.conf

/usr/local/lib/systemd/timesyncd.conf.d/*.conf

/usr/lib/systemd/timesyncd.conf.d/*.conf

## DESCRIPTION
These configuration files control NTP network time synchronization. See systemd.syntax(7) for a general description of the syntax.

## CONFIGURATION DIRECTORIES AND PRECEDENCE
The default configuration is set during compilation, so configuration is only needed when it is necessary to deviate from those defaults. The main configuration file is loaded from one of the listed directories in order of priority, only the first file found is used: /etc/systemd/, /run/systemd/, /usr/local/lib/systemd/ [1], /usr/lib/systemd/. The vendor version of the file contains commented out entries showing the defaults as a guide to the administrator. Local overrides can also be created by creating drop-ins, as described below. The main configuration file can also be edited for this purpose (or a copy in /etc/ if it is shipped under /usr/), however using drop-ins for local configuration is recommended over modifications to the main configuration file.

In addition to the main configuration file, drop-in configuration snippets are read from /usr/lib/systemd/*.conf.d/, /usr/local/lib/systemd/*.conf.d/, and /etc/systemd/*.conf.d/. Those drop-ins have higher precedence and override the main configuration file. Files in the *.conf.d/ configuration subdirectories are sorted by their filename in lexicographic order, regardless of in which of the subdirectories they reside. When multiple files specify the same option, for options which accept just a single value, the entry in the file sorted last takes precedence, and for options which accept a list of values, entries are collected as they occur in the sorted files.

When packages need to customize the configuration, they can install drop-ins under /usr/. Files in /etc/ are reserved for the local administrator, who may use this logic to override the configuration files installed by vendor packages. Drop-ins have to be used to override package drop-ins, since the main configuration file has lower precedence. It is recommended to prefix all filenames in those subdirectories with a two-digit number and a dash, to simplify the ordering. This also defines a concept of drop-in priorities to allow OS vendors to ship drop-ins within a specific range lower than the range used by users. This should lower the risk of package drop-ins overriding accidentally drop-ins defined by users. It is recommended to use the range 10-40 for drop-ins in /usr/ and the range 60-90 for drop-ins in /etc/ and /run/, to make sure that local and transient drop-ins take priority over drop-ins shipped by the OS vendor.

To disable a configuration file supplied by the vendor, the recommended way is to place a symlink to /dev/null in the configuration directory in /etc/, with the same filename as the vendor configuration file.

## OPTIONS
The following settings are configured in the [Time] section:

NTP=

A space-separated list of NTP server host names or IP addresses. During runtime this list is combined with any per-interface NTP servers acquired from systemd-networkd.service(8). systemd-timesyncd will contact all configured system or per-interface servers in turn, until one responds. When the empty string is assigned, the list of NTP servers is reset, and all prior assignments will have no effect. This setting defaults to an empty list. Added in version 216.

FallbackNTP=

A space-separated list of NTP server host names or IP addresses to be used as the fallback NTP servers. Any per-interface NTP servers obtained from systemd-networkd.service(8) take precedence over this setting, as do any servers set via NTP= above. This setting is hence only relevant if no other NTP server information is known. When the empty string is assigned, the list of NTP servers is reset, and all prior assignments will have no effect. If this option is not given, a compiled-in list of NTP servers is used. Added in version 216.

RootDistanceMaxSec=

Maximum acceptable root distance, i.e. the maximum estimated time required for a packet to travel to the server we are connected to from the server with the reference clock. If the current server does not satisfy this limit, systemd-timesyncd will switch to a different server. Takes a time span value. The default unit is seconds, but other units may be specified, see systemd.time(7). Defaults to 5 seconds.

Added in version 236.

PollIntervalMinSec=, PollIntervalMaxSec=

The minimum and maximum poll intervals for NTP messages. Polling starts at the minimum poll interval, and is adjusted within the specified limits in response to received packets. Each setting takes a time span value. The default unit is seconds, but other units may be specified, see systemd.time(7). PollIntervalMinSec= defaults to 32 seconds and must not be smaller than 16 seconds. PollIntervalMaxSec= defaults to 34 min 8 s (2048 seconds) and must be larger than PollIntervalMinSec=.

Added in version 236.

ConnectionRetrySec=

Specifies the minimum delay before subsequent attempts to contact a new NTP server are made. Takes a time span value. The default unit is seconds, but other units may be specified, see systemd.time(7). Defaults to 30 seconds and must not be smaller than 1 second.

Added in version 248.

SaveIntervalSec=

The interval at which the current time is periodically saved to disk, in the absence of any recent synchronisation from an NTP server. This is especially useful for offline systems with no local RTC, as it will guarantee that the system clock remains roughly monotonic across reboots. Takes a time interval value. The default unit is seconds, but other units may be specified, see systemd.time(7). Defaults to 60 seconds.

Added in version 250.

## SEE ALSO
systemd(1), systemd-timesyncd.service(8), systemd-networkd.service(8)

## NOTES
1.

💣💥🧨💥💥💣 Please note that those configuration files must be available at all times. If /usr/local/ is a separate partition, it may not be available during early boot, and must not be used for configuration.


initctl

package: sysvinit

title: initctl(5)

text:
# initctl(5)

## NAME
initctl - /dev/initctl is a named pipe which passes commands to SysV init.

## SYNOPSIS
/dev/initctl

## DESCRIPTION
This document describes the communiction pipe set up by SysV init at /dev/initctl. This named pipe allows programs with the proper permissions (typically programs run by root have read+write access to the pipe) to send signals to the init program (PID 1).

The init manual page has, up until recently, simply stated that people wishing to understand how to send messages to init should read the init program's source code, but that is not usually practical.

Messages sent to the pipe to talk to init must have a special format. This format is defined as a C structure and the technical break-down is presented here:

/*

* Because of legacy interfaces, "runlevel" and "sleeptime"

* aren't in a separate struct in the union.

*

* The weird sizes are because init expects the whole

* struct to be 384 bytes.

*/

struct init_request {

int magic; /* Magic number */

int cmd; /* What kind of request */

int runlevel; /* Runlevel to change to */

int sleeptime; /* Time between TERM and KILL */

union {

struct init_request_bsd bsd;

char data[368];

} i; };

Let's go through the init_request structure one line at a time. The first variable, the "magic" number must be of the value 0x03091969. The init program then knows that only programs with root access which send this magic number are authorized to communicate with init.

The cmd variable is a value in the range of 0-8 (currently). This cmd variable tells init what we want it to do. Here are the possible options:

1 - Set the current runlevel, specified by the runlevel variable.

2 - The power will fail soon (probably low battery) prepare to shutdown.

3 - The power is failing, do shutdown immediately.

4 - The power is okay, cancel shutdown.

6 - Set an environment variable to a value to be specified in

the data variable of this structure.

Other cmd options may be added to init later. For example, command values 0, 5 and 7 are defined but currently not implemented.

The runlevel variable will specify the runlevel to switch to (0-6).

The sleeptime variable is to be used when we want to tell init to change the time spent waiting between sending SIGTERM and SIGKILL during the shutdown process. Changing this at run time is not yet implemented.

The data variable (in the union) can be used to pass misc data which init might need to process our request. For example, when setting environment variables.

When setting an environment variable through init's /dev/initctl pipe, the data variable should have the format VARIABLE=VALUE. The string should be terminated with a NULL character.

## EXAMPLES
The following C code example shows how to send a set environment variable request to the init process using the /dev/initctl pipe. This example is simplified and skips the error checking. A more comlpete example can be found in the shutdown.c program's init_setnv() function.

```
struct init_request     request;           /* structure defined above */
int                     fd;                /* file descriptor for pipe */
memset(&request, 0, sizeof(request));      /* initialize structure */
request.magic = 0x03091969;                /* magic number required */
request.cmd = 6;                           /* 6 is to set a variable */
sprintf(request.data, "VARIABLE=VALUE");   /* set VAR to VALUE in init */
if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) /* open pipe for writing */
{

    size_t s  = sizeof(request);           /* size of structure to write */

    void *ptr = &request;                  /* temporary pointer */

    write(fd, ptr, s);                     /* send structure to the pipe */

    close(fd);                             /* close the pipe when done */
}
```

## NOTES
Usually the /dev/initctl pipe would only be used by low-level programs to request a power-related shutdown or change the runlevel, like telinit would do. Most of the time there is no need to talk to init directly, but this gives us an extenable approach so init can be taught how to learn more commands.

The commands passed through the /dev/initctl pipe must be sent in a specific binary format and be of a specific length. Larger data structures or ones not using the proper format will be ignored. Typically, only root has the ability to write to the initctl pipe for security reasons.

The /dev/initctl pipe can be closed by sending init (PID 1) the SIGUSR2 signal. This closes the pipe and leaves it closed. This may be useful for making sure init is not keeping any files open. However, when the pipe is closed, init no longer receives signals, such as those sent by shutdown or telinit. In other words if we close the pipe, init cannot change its runlevel directly. The pipe may be re-opened by sending init (PID 1) the SIGUSR1 signal.

If the /dev/initctl pipe is closed then it may still be possible to bring down the system using the shutdown command's -n flag, but this is not always clean and not recommended.

## FILES
/dev/initctl /sbin/init

## AUTHOR
Jesse Smith <jsmith@resonatingmedia.com>

## SEE ALSO
init(8)


initscript

title: initscript(5)

summary: script that executes inittab commands.

text:
# initscript(5)

## NAME
initscript - script that executes inittab commands.

## SYNOPSIS
/bin/sh /etc/initscript id runlevels action process

## DESCRIPTION
When the shell script /etc/initscript is present, init will use it to execute the commands from inittab. This script can be used to set things like ulimit and umask default values for every process.

## EXAMPLES
This is a sample initscript, which might be installed on your system as /etc/initscript.sample.

```
#
# initscript   Executed by init(8) for every program it
#              wants to spawn like this:
#
#              /bin/sh /etc/initscript <id> <level> <action> <process>
#

  # Set umask to safe level, and enable core dumps.

  umask 022

  ulimit -c 2097151

  PATH=/bin:/sbin:/usr/bin:/usr/sbin

  export PATH

  # Increase the hard file descriptor limit for all processes

  # to 8192.  The soft limit is still 1024, but any unprivileged

  # process can increase its soft limit up to the hard limit

  # with "ulimit -Sn xxx" (needs a 2.2.13 or later Linux kernel).

  ulimit -Hn 8192

  # Execute the program.

  eval exec "$4"
```

## NOTES
This script is not meant as startup script for daemons or services. It has nothing to do with a rc.local style script. It's just a handler for things executed from /etc/inittab. Experimenting with this can make your system un(re)bootable.

## FILES
/etc/inittab, /etc/initscript.

## AUTHOR
Miquel van Smoorenburg ,<miquels@cistron.nl>

## SEE ALSO
inittab(5), init(8).


inittab

title: inittab(5)

text:
# inittab(5)

## NAME
inittab - format of the inittab file used by the sysv-compatible init process

## DESCRIPTION
The inittab file describes which processes are started at bootup and during normal operation (e.g. /etc/init.d/boot, /etc/init.d/rc, gettys...). Init(8) distinguishes multiple runlevels, each of which can have its own set of processes that are started. Valid runlevels are 0-6 plus A, B, and C for ondemand entries. An entry in the inittab file has the following format:

id:runlevels:action:process

Lines beginning with `#' are ignored. id

is a unique sequence of 1-4 characters which identifies an entry in inittab (for versions of sysvinit compiled with the old libc5 (< 5.2.18) or a.out libraries the limit is 2 characters). Note: traditionally, for getty and other login processes, the value of the id field is kept the same as the suffix of the corresponding tty, e.g. 1 for tty1. Some ancient login accounting programs might expect this, though I can't think of any.

runlevels

lists the runlevels for which the specified action should be taken.

action

describes which action should be taken.

process

specifies the process to be executed. If the process field starts with a `+' character, init will not do utmp and wtmp accounting for that process. This is needed for gettys that insist on doing their own utmp/wtmp housekeeping. This is also a historic bug. The length of this field is limited to 127 characters.

The runlevels field may contain multiple characters for different runlevels. For example, 123 specifies that the process should be started in runlevels 1, 2, and 3. The runlevels for ondemand entries may contain an A, B, or C. The runlevels field of sysinit, boot, and bootwait entries are ignored.

When the system runlevel is changed, any running processes that are not specified for the new runlevel are killed, first with SIGTERM, then with SIGKILL.

Valid actions for the action field are:

respawn

The process will be restarted whenever it terminates (e.g. getty).

wait

The process will be started once when the specified runlevel is entered and init will wait for its termination.

once

The process will be executed once when the specified runlevel is entered.

boot

The process will be executed during system boot. The runlevels field is ignored.

bootwait

The process will be executed during system boot, while init waits for its termination (e.g. /etc/rc). The runlevels field is ignored.

off

This does nothing.

ondemand

A process marked with an ondemand runlevel will be executed whenever the specified ondemand runlevel is called. However, no runlevel change will occur (ondemand runlevels are `a', `b', and `c').

initdefault

An initdefault entry specifies the runlevel which should be entered after system boot. If none exists, init will ask for a runlevel on the console. The process field is ignored.

sysinit

The process will be executed during system boot. It will be executed before any boot or bootwait entries. The runlevels field is ignored.

powerwait

The process will be executed when the power goes down. Init is usually informed about this by a process talking to a UPS connected to the computer. Init will wait for the process to finish before continuing.

powerfail

As for powerwait, except that init does not wait for the process's completion.

powerokwait

This process will be executed as soon as init is informed that the power has been restored.

powerfailnow

This process will be executed when init is told that the battery of the external UPS is almost empty and the power is failing (provided that the external UPS and the monitoring process are able to detect this condition).

ctrlaltdel

The process will be executed when init receives the SIGINT signal. This means that someone on the system console has pressed the CTRL-ALT-DEL key combination. Typically one wants to execute some sort of shutdown either to get into single-user level or to reboot the machine.

kbrequest

The process will be executed when init receives a signal from the keyboard handler that a special key combination was pressed on the console keyboard. The documentation for this function is not complete yet; more documentation can be found in the kbd-x.xx packages (most recent was kbd-0.94 at the time of this writing). Basically you want to map some keyboard combination to the "KeyboardSignal" action. For example, to map Alt-Uparrow for this purpose use the following in your keymaps file:

alt keycode 103 = KeyboardSignal

## EXAMPLES
This is an example of a inittab which resembles the old Linux inittab:

```
# inittab for linux
id:1:initdefault:
rc::bootwait:/etc/rc
1:1:respawn:/etc/getty 9600 tty1
2:1:respawn:/etc/getty 9600 tty2
3:1:respawn:/etc/getty 9600 tty3
4:1:respawn:/etc/getty 9600 tty4
```

This inittab file executes /etc/rc during boot and starts gettys on tty1-tty4. A more elaborate inittab with different runlevels (see the comments inside):

```
# Level to run in
id:2:initdefault:
# Boot-time system configuration/initialization script.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# What to do at the "3 finger salute".
ca::ctrlaltdel:/sbin/shutdown -t1 -h now
# Runlevel 2,3: getty on virtual consoles
# Runlevel   3: getty on terminal (ttyS0) and modem (ttyS1)
1:23:respawn:/sbin/getty tty1 VC linux
2:23:respawn:/sbin/getty tty2 VC linux
3:23:respawn:/sbin/getty tty3 VC linux
4:23:respawn:/sbin/getty tty4 VC linux
S0:3:respawn:/sbin/getty -L 9600 ttyS0 vt320
S1:3:respawn:/sbin/mgetty -x0 -D ttyS1
```

## FILES
/etc/inittab

## AUTHOR
Init was written by Miquel van Smoorenburg (miquels@cistron.nl). This manual page was written by Sebastian Lederer (lederer@francium.informatik.uni-bonn.de) and modified by Michael Haardt (u31b3hs@pool.informatik.rwth-aachen.de).

## SEE ALSO
init(8), telinit(8)


saveconfig.json

package: target-restore

title: saveconfig.json(5)

text:
# saveconfig.json(5)

## NAME
saveconfig.json - Saved configuration file for rtslib-fb and LIO kernel target

## DESCRIPTION
/etc/target/saveconfig.json is the default location for storing the configuration of the Linux kernel target, also known as LIO. Since the target is in the kernel, tools like targetctl or targetcli must be used to save and restore the configuration across reboots.

Generating or modifying this file by hand, or with other tools, is also supported. This fills a gap for users whose needs are not met by the targetcli configuration shell, who cannot use the rtslib Python library, and yet also wish to avoid directly manipulating LIO's configfs interface.

## OVERVIEW
The configuration file is in the "json" text format, which is both human- and machine-readable. Its format is very closely modeled on the layout and terminology that LIO uses. Attributes may be string, boolean, or numeric values. All sizes are expressed in bytes.

## LAYOUT

### TOP LEVEL SUMMARY
storage_objects describes mappings of resources on the local machine that can be used to emulate block devices.

fabric_modules describes settings for LIO fabrics -- the hardware or software protocols that transport SCSI commands -- such as iSCSI or Fibre Channel over Ethernet (FCoE).

targets describes the SCSI target endpoints that export storage objects over a fabric.

### storage_objects
All storage objects must contain name and plugin values. Each name must be unique for all storage objects of its plugin type.

plugin must be one of: fileio, block, pscsi, or ramdisk.

Objects with plugin value of fileio must also contain dev, which is the full path to the file that is backing the storage object. Optional fileio attributes are wwn (string), write_back (boolean), and size (number). If the file given in dev does not exist, then size must be present, and a backing file of that size will be created.

Objects with plugin value of block must also contain dev, which is the full path to the block device that is backing the storage object. Optional block attributes are wwn (string), write_back (boolean), and readonly (boolean).

Objects with plugin value of pscsi must also contain dev, which is the full path to the SCSI device that is backing the storage object. There are no optional attributes.

Objects with plugin value of ramdisk must also contain size (number), which is the size in bytes of the ramdisk. Optional ramdisk attributes are wwn (string), and nullio (boolean).

All storage object definitions may also contain an attributes object. This contains LIO attribute values, all of which are also optional. Please see LIO documentation for more information on these.

### fabric_modules
This section is limited to setting discovery authentication settings for fabrics that support it (currently just iscsi). Objects here should contain name (e.g. "iscsi"), userid, password, mutual_userid, and mutual_password string values.

### targets
Target configuration is modeled on iSCSI, in which a named target can contain multiple sub-configurations called Target Port Groups (TPGs). LIO follows this model for describing configuration even for fabrics that do not support TPGs.

Objects in targets contain just three attributes: wwn is the world-wide name the target has been given. This may start with "iqn", or "naa", for example. fabric is the name of the fabric module this target is exported over. Allowed values for this depend on the system configuration, but examples include "iscsi", "loopback", and "tcm_fc". tpgs is a list of objects describing 1 or more TPGs, described below.

### tpgs
TPG object attributes are all optional. Values not supplied will be set to default values. tag (number) allows the tpg tag to be specified. enable (bool, default to true) allows the TPG to be disabled or enabled. luns, portals, and node_acls contain further lists of objects, descibed below. Finally, userid, password, mutual_userid, and mutual_password allow main-phase authentication values to be set for fabrics (like iSCSI) that support TPG-level authentication. (Please see targetcli(8) for details on TPG versus ACL-based authentication.) Finally, TPGs can also contain optional attributes and parameters lists, see LIO documentation for more information.

### luns
This list of objects maps storage objects to the TPG. index is a TPG-unique number for the assignment, which may be used as the LU number for fabrics that do not support ACL mappings. storage_object is a string linking back to a storage object, of the format "/backstores/<plugin>/<name>", where <plugin> and <name> correspond to a storage object defined under storage_objects.

### portals
Portals describe connection endpoints for iSCSI targets. Required values are ip_address (string) and port (number). iser (boolean) is an optional value to enable iSER. offload (boolean) is an optional value to enable hardware offload.

### node_acls
This contains information about explicit initiator LUN mappings. node_wwn (string) must be present. Authentication may also be set on a per-ACL basis with userid, password, mutual_userid, and mutual_password, similar to TPGs. mapped_luns is a list of mapped luns, described below. Finally, node_acls can contain an optional attributes list.

### mapped_luns
Objects in mapped_luns contain three required attributes. write_protect (boolean) sets the write-protect status of the mapped LUN. tpg_lun (number) corresponds to an existing entry in the TPG's luns list. index is the LU number that the mapped LUN will claim.

## EXAMPLE CONFIGURATION
Since tools generate this file, one good way to understand its format is to use a tool like targetcli to configure a target, then run saveconfig, and view the resulting json file.

## SEE ALSO
targetcli(8), targetctl(8)

## FILES
/etc/target/saveconfig.json

## AUTHOR
Man page written by Andy Grover <agrover@redhat.com>.

## REPORTING BUGS
Report bugs via <targetcli-fb-devel@lists.fedorahosted.org>

or <https://github.com/open-iscsi/rtslib-fb/issues>


task-color

package: task-core

title: task-color(5)

text:
# task-color(5)

## NAME
task-color - A color tutorial for the Taskwarrior command line todo manager.

## AUTOMATIC MONOCHROME
It should be mentioned that Taskwarrior is aware of whether its output is going to a terminal, or to a file or through a pipe. When Taskwarrior output goes to a terminal, color is desirable, but consider the following command:

```
    $ task list > file.txt
```

Do we really want all those color control codes in the file? Taskwarrior assumes that you do not, and temporarily sets color to 'off' while generating the output. This explains the output from the following command:

```
    $ task show | grep '^color '

    color                        off
```

it always returns 'off', no matter what the setting, because the output is being sent to a pipe.

If you wanted those color codes, you can override this behavior by setting the _forcecolor variable to on, like this:

```
    $ task config _forcecolor on

    $ task config | grep '^color '

    color                        on
```

or by temporarily overriding it like this:

```
    $ task rc._forcecolor=on config | grep '^color '

    color                        on
```

## AVAILABLE COLORS
Taskwarrior has a 'color' command that will show all the colors it is capable of displaying. Try this:

```
    $ task color
```

The output cannot be replicated here in a man page, but you should see a set of color samples. How many you see depends on your terminal program's ability to render them.

You should at least see the Basic colors and Effects - if you do, then you have 16-color support. If your terminal supports 256 colors, you'll know it!

## 16-COLOR SUPPORT
The basic color support is provided through named colors:

```
    black, red, blue, green, magenta, cyan, yellow, white
```

Foreground color (for text) is simply specified as one of the above colors, or not specified at all to use the default terminal text color.

Background color is specified by using the word 'on', and one of the above colors. Some examples:

```
    green                 # green text, default background color

    green on yellow       # green text, yellow background

    on yellow             # default text color, yellow background
```

These colors can be modified further, by making the foreground bold, or by making the background bright. Some examples:

```
    bold green

    bold white on bright red

    on bright cyan
```

The order of the words is not important, so the following are equivalent:

```
    bold green

    green bold
```

But the 'on' is important - colors before the 'on' are foreground, and colors after 'on' are background.

There is an additional 'underline' attribute that may be used:

```
    underline bold red on black
```

And an 'inverse' attribute:

```
    inverse red
```

Taskwarrior has a command that helps you visualize these color combinations. Try this:

```
    $ task color underline bold red on black
```

You can use this command to see how the various color combinations work. You will also see some sample colors displayed, like the ones above, in addition to the sample requested.

Some combinations look very nice, some look terrible. Different terminal programs do implement slightly different versions of 'red', for example, so you may see some unexpected variation across machines. The brightness of your display is also a factor.

## 256-COLOR SUPPORT
Using 256 colors follows the same form, but the names are different, and some colors can be referenced in different ways. First there is by color ordinal, which is like this:

```
    color0

    color1

    color2

    ...

    color255
```

This gives you access to all 256 colors, but doesn't help you much. This range is a combination of 8 basic colors (color0 - color7), then 8 brighter variations (color8 - color15). Then a block of 216 colors (color16 - color231). Then a block of 24 gray colors (color232 - color255).

The large block of 216 colors (6x6x6 = 216) represents a color cube, which can be addressed via RGB values from 0 to 5 for each component color. A value of 0 means none of this component color, and a value of 5 means the most intense component color. For example, a bright red is specified as:

```
    rgb500
```

And a darker red would be:

```
    rgb300
```

Note that the three digits represent the three component values, so in this example the 5, 0 and 0 represent red=5, green=0, blue=0. Combining intense red with no green and no blue yields red. Similarly, blue and green are:

```
    rgb005

    rgb050
```

Another example - bright yellow - is a mix of bright red and bright green, but no blue component, so bright yellow is addressed as:

```
    rgb550
```

A soft pink would be addressed as:

```
    rgb515
```

See if you agree, by running:

```
    $ task color black on rgb515
```

You may notice that the large color block is represented as 6 squares. All colors in the first square have a red value of 0. All colors in the 6th square have a red value of 5. Within each square, blue ranges from 0 to 5 left to right, and within each square green ranges from 0 to 5, top to bottom. This scheme takes some getting used to.

The block of 24 gray colors can also be accessed as gray0 - gray23, in a continuous ramp from black to white.

## MIXING 16- AND 256-COLORS
If you specify 16-colors, and view on a 256-color terminal, no problem. If you try the reverse, specifying 256-colors and viewing on a 16-color terminal, you will be disappointed, perhaps even appalled.

There is some limited color mapping - for example, if you were to specify this combination:

```
    red on gray3
```

you are mixing a 16-color and 256-color specification. Taskwarrior will map red to color1, and proceed. Note that red and color1 are not quite the same tone.

Note also that there is no bold or bright attributes when dealing with 256 colors, but there is still underline available.

## LEGEND
Taskwarrior will show examples of all defined colors used in your .taskrc, or theme, if you run this command:

```
    $ task color legend
```

This gives you an example of each of the colors, so you can see the effect, without necessarily creating a set of tasks that meet each of the rule criteria.

## RULES
Taskwarrior supports colorization rules. These are configuration values that specify a color, and the conditions under which that color is used. By example, let us add a few tasks:

```
    $ task add project:Home priority:H pay the bills               (1)

    $ task add project:Home            clean the rug               (2)

    $ task add project:Garden          clean out the garage        (3)
```

We can add a color rule that uses a blue background for all tasks in the Home project:

```
    $ task config color.project.Home 'on blue'
```

We use quotes around 'on blue' because there are two words, but they represent one value in the .taskrc file. Now suppose we wish to use a bold yellow text color for all cleaning work:

```
    $ task config color.keyword.clean 'bold yellow'
```

Now what happens to task 2, which belongs to project Home (blue background), and is also a cleaning task (bold yellow foreground)? The colors are combined, and the task is shown as "bold yellow on blue".

Color rules can be applied by project and description keyword, as shown, and also by priority (or lack of priority), by active status, by being due or overdue, by being tagged, or having a specific tag (perhaps the most useful rule) or by being a recurring task.

It is possible to create a very colorful mix of rules. With 256-color support, those colors can be made subtle, and complementary, but without care, this can be a visual mess. Beware!

In such cases, consider using the 'rule.color.merge=no' option to disable the color blending.

The precedence for the color rules is determined by the configuration variable 'rule.precedence.color', which by default contains:

```
    deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.
```

These are just the color rules with the 'color.' prefix removed. The rule 'color.deleted' has the highest precedence, and 'color.uda.' the lowest.

The keyword rule shown here as 'keyword.' corresponds to a wildcard pattern, meaning 'color.keyword.*', or in other words all the keyword rules.

There is also 'color.project.none', 'color.tag.none' and 'color.uda.priority.none' to specifically represent missing data.

## THEMES
Taskwarrior supports themes. What this really means is that with the ability to include other files into the .taskrc file, different sets of color rules can be included.

To get a good idea of what a color theme looks like, try adding this entry to your .taskrc file:

```
    include dark-256.theme
```

You can use any of the standard Taskwarrior themes:

```
    dark-16.theme

    dark-256.theme

    dark-blue-256.theme

    dark-gray-256.theme

    dark-green-256.theme

    dark-red-256.theme

    dark-violets-256.theme

    dark-yellow-green.theme

    light-16.theme

    light-256.theme

    solarized-dark-256.theme

    solarized-light-256.theme

    dark-default-16.theme

    dark-gray-blue-256.theme

    no-color.theme
```

Bear in mind that if you are using a terminal with a dark background, you will see better results using a dark theme.

You can also see how the theme will color the various tasks with the command:

```
    $ task color legend
```

Better yet, create your own, and share it. We will gladly host the theme file on <https://taskwarrior.org>.

## CREDITS & COPYRIGHTS
Copyright (C) 2006 - 2021 T. Babej, P. Beckingham, F. Hernandez.

Taskwarrior is distributed under the MIT license. See https://www.opensource.org/licenses/mit-license.php for more information.

## SEE ALSO
task(1), taskrc(5), task-sync(5)

For more information regarding Taskwarrior, see the following:

The official site at

<https://taskwarrior.org>

The official code repository at

<https://github.com/GothenburgBitFactory/taskwarrior>

You can contact the project by emailing

<support@GothenburgBitFactory.org>

## REPORTING BUGS
Bugs in Taskwarrior may be reported to the issue-tracker at

<https://github.com/GothenburgBitFactory/taskwarrior/issues>


task-sync

title: task-sync(5)

text:
# task-sync(5)

## NAME
task-sync - A discussion and tutorial for the various task(1) data synchronization capabilities.

## INTRODUCTION
Taskwarrior can synchronize your tasks to a server. This has a few benefits:

- Makes your tasks accessible from multiple systems, called "replicas".

- Provides a backup of your tasks.

- Saves disk space.

For example, you might want a replica of your tasks on your laptop and on your phone.

NOTE: A side-effect of synchronization is that once changes have been synchronized, they cannot be undone. This means that each time synchronization is run, it is no longer possible to undo previous operations.

## MANAGING SYNCHRONIZATION

### Adding a Replica
To add a new replica, configure a new, empty replica identically to the existing replica, and run `task sync`.

### When to Synchronize
For synchronization to a server, a common solution is to run

```
    $ task sync
```

periodically, such as via cron(8).

## CONFIGURATION
Taskwarrior provides several options for synchronizing your tasks:

- To a server specifically designed to handle Taskwarrior data.

+ To a cloud storage provider. Currently both AWS and GCP are supported.

- To a local, on-disk file.

For most of these, you will need an encryption secret used to encrypt and decrypt your tasks. This can be any secret string, and must match for all replicas sharing tasks.

```
    $ task config sync.encryption_secret <encryption_secret>
```

Tools such as pwgen(1) can generate suitable secret values.

### Sync Server
To synchronize your tasks to a sync server, you will need the following information from the server administrator:

- The server's URL (such as "https://tw.example.com/path")

- A client ID ("client_id") identifying your tasks

Configure Taskwarrior with these details:

```
    $ task config sync.server.url               <url>

    $ task config sync.server.client_id         <client_id>
```

Note that the URL must include the scheme, such as 'http://' or 'https://'.

$ task config sync.server.origin <origin>

Is a deprecated synonym for "sync.server.url".

### Google Cloud Platform
To synchronize your tasks to GCP, use the GCP Console to create a new project, and within that project a new Cloud Storage bucket. The default settings for the bucket are adequate.

Authenticate to the project with:

```
    $ gcloud config set project $PROJECT_NAME

    $ gcloud auth application-default login
```

Then configure Taskwarrior with:

```
    $ task config sync.gcp.bucket               <bucket-name>
```

However you can bring your own service account credentials if your `application-default` is already being used by some other application

To begin, navigate to the "IAM and Admin" section in the Navigation Menu, then select "Roles."

On the top menu bar within the "Roles" section, click "CREATE ROLE." Provide an appropriate name and description for the new role.

Add permissions to your new role using the filter "Service:storage" (not the "Filter permissions by role" input box). Select the following permissions:

- storage.buckets.create

- storage.buckets.get

- storage.buckets.update

- storage.objects.create

- storage.objects.delete

- storage.objects.get

- storage.objects.list

- storage.objects.update

Create your new role.

On the left sidebar, navigate to "Service accounts."

On the top menu bar within the "Service accounts" section, click "CREATE SERVICE ACCOUNT." Provide an appropriate name and description for the new service account. Select the role you just created and complete the service account creation process.

Now, in the Service Account dashboard, click into the new service account and select "keys" on the top menu bar. Click on "ADD KEY" to create and download a new key (a JSON key).

Then configure Taskwarrior with:

```
    $ task config sync.gcp.bucket               <bucket-name>

    $ task config sync.gcp.credential_path      <absolute-path-to-downloaded-credentials>
```

### Amazon Web Services
To synchronize your tasks to AWS, select a region near you and use the AWS console to create a new S3 bucket. The default settings for the bucket are adequate. In particular, ensure that no lifecycle policies are enabled, as they may automatically delete or transition objects, potentially impacting data availability.

You will also need an AWS IAM user with the following policy, where BUCKETNAME is the name of the bucket. The same user can be configured for multiple Taskwarrior clients.

```
    {

        "Version": "2012-10-17",

        "Statement": [

            {

                "Sid": "TaskChampion",

                "Effect": "Allow",

                "Action": [

                    "s3:PutObject",

                    "s3:GetObject",

                    "s3:ListBucket",

                    "s3:DeleteObject"

                ],

                "Resource": [

                    "arn:aws:s3:::BUCKETNAME",

                    "arn:aws:s3:::BUCKETNAME/*"

                ]

            }

        ]

    }
```

To create such a user, create a new policy in the IAM console, select the JSON option in the policy editor, and paste the policy. Click "Next" and give the policy a name such as "TaskwarriorSync". Next, create a new user, with a name of your choosing, select "Attach Policies Directly", and then choose the newly-created policy.

You will need access keys configured for the new user. Find the user in the user list, open the "Security Credentials" tab, then click "Create access key" and follow the steps.

At this point, you can choose how to provide those credentials to Taskwarrior. The simplest is to include them in the Taskwarrior configuration:

```
    $ task config sync.aws.region              <region>

    $ task config sync.aws.bucket              <bucket-name>

    $ task config sync.aws.access_key_id       <access-key-id>

    $ task config sync.aws.secret_access_key   <secret-access-key>
```

Alternatively, you can set up an AWS CLI profile, using a profile name of your choosing such as "taskwarrior-creds":

```
    $ aws configure --profile taskwarrior-creds
```

Enter the access key ID and secret access key. The default region and format are not important. Then configure Taskwarrior with:

```
    $ task config sync.aws.region              <region>

    $ task config sync.aws.bucket              <bucket-name>

    $ task config sync.aws.profile             taskwarrior-creds
```

To use AWS's default credential sources, such as environment variables, the default profile, or an instance profile, set

```
    $ task config sync.aws.region              <region>

    $ task config sync.aws.bucket              <bucket-name>

    $ task config sync.aws.default_credentials true
```

### Local Synchronization
In order to take advantage of synchronization's side effect of saving disk space without setting up a remote server, it is possible to sync tasks locally. To configure local sync:

```
    $ task config sync.local.server_dir /path/to/sync
```

The default configuration is to sync to a database in the task directory ("data.location").

## RUNNING TASKCHAMPION-SYNC-SERVER
The TaskChampion sync server is an HTTP server supporting multiple users. Users are identified by a client ID, and users with different client IDs are entirely independent. Task data is encrypted by Taskwarrior, and the sync server never sees un-encrypted data.

The server is developed in https://github.com/GothenburgBitFactory/taskchampion-sync-server.

### Adding a New User
To add a new user to the server, invent a new client ID with a tool like `uuidgen` or an online UUID generator. There is no need to configure the server for this new client ID: the sync server will automatically create a new user whenever presented with a new client ID. Supply the ID, along with the URL, to the user for inclusion in their Taskwarrior config. The user should invent their own "encryption_secret".

## AVOIDING DUPLICATE RECURRING TASKS
If you run multiple clients that sync to the same server, you will need to run this command on your primary client (the one you use most often):

```
    $ task config recurrence on
```

And on the other clients, run:

```
    $ task config recurrence off
```

This protects you against the effects of a sync/duplication bug.

## ALTERNATIVE: FILE SHARING SERVICES
There are many file sharing services, such as DropBox, Amazon S3, Google Drive, SkyDrive and more. This technique involves storing your .task directory in a shared directory under the control of the file hosting services.

Syncing happens quickly, although it is possible to run into conflict situations when there is no network connectivity, and the tasks are modified in two separate locations. This is because the file hosting service knows only about files, and it has no idea how to merge tasks. Avoid this problem by never modifying the same task on two machines, without an intervening sync.

Setup simply involves creating the directory and modifying your data.location configuration variable like this:

```
    $ task config data.location /path/to/shared/directory
```

Strengths:

- Good client support

- Easy setup

- Transparent use

Weaknesses:

- Tasks are not properly merged

## CREDITS & COPYRIGHTS
Copyright (C) 2006 - 2021 T. Babej, P. Beckingham, F. Hernandez.

Taskwarrior is distributed under the MIT license. See https://www.opensource.org/licenses/mit-license.php for more information.

## SEE ALSO
task(1), taskrc(5), task-color(5),

For more information regarding Taskwarrior, see the following:

The official site at

<https://taskwarrior.org>

The official code repository at

<https://github.com/GothenburgBitFactory/taskwarrior>

You can contact the project by emailing

<support@GothenburgBitFactory.org>

## REPORTING BUGS
Bugs in Taskwarrior may be reported to the issue-tracker at

<https://github.com/GothenburgBitFactory/taskwarrior/issues>