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

Remove broken pacman command for installing packages #9444

Merged
merged 2 commits into from
Aug 8, 2024
Merged
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: 9 additions & 10 deletions lib/puppet/provider/package/pacman.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def self.yaourt?
# Checks if a given name is a group
def self.group?(name)
begin
!pacman("-Sg", name).empty?
!pacman('--sync', '--groups', name).empty?
rescue Puppet::ExecutionFailure
# pacman returns an expected non-zero exit code when the name is not a group
false
Expand Down Expand Up @@ -75,7 +75,7 @@ def self.instances
def self.get_installed_packages
begin
packages = {}
execpipe([command(:pacman), "-Q"]) do |pipe|
execpipe([command(:pacman), "--query"]) do |pipe|
# pacman -Q output is 'packagename version-rel'
regex = %r{^(\S+)\s(\S+)}
pipe.each_line do |line|
Expand All @@ -98,7 +98,7 @@ def self.get_installed_groups(installed_packages, filter = nil)
groups = {}
begin
# Build a hash of group name => list of packages
command = [command(:pacman), "-Sgg"]
command = [command(:pacman), '--sync', '-gg']
command << filter if filter
execpipe(command) do |pipe|
pipe.each_line do |line|
Expand Down Expand Up @@ -136,14 +136,14 @@ def latest
resource_name = @resource[:name]

# If target is a group, construct the group version
return pacman("-Sp", "--print-format", "%n %v", resource_name).lines.map{ |line| line.chomp }.sort.join(', ') if self.class.group?(resource_name)
return pacman("--sync", "--print", "--print-format", "%n %v", resource_name).lines.map{ |line| line.chomp }.sort.join(', ') if self.class.group?(resource_name)

# Start by querying with pacman first
# If that fails, retry using yaourt against the AUR
pacman_check = true
begin
if pacman_check
output = pacman "-Sp", "--print-format", "%v", resource_name
output = pacman "--sync", "--print", "--print-format", "%v", resource_name
return output.chomp
else
output = yaourt "-Qma", resource_name
Expand Down Expand Up @@ -212,8 +212,8 @@ def remove_package(purge_configs = false)

cmd = %w{--noconfirm --noprogressbar}
cmd += uninstall_options if @resource[:uninstall_options]
cmd << "-R"
cmd << '-s' if is_group
cmd << "--remove"
cmd << '--recursive' if is_group
cmd << '--nosave' if purge_configs
cmd << resource_name

Expand Down Expand Up @@ -250,8 +250,7 @@ def install_from_file
else
fail _("Source %{source} is not supported by pacman") % { source: source }
end
pacman "--noconfirm", "--noprogressbar", "-S"
pacman "--noconfirm", "--noprogressbar", "-U", source
pacman "--noconfirm", "--noprogressbar", "--update", source
end

def install_from_repo
Expand All @@ -262,7 +261,7 @@ def install_from_repo

cmd = %w{--noconfirm --needed --noprogressbar}
cmd += install_options if @resource[:install_options]
cmd << "-S" << resource_name
cmd << "--sync" << resource_name

if self.class.yaourt?
yaourt(*cmd)
Expand Down
81 changes: 35 additions & 46 deletions spec/unit/provider/package/pacman_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
end

it "should call pacman to install the right package quietly when yaourt is not installed" do
args = ['--noconfirm', '--needed', '--noprogressbar', '-S', resource[:name]]
args = ['--noconfirm', '--needed', '--noprogressbar', '--sync', resource[:name]]
expect(provider).to receive(:pacman).at_least(:once).with(*args).and_return('')
provider.install
end

it "should call yaourt to install the right package quietly when yaourt is installed" do
without_partial_double_verification do
allow(described_class).to receive(:yaourt?).and_return(true)
args = ['--noconfirm', '--needed', '--noprogressbar', '-S', resource[:name]]
args = ['--noconfirm', '--needed', '--noprogressbar', '--sync', resource[:name]]
expect(provider).to receive(:yaourt).at_least(:once).with(*args).and_return('')
provider.install
end
Expand Down Expand Up @@ -70,15 +70,15 @@
end

it "should call pacman to install the right package quietly when yaourt is not installed" do
args = ['--noconfirm', '--needed', '--noprogressbar', '-x', '--arg=value', '-S', resource[:name]]
args = ['--noconfirm', '--needed', '--noprogressbar', '-x', '--arg=value', '--sync', resource[:name]]
expect(provider).to receive(:pacman).at_least(:once).with(*args).and_return('')
provider.install
end

it "should call yaourt to install the right package quietly when yaourt is installed" do
without_partial_double_verification do
expect(described_class).to receive(:yaourt?).and_return(true)
args = ['--noconfirm', '--needed', '--noprogressbar', '-x', '--arg=value', '-S', resource[:name]]
args = ['--noconfirm', '--needed', '--noprogressbar', '-x', '--arg=value', '--sync', resource[:name]]
expect(provider).to receive(:yaourt).at_least(:once).with(*args).and_return('')
provider.install
end
Expand All @@ -98,12 +98,7 @@
resource[:source] = source

expect(executor).to receive(:execute).
with(include("-S") & include("--noprogressbar"), no_extra_options).
ordered.
and_return("")

expect(executor).to receive(:execute).
with(include("-U") & include(source), no_extra_options).
with(include("--update") & include(source), no_extra_options).
ordered.
and_return("")

Expand All @@ -121,13 +116,7 @@

it "should install from the path segment of the URL" do
expect(executor).to receive(:execute).
with(include("-S") & include("--noprogressbar") & include("--noconfirm"),
no_extra_options).
ordered.
and_return("")

expect(executor).to receive(:execute).
with(include("-U") & include(actual_file_path), no_extra_options).
with(include("--update") & include(actual_file_path), no_extra_options).
ordered.
and_return("")

Expand Down Expand Up @@ -170,58 +159,58 @@

describe "when purging" do
it "should call pacman to remove the right package and configs quietly" do
args = ["/usr/bin/pacman", "--noconfirm", "--noprogressbar", "-R", "--nosave", resource[:name]]
args = ["/usr/bin/pacman", "--noconfirm", "--noprogressbar", "--remove", "--nosave", resource[:name]]
expect(executor).to receive(:execute).with(args, no_extra_options).and_return("")
provider.purge
end
end

describe "when uninstalling" do
it "should call pacman to remove the right package quietly" do
args = ["/usr/bin/pacman", "--noconfirm", "--noprogressbar", "-R", resource[:name]]
args = ["/usr/bin/pacman", "--noconfirm", "--noprogressbar", "--remove", resource[:name]]
expect(executor).to receive(:execute).with(args, no_extra_options).and_return("")
provider.uninstall
end

it "should call yaourt to remove the right package quietly" do
without_partial_double_verification do
allow(described_class).to receive(:yaourt?).and_return(true)
args = ["--noconfirm", "--noprogressbar", "-R", resource[:name]]
args = ["--noconfirm", "--noprogressbar", "--remove", resource[:name]]
expect(provider).to receive(:yaourt).with(*args)
provider.uninstall
end
end

it "adds any uninstall_options" do
resource[:uninstall_options] = ['-x', {'--arg' => 'value'}]
args = ["/usr/bin/pacman", "--noconfirm", "--noprogressbar", "-x", "--arg=value", "-R", resource[:name]]
args = ["/usr/bin/pacman", "--noconfirm", "--noprogressbar", "-x", "--arg=value", "--remove", resource[:name]]
expect(executor).to receive(:execute).with(args, no_extra_options).and_return("")
provider.uninstall
end

it "should recursively remove packages when given a package group" do
allow(described_class).to receive(:group?).and_return(true)
args = ["/usr/bin/pacman", "--noconfirm", "--noprogressbar", "-R", "-s", resource[:name]]
args = ["/usr/bin/pacman", "--noconfirm", "--noprogressbar", "--remove", "--recursive", resource[:name]]
expect(executor).to receive(:execute).with(args, no_extra_options).and_return("")
provider.uninstall
end
end

describe "when querying" do
it "should query pacman" do
expect(executor).to receive(:execpipe).with(["/usr/bin/pacman", '-Q'])
expect(executor).to receive(:execpipe).with(["/usr/bin/pacman", '-Sgg', 'package'])
expect(executor).to receive(:execpipe).with(["/usr/bin/pacman", '--query'])
expect(executor).to receive(:execpipe).with(["/usr/bin/pacman", '--sync', '-gg', 'package'])
provider.query
end

it "should return the version" do
expect(executor).to receive(:execpipe).
with(["/usr/bin/pacman", "-Q"]).and_yield(<<EOF)
with(["/usr/bin/pacman", "--query"]).and_yield(<<EOF)
otherpackage 1.2.3.4
package 1.01.3-2
yetanotherpackage 1.2.3.4
EOF
expect(executor).to receive(:execpipe).with(['/usr/bin/pacman', '-Sgg', 'package']).and_yield('')
expect(executor).to receive(:execpipe).with(['/usr/bin/pacman', '--sync', '-gg', 'package']).and_yield('')

expect(provider.query).to eq({ :name => 'package', :ensure => '1.01.3-2', :provider => :pacman, })
end
Expand All @@ -239,8 +228,8 @@

describe 'when querying a group' do
before :each do
expect(executor).to receive(:execpipe).with(['/usr/bin/pacman', '-Q']).and_yield('foo 1.2.3')
expect(executor).to receive(:execpipe).with(['/usr/bin/pacman', '-Sgg', 'package']).and_yield('package foo')
expect(executor).to receive(:execpipe).with(['/usr/bin/pacman', '--query']).and_yield('foo 1.2.3')
expect(executor).to receive(:execpipe).with(['/usr/bin/pacman', '--sync', '-gg', 'package']).and_yield('package foo')
end

it 'should warn when allow_virtual is false' do
Expand All @@ -259,14 +248,14 @@

describe "when determining instances" do
it "should retrieve installed packages and groups" do
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '-Q'])
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '-Sgg'])
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '--query'])
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '--sync', '-gg'])
described_class.instances
end

it "should return installed packages" do
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '-Q']).and_yield(StringIO.new("package1 1.23-4\npackage2 2.00\n"))
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '-Sgg']).and_yield("")
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '--query']).and_yield(StringIO.new("package1 1.23-4\npackage2 2.00\n"))
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '--sync', '-gg']).and_yield("")
instances = described_class.instances

expect(instances.length).to eq(2)
Expand All @@ -285,11 +274,11 @@
end

it "should return completely installed groups with a virtual version together with packages" do
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '-Q']).and_yield(<<EOF)
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '--query']).and_yield(<<EOF)
package1 1.00
package2 1.00
EOF
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '-Sgg']).and_yield(<<EOF)
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '--sync', '-gg']).and_yield(<<EOF)
group1 package1
group1 package2
EOF
Expand All @@ -315,10 +304,10 @@
end

it "should not return partially installed packages" do
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '-Q']).and_yield(<<EOF)
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '--query']).and_yield(<<EOF)
package1 1.00
EOF
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '-Sgg']).and_yield(<<EOF)
expect(described_class).to receive(:execpipe).with(["/usr/bin/pacman", '--sync', '-gg']).and_yield(<<EOF)
group1 package1
group1 package2
EOF
Expand All @@ -334,7 +323,7 @@
end

it 'should sort package names for installed groups' do
expect(described_class).to receive(:execpipe).with(['/usr/bin/pacman', '-Sgg', 'group1']).and_yield(<<EOF)
expect(described_class).to receive(:execpipe).with(['/usr/bin/pacman', '--sync', '-gg', 'group1']).and_yield(<<EOF)
group1 aa
group1 b
group1 a
Expand Down Expand Up @@ -365,7 +354,7 @@
it "should get query pacman for the latest version" do
expect(executor).to receive(:execute).
ordered.
with(['/usr/bin/pacman', '-Sp', '--print-format', '%v', resource[:name]], no_extra_options).
with(['/usr/bin/pacman', '--sync', '--print', '--print-format', '%v', resource[:name]], no_extra_options).
and_return("")

provider.latest
Expand All @@ -379,7 +368,7 @@

it "should return a virtual group version when resource is a package group" do
allow(described_class).to receive(:group?).and_return(true)
expect(executor).to receive(:execute).with(['/usr/bin/pacman', '-Sp', '--print-format', '%n %v', resource[:name]], no_extra_options).ordered.
expect(executor).to receive(:execute).with(['/usr/bin/pacman', '--sync', '--print', '--print-format', '%n %v', resource[:name]], no_extra_options).ordered.
and_return(<<EOF)
package2 1.0.1
package1 1.0.0
Expand All @@ -394,17 +383,17 @@
end

it 'should return false on non-zero pacman exit' do
allow(executor).to receive(:execute).with(['/usr/bin/pacman', '-Sg', 'git'], {:failonfail => true, :combine => true, :custom_environment => {}}).and_raise(Puppet::ExecutionFailure, 'error')
allow(executor).to receive(:execute).with(['/usr/bin/pacman', '--sync', '--groups', 'git'], {:failonfail => true, :combine => true, :custom_environment => {}}).and_raise(Puppet::ExecutionFailure, 'error')
expect(described_class.group?('git')).to eq(false)
end

it 'should return false on empty pacman output' do
allow(executor).to receive(:execute).with(['/usr/bin/pacman', '-Sg', 'git'], {:failonfail => true, :combine => true, :custom_environment => {}}).and_return('')
allow(executor).to receive(:execute).with(['/usr/bin/pacman', '--sync', '--groups', 'git'], {:failonfail => true, :combine => true, :custom_environment => {}}).and_return('')
expect(described_class.group?('git')).to eq(false)
end

it 'should return true on non-empty pacman output' do
allow(executor).to receive(:execute).with(['/usr/bin/pacman', '-Sg', 'vim-plugins'], {:failonfail => true, :combine => true, :custom_environment => {}}).and_return('vim-plugins vim-a')
allow(executor).to receive(:execute).with(['/usr/bin/pacman', '--sync', '--groups', 'vim-plugins'], {:failonfail => true, :combine => true, :custom_environment => {}}).and_return('vim-plugins vim-a')
expect(described_class.group?('vim-plugins')).to eq(true)
end
end
Expand All @@ -414,21 +403,21 @@
let(:groups) { [['foo package1'], ['foo package2'], ['bar package3'], ['bar package4'], ['baz package5']] }

it 'should raise an error on non-zero pacman exit without a filter' do
expect(executor).to receive(:open).with('| /usr/bin/pacman -Sgg 2>&1').and_return('error!')
expect(executor).to receive(:open).with('| /usr/bin/pacman --sync -gg 2>&1').and_return('error!')
expect(Puppet::Util::Execution).to receive(:exitstatus).and_return(1)
expect { described_class.get_installed_groups(installed_packages) }.to raise_error(Puppet::ExecutionFailure, 'error!')
end

it 'should return empty groups on non-zero pacman exit with a filter' do
expect(executor).to receive(:open).with('| /usr/bin/pacman -Sgg git 2>&1').and_return('')
expect(executor).to receive(:open).with('| /usr/bin/pacman --sync -gg git 2>&1').and_return('')
expect(Puppet::Util::Execution).to receive(:exitstatus).and_return(1)
expect(described_class.get_installed_groups(installed_packages, 'git')).to eq({})
end

it 'should return empty groups on empty pacman output' do
pipe = double()
expect(pipe).to receive(:each_line)
expect(executor).to receive(:open).with('| /usr/bin/pacman -Sgg 2>&1').and_yield(pipe).and_return('')
expect(executor).to receive(:open).with('| /usr/bin/pacman --sync -gg 2>&1').and_yield(pipe).and_return('')
expect(Puppet::Util::Execution).to receive(:exitstatus).and_return(0)
expect(described_class.get_installed_groups(installed_packages)).to eq({})
end
Expand All @@ -438,7 +427,7 @@
pipe_expectation = receive(:each_line)
groups.each { |group| pipe_expectation = pipe_expectation.and_yield(*group) }
expect(pipe).to pipe_expectation
expect(executor).to receive(:open).with('| /usr/bin/pacman -Sgg 2>&1').and_yield(pipe).and_return('')
expect(executor).to receive(:open).with('| /usr/bin/pacman --sync -gg 2>&1').and_yield(pipe).and_return('')
expect(Puppet::Util::Execution).to receive(:exitstatus).and_return(0)
expect(described_class.get_installed_groups(installed_packages)).to eq({'foo' => 'package1 1.0, package2 2.0'})
end
Expand Down