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

Support setting var type with configure_server_settings.rb #17039

Merged
merged 11 commits into from
Feb 27, 2018
Merged

Support setting var type with configure_server_settings.rb #17039

merged 11 commits into from
Feb 27, 2018

Conversation

rvalente
Copy link
Contributor

@rvalente rvalente commented Feb 23, 2018

https://bugzilla.redhat.com/show_bug.cgi?id=1550157

Changing the worker count across our environment for ems_metrics_collector_worker from 2 to 4 caused C & U to stop function because the value was change from 2 to '4'. Subsequently miq_worker.rb:149 was trying to compare current workers [0] to ['4'] and throwing a string comparison exception.

Here is the view in the advanced config screen before the fix

screen shot 2018-02-22 at 5 52 49 pm

and after

screen shot 2018-02-22 at 5 57 30 pm

Steps for Testing/QA

This will break with both the new code and the existing code.

  • ./tools/configure_server_settings.rb -s 1 -p workers/worker_base/queue_worker_base/ems_metrics_collector_worker/defaults/count -v 4

The following will cast the the value as an integer and it will update the configuration accordingly.

  • ./tools/configure_server_settings.rb -s 1 -p workers/worker_base/queue_worker_base/ems_metrics_collector_worker/defaults/count -v 4 -t integer

@rvalente
Copy link
Contributor Author

@jrafanie heh I don't trust users as much as you do, I wanted an explicit decision by the user that they were providing an Integer.

@@ -4,19 +4,26 @@

opts = Trollop.options(ARGV) do
banner "USAGE: #{__FILE__} -s <server id> -p <settings path separated by a /> -v <new value>\n" \
"Example: #{__FILE__} -d -s 1 -p reporting/history/keep_reports -v 42"
Copy link
Member

Choose a reason for hiding this comment

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

hmm, was this wrong previously? Perhaps this example should also specify a -i

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added new line because a 3rd example was added below with -i

opt :serverid, "Server Id", :short => "s", :type => :integer, :required => true
opt :path, "Path within advanced settings hash", :short => "p", :type => :string, :required => true
opt :value, "New Value for setting", :short => "v", :type => :string, :required => true
opt :integer, "Value Provided is an Integer", :short => "i", :type => :boolean, :default => false
Copy link
Member

Choose a reason for hiding this comment

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

I didn't go this route in #17043 because it's not obvious it's required for some values...

Copy link
Member

Choose a reason for hiding this comment

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

See below @rvalente, I think warning the user they're changing an existing Integer value to a String and telling them to look at the help banner to specify an integer may make this option easier to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, I'll improve the output

Copy link
Member

Choose a reason for hiding this comment

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

@rvalente Was looking at #17043 with @jrafanie and we were thinking that this approach would be better if, instead of having the boolean option :integer

opt :integer,  "Value Provided is an Integer",       :short => "i", :type => :boolean, :default => false

an option that specifies the type of the value, defaulting to string and only accepts string, integer, boolean, symbol and float. Something like this -

TYPES = %w{ string integer boolean symbol float }
opt :type,  "Type of value provided, #{TYPES.inspect}",       :short => "t",  :type => :string, :default => "string"

Trollop.die :type, "must be one of #{TYPES.inspect}" unless TYPES.include?(opts[:type])

I think it would still be good to warn if the new type of the new value is different than the old one.

Copy link
Member

Choose a reason for hiding this comment

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

I agree, this make sense to me. In this way, we're not forcing casting of strings to other types.

We default to string and use the check mentioned below to detect when we're changing a sensible default from the correct type to a String type (count from 1,2,3, etc. to "1", "2", "3") and request the user to either allow this to happen or inform them they need to specify the type.

Copy link
Member

Choose a reason for hiding this comment

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

Note, integer was requested here, but boolean was also requested here so having a single flag that allows us to specify a type would help solve all of these at once.

@@ -32,7 +39,7 @@
keys.each { |p| path = path[p.to_sym] }

puts "Setting [#{opts[:path]}], old value: [#{path[key]}], new value: [#{opts[:value]}]"
Copy link
Member

Choose a reason for hiding this comment

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

Should we cherry-pick the first commit from #17043 so we can see the class?

Or perhaps we don't need to care about telling the user about the string/integer class unless they don't match:

# allow user to escape if the new value's class is not the same as the original,
# such as setting a String where it was previously an Integer
if path[key] && path[key].class != opts[:value].class
  STDERR.puts "The new value's class #{opts[:value].class} does not match the prior one's #{path[key].class}.  Do you want to continue? (Y/N)"
  exit 1 if STDERR.gets.strip.downcase == "n"
end  

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps the above condition could advise the user to run tools/configure_server_settings.rb -h to see how to specify Integer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is a good idea, essentially being able to tell the user that the input made is not valid.

@rvalente rvalente changed the title Support Integers with configure_server_settings.rb Support setting var type with configure_server_settings.rb Feb 26, 2018
Copy link
Member

@gtanzillo gtanzillo left a comment

Choose a reason for hiding this comment

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

LGTM 👍

if opts[:force]
puts "Change [#{opts[:path]}], old class: [#{path[key].class}], new class: [#{newval.class}]"
elsif path[key] && path[key].class != newval.class
STDERR.puts "The new value's class #{newval.class} does not match the prior one's #{path[key].class}. Use -f to force update, this may break things!"
Copy link
Member

Choose a reason for hiding this comment

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

Use -f to force update, this may break things!"

"Use -t to specify the type for the provided value. Use -f to force changing this value. Note, -f may break things! See -h for examples."

@abraverm
Copy link
Contributor

Looks good but what about lists?

@jrafanie
Copy link
Member

Looks good but what about lists?

@abraverm I think that's reasonable to want do but then it starts getting really complicated. As soon as we do that, we'll want an ability to append/prepend to an array/list instead of replacing it because the list is really long. I'm not sure command line is best for something like that. Perhaps, taking an input settings.yml and blasting it out to specific server settings is another way to solve arrays/hashes or anything more complicated than a single value.

Either way, I'm of the opinion that it's outside the scope for this PR and would require more discussion on how much that feature is desired and how much effort it is to write and maintain.

@abraverm
Copy link
Contributor

@jrafanie I agree, array configurations seem like advanced setting which may require a different approach, for exmaple augeas.

@rvalente
Copy link
Contributor Author

@jrafanie I agree, array configurations seem like advanced setting which may require a different approach, for exmaple augeas.

@abraverm yes, it does start getting a little out of control at that point. At that point I would prefer to leverage the API directly to make changes or an external configuration key/value store all together a la etcd or consul or OpenShift ConfigMaps.

opts = Trollop.options(ARGV) do
banner "USAGE: #{__FILE__} -s <server id> -p <settings path separated by a /> -v <new value>\n" \
"Example: #{__FILE__} -d -s 1 -p reporting/history/keep_reports -v 42"
"Example (String): #{__FILE__} -s 1 -p reporting/history/keep_reports -v 42\n" \
Copy link
Member

Choose a reason for hiding this comment

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

Using a duration is probably a more helpful example for a string:
Example (String): #{__FILE__} -s 1 -p reporting/history/keep_reports -v '3.months'

Copy link
Member

Choose a reason for hiding this comment

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

I realize that value was there already but now that you changed it, it seems like a strange example for a string.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 yeah - when I was testing moving from 6.months -> 42 caught me off guard.

newval = opts[:value].to_sym
when "float"
newval = opts[:value].to_f
end
Copy link
Member

Choose a reason for hiding this comment

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

This would eliminate some of the extra assignments: (I hope rubocop doesn't hate me):

newval =
  case opts[:type]
  when "integer"
    opts[:value].to_i
  when "boolean"
    if opts[:value].downcase == "true"
      true
    elsif opts[:value].downcase == "false"
      false
    end
  when "symbol"
    opts[:value].to_sym
  when "float"
    opts[:value].to_f
  end

Copy link
Member

@jrafanie jrafanie left a comment

Choose a reason for hiding this comment

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

Looks great other than a few minor nitpicks mentioned below.

@rvalente
Copy link
Contributor Author

@jrafanie should be all set, thanks for the feedback! I was not happy with all that assignment either. 👊

@miq-bot
Copy link
Member

miq-bot commented Feb 27, 2018

Checked commits https://github.com/rvalente/manageiq/compare/b55557bf5668581cfcc13b85de7f7fda173df02b~...ceccaccb2f3fd16a1fccc15bc5a67fdbf5e2b9c4 with ruby 2.3.3, rubocop 0.52.0, haml-lint 0.20.0, and yamllint 1.10.0
1 file checked, 0 offenses detected
Everything looks fine. 🍪

@jrafanie jrafanie merged commit 533fb20 into ManageIQ:master Feb 27, 2018
@jrafanie
Copy link
Member

Thanks @rvalente 👍

@jrafanie jrafanie added this to the Sprint 80 Ending Feb 26, 2018 milestone Feb 27, 2018
@jrafanie jrafanie self-assigned this Feb 27, 2018
@bdunne bdunne removed this from the Sprint 80 Ending Feb 26, 2018 milestone Feb 28, 2018
@bdunne bdunne added this to the Sprint 81 Ending Mar 12, 2018 milestone Feb 28, 2018
@jrafanie
Copy link
Member

Added a BZ link to the description so we can backport this change.

@jrafanie
Copy link
Member

Note, this script only exists on gaprindashvili/master, not euwe or fine.

simaishi pushed a commit that referenced this pull request Mar 7, 2018
Support setting var type with configure_server_settings.rb
(cherry picked from commit 533fb20)

https://bugzilla.redhat.com/show_bug.cgi?id=1552804
@simaishi
Copy link
Contributor

simaishi commented Mar 7, 2018

Gaprindashvili backport details:

$ git log -1
commit c1b9b6f037af35e238896f1a403e9f752ee548d3
Author: Joe Rafaniello <[email protected]>
Date:   Tue Feb 27 13:38:00 2018 -0500

    Merge pull request #17039 from rvalente/bug-intval-support
    
    Support setting var type with configure_server_settings.rb
    (cherry picked from commit 533fb206eabe3d64fc590739fbc9b60bc1332e6b)
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1552804

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants