Class: Chef::Provider::RightScript

Inherits:
Chef::Provider show all
Includes:
Mixin::Command
Defined in:
lib/chef/providers/right_script_provider.rb

Overview

RightScript chef provider.

Instance Method Summary collapse

Instance Method Details

#action_runObject

runs the RightScript in a child process.

Return

true

Always return true

Raise

RightScale::Exceptions::Exec

Invalid process exit status



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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/chef/providers/right_script_provider.rb', line 51

def action_run
  nickname        = @new_resource.name
  display_version = @new_resource.display_version || ''
  run_started_at  = Time.now
  platform        = RightScale::Platform
  current_state   = all_state

  # 1. Setup audit and environment
  begin
     = ::File.join(RightScale::AgentConfig.cloud_state_dir, 'meta-data-cache.rb')
    #metadata does not exist on all clouds, hence the conditional
    load() if ::File.exists?()
  rescue Exception => e
    ::Chef::Log.info("Could not load cloud metadata; script will execute without metadata in environment!")
    RightScale::Log.error("Failed loading cloud metadata", e)
  end
  begin
    user_data = ::File.join(RightScale::AgentConfig.cloud_state_dir, 'user-data.rb')
    #user-data should always exist
    load(user_data)
  rescue Exception => e
    ::Chef::Log.info("Could not load user data; script will execute without user data in environment!")
    RightScale::Log.error("Failed loading user data", e)
  end
  @new_resource.parameters.each { |key, val| ENV[key] = val }

  # Provide the customary RightScript environment metadata
  ENV['ATTACH_DIR'] = ENV['RS_ATTACH_DIR'] = @new_resource.cache_dir
  ENV['RS_ALREADY_RUN']                    = current_state[:chef_state].past_scripts.include?(nickname) ? 'true' : nil
  ENV['RS_REBOOT']                         = current_state[:cook_state].reboot? ? 'true' : nil

  # RightScripts expect to find RS_DISTRO, RS_DIST and RS_ARCH in the environment.
  # Massage the distro name into the format they expect (all lower case, one word, no release info).
  if platform.linux?
    distro = platform.flavor.downcase
    ENV['RS_DISTRO'] = distro
    ENV['RS_DIST']   = distro
    arch_info=`uname -i`.downcase + `uname -m`.downcase
    if arch_info =~ /i386/ || arch_info =~ /i686/
        ENV['RS_ARCH'] = "i386"
    elsif arch_info =~ /64/
        ENV['RS_ARCH'] = "x86_64"
    else
        ENV['RS_ARCH'] = "unknown"
    end
  end

  # Add Cloud-Independent Attributes
  if node[:cloud]
    ENV['RS_CLOUD_PROVIDER'] = node[:cloud][:provider]
    instance_public_ip = node[:cloud][:public_ipv4] || (node[:cloud][:public_ips].is_a?(Array) && node[:cloud][:public_ips].first)
    if instance_public_ip
      ENV['RS_PUBLIC_IP'] = instance_public_ip
    else
      ::Chef::Log.info("Could not retrieve instance public IP")
    end
    instance_private_ip = node[:cloud][:local_ipv4] || (node[:cloud][:private_ips].is_a?(Array) && node[:cloud][:private_ips].first)
    if instance_private_ip
      ENV['RS_PRIVATE_IP'] = instance_private_ip
    else
      ::Chef::Log.info("Could not retrieve instance private IP")
    end
  else
    ::Chef::Log.info("Could not retrieve cloud information")
  end

  # 2. Fork and wait
  # Bit of a hack here just so we can create a new audit section each time a RightScript is run
  name_and_version = display_version.empty? ?
    "'#{nickname}'" :
    "'#{nickname}' #{display_version}"

  Chef::Log.logger.create_new_section("RightScript: #{name_and_version}")

  status = run_script_file(@new_resource.source_file)
  duration = Time.now - run_started_at
  # Security paranoia: wipe inputs from env so next script can't see them
  @new_resource.parameters.each { |key, _| ENV[key] = nil }

  # 3. Handle process exit status
  if status
    ::Chef::Log.info("Script exit status: #{status.exitstatus}")
  else
    ::Chef::Log.info("Script exit status: UNKNOWN; presumed success")
  end
  ::Chef::Log.info("Script duration: #{duration}")

  if !status || status.success?
    current_state[:chef_state].record_script_execution(nickname)
    @new_resource.updated_by_last_action(true)

    # a script may have requested reboot via rs_shutdown command line
    # tool. if the script requested immediate shutdown then we must call
    # exit here to interrupt the Chef converge (assuming any subsequent
    # boot recipes are pending). otherwise, defer shutdown until scripts/
    # recipes finish or another script escalates to an immediate shutdown.
    exit 0 if RightScale::ShutdownRequestProxy.instance.immediately?
  else
    raise RightScale::Exceptions::Exec,
          "RightScript < #{name_and_version} > #{RightScale::SubprocessFormatting.reason(status)}"
  end

  true
end

#load_current_resourceObject

No concept of a ‘current’ resource for RightScript execution, this is a no-op

Return

true

Always return true



40
41
42
# File 'lib/chef/providers/right_script_provider.rb', line 40

def load_current_resource
  true
end