Follow some Google shell scripting advice

I already do pretty much everything they advise anyway
Grouping functions together by using "prefix::" is quite a nice feature though.
Nothing too clever, just makes use of the fact that a colon appears
to be a valid character in a shell function.
This commit is contained in:
Matt Churchyard
2016-06-09 10:47:47 +01:00
parent 872fb319ce
commit 52b9f2eb8b
12 changed files with 662 additions and 662 deletions

View File

@@ -31,12 +31,12 @@
#
# @param string _cmd the command right after 'vm '
#
__parse_info_cmd(){
cmd::parse_info(){
local _cmd="$1"
case "${_cmd}" in
version) __version && exit ;;
usage) __usage ;;
version) util::version && exit ;;
usage) util::usage ;;
esac
}
@@ -46,38 +46,38 @@ __parse_info_cmd(){
#
# @param string _cmd the command right after 'vm '
#
__parse_cmd(){
cmd::parse(){
local _cmd="$1"
shift
case "${_cmd}" in
init) __setup
__switch_init ;;
switch) __parse_switch_cmd "$@" ;;
datastore) __parse_datastore_cmd "$@" ;;
image) __parse_image_cmd "$@" ;;
list) __vm_list ;;
info) __vm_info "$@" ;;
create) __vm_create "$@" ;;
destroy) __vm_destroy "$@" ;;
rename) __vm_rename "$@" ;;
install) __vm_install "$@" ;;
start) __vm_start "$1" ;;
stop) __vm_stop "$@" ;;
add) __vm_add "$@" ;;
reset) __vm_reset "$@" ;;
poweroff) __vm_poweroff "$@" ;;
startall) __vm_startall ;;
stopall) __vm_stopall ;;
console) __vm_console "$@" ;;
_run) __vm_run "$@" ;;
iso) __vm_iso "$@" ;;
configure) __vm_configure "$@" ;;
passthru) __vm_passthru ;;
clone) __zfs_clone "$@" ;;
snapshot) __zfs_snapshot "$@" ;;
rollback) __zfs_rollback "$@" ;;
*) __usage ;;
init) util::setup
switch::init ;;
switch) cmd::parse_switch "$@" ;;
datastore) cmd::parse_datastore "$@" ;;
image) cmd::parse_image "$@" ;;
list) core::list ;;
info) info::guest "$@" ;;
create) core::create "$@" ;;
destroy) core::destroy "$@" ;;
rename) core::rename "$@" ;;
install) core::install "$@" ;;
start) core::start "$1" ;;
stop) core::stop "$@" ;;
add) core::add "$@" ;;
reset) core::reset "$@" ;;
poweroff) core::poweroff "$@" ;;
startall) core::startall ;;
stopall) core::stopall ;;
console) core::console "$@" ;;
_run) vm::run "$@" ;;
iso) core::iso "$@" ;;
configure) core::configure "$@" ;;
passthru) core::passthru ;;
clone) zfs::clone "$@" ;;
snapshot) zfs::snapshot "$@" ;;
rollback) zfs::rollback "$@" ;;
*) util::usage ;;
esac
}
@@ -88,21 +88,21 @@ __parse_cmd(){
#
# @param string _cmd the command right after 'vm switch '
#
__parse_switch_cmd(){
cmd::parse_switch(){
local _cmd="$1"
shift
case "${_cmd}" in
create) __switch_create "$@" ;;
list) __switch_list ;;
info) __vm_info_switch "$@" ;;
destroy) __switch_remove "$@" ;;
import) __switch_import "$@" ;;
add) __switch_add_member "$@" ;;
remove) __switch_remove_member "$@" ;;
vlan) __switch_vlan "$@" ;;
nat) __switch_nat "$@" ;;
*) __usage ;;
create) switch::create "$@" ;;
list) switch::list ;;
info) info::guest_switch "$@" ;;
destroy) switch::remove "$@" ;;
import) switch::import "$@" ;;
add) switch::add_member "$@" ;;
remove) switch::remove_member "$@" ;;
vlan) switch::vlan "$@" ;;
nat) switch::nat "$@" ;;
*) util::usage ;;
esac
}
@@ -112,15 +112,15 @@ __parse_switch_cmd(){
#
# @param string _cmd the command after 'vm datastore ...'
#
__parse_datastore_cmd(){
cmd::parse_datastore(){
local _cmd="$1"
shift
case "${_cmd}" in
list) __datastore_list ;;
add) __datastore_add "$@" ;;
remove) __datastore_remove "$@" ;;
*) __usage ;;
list) datastore::list ;;
add) datastore::add "$@" ;;
remove) datastore::remove "$@" ;;
*) util::usage ;;
esac
}
@@ -129,18 +129,18 @@ __parse_datastore_cmd(){
#
# @param string _cmd the command after 'vm image '
#
__parse_image_cmd(){
cmd::parse_image(){
local _cmd="$1"
shift
[ -z "${VM_ZFS}" ] && __err "\$vm_dir must be a ZFS datastore to use these functions"
[ -z "${VM_ZFS}" ] && util::err "\$vm_dir must be a ZFS datastore to use these functions"
case "${_cmd}" in
list) __zfs_image_list ;;
create) __zfs_image_create "$@" ;;
provision) __zfs_image_provision "$@" ;;
destroy) __zfs_image_destroy "$@" ;;
*) __usage ;;
list) zfs::image_list ;;
create) zfs::image_create "$@" ;;
provision) zfs::image_provision "$@" ;;
destroy) zfs::image_destroy "$@" ;;
*) util::usage ;;
esac
}
@@ -152,7 +152,7 @@ __parse_image_cmd(){
#
# @modifies VM_COMMAND VM_FOREGROUND vm_dir
#
__parse_cmd_args(){
cmd::parse_args(){
local _opt
while getopts f _opt; do

View File

@@ -34,7 +34,7 @@
# @param string _file full path of the file to read
# @modifies VM_CONFIG
#
__config_load(){
config::load(){
local _file="$1"
# read config file
@@ -50,7 +50,7 @@ __config_load(){
# @param optional string _def default value to return if setting not found
# @return true if setting found
#
__config_get(){
config::get(){
local _c_var="$1"
local _c_key="$2"
local _c_def="$3"
@@ -71,7 +71,7 @@ __config_get(){
# load core configuration file
#
__config_core_load(){
config::core_load(){
# check config file exists
# this is mainly for upgrades to make sure switch/datastore config are migrated
if [ ! -e "${vm_dir}/.config/system.conf" ]; then
@@ -89,7 +89,7 @@ __config_core_load(){
# @param string _c_def default value if not value
# @return 0 if found
#
__config_core_get(){
config::core_get(){
local _c_var="$1"
local _c_key="$2"
local _c_def="$3"
@@ -114,7 +114,7 @@ __config_core_get(){
# @param string _value new value
# @param string _append non-empty to append to existing value
#
__config_core_set(){
config::core_set(){
local _var="$1"
local _value="$2"
local _append="$3"
@@ -134,7 +134,7 @@ __config_core_set(){
# @param string _value if non-empty we will try to remove just this value from setting
# @return non-zero on error
#
__config_core_remove(){
config::core_remove(){
local _var="$1"
local _value="$2"

View File

@@ -27,42 +27,42 @@
# 'vm list'
# list virtual machines
#
__vm_list(){
core::list(){
local _name _loader _cpu _our_host
local _memory _run _vm _auto _num _uefi _graphics _vnc
local _format="%-15s %-15s %-11s %-6s %-9s %-20s %-12s %s\n"
_our_host=$(hostname)
__vm_running_load
vm::running_load
printf "${_format}" "NAME" "DATASTORE" "LOADER" "CPU" "MEMORY" "VNC" "AUTOSTART" "STATE"
for _ds in ${VM_DATASTORE_LIST}; do
__datastore_get "${_ds}" || continue
datastore::get "${_ds}" || continue
ls -1 "${VM_DS_PATH}" 2>/dev/null | \
while read _name; do
[ ! -e "${VM_DS_PATH}/${_name}/${_name}.conf" ] && continue
__config_load "${VM_DS_PATH}/${_name}/${_name}.conf"
__config_get "_loader" "loader" "none"
__config_get "_cpu" "cpu"
__config_get "_memory" "memory"
__config_get "_uefi" "uefi"
__config_get "_graphics" "graphics"
config::load "${VM_DS_PATH}/${_name}/${_name}.conf"
config::get "_loader" "loader" "none"
config::get "_cpu" "cpu"
config::get "_memory" "memory"
config::get "_uefi" "uefi"
config::get "_graphics" "graphics"
# show uefi in loader column if it's a uefi guest
__checkyesno "${_uefi}" && _loader="uefi"
util::checkyesno "${_uefi}" && _loader="uefi"
# defaults
_vnc="-"
# check if the guest is running
if __vm_running_check "_run" "${_name}" || \
if vm::running_check "_run" "${_name}" || \
[ -e "${VM_DS_PATH}/${_name}/run.lock" -a "$(head -n1 ${VM_DS_PATH}/${_name}/run.lock 2>/dev/null)" = "${_our_host}" ]; then
# if running and graphics, try to get vnc port
if __checkyesno "${_graphics}"; then
if util::checkyesno "${_graphics}"; then
_vnc=$(grep vnc "${VM_DS_PATH}/${_name}/console" 2>/dev/null |cut -d= -f2)
[ -z "${_vnc}" ] && _vnc="-"
fi
@@ -93,7 +93,7 @@ __vm_list(){
#
# @return int 0 if name is valid
#
__vm_check_name(){
core::check_name(){
echo "$1" | egrep -iqs '^[a-z0-9][.a-z0-9-]{0,14}[a-z0-9]$'
}
@@ -104,7 +104,7 @@ __vm_check_name(){
# @param optional string (-s) _size guest size (default = 20G)
# @param string _name the name of the guest to create
#
__vm_create(){
core::create(){
local _name _opt _size _vmdir _disk _disk_dev _uuid _num=0
local _zfs_opts _disk_size _template="default" _ds="default" _ds_path
@@ -113,49 +113,49 @@ __vm_create(){
t) _template=${OPTARG} ;;
s) _size=${OPTARG} ;;
d) _ds=${OPTARG} ;;
*) __usage ;;
*) util::usage ;;
esac
done
shift $((OPTIND - 1))
_name=$1
[ -z "${_name}" ] && __usage
[ -z "${_name}" ] && util::usage
# check guest name
__vm_check_name "${_name}" || __err "invalid virtual machine name - '${_name}'"
__datastore_get_guest "${_name}" && __err "virtual machine already exists in ${VM_DS_PATH}/${_name}"
__datastore_get "${_ds}" || __err "unable to load datastore - '${_ds}'"
core::check_name "${_name}" || util::err "invalid virtual machine name - '${_name}'"
datastore::get_guest "${_name}" && util::err "virtual machine already exists in ${VM_DS_PATH}/${_name}"
datastore::get "${_ds}" || util::err "unable to load datastore - '${_ds}'"
[ ! -f "${vm_dir}/.templates/${_template}.conf" ] && \
__err "unable to find template ${vm_dir}/.templates/${_template}.conf"
util::err "unable to find template ${vm_dir}/.templates/${_template}.conf"
# we need to get disk0 name and device type from the template
__config_load "${vm_dir}/.templates/${_template}.conf"
__config_get "_disk" "disk0_name"
__config_get "_disk_dev" "disk0_dev"
__config_get "_disk_size" "disk0_size" "20G"
__config_get "_zfs_opts" "zfs_dataset_opts"
config::load "${vm_dir}/.templates/${_template}.conf"
config::get "_disk" "disk0_name"
config::get "_disk_dev" "disk0_dev"
config::get "_disk_size" "disk0_size" "20G"
config::get "_zfs_opts" "zfs_dataset_opts"
# make sure template has a disk before we start creating anything
[ -z "${_disk}" ] && __err "template is missing disk0_name specification"
[ -z "${_disk}" ] && util::err "template is missing disk0_name specification"
# if we're on zfs, make a new filesystem
__zfs_make_dataset "${VM_DS_ZFS_DATASET}/${_name}" "${_zfs_opts}"
zfs::make_dataset "${VM_DS_ZFS_DATASET}/${_name}" "${_zfs_opts}"
[ ! -d "${VM_DS_PATH}/${_name}" ] && mkdir "${VM_DS_PATH}/${_name}" >/dev/null 2>&1
[ ! -d "${VM_DS_PATH}/${_name}" ] && __err "unable to create virtual machine directory ${VM_DS_PATH}/${_name}"
[ ! -d "${VM_DS_PATH}/${_name}" ] && util::err "unable to create virtual machine directory ${VM_DS_PATH}/${_name}"
cp "${vm_dir}/.templates/${_template}.conf" "${VM_DS_PATH}/${_name}/${_name}.conf"
[ $? -ne 0 ] && __err "unable to copy template to virtual machine directory"
[ $? -ne 0 ] && util::err "unable to copy template to virtual machine directory"
# generate a uuid
# jump through some hoops to make sure it gets its own line (but no gap)
_uuid=$(uuidgen)
__vm_config_set "${_name}" "uuid" "${_uuid}"
core::guest_config_set "${_name}" "uuid" "${_uuid}"
# get any zvol options
__config_get "_zfs_opts" "zfs_zvol_opts"
config::get "_zfs_opts" "zfs_zvol_opts"
# use cmd line size for disk 0 if specified
[ -n "${_size}" ] && _disk_size="${_size}"
@@ -164,14 +164,14 @@ __vm_create(){
while [ -n "${_disk}" ]; do
case "${_disk_dev}" in
zvol)
__zfs_make_zvol "${VM_DS_ZFS_DATASET}/${_name}/${_disk}" "${_disk_size}" "0" "${_zfs_opts}"
zfs::make_zvol "${VM_DS_ZFS_DATASET}/${_name}/${_disk}" "${_disk_size}" "0" "${_zfs_opts}"
;;
sparse-zvol)
__zfs_make_zvol "${VM_DS_ZFS_DATASET}/${_name}/${_disk}" "${_disk_size}" "1" "${_zfs_opts}"
zfs::make_zvol "${VM_DS_ZFS_DATASET}/${_name}/${_disk}" "${_disk_size}" "1" "${_zfs_opts}"
;;
*)
truncate -s "${_disk_size}" "${VM_DS_PATH}/${_name}/${_disk}"
[ $? -ne 0 ] && __err "failed to create sparse file for disk image"
[ $? -ne 0 ] && util::err "failed to create sparse file for disk image"
;;
esac
@@ -180,9 +180,9 @@ __vm_create(){
# look for another disk
_num=$((_num + 1))
__config_get "_disk" "disk${_num}_name"
__config_get "_disk_dev" "disk${_num}_dev"
__config_get "_disk_size" "disk${_num}_size" "20G"
config::get "_disk" "disk${_num}_name"
config::get "_disk_dev" "disk${_num}_dev"
config::get "_disk_size" "disk${_num}_size" "20G"
done
}
@@ -194,7 +194,7 @@ __vm_create(){
# @param string (-s) _sopt for disk the size, for network the virtual switch name
# @param string _name name of the guest
#
__vm_add(){
core::add(){
local _name _device _type _sopt _opt
while getopts d:t:s: _opt; do
@@ -202,7 +202,7 @@ __vm_add(){
d) _device=${OPTARG} ;;
t) _type=${OPTARG} ;;
s) _sopt=${OPTARG} ;;
*) __usage ;;
*) util::usage ;;
esac
done
@@ -210,13 +210,13 @@ __vm_add(){
_name="$1"
# check guest
[ -z "${_name}" ] && __usage
__datastore_get_guest "${_name}" || "${_name} does not appear to be a valid virtual machine"
[ -z "${_name}" ] && util::usage
datastore::get_guest "${_name}" || "${_name} does not appear to be a valid virtual machine"
case "${_device}" in
disk) __vm_add_disk "${_name}" "${_type}" "${_sopt}" ;;
network) __vm_add_network "${_name}" "${_sopt}" ;;
*) __err "device must be one of the following: disk network" ;;
disk) core::add_disk "${_name}" "${_type}" "${_sopt}" ;;
network) core::add_network "${_name}" "${_sopt}" ;;
*) util::err "device must be one of the following: disk network" ;;
esac
}
@@ -229,7 +229,7 @@ __vm_add(){
# @param string _device type of device file|zvol|sparse-zvol
# @param string _size size of the disk to create
#
__vm_add_disk(){
core::add_disk(){
local _name="$1"
local _device="$2"
local _size="$3"
@@ -237,46 +237,46 @@ __vm_add_disk(){
: ${_device:=file}
[ -z "${_size}" ] && __usage
[ -z "${_size}" ] && util::usage
# get the last existing disk
__config_load "${VM_DS_PATH}/${_name}/${_name}.conf"
__config_get "_zfs_opts" "zfs_zvol_opts"
config::load "${VM_DS_PATH}/${_name}/${_name}.conf"
config::get "_zfs_opts" "zfs_zvol_opts"
while [ 1 ]; do
__config_get "_curr" "disk${_num}_name"
config::get "_curr" "disk${_num}_name"
[ -z "${_curr}" ] && break
__config_get "_emulation" "disk${_num}_type"
config::get "_emulation" "disk${_num}_type"
_num=$((_num + 1))
done
[ -z "${_emulation}" ] && __err "failed to get emulation type of the existing guest disks"
[ -z "${_emulation}" ] && util::err "failed to get emulation type of the existing guest disks"
# create the disk first, then update config if no problems
case "${_device}" in
zvol)
__zfs_make_zvol "${VM_DS_ZFS_DATASET}/${_name}/disk${_num}" "${_size}" "0" "${_zfs_opts}"
zfs::make_zvol "${VM_DS_ZFS_DATASET}/${_name}/disk${_num}" "${_size}" "0" "${_zfs_opts}"
_diskname="disk${_num}"
;;
sparse-zvol)
__zfs_make_zvol "${VM_DS_ZFS_DATASET}/${_name}/disk${_num}" "${_size}" "1" "${_zfs_opts}"
zfs::make_zvol "${VM_DS_ZFS_DATASET}/${_name}/disk${_num}" "${_size}" "1" "${_zfs_opts}"
_diskname="disk${_num}"
;;
file)
truncate -s "${_size}" "${VM_DS_PATH}/${_name}/disk${_num}.img"
[ $? -ne 0 ] && __err "failed to create sparse file for disk image"
[ $? -ne 0 ] && util::err "failed to create sparse file for disk image"
_diskname="disk${_num}.img"
;;
*)
__err "device type must be one of the following: zvol sparse-zvol file"
util::err "device type must be one of the following: zvol sparse-zvol file"
;;
esac
# update configuration
__vm_config_set "${_name}" "disk${_num}_name" "${_diskname}"
__vm_config_set "${_name}" "disk${_num}_type" "${_emulation}" "1"
__vm_config_set "${_name}" "disk${_num}_dev" "${_device}" "1"
[ $? -ne 0 ] && __err "disk image created but errors while updating guest configuration"
core::guest_config_set "${_name}" "disk${_num}_name" "${_diskname}"
core::guest_config_set "${_name}" "disk${_num}_type" "${_emulation}" "1"
core::guest_config_set "${_name}" "disk${_num}_dev" "${_device}" "1"
[ $? -ne 0 ] && util::err "disk image created but errors while updating guest configuration"
}
# add network interface to guest
@@ -285,18 +285,18 @@ __vm_add_disk(){
# @param string _name name of the guest
# @param string _switch the switch name for this interface
#
__vm_add_network(){
core::add_network(){
local _name="$1"
local _switch="$2"
local _num=0 _curr _emulation
[ -z "${_switch}" ] && __usage
[ -z "${_switch}" ] && util::usage
__config_load "${VM_DS_PATH}/${_name}/${_name}.conf"
config::load "${VM_DS_PATH}/${_name}/${_name}.conf"
while [ 1 ]; do
_emulation="${_curr}"
__config_get "_curr" "network${_num}_type"
config::get "_curr" "network${_num}_type"
[ -z "${_curr}" ] && break
_num=$((_num + 1))
done
@@ -305,9 +305,9 @@ __vm_add_network(){
: ${_emulation:=virtio-net}
# update configuration
__vm_config_set "${_name}" "network${_num}_type" "${_emulation}"
__vm_config_set "${_name}" "network${_num}_switch" "${_switch}" "1"
[ $? -ne 0 ] && __err "errors encountered while updating guest configuration"
core::guest_config_set "${_name}" "network${_num}_type" "${_emulation}"
core::guest_config_set "${_name}" "network${_num}_switch" "${_switch}" "1"
[ $? -ne 0 ] && util::err "errors encountered while updating guest configuration"
}
# 'vm install'
@@ -316,20 +316,20 @@ __vm_add_network(){
# @param string _name the guest to install to
# @param string _iso the iso file in $vm_dir/.iso to use
#
__vm_install(){
core::install(){
local _name="$1"
local _iso="$2"
[ -z "${_name}" -o -z "${_iso}" ] && __usage
[ -z "${_name}" -o -z "${_iso}" ] && util::usage
# just run start with an iso
__vm_start "$1" "$2"
core::start "$1" "$2"
}
# 'vm startall'
# start all virtual machines listed in rc.conf:$vm_list
#
__vm_startall(){
core::startall(){
local _vm _done _conf
[ -z "${vm_list}" ] && exit
@@ -342,7 +342,7 @@ __vm_startall(){
[ -n "${_done}" ] && sleep ${vm_delay}
echo "Starting ${_vm}..."
__vm_start "${_vm}"
core::start "${_vm}"
_done=1
done
}
@@ -351,7 +351,7 @@ __vm_startall(){
# stop all bhyve instances
# note this will also stop instances not started by vm-bhyve
#
__vm_stopall(){
core::stopall(){
local _pids=$(pgrep -f 'bhyve:')
echo "Shutting down all bhyve virtual machines"
@@ -367,38 +367,38 @@ __vm_stopall(){
# @param string _name the name of the guest to start
# @param optional string _iso iso file is this is an install (can only be provided through 'vm install' command)
#
__vm_start(){
core::start(){
local _name="$1"
local _iso="$2"
local _cpu _memory _disk _guest _loader
[ -z "${_name}" ] && __usage
[ -z "${_name}" ] && util::usage
# try to find guest
if ! __datastore_get_guest "${_name}"; then
__warn "${_name} does not seem to be a valid virtual machine"
if ! datastore::get_guest "${_name}"; then
util::warn "${_name} does not seem to be a valid virtual machine"
return 1
fi
# confirm we aren't running
__vm_confirm_stopped "${_name}" "1" || return 1
vm::confirm_stopped "${_name}" "1" || return 1
# check basic settings before going into background mode
__config_load "${VM_DS_PATH}/${_name}/${_name}.conf"
__config_get "_cpu" "cpu"
__config_get "_memory" "memory"
__config_get "_disk" "disk0_name"
__config_get "_loader" "loader"
config::load "${VM_DS_PATH}/${_name}/${_name}.conf"
config::get "_cpu" "cpu"
config::get "_memory" "memory"
config::get "_disk" "disk0_name"
config::get "_loader" "loader"
# check minimum configuration
if [ -z "${_cpu}" -o -z "${_memory}" -o -z "${_disk}" ]; then
__warn "incomplete virtual machine configuration"
util::warn "incomplete virtual machine configuration"
return 1
fi
# we can only load freebsd without unrestricted guest support
if [ -n "${VM_NO_UG}" -a "${_loader}" != "bhyveload" ]; then
__warn "no unrestricted guest support in cpu. only single vcpu FreeBSD guests supported"
util::warn "no unrestricted guest support in cpu. only single vcpu FreeBSD guests supported"
return 1
fi
@@ -416,15 +416,15 @@ __vm_start(){
#
# @param string _name name of the guest to stop
#
__vm_stop(){
core::stop(){
local _name="$1"
local _pid _loadpid
[ -z "${_name}" ] && __usage
[ -z "${_name}" ] && util::usage
while [ -n "${_name}" ]; do
if [ ! -e "/dev/vmm/${_name}" ]; then
__warn "${_name} doesn't appear to be a running virtual machine"
util::warn "${_name} doesn't appear to be a running virtual machine"
else
_pid=$(pgrep -fx "bhyve: ${_name}")
_loadpid=$(pgrep -fl "grub-bhyve|bhyveload" | grep " ${_name}\$" |cut -d' ' -f1)
@@ -435,13 +435,13 @@ __vm_stop(){
sleep 1
kill "${_pid}"
elif [ -n "${_loadpid}" ]; then
if __confirm "Guest ${_name} is in bootloader stage, do you wish to force exit"; then
if util::confirm "Guest ${_name} is in bootloader stage, do you wish to force exit"; then
echo "Killing ${_name}"
kill "${_loadpid}"
bhyvectl --destroy --vm=${_name} >/dev/null 2>&1
fi
else
__warn "unable to locate process id for ${_name}"
util::warn "unable to locate process id for ${_name}"
fi
fi
shift
@@ -454,13 +454,13 @@ __vm_stop(){
#
# @param string _name name of the guest
#
__vm_reset(){
core::reset(){
local _name="$1"
[ -z "${_name}" ] && __usage
[ ! -e "/dev/vmm/${_name}" ] && __err "${_name} doesn't appear to be a running virtual machine"
[ -z "${_name}" ] && util::usage
[ ! -e "/dev/vmm/${_name}" ] && util::err "${_name} doesn't appear to be a running virtual machine"
__confirm "Are you sure you want to forcefully reset this virtual machine" || exit 0
util::confirm "Are you sure you want to forcefully reset this virtual machine" || exit 0
bhyvectl --force-reset --vm=${_name}
}
@@ -469,13 +469,13 @@ __vm_reset(){
#
# @param string _name name of the guest
#
__vm_poweroff(){
core::poweroff(){
local _name="$1"
[ -z "${_name}" ] && __usage
[ ! -e "/dev/vmm/${_name}" ] && __err "${_name} doesn't appear to be a running virtual machine"
[ -z "${_name}" ] && util::usage
[ ! -e "/dev/vmm/${_name}" ] && util::err "${_name} doesn't appear to be a running virtual machine"
__confirm "Are you sure you want to forcefully poweroff this virtual machine" || exit 0
util::confirm "Are you sure you want to forcefully poweroff this virtual machine" || exit 0
bhyvectl --force-poweroff --vm=${_name}
}
@@ -484,17 +484,17 @@ __vm_poweroff(){
#
# @param string _name name of the guest
#
__vm_destroy(){
core::destroy(){
local _name="$1"
[ -z "${_name}" ] && __usage
__datastore_get_guest "${_name}" || __err "${_name} doesn't appear to be a valid virtual machine"
[ -z "${_name}" ] && util::usage
datastore::get_guest "${_name}" || util::err "${_name} doesn't appear to be a valid virtual machine"
# make sure it's stopped!
__vm_confirm_stopped "${_name}" || exit 1
vm::confirm_stopped "${_name}" || exit 1
__confirm "Are you sure you want to completely remove this virtual machine" || exit 0
__zfs_destroy_dataset "${VM_DS_ZFS_DATASET}/${_name}"
util::confirm "Are you sure you want to completely remove this virtual machine" || exit 0
zfs::destroy_dataset "${VM_DS_ZFS_DATASET}/${_name}"
[ -e "${VM_DS_PATH}/${_name}" ] && rm -R "${VM_DS_PATH}/${_name}"
}
@@ -504,31 +504,31 @@ __vm_destroy(){
# @param string _old the existing guest name
# @param string _new the new guest name
#
__vm_rename(){
core::rename(){
local _old="$1"
local _new="$2"
[ -z "${_old}" -o -z "${_new}" ] && __usage
__vm_check_name "${_new}" || __err "invalid virtual machine name - '${_name}'"
[ -z "${_old}" -o -z "${_new}" ] && util::usage
core::check_name "${_new}" || util::err "invalid virtual machine name - '${_name}'"
__datastore_get_guest "${_new}" && __err "directory ${VM_DS_PATH}/${_new} already exists"
__datastore_get_guest "${_old}" || __err "${_old} doesn't appear to be a valid virtual machine"
datastore::get_guest "${_new}" && util::err "directory ${VM_DS_PATH}/${_new} already exists"
datastore::get_guest "${_old}" || util::err "${_old} doesn't appear to be a valid virtual machine"
# confirm guest stopped
__vm_confirm_stopped "${_old}" || exit 1
vm::confirm_stopped "${_old}" || exit 1
# rename zfs dataset
__zfs_rename_dataset "${_old}" "${_new}"
zfs::rename_dataset "${_old}" "${_new}"
# rename folder if it still exists (shouldn't if zfs mode and rename worked)
if [ -d "${VM_DS_PATH}/${_old}" ]; then
mv "${VM_DS_PATH}/${_old}" "${VM_DS_PATH}/${_new}" >/dev/null 2>&1
[ $? -ne 0 ] && __err "failed to rename guest directory"
[ $? -ne 0 ] && util::err "failed to rename guest directory"
fi
# rename config file
mv "${VM_DS_PATH}/${_new}/${_old}.conf" "${VM_DS_PATH}/${_new}/${_new}.conf" >/dev/null 2>&1
[ $? -ne 0 ] && __err "changed guest directory but failed to rename configuration file"
[ $? -ne 0 ] && util::err "changed guest directory but failed to rename configuration file"
}
# 'vm console'
@@ -541,16 +541,16 @@ __vm_rename(){
# @param string _name name of the guest
# @param string _port the port to connect to (default = first in configuration)
#
__vm_console(){
core::console(){
local _name="$1"
local _port="$2"
local _console
[ -z "${_name}" ] && __usage
[ -z "${_name}" ] && util::usage
__datastore_get_guest "${_name}" || __err "${_name} doesn't appear to be a valid virtual machine"
[ ! -e "/dev/vmm/${_name}" ] && __err "${_name} doesn't appear to be a running virtual machine"
[ ! -e "${VM_DS_PATH}/${_name}/console" ] && __err "can't locate console data for ${_name}"
datastore::get_guest "${_name}" || util::err "${_name} doesn't appear to be a valid virtual machine"
[ ! -e "/dev/vmm/${_name}" ] && util::err "${_name} doesn't appear to be a running virtual machine"
[ ! -e "${VM_DS_PATH}/${_name}/console" ] && util::err "can't locate console data for ${_name}"
# did user specify a com port?
# if not, get first in the file (the first will also be the console used for loader)
@@ -560,7 +560,7 @@ __vm_console(){
_console=$(head -n 1 "${VM_DS_PATH}/${_name}/console" | cut -d= -f2)
fi
[ -z "${_console}" ] && __err "unable to locate console device for this virtual machine"
[ -z "${_console}" ] && util::err "unable to locate console device for this virtual machine"
cu -l "${_console}"
}
@@ -569,14 +569,14 @@ __vm_console(){
#
# @param string _name name of the guest
#
__vm_configure(){
core::configure(){
local _name="$1"
[ -z "${_name}" ] && __usage
[ -z "${_name}" ] && util::usage
[ -z "${EDITOR}" ] && EDITOR=vi
__datastore_get_guest "${_name}" || \
__err "cannot locate configuration file for virtual machine: ${_name}"
datastore::get_guest "${_name}" || \
util::err "cannot locate configuration file for virtual machine: ${_name}"
$EDITOR "${VM_DS_PATH}/${_name}/${_name}.conf"
}
@@ -586,7 +586,7 @@ __vm_configure(){
#
# @param string _url if specified, the url will be fetch'ed into $vm_dir/.iso
#
__vm_iso(){
core::iso(){
local _url="$1"
if [ -n "${_url}" ]; then
@@ -601,7 +601,7 @@ __vm_iso(){
# show a list of available passthrough devices
# and their device number
#
__vm_passthru(){
core::passthru(){
local _dev _sbf _desc _ready
local _format="%-10s %-12s %-12s %s\n"
@@ -628,7 +628,7 @@ __vm_passthru(){
# @param string _value value
# @param int _skip_newline_check skip the check for newline
#
__vm_config_set(){
core::guest_config_set(){
local _name="$1"
local _key="$2"
local _value="$3"

View File

@@ -27,7 +27,7 @@
# 'vm datastore list'
# show configured datastores
#
__datastore_list(){
datastore::list(){
local _format="%-15s %-11s %-25s %s"
local _name _type _dataset _path _ds _spec
@@ -50,16 +50,16 @@ __datastore_list(){
printf "${_format}\n" "${_name}" "${_type}" "${_path}" "${_dataset}"
# load the rest
__config_core_get "_ds" "datastore_list"
config::core_get "_ds" "datastore_list"
for _name in ${_ds}; do
__config_core_get "_spec" "path_${_name}"
config::core_get "_spec" "path_${_name}"
[ -z "${_spec}" ] && continue
if [ "${_spec%%:*}" = "zfs" ]; then
_type="zfs"
_dataset="${_spec#*:}"
__datastore_resolve_path "_path" "${_spec}"
datastore::__resolve_path "_path" "${_spec}"
else
_type="directory"
_path="${_spec}"
@@ -79,41 +79,41 @@ __datastore_list(){
# @param string _name datastore name
# @param string _spec specification (either /path or zfs:dataset)
#
__datastore_add(){
datastore::add(){
local _name="$1"
local _spec="$2"
local _mount _num=0 _list _curr
[ -z "${_name}" -o -z "${_spec}" ] && __usage
[ "${_name}" = "default" ] && __err "additional datastore cannot be named 'default'"
__vm_check_name "${_name}" || __err "invalid datastore name - '${_name}'"
[ -z "${_name}" -o -z "${_spec}" ] && util::usage
[ "${_name}" = "default" ] && util::err "additional datastore cannot be named 'default'"
core::check_name "${_name}" || util::err "invalid datastore name - '${_name}'"
# check name not in use
__config_core_get "_list" "datastore_list"
config::core_get "_list" "datastore_list"
for _curr in ${_list}; do
[ "${_curr}" = "${_name}" ] && __err "datstore ${_name} already exists!"
[ "${_curr}" = "${_name}" ] && util::err "datstore ${_name} already exists!"
done
# look for zfs
if [ "${_spec%%:*}" = "zfs" ]; then
# try to find mountpoint
_mount=$(mount | grep "^${_spec#*:} " |cut -d' ' -f3)
[ -z "${_mount}" ] && __err "${_spec} doesn't seem to be a valid, mounted dataset"
[ -z "${_mount}" ] && util::err "${_spec} doesn't seem to be a valid, mounted dataset"
else
# make sure it's a directory
[ ! -d "${_spec}" ] && __err "${_spec} doesn't seem to be a valid directory"
[ ! -d "${_spec}" ] && util::err "${_spec} doesn't seem to be a valid directory"
_mount="${_spec}"
fi
# see if this is already our default datastore
[ "${_mount}" = "${vm_dir}" ] && __err "specified path already exists as default datastore"
[ "${_mount}" = "${vm_dir}" ] && util::err "specified path already exists as default datastore"
# save
__config_core_set "datastore_list" "${_name}" "1"
__config_core_set "path_${_name}" "${_spec}"
[ $? -ne 0 ] && __err "error saving settings to configuration file"
config::core_set "datastore_list" "${_name}" "1"
config::core_set "path_${_name}" "${_spec}"
[ $? -ne 0 ] && util::err "error saving settings to configuration file"
}
# remove a datastore
@@ -121,16 +121,16 @@ __datastore_add(){
#
# @param string _name name of dataset
#
__datastore_remove(){
datastore::remove(){
local _name="$1"
[ "${_name}" = "default" ] && __err "cannot remove default datastore"
[ "${_name}" = "default" ] && util::err "cannot remove default datastore"
__datastore_get "${_name}" || __err "unable to locate the specified dataset"
datastore::get "${_name}" || util::err "unable to locate the specified dataset"
__config_core_remove "datastore_list" "${_name}"
__config_core_remove "path_${_name}"
[ $? -ne 0 ] && __err "error removing settings from configuration file"
config::core_remove "datastore_list" "${_name}"
config::core_remove "path_${_name}"
[ $? -ne 0 ] && util::err "error removing settings from configuration file"
}
# get the filesystem path for the specified dataset spec
@@ -140,7 +140,7 @@ __datastore_remove(){
# @param string _spec the path spec (either directory or zfs:dataset)
# @return non-zero on error
#
__datastore_resolve_path(){
datastore::__resolve_path(){
local _var="$1"
local _spec="$2"
@@ -166,8 +166,8 @@ __datastore_resolve_path(){
#
# @modifies VM_DATASTORE_LIST
#
__datastore_load(){
__config_core_get "VM_DATASTORE_LIST" "datastore_list"
datastore::load(){
config::core_get "VM_DATASTORE_LIST" "datastore_list"
VM_DATASTORE_LIST="default${VM_DATASTORE_LIST:+ }${VM_DATASTORE_LIST}"
}
@@ -180,7 +180,7 @@ __datastore_load(){
# @return non-zero on error
# @modifies VM_DS_NAME VM_DS_PATH VM_DS_ZFS VM_DS_ZFS_DATASET
#
__datastore_get_guest(){
datastore::get_guest(){
local _guest="$1"
local _ds _spec _path _found _zfs _dataset
@@ -197,8 +197,8 @@ __datastore_get_guest(){
if [ -z "${_found}" ]; then
for _ds in ${VM_DATASTORE_LIST}; do
[ "${_ds}" = "default" ] && continue
__config_core_get "_spec" "path_${_ds}"
__datastore_resolve_path "_path" "${_spec}"
config::core_get "_spec" "path_${_ds}"
datastore::__resolve_path "_path" "${_spec}"
if [ -f "${_path}/${_guest}/${_guest}.conf" ]; then
[ "${_spec%%:*}" = "zfs" ] && _zfs="1" && _dataset="${_spec#*:}"
@@ -226,7 +226,7 @@ __datastore_get_guest(){
# @return non-zero on error
# @modifies VM_DS_PATH VM_DS_ZFS VM_DS_ZFS_DATASET
#
__datastore_get(){
datastore::get(){
local _ds="$1"
local _spec _path _zfs _dataset
@@ -239,10 +239,10 @@ __datastore_get(){
return 0
fi
__config_core_get "_spec" "path_${_ds}"
config::core_get "_spec" "path_${_ds}"
[ -z "${_spec}" ] && return 1
__datastore_resolve_path "_path" "${_spec}" || return 1
datastore::__resolve_path "_path" "${_spec}" || return 1
[ "${_spec%%:*}" = "zfs" ] && _zfs="1" && _dataset="${_spec#*:}"
# set variables

View File

@@ -24,12 +24,12 @@
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# __guest_load
# guest::load
# this function is responsible for doing any pre-load tasks for a guest.
# for non uefi guests this normally means running bhyveload or grub-bhyve.
# this function should return a non-zero value if there's a problem
# or 0 on success.
# As this is called from within the scope of __vm_run,
# As this is called from within the scope of vm::run,
# the following variables are already set (among others)
#
# _name: guest name
@@ -42,12 +42,12 @@
# _bootdisk: full path to primary disk
#
# I've written append wrong as it just needs to be something other than 'write',
# and is much more readable when all the __log* calls line up
# and is much more readable when all the util::log* calls line up
#
# @param optional string _iso set to the boot iso on install, or not given for normal run
# @return int 0=success, 15=vm-bhyve error (see log), other=bhyveload|grub-bhyve error code
#
__guest_load(){
guest::load(){
local _iso="$1"
local _args _command _timeout _grub_opt
@@ -56,7 +56,7 @@ __guest_load(){
[ "${_wiredmem}" = "1" ] && _args="${_args}${_args:+ }-S"
# get timeout
__config_get "_timeout" "loader_timeout" "3"
config::get "_timeout" "loader_timeout" "3"
case "${_loader}" in
bhyveload)
@@ -74,7 +74,7 @@ __guest_load(){
# check we have grub-bhyve
if [ $? -ne 0 ]; then
__log "guest" "${_name}" "grub requested but sysutils/grub2-bhyve not installed?"
util::log "guest" "${_name}" "grub requested but sysutils/grub2-bhyve not installed?"
return 15
fi
@@ -83,45 +83,45 @@ __guest_load(){
if [ -n "${_iso}" ]; then
_root="cd0"
__log_and_write "write" "${_name}" "device.map" "(hd0) ${_bootdisk}"
__log_and_write "appnd" "${_name}" "device.map" "(cd0) ${vm_dir}/.iso/${_iso}"
util::log_and_write "write" "${_name}" "device.map" "(hd0) ${_bootdisk}"
util::log_and_write "appnd" "${_name}" "device.map" "(cd0) ${vm_dir}/.iso/${_iso}"
# if we have local grub config, we need to point grub-bhyve at the host.
# if not, just use defaults
if __guest_write_config "install"; then
if guest::write_config "install"; then
_args="${_args} -r host -d ${VM_DS_PATH}/${_name}"
else
_args="${_args} -r ${_root}"
fi
else
_root="hd0,1"
__log_and_write "write" "${_name}" "device.map" "(hd0) ${_bootdisk}"
util::log_and_write "write" "${_name}" "device.map" "(hd0) ${_bootdisk}"
__config_get "_grub_opt" "grub_run_partition"
config::get "_grub_opt" "grub_run_partition"
[ -n "${_grub_opt}" ] && _root="hd0,${_grub_opt}"
# if we have local config, point grub-bhyve at it
# otherwise we use defaults, or directory and file specified by user
if __guest_write_config "run"; then
if guest::write_config "run"; then
_args="${_args} -r host -d ${VM_DS_PATH}/${_name}"
else
_args="${_args} -r ${_root}"
__config_get "_grub_opt" "grub_run_dir"
config::get "_grub_opt" "grub_run_dir"
[ -n "${_grub_opt}" ] && _args="${_args} -d ${_grub_opt}"
__config_get "_grub_opt" "grub_run_file"
config::get "_grub_opt" "grub_run_file"
[ -n "${_grub_opt}" ] && _args="${_args} -g ${_grub_opt}"
fi
fi
;;
*)
__log "guest" "${_name}" "unsupported loader - '${_loader}'"
util::log "guest" "${_name}" "unsupported loader - '${_loader}'"
return 15
;;
esac
# run the command
__log "guest" "${_name}" "${_command} ${_args} ${_name}"
util::log "guest" "${_name}" "${_command} ${_args} ${_name}"
${_command} ${_args} ${_name}
return $?
}
@@ -133,7 +133,7 @@ __guest_load(){
# @param string _type=install|run which commands to load
# @return int true (0) if commands were loaded
#
__guest_write_config(){
guest::write_config(){
local _type="$1"
local _command _num=0
@@ -142,22 +142,22 @@ __guest_write_config(){
# default for grub-bhyve and makes one less option needed
rm "${VM_DS_PATH}/${_name}/grub.*" >/dev/null 2>&1
__config_get "_command" "grub_${_type}${_num}"
config::get "_command" "grub_${_type}${_num}"
[ -z "${_command}" ] && return 1
__log_and_write "write" "${_name}" "grub.cfg" "timeout=${_timeout}"
__log_and_write "appnd" "${_name}" "grub.cfg" "menuentry '${_name} (bhyve ${_type})' {"
__log_and_write "appnd" "${_name}" "grub.cfg" " root=${_root}"
util::log_and_write "write" "${_name}" "grub.cfg" "timeout=${_timeout}"
util::log_and_write "appnd" "${_name}" "grub.cfg" "menuentry '${_name} (bhyve ${_type})' {"
util::log_and_write "appnd" "${_name}" "grub.cfg" " root=${_root}"
while [ -n "${_command}" ]; do
# we don't need boot command anymore
[ "${_command}" != "boot" ] && __log_and_write "appnd" "${_name}" "grub.cfg" " ${_command}"
[ "${_command}" != "boot" ] && util::log_and_write "appnd" "${_name}" "grub.cfg" " ${_command}"
_num=$((_num + 1))
__config_get "_command" "grub_${_type}${_num}"
config::get "_command" "grub_${_type}${_num}"
done
__log_and_write "appnd" "${_name}" "grub.cfg" "}"
util::log_and_write "appnd" "${_name}" "grub.cfg" "}"
return 0
}

View File

@@ -29,27 +29,27 @@
#
# @param optional string _name name of the guest to display
#
__vm_info(){
info::guest(){
local _name="$1"
local _bridge_list=$(ifconfig | grep ^bridge | cut -d: -f1)
local _ds
__vm_running_load
vm::running_load
# see if one guest provided
if [ -n "${_name}" ]; then
__datastore_get_guest "${_name}" || __err "unable to locate virtual machine '${_name}'"
__vm_info_guest "${_name}"
datastore::get_guest "${_name}" || util::err "unable to locate virtual machine '${_name}'"
info::guest_guest "${_name}"
exit
fi
# show all guests from all datastores
for _ds in ${VM_DATASTORE_LIST}; do
__datastore_get "${_ds}" || continue
datastore::get "${_ds}" || continue
ls -1 "${VM_DS_PATH}" 2>/dev/null | \
while read _name; do
[ -e "${VM_DS_PATH}/${_name}/${_name}.conf" ] && __vm_info_guest "${_name}"
[ -e "${VM_DS_PATH}/${_name}/${_name}.conf" ] && info::guest_guest "${_name}"
done
done
}
@@ -59,22 +59,22 @@ __vm_info(){
#
# @param optional string _switch name of switch to display
#
__vm_info_switch(){
info::guest_switch(){
local _switch="$1"
local _list
# load config file manually using non-core function
# this means we can share the config_output function with guest
__config_load "${vm_dir}/.config/system.conf"
__config_get "_list" "switch_list"
config::load "${vm_dir}/.config/system.conf"
config::get "_list" "switch_list"
if [ -n "${_switch}" ]; then
__vm_info_switch_show "${_switch}"
info::guest_switch_show "${_switch}"
exit
fi
for _switch in ${_list}; do
__vm_info_switch_show "${_switch}"
info::guest_switch_show "${_switch}"
done
}
@@ -82,51 +82,51 @@ __vm_info_switch(){
#
# @param string _switch the name of the switch
#
__vm_info_switch_show(){
info::guest_switch_show(){
local _switch="$1"
local _bridge _vale _id
local _INDENT=" "
[ -z "${_switch}" ] && return 1
__config_get "_bridge" "bridge_${_switch}"
__config_get "_vale" "vale_${_switch}"
config::get "_bridge" "bridge_${_switch}"
config::get "_vale" "vale_${_switch}"
echo "------------------------"
echo "Virtual Switch: ${_switch}"
echo "------------------------"
if __checkyesno "${_vale}"; then
if util::checkyesno "${_vale}"; then
echo "${_INDENT}type: vale"
__switch_vale_id "_id" "${_switch}"
switch::vale_id "_id" "${_switch}"
elif [ -n "${_bridge}" ]; then
echo "${_INDENT}type: manual"
_id="${_bridge}"
else
echo "${_INDENT}type: auto"
__switch_get_ident "_bridge" "${_switch}"
switch::get_ident "_bridge" "${_switch}"
_id="${_bridge}"
fi
echo "${_INDENT}ident: ${_id:--}"
__vm_info_output_config "vlan_${_switch}" "vlan"
__vm_info_output_config "nat_${_switch}" "nat"
__vm_info_output_config "ports_${_switch}" "physical-ports"
info::guest_output_config "vlan_${_switch}" "vlan"
info::guest_output_config "nat_${_switch}" "nat"
info::guest_output_config "ports_${_switch}" "physical-ports"
if [ -n "${_bridge}" ]; then
_stats=$(netstat -biI "${_bridge}" |grep '<Link#' | tail -n1 | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }' | awk '{print $5,$2}')
if [ -n "${_stats}" ]; then
_b_in=$(__vm_info_bytes_human "${_stats%% *}")
_b_out=$(__vm_info_bytes_human "${_stats##* }")
_b_in=$(info::guest_bytes_human "${_stats%% *}")
_b_out=$(info::guest_bytes_human "${_stats##* }")
echo "${_INDENT}bytes-in: ${_stats%% *} (${_b_in})"
echo "${_INDENT}bytes-out: ${_stats##* } (${_b_out})"
fi
# show guest ports
__vm_info_switch_ports
info::guest_switch_ports
fi
echo ""
@@ -134,7 +134,7 @@ __vm_info_switch_show(){
# get all guest ports for current bridge
#
__vm_info_switch_ports(){
info::guest_switch_ports(){
local _port_list=$(ifconfig "${_bridge}" |grep 'member: tap' |awk '{print $2}')
local _port _guest
@@ -152,7 +152,7 @@ __vm_info_switch_ports(){
#
# @param string _name name of the guest to display
#
__vm_info_guest(){
info::guest_guest(){
local _name="$1"
local _conf="${VM_DS_PATH}/${_name}/${_name}.conf"
local _INDENT=" "
@@ -162,11 +162,11 @@ __vm_info_guest(){
[ -z "${_name}" ] && return 1
[ ! -f "${_conf}" ] && return 1
__config_load "${_conf}"
config::load "${_conf}"
# check local and global runstate
[ -e "/dev/vmm/${_name}" ] && _RUN="1"
__vm_running_check "_global_run" "${_name}"
vm::running_check "_global_run" "${_name}"
_global_run=$(echo "${_global_run}" | tr '[:upper:]' '[:lower:]')
echo "------------------------"
@@ -177,18 +177,18 @@ __vm_info_guest(){
echo "${_INDENT}datastore: ${VM_DS_NAME}"
# basic guest configuration
__vm_info_output_config "loader" "" "default"
__vm_info_output_config "uuid" "" "auto"
__vm_info_output_config "uefi" "" "no"
__vm_info_output_config "cpu"
__vm_info_output_config "memory"
info::guest_output_config "loader" "" "default"
info::guest_output_config "uuid" "" "auto"
info::guest_output_config "uefi" "" "no"
info::guest_output_config "cpu"
info::guest_output_config "memory"
# running system details
if [ "${_RUN}" = "1" ]; then
_res_mem=$(bhyvectl --get-stats --vm="${_name}" |grep 'Resident memory' |awk '{print $3}')
if [ -n "${_res_mem}" ]; then
_b_res_mem=$(__vm_info_bytes_human "${_res_mem}")
_b_res_mem=$(info::guest_bytes_human "${_res_mem}")
echo "${_INDENT}memory-resident: ${_res_mem} (${_b_res_mem})"
fi
@@ -205,38 +205,38 @@ __vm_info_guest(){
fi
# network interfaces
__vm_info_networking
info::guest_networking
# disks
__vm_info_disks
info::guest_disks
echo ""
}
# display disks
#
__vm_info_disks(){
info::guest_disks(){
local _num=0
local _disk _type _dev _path _size _b_size _used _b_used
local _INDENT=" "
while [ 1 ]; do
__config_get "_disk" "disk${_num}_name"
__config_get "_type" "disk${_num}_type"
__config_get "_dev" "disk${_num}_dev"
config::get "_disk" "disk${_num}_name"
config::get "_type" "disk${_num}_type"
config::get "_dev" "disk${_num}_dev"
[ -z "${_disk}" -o -z "${_type}" ] && break
: ${_dev:=file}
__vm_get_disk_path "_path" "${_name}" "${_disk}" "${_dev}"
vm::get_disk_path "_path" "${_name}" "${_disk}" "${_dev}"
echo ""
echo " virtual-disk"
echo "${_INDENT}number: ${_num}"
__vm_info_output_config "disk${_num}_dev" "device-type" "file"
__vm_info_output_config "disk${_num}_type" "emulation"
__vm_info_output_config "disk${_num}_opts" "options"
info::guest_output_config "disk${_num}_dev" "device-type" "file"
info::guest_output_config "disk${_num}_type" "emulation"
info::guest_output_config "disk${_num}_opts" "options"
echo "${_INDENT}system-path: ${_path:--}"
@@ -257,8 +257,8 @@ __vm_info_disks(){
esac
if [ -n "${_size}" -a -n "${_used}" ]; then
_b_size=$(__vm_info_bytes_human "${_size}")
_b_used=$(__vm_info_bytes_human "${_used}")
_b_size=$(info::guest_bytes_human "${_size}")
_b_used=$(info::guest_bytes_human "${_used}")
echo "${_INDENT}bytes-size: ${_size} (${_b_size})"
echo "${_INDENT}bytes-used: ${_used} (${_b_used})"
fi
@@ -270,13 +270,13 @@ __vm_info_disks(){
# display networking configuration
#
__vm_info_networking(){
info::guest_networking(){
local _num=0
local _int _id _tag _switch _stats _b_in _b_out
local _INDENT=" "
while [ 1 ]; do
__config_get "_int" "network${_num}_type"
config::get "_int" "network${_num}_type"
[ -z "${_int}" ] && break
echo ""
@@ -284,20 +284,20 @@ __vm_info_networking(){
echo "${_INDENT}number: ${_num}"
# basic interface config
__vm_info_output_config "network${_num}_type" "emulation"
__vm_info_output_config "network${_num}_switch" "virtual-switch"
__vm_info_output_config "network${_num}_mac" "fixed-mac-address"
__vm_info_output_config "network${_num}_device" "fixed-device"
info::guest_output_config "network${_num}_type" "emulation"
info::guest_output_config "network${_num}_switch" "virtual-switch"
info::guest_output_config "network${_num}_mac" "fixed-mac-address"
info::guest_output_config "network${_num}_device" "fixed-device"
# if running, try to get some more interface details
if [ "${_RUN}" = "1" ]; then
__config_get "_switch" "network${_num}_switch"
config::get "_switch" "network${_num}_switch"
_int=$(ifconfig | grep -B1 "vmnet-${_name}-${_num}-" | head -n1 | cut -d' ' -f1,6)
_id=${_int%%:*}
_tag=$(ifconfig | grep "vmnet-${_name}-${_num}-" | cut -d' ' -f2)
__vm_info_find_bridge "_bridge" "${_id}"
info::guest_find_bridge "_bridge" "${_id}"
echo "${_INDENT}active-device: ${_id:--}"
echo "${_INDENT}desc: ${_tag:--}"
@@ -306,8 +306,8 @@ __vm_info_networking(){
if [ -n "${_id}" ]; then
_stats=$(netstat -biI "${_id}" | tail -n1 | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }' | awk '{print $2,$5}')
_b_in=$(__vm_info_bytes_human "${_stats%% *}")
_b_out=$(__vm_info_bytes_human "${_stats##* }")
_b_in=$(info::guest_bytes_human "${_stats%% *}")
_b_out=$(info::guest_bytes_human "${_stats##* }")
echo "${_INDENT}bytes-in: ${_stats%% *} (${_b_in})"
echo "${_INDENT}bytes-out: ${_stats##* } (${_b_out})"
@@ -325,27 +325,27 @@ __vm_info_networking(){
# @param optional string _title title to display instead of using option name
# @param optional string _default default value to display if not -
#
__vm_info_output_config(){
info::guest_output_config(){
local _option="$1"
local _title="$2"
local _default="$3"
local _var
__config_get "_var" "${_option}" "${_default:--}"
config::get "_var" "${_option}" "${_default:--}"
[ -z "${_title}" ] && _title="${_option}"
echo "${_INDENT}${_title}: ${_var}"
}
# try and find the bridge an interface is a member of.
# we do this rather than just use __switch_get_ident as
# we do this rather than just use switch::get_ident as
# this should be able to locate the bridge even for devices
# that have been bridged manually and have no switch name configured
#
# @param string _var variable to put value into
# @param string _interface interface to look for
#
__vm_info_find_bridge(){
info::guest_find_bridge(){
local _var="$1"
local _interface="$2"
local _br _found
@@ -369,7 +369,7 @@ __vm_info_find_bridge(){
#
# @param int _val the value to convert
#
__vm_info_bytes_human(){
info::guest_bytes_human(){
local _val="$1" _int _ext
local _num=1

View File

@@ -28,16 +28,16 @@
# set limits to virtual machine
# this is the background process
#
__rctl_set_limits(){
rctl::set_limits(){
local _pcpu _rbps _wbps _riops _wiops
local _pid
# get limit settings
__config_get "_pcpu" "limit_pcpu"
__config_get "_rbps" "limit_rbps"
__config_get "_wbps" "limit_wbps"
__config_get "_riops" "limit_riops"
__config_get "_wiops" "limit_wiops"
config::get "_pcpu" "limit_pcpu"
config::get "_rbps" "limit_rbps"
config::get "_wbps" "limit_wbps"
config::get "_riops" "limit_riops"
config::get "_wiops" "limit_wiops"
# return if there are no limits
[ -z "${_pcpu}${_rbps}${_wbps}${_riops}${_wiops}" ] && return 1
@@ -50,13 +50,13 @@ __rctl_set_limits(){
# see if rctl works
/usr/bin/rctl >/dev/null 2>&1
[ $? -ne 0 ] && \
__log "guest" "${_name}" "RCTL support requested but RCTL not available" && return 1
util::log "guest" "${_name}" "RCTL support requested but RCTL not available" && return 1
__log "guest" "${_name}" "applying rctl limits"
util::log "guest" "${_name}" "applying rctl limits"
if [ -n "${_pcpu}" ]; then
/usr/bin/rctl -a process:${_pid}:pcpu:deny=${_pcpu} >/dev/null 2>&1
[ $? -eq 0 ] && __log "guest" "${_name}" " pcpu=${_pcpu}"
[ $? -eq 0 ] && util::log "guest" "${_name}" " pcpu=${_pcpu}"
fi
# at this point we can return if < FreeBSD 11
@@ -64,21 +64,21 @@ __rctl_set_limits(){
if [ -n "${_rbps}" ]; then
/usr/bin/rctl -a process:${_pid}:readbps:throttle=${_rbps} >/dev/null 2>&1
[ $? -eq 0 ] && __log "guest" " readbps=${_rbps}"
[ $? -eq 0 ] && util::log "guest" " readbps=${_rbps}"
fi
if [ -n "${_wbps}" ]; then
/usr/bin/rctl -a process:${_pid}:writebps:throttle=${_wbps} >/dev/null 2>&1
[ $? -eq 0 ] && __log "guest" " writebps=${_wbps}"
[ $? -eq 0 ] && util::log "guest" " writebps=${_wbps}"
fi
if [ -n "${_riops}" ]; then
/usr/bin/rctl -a process:${_pid}:readiops:throttle=${_riops} >/dev/null 2>&1
[ $? -eq 0 ] && __log "guest" " readiops=${_riops}"
[ $? -eq 0 ] && util::log "guest" " readiops=${_riops}"
fi
if [ -n "${_wiops}" ]; then
/usr/bin/rctl -a process:${_pid}:writeiops:throttle=${_wiops} >/dev/null 2>&1
[ $? -eq 0 ] && __log "guest" " writeiops=${_wiops}"
[ $? -eq 0 ] && util::log "guest" " writeiops=${_wiops}"
fi
}

View File

@@ -32,7 +32,7 @@
# @param string _name the name of the guest to run
# @param optional string _iso the iso file for an install
#
__vm_run(){
vm::run(){
local _name="$1"
local _iso="$2" _iso_dev
local _cpu _memory _bootdisk _bootdisk_dev _guest _wiredmem
@@ -41,41 +41,41 @@ __vm_run(){
local _com _comports _comstring _logpath="/dev/null" _bootrom
# try to load datstore details
__datastore_get_guest "${_name}" || exit 5
datastore::get_guest "${_name}" || exit 5
# bail out immediately if guest running
__vm_confirm_stopped "${_name}" "1" || exit 10
vm::confirm_stopped "${_name}" "1" || exit 10
__config_load "${VM_DS_PATH}/${_name}/${_name}.conf"
__config_get "_cpu" "cpu"
__config_get "_memory" "memory"
__config_get "_loader" "loader"
__config_get "_bootdisk" "disk0_name"
__config_get "_bootdisk_dev" "disk0_dev" "file"
__config_get "_uefi" "uefi" "no"
__config_get "_hostbridge" "hostbridge" "standard"
__config_get "_comports" "comports" "com1"
__config_get "_uuid" "uuid"
__config_get "_utc" "utctime" "no"
__config_get "_debug" "debug" "no"
config::load "${VM_DS_PATH}/${_name}/${_name}.conf"
config::get "_cpu" "cpu"
config::get "_memory" "memory"
config::get "_loader" "loader"
config::get "_bootdisk" "disk0_name"
config::get "_bootdisk_dev" "disk0_dev" "file"
config::get "_uefi" "uefi" "no"
config::get "_hostbridge" "hostbridge" "standard"
config::get "_comports" "comports" "com1"
config::get "_uuid" "uuid"
config::get "_utc" "utctime" "no"
config::get "_debug" "debug" "no"
__log_rotate "guest" "${_name}"
__log "guest" "${_name}" "initialising"
__log "guest" "${_name}" " [loader: ${_loader:-none}]"
__log "guest" "${_name}" " [uefi: ${_uefi}]"
__log "guest" "${_name}" " [cpu: ${_cpu}]"
__log "guest" "${_name}" " [memory: ${_memory}]"
__log "guest" "${_name}" " [hostbridge: ${_hostbridge}]"
__log "guest" "${_name}" " [com ports: ${_comports}]"
__log "guest" "${_name}" " [uuid: ${_uuid:-auto}]"
__log "guest" "${_name}" " [utctime: ${_utc}]"
__log "guest" "${_name}" " [debug mode: ${_debug}]"
__log "guest" "${_name}" " [primary disk: ${_bootdisk}]"
__log "guest" "${_name}" " [primary disk dev: ${_bootdisk_dev}]"
util::log_rotate "guest" "${_name}"
util::log "guest" "${_name}" "initialising"
util::log "guest" "${_name}" " [loader: ${_loader:-none}]"
util::log "guest" "${_name}" " [uefi: ${_uefi}]"
util::log "guest" "${_name}" " [cpu: ${_cpu}]"
util::log "guest" "${_name}" " [memory: ${_memory}]"
util::log "guest" "${_name}" " [hostbridge: ${_hostbridge}]"
util::log "guest" "${_name}" " [com ports: ${_comports}]"
util::log "guest" "${_name}" " [uuid: ${_uuid:-auto}]"
util::log "guest" "${_name}" " [utctime: ${_utc}]"
util::log "guest" "${_name}" " [debug mode: ${_debug}]"
util::log "guest" "${_name}" " [primary disk: ${_bootdisk}]"
util::log "guest" "${_name}" " [primary disk dev: ${_bootdisk_dev}]"
# check basic settings
if [ -z "${_cpu}" -o -z "${_memory}" -o -z "${_bootdisk}" ]; then
__log "guest" "${_name}" "fatal; unable to start - missing required configuration"
util::log "guest" "${_name}" "fatal; unable to start - missing required configuration"
exit 15
fi
@@ -84,14 +84,14 @@ __vm_run(){
# only FreeBSD guests. these start direct in 64bit mode and don't need UG
if [ "${_loader}" != "bhyveload" ]; then
__log "guest" "${_name}" "fatal; unable to start - no unrestricted guest support"
util::log "guest" "${_name}" "fatal; unable to start - no unrestricted guest support"
exit 15
fi
# only 1 vcpu
if [ "${_cpu}" -gt "1" ]; then
_cpu=1
__log "guest" "${_name}" "warning; no unrestricted guest support. reducing vcpu count to 1"
util::log "guest" "${_name}" "warning; no unrestricted guest support. reducing vcpu count to 1"
fi
fi
@@ -99,9 +99,9 @@ __vm_run(){
_opts="-AHP"
# if uefi, make sure we have bootrom, then update options for uefi support
if __checkyesno "${_uefi}"; then
if util::checkyesno "${_uefi}"; then
if [ ${VERSION_BSD} -lt 1002509 ]; then
__log "guest" "${_name}" "fatal; uefi guests can only be run on FreeBSD 10.3 or newer"
util::log "guest" "${_name}" "fatal; uefi guests can only be run on FreeBSD 10.3 or newer"
exit 15
fi
@@ -113,7 +113,7 @@ __vm_run(){
[ -z "${_bootrom}" ] && _bootrom="${vm_dir}/.config/BHYVE_UEFI.fd"
if [ ! -e "${_bootrom}" ]; then
__log "guest" "${_name}" "fatal; please download relevant uefi firmware to ${_bootrom}"
util::log "guest" "${_name}" "fatal; please download relevant uefi firmware to ${_bootrom}"
exit 15
fi
@@ -125,16 +125,16 @@ __vm_run(){
# we must have a loader
if [ -z "${_loader}" ]; then
__log "guest" "${_name}" "fatal; guest does not have a loader specified"
util::log "guest" "${_name}" "fatal; guest does not have a loader specified"
exit 15
fi
fi
# if we have passthru, check vt-d support now and exit
__config_get "_passdev" "passthru0"
config::get "_passdev" "passthru0"
if [ -n "${_passdev}" ] && ! __check_bhyve_iommu; then
__log "guest" "${_name}" "fatal; pci passthrough not supported on this system (no VT-d)"
if [ -n "${_passdev}" ] && ! util::check_bhyve_iommu; then
util::log "guest" "${_name}" "fatal; pci passthrough not supported on this system (no VT-d)"
exit 15
fi
@@ -143,32 +143,32 @@ __vm_run(){
[ -n "${_uuid}" ] && _opts="${_opts} -U ${_uuid}"
# set utc time in opts if requested
if __checkyesno "${_utc}"; then
if util::checkyesno "${_utc}"; then
if [ ${VERSION_BSD} -ge 1002000 ]; then
_opts="${_opts} -u"
else
__log "guest" "${_name}" "warning; utc time requested but not available pre FreeBSD 10.2"
util::log "guest" "${_name}" "warning; utc time requested but not available pre FreeBSD 10.2"
fi
fi
# send bhyve output to bhyve.log if debug=yes
__checkyesno "${_debug}" && _logpath="${VM_DS_PATH}/${_name}/bhyve.log"
util::checkyesno "${_debug}" && _logpath="${VM_DS_PATH}/${_name}/bhyve.log"
# complete the boot disk path
__vm_get_disk_path "_bootdisk" "${_name}" "${_bootdisk}" "${_bootdisk_dev}"
vm::get_disk_path "_bootdisk" "${_name}" "${_bootdisk}" "${_bootdisk_dev}"
# build bhyve device string
__vm_bhyve_device_comports
__vm_bhyve_device_basic
__vm_bhyve_device_disks
__vm_bhyve_device_networking
__vm_bhyve_device_rand
__vm_bhyve_device_passthru
__vm_bhyve_device_fbuf
__vm_bhyve_device_mouse
vm::bhyve_device_comports
vm::bhyve_device_basic
vm::bhyve_device_disks
vm::bhyve_device_networking
vm::bhyve_device_rand
vm::bhyve_device_passthru
vm::bhyve_device_fbuf
vm::bhyve_device_mouse
__vm_lock
__log "guest" "${_name}" "booting"
vm::lock
util::log "guest" "${_name}" "booting"
while [ 1 ]; do
@@ -179,7 +179,7 @@ __vm_run(){
if [ -e "/dev/vmm/${_name}" -a -z "${_uefi}" ]; then
bhyvectl --vm="${_name}" --destroy >/dev/null 2>&1
if [ $? -ne 0 ]; then
__log "guest" "${_name}" "fatal; failed to destroy existing vmm device"
util::log "guest" "${_name}" "fatal; failed to destroy existing vmm device"
_exit=15
break
fi
@@ -193,24 +193,24 @@ __vm_run(){
# load guest
if [ -n "${_loader}" ]; then
__guest_load "${_iso}"
guest::load "${_iso}"
_exit=$?
# check no errors
if [ ${_exit} -ne 0 ]; then
__log "guest" "${_name}" "fatal; loader returned error ${_exit}"
util::log "guest" "${_name}" "fatal; loader returned error ${_exit}"
break
fi
fi
__log "guest" "${_name}" " [bhyve options: ${_opts}]"
__log "guest" "${_name}" " [bhyve devices: ${_devices}]"
__log "guest" "${_name}" " [bhyve console: ${_comstring}]"
[ -n "${_iso_dev}" ] && __log "guest" "${_name}" " [bhyve iso device: ${_iso_dev}]"
__log "guest" "${_name}" "starting bhyve"
util::log "guest" "${_name}" " [bhyve options: ${_opts}]"
util::log "guest" "${_name}" " [bhyve devices: ${_devices}]"
util::log "guest" "${_name}" " [bhyve console: ${_comstring}]"
[ -n "${_iso_dev}" ] && util::log "guest" "${_name}" " [bhyve iso device: ${_iso_dev}]"
util::log "guest" "${_name}" "starting bhyve"
# call rctl now as next line will block until bhyve exits
__rctl_set_limits &
rctl::set_limits &
# actually run bhyve!
# we're already in the background so we just wait for it to exit
@@ -222,12 +222,12 @@ __vm_run(){
# get bhyve exit code
_exit=$?
__log "guest" "${_name}" "bhyve exited with status ${_exit}"
util::log "guest" "${_name}" "bhyve exited with status ${_exit}"
# if 0, guest rebooted so continue loop
# anything else we break and shutdown
[ $_exit -ne 0 ] && break
__log "guest" "${_name}" "restarting"
util::log "guest" "${_name}" "restarting"
# remove install iso so guest reboots from disk
# after install non-uefi guests will still get install cd until a full shutdown+restart
@@ -237,13 +237,13 @@ __vm_run(){
# destroy taps
for _devices in ${_taplist}; do
__log "guest" "${_name}" "destroying network device ${_devices}"
util::log "guest" "${_name}" "destroying network device ${_devices}"
ifconfig "${_devices}" destroy
done
__log "guest" "${_name}" "stopped"
util::log "guest" "${_name}" "stopped"
bhyvectl --destroy --vm=${_name}
__vm_unlock
vm::unlock
exit ${_exit}
}
@@ -253,7 +253,7 @@ __vm_run(){
#
# @param string - the name of the guest to lock
#
__vm_lock(){
vm::lock(){
hostname > "${VM_DS_PATH}/${_name}/run.lock"
}
@@ -261,7 +261,7 @@ __vm_lock(){
#
# @param string - the name of the guest to unlock
#
__vm_unlock(){
vm::unlock(){
unlink "${VM_DS_PATH}/${_name}/run.lock" >/dev/null 2>&1
unlink "${VM_DS_PATH}/${_name}/console" >/dev/null 2>&1
}
@@ -275,7 +275,7 @@ __vm_unlock(){
#
# @modifies _com _comstring
#
__vm_bhyve_device_comports(){
vm::bhyve_device_comports(){
local _port _num=1 _nmdm=""
unlink "${VM_DS_PATH}/${_name}/console" >/dev/null 2>&1
@@ -287,7 +287,7 @@ __vm_bhyve_device_comports(){
continue
fi
__vm_find_console "_nmdm" "${_nmdm}"
vm::find_console "_nmdm" "${_nmdm}"
# use first com port for the loader
[ ${_num} -eq 1 ] && _com="/dev/nmdm${_nmdm}A"
@@ -304,7 +304,7 @@ __vm_bhyve_device_comports(){
#
# @modifies _devices
#
__vm_bhyve_device_basic(){
vm::bhyve_device_basic(){
# add hostbridge
case "$_hostbridge" in
@@ -325,18 +325,18 @@ __vm_bhyve_device_basic(){
#
# @modifies _devices _slot
#
__vm_bhyve_device_disks(){
vm::bhyve_device_disks(){
local _disk _type _dev _path _opts
local _num=0
# get disks
while [ 1 ]; do
__config_get "_disk" "disk${_num}_name"
__config_get "_type" "disk${_num}_type"
config::get "_disk" "disk${_num}_name"
config::get "_type" "disk${_num}_type"
[ -z "${_disk}" -o -z "${_type}" ] && break
__config_get "_dev" "disk${_num}_dev"
__config_get "_opts" "disk${_num}_opts"
config::get "_dev" "disk${_num}_dev"
config::get "_opts" "disk${_num}_opts"
# we need to move slot if we've hit function 8
if [ ${_func} -ge 8 ]; then
@@ -344,7 +344,7 @@ __vm_bhyve_device_disks(){
_slot=$((_slot + 1))
fi
__vm_get_disk_path "_path" "${_name}" "${_disk}" "${_dev}"
vm::get_disk_path "_path" "${_name}" "${_disk}" "${_dev}"
_devices="${_devices} -s ${_slot}:${_func},${_type},${_path}"
[ -n "${_opts}" ] && _devices="${_devices},${_opts}"
@@ -353,7 +353,7 @@ __vm_bhyve_device_disks(){
# can't go past slot 6 with current UEFI firmware
if [ ${_slot} -ge 7 ]; then
__log "guest" "${_name}" "ending disks at disk${_num} due to UEFI firmware limitations"
util::log "guest" "${_name}" "ending disks at disk${_num} due to UEFI firmware limitations"
break
fi
else
@@ -374,25 +374,25 @@ __vm_bhyve_device_disks(){
# get bhyve device string for networking
# we dynamically create a new tap device for each interface
# if we can find the correct bridge, we then add the tap as a member
# we add each tap to __taplist from __vm_run which it will
# we add each tap to __taplist from vm::run which it will
# use to desstroy them all on shutdown
#
# @modifies _devices _slot _taplist
#
__vm_bhyve_device_networking(){
vm::bhyve_device_networking(){
local _type _switch _mac _custom_tap _tap _sid _mtu
local _num=0
while [ 1 ]; do
__config_get "_type" "network${_num}_type"
config::get "_type" "network${_num}_type"
[ -z "${_type}" ] && break
__config_get "_switch" "network${_num}_switch"
__config_get "_mac" "network${_num}_mac"
__config_get "_custom_tap" "network${_num}_device"
config::get "_switch" "network${_num}_switch"
config::get "_mac" "network${_num}_mac"
config::get "_custom_tap" "network${_num}_device"
# set a static mac if we don't have one
[ -z "${_mac}" ] && __vm_generate_static_mac
[ -z "${_mac}" ] && vm::generate_static_mac
# move slot if we've hit function 8
if [ ${_func} -ge 8 ]; then
@@ -400,11 +400,11 @@ __vm_bhyve_device_networking(){
_slot=$((_slot + 1))
fi
if __switch_is_vale "${_switch}"; then
if switch::is_vale "${_switch}"; then
# create a vale port id
__switch_vale_id "_tap" "${_switch}" "${_mac}"
switch::vale_id "_tap" "${_switch}" "${_mac}"
__log "guest" "${_name}" "adding vale interface ${_tap} (${_switch})"
util::log "guest" "${_name}" "adding vale interface ${_tap} (${_switch})"
_devices="${_devices} -s ${_slot}:${_func},${_type},${_tap}"
[ -n "${_mac}" ] && _devices="${_devices},mac=${_mac}"
@@ -418,25 +418,25 @@ __vm_bhyve_device_networking(){
fi
if [ -n "${_tap}" ]; then
__log "guest" "${_name}" "initialising network device ${_tap}"
util::log "guest" "${_name}" "initialising network device ${_tap}"
ifconfig "${_tap}" description "vmnet-${_name}-${_num}-${_switch:-custom}" >/dev/null 2>&1
if [ -n "${_switch}" ]; then
__switch_get_ident "_sid" "${_switch}"
switch::get_ident "_sid" "${_switch}"
if [ -n "${_sid}" ]; then
_mtu=$(ifconfig "${_sid}" | head -n1 | awk '{print $NF}')
if [ "${_mtu}" != "1500" ]; then
__log "guest" "${_name}" "setting mtu of ${_tap} to ${_mtu}"
util::log "guest" "${_name}" "setting mtu of ${_tap} to ${_mtu}"
ifconfig "${_tap}" mtu "${_mtu}" >/dev/null 2>&1
fi
__log "guest" "${_name}" "adding ${_tap} -> ${_sid} (${_switch})"
util::log "guest" "${_name}" "adding ${_tap} -> ${_sid} (${_switch})"
ifconfig "${_sid}" addm "${_tap}" >/dev/null 2>&1
[ $? -ne 0 ] && __log "guest" "${_name}" "failed to add ${_tap} to ${_sid}"
[ $? -ne 0 ] && util::log "guest" "${_name}" "failed to add ${_tap} to ${_sid}"
else
__log "guest" "${_name}" "failed to find virtual switch '${_switch}'"
util::log "guest" "${_name}" "failed to find virtual switch '${_switch}'"
fi
fi
@@ -461,12 +461,12 @@ __vm_bhyve_device_networking(){
#
# @modifies _devices _slot
#
__vm_bhyve_device_rand(){
vm::bhyve_device_rand(){
local _rand
__config_get "_rand" "virt_random"
config::get "_rand" "virt_random"
if __checkyesno "${_rand}"; then
if util::checkyesno "${_rand}"; then
_devices="${_devices} -s ${_slot}:0,virtio-rnd"
_slot=$((_slot + 1))
fi
@@ -474,18 +474,18 @@ __vm_bhyve_device_rand(){
# add frame buffer output
#
__vm_bhyve_device_fbuf(){
vm::bhyve_device_fbuf(){
local _graphics _port _listen _res _wait
local _fbuf_conf
__config_get "_graphics" "graphics"
__config_get "_port" "graphics_port"
__config_get "_listen" "graphics_listen"
__config_get "_res" "graphics_res"
__config_get "_wait" "graphics_wait" "auto"
config::get "_graphics" "graphics"
config::get "_port" "graphics_port"
config::get "_listen" "graphics_listen"
config::get "_res" "graphics_res"
config::get "_wait" "graphics_wait" "auto"
# return if graphics disabled
! __checkyesno "${_graphics}" && return 0
! util::checkyesno "${_graphics}" && return 0
[ -z "${_uefi}" ] && return 0
# check if graphics_wait is auto
@@ -497,20 +497,20 @@ __vm_bhyve_device_fbuf(){
# try to get port
# return if we can't
if [ -z "${_port}" ]; then
__vm_find_available_port "_port" "5900"
vm::find_available_net_port "_port" "5900"
if [ -z "${_port}" ]; then
__log "guest" "${_name}" "warning; unable to allocate a network port for graphics/vnc"
util::log "guest" "${_name}" "warning; unable to allocate a network port for graphics/vnc"
return 1
fi
__log "guest" "${_name}" "dynamically allocated port ${_port} for vnc connections"
util::log "guest" "${_name}" "dynamically allocated port ${_port} for vnc connections"
fi
# add ip, port, resolution, wait
_fbuf_conf="tcp=${_listen:-0.0.0.0}:${_port}"
[ -n "${_res}" ] && _fbuf_conf="${_fbuf_conf},w=${_res%%x*},h=${_res##*x}"
__checkyesno "${_wait}" && _fbuf_conf="${_fbuf_conf},wait"
util::checkyesno "${_wait}" && _fbuf_conf="${_fbuf_conf},wait"
# write vnc port to console data
echo "vnc=${_listen:-0.0.0.0}:${_port}" >> "${VM_DS_PATH}/${_name}/console"
@@ -522,13 +522,13 @@ __vm_bhyve_device_fbuf(){
# add a xhci mouse device
#
__vm_bhyve_device_mouse(){
vm::bhyve_device_mouse(){
local _mouse
__config_get "_mouse" "xhci_mouse"
config::get "_mouse" "xhci_mouse"
# add a tablet device if enabled
if __checkyesno "${_mouse}"; then
if util::checkyesno "${_mouse}"; then
_devices="${_devices} -s ${_slot}:0,xhci,tablet"
_slot=$((_slot + 1))
fi
@@ -540,13 +540,13 @@ __vm_bhyve_device_mouse(){
#
# @modifies _devices _slot _opts _wiredmem
#
__vm_bhyve_device_passthru(){
vm::bhyve_device_passthru(){
local _dev _orig_slot _func=0
local _last_orig_slot
local _num=0
while [ 1 ]; do
__config_get "_dev" "passthru${_num}"
config::get "_dev" "passthru${_num}"
[ -z "${_dev}" ] && break
_orig_slot=${_dev%%/*}
@@ -587,7 +587,7 @@ __vm_bhyve_device_passthru(){
# @param string _disk the name of the disk
# @param string _disk_dev=file|zvol|sparse-zvol|custom type of device
#
__vm_get_disk_path(){
vm::get_disk_path(){
local _var="$1"
local _name="$2"
local _disk="$3"
@@ -617,7 +617,7 @@ __vm_get_disk_path(){
# @param string _var variable to put value into
# @param optional int _num the device number to start searching at (default = 0)
#
__vm_find_console(){
vm::find_console(){
local _var="$1"
local _num="$2"
local _ls
@@ -650,7 +650,7 @@ __vm_find_console(){
#
# @modifies VM_RUN_BHYVE VM_RUN_LOAD
#
__vm_running_load(){
vm::running_load(){
VM_RUN_BHYVE=$(pgrep -fl "bhyve:" | awk '{print $1,$NF}')
VM_RUN_LOAD=$(pgrep -fl "grub-bhyve|bhyveload" | awk '{print $1,$NF}')
}
@@ -664,7 +664,7 @@ __vm_running_load(){
# @param string _name name of the guest to look for
# @return success if running
#
__vm_running_check(){
vm::running_check(){
local _var="$1"
local _name="$2"
local IFS=$'\n'
@@ -698,7 +698,7 @@ __vm_running_check(){
# @param int _skip_lock skip local lock file if no /dev/vmm found
# @return success if not running
#
__vm_confirm_stopped(){
vm::confirm_stopped(){
local _name="$1"
local _skip_lock="$2"
local _host _our_host
@@ -711,14 +711,14 @@ __vm_confirm_stopped(){
_host=$(head -n 1 "${VM_DS_PATH}/${_name}/run.lock")
if [ "${_host}" != "${_our_host}" -o "${_skip_lock}" != "1" ]; then
__warn "${_name} appears to be running on ${_host} (locked)"
util::warn "${_name} appears to be running on ${_host} (locked)"
return 1
fi
fi
# check local machine, just in case guest run manually
if [ -e "/dev/vmm/${_name}" ]; then
__warn "${_name} appears to be running locally (vmm exists)"
util::warn "${_name} appears to be running locally (vmm exists)"
return 1
fi
@@ -734,7 +734,7 @@ __vm_confirm_stopped(){
# with an incrementing integer just in case we happen to
# get 5 zeros.
#
__vm_generate_static_mac(){
vm::generate_static_mac(){
local _time=$(date +%s)
local _key _part="0:00:00"
local _base _int=0
@@ -752,8 +752,8 @@ __vm_generate_static_mac(){
# add base bhyve OUI
_mac="58:9c:fc:0${_part}"
__log "guest" "${_name}" "generated static mac ${_mac} (based on '${_key}')"
__vm_config_set "${_name}" "network${_num}_mac" "${_mac}"
util::log "guest" "${_name}" "generated static mac ${_mac} (based on '${_key}')"
core::guest_config_set "${_name}" "network${_num}_mac" "${_mac}"
}
# try to find an available network port to listen on
@@ -763,7 +763,7 @@ __vm_generate_static_mac(){
# @param int _curr the port to start searching from
# @return true if we found a port
#
__vm_find_available_port(){
vm::find_available_net_port(){
local _var="$1"
local _curr="$2"
local _open _line _max _used

View File

@@ -29,35 +29,35 @@
# configuration file have bridge interfaces. If any new switches are
# created, the bridge is done at the same time
#
__switch_init(){
switch::init(){
local _switchlist _switch _id
local _nat _havenat=0 _bridge _vale
__config_core_get "_switchlist" "switch_list"
config::core_get "_switchlist" "switch_list"
# create bridges for each switch if they don't already exist
if [ -n "${_switchlist}" ]; then
for _switch in ${_switchlist}; do
# do nothing if it's a vale switch
__config_core_get "_vale" "vale_${_switch}"
__checkyesno "${_vale}" && continue
config::core_get "_vale" "vale_${_switch}"
util::checkyesno "${_vale}" && continue
# do nothing if the bridge already exists
__switch_get_ident "_id" "${_switch}"
switch::get_ident "_id" "${_switch}"
[ -n "${_id}" ] && continue
__config_core_get "_nat" "nat_${_switch}"
__config_core_get "_bridge" "bridge_${_switch}"
config::core_get "_nat" "nat_${_switch}"
config::core_get "_bridge" "bridge_${_switch}"
if [ -n "${_bridge}" ]; then
ifconfig "${_bridge}" description "vm-${_switch}" up >/dev/null 2>&1
else
_id=$(ifconfig bridge create)
[ $? -ne 0 ] && __err "failed to create bridge interface"
[ $? -ne 0 ] && util::err "failed to create bridge interface"
ifconfig "${_id}" description "vm-${_switch}" up
# add all member interfaces
__switch_add_allmembers "${_switch}" "${_id}"
switch::__add_allmembers "${_switch}" "${_id}"
fi
[ -n "${_nat}" ] &&_havenat="1"
@@ -65,33 +65,33 @@ __switch_init(){
fi
# only load dnsmasq/pf if we have a nat switch
[ "${_havenat}" = "1" ] && __switch_nat_init
[ "${_havenat}" = "1" ] && switch::nat_init
}
# list switches, currently just from stored configuration
#
__switch_list(){
switch::list(){
local _switchlist _portlist _switch _port
local _vlan _nat _bridge _type _vale
local _id _format="%-15s %-10s %-11s %-9s %-12s %s\n"
__config_core_get "_switchlist" "switch_list"
config::core_get "_switchlist" "switch_list"
printf "${_format}" "NAME" "TYPE" "IDENT" "VLAN" "NAT" "PORTS"
for _switch in ${_switchlist}; do
__switch_get_ident "_id" "${_switch}"
switch::get_ident "_id" "${_switch}"
[ -z "${_id}" ] && _id="-"
__config_core_get "_portlist" "ports_${_switch}"
__config_core_get "_vlan" "vlan_${_switch}"
__config_core_get "_nat" "nat_${_switch}"
__config_core_get "_bridge" "bridge_${_switch}"
__config_core_get "_vale" "vale_${_switch}"
config::core_get "_portlist" "ports_${_switch}"
config::core_get "_vlan" "vlan_${_switch}"
config::core_get "_nat" "nat_${_switch}"
config::core_get "_bridge" "bridge_${_switch}"
config::core_get "_vale" "vale_${_switch}"
if __checkyesno "${_vale}"; then
if util::checkyesno "${_vale}"; then
_type="vale"
__switch_vale_id "_id" "${_switch}"
switch::vale_id "_id" "${_switch}"
: ${_portlist:=n/a}
: ${_vlan:=n/a}
: ${_nat:=n/a}
@@ -116,22 +116,22 @@ __switch_list(){
#
# @param string _switch name of the switch to create
#
__switch_create(){
switch::create(){
local _switch="$1"
local _id _curr_list _curr
__vm_check_name "${_switch}" || __err "invalid switch name - '${_name}'"
__config_core_get "_curr_list" "switch_list"
core::check_name "${_switch}" || util::err "invalid switch name - '${_name}'"
config::core_get "_curr_list" "switch_list"
for _curr in $_curr_list; do
[ "${_switch}" = "${_curr}" ] && __err "switch ${_switch} already exists"
[ "${_switch}" = "${_curr}" ] && util::err "switch ${_switch} already exists"
done
__config_core_set "switch_list" "${_switch}" "1"
[ $? -ne 0 ] && __err "failed to add switch to configuration file"
config::core_set "switch_list" "${_switch}" "1"
[ $? -ne 0 ] && util::err "failed to add switch to configuration file"
_id=$(ifconfig bridge create)
[ $? -ne 0 ] && __err "failed to create bridge interface"
[ $? -ne 0 ] && util::err "failed to create bridge interface"
ifconfig "${_id}" description "vm-${_switch}" up
}
@@ -141,25 +141,25 @@ __switch_create(){
# @param string _switch name of the switch to create
# @param string _bridge name of the bridge interface to import
#
__switch_import(){
switch::import(){
local _switch="$1"
local _bridge="$2"
local _exists
[ -z "${_switch}" -o -z "${_bridge}" ] && __usage
__vm_check_name "${_switch}" || __err "invalid switch name - '${_name}'"
__config_core_get "_curr_list" "switch_list"
[ -z "${_switch}" -o -z "${_bridge}" ] && util::usage
core::check_name "${_switch}" || util::err "invalid switch name - '${_name}'"
config::core_get "_curr_list" "switch_list"
for _curr in $_curr_list; do
[ "${_switch}" = "${_curr}" ] && __err "switch ${_switch} already exists"
[ "${_switch}" = "${_curr}" ] && util::err "switch ${_switch} already exists"
done
_exists=$(ifconfig | grep "^${_bridge}: ")
[ -z "${_exists}" ] && __err "${_bridge} does not appear to be a valid existing bridge"
[ -z "${_exists}" ] && util::err "${_bridge} does not appear to be a valid existing bridge"
__config_core_set "switch_list" "${_switch}" "1"
__config_core_set "bridge_${_switch}" "${_bridge}"
[ $? -ne 0 ] && __err "failed to add switch to configuration file"
config::core_set "switch_list" "${_switch}" "1"
config::core_set "bridge_${_switch}" "${_bridge}"
[ $? -ne 0 ] && util::err "failed to add switch to configuration file"
# attach our description to bridge
# this will allow vm-bhyve to find it and attach guests
@@ -171,40 +171,40 @@ __switch_import(){
#
# @param string _switch name of the switch
#
__switch_remove(){
switch::remove(){
local _switch="$1"
local _id _nat _bridge _vale
__config_core_get "_bridge" "bridge_${_switch}"
__config_core_get "_nat" "nat_${_switch}"
__config_core_get "_vale" "vale_${_switch}"
config::core_get "_bridge" "bridge_${_switch}"
config::core_get "_nat" "nat_${_switch}"
config::core_get "_vale" "vale_${_switch}"
# if manual, leave it there and just remove from our config
if [ -n "${_bridge}" ]; then
ifconfig "${_bridge}" description "" >/dev/null 2>&1
__config_core_remove "switch_list" "${_switch}"
__config_core_remove "bridge_${_switch}"
config::core_remove "switch_list" "${_switch}"
config::core_remove "bridge_${_switch}"
exit 0
fi
if [ -z "${_vale}" ]; then
__switch_get_ident "_id" "${_switch}"
__switch_remove_allmembers "${_switch}" "${_id}"
switch::get_ident "_id" "${_switch}"
switch::remove_allmembers "${_switch}" "${_id}"
fi
__config_core_remove "switch_list" "${_switch}" "1"
__config_core_remove "ports_${_switch} vlan_${_switch} nat_${_switch} vale_${_switch}"
config::core_remove "switch_list" "${_switch}" "1"
config::core_remove "ports_${_switch} vlan_${_switch} nat_${_switch} vale_${_switch}"
if [ -z "${_vale}" ]; then
if [ -n "${_id}" ]; then
ifconfig "${_id}" destroy >/dev/null 2>&1
[ $? -ne 0 ] && __warn "removed configuration but failed to remove bridge"
[ $? -ne 0 ] && util::warn "removed configuration but failed to remove bridge"
else
__warn "removed configuration but failed to remove bridge"
util::warn "removed configuration but failed to remove bridge"
fi
# reset nat if this switch had nat
[ -n "${_nat}" ] && __switch_nat_init
[ -n "${_nat}" ] && switch::nat_init
fi
}
@@ -215,29 +215,29 @@ __switch_remove(){
# @param string _switch name of the switch
# @param int _vlan vlan number (or 0 to switch vlan off)
#
__switch_vlan(){
switch::vlan(){
local _switch="$1"
local _vlan="$2"
[ -z "${_switch}" -o -z "${_vlan}" ] && __usage
__switch_auto "${_switch}"
[ -z "${_switch}" -o -z "${_vlan}" ] && util::usage
switch::__check_auto "${_switch}"
echo "${_vlan}" | egrep -qs '^[0-9]{1,4}$'
[ $? -ne 0 ] && __err "invalid vlan number"
[ ${_vlan} -ge 4095 ] && __err "invalid vlan number"
[ $? -ne 0 ] && util::err "invalid vlan number"
[ ${_vlan} -ge 4095 ] && util::err "invalid vlan number"
# we need to remove everything and re-add as raw interfaces will
# change to vlan or visa-versa
__switch_remove_allmembers "${_switch}"
switch::remove_allmembers "${_switch}"
if [ "${_vlan}" = "0" ]; then
__config_core_remove "vlan_${_switch}"
config::core_remove "vlan_${_switch}"
else
__config_core_set "vlan_${_switch}" "${_vlan}"
config::core_set "vlan_${_switch}" "${_vlan}"
fi
# put interfaces back in
__switch_add_allmembers "${_switch}"
switch::__add_allmembers "${_switch}"
}
# physically add switch member interfaces
@@ -248,21 +248,21 @@ __switch_vlan(){
# @param string _switch the switch to configure
# @param optional string _id switch id (eg bridge0) if already known
#
__switch_add_allmembers(){
switch::__add_allmembers(){
local _switch="$1"
local _id="$2"
local _portlist _port
if [ -z "${_id}" ]; then
__switch_get_ident "_id" "${_switch}"
[ -z "${_id}" ] && __err "failed to get switch id while adding members"
switch::get_ident "_id" "${_switch}"
[ -z "${_id}" ] && util::err "failed to get switch id while adding members"
fi
__config_core_get "_portlist" "ports_${_switch}"
config::core_get "_portlist" "ports_${_switch}"
if [ -n "${_portlist}" ]; then
for _port in ${_portlist}; do
__switch_configure_port "${_switch}" "${_id}" "${_port}"
switch::__configure_port "${_switch}" "${_id}" "${_port}"
done
fi
}
@@ -273,21 +273,21 @@ __switch_add_allmembers(){
# @param string _switch name of the switch
# @param optional string _id switch id if already known
#
__switch_remove_allmembers(){
switch::remove_allmembers(){
local _switch="$1"
local _id="$2"
local _portlist _port
if [ -z "${_id}" ]; then
__switch_get_ident "_id" "${_switch}"
[ -z "${_id}" ] && __err "failed to get switch id while removing members"
switch::get_ident "_id" "${_switch}"
[ -z "${_id}" ] && util::err "failed to get switch id while removing members"
fi
__config_core_get "_portlist" "ports_${_switch}"
config::core_get "_portlist" "ports_${_switch}"
if [ -n "${_portlist}" ]; then
for _port in ${_portlist}; do
__switch_unconfigure_port "${_switch}" "${_id}" "${_port}"
switch::__unconfigure_port "${_switch}" "${_id}" "${_port}"
done
fi
}
@@ -301,20 +301,20 @@ __switch_remove_allmembers(){
# @param string _id the switch id
# @param string _member name of the member interface to add
#
__switch_configure_port(){
switch::__configure_port(){
local _switch="$1"
local _id="$2"
local _member="$3"
local _vlan _vid
__config_core_get "_vlan" "vlan_${_switch}"
config::core_get "_vlan" "vlan_${_switch}"
if [ -n "${_vlan}" ]; then
__switch_get_ident "_vid" "vlan-${_member}-${_vlan}"
switch::get_ident "_vid" "vlan-${_member}-${_vlan}"
if [ -z "${_vid}" ]; then
_vid=$(ifconfig vlan create)
[ $? -ne 0 ] && __err "failed to create vlan interface"
[ $? -ne 0 ] && util::err "failed to create vlan interface"
ifconfig "${_vid}" vlandev "${_member}" vlan "${_vlan}" description "vm-vlan-${_member}-${_vlan}"
fi
@@ -323,7 +323,7 @@ __switch_configure_port(){
ifconfig ${_id} addm ${_member} >/dev/null 2>&1
fi
[ $? -ne 0 ] && __err "failed to add member to the virtual switch"
[ $? -ne 0 ] && util::err "failed to add member to the virtual switch"
}
# 'vm switch add'
@@ -333,19 +333,19 @@ __switch_configure_port(){
# @param string _switch name of the switch
# @param string _member name of the interface to add
#
__switch_add_member(){
switch::add_member(){
local _switch="$1"
local _member="$2"
local _id
[ -z "${_switch}" -o -z "${_member}" ] && __usage
[ -z "${_switch}" -o -z "${_member}" ] && util::usage
__switch_auto "${_switch}"
__switch_get_ident "_id" "${_switch}"
[ -z "${_id}" ] && __err "unable to locate virtual switch ${_id}"
switch::__check_auto "${_switch}"
switch::get_ident "_id" "${_switch}"
[ -z "${_id}" ] && util::err "unable to locate virtual switch ${_id}"
__switch_configure_port "${_switch}" "${_id}" "${_member}"
__config_core_set "ports_${_switch}" "${_member}" "1"
switch::__configure_port "${_switch}" "${_id}" "${_member}"
config::core_set "ports_${_switch}" "${_member}" "1"
}
# physically remove a port from a virtual switch / bridge
@@ -355,24 +355,24 @@ __switch_add_member(){
# @param string _id the switch id
# @param string _member the interface to remove
#
__switch_unconfigure_port(){
switch::__unconfigure_port(){
local _switch="$1"
local _id="$2"
local _member="$3"
local _id _vlan _vid _usage
__config_core_get "_vlan" "vlan_${_switch}"
config::core_get "_vlan" "vlan_${_switch}"
if [ -n "${_vlan}" ]; then
__switch_get_ident "_vid" "vlan-${_member}-${_vlan}"
[ -z "${_vid}" ] && __err "unable to find relevent vlan interface for ${_member}"
switch::get_ident "_vid" "vlan-${_member}-${_vlan}"
[ -z "${_vid}" ] && util::err "unable to find relevent vlan interface for ${_member}"
ifconfig ${_id} deletem ${_vid} >/dev/null 2>&1
else
ifconfig ${_id} deletem ${_member} >/dev/null 2>&1
fi
[ $? -ne 0 ] && __err "failed to remove member from the virtual switch"
[ $? -ne 0 ] && util::err "failed to remove member from the virtual switch"
# it's possible a vlan interface may be assigned to multiple switches
# we want to remove the vlan interface if possible, but not if it's
@@ -390,19 +390,19 @@ __switch_unconfigure_port(){
# @param string _switch the switch to update
# @param string _member the interface to remove
#
__switch_remove_member(){
switch::remove_member(){
local _switch="$1"
local _member="$2"
local _id
[ -z "${_switch}" -o -z "${_member}" ] && __usage
[ -z "${_switch}" -o -z "${_member}" ] && util::usage
__switch_auto "${_switch}"
__switch_get_ident "_id" "${_switch}"
[ -z "${_id}" ] && __err "unable to locate virtual switch ${_id}"
switch::__check_auto "${_switch}"
switch::get_ident "_id" "${_switch}"
[ -z "${_id}" ] && util::err "unable to locate virtual switch ${_id}"
__config_core_remove "ports_${_switch}" "${_member}"
__switch_unconfigure_port "${_switch}" "${_id}" "${_member}"
config::core_remove "ports_${_switch}" "${_member}"
switch::__unconfigure_port "${_switch}" "${_id}" "${_member}"
}
# 'vm switch nat'
@@ -412,24 +412,24 @@ __switch_remove_member(){
# @param string _switch the name of the switch
# @param string _nat=on|off whether to switch it on or off
#
__switch_nat(){
switch::nat(){
local _switch="$1"
local _nat="$2"
[ -z "${_switch}" ] && __usage
__switch_auto "${_switch}"
[ -z "${_switch}" ] && util::usage
switch::__check_auto "${_switch}"
case "${_nat}" in
off)
__config_core_remove "nat_${_switch}"
config::core_remove "nat_${_switch}"
;;
on)
if ! checkyesno pf_enable; then
__err "pf needs to be enabled for nat functionality"
util::err "pf needs to be enabled for nat functionality"
fi
__config_core_set "nat_${_switch}" "yes"
[ $? -ne 0 ] && __err "failed to store nat configuration"
config::core_set "nat_${_switch}" "yes"
[ $? -ne 0 ] && util::err "failed to store nat configuration"
echo "******"
echo " NAT has been enabled on the specified switch"
@@ -438,12 +438,12 @@ __switch_nat(){
echo "******"
;;
*)
__err "last option should either be 'on' or 'off' to enable/disable nat functionality"
util::err "last option should either be 'on' or 'off' to enable/disable nat functionality"
;;
esac
# reset nat configuration
__switch_nat_init
switch::nat_init
}
# set the system up for nat usage
@@ -454,7 +454,7 @@ __switch_nat(){
#
# @private
#
__switch_nat_init(){
switch::nat_init(){
local _pf_rules="${vm_dir}/.config/pf-nat.conf"
local _havenat=0
local _grep _switchlist _nat _net24 _if
@@ -481,12 +481,12 @@ __switch_nat_init(){
_grep=$(grep "${_pf_rules}" /etc/pf.conf)
[ -z "${_grep}" ] && echo "include \"${_pf_rules}\"" >> /etc/pf.conf
__config_core_get "_switchlist" "switch_list"
config::core_get "_switchlist" "switch_list"
# add each nat switch to dnsmasq.conf and .config/pf-nat.conf
for _switch in ${_switchlist}; do
__config_core_get "_nat" "nat_${_switch}"
__switch_get_ident "_id" "${_switch}"
config::core_get "_nat" "nat_${_switch}"
switch::get_ident "_id" "${_switch}"
if [ "${_nat}" = "yes" -a -n "${_id}" ]; then
_bnum=$(echo "${_id}" |awk -F'bridge' '{print $2}')
@@ -510,7 +510,7 @@ __switch_nat_init(){
# restart services regardless
# still need to restart if _havenat=0, in case we've just removed last nat switch
__restart_service "pf"
util::restart_service "pf"
}
# check if a switch is a vale switch
@@ -520,13 +520,13 @@ __switch_nat_init(){
#
# @return int 0 is switch is vale
#
__switch_is_vale(){
switch::is_vale(){
local _switch="$1"
__config_core_get "_is_vale" "vale_${_switch}"
config::core_get "_is_vale" "vale_${_switch}"
[ -z "${_is_vale}" ] && return 1
__checkyesno "${_is_vale}"
util::checkyesno "${_is_vale}"
}
# gets a unique port name for a vale interface
@@ -538,7 +538,7 @@ __switch_is_vale(){
# @param string _switch the name of the switch
# @param string _port unique port identifier (usually mac address)
#
__switch_vale_id(){
switch::vale_id(){
local _var="$1"
local _switch="$2"
local _port="$3"
@@ -563,15 +563,15 @@ __switch_vale_id(){
#
# @param string _switch the name of the switch
#
__switch_auto(){
switch::__check_auto(){
local _switch="$1"
local _bridge _vale
__config_core_get "_bridge" "bridge_${_switch}"
__config_core_get "_vale" "vale_${_switch}"
config::core_get "_bridge" "bridge_${_switch}"
config::core_get "_vale" "vale_${_switch}"
[ -n "${_bridge}" ] && __err "this is a manual switch that is managed outside of vm-bhyve"
[ -n "${_vale}" ] && __err "this command is not currently supported on vale switches"
[ -n "${_bridge}" ] && util::err "this is a manual switch that is managed outside of vm-bhyve"
[ -n "${_vale}" ] && util::err "this command is not currently supported on vale switches"
}
# get the interface name for a switch
@@ -581,7 +581,7 @@ __switch_auto(){
# @param string _var variable to put id into
# @param string _switch the switch to look for
#
__switch_get_ident(){
switch::get_ident(){
local _var="$1"
local _switch="$2"
local _c_id

View File

@@ -26,11 +26,11 @@
# make sure we have the right environment
#
__setup(){
__load_module "vmm"
__load_module "nmdm"
__load_module "if_bridge"
__load_module "if_tap"
util::setup(){
util::load_module "vmm"
util::load_module "nmdm"
util::load_module "if_bridge"
util::load_module "if_tap"
sysctl net.link.tap.up_on_open=1 >/dev/null 2>&1
}
@@ -39,12 +39,12 @@ __setup(){
#
# @param string _mod the module name
#
__load_module(){
util::load_module(){
local _mod="$1"
kldstat -qm ${_mod} >/dev/null 2>&1
if [ $? -ne 0 ]; then
kldload ${_mod} >/dev/null 2>&1
[ $? -ne 0 ] && __err "unable to load ${_mod}.ko!"
[ $? -ne 0 ] && util::err "unable to load ${_mod}.ko!"
fi
}
@@ -54,12 +54,12 @@ __load_module(){
#
# @modifies VM_NO_UG
#
__check_bhyve_support(){
util::check_bhyve_support(){
local _mesg _result
# basic checks
[ `id -u` -ne 0 ] && __err "virtual machines can only be managed by root"
[ ${VERSION_BSD} -lt 1000000 ] && __err "please upgrade to FreeBSD 10 or newer for bhyve support"
[ `id -u` -ne 0 ] && util::err "virtual machines can only be managed by root"
[ ${VERSION_BSD} -lt 1000000 ] && util::err "please upgrade to FreeBSD 10 or newer for bhyve support"
# get features2 line which should include popcnt
_mesg=$(grep -E '^[ ]+Features2' /var/run/dmesg.boot | tail -n 1)
@@ -69,7 +69,7 @@ __check_bhyve_support(){
# look for pop cnt
_result=$(echo "${_mesg}" |grep "POPCNT")
[ -z "${_result}" ] && __err "it doesn't look like your cpu supports bhyve (missing POPCNT)"
[ -z "${_result}" ] && util::err "it doesn't look like your cpu supports bhyve (missing POPCNT)"
fi
# check ept for intel
@@ -79,7 +79,7 @@ __check_bhyve_support(){
# look for ept
_result=$(echo "${_mesg}" |grep "EPT")
[ -z "${_result}" ] && __err "it doesn't look like your cpu supports bhyve (missing EPT)"
[ -z "${_result}" ] && util::err "it doesn't look like your cpu supports bhyve (missing EPT)"
# look for unrestricted guest
_result=$(echo "${_mesg}" |grep ",UG")
@@ -92,7 +92,7 @@ __check_bhyve_support(){
#
# @return success if host has vt-d
#
__check_bhyve_iommu(){
util::check_bhyve_iommu(){
local _mesg
_mesg=$(acpidump -t |grep DMAR)
@@ -106,7 +106,7 @@ __check_bhyve_iommu(){
#
# @param string _serv the name of the service
#
__restart_service(){
util::restart_service(){
local _serv="$1"
local _cmd="restart"
@@ -115,20 +115,20 @@ __restart_service(){
[ $? -ne 0 ] && _cmd="start"
service ${_serv} ${_cmd} >/dev/null 2>&1
[ $? -ne 0 ] && __warn "failed to ${_cmd} service ${_serv}"
[ $? -ne 0 ] && util::warn "failed to ${_cmd} service ${_serv}"
}
# show version
#
__version(){
util::version(){
echo "vm-bhyve: Bhyve virtual machine management v${VERSION} (build ${VERSION_INT})"
}
# show version & usage information
# we exit after running this
#
__usage(){
__version
util::usage(){
util::version
cat << EOT
Usage: vm ...
version
@@ -178,7 +178,7 @@ EOT
#
# @param string - the message to display
#
__err(){
util::err(){
echo "${0}: ERROR: $1" >&2
exit 1
}
@@ -188,7 +188,7 @@ __err(){
#
# @param string - the message to display
#
__warn(){
util::warn(){
echo "${0}: WARNING: $1" >&2
}
@@ -200,7 +200,7 @@ __warn(){
#
# @param string _type whether to rotate guest or main log
#
__log_rotate(){
util::log_rotate(){
local _type="$1"
local _lf="vm-bhyve.log"
local _file _size _guest
@@ -235,7 +235,7 @@ __log_rotate(){
# @param optional string _guest if _type=guest, the guest name, otherwise do not provide at all
# @param string _message the message to log
#
__log(){
util::log(){
local _type="$1"
local _lf="vm-bhyve.log"
local _guest _message _file _date
@@ -266,20 +266,20 @@ __log(){
# @param string _file the file name to write to
# @param string _message the data to write
#
__log_and_write(){
util::log_and_write(){
local _type="$1"
local _guest="$2"
local _file="${VM_DS_PATH}/${_guest}/$3"
local _message="$4"
if [ "${_type}" = "write" ]; then
__log "guest" "${_guest}" "create file ${_file}"
util::log "guest" "${_guest}" "create file ${_file}"
echo "${_message}" > "${_file}"
else
echo "${_message}" >> "${_file}"
fi
__log "guest" "${_guest}" " -> ${_message}"
util::log "guest" "${_guest}" " -> ${_message}"
}
# confirm yes or no
@@ -287,7 +287,7 @@ __log_and_write(){
# @param string _msh message to display
# @return int success if confirmed
#
__confirm(){
util::confirm(){
local _msg="$1"
local _resp
@@ -306,7 +306,7 @@ __confirm(){
# @param _value the value to test
# @return int 1 if set to "off/false/no/0", 0 otherwise
#
__checkyesno(){
util::checkyesno(){
local _value="$1"
[ -z "${_value}" ] && return 1

View File

@@ -41,7 +41,7 @@
#
# @modifies VM_ZFS VM_ZFS_DATASET vm_dir
#
__zfs_init(){
zfs::init(){
local _zfs
# check for zfs storage location
@@ -50,7 +50,7 @@ __zfs_init(){
# check zfs running
kldstat -qm zfs >/dev/null 2>&1
[ $? -ne 0 ] && __err "ZFS support requested but ZFS not available"
[ $? -ne 0 ] && util::err "ZFS support requested but ZFS not available"
# global zfs details
VM_ZFS="1"
@@ -59,7 +59,7 @@ __zfs_init(){
# update vm_dir
# this makes sure it exists, confirms it's mounted & gets correct path in one go
vm_dir=$(mount | grep "^${VM_ZFS_DATASET} " |cut -d' ' -f3)
[ -z "${vm_dir}" ] && __err "unable to locate mountpoint for ZFS dataset ${VM_ZFS_DATASET}"
[ -z "${vm_dir}" ] && util::err "unable to locate mountpoint for ZFS dataset ${VM_ZFS_DATASET}"
fi
}
@@ -68,14 +68,14 @@ __zfs_init(){
#
# @param string _name name of the dataset to create
#
__zfs_make_dataset(){
zfs::make_dataset(){
local _name="$1"
local _opts="$2"
if [ -n "${_name}" -a "${VM_DS_ZFS}" = "1" ]; then
__zfs_format_options "_opts" "${_opts}"
zfs::__format_options "_opts" "${_opts}"
zfs create ${_opts} "${_name}"
[ $? -ne 0 ] && __err "failed to create new ZFS dataset ${_name}"
[ $? -ne 0 ] && util::err "failed to create new ZFS dataset ${_name}"
fi
}
@@ -83,12 +83,12 @@ __zfs_make_dataset(){
#
# @param string _name name of the dataset to destroy
#
__zfs_destroy_dataset(){
zfs::destroy_dataset(){
local _name="$1"
if [ -n "${_name}" -a "${VM_DS_ZFS}" = "1" ]; then
zfs destroy -rf "${_name}" >/dev/null 2>&1
[ $? -ne 0 ] && __err "failed to destroy ZFS dataset ${_name}"
[ $? -ne 0 ] && util::err "failed to destroy ZFS dataset ${_name}"
fi
}
@@ -99,13 +99,13 @@ __zfs_destroy_dataset(){
# @param string _old the name of the dataset to rename
# @param string _new the new name
#
__zfs_rename_dataset(){
zfs::rename_dataset(){
local _old="$1"
local _new="$2"
if [ -n "${_old}" -a -n "${_new}" -a "${VM_DS_ZFS}" = "1" ]; then
zfs rename "${VM_DS_ZFS_DATASET}/${_old}" "${VM_DS_ZFS_DATASET}/${_new}" >/dev/null 2>&1
[ $? -ne 0 ] && __err "failed to rename ZFS dataset ${VM_DS_ZFS_DATASET}/${_old}"
[ $? -ne 0 ] && util::err "failed to rename ZFS dataset ${VM_DS_ZFS_DATASET}/${_old}"
fi
}
@@ -115,19 +115,19 @@ __zfs_rename_dataset(){
# @param string _size how big to create the dataset
# @param int _sparse=0 set to 1 for a sparse zvol
#
__zfs_make_zvol(){
zfs::make_zvol(){
local _name="$1"
local _size="$2"
local _sparse="$3"
local _user_opts="$4"
local _opt="-V"
[ ! "${VM_DS_ZFS}" = "1" ] && __err "cannot use ZVOL storage unless ZFS support is enabled"
[ ! "${VM_DS_ZFS}" = "1" ] && util::err "cannot use ZVOL storage unless ZFS support is enabled"
[ "${_sparse}" = "1" ] && _opt="-sV"
__zfs_format_options "_user_opts" "${_user_opts}"
zfs::__format_options "_user_opts" "${_user_opts}"
zfs create ${_opt} ${_size} -o volmode=dev ${_user_opts} "${_name}"
[ $? -ne 0 ] && __err "failed to create new ZVOL ${_name}"
[ $? -ne 0 ] && util::err "failed to create new ZVOL ${_name}"
}
# format options for zfs commands
@@ -136,7 +136,7 @@ __zfs_make_zvol(){
#
# @modifies $_val
#
__zfs_format_options(){
zfs::__format_options(){
local _val="$1"
local _c_opts="$2"
@@ -158,13 +158,13 @@ __zfs_format_options(){
# @param flag (-f) force snapshot if guest is running
# @param string _name the name of the guest to snapshot
#
__zfs_snapshot(){
zfs::snapshot(){
local _name _snap _opt _force _snap_exists
while getopts f _opt; do
case $_opt in
f) _force=1 ;;
*) __usage ;;
*) util::usage ;;
esac
done
@@ -180,17 +180,17 @@ __zfs_snapshot(){
_name=${_name%%@*}
fi
[ -z "${_name}" ] && __usage
__datastore_get_guest "${_name}" || __err "${_name} does not appear to be an existing virtual machine"
[ ! "${VM_DS_ZFS}" = "1" ] && __err "cannot snapshot guests on non-zfs datastores"
[ -z "${_name}" ] && util::usage
datastore::get_guest "${_name}" || util::err "${_name} does not appear to be an existing virtual machine"
[ ! "${VM_DS_ZFS}" = "1" ] && util::err "cannot snapshot guests on non-zfs datastores"
[ -z "${_snap}" ] && _snap=$(date +"%Y-%m-%d-%H:%M:%S")
if ! __vm_confirm_stopped "${_name}" >/dev/null; then
[ -z "${_force}" ] && __err "${_name} must be powered off first (use -f to override)"
if ! vm::confirm_stopped "${_name}" >/dev/null; then
[ -z "${_force}" ] && util::err "${_name} must be powered off first (use -f to override)"
fi
zfs snapshot -r ${VM_DS_ZFS_DATASET}/${_name}@${_snap}
[ $? -ne 0 ] && __err "failed to create recursive snapshot of virtual machine"
[ $? -ne 0 ] && util::err "failed to create recursive snapshot of virtual machine"
}
# 'vm rollback'
@@ -203,30 +203,30 @@ __zfs_snapshot(){
# @param flag (-r) force deletion of more recent snapshots
# @param string _name name of the guest
#
__zfs_rollback(){
zfs::rollback(){
local _name _snap _opt _force _fs _snap_exists
while getopts r _opt; do
case $_opt in
r) _force="-r" ;;
*) __usage ;;
*) util::usage ;;
esac
done
shift $((OPTIND - 1))
_snap_exists=$(echo "${1}" | grep "@")
[ -z "${_snap_exists}" ] && __err "a snapshot name must be provided in guest@snapshot format"
[ -z "${_snap_exists}" ] && util::err "a snapshot name must be provided in guest@snapshot format"
_name="${1%%@*}"
_snap="${1##*@}"
[ -z "${_name}" -o -z "${_snap}" ] && __usage
[ -z "${_name}" -o -z "${_snap}" ] && util::usage
__datastore_get_guest "${_name}" || __err "${_name} does not appear to be an existing virtual machine"
[ ! "${VM_DS_ZFS}" = "1" ] && __err "cannot rollback guests on non-zfs datastores"
datastore::get_guest "${_name}" || util::err "${_name} does not appear to be an existing virtual machine"
[ ! "${VM_DS_ZFS}" = "1" ] && util::err "cannot rollback guests on non-zfs datastores"
__vm_confirm_stopped "${_name}" || exit 1
vm::confirm_stopped "${_name}" || exit 1
# list all datasets and zvols under guest
zfs list -o name -rHt filesystem,volume ${VM_DS_ZFS_DATASET}/${_name} | \
@@ -243,7 +243,7 @@ __zfs_rollback(){
# @param string _old the guest to clone
# @param string _new name of the new guest
#
__zfs_clone(){
zfs::clone(){
local _old="$1"
local _name="$2"
local _fs _newfs _snap _snap_exists _fs_list _entry
@@ -251,8 +251,8 @@ __zfs_clone(){
local _uuid=$(uuidgen)
# check args and make sure new guest doesn't already exist
[ -z "${_old}" -o -z "${_name}" ] && __usage
__datastore_get_guest "${_name}" && __err "new guest already exists in ${VM_DS_PATH}/${_name}"
[ -z "${_old}" -o -z "${_name}" ] && util::usage
datastore::get_guest "${_name}" && util::err "new guest already exists in ${VM_DS_PATH}/${_name}"
# try to get snapshot name
# we support normal zfs syntax for this
@@ -264,24 +264,24 @@ __zfs_clone(){
fi
# make sure old guest exists
__datastore_get_guest "${_old}" || __err "${_old} does not appear to be an existing virtual machine"
[ ! "${VM_DS_ZFS}" = "1" ] && __err "cannot clone guests on non-zfs datastores"
datastore::get_guest "${_old}" || util::err "${_old} does not appear to be an existing virtual machine"
[ ! "${VM_DS_ZFS}" = "1" ] && util::err "cannot clone guests on non-zfs datastores"
# get list of datasets to copy
_fs_list=$(zfs list -rHo name -t filesystem,volume "${VM_DS_ZFS_DATASET}/${_old}")
[ $? -ne 0 ] && __err "unable to list datasets for ${VM_DS_ZFS_DATASET}/${_old}"
[ $? -ne 0 ] && util::err "unable to list datasets for ${VM_DS_ZFS_DATASET}/${_old}"
# generate a short uuid and create snapshot if no custom snap given
if [ -z "${_snap}" ]; then
__vm_confirm_stopped "${_old}" || exit 1
vm::confirm_stopped "${_old}" || exit 1
_snap=$(echo "${_uuid}" |awk -F- '{print $1}')
zfs snapshot -r "${VM_DS_ZFS_DATASET}/${_old}@${_snap}"
[ $? -ne 0 ] && __err "failed to create snapshot ${VM_DS_ZFS_DATASET}/${_old}@${_snap}"
[ $? -ne 0 ] && util::err "failed to create snapshot ${VM_DS_ZFS_DATASET}/${_old}@${_snap}"
else
for _fs in ${_fs_list}; do
zfs get creation "${_fs}@${_snap}" >/dev/null 2>&1
[ $? -ne 0 ] && __err "snapshot ${_fs}@${_snap} doesn't seem to exist"
[ $? -ne 0 ] && util::err "snapshot ${_fs}@${_snap} doesn't seem to exist"
done
fi
@@ -290,7 +290,7 @@ __zfs_clone(){
_newfs=$(echo "${_fs}" | sed "s@${VM_DS_ZFS_DATASET}/${_old}@${VM_DS_ZFS_DATASET}/${_name}@")
zfs clone "${_fs}@${_snap}" "${_newfs}"
[ $? -ne 0 ] && __err "error while cloning dataset ${_fs}@${_snap}"
[ $? -ne 0 ] && util::err "error while cloning dataset ${_fs}@${_snap}"
done
# update new guest files
@@ -304,15 +304,15 @@ __zfs_clone(){
fi
# update mac addresses and uuid
__config_load "${VM_DS_PATH}/${_name}/${_name}.conf"
__vm_config_set "${_name}" "uuid" "${_uuid}"
config::load "${VM_DS_PATH}/${_name}/${_name}.conf"
core::guest_config_set "${_name}" "uuid" "${_uuid}"
# find all network interfaces and change mac
while [ 1 ]; do
__config_get "_entry" "network${_num}_type"
config::get "_entry" "network${_num}_type"
[ -z "${_entry}" ] && break
__vm_generate_static_mac
vm::generate_static_mac
_num=$((_num + 1))
done
}
@@ -325,7 +325,7 @@ __zfs_clone(){
# @param optional string (-d) description of the image
# @param string _name name of guest to take image of
#
__zfs_image_create(){
zfs::image_create(){
local _name _opt _desc
local _uuid _snap _date _no_compress _filename
@@ -333,7 +333,7 @@ __zfs_image_create(){
case $_opt in
d) _desc=${OPTARG} ;;
u) _no_compress="1" ;;
*) __usage ;;
*) util::usage ;;
esac
done
@@ -345,18 +345,18 @@ __zfs_image_create(){
[ -z "${_desc}" ] && _desc="No description provided"
__datastore_get_guest "${_name}" || __err "${_name} does not appear to be a valid virtual machine"
[ -z "${VM_ZFS}" -o -z "${VM_DS_ZFS}" ] && __err "this command is only supported on zfs datastores"
datastore::get_guest "${_name}" || util::err "${_name} does not appear to be a valid virtual machine"
[ -z "${VM_ZFS}" -o -z "${VM_DS_ZFS}" ] && util::err "this command is only supported on zfs datastores"
# create the image dataset if we don't have it
if [ ! -e "${vm_dir}/images" ]; then
zfs create "${VM_ZFS_DATASET}/images" >/dev/null 2>&1
[ $? -ne 0 ] && __err "failed to create image store ${VM_ZFS_DATASET}/images"
[ $? -ne 0 ] && util::err "failed to create image store ${VM_ZFS_DATASET}/images"
fi
# try to snapshot
zfs snapshot -r "${VM_DS_ZFS_DATASET}/${_name}@${_snap}" >/dev/null 2>&1
[ $? -ne 0 ] && __err "failed to create snapshot of source dataset ${VM_DS_ZFS_DATASET}/${_name}@${_snap}"
[ $? -ne 0 ] && util::err "failed to create snapshot of source dataset ${VM_DS_ZFS_DATASET}/${_name}@${_snap}"
# copy source
if [ -n "${_no_compress}" ]; then
@@ -391,14 +391,14 @@ __zfs_image_create(){
# @param string _uuid the uuid of the image to use
# @param string _name name of the new guest
#
__zfs_image_provision(){
zfs::image_provision(){
local _uuid _name _file _oldname _entry _num=0 _type
local _datastore="default"
while getopts d: _opt ; do
case $_opt in
d) _datastore="${OPTARG}" ;;
*) __usage ;;
*) util::usage ;;
esac
done
@@ -406,20 +406,20 @@ __zfs_image_provision(){
_uuid="$1"
_name="$2"
[ -z "${_uuid}" -o -z "${_name}" ] && __usage
[ ! -e "${vm_dir}/images/${_uuid}.manifest" ] && __err "unable to locate image with uuid ${_uuid}"
__datastore_get_guest "${_name}" && __err "new guest already exists in ${VM_DS_PATH}/${_name}"
[ -z "${_uuid}" -o -z "${_name}" ] && util::usage
[ ! -e "${vm_dir}/images/${_uuid}.manifest" ] && util::err "unable to locate image with uuid ${_uuid}"
datastore::get_guest "${_name}" && util::err "new guest already exists in ${VM_DS_PATH}/${_name}"
# get the data filename
_file=$(sysrc -inqf "${vm_dir}/images/${_uuid}.manifest" filename)
_type=${_file##*.}
_oldname=$(sysrc -inqf "${vm_dir}/images/${_uuid}.manifest" name)
[ -z "${_file}" -o -z "${_oldname}" ] && __err "unable to locate required details from the specified image manifest"
[ ! -e "${vm_dir}/images/${_file}" ] && __err "image data file does not exist: ${vm_dir}/images/${_file}"
[ -z "${_file}" -o -z "${_oldname}" ] && util::err "unable to locate required details from the specified image manifest"
[ ! -e "${vm_dir}/images/${_file}" ] && util::err "image data file does not exist: ${vm_dir}/images/${_file}"
# get the datastore to create on
__datastore_get "${_datastore}" || __err "unable to locate datastore '${_datastore}'"
datastore::get "${_datastore}" || util::err "unable to locate datastore '${_datastore}'"
# try to recieve
echo "Unpacking guest image, this may take some time..."
@@ -428,31 +428,31 @@ __zfs_image_provision(){
case ${_type} in
zfs) cat "${vm_dir}/images/${_file}" | zfs recv "${VM_DS_ZFS_DATASET}/${_name}" ;;
xz) cat "${vm_dir}/images/${_file}" | xz -d | zfs recv "${VM_DS_ZFS_DATASET}/${_name}" ;;
*) __err "unsupported guest image type - '${_type}'" ;;
*) util::err "unsupported guest image type - '${_type}'" ;;
esac
# error unpacking?
[ $? -ne 0 ] && __err "errors occured while trying to unpackage the image file"
[ $? -ne 0 ] && util::err "errors occured while trying to unpackage the image file"
# remove the original snapshot
zfs destroy -r "${VM_DS_ZFS_DATASET}/${_name}@${_uuid%%-*}" >/dev/null 2>&1
# rename the guest configuration file
mv "${VM_DS_PATH}/${_name}/${_oldname}.conf" "${VM_DS_PATH}/${_name}/${_name}.conf" >/dev/null 2>&1
[ $? -ne 0 ] && __err "unpackaged image but unable to update guest configuration file"
[ $? -ne 0 ] && util::err "unpackaged image but unable to update guest configuration file"
# update mac addresses and create a new uuid
_uuid=$(uuidgen)
__config_load "${VM_DS_PATH}/${_name}/${_name}.conf"
__vm_config_set "${_name}" "uuid" "${_uuid}"
config::load "${VM_DS_PATH}/${_name}/${_name}.conf"
core::guest_config_set "${_name}" "uuid" "${_uuid}"
# find all network interfaces and change mac
while [ 1 ]; do
__config_get "_entry" "network${_num}_type"
config::get "_entry" "network${_num}_type"
[ -z "${_entry}" ] && break
__vm_generate_static_mac
vm::generate_static_mac
_num=$((_num + 1))
done
@@ -464,7 +464,7 @@ __zfs_image_provision(){
# 'vm image list'
# list available images
#
__zfs_image_list(){
zfs::image_list(){
local _file _uuid _ext
local _format="%-38s %-16s %-30s %s\n"
@@ -490,16 +490,16 @@ __zfs_image_list(){
#
# @param string _uuid the uuid of the image
#
__zfs_image_destroy(){
zfs::image_destroy(){
local _uuid="$1"
local _file
[ -z "${_uuid}" ] && __usage
[ ! -e "${vm_dir}/images/${_uuid}.manifest" ] && __err "unable to locate image with uuid ${_uuid}"
[ -z "${_uuid}" ] && util::usage
[ ! -e "${vm_dir}/images/${_uuid}.manifest" ] && util::err "unable to locate image with uuid ${_uuid}"
# get the image filename
_file=$(sysrc -inqf "${vm_dir}/images/${_uuid}.manifest" filename)
[ -z "${_file}" ] && __err "unable to locate filename for the specified image"
[ -z "${_file}" ] && util::err "unable to locate filename for the specified image"
unlink "${vm_dir}/images/${_uuid}.manifest"
unlink "${vm_dir}/images/${_file}"

22
vm
View File

@@ -25,7 +25,7 @@
# POSSIBILITY OF SUCH DAMAGE.
VERSION=1.1-alpha
VERSION_INT=101045
VERSION_INT=101046
VERSION_BSD=$(uname -K)
PATH=${PATH}:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
@@ -44,7 +44,6 @@ fi
# load libs
. "${LIB}/vm-cmd"
. "${LIB}/vm-common"
. "${LIB}/vm-config"
. "${LIB}/vm-core"
. "${LIB}/vm-datastore"
@@ -53,32 +52,33 @@ fi
. "${LIB}/vm-rctl"
. "${LIB}/vm-run"
. "${LIB}/vm-switch"
. "${LIB}/vm-util"
. "${LIB}/vm-zfs"
# check informational commands
__parse_info_cmd $@
cmd::parse_info $@
# we should be enabled in rc.conf
# or call it using forcestart
[ -z "$rc_force" ] && ! checkyesno vm_enable && __err "\$vm_enable is not enabled in /etc/rc.conf!"
[ -z "$rc_force" ] && ! checkyesno vm_enable && util::err "\$vm_enable is not enabled in /etc/rc.conf!"
# check we can run bhyve
__check_bhyve_support
util::check_bhyve_support
# init for zfs
__zfs_init
zfs::init
# create directories as needed
[ ! -d "${vm_dir}" ] && __err "\$vm_dir has not been configured or is not a valid directory"
[ ! -d "${vm_dir}" ] && util::err "\$vm_dir has not been configured or is not a valid directory"
[ ! -d "${vm_dir}/.config" ] && mkdir "${vm_dir}/.config"
[ ! -e "${vm_dir}/.config/null.iso" ] && touch "${vm_dir}/.config/null.iso"
[ ! -d "${vm_dir}/.templates" ] && mkdir "${vm_dir}/.templates"
[ ! -d "${vm_dir}/.iso" ] && mkdir "${vm_dir}/.iso"
# load core configuration
__config_core_load
__datastore_load
config::core_load
datastore::load
# run the requested command
__parse_cmd_args $@
__parse_cmd ${VM_COMMAND}
cmd::parse_args $@
cmd::parse ${VM_COMMAND}