Class: Server

Inherits:
FogModel show all
Defined in:
lib/dew/models/server.rb

Constant Summary collapse

TAG_CREATION_TIMEOUT =
60
AMI_RECOGNITION_TIMEOUT =
60
DEFAULT_SSH_CONNECTION_TIMEOUT =
180
RUNNING_SERVER_STATES =
%w{pending running}

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from FogModel

#id, #initialize, #method_missing

Constructor Details

This class inherits a constructor from FogModel

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class FogModel

Class Method Details

.create!(options) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/dew/models/server.rb', line 8

def self.create!(options)
  ami = options.fetch(:ami)
  size = options.fetch(:size)
  keypair = options.fetch(:keypair)
  groups = options.fetch(:groups)
  disk_size = options.fetch(:disk_size, nil)
  
  Inform.info "Creating server using AMI %{ami} of size %{size}, keypair %{keypair} and security groups %{groups}",
    :ami => ami, :size => size, :keypair => keypair, :groups => groups.join(',') do

    server_options = {
      :image_id => ami,
      :flavor_id => size,
      :key_name => keypair,
      :groups => groups      
    }
    
    if disk_size
      server_options.merge!(
        :block_device_mapping => [
          {
            'DeviceName' => '/dev/sda1',
            'Ebs.VolumeSize' => disk_size.to_s
          }
        ]        
      )
    end

    new(Cloud.compute.servers.create(server_options))
  end
end

.find(tag_name, tag_value) ⇒ Object



40
41
42
# File 'lib/dew/models/server.rb', line 40

def self.find tag_name, tag_value
  Cloud.compute.servers.all("tag:#{tag_name}" => tag_value).select{|s| RUNNING_SERVER_STATES.include?(s.state)}.map {|s| new s }
end

Instance Method Details

#add_tag(key, val) ⇒ Object



48
49
50
51
52
# File 'lib/dew/models/server.rb', line 48

def add_tag key, val
  try_for(TAG_CREATION_TIMEOUT) do
    Cloud.compute.tags.create(:resource_id => id, :key => key, :value => val)
  end
end

#configure_for_database(database, password) ⇒ Object



54
55
56
57
# File 'lib/dew/models/server.rb', line 54

def configure_for_database database, password
  ssh.write(database.db_environment_file(password), '/tmp/envfile')
  ssh.run('sudo mv /tmp/envfile /etc/environment')
end

#create_ami(ami_name) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/dew/models/server.rb', line 82

def create_ami ami_name
  image_id = Cloud.compute.create_image(id, ami_name, "Created by #{ENV['USER']} on #{Time.now.strftime("%Y-%m-%d")}").body['imageId']

  Inform.debug("Created image at %{id}, waiting for AWS to recognize it...", :id => image_id)
  # Sometimes takes a while for AWS to realise there's a new image...
  image = Timeout::timeout(AMI_RECOGNITION_TIMEOUT) do
    image = nil
    while image == nil
      image = Cloud.compute.images.get(image_id)
    end
    image
  end
  Inform.debug("Image recognized, waiting for it to become available...")

  image.wait_for { state == 'available' }
  Inform.debug("Image available, sharing with other accounts...")

  Account.user_ids.each do |user_id|
    Inform.debug("Sharing %{id} with %{user_id}", :id => image_id, :user_id => user_id)
    Cloud.compute.modify_image_attributes(image_id, 'launchPermission', 'add', 'UserId' => user_id)
  end
  image_id
end

#creatorObject



44
45
46
# File 'lib/dew/models/server.rb', line 44

def creator
  @creator ||= fog_object.tags["Creator"]
end

#credentialsObject



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/dew/models/server.rb', line 106

def credentials
  @credentials ||= if key_name
    keyfile_path = Cloud.keyfile_path(key_name)

    sanitize_key_file(key_name, keyfile_path)

    "-i #{keyfile_path} -o Port=#{ssh_port} -o StrictHostKeyChecking=no #{username}@#{public_ip_address}"
  else
    Inform.warning("Server %{id} has no key and therefore can not be accessed.", :id => id)
    false
  end
end

#resize_diskObject



59
60
61
# File 'lib/dew/models/server.rb', line 59

def resize_disk
  ssh.run('sudo resize2fs -p /dev/sda1')
end

#sshObject



71
72
73
# File 'lib/dew/models/server.rb', line 71

def ssh
  Gofer::Host.new(public_ip_address, username, :port => ssh_port, :key_data => [File.read(Cloud.keyfile_path(key_name))], :paranoid => false, :quiet => true)
end

#ssh_portObject



67
68
69
# File 'lib/dew/models/server.rb', line 67

def ssh_port
  fog_object.tags['SSHPort'] || '22'
end

#usernameObject



63
64
65
# File 'lib/dew/models/server.rb', line 63

def username
  fog_object.tags['Username'] || 'ubuntu'
end

#wait_until_ready(ssh_timeout = DEFAULT_SSH_CONNECTION_TIMEOUT) ⇒ Object



75
76
77
78
79
80
# File 'lib/dew/models/server.rb', line 75

def wait_until_ready ssh_timeout=DEFAULT_SSH_CONNECTION_TIMEOUT
  super()
  Inform.debug("%{id} online at %{ip}, waiting for SSH connection...", :id => id, :ip => public_ip_address)
  wait_for_ssh ssh_timeout
  Inform.debug("Connected to %{id} via SSH successfully", :id => id)
end