initial bits for boxctl

This commit is contained in:
Aaron Bieber 2019-09-23 18:13:18 -06:00
commit 8ba54c36eb
Signed by: qbit
GPG Key ID: 279160AB1BE1236B
5 changed files with 467 additions and 0 deletions

15
LICENSE Normal file
View File

@ -0,0 +1,15 @@
/*
* 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.
*/

27
Makefile Normal file
View File

@ -0,0 +1,27 @@
# $OpenBSD$
PREFIX ?= /usr/local
SCRIPT = boxctl.sh
MAN = man/boxctl.8
MANDIR ?= ${PREFIX}/man/man
BINDIR ?= ${PREFIX}/bin
README.md: man/boxctl.8
mandoc -T lint man/boxctl.8
mandoc -T markdown man/boxctl.8 >$@
sign:
@sha256 boxctl.sh > SHA256
@signify -S -s ~/signify/boxctl.sec -m SHA256 -x SHA256.sig
@cat SHA256 >> SHA256.sig
verify:
@signify -C -p /etc/signify/boxctl.pub -x SHA256.sig boxctl.sh
realinstall:
${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/${SCRIPT} ${DESTDIR}${BINDIR}/boxctl
.PHONY: verify sign
.include <bsd.prog.mk>

117
README.md Normal file
View File

@ -0,0 +1,117 @@
BOXCTL(8) - System Manager's Manual
# NAME
**boxctl** - tool to manage remote
OpenBSD
machines
# SYNOPSIS
**boxctl**
\[**-mnv**]
\[**-h**&nbsp;*host*]
\[**-u**&nbsp;*user*]
# DESCRIPTION
**boxctl**
is a
ksh(1)
script designed to help manage
OpenBSD
machines.
It uses only tools contained in
OpenBSD
base.
The options are as follows:
**-h** *host*
> Remote host to be managed.
**-u** *user*
> User to connect to
> *host*
> with.
> Defaults to
> *root*.
**-m**
> Run maintenance tasks.
> This includes deleting unused dependencies using
> pkg\_delete(1).
> And installing / updating firmware using
> fw\_update(1).
**-n**
> Dry run.
> This will only print the commands that will be run.
**-v**
> Increase verbosity.
> More v's can be specified to increase information output.
> The number of v's are passed to tools used by
> **boxctl**.
# FILES
*$CWD/files*
> Is a ":" delimited index of source file, owner, group, mode and destination.
> Each source will be copied to the specified destination, then chown/chmod will
> be run with the values specified.
> If this file does not exist, no files are copied.
*$CWD/services*
> An optional file that contains a list of services to enable on the remote
> host.
> If a service is already enabled, it will be restarted each run of
> **boxctl**.
*$CWD/packages*
> When this file exists,
> **boxctl**
> will install the packages contained therewithin on the remote host.
> A list is cached on the remote host under /etc/packages.
> This list (if it exists) will be compared using
> diff(1)
> and only missing packages will be installed.
> Package names should be listed by their fuzzy names.
> See
> pkg\_info(1)
> for more information on fuzzy names.
# SEE ALSO
chmod(1),
diff(1),
fw\_update(1),
pkg\_add(1),
pkg\_delete(1),
pkg\_info(1),
scp(1),
ssh(1),
chown(8),
rcctl(8)
# HISTORY
The first version of
**boxctl**
was released in September of 2019.
# AUTHORS
**boxctl**
was written by
Aaron Bieber &lt;[aaron@bolddaemon.com](mailto:aaron@bolddaemon.com)&gt;.
OpenBSD 6.6 - September 23, 2019

198
boxctl.sh Executable file
View File

@ -0,0 +1,198 @@
#!/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
SSH_CTL_PATH="/tmp/boxctl-%r@%h:%p"
SSH_OPTS="-o ControlMaster=auto -o ControlPersist=60s -o ControlPath=${SSH_CTL_PATH}"
SERVICE_START_RESTART=$(cat <<EOF
/usr/sbin/rcctl enable %s; \
/usr/sbin/rcctl check %s && \
/usr/sbin/rcctl restart %s || \
/usr/sbin/rcctl start %s
EOF
)
PKG_DIFF_INSTALL=$(cat <<EOF
if [ -f /etc/packages ]; 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 -z -l /tmp/new_packages
else
/usr/sbin/pkg_add %s -z -l /etc/packages.tmp
fi
mv /etc/packages.tmp /etc/packages
EOF
)
while getopts "h:u:nv" arg; do
case $arg in
h)
SERVER=$OPTARG
;;
v)
VERBOSITY=$((VERBOSITY+1))
;;
n)
DRY=1
;;
u)
RUN_USER=$OPTARG
;;
m)
MAINTENANCE=1
;;
esac
done
msg() {
local _level _msg
_level=$1
_msg=$2
if [ $VERBOSITY -ge $_level ] && [ $DRY == 0 ]; then
echo "==> $_msg"
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
}
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
}
_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)
if [ -f ./files ]; then
msg 0 "Installing files"
for file in $(cat files); do
local _src _dest _mode _owner _group
read _src _owner _group _mode _dest <<EOF
$(echo $file | sed 's/:/ /g')
EOF
msg 1 "\t${_src} -> ${_dest}"
msg 2 "\t\tchown ${_owner}:${_group} $_dest"
msg 2 "\t\tchmod ${_mode} $_dest"
_scp $_src "${RUN_USER}@${SERVER}:$_dest"
_ssh ${RUN_USER}@${SERVER} "/sbin/chown ${_owner}:${_group} $_dest; \
/bin/chmod ${_mode} $_dest"
done
fi
if [ -f ./services ]; then
msg 0 "Enabling services"
for service in $(cat services); do
msg 1 "\tenabling/restarting ${service}"
cmd="$(printf "$SERVICE_START_RESTART" \
$service $service $service $service)"
_ssh ${RUN_USER}@${SERVER} "${cmd}"
done
fi
if [ -f ./packages ]; then
msg 0 "Installing $(wc -l packages | awk '{print $1 " " $2}') on ${SERVER}"
cmd=$(printf "${PKG_DIFF_INSTALL}" $V $V)
_scp packages "${RUN_USER}@${SERVER}:/etc/packages.tmp"
_ssh ${RUN_USER}@${SERVER} "${cmd}"
fi
if [ $MAINTENANCE == 1 ]; then
msg 0 "Cleaning up unused packages"
_ssh ${RUN_USER}@${SERVER} "/usr/sbin/pkg_delete -a"
fi

110
man/boxctl.8 Normal file
View File

@ -0,0 +1,110 @@
.\" $OpenBSD$
.\"
.\" 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.
.\"
.Dd $Mdocdate: September 23 2019 $
.Dt BOXCTL 8
.Os
.Sh NAME
.Nm boxctl
.Nd tool to manage remote
.Ox
machines
.Sh SYNOPSIS
.Nm boxctl
.Op Fl mnv
.Op Fl h Ar host
.Op Fl u Ar user
.Sh DESCRIPTION
.Nm
is a
.Xr ksh 1
script designed to help manage
.Ox
machines.
It uses only tools contained in
.Ox
base.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl h Ar host
Remote host to be managed.
.It Fl u Ar user
User to connect to
.Pa host
with.
Defaults to
.Pa root .
.It Fl m
Run maintenance tasks.
This includes deleting unused dependencies using
.Xr pkg_delete 1 .
And installing / updating firmware using
.Xr fw_update 1 .
.It Fl n
Dry run.
This will only print the commands that will be run.
.It Fl v
Increase verbosity.
More v's can be specified to increase information output.
The number of v's are passed to tools used by
.Nm .
.El
.Sh FILES
.Bl -tag -width $CWD/packages
.It Pa $CWD/files
Is a ":" delimited index of source file, owner, group, mode and destination.
Each source will be copied to the specified destination, then chown/chmod will
be run with the values specified.
If this file does not exist, no files are copied.
.It Pa $CWD/services
An optional file that contains a list of services to enable on the remote
host.
If a service is already enabled, it will be restarted each run of
.Nm .
.It Pa $CWD/packages
When this file exists,
.Nm
will install the packages contained therewithin on the remote host.
A list is cached on the remote host under /etc/packages.
This list (if it exists) will be compared using
.Xr diff 1
and only missing packages will be installed.
Package names should be listed by their fuzzy names.
See
.Xr pkg_info 1
for more information on fuzzy names.
.El
.Sh SEE ALSO
.Xr chmod 1 ,
.Xr diff 1 ,
.Xr fw_update 1 ,
.Xr pkg_add 1 ,
.Xr pkg_delete 1 ,
.Xr pkg_info 1 ,
.Xr scp 1 ,
.Xr ssh 1 ,
.Xr chown 8 ,
.Xr rcctl 8
.Sh HISTORY
The first version of
.Nm
was released in September of 2019.
.Sh AUTHORS
.An -nosplit
.Nm
was written by
.An Aaron Bieber Aq Mt aaron@bolddaemon.com .