From d80bc88723e1bbda04e26b74b6d74116634d85da Mon Sep 17 00:00:00 2001 From: Karl Czajkowski Date: Tue, 26 Sep 2023 15:53:11 -0700 Subject: [PATCH] add basic Makefile with deploy target to run as root This just installs a default mod_wsgi config file and a default hatrac service config file. It will not overwrite existing configs. --- Makefile | 62 ++++++++++++++++++ install-script | 165 +++++++++++++++++++++++++++++++++++++++++++++++ wsgi_hatrac.conf | 22 ------- 3 files changed, 227 insertions(+), 22 deletions(-) create mode 100644 Makefile create mode 100755 install-script delete mode 100644 wsgi_hatrac.conf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eda3492 --- /dev/null +++ b/Makefile @@ -0,0 +1,62 @@ + + +# this ugly hack necessitated by Ubuntu... grrr... +SYSPREFIX=$(shell python3 -c 'import site;print(site.getsitepackages()[0])' | sed -e 's|/[^/]\+/[^/]\+/[^/]\+$$||') +# try to find the architecture-neutral lib dir by looking for one of our expected prereqs... double grrr... +PYLIBDIR=$(shell python3 -c 'import site;import os.path;print([d for d in site.getsitepackages() if os.path.exists(d+"/globus_sdk")][0])') + +CONFDIR=/etc +SHAREDIR=$(SYSPREFIX)/share/hatrac + +ifeq ($(wildcard /etc/httpd/conf.d),/etc/httpd/conf.d) + HTTPSVC=httpd +else + HTTPSVC=apache2 +endif + +HTTPDCONFDIR=/etc/$(HTTPSVC)/conf.d +WSGISOCKETPREFIX=/var/run/$(HTTPSVC)/wsgi +DAEMONUSER=hatrac +DAEMONHOME=$(shell getent passwd $(DAEMONUSER) | cut -f6 -d: ) + +# turn off annoying built-ins +.SUFFIXES: + +INSTALL=./install-script + +# make this the default target +install: force + pip3 install --upgrade . + +testvars: force + @echo DAEMONUSER=$(DAEMONUSER) + @echo DAEMONHOME=$(DAEMONHOME) + @echo CONFDIR=$(CONFDIR) + @echo SYSPREFIX=$(SYSPREFIX) + @echo SHAREDIR=$(SHAREDIR) + @echo HTTPDCONFDIR=$(HTTPDCONFDIR) + @echo WSGISOCKETPREFIX=$(WSGISOCKETPREFIX) + @echo PYLIBDIR=$(PYLIBDIR) + +wsgi_hatrac.conf: force + sudo su -c \ + 'python3 -c "import hatrac as m;m.sample_httpd_config()"' \ + - hatrac > $@ + +$(HTTPDCONFDIR)/%.conf: ./%.conf force + $(INSTALL) -o root -g root -m a+r -p -D -n $< $@ + +$(DAEMONHOME)/%config.json: test/%config.json force + $(INSTALL) -o root -g apache -m a+r -p -D -n $< $@ + +DEPLOY_FILES=\ + $(HTTPDCONFDIR)/wsgi_hatrac.conf \ + $(DAEMONHOME)/hatrac_config.json + +deploy: $(DEPLOY_FILES) force + +uninstall: force + pip3 uninstall -y ermresolve + +force: + diff --git a/install-script b/install-script new file mode 100755 index 0000000..e01be77 --- /dev/null +++ b/install-script @@ -0,0 +1,165 @@ +#!/bin/bash + +# usage: install-script [opt]... srcfile dst + +inopts=true + +owner= +group= +mode= +flags=() +noclobber= + +replace_mode=assign +replacement_keys=() +replacement_values=() + +error() +{ + cat >&2 <]... [--] + +Options: + -o owner set owner of dstfile + -g group set group ownership of dstfile + -m mode set mode of dstfile + -n no-clobber + -Z context set SE-Linux context and rule for dstfile + -p preserve timestamp on dstfile + -D create parent directories of dstfile + -M mode replacement mode: assign (default), ref, sed + -R key=value... apply replacements, e.g. + "s/^key=.*/key=value/" (assign mode) + +When using pattern replacement, srcfile is rewritten to a temporary +before being installed to dstfile. The replacment modes correspond +to: + + assign: replace shell script variable assignments such as + "key=rest-of-line" with "key=value" + + ref: replace shell script variable references such as + "\${key}" with "value" + + sed: replace using arbitrary sed pattern/value expressions + +The final mode specification applies to all replacements. + +Installation is handled by the regular "install" utility, which +supports a target filepath or a target directory path for the +destination argument. However, this script does not support the + +EOF + exit 1 +} + +while [[ $# -gt 0 ]] && [[ -n "$inopts" ]] +do + case "$1" in + -o) owner="$2" ; shift 2 ;; + -g) group="$2" ; shift 2 ;; + -m) mode="$2" ; shift 2 ;; + -n) noclobber=true ; shift 1 ;; + -Z) context="$2" ; shift 2 ;; + -p|-D) flags+=( "$1" ) ; shift 1 ;; + -M) + case "$2" in + assign|ref|sed) + replace_mode="$2" + ;; + *) + error Unrecognized replacement mode "\"$2\"". + ;; + esac + shift 2 + ;; + -R) + shift 1 + inreplace=true + while [[ $# -gt 0 ]] && [[ -n "$inreplace" ]] + do + case "$1" in + --) inreplace= ; shift 1 ;; + ?*=*) + key="${1%%=*}" + value="${1##${key}=}" + key="${key//\//\\/}" + value="${value//\//\\/}" + + replacement_keys+=( "$key" ) + replacement_values+=( "$value" ) + + shift 1 + ;; + *) inreplace= ;; + esac + done + ;; + -*) + error Unrecognized option "\"$1\"". + exit 1 + ;; + --) inopts= ; shift 1 ;; + *) inopts= ;; + esac +done + +[[ $# -lt 2 ]] && error Require srcfile and dst arguments after options. +[[ ! -r "$1" ]] && error Cannot read srcfile "\"$1\"". + +srcfile="$1" +dstfile="$2" + +[[ -n "$owner" ]] && flags+=( -o "$owner" ) +[[ -n "$group" ]] && flags+=( -g "$group" ) +[[ -n "$mode" ]] && flags+=( -m "$mode" ) +if [[ -n "$context" ]] +then + #flags+=( -Z "$context" ) + semanage fcontext --add --type "$context" "$dstfile" || error Could not install SE-Linux context "$context" for "$dstfile" +fi + +TMP= + +cleanup() +{ + [[ -n "$TMP" ]] && [[ -e "$TMP" ]] && rm -f "$TMP" +} + +trap cleanup 0 + +replacements=() + +for i in ${!replacement_keys[@]} +do + case "${replace_mode}" in + assign) replacements+=( -e "s/^${replacement_keys[$i]}=.*/${replacement_keys[$i]}=\"${replacement_values[$i]}\"/" ) ;; + ref) replacements+=( -e "s/\${${replacement_keys[$i]}}/${replacement_values[$i]}/g" ) ;; + sed) replacements+=( -e "s/${replacement_keys[$i]}/${replacement_values[$i]}/g" ) ;; + esac +done + +#echo -- "${replacements[@]}" + +if [[ "$noclobber" = "true" ]] && [[ -r "$dstfile" ]] +then + echo Skipping installation that would overwrite existing "$dstfile" + exit 0 +fi + +if [[ "${#replacements[@]}" -gt 0 ]] +then + TMP=$(mktemp) + [[ -w "$TMP" ]] || error Could not create temporary file. + sed "${replacements[@]}" < "$srcfile" > "$TMP" && { + touch -r "$srcfile" "$TMP" + install "${flags[@]}" "$TMP" "$dstfile" + } || { + echo replacement "${replacements[@]}" failed >&2 + exit 1 + } +else + install "${flags[@]}" "$srcfile" "$dstfile" +fi + diff --git a/wsgi_hatrac.conf b/wsgi_hatrac.conf deleted file mode 100644 index 6fcf242..0000000 --- a/wsgi_hatrac.conf +++ /dev/null @@ -1,22 +0,0 @@ -# this file must be loaded (alphabetically) after wsgi.conf -AllowEncodedSlashes On - -WSGIPythonOptimize 1 -WSGIDaemonProcess hatrac processes=4 threads=4 user=hatrac maximum-requests=2000 -WSGIScriptAlias /hatrac /usr/local/lib/python3.7/site-packages/hatrac/hatrac.wsgi -WSGIPassAuthorization On - -WSGISocketPrefix /var/run/wsgi/wsgi - - - - AuthType webauthn - Require webauthn-optional - - WSGIProcessGroup hatrac - - # site can disable redundant service logging by adding env=!dontlog to their CustomLog or similar directives - SetEnv dontlog - - -