repo-mgmt/repo-mgmt
2024-04-20 20:38:56 +02:00

280 lines
8 KiB
Bash
Executable file

#!/usr/bin/env bash
readonly PODMAN_IMAGE="noveria:alpine-repo"
readonly ROOT_DIR="$(dirname $(readlink -f $(which ${0})))"
readonly PODMAN_IMAGE_DIR="${ROOT_DIR}/image"
readonly CONFIG="/etc/repo-mgmt/config.json"
readonly KEYS_DIR="${ROOT_DIR}/keys"
readonly REPO_DIR="${ROOT_DIR}/repo"
readonly BUILD_DIR="${ROOT_DIR}/build"
readonly PKG_LIST_FILE="${ROOT_DIR}/pkgs.list"
readonly NO_FORMAT="\033[0m"
readonly F_BOLD="\033[1m"
readonly F_DIM="\033[2m"
readonly PRIV_KEY_NAME="alpine@noveria.org"
readonly PUB_KEY_NAME="${PRIV_KEY_NAME}.pub"
readonly APKBUILD_GIT_REPO_BASE="https://git.noveria.org/APKBUILD"
##
# Miscellaneous functions
##
function init_local() {
if [[ ! -d "${BUILD_DIR}" || ! -d "${REPO_DIR}" || ! -d "${KEYS_DIR}" || ! -f "${PKG_LIST_FILE}" ]]; then
message_blue_double_colon "Initializing local directories"
if [[ ! -d "${BUILD_DIR}" ]]; then
message_blue_single_arrow "$(basename $BUILD_DIR)"
mkdir -p "${BUILD_DIR}"
fi
if [[ ! -d "${REPO_DIR}" ]]; then
message_blue_single_arrow "$(basename $REPO_DIR)"
mkdir -p "${REPO_DIR}"
fi
if [[ ! -d "${KEYS_DIR}" ]]; then
message_blue_single_arrow "$(basename $KEYS_DIR)"
mkdir -p "${KEYS_DIR}"
fi
if [[ ! -f "${PKG_LIST_FILE}" ]]; then
message_blue_single_arrow "$(basename $PKG_LIST_FILE)"
touch $PKG_LIST_FILE
fi
message_green_double_arrow "DONE"
fi
}
function init_container() {
check_container_image_existance
message_blue_double_colon "Initializing container"
container_run "exit"
message_green_double_arrow "DONE"
}
##
# Messaging functions
##
function message_green_double_arrow() {
local C_LIME="\033[38;5;10m"
echo -e "${F_BOLD}${F_DIM}${C_LIME}==>${NO_FORMAT}${F_BOLD} ${1}...${NO_FORMAT}"
}
function message_blue_double_colon() {
local C_BLUE="\033[38;5;12m"
echo -e "${F_BOLD}${F_DIM}${C_BLUE}::${NO_FORMAT}${F_BOLD} ${1}...${NO_FORMAT}"
}
function message_blue_single_arrow() {
local C_BLUE="\033[38;5;12m"
echo -e " ${F_BOLD}${F_DIM}${C_BLUE}->${NO_FORMAT}${F_BOLD} ${1}...${NO_FORMAT}"
}
function message_question() {
local C_FUCHSIA="\033[38;5;13m"
echo -e "${F_BOLD}${F_DIM}${C_FUCHSIA}==> QUOI:${NO_FORMAT}${F_BOLD} ${1}${NO_FORMAT}"
}
function message_warning() {
local C_YELLOW="\033[38;5;11m"
echo -e "${F_BOLD}${F_DIM}${C_YELLOW}==> WARNING:${NO_FORMAT}${F_BOLD} ${1}${NO_FORMAT}"
}
function message_error() {
local C_RED="\033[38;5;9m"
echo -e "${F_BOLD}${F_DIM}${C_RED}==> ERROR:${NO_FORMAT}${F_BOLD} ${1}${NO_FORMAT}"
exit 1
}
##
# Podman functions
##
function container_run() {
podman run --userns=keep-id:uid=1001,gid=1001 --rm -it -v "${KEYS_DIR}":/home/apkbuild/.abuild -v "${REPO_DIR}":/repo -v "${BUILD_DIR}":/build $PODMAN_IMAGE "$1"
}
function build_container_image() {
if [[ -n $(podman image ls | grep $(echo "$PODMAN_IMAGE" | cut -d: -f2)) ]]; then
podman image rm $(podman image ls | grep $(echo "$PODMAN_IMAGE" | cut -d: -f2) | awk '{print $3}')
fi
podman build -t "$PODMAN_IMAGE" "$PODMAN_IMAGE_DIR"
}
function check_container_image_existance() {
if [[ -z $(podman image ls | grep $(echo "$PODMAN_IMAGE" | cut -d: -f2)) ]]; then
message_error "Image doesn't exist! Please build it first withr '$(basename $0) -b'"
fi
}
##
# Repo functions
##
function refresh_repo() {
check_container_image_existance
message_blue_double_colon "Refreshing DB with all package files"
local VERSION_ID=$(container_run "grep VERSION_ID= /etc/os-release")
container_run "cd /repo/v$(echo $VERSION_ID | cut -d= -f2 | rev | cut -d. -f2- | rev)/noveria/x86_64 && apk index --no-warnings -vU -o APKINDEX.tar.gz *.apk"
}
function sign_repo() {
check_container_image_existance
message_blue_double_colon "Signing package DB"
local VERSION_ID=$(container_run "grep VERSION_ID= /etc/os-release")
container_run "cd /repo/v$(echo $VERSION_ID | cut -d= -f2 | rev | cut -d. -f2- | rev)/noveria/x86_64 && abuild-sign -k /home/apkbuild/.abuild/${PRIV_KEY_NAME} APKINDEX.tar.gz"
}
function delete_pkg_from_repo() {
check_container_image_existance
local VERSION_ID=$(container_run "grep VERSION_ID= /etc/os-release")
if [[ -z $(find $REPO_DIR/v$(echo $VERSION_ID | cut -d= -f2 | rev | cut -d. -f2- | rev)/noveria/x86_64 -name $1*.apk) ]]; then
message_error "Package does not exist: $1!"
fi
message_green_double_arrow "Deleting package: $1"
if [ "$1" = "" ]; then
>&2 message_error "Please provide a package name!"
else
message_blue_single_arrow "Removing package from database"
find $REPO_DIR/v$(echo $VERSION_ID | cut -d= -f2 | rev | cut -d. -f2- | rev)/noveria/x86_64 -name $1*.apk -exec rm -f {} \;
refresh_repo
sign_repo
fi
}
function publish_repo() {
if [[ -z $(jq -r '.remote_user' $CONFIG) || -z $(jq -r '.remote_server' $CONFIG) || -z $(jq -r '.remote_path' $CONFIG) || -z $(jq -r '.ssh_priv_key_path' $CONFIG) ]]; then
message_error "Config is incomplete. Please fill out first!"
fi
local remote_user="$(jq -r '.remote_user' $CONFIG)"
local remote_server="$(jq -r '.remote_server' $CONFIG)"
local remote_path="$(jq -r '.remote_path' $CONFIG)"
local ssh_priv_key_path="$(jq -r '.ssh_priv_key_path' $CONFIG)"
message_blue_double_colon "Publishing files to remote webserver: ${remote_user}@${remote_server}:${remote_path}/"
rsync -a --delete --progress --rsync-path="mkdir -p ${remote_path} && rsync" "${REPO_DIR}/" "${remote_user}@${remote_server}:${remote_path}"
}
##
# Build functions
##
function build_pkgs() {
if [ "${1##*.}" == "list" ]; then
message_blue_single_arrow "Reading packages from pkgs.list"
mapfile -t PKGARRAY <<< "$1"
else
message_blue_single_arrow "Parsing packages from parameters"
IFS=' ' read -r -a PKGARRAY <<< "$@"
fi
for pkg in ${PKGARRAY[@]}; do
local continue=false
if [[ -d "$BUILD_DIR/$pkg" ]]; then
message_warning "Directory exists in ${BUILD_DIR}: $pkg"
while [[ ! "$removepkgdirAns" =~ [Yy] ]]; do
read -p "$(message_question 'Do you want to remove it? (Y/N): ')" removepkgdirAns
if [[ "$removepkgdirAns" =~ [Yy] ]]; then
message_blue_single_arrow "Removing $pkg"
rm -rf "${BUILD_DIR}/$pkg"
break
fi
if [[ "$removepkgdirAns" =~ [Nn] ]]; then
message_warning "Not removing. Skipping $pkg..."
continue=true
break
fi
done
fi
if [[ "$continue" == false ]]; then
if [[ ! -d "$BUILD_DIR/$pkg" ]]; then
container_run "git clone $APKBUILD_GIT_REPO_BASE/${pkg}.git /build/$pkg"
fi
container_run "sudo apk update && sudo apk upgrade && cd /build/$pkg && abuild checksum && abuild -r && find /home/apkbuild/packages/build -name $1*.apk -exec mv {} /build/$1 \;"
message_blue_single_arrow "Copying package to repo"
local VERSION_ID=$(container_run "grep VERSION_ID= /etc/os-release")
rsync -a --delete-before --progress "${BUILD_DIR}/$pkg"/*.apk "${REPO_DIR}/v$(echo $VERSION_ID | cut -d= -f2 | rev | cut -d. -f2- | rev)/noveria/x86_64"
rm -f "${BUILD_DIR}/$pkg"/*.apk
refresh_repo
sign_repo
fi
done
}
###
## SCRIPT START
###
OPT_SHORT="bhd:rspk:"
OPT_LONG="build,help,delete:,refresh,sign,publish,apkbuild:,debug,init"
TEMP=$(getopt -q -o ${OPT_SHORT} --long ${OPT_LONG} -n $(basename ${0}) -- "$@")
if [[ "$?" != 0 ]]; then
usage
message_error "Unknown parameter '$@'!"
fi
eval set -- "${TEMP}"
while true; do
case "${1}" in
-h|--help)
usage
exit 0
;;
-b|--build)
build_container_image
exit 0
;;
-d|--delete)
shift
delete_pkg_from_repo "$1"
;;
-r|--refresh)
refresh_repo
;;
-s|--sign)
sign_repo
;;
-p|--publish)
publish_repo
;;
-k|--apkbuild)
shift
build_pkgs "$1"
;;
--debug)
container_run "bash"
exit 0
;;
--init)
init_local
init_container
exit 0
;;
--)
exit 0
;;
*)
usage
message_error "Unknown parameter '$@'!"
;;
esac
shift
done
###
## SCRIPT END
###