Class: Jupiter::Host
- Inherits:
-
Object
show all
- Defined in:
- lib/jupiter/host.rb
Defined Under Namespace
Classes: InvalidGBSizeError, InvalidVMStateError
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#answer_vm_question(vm) ⇒ Object
-
#change_config_value(key, value) ⇒ Object
-
#clone_vm(vm, newvm) ⇒ Object
-
#close_ssh ⇒ Object
-
#consolidate_snapshots(vm) ⇒ Object
-
#extract_template(original_name, new_name) ⇒ Object
-
#flatten_hash(hash_to_flatten) ⇒ Object
-
#generate_mac_address ⇒ Object
-
#guest_ip(vm) ⇒ Object
-
#guestvm(vmname) ⇒ Object
-
#initialize(options) ⇒ Host
constructor
-
#power_cycle_vm(vm) ⇒ Object
-
#power_off_vm(vm) ⇒ Object
-
#power_on_vm(vm) ⇒ Object
-
#read_config_to_hash(file) ⇒ Object
-
#reboot_vm(vm) ⇒ Object
-
#register_vm(vm) ⇒ Object
-
#rename_copied_template(original_name, new_name) ⇒ Object
-
#rename_cp_files(vm, newvm) ⇒ Object
-
#resize_vmdk(vm, size_in_GB) ⇒ Object
-
#server_uptime ⇒ Object
-
#server_vm_list ⇒ Object
-
#setup_template(original_name, new_name) ⇒ Object
-
#shutdown_vm(vm) ⇒ Object
-
#snapshot_create(vm) ⇒ Object
-
#snapshots_remove(vm) ⇒ Object
-
#ssh ⇒ Object
-
#unregister_vm(vm) ⇒ Object
-
#update_vmdk(vm, newvm) ⇒ Object
-
#update_vmx(vm, newvm) ⇒ Object
-
#update_vmxf(vm, newvm) ⇒ Object
-
#uuid(newvm) ⇒ Object
-
#vm_state(vm) ⇒ Object
-
#vmdk_size(vm) ⇒ Object
-
#vmhost ⇒ Object
-
#write_to_file(file_content, full_path_to_file) ⇒ Object
Constructor Details
#initialize(options) ⇒ Host
Returns a new instance of Host.
6
7
8
9
10
11
12
13
14
15
|
# File 'lib/jupiter/host.rb', line 6
def initialize(options)
self.name = options.fetch(:name)
self.vmpath = options.fetch(:vmpath)
self.host = options.fetch(:host)
self.sshport = options.fetch(:sshport)
self.sshuser = options.fetch(:sshuser)
self.sshpass = options.fetch(:sshpass)
self.dcname = options.fetch(:dcname)
self.timestamp = Time.new.strftime('%Y-%m-%d-%H%M').freeze
end
|
Instance Attribute Details
#dcname ⇒ Object
Returns the value of attribute dcname.
4
5
6
|
# File 'lib/jupiter/host.rb', line 4
def dcname
@dcname
end
|
#host ⇒ Object
Returns the value of attribute host.
4
5
6
|
# File 'lib/jupiter/host.rb', line 4
def host
@host
end
|
#name ⇒ Object
Returns the value of attribute name.
4
5
6
|
# File 'lib/jupiter/host.rb', line 4
def name
@name
end
|
#sshpass ⇒ Object
Returns the value of attribute sshpass.
4
5
6
|
# File 'lib/jupiter/host.rb', line 4
def sshpass
@sshpass
end
|
#sshport ⇒ Object
Returns the value of attribute sshport.
4
5
6
|
# File 'lib/jupiter/host.rb', line 4
def sshport
@sshport
end
|
#sshuser ⇒ Object
Returns the value of attribute sshuser.
4
5
6
|
# File 'lib/jupiter/host.rb', line 4
def sshuser
@sshuser
end
|
#timestamp ⇒ Object
Returns the value of attribute timestamp.
4
5
6
|
# File 'lib/jupiter/host.rb', line 4
def timestamp
@timestamp
end
|
#vmpath ⇒ Object
Returns the value of attribute vmpath.
4
5
6
|
# File 'lib/jupiter/host.rb', line 4
def vmpath
@vmpath
end
|
Instance Method Details
#answer_vm_question(vm) ⇒ Object
214
215
216
|
# File 'lib/jupiter/host.rb', line 214
def answer_vm_question(vm)
result = guestvm(vm).AnswerVM(questionId: '_vmx1', answerChoice: '2')
end
|
#change_config_value(key, value) ⇒ Object
139
140
141
142
|
# File 'lib/jupiter/host.rb', line 139
def change_config_value(key, value)
self[key] = value
return self
end
|
#clone_vm(vm, newvm) ⇒ Object
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/jupiter/host.rb', line 102
def clone_vm(vm, newvm)
snapshot_create(vm)
sleep 5
ssh.exec!("mkdir #{vmpath}/#{newvm}")
ssh.exec!("cp -Rfv #{vmpath}/#{vm}/* #{vmpath}/#{newvm}")
rename_cp_files(vm, newvm)
update_vmx(vm, newvm)
update_vmxf(vm, newvm)
update_vmdk(vm, newvm)
register_vm(newvm)
close_ssh
snapshots_remove(vm)
consolidate_snapshots(vm)
sleep 5
power_on_vm(newvm)
sleep 5
answer_vm_question(newvm) sleep 5
power_on_vm(newvm)
end
|
#close_ssh ⇒ Object
32
33
34
35
36
|
# File 'lib/jupiter/host.rb', line 32
def close_ssh
ssh.close
@ssh = nil
true
end
|
#consolidate_snapshots(vm) ⇒ Object
67
68
69
|
# File 'lib/jupiter/host.rb', line 67
def consolidate_snapshots(vm)
result = guestvm(vm).ConsolidateVMDisks_Task
end
|
234
235
236
237
238
239
240
241
242
|
# File 'lib/jupiter/host.rb', line 234
def (original_name, new_name)
file_exists = ssh.exec!("find #{vmpath}/#{original_name}.tar.gz").chomp
if file_exists == "#{vmpath}/#{original_name}.tar.gz"
ssh.exec!("cd #{vmpath} && tar -zxvf #{original_name}.tar.gz && rm #{original_name}.tar.gz")
else
close_ssh
return false
end
end
|
#flatten_hash(hash_to_flatten) ⇒ Object
153
154
155
|
# File 'lib/jupiter/host.rb', line 153
def flatten_hash(hash_to_flatten)
hash_to_flatten.map{|k,v| "#{k} = \"#{v}\""}.join("\n")
end
|
#generate_mac_address ⇒ Object
161
162
163
|
# File 'lib/jupiter/host.rb', line 161
def generate_mac_address
(1..6).map{"%0.2X"%rand(256)}.join(":")
end
|
#guest_ip(vm) ⇒ Object
51
52
53
|
# File 'lib/jupiter/host.rb', line 51
def guest_ip(vm)
result = guestvm(vm).guest_ip
end
|
#guestvm(vmname) ⇒ Object
47
48
49
|
# File 'lib/jupiter/host.rb', line 47
def guestvm(vmname)
vm = vmhost.find_vm(vmname) or fail "\n\nVirtual Machine was not found. Although its files might exist, it may not be registered on the server. You can register the VM with the following command:\n\njupiter register --guest=#{vmname} --host=#{name}\n\n"
end
|
#power_cycle_vm(vm) ⇒ Object
88
89
90
91
92
|
# File 'lib/jupiter/host.rb', line 88
def power_cycle_vm(vm)
guestvm(vm).PowerOffVM_Task
sleep 5
guestvm(vm).PowerOnVM_Task
end
|
#power_off_vm(vm) ⇒ Object
84
85
86
|
# File 'lib/jupiter/host.rb', line 84
def power_off_vm(vm)
result = guestvm(vm).PowerOffVM_Task
end
|
#power_on_vm(vm) ⇒ Object
80
81
82
|
# File 'lib/jupiter/host.rb', line 80
def power_on_vm(vm)
result = guestvm(vm).PowerOnVM_Task
end
|
#read_config_to_hash(file) ⇒ Object
144
145
146
147
|
# File 'lib/jupiter/host.rb', line 144
def read_config_to_hash(file)
file_contents = ssh.exec!(%Q[cat #{file}])
Hash[file_contents.split("\n").map { |line| line.split('=').map(&:strip).map { |value| value.gsub(/\A"|"\z/, '') } }]
end
|
#reboot_vm(vm) ⇒ Object
94
95
96
|
# File 'lib/jupiter/host.rb', line 94
def reboot_vm(vm)
result = guestvm(vm).RebootGuest
end
|
#register_vm(vm) ⇒ Object
71
72
73
74
|
# File 'lib/jupiter/host.rb', line 71
def register_vm(vm)
ssh.exec!("vim-cmd solo/registervm #{vmpath}/#{vm}/#{vm}.vmx")
snapshots_remove(vm)
end
|
#rename_copied_template(original_name, new_name) ⇒ Object
244
245
246
247
248
249
250
251
|
# File 'lib/jupiter/host.rb', line 244
def rename_copied_template(original_name, new_name)
if !new_name.nil? && !original_name.nil?
ssh.exec!("mv #{vmpath}/#{original_name} #{vmpath}/#{new_name}")
rename_cp_files(original_name, new_name)
else
return false
end
end
|
#rename_cp_files(vm, newvm) ⇒ Object
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/jupiter/host.rb', line 123
def rename_cp_files(vm, newvm)
old_files_path = "#{vmpath}/#{newvm}/#{vm}"
new_files_path = "#{vmpath}/#{newvm}/#{newvm}"
ssh.exec!("rm -f #{vmpath}/#{newvm}/vmware-*.log")
ssh.exec!("rm -f #{old_files_path}.vmx~")
ssh.exec!("rm -f #{old_files_path}.vmsd")
ssh.exec!("rm -f #{old_files_path}-*.vmsn")
ssh.exec!("rm -f #{old_files_path}-0000*.vmdk")
ssh.exec!("mv #{old_files_path}-aux.xml #{new_files_path}-aux.xml")
ssh.exec!("mv #{old_files_path}-flat.vmdk #{new_files_path}-flat.vmdk")
ssh.exec!("mv #{old_files_path}.nvram #{new_files_path}.nvram")
ssh.exec!("mv #{old_files_path}.vmdk #{new_files_path}.vmdk")
ssh.exec!("mv #{old_files_path}.vmx #{new_files_path}.vmx")
ssh.exec!("mv #{old_files_path}.vmxf #{new_files_path}.vmxf")
end
|
#resize_vmdk(vm, size_in_GB) ⇒ Object
205
206
207
208
209
210
211
212
|
# File 'lib/jupiter/host.rb', line 205
def resize_vmdk(vm, size_in_GB)
size_in_GB.tr!('^.0-9', '')
raise InvalidGBSizeError.new("You can only increase the size of the drive, not reduce it.") if vmdk_size(vm).to_f > size_in_GB.to_f
raise InvalidVMStateError.new("#{vm} must be shutdown before the drive can be resized.") if vm_state(vm) == 'running'
result = ssh.exec!(%Q[vmkfstools -X #{size_in_GB}G #{vmpath}/#{vm}/#{vm}.vmdk])
close_ssh
return result
end
|
#server_uptime ⇒ Object
17
18
19
20
|
# File 'lib/jupiter/host.rb', line 17
def server_uptime
puts ssh.exec!("uptime")
close_ssh
end
|
#server_vm_list ⇒ Object
22
23
24
25
26
|
# File 'lib/jupiter/host.rb', line 22
def server_vm_list
vm_list = ssh.exec!("ls #{vmpath}").to_s
close_ssh
vm_list.split("\n")
end
|
#setup_template(original_name, new_name) ⇒ Object
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
# File 'lib/jupiter/host.rb', line 218
def setup_template(original_name, new_name)
(original_name, new_name)
rename_copied_template(original_name, new_name)
update_vmx(original_name, new_name)
update_vmxf(original_name, new_name)
update_vmdk(original_name, new_name)
register_vm(new_name)
close_ssh
sleep 5
power_on_vm(new_name)
sleep 5
answer_vm_question(new_name) sleep 5
power_on_vm(new_name)
end
|
#shutdown_vm(vm) ⇒ Object
98
99
100
|
# File 'lib/jupiter/host.rb', line 98
def shutdown_vm(vm)
result = guestvm(vm).ShutdownGuest
end
|
#snapshot_create(vm) ⇒ Object
59
60
61
|
# File 'lib/jupiter/host.rb', line 59
def snapshot_create(vm)
result = guestvm(vm).CreateSnapshot_Task(name: "snapshot_#{timestamp}", memory: false, quiesce: true)
end
|
#snapshots_remove(vm) ⇒ Object
63
64
65
|
# File 'lib/jupiter/host.rb', line 63
def snapshots_remove(vm)
result = guestvm(vm).RemoveAllSnapshots_Task
end
|
#ssh ⇒ Object
28
29
30
|
# File 'lib/jupiter/host.rb', line 28
def ssh
@ssh ||= Net::SSH.start(host, sshuser, password: sshpass, port: sshport)
end
|
#unregister_vm(vm) ⇒ Object
76
77
78
|
# File 'lib/jupiter/host.rb', line 76
def unregister_vm(vm)
ssh.exec!("vim-cmd vmsvc/unregister #{vmpath}/#{vm}/#{vm}.vmx")
end
|
#update_vmdk(vm, newvm) ⇒ Object
189
190
191
192
193
194
195
|
# File 'lib/jupiter/host.rb', line 189
def update_vmdk(vm, newvm)
file_with_path = "#{vmpath}/#{newvm}/#{newvm}.vmdk"
file_contents = ssh.exec!(%Q[cat #{file_with_path}])
file_contents[vm]= newvm
write_to_file(file_contents, file_with_path)
return true
end
|
#update_vmx(vm, newvm) ⇒ Object
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
# File 'lib/jupiter/host.rb', line 165
def update_vmx(vm, newvm)
vmx_hash = read_config_to_hash("#{vmpath}/#{newvm}/#{newvm}.vmx")
vmx_hash['ethernet0.generatedAddress'] = generate_mac_address
vmx_hash['uuid.bios'] = uuid(newvm)
vmx_hash['uuid.location'] = uuid(newvm)
vmx_hash['displayName'] = newvm
vmx_hash['nvram'] = "#{newvm}.nvram"
vmx_hash['extendedConfigFile'] = "#{newvm}.vmxf"
vmx_hash['scsi0:0.fileName'] = "#{newvm}.vmdk"
swap_derived_name = vmx_hash['sched.swap.derivedName']
swap_derived_name["#{vm}/#{vm}"]= "#{newvm}/#{newvm}"
vmx_hash['sched.swap.derivedName'] = swap_derived_name
write_to_file(flatten_hash(vmx_hash), "#{vmpath}/#{newvm}/#{newvm}.vmx")
return true
end
|
#update_vmxf(vm, newvm) ⇒ Object
181
182
183
184
185
186
187
|
# File 'lib/jupiter/host.rb', line 181
def update_vmxf(vm, newvm)
file_with_path = "#{vmpath}/#{newvm}/#{newvm}.vmxf"
newuuid = uuid(newvm)
file_contents = "<?xml version=\"1.0\"?>\n<Foundry>\n<VM>\n<VMId type=\"string\">#{newuuid}</VMId>\n<ClientMetaData>\n<clientMetaDataAttributes/>\n<HistoryEventList/></ClientMetaData>\n<vmxPathName type=\"string\">#{newvm}.vmx</vmxPathName></VM></Foundry>"
write_to_file(file_contents, file_with_path)
return true
end
|
#uuid(newvm) ⇒ Object
149
150
151
|
# File 'lib/jupiter/host.rb', line 149
def uuid(newvm)
@uuid ||= Jupiter::UUID.new.generate(newvm)
end
|
#vm_state(vm) ⇒ Object
55
56
57
|
# File 'lib/jupiter/host.rb', line 55
def vm_state(vm)
result = guestvm(vm).guest.guestState
end
|
#vmdk_size(vm) ⇒ Object
197
198
199
200
201
202
203
|
# File 'lib/jupiter/host.rb', line 197
def vmdk_size(vm)
file_with_path = "#{vmpath}/#{vm}/#{vm}.vmdk"
vmdk_contents = ssh.exec!(%Q[cat #{file_with_path}])
close_ssh
vmfs_sectors = vmdk_contents[/\RW(.*?)VMFS/,1]
gb_size = ((vmfs_sectors.to_f * 512) / (1024 * 1024 * 1024))
end
|
#vmhost ⇒ Object
38
39
40
41
42
43
44
45
|
# File 'lib/jupiter/host.rb', line 38
def vmhost
if /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.match(host)
vim = RbVmomi::VIM.connect host: host, user: sshuser, password: sshpass, insecure: true
dc = vim.serviceInstance.find_datacenter(dcname) or fail "datacenter not found"
else
return false
end
end
|
#write_to_file(file_content, full_path_to_file) ⇒ Object
157
158
159
|
# File 'lib/jupiter/host.rb', line 157
def write_to_file(file_content, full_path_to_file)
ssh.exec!(%Q[echo '#{file_content}' > #{full_path_to_file}])
end
|