Class: Sunzi::Cloud::Linode

Inherits:
Base
  • Object
show all
Defined in:
lib/sunzi/cloud/linode.rb

Instance Method Summary collapse

Methods inherited from Base

#ask, #assign_config_and_dns, #initialize, #instance_config_path, #proceed?, #provider_config_path, #setup, #teardown

Methods included from Utility

#abort_with, #exit_with, #say

Constructor Details

This class inherits a constructor from Sunzi::Cloud::Base

Instance Method Details

#assign_apiObject



139
140
141
# File 'lib/sunzi/cloud/linode.rb', line 139

def assign_api
  @api = ::Linode.new(:api_key => @config['api_key'])
end

#choose(key, result, options = {}) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/sunzi/cloud/linode.rb', line 110

def choose(key, result, options = {})
  label_method = options[:label_method] || :label
  id    = :"#{key}id"
  label = :"#{key}_#{label_method}"

  # Filters
  if options[:filter] and @config[options[:filter]]
    result = result.select{|i| i.label.match Regexp.new(@config[options[:filter]], Regexp::IGNORECASE) }
  end

  result.each{|i| say "#{i.send(id)}: #{i.send(label_method)}" }
  @attributes[id] = ask("which #{key}?: ", Integer) {|q| q.in = result.map(&id); q.default = result.first.send(id) }
  @attributes[label] = result.find{|i| i.send(id) == @attributes[id] }.send(label_method)
end

#do_setupObject



6
7
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
39
40
41
42
43
44
45
46
47
48
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
79
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
107
108
# File 'lib/sunzi/cloud/linode.rb', line 6

def do_setup
  @sshkey = File.read(File.expand_path(@config['root_sshkey_path'])).chomp
  if @sshkey.match(/\n/)
    abort_with "RootSSHKey #{@sshkey.inspect} must not be multi-line! Check inside \"#{@config['root_sshkey_path']}\""
  end

  choose(:plan, @api.avail.linodeplans)
  choose(:datacenter, @api.avail.datacenters, :label_method => :location)
  choose(:distribution, @api.avail.distributions, :filter => 'distributions_filter')
  choose(:kernel, @api.avail.kernels, :filter => 'kernels_filter')

  # Choose swap size
  @swap_size = ask('swap size in MB? (default: 256MB): ', Integer) { |q| q.default = 256 }

  # Go ahead?
  proceed?

  # Create
  say "creating a new linode..."
  result = @api.linode.create(
    :DatacenterID => @attributes[:datacenterid],
    :PlanID => @attributes[:planid],
    :PaymentTerm => @config['payment_term'])
  @linodeid = result.linodeid
  say "created a new instance: linodeid = #{@linodeid}"

  result = @api.linode.list.select{|i| i.linodeid == @linodeid }.first
  @totalhd = result.totalhd

  # Update settings
  say "Updating settings..."
  @group = @config['group'][@env]
  settings = { :LinodeID => @linodeid, :Label => @name, :lpm_displayGroup => @group }
  settings.update(@config['settings']) if @config['settings']
  @api.linode.update(settings)

  # Create a root disk
  say "Creating a root disk..."
  result = @api.linode.disk.createfromdistribution(
    :LinodeID => @linodeid,
    :DistributionID => @attributes[:distributionid],
    :Label => "#{@attributes[:distribution_label]} Image",
    :Size => @totalhd - @swap_size,
    :rootPass => @config['root_pass'],
    :rootSSHKey => @sshkey
  )
  @root_diskid = result.diskid

  # Create a swap disk
  say "Creating a swap disk..."
  result = @api.linode.disk.create(
    :LinodeID => @linodeid,
    :Label => "#{@swap_size}MB Swap Image",
    :Type => 'swap',
    :Size => @swap_size
  )
  @swap_diskid = result.diskid

  # Create a config profiile
  say "Creating a config profile..."
  result = @api.linode.config.create(
    :LinodeID => @linodeid,
    :KernelID => @attributes[:kernelid],
    :Label => "#{@attributes[:distribution_label]} Profile",
    :DiskList => [ @root_diskid, @swap_diskid ].join(',')
  )
  @config_id = result.configid

  # Add a private IP
  say "Adding a private IP..."
  result = @api.linode.ip.list(:LinodeID => @linodeid)
  @public_ip = result.first.ipaddress
  result = @api.linode.ip.addprivate(:LinodeID => @linodeid)
  result = @api.linode.ip.list(:LinodeID => @linodeid).find{|i| i.ispublic == 0 }
  @private_ip = result.ipaddress

  @instance = {
    :linode_id => @linodeid,
    :env => @env,
    :host => @host,
    :fqdn => @fqdn,
    :label => @name,
    :group => @group,
    :plan_id =>             @attributes[:planid],
    :datacenter_id =>       @attributes[:datacenterid],
    :datacenter_location => @attributes[:datacenter_location],
    :distribution_id =>     @attributes[:distributionid],
    :distribution_label =>  @attributes[:distribution_label],
    :kernel_id =>           @attributes[:kernelid],
    :kernel_label =>        @attributes[:kernel_label],
    :swap_size => @swap_size,
    :totalhd => @totalhd,
    :root_diskid => @root_diskid,
    :swap_diskid => @swap_diskid,
    :config_id => @config_id,
    :public_ip => @public_ip,
    :private_ip => @private_ip,
  }

  # Boot
  say 'Done. Booting...'
  @api.linode.boot(:LinodeID => @linodeid)
end

#do_teardownObject



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/sunzi/cloud/linode.rb', line 125

def do_teardown
  @linode_id_hash = { :LinodeID => @instance[:linode_id] }

  # Shutdown first or disk deletion will fail
  say 'shutting down...'
  @api.linode.shutdown(@linode_id_hash)
  # Wait until linode.shutdown has completed
  wait_for('linode.shutdown')

  # Delete the instance
  say 'deleting linode...'
  @api.linode.delete(@linode_id_hash.merge(:skipChecks => 1))
end

#ip_keyObject



143
144
145
# File 'lib/sunzi/cloud/linode.rb', line 143

def ip_key
  :public_ip
end

#wait_for(action) ⇒ Object



147
148
149
150
151
# File 'lib/sunzi/cloud/linode.rb', line 147

def wait_for(action)
  begin
    sleep 3
  end until @api.linode.job.list(@linode_id_hash).find{|i| i.action == action }.host_success == 1
end