require 'fog/compute/models/server' module Fog module Compute class Brightbox class Server < Fog::Compute::Server identity :id attribute :resource_type attribute :url attribute :name attribute :state, :aliases => 'status' attribute :hostname attribute :fqdn attribute :user_data attribute :console_url attribute :fqdn attribute :console_token # Times attribute :created_at, :type => :time attribute :started_at, :type => :time attribute :console_token_expires, :type => :time attribute :deleted_at, :type => :time # Links - to be replaced attribute :account_id, :aliases => "account", :squash => "id" attribute :image_id, :aliases => "image", :squash => "id" attribute :snapshots attribute :cloud_ips attribute :interfaces attribute :server_groups attribute :zone attribute :server_type def initialize(attributes={}) # Call super first to initialize the service object for our default image super self.image_id ||= service.default_image end def zone_id if t_zone_id = attributes[:zone_id] t_zone_id elsif zone zone[:id] || zone['id'] end end def flavor_id if t_flavour_id = attributes[:flavor_id] t_flavour_id elsif server_type server_type[:id] || server_type['id'] end end def zone_id=(incoming_zone_id) attributes[:zone_id] = incoming_zone_id end def flavor_id=(incoming_flavour_id) attributes[:flavor_id] = incoming_flavour_id end def snapshot requires :identity service.snapshot_server(identity) end # Directly requesting a server reboot is not supported in the API # so needs to attempt a shutdown/stop, wait and start again. # # Default behaviour is a hard reboot because it is more reliable # because the state of the server's OS is irrelevant. # # @param [Boolean] use_hard_reboot # @return [Boolean] def reboot(use_hard_reboot = true) requires :identity if ready? unless use_hard_reboot soft_reboot else hard_reboot end else # Not able to reboot if not ready in the first place false end end def start requires :identity service.start_server(identity) true end def stop requires :identity service.stop_server(identity) true end def shutdown requires :identity service.shutdown_server(identity) true end def destroy requires :identity service.destroy_server(identity) true end def flavor requires :flavor_id service.flavors.get(flavor_id) end def image requires :image_id service.images.get(image_id) end # Returns the public DNS name of the server # # @return [String] # def dns_name ["public", fqdn].join(".") end def private_ip_address unless interfaces.empty? interfaces.first["ipv4_address"] else nil end end def public_ip_address unless cloud_ips.empty? cloud_ips.first["public_ip"] else nil end end def ready? self.state == 'active' end def activate_console requires :identity response = service.activate_console_server(identity) [response["console_url"], response["console_token"], response["console_token_expires"]] end def save raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted? requires :image_id options = { :image => image_id, :name => name, :zone => zone_id, :user_data => user_data, :server_groups => server_groups }.delete_if {|k,v| v.nil? || v == "" } unless flavor_id.nil? || flavor_id == "" options.merge!(:server_type => flavor_id) end data = service.create_server(options) merge_attributes(data) true end private # Hard reboots are fast, avoiding the OS by doing a "power off" def hard_reboot stop wait_for { ! ready? } start end # Soft reboots often timeout if the OS missed the request so we do more # error checking trying to detect the timeout # # @todo Needs cleaner error handling when the OS times out def soft_reboot shutdown # FIXME Using side effect of wait_for's (evaluated block) to detect timeouts begin wait_for(20) { ! ready? } start rescue Fog::Errors::Timeout => e false end end end end end end