2019-09-23 18:13:18 -06:00
|
|
|
#!/bin/ksh
|
|
|
|
|
|
|
|
# /*
|
|
|
|
# * Copyright (c) 2019 Aaron Bieber <aaron@bolddaemon.com>
|
|
|
|
# *
|
|
|
|
# * Permission to use, copy, modify, and distribute this software for any
|
|
|
|
# * purpose with or without fee is hereby granted, provided that the above
|
|
|
|
# * copyright notice and this permission notice appear in all copies.
|
|
|
|
# *
|
|
|
|
# * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
# * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
# * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
# * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
# * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
# * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
# * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
# */
|
|
|
|
|
|
|
|
set -au
|
|
|
|
|
|
|
|
SERVER=""
|
|
|
|
RUN_USER="root"
|
|
|
|
VERBOSITY=0
|
|
|
|
DRY=0
|
|
|
|
MAINTENANCE=0
|
2019-10-10 07:27:20 -06:00
|
|
|
SNAPSHOT=""
|
|
|
|
FORCE=0
|
2020-05-17 07:35:09 -06:00
|
|
|
COPY=0
|
2019-09-23 18:13:18 -06:00
|
|
|
SSH_CTL_PATH="/tmp/boxctl-%r@%h:%p"
|
|
|
|
SSH_OPTS="-o ControlMaster=auto -o ControlPersist=60s -o ControlPath=${SSH_CTL_PATH}"
|
2019-10-21 06:58:21 -06:00
|
|
|
RSYNC_OPTS="--rsync-path=/usr/bin/openrsync -Dlrt"
|
2019-09-23 18:13:18 -06:00
|
|
|
|
2020-05-17 07:35:09 -06:00
|
|
|
while getopts "cfh:mnu:sv" arg; do
|
2019-09-23 18:13:18 -06:00
|
|
|
case $arg in
|
2020-05-17 07:35:09 -06:00
|
|
|
c)
|
|
|
|
COPY=1
|
|
|
|
;;
|
2019-10-10 07:27:20 -06:00
|
|
|
f)
|
|
|
|
FORCE=1
|
|
|
|
;;
|
2019-09-23 18:13:18 -06:00
|
|
|
h)
|
|
|
|
SERVER=$OPTARG
|
|
|
|
;;
|
2019-09-24 06:05:53 -06:00
|
|
|
m)
|
|
|
|
MAINTENANCE=1
|
2019-09-23 18:13:18 -06:00
|
|
|
;;
|
|
|
|
n)
|
|
|
|
DRY=1
|
|
|
|
;;
|
|
|
|
u)
|
|
|
|
RUN_USER=$OPTARG
|
|
|
|
;;
|
2019-10-10 07:27:20 -06:00
|
|
|
s)
|
|
|
|
SNAPSHOT="-Dsnap"
|
|
|
|
;;
|
2019-09-24 06:05:53 -06:00
|
|
|
v)
|
|
|
|
VERBOSITY=$((VERBOSITY+1))
|
2019-09-23 18:13:18 -06:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2019-10-10 07:27:20 -06:00
|
|
|
PKG_DIFF_INSTALL=$(cat <<EOF
|
|
|
|
if [ -f /etc/packages ] && [ "${FORCE}" == "0" ]; then
|
|
|
|
# Already ran a full install, so only install new packages
|
|
|
|
diff -u /etc/packages /etc/packages.tmp | grep -e ^+[a-z0-9] | \
|
|
|
|
sed 's/^+//' > /tmp/new_packages
|
|
|
|
/usr/sbin/pkg_add %s ${SNAPSHOT} -z -l /tmp/new_packages
|
|
|
|
else
|
|
|
|
/usr/sbin/pkg_add %s ${SNAPSHOT} -z -l /etc/packages.tmp
|
|
|
|
fi
|
|
|
|
mv /etc/packages.tmp /etc/packages
|
|
|
|
EOF
|
|
|
|
)
|
|
|
|
|
|
|
|
SERVICE_START_RESTART=$(cat <<EOF
|
2019-10-21 21:07:00 -06:00
|
|
|
/usr/sbin/rcctl enable %s;
|
|
|
|
if /usr/sbin/rcctl check %s; then
|
|
|
|
AGE=\$(stat -s %s | awk -v now=\$(date +%%s) \
|
|
|
|
'{split(\$10,a,"="); print now - a[2]}')
|
2019-10-21 21:26:55 -06:00
|
|
|
if [ \$AGE -lt 100 ] || [ "${FORCE}" == "1" ]; then
|
2019-10-21 21:07:00 -06:00
|
|
|
logger -t boxctl "restarting %s (\$AGE seconds old)"
|
|
|
|
/usr/sbin/rcctl restart %s
|
|
|
|
else
|
|
|
|
logger -t boxctl "not restarting %s (\$AGE seconds old)"
|
|
|
|
fi
|
|
|
|
else
|
2019-10-10 07:27:20 -06:00
|
|
|
/usr/sbin/rcctl start %s
|
2019-10-21 21:07:00 -06:00
|
|
|
fi
|
2019-10-10 07:27:20 -06:00
|
|
|
EOF
|
|
|
|
)
|
|
|
|
|
2019-09-23 18:13:18 -06:00
|
|
|
msg() {
|
|
|
|
local _level _msg
|
|
|
|
_level=$1
|
|
|
|
_msg=$2
|
|
|
|
if [ $VERBOSITY -ge $_level ] && [ $DRY == 0 ]; then
|
2019-09-24 06:30:27 -06:00
|
|
|
echo "==> ${SERVER} -> $_msg"
|
2019-09-23 18:13:18 -06:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
expand_v() {
|
|
|
|
V=""
|
|
|
|
if [ $VERBOSITY -gt 0 ]; then
|
|
|
|
for v in $(jot $VERBOSITY); do
|
|
|
|
V="${V}v"
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
if [ "${V}" == "" ]; then
|
|
|
|
echo "${V}"
|
|
|
|
else
|
|
|
|
echo "-${V}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2019-10-21 06:58:21 -06:00
|
|
|
rsync_verbose() {
|
|
|
|
local _opt=""
|
|
|
|
if [ $VERBOSITY -ge 2 ]; then
|
|
|
|
_opt="$V"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $DRY == 1 ]; then
|
|
|
|
echo openrsync ${RSYNC_OPTS} $_opt "$1" "$2"
|
|
|
|
else
|
|
|
|
openrsync ${RSYNC_OPTS} $_opt "$1" "$2"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
rsync_quiet() {
|
|
|
|
if [ $DRY == 1 ]; then
|
|
|
|
echo openrsync ${RSYNC_OPTS} "$1" "$2"
|
|
|
|
else
|
|
|
|
openrsync ${RSYNC_OPTS} "$1" "$2" >/dev/null
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2019-09-23 18:13:18 -06:00
|
|
|
ssh_verbose() {
|
|
|
|
local _opt=""
|
|
|
|
if [ $VERBOSITY -ge 4 ]; then
|
|
|
|
_opt="$V"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $DRY == 1 ]; then
|
|
|
|
echo ssh ${SSH_OPTS} $_opt "$1" "${2}"
|
|
|
|
else
|
|
|
|
ssh ${SSH_OPTS} $_opt "$1" "${2}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
ssh_quiet() {
|
|
|
|
if [ $DRY == 1 ]; then
|
|
|
|
echo "ssh ${SSH_OPTS} '$1' '${2}' >/dev/null"
|
|
|
|
else
|
|
|
|
ssh ${SSH_OPTS} "$1" "${2}" >/dev/null
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
scp_verbose() {
|
|
|
|
local _opt=""
|
|
|
|
if [ $VERBOSITY -ge 4 ]; then
|
|
|
|
_opt="$V"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $DRY == 1 ]; then
|
|
|
|
echo scp ${SSH_OPTS} $_opt "$1" "${2}"
|
|
|
|
else
|
|
|
|
scp ${SSH_OPTS} $_opt "$1" "${2}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
scp_quiet() {
|
|
|
|
if [ $DRY == 1 ]; then
|
|
|
|
echo "scp ${SSH_OPTS} '$1' '${2}' >/dev/null"
|
|
|
|
else
|
|
|
|
scp ${SSH_OPTS} "$1" "${2}" >/dev/null
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-21 06:58:21 -06:00
|
|
|
_rsync() {
|
|
|
|
local _src _dest
|
|
|
|
_src=$1
|
|
|
|
_dest="$(dirname $2)"
|
|
|
|
|
|
|
|
if [ $VERBOSITY -gt 2 ]; then
|
|
|
|
rsync_verbose "$_src" "$_dest"
|
|
|
|
else
|
|
|
|
rsync_quiet "$_src" "$_dest"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2019-09-23 18:13:18 -06:00
|
|
|
_scp() {
|
|
|
|
local _src _dest
|
|
|
|
_src=$1
|
|
|
|
_dest=$2
|
|
|
|
|
|
|
|
if [ $VERBOSITY -gt 2 ]; then
|
|
|
|
scp_verbose "$_src" "$_dest"
|
|
|
|
else
|
|
|
|
scp_quiet "$_src" "$_dest"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
_ssh() {
|
|
|
|
local _server _cmd
|
|
|
|
_server=$1
|
|
|
|
_cmd=$2
|
|
|
|
|
|
|
|
if [ $VERBOSITY -gt 2 ]; then
|
|
|
|
ssh_verbose "$_server" "$_cmd"
|
|
|
|
else
|
|
|
|
ssh_quiet "$_server" "$_cmd"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
V=$(expand_v)
|
|
|
|
|
2019-10-27 09:12:12 -06:00
|
|
|
fnc() {
|
|
|
|
local _count
|
|
|
|
_count=$(grep -v ^# $1 | wc -l | awk '{print $1}')
|
|
|
|
echo "${1} ${_count}"
|
|
|
|
}
|
|
|
|
|
2020-05-17 07:35:09 -06:00
|
|
|
|
|
|
|
if [ "${COPY}" == "1" ]; then
|
|
|
|
if [ -f ./files ]; then
|
|
|
|
msg 0 "syncing $(fnc files) from ${SERVER}"
|
|
|
|
for file in $(cat files | grep -v ^#); do
|
|
|
|
local _src _dest _mode _owner _group _dir
|
|
|
|
read _src _owner _group _mode _dest <<EOF
|
|
|
|
$(echo $file | sed 's/:/ /g')
|
|
|
|
EOF
|
|
|
|
_dir=$(dirname $_dest)
|
|
|
|
msg 1 "\t${_dest} -> ${_src}"
|
|
|
|
_rsync "${RUN_USER}@${SERVER}:$_dest" $_src
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2019-10-23 17:11:19 -06:00
|
|
|
if [ -f ./packages ]; then
|
2019-10-27 09:12:12 -06:00
|
|
|
msg 0 "installing $(fnc packages)"
|
2019-10-23 17:11:19 -06:00
|
|
|
cmd=$(printf "${PKG_DIFF_INSTALL}" $V $V)
|
|
|
|
_scp packages "${RUN_USER}@${SERVER}:/etc/packages.tmp"
|
|
|
|
_ssh ${RUN_USER}@${SERVER} "${cmd}"
|
|
|
|
fi
|
|
|
|
|
2019-10-15 20:53:30 -06:00
|
|
|
if [ -f ./groups ]; then
|
2019-10-27 09:12:12 -06:00
|
|
|
msg 0 "adding $(fnc groups)"
|
|
|
|
for group in $(cat groups | grep -v ^#); do
|
2019-10-15 20:53:30 -06:00
|
|
|
local _group _gid
|
|
|
|
read _group _gid <<EOF
|
|
|
|
$(echo $group | sed 's/:/ /g')
|
|
|
|
EOF
|
|
|
|
msg 1 "\t${_group} (${_gid})"
|
|
|
|
_ssh ${RUN_USER}@${SERVER} "grep -q ^${_group} /etc/group || \
|
|
|
|
/usr/sbin/groupadd -g ${_gid} ${_group}"
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -f ./users ]; then
|
2019-10-27 09:12:12 -06:00
|
|
|
msg 0 "adding $(fnc users)"
|
|
|
|
for user in $(cat users | grep -v ^#); do
|
2019-10-15 20:53:30 -06:00
|
|
|
local _u _uid _gid _c _home _shell _pass
|
|
|
|
read _u _uid _gid _c _home _shell _pass <<EOF
|
|
|
|
$(echo $user | sed 's/:/ /g')
|
|
|
|
EOF
|
|
|
|
msg 1 "\t${_u} (${_c})"
|
|
|
|
_ssh ${RUN_USER}@${SERVER} "grep -q ^${_u} /etc/passwd || \
|
|
|
|
/usr/sbin/useradd \
|
|
|
|
-s ${_shell} \
|
|
|
|
-c '${_c}' \
|
|
|
|
-d '${_home}' \
|
|
|
|
-m \
|
|
|
|
-g ${_gid} \
|
|
|
|
-u ${_uid} \
|
|
|
|
-p ${_pass} \
|
|
|
|
${_u}"
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
2019-10-16 06:41:33 -06:00
|
|
|
if [ -f ./files ]; then
|
2019-10-27 09:12:12 -06:00
|
|
|
msg 0 "installing $(fnc files)"
|
|
|
|
for file in $(cat files | grep -v ^#); do
|
2019-10-16 06:41:33 -06:00
|
|
|
local _src _dest _mode _owner _group _dir
|
|
|
|
read _src _owner _group _mode _dest <<EOF
|
|
|
|
$(echo $file | sed 's/:/ /g')
|
|
|
|
EOF
|
|
|
|
_dir=$(dirname $_dest)
|
|
|
|
msg 1 "\t${_src} -> ${_dest}"
|
|
|
|
msg 2 "\t\tmkdir -p ${_dir}"
|
|
|
|
msg 2 "\t\tchown ${_owner}:${_group} $_dest"
|
|
|
|
msg 2 "\t\tchmod ${_mode} $_dest"
|
|
|
|
|
|
|
|
_ssh ${RUN_USER}@${SERVER} "mkdir -p ${_dir}"
|
2019-10-21 06:58:21 -06:00
|
|
|
_rsync $_src "${RUN_USER}@${SERVER}:$_dest"
|
2019-10-16 06:41:33 -06:00
|
|
|
_ssh ${RUN_USER}@${SERVER} "/sbin/chown ${_owner}:${_group} \
|
|
|
|
$_dest; /bin/chmod ${_mode} $_dest"
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
2019-09-23 18:13:18 -06:00
|
|
|
if [ -f ./services ]; then
|
2019-10-27 09:12:12 -06:00
|
|
|
msg 0 "enabling services $(fnc services)"
|
2019-10-21 21:07:00 -06:00
|
|
|
local _svc _chfile
|
2019-10-27 09:12:12 -06:00
|
|
|
for service in $(cat services | grep -v ^#); do
|
2019-10-21 21:07:00 -06:00
|
|
|
read _svc _chfile <<EOF
|
|
|
|
$(echo $service | sed 's/:/ /g')
|
|
|
|
EOF
|
|
|
|
msg 1 "\tenabling/restarting ${_svc}"
|
2019-09-23 18:13:18 -06:00
|
|
|
cmd="$(printf "$SERVICE_START_RESTART" \
|
2019-10-21 21:07:00 -06:00
|
|
|
$_svc $_svc $_chfile $_svc $_svc $_svc $_svc)"
|
2019-09-23 18:13:18 -06:00
|
|
|
_ssh ${RUN_USER}@${SERVER} "${cmd}"
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ $MAINTENANCE == 1 ]; then
|
2019-09-24 06:30:55 -06:00
|
|
|
msg 0 "cleaning up unused packages"
|
2019-09-24 06:16:07 -06:00
|
|
|
_ssh ${RUN_USER}@${SERVER} "/usr/sbin/pkg_delete $V -a"
|
2019-10-21 21:29:51 -06:00
|
|
|
msg 0 "updating installed packages"
|
|
|
|
_ssh ${RUN_USER}@${SERVER} "/usr/sbin/pkg_add $V -u"
|
2019-09-24 06:30:55 -06:00
|
|
|
msg 0 "installing firmware updates"
|
2019-10-27 08:15:53 -06:00
|
|
|
_ssh ${RUN_USER}@${SERVER} "/usr/sbin/fw_update $V"
|
2019-09-23 18:13:18 -06:00
|
|
|
fi
|
2019-10-12 08:40:05 -06:00
|
|
|
|
|
|
|
if [ -f ./commands ]; then
|
|
|
|
local _tmp=$(mktemp)
|
|
|
|
rm $_tmp
|
|
|
|
msg 0 "executing 'commands' file"
|
|
|
|
_scp commands "${RUN_USER}@${SERVER}:${_tmp}"
|
2019-10-15 20:14:14 -06:00
|
|
|
_ssh ${RUN_USER}@${SERVER} "chmod +x ${_tmp}; . ${_tmp}; rm ${_tmp}"
|
2019-10-12 08:40:05 -06:00
|
|
|
fi
|