Class: Chef::Provisioning::ConvergenceStrategy::InstallSh

Inherits:
PrecreateChefObjects show all
Defined in:
lib/chef/provisioning/convergence_strategy/install_sh.rb

Constant Summary collapse

@@install_sh_cache =
{}

Instance Attribute Summary collapse

Attributes inherited from Chef::Provisioning::ConvergenceStrategy

#config, #convergence_options

Instance Method Summary collapse

Methods inherited from PrecreateChefObjects

#chef_server, #cleanup_convergence

Methods inherited from Chef::Provisioning::ConvergenceStrategy

#cleanup_convergence

Constructor Details

#initialize(convergence_options, config) ⇒ InstallSh

Returns a new instance of InstallSh.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 10

def initialize(convergence_options, config)
  convergence_options = Cheffish::MergedConfig.new(convergence_options, {
    :client_rb_path => '/etc/chef/client.rb',
    :client_pem_path => '/etc/chef/client.pem'
  })
  super(convergence_options, config)
  @install_sh_url = convergence_options[:install_sh_url] || 'https://www.chef.io/chef/install.sh'
  @install_sh_path = convergence_options[:install_sh_path] || '/tmp/chef-install.sh'
  @chef_version = convergence_options[:chef_version]
  @prerelease = convergence_options[:prerelease]
  @install_sh_arguments = convergence_options[:install_sh_arguments]
  @bootstrap_env = convergence_options[:bootstrap_proxy] ? "http_proxy=#{convergence_options[:bootstrap_proxy]} https_proxy=$http_proxy " : ""
  @chef_client_timeout = convergence_options.has_key?(:chef_client_timeout) ? convergence_options[:chef_client_timeout] : 120*60 # Default: 2 hours
end

Instance Attribute Details

#bootstrap_envObject (readonly)

Returns the value of attribute bootstrap_env.



30
31
32
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 30

def bootstrap_env
  @bootstrap_env
end

#chef_versionObject (readonly)

Returns the value of attribute chef_version.



25
26
27
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 25

def chef_version
  @chef_version
end

#install_sh_argumentsObject (readonly)

Returns the value of attribute install_sh_arguments.



29
30
31
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 29

def install_sh_arguments
  @install_sh_arguments
end

#install_sh_pathObject (readonly)

Returns the value of attribute install_sh_path.



28
29
30
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 28

def install_sh_path
  @install_sh_path
end

#install_sh_urlObject (readonly)

Returns the value of attribute install_sh_url.



27
28
29
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 27

def install_sh_url
  @install_sh_url
end

#prereleaseObject (readonly)

Returns the value of attribute prerelease.



26
27
28
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 26

def prerelease
  @prerelease
end

Instance Method Details

#converge(action_handler, machine) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 86

def converge(action_handler, machine)
  super

  action_handler.open_stream(machine.node['name']) do |stdout|
    action_handler.open_stream(machine.node['name']) do |stderr|
      command_line = "chef-client"
      command_line << " -l #{config[:log_level].to_s}" if config[:log_level]
      machine.execute(action_handler, command_line,
        :stream_stdout => stdout,
        :stream_stderr => stderr,
        :timeout => @chef_client_timeout)
    end
  end
end

#install_sh_command_lineObject



32
33
34
35
36
37
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 32

def install_sh_command_line
  arguments = install_sh_arguments ? " #{install_sh_arguments}" : ""
  arguments << " -v #{chef_version}" if chef_version
  arguments << " -p" if prerelease
  "bash -c '#{bootstrap_env} bash #{install_sh_path}#{arguments}'"
end

#setup_convergence(action_handler, machine) ⇒ Object



39
40
41
42
43
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/chef/provisioning/convergence_strategy/install_sh.rb', line 39

def setup_convergence(action_handler, machine)
  super

  # Check for existing chef client.
  version = machine.execute_always('chef-client -v')

  # Don't do install/upgrade if a chef client exists and
  # no chef version is defined by user configs or
  # the chef client's version already matches user config
  if version.exitstatus == 0
    version = version.stdout.strip
    if !chef_version
      return
    # This logic doesn't cover the case for a client with 12.0.1.dev.0 => 12.0.1
    # so we decided to just use exact version for the time being (see comments in PR 303)
    #elsif version.stdout.strip =~ /Chef: #{chef_version}([^0-9]|$)/
    elsif version =~ /Chef: #{chef_version}$/
      Chef::Log.debug "Already installed chef version #{version}"
      return
    elsif version.include?(chef_version)
      Chef::Log.warn "Installed chef version #{version} contains desired version #{chef_version}.  " +
        "If you see this message on consecutive chef runs tighten your desired version constraint to prevent " +
        "multiple convergence."
    end
  end

  # Install chef client
  # TODO ssh verification of install.sh before running arbtrary code would be nice?
  if !convergence_options[:bootstrap_proxy] || convergence_options[:bootstrap_proxy].empty?
    @@install_sh_cache[install_sh_url] ||= Net::HTTP.get(URI(install_sh_url))
  else
    @@install_sh_cache[install_sh_url] ||= begin
      proxy_uri = URI.parse(convergence_options[:bootstrap_proxy])
      chef_uri  = URI.parse(@install_sh_url)
      proxy     = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
      req       = Net::HTTP::Get.new(chef_uri.path)
      script    = proxy.start(chef_uri.host, :use_ssl => proxy_uri.scheme == 'https') do |http|
        http.request(req)
      end
      script.body
    end
  end
  machine.write_file(action_handler, install_sh_path, @@install_sh_cache[install_sh_url], :ensure_dir => true)
  # TODO handle bad version case better
  machine.execute(action_handler, install_sh_command_line)
end