10 Commits

Author SHA1 Message Date
Matt Churchyard
826b2fa2bf Wrong commands listed in cms::parse_image 2018-07-30 10:54:22 +01:00
Matt Churchyard
73e50e3bc9 Remove beta label 2018-07-04 09:45:57 +01:00
Matt Churchyard
85730621e7 Import switch name/descr change from master before 1.2 rel
Useful feature as, if switch names are <= 12 characters, users can reference
the interface by the fixed switch name rather than the dynamically assigned "bridgeX"
2018-07-04 09:16:07 +01:00
Matt Churchyard
851e2eb459 Tidy up some switch code and set as 1.2-beta2 2018-06-29 08:21:03 +00:00
Matt Churchyard
b87d2073b9 Change switch handling again
Hopefully this should be the last time. Now assign a unique id to every
switch using groups, then use this to identify interfaces without needing
any ifconfig parsing antics. id is a fixed length so doesn't matter about switch name
2018-06-28 08:52:55 +00:00
Matt Churchyard
4dd6012289 Trial a 12 character switch name limit
If it causes too much backlash we'll need to revert to using descriptions to
track network interfaces
2018-06-27 08:46:21 +00:00
Matt Churchyard
93ecbe1481 Fix bridge interface listing 2018-06-26 10:17:03 +00:00
Matt Churchyard
ec971814fc Merge remote-tracking branch 'origin/master' into 1.2-stable
Merge 'destroy guest@snap' and issue #225 fix into 1.2-stable
2018-06-25 13:25:13 +00:00
Matt Churchyard
307999751b Remove nat setting from info as it's meaningless 2018-06-25 08:36:31 +00:00
Matt Churchyard
c6a44b8476 Merge remote-tracking branch 'origin/master' into 1.2-stable
* origin/master:
  Disable debug mode!
  Fix vlan device naming and check all calls to switch::standard::id return id is always set so we need to check return status

Import vlan and standard::id fixes from master
2018-06-25 08:22:49 +00:00
14 changed files with 131 additions and 64 deletions

View File

@@ -165,7 +165,7 @@ cmd::parse_image(){
[ -z "${VM_ZFS}" ] && util::err "\$vm_dir must be a ZFS datastore to use these functions"
# try to find a matching command
cmd::find "_cmd" "$1" "create,list,destroy,add,remove,vlan,nat,address,private,info"
cmd::find "_cmd" "$1" "list,create,provision,destroy"
[ $? -ne 0 ] && util::usage
# remove parsed command

View File

@@ -92,15 +92,6 @@ core::list(){
} | column -ts^
}
# 'vm check name'
# check name of virtual machine
#
# @return int 0 if name is valid
#
core::check_name(){
echo "$1" | egrep -iqs '^[a-z0-9][.a-z0-9-]{0,30}[a-z0-9]$'
}
# 'vm create'
# create a new virtual machine
#
@@ -127,7 +118,7 @@ core::create(){
[ -z "${_name}" ] && util::usage
# check guest name
core::check_name "${_name}" || util::err "invalid virtual machine name - '${_name}'"
util::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}'"
@@ -586,7 +577,7 @@ core::rename(){
local _new="$2"
[ -z "${_old}" -o -z "${_new}" ] && util::usage
core::check_name "${_new}" || util::err "invalid virtual machine name - '${_name}'"
util::check_name "${_new}" || util::err "invalid virtual machine name - '${_name}'"
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"

View File

@@ -88,7 +88,7 @@ datastore::add(){
local _mount _num=0 _curr
[ -z "${_name}" -o -z "${_spec}" ] && util::usage
core::check_name "${_name}" || util::err "invalid datastore name - '${_name}'"
util::check_name "${_name}" || util::err "invalid datastore name - '${_name}'"
# check name not in use
for _curr in ${VM_DATASTORE_LIST}; do
@@ -277,7 +277,7 @@ datastore::iso(){
local _path="$2"
[ -z "${_name}" -o -z "${_path}" ] && util::usage
core::check_name "${_name}" || util::err "invalid datastore name - '${_name}'"
util::check_name "${_name}" || util::err "invalid datastore name - '${_name}'"
# check name not in use
for _curr in ${VM_DATASTORE_LIST}; do

View File

@@ -31,7 +31,7 @@
#
info::guest(){
local _name="$1"
local _bridge_list=$(ifconfig | grep ^bridge | cut -d: -f1)
local _bridge_list=$(ifconfig -g vm-switch)
local _ds
vm::running_load

View File

@@ -49,7 +49,7 @@ migration::recv(){
_name="$1"
[ -z "${_name}" ] && util::usage
core::check_name "${_name}" || util::err "invalid virtual machine name - '${_name}'"
util::check_name "${_name}" || util::err "invalid virtual machine name - '${_name}'"
datastore::get "${_ds}" || util::err "unable to load datastore - '${_ds}'"
[ -z "${VM_DS_ZFS}" ] && util::err "${_ds} datastore must be on ZFS to support migration"
[ -n "${_stage}" -a -n "${_triple}" ] && util::err "single stage and triple stage are mutually exclusive"

View File

@@ -535,7 +535,7 @@ vm::bhyve_device_networking(){
if [ -n "${_tap}" ]; then
util::log "guest" "${_name}" "initialising network device ${_tap}"
ifconfig "${_tap}" description "vmnet-${_name}-${_num}-${_switch:-custom}" >/dev/null 2>&1
ifconfig "${_tap}" descr "vmnet-${_name}-${_num}-${_switch:-custom}" group vm-port >/dev/null 2>&1
if [ -n "${_switch}" ]; then
switch::id "_sid" "${_switch}"

View File

@@ -66,7 +66,7 @@ switch::list(){
config::core::get "_switchlist" "switch_list"
{
printf "${_format}" "NAME" "TYPE" "IDENT" "ADDRESS" "PRIVATE" "MTU" "VLAN" "PORTS"
printf "${_format}" "NAME" "TYPE" "IFACE" "ADDRESS" "PRIVATE" "MTU" "VLAN" "PORTS"
if [ -n "${_switchlist}" ]; then
for _switch in ${_switchlist}; do
@@ -111,7 +111,7 @@ switch::create(){
_switch="$1"
# check for a valid switch name
core::check_name "${_switch}" || util::err "invalid switch name - '${_switch}'"
util::check_name "${_switch}" || util::err "invalid switch name - '${_switch}'"
# make sure it's not an existing name
config::core::get "_list" "switch_list"
@@ -422,3 +422,44 @@ switch::__migrate(){
# reload configuration
[ -n "${_update}" ] && config::core::load
}
# get a virt interface id for a port/switch
#
# @param string _var variable name to put result into
# @param string _switch switch name to get id for
#
switch::__viid(){
local _hash=$(md5 -qs "${2}" | cut -c1-5)
setvar "$1" "viid-${_hash}@"
}
# retrieve interface name based on a switch viid
#
# @param string _var variable to put interface name into
# @param string _switch the switch name
#
switch::find(){
local _var="$1"
local _switch="$2"
local _viid _name
switch::__viid "_viid" "${_switch}"
_name=$(ifconfig -g "${_viid}" 2>/dev/null)
[ -n "${_name}" ] && setvar "${_var}" "${_name}"
}
# mark an interface with a unique viid
# i say unique, its 5 chars from an md5 hash which
# should be enough for half a dozen switches
#
# @parem string _switch switch name
# @param string _iface interface to mark
#
switch::set_viid(){
local _switch="$1"
local _iface="$2"
local _viid
switch::__viid "_viid" "${_switch}"
ifconfig "${_iface}" group "${_viid}" >/dev/null 2>&1
}

View File

@@ -31,15 +31,17 @@
#
switch::manual::init(){
local _name="$1"
local _id _bridge
local _bridge="$2"
# get bridge
config::core::get "_bridge" "bridge_${_name}"
[ -z "${_bridge}" ] && return 1
if [ -z "${_bridge}" ]; then
config::core::get "_bridge" "bridge_${_name}"
[ -z "${_bridge}" ] && return 1
fi
# don't rename custom bridges. user can set this in rc.conf
# or just stick with bridgeX
ifconfig "${_bridge}" description "vm-${_name}" up >/dev/null 2>&1
# don't rename custom bridges. user can set this in rc.conf or just stick with bridgeX
ifconfig "${_bridge}" descr "vm-${_name}" group vm-switch up >/dev/null 2>&1
switch::set_viid "${_name}" "${_bridge}"
}
# show the configuration details for a manual switch
@@ -77,7 +79,7 @@ switch::manual::create(){
[ -n "${_priv}" ] && config::core::set "private_${_switch}" "${_priv}"
# import
ifconfig "${_bridge}" description "vm-${_switch}" up
switch::manual::init "${_switch}" "${_bridge}"
}
# remove a manual switch
@@ -92,7 +94,8 @@ switch::manual::remove(){
[ -z "${_id}" ] && return 0
# try to remove our description
ifconfig ${_id} description "" >/dev/null 2>&1
# viid stays but it's not worth the extra hassle to remove that
ifconfig ${_id} -descr -group vm-switch >/dev/null 2>&1
}
# add a new interface to this switch

View File

@@ -30,15 +30,28 @@
#
switch::standard::init(){
local _name="$1"
local _id _addr _mtu
local _id _addr _mtu _len _ifconf
# see if it already exists
switch::standard::id "_id" "${_name}" && return 0
switch::find "_id" "${_name}" && return 0
# get the length of the switch name
# it's useful for other utilities to use switch name as interface name
# as it's static. can't do that if it's > 12 chars
_len=$(echo -n "${_name}" | wc -m)
if [ ${_len} -le 12 ]; then
_ifconf="name vm-${_name}"
else
_ifconf="descr vm-${_name}"
fi
# create a bridge for this switch
ifconfig bridge create name "${_id}" up >/dev/null 2>&1
_id=$(ifconfig bridge create ${_ifconf} group vm-switch up 2>/dev/null)
[ $? -eq 0 ] || util::err "failed to create bridge interface for switch ${_name}"
switch::set_viid "${_name}" "${_id}"
# randomise mac if feature is available
[ ${VERSION_BSD} -ge 1102000 ] && ifconfig "${_id}" link random
@@ -64,13 +77,14 @@ switch::standard::show(){
local _format="$2"
local _id _vlan _ports _addr _mtu _priv
switch::find "_id" "${_name}"
config::core::get "_ports" "ports_${_name}"
config::core::get "_vlan" "vlan_${_name}"
config::core::get "_addr" "addr_${_name}"
config::core::get "_mtu" "mtu_${_name}"
config::core::get "_priv" "private_${_name}" "no"
printf "${_format}" "${_name}" "standard" "-" "${_addr:--}" "${_priv}" "${_mtu:--}" \
printf "${_format}" "${_name}" "standard" "${_id:--}" "${_addr:--}" "${_priv}" "${_mtu:--}" \
"${_vlan:--}" "${_ports:--}"
}
@@ -101,8 +115,7 @@ switch::standard::remove(){
local _id
# get the bridge id
switch::standard::id "_id" "${_switch}"
[ $? -eq 0 ] || return 1
switch::find "_id" "${_switch}" || return 1
# remove all member interfaces
switch::standard::__remove_members "${_switch}" "${_id}"
@@ -121,7 +134,7 @@ switch::standard::add_member(){
local _if="$2"
local _id _vlan _mtu
switch::standard::id "_id" "${_switch}" || util::err "unable to locate switch id"
switch::find "_id" "${_switch}" || util::err "unable to locate switch id"
config::core::get "_vlan" "vlan_${_switch}"
config::core::get "_mtu" "mtu_${_switch}"
switch::standard::__configure_port "${_switch}" "${_id}" "${_if}" "${_vlan}" "${_mtu}"
@@ -138,10 +151,10 @@ switch::standard::remove_member(){
local _if="$2"
local _id _vlan
switch::standard::id "_id" "${_switch}" || util::err "unable to locate switch id"
switch::find "_id" "${_switch}" || util::err "unable to locate switch id"
config::core::remove "ports_${_switch}" "${_if}"
config::core::get "_vlan" "vlan_${_switch}"
switch::standard::__unconfigure_port "${_switch}" "${_id}" "${_if}"
switch::standard::__unconfigure_port "${_switch}" "${_id}" "${_if}" "${_vlan}"
}
# set vlan id
@@ -154,7 +167,7 @@ switch::standard::vlan(){
local _vlan="$2"
local _id
switch::standard::id "_id" "${_switch}" || util::err "unable to locate switch id"
switch::find "_id" "${_switch}" || util::err "unable to locate switch id"
switch::standard::__remove_members "${_switch}" "${_id}"
# update configuration
@@ -205,7 +218,7 @@ switch::standard::__add_members(){
# get the id if not provided
if [ -z "${_id}" ]; then
switch::standard::id "_id" "${_switch}" || util:err "failed to get switch id while adding members"
switch::find "_id" "${_switch}" || util:err "failed to get switch id while adding members"
fi
config::core::get "_ports" "ports_${_switch}"
@@ -231,8 +244,7 @@ switch::standard::__remove_members(){
# get id if not given to us
if [ -z "${_id}" ]; then
switch::standard::id "_id" "${_switch}"
[ $? -eq 0 ] || util::err "failed to get switch id while removing members"
switch::find "_id" "${_switch}" || util::err "failed to get switch id while removing members"
fi
# get full port list
@@ -260,23 +272,29 @@ switch::standard::__configure_port(){
local _port="$3"
local _vlan="$4"
local _mtu="$5"
local _vid
local _viface _vname
# try to set mtu of port?
[ -n "${_mtu}" ] && ifconfig "${_port}" mtu ${_mtu} >/dev/null 2>&1
# vlan enabled?
if [ -n "${_vlan}" ]; then
# see if vlan interface already exists
switch::standard::id "_vid" "${_port}.${_vlan}"
_vname="${_port}.${_vlan}"
switch::find "_viface" "${_vname}"
# create if needed
if [ $? -ne 0 ]; then
_vid=$(ifconfig vlan create vlandev "${_port}" vlan "${_vlan}" name "vm-${_port}.${_vlan}" up)
# use our id as the interface name here.
# it should always be a valid name and interface.vlan-id is much easier to understand in ifconfig
# than a bunch of vlanX interfaces
_viface=$(ifconfig vlan create vlandev "${_port}" vlan "${_vlan}" descr "vm-vlan-${_switch}-${_vname}" name "${_vname}" group vm-vlan up 2>/dev/null)
[ $? -eq 0 ] || util::err "failed to create vlan interface for port ${_port} on switch ${_switch}"
fi
ifconfig ${_id} addm ${_vid} >/dev/null 2>&1
switch::set_viid "${_vname}" "${_viface}"
ifconfig ${_id} addm ${_viface} >/dev/null 2>&1
else
# add to bridge, nice and simple :)
ifconfig ${_id} addm ${_port} >/dev/null 2>&1
@@ -301,7 +319,7 @@ switch::standard::__unconfigure_port(){
if [ -n "${_vlan}" ]; then
# get vlan interface
switch::standard::id "_vid" "${_port}.${_vlan}"
switch::find "_vid" "${_port}.${_vlan}"
# remove the vlan interface, it will be removed from bridge automatically
[ $? -eq 0 ] && ifconfig ${_vid} destroy >/dev/null 2>&1
@@ -311,17 +329,12 @@ switch::standard::__unconfigure_port(){
}
# get the id for a standard switch
# this is just vm-<switch-name>
# we do make sure it exists here though
# this returns the associated bridge name
#
# @param string _var variable to put id into
# @param string _switch the switch to look for
# @return 0 on success
#
switch::standard::id(){
local _var="$1"
local _switch="$2"
setvar "${_var}" "vm-${_switch}"
ifconfig "vm-${_switch}" >/dev/null 2>&1
switch::find "$1" "$2"
}

View File

@@ -97,11 +97,11 @@ switch::vale::id(){
local _id_s _id_p
# get a switch id
_id_s=$(md5 -qs "${_switch}" | awk '{print substr($0,0,5)}')
_id_s=$(md5 -qs "${_switch}" | cut -c1-5)
# given port?
if [ -n "${_port}" ]; then
_id_p=$(md5 -qs "${_port}" | awk '{print substr($0,0,5)}')
_id_p=$(md5 -qs "${_port}" | cut -c1-5)
setvar "${_var}" "vale${_id_s}:${_id_p}"
else
setvar "${_var}" "vale${_id_s}"

View File

@@ -34,7 +34,7 @@ switch::vxlan::init(){
local _id _vlan _if _maddr _addr
# see if the bridge already exists
switch::standard::id "_id" "${_name}" && return 0
switch::find "_id" "${_name}" && return 0
# need a vlan id and interface
config::core::get "_vlan" "vlan_${_name}"
@@ -50,13 +50,15 @@ switch::vxlan::init(){
# create the vxlan interface
ifconfig "vxlan${_vlan}" create vxlanid "${_vlan}" vxlanlocal "${_local}" vxlangroup "${_maddr}" \
vxlandev "${_if}" description "vm-vxlan-${_switch}" up >/dev/null 2>&1
vxlandev "${_if}" descr "vm-vxlan-${_switch}" group vm-vlan up >/dev/null 2>&1
[ $? -eq 0 ] || return 1
# create a bridge for this switch
ifconfig bridge create name "${_id}" up >/dev/null 2>&1
_id=$(ifconfig bridge create descr "vm-${_name}" group vm-switch up 2>/dev/null)
[ $? -eq 0 ] || util::err "failed to create bridge interface for switch ${_name}"
switch::set_viid "${_name}" "${_id}"
# randomise mac if feature is available
[ ${VERSION_BSD} -ge 1102000 ] && ifconfig "${_id}" link random
@@ -80,13 +82,13 @@ switch::vxlan::show(){
local _format="$2"
local _id _vlan _port _addr _priv
switch::standard::id "_id" "${_name}"
switch::find "_id" "${_name}"
config::core::get "_vlan" "vlan_${_name}"
config::core::get "_port" "ports_${_name}"
config::core::get "_addr" "addr_${_name}"
config::core::get "_priv" "private_${_name}" "no"
printf "${_format}" "${_name}" "vxlan" "${_id}" "${_addr}" "${_priv}" "n/a" "${_vlan}" "${_port}"
printf "${_format}" "${_name}" "vxlan" "${_id:--}" "${_addr}" "${_priv}" "n/a" "${_vlan}" "${_port}"
}
# create a vxlan switch
@@ -118,7 +120,7 @@ switch::vxlan::remove(){
local _id _vlan _maddr
# try to get guest bridge and vxlan id
switch::standard::id "_id" "${_switch}"
switch::find "_id" "${_switch}"
[ $? -eq 0 ] || return 1
config::core::get "_vlan" "vlan_${_switch}"

View File

@@ -36,7 +36,7 @@ util::setup(){
# do we have the default template example, but no default in our .templates?
# if so, get a copy, this at least allows a simple "vm create" to work out of the box
if [ -e "/usr/local/share/examples/vm-bhyve/default.conf" ] && [ ! -e "${vm_dir}/.templates/default.conf" ]; then
if [ -e "/usr/local/share/examples/vm-bhyve/default.conf" -a ! -e "${vm_dir}/.templates/default.conf" ]; then
cp "/usr/local/share/examples/vm-bhyve/default.conf" "${vm_dir}/.templates/" >/dev/null 2>&1
fi
}
@@ -110,7 +110,7 @@ util::check_bhyve_iommu(){
_vtd=$(acpidump -t |grep DMAR)
_amdvi=$(sysctl hw |grep 'vmm.amdvi.enable: 1')
[ -z "${_vtd}" ] && [ -z "${_amdvi}" ] && return 1
[ -z "${_vtd}" -a -z "${_amdvi}" ] && return 1
return 0
}
@@ -344,3 +344,18 @@ util::checkyesno(){
*) return 0 ;;
esac
}
# check a name contains no risky characters
# currently limited to "0-9a-z.-", but without ".-" on the end or beginning
#
# @param _name name to check
# @param _maxlen=30 maximum name length (NOTE should be 2 less than desired)
# @return int 0 if name is valid
#
util::check_name(){
local _name="$1"
local _maxlen="$2"
: ${_maxlen:=30}
echo "${_name}" | egrep -iqs "^[a-z0-9][.a-z0-9-]{0,${_maxlen}}[a-z0-9]\$"
}

4
vm
View File

@@ -24,8 +24,8 @@
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
VERSION=1.2-beta1
VERSION_INT=102065
VERSION=1.2-p3
VERSION_INT=102071
VERSION_BSD=$(uname -K)
PATH=${PATH}:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin

2
vm.8
View File

@@ -471,6 +471,8 @@ Create a new virtual switch.
The name must be supplied and may only contain
letters, numbers and dashes.
However, it may not contain a dash at the beginning or end.
Note that the maximum length of a switch name is also limited to
12 characters, due to the way we use this as the interface name.
.Pp
There are currently 4 types of virtual switch that can be created.
These are