diff --git a/.gitignore b/.gitignore index f4882b7..08f6bde 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,12 @@ node_modules __pycache__/ /db.sqlite3 /venv/ +/debian/*debhelper* +/debian/*.substvars +/debian/files +/debian/python3-userausfall/ +/debian/userausfall/ +/debian/userausfall-webapp/ +/.pybuild/ +/build/ +/userausfall.egg-info/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e824e98 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +DIR_BUILD ?= build + +.PHONY: default-target +default-target: + @true + +.PHONY: clean +clean: + rm -rf "$(DIR_BUILD)" + +include make.d/assets.mk +include make.d/deb.mk +include make.d/release.mk diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..4f539d6 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +userausfall (0.0.1-1) unstable; urgency=medium + + * Initial release. + + -- Robert Fri, 16 Apr 2021 10:00:20 +0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +10 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..8def355 --- /dev/null +++ b/debian/control @@ -0,0 +1,36 @@ +Source: userausfall +Section: web +Priority: optional +Maintainer: Robert Waltemath +Build-Depends: + debhelper (>= 9), + dh-exec, + dh-python, + python3-all, + python3-django (>= 2.2), + python3-djangorestframework, +# python3-djoser (>= 2.1), + python3-setuptools, +Standards-Version: 4.5.0 + +Package: userausfall +Architecture: all +Depends: + ${misc:Depends}, + python3-userausfall, +Description: User account management interface for systemausfall.org + +Package: userausfall-webapp +Architecture: all +Description: Frontend assets for userausfall + +Package: python3-userausfall +Architecture: all +Depends: + ${misc:Depends}, + ${python3:Depends}, + python3-django (>= 2.2), + python3-django-imagekit, + python3-djangorestframework, + python3-djoser (>= 2.1), +Description: Python backend for the userausfall web application diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..7dad069 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,3 @@ +Files: * +Copyright: 2021 Robert Waltemath +License: AGPL-3+ diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..c638af0 --- /dev/null +++ b/debian/rules @@ -0,0 +1,16 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=userausfall +export PYBUILD_DISABLE=test + +%: + dh $@ --package=python3-userausfall --with=python3 --buildsystem=pybuild + dh $@ --package=userausfall + dh $@ --package=userausfall-webapp + +.PHONY: override_dh_auto_install +override_dh_auto_install: + dh_auto_install --package=python3-userausfall --destdir=debian/python3-userausfall + if echo "$$DH_INTERNAL_OPTIONS" | sed 's/-O/\n/g' | grep -qF -- '--package=userausfall-webapp'; then \ + $(MAKE) assets-install DESTDIR=$$(realpath -m debian/userausfall-webapp/usr/share/userausfall-webapp); \ + fi diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..af745b3 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (git) diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 0000000..a9cf8a5 --- /dev/null +++ b/debian/source/options @@ -0,0 +1 @@ +extend-diff-ignore="/__pycache__/" diff --git a/debian/system-files/userausfall.ini b/debian/system-files/userausfall.ini new file mode 100644 index 0000000..e652d4b --- /dev/null +++ b/debian/system-files/userausfall.ini @@ -0,0 +1,37 @@ +[uwsgi] +# basic uwsgi configuration +plugin = python3 +plugin = router_redirect +master = True +workers = 4 +threads = 2 +vacuum = True + +# python app configuration +chdir = /var/lib/userausfall +pythonpath = /etc/userausfall +touch-reload = /etc/userausfall/settings.py +for-readline = /etc/default/userausfall + env = %(_) +endfor = +module = userausfall.wsgi:application + +# runtime configuration +uid = _userausfall + +# socket configuration +chown-socket = www-data:www-data +chmod-socket = 640 + +# maintenance mode +touch-reload = /etc/userausfall/maintenance_mode +if-exists = /etc/userausfall/maintenance_mode +route = .* break:503 +endif = + +# Logging will catch a lot of OSErrors if clients prematurely close +# connections before a response was sent. This is not something we want +# to know about. +ignore-sigpipe = true +ignore-write-errors = true +disable-write-exception = true diff --git a/debian/system-files/userausfallctl b/debian/system-files/userausfallctl new file mode 100755 index 0000000..5fce389 --- /dev/null +++ b/debian/system-files/userausfallctl @@ -0,0 +1,20 @@ +#!/bin/sh + +set -eu + +EXEC_USER=_userausfall + +. /etc/default/userausfall + +export PYTHONPATH +export DJANGO_SETTINGS_MODULE +export USERAUSFALL_DATA_DIR + +if [ "$(id -nu)" = "$EXEC_USER" ]; then + exec python3 -m django "$@" +elif [ "$(id -u)" = 0 ]; then + exec su -s "$0" "$EXEC_USER" -- "$@" +else + echo "please run $(basename "$0") as root or '$EXEC_USER'" >&2 + exit 1 +fi diff --git a/debian/userausfall.default b/debian/userausfall.default new file mode 100644 index 0000000..acbbc7f --- /dev/null +++ b/debian/userausfall.default @@ -0,0 +1,3 @@ +PYTHONPATH=/etc/userausfall +DJANGO_SETTINGS_MODULE=userausfall_settings +USERAUSFALL_DATA_DIR=/var/lib/userausfall diff --git a/debian/userausfall.install b/debian/userausfall.install new file mode 100644 index 0000000..2914550 --- /dev/null +++ b/debian/userausfall.install @@ -0,0 +1,2 @@ +debian/system-files/userausfallctl usr/bin +debian/system-files/userausfall.ini etc/uwsgi/apps-available diff --git a/debian/userausfall.postinst b/debian/userausfall.postinst new file mode 100644 index 0000000..4b3f299 --- /dev/null +++ b/debian/userausfall.postinst @@ -0,0 +1,59 @@ +#!/bin/sh + +set -eu + +APP_NAME=userausfall +APP_USER=_$APP_NAME +APP_HOME=/var/lib/$APP_NAME +APP_ETC=/etc/$APP_NAME +APP_SETTINGS=$APP_ETC/settings.py +APP_PID=/var/run/uwsgi/app/$APP_NAME/pid +APP_UWSGI_CONFIG=/etc/uwsgi/apps-enabled/$APP_NAME.ini +APP_BACKUPS=/var/backups/$APP_NAME +APP_MEDIA=$APP_HOME/media +APP_CTL_SCRIPT="$APP_NAME"ctl + +if [ "$1" = "configure" ]; then + if ! getent passwd "$APP_USER" >/dev/null; then + # adduser still recognizes usernames with leading underscores as bad name + # even though the current debian packaging guidelines enforces this. + adduser --quiet --system --group --disabled-password --force-badname \ + --home "$APP_HOME" "$APP_USER" + fi + + if [ -f "$APP_UWSGI_CONFIG" ]; then + if "$APP_CTL_SCRIPT" migrate --no-input >/dev/null; then + rm -f "$APP_ETC/maintenance_mode" + else + echo "error while executing $APP_USER migrations. maintenance mode still active" >&2 + fi + fi + + if [ -f "$APP_SETTINGS" ]; then + chown "$APP_USER:" "$APP_SETTINGS" + fi + + # create secure user dirs + install -d -o "$APP_USER" -g nogroup -m 700 "$APP_BACKUPS" + install -d -o "$APP_USER" -g "$APP_USER" -m 755 "$APP_MEDIA" + + "$APP_CTL_SCRIPT" collectstatic --no-input --clear + + if [ -f "$APP_PID" ]; then + printf "reloading $APP_USER app server... " + kill -HUP "$(cat "$APP_PID")" 2>/dev/null && echo "ok" || echo "failed" + fi +fi + +if [ "$1" = "triggered" ]; then + "$APP_CTL_SCRIPT" collectstatic --no-input --clear +fi + +set +eu + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/make.d/assets.mk b/make.d/assets.mk new file mode 100644 index 0000000..95079a1 --- /dev/null +++ b/make.d/assets.mk @@ -0,0 +1,48 @@ +DIR_ASSETS = . +DIR_NODE = $(DIR_ASSETS)/node_modules +DIR_NODE_BIN = $(DIR_NODE)/.bin + +BIN_NODE_PKG = npm --prefix "$(DIR_ASSETS)" +BIN_VUE_CLI = $(DIR_NODE_BIN)/vue-cli-service + +OUTPUT_DIR_STATIC = $(DIR_BUILD)/webapp +OUTPUT_ASSET_TEMPLATE = $(OUTPUT_DIR_STATIC)/index.html + +DEPS_ASSETS = $(shell find "$(DIR_ASSETS)" -type f -not -path "$(DIR_ASSETS)/node_modules/*" -not -path "$(DIR_ASSETS)/venv/*") + +# dpkg-buildpackage and related tools may interface with +# proxy settings to prevent internet access during package builds. +# We don’t care about that. +undefine no_proxy +undefine http_proxy +undefine https_proxy + +$(DIR_NODE): $(DIR_ASSETS)/package.json $(DIR_ASSETS)/package-lock.json + ADBLOCK=true $(BIN_NODE_PKG) ci --no-progress + @touch -c $(DIR_NODE) + +$(BIN_VUE_CLI): $(DIR_NODE) + +$(OUTPUT_ASSET_TEMPLATE): $(BIN_VUE_CLI) $(DEPS_ASSETS) + $(BIN_NODE_PKG) run build + +.PHONY: lint-js +lint-js: $(BIN_VUE_CLI) + $(BIN_NODE_PKG) run lint + +lint: lint-js + +.PHONY: clean-assets +clean-assets: + rm -rf \ + $(DIR_NODE) \ + $(OUTPUT_DIR_STATIC) + +clean: clean-assets + +.PHONY: assets +assets: $(OUTPUT_ASSET_TEMPLATE) + +.PHONY: assets-install +assets-install: assets + (cd "$(OUTPUT_DIR_STATIC)"; find * -type f -print0 | xargs -0 -I '{}' install -D '{}' "$(DESTDIR)/public/{}") diff --git a/make.d/deb.mk b/make.d/deb.mk new file mode 100644 index 0000000..2bc6fa1 --- /dev/null +++ b/make.d/deb.mk @@ -0,0 +1,5 @@ +PHONY: dist-deb +dist-deb: + dpkg-buildpackage --no-sign + mkdir -p "$(DIR_BUILD)/deb" + mv ../*.deb ../*.changes ../*.buildinfo ../*.git ../*.dsc build/deb diff --git a/make.d/release.mk b/make.d/release.mk new file mode 100644 index 0000000..bc3696e --- /dev/null +++ b/make.d/release.mk @@ -0,0 +1,21 @@ +.PHONY: release-ready +release-ready: + @[ -n "$$(git status --porcelain)" ] && echo "working directory must be clean for release" >&2 && exit 1 + true +# $(MAKE) test + +release-major: BUMP=major +release-minor: BUMP=minor +release-patch: BUMP=patch + +.PHONY: release-major release-minor release-patch +release-major release-minor release-patch: release-generic + +.PHONY: release-generic +.ONESHELL: +release-generic: release-ready + CURRENT_VERSION="$$(bumpversion --no-commit --no-tag $(BUMP) && cat VERSION)" + debchange --newversion "$${CURRENT_VERSION}-1" "New upstream release" + debchange --release "" + git commit -a -m "Release $${CURRENT_VERSION}" + git tag -m "Release $${CURRENT_VERSION}" "v$${CURRENT_VERSION}"