Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove queue serialization #13722

Merged
merged 1 commit into from
Mar 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,13 @@ def scan_job_create(entity)
check_policy_prevent(:request_containerimage_scan, entity, :raw_scan_job_create)
end

def raw_scan_job_create(entity)
def raw_scan_job_create(target_class, target_id = nil)
target_class, target_id = target_class.class.name, target_class.id if target_class.kind_of?(ContainerImage)
Copy link
Member

@kbrock kbrock Mar 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks.
This allows us to be backward compatible and to not require a migration.

Job.create_job(
"ManageIQ::Providers::Kubernetes::ContainerManager::Scanning::Job",
:name => "Container image analysis",
:target_class => entity.class.name,
:target_id => entity.id,
:target_class => target_class,
:target_id => target_id,
:zone => my_zone,
:miq_server_host => MiqServer.my_server.hostname,
:miq_server_guid => MiqServer.my_server.guid,
Expand All @@ -174,7 +175,7 @@ def check_policy_prevent(policy_event, event_target, cb_method)
:class_name => self.class.to_s,
:instance_id => id,
:method_name => :check_policy_prevent_callback,
:args => [cb_method, event_target],
:args => [cb_method, event_target.class.name, event_target.id],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at other check_policy_prevent functions (host, vm_or_template), they don't take target, just *cb_method and use [*cb_method] here.
You could the same and then scan_job_create would have to do

     check_policy_prevent(:request_containerimage_scan, :raw_scan_job_create, entity.class.name, entity.id)

I like that better because one can understand scan_job_create -> raw_scan_job_create path without looking into the policy methods.
Plus less obstacles to dedup these functions one day... (AFAICT the main diffrence is in building inputs hashes for MiqEvent.raise_evm_event.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @cben here. And, unlike those other poorly documented examples, you could extend your useful comment here to indicate that *cb_method includes the callback method name (symbol) and callback method args.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cben So you are suggesting accepting any input and copying them straight to the queue?

I view the purpose of methods like these to dictate and protect the messages that go onto the queue.

If you are going to document what parameters are going into *cb_method then why not just document it by having actual variables?

But I was having trouble understanding the full implications of comment from @cben - sorry if I totally botched it.

Copy link
Contributor

@cben cben Mar 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I view the purpose of methods like these to dictate and protect the messages that go onto the queue.

Good point. The ability to understand scan_job_create -> raw_scan_job_create without thinking about how check_policy_prevent() works might actually be a drawback :-|
However, if you read the following, without knowing what exactly check_policy_prevent() does:

   def scan_job_create(entity)
     check_policy_prevent(:request_containerimage_scan,
                          :raw_scan_job_create, entity.class.name, entity.id)
   end

isn't it "obvious" that a raw_scan_job_create(name, id) callback is being queued?
(What one misses by not looking into check_policy_prevent() is that there is another level of queuing first.)
And if not obvious, could it be improved by naming (e.g. "queue_if_policy_doesnt_prevent" or something)?

P.S. I wish there was a way to actually prevent AR serializion, instead of constrained coding style that "dictates and protects"... I know it's a hard problem.

If you are going to document what parameters are going into *cb_method then why not just document it by having actual variables?

👍 The function is trying to be generic, but could at least take ..., cb_method, *cb_args.

Anyway, feel free to override me. My suggestion was purely cosmetic.
E.g. @simon3z's concern about migration, if it conflicts, is more important.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. I wish there was a way to actually prevent AR serializion, instead of constrained coding style that "dictates and protects"... I know it's a hard problem.

would having a (dev mode?) functionality of preventing args of a type (application record?) from going in the queue work?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@moolitayer Does check_policy_prevent_callback work?

I think I'm misreading the code before your change:

    cb = {
      :class_name  => self.class.to_s,
      :instance_id => id,
      :method_name => :check_policy_prevent_callback,
      :args        => [cb_method, event_target],
      :server_guid => MiqServer.my_guid
    }

def check_policy_prevent_callback(*action, _status, _message, result)
end

I don't see how this callback can produce an action, status, message, and result. I only see 2 arguments. None of which are event_target. I must be mistaking how callback works.

I expected something closer to :args => [*cb_method, nil, nil, event_target]

Then this PR would proceed by changing event_target into class/id...

Copy link
Author

@moolitayer moolitayer Mar 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kbrock I hope I understand your comment

Turns out in ruby:

def strange_example(*a,b,c)
  puts "[#{a}] [#{b}] [#{c}]"
end

> strange_example(1,2,3,4)
[[1, 2]] [3] [4]

> strange_example(1,2)
[[]] [1] [2]

Also I tested this code (which wasn't introduced here).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kbrock actually that wasn't the correct answer,
This is where the parameters for the callback are built:

cb_args = miq_callback[:args] + [state, msg, result]

you wrote that line actually :bowtie:

Copy link
Member

@kbrock kbrock Mar 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UGH - totally

(to be fair, I only modified that line. but sure enough, my name is on it)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I wan't saying you should have remembered it since 2015 😄 just commenting on the coincidence ⭐

:server_guid => MiqServer.my_guid
}
enforce_policy(event_target, policy_event, {}, { :miq_callback => cb }) unless policy_event.nil?
Expand Down
2 changes: 1 addition & 1 deletion spec/models/job_proxy_dispatcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@
context "with container and vms jobs" do
before(:each) do
@jobs = (@vms + @repo_vms).collect(&:scan)
@jobs += @container_images.map { |img| img.ext_management_system.raw_scan_job_create(img) }
@jobs += @container_images.map { |img| img.ext_management_system.raw_scan_job_create(img.class, img.id) }
@dispatcher = JobProxyDispatcher.new
end

Expand Down
2 changes: 1 addition & 1 deletion spec/models/job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@
:container_image, :ext_management_system => @ems_k8s, :name => 'test',
:image_ref => "docker://3629a651e6c11d7435937bdf41da11cf87863c03f2587fa788cf5cbfe8a11b9a"
)
@image_scan_job = @image.ext_management_system.raw_scan_job_create(@image)
@image_scan_job = @image.ext_management_system.raw_scan_job_create(@image.class, @image.id)
end

context "#target_entity" do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,31 @@ def fetch_oscap_arf
@ems = FactoryGirl.create(:ems_kubernetes, :hostname => 'hostname')
end

it "#initialize" do
image = FactoryGirl.create(:container_image, :ext_management_system => @ems)
job = @ems.raw_scan_job_create(image)
expect(job).to have_attributes(
:dispatch_status => "pending",
:state => "waiting_to_start",
:status => "ok",
:message => "process initiated",
:target_class => "ContainerImage"
)
context "#initialize" do
it "Creates a new scan job" do
image = FactoryGirl.create(:container_image, :ext_management_system => @ems)
job = @ems.raw_scan_job_create(image.class, image.id)
expect(job).to have_attributes(
:dispatch_status => "pending",
:state => "waiting_to_start",
:status => "ok",
:message => "process initiated",
:target_class => "ContainerImage"
)
end

it "Is backward compatible with #13722" do
# https://github.com/ManageIQ/manageiq/pull/13722
image = FactoryGirl.create(:container_image, :ext_management_system => @ems)
job = @ems.raw_scan_job_create(image)
expect(job).to have_attributes(
:dispatch_status => "pending",
:state => "waiting_to_start",
:status => "ok",
:message => "process initiated",
:target_class => "ContainerImage"
)
end
end
end

Expand Down Expand Up @@ -112,7 +127,7 @@ def fetch_oscap_arf
@job.signal(:data, '<summary><syncmetadata></syncmetadata></summary>')
end

@job = @ems.raw_scan_job_create(@image)
@job = @ems.raw_scan_job_create(@image.class, @image.id)
allow(MiqQueue).to receive(:put_unless_exists) do |args|
@job.signal(*args[:args])
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@

it ".scan_job_create" do
image = FactoryGirl.create(:container_image, :ext_management_system => @ems)
job = @ems.raw_scan_job_create(image)
job = @ems.raw_scan_job_create(image.class, image.id)

expect(job.state).to eq("waiting_to_start")
expect(job.status).to eq("ok")
Expand Down