puppet 6.4.3-x86-mingw32 → 6.4.4-x86-mingw32

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +9 -9
  3. data/Gemfile +2 -2
  4. data/Gemfile.lock +23 -23
  5. data/ext/project_data.yaml +2 -2
  6. data/install.rb +3 -21
  7. data/lib/puppet/application/agent.rb +12 -0
  8. data/lib/puppet/application/device.rb +14 -4
  9. data/lib/puppet/application/resource.rb +4 -4
  10. data/lib/puppet/defaults.rb +12 -0
  11. data/lib/puppet/face/config.rb +10 -48
  12. data/lib/puppet/face/facts.rb +1 -1
  13. data/lib/puppet/face/help.rb +1 -1
  14. data/lib/puppet/face/plugin.rb +9 -2
  15. data/lib/puppet/indirector/catalog/compiler.rb +11 -5
  16. data/lib/puppet/module_tool/tar/mini.rb +11 -1
  17. data/lib/puppet/network/http/factory.rb +1 -11
  18. data/lib/puppet/provider/file/posix.rb +5 -0
  19. data/lib/puppet/provider/nameservice.rb +10 -3
  20. data/lib/puppet/provider/package/dnf.rb +1 -1
  21. data/lib/puppet/provider/package/pip.rb +2 -2
  22. data/lib/puppet/provider/package/rpm.rb +51 -13
  23. data/lib/puppet/provider/package/yum.rb +8 -4
  24. data/lib/puppet/provider/service/launchd.rb +20 -5
  25. data/lib/puppet/provider/service/systemd.rb +5 -10
  26. data/lib/puppet/provider/service/windows.rb +8 -0
  27. data/lib/puppet/provider/user/pw.rb +12 -3
  28. data/lib/puppet/provider/user/user_role_add.rb +4 -0
  29. data/lib/puppet/provider/user/useradd.rb +23 -7
  30. data/lib/puppet/resource.rb +17 -0
  31. data/lib/puppet/settings.rb +40 -0
  32. data/lib/puppet/type/exec.rb +14 -6
  33. data/lib/puppet/type/package.rb +10 -0
  34. data/lib/puppet/type/service.rb +7 -2
  35. data/lib/puppet/util/execution.rb +4 -3
  36. data/lib/puppet/util/http_proxy.rb +19 -5
  37. data/lib/puppet/util/selinux.rb +5 -1
  38. data/lib/puppet/util/windows/security.rb +2 -0
  39. data/lib/puppet/util/windows/service.rb +149 -4
  40. data/lib/puppet/util/windows/sid.rb +1 -0
  41. data/lib/puppet/version.rb +1 -1
  42. data/locales/puppet.pot +168 -152
  43. data/man/man5/puppet.conf.5 +18 -2
  44. data/man/man8/puppet-agent.8 +1 -1
  45. data/man/man8/puppet-apply.8 +1 -1
  46. data/man/man8/puppet-catalog.8 +1 -1
  47. data/man/man8/puppet-config.8 +1 -1
  48. data/man/man8/puppet-describe.8 +1 -1
  49. data/man/man8/puppet-device.8 +1 -1
  50. data/man/man8/puppet-doc.8 +1 -1
  51. data/man/man8/puppet-epp.8 +1 -1
  52. data/man/man8/puppet-facts.8 +1 -1
  53. data/man/man8/puppet-filebucket.8 +1 -1
  54. data/man/man8/puppet-generate.8 +1 -1
  55. data/man/man8/puppet-help.8 +1 -1
  56. data/man/man8/puppet-key.8 +1 -1
  57. data/man/man8/puppet-lookup.8 +1 -1
  58. data/man/man8/puppet-man.8 +1 -1
  59. data/man/man8/puppet-module.8 +1 -1
  60. data/man/man8/puppet-node.8 +1 -1
  61. data/man/man8/puppet-parser.8 +1 -1
  62. data/man/man8/puppet-plugin.8 +1 -1
  63. data/man/man8/puppet-report.8 +1 -1
  64. data/man/man8/puppet-resource.8 +1 -1
  65. data/man/man8/puppet-script.8 +1 -1
  66. data/man/man8/puppet-ssl.8 +1 -1
  67. data/man/man8/puppet-status.8 +1 -1
  68. data/man/man8/puppet.8 +3 -3
  69. data/spec/integration/provider/service/systemd_spec.rb +8 -5
  70. data/spec/integration/type/file_spec.rb +28 -0
  71. data/spec/integration/util/execution_spec.rb +27 -0
  72. data/spec/unit/application/agent_spec.rb +20 -8
  73. data/spec/unit/application/device_spec.rb +27 -1
  74. data/spec/unit/face/facts_spec.rb +9 -0
  75. data/spec/unit/face/plugin_spec.rb +8 -0
  76. data/spec/unit/indirector/catalog/compiler_spec.rb +62 -5
  77. data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
  78. data/spec/unit/network/http/api/indirected_routes_spec.rb +25 -10
  79. data/spec/unit/network/http/factory_spec.rb +27 -5
  80. data/spec/unit/pops/validator/validator_spec.rb +7 -0
  81. data/spec/unit/provider/package/aptrpm_spec.rb +1 -1
  82. data/spec/unit/provider/package/dnf_spec.rb +7 -0
  83. data/spec/unit/provider/package/dpkg_spec.rb +2 -2
  84. data/spec/unit/provider/package/pip_spec.rb +8 -0
  85. data/spec/unit/provider/package/rpm_spec.rb +150 -16
  86. data/spec/unit/provider/package/yum_spec.rb +7 -0
  87. data/spec/unit/provider/service/launchd_spec.rb +28 -0
  88. data/spec/unit/provider/service/systemd_spec.rb +14 -0
  89. data/spec/unit/provider/service/windows_spec.rb +20 -0
  90. data/spec/unit/provider/user/pw_spec.rb +37 -0
  91. data/spec/unit/provider/user/useradd_spec.rb +42 -0
  92. data/spec/unit/resource_spec.rb +26 -1
  93. data/spec/unit/transaction_spec.rb +18 -0
  94. data/spec/unit/type/exec_spec.rb +9 -0
  95. data/spec/unit/type/file/source_spec.rb +4 -4
  96. data/spec/unit/type/schedule_spec.rb +3 -1
  97. data/spec/unit/type/service_spec.rb +16 -0
  98. data/spec/unit/util/http_proxy_spec.rb +40 -1
  99. data/spec/unit/util/log_spec.rb +27 -1
  100. data/spec/unit/util/windows/service_spec.rb +9 -0
  101. metadata +5 -9
  102. data/ext/windows/eventlog/Rakefile +0 -32
  103. data/ext/windows/eventlog/puppetres.dll +0 -0
  104. data/ext/windows/eventlog/puppetres.mc +0 -18
@@ -370,9 +370,19 @@ describe Puppet::Application::Device do
370
370
  allow(configurer).to receive(:run)
371
371
  allow(Puppet::Configurer).to receive(:new).and_return(configurer)
372
372
 
373
+ allow(Puppet::FileSystem).to receive(:exist?)
374
+ allow(Puppet::FileSystem).to receive(:symlink)
375
+ allow(Puppet::FileSystem).to receive(:dir_mkpath).and_return(true)
376
+ allow(Puppet::FileSystem).to receive(:dir_exist?).and_return(true)
377
+
373
378
  allow(plugin_handler).to receive(:download_plugins)
374
379
  end
375
380
 
381
+ it "sets ssldir relative to the global confdir" do
382
+ expect(Puppet).to receive(:[]=).with(:ssldir, make_absolute("/dummy/devices/device1/ssl"))
383
+ expect { device.main }.to exit_with 1
384
+ end
385
+
376
386
  it "sets vardir to the device vardir" do
377
387
  expect(Puppet).to receive(:[]=).with(:vardir, make_absolute("/dummy/devices/device1"))
378
388
  expect { device.main }.to exit_with 1
@@ -390,6 +400,22 @@ describe Puppet::Application::Device do
390
400
  end
391
401
 
392
402
  context 'with --target=device1' do
403
+ it "symlinks the ssl directory if it doesn't exist" do
404
+ allow(device.options).to receive(:[]).with(:target).and_return('device1')
405
+ allow(Puppet::FileSystem).to receive(:exist?).and_return(false)
406
+
407
+ expect(Puppet::FileSystem).to receive(:symlink).with(Puppet[:ssldir], File.join(Puppet[:confdir], 'ssl')).and_return(true)
408
+ expect { device.main }.to exit_with 1
409
+ end
410
+
411
+ it "creates the device confdir under the global confdir" do
412
+ allow(device.options).to receive(:[]).with(:target).and_return('device1')
413
+ allow(Puppet::FileSystem).to receive(:dir_exist?).and_return(false)
414
+
415
+ expect(Puppet::FileSystem).to receive(:dir_mkpath).with(Puppet[:ssldir]).and_return(true)
416
+ expect { device.main }.to exit_with 1
417
+ end
418
+
393
419
  it "manages the specified target" do
394
420
  allow(device.options).to receive(:[]).with(:target).and_return('device1')
395
421
 
@@ -438,7 +464,7 @@ describe Puppet::Application::Device do
438
464
  allow(device.options).to receive(:[]).with(:to_yaml).and_return(true)
439
465
  allow(device.command_line).to receive(:args).and_return(['user'])
440
466
  expect(Puppet::Resource.indirection).to receive(:search).with('user/', {}).and_return(resources)
441
- expect(device).to receive(:puts).with("user:\n title:\n")
467
+ expect(device).to receive(:puts).with("---\nuser:\n title: {}\n")
442
468
  expect { device.main }.to exit_with 0
443
469
  end
444
470
  end
@@ -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
 
@@ -50,6 +50,14 @@ describe Puppet::Face[:plugin, :current] do
50
50
  expect(receive_count).to eq(3)
51
51
  expect(render(result)).to eq('Downloaded these plugins: /a, /b, /c')
52
52
  end
53
+
54
+ it "uses persistent HTTP pool" do
55
+ allow_any_instance_of(Puppet::Configurer::Downloader).to receive(:evaluate) do
56
+ expect(Puppet.lookup(:http_pool)).to be_instance_of(Puppet::Network::HTTP::Pool)
57
+ end.and_return([])
58
+
59
+ pluginface.download
60
+ end
53
61
  end
54
62
 
55
63
  context "download when server_agent_version is 5.3.3" do
@@ -4,6 +4,12 @@ require 'matchers/resource'
4
4
 
5
5
  require 'puppet/indirector/catalog/compiler'
6
6
 
7
+ def set_facts(fact_hash)
8
+ fact_hash.each do |key, value|
9
+ allow(Facter).to receive(:value).with(key).and_return(value)
10
+ end
11
+ end
12
+
7
13
  describe Puppet::Resource::Catalog::Compiler do
8
14
  let(:compiler) { described_class.new }
9
15
  let(:node_name) { "foo" }
@@ -16,8 +22,11 @@ describe Puppet::Resource::Catalog::Compiler do
16
22
  describe "when initializing" do
17
23
  before do
18
24
  expect(Puppet).to receive(:version).and_return(1)
19
- expect(Facter).to receive(:value).with('fqdn').and_return("my.server.com")
20
- expect(Facter).to receive(:value).with('ipaddress').and_return("my.ip.address")
25
+ set_facts({
26
+ 'fqdn' => "my.server.com",
27
+ 'ipaddress' => "my.ip.address",
28
+ 'ipaddress6' => nil
29
+ })
21
30
  end
22
31
 
23
32
  it "should gather data about itself" do
@@ -390,9 +399,12 @@ describe Puppet::Resource::Catalog::Compiler do
390
399
 
391
400
  describe "after finding nodes" do
392
401
  before do
393
- expect(Puppet).to receive(:version).and_return(1)
394
- expect(Facter).to receive(:value).with('fqdn').and_return("my.server.com")
395
- expect(Facter).to receive(:value).with('ipaddress').and_return("my.ip.address")
402
+ allow(Puppet).to receive(:version).and_return(1)
403
+ set_facts({
404
+ 'fqdn' => "my.server.com",
405
+ 'ipaddress' => "my.ip.address",
406
+ 'ipaddress6' => nil
407
+ })
396
408
  @request = Puppet::Indirector::Request.new(:catalog, :find, node_name, nil)
397
409
  allow(compiler).to receive(:compile)
398
410
  allow(Puppet::Node.indirection).to receive(:find).with(node_name, anything).and_return(node)
@@ -412,6 +424,51 @@ describe Puppet::Resource::Catalog::Compiler do
412
424
  expect(node).to receive(:merge).with(hash_including("serverip" => "my.ip.address"))
413
425
  compiler.find(@request)
414
426
  end
427
+
428
+ it "shouldn't warn if there is at least one ip fact" do
429
+ expect(node).to receive(:merge).with(hash_including("serverip" => "my.ip.address"))
430
+ compiler.find(@request)
431
+ expect(@logs).not_to be_any {|log| log.level == :warning and log.message =~ /Could not retrieve either serverip or serverip6 fact/}
432
+ end
433
+ end
434
+
435
+ describe "in an IPv6 only environment" do
436
+ before do |example|
437
+ allow(Puppet).to receive(:version).and_return(1)
438
+ set_facts({
439
+ 'fqdn' => "my.server.com",
440
+ 'ipaddress' => nil,
441
+ })
442
+ if example.metadata[:nil_ipv6]
443
+ set_facts({
444
+ 'ipaddress6' => nil
445
+ })
446
+ else
447
+ set_facts({
448
+ 'ipaddress6' => "my.ipv6.address"
449
+ })
450
+ end
451
+ @request = Puppet::Indirector::Request.new(:catalog, :find, node_name, nil)
452
+ allow(compiler).to receive(:compile)
453
+ allow(Puppet::Node.indirection).to receive(:find).with(node_name, anything).and_return(node)
454
+ end
455
+
456
+ it "should populate the :serverip6 fact" do
457
+ expect(node).to receive(:merge).with(hash_including("serverip6" => "my.ipv6.address"))
458
+ compiler.find(@request)
459
+ end
460
+
461
+ it "shouldn't warn if there is at least one ip fact" do
462
+ expect(node).to receive(:merge).with(hash_including("serverip6" => "my.ipv6.address"))
463
+ compiler.find(@request)
464
+ expect(@logs).not_to be_any {|log| log.level == :warning and log.message =~ /Could not retrieve either serverip or serverip6 fact/}
465
+ end
466
+
467
+ it "should warn if there are no ip facts", :nil_ipv6 do
468
+ expect(node).to receive(:merge)
469
+ compiler.find(@request)
470
+ expect(@logs).to be_any {|log| log.level == :warning and log.message =~ /Could not retrieve either serverip or serverip6 fact/}
471
+ end
415
472
  end
416
473
 
417
474
  describe "when filtering resources" do
@@ -82,7 +82,7 @@ describe Puppet::ModuleTool::Tar::Mini, :if => (Puppet.features.minitar? and Pup
82
82
  expect(Zlib::GzipReader).to receive(:open).with(sourcefile).and_yield(reader)
83
83
  expect(minitar).to receive(:find_valid_files).with(reader).and_return([name])
84
84
  entry = MockFileStatEntry.new(mode)
85
- expect(Archive::Tar::Minitar).to receive(:unpack).with(reader, destdir, [name]).
85
+ expect(Archive::Tar::Minitar).to receive(:unpack).with(reader, destdir, [name], :fsync => false).
86
86
  and_yield(type, name, {:entry => entry})
87
87
  entry
88
88
  end
@@ -40,19 +40,27 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
40
40
  end
41
41
 
42
42
  it "should fail if there is no environment specified" do
43
- expect(lambda { handler.uri2indirection("GET", "#{master_url_prefix}/node/bar", {}) }).to raise_error(bad_request_error)
43
+ expect {
44
+ handler.uri2indirection("GET", "#{master_url_prefix}/node/bar", {})
45
+ }.to raise_error(bad_request_error)
44
46
  end
45
47
 
46
48
  it "should fail if the environment is not alphanumeric" do
47
- expect(lambda { handler.uri2indirection("GET", "#{master_url_prefix}/node/bar", {:environment => "env ness"}) }).to raise_error(bad_request_error)
49
+ expect {
50
+ handler.uri2indirection("GET", "#{master_url_prefix}/node/bar", {:environment => "env ness"})
51
+ }.to raise_error(bad_request_error)
48
52
  end
49
53
 
50
54
  it "should fail if the indirection does not match the prefix" do
51
- expect(lambda { handler.uri2indirection("GET", "#{master_url_prefix}/certificate/foo", params) }).to raise_error(bad_request_error)
55
+ expect {
56
+ handler.uri2indirection("GET", "#{master_url_prefix}/certificate/foo", params)
57
+ }.to raise_error(bad_request_error)
52
58
  end
53
59
 
54
60
  it "should fail if the indirection does not have the correct version" do
55
- expect(lambda { handler.uri2indirection("GET", "#{Puppet::Network::HTTP::MASTER_URL_PREFIX}/v1/node/bar", params) }).to raise_error(bad_request_error)
61
+ expect {
62
+ handler.uri2indirection("GET", "#{Puppet::Network::HTTP::MASTER_URL_PREFIX}/v1/node/bar", params)
63
+ }.to raise_error(bad_request_error)
56
64
  end
57
65
 
58
66
  it "should not pass a buck_path parameter through (See Bugs #13553, #13518, #13511)" do
@@ -76,7 +84,9 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
76
84
  end
77
85
 
78
86
  it "should fail if the indirection name is not alphanumeric" do
79
- expect(lambda { handler.uri2indirection("GET", "#{master_url_prefix}/foo ness/bar", params) }).to raise_error(bad_request_error)
87
+ expect {
88
+ handler.uri2indirection("GET", "#{master_url_prefix}/foo ness/bar", params)
89
+ }.to raise_error(bad_request_error)
80
90
  end
81
91
 
82
92
  it "should use the remainder of the URI as the indirection key" do
@@ -88,7 +98,9 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
88
98
  end
89
99
 
90
100
  it "should fail if no indirection key is specified" do
91
- expect(lambda { handler.uri2indirection("GET", "#{master_url_prefix}/node", params) }).to raise_error(bad_request_error)
101
+ expect {
102
+ handler.uri2indirection("GET", "#{master_url_prefix}/node", params)
103
+ }.to raise_error(bad_request_error)
92
104
  end
93
105
 
94
106
  it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is singular" do
@@ -128,7 +140,9 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
128
140
  end
129
141
 
130
142
  it "should fail if an indirection method cannot be picked" do
131
- expect(lambda { handler.uri2indirection("UPDATE", "#{master_url_prefix}/node/bar", params) }).to raise_error(method_not_allowed_error)
143
+ expect {
144
+ handler.uri2indirection("UPDATE", "#{master_url_prefix}/node/bar", params)
145
+ }.to raise_error(method_not_allowed_error)
132
146
  end
133
147
 
134
148
  it "should not URI unescape the indirection key" do
@@ -148,9 +162,10 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
148
162
  expect(handler).to receive(:check_authorization).with(anything,
149
163
  anything,
150
164
  excluding(:environment))
151
- expect(lambda { handler.uri2indirection("GET",
152
- "#{master_url_prefix}/node/bar",
153
- {:environment => 'bogus'}) }).to raise_error(not_found_error)
165
+ expect { handler.uri2indirection("GET",
166
+ "#{master_url_prefix}/node/bar",
167
+ {:environment => 'bogus'})
168
+ }.to raise_error(not_found_error)
154
169
  end
155
170
 
156
171
  it "should not URI unescape the indirection key as passed through to a call to check_authorization" do
@@ -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
@@ -699,6 +699,13 @@ describe "validating 4x" do
699
699
  end
700
700
  end
701
701
 
702
+ context 'for hash keys' do
703
+ it "should not allow reassignment of hash keys" do
704
+ source = "$my_hash = {'one' => '1', 'two' => '2' }; $my_hash['one']='1.5'"
705
+ expect(validate(parse(source))).to have_issue(Puppet::Pops::Issues::ILLEGAL_INDEXED_ASSIGNMENT)
706
+ end
707
+ end
708
+
702
709
  context 'for parameter names' do
703
710
  ['class', 'define'].each do |word|
704
711
  it "should require that #{word} parameter names are unique" do
@@ -16,7 +16,7 @@ describe Puppet::Type.type(:package).provider(:aptrpm) do
16
16
  end
17
17
 
18
18
  def rpm_args
19
- ['-q', 'faff', '--nosignature', '--nodigest', '--qf', "'%{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH}\\n'"]
19
+ ['-q', 'faff', '--nosignature', '--nodigest', '--qf', "%{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH}\\n"]
20
20
  end
21
21
 
22
22
  it "should report purged packages" do
@@ -44,5 +44,12 @@ describe Puppet::Type.type(:package).provider(:dnf) do
44
44
  end
45
45
  end
46
46
 
47
+ describe 'provider features' do
48
+ it { is_expected.to be_versionable }
49
+ it { is_expected.to be_install_options }
50
+ it { is_expected.to be_virtual_packages }
51
+ it { is_expected.to be_install_only }
52
+ end
53
+
47
54
  it_behaves_like 'RHEL package provider', described_class, 'dnf'
48
55
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'stringio'
3
3
 
4
- describe Puppet::Type.type(:package).provider(:dpkg) do
4
+ describe Puppet::Type.type(:package).provider(:dpkg), unless: Puppet::Util::Platform.jruby? do
5
5
  let(:bash_version) { '4.2-5ubuntu3' }
6
6
  let(:bash_installed_output) { "install ok installed bash #{bash_version}\n" }
7
7
  let(:bash_installed_io) { StringIO.new(bash_installed_output) }
@@ -218,7 +218,7 @@ describe Puppet::Type.type(:package).provider(:dpkg) do
218
218
 
219
219
  before do
220
220
  allow(tempfile).to receive(:write)
221
- allow(Tempfile).to receive(:open).and_yield(tempfile)
221
+ allow(Tempfile).to receive(:new).and_return(tempfile)
222
222
  end
223
223
 
224
224
  it "installs first if package is not present and ensure holding" do
@@ -29,6 +29,14 @@ describe Puppet::Type.type(:package).provider(:pip) do
29
29
  })
30
30
  end
31
31
 
32
+ it "should correctly parse arbitrary equality" do
33
+ expect(described_class.parse("real_package===1.2.5")).to eq({
34
+ :ensure => "1.2.5",
35
+ :name => "real_package",
36
+ :provider => :pip,
37
+ })
38
+ end
39
+
32
40
  it "should return nil on invalid input" do
33
41
  expect(described_class.parse("foo")).to eq(nil)
34
42
  end
@@ -9,6 +9,8 @@ describe Puppet::Type.type(:package).provider(:rpm) do
9
9
  myresource 0 1.2.3.4 5.el4 noarch
10
10
  mysummaryless 0 1.2.3.4 5.el4 noarch
11
11
  tomcat 1 1.2.3.4 5.el4 x86_64
12
+ kernel 1 1.2.3.4 5.el4 x86_64
13
+ kernel 1 1.2.3.6 5.el4 x86_64
12
14
  '
13
15
  RPM_OUTPUT
14
16
  end
@@ -57,7 +59,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
57
59
  describe "with a modern version of RPM" do
58
60
  it "includes all the modern flags" do
59
61
  expect(Puppet::Util::Execution).to receive(:execpipe)
60
- .with("/bin/rpm -qa --nosignature --nodigest --qf '#{nevra_format}'")
62
+ .with("/bin/rpm -qa --nosignature --nodigest --qf '#{nevra_format}' | sort")
61
63
  .and_yield(packages)
62
64
 
63
65
  described_class.instances
@@ -69,7 +71,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
69
71
 
70
72
  it "excludes the --nosignature flag" do
71
73
  expect(Puppet::Util::Execution).to receive(:execpipe)
72
- .with("/bin/rpm -qa --nodigest --qf '#{nevra_format}'")
74
+ .with("/bin/rpm -qa --nodigest --qf '#{nevra_format}' | sort")
73
75
  .and_yield(packages)
74
76
 
75
77
  described_class.instances
@@ -81,7 +83,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
81
83
 
82
84
  it "excludes the --nodigest flag" do
83
85
  expect(Puppet::Util::Execution).to receive(:execpipe)
84
- .with("/bin/rpm -qa --qf '#{nevra_format}'")
86
+ .with("/bin/rpm -qa --qf '#{nevra_format}' | sort")
85
87
  .and_yield(packages)
86
88
 
87
89
  described_class.instances
@@ -90,7 +92,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
90
92
 
91
93
  it "returns an array of packages" do
92
94
  expect(Puppet::Util::Execution).to receive(:execpipe)
93
- .with("/bin/rpm -qa --nosignature --nodigest --qf '#{nevra_format}'")
95
+ .with("/bin/rpm -qa --nosignature --nodigest --qf '#{nevra_format}' | sort")
94
96
  .and_yield(packages)
95
97
 
96
98
  installed_packages = described_class.instances
@@ -161,6 +163,17 @@ describe Puppet::Type.type(:package).provider(:rpm) do
161
163
  :ensure => "1:1.2.3.4-5.el4",
162
164
  }
163
165
  )
166
+ expect(installed_packages[6].properties).to eq(
167
+ {
168
+ :provider => :rpm,
169
+ :name => "kernel",
170
+ :epoch => "1",
171
+ :version => "1.2.3.4",
172
+ :release => "5.el4",
173
+ :arch => "x86_64",
174
+ :ensure => "1:1.2.3.4-5.el4; 1:1.2.3.6-5.el4",
175
+ }
176
+ )
164
177
  end
165
178
  end
166
179
 
@@ -218,7 +231,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
218
231
  it "retrieves version string after querying rpm for version from source file" do
219
232
  expect(resource).to receive(:[]).with(:source).and_return('source-string')
220
233
  expect(Puppet::Util::Execution).to receive(:execute)
221
- .with(["/bin/rpm", "-q", "--qf", "'#{nevra_format}'", "-p", "source-string"])
234
+ .with(["/bin/rpm", "-q", "--qf", "#{nevra_format}", "-p", "source-string"])
222
235
  .and_return(Puppet::Util::Execution::ProcessOutput.new("myresource 0 1.2.3.4 5.el4 noarch\n", 0))
223
236
  expect(provider.latest).to eq("1.2.3.4-5.el4")
224
237
  end
@@ -226,7 +239,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
226
239
  it "raises an error if the rpm command fails" do
227
240
  expect(resource).to receive(:[]).with(:source).and_return('source-string')
228
241
  expect(Puppet::Util::Execution).to receive(:execute)
229
- .with(["/bin/rpm", "-q", "--qf", "'#{nevra_format}'", "-p", "source-string"])
242
+ .with(["/bin/rpm", "-q", "--qf", "#{nevra_format}", "-p", "source-string"])
230
243
  .and_raise(Puppet::ExecutionFailure, 'rpm command failed')
231
244
 
232
245
  expect {
@@ -248,7 +261,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
248
261
 
249
262
  before(:each) do
250
263
  expect(Puppet::Util::Execution).to receive(:execute)
251
- .with(["/bin/rpm", "-q", resource_name, '', '', '--qf', "'#{nevra_format}'"], execute_options)
264
+ .with(["/bin/rpm", "-q", resource_name, '', '', '--qf', "#{nevra_format}"], execute_options)
252
265
  .and_return(Puppet::Util::Execution::ProcessOutput.new("#{resource_name} 0 1.2.3.4 5.el4 noarch\n", 0))
253
266
  end
254
267
 
@@ -266,7 +279,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
266
279
 
267
280
  before(:each) do
268
281
  expect(Puppet::Util::Execution).to receive(:execute)
269
- .with(["/bin/rpm", "-q", resource_name, '--nosignature', '--nodigest', "--qf", "'#{nevra_format}'"], execute_options)
282
+ .with(["/bin/rpm", "-q", resource_name, '--nosignature', '--nodigest', "--qf", "#{nevra_format}"], execute_options)
270
283
  .and_return(Puppet::Util::Execution::ProcessOutput.new("#{resource_name} 0 1.2.3.4 5.el4 noarch\n", 0))
271
284
  end
272
285
 
@@ -290,7 +303,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
290
303
 
291
304
  before(:each) do
292
305
  expect(Puppet::Util::Execution).to receive(:execute)
293
- .with(["/bin/rpm", "-q", "#{resource_name}.noarch", '--nosignature', '--nodigest', "--qf", "'#{nevra_format}'"], execute_options)
306
+ .with(["/bin/rpm", "-q", "#{resource_name}.noarch", '--nosignature', '--nodigest', "--qf", "#{nevra_format}"], execute_options)
294
307
  .and_return(Puppet::Util::Execution::ProcessOutput.new("#{resource_name} 0 1.2.3.4 5.el4 noarch\n", 0))
295
308
  end
296
309
 
@@ -312,7 +325,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
312
325
 
313
326
  before(:each) do
314
327
  expect(Puppet::Util::Execution).to receive(:execute)
315
- .with(["/bin/rpm", "-q", "#{resource_name}-1.2.3.4-5.el4", '--nosignature', '--nodigest', "--qf", "'#{nevra_format}'"], execute_options)
328
+ .with(["/bin/rpm", "-q", "#{resource_name}-1.2.3.4-5.el4", '--nosignature', '--nodigest', "--qf", "#{nevra_format}"], execute_options)
316
329
  .and_return(Puppet::Util::Execution::ProcessOutput.new("#{resource_name} 0 1.2.3.4 5.el4 noarch\n", 0))
317
330
  end
318
331
 
@@ -334,7 +347,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
334
347
 
335
348
  before(:each) do
336
349
  expect(Puppet::Util::Execution).to receive(:execute)
337
- .with(["/bin/rpm", "-q", "#{resource_name}-1.2.3.4", '--nosignature', '--nodigest', "--qf", "'#{nevra_format}'"], execute_options)
350
+ .with(["/bin/rpm", "-q", "#{resource_name}-1.2.3.4", '--nosignature', '--nodigest', "--qf", "#{nevra_format}"], execute_options)
338
351
  .and_return(Puppet::Util::Execution::ProcessOutput.new("#{resource_name} 0 1.2.3.4 5.el4 noarch\n", 0))
339
352
  end
340
353
 
@@ -358,7 +371,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
358
371
 
359
372
  before(:each) do
360
373
  expect(Puppet::Util::Execution).to receive(:execute)
361
- .with(["/bin/rpm", "-q", resource_name, '--nosignature', '--nodigest', "--qf", "'#{nevra_format}'"], execute_options)
374
+ .with(["/bin/rpm", "-q", resource_name, '--nosignature', '--nodigest', "--qf", "#{nevra_format}"], execute_options)
362
375
  .and_return(Puppet::Util::Execution::ProcessOutput.new("#{resource_name} 0 1.2.3.4 5.el4 noarch\n", 0))
363
376
  end
364
377
 
@@ -374,7 +387,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
374
387
  def parser_test(rpm_output_string, gold_hash, number_of_debug_logs = 0)
375
388
  expect(Puppet).to receive(:debug).exactly(number_of_debug_logs).times()
376
389
  expect(Puppet::Util::Execution).to receive(:execute)
377
- .with(["/bin/rpm", "-q", resource_name, "--nosignature", "--nodigest", "--qf", "'#{nevra_format}'"], execute_options)
390
+ .with(["/bin/rpm", "-q", resource_name, "--nosignature", "--nodigest", "--qf", "#{nevra_format}"], execute_options)
378
391
  .and_return(Puppet::Util::Execution::ProcessOutput.new(rpm_output_string, 0))
379
392
  expect(provider.query).to eq(gold_hash)
380
393
  end
@@ -413,7 +426,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
413
426
  describe "when the package is not found" do
414
427
  before do
415
428
  expect(Puppet).not_to receive(:debug)
416
- expected_args = ["/bin/rpm", "-q", resource_name, "--nosignature", "--nodigest", "--qf", "'#{nevra_format}'"]
429
+ expected_args = ["/bin/rpm", "-q", resource_name, "--nosignature", "--nodigest", "--qf", "#{nevra_format}"]
417
430
  expect(Puppet::Util::Execution).to receive(:execute)
418
431
  .with(expected_args, execute_options)
419
432
  .and_raise(Puppet::ExecutionFailure.new("package #{resource_name} is not installed"))
@@ -426,7 +439,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
426
439
 
427
440
  it "does not log or fail if allow_virtual is true" do
428
441
  resource[:allow_virtual] = true
429
- expected_args = ['/bin/rpm', '-q', resource_name, '--nosignature', '--nodigest', '--qf', "'#{nevra_format}'", '--whatprovides']
442
+ expected_args = ['/bin/rpm', '-q', resource_name, '--nosignature', '--nodigest', '--qf', "#{nevra_format}", '--whatprovides']
430
443
  expect(Puppet::Util::Execution).to receive(:execute)
431
444
  .with(expected_args, execute_options)
432
445
  .and_raise(Puppet::ExecutionFailure.new("package #{resource_name} is not provided"))
@@ -436,7 +449,7 @@ describe Puppet::Type.type(:package).provider(:rpm) do
436
449
 
437
450
  it "parses virtual package" do
438
451
  provider.resource[:allow_virtual] = true
439
- expected_args = ["/bin/rpm", "-q", resource_name, "--nosignature", "--nodigest", "--qf", "'#{nevra_format}'"]
452
+ expected_args = ["/bin/rpm", "-q", resource_name, "--nosignature", "--nodigest", "--qf", "#{nevra_format}"]
440
453
  expect(Puppet::Util::Execution).to receive(:execute)
441
454
  .with(expected_args, execute_options)
442
455
  .and_raise(Puppet::ExecutionFailure.new("package #{resource_name} is not installed"))
@@ -749,4 +762,125 @@ describe Puppet::Type.type(:package).provider(:rpm) do
749
762
  provider.compare_values('s1', 's2')
750
763
  end
751
764
  end
765
+
766
+
767
+ describe 'insync?' do
768
+ context 'for multiple versions' do
769
+ let(:is) { '1:1.2.3.4-5.el4; 1:5.6.7.8-5.el4' }
770
+ it 'returns true if there is match and feature is enabled' do
771
+ resource[:install_only] = true
772
+ resource[:ensure] = '1:1.2.3.4-5.el4'
773
+ expect(provider).to be_insync(is)
774
+ end
775
+ it 'returns false if there is match and feature is not enabled' do
776
+ resource[:ensure] = '1:1.2.3.4-5.el4'
777
+ expect(provider).to_not be_insync(is)
778
+ end
779
+ it 'returns false if no match and feature is enabled' do
780
+ resource[:install_only] = true
781
+ resource[:ensure] = '1:1.2.3.6-5.el4'
782
+ expect(provider).to_not be_insync(is)
783
+ end
784
+ it 'returns false if no match and feature is not enabled' do
785
+ resource[:ensure] = '1:1.2.3.6-5.el4'
786
+ expect(provider).to_not be_insync(is)
787
+ end
788
+ end
789
+ context 'for simple versions' do
790
+ let(:is) { '1:1.2.3.4-5.el4' }
791
+ it 'returns true if there is match and feature is enabled' do
792
+ resource[:install_only] = true
793
+ resource[:ensure] = '1:1.2.3.4-5.el4'
794
+ expect(provider).to be_insync(is)
795
+ end
796
+ it 'returns true if there is match and feature is not enabled' do
797
+ resource[:ensure] = '1:1.2.3.4-5.el4'
798
+ expect(provider).to be_insync(is)
799
+ end
800
+ it 'returns false if no match and feature is enabled' do
801
+ resource[:install_only] = true
802
+ resource[:ensure] = '1:1.2.3.6-5.el4'
803
+ expect(provider).to_not be_insync(is)
804
+ end
805
+ it 'returns false if no match and feature is not enabled' do
806
+ resource[:ensure] = '1:1.2.3.6-5.el4'
807
+ expect(provider).to_not be_insync(is)
808
+ end
809
+ end
810
+ end
811
+
812
+ describe 'rpm multiversion to hash' do
813
+ it 'should return empty hash for empty imput' do
814
+ package_hash = described_class.nevra_to_multiversion_hash('')
815
+ expect(package_hash).to eq({})
816
+ end
817
+
818
+ it 'should return package hash for one package input' do
819
+ package_list = <<-RPM_OUTPUT
820
+ kernel-devel 1 1.2.3.4 5.el4 x86_64
821
+ RPM_OUTPUT
822
+ package_hash = described_class.nevra_to_multiversion_hash(package_list)
823
+ expect(package_hash).to eq(
824
+ {
825
+ :arch => "x86_64",
826
+ :ensure => "1:1.2.3.4-5.el4",
827
+ :epoch => "1",
828
+ :name => "kernel-devel",
829
+ :provider => :rpm,
830
+ :release => "5.el4",
831
+ :version => "1.2.3.4",
832
+ }
833
+ )
834
+ end
835
+
836
+ it 'should return package hash with versions concatenated in ensure for two package input' do
837
+ package_list = <<-RPM_OUTPUT
838
+ kernel-devel 1 1.2.3.4 5.el4 x86_64
839
+ kernel-devel 1 5.6.7.8 5.el4 x86_64
840
+ RPM_OUTPUT
841
+ package_hash = described_class.nevra_to_multiversion_hash(package_list)
842
+ expect(package_hash).to eq(
843
+ {
844
+ :arch => "x86_64",
845
+ :ensure => "1:1.2.3.4-5.el4; 1:5.6.7.8-5.el4",
846
+ :epoch => "1",
847
+ :name => "kernel-devel",
848
+ :provider => :rpm,
849
+ :release => "5.el4",
850
+ :version => "1.2.3.4",
851
+ }
852
+ )
853
+ end
854
+
855
+ it 'should return list of packages for one multiversion and one package input' do
856
+ package_list = <<-RPM_OUTPUT
857
+ kernel-devel 1 1.2.3.4 5.el4 x86_64
858
+ kernel-devel 1 5.6.7.8 5.el4 x86_64
859
+ basesystem 0 8.0 5.1.1.el5.centos noarch
860
+ RPM_OUTPUT
861
+ package_hash = described_class.nevra_to_multiversion_hash(package_list)
862
+ expect(package_hash).to eq(
863
+ [
864
+ {
865
+ :arch => "x86_64",
866
+ :ensure => "1:1.2.3.4-5.el4; 1:5.6.7.8-5.el4",
867
+ :epoch => "1",
868
+ :name => "kernel-devel",
869
+ :provider => :rpm,
870
+ :release => "5.el4",
871
+ :version => "1.2.3.4",
872
+ },
873
+ {
874
+ :provider => :rpm,
875
+ :name => "basesystem",
876
+ :epoch => "0",
877
+ :version => "8.0",
878
+ :release => "5.1.1.el5.centos",
879
+ :arch => "noarch",
880
+ :ensure => "8.0-5.1.1.el5.centos",
881
+ }
882
+ ]
883
+ )
884
+ end
885
+ end
752
886
  end