pacwrap v0.9.8
- Heavy refactor with code cleanup - Completed common logging infrastructure - Distribution agnosticism attained! - pacwrap-common: Initial commit - pacwrap-common: Dependency check - pacwrap-utils: Replication functionality - pacwrap-sync: Increased resolution of linker progress - pacwrap-sync: Container configuration with explicit package array - pacwrap-sync: Improved UX, catching erronous exit codes from pacman - pacwrap-create: Refactor and cleanup - pacwrap-create: Replaced pacstrap with tarball installer
This commit is contained in:
parent
72e88098c3
commit
a16f74191d
5 changed files with 847 additions and 568 deletions
69
bin/pacwrap
69
bin/pacwrap
|
@ -18,33 +18,27 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
BOLD=$(tput bold)
|
||||
RED=$(tput setaf 1)
|
||||
RESET=$(tput sgr0)
|
||||
source pacwrap-common
|
||||
|
||||
VER="v0.9.7 R4 ${BOLD}BETA$RESET"
|
||||
EXEC_NAME="pacwrap"
|
||||
UTILS_SCRIPT="pacwrap-utils"
|
||||
|
||||
|
||||
main () {
|
||||
|
||||
distro_check
|
||||
parse_args "$@"
|
||||
init_structures
|
||||
|
||||
distro_warn
|
||||
|
||||
case $SWITCH in
|
||||
C)
|
||||
pacwrap-create ${ARGS[@]}
|
||||
$CREATE_SCRIPT ${ARGS[@]}
|
||||
;;
|
||||
E)
|
||||
pacwrap-exec ${ARGS[@]}
|
||||
$EXEC_SCRIPT ${ARGS[@]}
|
||||
;;
|
||||
S)
|
||||
pacwrap-sync ${ARGS[@]}
|
||||
$SYNC_SCRIPT ${ARGS[@]}
|
||||
;;
|
||||
U)
|
||||
pacwrap-utils ${ARGS[@]}
|
||||
$UTILS_SCRIPT ${ARGS[@]}
|
||||
;;
|
||||
h)
|
||||
help_operation $HELP
|
||||
|
@ -63,21 +57,6 @@ main () {
|
|||
esac
|
||||
}
|
||||
|
||||
init_structures() {
|
||||
INSTANCE_DATA_DIR="$HOME/.local/share/pacwrap"
|
||||
INSTANCE_CACHE_DIR="$HOME/.cache/pacwrap/pkg"
|
||||
INSTANCE_CONFIG_DIR="$HOME/.config/pacwrap"
|
||||
|
||||
if [[ $PACWRAP_DEBUG ]]; then
|
||||
INSTANCE_DATA_DIR="$PACWRAP_DEBUG"
|
||||
INSTANCE_CONFIG_DIR="$PACWRAP_DEBUG/cfg"
|
||||
fi
|
||||
|
||||
if [[ ! -d $INSTANCE_DATA_DIR ]] || [[ ! -d $INSTANCE_DATA_DIR ]] || [[ ! -d $INSTANCE_DATA_DIR ]]; then
|
||||
$UTILS_SCRIPT -Ui
|
||||
fi
|
||||
}
|
||||
|
||||
parse_args () {
|
||||
ARGS=()
|
||||
for var in "$@"; do
|
||||
|
@ -115,30 +94,6 @@ parse_args () {
|
|||
done
|
||||
}
|
||||
|
||||
distro_check() {
|
||||
|
||||
source /etc/os-release
|
||||
|
||||
if [[ ! -f /usr/bin/pacman ]]; then
|
||||
|
||||
version
|
||||
cat << _WARN
|
||||
|
||||
$BOLD${RED}error:$RESET An attempt was made to execute pachwrap on an unsupported distribution.
|
||||
pachwrap is currently only supported on distributions utilising Arch Linux's pacman package manager.
|
||||
Support for other package managers with a similar, requisite subset of features may be possible in future.
|
||||
_WARN
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! $ID == "arch" ]]; then cat << _WARN
|
||||
$BOLD${RED}WARNING:$RESET You are running pachwrap on an unsupported derviative of Arch Linux.
|
||||
|
||||
Support is not guaranteed. Use at your ${BOLD}OWN$RESET risk.
|
||||
|
||||
_WARN
|
||||
fi
|
||||
}
|
||||
|
||||
version () {
|
||||
if [[ ! $VER_DISPLAY ]]; then
|
||||
|
@ -283,4 +238,14 @@ _USAGE
|
|||
esac
|
||||
}
|
||||
|
||||
function distro_warn() {
|
||||
source /etc/os-release
|
||||
[[ ! $ID == "arch" ]] && cat << _WARN
|
||||
$BOLD${RED}WARNING:$RESET You are running pacwrap on an unsupported distribution of Linux or Unix.
|
||||
|
||||
Support is not guaranteed. Use at your ${BOLD}OWN$RESET risk.
|
||||
|
||||
_WARN
|
||||
}
|
||||
|
||||
main $@
|
||||
|
|
343
bin/pacwrap-common
Executable file
343
bin/pacwrap-common
Executable file
|
@ -0,0 +1,343 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# PacWrap -- common script
|
||||
#
|
||||
# Copyright (C) 2023 Xavier R.M.
|
||||
# sapphirus(at)azorium(dot)net
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, with only version 3 of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
RUNTIME_ARGS="$0 $@"
|
||||
|
||||
BOLD=$(tput bold)
|
||||
RED=$(tput setaf 1)
|
||||
GREEN=$(tput setaf 2)
|
||||
CYAN=$(tput setaf 6)
|
||||
YELLOW=$(tput setaf 11)
|
||||
RESET=$(tput sgr0)
|
||||
UNDERLINE=$(tput smul)
|
||||
|
||||
BAR="$RED$BOLD::$RESET$BOLD"
|
||||
BAR_GREEN="$GREEN$BOLD::$RESET$BOLD"
|
||||
ARROW="$CYAN$BOLD->$RESET"
|
||||
ARROW_GREEN="$GREEN$BOLD->$RESET"
|
||||
ARROW_RED="$RED$BOLD->$RESET"
|
||||
|
||||
VER="v0.9.8 ${BOLD}BETA$RESET"
|
||||
|
||||
EXEC_SCRIPT="pacwrap-exec"
|
||||
CREATE_SCRIPT="pacwrap-create"
|
||||
UTILS_SCRIPT="pacwrap-utils"
|
||||
SYNC_SCRIPT="pacwrap-sync"
|
||||
|
||||
LOG_ERR_HELP=1
|
||||
LOG_ERR_WARN=2
|
||||
LOG_ERR_ERROR=3
|
||||
|
||||
declare -A INSTANCE_CONFIG
|
||||
[[ ! $PACWRAP_DATA_DIR ]] && PACWRAP_DATA_DIR="$HOME/.local/share/pacwrap"
|
||||
[[ ! $PACWRAP_CACHE_DIR ]] && PACWRAP_CACHE_DIR="$HOME/.cache/pacwrap"
|
||||
[[ ! $PACWRAP_CONFIG_DIR ]] && PACWRAP_CONFIG_DIR="$HOME/.config/pacwrap"
|
||||
|
||||
VERBOSE="/dev/null"
|
||||
|
||||
LOCK_FILE="$PACWRAP_DATA_DIR/pacwrap.lck"
|
||||
LOG_FILE="$PACWRAP_DATA_DIR/pacwrap.log"
|
||||
OUTPUT_DEST=$LOG_FILE
|
||||
|
||||
INSTANCE_ROOT_DIR=$PACWRAP_DATA_DIR/root
|
||||
INSTANCE_HOME_DIR=$PACWRAP_DATA_DIR/home
|
||||
INSTANCE_CONFIG_DIR=$PACWRAP_CONFIG_DIR/root
|
||||
INSTANCE_DB_DIR=$PACWRAP_DATA_DIR/database
|
||||
|
||||
INSTANCE_PACMAN_DIR="$PACWRAP_DATA_DIR/pacman"
|
||||
INSTANCE_PACMAN_GNUPG="$INSTANCE_PACMAN_DIR/gnupg"
|
||||
INSTANCE_PACMAN_SYNC="$INSTANCE_PACMAN_DIR/sync"
|
||||
INSTANCE_PACMAN_MIRRORLIST="$PACWRAP_CONFIG_DIR/pacman.d/mirrorlist"
|
||||
INSTANCE_PACMAN_CACHE="$PACWRAP_CACHE_DIR/pkg"
|
||||
|
||||
INSTANCE_PACMAN_CFG_DIR="$PACWRAP_CONFIG_DIR/pacman"
|
||||
|
||||
init() {
|
||||
runtime_check
|
||||
|
||||
[[ $SWITCH == *n* ]] && SWITCH_NOCONFIRM=1
|
||||
[[ $SWITCH == *v* ]] && VERBOSE="/dev/stdout"
|
||||
[[ ! -f $LOG_FILE ]] && touch $LOG_FILE
|
||||
|
||||
[[ ! $1 ]] && [[ -f $LOCK_FILE ]] &&
|
||||
log_error "pacwrap is locked: $LOCK_FILE$RESET" 2
|
||||
|
||||
|
||||
local list="ls -U -1F $INSTANCE_ROOT_DIR"
|
||||
local rootlist=$($list 2>/dev/null | grep -i "/" | tr -d "/")
|
||||
|
||||
for instance in $rootlist; do
|
||||
source_configuration
|
||||
populate_configuration
|
||||
populate_container_array
|
||||
done
|
||||
|
||||
if [[ $SWITCH == v ]]; then
|
||||
VER_DISPLAY=$EXEC_NAME pacwrap -v
|
||||
exit
|
||||
fi
|
||||
|
||||
script_init
|
||||
perform_datadir_check
|
||||
}
|
||||
|
||||
populate_container_array() {
|
||||
case $TYPE in
|
||||
BASE)
|
||||
baserootdeps+=($instance)
|
||||
;;
|
||||
DEP)
|
||||
rootdeps+=($instance)
|
||||
;;
|
||||
*)
|
||||
roots+=($instance)
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
source_configuration() {
|
||||
source $INSTANCE_CONFIG_DIR/$instance
|
||||
}
|
||||
|
||||
populate_configuration() {
|
||||
INSTANCE_CONFIG[$instance,0]=$TYPE
|
||||
INSTANCE_CONFIG[$instance,1]="deps=(${DEPS[@]})"
|
||||
INSTANCE_CONFIG[$instance,2]=$SYNC_PACMANDB
|
||||
INSTANCE_CONFIG[$instance,3]="pkgs=(${PKG[@]})"
|
||||
}
|
||||
|
||||
return_sync_pacmandb() {
|
||||
echo ${INSTANCE_CONFIG[$instance,2]}
|
||||
}
|
||||
|
||||
return_base() {
|
||||
[[ $(return_type) == "BASE" ]] && echo $instance && return
|
||||
eval ${INSTANCE_CONFIG[$instance,1]}
|
||||
echo ${deps[0]}
|
||||
}
|
||||
|
||||
return_dependencies() {
|
||||
eval ${INSTANCE_CONFIG[$instance,1]}
|
||||
echo ${deps[@]}
|
||||
}
|
||||
|
||||
return_packages() {
|
||||
eval ${INSTANCE_CONFIG[$instance,3]}
|
||||
echo ${pkgs[@]}
|
||||
}
|
||||
|
||||
return_type() {
|
||||
echo ${INSTANCE_CONFIG[$instance,0]}
|
||||
}
|
||||
|
||||
return_dependency() {
|
||||
eval ${INSTANCE_CONFIG[$instance,1]}
|
||||
echo ${deps[$((${#deps[@]} - 1))]}
|
||||
}
|
||||
|
||||
return_pacman_template() {
|
||||
echo "$INSTANCE_PACMAN_CFG_DIR/template/pacman.$1$INSTANCE.conf"
|
||||
}
|
||||
|
||||
return_pacman_sync() {
|
||||
echo "$INSTANCE_PACMAN_CFG_DIR/sync/pacman.$1$INSTANCE.conf"
|
||||
}
|
||||
|
||||
return_pacman_syncdb() {
|
||||
echo "$INSTANCE_PACMAN_CFG_DIR/syncdb/pacman.$1$INSTANCE.conf"
|
||||
}
|
||||
|
||||
log () {
|
||||
printf "%s$RESET\n" "$1"
|
||||
[[ $2 ]] && case $2 in
|
||||
1)
|
||||
log_to_file "$1"
|
||||
;;
|
||||
*)
|
||||
log_to_file "$2"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
log_error() {
|
||||
case $1 in
|
||||
$LOG_ERR_HELP)
|
||||
printf "%s %s\n%s\n" "$EXEC_NAME error:" "$2" \
|
||||
"Try 'pacwrap -h' for more information on valid operational parameters."
|
||||
exit
|
||||
;;
|
||||
$ARROW_RED)
|
||||
printf "$ARROW_RED %s\n %s\n" "$2" "$3"
|
||||
log_to_file "$2"
|
||||
[[ $4 ]] && exit $4
|
||||
;;
|
||||
$LOG_ERR_WARN)
|
||||
printf "$BOLD$YELLOW%s$RESET %s\n" "warning:" "$2"
|
||||
[[ $3 ]] && exit $3
|
||||
;;
|
||||
*)
|
||||
printf "$BOLD$RED%s$RESET %s\n" "error:" "$1"
|
||||
[[ $2 ]] && exit $2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
log_to_file() {
|
||||
printf "[%s] [%s] %s\n" $(date '+%FT%H:%M:%S%z') $EXEC_NAME "$1" >>$LOG_FILE
|
||||
}
|
||||
|
||||
print_progress_bar() {
|
||||
printf "\r$PROGRESS_LABEL$RESET"
|
||||
printf "%-*s" $(($2+1)) '[' | tr ' ' '#'
|
||||
printf "%*s% 3d%%\r" $(($1-$2)) "]" "$3"
|
||||
}
|
||||
|
||||
|
||||
init_progress() {
|
||||
TTY_SIZE=($(stty size))
|
||||
PROGRESS_LENGTH=$((${TTY_SIZE[1]}/2))
|
||||
}
|
||||
|
||||
set_progress_label() {
|
||||
[[ $PROGRESS_OFF ]] && printf "\r%s" "$2 $1" && return
|
||||
|
||||
PROGRESS_LABEL="$1"
|
||||
|
||||
local label_length=${#PROGRESS_LABEL}
|
||||
local padding_length=$(($PROGRESS_LENGTH-$label_length-8))
|
||||
|
||||
[[ $2 ]] && PROGRESS_LABEL="$2 $1" && padding_length=$(($padding_length-3))
|
||||
|
||||
|
||||
for ((i=0; i<=padding_length; i+=1)); do
|
||||
PROGRESS_LABEL+=" "
|
||||
done
|
||||
|
||||
progress_bar
|
||||
}
|
||||
|
||||
progress_bar() {
|
||||
[[ $PROGRESS_OFF ]] && return
|
||||
|
||||
local bar_percent=$(($((PROGRESS_LENGTH*2))*$amt_done/$amt % 2 + $PROGRESS_LENGTH*$amt_done/$amt))
|
||||
local percent=$((200*$amt_done/$amt % 2 + 100*$amt_done/$amt))
|
||||
|
||||
print_progress_bar $((PROGRESS_LENGTH+1)) $bar_percent $percent
|
||||
}
|
||||
|
||||
query_confirm_yN () {
|
||||
if [[ $SWITCH == *n* ]]; then
|
||||
echo 1
|
||||
return
|
||||
fi
|
||||
read -rp "$BAR $@ [y/N]$RESET " input
|
||||
if [[ "$input" != "y" ]] &&
|
||||
[[ "$input" != "Y" ]] &&
|
||||
([[ "$input" == "" ]] ||
|
||||
[[ "$input" != "" ]]); then
|
||||
return
|
||||
fi
|
||||
echo 1
|
||||
}
|
||||
|
||||
query_confirm_Yn () {
|
||||
if [[ $SWITCH == *n* ]]; then
|
||||
echo 1
|
||||
return
|
||||
fi
|
||||
read -rp "$BAR $@ [Y/n]$RESET " input
|
||||
if [[ "$input" != "Y" ]] &&
|
||||
[[ "$input" != "y" ]] &&
|
||||
[[ "$input" != "" ]]; then
|
||||
return
|
||||
fi
|
||||
echo 1
|
||||
}
|
||||
|
||||
perform_datadir_check() {
|
||||
([[ ! -d $PACWRAP_DATA_DIR ]] ||
|
||||
[[ ! -d $PACWRAP_CACHE_DIR ]] ||
|
||||
[[ ! -d $PACWRAP_CONFIG_DIR ]]) &&
|
||||
initialize_data_directory
|
||||
|
||||
([[ ! -d $PACWRAP_DATA_DIR ]] ||
|
||||
[[ ! -d $PACWRAP_CACHE_DIR ]] ||
|
||||
[[ ! -d $PACWRAP_CONFIG_DIR ]]) &&
|
||||
printf "$BOLD$RED%s$RESET %s\n%s" "error:" "Data directories not found." && exit 2
|
||||
}
|
||||
|
||||
initialize_data_directory() {
|
||||
mkdir -p $PACWRAP_DATA_DIR/root \
|
||||
$PACWRAP_DATA_DIR/home \
|
||||
$PACWRAP_DATA_DIR/database \
|
||||
$PACWRAP_DATA_DIR/pacman/sync \
|
||||
$PACWRAP_DATA_DIR/pacman/gnupg \
|
||||
$PACWRAP_CACHE_DIR/pkg \
|
||||
$PACWRAP_CONFIG_DIR/root \
|
||||
$PACWRAP_CONFIG_DIR/pacman.d \
|
||||
$PACWRAP_CONFIG_DIR/pacman/sync \
|
||||
$PACWRAP_CONFIG_DIR/pacman/syncdb \
|
||||
$PACWRAP_CONFIG_DIR/pacman/template \
|
||||
$PACWRAP_CONFIG_DIR/bwrap
|
||||
|
||||
local ins_string="\[options\]"
|
||||
local template="\n\n###IGNOREPKG###\n"
|
||||
|
||||
([[ ! -f $INSTANCE_PACMAN_MIRRORLIST ]] || [[ $SWITCH == *m* ]]) && cp /etc/pacman.d/mirrorlist $INSTANCE_PACMAN_MIRRORLIST
|
||||
[[ ! -f $INSTANCE_PACMAN_CFG_DIR/pacman.conf ]] && echo -e $(pacman_conf) > $INSTANCE_PACMAN_CFG_DIR/pacman.conf
|
||||
|
||||
cat $INSTANCE_PACMAN_CFG_DIR/pacman.conf | sed -z "s,$ins_string,$ins_string$template,g" > $INSTANCE_PACMAN_CFG_DIR/pacman.template.conf
|
||||
}
|
||||
|
||||
pacman_conf() {
|
||||
echo $(cat << _CONFIG
|
||||
[options]\nHoldPkg = pacman glibc\nArchitecture = auto\nNoExtract = pacman-mirrorlist\n\nColor\nCheckSpace
|
||||
\n#ParallelDownloads = 5\n\nSigLevel = Required DatabaseOptional\nLocalFileSigLevel = Optional\n\n#[testing]
|
||||
\n#Include = /etc/pacman.d/mirrorlist\n\n[core]\nInclude = /etc/pacman.d/mirrorlist\n\n[extra]
|
||||
\nInclude = /etc/pacman.d/mirrorlist\n\n#[community-testing]\n#Include = /etc/pacman.d/mirrorlist
|
||||
\n\n[community]\nInclude = /etc/pacman.d/mirrorlist\n\n#[multilib-testing]\n#Include = /etc/pacman.d/mirrorlist
|
||||
\n\n#[multilib]\n#Include = /etc/pacman.d/mirrorlist
|
||||
_CONFIG
|
||||
)
|
||||
}
|
||||
|
||||
generate_config() {
|
||||
local config=$(cat << _CONFIG
|
||||
##\n## Configuration for $instance container\n## generated on $(date "+%F %T") by $EXEC_NAME.
|
||||
\n##\n\n# Container type (DO NOT EDIT)\nTYPE=($(return_type))\n\n# Container dependency array (DO NOT EDIT)
|
||||
\nDEPS=($(return_dependencies))\n\n# Container explicit install array\nPKG=($@)\n\n# Forcibly apply pacman -Sy to container
|
||||
\n# Not applicable to ROOT containers\nSYNC_PACMANDB=$(return_sync_pacmandb)
|
||||
_CONFIG
|
||||
)
|
||||
echo -e $config > $INSTANCE_CONFIG_DIR/$instance
|
||||
}
|
||||
|
||||
runtime_check() {
|
||||
if [[ ! $(type -P bwrap) ]] || [[ ! $(type -P bwrap) ]] || [[ ! $(type -P pacman-key gpg) ]]; then
|
||||
cat << _WARN
|
||||
$BOLD${RED}error:$RESET Requisite dependencies are missing.
|
||||
Please make sure that the following binaries are present in \$PATH:
|
||||
|
||||
${BOLD}bwrap$RESET, ${BOLD}zstd$RESET, ${BOLD}pacman-key$RESET or ${BOLD}gpg$RESET.
|
||||
|
||||
_WARN
|
||||
exit 2
|
||||
fi
|
||||
}
|
|
@ -18,33 +18,22 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
BOLD=$(tput bold)
|
||||
RED=$(tput setaf 1)
|
||||
RESET=$(tput sgr0)
|
||||
source pacwrap-common
|
||||
|
||||
EXEC_NAME="pacwrap-exec"
|
||||
|
||||
main () {
|
||||
|
||||
export PACWRAP_EXEC=1
|
||||
parse_args "$@"
|
||||
init 1
|
||||
|
||||
if [[ $SWITCH == v ]]; then
|
||||
VER_DISPLAY=$EXEC_NAME pachwrap -v
|
||||
exit
|
||||
fi
|
||||
[[ ! $INSTANCE ]] &&
|
||||
log_error $LOG_ERR_HELP "Target not specified." 1
|
||||
|
||||
|
||||
if [[ $SANDBOX == "" ]]; then
|
||||
echo "$EXEC_NAME $BOLD${RED}ERROR$RESET: Target not specified."
|
||||
echo "Try 'pacwrap -h' for more information on valid operational parameters."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
init_vars
|
||||
|
||||
if [[ ! -d $INSTANCE_ROOT ]] || [[ ! -d $INSTANCE_HOME ]]; then
|
||||
echo "$EXEC_NAME $BOLD${RED}ERROR$RESET: Sandbox $SANDBOX not found."
|
||||
echo "Try 'pacwrap -h' for more information on valid operational parameters."
|
||||
exit 1
|
||||
fi
|
||||
[[ ! -d $INSTANCE_ROOT ]] || [[ ! -d $INSTANCE_HOME ]] &&
|
||||
log_error $LOG_ERR_HELP "Container $INSTANCE not found." 1
|
||||
|
||||
|
||||
case $SWITCH in
|
||||
*rc*|*cr*)
|
||||
|
@ -62,24 +51,12 @@ main () {
|
|||
esac
|
||||
}
|
||||
|
||||
init_vars () {
|
||||
INSTANCE_DATA_DIR="$HOME/.local/share/pacwrap"
|
||||
INSTANCE_CACHE_DIR="$HOME/.cache/pacwrap/pkg"
|
||||
INSTANCE_CONFIG_DIR="$HOME/.config/pacwrap"
|
||||
|
||||
if [[ $PACWRAP_DEBUG ]]; then
|
||||
INSTANCE_DATA_DIR="$PACWRAP_DEBUG"
|
||||
INSTANCE_CONFIG_DIR="$PACWRAP_DEBUG/cfg"
|
||||
fi
|
||||
|
||||
LOG_FILE="$INSTANCE_DATA_DIR/pacwrap.log"
|
||||
INSTANCE_ROOT_DIR=$INSTANCE_DATA_DIR/root
|
||||
INSTANCE_HOME_DIR=$INSTANCE_DATA_DIR/home
|
||||
INSTANCE_ROOT=$INSTANCE_ROOT_DIR/$SANDBOX
|
||||
INSTANCE_HOME=$INSTANCE_HOME_DIR/$SANDBOX
|
||||
script_init () {
|
||||
INSTANCE_ROOT=$INSTANCE_ROOT_DIR/$INSTANCE
|
||||
INSTANCE_HOME=$INSTANCE_HOME_DIR/$INSTANCE
|
||||
INSTANCE_USER=user
|
||||
INSTANCE_HOME_MOUNT=/home/$INSTANCE_USER
|
||||
INSTANCE_SCRIPT="$INSTANCE_CONFIG_DIR/bwrap/$SANDBOX.sh"
|
||||
INSTANCE_SCRIPT="$PACWRAP_CONFIG_DIR/bwrap/$INSTANCE.sh"
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,7 +83,7 @@ parse_args () {
|
|||
;;
|
||||
*)
|
||||
if [[ ! $sbdefined ]]; then
|
||||
SANDBOX=$var
|
||||
INSTANCE=$var
|
||||
sbdefined=1
|
||||
continue
|
||||
fi
|
||||
|
@ -134,16 +111,16 @@ execute_fakeroot() {
|
|||
--ro-bind /usr/bin/fakechroot /usr/bin/fakechroot \
|
||||
--ro-bind /usr/bin/faked /usr/bin/faked \
|
||||
--ro-bind /etc/resolv.conf /etc/resolv.conf \
|
||||
--ro-bind $INSTANCE_CONFIG_DIR/pacman/sync/pacman.$SANDBOX.conf /etc/pacman.conf \
|
||||
--ro-bind /etc/localtime /etc/localtime \
|
||||
--bind $INSTANCE_DATA_DIR/pacman/sync /var/lib/pacman/sync \
|
||||
--bind $INSTANCE_DATA_DIR/pacman/gnupg /etc/pacman.d/gnupg \
|
||||
--bind $INSTANCE_CACHE_DIR /var/cache/pacman/pkg \
|
||||
--bind $INSTANCE_PACMAN_SYNC /var/lib/pacman/sync \
|
||||
--bind $INSTANCE_PACMAN_GNUPG /etc/pacman.d/gnupg \
|
||||
--bind $INSTANCE_PACMAN_CACHE /var/cache/pacman/pkg \
|
||||
--dev /dev \
|
||||
--proc /proc \
|
||||
--tmpfs /tmp \
|
||||
--ro-bind $INSTANCE_CONFIG_DIR/pacman/syncdb/pacman.$SANDBOX.conf /tmp/pacman.conf \
|
||||
--ro-bind $INSTANCE_CONFIG_DIR/pacman.d/mirrorlist /etc/pacman.d/mirrorlist \
|
||||
--ro-bind $(return_pacman_syncdb) /tmp/pacman.conf \
|
||||
--ro-bind $(return_pacman_sync) /etc/pacman.conf \
|
||||
--ro-bind $INSTANCE_PACMAN_MIRRORLIST /etc/pacman.d/mirrorlist \
|
||||
--bind $LOG_FILE /tmp/pacman.log \
|
||||
--bind $INSTANCE_HOME $INSTANCE_HOME_MOUNT \
|
||||
--unshare-all \
|
||||
|
|
530
bin/pacwrap-sync
530
bin/pacwrap-sync
|
@ -18,17 +18,11 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
BOLD=$(tput bold)
|
||||
RED=$(tput setaf 1)
|
||||
GREEN=$(tput setaf 2)
|
||||
CYAN=$(tput setaf 6)
|
||||
YELLOW=$(tput setaf 11)
|
||||
RESET=$(tput sgr0)
|
||||
BAR="$RED$BOLD::$RESET$BOLD"
|
||||
BAR_GREEN="$GREEN$BOLD::$RESET$BOLD"
|
||||
ARROW="$CYAN$BOLD->$RESET"
|
||||
ARROW_GREEN="$GREEN$BOLD->$RESET"
|
||||
ARROW_RED="$RED$BOLD->$RESET"
|
||||
source pacwrap-common
|
||||
|
||||
declare -A updated
|
||||
declare -A synced
|
||||
declare -A syncreq
|
||||
|
||||
EXEC_NAME="pacwrap-sync"
|
||||
EXEC_SCRIPT="pacwrap-exec --root --exec"
|
||||
|
@ -36,50 +30,58 @@ EXEC_SCRIPT="pacwrap-exec --root --exec"
|
|||
LINKFILES=("bin" "lib" "lib32" "share")
|
||||
|
||||
main () {
|
||||
parse_args $@
|
||||
|
||||
if [[ $SWITCH == v ]]; then
|
||||
VER_DISPLAY=$EXEC_NAME pacwrap -v
|
||||
exit
|
||||
fi
|
||||
export PACWRAP_UTILS=1
|
||||
trap abort INT
|
||||
|
||||
local roots=()
|
||||
local rootdeps=()
|
||||
local baserootdeps=()
|
||||
local syncroots=()
|
||||
local syncreq=
|
||||
|
||||
init_vars
|
||||
parse_args $@
|
||||
init $PACWRAP_CREATE
|
||||
|
||||
[[ ! $SWITCH ]] && log_error "No switch provided." 1
|
||||
|
||||
log_to_file "Running '$RUNTIME_ARGS'"
|
||||
|
||||
if [[ $SWITCH == *g* ]]; then
|
||||
generate_pacman_conf ${ARGS[@]}
|
||||
return
|
||||
log "$ARROW Configuring container..."
|
||||
local instance=${ARGS[0]}
|
||||
check_root "pacman.conf generation"
|
||||
sync_pacman_conf
|
||||
exit
|
||||
fi
|
||||
|
||||
[[ $SWITCH == *yyyy* ]] && SYNCREQ=1
|
||||
|
||||
if [[ $SWITCH == *u* ]] || ([[ $SWITCH == *y* ]] && [[ ! $SYNCREQ ]]); then
|
||||
log $BAR "Update container \n\n${baserootdeps[@]} ${rootdeps[@]} ${roots[@]}\n"
|
||||
|
||||
[[ ! "$(query_confirm "Proceed with update?")" ]] && return
|
||||
generate_pacman_conf ${baserootdeps[@]} ${rootdeps[@]}
|
||||
if [[ $SYNC_UPGRADE ]] || ([[ $SYNC_UPDATE ]] && [[ ! $SYNC_FORCE ]]); then
|
||||
log "$BAR_GREEN Starting container upgrade..."
|
||||
[[ ! $SWITCH_NOCONFIRM ]] && echo -e $BAR "Update container \n\n${baserootdeps[@]} ${rootdeps[@]} ${roots[@]}\n"
|
||||
[[ ! "$(query_confirm_Yn "Proceed with update?")" ]] && return
|
||||
configure_containers ${baserootdeps[@]} ${rootdeps[@]}
|
||||
update ${baserootdeps[@]} ${rootdeps[@]}
|
||||
fi
|
||||
|
||||
if [[ $SWITCH == *yyy* ]] || [[ $SYNCREQ == 1 ]]; then
|
||||
[[ $PACWRAP_CREATE ]] && syncroots=${roots[@]}
|
||||
log $BAR_GREEN "Synchronizing container structures..."
|
||||
generate_cache ${baserootdeps[@]}
|
||||
update_links ${rootdeps[@]} ${syncroots[@]}
|
||||
cleanup_cache ${rootdeps[@]} ${baserootdeps[@]}
|
||||
[[ $SWITCH == *yyyy* ]] && return
|
||||
fi
|
||||
[[ ${#roots[@]} > 0 ]] && [[ ! $SYNC_FORCE ]] &&
|
||||
log "$BAR_GREEN Starting contingent container upgrade..."
|
||||
|
||||
if [[ $SWITCH == *u* ]] || [[ $SWITCH == *y* ]]; then
|
||||
generate_pacman_conf ${roots[@]}
|
||||
for b in ${baserootdeps[@]}; do
|
||||
[[ ${syncreq[$(return_base)]} ]] && syncreq=1 && break; done
|
||||
|
||||
if [[ $SYNC_OVERRIDE ]] || [[ $syncreq ]]; then
|
||||
update_links ${syncroots[@]}
|
||||
cleanup_cache ${rootdeps[@]} ${baserootdeps[@]}
|
||||
[[ $SYNC_FORCE ]] && return
|
||||
fi
|
||||
|
||||
[[ ${#roots[@]} -le 0 ]] && return
|
||||
|
||||
if [[ $SYNC_UPGRADE ]] || [[ $SYNC_UPDATE ]]; then
|
||||
configure_containers ${roots[@]}
|
||||
update ${roots[@]}
|
||||
if [[ -f /usr/bin/paccache ]]; then
|
||||
paccache --cachedir $INSTANCE_CACHE_DIR -r -k 1 --min-mtime "14 days ago"
|
||||
fi
|
||||
[[ -f /usr/bin/paccache ]] &&
|
||||
paccache --cachedir $INSTANCE_PACMAN_CACHE -r -k 1 --min-mtime "14 days ago"
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -98,8 +100,8 @@ parse_args () {
|
|||
--sync|-y)
|
||||
SWITCH=y$SWITCH
|
||||
;;
|
||||
-*)
|
||||
SWITCH=$(echo $var | cut -c 2-)
|
||||
-S*)
|
||||
SWITCH=$(echo $var | cut -c 3-)
|
||||
;;
|
||||
*)
|
||||
ARGS+=("$var")
|
||||
|
@ -108,60 +110,39 @@ parse_args () {
|
|||
done
|
||||
}
|
||||
|
||||
init_vars() {
|
||||
INSTANCE_DATA_DIR="$HOME/.local/share/pacwrap"
|
||||
INSTANCE_CACHE_DIR="$HOME/.cache/pacwrap/pkg"
|
||||
INSTANCE_CONFIG_DIR="$HOME/.config/pacwrap"
|
||||
script_init () {
|
||||
[[ $SWITCH == *y* ]] && SYNC_UPDATE=1
|
||||
[[ $SWITCH == *u* ]] && SYNC_UPGRADE=1
|
||||
[[ $SWITCH == *yy* ]] && SYNC_FOREIGN=1
|
||||
[[ $SWITCH == *yyy* ]] && SYNC_OVERRIDE=1
|
||||
[[ $SWITCH == *yyyy* ]] && SYNC_FORCE=1
|
||||
|
||||
if [[ $PACWRAP_DEBUG ]]; then
|
||||
INSTANCE_DATA_DIR="$PACWRAP_DEBUG"
|
||||
INSTANCE_CONFIG_DIR="$PACWRAP_DEBUG/cfg"
|
||||
fi
|
||||
|
||||
VERBOSE="/dev/null"
|
||||
[[ $SWITCH == *v* ]] && VERBOSE="/dev/stdout"
|
||||
|
||||
LOG_FILE="$INSTANCE_DATA_DIR/pacwrap.log"
|
||||
OUTPUT_DEST=$LOG_FILE
|
||||
|
||||
INSTANCE_ROOT=$INSTANCE_DATA_DIR/root
|
||||
INSTANCE_DB_ROOT=$INSTANCE_DATA_DIR/database
|
||||
INSTANCE_CONFIG_ROOT=$INSTANCE_CONFIG_DIR/root
|
||||
INSTANCE_PACMAN_SYNC=$INSTANCE_CONFIG_DIR/pacman/sync
|
||||
INSTANCE_PACMAN_SYNCDB=$INSTANCE_CONFIG_DIR/pacman/syncdb
|
||||
INSTANCE_PACMAN_TEMPLATE=$INSTANCE_CONFIG_DIR/pacman/template
|
||||
|
||||
if [[ ! -d $INSTANCE_ROOT ]]; then
|
||||
echo $BOLD$RED"error:$RESET Sandbox root is either missing or an environmental variable is misconfigured.$RESET"
|
||||
exit
|
||||
fi
|
||||
|
||||
local rootlist=$(ls -U -1F $INSTANCE_ROOT | grep -i "/" | tr -d "/")
|
||||
for sandbox in $rootlist; do
|
||||
local type=$(return_type)
|
||||
case $type in
|
||||
BASE)
|
||||
baserootdeps+=("$sandbox")
|
||||
;;
|
||||
DEP)
|
||||
rootdeps+=("$sandbox")
|
||||
;;
|
||||
*)
|
||||
roots+=("$sandbox")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
syncroots=${roots[@]}
|
||||
syncroots=(${roots[@]})
|
||||
|
||||
if [[ ${ARGS[@]} ]]; then
|
||||
roots=()
|
||||
for sandbox in $ARGS; do
|
||||
for instance in $ARGS; do
|
||||
check_root "container"
|
||||
[[ $? == 1 ]] && continue
|
||||
roots+=("$sandbox")
|
||||
[[ $(return_type) != "ROOT" ]] &&
|
||||
[[ ! $PACWRAP_CREATE ]] && continue
|
||||
roots+=("$instance")
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
[[ $SYNC_FORCE ]] && syncroots+=(${rootdeps[@]})
|
||||
|
||||
if [[ $PACWRAP_CREATE ]]; then
|
||||
local instance=${roots[0]}
|
||||
syncroots=($instance)
|
||||
for instance in $(return_dependencies); do
|
||||
[[ $(return_type) == "BASE" ]] && continue
|
||||
syncroots+=($instance)
|
||||
done
|
||||
fi
|
||||
|
||||
touch $LOCK_FILE
|
||||
trap on_exit EXIT
|
||||
}
|
||||
|
||||
invoke_link_deletion() {
|
||||
|
@ -179,133 +160,161 @@ invoke_link_deletion() {
|
|||
}
|
||||
|
||||
invoke_update_link() {
|
||||
local sandbox=$1
|
||||
|
||||
if [[ ${synced[$sandbox]} ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ $(return_type) == "BASE" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local instance=$1
|
||||
local linkfiles=${LINKFILES[@]}
|
||||
local dep=$(return_dependency)
|
||||
|
||||
if [[ $SWITCH != *f* ]]; then
|
||||
for item in ${linkfiles[@]}; do
|
||||
local root=$INSTANCE_ROOT/$sandbox
|
||||
local link=$INSTANCE_DB_ROOT/$dep
|
||||
invoke_link_deletion
|
||||
# log_to_file "Deleted stray files from $dep/$item in $sandbox."
|
||||
done
|
||||
|
||||
[[ ${synced[$instance]} ]] && return
|
||||
|
||||
if [[ $(return_type) == "BASE" ]]; then
|
||||
invoke_generate_cache
|
||||
synced[$instance]=1
|
||||
return
|
||||
fi
|
||||
|
||||
local dep=$(return_dependency)
|
||||
|
||||
for item in ${linkfiles[@]}; do
|
||||
local root=$INSTANCE_ROOT/$sandbox
|
||||
local source=$INSTANCE_ROOT/$dep
|
||||
local root=$INSTANCE_ROOT_DIR/$instance
|
||||
local link=$INSTANCE_DB_DIR/$dep
|
||||
invoke_link_deletion
|
||||
#log_to_file "Deleted stray files from $dep/$item in $instance."
|
||||
|
||||
if [[ $amt ]]; then
|
||||
((amt_done++))
|
||||
progress_bar
|
||||
fi
|
||||
done
|
||||
|
||||
for item in ${linkfiles[@]}; do
|
||||
local root=$INSTANCE_ROOT_DIR/$instance
|
||||
local source=$INSTANCE_ROOT_DIR/$dep
|
||||
local src=$source/usr/$item
|
||||
local dest=$root/usr/
|
||||
|
||||
([[ ! -d $src ]] || [[ ! -d $dest ]]) && continue
|
||||
([[ ! -d $src ]] || [[ ! -d $dest ]]) && ((amt_done++)) && continue
|
||||
|
||||
cp -flR $src $dest 2>>$OUTPUT_DEST 1>>$OUTPUT_DEST
|
||||
log_to_file "Linked $sandbox/$item against $dep/$item."
|
||||
log_to_file "Linked $instance/$item against $dep/$item."
|
||||
|
||||
if [[ $amt ]]; then
|
||||
((amt_done++))
|
||||
progress_bar
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $(return_type) == "DEP" ]]; then
|
||||
invoke_generate_cache
|
||||
fi
|
||||
synced[$sandbox]=1
|
||||
[[ $(return_type) == "DEP" ]] && invoke_generate_cache
|
||||
[[ $ABORT ]] && exit 1
|
||||
|
||||
synced[$instance]=1
|
||||
}
|
||||
|
||||
update_links() {
|
||||
declare -A synced
|
||||
local amt=${#@}
|
||||
local amt_done=0
|
||||
|
||||
local amt=$((${#@} * 8))
|
||||
local check_root="link synchronization"
|
||||
|
||||
SYNC=1
|
||||
init_progress
|
||||
set_progress_label " Linking structures"
|
||||
set_progress_label "Linking structures" $ARROW
|
||||
|
||||
for sandbox in "$@"; do
|
||||
((amt_done++))
|
||||
progress_bar
|
||||
check_root "link synchronization"
|
||||
for instance in "$@"; do check_root $check_root
|
||||
[[ $? == 1 ]] && continue
|
||||
for dep in $(return_dependencies); do
|
||||
check_root "link synchronization"
|
||||
[[ $? == 1 ]] && continue
|
||||
invoke_update_link $dep
|
||||
local syncreq=$SYNC_OVERRIDE
|
||||
|
||||
for instance_dep in $(return_dependencies); do check_root $check_root
|
||||
[[ $? == 1 ]] && break
|
||||
[[ $syncreq ]] && invoke_update_link $instance_dep
|
||||
[[ ${synced[$instance_dep]} ]] && syncreq=1
|
||||
done
|
||||
invoke_update_link $sandbox
|
||||
done; echo
|
||||
|
||||
if [[ $syncreq ]]; then
|
||||
invoke_update_link $instance
|
||||
else
|
||||
((amt_done+=8))
|
||||
progress_bar
|
||||
fi
|
||||
done; SYNC= && echo
|
||||
}
|
||||
|
||||
cleanup_cache() {
|
||||
for sandbox in "$@"; do
|
||||
for instance in "$@"; do
|
||||
check_root "cache file operation"
|
||||
[[ $? == 1 ]] && continue
|
||||
|
||||
local linkfiles=${LINKFILES[@]}
|
||||
|
||||
for item in ${linkfiles[@]}; do
|
||||
[[ -f $INSTANCE_DB_ROOT/$sandbox/$item.old.zst ]] &&
|
||||
rm $INSTANCE_DB_ROOT/$sandbox/$item.old.zst 2>>$OUTPUT_DEST 1>>$OUTPUT_DEST
|
||||
[[ -f $INSTANCE_DB_DIR/$instance/$item.old.zst ]] &&
|
||||
rm $INSTANCE_DB_DIR/$instance/$item.old.zst 2>>$OUTPUT_DEST 1>>$OUTPUT_DEST
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
invoke_generate_cache() {
|
||||
local dep=$sandbox
|
||||
local dep=$instance
|
||||
local linkfiles=${LINKFILES[@]}
|
||||
|
||||
for item in ${linkfiles[@]}; do
|
||||
local root=$INSTANCE_ROOT/$sandbox
|
||||
local link=$INSTANCE_DB_ROOT/$sandbox
|
||||
local root=$INSTANCE_ROOT_DIR/$instance
|
||||
local link=$INSTANCE_DB_DIR/$instance
|
||||
local rdir=$root/usr/
|
||||
local tdir=$root/usr/$item
|
||||
|
||||
if ([[ ! -d $root ]] || [[ ! -d $tdir ]]); then
|
||||
log $ARROW_RED$RESET "Root or link target for $BOLD$sandbox$RESET not found..."
|
||||
log_to_file "Root or link target for $sandbox not found during synchronization operation."
|
||||
log_error "Root or link target for $BOLD$instance$RESET not found..."
|
||||
return
|
||||
fi
|
||||
|
||||
[[ -f $link/$item.zst ]] && mv $link/$item.zst $link/$item.old.zst 2>>$OUTPUT_DEST 1>>$OUTPUT_DEST
|
||||
find $tdir -type f,d,l | sed -z "s,$rdir,,g" | zstd -fq -o $link/$item.zst
|
||||
done
|
||||
log_to_file "Generated link cache for $sandbox!"
|
||||
}
|
||||
|
||||
generate_cache() {
|
||||
for sandbox in "$@"; do
|
||||
check_root "cache"
|
||||
[[ $? == 1 ]] && continue
|
||||
|
||||
invoke_generate_cache
|
||||
done
|
||||
log_to_file "Generated link cache for $instance!"
|
||||
}
|
||||
|
||||
check_root() {
|
||||
if [[ ! -d $INSTANCE_ROOT/$sandbox ]]; then
|
||||
log $ARROW_RED$RESET "Root for $BOLD$sandbox$RESET not found.$RESET\n Skipping $@..."
|
||||
if [[ ! -d $INSTANCE_ROOT_DIR/$instance ]]; then
|
||||
log_error $ARROW_RED "Root for $BOLD$instance$RESET not found." "Skipping..."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
invoke_vdb () {
|
||||
local root=$INSTANCE_ROOT/$sandbox
|
||||
local dep=
|
||||
update_config() {
|
||||
declare -A skip
|
||||
|
||||
local i=
|
||||
local local_pkgs=$($EXEC_SCRIPT $instance pacman -Qqe)
|
||||
local old_local_pkgs=$(return_packages)
|
||||
local package_list=()
|
||||
|
||||
if [[ $(return_type) != "ROOT" ]]; then
|
||||
dep=$sandbox
|
||||
else
|
||||
dep=$(return_dependency)
|
||||
if [[ $(return_type) != "BASE" ]]; then
|
||||
local pkgs=$($EXEC_SCRIPT $(return_dependency) pacman -Qqe)
|
||||
|
||||
for pkg in $pkgs; do
|
||||
skip[$pkg]=1
|
||||
done
|
||||
fi
|
||||
|
||||
declare -A skip
|
||||
local template="cat $INSTANCE_PACMAN_TEMPLATE/pacman.$dep.conf"
|
||||
for pkg in $local_pkgs; do
|
||||
[[ ${skip[$pkg]} ]] && continue
|
||||
package_list[i++]="$pkg"
|
||||
done
|
||||
|
||||
local pacmanconf=$INSTANCE_PACMAN_SYNC/pacman.$sandbox.conf
|
||||
[[ "$(echo ${package_list[@]})" != "$(echo ${old_local_pkgs[@]})" ]] &&
|
||||
generate_config ${package_list[@]}
|
||||
|
||||
((amt_done++))
|
||||
progress_bar
|
||||
}
|
||||
|
||||
sync_pacman_conf () {
|
||||
local dep=$instance
|
||||
|
||||
[[ $(return_type) == "ROOT" ]] && dep=$(return_dependency)
|
||||
|
||||
declare -A skip
|
||||
local template="cat $(return_pacman_template $dep)"
|
||||
|
||||
local pacmanconf=$(return_pacman_sync $instance)
|
||||
local ignorepkg="## Start of automated configuration ##\n"
|
||||
|
||||
if [[ $(return_type) != "BASE" ]]; then
|
||||
|
@ -333,12 +342,18 @@ invoke_vdb () {
|
|||
echo -e $header > $pacmanconf
|
||||
$template | sed -z "s/###IGNOREPKG###/$ignorepkg/g" >> $pacmanconf
|
||||
log_to_file "Generated $pacmanconf."
|
||||
invoke_vdb_update
|
||||
|
||||
if [[ $amt ]]; then
|
||||
((amt_done++))
|
||||
progress_bar
|
||||
fi
|
||||
|
||||
syncdb_pacman_conf
|
||||
}
|
||||
|
||||
invoke_vdb_update() {
|
||||
local pacmanconf=$INSTANCE_PACMAN_SYNCDB/pacman.$sandbox.conf
|
||||
local local_pkgs=$($EXEC_SCRIPT $sandbox pacman -Qq)
|
||||
syncdb_pacman_conf() {
|
||||
local pacmanconf=$(return_pacman_syncdb $instance)
|
||||
local local_pkgs=$($EXEC_SCRIPT $instance pacman -Qq)
|
||||
local ignorepkg="## Start of automated configuration ##\n"
|
||||
|
||||
if [[ $(return_type) != "BASE" ]]; then
|
||||
|
@ -352,145 +367,128 @@ invoke_vdb_update() {
|
|||
echo -e $header > $pacmanconf
|
||||
$template | sed -z "s/###IGNOREPKG###/$ignorepkg/g" >> $pacmanconf
|
||||
log_to_file "Generated $pacmanconf."
|
||||
|
||||
if [[ $amt ]]; then
|
||||
((amt_done++))
|
||||
progress_bar
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
invoke_update() {
|
||||
log_to_file "Checking $sandbox container for updates..."
|
||||
log $BAR_GREEN "Checking $sandbox for updates..."
|
||||
local instance=$1
|
||||
|
||||
[[ ${updated[$instance]} ]] && return
|
||||
updated[$instance]=1
|
||||
log "$BAR_GREEN Checking $instance for updates..." \
|
||||
"Checking $instance container for updates..."
|
||||
|
||||
|
||||
local type=$(return_type);
|
||||
local syncdb=$(return_pacman_syncdb)
|
||||
local syncdb=$(return_sync_pacmandb)
|
||||
|
||||
if [[ $SWITCH == *y* ]] && ([[ $type == "BASE" ]] || [[ $type == "DEP" ]]); then
|
||||
([[ ! $PMSYNCED ]] || ([[ $syncdb ]] && [[ $syncdb == 1 ]])) &&
|
||||
$EXEC_SCRIPT $sandbox pacman --logfile /tmp/pacman.log -Sy
|
||||
if [[ $SYNC_UPDATE ]] && [[ $type != "ROOT" ]]; then
|
||||
if [[ ! $PMSYNCED ]] || [[ $syncdb == 1 ]]; then
|
||||
$EXEC_SCRIPT $instance pacman --logfile /tmp/pacman.log -Sy
|
||||
[[ $? != 0 ]] &&
|
||||
log_error $ARROW_RED "Remote database synchronization failed." \
|
||||
"Use pacwrap -Sv and examine stdout for details." 1
|
||||
fi
|
||||
PMSYNCED=1
|
||||
fi
|
||||
|
||||
local result=$($EXEC_SCRIPT $sandbox pacman --color always -Qu | grep -v "ignored")
|
||||
local result=$($EXEC_SCRIPT $instance pacman --color always -Qu | grep -v "ignored")
|
||||
|
||||
if ([[ $SYNC_OVERRIDE ]] || [[ ${syncreq[$(return_base)]} ]]) &&
|
||||
[[ $type != "ROOT" ]]; then
|
||||
log "$ARROW Linking structures..."
|
||||
invoke_update_link $instance
|
||||
fi
|
||||
|
||||
if ([[ $SYNC_FOREIGN ]] || ([[ $result ]] && [[ $SYNC_UPGRADE ]])) &&
|
||||
[[ $(return_type) != "BASE" ]]; then
|
||||
log "$ARROW Synchronizing database against foreign packages..."
|
||||
$EXEC_SCRIPT $instance pacman -Su \
|
||||
--logfile /tmp/pacman.log \
|
||||
--dbonly --noconfirm \
|
||||
--config=/tmp/pacman.conf 2>/dev/null 1>$VERBOSE
|
||||
|
||||
[[ $? != 0 ]] &&
|
||||
log_error $ARROW_RED "Foreign database synchronization failed." \
|
||||
"Use pacwrap -Sv and examine stdout for details." 1
|
||||
|
||||
if ([[ $SWITCH == *yy* ]] || ([[ $result ]] && [[ $SWITCH == *u* ]])) && [[ $(return_type) != "BASE" ]]; then
|
||||
log $ARROW "Synchronizing database against foreign packages..."
|
||||
$EXEC_SCRIPT $sandbox pacman -Su --logfile /tmp/pacman.log --dbonly --noconfirm --config=/tmp/pacman.conf 2>/dev/null 1>$VERBOSE
|
||||
log " Database synchronization complete!"
|
||||
fi
|
||||
|
||||
if [[ ! $result ]]; then
|
||||
log "$ARROW Container $BOLD$sandbox$RESET is up to date!"
|
||||
log_to_file "Database up-to-date for $sandbox."
|
||||
log "$ARROW Container $BOLD$instance$RESET is up to date!" \
|
||||
"Database up-to-date for $instance."
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "$BAR Package changes: $RESET \n\n$result\n"
|
||||
[[ $SWITCH != *u* ]] && return
|
||||
[[ ! $(query_confirm "Proceed with installation on $sandbox") ]] && return
|
||||
log_to_file "Updating $sandbox container.."
|
||||
|
||||
[[ ! $SYNC_UPGRADE ]] && return
|
||||
[[ ! $(query_confirm_Yn "Proceed with installation on $instance") ]] && return
|
||||
|
||||
SYNCREQ=1
|
||||
$EXEC_SCRIPT $sandbox pacman -Su --logfile /tmp/pacman.log --noconfirm 2>/dev/null
|
||||
log $ARROW_GREEN "Upgrade complete!"
|
||||
log_to_file "Updating $instance container.."
|
||||
$EXEC_SCRIPT $instance pacman -Su \
|
||||
--logfile /tmp/pacman.log \
|
||||
--noconfirm 2>/dev/null
|
||||
|
||||
[[ $? != 0 ]] &&
|
||||
log_error $ARROW_RED "Upgrade for $instance failed." \
|
||||
"Use pacwrap -Sv and examine stdout for details." 1
|
||||
|
||||
if [[ $(return_type) != "ROOT" ]]; then
|
||||
log "$ARROW Generating link cache..."
|
||||
invoke_generate_cache $instance
|
||||
synced[$instance]=1
|
||||
fi
|
||||
|
||||
syncreq[$(return_base)]=1
|
||||
|
||||
log "$ARROW_GREEN Upgrade complete!"
|
||||
}
|
||||
|
||||
update () {
|
||||
for sandbox in "$@"; do
|
||||
update () {
|
||||
for instance in "$@"; do
|
||||
check_root "update"
|
||||
[[ $? == 1 ]] && continue
|
||||
invoke_update
|
||||
for dep in $(return_dependencies); do
|
||||
invoke_update $dep
|
||||
done
|
||||
|
||||
invoke_update $instance
|
||||
done
|
||||
}
|
||||
|
||||
print_progress_bar() {
|
||||
printf "$PROGRESS_LABEL"
|
||||
printf "%-*s" $(($2+1)) '[' | tr ' ' '#'
|
||||
printf "%*s% 3d%%\r" $(($1-$2)) "]" "$3"
|
||||
}
|
||||
|
||||
|
||||
init_progress() {
|
||||
TTY_SIZE=($(stty size))
|
||||
PROGRESS_LENGTH=$((${TTY_SIZE[1]}/2))
|
||||
}
|
||||
|
||||
|
||||
set_progress_label() {
|
||||
PROGRESS_LABEL="$1"
|
||||
local label_length=${#PROGRESS_LABEL}
|
||||
local padding_length=$(($PROGRESS_LENGTH-$label_length-8))
|
||||
for ((i=0; i<=padding_length; i+=1)); do
|
||||
PROGRESS_LABEL+=" "
|
||||
done
|
||||
}
|
||||
|
||||
progress_bar() {
|
||||
local bar_percent=$(($((PROGRESS_LENGTH*2))*$amt_done/$amt % 2 + $PROGRESS_LENGTH*$amt_done/$amt))
|
||||
local percent=$((200*$amt_done/$amt % 2 + 100*$amt_done/$amt))
|
||||
|
||||
print_progress_bar $((PROGRESS_LENGTH+1)) $bar_percent $percent
|
||||
}
|
||||
|
||||
generate_pacman_conf () {
|
||||
log $BAR_GREEN "Generating pacman configuration..."
|
||||
init_progress
|
||||
set_progress_label " pacman.conf"
|
||||
local amt=${#@}
|
||||
configure_containers () {
|
||||
local amt=$((${#@}*3))
|
||||
local amt_done=0
|
||||
|
||||
for sandbox in "$@"; do
|
||||
((amt_done++))
|
||||
progress_bar
|
||||
check_root "pacman.conf generation"
|
||||
init_progress
|
||||
set_progress_label "Configuring containers" $ARROW
|
||||
|
||||
for instance in "$@"; do check_root "pacman.conf generation"
|
||||
[[ $? == 1 ]] && continue
|
||||
invoke_vdb
|
||||
sync_pacman_conf
|
||||
done
|
||||
|
||||
for instance in "$@"; do check_root "configuration update"
|
||||
[[ $? == 1 ]] && continue
|
||||
update_config
|
||||
done; echo
|
||||
}
|
||||
|
||||
return_pacman_syncdb() {
|
||||
source $INSTANCE_CONFIG_ROOT/$sandbox
|
||||
echo $SYNC_PACMANDB
|
||||
abort () {
|
||||
echo
|
||||
ABORT=1
|
||||
[[ ! $SYNC ]] && exit
|
||||
}
|
||||
|
||||
return_type() {
|
||||
source $INSTANCE_CONFIG_ROOT/$sandbox
|
||||
echo $TYPE
|
||||
}
|
||||
|
||||
return_dependencies() {
|
||||
source $INSTANCE_CONFIG_ROOT/$sandbox
|
||||
echo ${DEPS[@]}
|
||||
}
|
||||
|
||||
return_base() {
|
||||
source $INSTANCE_CONFIG_ROOT/$sandbox
|
||||
echo ${DEPS[0]}
|
||||
}
|
||||
|
||||
return_dependency() {
|
||||
source $INSTANCE_CONFIG_ROOT/$sandbox
|
||||
echo ${DEPS[$((${#DEPS[@]} - 1))]}
|
||||
}
|
||||
|
||||
log () {
|
||||
echo -e "$@ $RESET"
|
||||
}
|
||||
|
||||
log_to_file() {
|
||||
echo -e "[$(date '+%FT%H:%M:%S%z')] [$EXEC_NAME] $@" >>$LOG_FILE
|
||||
}
|
||||
|
||||
|
||||
query_confirm () {
|
||||
if [[ $SWITCH == *n* ]]; then
|
||||
echo 1
|
||||
return
|
||||
fi
|
||||
read -rp "$BAR $@ [Y/n]$RESET " input
|
||||
if [[ "$input" != "Y" ]] &&
|
||||
[[ "$input" != "y" ]] &&
|
||||
[[ "$input" != "" ]]; then
|
||||
return
|
||||
fi
|
||||
echo 1
|
||||
on_exit() {
|
||||
[[ ! $PACWRAP_CREATE ]] && [[ -f $LOCK_FILE ]] && rm $LOCK_FILE
|
||||
}
|
||||
|
||||
main $@
|
||||
|
|
|
@ -18,45 +18,29 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
BOLD=$(tput bold)
|
||||
RED=$(tput setaf 1)
|
||||
GREEN=$(tput setaf 2)
|
||||
CYAN=$(tput setaf 6)
|
||||
YELLOW=$(tput setaf 11)
|
||||
RESET=$(tput sgr0)
|
||||
UNDERLINE=$(tput smul)
|
||||
|
||||
NUMFMT="numfmt --to=si --suffix=B --round=nearest --from-unit=1000 --format=%2f "
|
||||
|
||||
BAR="$RED$BOLD::$RESET$BOLD"
|
||||
BAR_GREEN="$GREEN$BOLD::$RESET$BOLD"
|
||||
ARROW="$CYAN$BOLD->$RESET"
|
||||
ARROW_GREEN="$GREEN$BOLD->$RESET"
|
||||
ARROW_RED="$RED$BOLD->$RESET"
|
||||
source pacwrap-common
|
||||
|
||||
EXEC_NAME="pacwrap-utils"
|
||||
EXEC_SCRIPT="pacwrap-exec"
|
||||
NUMFMT="numfmt --to=si --suffix=B --round=nearest --from-unit=1000 --format=%2f "
|
||||
|
||||
main () {
|
||||
parse_args $@
|
||||
export PACWRAP_UTILS=1
|
||||
trap exit INT
|
||||
|
||||
if [[ $SWITCH == v ]]; then
|
||||
VER_DISPLAY=$EXEC_NAME pacwrap -v
|
||||
exit
|
||||
fi
|
||||
|
||||
local roots=;
|
||||
local rootdeps=
|
||||
local baserootdeps=
|
||||
local roots=()
|
||||
local rootdeps=()
|
||||
local baserootdeps=()
|
||||
local syncroots=()
|
||||
local links=
|
||||
local total=0
|
||||
|
||||
init_vars
|
||||
parse_args $@
|
||||
init
|
||||
|
||||
if [[ ! -d $INSTANCE_ROOT ]] && [[ $SWITCH != i* ]]; then
|
||||
echo $BOLD$RED"error:$RESET Sandbox root is either missing or an environmental variable is misconfigured.$RESET"
|
||||
exit
|
||||
fi
|
||||
[[ $SWITCH != h* ]] &&
|
||||
[[ $SWITCH != v ]] &&
|
||||
[[ $SWITCH != ls* ]] &&
|
||||
[[ $SWITCH != v* ]] &&
|
||||
log_to_file "Running '$RUNTIME_ARGS'"
|
||||
|
||||
case $SWITCH in
|
||||
c*)
|
||||
|
@ -64,10 +48,12 @@ main () {
|
|||
paccache --cachedir $INSTANCE_CACHE_DIR ${ARGS[@]}
|
||||
fi
|
||||
;;
|
||||
|
||||
i*)
|
||||
initialize_data_directory
|
||||
;;
|
||||
r*)
|
||||
replicate ${baserootdeps[@]} ${rootdeps[@]} ${roots[@]}
|
||||
;;
|
||||
v*)
|
||||
edit_file 1
|
||||
;;
|
||||
|
@ -81,8 +67,8 @@ main () {
|
|||
link_root
|
||||
;;
|
||||
d*)
|
||||
[[ $SWITCH == *r* ]] && delete_root
|
||||
[[ $SWITCH == *h* ]] && delete_home
|
||||
[[ $SWITCH == *r* ]] && delete "root" "$INSTANCE_ROOT_DIR"
|
||||
[[ $SWITCH == *h* ]] && delete "home" "$INSTANCE_HOME_DIR"
|
||||
;;
|
||||
h*)
|
||||
pacwrap --help=utils
|
||||
|
@ -95,12 +81,26 @@ main () {
|
|||
fi
|
||||
echo "Try '$EXEC_NAME -h' for more information on valid operational parameters."
|
||||
;;
|
||||
|
||||
esac
|
||||
}
|
||||
|
||||
summary() {
|
||||
script_init () {
|
||||
[[ $REPLICATION_CONFIG_DIR ]] &&
|
||||
INSTANCE_CONFIG_DIR=$REPLICATION_CONFIG_DIR
|
||||
|
||||
local linklist=$($list 2>/dev/null | grep -i "@" | tr -d "@")
|
||||
|
||||
for f in $linklist; do
|
||||
links+=($f)
|
||||
done
|
||||
|
||||
touch $LOCK_FILE
|
||||
trap on_exit EXIT
|
||||
}
|
||||
|
||||
summary() {
|
||||
declare -A size
|
||||
local total=0
|
||||
|
||||
parse_du
|
||||
|
||||
|
@ -111,8 +111,7 @@ summary() {
|
|||
rm $tmpfile
|
||||
fi
|
||||
|
||||
if [[ $SWITCH == *d* ]]; then
|
||||
|
||||
if [[ $SWITCH == *d* ]]; then
|
||||
local actual_size=${size["root"]}
|
||||
local diff=$(($total - $actual_size))
|
||||
|
||||
|
@ -140,6 +139,9 @@ parse_args () {
|
|||
-U*)
|
||||
SWITCH=$(echo $var | cut -c 3-)
|
||||
;;
|
||||
--cfg-dir=*)
|
||||
REPLICATION_CONFIG_DIR=$(echo $var | cut -c 11-)
|
||||
;;
|
||||
*)
|
||||
ARGS+=("$var")
|
||||
;;
|
||||
|
@ -147,148 +149,190 @@ parse_args () {
|
|||
done
|
||||
}
|
||||
|
||||
init_vars() {
|
||||
INSTANCE_DATA_DIR="$HOME/.local/share/pacwrap"
|
||||
INSTANCE_CACHE_DIR="$HOME/.cache/pacwrap/pkg"
|
||||
INSTANCE_CONFIG_DIR="$HOME/.config/pacwrap"
|
||||
replicate() {
|
||||
local instances=()
|
||||
local baserootdeps=
|
||||
local rootdeps=
|
||||
local roots=
|
||||
|
||||
if [[ $PACWRAP_DEBUG ]]; then
|
||||
INSTANCE_DATA_DIR="$PACWRAP_DEBUG"
|
||||
INSTANCE_CONFIG_DIR="$PACWRAP_DEBUG/cfg"
|
||||
fi
|
||||
if [[ $SWITCH == *t* ]]; then
|
||||
local default=$([[ ${#ARGS[@]} -le 1 ]] && echo 1)
|
||||
local tar_archive=${ARGS[0]}
|
||||
|
||||
INSTANCE_ROOT=$INSTANCE_DATA_DIR/root
|
||||
INSTANCE_HOME=$INSTANCE_DATA_DIR/home
|
||||
INSTANCE_DB_ROOT=$INSTANCE_DATA_DIR/database
|
||||
INSTANCE_CONFIG_ROOT=$INSTANCE_CONFIG_DIR/root
|
||||
INSTANCE_PACMAND=$INSTANCE_CONFIG_DIR/etc/pacman.d
|
||||
|
||||
local list="ls -U -1F $INSTANCE_ROOT"
|
||||
local rootlist=$($list | grep -i "/" | tr -d "/")
|
||||
local linklist=$($list | grep -i "@" | tr -d "@")
|
||||
|
||||
for instance in $rootlist; do
|
||||
local type=$(return_type)
|
||||
case $type in
|
||||
BASE)
|
||||
baserootdeps+=($instance)
|
||||
;;
|
||||
DEP)
|
||||
rootdeps+=($instance)
|
||||
;;
|
||||
*)
|
||||
roots+=($instance)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for f in $linklist; do
|
||||
links+=($f)
|
||||
done
|
||||
}
|
||||
[[ ! $tar_archive ]] && log_error $LOG_ERR_HELP "tar not specified." 1
|
||||
[[ ! -f $tar_archive ]] && log_error "tar archive $tar_archive not found." 1
|
||||
|
||||
|
||||
delete_home() {
|
||||
local instances=${ARGS[@]};
|
||||
|
||||
if [[ ! $instances ]]; then
|
||||
printf "%s\n%s\n" "$EXEC_NAME: instance not specified." \
|
||||
"Try '$EXEC_NAME -h' for more information on valid operational parameters."
|
||||
return
|
||||
fi
|
||||
|
||||
printf "%s\n\n$BOLD%s\n\n$RESET" "$BAR Delete home" "$instances"
|
||||
|
||||
if [[ "$(query_confirm "Proceed with deletion?")" ]]; then
|
||||
local tar_list=($(tar tf ${ARGS[0]}))
|
||||
|
||||
for instance in $instances; do
|
||||
if [[ ! -d $INSTANCE_HOME/$instance ]]; then
|
||||
echo "$RED${BOLD}error:$RESET Home $instance does not exist."
|
||||
continue
|
||||
fi
|
||||
|
||||
rm -rf $INSTANCE_HOME/$instance
|
||||
printf "$ARROW_GREEN %s$RESET\n" "Deletion of $instance's home complete!"
|
||||
for file in ${tar_list[@]}; do
|
||||
local instance=${file##*/}
|
||||
local this=$default
|
||||
[[ ! $this ]] && for instance_list in ${ARGS[@]}; do
|
||||
[[ "$instance" == "$instance_list" ]] && this=1 && break; done
|
||||
[[ ! $instance ]] || [[ ! $this ]] && continue
|
||||
eval $(tar axfO $tar_archive $file | grep -v "#")
|
||||
populate_configuration
|
||||
populate_container_array
|
||||
instances+=($instance)
|
||||
done
|
||||
else
|
||||
instances=(${ARGS[@]})
|
||||
[[ ${#ARGS[@]} -le 0 ]] && instances=$@
|
||||
[[ ! $instances ]] && log_error $LOG_ERR_HELP "Instance not specified." 1
|
||||
|
||||
for instance in ${instances[@]}; do
|
||||
[[ ! -f $INSTANCE_CONFIG_DIR/$instance ]] && continue
|
||||
source_configuration
|
||||
populate_configuration
|
||||
populate_container_array
|
||||
done
|
||||
fi
|
||||
|
||||
[[ ! $SWITCH_NOCONFIRM ]] && echo -e "$BAR Replicate \n\n${instances[@]}\n"
|
||||
[[ ! "$(query_confirm_yN "Proceed with replication?")" ]] && return
|
||||
|
||||
invoke_replication ${baserootdeps[@]} ${rootdeps[@]} ${roots[@]}
|
||||
}
|
||||
|
||||
delete_root() {
|
||||
local instances=${ARGS[@]};
|
||||
|
||||
if [[ ! $instances ]]; then
|
||||
printf "%s\n%s\n" "$EXEC_NAME: instance not specified." \
|
||||
"Try '$EXEC_NAME -h' for more information on valid operational parameters."
|
||||
return
|
||||
invoke_replication() {
|
||||
if [[ $SWITCH = *d* ]]; then
|
||||
printf "$BAR_GREEN %s$RESET\n" "Deleting root instances..."
|
||||
for instance in $@; do
|
||||
[[ ! -d $INSTANCE_ROOT_DIR/$instance ]] && continue
|
||||
rm -rf $INSTANCE_ROOT_DIR/$instance
|
||||
printf "$ARROW_GREEN %s$RESET\n" "Deletion of $instance's root complete!"
|
||||
log_to_file "Deleted root $instance."
|
||||
done
|
||||
fi
|
||||
|
||||
printf "%s\n\n$BOLD%s\n\n$RESET" "$BAR Delete instance" "$instances"
|
||||
printf "$BAR_GREEN %s$RESET\n" "Replication of root filesystems from configuration..."
|
||||
|
||||
if [[ "$(query_confirm "Proceed with deletion?")" ]]; then
|
||||
declare -A completed
|
||||
|
||||
for instance in $instances; do
|
||||
if [[ ! -d $INSTANCE_ROOT/$instance ]]; then
|
||||
echo "$RED${BOLD}error:$RESET $instance does not exist."
|
||||
continue
|
||||
fi
|
||||
rm -rf $INSTANCE_ROOT/$instance
|
||||
|
||||
printf "$ARROW_GREEN %s$RESET\n" "Deletion of $instance complete!"
|
||||
for instance in $@; do
|
||||
local deps_return=$(return_dependencies)
|
||||
local deps=()
|
||||
|
||||
for dep in ${baserootdeps[@]}; do
|
||||
for depr in $deps_return; do
|
||||
[[ $dep == $depr ]] && deps+=($dep)
|
||||
done
|
||||
done
|
||||
|
||||
for dep in ${rootdeps[@]}; do
|
||||
for depr in $deps_return; do
|
||||
[[ $dep == $depr ]] && deps+=($dep)
|
||||
done
|
||||
done
|
||||
|
||||
for dep in ${deps[@]}; do
|
||||
replicate_instance $dep
|
||||
done
|
||||
|
||||
for depr in $deps_return; do
|
||||
if [[ ! -d $INSTANCE_ROOT_DIR/$depr ]]; then
|
||||
log_error $LOG_ERR_HELP "Dependency $depr not fulfilled for $instance."
|
||||
fi
|
||||
done
|
||||
|
||||
replicate_instance $instance
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
replicate_instance() {
|
||||
local instance=$1
|
||||
|
||||
[[ ${completed[$instance]} ]] && return
|
||||
|
||||
log_to_file "Beginning replication of $instance."
|
||||
|
||||
local type=$(return_type)
|
||||
local params="-Cn"
|
||||
|
||||
[[ $SWITCH == *v* ]] && params+="v"
|
||||
|
||||
case $type in
|
||||
BASE)
|
||||
params+="b"
|
||||
;;
|
||||
DEP)
|
||||
params+="d --dep=$(return_dependency)"
|
||||
;;
|
||||
ROOT)
|
||||
params+=" --dep=$(return_dependency)"
|
||||
;;
|
||||
esac
|
||||
|
||||
$CREATE_SCRIPT $params $instance $(return_packages)
|
||||
|
||||
if [[ $? == 0 ]]; then
|
||||
printf " %s$RESET\n" "Replication of $BOLD$instance$RESET complete!"
|
||||
log_to_file "Replication of $instance complete!"
|
||||
fi
|
||||
|
||||
completed[$instance]=1
|
||||
}
|
||||
|
||||
|
||||
delete() {
|
||||
local instances=${ARGS[@]};
|
||||
|
||||
[[ ! $instances ]] && log_error $LOG_ERR_HELP "Instance not specified."
|
||||
[[ ! $SWITCH_NOCONFIRM ]] && printf "%s\n\n$BOLD%s\n\n$RESET" "$BAR Delete $1" "$instances"
|
||||
[[ ! "$(query_confirm_yN "Proceed with $1?")" ]] && return
|
||||
|
||||
for instance in $instances; do
|
||||
if [[ ! -d $2/$instance ]]; then
|
||||
log_error $LOG_ERR_WARN "$instance does not exist."
|
||||
continue
|
||||
fi
|
||||
|
||||
rm -rf $2/$instance
|
||||
|
||||
printf "$ARROW_GREEN %s$RESET\n" "Deletion of $instance's $1 complete!"
|
||||
log_to_file "Deleted $instance's $1."
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
link_root() {
|
||||
local instance=${ARGS[1]};
|
||||
local link=${ARGS[0]};
|
||||
local instance=${ARGS[0]};
|
||||
local link=${ARGS[1]};
|
||||
|
||||
if [[ ! $instance ]] || [[ ! $link ]]; then
|
||||
printf "%s\n%s\n" "$EXEC_NAME: instance or link not specified." \
|
||||
"Try '$EXEC_NAME -h' for more information on valid operational parameters."
|
||||
return
|
||||
fi
|
||||
[[ ! $instance ]] && log_error $LOG_ERR_HELP "Instance not specified."
|
||||
[[ ! $link ]] && log_error $LOG_ERR_HELP "Link not specified."
|
||||
[[ -d $INSTANCE_ROOT_DIR/$instance ]] && log_error "$instance already exists." 1
|
||||
[[ ! -d $INSTANCE_ROOT_DIR/$link ]] && log_error "Instance $link doesn't exist." 1
|
||||
|
||||
if [[ -d $INSTANCE_ROOT/$instance ]]; then
|
||||
echo "$RED${BOLD}error:$RESET $instance already exists."
|
||||
return
|
||||
fi
|
||||
[[ ! $SWITCH_NOCONFIRM ]] && printf "$BAR%s\n\n$BOLD%s\n\n" "Create virtual instance" "$instance $ARROW $BOLD$link"
|
||||
[[ ! "$(query_confirm_Yn "Proceed with creation?")" ]] && return
|
||||
|
||||
if [[ ! -d $INSTANCE_ROOT/$link ]]; then
|
||||
echo "$RED${BOLD}error:$RESET $link doesn't exist."
|
||||
return
|
||||
fi
|
||||
log "$BAR_GREEN Creating virtual instance $instance $ARROW $BOLD$link"
|
||||
|
||||
printf "%s\n\n$BOLD%s\n\n" "$BAR Create virtual instance" "$instance $ARROW $link"
|
||||
ln -s $INSTANCE_ROOT_DIR/$link $INSTANCE_ROOT_DIR/$instance
|
||||
mkdir -p $INSTANCE_HOME_DIR/$instance
|
||||
echo 'PS1="'$instance'> "' > $INSTANCE_HOME_DIR/$instance/.bashrc
|
||||
|
||||
if [[ "$(query_confirm "Proceed with creation?")" ]]; then
|
||||
ln -s $INSTANCE_ROOT/$link $INSTANCE_ROOT/$instance
|
||||
|
||||
mkdir -p $INSTANCE_HOME/$instance
|
||||
echo 'PS1="'$instance'> "' > $INSTANCE_HOME/$instance/.bashrc
|
||||
|
||||
printf "$BAR_GREEN %s$RESET\n" "Creation of virtual instance $instance complete!"
|
||||
fi
|
||||
log "$ARROW_GREEN Process complete!" \
|
||||
"Created $instance -> $link"
|
||||
}
|
||||
|
||||
|
||||
parse_du() {
|
||||
for string in $(du -d 1 $INSTANCE_ROOT | tr ' ' '-'); do
|
||||
for string in $(du -d 1 $INSTANCE_ROOT_DIR | tr ' ' '-'); do
|
||||
local bytes=${string%%-*}
|
||||
local instance=${string##*/}
|
||||
|
||||
size["$instance"]=$bytes
|
||||
|
||||
|
||||
if [[ $SWITCH == *dd* ]] && [[ $SWITCH != *dddd* ]]; then
|
||||
[[ $instance == "root" ]] && continue
|
||||
local dh=$(du -d 1 $INSTANCE_ROOT/$instance | tail -n-1)
|
||||
local dh=$(du -d 1 $INSTANCE_ROOT_DIR/$instance | tail -n-1)
|
||||
bytes=${dh% *}
|
||||
size["$instance"]=$bytes
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
[[ $instance == "root" ]] && continue
|
||||
((total+=bytes))
|
||||
|
@ -305,7 +349,7 @@ list_root() {
|
|||
local bytes=0
|
||||
|
||||
if [[ ! ${size["$instance"]} ]]; then
|
||||
dep="$(ls -l $INSTANCE_ROOT/$instance | sed -z "s,$INSTANCE_ROOT/,,g")"
|
||||
dep="$(ls -l $INSTANCE_ROOT_DIR/$instance | sed -z "s,$INSTANCE_ROOT_DIR/,,g")"
|
||||
type="LINK"
|
||||
else
|
||||
bytes=${size["$instance"]}
|
||||
|
@ -334,10 +378,8 @@ edit_file() {
|
|||
EDITOR="vi"
|
||||
fi
|
||||
|
||||
if [[ ! -f $EDITOR ]]; then
|
||||
printf "%s%s\n" "$RED$BOLD" "error:$RESET \$EDITOR was not found at $EDITOR."
|
||||
exit
|
||||
fi
|
||||
[[ ! -f $(type -P $EDITOR) ]] &&
|
||||
log_error "\$EDITOR was not found at $EDITOR." 1
|
||||
|
||||
[[ $1 ]] && dissolve=1
|
||||
|
||||
|
@ -345,37 +387,37 @@ edit_file() {
|
|||
|
||||
case $SWITCH in
|
||||
*c*)
|
||||
file="$INSTANCE_CONFIG_ROOT/$instance"
|
||||
file="$INSTANCE_CONFIG_DIR/$instance"
|
||||
error="config file"
|
||||
;;
|
||||
*b*)
|
||||
file="$INSTANCE_CONFIG_DIR/bwrap/$instance.sh"
|
||||
file="$PACWRAP_CONFIG_DIR/bwrap/$instance.sh"
|
||||
error="bubblewrap script $file"
|
||||
create=1
|
||||
;;
|
||||
*ips*)
|
||||
file="$INSTANCE_CONFIG_DIR/pacman/syncdb/pacman.$instance.conf"
|
||||
file=$(return_pacman_syncdb $instance)
|
||||
error="instanced pacman $file"
|
||||
printf "##\n## %s\n" "For the purposes of overview or diagnostics only." > $tmpfile
|
||||
dissolve=1
|
||||
;;
|
||||
*ip*)
|
||||
file="$INSTANCE_CONFIG_DIR/pacman/sync/pacman.$instance.conf"
|
||||
file=$(return_pacman_sync $instance)
|
||||
error="instanced template $file"
|
||||
printf "##\n## %s\n" "For the purposes of overview or diagnostics only." > $tmpfile
|
||||
dissolve=1
|
||||
;;
|
||||
*l*)
|
||||
file="$INSTANCE_DATA_DIR/pacwrap.log"
|
||||
file="$PACWRAP_DATA_DIR/pacwrap.log"
|
||||
error="$file"
|
||||
dissolve=1
|
||||
;;
|
||||
*pt*)
|
||||
file="$INSTANCE_CONFIG_DIR/pacman/template/pacman.$instance.conf"
|
||||
file=$(return_pacman_template $instance)
|
||||
error="pacman template $file"
|
||||
;;
|
||||
*p*)
|
||||
file="$INSTANCE_CONFIG_DIR/pacman/pacman.conf"
|
||||
file="$INSTANCE_PACMAN_CFG_DIR/pacman.conf"
|
||||
error="default pacman.conf"
|
||||
;;
|
||||
*)
|
||||
|
@ -392,7 +434,6 @@ edit_file() {
|
|||
return
|
||||
fi
|
||||
|
||||
#sed -r "s/(\x1B\^O|\x1B\[[0-9;]*[JKmsu])//g"
|
||||
cat $file >> $tmpfile
|
||||
$EDITOR $tmpfile
|
||||
|
||||
|
@ -404,65 +445,20 @@ edit_file() {
|
|||
|
||||
if [[ "${tmp_sum% *}" != "${config_sum% *}" ]]; then
|
||||
cp $tmpfile $file
|
||||
log "$ARROW_GREEN Changes written." \
|
||||
"Changes written to $file."
|
||||
else
|
||||
echo "$BAR_GREEN No changes made.$RESET"
|
||||
log "$BAR_GREEN No changes made"
|
||||
fi
|
||||
else
|
||||
echo "$BAR_GREEN No changes made.$RESET"
|
||||
log "$BAR_GREEN No changes made."
|
||||
fi
|
||||
|
||||
rm $tmpfile
|
||||
}
|
||||
|
||||
initialize_data_directory() {
|
||||
mkdir -v -p $INSTANCE_DATA_DIR/root \
|
||||
$INSTANCE_DATA_DIR/home \
|
||||
$INSTANCE_DATA_DIR/database \
|
||||
$INSTANCE_DATA_DIR/pacman/sync \
|
||||
$INSTANCE_DATA_DIR/pacman/gnupg \
|
||||
$INSTANCE_CACHE_DIR \
|
||||
$INSTANCE_CONFIG_DIR/root \
|
||||
$INSTANCE_CONFIG_DIR/pacman.d \
|
||||
$INSTANCE_CONFIG_DIR/pacman/sync \
|
||||
$INSTANCE_CONFIG_DIR/pacman/syncdb \
|
||||
$INSTANCE_CONFIG_DIR/pacman/template \
|
||||
$INSTANCE_CONFIG_DIR/bwrap
|
||||
|
||||
local ins_string="\[options\]\n"
|
||||
local template="\n###IGNOREPKG###\n\n"
|
||||
local install="\nNoExtract = usr/lib/*\nNoExtract = usr/lib32/*\nNoExtract = usr/bin/*\nNoExtract = usr/share/*\n\n"
|
||||
|
||||
([[ ! -f $INSTANCE_CONFIG_DIR/pacman.d/mirrorlist ]] || [[ $SWITCH == *m* ]]) && cp /etc/pacman.d/mirrorlist $INSTANCE_CONFIG_DIR/pacman.d/mirrorlist
|
||||
[[ ! -f $INSTANCE_CONFIG_DIR/pacman/pacman.conf ]] && cp /etc/pacman.conf $INSTANCE_CONFIG_DIR/pacman/pacman.conf
|
||||
|
||||
cat $INSTANCE_CONFIG_DIR/pacman/pacman.conf | sed -z "s,$ins_string,$ins_string$template,g" > $INSTANCE_CONFIG_DIR/pacman/pacman.template.conf
|
||||
cat $INSTANCE_CONFIG_DIR/pacman/pacman.conf | sed -z "s,$ins_string,$ins_string$install,g" > $INSTANCE_CONFIG_DIR/pacman/pacman.install.conf
|
||||
}
|
||||
|
||||
|
||||
return_type() {
|
||||
source $INSTANCE_CONFIG_ROOT/$instance
|
||||
echo $TYPE
|
||||
}
|
||||
|
||||
return_dependency() {
|
||||
source $INSTANCE_CONFIG_ROOT/$instance
|
||||
echo ${DEPS[$((${#DEPS[@]} - 1))]}
|
||||
}
|
||||
|
||||
query_confirm () {
|
||||
if [[ $SWITCH == *n* ]]; then
|
||||
echo 1
|
||||
return
|
||||
fi
|
||||
read -rp "$BAR $@ [y/N]$RESET " input
|
||||
if [[ "$input" != "y" ]] &&
|
||||
[[ "$input" != "Y" ]] &&
|
||||
([[ "$input" == "" ]] ||
|
||||
[[ "$input" != "" ]]); then
|
||||
return
|
||||
fi
|
||||
echo 1
|
||||
on_exit () {
|
||||
[[ -f $LOCK_FILE ]] && rm $LOCK_FILE
|
||||
}
|
||||
|
||||
main $@
|
||||
|
|
Loading…
Reference in a new issue