Init
This commit is contained in:
commit
08f693c910
8
Dockerfile
Normal file
8
Dockerfile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
FROM nginx:mainline-bookworm
|
||||||
|
|
||||||
|
RUN apt update && apt install -y dpkg-dev cron
|
||||||
|
|
||||||
|
COPY aux /aux
|
||||||
|
COPY init/* /docker-entrypoint.d/
|
||||||
|
COPY other/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
28
README.md
Normal file
28
README.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# supercow
|
||||||
|
|
||||||
|
The [apt repo](https://wiki.debian.org/DebianRepository) server with [super-cow powers](https://unix.stackexchange.com/questions/92185/whats-the-story-behind-super-cow-powers)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Periodic Auto-Signing
|
||||||
|
- Periodic Auto-Indexing
|
||||||
|
- Hosted through [nginx](https://nginx.org/)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
Run `docker run -ti --name supercow -v ./signing.key:/private/signing.key:ro -v ./pkgs:/private/pkgs:ro -e REPO_DOMAIN=apt.example.com supercow` and enjoy your apt repository.
|
||||||
|
|
||||||
|
### Environment variables
|
||||||
|
|
||||||
|
- `REPO_DOMAIN`: the base domain of your repository, e.g. pkg.maride.cc
|
||||||
|
- `REPO_DESCRIPTION`: repository description, e.g. "maride's finest packages"
|
||||||
|
|
||||||
|
### Volumes & Files
|
||||||
|
|
||||||
|
- `/private/signing.key`: supercow expects an already generated [GPG key](https://gnupg.org/); see `gengpg.sh` for a quickstart
|
||||||
|
- `/private/pkgs`: contains the .deb files to be hosted.
|
||||||
|
|
||||||
|
No file will be modified by supercow; the readonly bind option (`:ro`) may be used.
|
||||||
|
|
9
aux/Release.template
Normal file
9
aux/Release.template
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Origin: <<DOMAIN>>
|
||||||
|
Label: <<DOMAIN>>
|
||||||
|
Suite: stable
|
||||||
|
Codename: stable
|
||||||
|
Version: 1.0
|
||||||
|
Architectures: amd64
|
||||||
|
Components: main
|
||||||
|
Description: <<DESCRIPTION>>
|
||||||
|
Date: <<DATE>>
|
54
aux/build.sh
Executable file
54
aux/build.sh
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash -ex
|
||||||
|
|
||||||
|
# Check if cleanup happened before
|
||||||
|
if [ -d "/staging" ]; then
|
||||||
|
echo "/staging exists! Please check the logs to see why the cleanup process didn't run" 1>&2
|
||||||
|
# ... however, we can fix that ...
|
||||||
|
echo -n "Running cleanup now... "
|
||||||
|
rm -rf /staging && echo "OK, proceeding." || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create temporary folder structure
|
||||||
|
mkdir -p /staging
|
||||||
|
cd /staging
|
||||||
|
mkdir -p pool/main dists/stable/main/binary-amd64
|
||||||
|
cp /private/pkgs/*.deb pool/main/.
|
||||||
|
|
||||||
|
# Create Package indexes
|
||||||
|
dpkg-scanpackages --arch amd64 pool/ > dists/stable/main/binary-amd64/Packages
|
||||||
|
cat dists/stable/main/binary-amd64/Packages | gzip -9 > dists/stable/main/binary-amd64/Packages.gz
|
||||||
|
|
||||||
|
# Create Release file
|
||||||
|
# taken from https://earthly.dev/blog/creating-and-hosting-your-own-deb-packages-and-apt-repo/
|
||||||
|
do_hash() {
|
||||||
|
HASH_NAME=$1
|
||||||
|
HASH_CMD=$2
|
||||||
|
echo "${HASH_NAME}:"
|
||||||
|
for f in $(find -type f); do
|
||||||
|
f=$(echo $f | cut -c3-) # remove ./ prefix
|
||||||
|
if [ "$f" = "Release" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo " $(${HASH_CMD} ${f} | cut -d" " -f1) $(wc -c $f)"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
/aux/generate-release.sh "$REPO_DOMAIN" "$REPO_DESCRIPTION" > dists/stable/Release
|
||||||
|
do_hash "MD5Sum" "md5sum" >> dists/stable/Release
|
||||||
|
do_hash "SHA1" "sha1sum" >> dists/stable/Release
|
||||||
|
do_hash "SHA256" "sha256sum" >> dists/stable/Release
|
||||||
|
|
||||||
|
cat dists/stable/Release
|
||||||
|
|
||||||
|
# Sign Release file
|
||||||
|
cat dists/stable/Release | gpg --default-key $(gpg --list-keys | head -n 4 | tail -n 1) --armor --detach-sign --sign --output dists/stable/Release.gpg
|
||||||
|
cat dists/stable/Release | gpg --default-key $(gpg --list-keys | head -n 4 | tail -n 1) --armor --clearsign --sign --output dists/stable/InRelease
|
||||||
|
|
||||||
|
# Make pubkey accessible
|
||||||
|
gpg --armor --export > signing.pub
|
||||||
|
|
||||||
|
# Move files and clean up staging directory
|
||||||
|
rm -rf /usr/share/nginx/html/*
|
||||||
|
mv /staging/* /usr/share/nginx/html/.
|
||||||
|
rm -rf /staging
|
||||||
|
|
18
aux/generate-release.sh
Executable file
18
aux/generate-release.sh
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
# release.sh: prints out a Release file header
|
||||||
|
# Arguments: release.sh <base domain> <description>
|
||||||
|
|
||||||
|
if [ "$#" -ne 2 ]; then
|
||||||
|
echo "$0: <base domain> <description>" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DOMAIN="$1"
|
||||||
|
DESCRIPTION="$2"
|
||||||
|
DATE="$(date --utc --rfc-email)"
|
||||||
|
|
||||||
|
cat /aux/Release.template | \
|
||||||
|
sed "s/<<DOMAIN>>/$DOMAIN/g" | \
|
||||||
|
sed "s/<<DESCRIPTION>>/$DESCRIPTION/g" | \
|
||||||
|
sed "s/<<DATE>>/$DATE/g" | \
|
||||||
|
cat
|
32
gengpg.sh
Executable file
32
gengpg.sh
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
# Mostly inspired from https://earthly.dev/blog/creating-and-hosting-your-own-deb-packages-and-apt-repo/#pgp-gpg-and-gnupgp
|
||||||
|
|
||||||
|
if [ -f "signing.key" ]; then
|
||||||
|
echo "signing.key exists, refuse to override" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create temporary directory
|
||||||
|
GNUPGHOME="$(mktemp --directory /tmp/pgpkeys-XXXXXX)"
|
||||||
|
export GNUPGHOME
|
||||||
|
echo "Creating a temporary keyring at $GNUPGHOME..."
|
||||||
|
chmod 700 "$GNUPGHOME"
|
||||||
|
|
||||||
|
# Create the request
|
||||||
|
echo "Key-Type: RSA
|
||||||
|
Key-Length: 4096
|
||||||
|
Name-Real: supercow signing key
|
||||||
|
Name-Email: supercow@example.com
|
||||||
|
Expire-Date: 0
|
||||||
|
%no-ask-passphrase
|
||||||
|
%no-protection
|
||||||
|
%commit" > "$GNUPGHOME/batchrequest"
|
||||||
|
|
||||||
|
# Execute request
|
||||||
|
gpg --no-tty --batch --gen-key "$GNUPGHOME/batchrequest"
|
||||||
|
gpg --armor --export-secret-keys > signing.key
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
echo "Removing temporary keyring at $GNUPGHOME..."
|
||||||
|
rm -rf "$GNUPGHOME"
|
||||||
|
|
10
init/10-cron.sh
Executable file
10
init/10-cron.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
# Run the pull script regularly
|
||||||
|
target="/aux/build.sh"
|
||||||
|
entry="*/10 * * * * $target"
|
||||||
|
grep "$target" /etc/cron.d/supercow || echo "$entry" >> /etc/cron.d/supercow
|
||||||
|
|
||||||
|
# start cron daemon (goes into background)
|
||||||
|
cron
|
||||||
|
|
4
init/10-gpg.sh
Executable file
4
init/10-gpg.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
gpg --import /private/signing.key
|
||||||
|
|
4
init/99-build.sh
Executable file
4
init/99-build.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
/aux/build.sh
|
||||||
|
exit $?
|
12
other/nginx.conf
Normal file
12
other/nginx.conf
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
autoindex on;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user