lab 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,180 @@
1
+ ##
2
+ ## $Id$
3
+ ##
4
+
5
+ #
6
+ # !!WARNING!! - All drivers are expected to filter input before running
7
+ # anything based on it. This is particularly important in the case
8
+ # of the drivers which wrap a command line to provide functionality.
9
+ #
10
+
11
+ module Lab
12
+ module Drivers
13
+ class VmDriver
14
+
15
+ attr_accessor :vmid
16
+ attr_accessor :location
17
+ attr_accessor :os
18
+ attr_accessor :tools
19
+ attr_accessor :credentials
20
+
21
+ def initialize(config)
22
+
23
+ @vmid = filter_command(config["vmid"].to_s)
24
+ @location = filter_command(config["location"])
25
+ @credentials = config["credentials"] || []
26
+ @tools = filter_input(config["tools"])
27
+ @os = filter_input(config["os"])
28
+ @hostname = filter_input(config["hostname"]) || filter_input(config["vmid"].to_s)
29
+
30
+ # Currently only implemented for the first set
31
+ if @credentials.count > 0
32
+ @vm_user = filter_input(@credentials[0]['user'])
33
+ @vm_pass = filter_input(@credentials[0]['pass'])
34
+ @vm_keyfile = filter_input(@credentials[0]['keyfile'])
35
+ end
36
+ end
37
+
38
+ ## This interface must be implemented in a child driver class
39
+ ## #########################################################
40
+
41
+ def register
42
+ raise "Command not Implemented"
43
+ end
44
+
45
+ def unregister
46
+ raise "Command not Implemented"
47
+ end
48
+
49
+ def start
50
+ raise "Command not Implemented"
51
+ end
52
+
53
+ def stop
54
+ raise "Command not Implemented"
55
+ end
56
+
57
+ def suspend
58
+ raise "Command not Implemented"
59
+ end
60
+
61
+ def pause
62
+ raise "Command not Implemented"
63
+ end
64
+
65
+ def resume
66
+ raise "Command not Implemented"
67
+ end
68
+
69
+ def reset
70
+ raise "Command not Implemented"
71
+ end
72
+
73
+ def create_snapshot(snapshot)
74
+ raise "Command not Implemented"
75
+ end
76
+
77
+ def revert_snapshot(snapshot)
78
+ raise "Command not Implemented"
79
+ end
80
+
81
+ def delete_snapshot(snapshot)
82
+ raise "Command not Implemented"
83
+ end
84
+
85
+ def run_command(command)
86
+ raise "Command not Implemented"
87
+ end
88
+
89
+ def copy_from(from, to)
90
+ raise "Command not Implemented"
91
+ end
92
+
93
+ def copy_to(from, to)
94
+ raise "Command not Implemented"
95
+ end
96
+
97
+ def check_file_exists(file)
98
+ raise "Command not Implemented"
99
+ end
100
+
101
+ def create_directory(directory)
102
+ raise "Command not Implemented"
103
+ end
104
+
105
+ def cleanup
106
+ raise "Command not Implemented"
107
+ end
108
+
109
+ ## End Interface
110
+ ## #########################################################
111
+
112
+ private
113
+
114
+ def scp_to(local,remote)
115
+ #require 'net/scp'
116
+ #::Net::SCP.start(@hostname, @vm_user, :password => @vm_pass) do |scp|
117
+ # scp.upload!(from,to)
118
+ #end
119
+
120
+ system_command("scp #{local} #{@vm_user}@#{@hostname}:#{remote}")
121
+ end
122
+
123
+ def scp_from(local,remote)
124
+ #require 'net/scp'
125
+ # download a file from a remote server
126
+ #::Net::SCP.start(@hostname, @vm_user, :password => @vm_pass) do |scp|
127
+ # scp.download!(from,to)
128
+ #end
129
+
130
+ system_command("scp #{@vm_user}@#{@hostname}:#{remote} #{local}")
131
+
132
+ end
133
+
134
+ def ssh_exec(command)
135
+
136
+ ::Net::SSH.start(@hostname, @vm_user, :password => @vm_pass) do |ssh|
137
+ result = ssh.exec!(command)
138
+ end
139
+
140
+ `scp #{@vm_user}@#{@hostname} from to`
141
+ end
142
+
143
+ def filter_input(string)
144
+ return "" unless string # nil becomes empty string
145
+ return unless string.class == String # Allow other types unmodified
146
+
147
+ unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\):!]*$/.match string
148
+ raise "WARNING! Invalid character in: #{string}"
149
+ end
150
+
151
+ string
152
+ end
153
+
154
+ def filter_command(string)
155
+ return "" unless string # nil becomes empty string
156
+ return unless string.class == String # Allow other types unmodified
157
+
158
+ unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\)]*$/.match string
159
+ raise "WARNING! Invalid character in: #{string}"
160
+ end
161
+
162
+ string
163
+ end
164
+
165
+ # The only reason we don't filter here is because we need
166
+ # the ability to still run clean (controlled entirely by us)
167
+ # command lines.
168
+ def system_command(command)
169
+ #puts "DEBUG: system command #{command}"
170
+ system(command)
171
+ end
172
+
173
+
174
+ def remote_system_command(command)
175
+ system_command("ssh #{@user}@#{@host} \"#{command}\"")
176
+ end
177
+ end
178
+
179
+ end
180
+ end
@@ -0,0 +1,188 @@
1
+ require 'vm_driver'
2
+
3
+ ##
4
+ ## $Id$
5
+ ##
6
+
7
+ module Lab
8
+ module Drivers
9
+
10
+ class WorkstationDriver < VmDriver
11
+
12
+ def initialize(config)
13
+ super(config)
14
+
15
+ if !File.exist?(@location)
16
+ raise ArgumentError,"Couldn't find: #{@location}"
17
+ end
18
+ end
19
+
20
+ def start
21
+ system_command("vmrun -T ws start " + "\'#{@location}\' nogui")
22
+ end
23
+
24
+ def stop
25
+ system_command("vmrun -T ws stop " + "\'#{@location}\' nogui")
26
+ end
27
+
28
+ def suspend
29
+ system_command("vmrun -T ws suspend " + "\'#{@location}\' nogui")
30
+ end
31
+
32
+ def pause
33
+ system_command("vmrun -T ws pause " + "\'#{@location}\' nogui")
34
+ end
35
+
36
+ def reset
37
+ system_command("vmrun -T ws reset " + "\'#{@location}\' nogui")
38
+ end
39
+
40
+ def create_snapshot(snapshot)
41
+ snapshot = filter_input(snapshot)
42
+ system_command("vmrun -T ws snapshot " + "\'#{@location}\' \'#{snapshot}\' nogui")
43
+ end
44
+
45
+ def revert_snapshot(snapshot)
46
+ snapshot = filter_input(snapshot)
47
+ system_command("vmrun -T ws revertToSnapshot " + "\'#{@location}\' \'#{snapshot}\' nogui")
48
+ end
49
+
50
+ def delete_snapshot(snapshot)
51
+ snapshot = filter_input(snapshot)
52
+ system_command("vmrun -T ws deleteSnapshot " + "\'#{@location}\' \'#{snapshot}\' nogui" )
53
+ end
54
+
55
+ def run_command(command)
56
+
57
+ script_rand_name = rand(10000)
58
+
59
+ if @os == "windows"
60
+ local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.bat"
61
+ remote_tempfile_path = "C:\\\\lab_script_#{script_rand_name}.bat"
62
+ remote_run_command = remote_tempfile_path
63
+ else
64
+ local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
65
+ remote_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
66
+ remote_run_command = "/bin/sh #{remote_tempfile_path}"
67
+ end
68
+
69
+ # write out our script locally
70
+ File.open(local_tempfile_path, 'w') {|f| f.write(command) }
71
+
72
+ # we really can't filter command, so we're gonna stick it in a script
73
+ if @tools
74
+ # copy our local tempfile to the guest
75
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
76
+ "copyFileFromHostToGuest \'#{@location}\' \'#{local_tempfile_path}\'" +
77
+ " \'#{remote_tempfile_path}\' nogui"
78
+ system_command(vmrunstr)
79
+
80
+ # now run it on the guest
81
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
82
+ "runProgramInGuest \'#{@location}\' -noWait -activeWindow \'#{remote_run_command}\'"
83
+ system_command(vmrunstr)
84
+
85
+ ## CLEANUP
86
+ # delete it on the guest
87
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
88
+ "deleteFileInGuest \'#{@location}\' \'#{remote_tempfile_path}\'"
89
+ system_command(vmrunstr)
90
+
91
+ # delete it locally
92
+ local_delete_command = "rm #{local_tempfile_path}"
93
+ system_command(local_delete_command)
94
+ else
95
+ # since we can't copy easily w/o tools, let's just run it directly :/
96
+ if @os == "linux"
97
+
98
+ output_file = "/tmp/lab_command_output_#{rand(1000000)}"
99
+
100
+ scp_to(local_tempfile_path, remote_tempfile_path)
101
+ ssh_exec(remote_run_command + "> #{output_file}")
102
+ scp_from(output_file, output_file)
103
+
104
+ ssh_exec("rm #{output_file}")
105
+ ssh_exec("rm #{remote_tempfile_path}")
106
+
107
+ # Ghettohack!
108
+ string = File.open(output_file,"r").read
109
+ `rm #{output_file}`
110
+
111
+ else
112
+ raise "zomgwtfbbqnotools"
113
+ end
114
+ end
115
+ return string
116
+ end
117
+
118
+ def copy_from(from, to)
119
+ from = filter_input(from)
120
+ to = filter_input(to)
121
+ if @tools
122
+ vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' copyFileFromGuestToHost " +
123
+ "\'#{@location}\' \'#{from}\' \'#{to}\'"
124
+ else
125
+ scp_from(from, to)
126
+ end
127
+ system_command(vmrunstr)
128
+ end
129
+
130
+ def copy_to(from, to)
131
+ from = filter_input(from)
132
+ to = filter_input(to)
133
+ if @tools
134
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} copyFileFromHostToGuest " +
135
+ "\'#{@location}\' \'#{from}\' \'#{to}\'"
136
+ system_command(vmrunstr)
137
+ else
138
+ scp_to(from, to)
139
+ end
140
+ end
141
+
142
+ def check_file_exists(file)
143
+ file = filter_input(file)
144
+ if @tools
145
+ vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' fileExistsInGuest " +
146
+ "\'#{@location}\' \'#{file}\' "
147
+ system_command(vmrunstr)
148
+ else
149
+ raise "Unsupported"
150
+ end
151
+ end
152
+
153
+ def create_directory(directory)
154
+ directory = filter_input(directory)
155
+ if @tools
156
+ vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' createDirectoryInGuest " +
157
+ " \'#{@location}\' \'#{directory}\' "
158
+ system_command(vmrunstr)
159
+ else
160
+ raise "Unsupported"
161
+ end
162
+
163
+
164
+ end
165
+
166
+ def cleanup
167
+
168
+ end
169
+
170
+ def running?
171
+ ## Get running Vms
172
+ running = `vmrun list`
173
+ running_array = running.split("\n")
174
+ running_array.shift
175
+
176
+ running_array.each do |vmx|
177
+ if vmx.to_s == @location.to_s
178
+ return true
179
+ end
180
+ end
181
+
182
+ return false
183
+ end
184
+
185
+ end
186
+
187
+ end
188
+ end
@@ -0,0 +1,126 @@
1
+ require 'vm_driver'
2
+ ##
3
+ ## $Id$
4
+ ##
5
+
6
+ # This requires rhythmx's vixr driver from https://github.com/rhythmx/vixr
7
+ # and below that, the VIX api from vmware http://www.vmware.com/support/developer/vix-api/
8
+
9
+ module Lab
10
+ module Drivers
11
+
12
+ class WorkstationVixrDriver < VmDriver
13
+
14
+ attr_accessor :type
15
+ attr_accessor :location
16
+
17
+ def initialize(vmid, location, os=nil, tools=false, credentials=nil)
18
+
19
+ # We have to treat this differently, as it's not in the same tree
20
+ begin
21
+ require 'vixr'
22
+ rescue LoadError
23
+ puts "WARNING: Library pro_vixr not found. To resolve this error, please\n" +
24
+ " install the vixr gem. Latest is available here:\n" +
25
+ "https://github.com/rhythmx/vixr ."
26
+ raise "Unable to create vixr driver"
27
+ end
28
+
29
+ @vmid = filter_command(vmid)
30
+ @location = filter_command(location)
31
+
32
+ if !File.exist?(@location)
33
+ raise ArgumentError,"Couldn't find: " + location
34
+ end
35
+
36
+ @credentials = credentials
37
+ @tools = tools # not used in command lines, no filter
38
+ @os = os # not used in command lines, no filter
39
+
40
+ # TODO - Currently only implemented for the first set
41
+ if @credentials.count > 0
42
+ @vm_user = filter_input(@credentials[0]['user']) || "\'\'"
43
+ @vm_pass = filter_input(@credentials[0]['pass']) || "\'\'"
44
+ end
45
+
46
+ host = VixR.connect()
47
+ vm = host.open_vmx(@location)
48
+
49
+ end
50
+
51
+ def start
52
+ vm.power_on
53
+ end
54
+
55
+ def stop
56
+ vm.power_off
57
+ end
58
+
59
+ def suspend
60
+ vm.suspend
61
+ end
62
+
63
+ def pause
64
+ vm.pause
65
+ end
66
+
67
+ def reset
68
+ vm.reset
69
+ end
70
+
71
+ def create_snapshot(snapshot)
72
+ snapshot = filter_input(snapshot)
73
+ system_command("ssh #{@user}@#{@host} vmrun -T ws snapshot \\\'#{@location}\\\' #{snapshot} nogui")
74
+ end
75
+
76
+ def revert_snapshot(snapshot)
77
+ snapshot = filter_input(snapshot)
78
+ system_command("ssh #{@user}@#{@host} vmrun -T ws revertToSnapshot \\\'#{@location}\\\' #{snapshot} nogui")
79
+ end
80
+
81
+ def delete_snapshot(snapshot)
82
+ snapshot = filter_input(snapshot)
83
+ system_command("ssh #{@user}@#{@host} vmrun -T ws deleteSnapshot \\\'#{@location}\\\' #{snapshot} nogui" )
84
+ end
85
+
86
+
87
+ def run_command(command)
88
+ command = filter_input(command)
89
+ if vm.login(@vm_user,@vm_pass)
90
+ vm.run_prog(command)
91
+ end
92
+ end
93
+
94
+ def copy_from(from, to)
95
+ from = filter_input(from)
96
+ to = filter_input(to)
97
+ cp_from_host(from,to)
98
+ end
99
+
100
+ def copy_to(from, to)
101
+ from = filter_input(from)
102
+ to = filter_input(to)
103
+ vm.cp_to_guest(from,to)
104
+ end
105
+
106
+ def check_file_exists(file)
107
+ file = filter_input(file)
108
+ file_exists?(file)
109
+ end
110
+
111
+ def create_directory(directory)
112
+ directory = filter_input(directory)
113
+ end
114
+
115
+ def cleanup
116
+
117
+ end
118
+
119
+ def running?
120
+ vm.running?
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+ end