Class: Rudy::Machine

Inherits:
Storable
  • Object
show all
Includes:
Gibbler::Complex, Metadata
Defined in:
lib/rudy/metadata/machine.rb

Constant Summary

Constants included from Metadata

Rudy::Metadata::COMMON_FIELDS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Metadata

#==, build_criteria, connect, create_domain, #descriptors, destroy, destroy_domain, domain, domain=, exists?, #exists?, get, get_rclass, included, #name, put, #save, select

Methods included from Huxtable

config, #config_dirname, create_domain, #current_group_name, #current_machine_address, #current_machine_bucket, #current_machine_count, #current_machine_group, #current_machine_hostname, #current_machine_image, #current_machine_name, #current_machine_os, #current_machine_size, #current_machine_user, #current_user_keypairname, #current_user_keypairpath, #defined_keypairpath, domain, domain_exists?, global, keypair_path_to_name, #known_machine_group?, ld, #ld, #le, le, li, #li, logger, reset_config, reset_global, #root_keypairname, #root_keypairpath, update_config, update_global, update_logger, #user_keypairname, #user_keypairpath

Constructor Details

#initialize(position = '01', opts = {}) ⇒ Machine

  • position

  • opts is a hash of machine options.

Valid options are:

  • :position (overridden by position arg)

  • :size

  • :os

  • :ami

  • :group

  • :keypair

  • :address



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rudy/metadata/machine.rb', line 55

def initialize(position='01', opts={})
  
  opts = {
    :size => current_machine_size,
    :os => current_machine_os,
    :ami => current_machine_image,
    :group => current_group_name,
    :keypair => root_keypairname
  }.merge opts
  
  opts[:address] = current_machine_address opts[:position] || position
  
  super Rudy::Machines::RTYPE, opts  # Rudy::Metadata#initialize
  
  @position = position
  
  # Defaults:
  @created = Time.now.utc
  @available = false
  postprocess
  
end

Instance Attribute Details

#available=(value) ⇒ Object (writeonly)

An ephemeral value which is set after checking whether the SSH daemon is running. By default this will be set to false but can be set to true to avoid checking again. See available?



41
42
43
# File 'lib/rudy/metadata/machine.rb', line 41

def available=(value)
  @available = value
end

#instanceObject (readonly)

Returns the value of attribute instance.



35
36
37
# File 'lib/rudy/metadata/machine.rb', line 35

def instance
  @instance
end

Instance Method Details

#attached_volumesObject



194
195
196
197
198
# File 'lib/rudy/metadata/machine.rb', line 194

def attached_volumes
  volumes = []
  return volumes if @instid.nil?
  Rudy::AWS::EC2::Volumes.list_by_instance( @instid) || []
end

#available?Boolean

See available attribute

Returns:

  • (Boolean)


241
# File 'lib/rudy/metadata/machine.rb', line 241

def available?; @available; end

#createObject



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/rudy/metadata/machine.rb', line 139

def create
  raise "#{name} is already running" if instance_running?
  
  # Options for Rudy::AWS::EC2::Instances#create
  opts = {
    :min  => 1,
    :size => @size,
    :ami => @ami,
    :group => @group,
    :keypair => @keypair, 
    :zone => @zone,
    :machine_data => self.generate_machine_data.to_yaml
  }
  
  ld "OPTS: #{opts.inspect}"
  
  Rudy::AWS::EC2::Instances.create(opts) do |inst|
    @instid = inst.awsid
    @created = @started = Time.now
    @state = inst.state
    # We need to be safe when creating machines because if an exception is
    # raised, instances will have been created but the calling class won't know. 
    begin
      # Assign IP address only if we have one for that position
      if @address
        # Make sure the address is associated to the current account
        if Rudy::AWS::EC2::Addresses.exists?(@address)
          li "Associating #{@address} to #{@instid}"
          Rudy::AWS::EC2::Addresses.associate(@address, @instid)
        else
          le "Unknown address: #{@address}"
        end
      end
    rescue => ex
      le "Error: #{ex.message}"
      le ex.backtrace if Rudy.debug?
    end
  end
  
  self.save
  
  sleep 1 # Eventual consistency in SimpleDB
  
  self
end

#create_mockObject



129
130
131
132
133
134
135
136
137
# File 'lib/rudy/metadata/machine.rb', line 129

def create_mock
  refresh!
  @dns_public = @dns_private = nil
  inst = Rudy::AWS::EC2::Instances.list(:running).first
  @instid = inst.awsid
  self.save :replace
  sleep 1
  self
end

#default_deviceObject



227
228
229
# File 'lib/rudy/metadata/machine.rb', line 227

def default_device
  windows? ? Rudy::DEFAULT_WINDOWS_DEVICE : Rudy::DEFAULT_LINUX_DEVICE
end

#default_fstypeObject



223
224
225
# File 'lib/rudy/metadata/machine.rb', line 223

def default_fstype
  windows? ? Rudy::DEFAULT_WINDOWS_FS : Rudy::DEFAULT_LINUX_FS
end

#destroyObject



185
186
187
188
# File 'lib/rudy/metadata/machine.rb', line 185

def destroy
  Rudy::AWS::EC2::Instances.destroy(@instid) if instance_running?
  super
end

#disksObject



91
92
93
# File 'lib/rudy/metadata/machine.rb', line 91

def disks
  Rudy::Disks.list
end

#dns_private?Boolean

Returns:

  • (Boolean)


238
# File 'lib/rudy/metadata/machine.rb', line 238

def dns_private?; !@dns_private.nil? && !@dns_private.empty?; end

#dns_public?Boolean

Returns:

  • (Boolean)


237
# File 'lib/rudy/metadata/machine.rb', line 237

def dns_public?;  !@dns_public.nil? && !@dns_public.empty?;   end

#generate_machine_dataObject



215
216
217
218
219
220
221
# File 'lib/rudy/metadata/machine.rb', line 215

def generate_machine_data
  d = {}
  [:region, :zone, :environment, :role, :position].each do |k|
    d[k] = self.send k
  end
  d
end

#get_consoleObject



100
101
102
103
104
105
106
107
108
109
# File 'lib/rudy/metadata/machine.rb', line 100

def get_console
  raise "Instance not running" unless instance_running?
  raw = Rudy::AWS::EC2::Instances.console @instid
  console = Base64.decode64(raw)
  # The linux console can include ANSI escape codes for color, 
  # clear screen etc... We strip them out to get rid of the 
  # clear specifically. Otherwise the display is messed!
  console &&= console.noansi if console.respond_to? :noansi
  console
end

#get_instanceObject



96
97
98
# File 'lib/rudy/metadata/machine.rb', line 96

def get_instance
  Rudy::AWS::EC2::Instances.get @instid
end

#get_passwordObject



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/rudy/metadata/machine.rb', line 111

def get_password
  unless windows?
    raise "Password support is Windows only (this is #{@os})" 
  end
  console = get_console
  
  raise "Console output not yet available. Please wait." if console.nil?
  
  unless console.match(/<Password>(.+)<\/Password>/m)  
    # /m, match multiple lines
    raise "Password not yet available. Is this a custom AMI?"
  end  
  
  encrtypted_text = ($1 || '').strip
  k = Rye::Key.from_file root_keypairpath
  k.decrypt encrtypted_text
end

#linux?Boolean

Returns:

  • (Boolean)


234
# File 'lib/rudy/metadata/machine.rb', line 234

def linux?; os? 'linux'; end

#os?(v) ⇒ Boolean

Returns:

  • (Boolean)


232
# File 'lib/rudy/metadata/machine.rb', line 232

def os?(v); @os.to_s == v.to_s; end

#postprocessObject



78
79
80
81
# File 'lib/rudy/metadata/machine.rb', line 78

def postprocess
  @position &&= @position.to_s.rjust(2, '0')
  @os &&= @os.to_sym
end

#rboxObject



87
88
89
# File 'lib/rudy/metadata/machine.rb', line 87

def rbox
  r = Rudy::Routines::Handlers::RyeTools.create_box self
end

#refresh!(metadata = true) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/rudy/metadata/machine.rb', line 200

def refresh!(=true)
  ## Updating the metadata isn't necessary
  super() if  # update metadata
  @instance = get_instance
  if @instance.is_a?(Rudy::AWS::EC2::Instance)
    @dns_public, @dns_private = @instance.dns_public, @instance.dns_private
    @state = @instance.state
    save :replace
  elsif @instance.nil?
    @awsid = @dns_public = @dns_private = nil
    @state = 'rogue'
    # Don't save it b/c it's possible the EC2 server is just down. 
  end
end

#restartObject



190
191
192
# File 'lib/rudy/metadata/machine.rb', line 190

def restart
  Rudy::AWS::EC2::Instances.restart(@instid) if instance_running?
end

#solaris?Boolean

Returns:

  • (Boolean)


235
# File 'lib/rudy/metadata/machine.rb', line 235

def solaris?; os? 'solaris'; end

#to_s(*args) ⇒ Object



83
84
85
# File 'lib/rudy/metadata/machine.rb', line 83

def to_s(*args)
  [self.name.bright, self.instid, self.dns_public].join '; '
end

#windows?Boolean

Returns:

  • (Boolean)


233
# File 'lib/rudy/metadata/machine.rb', line 233

def windows?; os? 'windows'; end