You've already forked Proxmox-Container-Template
Initialize Git Repository: 'Proxmox-Container-Template'
This commit is contained in:
375
pct-template/usr/sbin/pct-template
Normal file
375
pct-template/usr/sbin/pct-template
Normal file
@@ -0,0 +1,375 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
###
|
||||
#
|
||||
# Options Section
|
||||
#
|
||||
###
|
||||
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
|
||||
###
|
||||
#
|
||||
# Variable Section
|
||||
#
|
||||
###
|
||||
|
||||
REPOSITORY_URL='https://repository.privlab.it/pct-template'
|
||||
REPOSITORY_PATH='/var/lib/pct-template'
|
||||
|
||||
|
||||
###
|
||||
#
|
||||
# Function Section
|
||||
#
|
||||
###
|
||||
|
||||
|
||||
function error () {
|
||||
if [[ -n "${1:-}" ]]; then
|
||||
/usr/bin/echo -n -e "${1}"
|
||||
fi
|
||||
if [[ -n "${2:-}" ]]; then
|
||||
/usr/bin/echo -n -e "${2}"
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
function help () {
|
||||
local HELP="${1}"
|
||||
case "${HELP}" in
|
||||
archive)
|
||||
read -r -d '' HELP << EOL
|
||||
Usage: pct-template -a (Template)
|
||||
|
||||
Description:
|
||||
Archives a Proxmox container template from the local repository,
|
||||
computes its checksum, and saves it to the current directory.
|
||||
|
||||
Templates available in the local repository can be listed
|
||||
with the command 'pct-template -i'.
|
||||
EOL
|
||||
;;
|
||||
chroot)
|
||||
read -r -d '' HELP << EOL
|
||||
Usage: pct-template -c (Image / Storage / Template)
|
||||
|
||||
Description:
|
||||
Opens a CHROOT environment for a Proxmox container template, storage, or image.
|
||||
The following host filesystems are binded and slaved into the CHROOT environment:
|
||||
- 'devtmpfs' - '/dev'
|
||||
- 'mqueue' - '/dev/mqueue'
|
||||
- 'devpts' - '/dev/pts'
|
||||
- 'proc' - '/proc'
|
||||
- 'sys' - '/sys'
|
||||
- 'tmpfs' - '/run'
|
||||
All mounted filesystems are cleanly unmounted when exiting the CHROOT environment.
|
||||
EOL
|
||||
;;
|
||||
download)
|
||||
read -r -d '' HELP << EOL
|
||||
Usage: pct-template -d (Template)
|
||||
|
||||
Description:
|
||||
Downloads a Proxmox container template from the online repository or updates it.
|
||||
If the local template is a newer version than the online repository,
|
||||
user interaction to delete the local template is required before overwriting.
|
||||
If the version in the online repository is newer, the local template is replaced
|
||||
by the version from the online repository.
|
||||
EOL
|
||||
;;
|
||||
help)
|
||||
read -r -d '' HELP << EOL
|
||||
Usage: pct-template (Option) (Image / Storage / Template)
|
||||
|
||||
Options (User):
|
||||
[ -a ] [ Template ] | Archive a Proxmox container template
|
||||
[ -c ] [ Template ] | Open a chroot environment in a Proxmox container image, storage or template
|
||||
[ -d ] [ Template ] | Dowload / Update a Proxmox container template to local repository
|
||||
[ -h ] | Display help
|
||||
[ -i ] | Display repository information
|
||||
[ -m ] [ Template ] | Mount / Umount a Proxmox container image or storage
|
||||
[ -u ] [ Template ] | Update an prepare Proxmox container template to a new version
|
||||
EOL
|
||||
;;
|
||||
info)
|
||||
read -r -d '' HELP << EOL
|
||||
Usage: pct-template -i
|
||||
|
||||
Description:
|
||||
Lists all available Proxmox container templates from the local and
|
||||
online repositories and compares their versions.
|
||||
EOL
|
||||
;;
|
||||
mount)
|
||||
read -r -d '' HELP << EOL
|
||||
Usage: pct-template -m (Image / Storage)
|
||||
|
||||
Description:
|
||||
Mount at path '/mnt' either a Proxmox container template;
|
||||
if the Proxmox container template is already mounted, unmount it.
|
||||
EOL
|
||||
;;
|
||||
update)
|
||||
read -r -d '' HELP << EOL
|
||||
Usage: pct-template -u (Template)
|
||||
|
||||
Description:
|
||||
An editor opens displaying a list of files and folders to be removed from the
|
||||
Proxmox container template. After removal, the template version is updated accordingly.
|
||||
Since this Proxmox container template is, in a broad sense, a fork, it should be
|
||||
considered whether renaming it would be appropriate.
|
||||
EOL
|
||||
;;
|
||||
esac
|
||||
/usr/bin/echo -e "${HELP}"
|
||||
}
|
||||
|
||||
function output () {
|
||||
if [[ -n "${1:-}" ]]; then
|
||||
/usr/bin/echo -n -e "${1}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
###
|
||||
#
|
||||
# Runtime Environment
|
||||
#
|
||||
###
|
||||
|
||||
/usr/bin/echo -e 'Proxmox LXC Template Tool\n'
|
||||
|
||||
while getopts ':a:c:d:him:u:' OPT; do
|
||||
case "${OPT}" in
|
||||
a)
|
||||
exit 0
|
||||
;;
|
||||
c)
|
||||
exit 0
|
||||
;;
|
||||
d)
|
||||
exit 0
|
||||
;;
|
||||
i)
|
||||
exit 0
|
||||
;;
|
||||
m)
|
||||
exit 0
|
||||
;;
|
||||
u)
|
||||
exit 0
|
||||
;;
|
||||
-*|*)
|
||||
set +e
|
||||
case "${1}" in
|
||||
-a)
|
||||
help 'archive'
|
||||
exit 0
|
||||
;;
|
||||
-c)
|
||||
help 'chroot'
|
||||
exit 0
|
||||
;;
|
||||
-d)
|
||||
help 'download'
|
||||
exit 0
|
||||
;;
|
||||
-i)
|
||||
help 'info'
|
||||
exit 0
|
||||
;;
|
||||
-m)
|
||||
help 'mount'
|
||||
exit 0
|
||||
;;
|
||||
-u)
|
||||
help 'update'
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
set +e
|
||||
help 'help'
|
||||
shift $((OPTIND-1))
|
||||
|
||||
|
||||
while getopts ':c:g:hp:r:' OPT; do
|
||||
case "${OPT}" in
|
||||
c)
|
||||
CT_BASENAME=$(/usr/bin/basename "${OPTARG}")
|
||||
CT_REALPATH=$(/usr/bin/realpath "${OPTARG}")
|
||||
consistency
|
||||
trap 'unbind' EXIT
|
||||
bind_chroot
|
||||
trap "resolvconf 'reset' && unbind" EXIT
|
||||
resolvconf 'prepare'
|
||||
message '\n ... Enter chroot environment ... \n\n'
|
||||
/usr/bin/sleep '3s'
|
||||
/usr/sbin/chroot "${CT_REALPATH}" || true
|
||||
message '\n ... Exit chroot environment ... \n\n'
|
||||
/usr/bin/sleep '3s'
|
||||
exit 0
|
||||
;;
|
||||
g)
|
||||
CT_BASENAME=$(/usr/bin/basename "${OPTARG}")
|
||||
CT_REALPATH=$(/usr/bin/realpath "${OPTARG}")
|
||||
CT_DIRNAME=$(/usr/bin/dirname "${CT_REALPATH}")
|
||||
consistency
|
||||
trap "/usr/bin/rm --force ${CT_DIRNAME}/${CT_BASENAME}.tar.xz"* EXIT
|
||||
message 'Generate container template ...'
|
||||
/usr/bin/tar --create --use-compress-program="/usr/bin/xz -9 --extreme" --file "${CT_DIRNAME}/${CT_BASENAME}.tar.xz" --directory="${CT_REALPATH}" '.' || \
|
||||
error '\r\rGenerate container template [ERROR]\n' \
|
||||
' => The container folder could not be compressed.\n'
|
||||
message '\r\rGenerate container template [OK]\n'
|
||||
message 'Generate container hashsum ...'
|
||||
/usr/bin/sha512sum "${CT_DIRNAME}/${CT_BASENAME}.tar.xz" | /usr/bin/sed --expression='s, .*/, ,' >> "${CT_DIRNAME}/${CT_BASENAME}.tar.xz.sha512sum" || \
|
||||
error '\r\rGenerate container hashsum [ERROR]\n' \
|
||||
' => The container hashsum could not be generated.\n'
|
||||
message '\r\rGenerate container hashsum [OK]\n'
|
||||
trap '' EXIT
|
||||
exit 0
|
||||
;;
|
||||
h)
|
||||
set +e
|
||||
help 'command'
|
||||
exit 0
|
||||
;;
|
||||
p)
|
||||
CT_BASENAME=$(/usr/bin/basename "${OPTARG}")
|
||||
CT_REALPATH=$(/usr/bin/realpath "${OPTARG}")
|
||||
CT_DIRNAME=$(/usr/bin/dirname "${CT_REALPATH}")
|
||||
consistency
|
||||
trap "/usr/bin/rm --force ${CT_DIRNAME}/.${CT_BASENAME}" EXIT
|
||||
message 'Prepare the planned file remove list ...'
|
||||
if [ -f "/usr/share/pct-template/prepare/${CT_BASENAME}" ]; then
|
||||
/usr/bin/cp --update='none' "/usr/share/pct-template/prepare/${CT_BASENAME}" "${CT_DIRNAME}/.${CT_BASENAME}" || \
|
||||
error '\r\rPrepare the planned file remove list [ERROR]\n' \
|
||||
" => The remove list '${CT_BASENAME}' could not be copied.\n"
|
||||
elif [[ ! -f "/usr/share/pct-template/prepare/${CT_BASENAME}" ]]; then
|
||||
/usr/bin/cp --update='none' "/usr/share/pct-template/prepare/default" "${CT_DIRNAME}/.${CT_BASENAME}" || \
|
||||
error '\r\rPrepare the planned file remove list [ERROR]\n' \
|
||||
" => The remove list 'default' could not be copied.\n"
|
||||
fi
|
||||
/usr/bin/editor "${CT_DIRNAME}/.${CT_BASENAME}" || \
|
||||
error '\r\rPrepare the planned file remove list [ERROR]\n' \
|
||||
" => The remove list '.${CT_BASENAME}' could not be opened.\n"
|
||||
message '\r\rPrepare the planned file remove list [OK]\n'
|
||||
message 'Remove files from remove list ...'
|
||||
mapfile -t CLEANUP_LIST < <(/usr/bin/cat "${CT_DIRNAME}/.${CT_BASENAME}" | /usr/bin/sed '/#.*/d' | while read -r CLEANUP_PATH; do /usr/bin/echo "${CT_REALPATH}${CLEANUP_PATH}"; done)
|
||||
for CLEANUP_LIST in "${CLEANUP_LIST[@]}"; do
|
||||
/usr/bin/sh -c "/usr/bin/ls --directory ${CLEANUP_LIST} | /usr/bin/xargs /usr/bin/rm --force --recursive" &> '/dev/null' || \
|
||||
error '\r\rRemove files from remove list [ERROR]\n' \
|
||||
" => The file or directory '${CLEANUP_LIST}' could not be removed.\n"
|
||||
done
|
||||
unset CLEANUP_LIST
|
||||
message '\r\rRemove files from remove list [OK]\n'
|
||||
message 'Cleaning up the log files ...'
|
||||
mapfile -t CLEANUP_LIST < <(/usr/bin/find "${CT_REALPATH}/var/log" -type 'f')
|
||||
for CLEANUP_LIST in "${CLEANUP_LIST[@]}"; do
|
||||
/usr/bin/dd if=/dev/null of="${CLEANUP_LIST}" &> '/dev/null' || \
|
||||
error '\r\rCleaning up the log files [ERROR]\n' \
|
||||
" => The file '${CLEANUP_LIST}' could not be emptied.\n"
|
||||
done
|
||||
unset CLEANUP_LIST
|
||||
mapfile -t CLEANUP_LIST < <(/usr/bin/find "${CT_REALPATH}/var/logrotate" -type 'f')
|
||||
for CLEANUP_LIST in "${CLEANUP_LIST[@]}"; do
|
||||
/usr/bin/sh -c "/usr/bin/ls --directory ${CLEANUP_LIST} | /usr/bin/xargs /usr/bin/rm --force --recursive" &> '/dev/null' || \
|
||||
error '\r\rCleaning up the log files [ERROR]\n' \
|
||||
" => The file '${CLEANUP_LIST}' could not be removed.\n"
|
||||
done
|
||||
message '\r\rCleaning up the log files [OK]\n'
|
||||
message 'Load container information ...'
|
||||
source "${CT_REALPATH}/etc/os-release" || \
|
||||
error '\r\rcontainer information [ERROR]\n' \
|
||||
" => The system information '/etc/os-release' could not be loaded.\n"
|
||||
message '\r\rLoad container information [OK]\n'
|
||||
message 'Prepare container hostname ...'
|
||||
/usr/bin/echo 'LXC_NAME' > "${CT_REALPATH}/etc/hostname" || \
|
||||
error '\r\rPrepare container hostname [ERROR]\n' \
|
||||
" => The file '/etc/hostname' could not be written.\n"
|
||||
message '\r\rPrepare container hostname [OK]\n'
|
||||
message 'Prepare container hosts ...'
|
||||
/usr/bin/cp --force '/usr/share/pct-template/etc/hosts' "${CT_REALPATH}/etc/hosts" || \
|
||||
error '\r\rPrepare container hosts [ERROR]\n' \
|
||||
" => The file '/etc/hosts' could not be replaced.\n"
|
||||
message '\r\rPrepare container hosts [OK]\n'
|
||||
case "${NAME}" in
|
||||
'Debian GNU/Linux')
|
||||
message 'Prepare container network interfaces ...'
|
||||
/usr/bin/cp --force '/usr/share/pct-template/etc/interfaces' "${CT_REALPATH}/etc/network/interfaces" || \
|
||||
error '\r\rPrepare container network interfaces [ERROR]\n' \
|
||||
" => The file '/etc/network/interfaces' could not be replaced.\n"
|
||||
message '\r\rPrepare container network interfaces [OK]\n'
|
||||
;;
|
||||
esac
|
||||
resolvconf 'reset'
|
||||
exit 0
|
||||
;;
|
||||
r)
|
||||
message 'Download container template ...'
|
||||
if [[ -d "./${OPTARG}" ]]; then
|
||||
error '\r\rDownload container template [ERROR]\n' \
|
||||
" => The container '${OPTARG}' already exists.\n"
|
||||
fi
|
||||
trap "/usr/bin/rm --force --recursive ./${OPTARG}.tar.xz"* EXIT
|
||||
/usr/bin/wget --quiet --output-document="./${OPTARG}.tar.xz" --no-hsts "https://repository.privlab.it/pct-template/${OPTARG}.tar.xz" &> '/dev/null' || \
|
||||
error '\r\rDownload container template [ERROR]\n' \
|
||||
" => The file '${OPTARG}.tar.xz' could not be downloaded.\n"
|
||||
/usr/bin/wget --quiet --output-document="./${OPTARG}.tar.xz.sha512sum" --no-hsts "https://repository.privlab.it/pct-template/${OPTARG}.tar.xz.sha512sum" &> '/dev/null' || \
|
||||
error '\r\rDownload container template [ERROR]\n' \
|
||||
" => The file '${OPTARG}.tar.xz.sha512sum' could not be downloaded.\n"
|
||||
message '\r\rDownload container template [OK]\n'
|
||||
message 'Security check of the container archive ...'
|
||||
/usr/bin/sha512sum --check --strict "./${OPTARG}.tar.xz.sha512sum" &> '/dev/null' || \
|
||||
error '\r\rSecurity check of the container archive [ERROR]\n' \
|
||||
" => The SHA512 hash value for '${OPTARG}.tar.xz' could not be verified.\n"
|
||||
message '\r\rSecurity check of the container archive [OK]\n'
|
||||
message 'Decompress container archive ...'
|
||||
/usr/bin/install --directory "./${OPTARG}" || \
|
||||
error '\r\rDecompress container archive [ERROR]\n' \
|
||||
" => The path '${OPTARG}' could not be installed.\n"
|
||||
/usr/bin/tar --extract --file="./${OPTARG}.tar.xz" --directory="./${OPTARG}" || \
|
||||
error '\r\rDecompress container archive [ERROR]\n' \
|
||||
" => The container archive '${OPTARG}.tar.xz' could not be decompressed.\n"
|
||||
/usr/bin/rm --force "./${OPTARG}.tar.xz" || \
|
||||
error '\r\rDecompress container archive [ERROR]\n' \
|
||||
" => The container archive '${OPTARG}.tar.xz' could not be removed.\n"
|
||||
message '\r\rDecompress container archive [OK]\n'
|
||||
trap "/usr/bin/rm --force --recursive ./${OPTARG}.tar.xz.sha512sum"* EXIT
|
||||
exit 0
|
||||
;;
|
||||
-*|*)
|
||||
set +e
|
||||
case "${1}" in
|
||||
-a)
|
||||
help 'archive'
|
||||
exit 0
|
||||
;;
|
||||
-c)
|
||||
help 'chroot'
|
||||
exit 0
|
||||
;;
|
||||
-p)
|
||||
help 'prepare'
|
||||
exit 0
|
||||
;;
|
||||
-r)
|
||||
help 'repository'
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
help 'command'
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
set +e
|
||||
help 'command'
|
||||
shift $((OPTIND-1))
|
||||
Reference in New Issue
Block a user