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

Ohai merges duplicate plugins in very dangerous ways #1212

Closed
jaymzh opened this issue Jul 6, 2018 · 9 comments · Fixed by #1224
Closed

Ohai merges duplicate plugins in very dangerous ways #1212

jaymzh opened this issue Jul 6, 2018 · 9 comments · Fixed by #1224

Comments

@jaymzh
Copy link
Collaborator

jaymzh commented Jul 6, 2018

Description

It turns out that Ohai evals every plugin in every directory... and so all methods inside of Ohai.plugin blocks are evaluated... however the collect_data blocks are not - if a second one is hit on the same platform, it will not evaluate it, it runs on the first one it hits. This means the methods from the last plugin seen win, but the collector code from the first plugin seen wins.

This means that you can into a problem where if you have two versions of the same module in different plugin paths, the first path will be run but call the methods from the second plugin.

So if you have /root/ohai_repro/test.rb with:

Ohai.plugin(:Test) do
  provides 'xtest'
  def test(a, b, c)
    Ohai::Log.warn("this is test() from test1")
  end
  collect_data do
    Ohai::Log.warn("this is collect_data from test1")
    test(1, 2, 3)
    xtest 'test1'
  end
end

So if you have /root/ohai_repro2/test.rb with:

Ohai.plugin(:Test) do
  provides 'xtest'
  def test(a, b, c)
    Ohai::Log.warn("this is test() from test2")
  end
  collect_data do
    Ohai::Log.warn("this is collect_data from test2")
    test(1, 2, 3)
    xtest 'test2'
  end
end

Your output will be the very unexpected:

[2018-07-06T10:36:27-07:00] WARN: this is collect_data from test1
[2018-07-06T10:36:27-07:00] WARN: this is test() from test2

Woah!! That's pretty weird.

Ohai Version

13.8.0

works on 12 too.

Platform Version

CentOS 7.5

@jaymzh jaymzh changed the title Ohai can't handle two different plugin paths with different versions of a plugin if methods change Ohai merges duplicate plugins in very dangerous ways Jul 6, 2018
@btm
Copy link
Contributor

btm commented Jul 9, 2018

@jaymzh what's the ideal/expected behavior for you? One plugin always wins? An exception is raised for duplicate plugins?

@jaymzh
Copy link
Collaborator Author

jaymzh commented Jul 9, 2018

@btm I'd expect the behavior to be the same as the collect_data blocks

Currently that means first one wins (with a warning on subsequent ones), but I don't really care if it's first one wins or last one wins, I can order my plugin list accordingly. It seems like last one should win since core plugins come first, but that would be a very significant change and not a bugfix, so we probably don't want to do that without an RFC. But making sure the whole plugin follows the same rules as collect_data (which right now is first-win) is a critical bugfix.

@lamont-granquist
Copy link
Contributor

It looks like someone tried to make multiple collect_data statements for the same platform fail with an exception:

https:/chef/ohai/blob/master/lib/ohai/dsl/plugin/versionvii.rb#L111-L115

Its possible that gets raised only if it is declared in the same file, and not across two different files?

Whatever the fix, probably need to be careful about explicitly allowing different implementations for e.g. linux and solaris in different files to still work.

@jaymzh
Copy link
Collaborator Author

jaymzh commented Jul 9, 2018

That error is raised - and like any other error in Ohai - is caught, printed, and then it carry's on.

So we have several of those. ;) But it shouldn't have eval'd it in the same namespace to determine that, IMO.

However, It does because that collect_data block could be for a different platform.

@lamont-granquist
Copy link
Contributor

ah, so that's the problem.

we're monkeypatching the class, so last-writer-wins for methods, but the last-writer throws an exception there instead of wiring up its collect_data method.

the intent seems to be that it should throw and fail, but that's difficult with ohai's never-fail "philosophy"

@btm
Copy link
Contributor

btm commented Jul 12, 2018

@jaymzh how are you specifying multiple ohai plugin directories in your repro case?

@jaymzh
Copy link
Collaborator Author

jaymzh commented Jul 12, 2018

I put those two dirs in client.rb and then ran chef-client -o test where test::default was an empty recipe..

@jaymzh
Copy link
Collaborator Author

jaymzh commented Jul 12, 2018

@btm you may want to base your work on #1221 to make your life easier :)

btm added a commit to btm/ohai that referenced this issue Jul 12, 2018
If we happen to load a plugin with the same name twice, we refuse to run #collect_data but we still
load the rest of the plugin, which means you get #collect_data from the first plugin and rest of the
plugin from the last plugin.

This makes it so you get #collect_data from the last plugin as well.

I don't know how to use the logger from the class method so I fell back to `Ohai::Log`. Happy to fix that
if someone knows the magic.

Fixes chef#1212

Signed-off-by: Bryan McLellan <[email protected]>
@lock
Copy link

lock bot commented Jan 24, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants