-
Notifications
You must be signed in to change notification settings - Fork 681
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
Add rpm_dbpath
support to the package resource
#1960
Add rpm_dbpath
support to the package resource
#1960
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks really great @jerryaldrichiii I just added a suggestion for a minor improvement
lib/resources/package.rb
Outdated
@dbpath = opts.fetch(:rpm_dbpath, nil) | ||
end | ||
|
||
def rpm_command(package_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that should be a private function of that class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I'll make the change now!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, very quick turn-around @jerryaldrichiii
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jerryaldrichiii this is a great contribution, thank you!
My main concern is the one that I raised with you directly regarding returning false
if the RPM DB cannot be found. We've already seen similar situations confuse our users (i.e. returning nil file contents simply because the InSpec user didn't have permissions to read, but not giving them that feedback). In this case, we'd return false
but if they log in manually and poke around, they'd see it's installed. Ideally, we'd be able to raise an exception and provide the user with more helpful error messaging, but until we implement #1205, our best option is to skip_resource
.
Since you can't skip_resource
in an object that's not an Inspec::Resource
, you need to handle this in the top-level of the resource. Take a look at the missing_requirements
pattern in the host
resource:
https://github.com/chef/inspec/blob/master/lib/resources/host.rb#L68-L71
https://github.com/chef/inspec/blob/master/lib/resources/host.rb#L136-L140
https://github.com/chef/inspec/blob/master/lib/resources/host.rb#L182-L190
I'd love to see something like that implemented for this before we merge. Then, after #1205 is implemented, we can change that skip_resource
into an exception that either skips or fails the test as necessary. I'm happy to pair with you if needed.
Great feedback @adamleff and thank you for the reference material! I added something similar by doing the following:
|
@adamleff, I took your offline feedback and made some modifications. Now the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jerryaldrichiii this is much closer to what I'd like to see! I think there's a couple of small clean-up things we can do and then this will be good to go.
lib/resources/package.rb
Outdated
@@ -44,8 +44,10 @@ def initialize(package_name = nil) # rubocop:disable Metrics/AbcSize | |||
elsif ['hpux'].include?(os[:family]) | |||
@pkgman = HpuxPkg.new(inspec) | |||
else | |||
return skip_resource 'The `package` resource is not supported on your OS yet.' | |||
skip_resource 'The `package` resource is not supported on your OS yet.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably want to leave the return
here - there's no reason to continue to evaluating missing requirements if the resource isn't supported on the target OS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will fix!
lib/resources/package.rb
Outdated
end | ||
|
||
evaluate_missing_requirements(@pkgman.missing_requirements) if @pkgman |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you leave the return
above, you'll always have a populated @pkgman
variable, so I'd just remove if @pkgman
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, since the pkg manager is stored in an instance variable, you probably don't need to pass it. Just let evaluate_missing_requirements
take zero arguments and it can refer to @pkgman
by itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will fix!
lib/resources/package.rb
Outdated
|
||
private | ||
|
||
def evaluate_missing_requirements(missing_requirements) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to bail out of a method as quickly as possible if you can. In this case, you build up a skip_msg
that you may never use because you don't check for emptiness of the missing requirements until the very last step.
I'd rewrite this method like this:
def evaluate_missing_requirements
missing_requirements = @pkgman.missing_requirements
return if missing_requirements.empty?
skip_resource "The following requirements are not met for this resource: #{missing_requirements.join(', ')}"
end
I don't know that you need to compact and uniq unless you're doing something in your code that you think would require that... in which case I'd encourage you to solve that problem since you control the whole kit and kaboodle. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will fix!
lib/resources/package.rb
Outdated
|
||
private | ||
|
||
def validate_arguments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like this method and the one below it are unnecessary layers of abstraction. Any reason not just to fold these into missing_requirements
in the Rpm
class? If we collect additional requirements later, we can break those down until separate methods but it feels like a bunch of hopping around between methods to get to a simple "if this parameter isn't nil, check to make sure it's actually a file on disk" check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will fix!
Signed-off-by: Jerry Aldrich III <[email protected]>
@adamleff I pushed up my recent changes based on your feedback. Keep it coming! |
Looks great, @jerryaldrichiii - thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great addition @jerryaldrichiii
|
||
private | ||
|
||
def evaluate_missing_requirements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I agree that we need to find a pattern for checking missing options, the current approach feels bloated and very complicated. I'd like to replace this with a version that is more lightweight and more flexible to be used in all resources. I do not have an idea right now, therefore this is not a PR blocker.
This adds support for querying a specific RPMDB
Example:
Fixes #1959