Project

General

Profile

Actions

Bug #27066

closed

Clearing content source from hostgroup fails with error to 'unable to flatten recursive array'

Added by William Clark almost 5 years ago. Updated almost 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
-
Target version:
Difficulty:
Triaged:
Yes
Fixed in Releases:
Found in Releases:

Description

Description of problem:

When installation medium is defined for a hostgroup and the user tries to clear the content source, it will fail due to 'ArgumentError: tried to flatten recursive array'

How reproducible:

100%

Steps to reproduce:

1. Create a hostgroup.
2. Assign content source, lifecycle environment, and content view.
3. Assign installation medium.
4. Attempt to clear the content source and save the hostgroup, observe the error 'tried to flatten recursive array'

Further details:

Working through the top of the stack trace,

ArgumentError: tried to flatten recursive array
/opt/theforeman/tfm-ror51/root/usr/share/gems/gems/activemodel-5.1.6/lib/active_model/errors.rb:175:in `flatten'
/opt/theforeman/tfm-ror51/root/usr/share/gems/gems/activemodel-5.1.6/lib/active_model/errors.rb:175:in `size'
/opt/theforeman/tfm-ror51/root/usr/share/gems/gems/activemodel-5.1.6/lib/active_model/errors.rb:201:in `empty?'
/opt/theforeman/tfm-ror51/root/usr/share/gems/gems/activemodel-5.1.6/lib/active_model/validations.rb:406:in `run_validations!'
....

The issue occurs here:

/opt/theforeman/tfm-ror51/root/usr/share/gems/gems/activemodel-5.1.6/lib/active_model/errors.rb:175:in `size'

def size
values.flatten.size
end
alias :count :size

We are checking the size of the errors array produced by _run_validation_callbacks to determine whether it is empty, but it fails because the size function is not able to handle the case where errors is a recursive array.

Adding the below line to /opt/theforeman/tfm-ror51/root/usr/share/gems/gems/activemodel-5.1.6/lib/active_model/validations.rb:406:in `run_validations!'

def run_validations!
_run_validate_callbacks
logger.info errors.inspect # added this line
errors.empty?
end

I can observe the errors array in the logs:

[I|app|6b90d] #<ActiveModel::Errors:0x00007ff2dd253f50 @base=#<Hostgroup id: 7, name: "Parent2", created_at: "2019-03-28 17:31:09", updated_at: "2019-03-28 17:31:09", environment_id: nil, operatingsystem_id: 1, architecture_id: 1, medium_id: nil, ptable_id: nil, root_pass: "", puppet_ca_proxy_id: nil, use_image: nil, image_file: nil, ancestry: nil, vm_defaults: nil, subnet_id: nil, domain_id: nil, puppet_proxy_id: nil, title: "Parent2", realm_id: nil, compute_profile_id: nil, content_source_id: nil, grub_pass: "", content_view_id: 2, lifecycle_environment_id: 3, lookup_value_matcher: "hostgroup=Parent2", kickstart_repository_id: 58, subnet6_id: nil, pxe_loader: "PXELinux BIOS", description: "", compute_resource_id: nil, openscap_proxy_id: nil>, @messages={:name=>[], :base=>["Please select a content source before assigning a kickstart repository", [...]]}, @details={:base=>[{:error=>"Please select a content source before assigning a kickstart repository"}, {:error=>["Please select a content source before assigning a kickstart repository", [...]]}]}>

So the resolution of the issue should be to display the actual error message "Please select a content source before assigning a kickstart repository" rather than the cryptic "unable to flatten recursive array".

I have tried to rewrite the size function to handle the recursive array:

def size
values.flatten(1).size # only flattening one level
end
alias :count :size

But this just results in the next error occurring as other components are unable to handle the recursive array either:

ArgumentError: recursive array join
/usr/share/foreman/app/controllers/application_controller.rb:302:in `join'
/usr/share/foreman/app/controllers/application_controller.rb:302:in `process_error'
/usr/share/foreman/app/controllers/hostgroups_controller.rb:70:in `update'
/opt/theforeman/tfm-ror51/root/usr/share/gems/gems/actionpack-5.1.6/lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
....

Requesting guidance on determining whether it's appropriate to make changes to /usr/share/foreman/app/controllers/application_controller.rb:302:in `join' as well or if it's better (and how) to determine why the errors array is recursive in the first place.

Actions

Also available in: Atom PDF