Top Level Namespace

Defined Under Namespace

Modules: Apt, Gems, Ohai, RightLink, RightScale, RunShell, Yum Classes: Chef, Class, FalseClass, File, NilClass, Numeric, Object, Symbol, TrueClass

Constant Summary collapse

CLOUDS_BASE_DIR =

Copyright © 2011 RightScale Inc

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File.join(File.dirname(__FILE__), 'clouds')
INSTANCE_BASE_DIR =

Copyright © 2009-2011 RightScale Inc

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File.join(File.dirname(__FILE__), 'instance')
EXCLUDED_OHAI_PLUGINS =

Copyright © 2009-2011 RightScale Inc

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[ 'linux::block_device' ]
COOK_BASE_DIR =

Load files required by then runner process This process is responsible for running Chef It’s a short lived process that runs one Chef converge then dies It talks back to the RightLink agent using the command protocol

File.join(File.dirname(__FILE__), 'cook')
HOST =

host/port are constants for Google Compute Engine.

'metadata'
PORT =
80
SHEBANG_REGEX =
/^#!/
CERT_FILE =

Location for injected certificate

'/var/lib/waagent/Certificates.pem'
ISSUER_STATE_KEY =

Windows changes the ST=CA portion of our issuer name to S=CA at some point.

platform.windows? ? 'S' : 'ST'
BASE_RIGHT_CHEF_LIB_DIR_PATH =
File.normalize_path(File.dirname(__FILE__))
BASE_RIGHT_CHEF_PROVIDER_DIR_PATH =
File.join(BASE_RIGHT_CHEF_LIB_DIR_PATH, 'providers')
DYNAMIC_WINDOWS_CHEF_PROVIDERS_PATH =
File.join(BASE_RIGHT_CHEF_LIB_DIR_PATH, 'windows')
STATIC_WINDOWS_CHEF_PROVIDERS_PATH =
File.join(BASE_RIGHT_CHEF_PROVIDER_DIR_PATH, 'windows')
WINDOWS_CHEF_PROVIDERS_PATHS =
[STATIC_WINDOWS_CHEF_PROVIDERS_PATH, DYNAMIC_WINDOWS_CHEF_PROVIDERS_PATH]
REPO_CONF_GENERATORS_BASE_DIR =

Copyright © 2009-2011 RightScale Inc

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File.join(File.dirname(__FILE__), 'repo_conf_generators')
CONFIG_DRIVE_MOUNTPOINT =

Copyright © 2011 RightScale Inc

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File.join(ENV['ProgramW6432'], 'RightScale', 'Mount', 'Softlayer').gsub('/', '\\')
EUCA_HOST =

eucalyptus can use any DNS name for host but port is known and we are constrained to requiring a specific DNS name by default.

'euca-metadata'
EUCA_PORT =
8773

Instance Method Summary collapse

Instance Method Details

#add_server(key, data) ⇒ Object

Adds RightScale server FQDNs to the rightscale_deprecated servers Mash

NOTE: This is a hack to convert the RS_(server) tokens into something more intuative. Hopefully this will be removed when we stop using EC2 userdata.

Parameters

key(String)

RightScale server token from user-data

data(String):

FQDN for the RightScale server



54
55
56
57
58
59
60
61
62
63
# File 'lib/chef/plugins/rightscale.rb', line 54

def add_server(key, data)
  rightscale_deprecated[:server] = Mash.new unless rightscale_deprecated.has_key?(:server)
  server_names = {
    "RS_sketchy" => "sketchy",
    "RS_syslog" => "syslog",
    "RS_lumberjack" => "lumberjack",
    "RS_server" => "core"
  }
  rightscale_deprecated[:server][server_names[key]] = data unless (server_names[key] == nil)
end

#cloud_metadata_generation_commandObject

Assembles the command line needed to regenerate cloud metadata on demand.



35
36
37
38
39
# File 'lib/clouds/clouds/ec2.rb', line 35

def 
  ruby_path = File.normalize_path(AgentConfig.ruby_cmd)
  rs_cloud_path = File.normalize_path(Gem.bin_path('right_link', 'cloud'))
  return "#{ruby_path} #{rs_cloud_path} --action write_cloud_metadata"
end

#create_user_metadata_leaf(tree_climber, data) ⇒ Object

Parses softlayer user metadata into a hash.

Parameters

tree_climber(MetadataTreeClimber)

tree climber

data(String)

raw data

Return

result(Hash)

Hash-like leaf value



78
79
80
81
82
83
84
85
86
87
# File 'lib/clouds/clouds/ec2.rb', line 78

def (tree_climber, data)
  result = tree_climber.create_branch
  data = data.strip
  if data =~ SHEBANG_REGEX
    ::RightScale::CloudUtilities.(data.gsub("\r\n", "\n"), "\n", result)
  else
    ::RightScale::CloudUtilities.(data, '&', result)
  end
  result
end

#derive_bcast(ipaddr, ipmask, zero_bcast = false) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/chef/plugins/windows/network.rb', line 26

def derive_bcast(ipaddr, ipmask, zero_bcast = false)
  begin
    ipaddr_int = ipaddr.split(".").collect{ |x| x.to_i}.pack("C4").unpack("N").first
    ipmask_int = ipmask.split(".").collect{ |x| x.to_i}.pack("C4").unpack("N").first
    if zero_bcast
      bcast_int = ipaddr_int & ipmask_int
    else
      bcast_int = ipaddr_int | 2 ** 32 - ipmask_int - 1
    end
    bcast = [bcast_int].pack("N").unpack("C4").join(".")
    return bcast
  rescue
    return nil
  end
end

#dhcp_lease_providerObject

Searches for a file containing dhcp lease information.



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
# File 'lib/clouds/clouds/cloudstack.rb', line 27

def dhcp_lease_provider
  if platform.windows?
    timeout = Time.now + 20 * 60  # 20 minutes
    logger = option(:logger)
    while Time.now < timeout
      ipconfig_data = `ipconfig /all`
      match_result = ipconfig_data.match(/DHCP Server.*\: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/)
      unless match_result.nil? || match_result[1].nil?
        return match_result[1]
      end
      # it may take time to resolve the DHCP Server for this instance, so sleepy wait.
      logger.info("ipconfig /all did not contain any DHCP Servers. Retrying in 10 seconds...")
      sleep 10
    end
  else
    leases_file = %w{/var/lib/dhcp/dhclient.eth0.leases /var/lib/dhcp3/dhclient.eth0.leases /var/lib/dhclient/dhclient-eth0.leases /var/lib/dhclient-eth0.leases /var/lib/dhcpcd/dhcpcd-eth0.info}.find{|dhcpconfig| File.exist?(dhcpconfig)}
    unless leases_file.nil?
      lease_file_content = File.read(leases_file)

      dhcp_lease_provider_ip = lease_file_content[/DHCPSID='(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'/, 1]
      return dhcp_lease_provider_ip unless dhcp_lease_provider_ip.nil?

      # leases are appended to the lease file, so to get the appropriate dhcp lease provider, we must grab
      # the info from the last lease entry.
      #
      # reverse the content and reverse the regex to find the dhcp lease provider from the last lease entry
      lease_file_content.reverse!
      dhcp_lease_provider_ip = lease_file_content[/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) reifitnedi-revres-pchd/, 1]
      return dhcp_lease_provider_ip.reverse unless dhcp_lease_provider_ip.nil?
    end
  end

  # no known defaults so we must fail at this point.
  fail("Cannot determine dhcp lease provider for cloudstack instance")
end

#encaps_lookup(encap) ⇒ Object



21
22
23
24
# File 'lib/chef/plugins/windows/network.rb', line 21

def encaps_lookup(encap)
  return "Ethernet" if encap.eql?("Ethernet 802.3")
  encap
end

#get_dataObject

add all ‘RS_’ tokens in medadata file, but perform translation for server names



111
112
113
114
115
116
117
118
119
# File 'lib/chef/plugins/rightscale.rb', line 111

def get_data
  data_array = File.open(RightScale::MetaDataFile)
  data_array.each do |d|
    key, data = d.split('=')
    key.strip!
    data.strip!
    rightscale_deprecated[key.sub(/RS_/,'')] = data unless add_server(key,data) 
  end
end

#get_data_from_ec2_user_dateObject

add all ‘RS_’ tokens in userdata, but perform translation for server names



81
82
83
84
85
86
87
# File 'lib/chef/plugins/rightscale.rb', line 81

def get_data_from_ec2_user_date
  data_array = ec2[:userdata].split('&')
  data_array.each do |d|
    key, data = d.split('=')
    rightscale_deprecated[key.sub(/RS_/,'')] = data unless add_server(key,data) 
  end
end

#is_current_cloud?Boolean

Determines if the current instance is running on cloudstack.

Returns:

  • (Boolean)


105
106
107
108
109
110
111
112
113
# File 'lib/clouds/clouds/ec2.rb', line 105

def is_current_cloud?
  if ohai = @options[:ohai_node]
    if ::RightScale::CloudUtilities.has_mac?(ohai, "fe:ff:ff:ff:ff:ff")
      source = create_dependency_type(:user_metadata, :metadata_source)
      return ::RightScale::CloudUtilities.(source.host, source.port)
    end
  end
  false
end

#on_rightscale_ec2_platform?Boolean

Detect if RightScale platform is running on ec2 cloud

Returns

true

If ec2 Mash exists amd RightScale tokens found in user-data

false

Otherwise

Returns:

  • (Boolean)


75
76
77
78
# File 'lib/chef/plugins/rightscale.rb', line 75

def on_rightscale_ec2_platform?
  return false if (ec2 == nil || ec2[:userdata].match(/RS_/) == nil) # only ec2 supported
  true
end

#on_rightscale_platform?Boolean

Detect if RightScale platform is running on other cloud. currently only rackspace is supported.

Returns

true

If ec2 Mash exists amd RightScale tokens found in user-data

false

Otherwise

Returns:

  • (Boolean)


106
107
108
# File 'lib/chef/plugins/rightscale.rb', line 106

def on_rightscale_platform?
  File.exists?(RightScale::MetaDataFile)
end

#select_rs_metadata(_, path, metadata_source_type, query_result, previous_metadata) ⇒ Object

Selects metadata from multiple sources in support of serverizing existing long-running instances. Stops merging metadata as soon as RS_ variables are found.



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
# File 'lib/clouds/clouds/ec2.rb', line 44

def (_, path, , query_result, )
  # note that clouds can extend this cloud and change the user root option.
   = option([:user_metadata, :metadata_tree_climber, :root_path]) unless 
   = false
   = query_result
  if path == 
    # metadata from file source is delimited by newline while metadata from http
    # is delimited by ampersand (unless shebang is present for legacy reasons).
    # convert ampersand-delimited to newline-delimited for easier comparison
    # with regular expression.
    .strip!
    query_result.strip!
    if ( == 'metadata_sources/file_metadata_source') || (query_result =~ SHEBANG_REGEX)
       = query_result.gsub("\r\n", "\n").strip
    else
       = query_result.gsub("&", "\n").strip
    end

    # will query next source only if current metadata does not contain RS_
     = !( =~ /^RS_rn_id/i)
     = ( + "\n" + ).strip
     = .gsub("\n", "&") unless  =~ SHEBANG_REGEX
  end
  return {:query_next_metadata => , :merged_metadata => }
end

#update_detailsObject

Updates details of cloudstack instance.



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/clouds/clouds/none.rb', line 64

def update_details
  details = {}
  if ohai = @options[:ohai_node]
    if platform.windows?
      details[:public_ip] = ::RightScale::CloudUtilities.ip_for_windows_interface(ohai, 'public')
      details[:private_ip] = ::RightScale::CloudUtilities.ip_for_windows_interface(ohai, 'private')
    else
      details[:public_ip] = ::RightScale::CloudUtilities.ip_for_interface(ohai, :eth0)
      details[:private_ip] = ::RightScale::CloudUtilities.ip_for_interface(ohai, :eth1)
    end
  end
  return details
end

#wait_for_instance_readyObject



58
59
60
61
62
63
64
65
66
# File 'lib/clouds/clouds/azure.rb', line 58

def wait_for_instance_ready
  if platform.linux?
    STDOUT.puts "Waiting for instance to appear ready."
    until File.exist?(CERT_FILE) && File.mtime(CERT_FILE).to_f > platform.shell.booted_at.to_f do
      sleep(1)
    end
    STDOUT.puts "Instance appears ready."
  end
end