#!/bin/bash
# apt - Debian/Ubuntu apt command support
set -e
lib_load 'net/remote'
lib_load 'sys/tool/chroot'
######
# Settings
sys_tool_apt_config_init() {
lib_setting_vars apt_pretend
lib_setting_arrays \
apt_update_opts apt_install_opts apt_upgrade_opts
}
# sys_tool_apt_config_check - scans libraries and script for package settings
sys_tool_apt_config_check() {
apt_pretend=${apt_pretend:-false}
for_each_lib _sys_tool_apt_config_check
_sys_tool_apt_config_check "$script_name"
}
# scans one library/script for apt package settings
_sys_tool_apt_config_check() {
local name=$1
for ext in client server; do
local var="$(lib_symbol $name)_${ext}_packages"
if eval "[ \"\${${var}[*]}\" ]"; then
settings_add_arrays "apt" "$var"
fi
done
}
######
# Internal functions
apt_options() {
local var=$1
list_append $var '--yes'
list_append $var --quiet
$verbose || list_append $var --quiet
! $apt_pretend || list_append $var '--dry-run'
}
apt_deps_append() {
has_args 3 "$@"
local var=$1
local class=$2
local prefix=$3
local sym
sym=$(lib_symbol $prefix)
local name="${sym}_${class}_packages"
local -a packages
eval "packages=( \"\${$name[@]}\" )"
if [ "${packages[*]}" ]; then
info "$prefix: adding $class packages: ${packages[*]}"
list_append $var "${packages[@]}"
else
debug "$prefix: no $class packages"
fi
}
######
# Public interface
apt_install() {
local -a opts
apt_options opts
run_sudo apt install "${opts[@]}" "$@"
}
apt_upgrade() {
local -a opts
apt_options opts
run_sudo apt "${opts[@]}" update
run_sudo apt "${opts[@]}" dist-upgrade
run_sudo apt "${opts[@]}" autoremove
}
######
# Package class support
# apt_class_usage - Prints common command usage for client/server CLI
apt_class_usage() {
has_args 1 "$@"
local class=$1
cat <<USAGE
<cmd> ...
Package Commands:
deps List $class packages
install Install $class packages
USAGE
}
_apt_class_deps() {
has_args 2 "$@"
local var=$1
local class=$2
for_each_lib apt_deps_append $var $class
apt_deps_append $var $class $script_name
}
apt_class_deps() {
has_args 1 "$@"
local class=$1
local -a deps
_apt_class_deps deps "$class"
IFS=$'\n' echo "${deps[*]}"
}
apt_class_install() {
has_args 1 "$@"
local class=$1
local -a deps
_apt_class_deps deps $class
apt_install "${deps[@]}"
}
# apt_install_remote() - Installs packages ($@) on a remote host ($1)
apt_install_remote() {
min_args 2 "$@"
local pkg_host=$1
shift
remote_sudo $pkg_host apt install "$@"
}
# apt_install_remote_class() - Installs a class ($2) of packages ($@) on a
# remote host ($1)
apt_install_remote_class() {
local host=$1
local class=$2
local -a deps
deps=( $(tool_class_deps_all $class) )
apt_install_remote "$host" "${deps[@]}"
}
# apt_install_tool_class() - Installs all of the tool dependencies
# $1 - library name
apt_install_tool_class() {
local class=$1
local -a deps
deps=( $(tool_class_deps $class) )
apt_install "${deps[@]}"
}
######
# Cloud package management
# apt_install_cloud_class() - Installs a class of deps ($2) on the named
# cloud ($1)
# $1 - cloud name
# $2 - package class name
apt_install_cloud_class() {
min_args 2 "$@"
local cloud=$1
for_each_cloud_host "$cloud" apt_install_cloud_class_host "$@"
}
# apt_install_cloud_class_host() - Installs a class of deps ($2) on the
# name host ($3) in the given cloud ($2)
# $1 - cloud name
# $2 - package class name
# $@ - host name
apt_install_cloud_class_host() {
min_args 3 "$@"
local cloud=$1
local class=$2
shift 2
local args=( "$@" )
local name
name=$(list_pop args)
app_echo "$cloud: $name: cloud host $class install: starting..."
if is_localhost $name; then
apt_install_tool_class $class "${args[@]}"
else
remote_class_install $name $class "${args[@]}"
fi
app_echo "$cloud: $name: cloud host $class install: ... done!"
}
# apt_upgrade_cloud() - Upgrades all hosts in the named cloud ($1)
# $1 - cloud name
apt_upgrade_cloud() {
has_args 1 "$@"
local cloud=$1
cloud_required "$cloud"
for_each_cloud_host "$cloud" apt_upgrade_cloud_host "$cloud"
}
# apt_upgrade_cloud_host() - Upgrades a single host ($2) in a cloud ($1)
# $1 - cloud name
# $2 - host name
apt_upgrade_cloud_host() {
has_args 2 "$@"
local cloud=$1
local name=$2
app_echo "$cloud: $name: cloud host upgrade: starting..."
if is_localhost "$name"; then
apt_upgrade
else
local -a opts=( --yes --quiet )
$verbose || list_append opts --quiet
local tmp
tmp=$(cmd_tempfile)
cat <<EOF >$tmp
apt update ${opts[*]}
apt dist-upgrade ${opts[*]}
apt autoremove ${opts[*]}
EOF
local installer="cloud_upgrade.sh"
remote_copy_to "$name" "$tmp" "$installer"
remote_sudo $name bash "$installer"
remote_run $name rm -f "$installer"
fi
app_echo "$cloud: $name: cloud host upgrade: ... done!"
}
######
# Apt inside chroots
apt_chroot() {
local action=$1
local name=$2
shift 2
local -a cmd
list_append cmd env "DEBIAN_FRONTEND=noninteractive"
list_append cmd apt "$action" --yes
# list_append cmd -o 'Dpkg::Options::="--force-confdef"'
# list_append cmd -o 'Dpkg::Options::="--force-confold"'
local var="apt_${action}_opts"
eval "list_append cmd \"\${$var[@]}\""
run_chroot "$name" "${cmd[@]}" "$@"
}
apt_chroot_update() { apt_chroot update "$@"; }
apt_chroot_install() { apt_chroot install "$@"; }
apt_chroot_upgrade() { apt_chroot upgrade "$@"; }
Generated on Thu May 4 19:00:25 PDT 2017 by mcsh i7 v0.19.0.