view files/fbhyve.in @ 649:4ee9a8042f4a

common.subr: _get_jail_from_path() now just returns when the jail is dying. But it prints the name of the jail if it is yet dying. Real error reporting must not consistently be done in the caller.
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 27 Sep 2024 21:21:34 +0200
parents 30ba5e272030
children 24129dd789f0
line wrap: on
line source

#!/bin/sh
# -*- indent-tabs-mode: nil -*-

# PROVIDE: fbhyve
# REQUIRE: LOGIN FILESYSTEMS
# KEYWORD: shutdown nojail
#

# @(#)%%SIMPLEVERSIONTAG%%

#
# Add the following lines to /etc/rc.conf to enable bhyve:
#
# fbhyve_enable (bool):  Set to "NO" by default.
#                        Acts as default for all listed VMs.
#                        Set it to "YES" to enable bhyve.
# fbhyve_list (str):     Set to "" by default.
#                        Define the names of your VMs here.
# fbhyve_tmux_session_prefix (str):  All tmux session names will have this
#                                    prefix string.
# fbhyve_configdir (str): Where by default config files for all VMs live.
#                         Default: $PREFIX/etc/fbhyve
#
#
# fbhyve_<vm>_enable (bool):  Allow to enable or disable a specific VM.
#                             Set to $fbhyve_enable by default.
# fbhyve_<vm>_config (str):   The bhyve configuration file to use to.
#                             The default is $fbhyve_configdir/<vm>.conf
#

. /etc/rc.subr

name="fbhyve"
desc="Manage system bhyve virtual machines"
rcvar="fbhyve_enable"

extra_commands="kill"
start_precmd="fbhyve_pre_start"
stop_postcmd="fbhyve_post_stop"
status_cmd="fbhyve_status"
kill_cmd="fbhyve_kill"


load_rc_config $name

: ${fbhyve_enable:="NO"}
: ${fbhyve_list=}
: ${fbhyve_tmux_session_prefix:="${name}_"}
: ${fbhyve_configdir:="%%FBHYVE_ETCDIR%%"}


_fbhyve_vm_exists()
{
    local _p
    for _p in ${fbhyve_list}; do
        [ "${_p}" = "$1" ] && return 0;
    done
    return 1
}


if [ $# -eq 2 ]; then
    _vm="$2"
    if ! _fbhyve_vm_exists "${_vm}"; then
        echo "ERROR: no VM named \`${_vm}' in \`fbhyve_list'" 1>&2
        exit 1
    fi
    echo "-- VM: ${_vm} --"
    _session="${fbhyve_tmux_session_prefix}${_vm}"
    _window="${_session}_console"
    eval fbhyve_enable="\${fbhyve_${_vm}_enable:-${fbhyve_enable}}"
    eval fbhyve_config="\${fbhyve_${_vm}_config:-\"${fbhyve_configdir}/${_vm}.conf\"}"
else
    _ec=0
    _swap=$*; shift; _vmarglist=$*
    _vmlist=${_vmarglist:-${fbhyve_list}}
    set -- ${_swap}
    for _vm in ${_vmlist}; do
        "$0" "$1" "${_vm}"
        _vmec=$?
        if [ ${_vmec} -gt ${_ec} ]; then
            _ec=${_vmec}
        fi
    done
    exit ${_ec}
fi

_rundir="%%FBHYVE_RUNDIR%%"
pidfile="${_rundir}/${_vm}.pid"
command="%%LOCALBASE%%/bin/tmux"
procname="bhyve:"         # something like bhyve: <vmname> (bhyve)

required_dirs="${_rundir}"
required_files="${fbhyve_config} ${command}"

command_args="new-session -ds ${_session} -n ${_window} \"sh -c 'echo \\\$\\\$ >\\\"${pidfile}\\\"; /usr/sbin/bhyve -k \\\"${fbhyve_config}\\\" \\\"${_vm}\\\"'\""


fbhyve_status()
{
    local _pid _rc

    _rc=0
    _pid=$(check_pidfile "$pidfile" "$procname")
    if [ -n "${_pid}" ]; then
        echo "VM ${_vm} is running as pid $_pid."
    else
        echo "VM ${_vm} is not running."
        _rc=1
    fi

    if ${command} has-session -t ${_session} 2>/dev/null; then
	echo "tmux session ${_session} exists."
        if [ ${_rc} -gt 0 ]; then
            _rc=2
        fi
    else
	echo "tmux session ${_session} does not exist."
        if [ ${_rc} -gt 0 ]; then
            _rc=2
        fi
    fi
    return ${_rc}
}


fbhyve_pre_start()
{
    local _level

    if [ -z "${rc_force}" ]; then
        _level="ERROR:"
    else
        _level="WARNING:"
    fi
    if ! load_kld -m vmm vmm.ko; then
        echo "ERROR: Cannot load kernel module \`vmm'" 1>&2
        [ -z "${rc_force}" ] && return 1
    fi
    if [ -e "/dev/vmm/${_vm}" ]; then
        echo "${_level} VM \`${_vm}' already created in the VM monitor" 1>&2
        [ -z "${rc_force}" ] && return 1        
    fi
    if ${command} has-session -t "${_session}" 2>/dev/null; then
        echo "${_level} tmux session \`${_session}' already exists" 1>&2
        [ -z "${rc_force}" ] && return 1        
    fi
    return 0
}


fbhyve_post_stop()
{
    if [ -e "/dev/vmm/${_vm}" ]; then
        /usr/sbin/bhyvectl --vm="${_vm}" --destroy
    fi
    if ${command} has-session -t "${_session}" 2>/dev/null; then
        ${command} kill-session -t "${_session}"
    fi
    rm -f "${pidfile}"
    return 0
}


fbhyve_kill()
{
    # Just kill without terminating
    if [ -e "/dev/vmm/${_vm}" ]; then
        /usr/sbin/bhyvectl --vm="${_vm}" --force-poweroff 2>/dev/null 1>/dev/null
    fi
    # and do the normal cleanup
    fbhyve_post_stop
}


run_rc_command "$1"