chef 14.5.33 → 14.6.47

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -3
  3. data/chef-universal-mingw32.gemspec +3 -2
  4. data/chef.gemspec +3 -4
  5. data/lib/chef/api_client.rb +5 -3
  6. data/lib/chef/api_client_v1.rb +6 -4
  7. data/lib/chef/application.rb +1 -1
  8. data/lib/chef/audit/audit_reporter.rb +1 -1
  9. data/lib/chef/audit/control_group_data.rb +12 -6
  10. data/lib/chef/chef_fs/chef_fs_data_store.rb +2 -2
  11. data/lib/chef/chef_fs/data_handler/data_handler_base.rb +1 -1
  12. data/lib/chef/cookbook/manifest_v0.rb +34 -29
  13. data/lib/chef/cookbook/manifest_v2.rb +15 -11
  14. data/lib/chef/cookbook/metadata.rb +4 -2
  15. data/lib/chef/cookbook_manifest.rb +8 -5
  16. data/lib/chef/cookbook_version.rb +1 -1
  17. data/lib/chef/data_bag.rb +4 -2
  18. data/lib/chef/data_bag_item.rb +5 -3
  19. data/lib/chef/data_collector.rb +2 -2
  20. data/lib/chef/data_collector/resource_report.rb +4 -4
  21. data/lib/chef/encrypted_data_bag_item.rb +4 -2
  22. data/lib/chef/environment.rb +4 -2
  23. data/lib/chef/file_content_management/deploy/mv_unix.rb +5 -4
  24. data/lib/chef/handler.rb +2 -2
  25. data/lib/chef/json_compat.rb +1 -1
  26. data/lib/chef/key.rb +7 -5
  27. data/lib/chef/knife/bootstrap.rb +7 -1
  28. data/lib/chef/knife/client_edit.rb +2 -2
  29. data/lib/chef/knife/data_bag_show.rb +2 -2
  30. data/lib/chef/knife/osc_user_edit.rb +2 -2
  31. data/lib/chef/knife/user_edit.rb +2 -2
  32. data/lib/chef/mixin/params_validate.rb +4 -2
  33. data/lib/chef/node/attribute.rb +4 -4
  34. data/lib/chef/org.rb +6 -4
  35. data/lib/chef/policy_builder/policyfile.rb +5 -3
  36. data/lib/chef/provider/package.rb +9 -4
  37. data/lib/chef/provider/package/windows.rb +23 -1
  38. data/lib/chef/provider/package/yum/yum_helper.py +3 -2
  39. data/lib/chef/provider/package/zypper.rb +12 -8
  40. data/lib/chef/provider/registry_key.rb +15 -6
  41. data/lib/chef/provider/user/windows.rb +4 -3
  42. data/lib/chef/provider/windows_task.rb +11 -2
  43. data/lib/chef/resource.rb +3 -1
  44. data/lib/chef/resource/locale.rb +1 -1
  45. data/lib/chef/resource/ohai_hint.rb +4 -4
  46. data/lib/chef/resource/rhsm_errata_level.rb +1 -1
  47. data/lib/chef/resource/timezone.rb +91 -0
  48. data/lib/chef/resource/user/windows_user.rb +4 -0
  49. data/lib/chef/resource/windows_task.rb +240 -238
  50. data/lib/chef/resource/zypper_package.rb +5 -0
  51. data/lib/chef/resource_collection/resource_collection_serialization.rb +4 -2
  52. data/lib/chef/resources.rb +1 -0
  53. data/lib/chef/role.rb +4 -2
  54. data/lib/chef/run_list/run_list_expansion.rb +5 -3
  55. data/lib/chef/run_status.rb +4 -2
  56. data/lib/chef/user.rb +7 -5
  57. data/lib/chef/user_v1.rb +8 -6
  58. data/lib/chef/version.rb +1 -1
  59. data/lib/chef/win32/security/sid.rb +39 -0
  60. data/spec/functional/assets/zypprepo/chef_rpm-1.10-1.aarch64.rpm +0 -0
  61. data/spec/functional/assets/zypprepo/chef_rpm-1.10-1.i686.rpm +0 -0
  62. data/spec/functional/assets/zypprepo/chef_rpm-1.10-1.ppc64.rpm +0 -0
  63. data/spec/functional/assets/zypprepo/chef_rpm-1.10-1.ppc64le.rpm +0 -0
  64. data/spec/functional/assets/zypprepo/chef_rpm-1.10-1.s390x.rpm +0 -0
  65. data/spec/functional/assets/zypprepo/chef_rpm-1.10-1.src.rpm +0 -0
  66. data/spec/functional/assets/zypprepo/chef_rpm-1.10-1.x86_64.rpm +0 -0
  67. data/spec/functional/assets/zypprepo/chef_rpm-1.2-1.aarch64.rpm +0 -0
  68. data/spec/functional/assets/zypprepo/chef_rpm-1.2-1.i686.rpm +0 -0
  69. data/spec/functional/assets/zypprepo/chef_rpm-1.2-1.ppc64.rpm +0 -0
  70. data/spec/functional/assets/zypprepo/chef_rpm-1.2-1.ppc64le.rpm +0 -0
  71. data/spec/functional/assets/zypprepo/chef_rpm-1.2-1.s390x.rpm +0 -0
  72. data/spec/functional/assets/zypprepo/chef_rpm-1.2-1.src.rpm +0 -0
  73. data/spec/functional/assets/zypprepo/chef_rpm-1.2-1.x86_64.rpm +0 -0
  74. data/spec/functional/http/simple_spec.rb +2 -2
  75. data/spec/functional/resource/remote_file_spec.rb +2 -2
  76. data/spec/functional/resource/user/windows_spec.rb +1 -1
  77. data/spec/functional/resource/windows_task_spec.rb +1 -1
  78. data/spec/functional/resource/zypper_package_spec.rb +233 -0
  79. data/spec/spec_helper.rb +1 -0
  80. data/spec/unit/audit/audit_reporter_spec.rb +4 -4
  81. data/spec/unit/audit/control_group_data_spec.rb +17 -17
  82. data/spec/unit/environment_spec.rb +1 -1
  83. data/spec/unit/file_content_management/deploy/mv_unix_spec.rb +13 -1
  84. data/spec/unit/node_spec.rb +33 -0
  85. data/spec/unit/provider/package/rpm_spec.rb +5 -5
  86. data/spec/unit/provider/package/zypper_spec.rb +51 -0
  87. data/spec/unit/provider/package_spec.rb +32 -2
  88. data/spec/unit/provider/registry_key_spec.rb +74 -0
  89. data/spec/unit/provider/user/windows_spec.rb +12 -3
  90. data/spec/unit/provider/windows_task_spec.rb +1 -0
  91. data/spec/unit/resource/timezone.rb +39 -0
  92. data/spec/unit/resource/windows_task_spec.rb +1 -1
  93. data/spec/unit/resource_collection_spec.rb +1 -1
  94. data/spec/unit/run_context/child_run_context_spec.rb +3 -3
  95. data/spec/unit/shell/shell_session_spec.rb +3 -2
  96. metadata +21 -43
  97. data/CONTRIBUTING.md +0 -152
  98. data/VERSION +0 -1
  99. data/distro/powershell/chef/chef.psm1 +0 -459
  100. data/distro/ruby_bin_folder/Chef.PowerShell.Wrapper.dll +0 -0
  101. data/distro/ruby_bin_folder/Chef.PowerShell.dll +0 -0
  102. data/distro/ruby_bin_folder/Newtonsoft.Json.dll +0 -0
@@ -34,6 +34,11 @@ class Chef
34
34
  property :allow_downgrade, [ TrueClass, FalseClass ],
35
35
  description: "Allow downgrading a package to satisfy requested version requirements.",
36
36
  default: false, introduced: "13.6"
37
+
38
+ property :global_options, [ String, Array ],
39
+ description: "One (or more) additional options that are passed to the package resource other than options to the command.",
40
+ coerce: proc { |x| x.is_a?(String) ? x.shellsplit : x },
41
+ introduced: "14.6"
37
42
  end
38
43
  end
39
44
  end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Tyler Ball (<tball@chef.io>)
3
- # Copyright:: Copyright 2014-2016, Chef Software, Inc.
3
+ # Copyright:: Copyright 2014-2018, Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,7 @@ class Chef
22
22
  class ResourceCollection
23
23
  module ResourceCollectionSerialization
24
24
  # Serialize this object as a hash
25
- def to_hash
25
+ def to_h
26
26
  instance_vars = Hash.new
27
27
  instance_variables.each do |iv|
28
28
  instance_vars[iv] = instance_variable_get(iv)
@@ -33,6 +33,8 @@ class Chef
33
33
  }
34
34
  end
35
35
 
36
+ alias_method :to_hash, :to_h
37
+
36
38
  def to_json(*a)
37
39
  Chef::JSONCompat.to_json(to_hash, *a)
38
40
  end
@@ -141,3 +141,4 @@ require "chef/resource/windows_printer_port"
141
141
  require "chef/resource/windows_shortcut"
142
142
  require "chef/resource/windows_task"
143
143
  require "chef/resource/windows_workgroup"
144
+ require "chef/resource/timezone"
@@ -130,7 +130,7 @@ class Chef
130
130
  )
131
131
  end
132
132
 
133
- def to_hash
133
+ def to_h
134
134
  env_run_lists_without_default = @env_run_lists.dup
135
135
  env_run_lists_without_default.delete("_default")
136
136
  result = {
@@ -152,9 +152,11 @@ class Chef
152
152
  result
153
153
  end
154
154
 
155
+ alias_method :to_hash, :to_h
156
+
155
157
  # Serialize this object as a hash
156
158
  def to_json(*a)
157
- Chef::JSONCompat.to_json(to_hash, *a)
159
+ Chef::JSONCompat.to_json(to_h, *a)
158
160
  end
159
161
 
160
162
  def update_from!(o)
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # Author:: Daniel DeLeo (<dan@chef.io>)
3
3
  # Author:: Tim Hinderliter (<tim@chef.io>)
4
- # Copyright:: Copyright 2010-2016, Chef Software Inc.
4
+ # Copyright:: Copyright 2010-2018, Chef Software Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -144,14 +144,16 @@ class Chef
144
144
  end
145
145
 
146
146
  def to_json(*a)
147
- Chef::JSONCompat.to_json(to_hash, *a)
147
+ Chef::JSONCompat.to_json(to_h, *a)
148
148
  end
149
149
 
150
- def to_hash
150
+ def to_h
151
151
  seen_items = { recipe: {}, role: {} }
152
152
  { id: @environment, run_list: convert_run_list_trace("top level", seen_items) }
153
153
  end
154
154
 
155
+ alias_method :to_hash, :to_h
156
+
155
157
  private
156
158
 
157
159
  # these methods modifies internal state based on arguments, so hide it.
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Daniel DeLeo (<dan@chef.io>)
3
- # Copyright:: Copyright 2010-2016, Chef Software Inc.
3
+ # Copyright:: Copyright 2010-2018, Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -102,7 +102,7 @@ class Chef::RunStatus
102
102
  # * :updated_resources
103
103
  # * :exception
104
104
  # * :backtrace
105
- def to_hash
105
+ def to_h
106
106
  # use a flat hash here so we can't errors from intermediate values being nil
107
107
  { node: node,
108
108
  success: success?,
@@ -116,6 +116,8 @@ class Chef::RunStatus
116
116
  run_id: run_id }
117
117
  end
118
118
 
119
+ alias_method :to_hash, :to_h
120
+
119
121
  # Returns a string of the format "ExceptionClass: message" or +nil+ if no
120
122
  # +exception+ is set.
121
123
  def formatted_exception
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Steven Danna (steve@chef.io)
3
- # Copyright:: Copyright 2012-2016, Chef Software, Inc.
3
+ # Copyright:: Copyright 2012-2018, Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -77,7 +77,7 @@ class Chef
77
77
  arg, kind_of: String)
78
78
  end
79
79
 
80
- def to_hash
80
+ def to_h
81
81
  result = {
82
82
  "name" => @name,
83
83
  "public_key" => @public_key,
@@ -88,8 +88,10 @@ class Chef
88
88
  result
89
89
  end
90
90
 
91
+ alias_method :to_hash, :to_h
92
+
91
93
  def to_json(*a)
92
- Chef::JSONCompat.to_json(to_hash, *a)
94
+ Chef::JSONCompat.to_json(to_h, *a)
93
95
  end
94
96
 
95
97
  def destroy
@@ -100,7 +102,7 @@ class Chef
100
102
  payload = { name: name, admin: admin, password: password }
101
103
  payload[:public_key] = public_key if public_key
102
104
  new_user = chef_rest_v0.post("users", payload)
103
- Chef::User.from_hash(to_hash.merge(new_user))
105
+ Chef::User.from_hash(to_h.merge(new_user))
104
106
  end
105
107
 
106
108
  def update(new_key = false)
@@ -108,7 +110,7 @@ class Chef
108
110
  payload[:private_key] = new_key if new_key
109
111
  payload[:password] = password if password
110
112
  updated_user = chef_rest_v0.put("users/#{name}", payload)
111
- Chef::User.from_hash(to_hash.merge(updated_user))
113
+ Chef::User.from_hash(to_h.merge(updated_user))
112
114
  end
113
115
 
114
116
  def save(new_key = false)
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Steven Danna (steve@chef.io)
3
- # Copyright:: Copyright 2012-2016, Chef Software, Inc.
3
+ # Copyright:: Copyright 2012-2018, Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -112,7 +112,7 @@ class Chef
112
112
  arg, kind_of: String)
113
113
  end
114
114
 
115
- def to_hash
115
+ def to_h
116
116
  result = {
117
117
  "username" => @username,
118
118
  }
@@ -128,8 +128,10 @@ class Chef
128
128
  result
129
129
  end
130
130
 
131
+ alias_method :to_hash, :to_h
132
+
131
133
  def to_json(*a)
132
- Chef::JSONCompat.to_json(to_hash, *a)
134
+ Chef::JSONCompat.to_json(to_h, *a)
133
135
  end
134
136
 
135
137
  def destroy
@@ -180,7 +182,7 @@ class Chef
180
182
  new_user = chef_root_rest_v0.post("users", payload)
181
183
  end
182
184
 
183
- Chef::UserV1.from_hash(to_hash.merge(new_user))
185
+ Chef::UserV1.from_hash(to_h.merge(new_user))
184
186
  end
185
187
 
186
188
  def update(new_key = false)
@@ -213,7 +215,7 @@ class Chef
213
215
  end
214
216
  updated_user = chef_root_rest_v0.put("users/#{username}", payload)
215
217
  end
216
- Chef::UserV1.from_hash(to_hash.merge(updated_user))
218
+ Chef::UserV1.from_hash(to_h.merge(updated_user))
217
219
  end
218
220
 
219
221
  def save(new_key = false)
@@ -229,7 +231,7 @@ class Chef
229
231
  # Note: remove after API v0 no longer supported by client (and knife command).
230
232
  def reregister
231
233
  begin
232
- payload = to_hash.merge({ "private_key" => true })
234
+ payload = to_h.merge({ "private_key" => true })
233
235
  reregistered_self = chef_root_rest_v0.put("users/#{username}", payload)
234
236
  private_key(reregistered_self["private_key"])
235
237
  # only V0 supported for reregister
@@ -23,7 +23,7 @@ require "chef/version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("../..", __FILE__)
26
- VERSION = Chef::VersionString.new("14.5.33")
26
+ VERSION = Chef::VersionString.new("14.6.47")
27
27
  end
28
28
 
29
29
  #
@@ -246,6 +246,45 @@ class Chef
246
246
  SID.from_account("#{::ENV['USERDOMAIN']}\\#{::ENV['USERNAME']}")
247
247
  end
248
248
 
249
+ SERVICE_ACCOUNT_USERS = [self.LocalSystem,
250
+ self.NtLocal,
251
+ self.NtNetwork].flat_map do |user_type|
252
+ [user_type.account_simple_name.upcase,
253
+ user_type.account_name.upcase]
254
+ end.freeze
255
+
256
+ BUILT_IN_GROUPS = [self.BuiltinAdministrators,
257
+ self.BuiltinUsers, self.Guests].flat_map do |user_type|
258
+ [user_type.account_simple_name.upcase,
259
+ user_type.account_name.upcase]
260
+ end.freeze
261
+
262
+ SYSTEM_USER = SERVICE_ACCOUNT_USERS + BUILT_IN_GROUPS
263
+
264
+ # Сheck if the user belongs to service accounts category
265
+ #
266
+ # @return [Boolean] True or False
267
+ #
268
+ def self.service_account_user?(user)
269
+ SERVICE_ACCOUNT_USERS.include?(user.to_s.upcase)
270
+ end
271
+
272
+ # Сheck if the user is in builtin system group
273
+ #
274
+ # @return [Boolean] True or False
275
+ #
276
+ def self.group_user?(user)
277
+ BUILT_IN_GROUPS.include?(user.to_s.upcase)
278
+ end
279
+
280
+ # Сheck if the user belongs to system users category
281
+ #
282
+ # @return [Boolean] True or False
283
+ #
284
+ def self.system_user?(user)
285
+ SYSTEM_USER.include?(user.to_s.upcase)
286
+ end
287
+
249
288
  # See https://technet.microsoft.com/en-us/library/cc961992.aspx
250
289
  # In practice, this is SID.Administrators if the current_user is an admin (even if not
251
290
  # running elevated), and is current_user otherwise.
@@ -32,8 +32,8 @@ describe Chef::HTTP::Simple do
32
32
 
33
33
  before(:each) do
34
34
  Chef::Config[:rest_timeout] = 2
35
- Chef::Config[:http_retry_delay] = 0
36
- Chef::Config[:http_retry_count] = 0
35
+ Chef::Config[:http_retry_delay] = 1
36
+ Chef::Config[:http_retry_count] = 2
37
37
  end
38
38
 
39
39
  after(:all) do
@@ -29,8 +29,8 @@ describe Chef::Resource::RemoteFile do
29
29
  @old_file_cache = Chef::Config[:file_cache_path]
30
30
  Chef::Config[:file_cache_path] = file_cache_path
31
31
  Chef::Config[:rest_timeout] = 2
32
- Chef::Config[:http_retry_delay] = 0
33
- Chef::Config[:http_retry_count] = 0
32
+ Chef::Config[:http_retry_delay] = 1
33
+ Chef::Config[:http_retry_count] = 2
34
34
  end
35
35
 
36
36
  after(:each) do
@@ -36,7 +36,7 @@ describe Chef::Provider::User::Windows, :windows_only do
36
36
  let(:logger) { double("Mixlib::Log::Child").as_null_object }
37
37
  let(:run_context) { Chef::RunContext.new(node, {}, events) }
38
38
  let(:new_resource) do
39
- Chef::Resource::User.new(username, run_context).tap do |r|
39
+ Chef::Resource::User::WindowsUser.new(username, run_context).tap do |r|
40
40
  r.provider(Chef::Provider::User::Windows)
41
41
  r.password(password)
42
42
  end
@@ -1571,7 +1571,7 @@ describe Chef::Resource::WindowsTask, :windows_only do
1571
1571
  it "raises error" do
1572
1572
  subject.user "Administrator"
1573
1573
  subject.frequency :onstart
1574
- expect { subject.after_created }.to raise_error(%q{Cannot specify a user other than the system users without specifying a password!. Valid passwordless users: 'NT AUTHORITY\SYSTEM', 'SYSTEM', 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE', 'BUILTIN\USERS', 'USERS'})
1574
+ expect { subject.after_created }.to raise_error(%q{Cannot specify a user other than the system users without specifying a password!. Valid passwordless users: 'SYSTEM', 'NT AUTHORITY\SYSTEM', 'LOCAL SERVICE', 'NT AUTHORITY\LOCAL SERVICE', 'NETWORK SERVICE', 'NT AUTHORITY\NETWORK SERVICE', 'ADMINISTRATORS', 'BUILTIN\ADMINISTRATORS', 'USERS', 'BUILTIN\USERS', 'GUESTS', 'BUILTIN\GUESTS'})
1575
1575
  end
1576
1576
  end
1577
1577
 
@@ -0,0 +1,233 @@
1
+ #
2
+ # Author:: Dheeraj Dubey (<dheeraj.dubey@msystechnologies.com>)
3
+ # Copyright:: Copyright 2016-2018, Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require "spec_helper"
20
+ require "functional/resource/base"
21
+ require "chef/mixin/shell_out"
22
+
23
+ describe Chef::Resource::ZypperPackage, :requires_root, :suse_only do
24
+ include Chef::Mixin::ShellOut
25
+
26
+ # NOTE: every single test here needs to explicitly call preinstall.
27
+
28
+ def preinstall(*rpms)
29
+ rpms.each do |rpm|
30
+ shell_out!("rpm -ivh #{CHEF_SPEC_ASSETS}/zypprepo/#{rpm}")
31
+ end
32
+ end
33
+
34
+ before(:each) do
35
+ File.open("/etc/zypp/repos.d/chef-zypp-localtesting.repo", "w+") do |f|
36
+ f.write <<~EOF
37
+ [chef-zypp-localtesting]
38
+ name=Chef zypper spec testing repo
39
+ baseurl=file://#{CHEF_SPEC_ASSETS}/zypprepo
40
+ enable=1
41
+ gpgcheck=0
42
+ EOF
43
+ end
44
+ shell_out!("rpm -qa --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm | xargs -r rpm -e")
45
+ # next line is useful cleanup if you happen to have been testing zypper func tests on the same box and
46
+ # have some zypper garbage left around
47
+ # FileUtils.rm_f "/etc/zypp/repos.d/chef-zypp-localtesting.repo"
48
+ end
49
+
50
+ after(:all) do
51
+ shell_out!("rpm -qa --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm | xargs -r rpm -e")
52
+ FileUtils.rm_f "/etc/zypp/repos.d/chef-zypp-localtesting.repo"
53
+ end
54
+
55
+ let(:package_name) { "chef_rpm" }
56
+ let(:zypper_package) do
57
+ r = Chef::Resource::ZypperPackage.new(package_name, run_context)
58
+ r.global_options("--no-gpg-checks")
59
+ r
60
+ end
61
+
62
+ def pkg_arch
63
+ ohai[:kernel][:machine]
64
+ end
65
+
66
+ context "installing a package" do
67
+ after { remove_package }
68
+ it "installs the latest version" do
69
+ zypper_package.run_action(:install)
70
+ expect(zypper_package.updated_by_last_action?).to be true
71
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$")
72
+ end
73
+
74
+ it "does not install if the package is installed" do
75
+ preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
76
+ zypper_package.run_action(:install)
77
+ expect(zypper_package.updated_by_last_action?).to be false
78
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$")
79
+ end
80
+
81
+ it "does not install twice" do
82
+ zypper_package.run_action(:install)
83
+ expect(zypper_package.updated_by_last_action?).to be true
84
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$")
85
+ zypper_package.run_action(:install)
86
+ expect(zypper_package.updated_by_last_action?).to be false
87
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$")
88
+ end
89
+
90
+ it "does not install if the prior version package is installed" do
91
+ preinstall("chef_rpm-1.2-1.#{pkg_arch}.rpm")
92
+ zypper_package.run_action(:install)
93
+ expect(zypper_package.updated_by_last_action?).to be false
94
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.2-1.#{pkg_arch}$")
95
+ end
96
+ end
97
+
98
+ context "with versions" do
99
+ it "works with a version" do
100
+ zypper_package.package_name("chef_rpm")
101
+ zypper_package.version("1.10")
102
+ zypper_package.run_action(:install)
103
+ expect(zypper_package.updated_by_last_action?).to be true
104
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$")
105
+ end
106
+
107
+ it "works with an older version" do
108
+ zypper_package.package_name("chef_rpm")
109
+ zypper_package.version("1.2")
110
+ zypper_package.run_action(:install)
111
+ expect(zypper_package.updated_by_last_action?).to be true
112
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.2-1.#{pkg_arch}$")
113
+ end
114
+
115
+ it "works with version and release" do
116
+ zypper_package.package_name("chef_rpm")
117
+ zypper_package.version("1.2-1")
118
+ zypper_package.run_action(:install)
119
+ expect(zypper_package.updated_by_last_action?).to be true
120
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.2-1.#{pkg_arch}$")
121
+ end
122
+
123
+ it "downgrades when the installed version is higher than the package_name version" do
124
+ preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
125
+ zypper_package.allow_downgrade true
126
+ zypper_package.package_name("chef_rpm")
127
+ zypper_package.version("1.2-1")
128
+ zypper_package.run_action(:install)
129
+ expect(zypper_package.updated_by_last_action?).to be true
130
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.2-1.#{pkg_arch}$")
131
+ end
132
+ end
133
+
134
+ describe ":remove" do
135
+ context "vanilla use case" do
136
+ let(:package_name) { "chef_rpm" }
137
+ it "does nothing if the package is not installed" do
138
+ zypper_package.run_action(:remove)
139
+ expect(zypper_package.updated_by_last_action?).to be false
140
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^package chef_rpm is not installed$")
141
+ end
142
+
143
+ it "removes the package if the package is installed" do
144
+ preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
145
+ zypper_package.run_action(:remove)
146
+ expect(zypper_package.updated_by_last_action?).to be true
147
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^package chef_rpm is not installed$")
148
+ end
149
+
150
+ it "does not remove the package twice" do
151
+ preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
152
+ zypper_package.run_action(:remove)
153
+ expect(zypper_package.updated_by_last_action?).to be true
154
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^package chef_rpm is not installed$")
155
+ zypper_package.run_action(:remove)
156
+ expect(zypper_package.updated_by_last_action?).to be false
157
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^package chef_rpm is not installed$")
158
+ end
159
+
160
+ it "removes the package if the prior version package is installed" do
161
+ preinstall("chef_rpm-1.2-1.#{pkg_arch}.rpm")
162
+ zypper_package.run_action(:remove)
163
+ expect(zypper_package.updated_by_last_action?).to be true
164
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^package chef_rpm is not installed$")
165
+ end
166
+ end
167
+
168
+ context "with no available version" do
169
+ it "works when a package is installed" do
170
+ FileUtils.rm_f "/etc/zypp/repos.d/chef-zypp-localtesting.repo"
171
+ preinstall("chef_rpm-1.2-1.#{pkg_arch}.rpm")
172
+ zypper_package.run_action(:remove)
173
+ expect(zypper_package.updated_by_last_action?).to be true
174
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^package chef_rpm is not installed$")
175
+ end
176
+ end
177
+ end
178
+
179
+ describe ":lock and :unlock" do
180
+ before(:each) do
181
+ shell_out("zypper removelock chef_rpm") # will exit with error when nothing is locked, we don't care
182
+ end
183
+
184
+ it "locks an rpm" do
185
+ zypper_package.package_name("chef_rpm")
186
+ zypper_package.run_action(:lock)
187
+ expect(zypper_package.updated_by_last_action?).to be true
188
+ expect(shell_out("zypper locks | grep chef_rpm").stdout.chomp).to match("chef_rpm")
189
+ end
190
+
191
+ it "does not lock if its already locked" do
192
+ shell_out!("zypper addlock chef_rpm")
193
+ zypper_package.package_name("chef_rpm")
194
+ zypper_package.run_action(:lock)
195
+ expect(zypper_package.updated_by_last_action?).to be false
196
+ expect(shell_out("zypper locks | grep chef_rpm").stdout.chomp).to match("chef_rpm")
197
+ end
198
+
199
+ it "unlocks an rpm" do
200
+ shell_out!("zypper addlock chef_rpm")
201
+ zypper_package.package_name("chef_rpm")
202
+ zypper_package.run_action(:unlock)
203
+ expect(zypper_package.updated_by_last_action?).to be true
204
+ expect(shell_out("zypper locks | grep chef_rpm").stdout.chomp).not_to match("chef_rpm")
205
+ end
206
+
207
+ it "does not unlock an already locked rpm" do
208
+ zypper_package.package_name("chef_rpm")
209
+ zypper_package.run_action(:unlock)
210
+ expect(zypper_package.updated_by_last_action?).to be false
211
+ expect(shell_out("zypper locks | grep chef_rpm").stdout.chomp).not_to match("chef_rpm")
212
+ end
213
+
214
+ it "check that we can lock based on provides" do
215
+ zypper_package.package_name("chef_rpm_provides")
216
+ zypper_package.run_action(:lock)
217
+ expect(zypper_package.updated_by_last_action?).to be true
218
+ expect(shell_out("zypper locks | grep chef_rpm_provides").stdout.chomp).to match("chef_rpm_provides")
219
+ end
220
+
221
+ it "check that we can unlock based on provides" do
222
+ shell_out!("zypper addlock chef_rpm_provides")
223
+ zypper_package.package_name("chef_rpm_provides")
224
+ zypper_package.run_action(:unlock)
225
+ expect(zypper_package.updated_by_last_action?).to be true
226
+ expect(shell_out("zypper locks | grep chef_rpm_provides").stdout.chomp).not_to match("chef_rpm_provides")
227
+ end
228
+ end
229
+ def remove_package
230
+ pkg_to_remove = Chef::Resource::ZypperPackage.new(package_name, run_context)
231
+ pkg_to_remove.run_action(:remove)
232
+ end
233
+ end