Hello again,
I did manage to apply those two commits manually:
https://github.com/chef/chef/commit/d99e497874e7d08f017376717aa38a4c8d7fecd5
https://github.com/chef/chef/commit/6c10604f1e8e9b557b69449b484df3aae47ee468
omitting a few lines related to some intermediate versions.
Forking is working correctly, the result is visualized in attached munin
grapph. I also attach the diff result.
Such modified client has been used on about 80 servers for over 2
months. The only problem I noticed is that if client run fails, the
stacktrace.out file only contains stacktrace from the parent process.
Child stacktrace is printed out to stderr (it's not included in logs,
visible only while executing the manual, single run). I've made some
custom modifications comparing files with chef 11.12, but I think the
result is not yet what we really expect. If you want to look at it,
please let me know.
If you decide to backport the package, I would suggest to add one small
feature (from newer versions) by chance - I really miss the file_edited?
method in Chef::Util::FileEdit. It's just one getter, the diff is also
attached.
--
Greetings,
Piotr Pańczyk
________________________________
Asseco Business Solutions S.A.
ul. Konrada Wallenroda 4c
20-607 Lublin
tel.: +48 81 535 30 00
fax: +48 81 535 30 05
Sąd Rejonowy Lublin-Wschód w Lublinie z siedzibą w Świdniku
VI Wydział Gospodarczy Krajowego Rejestru Sądowego
KRS 0000028257
NIP 522-26-12-717
kapitał zakładowy 167 090 965,00 zł (w całości opłacony)
www.assecobs.pl
________________________________
Powyższa korespondencja przeznaczona jest wyłącznie dla osoby lub podmiotu, do
którego jest adresowana i może zawierać informacje o charakterze poufnym lub
zastrzeżonym. Nieuprawnione wykorzystanie informacji zawartych w wiadomości
e-mail przez osobę lub podmiot nie będący jej adresatem jest zabronione
odpowiednimi przepisami prawa. Odbiorca korespondencji, który otrzymał ją
omyłkowo, proszony jest o niezwłoczne zawiadomienie nadawcy drogą elektroniczną
lub telefonicznie i usunięcie tej treści z poczty elektronicznej. Dziękujemy.
Asseco Business Solutions S.A.
________________________________
Weź pod uwagę ochronę środowiska, zanim wydrukujesz ten e-mail.
________________________________
This information is intended only for the person or entity to which it is
addressed and may contain confidential and/or privileged material. Unauthorized
use of this information by person or entity other than the intended recipient
is prohibited by law. If you received this by mistake, please immediately
contact the sender by e-mail or by telephone and delete this information from
any computer. Thank you. Asseco Business Solutions S.A.
________________________________
Please consider your environmental responsibility before printing this e-mail.
--- chef-10.12.0.orig/lib/chef/config.rb
+++ chef-10.12.0/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
--- chef-10.12.0.orig/lib/chef/daemon.rb
+++ chef-10.12.0/lib/chef/daemon.rb
@@ -24,6 +24,7 @@ class Chef
class Daemon
class << self
attr_accessor :name
+ attr_accessor :forked_child
# Daemonize the current process, managing pidfiles and process uid/gid
#
@@ -46,7 +47,7 @@ class Chef
$stdout.reopen("/dev/null", "a")
$stderr.reopen($stdout)
save_pid_file
- at_exit { remove_pid_file }
+ at_exit { remove_pid_file unless forked_child }
rescue NotImplementedError => e
Chef::Application.fatal!("There is no fork: #{e.message}")
end
--- chef-10.12.0.orig/lib/chef/client.rb
+++ chef-10.12.0/lib/chef/client.rb
@@ -135,48 +135,29 @@ class Chef
end
# Do a full run for this Chef::Client. Calls:
+ # * do_run
#
- # * run_ohai - Collect information about the system
- # * build_node - Get the last known state, merge with local changes
- # * register - If not in solo mode, make sure the server knows about this client
- # * sync_cookbooks - If not in solo mode, populate the local cache with the node's cookbooks
- # * converge - Bring this system up to date
- #
+ # This provides a wrapper around #do_run allowing the
+ # run to be optionally forked.
# === Returns
- # true:: Always returns true.
+ # boolean:: Return value from #do_run. Should always returns true.
def run
- run_context = nil
-
- Chef::Log.info("*** Chef #{Chef::VERSION} ***")
- enforce_path_sanity
- run_ohai
- register unless Chef::Config[:solo]
- build_node
-
- begin
-
- run_status.start_clock
- Chef::Log.info("Starting Chef Run for #{node.name}")
- run_started
-
- run_context = setup_run_context
- converge(run_context)
- save_updated_node
-
- run_status.stop_clock
- Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds")
- run_completed_successfully
+ if(Chef::Config[:client_fork] && Process.respond_to?(:fork))
+ Chef::Log.info "Forking chef instance to converge..."
+ pid = fork do
+ Chef::Daemon.forked_child = true
+ Chef::Log.info "Forked instance now converging"
+ do_run
+ exit
+ end
+ Chef::Log.info "Fork successful. Waiting for new chef pid: #{pid}"
+ result = Process.waitpid2(pid)
+ raise "Forked convergence run failed" unless result.last.success?
+ Chef::Log.info "Forked child successfully reaped (pid: #{pid})"
true
- rescue Exception => e
- run_status.stop_clock
- run_status.exception = e
- run_failed
- Chef::Log.debug("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
- raise
- ensure
- run_status = nil
+ else
+ do_run
end
- true
end
@@ -333,6 +314,50 @@ class Chef
private
+ # 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
+ # * register - If not in solo mode, make sure the server knows about this client
+ # * sync_cookbooks - If not in solo mode, populate the local cache with the node's cookbooks
+ # * converge - Bring this system up to date
+ #
+ # === Returns
+ # true:: Always returns true.
+ def do_run
+ run_context = nil
+
+ Chef::Log.info("*** Chef #{Chef::VERSION} ***")
+ enforce_path_sanity
+ run_ohai
+ register unless Chef::Config[:solo]
+ build_node
+
+ begin
+ run_status.start_clock
+ Chef::Log.info("Starting Chef Run for #{node.name}")
+ run_started
+
+ run_context = setup_run_context
+ converge(run_context)
+ save_updated_node
+
+ run_status.stop_clock
+ Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds")
+ run_completed_successfully
+ true
+ rescue Exception => e
+ run_status.stop_clock
+ run_status.exception = e
+ run_failed
+ Chef::Log.debug("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
+ raise
+ ensure
+ run_status = nil
+ end
+ true
+ end
+
# Ensures runlist override contains RunListItem instances
def runlist_override_sanity_check!
@override_runlist = @override_runlist.split(',') if @override_runlist.is_a?(String)
--- chef-10.12.0.orig/lib/chef/application/client.rb
+++ chef-10.12.0/lib/chef/application/client.rb
@@ -153,6 +153,12 @@ class Chef::Application::Client < Chef::
}
}
+ option :client_fork,
+ :short => "-f",
+ :long => "--[no-]fork",
+ :description => "Fork client",
+ :boolean => true
+
attr_reader :chef_client_json
def initialize
--- chef-10.12.0.orig/lib/chef/application/solo.rb
+++ chef-10.12.0/lib/chef/application/solo.rb
@@ -122,6 +122,12 @@ class Chef::Application::Solo < Chef::Ap
}
}
+ option :client_fork,
+ :short => "-f",
+ :long => "--[no-]fork",
+ :description => "Fork client",
+ :boolean => true
+
attr_reader :chef_solo_json
def initialize
--- chef-10.12.0.orig/lib/chef/util/file_edit.rb
+++ chef-10.12.0/lib/chef/util/file_edit.rb
@@ -36,6 +36,11 @@ class Chef
raise ArgumentError, "File is blank" unless (@contents = File.new(@original_pathname).readlines).length > 0
end
+ # return if file has been edited
+ def file_edited?
+ @file_edited
+ end
+
#search the file line by line and match each line with the given regex
#if matched, replace the whole line with newline.
def search_file_replace_line(regex, newline)
_______________________________________________
Pkg-ruby-extras-maintainers mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-ruby-extras-maintainers