diff options
author | Wojtek Kosior <koszko@koszko.org> | 2022-11-21 13:55:12 +0100 |
---|---|---|
committer | Wojtek Kosior <koszko@koszko.org> | 2022-11-21 13:55:12 +0100 |
commit | 9bc697b85a69af4d1a270aa5272db150c98bed42 (patch) | |
tree | 93d3d1172ef9fc6de8dad6e56e8226146722029e | |
download | koszko-org-server-9bc697b85a69af4d1a270aa5272db150c98bed42.tar.gz koszko-org-server-9bc697b85a69af4d1a270aa5272db150c98bed42.zip |
initial commit
-rw-r--r-- | .gitignore | 11 | ||||
-rw-r--r-- | .gitmodules | 9 | ||||
-rw-r--r-- | .reuse/dep5 | 10 | ||||
-rw-r--r-- | LICENSES/CC0-1.0.txt | 121 | ||||
-rw-r--r-- | Makefile | 88 | ||||
-rw-r--r-- | README.md | 11 | ||||
-rw-r--r-- | README.md.license | 5 | ||||
-rw-r--r-- | container.scm | 99 | ||||
-rwxr-xr-x | fake-client-setup-mounts.sh | 18 | ||||
-rw-r--r-- | fake-client.sh | 12 | ||||
-rwxr-xr-x | guix-container.sh | 167 | ||||
-rw-r--r-- | hosts-extra | 10 | ||||
-rwxr-xr-x | run-with-fake-mounts.sh | 17 | ||||
m--------- | subrepos/koszko-org-website | 0 |
14 files changed, 578 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd17935 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: CC0-1.0 + +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# Available under the terms of Creative Commons Zero v1.0 Universal. + +container-runner +log/ +pidfile +hosts +*.touchfile diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7216302 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: CC0-1.0 + +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# Available under the terms of Creative Commons Zero v1.0 Universal. + +[submodule "koszko-org-website"] + path = subrepos/koszko-org-website + url = ../koszko-org-website diff --git a/.reuse/dep5 b/.reuse/dep5 new file mode 100644 index 0000000..7a5313f --- /dev/null +++ b/.reuse/dep5 @@ -0,0 +1,10 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: koszko.org server configuration +Upstream-Contact: W. Kosior <koszko@koszko.org> +Source: https://git.koszko.org/koszko-org-server + +# Sample paragraph, commented out: +# +# Files: src/* +# Copyright: $YEAR $NAME <$CONTACT> +# License: ... diff --git a/LICENSES/CC0-1.0.txt b/LICENSES/CC0-1.0.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3c5f7e8 --- /dev/null +++ b/Makefile @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: CC0-1.0 + +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# Available under the terms of Creative Commons Zero v1.0 Universal. + +GUIX := guix + +# Almost all commands in this Makefilo are run through `guix time-machine` with +# Guix revision fixed to the one from the commit below. This ensures that the +# same working environment is always used. +GUIX_COMMIT := a86979b41a49a8fcdaa887970ba594dbba701226 + +GUIX_TM = $(GUIX) time-machine --commit=$(GUIX_COMMIT) -- + +GUIX_LOAD_PATHS = $$( \ + find subrepos/ -mindepth 1 -maxdepth 1 \ + -exec printf '-L %s/guix-module-dir/' {} ';' \ + ) + +GUIX_SYS_CONTAINER = $(GUIX_TM) system container $(GUIX_LOAD_PATHS) + +GUIX_SHELL = $(GUIX_TM) shell + +KOSZKO_ORG_WEBSITE_INFO = \ + subrepos/koszko-org-website/src/koszko_org_website.egg-info/PKG-INFO + +all: | container-runner.touchfile log + +$(KOSZKO_ORG_WEBSITE_INFO): + $(MAKE) -C subrepos/koszko-org-website dist + +container-runner: | container.scm $(KOSZKO_ORG_WEBSITE_INFO) + $(GUIX_SYS_CONTAINER) container.scm -r container-runner + touch container-runner.touchfile + +container-runner.touchfile: \ + container.scm $(KOSZKO_ORG_WEBSITE_INFO) + $(MAKE) clean-runner + $(MAKE) container-runner + +hosts: hosts-extra /etc/hosts + cat $^ > $@ + +log: + mkdir -p log + +start-container: guix-container.sh container-runner.touchfile | log + ./run-with-fake-mounts.sh \ + ./$< start -e ./container-runner -p ./pidfile -l ./log + +stop-container: guix-container.sh + ./$< stop -e ./container-runner -p ./pidfile + +restart-container: guix-container.sh container-runner.touchfile | log + ./run-with-fake-mounts.sh \ + ./$< restart -e ./container-runner -p ./pidfile -l ./log + +enter-container: pidfile + nsenter -a -t "$$(cat pidfile)" \ + /run/current-system/profile/bin/bash --login + +fake-client: fake-client-setup-mounts.sh hosts + unshare --map-root-user --mount ./$< \ + "$${SHELL:-/bin/sh}" "$$(id -ru)" "$$(id -rg)" + +install: container.scm sdists + cp guix-container.sh /etc/init.d/guix-container + mkdir -p /usr/local/bin + $(GUIX_SYS_CONTAINER) container.scm -r /usr/local/bin/guix-container + +reinstall: + rm -rf /usr/local/bin/guix-container + $(MAKE) install + +clean-runner: + rm -rf container-runner container-runner.touchfile + +clean: clean-runner + $(MAKE) -C subrepos/koszko-org-website clean + rm -rf log hosts + +.PHONY: all \ + clean-runner clean \ + start-container stop-container restart-container \ + enter-container fake-client \ + install reinstall \ + sdists koszko-org-wesite-sdist diff --git a/README.md b/README.md new file mode 100644 index 0000000..5db8552 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# koszko.org server configuration + +This is Guix system (container) configuration used for the system serving +https://koszko.org + +## Copying + +Contents of this repository are Copyright (C) 2022 Wojtek Kosior. +The repository is [REUSE](https://reuse.software/)-compliant. Please look at +the SPDX identifiers to determine the licensing of particular files or use the +`reuse spdx` command to get a complete report. diff --git a/README.md.license b/README.md.license new file mode 100644 index 0000000..baf2b81 --- /dev/null +++ b/README.md.license @@ -0,0 +1,5 @@ +SPDX-License-Identifier: CC0-1.0 + +Copyright (C) 2022 Wojtek Kosior + +Available under the terms of Creative Commons Zero v1.0 Universal. diff --git a/container.scm b/container.scm new file mode 100644 index 0000000..628e2b3 --- /dev/null +++ b/container.scm @@ -0,0 +1,99 @@ +;; SPDX-License-Identifier: CC0-1.0 + +;; Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +;; +;; Available under the terms of Creative Commons Zero v1.0 Universal. + +(use-modules (gnu)) +(use-modules (koszko-org-website)) +(use-package-modules web) +(use-service-modules web) +(use-service-modules shepherd) + +(define %koszko-org-virtualhost + (httpd-virtualhost + "*:80" + (list "\ + ServerName koszko.org + ServerAlias www.koszko.org + DocumentRoot /srv/http/koszko.org + ServerAdmin koszko@koszko.org + + <If \"%{HTTP_HOST} != 'koszko.org'\"> + Redirect permanent / http://koszko.org/ + </If> + + Alias /sideload /srv/http/koszko.org + + WSGIScriptReloading On + " + #~(let* ((script-rel "/share/koszko-org-website/wsgi.py") + (wsgi-file (string-append #$koszko-org-website script-rel))) + (format #f + "\ + <Files ~s> + Require all granted + </Files> + WSGIScriptAlias / ~a + " + wsgi-file wsgi-file))))) + +(define %wsgi-module + (httpd-module + (name "wsgi_module") + (file (file-append mod-wsgi "/modules/mod_wsgi.so")))) + +;; logio is needed for the '%O' log format directive +(define %logio-module + (httpd-module + (name "logio_module") + (file (file-append httpd "/modules/mod_logio.so")))) + +(define %logformat-combined + "\"%h %l %u %t \\\"%r\\\" %>s %O \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\"") + +(define %koszko-httpd-service + (service + httpd-service-type + (httpd-configuration + (config + (httpd-config-file + (server-name "koszko.org") + (error-log "/var/log/httpd/error.log") + (modules (cons* %wsgi-module %logio-module %default-httpd-modules)) + (extra-config + (list + (string-join `("LogFormat" ,%logformat-combined "combined")) "\n" + "ErrorLog /var/log/httpd/error.log" "\n" + "CustomLog /var/log/httpd/access.log combined" "\n" + ))))))) + +(operating-system + (host-name "koszko") + (timezone "Europe/Warsaw") + + (file-systems (cons (file-system + (device (file-system-label "does-not-matter")) + (mount-point "/") + (type "ext4")) + %base-file-systems)) + (bootloader (bootloader-configuration + (bootloader grub-bootloader) + (targets '("/dev/sdDOES-NOT-MATTER")))) + (services + (cons* %koszko-httpd-service + (simple-service 'koszko-org-website httpd-service-type + (list %koszko-org-virtualhost)) + (service + (shepherd-service-type + 'dummy-network + (const + (shepherd-service + (documentation "Provide 'networking' without actually doing anything") + (provision '(networking)) + (start #~(const #t)) + (stop #~(const #t)) + (respawn? #f))) + (description "Make other services assume network is there.")) + #f) + %base-services))) diff --git a/fake-client-setup-mounts.sh b/fake-client-setup-mounts.sh new file mode 100755 index 0000000..c00a0e5 --- /dev/null +++ b/fake-client-setup-mounts.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# SPDX-License-Identifier: CC0-1.0 + +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# Available under the terms of Creative Commons Zero v1.0 Universal. + +set -e + +SHELL_TO_USE="$1" +USER_ID_TO_USE="$2" +GROUP_ID_TO_USE="$3" + +mount --bind hosts /etc/hosts; +mount -t tmpfs dummy /var/run/nscd 2>/dev/null || true; +unshare --map-user="$USER_ID_TO_USE" --map-group="$GROUP_ID_TO_USE" \ + "$SHELL_TO_USE" diff --git a/fake-client.sh b/fake-client.sh new file mode 100644 index 0000000..3c3ca7c --- /dev/null +++ b/fake-client.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# SPDX-License-Identifier: CC0-1.0 + +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# Available under the terms of Creative Commons Zero v1.0 Universal. + +set -e + +unshare --map-root-user --mount \ + fake-client-setup-mounts.sh "${SHELL:-/bin/sh}" "$(id -u)" diff --git a/guix-container.sh b/guix-container.sh new file mode 100755 index 0000000..04781e8 --- /dev/null +++ b/guix-container.sh @@ -0,0 +1,167 @@ +#!/bin/sh + +# SPDX-License-Identifier: CC0-1.0 + +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# Available under the terms of Creative Commons Zero v1.0 Universal. + +### BEGIN INIT INFO +# Provides: guix-container +# Required-Start: $local_fs $remote_fs $syslog +# Required-Stop: $local_fs $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start Wojtek's Guix container with various services +### END INIT INFO + +set -e + +. /lib/lsb/init-functions + +if [ 0 != $(id -u) ]; then + log_action_msg "Script '$0' must be run as root" + exit 1 +fi + +PIDFILE=/run/guix-container.pid +EXECUTABLE=/usr/local/bin/guix-container +LOG_DIR=/var/log/guix-container +MAX_CONTAINER_SPINUP_WAIT=60 + +ACTION="$1" +shift + +OPTIND=1 +while getopts qe:p:l:L: OPTION_LETTER ; do + case "$OPTION_LETTER" in + p) PIDFILE="$OPTARG" ;; + e) EXECUTABLE="$OPTARG" ;; + l) LOG_DIR="$OPTARG" ;; + w) MAX_CONTAINER_SPINUP_WAIT="$OPTARG" ;; + esac +done + +GUILE_PID= +SUCCESS= +QUIET_EXIT= + +is_running() { + test -e "$PIDFILE" && test -n "$(ps -o pid= --pid $(cat "$PIDFILE"))" + return $? +} + +network_rip() { + ip link delete veth-guix-out 2>/dev/null || true + ip netns delete guix-container-ns 2>/dev/null || true +} + +stop() { + network_rip + /sbin/start-stop-daemon \ + --stop --signal TERM --pidfile "$PIDFILE" --remove-pidfile --quiet \ + --retry 60 2>/dev/null || true +} + +onexit() { + if [ -z "$SUCCESS" ]; then + if [ "x$ACTION" = "xstart" -a -n "$GUILE_PID" ]; then + stop + kill $GUILE_PID >/dev/null || true + fi + if [ -z "$QUIET_EXIT" ]; then + log_failure_msg + fi + else + if [ -z "$QUIET_EXIT" ]; then + log_success_msg + fi + fi +} + +start() { + KOSZKO_SIDELOAD_REAL=/var/www/koszko.org/html + KOSZKO_SIDELOAD_INSIDE=/srv/http/koszko.org + HTTP_DIR_SHARE_OPT=--share="$KOSZKO_SIDELOAD_REAL"="$KOSZKO_SIDELOAD_INSIDE" + + mkdir -p "$(dirname "$LOG_DIR")" + mkdir --mode=700 -p "$LOG_DIR" + + "$EXECUTABLE" $HTTP_DIR_SHARE_OPT \ + > "$LOG_DIR"/stdout.log \ + 2> "$LOG_DIR"/stderr.log & + + GUILE_PID=$! + WAIT_TIME=0 + SHEPHERD_PID= + + while [ $WAIT_TIME -lt "$MAX_CONTAINER_SPINUP_WAIT" ]; do + sleep 1 + WAIT_TIME=$((WAIT_TIME + 1)) + SHEPHERD_PID=$(ps -o pid= --ppid $GUILE_PID || true) + if [ -n "$SHEPHERD_PID" ]; then + mkdir -p "$(dirname "$PIDFILE")" + printf '%s' $SHEPHERD_PID > "$PIDFILE" + break + fi + done + + if [ -z "$SHEPHERD_PID" ]; then + exit 1 + fi + + network_rip + + ip netns attach guix-container-ns $SHEPHERD_PID + ip link add veth-guix-out type veth peer name veth-guix-in + ip link set veth-guix-in netns guix-container-ns + + ip link set veth-guix-out up + ip addr add 10.207.87.1/24 dev veth-guix-out + + ip netns exec guix-container-ns ip link set lo up + ip netns exec guix-container-ns ip link set veth-guix-in up + ip netns exec guix-container-ns ip addr add 10.207.87.2/24 dev veth-guix-in +} + +trap onexit EXIT + +case "$ACTION" in + start) + if is_running; then + log_daemon_msg "Guix container" "already running" + log_warning_msg + QUIET_EXIT=1 + else + log_daemon_msg "Guix container" "starting" + start + fi + ;; + stop) + log_daemon_msg "Guix container" "stopping" + stop + ;; + restart) + QUIET_EXIT=1 + "$0" stop "$@" + "$0" start "$@" + ;; + reload|force-reload) + QUIET_EXIT=1 + "$0" stop "$@" + "$0" start "$@" + ;; + status) + status_of_proc -p "$PIDFILE" "$EXECUTABLE" "Guix container" + QUIET_EXIT=1 + ;; + *) + log_action_msg "Usage: $0 {start|stop|status|restart|reload|force-reload}" + QUIET_EXIT=1 + exit 2 + ;; +esac + +SUCCESS=1 + +exit 0 diff --git a/hosts-extra b/hosts-extra new file mode 100644 index 0000000..dd16317 --- /dev/null +++ b/hosts-extra @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: CC0-1.0 + +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# Available under the terms of Creative Commons Zero v1.0 Universal. + +10.207.87.2 koszko.org +10.207.87.2 www.koszko.org +10.207.87.2 koszkonutek-tmp.pl.eu.org +10.207.87.2 www.koszkonutek-tmp.pl.eu.org diff --git a/run-with-fake-mounts.sh b/run-with-fake-mounts.sh new file mode 100755 index 0000000..75675ed --- /dev/null +++ b/run-with-fake-mounts.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# SPDX-License-Identifier: CC0-1.0 + +# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org> +# +# Available under the terms of Creative Commons Zero v1.0 Universal. + +set -e + +mkdir -p /var/www +mount -t tmpfs dummy /var/www +mkdir -p /var/www/koszko.org/html + +printf ':D\n' > /var/www/koszko.org/html/index.html + +"$@" diff --git a/subrepos/koszko-org-website b/subrepos/koszko-org-website new file mode 160000 +Subproject b582468bb70afba7196b12a8dcd022547426ad9 |