mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
258 lines
7 KiB
Ruby
258 lines
7 KiB
Ruby
require 'fog/compute/models/server'
|
|
|
|
module Fog
|
|
module Compute
|
|
class Vmfusion
|
|
|
|
class Server < Fog::Compute::Server
|
|
|
|
identity :name
|
|
|
|
attribute :ipaddress
|
|
attribute :power_state
|
|
attribute :mac_addresses
|
|
attribute :path
|
|
|
|
attr_accessor :password
|
|
|
|
# There is currently no documented model of creating VMs from scratch
|
|
# sans Fusion's wizard.
|
|
def save
|
|
raise Fog::Errors::Error.new('Creating a new vm is not yet supported')
|
|
end
|
|
|
|
# Fussion doesn't have the concept of templates so one just clones
|
|
# regular VMs.
|
|
def clone(name)
|
|
requires :raw
|
|
|
|
::Fission::VM.clone(@raw[:fission].name,name)
|
|
return service.servers.get(name)
|
|
end
|
|
|
|
# Destroy, deletes the VM from the local disk but only hard stops the VM
|
|
# before doing so if you set :force to true.
|
|
def destroy(options = { :force => false })
|
|
requires :raw
|
|
|
|
if ready?
|
|
if options[:force]
|
|
stop
|
|
end
|
|
end
|
|
|
|
@raw[:fission].delete
|
|
end
|
|
|
|
# Start is pretty self explanatory...if you pass :headless as true you
|
|
# won't get a console on launch.
|
|
def start(options = { :headless => false })
|
|
requires :raw
|
|
|
|
unless ready?
|
|
@raw[:fission].start(:headless => options[:headless])
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
# We're covering a lot of bases here with the different ways one can
|
|
# stop a VM from running.
|
|
|
|
# Stop is a hard stop, like pulling out the power cord.
|
|
def stop
|
|
requires :raw
|
|
|
|
if ready?
|
|
@raw[:fission].stop(:hard => true)
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
# Halt and poweroff are just synonyms for stop.
|
|
def halt
|
|
stop
|
|
end
|
|
|
|
def poweroff
|
|
stop
|
|
end
|
|
|
|
# This is a graceful shutdown but Fusion is only capable of a graceful
|
|
# shutdown if tools are installed. Fusion does the right thing though
|
|
# and if graceful can't be initiated it just does a hard stop.
|
|
def shutdown
|
|
requires :raw
|
|
if ready?
|
|
@raw[:fission].stop
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
# Attempt a graceful shutdown, wait for the VM to completely shutdown
|
|
# and then start it again.
|
|
def reboot
|
|
if ready?
|
|
shutdown
|
|
wait_for { ! ready? }
|
|
start
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
# Resuming from suspend is the same thing as start to Fusion.
|
|
def resume
|
|
start
|
|
end
|
|
|
|
def suspend
|
|
requires :raw
|
|
if ready?
|
|
@raw[:fission].suspend
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
# Fusion VM Metadata.
|
|
|
|
# The power state of the VM is commonly going to be three values;
|
|
# running, not running, or suspended.
|
|
def power_state
|
|
requires :raw
|
|
@raw[:fission].state.data
|
|
end
|
|
|
|
def ready?
|
|
requires :raw
|
|
@raw[:fission].running?.data
|
|
end
|
|
|
|
# Path to the VM's vmx file on the local disk.
|
|
def path
|
|
requires :raw
|
|
@raw[:fission].path
|
|
end
|
|
|
|
# We obtain the first ipaddress. This should generally be a safe
|
|
# assumption for Fusion. Even if an address is provided via NAT,
|
|
# bridge, or host only it will by accessible from the host machine the
|
|
# VM resides on.
|
|
def ipaddress
|
|
requires :raw
|
|
ip(@raw[:fission])
|
|
end
|
|
|
|
# Keeping these three methods around for API compatibility reasons.
|
|
# Makes the vmfusion provider function similar to cloud providers and
|
|
# the vsphere provider. Future goal is to add an actual private and
|
|
# public concept. Needs changes to fission and a determination what is
|
|
# a public or private address here; bridge, nat, host-only.
|
|
def public_ip_address
|
|
ipaddress
|
|
end
|
|
|
|
def private_ip_address
|
|
ipaddress
|
|
end
|
|
|
|
def state
|
|
power_state
|
|
end
|
|
|
|
# Collecting all mac_addresses the VM has...mostly just because we are
|
|
# doing the same thing for the vSphere provider.
|
|
def mac_addresses
|
|
requires :raw
|
|
macs(@raw[:fission])
|
|
end
|
|
|
|
# Sets up a conveinent way to SSH into a Fusion VM using credentials
|
|
# stored in your .fog file.
|
|
|
|
# Simply spawn an SSH session.
|
|
def ssh(commands)
|
|
super(commands, password ? {:password => password} : {})
|
|
end
|
|
|
|
# SCP something to our VM.
|
|
def scp(local_path, remote_path, upload_options = {})
|
|
requires :ipaddress, :username
|
|
|
|
scp_options = {}
|
|
scp_options[:password] = password unless self.password.nil?
|
|
scp_options[:key_data] = [private_key] if self.private_key
|
|
|
|
Fog::SCP.new(ipaddress, username, scp_options).upload(local_path, remote_path, upload_options)
|
|
end
|
|
|
|
# Sets up a new SSH key on the VM so one doesn't need to use a password
|
|
# ever again.
|
|
def setup(credentials = {})
|
|
requires :public_key, :ipaddress, :username
|
|
|
|
credentials[:password] = password unless self.password.nil?
|
|
credentails[:key_data] = [private_key] if self.private_key
|
|
|
|
commands = [
|
|
%{mkdir .ssh},
|
|
]
|
|
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(ipaddress, 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(ipaddress, username, credentials).run(commands)
|
|
end
|
|
|
|
private
|
|
def ip(fission)
|
|
first_int = fission.network_info.data.keys.first
|
|
fission.network_info.data[first_int]['ip_address']
|
|
end
|
|
|
|
def macs(fission)
|
|
fission.mac_addresses.data
|
|
end
|
|
|
|
def raw
|
|
@raw
|
|
end
|
|
|
|
def raw=(new_raw)
|
|
@raw = new_raw
|
|
|
|
raw_attributes = {
|
|
:name => new_raw[:fission].name,
|
|
:power_state => new_raw[:state],
|
|
:ipaddress => ip(new_raw[:fission]),
|
|
:mac_addresses => macs(new_raw[:fission]),
|
|
:path => new_raw[:fission].path
|
|
}
|
|
|
|
merge_attributes(raw_attributes)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|