class Chef::Provisioning::FogDriver::Providers::SoftLayer
Constants
- POST_SCRIPT_DONE
Public Class Methods
compute_options_for(provider, id, config)
click to toggle source
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 26 def self.compute_options_for(provider, id, config) new_compute_options = {} new_compute_options[:provider] = provider new_config = { driver_options: { compute_options: new_compute_options } } new_defaults = { driver_options: { compute_options: Fog.credentials }, machine_options: { bootstrap_options: {} } } result = Cheffish::MergedConfig.new(new_config, config, new_defaults) id ||= "" new_defaults[:machine_options][:bootstrap_options][:datacenter] = id unless id.empty? [result, id] end
Public Instance Methods
bootstrap_options_for(machine_spec, machine_options)
click to toggle source
Calls superclass method
Chef::Provisioning::FogDriver::Driver#bootstrap_options_for
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 41 def bootstrap_options_for(machine_spec, machine_options) # probably best to only ADD options here since super class looks # for some values; for example, :key_name doesn't get saved to # chef_provisioning.reference if you remove it here. # Therefore, we remove things SoftLayer rejects in # create_many_servers just before the actual fog create calls. opts = super if opts[:key_name] key_label = opts[:key_name] opts[:key_pairs] = [compute.key_pairs.by_label(key_label)] if key_label.is_a? String end opts end
convergence_strategy_for(machine_spec, machine_options)
click to toggle source
Calls superclass method
Chef::Provisioning::FogDriver::Driver#convergence_strategy_for
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 20 def convergence_strategy_for(machine_spec, machine_options) machine_options = Cheffish::MergedConfig.new(machine_options, convergence_options: { ohai_hints: { "softlayer" => {} } }) super(machine_spec, machine_options) end
create_many_servers(num_servers, bootstrap_options, parallelizer)
click to toggle source
Calls superclass method
Chef::Provisioning::FogDriver::Driver#create_many_servers
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 58 def create_many_servers(num_servers, bootstrap_options, parallelizer) # need to filter out options that SoftLayer doesn't accept opts = bootstrap_options.dup # options are passed directly to SoftLayer API and # SoftLayer_Hardware_Server rejects requests with unrecognized # options opts.delete(:vlan) if opts[:vlan] && opts[:private_network_only] opts.keep_if do |opt, _val| ::Fog::Compute::Softlayer::Server.attributes.include?(opt) || opt =~ /private_vlan|vlan/ end # fog-softlayer defines :tags but SoftLayer_Hardware_Server rejects it... # opts.delete :tags # we hook in our own post-install script which uses userMetadata to # tell us when post-install is complete. If the user supplies their # own script it will be called by our hook before indicating # completion in userData. opts[:postInstallScriptUri] = "https://dal05.objectstorage.service.networklayer.com/v1/AUTH_b1b23a05-1c03-4961-8b08-2339886e476f/dist/sl-post-hook.sh" super(num_servers, opts, parallelizer) end
create_servers(action_handler, specs_and_options, parallelizer) { |machine_spec, server| ... }
click to toggle source
Calls superclass method
Chef::Provisioning::FogDriver::Driver#create_servers
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 115 def create_servers(action_handler, specs_and_options, parallelizer, &block) super do |machine_spec, server| machine_spec.reference["uid"] = server.uid machine_spec.reference["domain"] = server.domain machine_spec.save(action_handler) bootstrap_options = specs_and_options[machine_spec][:bootstrap_options] create_timeout = bootstrap_options[:create_timeout] || 3600 wait_for_id(action_handler, server, create_timeout) set_post_install_info(action_handler, server, bootstrap_options) yield(machine_spec, server) if block end end
creator()
click to toggle source
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 16 def creator compute_options[:softlayer_username] end
find_floating_ips(_server, _action_handler)
click to toggle source
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 82 def find_floating_ips(_server, _action_handler) [] end
request(server, path, **options)
click to toggle source
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 129 def request(server, path, **options) service = server.bare_metal? ? :hardware_server : :virtual_guest server.service.request(service, path, options) end
server_for(machine_spec)
click to toggle source
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 86 def server_for(machine_spec) if machine_spec.reference id = machine_spec.reference["server_id"] if id && (id != 0) compute.servers.get(id) else sv = compute.servers.new( uid: machine_spec.reference["uid"], name: machine_spec.name, domain: machine_spec.reference["domain"] ) Chef::Log.info("waiting for server.id") sv.wait_for_id machine_spec.reference["server_id"] = sv.id return sv end end end
servers_for(specs_and_options)
click to toggle source
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 106 def servers_for(specs_and_options) result = {} specs_and_options.each do |machine_spec, _machine_options| result[machine_spec] = server_for(machine_spec) end result end
set_post_install_info(action_handler, server, bootstrap_options)
click to toggle source
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 134 def set_post_install_info(action_handler, server, bootstrap_options) existing_user_data = request(server, server.id, query: { objectMask: "userData" }).body["userData"] Chef::Log.info("userData from SLAPI is #{existing_user_data.inspect}") if existing_user_data.is_a? Array existing_user_data = if existing_user_data.empty? "" else existing_user_data.first.fetch("value", "") end end Chef::Log.info("userData after processing is #{existing_user_data.inspect}") # VSI userData is empty; bare metal userData will be an Array if existing_user_data.empty? action_handler.report_progress("Setting userData to detect post install status.") sl_user = compute.instance_variable_get "@softlayer_username" sl_key = compute.instance_variable_get "@softlayer_api_key" service = server.bare_metal? ? "Hardware_Server" : "Virtual_Guest" ::Retryable.retryable(tries: 60, sleep: 5) do update_url = URI::HTTPS.build( userinfo: "#{sl_user}:#{sl_key}", host: "api.service.softlayer.com", path: "/rest/v3/SoftLayer_#{service}/#{server.id}/setUserMetadata" ).to_s post_install_info = <<SHELL ##POST_INSTALL_INFO POSTINST_UPDATE_URL='#{update_url}' POSTINST_REQUESTED_URL='#{bootstrap_options[:postInstallScriptUri]}' SHELL encoded_info = Base64.strict_encode64(post_install_info) Chef::Log.debug("encoded info: #{encoded_info.inspect}") res = request( server, "#{server.id}/setUserMetadata", http_method: "POST", body: [ [ encoded_info ] ] ) raise "Failed to setUserMetadata" unless (TrueClass == res.body.class) || res.body.first["value"] end end end
start_server(action_handler, machine_spec, server)
click to toggle source
Calls superclass method
Chef::Provisioning::FogDriver::Driver#start_server
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 210 def start_server(action_handler, machine_spec, server) ::Retryable.retryable(tries: 10, sleep: 2) do super end end
wait_for_id(action_handler, server, create_timeout)
click to toggle source
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 182 def wait_for_id(action_handler, server, create_timeout) return if server.id != 0 # Cannot use Fog.wait_for because it requires server.id which is # not initially available for bare metal. server.wait_for_id(create_timeout) do |srv_info| srv_id = srv_info ? srv_info["id"] : "not set yet" action_handler.report_progress "waiting for server.id on #{server.name} (#{server.uid}): #{srv_id} #{srv_info}" end end
wait_until_ready(action_handler, machine_spec, machine_options, server)
click to toggle source
Calls superclass method
Chef::Provisioning::FogDriver::Driver#wait_until_ready
# File lib/chef/provisioning/fog_driver/providers/softlayer.rb, line 193 def wait_until_ready(action_handler, machine_spec, machine_options, server) super action_handler.report_progress "waiting for post-install script on #{server.name} to finish" ::Retryable.retryable(tries: 600, sleep: 2) do action_handler.report_progress "checking post-install status on #{server.name}" res = request(server, server.id, query: "objectMask=userData") userData = res.body["userData"] value = userData.first["value"] raise "Waiting for post-install script" unless POST_SCRIPT_DONE == value end action_handler.report_progress "post-install done on #{server.name}" end