lab 0.0.3 → 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.
@@ -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