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

Fixes #29110 - updated fact parser to handle v3 debian OS #7482

Merged
merged 2 commits into from
May 3, 2020

Conversation

lzap
Copy link
Member

@lzap lzap commented Mar 3, 2020

Added example JSON output from Facter v3 (VMWare, Debian 10.3) and
updated fact parser to handle LSB information from v3 "os" tree.

As part of this patch, I am adding stubbing of DNS calls as I noticed it
slows down fact tests 10x. Chances are there are other places in our
huge test codebase.

@theforeman-bot
Copy link
Member

Issues: #29110

app/services/puppet_fact_parser.rb Show resolved Hide resolved
family = os.deduce_family || 'Operatingsystem'
os.description = family.constantize.shorten_description facts[:lsbdistdescription]
os.description = family.constantize.shorten_description(facts.dig(:os, :distro, :description).presence || facts[:lsbdistdescription])
Copy link
Member

Choose a reason for hiding this comment

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

Same here:

Suggested change
os.description = family.constantize.shorten_description(facts.dig(:os, :distro, :description).presence || facts[:lsbdistdescription])
os.description = family.constantize.shorten_description(facts.dig(:os, :distro, :description) || facts[:lsbdistdescription])

@@ -89,9 +89,20 @@ def after_teardown
end
end

module TestCaseNetworkStubExtensions
def setup
Copy link
Member

Choose a reason for hiding this comment

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

What about Resolv.getaddress and Resolv.getname? Or are they covered because they just instantiate a Resolv::DNS instance?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, that's how I understand the code however I haven't tested. Let me check.

def setup
Resolv::DNS.any_instance.stubs(:getname).returns("stubbed-host.example.com")
Resolv::DNS.any_instance.stubs(:getnames).returns(["stubbed-host.example.com"])
Resolv::DNS.any_instance.stubs(:getaddress).returns("127.0.0.13")
Copy link
Member

Choose a reason for hiding this comment

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

As said on IRC, I think we should raise an exception and don't pretend it exists:

[4] pry(main)> Resolv.getaddress('doesnotexist.example.com')
Resolv::ResolvError: no address for doesnotexist.example.com
from /usr/share/ruby/resolv.rb:94:in `getaddress'

Resolv::DNS.any_instance.stubs(:getname).returns("stubbed-host.example.com")
Resolv::DNS.any_instance.stubs(:getnames).returns(["stubbed-host.example.com"])
Resolv::DNS.any_instance.stubs(:getaddress).returns("127.0.0.13")
Resolv::DNS.any_instance.stubs(:getaddresses).returns(["127.0.0.13"])
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't pretend it exists:

[6] pry(main)> Resolv.getaddresses('doesnotexist.example.com')
=> []
Suggested change
Resolv::DNS.any_instance.stubs(:getaddresses).returns(["127.0.0.13"])
Resolv::DNS.any_instance.stubs(:getaddresses).returns([])

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok ok, I will do exceptions. I will do this in a separate PR tho, I want this one to be backported.

@lzap lzap force-pushed the debian-fact-parsing-v3-29110 branch from 0d3652c to 246fe36 Compare March 3, 2020 09:43
@lzap
Copy link
Member Author

lzap commented Mar 3, 2020

Rebased, DNS stubs are out!

@lzap
Copy link
Member Author

lzap commented Mar 5, 2020

Failure irrelevant? HostJSTest::hosts index multiple actions.test_0001_show action buttons

@lzap
Copy link
Member Author

lzap commented Mar 5, 2020

A user on the discourse reports it worked for them.

return "" if description.blank?
s = description.dup
s.gsub!('GNU/Linux', '')
s.gsub!(/\(.+?\)/, '')
s.squeeze! " "
s.strip!
s += '.' + minor unless s.include?('.')
Copy link
Member

Choose a reason for hiding this comment

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

Right now it's hard to see what the benefit is. I assume you want to change Debian GNU/Linux 10 (buster) into Debian 10.3 but I'm wondering if that's needed. Debian has dropped the use of minor versions since a few releases. Is there a reason we want to divert from the OS? Does the description column need to be unique?

Could you also add a test case for this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Description was previously "Debian 10", with the change it's gonna be "Debian 10.3".

Uniquness is a good question, I'd say yes we want it to be unique because that's the field we show in lists. You do not want to see this:

  • Debian 10
  • Debian 10
  • Debian 10
  • Debian 10

I vaguely remember that this field is preferred because users want to define their own naming convention e.g. RHEL 7.7 instead RedHat 7.7. So generally speaking, i'd rather keep them unique and do this patch than doing a big change on that.

We actually follow the same naming scheme for Red Hat systems and it makes sense to me. Every minor release of RHEL (I assume Debian too) has a installable tree (kickstart). To be able to install from different version trees, you actually need two OS entries otherwise you'd need to change minor version before every provisioning.

I will add a test case for this of couse.

Copy link
Member Author

Choose a reason for hiding this comment

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

@ekohl wait there is a test already, can you elaborate what you want me to do?

https://github.com/theforeman/foreman/pull/7482/files#diff-f6c009374a71e00e01084f53f35f47ba

ekohl
ekohl previously approved these changes Mar 20, 2020
Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

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

I was wondering whether we should even store the minor for Debian since version 7 since it's more like a patch level. However, I think it may also influence boot media so from a fact handling perspective I think this is correct.

I'm having some doubts about making it a non-static method. Should we keep it static and pass the minor as an optional parameter. On the other hand, in many languages using static methods with class inheritance doesn't even work. The method is only used in the fact importer so the impact is minimal. Given my uncertainty on this area, I'd like someone more familiar with Ruby (on Rails) to take a look as well. @tbrisker perhaps?

For what it's worth, if I'd design this today, I'd move the shorten_description into the PuppetFactParser but that'd make this particular PR too big.

@lzap
Copy link
Member Author

lzap commented Mar 23, 2020

Should we keep it static and pass the minor as an optional parameter.

Passing attributes of an instance into method that is defined as static on the class is almost always a bad idea, no matter the language. What we had (static methods inheritance) is something that can only be used with some languages and IMHO is also generally a bad idea. This patch fixes it, I believe.

I agree this would need an overhaul. If I had to pick, I'd rather work on the way we store reports, then facts :)

@ekohl
Copy link
Member

ekohl commented Mar 23, 2020

@tbrisker mind having a look?

@tbrisker
Copy link
Member

I don't have a strong preference here.
if we're passing a parameter to the method and not using any instance variables in it, does it actually matter if it's defined on the class or the instance? It would make sense to make it an instance method if it manipulated the description attribute for example, but as it is - it doesn't matter much to me where it's defined.
Regarding the naming scheme for debian I have no idea - i guess that depends on what is expected for the installation media.

Copy link
Member

@tbrisker tbrisker left a comment

Choose a reason for hiding this comment

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

My only thought regarding maybe keeping it as class method is that this is something we want to backport to stable releases, and the smaller the change the easier that will be.

@lzap
Copy link
Member Author

lzap commented Apr 2, 2020

@tbrisker @ekohl please give me clear statement if I should be refactoring this back to class methods or not. I believe class method inheritance is bad practice, particularly when it requires a parameter that is from the instance of the class. Data should be encapsulated.

@lzap
Copy link
Member Author

lzap commented Apr 2, 2020

Rebased conflicts.

@tbrisker
Copy link
Member

tbrisker commented Apr 2, 2020

@lzap ah, now i see you actually use an instance parameter in the debian one. I guess then it does make sense to make this into an instance method, although it is still a bit odd to me that it gets the description as a parameter and returns a new description rather than manipulating the instance's attributes directly. Still no idea regarding what makes sense from the debian install media pov

@tbrisker tbrisker self-assigned this Apr 22, 2020
@lzap lzap force-pushed the debian-fact-parsing-v3-29110 branch from 1d9beab to 51db133 Compare April 24, 2020 11:16
@lzap
Copy link
Member Author

lzap commented Apr 24, 2020

It's been long, so I am rebasing.

@tuxmea
Copy link

tuxmea commented Apr 29, 2020

@tbrisker @ekohl Any update on when this will be reviewed and merged?

@ekohl
Copy link
Member

ekohl commented Apr 29, 2020

I've been assuming that @tbrisker would continue his review since he had comments.

@tbrisker
Copy link
Member

My only comment was that I don't know what makes sense regarding the install media path for debian, other than that i'm fine with this change.

@mmoll mmoll force-pushed the debian-fact-parsing-v3-29110 branch from 51db133 to cffc41e Compare May 2, 2020 17:49
Copy link
Contributor

@mmoll mmoll left a comment

Choose a reason for hiding this comment

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

Seems to work just fine. The mediumpath doesn't contain the version, but the installer uses the distro code name.

Copy link
Member

@tbrisker tbrisker left a comment

Choose a reason for hiding this comment

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

Thanks @lzap !

@tbrisker tbrisker merged commit 5d61c18 into theforeman:develop May 3, 2020
@tbrisker
Copy link
Member

tbrisker commented May 3, 2020

Please open CP PRs against stable branches, this does not cherry-pick cleanly.

@lzap lzap deleted the debian-fact-parsing-v3-29110 branch May 4, 2020 13:45
lzap added a commit to lzap/foreman that referenced this pull request May 4, 2020
lzap added a commit to lzap/foreman that referenced this pull request May 4, 2020
@lzap
Copy link
Member Author

lzap commented May 4, 2020

Done, they are associated to the ticket. Thanks!

mmoll pushed a commit to lzap/foreman that referenced this pull request May 5, 2020
tbrisker pushed a commit that referenced this pull request May 6, 2020
tbrisker pushed a commit that referenced this pull request May 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants