From 41d36a4eb9a559f84b9d2efde315fb887c34b8b1 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 5 May 2017 01:33:36 -0600 Subject: [PATCH] add systemd and launchd scripts --- .../com.daplie.goldilocks.web.plist | 55 ++++++++ README.md | 13 +- etc/systemd/system/goldilocks.service | 68 +++++++++ etc/tmpfiles.d/goldilocks.conf | 10 ++ install.sh | 129 +++++++++++++++++- 5 files changed, 271 insertions(+), 4 deletions(-) create mode 100644 Library/LaunchDaemons/com.daplie.goldilocks.web.plist create mode 100644 etc/systemd/system/goldilocks.service create mode 100644 etc/tmpfiles.d/goldilocks.conf diff --git a/Library/LaunchDaemons/com.daplie.goldilocks.web.plist b/Library/LaunchDaemons/com.daplie.goldilocks.web.plist new file mode 100644 index 0000000..05e6830 --- /dev/null +++ b/Library/LaunchDaemons/com.daplie.goldilocks.web.plist @@ -0,0 +1,55 @@ + + + + + Label + Goldilocks + ProgramArguments + + /usr/local/bin/goldilocks + -agree + -conf + /etc/goldilocks/goldilocks.yml + -root + /var/tmp + + EnvironmentVariables + + GOLDILOCKS_PATH + /opt/goldilocks + + + UserName + root + GroupName + wheel + InitGroups + + + RunAtLoad + + KeepAlive + + Crashed + + SuccessfulExit + + + + SoftResourceLimits + + NumberOfFiles + 8192 + + HardResourceLimits + + + WorkingDirectory + /srv/www + + StandardErrorPath + /var/log/goldilocks/error.log + StandardOutPath + /var/log/goldilocks/info.log + + diff --git a/README.md b/README.md index 74313de..7fedd61 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ Install npm install -g goldilocks # master in git (via ssh) -npm install -g git+ssh://git@git.daplie.com:Daplie/goldilocks.js +npm install -g git+ssh://git@git.daplie.com:Daplie/goldilocks.js#v1 # master in git (unauthenticated) -npm install -g git+https://git@git.daplie.com:Daplie/goldilocks.js +npm install -g git+https://git@git.daplie.com:Daplie/goldilocks.js#v1 ``` ```bash @@ -48,6 +48,15 @@ goldilocks Serving /Users/foo/ at https://localhost.daplie.me:8443 ``` +With service support for + +* systemd +* launchd + +```bash +curl https://git.daplie.com/Daplie/goldilocks.js/raw/master/install.sh | bash +``` + Usage ----- diff --git a/etc/systemd/system/goldilocks.service b/etc/systemd/system/goldilocks.service new file mode 100644 index 0000000..1b70659 --- /dev/null +++ b/etc/systemd/system/goldilocks.service @@ -0,0 +1,68 @@ +[Unit] +Description=Goldilocks Internet Server +Documentation=https://git.daplie.com/Daplie/goldilocks.js +After=network-online.target +Wants=network-online.target systemd-networkd-wait-online.service + +[Service] +# Restart on crash (bad signal), and on 'clean' failure (error exit code) +# Allow up to 3 restarts within 10 seconds +# (it's unlikely that a user or properly-running script will do this) +Restart=on-failure +StartLimitInterval=10 +StartLimitBurst=3 + +# The v8 VM will output a "clean" for JavaScript errors. +# If we knew we were never going to accidentally exit cleanly +# we would use on-abnormal: +; Restart=on-abnormal + +# User and group the process will run as +# (www-data is the de facto standard on most systems) +User=www-data +Group=www-data + +# If we need to pass environment variables in the future +; Environment=GOLDILOCKS_PATH=/opt/goldilocks + +# Set a sane working directory, sane flags, and specify how to reload the config file +WorkingDirectory=/srv/www +ExecStart=/usr/local/bin/goldilocks --log stdout --config=/etc/goldilocks/goldilocks.yml +ExecReload=/bin/kill -USR1 $MAINPID + +# Limit the number of file descriptors and processes; see `man systemd.exec` for more limit settings. +# Unmodified goldilocks is not expected to use more than this. +LimitNOFILE=1048576 +LimitNPROC=64 + +# Use private /tmp and /var/tmp, which are discarded after goldilocks stops. +PrivateTmp=true +# Use a minimal /dev +PrivateDevices=true +# Hide /home, /root, and /run/user. Nobody will steal your SSH-keys. +ProtectHome=true +# Make /usr, /boot, /etc and possibly some more folders read-only. +ProtectSystem=full +# … except TLS/SSL, ACME, and Let's Encrypt certificates +# and /var/log/goldilocks, because we want a place where logs can go. +# This merely retains r/w access rights, it does not add any new. Must still be writable on the host! +ReadWriteDirectories=/etc/goldilocks /etc/acme /etc/letsencrypt /etc/ssl /var/log/goldilocks /opt/goldilocks /srv/www + +# Note: in v231 and above ReadWritePaths has been renamed to ReadWriteDirectories +; ReadWritePaths=/etc/goldilocks /var/log/goldilocks +; +# The following additional security directives only work with systemd v229 or later. +# They further retrict privileges that can be gained. +# Note that you may have to add capabilities required by any plugins in use. +CapabilityBoundingSet=CAP_NET_BIND_SERVICE +AmbientCapabilities=CAP_NET_BIND_SERVICE +NoNewPrivileges=true + +# Caveat: Some plugins need additional capabilities. +# For example "upload" needs CAP_LEASE +; CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_LEASE +; AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_LEASE +; NoNewPrivileges=true + +[Install] +WantedBy=multi-user.target diff --git a/etc/tmpfiles.d/goldilocks.conf b/etc/tmpfiles.d/goldilocks.conf new file mode 100644 index 0000000..f54125e --- /dev/null +++ b/etc/tmpfiles.d/goldilocks.conf @@ -0,0 +1,10 @@ +# /etc/tmpfiles.d/goldilocks.conf +# See https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html + +# Type Path Mode UID GID Age Argument +d /etc/goldilocks 0755 www-data www-data - - +d /opt/goldilocks 0775 www-data www-data - - +d /srv/www 0775 www-data www-data - - +d /etc/ssl/goldilocks 0750 www-data www-data - - +d /var/log/goldilocks 0750 www-data www-data - - +#d /run/goldilocks 0755 www-data www-data - - diff --git a/install.sh b/install.sh index c051a0c..2d5515a 100644 --- a/install.sh +++ b/install.sh @@ -1,4 +1,129 @@ #!/bin/bash -echo "no installer yet" -exit 1 +############################### +# # +# http_get # +# boilerplate for curl / wget # +# # +############################### + +# See https://git.daplie.com/Daplie/daplie-snippets/blob/master/bash/http-get.sh + +http_get="" +http_opts="" +http_out="" + +detect_http_get() +{ + if type -p curl >/dev/null 2>&1; then + http_get="curl" + http_opts="-fsSL" + http_out="-o" + elif type -p wget >/dev/null 2>&1; then + http_get="wget" + http_opts="--quiet" + http_out="-O" + else + echo "Aborted, could not find curl or wget" + return 7 + fi +} + +dap_dl() +{ + $http_get $http_opts $http_out "$2" "$1" +} + +dap_dl_bash() +{ + dap_url=$1 + #dap_args=$2 + rm -rf dap-tmp-runner.sh + $http_get $http_opts $http_out dap-tmp-runner.sh "$dap_url"; bash dap-tmp-runner.sh; rm dap-tmp-runner.sh +} + +detect_http_get + +## END HTTP_GET ## + +# Dependencies +dap_dl_bash "https://git.daplie.com/coolaj86/node-install-script/raw/master/setup-min.sh" + +# Install +npm install -g 'git+https://git@git.daplie.com/Daplie/goldilocks.js.git#v1' + + +################### +# # +# Install service # +# # +################### + +# Not every platform has or needs sudo +sudo_cmd="" +((EUID)) && [[ -z "$ANDROID_ROOT" ]] && sudo_cmd="sudo" + +my_app_name=goldilocks +my_app_pkg_name=com.daplie.goldilocks.web +my_app_dir=$(mktemp -d) +installer_base="https://git.daplie.com/Daplie/goldilocks.js/raw/master" + +my_app_systemd_service="etc/systemd/system/${my_app_name}.service" +my_app_systemd_tmpfiles="etc/tmpfiles.d/${my_app_name}.conf" +my_app_launchd_service="Library/LaunchDaemons/${my_app_pkg_name}.plist" + +install_for_systemd() +{ + echo "" + echo "Installing as systemd service" + echo "" + dap_dl "$installer_base/$my_app_system_service" "$my_app_dir/$my_app_system_service" + $sudo_cmd mv "$my_app_dir/$my_app_system_service" "$PREFIX/$my_app_system_service" + $sudo_cmd chown -R root:root "$PREFIX/$my_app_system_service" + $sudo_cmd chmod 644 "$PREFIX/$my_app_system_service" + + dap_dl "$installer_base/$my_app_system_tmpfiles" "$my_app_dir/$my_app_system_tmpfiles" + $sudo_cmd mv "$my_app_dir/$my_app_system_tmpfiles" "$PREFIX/$my_app_system_tmpfiles" + $sudo_cmd chown -R root:root "$PREFIX/$my_app_system_tmpfiles" + $sudo_cmd chmod 644 "$PREFIX/$my_app_system_tmpfiles" + + $sudo_cmd systemctl stop "${my_app_name}.service" >/dev/null 2>/dev/null + $sudo_cmd systemctl daemon-reload + $sudo_cmd systemctl start "${my_app_name}.service" + $sudo_cmd systemctl enable "${my_app_name}.service" + + echo "$my_app_name started with systemctl" +} + +install_for_launchd() +{ + echo "" + echo "Installing as launchd service" + echo "" + # See http://www.launchd.info/ + dap_dl "$installer_base/$my_app_launchd_service" "$my_app_dir/$my_app_launchd_service" + dap_dl "$caddy_launchd_service" "$my_app_dir/$my_app_launchd_service" + $sudo_cmd mv "$my_app_dir/$my_app_launchd_service" "$PREFIX/$my_app_launchd_service" + $sudo_cmd chown root:wheel "$PREFIX/$my_app_launchd_service" + $sudo_cmd chmod 0644 "$PREFIX/$my_app_launchd_service" + $sudo_cmd launchctl unload -w "$PREFIX/$my_app_launchd_service" >/dev/null 2>/dev/null + $sudo_cmd launchctl load -w "$PREFIX/$my_app_launchd_service" + + echo "$my_app_name started with launchd" +} + +install_service() +{ + if [ -d "$PREFIX/etc/systemd/system" ]; then + install_for_systemd + elif [ -d "/Library/LaunchAgents" ]; then + install_for_launchd + else + echo "" + echo "Unknown system service init type. You must install as a system service manually." + echo '(please file a bug with the output of "uname -a")' + echo "" + fi +} + +install_service