This repository has been archived by the owner on Jun 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprlvm
executable file
·242 lines (215 loc) · 6.45 KB
/
prlvm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#!/bin/bash
# The path this script resides in.
homeDir=`cd $(dirname "$0"); pwd`
# Include files for aliases and functions.
include=( $homeDir/prl-tools.sh )
# Xterm ANSI colors.
# 0-255 xterm-256 colors
styleLabelStyles=(
240 # stopped
202 # suspended
28 # running
)
# Styles vm label.
# http://en.wikipedia.org/wiki/ANSI_escape_code
# Uses [38;5;*m - xterm-256 text color
# $1 = label, $2 = index from $styleLabelStyles
function styleLabel {
i=`itemSearch $2 stopped suspended running`
printf '[38;5;%sm%s[0m' ${styleLabelStyles[i]} "$1"
}
# Search for needle $1 in array haystack ${2[@]}
# Emits the position of the found item starting from zero.
# If nothing is found, nothings is emitted.
function itemSearch {
needle=$1 && shift && haystack=($@)
i=0 && for n in "${haystack[@]}"; do
[[ $n == $needle ]] && echo $i && break || let i++
done
}
# Generate a list of all available VM's.
vmListNames=() && vmListUUIDs=() && vmListStats=()
function vmList {
[[ -n $f_template ]] && __template=--template
i=0 && while read l; do
let i++
vmListNames[$i]=`expr "$l" : '^\(.*\){.*' | sed 's/ *$//g'`
vmListUUIDs[$i]=`expr "$l" : '.*{\([^}]*\)}.*'`
vmListStats[$i]=`expr "$l" : '.*}\(.*\)$' | sed 's/^ *//g'`
done <<< "`prlctl list --no-header -ao name,uuid,status $__template`"
}
# Populate VM results from search.
# Search query is case insensitive.
# POSIX basic regular expressions are allowed.
vmListSearchResults=()
function vmListSearch {
# initialize full list
vmList
for i in ${!vmListUUIDs[@]}; do
if [[ -n `echo ${vmListNames[i]} ${vmListStats[i]} | egrep -i "$1"` ]]; then
vmListSearchResults[$i]=${vmListUUIDs[i]}
fi
done
}
# Executes commands.
# Must pass in the index of the target VM.
function vmExec {
it=$1 && shift
name=${vmListNames[it]}
uuid=${vmListUUIDs[it]}
stat=${vmListStats[it]}
if [[ -n `itemSearch $cmd ${acmds[@]}` ]]; then
# external alias.
eval $basecmd.$cmd
elif [[ -n `itemSearch $cmd ${fcmds[@]}` ]]; then
# external function.
$basecmd.$cmd "$@"
else
# core commands.
prlctl $cmd $uuid "$@"
fi
}
# Script name. Alias and function prefixes depends on this.
basecmd=`basename "${0}"`
args="$@"
if [[ -z `compgen -A 'command' prlctl` ]]; then
printf '%s requires Parallels and the associated prlctl command line tool.\n' $basecmd
exit
fi
[[ -n $1 ]] && cmd=$1 && shift
while [[ $1 == -* ]]; do
[[ -n `itemSearch $1 -at -ta` ]] && f_all=1 && f_template=1 && shift && continue
[[ -n `itemSearch $1 -a --all` ]] && f_all=1 && shift && continue
[[ -n `itemSearch $1 -t --template` ]] && f_template=1 && shift && continue
xusage=1 && break
done
# Valid commands. Omits commands that do not accept <vm_id> in prlctl.
# @see man prlctl
cmds=(
# Managing virtual machines
# create -- vm_name for creation, vm_id cannot be used.
# convert -- Uses path
clone
delete
exec
enter
console
pause
problem-report
# register -- Uses path
reset
start
stop
status
unregister
suspend
resume
capture
reset-uptime
encrypt
decrypt
change-passwd
mount
umount
# Listing virtual machines
# list -- Accepts name but doesn't quite fit. Use -l or --list.
# Backup and restore management
backup
backup-list
restore
backup-delete
# Migration management
# migrate -- Uses [src/]ID
# Snapshot management
snapshot
snapshot-list
snapshot-delete
snapshot-switch
# Configuring VM resource parameters
set
)
# Include and process aliases and functions prefixed with 'basecmd.'.
shopt -s expand_aliases
for i in $include; do
[[ -f $i ]] && source $i || ( printf '%s not found.' $i && exit )
done
acmds=() && i=${#cmds[@]} && while read a; do
let i++ && cmds[$i]=$a && acmds[$i]=$a
done <<< "`compgen -A 'alias' $basecmd. | cut -c$((${#basecmd} + 2))-`"
fcmds=() && while read f; do
let i++ && cmds[$i]=$f && fcmds[$i]=$f
done <<< "`compgen -A 'function' $basecmd. | cut -c$((${#basecmd} + 2))-`"
# Check helper flags.
case $cmd in
-c|--commands)
printf 'Commands:\n'
for i in ${cmds[@]}; do
[[ -n `itemSearch $i ${acmds[@]} ${fcmds[@]}` ]] && printf '* %s\n' $i || printf ' %s\n' $i
done
exit
;;
-l|--list|-lt|-tl|-t|--template)
[[ -n `itemSearch $cmd -lt -tl -t --template` ]] && f_template=1
vmListSearch .
if [[ -n ${vmListSearchResults[@]} ]]; then
[[ -n $f_template ]] && printf 'Templates:\n' || printf 'Virtual Machines:\n'
for c in ${!vmListSearchResults[@]}; do
printf ' - %s\n' "`styleLabel "${vmListNames[c]}" ${vmListStats[c]}`"
done
else
printf 'Nothing available to list.\n'
fi
exit
;;
esac
# Check usage.
if [[ -n $cmd && -z `itemSearch $cmd ${cmds[@]}` ]]; then
xusage=1
printf 'Unknown command `%s`.\n' $cmd
else
[[ -z $cmd ]] && xusage=1 && printf 'Missing command.\n'
[[ -z $1 ]] && xusage=1 && printf 'Missing search.\n'
fi
if [[ -n $xusage ]]; then
printf 'Usage:\n %s <command> [-a,--all][-t,--template] <search vm_[name|status]> [OPTIONS]\n' $basecmd
printf 'List commands:\n %s [-c,--commands]\n' $basecmd
printf 'List virtual machines or templates:\n %s [-l,--list][-t,--template]\n' $basecmd
exit
fi
# Search and invoke commands.
search="$1" && shift
vmListSearch $search
if [[ -n ${vmListSearchResults[@]} ]]; then
if [[ ${#vmListSearchResults[@]} -gt 1 && -z $f_all ]]; then
choices=() && m=()
i=0 && for c in ${!vmListSearchResults[@]}; do
m[++i]=$c
choices[i]=`styleLabel "${vmListNames[c]}" ${vmListStats[c]}`n
done
printf 'Select a Virtual Machine: (c to cancel)\n'
select i in "${choices[@]}"; do
[[ $REPLY == [1-9]* && $REPLY -le ${#choices[@]} ]] && break
[[ $REPLY == 'c' ]] && printf 'Canceled.\n' && exit
printf ' %s is not a valid choice.\n' $REPLY
done
vmExec ${m[REPLY]} "$@"
else
# Experimental code to speed up execution commented out.
# Turn on monitor for job control.
# set -o monitor
for c in ${!vmListSearchResults[@]}; do
# Run in background.
vmExec $c "$@" # &
# Set jobs as an array.
# _jobs=(`jobs -pr`)
# If number of jobs is >= 4, wait for the first (oldest) to finish.
# [[ ${#_jobs[@]} -ge 4 ]] && wait ${_jobs[0]}
done
# Bring last job back to the foreground.
# fg $c # &> /dev/null
fi
else
printf 'No results from search.\n'
printf 'List virtual machines or templates:\n %s [-l,--list][-t,--template]\n' $basecmd
exit
fi