mirror of
https://github.com/churchers/vm-bhyve.git
synced 2026-01-04 03:54:31 +01:00
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:
110
lib/vm-cmd
110
lib/vm-cmd
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
250
lib/vm-core
250
lib/vm-core
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
48
lib/vm-guest
48
lib/vm-guest
@@ -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
|
||||
}
|
||||
|
||||
120
lib/vm-info
120
lib/vm-info
@@ -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
|
||||
|
||||
|
||||
26
lib/vm-rctl
26
lib/vm-rctl
@@ -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
|
||||
}
|
||||
|
||||
248
lib/vm-run
248
lib/vm-run
@@ -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
|
||||
|
||||
232
lib/vm-switch
232
lib/vm-switch
@@ -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
|
||||
|
||||
@@ -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
|
||||
140
lib/vm-zfs
140
lib/vm-zfs
@@ -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
22
vm
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user