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
|
||||
|
||||
Eventually I will write an install script, but for now the process is manual.
|
||||
|
||||
First, download the main script (qq2clone) and place it somewhere in your path. Make it executable.
|
||||
|
||||
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.
|
||||
|
||||
Lastly, there is a bash completion file (qq2clone.completion) and a man page (qq2clone.1) above.
|
||||
|
||||
That's it!
|
||||
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.
|
||||
`
|
||||
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 &&
|
||||
./.qq2clone_installer.bash
|
||||
`
|
||||
|
||||
# FAQ
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ done
|
|||
|
||||
while [[ ! "$input" =~ (y|Y) ]]; do
|
||||
echo "Type in new location"
|
||||
read -r location
|
||||
read -r location; input=""
|
||||
while [[ ! "$input" =~ ^(y|n|Y|N)$ ]]; do
|
||||
echo "[y/n] Accept location \'$location\' ?"
|
||||
echo "[y/n] Accept location '$location' ?"
|
||||
read -rn 1 input; echo
|
||||
done
|
||||
done
|
||||
|
@ -43,6 +43,7 @@ echo
|
|||
if { command -v sudo &>/dev/null || [[ "$USER" == "root" ]]; }; then
|
||||
|
||||
input=""
|
||||
qq_moved=0
|
||||
while : ; do
|
||||
while [[ ! "$input" =~ ^(y|n|Y|N)$ ]]; do
|
||||
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
|
||||
sudo mv "${location}/qq2clone" /usr/bin/qq2clone || success=0
|
||||
fi
|
||||
((success)) && { echo "File moved"; break; }
|
||||
((success)) && { echo "File moved"; qq_moved=1; break; }
|
||||
echo "Attempt failed."; input=""; continue
|
||||
else
|
||||
echo "You have chosen to leave the main script file at:"
|
||||
|
@ -125,5 +126,11 @@ else
|
|||
echo " ${location}/qq2clone-completion.bash"
|
||||
fi
|
||||
echo
|
||||
|
||||
if ((qq_moved)); then
|
||||
/usr/bin/qq2clone setup
|
||||
else
|
||||
"${location}/qq2clone" setup
|
||||
fi
|
||||
|
||||
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
|
||||
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
|
||||
====
|
||||
|
||||
|
|
|
@ -268,6 +268,10 @@ Otherwise, all templates are checked
|
|||
: List all configuration options and their current value, get info about a
|
||||
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
|
||||
|
||||
*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"
|
||||
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
|
||||
local TEMPLATE_DIR="${QQ2_DIR}/templates"
|
||||
local POOL_DIR="${QQ2_DIR}/qq2clone-pool"
|
||||
|
||||
check_rw "$QQ2_DIR"
|
||||
check_depends
|
||||
|
||||
make_dir "$QQ2_DIR"
|
||||
make_dir "$TEMPLATE_DIR"
|
||||
make_dir "$POOL_DIR"
|
||||
check_rw -r "$TEMPLATE_DIR" "$POOL_DIR"
|
||||
check_rw -r "$QQ2_DIR"
|
||||
|
||||
local use_spice spicy
|
||||
if command -v virt-viewer &>/dev/null; then
|
||||
|
@ -385,6 +389,17 @@ else
|
|||
spicy=0
|
||||
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
|
||||
create table CLONES(uuid TEXT, id INTEGER, template TEXT, disks TEXT);
|
||||
|
||||
|
@ -3141,7 +3156,7 @@ if ! ((QQ2_NOEXECUTE)); then
|
|||
else
|
||||
QQ2_DIR="${HOME}/storage-qq2clone"
|
||||
fi
|
||||
[[ -e "${QQ2_DIR}/qq2clone.db" ]] || first_run_setup
|
||||
[[ "$1" == "setup" ]] && { first_run_setup; exit $?; }
|
||||
get_config
|
||||
exec_com "$@"
|
||||
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]]
|
||||
List all configuration options and their current value, get info about a
|
||||
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
|
||||
.PP
|
||||
\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