#!/usr/bin/env bash SCRIPTNAME="$( basename -- "$0" )" # check : current user is root? check_root () { [[ $EUID -eq 0 ]] } # ok if root ensure_root () { if ! check_root; then echo "ERROR : This script must be run as root" exit 1 else return 0 fi } # ok if non root ensure_not_root () { if check_root; then echo "ERROR : This script must not be *run* as root" exit 1 else return 0 fi } # ok if running script from current directory ensure_pwd_is_scriptdir () { if [[ $PWD != $ABSDIR ]]; then echo "Please cd in the script directory before running it :" echo "cd ${ABSDIR}" echo "./${SCRIPTNAME}" exit 1 fi } # ok if current user is the same (name) as script directory ensure_scriptdir_equals_user () { if [[ "$USER" != "${ABSDIR##*/}" ]]; then exit 1 fi } # make sure systemd directory exists ensure_systemd_as_user_dir_exists () { [[ -d ${HOME}/.config/systemd/user/ ]] || mkdir -p ${HOME}/.config/systemd/user/ } # sed or die trying sed_in_place () { ${podman_unshare} grep -q "${1}" "${3}" if [ $? -eq 0 ]; then ${podman_unshare} sed -i -e "s|${1}|${2}|g" ${3} else echo "Pattern ${1} not found in file ${3}, exiting." exit 1 fi } # podman_unshare prefixed podman_unshare_sed_in_place () { podman_unshare='podman unshare' sed_in_place "${1}" "${2}" "${3}" } # sed or die trying sed_in_place_multiline () { ${podman_unshare} grep -P -z -q "${1}" "${3}" if [ $? -eq 0 ]; then ${podman_unshare} sed -z -i -e "s|${1}|${2}|g" ${3} else echo "Pattern ${1} not found in file ${3}, exiting." exit 1 fi } # podman_unshare prefixed podman_unshare_sed_in_place_multiline () { podman_unshare='podman unshare' sed_in_place_multiline "${1}" "${2}" "${3}" } # check: systemd unit exists check_systemd_unit_exists () { systemctl --user cat -- ${1} &> /dev/null } # check if variable is empty check_variable_is_empty () { [[ -z ${!1} ]] } # ensure variable is defined ensure_variable_is_defined () { if check_variable_is_empty ${1}; then echo "Error : variable ${1} must be defined" exit 1 fi } # ensure all variables are defined ensure_variables_are_defined () { for i in ${1}; do ensure_variable_is_defined $i done } # check if IPv4 syntax is valid check_valid_ipv4() { re='^((1?[0-9]{1,2}|2([0-4][0-9]|5[0-5]))\.){3}' re+='(1?[0-9]{1,2}|2([0-4][0-9]|5[0-5]))$' if [[ ${1} =~ ${re} ]]; then return 0 else echo "ERROR : ${1} is not a valid IPv4 address" exit 1 fi } # Get default interface IPv4 address # and return result in variable passed as argument get_default_iface_ipv4() { # Call this function with the name of the variable # you want to store the result in : # get_default_iface_ipv4 myipv4 # See https://www.linuxjournal.com/content/return-values-bash-functions local __resultvar=${1} local __default_iface=$(awk '$2 == 00000000 { print $1 }' /proc/net/route) local __default_iface_ipv4=$(ip addr show dev "${__default_iface}" | awk '$1 == "inet" { sub("/.*", "", $2); print $2 }') if check_valid_ipv4 ${__default_iface_ipv4}; then eval $__resultvar="'${__default_iface_ipv4}'" return 0 else exit 1 fi } # ok if systemd unit file {1} exists ensure_systemd_unit_exists () { if ! check_systemd_unit_exists ${1}; then echo "ERROR : systemd unit ${1} does not exists!" exit 1 else return 0 fi } # ok if systemd unit file {1} does not exists ensure_systemd_unit_not_exists () { if check_systemd_unit_exists ${1}; then echo "ERROR : systemd unit ${1} exists!" exit 1 else return 0 fi } # check: systemd unit running check_systemd_unit_running () { systemctl --user is-active --quiet service ${1} } # ok if systemd unit {1} is running ensure_systemd_unit_running () { if ! check_systemd_unit_running ${1}; then echo "ERROR : systemd unit ${1} is not running!" exit 1 else return 0 fi } # ok if systemd unit {1} is NOT running ensure_systemd_unit_not_running () { if check_systemd_unit_running ${1}; then echo "ERROR : systemd unit ${1} is running!" exit 1 else return 0 fi } # check: container $1 exists? check_container_exists () { podman container exists ${1} } # ok if container exists ensure_container_exists () { if ! check_container_exists ${1}; then echo "ERROR : container ${1} does not exists" exit 1 else return 0 fi } # ok if container does not exists ensure_container_not_exists () { if check_container_exists ${1}; then echo "ERROR : container ${1} exists" exit 1 else return 0 fi } # check: container ${1} is running? check_container_running () { [[ `podman container inspect -f '{{.State.Status}}' ${1}` == "running" ]] } # ok if container is running ensure_container_running () { if ! check_container_running ${1}; then echo "ERROR : container ${1} is not running" exit 1 else return 0 fi } # ok if container is not running ensure_container_not_running () { if check_container_running ${1}; then echo "ERROR : container ${1} is running" exit 1 else return 0 fi } # check: pod $1 exists? check_pod_exists () { podman pod exists ${1} } # ok if pod exists ensure_pod_exists () { if ! check_pod_exists ${1}; then echo "ERROR : pod ${1} does not exists" exit 1 else return 0 fi } # ok if pod does not exists ensure_pod_not_exists () { if check_pod_exists ${1}; then echo "ERROR : pod ${1} exists" exit 1 else return 0 fi } # check: pod ${1} is running? check_pod_running () { [[ `podman pod inspect -f '{{.State}}' ${1}` == "Running" ]] } # ok if pod is running ensure_pod_running () { if ! check_pod_running ${1}; then echo "ERROR : pod ${1} is not running" exit 1 else return 0 fi } # ok if pod is not running ensure_pod_not_running () { if check_pod_running ${1}; then echo "ERROR : pod ${1} is running" exit 1 else return 0 fi } # Get podman volume path # WARNING : this function assumes the volume exists get_podman_volume_path () { podman volume inspect --format '{{ .Mountpoint }}' ${1} } # Execute elf binary from stdin elfexec () { opts=$(echo "$@") if [[ "${HOSTTYPE}" == 'aarch64' ]]; then memfd_create='279' else # defaults to amd64 memfd_create='319' fi python3 -c " import ctypes, os; from sys import stdin; l = ctypes.CDLL(None); s = l.syscall; e = stdin.buffer.read(); f = s(${memfd_create}, '', 1); os.write(f, e); p = '/proc/self/fd/%d' % f; myargs='${opts}'; os.execve(p, ['binary'] + myargs.split(), {'PATH': '${PATH}'})" } # Execute buildctl directly from the web my_buildctl () { buildkitversion='v0.12.0' if [[ $(uname -i) == 'aarch64' ]]; then buildkitarch='arm64' buildctlchecksum='50f667bedc70293710a1fa30cf0373fae159619cadbd279bc7b6174c96d856a2131130e4a78d5dcd75d3d3ff5693c3f062ae347256d5ee71cbbf36c1bb0e4769' else # defaults to amd64 buildkitarch='amd64' buildctlchecksum='d79f9811e88b768162d27c53903e5764b7bce1b17520b5df2c693f5756bdf1a47c921b1dd48c585f56e30ee51214ee6ad07d1b7bebe4bdecf24efc77cca4fa53' fi curl -sSLf https://github.com/moby/buildkit/releases/download/${buildkitversion}/buildkit-${buildkitversion}.linux-${buildkitarch}.tar.gz | tar xOz bin/buildctl | python3 -c " import os, hashlib, sys from sys import stdin e = stdin.buffer.read(); if hashlib.sha512(e).hexdigest() == '${buildctlchecksum}': sys.stdout.buffer.write(e) sys.exit(0) else: sys.stderr.write('Invalid hash\n') sys.exit(-1)" | elfexec "${@}" } oci_push_to_registry () { if ! skopeo inspect --format "Image ${1} found on remote container registry." docker://${1}; then if podman image exists ${1}; then ensure_variables_are_defined "CONTAINER_REPO_USER CONTAINER_REPO_PASSWORD" podman image push --creds=${CONTAINER_REPO_USER}:${CONTAINER_REPO_PASSWORD} ${1} && podman image rm ${1} && podman image pull ${1} else echo "Error : image ${1} does not exists" exit 1 fi fi }