class Chef::Application::Solo

Attributes

chef_client_json[R]

Public Instance Methods

configure_legacy_mode!() click to toggle source
# File lib/chef/application/solo.rb, line 258
def configure_legacy_mode!
  if Chef::Config[:daemonize]
    Chef::Config[:interval] ||= 1800
  end

  # supervisor processes are enabled by default for interval-running processes but not for one-shot runs
  if Chef::Config[:client_fork].nil?
    Chef::Config[:client_fork] = !!Chef::Config[:interval]
  end

  Chef::Application.fatal!(unforked_interval_error_message) if !Chef::Config[:client_fork] && Chef::Config[:interval]

  if Chef::Config[:recipe_url]
    cookbooks_path = Array(Chef::Config[:cookbook_path]).detect { |e| Pathname.new(e).cleanpath.to_s =~ /\/cookbooks\/*$/ }
    recipes_path = File.expand_path(File.join(cookbooks_path, ".."))

    if Chef::Config[:delete_entire_chef_repo]
      Chef::Log.trace "Cleanup path #{recipes_path} before extract recipes into it"
      FileUtils.rm_rf(recipes_path, :secure => true)
    end
    Chef::Log.trace "Creating path #{recipes_path} to extract recipes into"
    FileUtils.mkdir_p(recipes_path)
    tarball_path = File.join(recipes_path, "recipes.tgz")
    fetch_recipe_tarball(Chef::Config[:recipe_url], tarball_path)
    Mixlib::Archive.new(tarball_path).extract(Chef::Config.chef_repo_path, perms: false, ignore: /^\.$/)
  end

  # json_attribs shuld be fetched after recipe_url tarball is unpacked.
  # Otherwise it may fail if points to local file from tarball.
  if Chef::Config[:json_attribs]
    config_fetcher = Chef::ConfigFetcher.new(Chef::Config[:json_attribs])
    @chef_client_json = config_fetcher.fetch_json
  end

  # Disable auditing for solo
  Chef::Config[:audit_mode] = :disabled
end
reconfigure() click to toggle source
Calls superclass method Chef::Application#reconfigure
# File lib/chef/application/solo.rb, line 231
def reconfigure
  super

  load_dot_d(Chef::Config[:solo_d_dir]) if Chef::Config[:solo_d_dir]

  set_specific_recipes

  Chef::Config[:solo] = true

  if !Chef::Config[:solo_legacy_mode]
    # Because we re-parse ARGV when we move to chef-client, we need to tidy up some options first.
    ARGV.delete("--ez")

    # For back compat reasons, we need to ensure that we try and use the cache_path as a repo first
    Chef::Log.trace "Current chef_repo_path is #{Chef::Config.chef_repo_path}"

    if !Chef::Config.has_key?(:cookbook_path) && !Chef::Config.has_key?(:chef_repo_path)
      Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Chef::Config[:cache_path])
    end

    Chef::Config[:local_mode] = true
    Chef::Config[:listen] = false
  else
    configure_legacy_mode!
  end
end
run() click to toggle source

Get this party started

# File lib/chef/application/solo.rb, line 219
def run
  setup_signal_handlers
  reconfigure
  for_ezra if Chef::Config[:ez]
  if !Chef::Config[:solo_legacy_mode]
    Chef::Application::Client.new.run
  else
    setup_application
    run_application
  end
end
run_application() click to toggle source
# File lib/chef/application/solo.rb, line 300
def run_application
  if !Chef::Config[:client_fork] || Chef::Config[:once]
    # Run immediately without interval sleep or splay
    begin
      run_chef_client(Chef::Config[:specific_recipes])
    rescue SystemExit
      raise
    rescue Exception => e
      Chef::Application.fatal!("#{e.class}: #{e.message}", e)
    end
  else
    interval_run_chef_client
  end
end
setup_application() click to toggle source
# File lib/chef/application/solo.rb, line 296
def setup_application
  Chef::Daemon.change_privilege
end

Private Instance Methods

fetch_recipe_tarball(url, path) click to toggle source
# File lib/chef/application/solo.rb, line 361
def fetch_recipe_tarball(url, path)
  Chef::Log.trace("Download recipes tarball from #{url} to #{path}")
  File.open(path, "wb") do |f|
    open(url) do |r|
      f.write(r.read)
    end
  end
end
for_ezra() click to toggle source
# File lib/chef/application/solo.rb, line 317
  def for_ezra
    puts <<-EOH
For Ezra Zygmuntowicz:
  The man who brought you Chef Solo
  Early contributor to Chef
  Kind hearted open source advocate
  Rest in peace, Ezra.
EOH
  end
interval_run_chef_client() click to toggle source
# File lib/chef/application/solo.rb, line 327
def interval_run_chef_client
  if Chef::Config[:daemonize]
    Chef::Daemon.daemonize("chef-client")
  end

  loop do
    begin

      sleep_sec = 0
      sleep_sec += rand(Chef::Config[:splay]) if Chef::Config[:splay]
      sleep_sec += Chef::Config[:interval] if Chef::Config[:interval]
      if sleep_sec != 0
        Chef::Log.trace("Sleeping for #{sleep_sec} seconds")
        sleep(sleep_sec)
      end

      run_chef_client
      if !Chef::Config[:interval]
        Chef::Application.exit! "Exiting", 0
      end
    rescue SystemExit => e
      raise
    rescue Exception => e
      if Chef::Config[:interval]
        Chef::Log.error("#{e.class}: #{e}")
        Chef::Log.trace("#{e.class}: #{e}\n#{e.backtrace.join("\n")}")
        retry
      else
        Chef::Application.fatal!("#{e.class}: #{e.message}", e)
      end
    end
  end
end
unforked_interval_error_message() click to toggle source
# File lib/chef/application/solo.rb, line 370
def unforked_interval_error_message
  "Unforked chef-client interval runs are disabled in Chef 12." +
    "\nConfiguration settings:" +
    "#{"\n  interval  = #{Chef::Config[:interval]} seconds" if Chef::Config[:interval]}" +
    "\nEnable chef-client interval runs by setting `:client_fork = true` in your config file or adding `--fork` to your command line options."
end