diff --git a/app/models/miq_server/worker_management/kubernetes.rb b/app/models/miq_server/worker_management/kubernetes.rb index 4a87de6822b..bb9fb528cac 100644 --- a/app/models/miq_server/worker_management/kubernetes.rb +++ b/app/models/miq_server/worker_management/kubernetes.rb @@ -21,20 +21,31 @@ def sync_from_system end def sync_starting_workers - MiqWorker.find_all_starting.reject(&:rails_worker?).each do |worker| + starting = MiqWorker.find_all_starting + + # Non-rails workers cannot set their own miq_worker record to started once they + # have finished initializing. Check for any starting non-rails workers whose + # pod is running and mark the miq_worker as started. + starting.reject(&:rails_worker?).each do |worker| worker_pod = current_pods[worker.system_uid] next if worker_pod.nil? - worker.update!(:status => "started") if worker_pod[:running] + worker.update!(:status => MiqWorker::STATUS_STARTED) if worker_pod[:running] end + + starting.reload end def sync_stopping_workers - MiqWorker.find_all_stopping.reject(&:rails_worker?).each do |worker| + stopping = MiqWorker.find_all_stopping + + stopping.reject(&:rails_worker?).each do |worker| next if current_pods.key?(worker[:system_uid]) worker.update!(:status => MiqWorker::STATUS_STOPPED) end + + stopping.reload end def enough_resource_to_start_worker?(_worker_class) diff --git a/spec/models/miq_server/worker_management/kubernetes_spec.rb b/spec/models/miq_server/worker_management/kubernetes_spec.rb index f6532587722..407dde8cf19 100644 --- a/spec/models/miq_server/worker_management/kubernetes_spec.rb +++ b/spec/models/miq_server/worker_management/kubernetes_spec.rb @@ -210,6 +210,128 @@ end end + describe "#sync_starting_workers" do + before { MiqWorkerType.seed } + + context "podified" do + let(:rails_worker) { true } + let(:pod_name) { "1-generic-abcd" } + let(:pod_running) { true } + let(:worker) { FactoryBot.create(:miq_generic_worker, :miq_server => server, :status => status, :system_uid => pod_name) } + let(:current_pods) { {pod_name => {:label_name => pod_label, :last_state_terminated => false, :container_restarts => 0, :running => pod_running}} } + + before do + allow(worker.class).to receive(:rails_worker?).and_return(rails_worker) + server.worker_manager.current_pods = current_pods + end + + after do + server.worker_manager.current_pods.clear + end + + context "with no starting workers" do + let(:status) { MiqWorker::STATUS_STARTED } + + it "returns an empty array" do + expect(server.worker_manager.sync_starting_workers).to be_empty + end + end + + context "with a starting worker" do + let(:status) { MiqWorker::STATUS_STARTING } + + it "returns the starting worker" do + expect(server.worker_manager.sync_starting_workers).to include(worker) + end + + context "non-rails worker" do + let(:rails_worker) { false } + + context "without a pod" do + let(:current_pods) { {} } + + it "returns the worker as still starting" do + expect(server.worker_manager.sync_starting_workers).to include(worker) + end + end + + context "with a pod that is running" do + let(:pod_running) { true } + + it "marks the worker as running and returns an empty array" do + expect(server.worker_manager.sync_starting_workers).to be_empty + end + end + + context "with a pod that isn't running yet" do + let(:pod_running) { false } + + it "returns the starting worker" do + expect(server.worker_manager.sync_starting_workers).to include(worker) + end + end + end + end + end + end + + describe "#sync_stopping_workers" do + before { MiqWorkerType.seed } + + context "podified" do + let(:rails_worker) { true } + let(:pod_name) { "1-generic-abcd" } + let(:pod_running) { true } + let(:worker) { FactoryBot.create(:miq_generic_worker, :miq_server => server, :status => status, :system_uid => pod_name) } + let(:current_pods) { {pod_name => {:label_name => pod_label, :last_state_terminated => false, :container_restarts => 0, :running => pod_running}} } + + before do + allow(worker.class).to receive(:rails_worker?).and_return(rails_worker) + server.worker_manager.current_pods = current_pods + end + + after do + server.worker_manager.current_pods.clear + end + + context "with no stopping workers" do + let(:status) { MiqWorker::STATUS_STARTED } + + it "returns an empty array" do + expect(server.worker_manager.sync_stopping_workers).to be_empty + end + end + + context "with a stopping worker" do + let(:status) { MiqWorker::STATUS_STOPPING } + + it "returns the stopping worker" do + expect(server.worker_manager.sync_stopping_workers).to include(worker) + end + + context "non-rails worker" do + let(:rails_worker) { false } + + context "without a pod" do + let(:current_pods) { {} } + + it "marks the worker as stopped and returns an empty array" do + expect(server.worker_manager.sync_stopping_workers).to be_empty + end + end + + context "with a pod that is still running" do + let(:pod_running) { true } + + it "returns the stopping worker" do + expect(server.worker_manager.sync_stopping_workers).to include(worker) + end + end + end + end + end + end + context "#cleanup_orphaned_worker_rows" do context "podified" do let(:server2) { EvmSpecHelper.remote_miq_server }