Commit d2f1ac24 authored by Paul John King's avatar Paul John King

Implemented examine|verify pool|volume functions --

These functions also used slightly more robust XML functions -- I'll port to
the other examine functions later.
parent 13036eaf
......@@ -17,6 +17,31 @@ The command call
creates a directory-type storage pool with the name `«name»` under the path
`«path»`.
The command call
kvm_tool examine pool «name»
outputs the path of the storage pool with the name `«name»` as a Bourne-shell
variable assignment (suitable for shell evaluation) and returns
* 0 if the pool exists, and
* 1 otherwise.
The command call
kvm_tool verify pool «name» «path»
returns
* 0 if a storage pool with the name `«name»` and the path `«path»`
exists,
* 1 if a storage pool with the name `«name»` but other parameters exists,
and
* 2 if no storage pool with the name `«name»` exists.
The command call
kvm_tool destroy pool «name»
......@@ -34,6 +59,33 @@ creates a qcow2 storage volume with the name `«name»` in the storage pool
`«pool»` with the qcow2 file-system image at the path `«path»` as its backing
storage volume.
The command call
kvm_tool examine volume «name» «pool»
outputs the path of the backing storage volume of the storage volume with the
name `«name»` in the storage pool `«pool»` as a Bourne-shell variable
assignment (suitable for shell evaluation) and returns
* 0 if the volume exists in the pool, and
* 1 otherwise.
The command call
kvm_tool verify volume «name» «pool» «path»
returns
* 0 if a storage volume with the name `«name»` and a backing storage volume
at the path `«path»` exists in the storage pool `«pool»`,
* 1 if a storage volume with the name `«name»` but other parameters exists
in the storage pool `«pool»`, and
* 2 if no storage volume with the name `«name»` exists in the storage pool
`«pool»`.
The command call
kvm_tool destroy volume «name» «pool»
......
#!/bin/sh
# TODO: Implement examine and verify commands for pools and volumes.
# TODO: Implement better XML functions that track depth.
# TODO: Comment the private functions.
# TODO: Add a -j option to the examine commands that outputs JSON suitable
# for Ansible.
......@@ -8,8 +10,6 @@
# TODO: Containerise the script with statically compiled copies of dash and
# virsh.
# TODO: Comment the private functions.
# Public Functions
# ----------------
......@@ -24,14 +24,14 @@ Usage:
${0##*/} help
${0##*/} create pool «name» «path»
${0##*/} examine pool «name» -- NOT YET IMPLEMENTED
${0##*/} verify pool «name» «path» -- NOT YET IMPLEMENTED
${0##*/} examine pool «name»
${0##*/} verify pool «name» «path»
${0##*/} destroy pool «name»
${0##*/} help pool
${0##*/} create volume «name» «pool» «path»
${0##*/} examine volume «name» -- NOT YET IMPLEMENTED
${0##*/} verify volume «name» «pool» «path» -- NOT YET IMPLEMENTED
${0##*/} examine volume «name» «pool»
${0##*/} verify volume «name» «pool» «path»
${0##*/} destroy volume «name» «pool»
${0##*/} help volume
......@@ -94,6 +94,31 @@ The command call
creates a directory-type storage pool with the name \`«name»\` under the path
\`«path»\`.
The command call
${0##*/} examine pool «name»
outputs the path of the storage pool with the name \`«name»\` as a Bourne-shell
variable assignment (suitable for shell evaluation) and returns
* 0 if the pool exists, and
* 1 otherwise.
The command call
${0##*/} verify pool «name» «path»
returns
* 0 if a storage pool with the name \`«name»\` and the path \`«path»\`
exists,
* 1 if a storage pool with the name \`«name»\` but other parameters exists,
and
* 2 if no storage pool with the name \`«name»\` exists.
The command call
${0##*/} destroy pool «name»
......@@ -133,6 +158,67 @@ create_pool(){
} ;
examine_pool(){
if test $# != 1 ;
then
help_pool >&2 ;
return 1 ;
fi ;
local _NAME="${1}" ;
shift 1 ;
local _pool_xml ;
local _target_xml ;
local _path_xml ;
local _path ;
if _pool_xml=$(virsh -q pool-dumpxml "${_NAME}" 2> /dev/null) ;
then
_target_xml=$(_get_element_by_tag_from_xml "${_pool_xml}" "target" 0) || return 1 ;
_path_xml=$(_get_element_by_tag_from_xml "${_target_xml}" "path" 0) || return 1 ;
_path=$(_get_content_from_xml "${_path_xml}") || return 1 ;
echo "POOL_PATH='${_path}'" ;
return 0 ;
else
return 1 ;
fi ;
} ;
verify_pool(){
if test $# != 2 ;
then
help_pool >&2 ;
return 1 ;
fi ;
local _NAME="${1}" ;
local _PATH="${2}" ;
shift 2 ;
local _PARAMETERS ;
if _PARAMETERS=$(examine_pool "${_NAME}") ;
then
eval "${_PARAMETERS}" ;
if test "${POOL_PATH}" = "${_PATH}" ;
then
return 0 ;
else
return 1 ;
fi ;
else
return 2 ;
fi ;
} ;
destroy_pool(){
if test $# != 1 ;
......@@ -166,6 +252,33 @@ creates a qcow2 storage volume with the name \`«name»\` in the storage pool
\`«pool»\` with the qcow2 file-system image at the path \`«path»\` as its backing
storage volume.
The command call
${0##*/} examine volume «name» «pool»
outputs the path of the backing storage volume of the storage volume with the
name \`«name»\` in the storage pool \`«pool»\` as a Bourne-shell variable
assignment (suitable for shell evaluation) and returns
* 0 if the volume exists in the pool, and
* 1 otherwise.
The command call
${0##*/} verify volume «name» «pool» «path»
returns
* 0 if a storage volume with the name \`«name»\` and a backing storage volume
at the path \`«path»\` exists in the storage pool \`«pool»\`,
* 1 if a storage volume with the name \`«name»\` but other parameters exists
in the storage pool \`«pool»\`, and
* 2 if no storage volume with the name \`«name»\` exists in the storage pool
\`«pool»\`.
The command call
${0##*/} destroy volume «name» «pool»
......@@ -210,6 +323,69 @@ create_volume(){
} ;
examine_volume(){
if test $# != 2 ;
then
help_volume >&2 ;
return 1 ;
fi ;
local _NAME="${1}" ;
local _POOL="${2}" ;
shift 2 ;
local _volume_xml ;
local _target_xml ;
local _path_xml ;
local _path ;
if _volume_xml=$(virsh -q vol-dumpxml "${_NAME}" --pool "${_POOL}" 2> /dev/null) ;
then
_backing_store_xml=$(_get_element_by_tag_from_xml "${_volume_xml}" "backingStore" 0) || return 1 ;
_path_xml=$(_get_element_by_tag_from_xml "${_backing_store_xml}" "path" 0) || return 1 ;
_path=$(_get_content_from_xml "${_path_xml}") || return 1 ;
echo "VOLUME_PATH='${_path}'" ;
return 0 ;
else
return 1 ;
fi ;
} ;
verify_volume(){
if test $# != 3 ;
then
help_volume >&2 ;
return 1 ;
fi ;
local _NAME="${1}" ;
local _POOL="${2}" ;
local _PATH="${3}" ;
shift 3 ;
local _PARAMETERS ;
if _PARAMETERS=$(examine_volume "${_NAME}" "${_POOL}") ;
then
eval "${_PARAMETERS}" ;
if test "${VOLUME_PATH}" = "${_PATH}" ;
then
return 0 ;
else
return 1 ;
fi ;
else
return 2 ;
fi ;
} ;
destroy_volume(){
if test $# != 2 ;
......@@ -367,6 +543,12 @@ create_domain(){
examine_domain(){
if test $# != 1 ;
then
help_domain >&2 ;
return 1 ;
fi ;
local _NAME="${1}" ;
shift 1 ;
......@@ -999,6 +1181,134 @@ _echo_stdin(){
#
# Fortunately, `libvirt` seems to output XML that meets these conditions.
_get_content_from_xml(){
if test $# != 1 ;
then
help_utility >&2 ;
return 1 ;
fi ;
local _XML="${1}" ;
shift 1 ;
local _depth=0 ;
echo "${_XML}" |
while IFS="" read -r _line ;
do
case "${_line}" in
*"<"*"/>"*)
if test ${_depth} -eq 0 ;
then
echo "" ;
return 0 ;
else
echo "${_line}" ;
fi ;
;;
*"<"*">"*"</"*">"*)
if test ${_depth} -eq 0 ;
then
_line="${_line%%</*}"
_line="${_line##*>}" ;
echo "${_line}" ;
return 0 ;
else
echo "${_line}" ;
fi ;
;;
*"</"*">"*)
_depth=$((_depth - 1)) ;
test ${_depth} -eq 0 || echo "${_line}" ;
;;
*"<"*">"*)
test ${_depth} -eq 0 || echo "${_line}" ;
_depth=$((_depth + 1)) ;
;;
*)
test ${_depth} -eq 0 || echo "${_line}" ;
;;
esac ;
done ;
return 0 ;
} ;
_get_element_by_tag_from_xml(){
if test $# != 3 ;
then
return 1 ;
fi ;
local _XML="${1}" ;
local _TAG="${2}" ;
local _INDEX="${3}" ;
shift 3 ;
local _index=0 ;
local _depth=0 ;
local _print=false ;
echo "${_XML}" |
while IFS="" read -r _line ;
do
case "${_line}" in
*"<${_TAG}/>"*|\
*"<${_TAG} "*"/>"*|\
*"<${_TAG}>"*"</${_TAG}>"*|\
*"<${_TAG} "*">"*"</${_TAG}>"*)
if test ${_index} -eq ${_INDEX} ;
then
echo "${_line}" ;
fi ;
_index=$((_index + 1)) ;
;;
*"<${_TAG}>"*|\
*"<${_TAG} "*">"*)
if test ${_index} -eq ${_INDEX} ;
then
echo "${_line}" ;
_print=true ;
fi ;
_depth=$((_depth + 1)) ;
;;
*"</${_TAG}>"*)
_depth=$((_depth - 1)) ;
if test ${_index} -eq ${_INDEX} ;
then
echo "${_line}" ;
fi ;
if test ${_depth} -eq 0 ;
then
_print=false ;
_index=$((_index + 1)) ;
fi ;
;;
*)
if ${_print} ;
then
echo "${_line}" ;
fi ;
;;
esac ;
done ;
return 0 ;
} ;
#### TODO ####
_get_content_by_tag_from_xml(){
local _XML="${1}" ;
......@@ -1282,6 +1592,18 @@ _main(){
return $? ;
;;
"examine pool "*)
shift 2 ;
examine_pool "${@}" ;
return $? ;
;;
"verify pool "*)
shift 2 ;
verify_pool "${@}" ;
return $? ;
;;
"destroy pool "*)
shift 2 ;
destroy_pool "${@}" ;
......@@ -1299,6 +1621,18 @@ _main(){
return $? ;
;;
"examine volume "*)
shift 2 ;
examine_volume "${@}" ;
return $? ;
;;
"verify volume "*)
shift 2 ;
verify_volume "${@}" ;
return $? ;
;;
"destroy volume "*)
shift 2 ;
destroy_volume "${@}" ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment