vbox 0.0.4
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/.gitignore +14 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +68 -0
- data/README.md +5 -0
- data/Rakefile +91 -0
- data/bin/vbox +73 -0
- data/lib/java/README.txt +5 -0
- data/lib/java/dir2floppy.jar +0 -0
- data/lib/java/dir2floppy.java +134 -0
- data/lib/vagrant_init.rb +6 -0
- data/lib/vbox.rb +2 -0
- data/lib/vbox/command.rb +82 -0
- data/lib/vbox/config.rb +5 -0
- data/lib/vbox/export.rb +65 -0
- data/lib/vbox/scancode.rb +208 -0
- data/lib/vbox/session.rb +893 -0
- data/lib/vbox/shell.rb +54 -0
- data/lib/vbox/ssh.rb +193 -0
- data/lib/vbox/transaction.rb +122 -0
- data/lib/vbox/utils.rb +26 -0
- data/lib/vbox/version.rb +3 -0
- data/lib/vbox/web.rb +48 -0
- data/templates/CentOS-5.7-i386-netboot/definition.rb +16 -0
- data/templates/CentOS-5.7-i386-netboot/ks.cfg +45 -0
- data/templates/CentOS-5.7-i386-netboot/postinstall.sh +53 -0
- data/templates/CentOS-5.7-x86_64-netboot/definition.rb +16 -0
- data/templates/CentOS-5.7-x86_64-netboot/ks.cfg +45 -0
- data/templates/CentOS-5.7-x86_64-netboot/postinstall.sh +60 -0
- data/templates/CentOS-6.0-i386-netboot/definition.rb +16 -0
- data/templates/CentOS-6.0-i386-netboot/ks.cfg +52 -0
- data/templates/CentOS-6.0-i386-netboot/postinstall.sh +30 -0
- data/templates/CentOS-6.0-i386/definition.rb +17 -0
- data/templates/CentOS-6.0-i386/ks.cfg +47 -0
- data/templates/CentOS-6.0-i386/postinstall.sh +48 -0
- data/templates/CentOS-6.0-x86_64-netboot/definition.rb +16 -0
- data/templates/CentOS-6.0-x86_64-netboot/ks.cfg +52 -0
- data/templates/CentOS-6.0-x86_64-netboot/postinstall.sh +30 -0
- data/templates/CentOS-6.0-x86_64/definition.rb +17 -0
- data/templates/CentOS-6.0-x86_64/ks.cfg +47 -0
- data/templates/CentOS-6.0-x86_64/postinstall.sh +48 -0
- data/templates/Debian-6.0.3-amd64-netboot/definition.rb +42 -0
- data/templates/Debian-6.0.3-amd64-netboot/postinstall.sh +80 -0
- data/templates/Debian-6.0.3-amd64-netboot/preseed.cfg +42 -0
- data/templates/Debian-6.0.3-i386-netboot/definition.rb +44 -0
- data/templates/Debian-6.0.3-i386-netboot/postinstall.sh +80 -0
- data/templates/Debian-6.0.3-i386-netboot/preseed.cfg +42 -0
- data/templates/Fedora-15-i386-netboot/definition.rb +17 -0
- data/templates/Fedora-15-i386-netboot/ks.cfg +82 -0
- data/templates/Fedora-15-i386-netboot/postinstall.sh +18 -0
- data/templates/Fedora-15-i386/definition.rb +17 -0
- data/templates/Fedora-15-i386/ks.cfg +64 -0
- data/templates/Fedora-15-i386/postinstall.sh +33 -0
- data/templates/Fedora-15-x86_64-netboot/definition.rb +29 -0
- data/templates/Fedora-15-x86_64-netboot/ks.cfg +64 -0
- data/templates/Fedora-15-x86_64-netboot/postinstall.sh +33 -0
- data/templates/Fedora-15-x86_64/definition.rb +17 -0
- data/templates/Fedora-15-x86_64/ks.cfg +64 -0
- data/templates/Fedora-15-x86_64/postinstall.sh +33 -0
- data/templates/Sysrescuecd-2.0.0-experimental/autorun0 +3 -0
- data/templates/Sysrescuecd-2.0.0-experimental/definition.rb +20 -0
- data/templates/archlinux-i386-netboot/aif.cfg +34 -0
- data/templates/archlinux-i386-netboot/definition.rb +29 -0
- data/templates/archlinux-i386-netboot/postinstall.sh +87 -0
- data/templates/archlinux-i386-netboot/postinstall2.sh +28 -0
- data/templates/archlinux-i386/aif.cfg +33 -0
- data/templates/archlinux-i386/definition.rb +29 -0
- data/templates/archlinux-i386/postinstall.sh +106 -0
- data/templates/archlinux-x86_64-netboot/aif.cfg +34 -0
- data/templates/archlinux-x86_64-netboot/definition.rb +29 -0
- data/templates/archlinux-x86_64-netboot/postinstall.sh +90 -0
- data/templates/archlinux-x86_64-netboot/postinstall2.sh +28 -0
- data/templates/archlinux-x86_64/aif.cfg +33 -0
- data/templates/archlinux-x86_64/definition.rb +29 -0
- data/templates/archlinux-x86_64/postinstall.sh +90 -0
- data/templates/archlinux-x86_64/postinstall2.sh +38 -0
- data/templates/freebsd-8.2-experimental/definition.rb +19 -0
- data/templates/freebsd-8.2-experimental/postinstall.sh +191 -0
- data/templates/freebsd-8.2-pcbsd-i386-netboot/definition.rb +35 -0
- data/templates/freebsd-8.2-pcbsd-i386-netboot/pcinstall.fbg.cfg +58 -0
- data/templates/freebsd-8.2-pcbsd-i386-netboot/postinstall.sh +93 -0
- data/templates/freebsd-8.2-pcbsd-i386/definition.rb +31 -0
- data/templates/freebsd-8.2-pcbsd-i386/pcinstall.fbg.cfg +57 -0
- data/templates/freebsd-8.2-pcbsd-i386/postinstall.sh +93 -0
- data/templates/gentoo-latest-i386-experimental/definition.rb +29 -0
- data/templates/gentoo-latest-i386-experimental/postinstall.sh +184 -0
- data/templates/openSUSE-11.4-DVD-i586/autoinst_de.xml +1284 -0
- data/templates/openSUSE-11.4-DVD-i586/autoinst_en.xml +1284 -0
- data/templates/openSUSE-11.4-DVD-i586/definition.rb +28 -0
- data/templates/openSUSE-11.4-DVD-i586/postinstall.sh +43 -0
- data/templates/openSUSE-11.4-DVD-x86_64/autoinst_de.xml +1459 -0
- data/templates/openSUSE-11.4-DVD-x86_64/autoinst_en.xml +1459 -0
- data/templates/openSUSE-11.4-DVD-x86_64/definition.rb +28 -0
- data/templates/openSUSE-11.4-DVD-x86_64/postinstall.sh +43 -0
- data/templates/openSUSE-11.4-NET-i586/autoinst_de.xml +1278 -0
- data/templates/openSUSE-11.4-NET-i586/autoinst_en.xml +1278 -0
- data/templates/openSUSE-11.4-NET-i586/definition.rb +28 -0
- data/templates/openSUSE-11.4-NET-i586/postinstall.sh +43 -0
- data/templates/openSUSE-11.4-NET-x86_64/autoinst_de.xml +1453 -0
- data/templates/openSUSE-11.4-NET-x86_64/autoinst_en.xml +1453 -0
- data/templates/openSUSE-11.4-NET-x86_64/definition.rb +28 -0
- data/templates/openSUSE-11.4-NET-x86_64/postinstall.sh +43 -0
- data/templates/solaris-11-express-i386/auto_install/ai.dtd +58 -0
- data/templates/solaris-11-express-i386/auto_install/ai_manifest.xml +241 -0
- data/templates/solaris-11-express-i386/auto_install/configuration.dtd +44 -0
- data/templates/solaris-11-express-i386/auto_install/default.xml +124 -0
- data/templates/solaris-11-express-i386/auto_install/default.xml.orig +124 -0
- data/templates/solaris-11-express-i386/auto_install/sc_profiles/static_network.xml +105 -0
- data/templates/solaris-11-express-i386/auto_install/software.dtd +105 -0
- data/templates/solaris-11-express-i386/auto_install/target.dtd +196 -0
- data/templates/solaris-11-express-i386/default.xml +121 -0
- data/templates/solaris-11-express-i386/definition.rb +65 -0
- data/templates/solaris-11-express-i386/postinstall.sh +98 -0
- data/templates/ubuntu-10.04.3-server-amd64/definition.rb +54 -0
- data/templates/ubuntu-10.04.3-server-amd64/postinstall.sh +90 -0
- data/templates/ubuntu-10.04.3-server-amd64/preseed.cfg +87 -0
- data/templates/ubuntu-10.04.3-server-i386/definition.rb +24 -0
- data/templates/ubuntu-10.04.3-server-i386/postinstall.sh +91 -0
- data/templates/ubuntu-10.04.3-server-i386/preseed.cfg +87 -0
- data/templates/ubuntu-11.10-server-amd64/definition.rb +35 -0
- data/templates/ubuntu-11.10-server-amd64/postinstall.sh +90 -0
- data/templates/ubuntu-11.10-server-amd64/preseed.cfg +87 -0
- data/templates/ubuntu-11.10-server-i386/definition.rb +35 -0
- data/templates/ubuntu-11.10-server-i386/postinstall.sh +90 -0
- data/templates/ubuntu-11.10-server-i386/preseed.cfg +87 -0
- data/validation/features/steps/ssh_steps.rb +169 -0
- data/validation/support/env.rb +1 -0
- data/validation/vagrant-private.key +27 -0
- data/validation/vagrant.feature +52 -0
- data/validation/vagrant.pub +1 -0
- data/vbox.gemspec +32 -0
- metadata +338 -0
data/lib/vbox/shell.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#require 'open4'
|
|
2
|
+
|
|
3
|
+
module Vbox
|
|
4
|
+
class Shell
|
|
5
|
+
|
|
6
|
+
def self.execute2(command,options = {})
|
|
7
|
+
|
|
8
|
+
IO.popen("#{command}") { |f| print f }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
#pty allows you to gradually see the output of a local command
|
|
12
|
+
#http://www.shanison.com/?p=415
|
|
13
|
+
def self.execute(command, options = {} )
|
|
14
|
+
require "pty"
|
|
15
|
+
begin
|
|
16
|
+
PTY.spawn( command ) do |r, w, pid|
|
|
17
|
+
begin
|
|
18
|
+
r.each { }
|
|
19
|
+
#r.each { |line| print line;}
|
|
20
|
+
|
|
21
|
+
rescue Errno::EIO
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
rescue PTY::ChildExited => e
|
|
25
|
+
puts "The child process exited!"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#occassinally fails with 'no child processes
|
|
30
|
+
def self.execute3(command, options = {} )
|
|
31
|
+
defaults= { :port => "22", :exitcode => "0", :user => "root"}
|
|
32
|
+
options=defaults.merge(options)
|
|
33
|
+
|
|
34
|
+
status = POpen4::popen4(command) do |stdout,stderr,stdin|
|
|
35
|
+
stdout.each do |line|
|
|
36
|
+
puts line
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@status=status.to_i
|
|
41
|
+
|
|
42
|
+
if (@status.to_s != options[:exitcode] )
|
|
43
|
+
if (options[:exitcode]=="*")
|
|
44
|
+
#its a test so we don't need to worry
|
|
45
|
+
else
|
|
46
|
+
raise "Exitcode was not what we expected"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end #Class
|
|
54
|
+
end #Module
|
data/lib/vbox/ssh.rb
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
module Vbox
|
|
2
|
+
class Ssh
|
|
3
|
+
|
|
4
|
+
def self.when_ssh_login_works(ip="localhost", options = { } , &block)
|
|
5
|
+
|
|
6
|
+
defaults={ :port => '22', :timeout => 200 , :user => 'vagrant', :password => 'vagrant'}
|
|
7
|
+
|
|
8
|
+
options=defaults.merge(options)
|
|
9
|
+
|
|
10
|
+
puts
|
|
11
|
+
puts "Waiting for ssh login with user #{options[:user]} to sshd on port => #{options[:port]} to work"
|
|
12
|
+
|
|
13
|
+
begin
|
|
14
|
+
Timeout::timeout(options[:timeout]) do
|
|
15
|
+
connected=false
|
|
16
|
+
@key_auth_tried = false
|
|
17
|
+
ssh_options = { :port => options[:port] , :password => options[:password], :paranoid => false, :timeout => options[:timeout] }
|
|
18
|
+
while !connected do
|
|
19
|
+
begin
|
|
20
|
+
print "."
|
|
21
|
+
Net::SSH.start(ip, options[:user], ssh_options) do |ssh|
|
|
22
|
+
block.call(ip);
|
|
23
|
+
puts ""
|
|
24
|
+
return true
|
|
25
|
+
end
|
|
26
|
+
rescue Net::SSH::AuthenticationFailed
|
|
27
|
+
options[:keys] = File.join(File.dirname(__FILE__),'./../../validation/vagrant')
|
|
28
|
+
options.delete(:password)
|
|
29
|
+
ssh_options = options
|
|
30
|
+
if @key_auth_tried
|
|
31
|
+
raise
|
|
32
|
+
else
|
|
33
|
+
@key_auth_tried = true
|
|
34
|
+
retry
|
|
35
|
+
end
|
|
36
|
+
rescue Net::SSH::Disconnect,Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNABORTED, Errno::ECONNRESET, Errno::ENETUNREACH
|
|
37
|
+
sleep 5
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
rescue Timeout::Error
|
|
42
|
+
raise 'ssh timeout'
|
|
43
|
+
end
|
|
44
|
+
puts ""
|
|
45
|
+
return false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def self.transfer_file(host,filename,destination = '.' , options = {})
|
|
50
|
+
|
|
51
|
+
Net::SSH.start( host,options[:user],options ) do |ssh|
|
|
52
|
+
puts "Transferring #{filename} to #{destination} "
|
|
53
|
+
ssh.scp.upload!( filename, destination ) do |ch, name, sent, total|
|
|
54
|
+
# print "\r#{destination}: #{(sent.to_f * 100 / total.to_f).to_i}%"
|
|
55
|
+
print "."
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
puts
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
#we need to try the actual login because vbox gives us a connect
|
|
64
|
+
#after the machine boots
|
|
65
|
+
def self.execute_when_tcp_available(ip="localhost", options = { } , &block)
|
|
66
|
+
|
|
67
|
+
defaults={ :port => 22, :timeout => 2 , :pollrate => 5}
|
|
68
|
+
|
|
69
|
+
options=defaults.merge(options)
|
|
70
|
+
|
|
71
|
+
begin
|
|
72
|
+
Timeout::timeout(options[:timeout]) do
|
|
73
|
+
connected=false
|
|
74
|
+
while !connected do
|
|
75
|
+
begin
|
|
76
|
+
puts "trying connection"
|
|
77
|
+
s = TCPSocket.new(ip, options[:port])
|
|
78
|
+
s.close
|
|
79
|
+
block.call(ip);
|
|
80
|
+
return true
|
|
81
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
|
82
|
+
sleep options[:pollrate]
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
rescue Timeout::Error
|
|
87
|
+
raise 'timeout connecting to port'
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
return false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def self.execute(host,command, options = { :progress => "on"} )
|
|
94
|
+
defaults= { :port => "22", :exitcode => "0", :user => "root"}
|
|
95
|
+
options=defaults.merge(options)
|
|
96
|
+
@pid=""
|
|
97
|
+
@stdin=command
|
|
98
|
+
@stdout=""
|
|
99
|
+
@stderr=""
|
|
100
|
+
@status=-99999
|
|
101
|
+
|
|
102
|
+
puts "Executing command: #{command}"
|
|
103
|
+
|
|
104
|
+
@key_auth_tried = false
|
|
105
|
+
ssh_options = { :port => options[:port], :password => options[:password], :paranoid => false}
|
|
106
|
+
# ssh_options[:verbose] => :debug
|
|
107
|
+
begin
|
|
108
|
+
Net::SSH.start(host, options[:user], ssh_options) do |ssh|
|
|
109
|
+
|
|
110
|
+
# open a new channel and configure a minimal set of callbacks, then run
|
|
111
|
+
# the event loop until the channel finishes (closes)
|
|
112
|
+
channel = ssh.open_channel do |ch|
|
|
113
|
+
|
|
114
|
+
#request pty for sudo stuff and so
|
|
115
|
+
ch.request_pty do |ch, success|
|
|
116
|
+
raise "Error requesting pty" unless success
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
ch.exec "#{command}" do |ch, success|
|
|
121
|
+
raise "could not execute command" unless success
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# "on_data" is called when the process writes something to stdout
|
|
126
|
+
ch.on_data do |c, data|
|
|
127
|
+
@stdout+=data
|
|
128
|
+
|
|
129
|
+
print data
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# "on_extended_data" is called when the process writes something to stderr
|
|
134
|
+
ch.on_extended_data do |c, type, data|
|
|
135
|
+
@stderr+=data
|
|
136
|
+
|
|
137
|
+
print data
|
|
138
|
+
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
#exit code
|
|
142
|
+
#http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/a806b0f5dae4e1e2
|
|
143
|
+
channel.on_request("exit-status") do |ch, data|
|
|
144
|
+
exit_code = data.read_long
|
|
145
|
+
@status=exit_code
|
|
146
|
+
if exit_code > 0
|
|
147
|
+
puts "ERROR: exit code #{exit_code}"
|
|
148
|
+
else
|
|
149
|
+
#puts "Successfully executed"
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
channel.on_request("exit-signal") do |ch, data|
|
|
154
|
+
puts "SIGNAL: #{data.read_long}"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
ch.on_close {
|
|
158
|
+
#puts "done!"
|
|
159
|
+
}
|
|
160
|
+
#status=ch.exec "echo $?"
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
channel.wait
|
|
164
|
+
end
|
|
165
|
+
rescue Net::SSH::AuthenticationFailed
|
|
166
|
+
ssh_options[:keys] = Array.new([File.join(File.dirname(__FILE__),'./../../validation/vagrant')])
|
|
167
|
+
ssh_options.delete(:password)
|
|
168
|
+
ssh_options[:auth_methods] = ['publickey']
|
|
169
|
+
if @key_auth_tried
|
|
170
|
+
raise
|
|
171
|
+
else
|
|
172
|
+
@key_auth_tried = true
|
|
173
|
+
retry
|
|
174
|
+
end
|
|
175
|
+
rescue Net::SSH::Disconnect, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNABORTED, Errno::ECONNRESET, Errno::ENETUNREACH
|
|
176
|
+
sleep 1
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
if (@status.to_s != options[:exitcode] )
|
|
180
|
+
if (options[:exitcode]=="*")
|
|
181
|
+
#its a test so we don't need to worry
|
|
182
|
+
else
|
|
183
|
+
raise "Exitcode was not what we expected"
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
end #Class
|
|
193
|
+
end #Module
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
module Vbox
|
|
2
|
+
class Transaction
|
|
3
|
+
|
|
4
|
+
def transaction(name,params, &block)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def transaction2(name,options= { :checksum => "nochecksum"}, &block)
|
|
8
|
+
if snapshot_exists(@vmname,name+"-"+options[:checksum])
|
|
9
|
+
load_snapshot_vmachine(@vmname,name+"-"+options[:checksum])
|
|
10
|
+
else
|
|
11
|
+
if snapshot_version_exists(@vmname,name)
|
|
12
|
+
rollback_snapshot(@vmname,name)
|
|
13
|
+
#rollback to snapshot prior to this one
|
|
14
|
+
end
|
|
15
|
+
yield
|
|
16
|
+
create_snapshot_vmachine(@vmname,name+"-"+options[:checksum])
|
|
17
|
+
end
|
|
18
|
+
#end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.remove_snapshot_vmachine(vmname,snapname)
|
|
22
|
+
@vboxcmd=Vbox::Session.determine_vboxcmd
|
|
23
|
+
|
|
24
|
+
Vbox::Shell.execute("#{@vboxcmd} snapshot '#{vmname}' delete '#{snapname}'")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.create_snapshot_vmachine(vmname,snapname)
|
|
28
|
+
@vboxcmd=Vbox::Session.determine_vboxcmd
|
|
29
|
+
|
|
30
|
+
Vbox::Shell.execute("#{@vboxcmd} snapshot '#{vmname}' take '#{snapname}'")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.load_snapshot_vmachine(vmname,snapname)
|
|
34
|
+
@vboxcmd=Vbox::Session.determine_vboxcmd
|
|
35
|
+
|
|
36
|
+
#if it running , shutdown first
|
|
37
|
+
if (state_vmachine(vmname)=="running")
|
|
38
|
+
stop_vmachine(vmname)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
Vbox::Shell.execute("#{@vboxcmd} snapshot '#{vmname}' restore '#{snapname}'")
|
|
42
|
+
#sometimes it takes some time to shutdown
|
|
43
|
+
sleep 2
|
|
44
|
+
Vbox::Shell.execute("#{@vboxcmd} startvm '#{vmname}'")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.snapshot_exists(vmname,snapname)
|
|
48
|
+
list_snapshots(vmname).each { |name|
|
|
49
|
+
if (name==snapname) then
|
|
50
|
+
return true
|
|
51
|
+
end
|
|
52
|
+
}
|
|
53
|
+
return false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.snapshot_version_exists(vmname,snapname)
|
|
57
|
+
list_snapshots(vmname).each { |name|
|
|
58
|
+
if name.match(/^#{snapname}-/) then
|
|
59
|
+
return true
|
|
60
|
+
end
|
|
61
|
+
}
|
|
62
|
+
return false
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.rollback_snapshot(vmname,snapname)
|
|
66
|
+
delete_flag=false
|
|
67
|
+
@vboxcmd=Vbox::Session.determine_vboxcmd
|
|
68
|
+
|
|
69
|
+
savestate_recover=false
|
|
70
|
+
if (state_vmachine(vmname)=="running")
|
|
71
|
+
Vbox::Shell.execute("#{@vboxcmd} controlvm '#{vmname}' savestate")
|
|
72
|
+
savestate_recover=true
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
list_snapshots(vmname).each { |name|
|
|
76
|
+
if name.match(/^#{snapname}-/) then
|
|
77
|
+
delete_flag=true
|
|
78
|
+
end
|
|
79
|
+
if (delete_flag) then
|
|
80
|
+
remove_snapshot_vmachine(vmname,name)
|
|
81
|
+
sleep 1
|
|
82
|
+
end
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
sleep 2
|
|
87
|
+
|
|
88
|
+
Vbox::Shell.execute("#{@vboxcmd} startvm '#{vmname}'")
|
|
89
|
+
|
|
90
|
+
if (savestate_recover)
|
|
91
|
+
#Recovering from savestate nukes the network! This trick seem to work
|
|
92
|
+
#Also within the vm /etc/init.d/networking restart , but that is OS specific
|
|
93
|
+
#http://www.virtualbox.org/ticket/5666
|
|
94
|
+
#http://www.virtualbox.org/ticket/5654
|
|
95
|
+
#This is supposed to be fixed: http://www.virtualbox.org/changeset/25205 but alas
|
|
96
|
+
Vbox::Shell.execute("#{@vboxcmd} controlvm '#{vmname}' nic1 nat")
|
|
97
|
+
Vbox::Shell.execute("#{@vboxcmd} controlvm '#{vmname}' setlinkstate1 off")
|
|
98
|
+
Vbox::Shell.execute("#{@vboxcmd} controlvm '#{vmname}' setlinkstate1 on")
|
|
99
|
+
sleep 2
|
|
100
|
+
|
|
101
|
+
#hmmm, virtualbox => when recovering from a restore , it looses the nat settings!!! So we need to do this again!!
|
|
102
|
+
#thebox.ssh_enable_vmachine({:hostport => host_port , :guestport => 22} )
|
|
103
|
+
#http://www.virtualbox.org/changeset/25402
|
|
104
|
+
#[25402]: NAT: re-establish port-forwarding after savestate / restore state
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def self.list_snapshots(vmname)
|
|
112
|
+
@vboxcmd=Vbox::Session.determine_vboxcmd
|
|
113
|
+
|
|
114
|
+
snapshotresult=Vbox::Shell.execute("#{@vboxcmd} showvminfo --machinereadable '#{vmname}' |grep ^SnapshotName| cut -d '=' -f 2").stdout
|
|
115
|
+
snapshotlist=snapshotresult.gsub(/\"/,'').split(/\n/)
|
|
116
|
+
return snapshotlist
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
data/lib/vbox/utils.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'timeout'
|
|
3
|
+
|
|
4
|
+
module Vbox
|
|
5
|
+
class Utils
|
|
6
|
+
|
|
7
|
+
def self.is_port_open?(ip, port)
|
|
8
|
+
begin
|
|
9
|
+
Timeout::timeout(1) do
|
|
10
|
+
begin
|
|
11
|
+
s = TCPSocket.new(ip, port)
|
|
12
|
+
s.close
|
|
13
|
+
return true
|
|
14
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
|
15
|
+
return false
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
rescue Timeout::Error
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
return false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
end #Class
|
|
26
|
+
end #Module
|
data/lib/vbox/version.rb
ADDED
data/lib/vbox/web.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Vbox
|
|
2
|
+
class Web
|
|
3
|
+
|
|
4
|
+
require 'webrick'
|
|
5
|
+
include WEBrick
|
|
6
|
+
|
|
7
|
+
class FileServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
8
|
+
|
|
9
|
+
def initialize(server,localfile)
|
|
10
|
+
super(server)
|
|
11
|
+
@server=server
|
|
12
|
+
@localfile=localfile
|
|
13
|
+
end
|
|
14
|
+
def do_GET(request,response)
|
|
15
|
+
response['Content-Type']='text/plain'
|
|
16
|
+
response.status = 200
|
|
17
|
+
puts "Serving file #{@localfile}"
|
|
18
|
+
displayfile=File.open(@localfile,'r')
|
|
19
|
+
content=displayfile.read()
|
|
20
|
+
response.body=content
|
|
21
|
+
#If we shut too fast it might not get the complete file
|
|
22
|
+
sleep 2
|
|
23
|
+
@server.shutdown
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.wait_for_request(filename,options={:timeout => 10, :web_dir => "", :port => 7125})
|
|
28
|
+
|
|
29
|
+
webrick_logger=WEBrick::Log.new("/dev/null", WEBrick::Log::INFO)
|
|
30
|
+
|
|
31
|
+
web_dir=options[:web_dir]
|
|
32
|
+
filename=filename
|
|
33
|
+
s= HTTPServer.new(
|
|
34
|
+
:Port => options[:port],
|
|
35
|
+
:Logger => webrick_logger,
|
|
36
|
+
:AccessLog => webrick_logger
|
|
37
|
+
)
|
|
38
|
+
s.mount("/#{filename}", FileServlet,File.join(web_dir,filename))
|
|
39
|
+
trap("INT"){
|
|
40
|
+
s.shutdown
|
|
41
|
+
puts "Stopping webserver"
|
|
42
|
+
exit
|
|
43
|
+
}
|
|
44
|
+
s.start
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|