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

(PUP-4191,PUP-4203) Use execute function to run gem uninstall #3708

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions lib/puppet/provider/package/gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
interpreted as the path to a local gem file. If source is not present at all,
the gem will be installed from the default gem repositories.

This provider supports the `install_options` attribute, which allows command-line flags to be passed to the gem command.
This provider supports the `install_options` and `uninstall_options` attributes,
which allow command-line flags to be passed to the gem command.
These options should be specified as a string (e.g. '--flag'), a hash (e.g. {'--flag' => 'value'}),
or an array where each element is either a string or a hash."

has_feature :versionable, :install_options
has_feature :versionable, :install_options, :uninstall_options

commands :gemcmd => "gem"

Expand Down Expand Up @@ -122,7 +123,15 @@ def query
end

def uninstall
gemcmd "uninstall", "-x", "-a", resource[:name]
command = [command(:gemcmd), "uninstall"]
Copy link
Contributor

Choose a reason for hiding this comment

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

It is unfortunate that you have to do this... When you declare a command in your provider, puppet automatically creates a method, e.g. gemcmd, which ultimately calls into Puppet::Util::Execution.execute to execute the command. Unfortunately, it appears sensu_gem is able to override the value of command(:gem), but not the path used in gemcmd. So it's surprising when you use one vs the other:

0 ~/work/puppet (master)  $ bundle exec irb
...
irb(main):012:0> require 'puppet'
=> true
irb(main):013:0> Puppet::Type.type(:package).provide :sensu_gem, :parent => :gem do
irb(main):014:1*   desc "Sensu Embedded Ruby Gem support. If a URL is passed via `source`, then
irb(main):015:1"     that URL is used as the remote gem repository; if a source is present but is
irb(main):016:1"     not a valid URL, it will be interpreted as the path to a local gem file.  If
irb(main):017:1"     source is not present at all, the gem will be installed from the default gem
irb(main):018:1"     repositories."
irb(main):019:1>
irb(main):020:1*   has_feature :versionable, :install_options
irb(main):021:1>
irb(main):022:1*   commands :gemcmd => "/opt/sensu/embedded/bin/gem"
irb(main):023:1> end
=> Puppet::Type::Package::ProviderSensu_gem
...
irb(main):028:0> provider = Puppet::Type.type(:package).provider(:sensu_gem)
=> Puppet::Type::Package::ProviderSensu_gem
irb(main):029:0> provider.command(:gemcmd)
=> nil

This is because I don't have /opt/sensu/embedded/bin/gem, so this is returning the overridden value as expected. But

irb(main):030:0> provider.gemcmd
Puppet::ExecutionFailure: Execution of '/Users/josh/.rbenv/versions/2.1.5/bin/gem' returned 1: RubyGems is a sophisticated package manager for Ruby.

Is executing using the gem command from the base class.

So I'm 👍 with the changes, just sad puppet is not consistent in how commands are overridden.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@joshcooper I totally agree with you.

command << "--executables" << "--all" << resource[:name]

command += uninstall_options if resource[:uninstall_options]

output = execute(command)

# Apparently some stupid gem versions don't exit non-0 on failure
self.fail "Could not uninstall: #{output.chomp}" if output.include?("ERROR")
end

def update
Expand All @@ -132,4 +141,8 @@ def update
def install_options
join_options(resource[:install_options])
end

def uninstall_options
join_options(resource[:uninstall_options])
end
end
Loading