Add "media" datastores and extend iso handling

If you have a directory (or network mount) containing iso files, you
can configure vm-bhyve to look there by adding it as
a media datastore. (vm datastore iso my-media /path/to/iso/dir).
Also we now look in the current dir for iso files, and accept full paths.
This commit is contained in:
Matt Churchyard
2016-08-01 16:02:57 +01:00
parent f1d507cce4
commit 42289f5ca8
8 changed files with 126 additions and 8 deletions

View File

@@ -122,6 +122,7 @@ cmd::parse_datastore(){
list) datastore::list ;; list) datastore::list ;;
add) datastore::add "$@" ;; add) datastore::add "$@" ;;
remove) datastore::remove "$@" ;; remove) datastore::remove "$@" ;;
iso) datastore::iso "$@" ;;
*) util::usage ;; *) util::usage ;;
esac esac
} }

View File

@@ -317,11 +317,13 @@ core::add_network(){
core::install(){ core::install(){
local _name="$1" local _name="$1"
local _iso="$2" local _iso="$2"
local _fulliso
[ -z "${_name}" -o -z "${_iso}" ] && util::usage [ -z "${_name}" -o -z "${_iso}" ] && util::usage
# just run start with an iso # just run start with an iso
core::__start "$1" "$2" datastore::iso_find "_fulliso" "${_iso}" || util::err "unable to locate iso file - '${_iso}'"
core::__start "${_name}" "${_fulliso}"
} }
# 'vm startall' # 'vm startall'
@@ -645,8 +647,7 @@ core::iso(){
if [ -n "${_url}" ]; then if [ -n "${_url}" ]; then
fetch -o "${vm_dir}/.iso" "${_url}" fetch -o "${vm_dir}/.iso" "${_url}"
else else
echo "FILENAME" datastore::iso_list
ls -1 "${vm_dir}/.iso"
fi fi
} }

View File

@@ -59,6 +59,10 @@ datastore::list(){
_type="zfs" _type="zfs"
_dataset="${_spec#*:}" _dataset="${_spec#*:}"
datastore::__resolve_path "_path" "${_spec}" datastore::__resolve_path "_path" "${_spec}"
elif [ "${_spec%%:*}" = "iso" ]; then
_type="iso"
_path="${_spec#*:}"
_dataset="-"
else else
_type="directory" _type="directory"
_path="${_spec}" _path="${_spec}"
@@ -119,10 +123,16 @@ datastore::add(){
# #
datastore::remove(){ datastore::remove(){
local _name="$1" local _name="$1"
local _ds _found
[ "${_name}" = "default" ] && util::err "cannot remove default datastore" [ "${_name}" = "default" ] && util::err "cannot remove default datastore"
datastore::get "${_name}" || util::err "unable to locate the specified dataset" for _ds in ${VM_DATASTORE_LIST}; do
[ "${_ds}" = "${_name}" ] && _found="1"
done
# found the dataset?
[ -z "${_found}" ] && util::err "unable to locate the specified dataset"
config::core_remove "datastore_list" "${_name}" config::core_remove "datastore_list" "${_name}"
config::core_remove "path_${_name}" config::core_remove "path_${_name}"
@@ -147,6 +157,9 @@ datastore::__resolve_path(){
setvar "${_var}" "${_mount}" setvar "${_var}" "${_mount}"
return 0 return 0
fi fi
elif [ "${_spec%%:*}" = "iso" ]; then
setvar "${_var}" "${_spec#*:}"
return 0
else else
if [ -d "${_spec}" ]; then if [ -d "${_spec}" ]; then
setvar "${_var}" "${_spec}" setvar "${_var}" "${_spec}"
@@ -193,7 +206,10 @@ datastore::get_guest(){
if [ -z "${_found}" ]; then if [ -z "${_found}" ]; then
for _ds in ${VM_DATASTORE_LIST}; do for _ds in ${VM_DATASTORE_LIST}; do
[ "${_ds}" = "default" ] && continue [ "${_ds}" = "default" ] && continue
config::core_get "_spec" "path_${_ds}" config::core_get "_spec" "path_${_ds}"
[ "${_spec%%:*}" = "iso" ] && continue
datastore::__resolve_path "_path" "${_spec}" datastore::__resolve_path "_path" "${_spec}"
if [ -f "${_path}/${_guest}/${_guest}.conf" ]; then if [ -f "${_path}/${_guest}/${_guest}.conf" ]; then
@@ -238,6 +254,9 @@ datastore::get(){
config::core_get "_spec" "path_${_ds}" config::core_get "_spec" "path_${_ds}"
[ -z "${_spec}" ] && return 1 [ -z "${_spec}" ] && return 1
# don't find iso stores
[ "${_spec%%:*}" = "iso" ] && return 1
datastore::__resolve_path "_path" "${_spec}" || return 1 datastore::__resolve_path "_path" "${_spec}" || return 1
[ "${_spec%%:*}" = "zfs" ] && _zfs="1" && _dataset="${_spec#*:}" [ "${_spec%%:*}" = "zfs" ] && _zfs="1" && _dataset="${_spec#*:}"
@@ -247,3 +266,91 @@ datastore::get(){
VM_DS_ZFS="${_zfs}" VM_DS_ZFS="${_zfs}"
VM_DS_ZFS_DATASET="${_dataset}" VM_DS_ZFS_DATASET="${_dataset}"
} }
# add a datastore for iso files
#
# @param string _name the name of the datastore
# @param string _path filesystem path
#
datastore::iso(){
local _name="$1"
local _path="$2"
[ -z "${_name}" -o -z "${_path}" ] && util::usage
core::check_name "${_name}" || util::err "invalid datastore name - '${_name}'"
# check name not in use
for _curr in ${VM_DATASTORE_LIST}; do
[ "${_curr}" = "${_name}" ] && util::err "datstore '${_name}' already exists!"
done
# make sure directory exists
[ ! -d "${_path}" ] && util::err "specified directory does not appear to be valid"
# save
config::core_set "datastore_list" "${_name}" "1"
config::core_set "path_${_name}" "iso:${_path}"
[ $? -ne 0 ] && util::err "error saving settings to configuration file"
}
# find an iso file by looking in the default location
# and any "iso" datastores
#
# @param string _var variable name to put full iso path into
# @param string _file iso filename to look for
# @return int success if found
#
datastore::iso_find(){
local _var="$1"
local _file="$2"
local _ds _spec
# given a full path?
if [ -z "${_file%%/*}" ] && [ -r "${_file}" ]; then
setvar "${_var}" "${_file}"
return 0
fi
# file exists in current dir?
if [ -r "$(pwd)/${_file}" ]; then
setvar "${_var}" "$(pwd)/${_file}"
return 0
fi
# look in default store
if [ -r "${vm_dir}/.iso/${_file}" ]; then
setvar "${_var}" "${vm_dir}/.iso/${_file}"
return 0
fi
for _ds in ${VM_DATASTORE_LIST}; do
config::core_get "_spec" "path_${_ds}"
[ "${_spec%%:*}" != "iso" ] && continue
if [ -r "${_spec#*:}/${_file}" ]; then
setvar "${_var}" "${_spec#*:}/${_file}"
return 0
fi
done
return 1
}
# list iso files
#
datastore::iso_list(){
local _ds _spec _format="%-20s%s\n"
printf "${_format}" "DATASTORE" "FILENAME"
# look for default iso location
[ -d "${vm_dir}/.iso" ] && ls -1 "${vm_dir}/.iso" | awk '{printf "'${_format}'","default",$1}'
# look for iso datastores
for _ds in ${VM_DATASTORE_LIST}; do
config::core_get "_spec" "path_${_ds}"
[ "${_spec%%:*}" != "iso" ] && continue
[ -d "${_spec#*:}" ] && ls -1 ${_spec#*:} | awk '{printf "'${_format}'","'${_ds}'",$1}'
done
}

View File

@@ -64,7 +64,7 @@ guest::load(){
_args="${_args}${_args:+ }-m ${_memory} -e autoboot_delay=${_timeout}" _args="${_args}${_args:+ }-m ${_memory} -e autoboot_delay=${_timeout}"
if [ -n "${_iso}" ]; then if [ -n "${_iso}" ]; then
_args="${_args} -d ${vm_dir}/.iso/${_iso}" _args="${_args} -d ${_iso}"
else else
_args="${_args} -d ${_bootdisk}" _args="${_args} -d ${_bootdisk}"
fi fi
@@ -84,7 +84,7 @@ guest::load(){
if [ -n "${_iso}" ]; then if [ -n "${_iso}" ]; then
_root="cd0" _root="cd0"
util::log_and_write "write" "${_name}" "device.map" "(hd0) ${_bootdisk}" util::log_and_write "write" "${_name}" "device.map" "(hd0) ${_bootdisk}"
util::log_and_write "appnd" "${_name}" "device.map" "(cd0) ${vm_dir}/.iso/${_iso}" util::log_and_write "appnd" "${_name}" "device.map" "(cd0) ${_iso}"
# if we have local grub config, we need to point grub-bhyve at the host. # if we have local grub config, we need to point grub-bhyve at the host.
# if not, just use defaults # if not, just use defaults

View File

@@ -180,6 +180,7 @@ vm::run(){
vm::lock vm::lock
util::log "guest" "${_name}" "booting" util::log "guest" "${_name}" "booting"
cd /
while [ 1 ]; do while [ 1 ]; do
@@ -198,7 +199,7 @@ vm::run(){
# set full iso path # set full iso path
# use null.iso if not an install and uefi firmware # use null.iso if not an install and uefi firmware
[ -n "${_iso}" ] && _iso_dev="-s 3:0,ahci-cd,${vm_dir}/.iso/${_iso}" [ -n "${_iso}" ] && _iso_dev="-s 3:0,ahci-cd,${_iso}"
[ -z "${_iso}" -a -n "${_uefi}" -a "${_uefi}" != "csm" ] && \ [ -z "${_iso}" -a -n "${_uefi}" -a "${_uefi}" != "csm" ] && \
_iso_dev="-s 3:0,ahci-cd,${vm_dir}/.config/null.iso" _iso_dev="-s 3:0,ahci-cd,${vm_dir}/.config/null.iso"

View File

@@ -147,6 +147,7 @@ Usage: vm ...
datastore list datastore list
datastore add <name> <spec> datastore add <name> <spec>
datastore remove <name> datastore remove <name>
datastore add <name> <path>
list list
info [name] [...] info [name] [...]
create [-d datastore] [-t template] [-s size] <name> create [-d datastore] [-t template] [-s size] <name>

2
vm
View File

@@ -25,7 +25,7 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
VERSION=1.2-alpha VERSION=1.2-alpha
VERSION_INT=102012 VERSION_INT=102013
VERSION_BSD=$(uname -K) VERSION_BSD=$(uname -K)
PATH=${PATH}:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin PATH=${PATH}:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin

7
vm.8
View File

@@ -56,6 +56,9 @@
.Nm .Nm
.Cm datastore remove .Cm datastore remove
.Ar name .Ar name
.Nm
.Cm datastore iso
.Ar name path
.Pp .Pp
.Nm .Nm
.Cm create .Cm create
@@ -514,6 +517,10 @@ create it.
.It Cm datastore remove Ar name .It Cm datastore remove Ar name
Remove the specified datastore from the list. This does not destroy the directory Remove the specified datastore from the list. This does not destroy the directory
or dataset, leaving all files intact. or dataset, leaving all files intact.
.It Cm datastore iso Ar name path
Adds a new datastore location for storing iso files. Guests cannot be created in an
iso store, but this provides an easy way to configure vm-bhyve to look in any arbitrary
location on your system (or mounted network share) where you may want to store iso images.
.It Xo .It Xo
.Cm create .Cm create
.Op Fl d Ar datastore .Op Fl d Ar datastore