Installer script has all basic functionality, setup slightly modified, documentation updated
This commit is contained in:
parent
62c5bef25c
commit
95e5c65730
15
README.md
15
README.md
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
5
man.md
|
@ -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
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
23
qq2clone
23
qq2clone
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue