[DRE-commits] [chef] 03/03: Converge via fork
Antonio Terceiro
terceiro at moszumanska.debian.org
Sat Jun 13 18:47:30 UTC 2015
This is an automated email from the git hooks/post-receive script.
terceiro pushed a commit to branch patch-queue/debian/wheezy
in repository chef.
commit c37ae6f5b740d4e0ea19145765d42f1696d8d981
Author: Antonio Terceiro <terceiro at debian.org>
Date: Sat Feb 21 23:30:49 2015 -0300
Converge via fork
contains bits and pieces of the following upstream commits:
eab92691df5665994c888f3727eecc3577fb5f69
3772ff9857e9fd69e2d5ea3339189d1143123c50
d637073f6c53ff83c098a4f22598b77a7b975962
07ea110f8694b5b3a36fb936e7eaa46a9ce86050
---
lib/chef/application/client.rb | 8 ++++++--
lib/chef/application/solo.rb | 7 ++++++-
lib/chef/client.rb | 44 ++++++++++++++++++++++++++++++++++++++++++
lib/chef/config.rb | 1 +
lib/chef/daemon.rb | 17 +++++++++++++++-
lib/chef/exceptions.rb | 1 +
6 files changed, 74 insertions(+), 4 deletions(-)
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index e6806c0..889192f 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -153,6 +153,12 @@ class Chef::Application::Client < Chef::Application
}
}
+ option :client_fork,
+ :short => "-f",
+ :long => "--fork",
+ :description => "Fork client",
+ :boolean => true
+
attr_reader :chef_client_json
def initialize
@@ -272,7 +278,6 @@ class Chef::Application::Client < Chef::Application
rescue Exception => e
if Chef::Config[:interval]
Chef::Log.error("#{e.class}: #{e}")
- Chef::Application.debug_stacktrace(e)
Chef::Log.error("Sleeping for #{Chef::Config[:interval]} seconds before trying again")
unless SELF_PIPE.empty?
client_sleep Chef::Config[:interval]
@@ -282,7 +287,6 @@ class Chef::Application::Client < Chef::Application
end
retry
else
- Chef::Application.debug_stacktrace(e)
Chef::Application.fatal!("#{e.class}: #{e.message}", 1)
end
ensure
diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb
index 1844880..78ab57b 100644
--- a/lib/chef/application/solo.rb
+++ b/lib/chef/application/solo.rb
@@ -122,6 +122,12 @@ class Chef::Application::Solo < Chef::Application
}
}
+ option :client_fork,
+ :short => "-f",
+ :long => "--fork",
+ :description => "Fork client",
+ :boolean => true
+
attr_reader :chef_solo_json
def initialize
@@ -222,7 +228,6 @@ class Chef::Application::Solo < Chef::Application
sleep Chef::Config[:interval]
retry
else
- Chef::Application.debug_stacktrace(e)
Chef::Application.fatal!("#{e.class}: #{e.message}", 1)
end
ensure
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 55fc674..820d9d0 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -135,6 +135,49 @@ class Chef
end
# Do a full run for this Chef::Client. Calls:
+ # * do_run
+ #
+ # This provides a wrapper around #do_run allowing the
+ # run to be optionally forked.
+ # === Returns
+ # boolean:: Return value from #do_run. Should always returns true.
+ def run
+ if(Chef::Config[:client_fork] && Process.respond_to?(:fork))
+ Chef::Log.info "Forking chef instance to converge..."
+ pid = fork do
+ client_solo = Chef::Config[:solo] ? "chef-solo" : "chef-client"
+ $0 = "#{client_solo} worker: ppid=#{Process.ppid};start=#{Time.new.strftime("%R:%S")};"
+ begin
+ Chef::Log.debug "Forked instance now converging"
+ do_run
+ rescue Exception => e
+ exit 1
+ else
+ exit 0
+ end
+ end
+ Chef::Log.debug "Fork successful. Waiting for new chef pid: #{pid}"
+ result = Process.waitpid2(pid)
+ handle_child_exit(result)
+ Chef::Log.debug "Forked child successfully reaped (pid: #{pid})"
+ true
+ else
+ do_run
+ end
+ end
+
+ def handle_child_exit(pid_and_status)
+ status = pid_and_status[1]
+ return true if status.success?
+ message = if status.signaled?
+ "Chef run process terminated by signal #{status.termsig} (#{Signal.list.invert[status.termsig]})"
+ else
+ "Chef run process exited unsuccessfully (exit code #{status.exitstatus})"
+ end
+ raise Exceptions::ChildConvergeError, message
+ end
+
+ # Do a full run for this Chef::Client. Calls:
#
# * run_ohai - Collect information about the system
# * build_node - Get the last known state, merge with local changes
@@ -171,6 +214,7 @@ class Chef
run_status.stop_clock
run_status.exception = e
run_failed
+ Chef::Application.debug_stacktrace(e)
Chef::Log.debug("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
raise
ensure
diff --git a/lib/chef/config.rb b/lib/chef/config.rb
index dce9631..3de9ff4 100644
--- a/lib/chef/config.rb
+++ b/lib/chef/config.rb
@@ -184,6 +184,7 @@ class Chef
run_command_stdout_timeout 120
solo false
splay nil
+ client_fork true
# Set these to enable SSL authentication / mutual-authentication
# with the server
diff --git a/lib/chef/daemon.rb b/lib/chef/daemon.rb
index bb5ccf7..d5814df 100644
--- a/lib/chef/daemon.rb
+++ b/lib/chef/daemon.rb
@@ -115,8 +115,23 @@ class Chef
# Delete the PID from the filesystem
def remove_pid_file
- FileUtils.rm(pid_file) if File.exists?(pid_file)
+ if ! forked?
+ FileUtils.rm(pid_file) if File.exists?(pid_file)
+ end
end
+
+ def forked?
+ if running? and Process.ppid == pid_from_file.to_i
+ # chef daemon is running and this process is a child of it
+ true
+ elsif not running? and Process.ppid == 1
+ # an orphaned fork, its parent becomes init, launchd, etc. after chef daemon dies
+ true
+ else
+ false
+ end
+ end
+
# Change process user/group to those specified in Chef::Config
#
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index 72c8b8f..9bb064f 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -34,6 +34,7 @@ class Chef
class Override < RuntimeError; end
class UnsupportedAction < RuntimeError; end
class MissingLibrary < RuntimeError; end
+ class ChildConvergeError < RuntimeError; end
class MissingRole < RuntimeError; end
class CannotDetermineNodeName < RuntimeError; end
class User < RuntimeError; end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/chef.git
More information about the Pkg-ruby-extras-commits
mailing list