SHA256
Compare commits
23
Commits
| Author | SHA256 | Date | |
|---|---|---|---|
|
|
ee86603dcd
|
||
|
|
1eee4b2d1d
|
||
|
|
7555745704
|
||
|
|
49d2e35106
|
||
|
|
9722741bfd
|
||
|
|
22abaf6431
|
||
|
|
4e24ee218c
|
||
|
|
acac5b685b
|
||
|
|
3869ca5a95
|
||
|
|
3d5757effc
|
||
|
|
6c7db396b2
|
||
|
|
eeb0c9cb47
|
||
|
|
44cc111b3d
|
||
|
|
f0610091bb
|
||
|
|
f93f647504
|
||
|
|
32e88beedc
|
||
|
|
6b2847fec7
|
||
|
|
127fb83567
|
||
|
|
bfa15561d8
|
||
|
|
22675d1be3
|
||
|
|
62f6865a06
|
||
|
|
331f75a943
|
||
|
|
d1791cfcc8
|
+13
-13
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
[ "$(whoami)" != "root" ] && echo "Error: installation only works as root!" >&2 && exit 1
|
||||
(( EUID != 0 )) && echo "Error: installation only works as root!" >&2 && exit 1
|
||||
|
||||
API_ENDPOINT="https://git.ccc-rheintal.ch/api/v1/repos/spacefreak/pbc"
|
||||
|
||||
TMPDIR=''
|
||||
function cleanup_tmpdir() {
|
||||
[ -n "$TMPDIR" -a -d "$TMPDIR" ] && rm -r "$TMPDIR"
|
||||
WORK_DIR=''
|
||||
function cleanup_work_dir() {
|
||||
[ -n "$WORK_DIR" ] && [ -d "$WORK_DIR" ] && rm -r "$WORK_DIR"
|
||||
trap - EXIT
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@ function download_files() {
|
||||
local query_params=''
|
||||
[ -n "$GIT_TAG" ] && query_params="?ref=$GIT_TAG"
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
while (( $# > 0 )); do
|
||||
path=$1
|
||||
shift
|
||||
curl -s --output-dir "$TMPDIR/" --remote-name "$API_ENDPOINT/raw/$path$query_params"
|
||||
curl -fsSL --output-dir "$WORK_DIR/" --remote-name "$API_ENDPOINT/raw/$path$query_params"
|
||||
rc=$?
|
||||
if (( $rc != 0 )); then
|
||||
return $rc
|
||||
@@ -26,27 +26,27 @@ function download_files() {
|
||||
done
|
||||
}
|
||||
|
||||
GIT_TAG=$(curl -s "$API_ENDPOINT/tags" | jq -r '.[] | .name' | sort --version-sort | tail -n 1)
|
||||
GIT_TAG=$(curl -fsSL "$API_ENDPOINT/tags" | grep -o '{"name":"[^"]*"' | sed 's/^{"name":"//;s/"$//' | sort --version-sort | tail -n 1)
|
||||
if [ -n "$GIT_TAG" ]; then
|
||||
echo "Info: installing pbc version $GIT_TAG"
|
||||
else
|
||||
echo "Warning: no Git tag found, installing from repository default branch" >&2
|
||||
fi
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
trap cleanup_tmpdir EXIT
|
||||
WORK_DIR=$(mktemp -d)
|
||||
trap cleanup_work_dir EXIT
|
||||
|
||||
! download_files config.example pbc && echo "Error downloading files!" >&2 && exit 10
|
||||
chmod +x "$TMPDIR/pbc"
|
||||
chmod o= "$TMPDIR/config.example"
|
||||
chmod +x "$WORK_DIR/pbc"
|
||||
chmod o= "$WORK_DIR/config.example"
|
||||
|
||||
"$TMPDIR/pbc" install
|
||||
"$WORK_DIR/pbc" install
|
||||
rc=$?
|
||||
if (( $rc != 0 )); then
|
||||
echo "Error installing pbc requirements!" >&2
|
||||
exit $rc
|
||||
fi
|
||||
|
||||
! mv "$TMPDIR/pbc" /usr/local/bin/pbc && echo 'Error moving file!' >&2 && exit 20
|
||||
! install -m 0755 -o root -g root "$WORK_DIR/pbc" /usr/local/bin/pbc && echo 'Error installing file!' >&2 && exit 20
|
||||
|
||||
echo "Success!"
|
||||
|
||||
@@ -34,53 +34,34 @@ EOF
|
||||
|
||||
function full_usage() {
|
||||
usage true
|
||||
[ ! -e "$PBC" ] && echo "Error: $PBC is not executable!" >&2 && return 254
|
||||
[ ! -x "$PBC" ] && echo "Error: $PBC is not executable!" >&2 && return 254
|
||||
echo "Commands of proxmox-backup-client:"
|
||||
echo
|
||||
"$PBC" help | tail -n +3
|
||||
echo
|
||||
return $?
|
||||
}
|
||||
|
||||
function pbc-version() {
|
||||
local vers_info=$("$PBC" version)
|
||||
local rc=$?
|
||||
(( $rc != 0 )) && echo "Error running $PBC version ... exited with rc=$rc" >&2 && return $rc
|
||||
local vers_info rc
|
||||
vers_info=$("$PBC" version)
|
||||
rc=$?
|
||||
(( rc != 0 )) && echo "Error running $PBC version ... exited with rc=$rc" >&2 && return $rc
|
||||
echo "$vers_info" | grep client
|
||||
rc=$?
|
||||
(( $rc != 0 )) && echo "Error reading client version, output was:" >&2 && echo "$vers_info" >&2
|
||||
(( rc != 0 )) && echo "Error reading client version, output was:" >&2 && echo "$vers_info" >&2
|
||||
return $rc
|
||||
}
|
||||
|
||||
function pbc-backup() {
|
||||
"$PBC" backup --ns "$PBS_NAMESPACE" "${BACKUP[@]}"
|
||||
return $?
|
||||
}
|
||||
function pbc-backup() { "$PBC" backup --ns "$PBS_NAMESPACE" "${BACKUP[@]}" "$@"; }
|
||||
|
||||
function pbc-list() {
|
||||
"$PBC" list --ns "$PBS_NAMESPACE" "$@"
|
||||
return $?
|
||||
}
|
||||
function pbc-list() { "$PBC" list --ns "$PBS_NAMESPACE" "$@"; }
|
||||
|
||||
function pbc-snapshot-list() {
|
||||
"$PBC" snapshot list --ns "$PBS_NAMESPACE" "$@"
|
||||
return $?
|
||||
}
|
||||
function pbc-snapshot-list() { "$PBC" snapshot list --ns "$PBS_NAMESPACE" "$@"; }
|
||||
|
||||
function pbc-files() {
|
||||
"$PBC" files --ns "$PBS_NAMESPACE" "$@"
|
||||
return $?
|
||||
}
|
||||
function pbc-files() { "$PBC" files --ns "$PBS_NAMESPACE" "$@"; }
|
||||
|
||||
function pbc-catalog-shell() {
|
||||
"$PBC" catalog shell --ns "$PBS_NAMESPACE" "$@"
|
||||
return $?
|
||||
}
|
||||
function pbc-catalog-shell() { "$PBC" catalog shell --ns "$PBS_NAMESPACE" "$@"; }
|
||||
|
||||
function pbc-mount() {
|
||||
"$PBC" mount --ns "$PBS_NAMESPACE" "$@"
|
||||
return $?
|
||||
}
|
||||
function pbc-mount() { "$PBC" mount --ns "$PBS_NAMESPACE" "$@"; }
|
||||
|
||||
function get_group_names() {
|
||||
pbc-list --output-format json | jq -r '.[] | "\(.["backup-type"])/\(.["backup-id"])"'
|
||||
@@ -97,27 +78,27 @@ function get_snapshot_files() {
|
||||
function apt_get_install() {
|
||||
local package=$1
|
||||
echo "Installing $package using package manager ..."
|
||||
apt-get install "$package" >/dev/null
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$package" >/dev/null
|
||||
local rc=$?
|
||||
(( $rc != 0 )) && echo "Error installing package!" >&2
|
||||
return $rc
|
||||
}
|
||||
|
||||
TMPDIR=''
|
||||
function cleanup_tmpdir() {
|
||||
[ -n "$TMPDIR" -a -d "$TMPDIR" ] && rm -r "$TMPDIR"
|
||||
WORK_DIR=''
|
||||
function cleanup_work_dir() {
|
||||
[ -n "$WORK_DIR" ] && [ -d "$WORK_DIR" ] && rm -r "$WORK_DIR"
|
||||
trap - EXIT
|
||||
}
|
||||
|
||||
function install_proxmox_backup_client() {
|
||||
local update=${1:-false}
|
||||
local version
|
||||
|
||||
[ -f "$PBC" ] && local installed=true || local installed=false
|
||||
! $installed && update=false
|
||||
|
||||
if $installed && ! $update; then
|
||||
local version=$("$PBC" version | head -n 1)
|
||||
(( $? != 0 )) && echo "Error running $PBC version: exited with rc=$?" >&2 && return 10
|
||||
version=$(pbc-version) || return 10
|
||||
echo "Info: skip installation of proxmox-backup-client, already installed ($version)"
|
||||
return 0
|
||||
fi
|
||||
@@ -127,34 +108,37 @@ function install_proxmox_backup_client() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
if apt-get search proxmox-backup-client &>/dev/null; then
|
||||
if apt-cache show proxmox-backup-client &>/dev/null; then
|
||||
apt_get_install proxmox-backup-client
|
||||
return $?
|
||||
fi
|
||||
|
||||
echo "Info: proxmox-backup-client is not available from any configured apt repository"
|
||||
echo "Info: add the Proxmox pbs-client repository to install a signed, apt-managed package"
|
||||
|
||||
$update && local action='Updating' || local action='Installing'
|
||||
echo "$action proxmox-backup-client-static binary ..."
|
||||
|
||||
local pkgfile=$(curl -s "$PBC_DOWNLOAD_URL/" | grep proxmox-backup-client-static_ | tail -n 1 | sed 's#.*href="##g;s#".*##g;')
|
||||
local pkgfile=$(curl -fsSL "$PBC_DOWNLOAD_URL/" | grep proxmox-backup-client-static_ | sed 's#.*href="##g;s#".*##g;' | sort --version-sort | tail -n 1)
|
||||
[ -z "$pkgfile" ] && echo "Unable to determine current package file!" >&2 && return 30
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
trap cleanup_tmpdir EXIT
|
||||
WORK_DIR=$(mktemp -d)
|
||||
trap cleanup_work_dir EXIT
|
||||
|
||||
echo "Info: downloading $PBC_DOWNLOAD_URL/$pkgfile ..."
|
||||
! curl -s -o "$TMPDIR/$pkgfile" "$PBC_DOWNLOAD_URL/$pkgfile" && echo "Error downloading file!" >&2 && return 40
|
||||
! curl -fsSL -o "$WORK_DIR/$pkgfile" "$PBC_DOWNLOAD_URL/$pkgfile" && echo "Error downloading file!" >&2 && return 40
|
||||
|
||||
echo "Info: extracting $pkgfile ..."
|
||||
! dpkg-deb -x "$TMPDIR/$pkgfile" "$TMPDIR/" && echo "Error extracting file!" >&2 && return 50
|
||||
! dpkg-deb -x "$WORK_DIR/$pkgfile" "$WORK_DIR/" && echo "Error extracting file!" >&2 && return 50
|
||||
|
||||
echo "Info: copying proxmox-backup-client static binary to $PBC ..."
|
||||
! cp "$TMPDIR/usr/bin/proxmox-backup-client" "$PBC" && echo "Error copying binary!" >&2 && return 60
|
||||
echo "Info: installing proxmox-backup-client static binary to $PBC ..."
|
||||
! install -m 0755 -D "$WORK_DIR/usr/bin/proxmox-backup-client" "$PBC" && echo "Error installing binary!" >&2 && return 60
|
||||
|
||||
local version=$(pbc-version) || return $?
|
||||
version=$(pbc-version) || return $?
|
||||
$update && action='updated' || action='installed'
|
||||
echo "Info: successfully $action proxmox-backup-$version"
|
||||
|
||||
cleanup_tmpdir
|
||||
cleanup_work_dir
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +146,7 @@ function arr_contains() {
|
||||
local search=$1
|
||||
shift
|
||||
[ -z "$search" ] && return 1
|
||||
while [ -n "$1" ]; do
|
||||
while (( $# > 0 )); do
|
||||
[ "$1" == "$search" ] && return 0
|
||||
shift
|
||||
done
|
||||
@@ -178,8 +162,12 @@ function may_select() {
|
||||
if [ -z "$value" ]; then
|
||||
if (( $# == 1 )); then
|
||||
value=$1
|
||||
elif [ ! -t 0 ]; then
|
||||
echo "Error: no value given and stdin is not a terminal" >&2
|
||||
return 1
|
||||
else
|
||||
local sorted=($(printf "%s\n" "$@" | sort))
|
||||
local sorted
|
||||
readarray -t sorted < <(printf '%s\n' "$@" | sort)
|
||||
select value in "${sorted[@]}"; do
|
||||
[ -n "$value" ] && break
|
||||
done
|
||||
@@ -188,8 +176,8 @@ function may_select() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
[ -z "$value" ] && return 1
|
||||
echo "$value"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@@ -197,15 +185,17 @@ SCRIPT_PATH=$(realpath -s "$0")
|
||||
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
|
||||
SCRIPT=$(basename "$SCRIPT_PATH")
|
||||
|
||||
PBC=$(which proxmox-backup-client)
|
||||
PBC=$(command -v proxmox-backup-client)
|
||||
PBC_DOWNLOAD_URL='http://download.proxmox.com/debian/pbs-client/dists/trixie/main/binary-amd64'
|
||||
ETC_DIR="/etc/$SCRIPT"
|
||||
|
||||
FULL_HELP=false
|
||||
|
||||
action=''
|
||||
cfgfile="$ETC_DIR/config"
|
||||
args=()
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
while (( $# > 0 )); do
|
||||
opt=$1
|
||||
shift
|
||||
if [ -z "$action" ]; then
|
||||
@@ -213,20 +203,19 @@ while [ -n "$1" ]; do
|
||||
-c|--config)
|
||||
cfgfile=$1
|
||||
shift
|
||||
[ -z "$cfgfile" ] && usage && exit 255
|
||||
[ -z "$cfgfile" ] && echo "Error: missing argument for $opt" >&2 && usage >&2 && exit 255
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-H|--full-help)
|
||||
full_usage
|
||||
exit 0
|
||||
FULL_HELP=true
|
||||
;;
|
||||
-*)
|
||||
echo "Error: invalid option: $opt" >&2
|
||||
echo
|
||||
usage
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 255
|
||||
;;
|
||||
*)
|
||||
@@ -240,14 +229,14 @@ while [ -n "$1" ]; do
|
||||
;;
|
||||
-*)
|
||||
echo "Error: invalid option: $opt" >&2
|
||||
echo
|
||||
usage
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 255
|
||||
;;
|
||||
*)
|
||||
echo "Error: invalid argument: $opt" >&2
|
||||
echo
|
||||
usage
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 255
|
||||
;;
|
||||
esac
|
||||
@@ -257,33 +246,51 @@ while [ -n "$1" ]; do
|
||||
done
|
||||
|
||||
|
||||
if [ -f "$cfgfile" ]; then
|
||||
perms=$(stat -c '%a' "$cfgfile")
|
||||
(( 8#$perms & 0022 )) && echo "Error: $cfgfile is writable by group or others!" >&2 && exit 202
|
||||
(( 8#$perms & 0007 )) && echo "Warning: $cfgfile is readable by others!" >&2
|
||||
fi
|
||||
|
||||
if $FULL_HELP; then
|
||||
[ -f "$cfgfile" ] && source "$cfgfile"
|
||||
PBC=${PBC:-/usr/local/bin/proxmox-backup-client}
|
||||
full_usage
|
||||
exit $?
|
||||
fi
|
||||
|
||||
[ -z "$action" ] && usage >&2 && exit 255
|
||||
|
||||
if [ "$action" == 'install' ]; then
|
||||
if [ -f "$cfgfile" ]; then
|
||||
source "$cfgfile" || exit $?
|
||||
fi
|
||||
PBC=${PBC:-/usr/local/bin/proxmox-backup-client}
|
||||
for exe in apt-get dpkg dpkg-deb curl; do
|
||||
! which -s "$exe" && echo "Error: $exe executable not found!" >&2 && exit 200
|
||||
for exe in apt-cache apt-get dpkg dpkg-deb curl; do
|
||||
! command -v "$exe" >/dev/null && echo "Error: $exe executable not found!" >&2 && exit 200
|
||||
done
|
||||
else
|
||||
[ ! -f "$cfgfile" ] && echo "Error: $cfgfile: no such file" >&2 && exit 201
|
||||
[ ! -r "$cfgfile" ] && echo "Error: $cfgfile: not readable" >&2 && exit 201
|
||||
source "$cfgfile" || exit $?
|
||||
PBC=${PBC:-/usr/local/bin/proxmox-backup-client}
|
||||
[ ! -f "$PBC" ] && echo "Error: $PBC: no such file" >&2 && exit 200
|
||||
[ ! -e "$PBC" ] && echo "Error: $PBC: not executable" >&2 && exit 200
|
||||
! which -s jq && echo "Error: jq executable not found!" >&2 && exit 200
|
||||
[ ! -x "$PBC" ] && echo "Error: $PBC: not executable" >&2 && exit 200
|
||||
! command -v jq >/dev/null && echo "Error: jq executable not found!" >&2 && exit 200
|
||||
fi
|
||||
|
||||
export PBS_REPOSITORY="$PBS_USER@${PBS_SERVER:-8007}:$PBS_DATASTORE"
|
||||
export PBS_REPOSITORY="$PBS_USER@$PBS_SERVER:$PBS_DATASTORE"
|
||||
export PBS_PASSWORD="$PBS_PASSWORD"
|
||||
|
||||
case "$action" in
|
||||
backup)
|
||||
pbc-backup || exit $?
|
||||
pbc-backup "${args[@]}" || exit $?
|
||||
;;
|
||||
backup-cron)
|
||||
output=$(pbc-backup 2>&1)
|
||||
output=$(pbc-backup "${args[@]}" 2>&1)
|
||||
rc=$?
|
||||
(( $rc != 0 )) && echo "$output"
|
||||
(( rc != 0 )) && echo "$output" >&2
|
||||
exit $rc
|
||||
;;
|
||||
list)
|
||||
pbc-list "${args[@]}" || exit $?
|
||||
@@ -369,7 +376,7 @@ case "$action" in
|
||||
install)
|
||||
update=${args[0]:-false}
|
||||
|
||||
[ "$(whoami)" != "root" ] && echo "Error: installation only works as root!" >&2 && exit 1
|
||||
(( EUID != 0 )) && echo "Error: installation only works as root!" >&2 && exit 1
|
||||
|
||||
install_proxmox_backup_client "$update" || exit $?
|
||||
|
||||
@@ -388,8 +395,8 @@ case "$action" in
|
||||
|
||||
if [ -f "$SCRIPT_DIR/config.example" ]; then
|
||||
if $update || [ ! -f "$ETC_DIR/config.example" ]; then
|
||||
echo "Copy example config to $ETC_DIR/config.example ..."
|
||||
! cp "$SCRIPT_DIR/config.example" "$ETC_DIR/config.example" && echo "Error copying file!" >&2 && exit 4
|
||||
echo "Install example config to $ETC_DIR/config.example ..."
|
||||
! install -m 0640 "$SCRIPT_DIR/config.example" "$ETC_DIR/config.example" && echo "Error installing file!" >&2 && exit 4
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user