Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add openrc support #7

Open
coolaj86 opened this issue Dec 27, 2023 · 2 comments
Open

add openrc support #7

coolaj86 opened this issue Dec 27, 2023 · 2 comments

Comments

@coolaj86
Copy link
Contributor

coolaj86 commented Dec 27, 2023

Notes

Update

See the logrotate section below, which has not yet been integrated into this script.

Proof of Concept

Install

curl -L https://github.com/therootcompany/serviceman/files/15244697/serviceman.tar.gz \
  -o ./serviceman.tar.gz

mkdir -p ~/bin/
tar xvzf ./serviceman.tar.gz -C ~/bin/

Usage

# serviceman-add <app-name> <--> <command> [args]
serviceman-add my-app -- node ./server.js

Implementation

serviceman-add:

#!/bin/sh
set -e
set -u

g_sudo=''
if command -v sudo > /dev/null; then
    g_sudo='sudo'
fi

main() { (
    a_name="${1:-}"
    a_dashes="${2:-}"
    a_cmd="${3:-}"
    shift || true
    shift || true
    shift || true
    a_cmdargs="$*"

    if test "--" != "${a_dashes}"; then
        echo >&2 ""
        echo >&2 "USAGE"
        echo >&2 "    serviceman-add <service-name> -- <command> [args...]"
        echo >&2 ""
        echo >&2 "EXAMPLE"
        echo >&2 "    serviceman-add foo-api -- node ./server.js"
        echo >&2 ""
        return 1
    fi

    b_workdir="$(pwd)"
    b_cmdname="${a_name}"
    b_name="${a_name} service"
    b_desc="Accepts authorized API reqs to sets Title, Desc, etc"
    b_cmdpath="$(realpath "$(command -v "${a_cmd}")")"
    b_user="$(id -u -n)"
    b_group="$(id -g -n)"
    # b_stdout="/var/log/${b_cmdname}.log"
    # b_stderr="/var/log/${b_cmdname}.err"

    b_dir="$(dirname "${0}")"
    # shellcheck disable=SC2002
    cat "${b_dir}/_serviceman-openrc-tmpl" |
        sed "s;name=.*;name='${b_name}';" |
        sed "s;description=.*;description='${b_desc}';" |
        sed "s;command=.*;command='${b_cmdpath}';" |
        sed "s;command_args=.*;command_args='${a_cmdargs}';" |
        sed "s;command_user=.*;command_user='${b_user}:${b_group}';" |
        sed "s;supervise_daemon_args=.*;supervise_daemon_args='--chdir ${b_workdir} --env PATH=${PATH}';" |
        sed "s;root:;${b_user}:;" |
        sed "s;:www-data;:${b_group};" |
        sed "s;exampled;${b_cmdname};" > "${b_cmdname}"

    $g_sudo mv "${b_cmdname}" "/etc/init.d/${b_cmdname}"
    $g_sudo chown root "/etc/init.d/${b_cmdname}"
    $g_sudo chmod 0755 "/etc/init.d/${b_cmdname}"

    $g_sudo mkdir -p "/var/log/${b_cmdname}/"
    $g_sudo chmod 0750 "/var/log/${b_cmdname}"

    $g_sudo rc-service "${b_cmdname}" restart &&
        $g_sudo rc-update add "${b_cmdname}"
); }

main "${@:-}"

_serviceman-add-openrc-tmpl:

#!/sbin/openrc-run
supervisor=supervise-daemon

name="Example System Daemon"
description="runs exampled and captures stdout and stderr to log files"

command=/opt/exampled/bin/exampled
command_args="run --port 1337"
command_user=root:www-data
supervise_daemon_args="--chdir /tmp --env PATH='/bin'"
output_log=/var/log/exampled.log
error_log=/var/log/exampled.err

start_pre() {
    checkpath --directory --owner root:www-data --mode 0750 \
        /var/log/exampled

    checkpath --file --owner root:www-data --mode 0640 \
        /var/log/exampled/stdout.log \
        /var/log/exampled/stderr.err
}

depend() {
    need net
}
@coolaj86
Copy link
Contributor Author

logrotate

logrotate should be used to make sure that the logs don't fill up the disk.

A specific /etc/logrotate.d/MY_SERVICE_NAME should be created for the service.

The copytruncate option will work for "dumb" services that don't have a signal (such as SIGHUP or USR2 to cause them to close and reopen their file handle. It keeps the same file handle without restarting the process.

crond and /etc/periodic/ should already exist.

sudo apk --no-cache add logrotate
ls -lAhF /etc/periodic/*/*logrotate*
sudo rc-service crond status
echo '/var/log/MY_SERVICE_NAME/log.txt {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    copytruncate
}' | sudo tee /etc/logrotate.d/MY_SERVICE_NAME
sudo logrotate /etc/logrotate.d/MY_SERVICE_NAME --debug

@coolaj86
Copy link
Contributor Author

coolaj86 commented Sep 7, 2024

Alpine 19 is a little bit different. Not sure how yet, but here's a working config:

#!/sbin/openrc-run

name="x5c"
description="x5c API service"
command="/home/app/srv/x5c/x5c-server"
command_args="--port 3080"
command_user="app:app"

supervisor="supervise-daemon"
output_log="/var/log/x5c"
error_log="/var/log/x5c"

depend() {
    need net
}

start_pre() {
    checkpath --directory --owner root /var/log/
    checkpath --file --owner ${command_user} ${output_log} ${error_log}
}

start() {
    ebegin "Starting ${name}"
    supervise-daemon ${name} --start \
        --stdout ${output_log} \
        --stderr ${error_log} \
        --pidfile /run/${RC_SVCNAME}.pid \
        --respawn-delay 5 \
        --respawn-max 10 \
        -- \
        ${command} \
        ${command_args} \
    eend $?
}

stop() {
    ebegin "Stopping ${name}"
    supervise-daemon ${name} --stop \
        --pidfile /run/${RC_SVCNAME}.pid
    eend $?
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant