vbox-ng 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +93 -24
- data/VERSION +1 -1
- data/lib/vbox/cli.rb +58 -17
- data/lib/vbox/cmdlineapi.rb +1 -1
- data/spec/vm_spec.rb +5 -0
- data/vbox-ng.gemspec +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -9,7 +9,7 @@ Installation
|
|
9
9
|
------------
|
10
10
|
gem install vbox-ng
|
11
11
|
|
12
|
-
|
12
|
+
Commandline usage
|
13
13
|
-----
|
14
14
|
|
15
15
|
# vbox -h
|
@@ -21,28 +21,97 @@ Usage
|
|
21
21
|
vbox [options] <vm_name> <command> - make some action (start, reset, etc) on VM
|
22
22
|
|
23
23
|
COMMANDS:
|
24
|
-
|
25
|
-
acpisleepbutton
|
26
|
-
clone
|
27
|
-
delete
|
28
|
-
pause
|
29
|
-
poweroff
|
30
|
-
reset
|
31
|
-
resume
|
32
|
-
savestate
|
33
|
-
show
|
34
|
-
snapshots
|
35
|
-
start
|
24
|
+
start, pause, resume, reset, poweroff, savestate,
|
25
|
+
acpipowerbutton, acpisleepbutton, clone, delete, show, snapshots
|
36
26
|
|
37
27
|
OPTIONS:
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
28
|
+
-g, --[no-]glob (default: auto) assume <vm_name> is a wildcard,
|
29
|
+
and run on multiple VMs.
|
30
|
+
All glob(7) patterns like *,?,[a-z] are supported
|
31
|
+
plus additional pattern {1-20} which matches
|
32
|
+
a sequence of numbers: 1,2,3,...,19,20
|
33
|
+
-n, --dry-run do not change anything, just print commands to be invoked
|
34
|
+
-v, --verbose increase verbosity
|
35
|
+
-c, --clones N clone: make N clones
|
36
|
+
-S, --snapshot MODE clone: use LAST shapshot or make NEW
|
37
|
+
-H, --headless start: start VM in headless mode
|
38
|
+
-h, --help show this message
|
39
|
+
|
40
|
+
EXAMPLES:
|
41
|
+
vbox -v - list VMs with memory and dir sizes
|
42
|
+
vbox "d{1-10}" list - list only VMs named 'd1','d2','d3',...,'d10'
|
43
|
+
vbox "test*" start - start VMs which name starts with 'test'
|
44
|
+
vbox "v[ace]" cpus=2 - set 'number of cpus'=2 on VMs named 'va','vc','ve'
|
45
|
+
vbox d0 - list all parameters of VM named 'd0'
|
46
|
+
vbox d0 clone -c 10 -S last - make 10 new linked clones of vm 'd0' using the
|
47
|
+
latest hdd snapshot, if any
|
48
|
+
vbox d0 clone -c 10 -S new - make ONE new shapshot of VM 'd0' and then make
|
49
|
+
10 new clones linked to this snapshot
|
50
|
+
vbox "tmp?" delete - try to destroy all VMs which name is 4 letters long
|
51
|
+
and starts with 'tmp'
|
52
|
+
vbox ae340207-f472-4d63-80e7-855fca6808cb
|
53
|
+
- list all parameters of VM with this GUID
|
54
|
+
vbox --no-glob "*wtf?!*" rm - destroy VM which name is '*wtf?!*'
|
55
|
+
|
56
|
+
Ruby examples
|
57
|
+
=============
|
58
|
+
|
59
|
+
Clone first VM
|
60
|
+
-----
|
61
|
+
``` ruby
|
62
|
+
# irb
|
63
|
+
>> require 'vbox'
|
64
|
+
=> true
|
65
|
+
>> vm = VBOX::VM.first
|
66
|
+
=> #<VBOX::VM:0x000000012c5320 @all_vars={}, @uuid="{ae340207-f472-4d63-80e7-855fca6808cb}", @name="d0">
|
67
|
+
>> vm2 = vm.clone! :snapshot => :last
|
68
|
+
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
|
69
|
+
Machine has been successfully cloned as "d1"
|
70
|
+
[.] old macaddress1=dec0de000000
|
71
|
+
[.] new macaddress1=dec0de000001
|
72
|
+
=> #<VBOX::VM:0x00000001315820 @all_vars={}, @uuid="{59d9af2a-4401-4b38-ad74-b5c6c6b45a81}", @name="d1">
|
73
|
+
```
|
74
|
+
|
75
|
+
Find VM by name and start it
|
76
|
+
-----
|
77
|
+
``` ruby
|
78
|
+
>> vm2 = VBOX::VM.find 'd14'
|
79
|
+
>> vm2.start!
|
80
|
+
[.] $DISPLAY is not set, assuming --headless
|
81
|
+
Waiting for VM "59d9af2a-4401-4b38-ad74-b5c6c6b45a81" to power on...
|
82
|
+
VM "59d9af2a-4401-4b38-ad74-b5c6c6b45a81" has been successfully started.
|
83
|
+
=> true
|
84
|
+
```
|
85
|
+
|
86
|
+
Stop VM and destroy it (delete all its files)
|
87
|
+
-----
|
88
|
+
``` ruby
|
89
|
+
>> vm2 = VBOX::VM.find 'd14'
|
90
|
+
>> vm2.poweroff!
|
91
|
+
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
|
92
|
+
=> true
|
93
|
+
>> vm2.destroy!
|
94
|
+
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
|
95
|
+
=> true
|
96
|
+
>> vm2 = VBOX::VM.find 'd14'
|
97
|
+
=> nil
|
98
|
+
```
|
99
|
+
|
100
|
+
Calculate total disk space occupied by all VMs
|
101
|
+
-----
|
102
|
+
``` ruby
|
103
|
+
>> VBOX::VM.all.map(&:dir_size).inject(&:+)
|
104
|
+
=> 20271
|
105
|
+
```
|
106
|
+
|
107
|
+
Show all VMs sorted by directory size in reverse order
|
108
|
+
-----
|
109
|
+
``` ruby
|
110
|
+
>> VBOX::VM.all.sort_by(&:dir_size).reverse.each{ |vm| printf "%5d %s\n", vm.dir_size, vm.name }
|
111
|
+
9175 xp
|
112
|
+
5336 rwthCTF2012 vulnbox final
|
113
|
+
2962 ubuntu 12.04.1
|
114
|
+
2184 d0
|
115
|
+
109 u2
|
116
|
+
87 u1
|
117
|
+
```
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/lib/vbox/cli.rb
CHANGED
@@ -11,22 +11,62 @@ module VBOX
|
|
11
11
|
@argv = argv
|
12
12
|
end
|
13
13
|
|
14
|
+
def _join_by_width words, params = {}
|
15
|
+
params[:max_length] ||= 30
|
16
|
+
params[:separator] ||= ", "
|
17
|
+
params[:newline] ||= "\n"
|
18
|
+
lines = []
|
19
|
+
line = []
|
20
|
+
words.each do |word|
|
21
|
+
if (line+[word]).join(params[:separator]).size > params[:max_length]
|
22
|
+
lines << line.join(params[:separator])
|
23
|
+
line = []
|
24
|
+
end
|
25
|
+
line << word
|
26
|
+
end
|
27
|
+
lines << line.join(params[:separator]) unless line.empty?
|
28
|
+
lines.join params[:newline]
|
29
|
+
end
|
30
|
+
|
14
31
|
def banner
|
15
|
-
bname = File.basename(
|
32
|
+
bname = File.basename($0)
|
16
33
|
r = []
|
17
|
-
r <<
|
18
|
-
r <<
|
19
|
-
r <<
|
20
|
-
r <<
|
21
|
-
r <<
|
22
|
-
|
23
|
-
r <<
|
24
|
-
r <<
|
25
|
-
(COMMANDS+['snapshots']).sort.each do |c|
|
26
|
-
r <<
|
27
|
-
end
|
28
|
-
r <<
|
29
|
-
r <<
|
34
|
+
r << "USAGE:"
|
35
|
+
r << "\t#{bname} [options] - list VMs"
|
36
|
+
r << "\t#{bname} [options] <vm_name> - show VM params"
|
37
|
+
r << "\t#{bname} [options] <vm_name> <param>=<value> - change VM params (name, cpus, usb, etc)"
|
38
|
+
r << "\t#{bname} [options] <vm_name> <command> - make some action (start, reset, etc) on VM"
|
39
|
+
|
40
|
+
r << ""
|
41
|
+
r << "COMMANDS:"
|
42
|
+
# (COMMANDS+['snapshots']).sort.each do |c|
|
43
|
+
# r << "\t#{c}"
|
44
|
+
# end
|
45
|
+
r << "\t" + _join_by_width(COMMANDS+['snapshots'], newline: ",\n\t", max_length: 64 )
|
46
|
+
r << ""
|
47
|
+
r << "OPTIONS:"
|
48
|
+
r.join("\n")
|
49
|
+
end
|
50
|
+
|
51
|
+
def examples
|
52
|
+
bname = File.basename($0)
|
53
|
+
space = " "*bname.size
|
54
|
+
r = []
|
55
|
+
r << "EXAMPLES:"
|
56
|
+
r << %Q{\t#{bname} -v - list VMs with memory and dir sizes}
|
57
|
+
r << %Q{\t#{bname} "d{1-10}" list - list only VMs named 'd1','d2','d3',...,'d10'}
|
58
|
+
r << %Q{\t#{bname} "test*" start - start VMs which name starts with 'test'}
|
59
|
+
r << %Q{\t#{bname} "v[ace]" cpus=2 - set 'number of cpus'=2 on VMs named 'va','vc','ve'}
|
60
|
+
r << %Q{\t#{bname} d0 - list all parameters of VM named 'd0'}
|
61
|
+
r << %Q{\t#{bname} d0 clone -c 10 -S last - make 10 new linked clones of vm 'd0' using the}
|
62
|
+
r << %Q{\t#{space} latest hdd snapshot, if any}
|
63
|
+
r << %Q{\t#{bname} d0 clone -c 10 -S new - make ONE new shapshot of VM 'd0' and then make}
|
64
|
+
r << %Q{\t#{space} 10 new clones linked to this snapshot}
|
65
|
+
r << %Q{\t#{bname} "tmp?" delete - try to destroy all VMs which name is 4 letters long}
|
66
|
+
r << %Q{\t#{space} and starts with 'tmp'}
|
67
|
+
r << %Q{\t#{bname} ae340207-f472-4d63-80e7-855fca6808cb}
|
68
|
+
r << %Q{\t#{space} - list all parameters of VM with this GUID}
|
69
|
+
r << %Q{\t#{bname} --no-glob "*wtf?!*" rm - destroy VM which name is '*wtf?!*'}
|
30
70
|
r.join("\n")
|
31
71
|
end
|
32
72
|
|
@@ -34,8 +74,9 @@ module VBOX
|
|
34
74
|
@options = { :verbose => 0 }
|
35
75
|
optparser = OptionParser.new do |opts|
|
36
76
|
opts.banner = banner
|
77
|
+
opts.summary_indent = "\t"
|
37
78
|
|
38
|
-
opts.on "-
|
79
|
+
opts.on "-g", "--[no-]glob",
|
39
80
|
"(default: auto) assume <vm_name> is a wildcard,",
|
40
81
|
"and run on multiple VMs.",
|
41
82
|
"All glob(7) patterns like *,?,[a-z] are supported",
|
@@ -53,7 +94,7 @@ module VBOX
|
|
53
94
|
@options[:clones] = x
|
54
95
|
end
|
55
96
|
a = 'new last take make'.split.map{ |x| [x, x.upcase] }.flatten
|
56
|
-
opts.on "-
|
97
|
+
opts.on "-S", "--snapshot MODE", a, "clone: use LAST shapshot or make NEW" do |x|
|
57
98
|
@options[:snapshot] = x.downcase
|
58
99
|
end
|
59
100
|
opts.on "-H", "--headless", "start: start VM in headless mode" do
|
@@ -64,7 +105,7 @@ module VBOX
|
|
64
105
|
exit
|
65
106
|
end
|
66
107
|
end
|
67
|
-
@help = optparser.help
|
108
|
+
@help = optparser.help + "\n" + examples
|
68
109
|
@argv = optparser.parse(@argv)
|
69
110
|
|
70
111
|
# disable glob matching if first arg is a UUID
|
data/lib/vbox/cmdlineapi.rb
CHANGED
data/spec/vm_spec.rb
CHANGED
@@ -36,6 +36,11 @@ describe "VBOX::VM" do
|
|
36
36
|
vm = VBOX::VM.send(method, "{#{TEST_VM_UUID}}")
|
37
37
|
vm.should be_instance_of(VBOX::VM)
|
38
38
|
end
|
39
|
+
|
40
|
+
it "finds nothing" do
|
41
|
+
vm = VBOX::VM.send(method, "blah-blah-blah-unexistant-vm-#{rand}-#{rand}-#{rand}")
|
42
|
+
vm.should be_nil
|
43
|
+
end
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
data/vbox-ng.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vbox-ng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -118,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
118
|
version: '0'
|
119
119
|
segments:
|
120
120
|
- 0
|
121
|
-
hash: -
|
121
|
+
hash: -3650103115613908891
|
122
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
123
|
none: false
|
124
124
|
requirements:
|