diff --git a/bin/pdm-build b/bin/pdm-build
index 8a0ec65..d9a6539 100755
--- a/bin/pdm-build
+++ b/bin/pdm-build
@@ -4,19 +4,17 @@
quit() {
if [[ $1 == 0 || $FLAGS_debug == $FLAGS_FALSE ]]; then
podman rm -i -f tmp-$epoch 2>&1 > /dev/null
- podman rmi tmp:$epoch 2>&1 > /dev/null
fi
exit $1
}
-libdir=/tank/local/podman/lib
-today=$(date "+%Y-%m-%d-T%H%M")
-epoch=$(date "+%s.%3N")
+epoch=$(date +%s.%3N)
+today=$(date +%Y-%m-%d-T%H%M)
# Handle flags
-source $libdir/shflags
+source shflags
DEFINE_boolean 'squash' false 'squash newly built layers into a single new layer' 's'
-DEFINE_boolean 'debug' false "Don't delete temporary image/container on build fail" 'd'
+DEFINE_boolean 'debug' false "Don't delete temporary container on build fail" 'd'
DEFINE_string 'tag' 'latest' 'Tag (other than date) to assign to the image' 't'
FLAGS_HELP="Usage: $0 [-s] [-d] [-t tag] [directory] [name]
@@ -57,21 +55,21 @@ else
name=$(basename $(pwd))
fi
+# build options
+buildopts=""
if [[ $FLAGS_squash == $FLAGS_TRUE ]]; then
- buildopts="--squash"
-else
- buildopts=""
+ buildopts="$buildopts --squash"
fi
# Main
# build image
-echo "Building container ..."
-podman build -f Containerfile -t tmp:$epoch $buildopts || quit $?
+echo "Building image ..."
+podman build -f Containerfile -t tmp $buildopts || quit $?
# start container
echo "Creating container ..."
-podman create --name tmp-$epoch tmp:$epoch || quit $?
+podman create --name tmp-$epoch tmp || quit $?
podman start tmp-$epoch || quit $?
# Systemdfile is for commands that need systemd to execute
echo "Running build steps that require systemd ..."
diff --git a/bin/pdm-launch b/bin/pdm-launch
index 919f468..fad92fd 100755
--- a/bin/pdm-launch
+++ b/bin/pdm-launch
@@ -1,12 +1,7 @@
#!/bin/bash
-# potential flags: deploy config other than default, overwrite
-
-# Variables
-libdir=/tank/local/podman/lib
-
# Handle flags
-source $libdir/shflags
+source shflags
DEFINE_boolean 'overwrite' false 'Overwrite container if one with same name already exists.' 'o'
DEFINE_boolean 'config' false "Automatically configure container with deploy options stored in image metadata." 'c'
DEFINE_string 'deployopts' 'deployopts' 'Image metadata label from which to get the deploy options.' 'd'
diff --git a/lib/shflags b/bin/shflags
similarity index 100%
rename from lib/shflags
rename to bin/shflags
diff --git a/src/debian/Containerfile b/src/debian/Containerfile
index 8da200f..777a5fa 100644
--- a/src/debian/Containerfile
+++ b/src/debian/Containerfile
@@ -2,6 +2,8 @@ FROM debian:stable
CMD [ "/sbin/init" ]
ENTRYPOINT [ "/sbin/init" ]
+WORKDIR /root/
+
# We can't use timedatectl because systemd isn't available
# during the build process, so we have to set the timezone manually
ENV TZ=US/Central
@@ -12,7 +14,7 @@ RUN rm /etc/localtime && \
# Install packages
RUN apt update -y
RUN apt upgrade -y
-RUN apt install -y init sudo wget nano less man-db
+RUN apt install -y init sudo wget nano less man-db unzip
RUN apt autoremove -y --purge
RUN apt clean -y
diff --git a/src/gitea/Containerfile b/src/gitea/Containerfile
new file mode 100644
index 0000000..9eed7e4
--- /dev/null
+++ b/src/gitea/Containerfile
@@ -0,0 +1,94 @@
+###
+### Build Variables
+###
+FROM localhost/debian:latest
+
+# deploy options
+# -p (port) and -v (volume) both go host:container
+LABEL deployopts="\
+-p 9081:80 \
+-p 9022:22 \
+-v /tank/files/git:/vol/git \
+-v /tank/files/db/gitea:/vol/db"
+# make sure mount directories exist
+RUN mkdir -p /vol/git /vol/db
+
+# version of postgres
+ARG psqlv=11
+# uid that the files owner user should have
+ARG FILESUID=5000
+
+# Container Variables
+# database name and user
+ENV DBUSER=gtadmin
+ENV DBNAME=gitea
+# put environment variables in /etc/environment so we can access them from cron scripts
+RUN echo "DBUSER=$DBUSER" >> /etc/environment && \
+ echo "DBNAME=$DBNAME" >> /etc/environment
+
+###
+### General Setup
+###
+
+# install packages we want
+RUN apt update -y && apt install -y postgresql postgresql-doc git
+
+# create gitea user with file owner UID
+RUN addgroup --gid $FILESUID gitea && \
+ adduser gitea --ingroup gitea --uid $FILESUID --disabled-password --gecos "Gitea Server" --shell /usr/sbin/nologin
+
+# copy our custom scripts
+COPY resources/bin/ /usr/local/bin/
+
+###
+### PostgreSQL ###
+###
+
+# configure PostgreSQL access
+COPY --chown=postgres:postgres resources/pg_hba.conf /etc/postgresql/${psqlv}/main/pg_hba.conf
+
+###
+### Gitea
+###
+
+# dowload gitea
+RUN wget https://dl.gitea.io/gitea/master/gitea-master-linux-amd64 && \
+ mv gitea-master-linux-amd64 /usr/local/bin/gitea && \
+ chmod +x /usr/local/bin/gitea
+
+# make directories gitea needs
+RUN mkdir -p /var/lib/gitea/ && \
+ cd /var/lib/gitea/ && \
+ mkdir custom data log && \
+ chown -R gitea:gitea /var/lib/gitea/ && \
+ chmod -R 750 /var/lib/gitea/
+
+# copy gitea config template
+COPY resources/app.ini.esh /etc/gitea/
+# template config file
+RUN cd /etc/gitea/ && \
+ esh app.ini.esh > app.ini && \
+ rm app.ini.esh && \
+ chmod -R +r /etc/gitea/
+
+COPY resources/gitea.service /etc/systemd/system/
+
+###
+### Crontab
+###
+COPY resources/crontab /root/
+RUN crontab -u gitea /root/crontab
+
+###
+### Systemdfile
+###
+COPY Systemdfile /root/
+RUN chmod +x /root/Systemdfile
+
+###
+### Bugfix
+###
+
+# execute command to workaround bug in cron
+COPY bugfix/cronfix /root/
+RUN chmod +x /root/cronfix && /root/cronfix
diff --git a/src/gitea/Systemdfile b/src/gitea/Systemdfile
new file mode 100644
index 0000000..469fa94
--- /dev/null
+++ b/src/gitea/Systemdfile
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+# fail if any command returns error
+set -e
+set -x
+# wait 5 seconds to make sure all services have finished starting up
+sleep 5
+
+# make database for gitea
+db-make
+
+# enable and start gitea
+systemctl enable gitea
+systemctl start gitea
diff --git a/src/gitea/bugfix/cronfix b/src/gitea/bugfix/cronfix
new file mode 100644
index 0000000..483c9dc
--- /dev/null
+++ b/src/gitea/bugfix/cronfix
@@ -0,0 +1,2 @@
+#!/bin/sh
+sed -i '/session required pam_loginuid.so/c\#session required pam_loginuid.so' /etc/pam.d/cron
diff --git a/src/gitea/resources/app.ini.esh b/src/gitea/resources/app.ini.esh
new file mode 100644
index 0000000..2fca524
--- /dev/null
+++ b/src/gitea/resources/app.ini.esh
@@ -0,0 +1,69 @@
+APP_NAME = Gitea: Git with a cup of tea
+RUN_USER = gitea
+RUN_MODE = prod
+
+[oauth2]
+JWT_SECRET = <%= $(gitea generate secret JWT_SECRET) %>
+
+[security]
+INTERNAL_TOKEN = <%= $(gitea generate secret INTERNAL_TOKEN) %>
+INSTALL_LOCK = true
+SECRET_KEY = <%= $(gitea generate secret SECRET_KEY) %>
+; disable password complexity checks
+PASSWORD_COMPLEXITY = off
+
+[database]
+DB_TYPE = postgres
+HOST = /var/run/postgresql
+NAME = gitea
+USER = gtadmin
+PASSWD =
+SSL_MODE = disable
+CHARSET = utf8
+PATH = /var/lib/gitea/data/gitea.db
+
+[repository]
+ROOT = /vol/git/repos
+
+[server]
+DOMAIN = medusa.alemor.org
+ROOT_URL = http://medusa.casa.alemor.org/git/
+HTTP_PORT = 80
+START_SSH_SERVER = true
+SSH_PORT = 9022
+SSH_LISTEN_PORT = 22
+LFS_START_SERVER = trxue
+LFS_CONTENT_PATH = /vol/git/lfs
+LFS_JWT_SECRET = <%= $(gitea generate secret JWT_SECRET) %>
+OFFLINE_MODE = true
+
+[mailer]
+ENABLED = false
+
+[service]
+REGISTER_EMAIL_CONFIRM = false
+ENABLE_NOTIFY_MAIL = false
+DISABLE_REGISTRATION = true
+ALLOW_ONLY_EXTERNAL_REGISTRATION = false
+ENABLE_CAPTCHA = false
+REQUIRE_SIGNIN_VIEW = false
+DEFAULT_KEEP_EMAIL_PRIVATE = false
+DEFAULT_ALLOW_CREATE_ORGANIZATION = false
+DEFAULT_ENABLE_TIMETRACKING = true
+NO_REPLY_ADDRESS = noreply.localhost
+
+[picture]
+DISABLE_GRAVATAR = true
+ENABLE_FEDERATED_AVATAR = false
+
+[openid]
+ENABLE_OPENID_SIGNIN = true
+ENABLE_OPENID_SIGNUP = false
+
+[session]
+PROVIDER = file
+
+[log]
+MODE = file
+LEVEL = info
+ROOT_PATH = /var/lib/gitea/log
diff --git a/src/gitea/resources/bin/db-dump b/src/gitea/resources/bin/db-dump
new file mode 100755
index 0000000..411a6a8
--- /dev/null
+++ b/src/gitea/resources/bin/db-dump
@@ -0,0 +1,2 @@
+#!/bin/bash
+pg_dump -O -U $DBUSER -d $DBNAME -f $1
diff --git a/src/gitea/resources/bin/db-load b/src/gitea/resources/bin/db-load
new file mode 100755
index 0000000..a070565
--- /dev/null
+++ b/src/gitea/resources/bin/db-load
@@ -0,0 +1,3 @@
+#!/bin/bash
+db-make
+psql -U $DBUSER -d $DBNAME -f $1
diff --git a/src/gitea/resources/bin/db-make b/src/gitea/resources/bin/db-make
new file mode 100755
index 0000000..c34ee09
--- /dev/null
+++ b/src/gitea/resources/bin/db-make
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+cmd() {
+ sudo -u postgres psql -c "$1"
+}
+
+cd /var/lib/postgresql
+cmd "DROP DATABASE IF EXISTS $DBNAME;"
+cmd "DROP USER IF EXISTS $DBUSER;"
+cmd "CREATE USER $DBUSER;"
+cmd "CREATE DATABASE $DBNAME WITH TEMPLATE template0 ENCODING UTF8 LC_COLLATE 'C.UTF-8' LC_CTYPE 'C.UTF-8';"
+cmd "GRANT ALL PRIVILEGES ON DATABASE $DBNAME TO $DBUSER;"
diff --git a/src/gitea/resources/bin/esh b/src/gitea/resources/bin/esh
new file mode 100755
index 0000000..71698a3
--- /dev/null
+++ b/src/gitea/resources/bin/esh
@@ -0,0 +1,366 @@
+#!/bin/sh
+# vim: set ts=4:
+#---help---
+# USAGE:
+# esh [options] [--] [...]
+# esh <-h | -V>
+#
+# Process and evaluate an ESH template.
+#
+# ARGUMENTS:
+# Path of the template file or "-" to read from STDIN.
+# Variable(s) specified as = to pass into the
+# template (the have higher priority than environment
+# variables).
+#
+# OPTIONS:
+# -d Don't evaluate template, just dump a shell script.
+# -o Output file or "-" for STDOUT. Defaults to "-".
+# -s Command name or path of the shell to use for template
+# evaluation. It must not contain spaces.
+# Defaults to "/bin/sh".
+# -h Show this help message and exit.
+# -V Print version and exit.
+#
+# ENVIRONMENT:
+# ESH_AWK Command name of path of the awk program to use.
+# It must not contain spaces. Defaults to "awk".
+# ESH_MAX_DEPTH Maximum include depth. Defaults to 3.
+# ESH_SHELL Same as -s.
+#
+# EXIT STATUS:
+# 0 Clean exit, no error has encountered.
+# 1 Generic error.
+# 10 Invalid usage.
+# 11 ESH syntax error.
+# 12 Include error: file not found.
+# 13 Include error: exceeded max include depth (ESH_MAX_DEPTH).
+#
+# Please report bugs at .
+#---help---
+set -eu
+
+readonly PROGNAME='esh'
+readonly VERSION='0.3.0'
+readonly SCRIPTPATH="$0"
+
+AWK_CONVERTER=$(cat <<'AWK'
+function fail(code, msg) {
+ state = "ERROR"
+ # FIXME: /dev/stderr is not portable
+ printf("%s: %s\n", line_info(), msg) > "/dev/stderr"
+ exit code
+}
+function line_info() {
+ return FILENAME ? (filenames[depth] ":" linenos[depth]) : "(init)" # (init) if inside BEGIN
+}
+# IMPORTANT: This is the only function that should print a newline.
+function puts(str) {
+ print(line_info()) > MAP_FILE
+ print(str)
+}
+function fputs(str) {
+ printf("%s", str)
+}
+function trim(str) {
+ gsub(/^[ \t\r\n]+|[ \t\r\n]+$/, "", str)
+ return str
+}
+function read(len, _str) {
+ if (len == "") {
+ _str = buff
+ buff = ""
+ } else if (len > 0) {
+ _str = substr(buff, 1, len)
+ buff = substr(buff, len + 1, length(buff))
+ }
+ return _str
+}
+function skip(len) {
+ buff = substr(buff, len + 1, length(buff))
+}
+function flush(len, _str) {
+ _str = read(len)
+
+ if (state == "TEXT") {
+ gsub("'", "'\\''", _str)
+ }
+ if (state != "COMMENT") {
+ fputs(_str)
+ }
+}
+function file_exists(filename, _junk) {
+ if ((getline _junk < filename) >= 0) {
+ close(filename)
+ return 1
+ }
+ return 0
+}
+function dirname(path) {
+ return sub(/\/[^\/]+\/*$/, "/", path) ? path : ""
+}
+function include(filename) {
+ if (index(filename, "/") != 1) { # if does not start with "/"
+ filename = dirname(filenames[depth]) filename
+ }
+ if (!file_exists(filename)) {
+ fail(12, "cannot include " filename ": not a file or not readable")
+ }
+ if (depth > MAX_DEPTH) {
+ fail(13, "cannot include " filename ": exceeded maximum depth of " MAX_DEPTH)
+ }
+ buffs[depth] = buff
+ states[depth] = state
+ filenames[depth + 1] = filename
+ depth++
+
+ init()
+ while ((getline buff < filename) > 0) {
+ if (print_nl && state != "COMMENT") {
+ puts("")
+ }
+ process_line()
+ }
+ end_text()
+ close(filename)
+
+ depth--
+ buff = buffs[depth]
+ state = states[depth]
+}
+function init() {
+ buff = ""
+ linenos[depth] = 0
+ print_nl = 0
+ start_text()
+}
+function start_text() {
+ puts("")
+ fputs("printf '%s' '")
+ state = "TEXT"
+}
+function end_text() {
+ if (state != "TEXT") { return }
+ puts("' #< " line_info())
+ state = "UNDEF"
+}
+function process_line() {
+ linenos[depth]++
+
+ while (buff != "") {
+ print_nl = 1
+
+ if (state == "TEXT" && match(buff, /<%/)) {
+ flush(RSTART - 1) # print buff before "<%"
+ skip(2) # skip "<%"
+
+ flag = substr(buff, 1, 1)
+ if (flag != "%") {
+ end_text()
+ }
+ if (flag == "%") { # <%%
+ skip(1)
+ fputs("<%")
+ } else if (flag == "=") { # <%=
+ skip(1)
+ fputs("__print ")
+ state = "TAG"
+ } else if (flag == "+") { # <%+
+ if (!match(buff, /[^%]%>/)) {
+ fail(11, "syntax error: <%+ must be closed on the same line")
+ }
+ filename = trim(substr(buff, 2, match(buff, /.-?%>/) - 1))
+ skip(RSTART)
+ include(filename)
+ state = "TAG"
+ } else if (flag == "#") { # <%#
+ state = "COMMENT"
+ } else {
+ state = "TAG"
+ }
+ } else if (state != "TEXT" && match(buff, /%>/)) {
+ flag = RSTART > 1 ? substr(buff, RSTART - 1, 1) : ""
+
+ if (flag == "%") { # %%>
+ flush(RSTART - 2)
+ skip(1)
+ flush(2)
+ } else if (flag == "-") { # -%>
+ flush(RSTART - 2)
+ skip(3)
+ print_nl = 0
+ } else { # %>
+ flush(RSTART - 1)
+ skip(2)
+ }
+ if (flag != "%") {
+ start_text()
+ }
+ } else {
+ flush()
+ }
+ }
+}
+BEGIN {
+ FS = ""
+ depth = 0
+
+ puts("#!" (SHELL ~ /\// ? SHELL : "/usr/bin/env " SHELL))
+ puts("set -eu")
+ puts("if ( set -o pipefail 2>/dev/null ); then set -o pipefail; fi")
+ puts("__print() { printf '%s' \"$*\"; }")
+
+ split(VARS, _lines, /\n/)
+ for (_i in _lines) {
+ puts(_lines[_i])
+ }
+ init()
+}
+{
+ if (NR == 1) {
+ filenames[0] = FILENAME # this var is not defined in BEGIN so we must do it here
+ }
+ buff = $0
+ process_line()
+
+ if (print_nl && state != "COMMENT") {
+ puts("")
+ }
+}
+END {
+ end_text()
+}
+AWK
+)
+AWK_ERR_FILTER=$(cat <<'AWK'
+function line_info(lno, _line, _i) {
+ while ((getline _line < MAPFILE) > 0 && _i++ < lno) { }
+ close(MAPFILE)
+ return _line
+}
+{
+ if (match($0, "^" SRCFILE ":( line)? ?[0-9]+:") && match(substr($0, 1, RLENGTH), /[0-9]+:$/)) {
+ lno = substr($0, RSTART, RLENGTH - 1) + 0
+ msg = substr($0, RSTART + RLENGTH + 1) # v-- some shells duplicate filename
+ msg = index(msg, SRCFILE ":") == 1 ? substr(msg, length(SRCFILE) + 3) : msg
+ print(line_info(lno) ": " msg)
+ } else if ($0 != "") {
+ print($0)
+ }
+}
+AWK
+)
+readonly AWK_CONVERTER AWK_ERR_FILTER
+
+print_help() {
+ sed -En '/^#---help---/,/^#---help---/p' "$SCRIPTPATH" | sed -E 's/^# ?//; 1d;$d;'
+}
+
+filter_shell_stderr() {
+ $ESH_AWK \
+ -v SRCFILE="$1" \
+ -v MAPFILE="$2" \
+ -- "$AWK_ERR_FILTER"
+}
+
+evaluate() {
+ local srcfile="$1"
+ local mapfile="$2"
+
+ # This FD redirection magic is for swapping stdout/stderr back and forth.
+ exec 3>&1
+ { set +e; $ESH_SHELL "$srcfile" 2>&1 1>&3; echo $? >>"$mapfile"; } \
+ | filter_shell_stderr "$srcfile" "$mapfile" >&2
+ exec 3>&-
+
+ return $(tail -n 1 "$mapfile")
+}
+
+convert() {
+ local input="$1"
+ local vars="$2"
+ local map_file="${3:-"/dev/null"}"
+
+ $ESH_AWK \
+ -v MAX_DEPTH="$ESH_MAX_DEPTH" \
+ -v SHELL="$ESH_SHELL" \
+ -v MAP_FILE="$map_file" \
+ -v VARS="$vars" \
+ -- "$AWK_CONVERTER" "$input"
+}
+
+process() {
+ local input="$1"
+ local vars="$2"
+ local evaluate="${3:-yes}"
+ local ret=0 tmpfile mapfile
+
+ if [ "$evaluate" = yes ]; then
+ tmpfile=$(mktemp)
+ mapfile=$(mktemp)
+
+ convert "$input" "$vars" "$mapfile" > "$tmpfile" || ret=$?
+ test $ret -ne 0 || evaluate "$tmpfile" "$mapfile" || ret=$?
+
+ rm -f "$tmpfile" "$mapfile"
+ else
+ convert "$input" "$vars" || ret=$?
+ fi
+ return $ret
+}
+
+: ${ESH_AWK:="awk"}
+: ${ESH_MAX_DEPTH:=3}
+: ${ESH_SHELL:="/bin/sh"}
+EVALUATE='yes'
+OUTPUT=''
+
+while getopts ':dho:s:V' OPT; do
+ case "$OPT" in
+ d) EVALUATE=no;;
+ h) print_help; exit 0;;
+ o) OUTPUT="$OPTARG";;
+ s) ESH_SHELL="$OPTARG";;
+ V) echo "$PROGNAME $VERSION"; exit 0;;
+ '?') echo "$PROGNAME: unknown option: -$OPTARG" >&2; exit 10;;
+ esac
+done
+shift $(( OPTIND - 1 ))
+
+if [ $# -eq 0 ]; then
+ printf "$PROGNAME: %s\n\n" 'missing argument ' >&2
+ print_help >&2
+ exit 10
+fi
+
+INPUT="$1"; shift
+[ "$INPUT" != '-' ] || INPUT=''
+if [ "$INPUT" ] && ! [ -f "$INPUT" -a -r "$INPUT" ]; then
+ echo "$PROGNAME: can't read $INPUT: not a file or not readable" >&2; exit 10
+fi
+
+# Validate arguments.
+for arg in "$@"; do
+ case "$arg" in
+ *=*) ;;
+ *) echo "$PROGNAME: illegal argument: $arg" >&2; exit 10;;
+ esac
+done
+
+# Format variables into shell variable assignments.
+vars=''; for item in "$@"; do
+ vars="$vars\n${item%%=*}='$(
+ printf %s "${item#*=}" | $ESH_AWK "{ gsub(/'/, \"'\\\\\\\''\"); print }"
+ )'"
+done
+
+export ESH="$0"
+
+if [ "${OUTPUT#-}" ]; then
+ tmpfile="$(mktemp)"
+ trap "rm -f '$tmpfile'" EXIT HUP INT TERM
+ process "$INPUT" "$vars" "$EVALUATE" > "$tmpfile"
+ mv "$tmpfile" "$OUTPUT"
+else
+ process "$INPUT" "$vars" "$EVALUATE"
+fi
diff --git a/src/gitea/resources/bin/maint b/src/gitea/resources/bin/maint
new file mode 100755
index 0000000..85f6f89
--- /dev/null
+++ b/src/gitea/resources/bin/maint
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+# load environment variables
+source /etc/environment
+
+hour=$(date +%H)
+day=$(date +%d)
+month=$(date +%m)
+year=$(date +%Y)
+
+dumpdir=/vol/db
+errlog=error/$year-$month-$day-T$hour.log
+
+mkdir -p $dumpdir/error
+cd $dumpdir
+
+if [[ $# -lt 2 ]]; then
+ echo "Error: called with missing hour and/or day parameter. Script exited without running." | tee $errlog
+ exit 1
+fi
+
+if [[ $hour == $1 ]]; then
+ nc-occ maintenance:mode --on
+fi
+
+db-dump $DBNAME-hourly-$hour.sql 2>> $errlog
+
+if [[ $hour == $1 ]]; then
+ nc-occ maintenance:mode --off
+ mv $DBNAME-hourly-$hour.sql $DBNAME-daily-$day.sql 2>> $errlog
+
+ if [[ $day == $2 ]]; then
+ mv $DBNAME-daily-$day.sql $DBNAME-$year-$month-$day.sql 2>> $errlog
+ fi
+fi
+
+# If error log is size 0, erase it because I don't like seeing it
+if [[ ! -s $errlog ]]; then
+ rm $errlog
+ rmdir --ignore-fail-on-non-empty error
+fi
diff --git a/src/gitea/resources/crontab b/src/gitea/resources/crontab
new file mode 100644
index 0000000..38142c9
--- /dev/null
+++ b/src/gitea/resources/crontab
@@ -0,0 +1,5 @@
+PATH=/usr/local/bin:/bin:/usr/bin
+# m h dom mon dow command
+
+# Dump database every hour
+23 * * * * maint 01 01
diff --git a/src/gitea/resources/gitea.service b/src/gitea/resources/gitea.service
new file mode 100644
index 0000000..57f11d0
--- /dev/null
+++ b/src/gitea/resources/gitea.service
@@ -0,0 +1,33 @@
+[Unit]
+Description=Gitea (Git with a cup of tea)
+After=syslog.target
+After=network.target
+Requires=postgresql.service
+
+[Service]
+# Modify these two values and uncomment them if you have
+# repos with lots of files and get an HTTP error 500 because
+# of that
+###
+#LimitMEMLOCK=infinity
+#LimitNOFILE=65535
+RestartSec=2s
+Type=simple
+User=gitea
+Group=gitea
+WorkingDirectory=/var/lib/gitea/
+# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock file
+# (manually creating /run/gitea doesn't work, because it would not persist across reboots)
+#RuntimeDirectory=gitea
+ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
+Restart=always
+Environment=USER=gitea HOME=/home/gitea GITEA_WORK_DIR=/var/lib/gitea
+# If you want to bind Gitea to a port below 1024, uncomment
+# the two values below, or use socket activation to pass Gitea its ports as above
+###
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE
+AmbientCapabilities=CAP_NET_BIND_SERVICE
+###
+
+[Install]
+WantedBy=multi-user.target
diff --git a/src/gitea/resources/pg_hba.conf b/src/gitea/resources/pg_hba.conf
new file mode 100644
index 0000000..bf55f34
--- /dev/null
+++ b/src/gitea/resources/pg_hba.conf
@@ -0,0 +1 @@
+local all all trust
diff --git a/src/nextcloud/Containerfile b/src/nextcloud/Containerfile
index 8c8e2f4..4085abd 100644
--- a/src/nextcloud/Containerfile
+++ b/src/nextcloud/Containerfile
@@ -5,36 +5,40 @@ FROM localhost/debian
# deploy options
# -p (port) and -v (volume) both go host:container
-LABEL deployopts="-p 4380:80 \
+LABEL deployopts="\
+-p 9080:80 \
-v /tank/files/user/mar:/vol/files/mar/files \
-v /tank/files/db/nextcloud:/vol/db"
-# make directories that we will be mounting into
+# make sure mount directories exist
RUN mkdir -p /vol/files/mar/files /vol/db
-# php and postgres versions. will depend on version of debian we are running
+# Build Variables
+# versions of php and postgres
ARG phpv=7.3
ARG psqlv=11
+# uid that the files owner user should have
+ARG FILESUID=5000
-# database variables
+# Environment Variables
+# database name and user
ENV DBUSER=ncadmin
ENV DBNAME=nextcloud
+# put environment variables in /etc/environment so we can access them from cron scripts
+RUN echo "DBUSER=$DBUSER" >> /etc/environment && \
+ echo "DBNAME=$DBNAME" >> /etc/environment
###
### General Setup
###
# install packages we want
-RUN apt update -y && apt install -y systemd sudo wget apache2 php-fpm \
- php-gd php-zip php-pgsql php-curl php-mbstring php-intl php-imagick \
- php-xml php-json redis php-redis postgresql postgresql-doc \
- unzip php-ldap
-
-# this is a bug workaround b/c testing is currently between versions of php. should be removed ideally
-RUN update-alternatives --set php /usr/bin/php7.3
+RUN apt update -y && apt install -y apache2 php-fpm php-gd php-zip \
+ php-pgsql php-curl php-mbstring php-intl php-imagick php-xml \
+ php-json redis php-redis postgresql postgresql-doc php-ldap
# change www-data's UID to the file owner UID
-RUN usermod --uid 5000 www-data && \
- groupmod --gid 5000 www-data && \
+RUN usermod --uid $FILESUID www-data && \
+ groupmod --gid $FILESUID www-data && \
chown -R www-data:www-data /var/www /vol
# copy our custom scripts
@@ -99,9 +103,8 @@ COPY --chown=www-data:www-data resources/my.config.php nextcloud/config/
### Crontab
###
COPY resources/crontab /root/
-# the sed command is needed to workaround a bug in cron
-RUN sed -i '/session required pam_loginuid.so/c\#session required pam_loginuid.so' /etc/pam.d/cron && \
- crontab -u www-data /root/crontab
+# crontab for www-data
+RUN crontab -u www-data /root/crontab
###
### Systemdfile
@@ -115,3 +118,7 @@ RUN chmod +x /root/Systemdfile
# push the fixed systemd file for redis
COPY bugfix/redis.service /etc/systemd/system/redis.service
+
+# execute command to workaround bug in cron
+COPY bugfix/cronfix /root/
+RUN chmod +x /root/cronfix && /root/cronfix
diff --git a/src/nextcloud/bugfix/cronfix b/src/nextcloud/bugfix/cronfix
new file mode 100644
index 0000000..483c9dc
--- /dev/null
+++ b/src/nextcloud/bugfix/cronfix
@@ -0,0 +1,2 @@
+#!/bin/sh
+sed -i '/session required pam_loginuid.so/c\#session required pam_loginuid.so' /etc/pam.d/cron
diff --git a/src/nextcloud/resources/bin/maint b/src/nextcloud/resources/bin/maint
index 031582d..85f6f89 100755
--- a/src/nextcloud/resources/bin/maint
+++ b/src/nextcloud/resources/bin/maint
@@ -1,17 +1,21 @@
#!/bin/bash
+# load environment variables
+source /etc/environment
+
hour=$(date +%H)
day=$(date +%d)
month=$(date +%m)
year=$(date +%Y)
dumpdir=/vol/db
+errlog=error/$year-$month-$day-T$hour.log
-mkdir -p $dumpdir
+mkdir -p $dumpdir/error
cd $dumpdir
if [[ $# -lt 2 ]]; then
- echo "[$year-$month-$day] Error: called with missing hour and/or day parameter. Script exited without running." | tee error.log
+ echo "Error: called with missing hour and/or day parameter. Script exited without running." | tee $errlog
exit 1
fi
@@ -19,18 +23,19 @@ if [[ $hour == $1 ]]; then
nc-occ maintenance:mode --on
fi
-db-dump $DBNAME-hourly-$hour.sql 2>> error.log
+db-dump $DBNAME-hourly-$hour.sql 2>> $errlog
if [[ $hour == $1 ]]; then
nc-occ maintenance:mode --off
- mv $DBNAME-hourly-$hour.sql $DBNAME-daily-$day.sql 2>> error.log
+ mv $DBNAME-hourly-$hour.sql $DBNAME-daily-$day.sql 2>> $errlog
if [[ $day == $2 ]]; then
- mv $DBNAME-daily-$day.sql $DBNAME-$year-$month-$day.sql 2>> error.log
+ mv $DBNAME-daily-$day.sql $DBNAME-$year-$month-$day.sql 2>> $errlog
fi
fi
-# If error.log is size 0, erase it because I don't like seeing it
-if [[ ! -s ./error.log ]]; then
- rm error.log
+# If error log is size 0, erase it because I don't like seeing it
+if [[ ! -s $errlog ]]; then
+ rm $errlog
+ rmdir --ignore-fail-on-non-empty error
fi
diff --git a/src/nextcloud/resources/crontab b/src/nextcloud/resources/crontab
index 37704db..7c3641a 100644
--- a/src/nextcloud/resources/crontab
+++ b/src/nextcloud/resources/crontab
@@ -1,8 +1,11 @@
PATH=/usr/local/bin:/bin:/usr/bin
# m h dom mon dow command
+
# Run Nextcloud cron tasks every 5 minutes
*/5 * * * * php -f /var/www/html/nextcloud/cron.php
-# Dump database every hour
-10 * * * * maint 01 01
+
# Scan for new files every 15 minutes
*/15 * * * * nc-occ files:scan --all
+
+# Dump database every hour
+23 * * * * maint 01 01