2018-12-27 17:34:07 +01:00
|
|
|
#!/bin/bash
|
|
|
|
#
|
|
|
|
# fbopt version 0.4.1
|
|
|
|
#
|
|
|
|
# Written in 2018 by Franco Masotti/frnmst <franco.masotti@live.com>
|
|
|
|
#
|
|
|
|
# To the extent possible under law, the author(s) have dedicated all
|
|
|
|
# copyright and related and neighboring rights to this software to the public
|
|
|
|
# domain worldwide. This software is distributed without any warranty.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the CC0 Public Domain Dedication along
|
|
|
|
# with this software. If not, see
|
|
|
|
# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# See also https://frnmst.gitlab.io/notes/my-bash-option-parsing-template.html
|
|
|
|
#
|
|
|
|
|
|
|
|
show_help()
|
|
|
|
{
|
|
|
|
cat <<-EOF
|
|
|
|
Usage: qvm [OPTION]
|
|
|
|
Trivial management of 64 bit virtual machines with qemu.
|
|
|
|
|
|
|
|
Only a single option is accepted.
|
|
|
|
By default, the backup vhd is run.
|
|
|
|
Mandatory arguments to long options are mandatory for short options too.
|
|
|
|
Options:
|
|
|
|
-a, --attach connect to SSH locally
|
|
|
|
-b, --backup backup vhd
|
|
|
|
-c, --create create new vhd
|
|
|
|
-d, --delete delete vhd backup
|
|
|
|
-h, --help print this help
|
|
|
|
-i, --install install img on vhd
|
2019-01-04 12:02:39 +01:00
|
|
|
-m, --mkdir-shared create shared directory
|
2018-12-28 18:59:44 +01:00
|
|
|
-n, --nox run vm without opening a graphical window
|
2018-12-27 17:34:07 +01:00
|
|
|
which is useful for background jobs like SSH
|
2018-12-28 19:35:40 +01:00
|
|
|
-o, --orig run from the original vhd
|
2018-12-27 17:34:07 +01:00
|
|
|
-r, --remote connect to a vnc instance via ssh
|
2019-01-04 12:02:39 +01:00
|
|
|
-v, --vnc run vm with vnc
|
|
|
|
-V, --version print the software version
|
2018-12-27 17:34:07 +01:00
|
|
|
-x, --run run vm
|
|
|
|
|
|
|
|
Exit status:
|
|
|
|
0 if OK,
|
|
|
|
1 if an error occurred.
|
|
|
|
|
|
|
|
CC0 License
|
|
|
|
Written in 2016-2018 by Franco Masotti/frnmst <franco.masotti@live.com>
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
2019-01-04 12:02:39 +01:00
|
|
|
# TODO better FIXME.
|
|
|
|
show_version()
|
|
|
|
{
|
|
|
|
local program_name="${0}"
|
|
|
|
local program_version="$(cat version)"
|
|
|
|
|
|
|
|
wd="$(pwd)"
|
|
|
|
printf "%s\n" "${program_name} version ${program_version}"
|
|
|
|
}
|
|
|
|
|
2018-12-27 17:34:07 +01:00
|
|
|
# A function that prints the variable name and value of all
|
|
|
|
# the flags enabled by the user. This is useful to check that
|
|
|
|
# all the flags are correct, as kind of a dry run.
|
|
|
|
show_flags()
|
|
|
|
{
|
|
|
|
local flags="${*}"
|
|
|
|
|
|
|
|
for flag in ${flags}; do
|
|
|
|
printf "%s='%s'\n" "${flag}" "${!flag}"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
getopt_error()
|
|
|
|
{
|
|
|
|
local program_name="${0}"
|
|
|
|
|
|
|
|
printf "%s\n" "Try '"${program_name}" --help' for more information"
|
|
|
|
} 1>&2 2>&-
|
|
|
|
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
# Create a new array from the reference of the input one.
|
|
|
|
# See https://stackoverflow.com/questions/1063347/passing-arrays-as-parameters-in-bash
|
|
|
|
# See some comments below.
|
|
|
|
declare -a argc=("${!1}")
|
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
# Set the options.
|
2019-01-04 12:02:39 +01:00
|
|
|
local getopt_short_options='abcdhimnorvVx'
|
2018-12-27 19:57:01 +01:00
|
|
|
local getopt_long_options='attach,backup,create,delete,help,install,run,\
|
2019-01-04 12:02:39 +01:00
|
|
|
remote,vnc,mkdir-shared,nox,print-flags,version'
|
2018-12-27 17:34:07 +01:00
|
|
|
|
|
|
|
# Set the default values for the flags.
|
2018-12-27 19:57:01 +01:00
|
|
|
local attach='false'
|
|
|
|
local backup='false'
|
2019-01-04 12:02:39 +01:00
|
|
|
local create='false'
|
2018-12-27 19:57:01 +01:00
|
|
|
local delete='false'
|
|
|
|
local install='false'
|
|
|
|
local nox='false'
|
2018-12-28 18:59:44 +01:00
|
|
|
local origin='false'
|
2018-12-31 16:47:59 +01:00
|
|
|
local remote='false'
|
2018-12-27 19:57:01 +01:00
|
|
|
local run='false'
|
2018-12-28 18:59:44 +01:00
|
|
|
local mkdir_shared='false'
|
2019-01-04 12:02:39 +01:00
|
|
|
local version='false'
|
2018-12-27 19:57:01 +01:00
|
|
|
local vnc='false'
|
2018-12-27 17:34:07 +01:00
|
|
|
|
|
|
|
local program_name="${0}"
|
|
|
|
opts="$(getopt \
|
|
|
|
--name "${program_name}" \
|
|
|
|
--shell bash \
|
|
|
|
--options "${getopt_short_options}" \
|
|
|
|
--longoptions "${getopt_long_options}" \
|
|
|
|
-- \
|
|
|
|
"${argc[@]}")"
|
|
|
|
getopt_retval=${?}
|
|
|
|
# Check that getopt works and that some kind of argument
|
|
|
|
# is passed to the script. This is "quotation hell".
|
|
|
|
a="'"${argc[@]}"'"
|
|
|
|
{ [ ${getopt_retval} -ne 0 ] || [ -z "${a}" ]; } && getopt_error && return 1
|
|
|
|
eval set -- "${opts}"
|
|
|
|
|
|
|
|
# Option parsing.
|
|
|
|
while [ "${1}" != '--' ]; do
|
|
|
|
case "${1}" in
|
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-a | --attach ) attach='true' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-b | --backup ) backup='true' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-c | --create ) create='true' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-d | --delete ) delete='true' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-28 19:02:05 +01:00
|
|
|
-h | --help ) help='true' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-i | --install ) install='true' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-m | --mkdir-shared ) shared='true' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-n | --nox ) nox='nox' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-o | --origin ) origin='origin' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-28 19:35:40 +01:00
|
|
|
--print-flags ) print_flags='true' ;;
|
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-r | --remote ) remote='remote' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-v | --vnc ) vnc='vnc' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
2019-01-04 12:02:39 +01:00
|
|
|
-V | --version ) version='true' ;;
|
|
|
|
|
2018-12-27 19:57:01 +01:00
|
|
|
-x | --run ) run='true' ;;
|
2018-12-27 17:34:07 +01:00
|
|
|
|
|
|
|
esac
|
|
|
|
# Iterate through all arguments.
|
2018-12-27 19:57:01 +01:00
|
|
|
shift 1
|
2018-12-27 17:34:07 +01:00
|
|
|
done
|
|
|
|
|
|
|
|
shift 1
|
|
|
|
# Everything else after '--' is an argument.
|
|
|
|
argc="${*}"
|
|
|
|
|
|
|
|
# Check that the flags that must be non empty are actually not empty.
|
|
|
|
# A user might infact circumvent getopt's mechanisms like this
|
|
|
|
# ./program -flag ''
|
|
|
|
# This can also be done inside the option parser loop but to avoid nestings
|
|
|
|
# I prefer it done here.
|
2018-12-27 19:57:01 +01:00
|
|
|
# NOOP.
|
2018-12-27 17:34:07 +01:00
|
|
|
[ "${print_flags}" = 'true' ] \
|
|
|
|
&& show_flags \
|
2018-12-27 19:57:01 +01:00
|
|
|
'attach' \
|
|
|
|
'backup' \
|
2018-12-28 18:59:44 +01:00
|
|
|
'create' \
|
|
|
|
'delete' \
|
|
|
|
'help' \
|
|
|
|
'install' \
|
|
|
|
'mkdir_shared' \
|
|
|
|
'nox' \
|
2018-12-28 19:19:38 +01:00
|
|
|
'origin' \
|
2018-12-28 18:59:44 +01:00
|
|
|
'run' \
|
|
|
|
'remote' \
|
2019-01-04 12:02:39 +01:00
|
|
|
'version' \
|
2018-12-28 18:59:44 +01:00
|
|
|
'vnc' \
|
2018-12-27 17:34:07 +01:00
|
|
|
&& return 0
|
|
|
|
[ "${help}" = 'true' ] && show_help && return 0
|
2019-01-04 12:02:39 +01:00
|
|
|
[ "${version}" = 'true' ] && show_version && return 0
|
2018-12-27 17:34:07 +01:00
|
|
|
# Override values of optional parameters.
|
2018-12-27 19:57:01 +01:00
|
|
|
# NOOP.
|
2018-12-27 17:34:07 +01:00
|
|
|
|
|
|
|
# From now on you should call a function or an external program
|
|
|
|
# using the values of the flag variables.
|
2018-12-28 18:59:44 +01:00
|
|
|
local place=''
|
|
|
|
local display=''
|
|
|
|
|
2018-12-28 19:35:40 +01:00
|
|
|
check_dependencies || exit ${?}
|
2019-01-04 12:02:39 +01:00
|
|
|
{ [ "${attach}" = 'false' ] && [ "${backup}" = 'false' ] \
|
|
|
|
&& [ "${create}" = 'false' ] && [ "${delete}" = 'false' ] \
|
|
|
|
&& [ "${install}" = 'false' ] && [ "${run}" = 'false' ]; } \
|
|
|
|
&& printf "%s\n" 'an action needs to be specified' 1>&2 2>&- \
|
|
|
|
&& return 1
|
|
|
|
|
2018-12-28 18:59:44 +01:00
|
|
|
if [ "${attach}" = 'true' ]; then
|
2018-12-31 16:47:59 +01:00
|
|
|
[ "${remote}" = 'remote' ] && place='remote' || place='local'
|
|
|
|
[ "${vnc}" = 'vnc' ] && display='vnc' || display=''
|
2018-12-28 18:59:44 +01:00
|
|
|
{ attach "${place}" "${display}"; return ${?}; }
|
|
|
|
fi
|
2018-12-27 19:57:01 +01:00
|
|
|
[ "${backup}" = 'true' ] && { backup; return ${?}; }
|
|
|
|
[ "${create}" = 'true' ] && { create; return ${?}; }
|
|
|
|
[ "${delete}" = 'true' ] && { delete "${origin}"; return ${?}; }
|
|
|
|
[ "${install}" = 'true' ] && { installs "${vnc}"; return ${?}; }
|
|
|
|
if [ "${run}" = 'true' ]; then
|
2018-12-31 16:47:59 +01:00
|
|
|
if [ "${remote}" = 'remote' ]; then
|
|
|
|
# Start remote instance.
|
|
|
|
[ "${vnc}" = 'vnc' ] && display='vnc'
|
|
|
|
{ run_remote_instance "${display}"; return ${?}; }
|
|
|
|
else
|
|
|
|
[ "${vnc}" = 'vnc' ] && display='vnc'
|
|
|
|
[ "${nox}" = 'nox' ] && display='none'
|
|
|
|
[ -z "${display}" ] && display='gtk'
|
|
|
|
{ run "${display}" "${origin}"; return ${?}; }
|
|
|
|
fi
|
2018-12-28 18:59:44 +01:00
|
|
|
fi
|
2018-12-28 19:37:31 +01:00
|
|
|
[ "${mkdir_shared}" = 'true' ] && { mkdir_shared; return ${?}; }
|
2018-12-27 17:34:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Test dependencies and versions.
|
|
|
|
# getopt must return 4 to be fully compatible. See getopt's manual.
|
|
|
|
which bash getopt 1>/dev/null 2>/dev/null && { getopt -T; [ ${?} -eq 4 ]; }
|
|
|
|
|
|
|
|
# Get and pass argc to the main function.
|
|
|
|
# All this work with an array must be done to preserve
|
|
|
|
# quotations for arguments that have whitespaces.
|
|
|
|
# See https://lists.debian.org/debian-user/2007/12/msg01244.html
|
|
|
|
declare -a opts=()
|
|
|
|
for opt in "${@}"; do
|
|
|
|
opts=("${opts[@]}" "${opt}")
|
|
|
|
done
|
|
|
|
main 'opts[@]'
|
|
|
|
|