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 #27906 - Always prefer modern facts in Facter #8449

Merged
merged 2 commits into from
Nov 16, 2021

Conversation

ekohl
Copy link
Member

@ekohl ekohl commented Apr 16, 2021

Facter started to introduce structured facts in Facter 2. Since Facter 3, the old facts are deprecated. This introduces helper methods to provide the abstraction and always prefers modern facts.

It does make a change that it no longer considers the lsbdistrelease fact. 5d61c18 already preferred the os.release.full fact which is present with Facter 2.2 or newer. It should also fall back to the operatingsystemrelease fact which is present since Facter 1.5 and a more reliable fact.

To make things easier, it annotates which for each fact which version of Facter introduced it.

@theforeman-bot
Copy link
Member

Issues: #27906

Copy link
Member

@ares ares left a comment

Choose a reason for hiding this comment

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

Leaving some comments for just reading, happy to test once it's ready.

app/services/fact_parser.rb Outdated Show resolved Hide resolved
app/services/fact_parser.rb Outdated Show resolved Hide resolved
def model
name = facts[:productname] || facts[:model] || facts[:boardproductname]
def model_name
# TODO: not sure where model comes from, not Facter
Copy link
Member

Choose a reason for hiding this comment

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

could it be something in FDI? perhaps that was a custom fact, that should have been prefixed with foreman_, we may need to search in git history

Copy link
Member Author

Choose a reason for hiding this comment

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

It was added in 8ac3ea7 way back in 2010 as part of https://projects.theforeman.org/issues/289. I don't think FDI existed back then. My guess is that it was either a custom fact or a bug because it meant the fact hardwaremodel (which did exist back in the released Facter version at the time, which was 1.5).

Copy link
Member

Choose a reason for hiding this comment

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

This does not come from FDI. No idea, let's just remove these.

Copy link
Member

Choose a reason for hiding this comment

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

I am fine to keep it this way, I really don't know. Perhaps a custom fact, yeah. Maybe it is in use.

end
end

def os_release_full
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 have os_ and distro_ methods in abstract parser so all plugins parsers implement in a more standard way? I think you mentioned you wanted to do that, definitely not a must for this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

That is indeed where I think we should go to. In #8450 I did some of that work by using the minor releases from facter.

Comment on lines +14 to 18
if distro_codename
os.release_name = distro_codename
elsif os.release_name.blank?
os.release_name = 'unknown'
end
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this equal to

os.release_name = distro_codename || 'unknown'

Copy link
Member Author

Choose a reason for hiding this comment

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

Not really because it should only be set to unknown if it was blank. The distro code name is an optional fact that typically depends on lsb-release to be installed (maybe no longer in Facter 4, not sure). You don't want a host where that's not installed to reset a correct value back to unknown.

In the future I think the unknown part should be dropped, but that's out of scope for this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

In the future I think the unknown part should be dropped, but that's out of scope for this PR.

For what it's worth, I dropped it in #8450, specifically f667ef7. I'd be happy to submit that as a standalone PR with its own issue.

app/services/fact_parser.rb Outdated Show resolved Hide resolved
@ekohl
Copy link
Member Author

ekohl commented Apr 19, 2021

I opened #8451 to split off the discussion of model methods or not. I would prefer to merge that PR first but I'm fine either way. Please take a look.

@ekohl
Copy link
Member Author

ekohl commented Apr 19, 2021

This now removes all changes that are #8451. It still lacks tests, but at least it's a bit smaller to review.

@ekohl
Copy link
Member Author

ekohl commented Apr 19, 2021

I opened #8451 to split off the discussion of model methods or not. I would prefer to merge that PR first but I'm fine either way. Please take a look.

I changed my mind: let's get this in mergable order first.

@ekohl
Copy link
Member Author

ekohl commented Apr 21, 2021

Test failures related, will look into them.

@ekohl ekohl marked this pull request as ready for review April 21, 2021 09:11
@ekohl ekohl force-pushed the 27906-modern-facts branch 2 times, most recently from 35545c9 to 1ffea7a Compare April 21, 2021 09:12
@ekohl
Copy link
Member Author

ekohl commented Apr 21, 2021

Ok, updated the failing tests. I have updated the PR description with the latest commit message and I think it's ready for proper review now. I think dropping lsbdistrelease is safe and shouldn't affect anyone.

Copy link
Member

@lzap lzap left a comment

Choose a reason for hiding this comment

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

All those new methods require tests. This is a huge chance to start testing properly.

I suggest you add a JSON into our static_fixtures that is literally generated on the oldest supported facter you aim for (is that 2.2?) and please state in the filename clearly what is it. What we carry in our fixtures is a terrible mixture of various facts from unknown sources and I know that facter version is in facts themselves, but it should be in the filename (thus test helper) so it is obvious what we are testing.

We already have the following:

  • test/static_fixtures/facts/example_3.14.16.json
  • test/static_fixtures/facts/example_4.0.52.json

Ideally we would run a set of tests in a each loop for each major version we aim to support. This would be a huge stepup for the future proofing our puppet parsing - it has always been a mess.

app/services/puppet_fact_parser.rb Show resolved Hide resolved
@lzap
Copy link
Member

lzap commented Apr 22, 2021

Well I am not gonna block this but I feel like you are defining here what is the minimum supported facter version, here in this very patch. And I think it is worth making a fixture that clearly communicates that.

@ekohl
Copy link
Member Author

ekohl commented Apr 23, 2021

I did add tests, but they're fairly slow. I still would like to get this into 2.5 so please take a look.

bundler.d/test.rb Outdated Show resolved Hide resolved
lzap
lzap previously approved these changes Jun 18, 2021
Copy link
Member

@lzap lzap left a comment

Choose a reason for hiding this comment

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

It's okay, apologies for a late reply.

My only concern is that we are adding another minute to our 40-50 minutes test suite. We want to do exactly the opposite. I think I found a way how to shave a lot of the time tho - see my patch.

Now, I think we can merge this patch and if facterdb upstream likes my patch, it will speed up automatically after we bump the version. If not, I would like you to do similar thing in our codebase because I do not want another minute to be added. Are you okay with that?

# They are structured primairly based on OS rather than Facter version
# because FacterDB doesn't contain facts for every combination
describe 'Using FacterDB' do
subject { get_parser(get_facterdb_facts(facterversion, os_name, os_major)) }
Copy link
Member

Choose a reason for hiding this comment

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

The major problem of why these tests take 1 minute is not necessary in the fact that facterdb is slow, but because this subject is called 12 times /each test/ for each operating system /major, minor/, but it yields to the very same result. Let's cache it and I expect the time to drop significantly.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I saw that too. I also wondered if we should use the private method read_json_file.

test/unit/puppet_fact_parser_test.rb Show resolved Hide resolved
@lzap
Copy link
Member

lzap commented Jun 18, 2021

Oh wait, can you add that after(:suite) block to reclaim memory? And rebase please to retest it's been a while.

@ezr-ondrej
Copy link
Member

Ping @ekohl ? This is missing just the last comment and rebase to run the tests, if I'm reading correctly.

@lzap
Copy link
Member

lzap commented Nov 4, 2021

If you can get back to this @ekohl it would be nice to have this prior doing any refactoring changes that are planned by @domitea

Facter started to introduce structured facts in Facter 2. Since Facter
3, the old facts are deprecated. This introduces helper methods to
provide the abstraction and always prefers modern facts.

It does make a change that it no longer considers the lsbdistrelease
fact. 5d61c18 already preferred the
os.release.full fact which is present with Facter 2.2 or newer. It
should also fall back to the operatingsystemrelease fact which is
present since Facter 1.5 and a more reliable fact.

To make things easier, it annotates which for each fact which version of
Facter introduced it.
@ekohl
Copy link
Member Author

ekohl commented Nov 10, 2021

Rebased & set FacterDB 1.7 as the minimum version so it can safely call FacterDB.cleanup.

It should be noted that these tests are fairly slow. On my system they
add a minute of runtime to the tests.
Copy link
Member

@lzap lzap left a comment

Choose a reason for hiding this comment

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

I am good, great work and improvement of test coverage.

I assume that performance is now better and it should not add a minute or something to our test suite, I am not testing this. Last Jenkins duration seems okay, 53 mins. I will ensure this does not break Discovery and I am merging. Thanks!

@lzap
Copy link
Member

lzap commented Nov 10, 2021

Discovery works fine. I think we are still in the pre-branching period tho, not merging today.

@ekohl
Copy link
Member Author

ekohl commented Nov 16, 2021

We're past branching. Shall we merge this?

Copy link
Member

@ezr-ondrej ezr-ondrej left a comment

Choose a reason for hiding this comment

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

Thanks @ekohl ! 👍

@ezr-ondrej ezr-ondrej merged commit e98fc01 into theforeman:develop Nov 16, 2021
@ekohl ekohl deleted the 27906-modern-facts branch November 16, 2021 13:26
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