1#!/bin/sh 2# 3# Copyright (c) 2018-2021, Christer Edwards <christer.edwards@gmail.com> 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 9# * Redistributions of source code must retain the above copyright notice, this 10# list of conditions and the following disclaimer. 11# 12# * Redistributions in binary form must reproduce the above copyright notice, 13# this list of conditions and the following disclaimer in the documentation 14# and/or other materials provided with the distribution. 15# 16# * Neither the name of the copyright holder nor the names of its 17# contributors may be used to endorse or promote products derived from 18# this software without specific prior written permission. 19# 20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin 32 33. /usr/local/share/bastille/common.sh 34 35## root check first. 36bastille_root_check() { 37 if [ "$(id -u)" -ne 0 ]; then 38 ## permission denied 39 error_notify "Bastille: Permission Denied" 40 error_exit "root / sudo / doas required" 41 fi 42} 43 44bastille_root_check 45 46## check for config existance 47bastille_conf_check() { 48 if [ ! -r "/usr/local/etc/bastille/bastille.conf" ]; then 49 error_exit "Missing Configuration" 50 fi 51} 52 53bastille_conf_check 54 55## we only load the config if conf_check passes 56. /usr/local/etc/bastille/bastille.conf 57 58## bastille_prefix should be 0750 59## this restricts file system access to privileged users 60bastille_perms_check() { 61 if [ -d "${bastille_prefix}" ]; then 62 BASTILLE_PREFIX_PERMS=$(stat -f "%Op" "${bastille_prefix}") 63 if [ "${BASTILLE_PREFIX_PERMS}" != 40750 ]; then 64 error_notify "Insecure permissions on ${bastille_prefix}" 65 error_exit "Try: chmod 0750 ${bastille_prefix}" 66 fi 67 fi 68} 69 70bastille_perms_check 71 72## version 73BASTILLE_VERSION="0.9.20211225" 74 75usage() { 76 cat << EOF 77Bastille is an open-source system for automating deployment and management of 78containerized applications on FreeBSD. 79 80Usage: 81 bastille command TARGET [args] 82 83Available Commands: 84 bootstrap Bootstrap a FreeBSD release for container base. 85 cmd Execute arbitrary command on targeted container(s). 86 clone Clone an existing container. 87 config Get or set a config value for the targeted container(s). 88 console Console into a running container. 89 convert Convert a Thin container into a Thick container. 90 cp cp(1) files from host to targeted container(s). 91 create Create a new thin container or a thick container if -T|--thick option specified. 92 destroy Destroy a stopped container or a FreeBSD release. 93 edit Edit container configuration files (advanced). 94 export Exports a specified container. 95 help Help about any command. 96 htop Interactive process viewer (requires htop). 97 import Import a specified container. 98 limits Apply resources limits to targeted container(s). See rctl(8). 99 list List containers (running and stopped). 100 mount Mount a volume inside the targeted container(s). 101 pkg Manipulate binary packages within targeted container(s). See pkg(8). 102 rdr Redirect host port to container port. 103 rename Rename a container. 104 restart Restart a running container. 105 service Manage services within targeted container(s). 106 start Start a stopped container. 107 stop Stop a running container. 108 sysrc Safely edit rc files within targeted container(s). 109 template Apply file templates to targeted container(s). 110 top Display and update information about the top(1) cpu processes. 111 umount Unmount a volume from within the targeted container(s). 112 update Update container base -pX release. 113 upgrade Upgrade container release to X.Y-RELEASE. 114 verify Compare release against a "known good" index. 115 zfs Manage (get|set) ZFS attributes on targeted container(s). 116 117Use "bastille -v|--version" for version information. 118Use "bastille command -h|--help" for more information about a command. 119 120EOF 121 exit 1 122} 123 124[ $# -lt 1 ] && usage 125 126CMD=$1 127shift 128 129# Handle special-case commands first. 130case "${CMD}" in 131version|-v|--version) 132 info "${BASTILLE_VERSION}" 133 exit 0 134 ;; 135help|-h|--help) 136 usage 137 ;; 138bootstrap|create|destroy|export|import|list|rdr|restart|start|update|upgrade|verify) 139 # Nothing "extra" to do for these commands. -- cwells 140 ;; 141clone|config|cmd|console|convert|cp|edit|htop|limits|mount|pkg|rename|service|stop|sysrc|template|top|umount|zfs) 142 # Parse the target and ensure it exists. -- cwells 143 if [ $# -eq 0 ]; then # No target was given, so show the command's help. -- cwells 144 PARAMS='help' 145 elif [ "${1}" != 'help' ] && [ "${1}" != '-h' ] && [ "${1}" != '--help' ]; then 146 TARGET="${1}" 147 shift 148 149 if [ "${TARGET}" = 'ALL' ]; then 150 _JAILS=$(/usr/sbin/jls name) 151 JAILS="" 152 for _jail in ${_JAILS}; do 153 _JAILPATH=$(/usr/sbin/jls -j "${_jail}" path) 154 if [ -z ${_JAILPATH##${bastille_jailsdir}*} ]; then 155 JAILS="${JAILS} ${_jail}" 156 fi 157 done 158 elif [ "${CMD}" = "pkg" ] && [ "${TARGET}" = '-H' ] || [ "${TARGET}" = '--host' ]; then 159 TARGET="${1}" 160 USE_HOST_PKG=1 161 JAILS="${TARGET}" 162 shift 163 164 # Require the target to be running 165 if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then 166 error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'." 167 fi 168 elif [ "${CMD}" = 'template' ] && [ "${TARGET}" = '--convert' ]; then 169 # This command does not act on a jail, so we are temporarily bypassing the presence/started 170 # checks. The command will simply convert a template from hooks to a Bastillefile. -- cwells 171 else 172 JAILS="${TARGET}" 173 174 # Ensure the target exists. -- cwells 175 if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then 176 error_exit "[${TARGET}]: Not found." 177 fi 178 179 case "${CMD}" in 180 cmd|console|htop|pkg|service|stop|sysrc|template|top) 181 # Require the target to be running. -- cwells 182 if [ ! "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then 183 error_exit "[${TARGET}]: Not started. See 'bastille start ${TARGET}'." 184 fi 185 ;; 186 convert|rename) 187 # Require the target to be stopped. -- cwells 188 if [ "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then 189 error_exit "${TARGET} is running. See 'bastille stop ${TARGET}'." 190 fi 191 ;; 192 esac 193 fi 194 export USE_HOST_PKG 195 export TARGET 196 export JAILS 197 fi 198 ;; 199*) # Filter out all non-commands 200 usage 201 ;; 202esac 203 204SCRIPTPATH="${bastille_sharedir}/${CMD}.sh" 205if [ -f "${SCRIPTPATH}" ]; then 206 : "${UMASK:=022}" 207 umask "${UMASK}" 208 209 : "${SH:=sh}" 210 211 if [ -n "${PARAMS}" ]; then 212 exec "${SH}" "${SCRIPTPATH}" "${PARAMS}" 213 else 214 exec "${SH}" "${SCRIPTPATH}" "$@" 215 fi 216else 217 error_exit "${SCRIPTPATH} not found." 218fi 219