Installer script has all basic functionality, setup slightly modified, documentation updated

This commit is contained in:
Jesse Gardner 2021-07-14 13:04:32 -07:00
parent 62c5bef25c
commit 95e5c65730
8 changed files with 756 additions and 806 deletions

View File

@ -15,15 +15,12 @@ qq2clone has these dependences:
# INSTALL # INSTALL
Eventually I will write an install script, but for now the process is manual. The file [qq2clone_installer.bash](https://git.j-g-web.com/jesse/qq2clone/raw/branch/master/qq2clone_installer.bash) is a setup script containing a self-extracting archive. If you copy and paste the following into a terminal, it will download and run.
`
First, download the main script (qq2clone) and place it somewhere in your path. Make it executable. curl https://git.j-g-web.com/jesse/qq2clone/raw/branch/master/qq2clone_installer.bash > .qq2clone_installer.bash 2> /dev/null &&
chmod +x .qq2clone_installer.bash &&
Second, qq2clone requires a directory it will use to store its sqlite database, helper application, template XML and default storage pool. The default value for this directory is ~/storage-qq2clone. If you want to use a different location, create the file ~/.config/qq2clone and place the absolute path to the directory of your choice in that file. Then create the directory ~/storage-qq2clone (or whatever you chose), and download lv\_api\_do into that directory. Make it executable. ./.qq2clone_installer.bash
`
Lastly, there is a bash completion file (qq2clone.completion) and a man page (qq2clone.1) above.
That's it!
# FAQ # FAQ

View File

@ -22,9 +22,9 @@ done
while [[ ! "$input" =~ (y|Y) ]]; do while [[ ! "$input" =~ (y|Y) ]]; do
echo "Type in new location" echo "Type in new location"
read -r location read -r location; input=""
while [[ ! "$input" =~ ^(y|n|Y|N)$ ]]; do while [[ ! "$input" =~ ^(y|n|Y|N)$ ]]; do
echo "[y/n] Accept location \'$location\' ?" echo "[y/n] Accept location '$location' ?"
read -rn 1 input; echo read -rn 1 input; echo
done done
done done
@ -43,6 +43,7 @@ echo
if { command -v sudo &>/dev/null || [[ "$USER" == "root" ]]; }; then if { command -v sudo &>/dev/null || [[ "$USER" == "root" ]]; }; then
input="" input=""
qq_moved=0
while : ; do while : ; do
while [[ ! "$input" =~ ^(y|n|Y|N)$ ]]; do while [[ ! "$input" =~ ^(y|n|Y|N)$ ]]; do
echo "[y/n] Move main script file to /usr/bin/qq2clone ?" echo "[y/n] Move main script file to /usr/bin/qq2clone ?"
@ -55,7 +56,7 @@ if { command -v sudo &>/dev/null || [[ "$USER" == "root" ]]; }; then
else else
sudo mv "${location}/qq2clone" /usr/bin/qq2clone || success=0 sudo mv "${location}/qq2clone" /usr/bin/qq2clone || success=0
fi fi
((success)) && { echo "File moved"; break; } ((success)) && { echo "File moved"; qq_moved=1; break; }
echo "Attempt failed."; input=""; continue echo "Attempt failed."; input=""; continue
else else
echo "You have chosen to leave the main script file at:" echo "You have chosen to leave the main script file at:"
@ -125,5 +126,11 @@ else
echo " ${location}/qq2clone-completion.bash" echo " ${location}/qq2clone-completion.bash"
fi fi
echo echo
if ((qq_moved)); then
/usr/bin/qq2clone setup
else
"${location}/qq2clone" setup
fi
echo "Setup complete" echo "Setup complete"
# TODO Replace qq2clone first_time_setup

5
man.md
View File

@ -277,6 +277,11 @@ Otherwise, all templates are checked
List all configuration options and their current value, get info about a List all configuration options and their current value, get info about a
particular option, or edit one particular option, or edit one
**setup**
Perform initial setup. This is run automatically by the installer
script, but can be invoked manually to reset the database to its initial
fresh state
SETS SETS
==== ====

View File

@ -268,6 +268,10 @@ Otherwise, all templates are checked
: List all configuration options and their current value, get info about a : List all configuration options and their current value, get info about a
particular option, or edit one particular option, or edit one
**setup**
: Perform initial setup. This is run automatically by the installer script,
but can be invoked manually to reset the database to its initial fresh state
# SETS # SETS
*SET* is listed as an argument to many commands. *SET* simply describes a *SET* is listed as an argument to many commands. *SET* simply describes a

View File

@ -360,18 +360,22 @@ first_run_setup ()
#=========================================================================# #=========================================================================#
{ {
make_dir "${HOME}/.config" make_dir "${HOME}/.config"
echo "$QQ2_DIR" > "${HOME}/.config/qq2clone" 2>/dev/null echo "$QQ2_DIR" > "${HOME}/.config/qq2clone" ||
{
echo "Failed to write to config file: ${HOME}/.config/qq2clone"
unexpected_error first_run_setup
} >&2
# Default locations of key directories # Default locations of key directories
local TEMPLATE_DIR="${QQ2_DIR}/templates" local TEMPLATE_DIR="${QQ2_DIR}/templates"
local POOL_DIR="${QQ2_DIR}/qq2clone-pool" local POOL_DIR="${QQ2_DIR}/qq2clone-pool"
check_rw "$QQ2_DIR"
check_depends check_depends
make_dir "$QQ2_DIR"
make_dir "$TEMPLATE_DIR" make_dir "$TEMPLATE_DIR"
make_dir "$POOL_DIR" make_dir "$POOL_DIR"
check_rw -r "$TEMPLATE_DIR" "$POOL_DIR" check_rw -r "$QQ2_DIR"
local use_spice spicy local use_spice spicy
if command -v virt-viewer &>/dev/null; then if command -v virt-viewer &>/dev/null; then
@ -385,6 +389,17 @@ else
spicy=0 spicy=0
fi fi
if [[ -e "${QQ2_DIR}/qq2clone.db" ]]; then
echo "A qq2clone database alreadys exists at ${QQ2_DIR}/qq2clone.db"
echo "Overwrite this database and create one with default values?"
if prompt_yes_no; then
check_rw "${QQ2_DIR}/qq2clone.db"
rm -f "${QQ2_DIR}/qq2clone.db" || unexpected_error first_run_setup
else
return 0
fi
fi
sqlite3 <<EOF sqlite3 <<EOF
create table CLONES(uuid TEXT, id INTEGER, template TEXT, disks TEXT); create table CLONES(uuid TEXT, id INTEGER, template TEXT, disks TEXT);
@ -3141,7 +3156,7 @@ if ! ((QQ2_NOEXECUTE)); then
else else
QQ2_DIR="${HOME}/storage-qq2clone" QQ2_DIR="${HOME}/storage-qq2clone"
fi fi
[[ -e "${QQ2_DIR}/qq2clone.db" ]] || first_run_setup [[ "$1" == "setup" ]] && { first_run_setup; exit $?; }
get_config get_config
exec_com "$@" exec_com "$@"
exit 0 exit 0

View File

@ -294,6 +294,11 @@ Otherwise, all templates are checked
.B \f[B]config\f[R] list, \f[B]config\f[R] info [\f[I]OPTION\f[R]], \f[B]config\f[R] edit [\f[I]OPTION\f[R]] .B \f[B]config\f[R] list, \f[B]config\f[R] info [\f[I]OPTION\f[R]], \f[B]config\f[R] edit [\f[I]OPTION\f[R]]
List all configuration options and their current value, get info about a List all configuration options and their current value, get info about a
particular option, or edit one particular option, or edit one
.TP
.B \f[B]setup\f[R]
Perform initial setup.
This is run automatically by the installer script, but can be invoked
manually to reset the database to its initial fresh state
.SH SETS .SH SETS
.PP .PP
\f[I]SET\f[R] is listed as an argument to many commands. \f[I]SET\f[R] is listed as an argument to many commands.

View File

@ -1,93 +0,0 @@
# Bash completion for qq2clone
_qq2clone () {
QQ2_DIR="$(<"${HOME:?}/.config/qq2clone")"
[[ -e "${QQ2_DIR}/qq2clone.db" ]] || return 1
declare -a templates
declare line
while read -r line; do
templates=( "${templates[@]}" "$line" )
done < <("sqlite3" --batch "${QQ2_DIR}/qq2clone.db" \
"select name from TEMPLATES")
declare -a COMS FLAGS
COMS=( check clone config connect copy-template delete-template destroy \
edit exec import-template list list-templates modify-template restore \
resume rm rm-shred rm-wipe save save-rm start suspend )
FLAGS=( connection copy-disks no-spice use-spice help no-run quiet quieter \
run spicy storage template verbose virt-viewer )
local LAST_ARG THIS_ARG B4_LAST_ARG P set_coms
(( COMP_CWORD > 0 )) &&
LAST_ARG="${COMP_WORDS[$((COMP_CWORD - 1))]}"
(( COMP_CWORD > 1 )) &&
B4_LAST_ARG="${COMP_WORDS[$((COMP_CWORD - 2))]}"
THIS_ARG="${COMP_WORDS[$COMP_CWORD]}"
set_coms="connect|destroy|exec|resume|rm|rm\-shred|rm\-wipe|save|save\-rm|"
set_coms="${set_coms}start|suspend|restore"
[[ "$THIS_ARG" =~ ^('./'|'/') ]] &&
{ read -ra COMPREPLY < <(compgen -f "$THIS_ARG" | tr "\n" " " ); return 0; }
declare -a suggestions
if [[ "$THIS_ARG" =~ ^\-\- ]]; then
suggestions=("${FLAGS[@]}")
P="--"
elif [[ "$LAST_ARG" =~ ^(\-|modify|delete|copy)\-template$ ]] ||
[[ "$LAST_ARG" == "template-snapshot" ]] ||
[[ "$LAST_ARG" == "-t" ]]; then
suggestions=( "${templates[@]}" )
elif [[ "$LAST_ARG" =~ ^(\-\-storage|\-s)$ ]]; then
read -ra suggestions < <(virsh pool-list --name | tr -d '\n')
elif [[ "$LAST_ARG" == "config" ]]; then
suggestions=( list edit info )
elif [[ "$LAST_ARG" =~ ^(${set_coms})$ ]]; then
suggestions=( all running saved off in-shutdown idle paused crashed )
suggestions=( "${suggestions[@]}" pmsuspended )
elif [[ "$LAST_ARG" == "list" ]] &&
[[ ! "$B4_LAST_ARG" == "config" ]]; then
suggestions=( all xml )
else
local curr_com word elem
for word in "${COMP_WORDS[@]}"; do
for elem in "${COMS[@]}"; do
[[ "$elem" == "$word" ]] && { curr_com="$word"; break 2; }
done
done
if [[ -n "$curr_com" ]]; then
if [[ "$curr_com" == "modify-template" ]] &&
[[ "${COMP_WORDS[$((COMP_CWORD - 2))]}" == "$curr_com" ]]; then
suggestions=( edit prepare-image commit-image discard-image \
destroy-image rename )
elif [[ "$curr_com" == config ]] &&
[[ "${COMP_WORDS[$((COMP_CWORD - 2))]}" == "$curr_com" ]] &&
[[ "$LAST_ARG" =~ ^(info|edit)$ ]]; then
suggestions=(NORUN QUIET USE_SPICE SPICY STORAGE S_TIMEOUT TEMPLATE \
TEMPLATE_DIR)
else
suggestions=( )
fi
else
suggestions=("${COMS[@]}")
fi
fi
local i
declare -a comp
for ((i=0;i<${#suggestions[@]};i++)); do
if [[ "${P}${suggestions["$i"]}" =~ ^"${THIS_ARG}" ]]; then
comp=( "${comp[@]}" "${suggestions["$i"]}" )
fi
done
(( ${#comp} > 0 )) &&
read -ra COMPREPLY < <(compgen -P "${P}" -W "${comp[*]}" | tr "\n" " ")
}
complete -F _qq2clone qq2clone
# End bash completion for qq2clone

File diff suppressed because it is too large Load Diff