A => IMGBUILD +104 -0
@@ 1,104 @@
+# The name of this image. Mostly cosmetic, e.g. for output file naming.
+imgname=meta-srht
+
+# This enables the **experimental** support for building Alpine images.
+# The caveats that apply are plenty at the moment, make sure to read
+# the comments for each directive, especially the "ALPINE" notes.
+target=alpine
+
+# The image format to generate. See also the man page for options.
+# Generate raw image with msdos partition table and a single partition
+#format=(raw 6G msdos ext4)
+# Generate xz-compressed tarball
+#format=(tar xz)
+# Generate a directory
+#format=(dir)
+# Custom: the IMGBUILD has to implement setup() and cleanup()
+#format=(custom)
+#
+# ALPINE: the only supported format is `raw`, others may or may not work. For
+# raw, an Alpine images actually gets two partitions, boot and root. The boot
+# partition is similar to the one the installer would create by default. Both
+# partitions are formatted with the file system specified.
+format=(raw 4G msdos ext4)
+
+# Specify config items to be copied from the host building the image.
+# Add 'keyring' to install the host's pacman keyring on the image.
+# Otherwise the keyring must be installed manually via files or by running
+# `pacman-key` in the provision script.
+# Add 'mirrorlist' to install the host's mirrorlist. Otherwise the mirrorlist
+# must be installed manually by supplying a file or a patch to the default mirrorlist
+# or some custom solution in the provision script.
+# Default is to not use anything from the host.
+# hostconf=()
+#
+# ALPINE: for Alpine images, 'keyring' and 'mirrorlist' refer to
+# `/etc/apk/keys` and `/etc/apk/repositories` respectively. If the host (which
+# has to be Arch Linux) has those, you can add them here. Otherwise, it is
+# best to have a file `repositories` and a directory `keys` in the root of the
+# IMGBUILD. If those are present, they will be used. As a last fallback, a
+# repositories file and set of keys included in this script will be used
+# (currently 3.15 branch). Relying on this should be avoided.
+hostconf=()
+
+# The packages to install
+#
+# ALPINE: the packages currently must include `bash` for provisioning to work!
+packages=(
+ alpine-base
+ syslinux
+ linux-virt
+ openssh
+ sudo
+ util-linux
+ tzdata
+ e2fsprogs
+ bash
+ coreutils
+ redis
+ meta.sr.ht
+ postgresql
+)
+
+# The provisioning function. It is executed in the context of the new image.
+# Files have been copied, patches have been applied, templates have been
+# rendered (see the folders in this directory and the makeimg man page).
+provision() {
+ ln -sf "/usr/share/zoneinfo/Europe/Berlin" /etc/localtime
+ hwclock --systohc
+
+ # echo secret | openssl passwd -6 -stdin
+ echo 'root:$6$mpWkRUWMForQFL69$zceQFLgGasM6DxC9JyYAO6XrjPDEjfp7tOyVmkiag2C2TOyR/3aeD/V0OVVvJIfU2pjEqhN9ZlXD4EVsqNsrL1' | chpasswd -e
+
+ # Set up bootloader.
+ # PART is set by makeimg
+ UUID=$(lsblk -rno UUID ${PART})
+ sed -e "s|^root=|root=/dev/disk/by-uuid/${UUID}|" -i /etc/update-extlinux.conf
+ dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/mbr.bin of="${BLKDEV}"
+ extlinux --install /boot
+ update-extlinux -v
+}
+
+# Performed last as services may have been installed via custom files/commands
+#
+# ALPINE: for Alpine (open-rc) services, the special syntax
+# `<SERVICE>:<RUNLEVEL>` is supported. If the runlevel part is omitted, the
+# default runlevel will be used.
+services=(
+ modules:boot
+ hwclock:boot
+ urandom:boot
+ sysctl:boot
+ bootmisc:boot
+ networking:boot
+ hostname:boot
+ syslog:boot
+ loadkmap:boot
+ crond
+ sshd
+ redis
+ postgresql
+ meta.sr.ht-setup
+ meta.sr.ht-api
+ meta.sr.ht
+)
A => README.md +24 -0
@@ 1,24 @@
+# IMGBUILD for meta.sr.ht instance
+
+The files in this repository describe a VM disk image which can be built with
+[makeimg][1] (which currently only runs on Arch Linux) and which runs the
+[meta.sr.ht][2] component of [SourceHut][3].
+
+[1]: https://anemos.io/projects/makeimg "makeimg homepage"
+[2]: https://git.sr.ht/~sircmpwn/meta.sr.ht/ "meta.sr.ht source code"
+[3]: https://sr.ht/~sircmpwn/sourcehut/ "SourceHut project page"
+
+It uses the recently added (and not yet really documented) capability of
+`makeimg` to build Alpine Linux images. Consider this somewhat experimental.
+
+It serves as a codified documentation of how to get meta.sr.ht up and running.
+If you had access to my password store (which is used in the config template),
+you would get a ready-to-use meta.sr.ht instance.
+
+Some things need to be changed for this image to be useful for others. They
+will be documented here shortly. For now, hopefully the option to look at the
+code can help answer some questions you might have about the setup process.
+
+The image is intended to be run in a VM. It needs outgoing access to your mail
+server and must be accessible at least from the host to be useful. You can
+access meta.sr.ht on port :5000.
A => files/etc/conf.d/meta.sr.ht +2 -0
@@ 1,2 @@
+# Override to listen on all interfaces
+META_BIND=0.0.0.0:5000
A => files/etc/hostname +1 -0
@@ 1,1 @@
+meta.srht.bitfehler
A => files/etc/init.d/meta.sr.ht-setup +22 -0
@@ 1,22 @@
+#!/sbin/openrc-run
+
+depend() {
+ need postgresql
+ before meta.sr.ht
+}
+
+start() {
+ if [ ! -e "/etc/sr.ht/${SVCNAME}-done" ]; then
+ ebegin "Starting ${SVCNAME}"
+ touch "/etc/sr.ht/${SVCNAME}-done"
+ su postgres -c "psql -c 'CREATE DATABASE \"meta.sr.ht\"'"
+ metasrht-initdb
+ echo root | metasrht-manageuser -e admin@bitfehler.net -p -s -t admin root
+ echo test | metasrht-manageuser -e test@bitfehler.net -p -s -t active_paying test
+ eend $?
+ fi
+}
+
+stop() {
+ :
+}
A => files/etc/network/interfaces +6 -0
@@ 1,6 @@
+auto lo
+iface lo inet loopback
+
+auto eth0
+iface eth0 inet dhcp
+
A => files/etc/sr.ht/forge-key.pub.asc +14 -0
@@ 1,14 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEYfpOIxYJKwYBBAHaRw8BAQdASueeqExxBqdKc4Gh6OmRiL8nL8hvdu8+786g
+inpUkK20NGJpdGZlaGxlciBzci5odCBkZXYgZW52aXJvbm1lbnQgPHNyaHRAYml0
+ZmVobGVyLm5ldD6IkAQTFggAOBYhBPJJSxjjtoL+nNjT30JoZx8H0aYeBQJh+k4j
+AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEEJoZx8H0aYe5v0BAKIwA0qY
+es8cjRW1kA7lWAPafIeeXsxE62hu+uV1QlzBAP41nYHutVIo4WRML7pkBr50r041
+gEjt7GyIGmXWyZ0ND7g4BGH6TiMSCisGAQQBl1UBBQEBB0CdrtGSzeTnWtfG17pA
+qJR5Ja2TkjVKLijP3x5K2IDYUwMBCAeIeAQYFggAIBYhBPJJSxjjtoL+nNjT30Jo
+Zx8H0aYeBQJh+k4jAhsMAAoJEEJoZx8H0aYe/awBAN3IZQHQ8ygTA8DY9wLrfm4r
+0btGRCdWQUHRwbAnLv6wAQDrNYkG31ELqKoUkNHA6lPqnKvyvyNemybKXDQOOSGc
+Bw==
+=GmTr
+-----END PGP PUBLIC KEY BLOCK-----
A => keys/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub +9 -0
@@ 1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1yHJxQgsHQREclQu4Ohe
+qxTxd1tHcNnvnQTu/UrTky8wWvgXT+jpveroeWWnzmsYlDI93eLI2ORakxb3gA2O
+Q0Ry4ws8vhaxLQGC74uQR5+/yYrLuTKydFzuPaS1dK19qJPXB8GMdmFOijnXX4SA
+jixuHLe1WW7kZVtjL7nufvpXkWBGjsfrvskdNA/5MfxAeBbqPgaq0QMEfxMAn6/R
+L5kNepi/Vr4S39Xvf2DzWkTLEK8pcnjNkt9/aafhWqFVW7m3HCAII6h/qlQNQKSo
+GuH34Q8GsFG30izUENV9avY7hSLq7nggsvknlNBZtFUcmGoQrtx3FmyYsIC8/R+B
+ywIDAQAB
+-----END PUBLIC KEY-----
A => keys/alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub +9 -0
@@ 1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwlzMkl7b5PBdfMzGdCT0
+cGloRr5xGgVmsdq5EtJvFkFAiN8Ac9MCFy/vAFmS8/7ZaGOXoCDWbYVLTLOO2qtX
+yHRl+7fJVh2N6qrDDFPmdgCi8NaE+3rITWXGrrQ1spJ0B6HIzTDNEjRKnD4xyg4j
+g01FMcJTU6E+V2JBY45CKN9dWr1JDM/nei/Pf0byBJlMp/mSSfjodykmz4Oe13xB
+Ca1WTwgFykKYthoLGYrmo+LKIGpMoeEbY1kuUe04UiDe47l6Oggwnl+8XD1MeRWY
+sWgj8sF4dTcSfCMavK4zHRFFQbGp/YFJ/Ww6U9lA3Vq0wyEI6MCMQnoSMFwrbgZw
+wwIDAQAB
+-----END PUBLIC KEY-----
A => keys/alpine-devel@lists.alpinelinux.org-6165ee59.rsa.pub +14 -0
@@ 1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAutQkua2CAig4VFSJ7v54
+ALyu/J1WB3oni7qwCZD3veURw7HxpNAj9hR+S5N/pNeZgubQvJWyaPuQDm7PTs1+
+tFGiYNfAsiibX6Rv0wci3M+z2XEVAeR9Vzg6v4qoofDyoTbovn2LztaNEjTkB+oK
+tlvpNhg1zhou0jDVYFniEXvzjckxswHVb8cT0OMTKHALyLPrPOJzVtM9C1ew2Nnc
+3848xLiApMu3NBk0JqfcS3Bo5Y2b1FRVBvdt+2gFoKZix1MnZdAEZ8xQzL/a0YS5
+Hd0wj5+EEKHfOd3A75uPa/WQmA+o0cBFfrzm69QDcSJSwGpzWrD1ScH3AK8nWvoj
+v7e9gukK/9yl1b4fQQ00vttwJPSgm9EnfPHLAtgXkRloI27H6/PuLoNvSAMQwuCD
+hQRlyGLPBETKkHeodfLoULjhDi1K2gKJTMhtbnUcAA7nEphkMhPWkBpgFdrH+5z4
+Lxy+3ek0cqcI7K68EtrffU8jtUj9LFTUC8dERaIBs7NgQ/LfDbDfGh9g6qVj1hZl
+k9aaIPTm/xsi8v3u+0qaq7KzIBc9s59JOoA8TlpOaYdVgSQhHHLBaahOuAigH+VI
+isbC9vmqsThF2QdDtQt37keuqoda2E6sL7PUvIyVXDRfwX7uMDjlzTxHTymvq2Ck
+htBqojBnThmjJQFgZXocHG8CAwEAAQ==
+-----END PUBLIC KEY-----
A => keys/alpine@sr.ht.rsa.pub +10 -0
@@ 1,10 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Xz+dp7AfkiIjin35/D/
+o/WHs4bup9CCIrp2mtPU/ggpdUEKEJoOGfHvvnxHJsXISC9S2B5CgZWEWEpzQXln
+XOig++cukGCZBCV0px4p2+5NJjtws6y0sWo5cuHBnQK9b3K/VPxpMMq3dwFZ0+Oj
+719yGH1aDUz/xmsU/j2mtMWDTia2LoqBarznjXBcm73nAKGDc9uZxUv2ThseGGn/
+T6+pd3fA5KIIBr4LvOAY3dheD1cAEDq7tHEwgSD7lEskhdSqQAq5ZDQErFIJuO1l
+DUFHmt3ag26jgkbE0bbYjSN+Yx+Iisb9bFruA9absmdi9BVFGDcLm+Ymnu2UdnuC
+vQIDAQAB
+-----END PUBLIC KEY-----
+
A => repositories +3 -0
@@ 1,3 @@
+https://mirror.sr.ht/alpine/v3.15/sr.ht
+http://dl-cdn.alpinelinux.org/alpine/v3.15/main
+http://dl-cdn.alpinelinux.org/alpine/v3.15/community
A => templates/etc/motd +1 -0
@@ 1,1 @@
+This image was build on $(date)
A => templates/etc/sr.ht/config.ini +211 -0
@@ 1,211 @@
+[sr.ht]
+#
+# The name of your network of sr.ht-based sites
+site-name=srht-bf
+#
+# The top-level info page for your site
+site-info=https://srht.bitfehler
+#
+# {{ site-name }}, {{ site-blurb }}
+site-blurb=bitfehler's test forge
+#
+# If this != production, we add a banner to each page
+environment=development
+#
+# Contact information for the site owners
+owner-name=Conrad Hoffmann
+owner-email=ch@bitfehler.net
+#
+# The source code for your fork of sr.ht
+source-url=https://git.sr.ht/~sircmpwn/srht
+#
+# Link to your instance's privacy policy. Uses the sr.ht privacy policy as the
+# default, which describes the information collected by the upstream SourceHut
+# code.
+privacy-policy=
+#
+# A key used for encrypting session cookies. Use 'srht-keygen service' to
+# generate the service key. This must be shared between each node of the same
+# service (e.g. git1.sr.ht and git2.sr.ht), but different services may use
+# different keys. If you configure all of your services with the same
+# config.ini, you may use the same service-key for all of them.
+service-key=$(pass show dev/srht/service-key)
+#
+# A secret key to encrypt internal messages with. Use 'srht-keygen network' to
+# generate this key. It must be consistent between all services and nodes.
+network-key=$(pass show dev/srht/network-key)
+#
+# The redis host URL. This is used for caching and temporary storage, and must
+# be shared between nodes (e.g. git1.sr.ht and git2.sr.ht), but need not be
+# shared between services. It may be shared between services, however, with no
+# ill effect, if this better suits your infrastructure.
+redis-host=redis://127.0.0.1
+
+global-domain=srht.bitfehler
+
+[objects]
+#
+# Configure S3-compatible object storage for services. Optional.
+#
+# Minio is recommended as a FOSS solution over AWS: https://min.io
+s3-upstream=127.0.0.1:9123
+s3-access-key=$(pass show dev/srht/s3-access-key)
+s3-secret-key=$(pass show dev/srht/s3-secret-key)
+
+[mail]
+#
+# Outgoing SMTP settings
+smtp-host=mx.bitfehler.net
+smtp-port=587
+smtp-from=srht@bitfehler.net
+#
+# Default: starttls
+# Options: starttls, tls, insecure
+smtp-encryption=starttls
+#
+# Default: plain
+# Options: plain, none
+smtp-auth=plain
+# user / password are required if smtp-auth is plain
+smtp-user=conrad
+smtp-password=$(pass show mail/bitfehler)
+#
+# Application exceptions are emailed to this address
+error-to=err@bitfehler.net
+error-from=srht@bitfehler.net
+#
+# You should generate a PGP key to allow users to authenticate emails received
+# from your services. Use 'gpg --edit-key [key id]' to remove the password from
+# your private key, then export it to a file and set pgp-privkey to the path to
+# that file. pgp-pubkey should be set to the path to your public key, and
+# pgp-key-id should be set to the key ID string. Outgoing emails are signed with
+# this PGP key.
+pgp-privkey=/etc/sr.ht/forge-key.priv.asc
+pgp-pubkey=/etc/sr.ht/forge-key.pub.asc
+pgp-key-id=4268671F07D1A61E
+
+[webhooks]
+#
+# base64-encoded Ed25519 key for signing webhook payloads. This should be
+# consistent between all services.
+#
+# Use the 'srht-keygen webhook' command to generate this key. Put the private
+# key here and distribute the public key to anyone who would want to verify
+# webhook payloads from your service.
+private-key=$(pass show dev/srht/webhooks-private-key)
+#Public key: zsG93UL8DPN0jHg5rpn+gtAeMYqvpVf0iLDwRycRiZ8=
+
+[meta.sr.ht]
+#
+# URL meta.sr.ht is being served at (protocol://domain)
+origin=http://meta.srht.bitfehler:5000
+#
+# Address and port to bind the debug server to
+debug-host=0.0.0.0
+debug-port=5000
+#
+# Configures the SQLAlchemy connection string for the database.
+connection-string=postgresql://postgres@localhost/meta.sr.ht?sslmode=disable
+#
+# Set to "yes" to automatically run migrations on package upgrade.
+migrate-on-upgrade=yes
+#
+# The redis connection used for the webhooks worker
+webhooks=redis://localhost:6379/1
+#
+# If "yes", the user will be sent the stock sourcehut welcome emails after
+# signup (requires cron to be configured properly). These are specific to the
+# sr.ht instance so you probably want to patch these before enabling this.
+welcome-emails=no
+
+#
+# Origin URL for the API
+# By default, the API port is 100 more than the web port
+api-origin=http://127.0.0.1:5100
+
+[meta.sr.ht::api]
+#
+# Maximum complexity of GraphQL queries. The higher this number, the more work
+# that API clients can burden the API backend with. Complexity is equal to the
+# number of discrete fields which would be returned to the user. 200 is a good
+# default.
+max-complexity=200
+
+#
+# The maximum time the API backend will spend processing a single API request.
+#
+# See https://golang.org/pkg/time/#ParseDuration
+max-duration=3s
+
+#
+# Set of IP subnets which are permitted to utilize internal API
+# authentication. This should be limited to the subnets from which your
+# *.sr.ht services are running.
+#
+# Comma-separated, CIDR notation.
+internal-ipnet=127.0.0.0/8,::1/128,192.168.0.0/16,10.0.0.0/8
+
+[meta.sr.ht::settings]
+#
+# If "no", public registration will not be permitted.
+registration=yes
+#
+# Where to redirect new users upon registration
+onboarding-redirect=http://meta.srht.bitfehler:5000
+#
+# How many invites each user is issued upon registration (only applicable if
+# open registration is disabled)
+user-invites=5
+
+[meta.sr.ht::aliases]
+#
+# You can add aliases for the client IDs of commonly used OAuth clients here.
+#
+# Example:
+# git.sr.ht=12345
+
+[meta.sr.ht::billing]
+#
+# "yes" to enable the billing system
+enabled=no
+#
+# Get your keys at https://dashboard.stripe.com/account/apikeys
+stripe-public-key=
+stripe-secret-key=
+
+[meta.sr.ht::auth]
+#
+# What authentication method to use.
+# builtin: use sr.ht builtin authentication
+# unix-pam: use Unix PAM authentication
+auth-method=builtin
+
+[meta.sr.ht::auth::unix-pam]
+#
+# The default email domain to assign to newly created users when they first log
+# in.
+# User's email will be set to <username>@<email-default-domain>
+email-default-domain=example.com
+#
+# The PAM service to use for logging in.
+#service=sshd
+#
+# Whether to automatically create new users when authentication succeeds but the
+# user is not in the database.
+create-users=yes
+#
+# The UNIX group users need to belong to to have access to sourcehut.
+# If set,
+# only users belonging to this group will be able to log into the site.
+# If unset, any user on the system is able to log in if PAM authentication
+# succeeds.
+user-group=
+#
+# The UNIX group users need to belong to to have administrator permissions.
+# If set, administrator status on the site will be synced with group
+# association. Additionally, any user of this group will also be able to access
+# sourcehut even if they are not in the group specified in user-group.
+# If unset, administrator status can be manually assigned from the web
+# interface.
+admin-group=wheel
+
A => templates/etc/sr.ht/forge-key.priv.asc +1 -0
@@ 1,1 @@
+$(pass show dev/srht/forge-key)