diff --git a/app/models/embedded_ansible_worker.rb b/app/models/embedded_ansible_worker.rb index 2c6fa0c3517..05b49e7c924 100644 --- a/app/models/embedded_ansible_worker.rb +++ b/app/models/embedded_ansible_worker.rb @@ -17,6 +17,7 @@ def start_runner Thread.exit end end + nil # return no pid end def kill diff --git a/app/models/miq_worker.rb b/app/models/miq_worker.rb index 227ef77658e..00e9971c6c2 100644 --- a/app/models/miq_worker.rb +++ b/app/models/miq_worker.rb @@ -335,6 +335,10 @@ def self.close_pg_sockets_inherited_from_parent end def start_runner + ENV['MIQ_SPAWN_WORKERS'] ? start_runner_via_spawn : start_runner_via_fork + end + + def start_runner_via_fork self.class.before_fork pid = fork(:cow_friendly => true) do self.class.after_fork @@ -346,6 +350,23 @@ def start_runner pid end + def self.build_command_line(guid) + command_line = "#{Gem.ruby} #{runner_script} --heartbeat --guid=#{guid} #{name}" + ENV['APPLIANCE'] ? "nice #{nice_increment} #{command_line}" : command_line + end + + def self.runner_script + script = ManageIQ.root.join("lib/workers/bin/run_single_worker.rb") + raise "script not found: #{script}" unless File.exist?(script) + script + end + + def start_runner_via_spawn + pid = Kernel.spawn(self.class.build_command_line(guid), :out => "/dev/null", :err => [Rails.root.join("log", "evm.log"), "a"]) + Process.detach(pid) + pid + end + def start self.pid = start_runner save diff --git a/app/models/miq_worker/runner.rb b/app/models/miq_worker/runner.rb index 4dd26790e4d..31ca970cf71 100644 --- a/app/models/miq_worker/runner.rb +++ b/app/models/miq_worker/runner.rb @@ -11,6 +11,7 @@ class TemporaryFailure < RuntimeError INTERRUPT_SIGNALS = ["SIGINT", "SIGTERM"] + # DELETE ME OPTIONS_PARSER_SETTINGS = [ [:guid, 'EVM Worker GUID', String], ] diff --git a/lib/workers/bin/run_single_worker.rb b/lib/workers/bin/run_single_worker.rb index 5a446dc576c..5b22aeff807 100644 --- a/lib/workers/bin/run_single_worker.rb +++ b/lib/workers/bin/run_single_worker.rb @@ -23,6 +23,10 @@ options[:dry_run] = val end + opts.on("-g=GUID", "--guid=GUID", "Find an existing worker record instead of creating") do |val| + options[:guid] = val + end + opts.on("-h", "--help", "Displays this help") do puts opts exit @@ -52,7 +56,12 @@ worker_class = worker_class.constantize worker_class.before_fork unless options[:dry_run] - worker = worker_class.create_worker_record + worker = if options[:guid] + worker_class.find_by!(:guid => options[:guid]) + else + worker_class.create_worker_record + end + begin worker.class::Runner.start_worker(:guid => worker.guid) ensure diff --git a/spec/models/miq_worker_spec.rb b/spec/models/miq_worker_spec.rb index bf458efb772..704d0218cbe 100644 --- a/spec/models/miq_worker_spec.rb +++ b/spec/models/miq_worker_spec.rb @@ -29,6 +29,32 @@ def all_workers expect(result.command_line).to eq "renice -n 5 -p 123" end + context ".build_command_line" do + before do + allow(MiqGenericWorker).to receive(:nice_increment).and_return("+10") + end + + it "with ENV['APPLIANCE']" do + begin + old_env = ENV.delete('DATABASE_URL') + ENV['APPLIANCE'] = 'true' + w = FactoryGirl.build(:miq_generic_worker) + cmd = w.class.build_command_line(123) + expect(cmd).to start_with("nice +10") + expect(cmd).to end_with("MiqGenericWorker") + ensure + # ENV['x'] = nil deletes the key because ENV accepts only string values + ENV['APPLIANCE'] = old_env + end + end + + it "without ENV['APPLIANCE']" do + w = FactoryGirl.build(:miq_generic_worker) + cmd = w.class.build_command_line(123) + expect(cmd).to_not start_with("nice +10") + end + end + context ".has_required_role?" do def check_has_required_role(worker_role_names, expected_result) allow(described_class).to receive(:required_roles).and_return(worker_role_names)