summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2018-11-22 14:51:40 -0800
committerGitHub <noreply@github.com>2018-11-22 14:51:40 -0800
commitea2092cc6ed146b82042d744c3ee718830d850d5 (patch)
tree2826cb39d5d96ac8897323a4581ca0ee3339c076
parent7cccce14c33bb3556b384d93e97a766fcd25d21d (diff)
parent15381beafe5c1375154bb8ff4c7cf6b6a72ee6c5 (diff)
downloadchef-ea2092cc6ed146b82042d744c3ee718830d850d5.tar.gz
Merge pull request #7963 from chef/lcg/apt-get-allow-downgrades
Support apt-get --allow-downgrades
-rw-r--r--lib/chef/provider/package/apt.rb16
-rw-r--r--spec/unit/provider/package/apt_spec.rb85
2 files changed, 95 insertions, 6 deletions
diff --git a/lib/chef/provider/package/apt.rb b/lib/chef/provider/package/apt.rb
index bfb24e502d..de1b106d45 100644
--- a/lib/chef/provider/package/apt.rb
+++ b/lib/chef/provider/package/apt.rb
@@ -1,6 +1,6 @@
#
# Author:: Adam Jacob (<adam@chef.io>)
-# Copyright:: Copyright 2008-2017, Chef Software Inc.
+# Copyright:: Copyright 2008-2018, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -92,7 +92,8 @@ class Chef
package_name = name.zip(version).map do |n, v|
package_data[n][:virtual] ? n : "#{n}=#{v}"
end
- run_noninteractive("apt-get", "-q", "-y", config_file_options, default_release_options, options, "install", package_name)
+ dgrade = "--allow-downgrades" if supports_allow_downgrade? && allow_downgrade
+ run_noninteractive("apt-get", "-q", "-y", dgrade, config_file_options, default_release_options, options, "install", package_name)
end
def upgrade_package(name, version)
@@ -133,6 +134,17 @@ class Chef
private
+ # @return [String] version of apt-get which is installed
+ def apt_version
+ @apt_version ||= shell_out("apt-get --version").stdout.match(/^apt (\S+)/)[1]
+ end
+
+ # @return [Boolean] if apt-get supports --allow-downgrades
+ def supports_allow_downgrade?
+ return @supports_allow_downgrade unless @supports_allow_downgrade.nil?
+ @supports_allow_downgrade = ( version_compare(apt_version, "1.1.0") >= 0 )
+ end
+
# compare 2 versions to each other to see which is newer.
# this differs from the standard package method because we
# need to be able to parse debian version strings which contain
diff --git a/spec/unit/provider/package/apt_spec.rb b/spec/unit/provider/package/apt_spec.rb
index 05be08f332..24bd642317 100644
--- a/spec/unit/provider/package/apt_spec.rb
+++ b/spec/unit/provider/package/apt_spec.rb
@@ -256,7 +256,78 @@ describe Chef::Provider::Package::Apt do
})
end
+ def ubuntu1804downgrade_stubs
+ so = instance_double(Mixlib::ShellOut, stdout: "apt 1.6~beta1 (amd64)\notherstuff\n")
+ so2 = instance_double(Mixlib::ShellOut, error?: false)
+ allow(@provider).to receive(:shell_out).with("apt-get --version").and_return(so)
+ allow(@provider).to receive(:shell_out).with("dpkg", "--compare-versions", "1.6~beta1", "gt", "1.1.0").and_return(so2)
+ end
+
+ def ubuntu1404downgrade_stubs
+ so = instance_double(Mixlib::ShellOut, stdout: "apt 1.0.1ubuntu2 for amd64 compiled on Dec 8 2016 16:23:38\notherstuff\n")
+ so2 = instance_double(Mixlib::ShellOut, error?: true)
+ allow(@provider).to receive(:shell_out).with("apt-get --version").and_return(so)
+ allow(@provider).to receive(:shell_out).with("dpkg", "--compare-versions", "1.0.1ubuntu2", "gt", "1.1.0").and_return(so2)
+ allow(@provider).to receive(:shell_out).with("dpkg", "--compare-versions", "1.0.1ubuntu2", "eq", "1.1.0").and_return(so2)
+ end
+
describe "install_package" do
+ before(:each) do
+ ubuntu1804downgrade_stubs
+ end
+
+ it "should run apt-get install with the package name and version" do
+ expect(@provider).to receive(:shell_out_compacted!). with(
+ "apt-get", "-q", "-y", "--allow-downgrades", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "irssi=0.8.12-7",
+ env: { "DEBIAN_FRONTEND" => "noninteractive" },
+ timeout: @timeout
+ )
+ @provider.install_package(["irssi"], ["0.8.12-7"])
+ end
+
+ it "should run apt-get install with the package name and version and options if specified" do
+ expect(@provider).to receive(:shell_out_compacted!).with(
+ "apt-get", "-q", "-y", "--allow-downgrades", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "--force-yes", "install", "irssi=0.8.12-7",
+ env: { "DEBIAN_FRONTEND" => "noninteractive" },
+ timeout: @timeout
+ )
+ @new_resource.options("--force-yes")
+ @provider.install_package(["irssi"], ["0.8.12-7"])
+ end
+
+ it "should run apt-get install with the package name and version and default_release if there is one and provider is explicitly defined" do
+ @new_resource = nil
+ @new_resource = Chef::Resource::AptPackage.new("irssi", @run_context)
+ @new_resource.default_release("lenny-backports")
+ @new_resource.provider = nil
+ @provider.new_resource = @new_resource
+
+ expect(@provider).to receive(:shell_out_compacted!).with(
+ "apt-get", "-q", "-y", "--allow-downgrades", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "-o", "APT::Default-Release=lenny-backports", "install", "irssi=0.8.12-7",
+ env: { "DEBIAN_FRONTEND" => "noninteractive" },
+ timeout: @timeout
+ )
+
+ @provider.install_package(["irssi"], ["0.8.12-7"])
+ end
+
+ it "should run apt-get install with the package name and quotes options if specified" do
+ expect(@provider).to receive(:shell_out_compacted!).with(
+ "apt-get", "-q", "-y", "--allow-downgrades", "--force-yes", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confnew", "install", "irssi=0.8.12-7",
+ env: { "DEBIAN_FRONTEND" => "noninteractive" },
+ timeout: @timeout
+ )
+ @new_resource.options('--force-yes -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew"')
+ @provider.install_package(["irssi"], ["0.8.12-7"])
+ end
+ end
+
+ describe "install_package with old apt-get" do
+ # tests apt-get on 1404 that does not support --allow-downgrades
+ before(:each) do
+ ubuntu1404downgrade_stubs
+ end
+
it "should run apt-get install with the package name and version" do
expect(@provider).to receive(:shell_out_compacted!). with(
"apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "irssi=0.8.12-7",
@@ -449,9 +520,10 @@ describe Chef::Provider::Package::Apt do
describe "when installing a virtual package" do
it "should install the package without specifying a version" do
+ ubuntu1804downgrade_stubs
@provider.package_data["libmysqlclient15-dev"][:virtual] = true
expect(@provider).to receive(:shell_out_compacted!).with(
- "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "libmysqlclient15-dev",
+ "apt-get", "-q", "-y", "--allow-downgrades", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "libmysqlclient15-dev",
env: { "DEBIAN_FRONTEND" => "noninteractive" },
timeout: @timeout
)
@@ -485,9 +557,10 @@ describe Chef::Provider::Package::Apt do
describe "when installing multiple packages" do
it "can install a virtual package followed by a non-virtual package" do
+ ubuntu1804downgrade_stubs
# https://github.com/chef/chef/issues/2914
expect(@provider).to receive(:shell_out_compacted!).with(
- "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "libmysqlclient15-dev", "irssi=0.8.12-7",
+ "apt-get", "-q", "-y", "--allow-downgrades", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "libmysqlclient15-dev", "irssi=0.8.12-7",
env: { "DEBIAN_FRONTEND" => "noninteractive" },
timeout: @timeout
)
@@ -506,9 +579,11 @@ describe Chef::Provider::Package::Apt do
end
it "should install the package if the installed version is older" do
+ ubuntu1804downgrade_stubs
+ expect(@provider).to receive(:version_compare).with("1.6~beta1", "1.1.0").and_return(1)
allow(@provider).to receive(:get_current_versions).and_return("0.4.0")
allow(@new_resource).to receive(:allow_downgrade).and_return(false)
- expect(@provider).to receive(:version_compare).and_return(-1)
+ expect(@provider).to receive(:version_compare).with("0.4.0", any_args).and_return(-1)
expect(@provider).to receive(:shell_out_compacted!).with(
"apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "irssi=0.8.12-7",
env: { "DEBIAN_FRONTEND" => "noninteractive" },
@@ -518,9 +593,11 @@ describe Chef::Provider::Package::Apt do
end
it "should not compare versions if an existing version is not installed" do
+ ubuntu1804downgrade_stubs
+ expect(@provider).to receive(:version_compare).with("1.6~beta1", "1.1.0").and_return(1)
allow(@provider).to receive(:get_current_versions).and_return(nil)
allow(@new_resource).to receive(:allow_downgrade).and_return(false)
- expect(@provider).not_to receive(:version_compare)
+ expect(@provider).not_to receive(:version_compare).with("0.4.0", any_args)
expect(@provider).to receive(:shell_out_compacted!).with(
"apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "irssi=0.8.12-7",
env: { "DEBIAN_FRONTEND" => "noninteractive" },