puppet 6.15.0 → 6.16.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CODEOWNERS +2 -7
- data/Gemfile.lock +17 -14
- data/lib/puppet.rb +32 -8
- data/lib/puppet/agent.rb +18 -4
- data/lib/puppet/application/agent.rb +1 -2
- data/lib/puppet/application/device.rb +1 -1
- data/lib/puppet/application/plugin.rb +1 -0
- data/lib/puppet/application/ssl.rb +1 -1
- data/lib/puppet/configurer.rb +2 -2
- data/lib/puppet/context/trusted_information.rb +14 -8
- data/lib/puppet/daemon.rb +13 -27
- data/lib/puppet/defaults.rb +19 -0
- data/lib/puppet/face/facts.rb +1 -1
- data/lib/puppet/face/help.rb +29 -3
- data/lib/puppet/face/module/search.rb +5 -0
- data/lib/puppet/face/plugin.rb +1 -1
- data/lib/puppet/file_serving/http_metadata.rb +1 -1
- data/lib/puppet/file_system/uniquefile.rb +4 -0
- data/lib/puppet/forge/repository.rb +7 -6
- data/lib/puppet/functions/filter.rb +1 -0
- data/lib/puppet/http/client.rb +22 -11
- data/lib/puppet/http/external_client.rb +0 -6
- data/lib/puppet/indirector/file_content/http.rb +5 -0
- data/lib/puppet/indirector/file_metadata/http.rb +4 -4
- data/lib/puppet/indirector/rest.rb +7 -1
- data/lib/puppet/network/http/compression.rb +7 -0
- data/lib/puppet/network/http/connection.rb +2 -0
- data/lib/puppet/network/http/connection_adapter.rb +182 -0
- data/lib/puppet/network/http/nocache_pool.rb +1 -0
- data/lib/puppet/network/http_pool.rb +2 -2
- data/lib/puppet/pal/catalog_compiler.rb +5 -0
- data/lib/puppet/pal/pal_impl.rb +4 -1
- data/lib/puppet/parser/compiler.rb +28 -25
- data/lib/puppet/parser/functions/filter.rb +1 -0
- data/lib/puppet/provider/package/aix.rb +17 -2
- data/lib/puppet/provider/package/apt.rb +4 -1
- data/lib/puppet/provider/package/dnfmodule.rb +24 -4
- data/lib/puppet/provider/package/pip.rb +60 -37
- data/lib/puppet/provider/package/portage.rb +2 -2
- data/lib/puppet/provider/package/yum.rb +7 -0
- data/lib/puppet/provider/package/zypper.rb +59 -1
- data/lib/puppet/provider/service/systemd.rb +21 -4
- data/lib/puppet/provider/user/useradd.rb +5 -1
- data/lib/puppet/reports/http.rb +5 -3
- data/lib/puppet/runtime.rb +25 -2
- data/lib/puppet/ssl/state_machine.rb +33 -8
- data/lib/puppet/ssl/verifier_adapter.rb +9 -1
- data/lib/puppet/test/test_helper.rb +1 -1
- data/lib/puppet/type/file/source.rb +1 -1
- data/lib/puppet/type/package.rb +16 -1
- data/lib/puppet/type/service.rb +6 -8
- data/lib/puppet/type/user.rb +1 -7
- data/lib/puppet/util/autoload.rb +1 -18
- data/lib/puppet/util/log/destinations.rb +1 -10
- data/lib/puppet/util/package/version/range.rb +4 -1
- data/lib/puppet/util/package/version/range/eq.rb +14 -0
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +191 -111
- data/man/man5/puppet.conf.5 +21 -2
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +6 -3
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-module.8 +4 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +1 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-enabled.txt → dnf-module-list.txt} +6 -0
- data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
- data/spec/integration/application/agent_spec.rb +66 -1
- data/spec/integration/application/plugin_spec.rb +23 -0
- data/spec/integration/http/client_spec.rb +6 -1
- data/spec/integration/network/http_pool_spec.rb +56 -0
- data/spec/integration/util/windows/adsi_spec.rb +5 -0
- data/spec/lib/puppet_spec/https.rb +6 -0
- data/spec/unit/agent_spec.rb +47 -1
- data/spec/unit/application/agent_spec.rb +4 -4
- data/spec/unit/context/trusted_information_spec.rb +17 -0
- data/spec/unit/daemon_spec.rb +5 -64
- data/spec/unit/face/module/search_spec.rb +17 -0
- data/spec/unit/file_system/uniquefile_spec.rb +11 -0
- data/spec/unit/http/client_spec.rb +10 -10
- data/spec/unit/http/external_client_spec.rb +9 -9
- data/spec/unit/indirector/catalog/compiler_spec.rb +1 -0
- data/spec/unit/indirector/file_metadata/http_spec.rb +167 -0
- data/spec/unit/indirector/file_metadata/rest_spec.rb +15 -14
- data/spec/unit/indirector/rest_spec.rb +13 -0
- data/spec/unit/network/http/connection_spec.rb +542 -190
- data/spec/unit/network/http/nocache_pool_spec.rb +22 -0
- data/spec/unit/network/http_pool_spec.rb +63 -57
- data/spec/unit/network/http_spec.rb +1 -1
- data/spec/unit/provider/package/aix_spec.rb +29 -0
- data/spec/unit/provider/package/dnfmodule_spec.rb +25 -5
- data/spec/unit/provider/package/pip_spec.rb +42 -16
- data/spec/unit/provider/package/portage_spec.rb +5 -0
- data/spec/unit/provider/package/yum_spec.rb +16 -8
- data/spec/unit/provider/package/zypper_spec.rb +84 -0
- data/spec/unit/provider/service/init_spec.rb +1 -0
- data/spec/unit/provider/service/openbsd_spec.rb +9 -0
- data/spec/unit/provider/service/openwrt_spec.rb +1 -0
- data/spec/unit/provider/service/redhat_spec.rb +9 -0
- data/spec/unit/provider/service/systemd_spec.rb +84 -13
- data/spec/unit/provider/user/useradd_spec.rb +8 -0
- data/spec/unit/puppet_pal_catalog_spec.rb +43 -0
- data/spec/unit/puppet_spec.rb +33 -0
- data/spec/unit/reports/http_spec.rb +1 -1
- data/spec/unit/ssl/state_machine_spec.rb +52 -8
- data/spec/unit/type/service_spec.rb +9 -8
- data/spec/unit/type/user_spec.rb +1 -1
- data/spec/unit/util/autoload_spec.rb +2 -1
- data/spec/unit/util/log/destinations_spec.rb +1 -29
- data/spec/unit/util/package/version/range_spec.rb +22 -1
- data/tasks/manpages.rake +5 -35
- metadata +10 -4
@@ -39,4 +39,26 @@ describe Puppet::Network::HTTP::NoCachePool do
|
|
39
39
|
it 'has a close method' do
|
40
40
|
Puppet::Network::HTTP::NoCachePool.new.close
|
41
41
|
end
|
42
|
+
|
43
|
+
it 'logs a deprecation warning' do
|
44
|
+
http = double('http', start: nil, finish: nil, started?: true)
|
45
|
+
|
46
|
+
factory = Puppet::Network::HTTP::Factory.new
|
47
|
+
allow(factory).to receive(:create_connection).and_return(http)
|
48
|
+
Puppet::Network::HTTP::NoCachePool.new(factory)
|
49
|
+
|
50
|
+
expect(@logs).to include(an_object_having_attributes(level: :warning, message: /Puppet::Network::HTTP::NoCachePool is deprecated/))
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'omits the warning when deprecations are disabled' do
|
54
|
+
Puppet[:disable_warnings] = 'deprecations'
|
55
|
+
|
56
|
+
http = double('http', start: nil, finish: nil, started?: true)
|
57
|
+
|
58
|
+
factory = Puppet::Network::HTTP::Factory.new
|
59
|
+
allow(factory).to receive(:create_connection).and_return(http)
|
60
|
+
Puppet::Network::HTTP::NoCachePool.new(factory)
|
61
|
+
|
62
|
+
expect(@logs).to eq([])
|
63
|
+
end
|
42
64
|
end
|
@@ -1,41 +1,65 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'puppet/network/http_pool'
|
3
3
|
|
4
|
+
class Puppet::Network::HttpPool::FooClient
|
5
|
+
def initialize(host, port, options = {})
|
6
|
+
@host = host
|
7
|
+
@port = port
|
8
|
+
end
|
9
|
+
attr_reader :host, :port
|
10
|
+
end
|
11
|
+
|
4
12
|
describe Puppet::Network::HttpPool do
|
5
|
-
|
6
|
-
|
7
|
-
|
13
|
+
include PuppetSpec::Files
|
14
|
+
|
15
|
+
describe "when registering an http client class" do
|
16
|
+
let(:http_impl) { Puppet::Network::HttpPool::FooClient }
|
17
|
+
|
18
|
+
around :each do |example|
|
19
|
+
orig_class = Puppet::Network::HttpPool.http_client_class
|
20
|
+
begin
|
21
|
+
example.run
|
22
|
+
ensure
|
23
|
+
Puppet::Network::HttpPool.http_client_class = orig_class
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns instances of the http client class" do
|
28
|
+
Puppet::Network::HttpPool.http_client_class = http_impl
|
29
|
+
http = Puppet::Network::HttpPool.http_instance("me", 54321)
|
30
|
+
expect(http).to be_an_instance_of(http_impl)
|
31
|
+
expect(http.host).to eq('me')
|
32
|
+
expect(http.port).to eq(54321)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "uses the default http client" do
|
36
|
+
expect(Puppet.runtime[:http]).to be_an_instance_of(Puppet::HTTP::Client)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "switches to the external client implementation" do
|
40
|
+
Puppet::Network::HttpPool.http_client_class = http_impl
|
41
|
+
|
42
|
+
expect(Puppet.runtime[:http]).to be_an_instance_of(Puppet::HTTP::ExternalClient)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "always uses an explicitly registered http implementation" do
|
46
|
+
Puppet::Network::HttpPool.http_client_class = http_impl
|
47
|
+
|
48
|
+
new_impl = double('new_http_impl')
|
49
|
+
Puppet.initialize_settings([], true, true, http: new_impl)
|
50
|
+
|
51
|
+
expect(Puppet.runtime[:http]).to eq(new_impl)
|
52
|
+
end
|
8
53
|
end
|
9
54
|
|
10
55
|
describe "when managing http instances" do
|
11
56
|
it "should return an http instance created with the passed host and port" do
|
12
57
|
http = Puppet::Network::HttpPool.http_instance("me", 54321)
|
13
|
-
expect(http).to
|
58
|
+
expect(http).to be_a_kind_of Puppet::Network::HTTP::Connection
|
14
59
|
expect(http.address).to eq('me')
|
15
60
|
expect(http.port).to eq(54321)
|
16
61
|
end
|
17
62
|
|
18
|
-
it "should support using an alternate http client implementation" do
|
19
|
-
begin
|
20
|
-
class FooClient
|
21
|
-
def initialize(host, port, options = {})
|
22
|
-
@host = host
|
23
|
-
@port = port
|
24
|
-
end
|
25
|
-
attr_reader :host, :port
|
26
|
-
end
|
27
|
-
|
28
|
-
orig_class = Puppet::Network::HttpPool.http_client_class
|
29
|
-
Puppet::Network::HttpPool.http_client_class = FooClient
|
30
|
-
http = Puppet::Network::HttpPool.http_instance("me", 54321)
|
31
|
-
expect(http).to be_an_instance_of FooClient
|
32
|
-
expect(http.host).to eq('me')
|
33
|
-
expect(http.port).to eq(54321)
|
34
|
-
ensure
|
35
|
-
Puppet::Network::HttpPool.http_client_class = orig_class
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
63
|
it "should enable ssl on the http instance by default" do
|
40
64
|
expect(Puppet::Network::HttpPool.http_instance("me", 54321)).to be_use_ssl
|
41
65
|
end
|
@@ -82,53 +106,35 @@ describe Puppet::Network::HttpPool do
|
|
82
106
|
end
|
83
107
|
|
84
108
|
describe 'peer verification' do
|
85
|
-
def setup_standard_ssl_configuration
|
86
|
-
ca_cert_file = File.expand_path('/path/to/ssl/certs/ca_cert.pem')
|
87
|
-
|
88
|
-
Puppet[:ssl_client_ca_auth] = ca_cert_file
|
89
|
-
allow(Puppet::FileSystem).to receive(:exist?).with(ca_cert_file).and_return(true)
|
90
|
-
end
|
91
|
-
|
92
|
-
def setup_standard_hostcert
|
93
|
-
host_cert_file = File.expand_path('/path/to/ssl/certs/host_cert.pem')
|
94
|
-
allow(Puppet::FileSystem).to receive(:exist?).with(host_cert_file).and_return(true)
|
95
|
-
|
96
|
-
Puppet[:hostcert] = host_cert_file
|
97
|
-
end
|
98
|
-
|
99
|
-
def setup_standard_ssl_host
|
100
|
-
cert = double('cert', :content => 'real_cert')
|
101
|
-
key = double('key', :content => 'real_key')
|
102
|
-
host = double('host', :certificate => cert, :key => key, :ssl_store => double('store'))
|
103
109
|
|
104
|
-
|
105
|
-
|
110
|
+
before(:each) do
|
111
|
+
Puppet[:ssldir] = tmpdir('ssl')
|
112
|
+
Puppet.settings.use(:main)
|
106
113
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
114
|
+
Puppet[:certname] = 'signed'
|
115
|
+
File.write(Puppet[:localcacert], cert_fixture('ca.pem'))
|
116
|
+
File.write(Puppet[:hostcrl], crl_fixture('crl.pem'))
|
117
|
+
File.write(Puppet[:hostcert], cert_fixture('signed.pem'))
|
118
|
+
File.write(Puppet[:hostprivkey], key_fixture('signed-key.pem'))
|
111
119
|
end
|
112
120
|
|
113
121
|
it 'enables peer verification by default' do
|
114
|
-
|
122
|
+
stub_request(:get, "https://me:54321")
|
123
|
+
|
115
124
|
conn = Puppet::Network::HttpPool.http_instance("me", 54321, true)
|
116
|
-
|
125
|
+
expect_any_instance_of(Net::HTTP).to receive(:start) do |http|
|
117
126
|
expect(http.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
|
118
|
-
|
119
|
-
response
|
120
127
|
end
|
121
128
|
|
122
129
|
conn.get('/')
|
123
130
|
end
|
124
131
|
|
125
132
|
it 'can disable peer verification' do
|
126
|
-
|
133
|
+
stub_request(:get, "https://me:54321")
|
134
|
+
|
127
135
|
conn = Puppet::Network::HttpPool.http_instance("me", 54321, true, false)
|
128
|
-
|
136
|
+
expect_any_instance_of(Net::HTTP).to receive(:start) do |http|
|
129
137
|
expect(http.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
|
130
|
-
|
131
|
-
response
|
132
138
|
end
|
133
139
|
|
134
140
|
conn.get('/')
|
@@ -22,16 +22,26 @@ describe Puppet::Type.type(:package).provider(:aix) do
|
|
22
22
|
|
23
23
|
context "when installing" do
|
24
24
|
it "should install a package" do
|
25
|
+
allow(@provider).to receive(:query).and_return({:name => 'mypackage', :ensure => 'present', :status => :committed})
|
25
26
|
expect(@provider).to receive(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage')
|
26
27
|
@provider.install
|
27
28
|
end
|
28
29
|
|
29
30
|
it "should install a specific package version" do
|
30
31
|
allow(@resource).to receive(:should).with(:ensure).and_return("1.2.3.4")
|
32
|
+
allow(@provider).to receive(:query).and_return({:name => 'mypackage', :ensure => '1.2.3.4', :status => :committed})
|
31
33
|
expect(@provider).to receive(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage 1.2.3.4')
|
32
34
|
@provider.install
|
33
35
|
end
|
34
36
|
|
37
|
+
[:broken, :inconsistent].each do |state|
|
38
|
+
it "should fail if the installation resulted in a '#{state}' state" do
|
39
|
+
allow(@provider).to receive(:query).and_return({:name => 'mypackage', :ensure => 'present', :status => state})
|
40
|
+
expect(@provider).to receive(:installp).with('-acgwXY', '-d', 'mysource', 'mypackage')
|
41
|
+
expect { @provider.install }.to raise_error(Puppet::Error, "Package 'mypackage' is in a #{state} state and requires manual intervention")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
35
45
|
it "should fail if the specified version is superseded" do
|
36
46
|
@resource[:ensure] = '1.2.3.3'
|
37
47
|
allow(@provider).to receive(:installp).and_return(<<-OUTPUT)
|
@@ -126,4 +136,23 @@ END
|
|
126
136
|
expect(described_class).to receive(:execute).and_return('mypackage:mypackage.rte:1.8.6.4::I:T:::::N:A Super Cool Package::::0::\n')
|
127
137
|
described_class.prefetch({ 'mypackage' => latest, 'otherpackage' => absent })
|
128
138
|
end
|
139
|
+
|
140
|
+
context "when querying instances" do
|
141
|
+
before(:each) do
|
142
|
+
allow(described_class).to receive(:execute).and_return(<<-END.chomp)
|
143
|
+
sysmgt.cim.providers:sysmgt.cim.providers.metrics:2.12.1.1: : :B: :Metrics Providers for AIX OS: : : : : : :1:0:/:
|
144
|
+
sysmgt.cim.providers:sysmgt.cim.providers.osbase:2.12.1.1: : :C: :Base Providers for AIX OS: : : : : : :1:0:/:
|
145
|
+
openssl.base:openssl.base:1.0.2.1800: : :?: :Open Secure Socket Layer: : : : : : :0:0:/:
|
146
|
+
END
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should treat installed packages in broken and inconsistent state as absent" do
|
150
|
+
installed_packages = described_class.instances.map { |package| package.properties }
|
151
|
+
expected_packages = [{:name => 'sysmgt.cim.providers.metrics', :ensure => :absent, :status => :broken, :provider => :aix},
|
152
|
+
{:name => 'sysmgt.cim.providers.osbase', :ensure => '2.12.1.1', :status => :committed, :provider => :aix},
|
153
|
+
{:name => 'openssl.base', :ensure => :absent, :status => :inconsistent, :provider => :aix}]
|
154
|
+
|
155
|
+
expect(installed_packages).to eql(expected_packages)
|
156
|
+
end
|
157
|
+
end
|
129
158
|
end
|
@@ -18,7 +18,7 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
|
|
18
18
|
{:failonfail => true, :combine => true, :custom_environment => {}}
|
19
19
|
end
|
20
20
|
|
21
|
-
let(:packages) { File.read(my_fixture("dnf-module-list
|
21
|
+
let(:packages) { File.read(my_fixture("dnf-module-list.txt")) }
|
22
22
|
let(:dnf_path) { '/usr/bin/dnf' }
|
23
23
|
|
24
24
|
before(:each) { allow(Puppet::Util).to receive(:which).with('/usr/bin/dnf').and_return(dnf_path) }
|
@@ -81,7 +81,7 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
describe "when
|
84
|
+
describe "when ensuring a module" do
|
85
85
|
let(:name) { 'baz' }
|
86
86
|
|
87
87
|
let(:resource) do
|
@@ -200,14 +200,32 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
|
|
200
200
|
expect(provider.flavor).to eq('minimal')
|
201
201
|
end
|
202
202
|
end
|
203
|
+
|
204
|
+
context "when disabling a module" do
|
205
|
+
|
206
|
+
it "executed the disable command" do
|
207
|
+
resource[:ensure] = :disabled
|
208
|
+
expect(provider).to receive(:execute).with(array_including('disable'))
|
209
|
+
provider.disable
|
210
|
+
end
|
211
|
+
|
212
|
+
it "does not try to disable if package is already disabled" do
|
213
|
+
allow(described_class).to receive(:command).with(:dnf).and_return(dnf_path)
|
214
|
+
allow(Puppet::Util::Execution).to receive(:execute)
|
215
|
+
.with("/usr/bin/dnf module list -d 0 -e 1")
|
216
|
+
.and_return("baz 1.2 [d][x] common [d], complete Package Description")
|
217
|
+
resource[:ensure] = :disabled
|
218
|
+
expect(provider).to be_insync(:disabled)
|
219
|
+
end
|
220
|
+
end
|
203
221
|
end
|
204
222
|
|
205
|
-
context "parsing the output of module list
|
223
|
+
context "parsing the output of module list" do
|
206
224
|
before { allow(described_class).to receive(:command).with(:dnf).and_return(dnf_path) }
|
207
225
|
|
208
226
|
it "returns an array of enabled modules" do
|
209
227
|
allow(Puppet::Util::Execution).to receive(:execute)
|
210
|
-
.with("/usr/bin/dnf module list
|
228
|
+
.with("/usr/bin/dnf module list -d 0 -e 1")
|
211
229
|
.and_return(packages)
|
212
230
|
|
213
231
|
enabled_packages = described_class.instances.map { |package| package.properties }
|
@@ -219,7 +237,9 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
|
|
219
237
|
{name: "postgresql", ensure: "10", flavor: "server", provider: :dnfmodule},
|
220
238
|
{name: "ruby", ensure: "2.5", flavor: :absent, provider: :dnfmodule},
|
221
239
|
{name: "rust-toolset", ensure: "rhel8", flavor: "common", provider: :dnfmodule},
|
222
|
-
{name: "subversion", ensure: "1.10", flavor: "server", provider: :dnfmodule}
|
240
|
+
{name: "subversion", ensure: "1.10", flavor: "server", provider: :dnfmodule},
|
241
|
+
{name: "swig", ensure: :disabled, flavor: :absent, provider: :dnfmodule},
|
242
|
+
{name: "virt", ensure: :disabled, flavor: :absent, provider: :dnfmodule}]
|
223
243
|
|
224
244
|
expect(enabled_packages).to eql(expected_packages)
|
225
245
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
osfamilies = { 'windows' => ['pip.exe'], 'other' => ['pip', 'pip-python', 'pip2', 'pip-2'] }
|
4
|
+
pip_path_with_spaces = 'C:\Program Files (x86)\Python\Scripts\pip.exe'
|
4
5
|
|
5
6
|
describe Puppet::Type.type(:package).provider(:pip) do
|
6
7
|
|
@@ -102,6 +103,16 @@ describe Puppet::Type.type(:package).provider(:pip) do
|
|
102
103
|
expect(described_class.instances).to eq([])
|
103
104
|
end
|
104
105
|
end
|
106
|
+
|
107
|
+
context "when pip path location contains spaces" do
|
108
|
+
it "should quote the command before doing execpipe" do
|
109
|
+
allow(described_class).to receive(:which).and_return(pip_path_with_spaces)
|
110
|
+
allow(described_class).to receive(:pip_version).with(pip_path_with_spaces).and_return('8.0.1')
|
111
|
+
|
112
|
+
expect(described_class).to receive(:execpipe).with(["\"#{pip_path_with_spaces}\"", ["freeze"]])
|
113
|
+
described_class.instances
|
114
|
+
end
|
115
|
+
end
|
105
116
|
end
|
106
117
|
|
107
118
|
context "query" do
|
@@ -160,15 +171,18 @@ describe Puppet::Type.type(:package).provider(:pip) do
|
|
160
171
|
end
|
161
172
|
|
162
173
|
context "latest" do
|
174
|
+
before do
|
175
|
+
allow(described_class).to receive(:pip_version).with(pip_path).and_return(pip_version)
|
176
|
+
allow(described_class).to receive(:which).with('pip').and_return(pip_path)
|
177
|
+
allow(described_class).to receive(:which).with('pip-python').and_return(pip_path)
|
178
|
+
allow(described_class).to receive(:which).with('pip.exe').and_return(pip_path)
|
179
|
+
allow(described_class).to receive(:provider_command).and_return(pip_path)
|
180
|
+
allow(described_class).to receive(:validate_command).with(pip_path)
|
181
|
+
end
|
182
|
+
|
163
183
|
context "with pip version < 1.5.4" do
|
164
|
-
|
165
|
-
|
166
|
-
allow(described_class).to receive(:which).with('pip').and_return("/fake/bin/pip")
|
167
|
-
allow(described_class).to receive(:which).with('pip-python').and_return("/fake/bin/pip")
|
168
|
-
allow(described_class).to receive(:which).with('pip.exe').and_return("/fake/bin/pip")
|
169
|
-
allow(described_class).to receive(:provider_command).and_return('/fake/bin/pip')
|
170
|
-
allow(described_class).to receive(:validate_command).with('/fake/bin/pip')
|
171
|
-
end
|
184
|
+
let(:pip_version) { '1.0.1' }
|
185
|
+
let(:pip_path) { '/fake/bin/pip' }
|
172
186
|
|
173
187
|
it "should find a version number for new_pip_package" do
|
174
188
|
p = StringIO.new(
|
@@ -236,19 +250,22 @@ describe Puppet::Type.type(:package).provider(:pip) do
|
|
236
250
|
@resource[:install_options] = ['--index' => 'https://fake.example.com']
|
237
251
|
expect(@provider.latest).to eq(nil)
|
238
252
|
end
|
253
|
+
|
254
|
+
context "when pip path location contains spaces" do
|
255
|
+
let(:pip_path) { pip_path_with_spaces }
|
256
|
+
|
257
|
+
it "should quote the command before doing execpipe" do
|
258
|
+
expect(Puppet::Util::Execution).to receive(:execpipe).with(array_including("\"#{pip_path}\""))
|
259
|
+
@provider.latest
|
260
|
+
end
|
261
|
+
end
|
239
262
|
end
|
240
263
|
|
241
264
|
context "with pip version >= 1.5.4" do
|
242
265
|
# For Pip 1.5.4 and above, you can get a version list from CLI - which allows for native pip behavior
|
243
266
|
# with regards to custom repositories, proxies and the like
|
244
|
-
|
245
|
-
|
246
|
-
allow(described_class).to receive(:which).with('pip').and_return("/fake/bin/pip")
|
247
|
-
allow(described_class).to receive(:which).with('pip-python').and_return("/fake/bin/pip")
|
248
|
-
allow(described_class).to receive(:which).with('pip.exe').and_return("/fake/bin/pip")
|
249
|
-
allow(described_class).to receive(:provider_command).and_return('/fake/bin/pip')
|
250
|
-
allow(described_class).to receive(:validate_command).with('/fake/bin/pip')
|
251
|
-
end
|
267
|
+
let(:pip_version) { '1.5.4' }
|
268
|
+
let(:pip_path) { '/fake/bin/pip' }
|
252
269
|
|
253
270
|
it "should find a version number for real_package" do
|
254
271
|
p = StringIO.new(
|
@@ -296,6 +313,15 @@ describe Puppet::Type.type(:package).provider(:pip) do
|
|
296
313
|
@resource[:install_options] = ['--index' => 'https://fake.example.com']
|
297
314
|
expect(@provider.latest).to eq(nil)
|
298
315
|
end
|
316
|
+
|
317
|
+
context "when pip path location contains spaces" do
|
318
|
+
let(:pip_path) { pip_path_with_spaces }
|
319
|
+
|
320
|
+
it "should quote the command before doing execpipe" do
|
321
|
+
expect(Puppet::Util::Execution).to receive(:execpipe).with(array_including("\"#{pip_path}\""))
|
322
|
+
@provider.latest
|
323
|
+
end
|
324
|
+
end
|
299
325
|
end
|
300
326
|
end
|
301
327
|
|
@@ -72,6 +72,11 @@ describe Puppet::Type.type(:package).provider(:portage) do
|
|
72
72
|
expect(described_class).to be_reinstallable
|
73
73
|
end
|
74
74
|
|
75
|
+
it "should be the default provider on :osfamily => Gentoo" do
|
76
|
+
expect(Facter).to receive(:value).with(:osfamily).and_return("Gentoo")
|
77
|
+
expect(described_class.default?).to be_truthy
|
78
|
+
end
|
79
|
+
|
75
80
|
it 'should support string install options' do
|
76
81
|
expect(@provider).to receive(:emerge).with('--foo', '--bar', @resource[:name])
|
77
82
|
|
@@ -259,7 +259,7 @@ describe Puppet::Type.type(:package).provider(:yum) do
|
|
259
259
|
|
260
260
|
describe 'insync?' do
|
261
261
|
context 'when version is not a valid RPM version' do
|
262
|
-
let(:is) { 'a:123' }
|
262
|
+
let(:is) { '>===a:123' }
|
263
263
|
|
264
264
|
before do
|
265
265
|
resource[:ensure] = is
|
@@ -269,18 +269,26 @@ describe Puppet::Type.type(:package).provider(:yum) do
|
|
269
269
|
expect(Puppet).to receive(:debug).with("Cannot parse #{is} as a RPM version range")
|
270
270
|
provider.insync?(is)
|
271
271
|
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context 'with valid semantic versions' do
|
275
|
+
let(:is) { '1:1.2.3.4-5.el4' }
|
272
276
|
|
273
|
-
|
274
|
-
|
277
|
+
it 'returns true if the current version matches the given semantic version' do
|
278
|
+
resource[:ensure] = is
|
279
|
+
expect(provider).to be_insync(is)
|
275
280
|
end
|
276
281
|
|
277
|
-
|
278
|
-
|
282
|
+
it 'returns false if the current version does not match the given semantic version' do
|
283
|
+
resource[:ensure] = '999r'
|
284
|
+
expect(provider).not_to be_insync(is)
|
279
285
|
end
|
280
|
-
end
|
281
286
|
|
282
|
-
|
283
|
-
|
287
|
+
it 'no debug logs if the current version matches the given semantic version' do
|
288
|
+
resource[:ensure] = is
|
289
|
+
expect(Puppet).not_to receive(:debug)
|
290
|
+
provider.insync?(is)
|
291
|
+
end
|
284
292
|
|
285
293
|
it 'returns true if current version matches the greater or equal semantic version in ensure' do
|
286
294
|
resource[:ensure] = '<=1:1.2.3.4-5.el4'
|