commit 2db8bc87031576ecd884cdd601c23222f5f97327 Author: manuel Date: Sun Sep 28 12:27:18 2025 +0800 feat: joj container scripts diff --git a/admin/scripts/joj-container-config b/admin/scripts/joj-container-config new file mode 100755 index 0000000..7688092 --- /dev/null +++ b/admin/scripts/joj-container-config @@ -0,0 +1,58 @@ +#!/bin/bash + +COURSE=$(hostname) +GITEASSH="ssh://git@focs.ji.sjtu.edu.cn:2222" + +# when container starts network takes some time to come up +net_wait() { + + echo -n "Waiting for network" + while ! wget -q --spider https://focs.ji.sjtu.edu.cn; do + echo -n . + sleep 1 + done + echo +} + +# install config files from course-joj repo +import_config() { + + echo "Importing $COURSE JOJ configuration" + + cd /root + git clone -b master $GITEASSH/$COURSE/$COURSE-joj.git + + cd $COURSE-joj + rsync -r etc/ /etc + + . /etc/joj-container-config.conf + +} + +services_restart() { + + echo "Restarting services" + + for i in $SERVICES; do + systemctl restart $i + done + +} + +software_install() { + + echo "Installing $COURSE software" + + apt-get update && apt-get upgrade -y + apt-get install -y $PACKAGES && apt-get clean + +} + +net_wait + +import_config +services_restart + +software_install + +exit 0 diff --git a/admin/scripts/joj-container-deploy b/admin/scripts/joj-container-deploy new file mode 100755 index 0000000..78d2cca --- /dev/null +++ b/admin/scripts/joj-container-deploy @@ -0,0 +1,102 @@ +#!/bin/bash + +# exit on error +echoerr() { ERR=$1; shift; echo -e "Error: $@" 1>&2; exit $ERR; } + +# exit if no course provided +[ -z $1 ] && echoerr 255 "Usage: $0 coursecode" + + +COURSE=$1 +COURSECFG=$HOME/$COURSE +GITEAAPI="https://focs.ji.sjtu.edu.cn/git/api/v1" + +# dir for course config/setup +[ -d $COURSECFG ] || mkdir $COURSECFG + + +fs_create() { + + echo "Creating FS" + + sudo zfs create -o mountpoint=/home/ja/.local/share/lxc/$COURSE joj/$COURSE + sudo chown 100000:ja $HOME/.local/share/lxc/$COURSE + sudo chmod g+w $HOME/.local/share/lxc/$COURSE + +} + +# generate token (write user: ssh key, read org: action runner token) +# create course-joj action secret for teapot +gitea_config() { + + if [ ! -e $COURSECFG/teapot.env ]; then + + echo "Configuring Gitea access" + + read -s -p "Input bot-$COURSE passwd: " BOTPWD + GTOKEN=$(curl -s -X POST -u "bot-$COURSE:$BOTPWD" "$GITEAAPI/users/bot-$COURSE/tokens" -H "Content-Type: application/json" -d '{"name":"teapot","scopes":["write:issue", "read:organization", "write:repository", "write:user"]}' | jq -r '.sha1') + echo -e "GITEA_ORG_NAME=$COURSE\nGITEA_ACCESS_TOKEN=$GTOKEN" > $COURSECFG/teapot.env + + fi + + . $COURSECFG/teapot.env + + curl -s -X PUT "$GITEAAPI/repos/$COURSE/$COURSE-joj/actions/secrets/TEAPOT_GITEA_TOKEN" -H "Content-Type: application/json" -d "{\"data\":\"$GITEA_ACCESS_TOKEN\"}" -H "Authorization: Bearer $GITEA_ACCESS_TOKEN" + +} + +ssh_config() { + + [ -d $COURSECFG/ssh ] || mkdir $COURSECFG/ssh + + if [ ! -e "$COURSECFG/ssh/id_ed25519" ]; then + echo "Generating SSH key" + ssh-keygen -t ed25519 -N "" -f $COURSECFG/ssh/id_ed25519 + + PUBKEY=$(cat $COURSECFG/ssh/id_ed25519.pub) + curl -s -X POST "$GITEAAPI/user/keys" -H "Authorization: Bearer $GITEA_ACCESS_TOKEN" -H "Content-Type: application/json" -d "{\"key\":\"$PUBKEY\", \"title\":\"tt@$COURSE\"}" + fi + +} + +ar_preconfig() { + + echo "Getting an act_runner token" + + curl -X GET -s "$GITEAAPI/orgs/$COURSE/actions/runners/registration-token?token=$GITEA_ACCESS_TOKEN" | jq -r '.token' > $COURSECFG/act_runner.token + +} + + +container_create() { + + echo "Creating container $COURSE" + + lxc-stop jtc 2>/dev/null + +# lxc-copy -n jtc -N $COURSE --logfile $COURSE.log --logpriority DEBUG + lxc-copy -n jtc -N $COURSE + +} + +container_config() { + lxc-start -n $COURSE + lxc-attach -n $COURSE --clear-env -v HOME=/root -v TERM=tmux /usr/local/bin/joj-container-config +} + + +# +# deploy +# + +fs_create + +gitea_config +ssh_config +ar_preconfig + +container_create +container_config + +echo done + diff --git a/admin/scripts/joj-container-preconfig b/admin/scripts/joj-container-preconfig new file mode 100755 index 0000000..de21dcd --- /dev/null +++ b/admin/scripts/joj-container-preconfig @@ -0,0 +1,47 @@ +#!/bin/bash + +COURSE=${LXC_NAME} +COURSECFG=$HOME/$COURSE + +# import ssh key to both tt and root users +import_sshkey() { + + cp $COURSECFG/ssh/id_ed25519* $LXC_ROOTFS_MOUNT/home/tt/.ssh/ + + chmod 600 $LXC_ROOTFS_MOUNT/home/tt/.ssh/id_ed25519 + chmod 640 $LXC_ROOTFS_MOUNT/home/tt/.ssh/id_ed25519.pub + chown 1000:1000 $LXC_ROOTFS_MOUNT/home/tt/.ssh/id_ed25519* + + cp $COURSECFG/ssh/id_ed25519* $LXC_ROOTFS_MOUNT/root/.ssh/ +} + +# +# config to be set before 1st boot +# + +# act_runner config +ar_config() { + + ARTOKEN=$(cat $COURSECFG/act_runner.token) + sed -i "s/token [^ ]*/token $ARTOKEN/g" $LXC_ROOTFS_MOUNT/etc/systemd/system/act_runner.service + sed -i "s/ARCOURSE/AR-$COURSE/g" $LXC_ROOTFS_MOUNT/etc/systemd/system/act_runner.service + +} + +git_config() { + sed -i "s/COURSE/$COURSE/" $LXC_ROOTFS_MOUNT/home/tt/.gitconfig + echo "Git setup completed" +} + +grafana_config() { + sed -i "s/JOBNAME/${LXC_NAME}/" $LXC_ROOTFS_MOUNT/etc/promtail/config.yml + echo "Grafana setup completed" +} + +import_sshkey + +ar_config +git_config +grafana_config + +exit 0