diff --git a/man.rst b/man.rst new file mode 100644 index 0000000..8f384bf --- /dev/null +++ b/man.rst @@ -0,0 +1,169 @@ +cdist-type__evilham_single_binary_service(7) +============================================ + +NAME +---- +cdist-type__evilham_single_binary_service - Setup a single-binary service + + +DESCRIPTION +----------- +This type is designed to easily deploy and configure a single-binary service +named `${__object_id}`. + +A good example of this are Prometheus exporters. + +This type makes certain assumptions that might not be correct on your system. +If you need more flexibility, please get in touch and provide a use-case +(and hopefully a backwards-compatible patch). + +This type will place the downloaded binary and, if requested, other extra +binaries in `/usr/local/bin`. + +If a `--config-file-source` is provided, it will be placed under: +`/etc/${__object_id}.conf`. + +TODO (patches welcome!): +- It currently only supports `.tar.gz` archives. +- It currently only supports systemd units. +- Does not handle properly BSD-systems (wheel group, /usr/local/etc, systemd) + + +REQUIRED PARAMETERS +------------------- +checksum + This will be passed verbatim to `__download(7)`. + Use something like `sha256:...`. + +url + This will be passed verbatim to `__download(7)`. + +version + This type will use a thumbstone file with a "version" number to track + whether or not a service must be updated. + This thumbstone file is placed under + `/usr/local/bin/.${__object_id}.cdist.version`. + + +BOOLEAN PARAMETERS +------------------ +unpack + If present, the contents of `--url` will be treated as an archive to be + unpacked with `__unpack(7)`. + See also `--unpack-args` and `--extra-binary`. + +do-not-manage-user + Always considered present when `--user` is `root`. + If present, the user in `--user` will not be managed by this type with + `__user`, this means it *must* exist beforehand when installing the service + and it will not be removed by this type. + + +OPTIONAL PARAMETERS +------------------- +config-file-source + If present, this file's contents will be placed under + `/etc/${__object_id}.conf` with permissions `0440` and ownership assigned to + `--user` and `--group`. + If `-` is passed, this type's `stdin` will be used. + +user + The user under which the service will run. Defaults to `root`. + If this user is not `root` and `--do-not-manage-user` is not present, + this user will be created or removed as per the `--state` parameter. + +group + The group under which the service will run. Defaults to `--user`. + +state + Whether the service is to be `present` (default) or `absent`. + When `absent`, this type will clean any binaries listed in `--extra-binary` + and also the config file as described in `--config-file-source`. + +binary + This will be the binary name. Defaults to `${__object_id}`. + If `--unpack` is used, a binary with this name must be unpacked. + Otherwise, the contents of `--url` will be placed under this binary name. + +service-args + Any extra arguments to pass along with `--service-exec`. + +service-exec + The executable to use for this service. + Defaults to `/usr/local/bin/BINARY_NAME` where `BINARY_NAME` is the + resulting value of `--binary`. + +service-description + The service description to be used in, e.g. the systemd unit file. + Defaults to `cdist-managed '${__object_id}' service`. + +unpack-args + Only has an effect if `--unpack` is used. + These arguments will be passed verbatim to `__unpack(7)`. + Very useful as this type assumes the archive does not have the binaries in + subdirectories; that can be worked around with + `--unpack-args '--tar-strip 1'`. + + +OPTIONAL MULTIPLE PARAMETERS +---------------------------- +extra-binary + Only useful with `--unpack`. + If passed, these binaries will also be installed when `--state` is `present` + and removed when `--state` is `absent`. + Handle with care :-). + + +EXAMPLES +-------- + +.. code-block:: sh + + # Install and enable the ipmi_exporter service + # The variables are defined in the manifest previously + __evilham_single_binary_service ipmi_exporter \ + --user "${USER}" \ + --service-args ' --config.file=/etc/ipmi_exporter.conf' \ + --version "${SHOULD_VERSION}" \ + --checksum "${CHECKSUM}" \ + --url "${DOWNLOAD_URL}" \ + --state "present" \ + --unpack \ + --unpack-args "--tar-strip 1" \ + --config-file-source '-' <<-EOF + # Remotely managed, changes will be lost + # [...] config contents goes here + EOF + + # Remove the ipmi_exporter service along with the user and its config + __evilham_single_binary_service ipmi_exporter \ + --user "${USER}" \ + --version "${SHOULD_VERSION}" \ + --checksum "${CHECKSUM}" \ + --url "${DOWNLOAD_URL}" \ + --state "absent" + + # Same, but the service was using my user! Let's not delete that! + __evilham_single_binary_service ipmi_exporter \ + --user "evilham" \ + --do-not-manage-user \ + --version "${SHOULD_VERSION}" \ + --checksum "${CHECKSUM}" \ + --url "${DOWNLOAD_URL}" \ + --state "absent" + + +SEE ALSO +-------- +- `__download(7)` +- `__unpack(7)` + + +AUTHORS +------- +Evilham + + +COPYING +------- +Copyright \(C) 2021 Evilham. diff --git a/manifest b/manifest index d5df410..e279a05 100755 --- a/manifest +++ b/manifest @@ -1,9 +1,12 @@ #!/bin/sh -e BIN_DIR="/usr/local/bin" +ETC_DIR="/etc" # Ensure the target bin dir exists +# Care, we never want to remove it :-D __directory "${BIN_DIR}" \ + --state "exists" \ --mode 0755 export require="${require} __directory${BIN_DIR}" @@ -46,8 +49,13 @@ CHECKSUM="$(cat "${__object}/parameter/checksum")" SHOULD_VERSION="$(cat "${__object}/parameter/version")" # Create a user for the service if it is not root -if [ "${USER}" != "root" ]; then - __user "${USER}" \ +if [ "${USER}" != "root" ] && \ + [ ! -f "${__object}/parameter/do-not-manage-user" ]; then + if [ "${STATE}" = "absent" ]; then + # When removing, ensure user is not being used + user_require="__systemd_unit/${SERVICE_NAME}.service" + fi + require="${require} ${user_require}" __user "${USER}" \ --system \ --state "${STATE}" \ --home /nonexistent \ @@ -56,10 +64,29 @@ if [ "${USER}" != "root" ]; then service_require="${service_require} __user/${USER}" fi +# Place config file if necessary +CONFIG_FILE_DEST="${ETC_DIR}/${SERVICE_NAME}.conf" +CONFIG_FILE_SOURCE="$(cat "${__object}/parameter/config-file-source" 2>/dev/null || true)" +if [ "${CONFIG_FILE_SOURCE}" = "-" ]; then + CONFIG_FILE_SOURCE="${__object}/stdin" +fi +if [ -n "${CONFIG_FILE_SOURCE}" ] && [ "${STATE}" = "present" ]; then + require="${require} __user/${USER}" __file \ + "${CONFIG_FILE_DEST}" \ + --owner "${USER}" \ + --group "${GROUP}" \ + --mode "0440" \ + --source "${CONFIG_FILE_SOURCE}" + service_required="${service_required} __file${CONFIG_FILE_DEST}" +fi + + + # TODO: Support non-systemd __systemd_unit "${SERVICE_NAME}.service" \ --source "-" \ --state "${STATE}" \ + --restart \ --enablement-state "enabled" <