Class: NovaWhiz

Inherits:
Object
  • Object
show all
Defined in:
lib/novawhiz.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ NovaWhiz


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/novawhiz.rb', line 9

def initialize(opts)
  @os = OpenStack::Connection.create(
    :username => opts[:username],
    :api_key => opts[:password],
    :authtenant => opts[:authtenant],
    :auth_url => opts[:auth_url],
    :region => opts[:region],
    :service_type => "compute")

  #@fog = Fog::Compute.new(
  #    :provider      => opts[:provider],
  #    :hp_account_id  => opts[:hp_account_id],
  #    :hp_secret_key => opts[:hp_secret_key],
  #    :hp_auth_uri   => opts[:hp_auth_uri],
  #    :hp_tenant_id => opts[:hp_tenant_id],
  #    :hp_avl_zone => opts[:hp_avl_zone])
end

Instance Attribute Details

#osObject

Returns the value of attribute os


7
8
9
# File 'lib/novawhiz.rb', line 7

def os
  @os
end

Instance Method Details

#boot(opts) ⇒ Object

boot an instance and return creds


213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/novawhiz.rb', line 213

def boot(opts)
  opts[:flavor] ||= 'standard.xsmall'
  opts[:image]  ||= /Ubuntu Precise/
  opts[:sec_groups] ||= ['default']
  opts[:key_name] ||= 'default'
  opts[:region] ||= 'az-2.region-a.geo-1'

  raise 'no name provided' if !opts[:name] or opts[:name].empty?

  cleanup opts[:name]
  private_key = new_key opts[:name]
  write_key(private_key, File.expand_path('~/.ssh/hpcloud-keys/' + opts[:region] + '/'))

  server = @os.create_server(
    :imageRef => image_id(opts[:image]),
    :flavorRef => flavor_id(opts[:flavor]),
    :key_name => private_key[:name],
    :security_groups => opts[:sec_groups],
    :name => opts[:name])

  wait(300) do
    server = @os.server(server.id)
    raise 'error booting vm' if server.status == 'ERROR'
    server.status == 'ACTIVE'
  end
  sleep 60

  {
    :ip => public_ip(server),
    :user => 'ubuntu',
    :key => private_key[:private_key]
  }
end

#cleanup(name) ⇒ Object


153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/novawhiz.rb', line 153

def cleanup(name)
  if server_exists name
    delete_if_exists(name)
  end

  if keypair_exists name
    delete_keypair_if_exists(name)
  end

  #TODO: need consistent way of deciding that cleanup is complete. sleep for now.
  sleep(20)
end

#default_user(node) ⇒ Object


149
150
151
# File 'lib/novawhiz.rb', line 149

def default_user(node)
  'ubuntu'
end

#delete_if_exists(name) ⇒ Object


180
181
182
183
# File 'lib/novawhiz.rb', line 180

def delete_if_exists(name)
  s = server_by_name name
  s.delete! if s
end

#delete_keypair_if_exists(name) ⇒ Object


176
177
178
# File 'lib/novawhiz.rb', line 176

def delete_keypair_if_exists(name)
  @os.delete_keypair name if keypair_exists name
end

#flavor_id(name) ⇒ Object


73
74
75
76
77
# File 'lib/novawhiz.rb', line 73

def flavor_id(name)
  flavors = @os.flavors.select { |f| f[:name] == name }
  raise "ambiguous/unknown flavor: #{name}" unless flavors.length == 1
  flavors.first[:id]
end

#get_key(key_name, key_dir = File.expand_path('~/.ssh/hpcloud-keys/az-2.region-a.geo-1/')) ⇒ Object


98
99
100
101
102
103
104
105
106
# File 'lib/novawhiz.rb', line 98

def get_key(key_name, key_dir = File.expand_path('~/.ssh/hpcloud-keys/az-2.region-a.geo-1/'))
  key = ""
  File.open(key_dir + "/"  + replace_period_with_dash(key_name), 'r') do |f|
    while line = f.gets
      key+=line
    end
  end
  return key
end

#image_id(reg) ⇒ Object


79
80
81
82
83
# File 'lib/novawhiz.rb', line 79

def image_id(reg)
  images = @os.images.select { |i| i[:name] =~ reg }
  raise "ambiguous/unknown image: #{reg} : #{images.inspect}" unless images.length >= 1
  images.first[:id]
end

#keypair_exists(name) ⇒ Object


166
167
168
169
# File 'lib/novawhiz.rb', line 166

def keypair_exists(name)
  kp_names = @os.keypairs.values.map { |v| v[:name] }
  return true if kp_names.include? name
end

#keypair_name(server) ⇒ Object


145
146
147
# File 'lib/novawhiz.rb', line 145

def keypair_name(server)
  server.key_name
end

#new_key(name) ⇒ Object


93
94
95
96
# File 'lib/novawhiz.rb', line 93

def new_key(name)
  key = @os.create_keypair :name => replace_period_with_dash(name)
  key
end

#public_ip(server) ⇒ Object


122
123
124
# File 'lib/novawhiz.rb', line 122

def public_ip(server)
  server.accessipv4
end

#replace_period_with_dash(name) ⇒ Object


85
86
87
88
89
90
91
# File 'lib/novawhiz.rb', line 85

def replace_period_with_dash(name)
  # bugbug - handle hp cloud bug where key names with two "." can't be deleted.
  # when writing and reading keys, convert "." to "-".
  # remove this code when this openstack bug is fixed
  nameclean = name.gsub(".","-")
  return nameclean
end

#run_command(creds, cmd) ⇒ Object


185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/novawhiz.rb', line 185

def run_command(creds, cmd)
  res = Net::SSH::Simple.sync do
    ssh(creds[:ip], '/bin/bash', :user => creds[:user], :key_data => [creds[:key]], :timeout => 3600, :global_known_hosts_file => ['/dev/null'], :user_known_hosts_file => ['/dev/null']) do |e,c,d|
      case e
      when :start
        c.send_data "#{cmd}\n"
        c.eof!
      when :stdout        # read the input line-wise (it *will* arrive fragmented!)

        (@buf ||= '') << d
        while line = @buf.slice!(/(.*)\r?\n/)
          yield line.chomp if block_given?
        end
      when :stderr
        (@buf ||= '') << d
        while line = @buf.slice!(/(.*)\r?\n/)
          yield line.chomp if block_given?
        end
      end
    end
  end
  if res.exit_code != 0
    raise "command #{cmd} failed on #{creds[:ip]}:\n#{res.stdout}\n#{res.stderr}"
  end
  res
end

#server_by_name(name) ⇒ Object


134
135
136
137
138
139
# File 'lib/novawhiz.rb', line 134

def server_by_name(name)
  @os.servers.each do |s|
    return @os.server(s[:id]) if s[:name] == name
  end
  nil
end

#server_exists(name) ⇒ Object


171
172
173
174
# File 'lib/novawhiz.rb', line 171

def server_exists(name)
  s = server_by_name name
  return true if s
end

#server_listObject


141
142
143
# File 'lib/novawhiz.rb', line 141

def server_list()
  return @os.servers
end

#wait(timeout, interval = 10) ⇒ Object


126
127
128
129
130
131
132
# File 'lib/novawhiz.rb', line 126

def wait(timeout, interval=10)
  while timeout > 0 do
    return if yield
    sleep interval
    timeout -= interval
  end
end

#write_key(key, key_dir = File.expand_path('~/.ssh/hpcloud-keys/az-2.region-a.geo-1/')) ⇒ Object


108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/novawhiz.rb', line 108

def write_key(key, key_dir = File.expand_path('~/.ssh/hpcloud-keys/az-2.region-a.geo-1/'))
  begin
    FileUtils.mkdir_p(key_dir) unless File.exists?(key_dir)
    keyfile_path = key_dir + "/"  + key[:name]
    File.open(keyfile_path, "w") do |f|
      f.write(key[:private_key])
      f.close
    end
    File.chmod(0600,keyfile_path)
  rescue
    raise "Error with writing key at: #{keyfile_path}"
  end
end