puppet 6.7.2 → 6.8.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.

Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +9 -9
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +7 -7
  5. data/install.rb +3 -21
  6. data/lib/puppet/application/agent.rb +17 -13
  7. data/lib/puppet/application/device.rb +10 -0
  8. data/lib/puppet/defaults.rb +21 -6
  9. data/lib/puppet/face/facts.rb +1 -1
  10. data/lib/puppet/face/parser.rb +3 -2
  11. data/lib/puppet/forge.rb +19 -4
  12. data/lib/puppet/indirector/certificate/file.rb +1 -0
  13. data/lib/puppet/indirector/certificate/rest.rb +1 -0
  14. data/lib/puppet/indirector/certificate_request/file.rb +1 -0
  15. data/lib/puppet/indirector/certificate_request/memory.rb +1 -0
  16. data/lib/puppet/indirector/certificate_request/rest.rb +1 -0
  17. data/lib/puppet/indirector/key/file.rb +1 -0
  18. data/lib/puppet/indirector/key/memory.rb +1 -0
  19. data/lib/puppet/module_tool/applications/installer.rb +0 -3
  20. data/lib/puppet/network/http/factory.rb +1 -11
  21. data/lib/puppet/pops/lookup.rb +1 -0
  22. data/lib/puppet/pops/lookup/key_recorder.rb +18 -0
  23. data/lib/puppet/pops/lookup/lookup_adapter.rb +7 -0
  24. data/lib/puppet/provider/file/posix.rb +5 -0
  25. data/lib/puppet/provider/nameservice.rb +10 -3
  26. data/lib/puppet/provider/package/apt.rb +1 -1
  27. data/lib/puppet/provider/package/dpkg.rb +17 -3
  28. data/lib/puppet/provider/service/launchd.rb +20 -5
  29. data/lib/puppet/provider/service/systemd.rb +5 -10
  30. data/lib/puppet/provider/user/pw.rb +12 -3
  31. data/lib/puppet/provider/user/user_role_add.rb +4 -0
  32. data/lib/puppet/provider/user/useradd.rb +25 -11
  33. data/lib/puppet/ssl/certificate.rb +2 -0
  34. data/lib/puppet/ssl/host.rb +3 -0
  35. data/lib/puppet/ssl/key.rb +2 -0
  36. data/lib/puppet/util/http_proxy.rb +17 -3
  37. data/lib/puppet/util/monkey_patches.rb +0 -16
  38. data/lib/puppet/util/selinux.rb +5 -1
  39. data/lib/puppet/util/windows/security.rb +2 -0
  40. data/lib/puppet/util/windows/sid.rb +1 -0
  41. data/lib/puppet/version.rb +1 -1
  42. data/lib/puppet/x509/cert_provider.rb +13 -15
  43. data/locales/puppet.pot +77 -65
  44. data/man/man5/puppet.conf.5 +20 -4
  45. data/man/man8/puppet-agent.8 +24 -7
  46. data/man/man8/puppet-apply.8 +1 -1
  47. data/man/man8/puppet-catalog.8 +1 -1
  48. data/man/man8/puppet-config.8 +1 -1
  49. data/man/man8/puppet-describe.8 +1 -1
  50. data/man/man8/puppet-device.8 +1 -1
  51. data/man/man8/puppet-doc.8 +1 -1
  52. data/man/man8/puppet-epp.8 +1 -1
  53. data/man/man8/puppet-facts.8 +1 -1
  54. data/man/man8/puppet-filebucket.8 +1 -1
  55. data/man/man8/puppet-generate.8 +1 -1
  56. data/man/man8/puppet-help.8 +1 -1
  57. data/man/man8/puppet-key.8 +1 -1
  58. data/man/man8/puppet-lookup.8 +1 -1
  59. data/man/man8/puppet-man.8 +1 -1
  60. data/man/man8/puppet-module.8 +1 -1
  61. data/man/man8/puppet-node.8 +1 -1
  62. data/man/man8/puppet-parser.8 +1 -1
  63. data/man/man8/puppet-plugin.8 +1 -1
  64. data/man/man8/puppet-report.8 +1 -1
  65. data/man/man8/puppet-resource.8 +1 -1
  66. data/man/man8/puppet-script.8 +1 -1
  67. data/man/man8/puppet-ssl.8 +1 -1
  68. data/man/man8/puppet-status.8 +1 -1
  69. data/man/man8/puppet.8 +2 -2
  70. data/spec/integration/provider/service/systemd_spec.rb +7 -5
  71. data/spec/integration/type/file_spec.rb +28 -0
  72. data/spec/unit/application/device_spec.rb +26 -0
  73. data/spec/unit/face/facts_spec.rb +9 -0
  74. data/spec/unit/face/parser_spec.rb +17 -5
  75. data/spec/unit/forge/module_release_spec.rb +66 -31
  76. data/spec/unit/module_tool/applications/installer_spec.rb +0 -9
  77. data/spec/unit/network/http/factory_spec.rb +27 -5
  78. data/spec/unit/provider/package/dpkg_spec.rb +84 -4
  79. data/spec/unit/provider/service/launchd_spec.rb +28 -0
  80. data/spec/unit/provider/service/systemd_spec.rb +14 -0
  81. data/spec/unit/provider/user/pw_spec.rb +37 -0
  82. data/spec/unit/provider/user/useradd_spec.rb +42 -0
  83. data/spec/unit/transaction_spec.rb +18 -0
  84. data/spec/unit/util/http_proxy_spec.rb +24 -1
  85. data/spec/unit/x509/cert_provider_spec.rb +1 -1
  86. metadata +4 -7
  87. data/ext/windows/eventlog/Rakefile +0 -32
  88. data/ext/windows/eventlog/puppetres.dll +0 -0
  89. data/ext/windows/eventlog/puppetres.mc +0 -18
@@ -45,6 +45,15 @@ CONF
45
45
  subject.upload
46
46
  end
47
47
 
48
+ it "passes the current environment" do
49
+ env = Puppet::Node::Environment.remote('qa')
50
+ expect(model.indirection).to receive(:save).with(anything, nil, :environment => env)
51
+
52
+ Puppet.override(:current_environment => env) do
53
+ subject.upload
54
+ end
55
+ end
56
+
48
57
  it "uses settings from the agent section of puppet.conf" do
49
58
  expect(facter_terminus).to receive(:find).with(have_attributes(key: 'puppet.node.test')).and_return(test_data)
50
59
 
@@ -105,13 +105,25 @@ describe Puppet::Face[:parser, :current] do
105
105
  end
106
106
  end
107
107
 
108
- it "validates the contents of STDIN when no files given and STDIN is not a tty" do
109
- from_a_piped_input_of("{ invalid =>")
108
+ context "when no files given and STDIN is not a tty" do
109
+ it "validates the contents of STDIN" do
110
+ from_a_piped_input_of("{ invalid =>")
110
111
 
111
- Puppet.override(:current_environment => Puppet::Node::Environment.create(:special, [])) do
112
- parse_errors = parser.validate()
112
+ Puppet.override(:current_environment => Puppet::Node::Environment.create(:special, [])) do
113
+ parse_errors = parser.validate()
114
+
115
+ expect(parse_errors['STDIN']).to be_a_kind_of(Puppet::ParseErrorWithIssue)
116
+ end
117
+ end
113
118
 
114
- expect(parse_errors['STDIN']).to be_a_kind_of(Puppet::ParseErrorWithIssue)
119
+ it "runs error free when contents of STDIN is valid" do
120
+ from_a_piped_input_of("notify { valid: }")
121
+
122
+ Puppet.override(:current_environment => Puppet::Node::Environment.create(:special, [])) do
123
+ parse_errors = parser.validate()
124
+
125
+ expect(parse_errors).to be_empty
126
+ end
115
127
  end
116
128
  end
117
129
 
@@ -15,6 +15,7 @@ describe Puppet::Forge::ModuleRelease do
15
15
  let(:module_full_name) { "#{module_author}-#{module_name}" }
16
16
  let(:module_full_name_versioned) { "#{module_full_name}-#{module_version}" }
17
17
  let(:module_md5) { "bbf919d7ee9d278d2facf39c25578bf8" }
18
+ let(:module_sha256) { "b4c6f15cec64a9fe16ef0d291e2598fc84f381bc59f0e67198d61706fafedae4" }
18
19
  let(:uri) { " "}
19
20
  let(:release) { Puppet::Forge::ModuleRelease.new(ssl_repository, JSON.parse(release_json)) }
20
21
 
@@ -31,21 +32,6 @@ describe Puppet::Forge::ModuleRelease do
31
32
  allow(Digest::MD5).to receive(:file).and_return(double(:hexdigest => md5))
32
33
  end
33
34
 
34
- describe '#prepare' do
35
- before :each do
36
- allow(release).to receive(:tmpfile).and_return(mock_file)
37
- allow(release).to receive(:tmpdir).and_return(mock_dir)
38
- end
39
-
40
- it 'should call sub methods with correct params' do
41
- expect(release).to receive(:download).with("/#{api_version}/files/#{module_full_name_versioned}.tar.gz", mock_file)
42
- expect(release).to receive(:validate_checksum).with(mock_file, module_md5)
43
- expect(release).to receive(:unpack).with(mock_file, mock_dir)
44
-
45
- release.prepare
46
- end
47
- end
48
-
49
35
  describe '#tmpfile' do
50
36
  it 'should be opened in binary mode' do
51
37
  allow(Puppet::Forge::Cache).to receive(:base_path).and_return(Dir.tmpdir)
@@ -67,21 +53,6 @@ describe Puppet::Forge::ModuleRelease do
67
53
  end
68
54
  end
69
55
 
70
- describe '#verify_checksum' do
71
- it 'passes md5 check when valid' do
72
- # valid hash comes from file_md5 in JSON blob above
73
- mock_digest_file_with_md5(module_md5)
74
-
75
- release.send(:validate_checksum, mock_file, module_md5)
76
- end
77
-
78
- it 'fails md5 check when invalid' do
79
- mock_digest_file_with_md5('ffffffffffffffffffffffffffffffff')
80
-
81
- expect { release.send(:validate_checksum, mock_file, module_md5) }.to raise_error(RuntimeError, /did not match expected checksum/)
82
- end
83
- end
84
-
85
56
  describe '#unpack' do
86
57
  it 'should call unpacker with correct params' do
87
58
  expect(Puppet::ModuleTool::Applications::Unpacker).to receive(:unpack).with(mock_file.path, mock_dir).and_return(true)
@@ -130,6 +101,7 @@ describe Puppet::Forge::ModuleRelease do
130
101
  "file_uri": "/#{api_version}/files/#{module_full_name_versioned}.tar.gz",
131
102
  "file_size": 67586,
132
103
  "file_md5": "#{module_md5}",
104
+ "file_sha256": "#{module_sha256}",
133
105
  "downloads": 610751,
134
106
  "readme": "",
135
107
  "changelog": "",
@@ -142,6 +114,66 @@ describe Puppet::Forge::ModuleRelease do
142
114
  end
143
115
 
144
116
  it_behaves_like 'a module release'
117
+
118
+ context 'when verifying checksums' do
119
+ let(:json) { JSON.parse(release_json) }
120
+
121
+ def mock_release(json)
122
+ release = Puppet::Forge::ModuleRelease.new(ssl_repository, json)
123
+ allow(release).to receive(:tmpfile).and_return(mock_file)
124
+ allow(release).to receive(:tmpdir).and_return(mock_dir)
125
+ allow(release).to receive(:download).with("/#{api_version}/files/#{module_full_name_versioned}.tar.gz", mock_file)
126
+ allow(release).to receive(:unpack)
127
+ release
128
+ end
129
+
130
+ it 'verifies using SHA256' do
131
+ expect(Digest::SHA256).to receive(:file).and_return(double(:hexdigest => module_sha256))
132
+
133
+ release = mock_release(json)
134
+ release.prepare
135
+ end
136
+
137
+ it 'rejects an invalid release with SHA256' do
138
+ expect(Digest::SHA256).to receive(:file).and_return(double(:hexdigest => 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'))
139
+
140
+ release = mock_release(json)
141
+ expect {
142
+ release.prepare
143
+ }.to raise_error(RuntimeError, /did not match expected checksum/)
144
+ end
145
+
146
+ context 'when `file_sha256` is missing' do
147
+ before(:each) do
148
+ json.delete('file_sha256')
149
+ end
150
+
151
+ it 'verifies using MD5 if `file_sha256` is missing' do
152
+ expect(Digest::MD5).to receive(:file).and_return(double(:hexdigest => module_md5))
153
+
154
+ release = mock_release(json)
155
+ release.prepare
156
+ end
157
+
158
+ it 'rejects an invalid release with MD5' do
159
+ expect(Digest::MD5).to receive(:file).and_return(double(:hexdigest => 'ffffffffffffffffffffffffffffffff'))
160
+
161
+ release = mock_release(json)
162
+ expect {
163
+ release.prepare
164
+ }.to raise_error(RuntimeError, /did not match expected checksum/)
165
+ end
166
+
167
+ it 'raises if FIPS is enabled' do
168
+ allow(Facter).to receive(:value).with(:fips_enabled).and_return(true)
169
+
170
+ release = mock_release(json)
171
+ expect {
172
+ release.prepare
173
+ }.to raise_error(/Module install using MD5 is prohibited in FIPS mode./)
174
+ end
175
+ end
176
+ end
145
177
  end
146
178
 
147
179
  context 'forge module with no dependencies field' do
@@ -180,6 +212,7 @@ describe Puppet::Forge::ModuleRelease do
180
212
  "file_uri": "/#{api_version}/files/#{module_full_name_versioned}.tar.gz",
181
213
  "file_size": 67586,
182
214
  "file_md5": "#{module_md5}",
215
+ "file_sha256": "#{module_sha256}",
183
216
  "downloads": 610751,
184
217
  "readme": "",
185
218
  "changelog": "",
@@ -208,7 +241,8 @@ describe Puppet::Forge::ModuleRelease do
208
241
  },
209
242
  "file_uri": "/#{api_version}/files/#{module_full_name_versioned}.tar.gz",
210
243
  "file_size": 67586,
211
- "file_md5": "#{module_md5}"
244
+ "file_md5": "#{module_md5}",
245
+ "file_sha256": "#{module_sha256}"
212
246
  }
213
247
  }
214
248
  end
@@ -256,6 +290,7 @@ describe Puppet::Forge::ModuleRelease do
256
290
  "file_uri": "/#{api_version}/files/#{module_full_name_versioned}.tar.gz",
257
291
  "file_size": 67586,
258
292
  "file_md5": "#{module_md5}",
293
+ "file_sha256": "#{module_sha256}",
259
294
  "downloads": 610751,
260
295
  "readme": "",
261
296
  "changelog": "",
@@ -365,14 +365,5 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => RUBY_PLATFORM =
365
365
  end
366
366
  end
367
367
  end
368
-
369
- context 'when in FIPS mode...' do
370
- it 'module installer refuses to run' do
371
- allow(Facter).to receive(:value).with(:fips_enabled).and_return(true)
372
- expect {application.run}.to raise_error(/Module install is prohibited in FIPS mode./)
373
- end
374
- end
375
-
376
368
  end
377
-
378
369
  end
@@ -43,10 +43,11 @@ describe Puppet::Network::HTTP::Factory do
43
43
  context "proxy settings" do
44
44
  let(:proxy_host) { 'myhost' }
45
45
  let(:proxy_port) { 432 }
46
+ let(:proxy_user) { 'mo' }
47
+ let(:proxy_pass) { 'password' }
46
48
 
47
- it "should not set a proxy if the value is 'none'" do
49
+ it "should not set a proxy if the http_proxy_host setting is 'none'" do
48
50
  Puppet[:http_proxy_host] = 'none'
49
- expect(Puppet::Util::HttpProxy).to receive(:no_proxy?).and_return(false)
50
51
  conn = create_connection(site)
51
52
 
52
53
  expect(conn.proxy_address).to be_nil
@@ -55,7 +56,18 @@ describe Puppet::Network::HTTP::Factory do
55
56
  it 'should not set a proxy if a no_proxy env var matches the destination' do
56
57
  Puppet[:http_proxy_host] = proxy_host
57
58
  Puppet[:http_proxy_port] = proxy_port
58
- expect(Puppet::Util::HttpProxy).to receive(:no_proxy?).and_return(true)
59
+ Puppet::Util.withenv('NO_PROXY' => site.host) do
60
+ conn = create_connection(site)
61
+
62
+ expect(conn.proxy_address).to be_nil
63
+ expect(conn.proxy_port).to be_nil
64
+ end
65
+ end
66
+
67
+ it 'should not set a proxy if the no_proxy setting matches the destination' do
68
+ Puppet[:http_proxy_host] = proxy_host
69
+ Puppet[:http_proxy_port] = proxy_port
70
+ Puppet[:no_proxy] = site.host
59
71
  conn = create_connection(site)
60
72
 
61
73
  expect(conn.proxy_address).to be_nil
@@ -64,7 +76,6 @@ describe Puppet::Network::HTTP::Factory do
64
76
 
65
77
  it 'sets proxy_address' do
66
78
  Puppet[:http_proxy_host] = proxy_host
67
- expect(Puppet::Util::HttpProxy).to receive(:no_proxy?).and_return(false)
68
79
  conn = create_connection(site)
69
80
 
70
81
  expect(conn.proxy_address).to eq(proxy_host)
@@ -73,11 +84,22 @@ describe Puppet::Network::HTTP::Factory do
73
84
  it 'sets proxy address and port' do
74
85
  Puppet[:http_proxy_host] = proxy_host
75
86
  Puppet[:http_proxy_port] = proxy_port
76
- expect(Puppet::Util::HttpProxy).to receive(:no_proxy?).and_return(false)
77
87
  conn = create_connection(site)
78
88
 
79
89
  expect(conn.proxy_port).to eq(proxy_port)
80
90
  end
91
+
92
+ it 'sets proxy user and password' do
93
+ Puppet[:http_proxy_host] = proxy_host
94
+ Puppet[:http_proxy_port] = proxy_port
95
+ Puppet[:http_proxy_user] = proxy_user
96
+ Puppet[:http_proxy_password] = proxy_pass
97
+
98
+ conn = create_connection(site)
99
+
100
+ expect(conn.proxy_user).to eq(proxy_user)
101
+ expect(conn.proxy_pass).to eq(proxy_pass)
102
+ end
81
103
  end
82
104
 
83
105
  context 'socket timeouts' do
@@ -8,6 +8,7 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
8
8
  let(:vim_installed_output) { "install ok installed vim 2:7.3.547-6ubuntu5\n" }
9
9
  let(:all_installed_io) { StringIO.new([bash_installed_output, vim_installed_output].join) }
10
10
  let(:args) { ['-W', '--showformat', %Q{'${Status} ${Package} ${Version}\\n'}] }
11
+ let(:args_with_provides) { ['/bin/dpkg-query','-W', '--showformat', %Q{'${Status} ${Package} ${Version} [${Provides}]\\n'}]}
11
12
  let(:execute_options) do
12
13
  {:failonfail => true, :combine => true, :custom_environment => {}}
13
14
  end
@@ -31,7 +32,6 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
31
32
 
32
33
  installed = double('bash')
33
34
  expect(described_class).to receive(:new).with(:ensure => "4.2-5ubuntu3", :error => "ok", :desired => "install", :name => "bash", :status => "installed", :provider => :dpkg).and_return(installed)
34
-
35
35
  expect(described_class.instances).to eq([installed])
36
36
  end
37
37
 
@@ -68,31 +68,59 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
68
68
  expect(Puppet::Util::Execution).to receive(:execute).with(query_args, execute_options).and_return(Puppet::Util::Execution::ProcessOutput.new(output, 0))
69
69
  end
70
70
 
71
+ def dpkg_query_execution_with_multiple_args_returns(output, *args)
72
+ args.each do |arg|
73
+ expect(Puppet::Util::Execution).to receive(:execute).with(arg, execute_options).ordered.and_return(Puppet::Util::Execution::ProcessOutput.new(output, 0))
74
+ end
75
+ end
76
+
71
77
  before do
72
78
  allow(Puppet::Util).to receive(:which).with('/usr/bin/dpkg-query').and_return(dpkgquery_path)
79
+ allow(resource).to receive(:allow_virtual?).and_return(false)
73
80
  end
74
81
 
75
82
  it "considers the package purged if dpkg-query fails" do
76
83
  allow(Puppet::Util::Execution).to receive(:execute).with(query_args, execute_options).and_raise(Puppet::ExecutionFailure.new("eh"))
84
+ expect(provider.query[:ensure]).to eq(:purged)
85
+ end
77
86
 
87
+ it "considers the package purged if dpkg-query fails with allow_virtual enabled" do
88
+ allow(resource).to receive(:allow_virtual?).and_return(true)
89
+ allow(Puppet::Util::Execution).to receive(:execute).with(args_with_provides, execute_options).and_raise(Puppet::ExecutionFailure.new("eh"))
78
90
  expect(provider.query[:ensure]).to eq(:purged)
79
91
  end
80
92
 
81
93
  it "returns a hash of the found package status for an installed package" do
82
94
  dpkg_query_execution_returns(bash_installed_output)
95
+ expect(provider.query).to eq({:ensure => "4.2-5ubuntu3", :error => "ok", :desired => "install", :name => "bash", :status => "installed", :provider => :dpkg})
96
+ end
83
97
 
98
+ it "returns a hash of the found package status for an installed package with allo_virtual enabled" do
99
+ allow(resource).to receive(:allow_virtual?).and_return(true)
100
+ dpkg_query_execution_with_multiple_args_returns(bash_installed_output,args_with_provides,query_args)
84
101
  expect(provider.query).to eq({:ensure => "4.2-5ubuntu3", :error => "ok", :desired => "install", :name => "bash", :status => "installed", :provider => :dpkg})
85
102
  end
86
103
 
87
104
  it "considers the package absent if the dpkg-query result cannot be interpreted" do
105
+ allow(resource).to receive(:allow_virtual?).and_return(false)
88
106
  dpkg_query_execution_returns('some-bad-data')
107
+ expect(provider.query[:ensure]).to eq(:absent)
108
+ end
89
109
 
110
+ it "considers the package absent if the dpkg-query result cannot be interpreted with allow_virtual enabled" do
111
+ allow(resource).to receive(:allow_virtual?).and_return(true)
112
+ dpkg_query_execution_with_multiple_args_returns('some-bad-data',args_with_provides,query_args)
90
113
  expect(provider.query[:ensure]).to eq(:absent)
91
114
  end
92
115
 
93
116
  it "fails if an error is discovered" do
94
117
  dpkg_query_execution_returns(bash_installed_output.gsub("ok","error"))
118
+ expect { provider.query }.to raise_error(Puppet::Error)
119
+ end
95
120
 
121
+ it "fails if an error is discovered with allow_virtual enabled" do
122
+ allow(resource).to receive(:allow_virtual?).and_return(true)
123
+ dpkg_query_execution_with_multiple_args_returns(bash_installed_output.gsub("ok","error"),args_with_provides,query_args)
96
124
  expect { provider.query }.to raise_error(Puppet::Error)
97
125
  end
98
126
 
@@ -100,35 +128,74 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
100
128
  not_installed_bash = bash_installed_output.gsub("installed", "not-installed")
101
129
  not_installed_bash.gsub!(bash_version, "")
102
130
  dpkg_query_execution_returns(not_installed_bash)
131
+ expect(provider.query[:ensure]).to eq(:purged)
132
+ end
103
133
 
134
+ it "considers the package purged if it is marked 'not-installed' with allow_virtual enabled" do
135
+ allow(resource).to receive(:allow_virtual?).and_return(true)
136
+ not_installed_bash = bash_installed_output.gsub("installed", "not-installed")
137
+ not_installed_bash.gsub!(bash_version, "")
138
+ dpkg_query_execution_with_multiple_args_returns(not_installed_bash,args_with_provides,query_args)
104
139
  expect(provider.query[:ensure]).to eq(:purged)
105
140
  end
106
141
 
142
+
107
143
  it "considers the package absent if it is marked 'config-files'" do
108
144
  dpkg_query_execution_returns(bash_installed_output.gsub("installed","config-files"))
109
145
  expect(provider.query[:ensure]).to eq(:absent)
110
146
  end
111
147
 
148
+ it "considers the package absent if it is marked 'config-files' with allow_virtual enabled" do
149
+ allow(resource).to receive(:allow_virtual?).and_return(true)
150
+ dpkg_query_execution_with_multiple_args_returns(bash_installed_output.gsub("installed","config-files"),args_with_provides,query_args)
151
+ expect(provider.query[:ensure]).to eq(:absent)
152
+ end
153
+
112
154
  it "considers the package absent if it is marked 'half-installed'" do
113
155
  dpkg_query_execution_returns(bash_installed_output.gsub("installed","half-installed"))
114
156
  expect(provider.query[:ensure]).to eq(:absent)
115
157
  end
116
158
 
159
+ it "considers the package absent if it is marked 'half-installed' with allow_virtual enabled" do
160
+ allow(resource).to receive(:allow_virtual?).and_return(true)
161
+ dpkg_query_execution_with_multiple_args_returns(bash_installed_output.gsub("installed","half-installed"),args_with_provides,query_args)
162
+ expect(provider.query[:ensure]).to eq(:absent)
163
+ end
164
+
117
165
  it "considers the package absent if it is marked 'unpacked'" do
118
166
  dpkg_query_execution_returns(bash_installed_output.gsub("installed","unpacked"))
119
167
  expect(provider.query[:ensure]).to eq(:absent)
120
168
  end
121
169
 
170
+
171
+ it "considers the package absent if it is marked 'unpacked' with allow_virtual enabled" do
172
+ allow(resource).to receive(:allow_virtual?).and_return(true)
173
+ dpkg_query_execution_with_multiple_args_returns(bash_installed_output.gsub("installed","unpacked"),args_with_provides,query_args)
174
+ expect(provider.query[:ensure]).to eq(:absent)
175
+ end
176
+
122
177
  it "considers the package absent if it is marked 'half-configured'" do
123
178
  dpkg_query_execution_returns(bash_installed_output.gsub("installed","half-configured"))
124
179
  expect(provider.query[:ensure]).to eq(:absent)
125
180
  end
126
181
 
182
+ it "considers the package absent if it is marked 'half-configured' with allow_virtual enabled" do
183
+ allow(resource).to receive(:allow_virtual?).and_return(true)
184
+ dpkg_query_execution_with_multiple_args_returns(bash_installed_output.gsub("installed","half-configured"),args_with_provides,query_args)
185
+ expect(provider.query[:ensure]).to eq(:absent)
186
+ end
187
+
127
188
  it "considers the package held if its state is 'hold'" do
128
189
  dpkg_query_execution_returns(bash_installed_output.gsub("install","hold"))
129
190
  expect(provider.query[:ensure]).to eq(:held)
130
191
  end
131
192
 
193
+ it "considers the package held if its state is 'hold' with allow_virtual enabled" do
194
+ allow(resource).to receive(:allow_virtual?).and_return(true)
195
+ dpkg_query_execution_with_multiple_args_returns(bash_installed_output.gsub("install","hold"),args_with_provides,query_args)
196
+ expect(provider.query[:ensure]).to eq(:held)
197
+ end
198
+
132
199
  context "parsing tests" do
133
200
  let(:resource_name) { 'name' }
134
201
  let(:package_hash) do
@@ -144,6 +211,7 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
144
211
  let(:package_not_found_hash) do
145
212
  {:ensure => :purged, :status => 'missing', :name => resource_name, :error => 'ok'}
146
213
  end
214
+ let(:output) {'an unexpected dpkg msg with an exit code of 0'}
147
215
 
148
216
  def parser_test(dpkg_output_string, gold_hash, number_of_debug_logs = 0)
149
217
  dpkg_query_execution_returns(dpkg_output_string)
@@ -157,20 +225,33 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
157
225
  no_ensure = 'desired ok status name '
158
226
  parser_test(no_ensure, package_hash.merge(:ensure => ''))
159
227
  end
228
+ it "provides debug logging of unparsable lines with allow_virtual enabled" do
229
+ allow(resource).to receive(:allow_virtual?).and_return(true)
230
+ dpkg_query_execution_with_multiple_args_returns(output, args_with_provides, query_args)
231
+ expect(Puppet).not_to receive(:warning)
232
+ expect(Puppet).to receive(:debug).exactly(1).times
233
+ expect(provider.query).to eq(package_not_found_hash.merge(:ensure => :absent))
234
+ end
235
+
160
236
 
161
237
  it "provides debug logging of unparsable lines" do
162
238
  parser_test('an unexpected dpkg msg with an exit code of 0', package_not_found_hash.merge(:ensure => :absent), 1)
163
239
  end
240
+
241
+ it "does not log if execution returns with non-zero exit code with allow_virtual enabled" do
242
+ allow(resource).to receive(:allow_virtual?).and_return(true)
243
+ expect(Puppet::Util::Execution).to receive(:execute).with(args_with_provides, execute_options).ordered.and_raise(Puppet::ExecutionFailure.new("failed"))
244
+ expect(Puppet).not_to receive(:debug)
245
+ expect(provider.query).to eq(package_not_found_hash)
246
+ end
164
247
 
165
248
  it "does not log if execution returns with non-zero exit code" do
166
249
  expect(Puppet::Util::Execution).to receive(:execute).with(query_args, execute_options).and_raise(Puppet::ExecutionFailure.new("failed"))
167
250
  expect(Puppet).not_to receive(:debug)
168
-
169
251
  expect(provider.query).to eq(package_not_found_hash)
170
252
  end
171
253
  end
172
254
  end
173
-
174
255
  context "when installing" do
175
256
  before do
176
257
  allow(resource).to receive(:[]).with(:source).and_return("mypkg")
@@ -292,4 +373,3 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
292
373
  expect {provider.package_not_installed?("")}.to raise_error(ArgumentError,"Package name is nil or empty")
293
374
  end
294
375
  end
295
-