aboutsummaryrefslogtreecommitdiff
# SPDX-License-Identifier: CC0-1.0

# Copyright (C) 2022-2023 Wojtek Kosior <koszko@koszko.org>
#
# Available under the terms of Creative Commons Zero v1.0 Universal.

-include Makefile.local

GUIX ?= guix
export 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
export GUIX_COMMIT

GUIX_TM ?= $(GUIX) time-machine --commit=$(GUIX_COMMIT) --
export GUIX_TM

GUIX_LOAD_PATHS = $$(                                 \
	find subrepos/ -mindepth 1 -maxdepth 1        \
	-exec printf ' -L %s/guix-module-dir/' {} ';' \
	)                                             \
	-L ./guix-module-dir/

GUIX_SYS_CONTAINER = $(GUIX_TM) system container $(GUIX_LOAD_PATHS)

GUIX_SHELL = $(GUIX_TM) shell

GUIX_OPENSSL = $(GUIX_SHELL) openssl -- openssl

KOSZKO_ORG_WEBSITE_INFO = \
	subrepos/koszko-org-website/src/koszko_org_website.egg-info/PKG-INFO
HYDRILLA_WEBSITE_INFO = \
	subrepos/hydrilla-website/src/hydrilla_website.egg-info/PKG-INFO
HYDRILLA_INFO = subrepos/hydrilla/src/hydrilla.egg-info/PKG-INFO

ALL_EGG_INFOS =                    \
	$(KOSZKO_ORG_WEBSITE_INFO) \
	$(HYDRILLA_WEBSITE_INFO)   \
	$(HYDRILLA_INFO)

CONTAINER_PREREQUISITES = container.scm $(ALL_EGG_INFOS) hydrilla-wsgi.py \
	exim.conf Makefile.local test-ca-key.pem test-ca-cert.pem

PWD_DERIVED_DIRECTORY_NAME != pwd | sed 's|[/'\'']|!|g'
TEST_ROOT_DIR = '/tmp/$(PWD_DERIVED_DIRECTORY_NAME)!!test-root/current'

all: | container-runner.touchfile log sample-malcontent

$(KOSZKO_ORG_WEBSITE_INFO):
	$(MAKE) -C subrepos/koszko-org-website dist
$(HYDRILLA_WEBSITE_INFO):
	$(MAKE) -C subrepos/hydrilla-website dist
$(HYDRILLA_INFO):
	$(MAKE) -C subrepos/hydrilla dist

Makefile.local:
	touch $@

test-ca-key.pem:
	$(GUIX_OPENSSL) genrsa -out $@ 4096

test-ca-cert.pem: test-ca-key.pem
	$(GUIX_OPENSSL) req -x509 -new -nodes -key $< -sha256 -days 3650       \
		-out $@ -subj '/CN=Self-signed CA/C=PL/ST=PL/L=Krakow/O=Koszko'

test-ca-certificates.crt: /etc/ssl/certs/ca-certificates.crt \
		test-ca-cert.pem
	cat $^ > $@

container-runner: | $(CONTAINER_PREREQUISITES)
container-runner.touchfile: $(CONTAINER_PREREQUISITES)

container-runner container-runner.touchfile:
	$(MAKE) clean-runner
	$(GUIX_SYS_CONTAINER) container.scm -r container-runner
	touch container-runner.touchfile

hosts: hosts-extra /etc/hosts
	cat $^ > $@

log:
	ln -sf test-root/var/log/guix-container $@

sample-malcontent:
	mkdir $@
	printf 'hydrilla-builder -s tests/source-package-example/ -d %s' \
		"$$(realpath $@)" | \
		make -C subrepos/hydrilla shell-with-hydrilla-only

HYDRILLABUGS_HTML_DIR = $(TEST_ROOT_DIR)/var/www/hydrillabugs.koszko.org/html
LETSENCRYPT_ETC_DIR = $(TEST_ROOT_DIR)/etc/letsencrypt
EXIM_ETC_DIR = $(TEST_ROOT_DIR)/etc/exim
DOVECOT_ETC_DIR = $(TEST_ROOT_DIR)/etc/dovecot
HYDRILLA_WEBSITE_ETC_DIR = $(TEST_ROOT_DIR)/etc/guix-container/hydrilla-website
MALCONTENT_DIR = $(TEST_ROOT_DIR)/var/lib/hydrilla/malcontent_dirs
GITOLITE_DIR = $(TEST_ROOT_DIR)/var/lib/gitolite3
EXIM_SPOOL_DIR = $(TEST_ROOT_DIR)/var/spool/exim

test-root: sample-malcontent Makefile
	rm -f $@
	ln -sf $(TEST_ROOT_DIR) $@
	$(MAKE) prepare-test-root

.PHONY: ensure-test-root
ensure-test-root:
	$(MAKE) test-root
	if [ \! -e $(TEST_ROOT_DIR) ]; then \
		$(MAKE) prepare-test-root;  \
	fi

.PHONY: prepare-test-root
prepare-test-root: sample-malcontent
	@# Move the old test root
	if [ -e $(TEST_ROOT_DIR) ]; then                                       \
		mv $(TEST_ROOT_DIR)                                            \
			$(TEST_ROOT_DIR)/../"old-$$(date --iso-8601=seconds)"; \
	fi
	@# Prepare replacement `/var/www`
	for WWW_SUBDIR in                          \
		koszko.org/html                    \
		hydrillarepos.koszko.org/html      \
		hydrilla.koszko.org/html/downloads \
		hydrillarepos.koszko.org/html      \
		hydrillabugs.koszko.org/html       \
		; do \
		mkdir -p $(TEST_ROOT_DIR)/var/www/"$$WWW_SUBDIR";             \
		printf 'This is dummy file for %s :D\n' "$$WWW_SUBDIR"        \
			> $(TEST_ROOT_DIR)/var/www/"$$WWW_SUBDIR"/index.html; \
	done
	printf '/index /index.html\n' > $(HYDRILLABUGS_HTML_DIR)/uri-map.txt
	mkdir -p $(HYDRILLABUGS_HTML_DIR)/javascripts
	printf 'console.log("dummy js");\n'                           \
		> $(HYDRILLABUGS_HTML_DIR)'/javascripts/foo.js?31415'
	mkdir -p $(HYDRILLABUGS_HTML_DIR)/stylesheets
	printf 'dummy-css {\ncolor: #555;\n}\n'                         \
		> $(HYDRILLABUGS_HTML_DIR)'/stylesheets/b?a=r&ba=z.css'
	printf '/stylesheets/b?a=r&ba=z /stylesheets/b?a=r&ba=z.css' \
		>> $(HYDRILLABUGS_HTML_DIR)/uri-map.txt
	@# Prepare replacement `/var/log`
	mkdir -p $(TEST_ROOT_DIR)/var/log
	@# Prepare replacement `/etc/letsencrypt`
	mkdir --mode=755 -p $(LETSENCRYPT_ETC_DIR)
	printf 'test secret\n' > $(LETSENCRYPT_ETC_DIR)/dummy-keys-and-stuff.txt
	chmod 540 $(LETSENCRYPT_ETC_DIR)/dummy-keys-and-stuff.txt
	chgrp 1001 $(LETSENCRYPT_ETC_DIR)/dummy-keys-and-stuff.txt
	@# Prepare replacement `/etc/exim`
	mkdir --mode=755 -p $(EXIM_ETC_DIR)
	$(GUIX_SHELL) openssl --                                  \
		openssl genrsa -out $(EXIM_ETC_DIR)/dkim.pem 2048
	chmod 640 $(EXIM_ETC_DIR)/dkim.pem
	chown 106:113 $(EXIM_ETC_DIR)/dkim.pem
	printf koszko: > $(EXIM_ETC_DIR)/passwd
	printf silnehaslo |                                         \
		$(GUIX_SHELL) whois -- mkpasswd --method=sha-256 -s \
		>> $(EXIM_ETC_DIR)/passwd
	echo >> $(EXIM_ETC_DIR)/passwd
	chmod 640 $(EXIM_ETC_DIR)/passwd
	chown 106:113 $(EXIM_ETC_DIR)/passwd
	@# Prepare replacement `/etc/dovecot`
	mkdir --mode=755 -p $(DOVECOT_ETC_DIR)
	printf koszko: > $(DOVECOT_ETC_DIR)/users
	$(GUIX_SHELL) -C --no-cwd dovecot coreutils bash-minimal -- \
		bash -c 'mkdir /etc/dovecot;                        \
			 touch /etc/dovecot/dovecot.conf;           \
			 doveadm pw -s SHA256-CRYPT -p silnehaslo;' \
		>> $(DOVECOT_ETC_DIR)/users
	sed -i 's|$$|:1000:1000::/home/urz:/bin/bash:userdb_mail=maildir:/home/urz/Maildir/|' \
		$(DOVECOT_ETC_DIR)/users
	chmod 640 $(DOVECOT_ETC_DIR)/users
	chgrp 115 $(DOVECOT_ETC_DIR)/users
	@# Prepare replacement `/etc`
	mkdir --mode=750 -p $(HYDRILLA_WEBSITE_ETC_DIR)
	printf 'test non-secret\n' > $(HYDRILLA_WEBSITE_ETC_DIR)/secret.txt
	chgrp -R 133 $(HYDRILLA_WEBSITE_ETC_DIR)
	chmod 640 $(HYDRILLA_WEBSITE_ETC_DIR)/secret.txt
	@# Prepare replacement `/var/lib/hydrilla`
	mkdir -p $(MALCONTENT_DIR)/api_v2
	ln -sf api_v2 $(MALCONTENT_DIR)/api_v1
	cp -r $</* $(MALCONTENT_DIR)/api_v2/
	@# Prepare replacement `/var/lib/gitolite3`
	mkdir -p $(GITOLITE_DIR)/repositories
	git clone --bare ./subrepos/sheets-websites/ \
		$(GITOLITE_DIR)/repositories/sheets-websites.git
	printf "sheets-websites.git\n" > $(GITOLITE_DIR)/projects.list
	chmod -R o-rwx,g-w $(GITOLITE_DIR)
	chgrp -R 118 $(GITOLITE_DIR)
	@# Prepare replacement `/var/spool/exim`
	mkdir -p $(EXIM_SPOOL_DIR)
	chmod 750 $(EXIM_SPOOL_DIR)
	chown 106:113 $(EXIM_SPOOL_DIR)

GUIX_CONTAINER_FLAGS = -e ./container-runner -p ./pidfile \
	-r "$$(realpath test-root)"

start-container: guix-container.sh container-runner.touchfile ensure-test-root \
		| log
	./$< start $(GUIX_CONTAINER_FLAGS)

stop-container: guix-container.sh
	./$< stop $(GUIX_CONTAINER_FLAGS)

restart-container: guix-container.sh container-runner.touchfile \
		ensure-test-root | log
	./$< restart $(GUIX_CONTAINER_FLAGS)

enter-container: pidfile
	nsenter -a -t "$$(cat pidfile)" \
		/run/current-system/profile/bin/bash --login

fake-client: fake-client-setup-mounts.sh hosts test-ca-certificates.crt
	unshare --map-root-user --mount ./$< "$${SHELL:-/bin/sh}"

install: $(CONTAINER_PREREQUISITES)
	cp guix-container.sh /etc/init.d/guix-container
	mkdir -p /usr/local/bin
	if [ -e /usr/local/bin/guix-container ]; then \
		rm /usr/local/bin/guix-container;     \
	fi
	$(GUIX_SYS_CONTAINER) container.scm -r /usr/local/bin/guix-container

build-hydrilla-json-schemas:
	$(GUIX_TM) build -L ./guix-module-dir/ hydrilla-json-schemas

clean-runner:
	rm -rf container-runner container-runner.touchfile

SUBREPOS_WITH_MAKEFILE = $$(                                   \
	find subrepos/ -mindepth 2 -maxdepth 2 -name Makefile  \
		| sed 's|^subrepos/\([^/]\+\)/Makefile$$|\1|'  \
	)

clean: clean-runner
	for SUBREPO in $(SUBREPOS_WITH_MAKEFILE); do   \
		$(MAKE) -C subrepos/"$$SUBREPO" clean; \
	done
	rm -rf log test-root hosts test-ca-key.pem test-ca-cert.pem \
		test-ca-certificates.crt schemas sample-malcontent

.PHONY: all                                              \
	clean-runner clean                               \
	start-container stop-container restart-container \
	enter-container fake-client                      \
	install                                          \
	build-hydrilla-json-schemas