Class: Fog::Compute::Libvirt::Server
- Includes:
- Fog::Compute::LibvirtUtil
- Defined in:
- lib/fog/libvirt/models/compute/server.rb
Instance Attribute Summary collapse
-
#iso_dir ⇒ Object
The following attributes are only needed when creating a new vm.
-
#iso_file ⇒ Object
The following attributes are only needed when creating a new vm.
-
#network_bridge_name ⇒ Object
Returns the value of attribute network_bridge_name.
-
#network_interface_type ⇒ Object
Returns the value of attribute network_interface_type.
-
#network_nat_network ⇒ Object
Returns the value of attribute network_nat_network.
-
#password ⇒ Object
Returns the value of attribute password.
- #private_key ⇒ Object
- #private_key_path ⇒ Object
- #public_key ⇒ Object
- #public_key_path ⇒ Object
- #username ⇒ Object
-
#volume_allocation ⇒ Object
Returns the value of attribute volume_allocation.
-
#volume_capacity ⇒ Object
Returns the value of attribute volume_capacity.
-
#volume_format_type ⇒ Object
Returns the value of attribute volume_format_type.
-
#volume_name ⇒ Object
Returns the value of attribute volume_name.
-
#volume_path ⇒ Object
Returns the value of attribute volume_path.
-
#volume_pool_name ⇒ Object
Returns the value of attribute volume_pool_name.
-
#volume_template_name ⇒ Object
Returns the value of attribute volume_template_name.
Attributes inherited from Model
Instance Method Summary collapse
-
#addresses(options = {}) ⇒ Object
This retrieves the ip address of the mac address It returns an array of public and private ip addresses Currently only one ip address is returned, but in the future this could be multiple if the server has multiple network interface.
- #create_or_clone_volume ⇒ Object
-
#destroy(options = { :destroy_volumes => false}) ⇒ Object
In libvirt a destroy means a hard power-off of the domain In fog a destroy means the remove of a machine.
-
#halt ⇒ Object
Alias for poweroff.
-
#initialize(attributes = {}) ⇒ Server
constructor
Can be created by passing in :xml => “<xml to create domain/server>” or by providing :template_options => { :name => “”, :cpus => 1, :memory_size => 256 , :volume_template :}.
- #ip_address(key) ⇒ Object
-
#mac ⇒ Object
Retrieves the mac address from parsing the XML of the domain.
-
#poweroff ⇒ Object
In libvirt a destroy means a hard power-off of the domain In fog a destroy means the remove of a machine.
- #private_ip_address ⇒ Object
- #public_ip_address ⇒ Object
- #ready? ⇒ Boolean
- #reboot ⇒ Object
- #resume ⇒ Object
- #save ⇒ Object
-
#scp(local_path, remote_path, upload_options = {}) ⇒ Object
Transfers a file.
-
#setup(credentials = {}) ⇒ Object
Sets up a new key.
- #shutdown ⇒ Object
- #ssh(commands) ⇒ Object
- #ssh_proxy ⇒ Object
- #start ⇒ Object
- #stop ⇒ Object
- #suspend ⇒ Object
- #to_fog_state(raw_state) ⇒ Object
- #validate_template_options ⇒ Object
- #vnc_port ⇒ Object
- #xml_from_template ⇒ Object
Methods inherited from Model
#inspect, #reload, #to_json, #wait_for
Methods included from Attributes::ClassMethods
#_load, #aliases, #attribute, #attributes, #identity, #ignore_attributes, #ignored_attributes
Methods included from Attributes::InstanceMethods
#_dump, #attributes, #dup, #identity, #identity=, #merge_attributes, #new_record?, #requires, #requires_one
Constructor Details
#initialize(attributes = {}) ⇒ Server
Can be created by passing in :xml => “<xml to create domain/server>” or by providing :template_options =>
:name => "", :cpus => 1, :memory_size => 256 , :volume_template
:
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 49 def initialize(attributes={} ) self.xml ||= nil unless attributes[:xml] self.persistent ||=true unless attributes[:persistent] self.cpus ||=1 unless attributes[:cpus] self.memory_size ||=256 *1024 unless attributes[:memory_size] self.name ||="fog-#{SecureRandom.random_number*10E14.to_i.round}" unless attributes[:name] self.os_type ||="hvm" unless attributes[:os_type] self.arch ||="x86_64" unless attributes[:arch] self.domain_type ||="kvm" unless attributes[:domain_type] self.iso_file ||=nil unless attributes[:iso_file] self.iso_dir ||="/var/lib/libvirt/images" unless attributes[:iso_dir] self.volume_format_type ||=nil unless attributes[:volume_format_type] self.volume_capacity ||=nil unless attributes[:volume_capacity] self.volume_allocation ||=nil unless attributes[:volume_allocation] self.volume_name ||=nil unless attributes[:volume_name] self.volume_pool_name ||=nil unless attributes[:volume_pool_name] self.volume_template_name ||=nil unless attributes[:volume_template_name] self.network_interface_type ||="nat" unless attributes[:network_interface_type] self.network_nat_network ||="default" unless attributes[:network_nat_network] self.network_bridge_name ||="br0" unless attributes[:network_bridge_name] super end |
Instance Attribute Details
#iso_dir ⇒ Object
The following attributes are only needed when creating a new vm
36 37 38 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 36 def iso_dir @iso_dir end |
#iso_file ⇒ Object
The following attributes are only needed when creating a new vm
36 37 38 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 36 def iso_file @iso_file end |
#network_bridge_name ⇒ Object
Returns the value of attribute network_bridge_name.
37 38 39 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 37 def network_bridge_name @network_bridge_name end |
#network_interface_type ⇒ Object
Returns the value of attribute network_interface_type.
37 38 39 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 37 def network_interface_type @network_interface_type end |
#network_nat_network ⇒ Object
Returns the value of attribute network_nat_network.
37 38 39 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 37 def network_nat_network @network_nat_network end |
#password ⇒ Object
Returns the value of attribute password.
40 41 42 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 40 def password @password end |
#private_key ⇒ Object
392 393 394 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 392 def private_key @private_key ||= private_key_path && File.read(private_key_path) end |
#private_key_path ⇒ Object
387 388 389 390 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 387 def private_key_path @private_key_path ||= Fog.credentials[:private_key_path] @private_key_path &&= File.(@private_key_path) end |
#public_key ⇒ Object
401 402 403 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 401 def public_key @public_key ||= public_key_path && File.read(public_key_path) end |
#public_key_path ⇒ Object
396 397 398 399 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 396 def public_key_path @public_key_path ||= Fog.credentials[:public_key_path] @public_key_path &&= File.(@public_key_path) end |
#username ⇒ Object
184 185 186 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 184 def username @username ||= 'root' end |
#volume_allocation ⇒ Object
Returns the value of attribute volume_allocation.
38 39 40 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 38 def volume_allocation @volume_allocation end |
#volume_capacity ⇒ Object
Returns the value of attribute volume_capacity.
38 39 40 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 38 def volume_capacity @volume_capacity end |
#volume_format_type ⇒ Object
Returns the value of attribute volume_format_type.
38 39 40 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 38 def volume_format_type @volume_format_type end |
#volume_name ⇒ Object
Returns the value of attribute volume_name.
38 39 40 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 38 def volume_name @volume_name end |
#volume_path ⇒ Object
Returns the value of attribute volume_path.
38 39 40 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 38 def volume_path @volume_path end |
#volume_pool_name ⇒ Object
Returns the value of attribute volume_pool_name.
38 39 40 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 38 def volume_pool_name @volume_pool_name end |
#volume_template_name ⇒ Object
Returns the value of attribute volume_template_name.
38 39 40 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 38 def volume_template_name @volume_template_name end |
Instance Method Details
#addresses(options = {}) ⇒ Object
This retrieves the ip address of the mac address It returns an array of public and private ip addresses Currently only one ip address is returned, but in the future this could be multiple if the server has multiple network interface
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 276 def addresses(={}) mac=self.mac # Aug 24 17:34:41 juno arpwatch: new station 10.247.4.137 52:54:00:88:5a:0a eth0.4 # Aug 24 17:37:19 juno arpwatch: changed ethernet address 10.247.4.137 52:54:00:27:33:00 (52:54:00:88:5a:0a) eth0.4 # Check if another ip_command string was provided ip_command_global=@connection.ip_command.nil? ? 'grep $mac /var/log/arpwatch.log|sed -e "s/new station//"|sed -e "s/changed ethernet address//g" |sed -e "s/reused old ethernet //" |tail -1 |cut -d ":" -f 4-| cut -d " " -f 3' : @connection.ip_command ip_command_local=[:ip_command].nil? ? ip_command_global : [:ip_command] ip_command="mac=#{mac}; "+ip_command_local ip_address=nil if @connection.uri.ssh_enabled? # Retrieve the parts we need from the connection to setup our ssh options user=connection.uri.user #could be nil host=connection.uri.host keyfile=connection.uri.keyfile port=connection.uri.port # Setup the options ={} [:keys]=[ keyfile ] unless keyfile.nil? [:port]=port unless keyfile.nil? [:paranoid]=true if connection.uri.no_verify? # TODO: we need to take the time into account, when IP's are re-allocated, we might be executing # On the wrong host begin result=Fog::SSH.new(host, user, ).run(ip_command) rescue Errno::ECONNREFUSED raise Fog::Errors::Error.new("Connection was refused to host #{host} to retrieve the ip_address for #{mac}") rescue Net::SSH::AuthenticationFailed raise Fog::Errors::Error.new("Error authenticating over ssh to host #{host} and user #{user}") end #TODO: We currently just retrieve the ip address through the ip_command #TODO: We need to check if that ip_address is still valid for that mac-address # Check for a clean exit code if result.first.status == 0 ip_address=result.first.stdout.strip else # We got a failure executing the command raise Fog::Errors::Error.new("The command #{ip_command} failed to execute with a clean exit code") end else # It's not ssh enabled, so we assume it is if @connection.uri.transport=="tls" raise Fog::Errors::Error.new("TlS remote transport is not currently supported, only ssh") end # Execute the ip_command locally # Initialize empty ip_address string ip_address="" IO.popen("#{ip_command}") do |p| p.each_line do |l| ip_address+=l end status=Process.waitpid2(p.pid)[1].exitstatus if status!=0 raise Fog::Errors::Error.new("The command #{ip_command} failed to execute with a clean exit code") end end #Strip any new lines from the string ip_address=ip_address.chomp end # The Ip-address command has been run either local or remote now if ip_address=="" #The grep didn't find an ip address result" ip_address=nil else # To be sure that the command didn't return another random string # We check if the result is an actual ip-address # otherwise we return nil unless ip_address=~/^(\d{1,3}\.){3}\d{1,3}$/ raise Fog::Errors::Error.new( "The result of #{ip_command} does not have valid ip-address format\n"+ "Result was: #{ip_address}\n" ) end end return { :public => [ip_address], :private => [ip_address]} end |
#create_or_clone_volume ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 108 def create_or_clone_volume =Hash.new unless self.volume_name.nil? [:name]=self.volume_name else extension = self.volume_format_type.nil? ? "img" : self.volume_format_type volume_name = "#{self.name}.#{extension}" [:name]=volume_name end # Check if a disk template was specified unless self.volume_template_name.nil? template_volumes=connection.volumes.all(:name => self.volume_template_name) raise Fog::Errors::Error.new("Template #{self.volume_template_name} not found") unless template_volumes.length==1 orig_volume=template_volumes.first self.volume_format_type=orig_volume.format_type unless self.volume_format_type volume=orig_volume.clone("#{[:name]}") # This gets passed to the domain to know the path of the disk self.volume_path=volume.path else # If no template volume was given, let's create our own volume [:format_type]=self.volume_format_type unless self.volume_format_type.nil? [:capacity]=self.volume_capacity unless self.volume_capacity.nil? [:allocation]=self.volume_allocation unless self.volume_allocation.nil? begin volume=connection.volumes.create() self.volume_path=volume.path self.volume_format_type=volume.format_type unless self.volume_format_type rescue raise Fog::Errors::Error.new("Error creating the volume : #{$!}") end end end |
#destroy(options = { :destroy_volumes => false}) ⇒ Object
In libvirt a destroy means a hard power-off of the domain In fog a destroy means the remove of a machine
203 204 205 206 207 208 209 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 203 def destroy(={ :destroy_volumes => false}) requires :raw if @raw.active? @raw.destroy end @raw.undefine end |
#halt ⇒ Object
Alias for poweroff
217 218 219 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 217 def halt poweroff end |
#ip_address(key) ⇒ Object
378 379 380 381 382 383 384 385 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 378 def ip_address(key) ips=addresses[key] unless ips.nil? return ips.first else return nil end end |
#mac ⇒ Object
Retrieves the mac address from parsing the XML of the domain
481 482 483 484 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 481 def mac mac = document("domain/devices/interface/mac", "address") return mac end |
#poweroff ⇒ Object
In libvirt a destroy means a hard power-off of the domain In fog a destroy means the remove of a machine
223 224 225 226 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 223 def poweroff requires :raw @raw.destroy end |
#private_ip_address ⇒ Object
370 371 372 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 370 def private_ip_address ip_address(:private) end |
#public_ip_address ⇒ Object
374 375 376 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 374 def public_ip_address ip_address(:public) end |
#ready? ⇒ Boolean
256 257 258 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 256 def ready? state == "running" end |
#reboot ⇒ Object
211 212 213 214 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 211 def reboot requires :raw @raw.reboot end |
#resume ⇒ Object
233 234 235 236 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 233 def resume requires :raw @raw.resume end |
#save ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 80 def save raise Fog::Errors::Error.new('Resaving an existing server may create a duplicate') if uuid xml=xml_from_template if xml.nil? create_or_clone_volume xml=xml_from_template # We either now have xml provided by the user or generated by the template begin if !xml.nil? domain=nil if self.persistent domain=connection.raw.define_domain_xml(xml) else domain=connection.raw.create_domain_xml(xml) end self.raw=domain end rescue raise Fog::Errors::Error.new("Error saving the server: #{$!}") end end |
#scp(local_path, remote_path, upload_options = {}) ⇒ Object
Transfers a file
434 435 436 437 438 439 440 441 442 443 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 434 def scp(local_path, remote_path, = {}) requires :public_ip_address, :username = {} [:password] = password unless self.password.nil? [:key_data] = [private_key] if self.private_key [:proxy]= ssh_proxy unless self.ssh_proxy.nil? Fog::SCP.new(public_ip_address, username, ).upload(local_path, remote_path, ) end |
#setup(credentials = {}) ⇒ Object
Sets up a new key
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 447 def setup(credentials = {}) requires :public_key, :public_ip_address, :username require 'multi_json' credentials[:proxy]= ssh_proxy unless ssh_proxy.nil? credentials[:password] = password unless self.password.nil? credentails[:key_data] = [private_key] if self.private_key commands = [ %{mkdir .ssh}, # %{passwd -l #{username}}, #Not sure if we need this here # %{echo "#{MultiJson.encode(attributes)}" >> ~/attributes.json} ] if public_key commands << %{echo "#{public_key}" >> ~/.ssh/authorized_keys} end # wait for domain to be ready Timeout::timeout(360) do begin Timeout::timeout(8) do Fog::SSH.new(public_ip_address, username, credentials.merge(:timeout => 4)).run('pwd') end rescue Errno::ECONNREFUSED sleep(2) retry rescue Net::SSH::AuthenticationFailed, Timeout::Error retry end end Fog::SSH.new(public_ip_address, username, credentials).run(commands) end |
#shutdown ⇒ Object
228 229 230 231 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 228 def shutdown requires :raw @raw.shutdown end |
#ssh(commands) ⇒ Object
405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 405 def ssh(commands) requires :public_ip_address, :username #requires :password, :private_key ={} [:password] = password unless password.nil? [:key_data] = [private_key] if private_key [:proxy]= ssh_proxy unless ssh_proxy.nil? Fog::SSH.new(public_ip_address, @username, ).run(commands) end |
#ssh_proxy ⇒ Object
419 420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 419 def ssh_proxy proxy=nil if @connection.uri.ssh_enabled? relay=connection.uri.host user_string="" user_string="-l #{connection.uri.user}" unless connection.uri.user.nil? proxy = Net::SSH::Proxy::Command.new("ssh #{user_string} "+relay+" nc %h %p") return proxy else return nil # This is a direct connection, so we don't need a proxy to be set end end |
#start ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 188 def start requires :raw unless @raw.active? begin @raw.create true rescue false end end end |
#stop ⇒ Object
260 261 262 263 264 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 260 def stop requires :raw @raw.shutdown end |
#suspend ⇒ Object
238 239 240 241 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 238 def suspend requires :raw @raw.suspend end |
#to_fog_state(raw_state) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 243 def to_fog_state(raw_state) state=case raw_state when 0 then "nostate" when 1 then "running" when 2 then "blocked" when 3 then "paused" when 4 then "shutting-down" when 5 then "shutoff" when 6 then "crashed" end return state end |
#validate_template_options ⇒ Object
152 153 154 155 156 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 152 def unless self.network_interface_type.nil? raise Fog::Errors::Error.new("#{self.network_interface_type} is not a supported interface type") unless ["nat", "bridge"].include?(self.network_interface_type) end end |
#vnc_port ⇒ Object
486 487 488 489 490 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 486 def vnc_port port = document("domain/devices/graphics[@type='vnc']", "port") return port end |
#xml_from_template ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/fog/libvirt/models/compute/server.rb', line 158 def xml_from_template ={ :cpus => self.cpus, :memory_size => self.memory_size, :domain_type => self.domain_type, :name => self.name, :iso_file => self.iso_file, :iso_dir => self.iso_dir, :os_type => self.os_type, :arch => self.arch, :volume_path => self.volume_path, :volume_format_type => self.volume_format_type, :network_interface_type => self.network_interface_type, :network_nat_network => self.network_nat_network, :network_bridge_name => self.network_bridge_name } vars = ErbBinding.new() template_path=File.join(File.dirname(__FILE__),"templates","server.xml.erb") template=File.open(template_path).readlines.join erb = ERB.new(template) vars_binding = vars.send(:get_binding) result=erb.result(vars_binding) return result end |