Class: CloudProviders::CloudProviderInstance

Inherits:
Object
  • Object
show all
Includes:
Callbacks, Connections, Dslify
Defined in:
lib/cloud_providers/cloud_provider_instance.rb

Direct Known Subclasses

Ec2Instance, SshInstance, VmwareInstance

Instance Method Summary collapse

Methods included from Callbacks

included

Methods included from Connections

#host, #rsync, #run, #scp, #ssh, #ssh_options, #user

Constructor Details

#initialize(opts = {}, &block) ⇒ CloudProviderInstance

Returns a new instance of CloudProviderInstance.



24
25
26
27
28
29
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 24

def initialize(opts={}, &block)
  self.cloud_name= opts[:cloud].name if opts[:cloud]
  set_vars_from_options(opts)
  instance_eval(&block) if block
  loaded
end

Instance Method Details

#[](k) ⇒ Object



184
185
186
187
188
189
190
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 184

def [](k)
  if dsl_options.has_key? k
    dsl_options[k]
  else
    nil
  end
end

#[]=(k, v) ⇒ Object



192
193
194
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 192

def []=(k,v)
  dsl_options[k] = v
end

#after_bootstrapObject



245
246
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 245

def after_bootstrap
end

#after_configureObject



249
250
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 249

def after_configure
end

#before_bootstrapObject



243
244
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 243

def before_bootstrap
end

#before_configureObject



247
248
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 247

def before_configure
end

#bootstrap!(opts = {}) ⇒ Object

Bootstrap self. Bootstrap runs as root, even if user is set



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 45

def bootstrap!(opts={})
  callback :before_bootstrap
   if !bootstrapped? || opts[:force]
     old_user = user
     @user = "root"
     opts[:os] ||= os || determine_os
     if cloud && cloud.bootstrap_script
       opts[:filename] = cloud.bootstrap_script
     end
    script_file = Provision::Bootstrapper.bootstrap_script(opts)
    scp(:source => script_file, :destination => "/tmp")
    output = run("chmod +x /tmp/determine_os.sh; /bin/sh /tmp/#{File.basename(script_file)}")
    @user = old_user
    output.chomp if output
  end
  callback :after_bootstrap
end

#bootstrapped?Boolean

Determine if the node is bootstrapped

Returns:

  • (Boolean)


122
123
124
125
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 122

def bootstrapped?
  # @bootstrapped ||= !run('if [ -f /var/poolparty/bootstrapped ]; then echo "YES"; fi').match(/YES/).nil?
  @bootstrapped ||= !run('if [ -f /var/poolparty/bootstrapped ]; then echo "YES"; fi').chomp.empty? || false
end

#cloud_provider(opts = {}, &block) ⇒ Object

Raises:

  • (StandardError)


38
39
40
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 38

def cloud_provider(opts={}, &block)
  raise StandardError.new("cloud_provider has not been implemented for this CloudProviderInstance ")
end

#configure!(opts = {}) ⇒ Object

Configure the node

Raises:

  • (StandardError)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 64

def configure!(opts={})
  ddputs("Configuring: #{self.name}")
  bootstrap! unless bootstrapped?
  callback :before_configure
  raise StandardError.new("You must pass in a cloud to configure an instance") unless cloud
  cloud.compile(self)        
  
  # scp(:source       => keypair.full_filepath, 
  #     :destination  => "/etc/poolparty/keys/#{keypair.basename}")
  
  FileUtils.mkdir_p cloud.tmp_path/"etc"/"poolparty" unless File.directory?(cloud.tmp_path/"etc"/"poolparty")
  FileUtils.mkdir_p cloud.tmp_path/"etc"/"poolparty"/"keys" unless File.directory?(cloud.tmp_path/"etc"/"poolparty"/"keys")
  
  FileUtils.cp keypair.full_filepath, cloud.tmp_path/"etc"/"poolparty"/"keys"/keypair.basename
  File.open(cloud.tmp_path/"etc"/"poolparty"/"cloud_name", "w") {|f| f << cloud.name }
  
  pack_clouds_dot_rb_and_expected_directories
  
  dputs("Rsyncing #{cloud.tmp_path/"*"}")
  rsync(:source => cloud.tmp_path/"*", :destination => "/")
  run(cloud.dependency_resolver.compile_command)
  callback :after_configure
end

#determine_osObject

Determine the os Default to ubuntu Send the determine_os.sh script to the node and run it remotely



115
116
117
118
119
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 115

def determine_os
  scp(:source => Provision::Bootstrapper.determine_os_script, :destination => "/tmp")
  o = run("chmod +x /tmp/determine_os.sh; /bin/sh /tmp/determine_os.sh").chomp
  o.empty? ? :ubuntu : o
end

#eachObject

hash like methods



180
181
182
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 180

def each
  dsl_options.each{ |k,v| yield k,v }
end

#elapsed_runtimeObject



230
231
232
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 230

def elapsed_runtime
  Time.now.to_i - launching_time.to_time.to_i
end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


196
197
198
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 196

def has_key?(key)
  dsl_options.has_key?(key)
end

#keypair(n = keypair_name) ⇒ Object

Returns an instance of Keypair You can pass either a filename which will be searched for in ~/.ec2/ and ~/.ssh/ or you can pass a full filepath



34
35
36
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 34

def keypair(n=keypair_name)
  cloud_provider.keypair(n)
end

#keysObject



200
201
202
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 200

def keys
  dsl_options.keys
end

#loadedObject

Callbacks



235
236
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 235

def loaded
end

#on_all_callbacks(call_time, *args, &block) ⇒ Object



238
239
240
241
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 238

def on_all_callbacks(call_time, *args, &block)
  cloud.callback call_time if cloud
  super
end

#os(sym = nil) ⇒ Object Also known as: platform

get the os, if it’s not declared



94
95
96
97
98
99
100
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 94

def os(sym=nil)
  if sym
    dsl_options[:os] = sym
  else
    dsl_options[:os] ||= determine_os.to_sym
  end
end

#pack_clouds_dot_rb_and_expected_directoriesObject



103
104
105
106
107
108
109
110
111
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 103

def pack_clouds_dot_rb_and_expected_directories
  %w(lib plugins).each do |dir|
    if File.directory?(d = cloud.clouds_dot_rb_dir/dir)
      dputs("Adding local path: #{d}")
      FileUtils.cp_r d, cloud.tmp_path/cloud.base_config_directory, :verbose => true, :remove_destination => true # req'd for symlinks
    end
  end
  FileUtils.cp cloud.clouds_dot_rb_file, cloud.tmp_path/"/etc/poolparty/clouds.rb"
end

#pending?Boolean

Is this instance pending?

Returns:

  • (Boolean)


218
219
220
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 218

def pending?
  !(status =~ /pending/).nil?
end

#refresh!Object

Refresh the node with fresh data from the cloud provider. This is often usefully to update a recently launched instance, in case you want to trigger new behavior once the state changes ot ‘running’ and an ip is assigned Added rescue, but not sure if this is a proper fix yet. Will need to test on live instances to ensure



173
174
175
176
177
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 173

def refresh!
  dsl_options = cloud_provider.describe_instance(:instance_id => self.instance_id).dsl_options rescue {}
  self.dsl_options.merge!(dsl_options)
  self
end

#running?Boolean

Is this instance running?

Returns:

  • (Boolean)


214
215
216
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 214

def running?
  !(status =~ /running/).nil?
end

#terminate!Object

Terminate self



89
90
91
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 89

def terminate!
  cloud_provider.terminate_instance!(:instance_id => instance_id)
end

#terminated?Boolean

Has this instance been terminated?

Returns:

  • (Boolean)


226
227
228
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 226

def terminated?
  !(status =~ /terminated/).nil?
end

#terminating?Boolean

Is this instance terminating?

Returns:

  • (Boolean)


222
223
224
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 222

def terminating?
  !(status =~ /shutting/).nil?
end

#to_hashObject



208
209
210
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 208

def to_hash
  dsl_options
end

#valid?Boolean

The instances is only valid if there is an internal_ip and a name

Returns:

  • (Boolean)


253
254
255
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 253

def valid?
  (internal_ip.nil? || name.nil?) ? false : true
end

#valuesObject



204
205
206
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 204

def values
  dsl_options.values
end

#wait_for_port(port, opts = {}) ⇒ Object

Wait for port Test if the port is open and catch failures in the connection Options

public_ip || default public_ip
retry_times || 5


132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 132

def wait_for_port(port, opts={})
  ip          = opts.delete(:public_ip)   || public_ip
  retry_times = opts.delete(:retry_times) || 10
  pause_time  = opts.delete(:pause_time)  || 1
  
  retry_times.times do |i| 
    if is_port_open?(ip, port, opts)
      return true
    else
      sleep pause_time
    end
  end
  false
end

#wait_for_public_ip(timeout = 60) ⇒ Object

Wait for a public ip to be assigned, refreshing the instance data from the cloud provider on each query Default timeout value of 60 seconds, can be overriden by passing :timeout=>seconds



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/cloud_providers/cloud_provider_instance.rb', line 149

def wait_for_public_ip(timeout=60)
  ddputs("Waiting for public ip")
  begin
    Timeout::timeout(timeout) do
      loop do
        self.refresh!
        ddputs("After refreshing, the public_ip is: #{public_ip}")
        return public_ip if valid_ip?(public_ip)
        print '.'
        sleep 2
      end
    end
  rescue Timeout::Error
    return false
  end
end