chef 18.0.185-x64-mingw-ucrt → 18.1.0-x64-mingw-ucrt
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/chef/chef_fs/file_system.rb +21 -7
- data/lib/chef/property.rb +8 -3
- data/lib/chef/provider/launchd.rb +1 -0
- data/lib/chef/provider/package/yum/yum_helper.py +5 -17
- data/lib/chef/provider/yum_repository.rb +13 -1
- data/lib/chef/resource/launchd.rb +3 -0
- data/lib/chef/resource/macos_userdefaults.rb +3 -3
- data/lib/chef/resource/rhsm_register.rb +2 -1
- data/lib/chef/resource/yum_repository.rb +4 -0
- data/lib/chef/version.rb +1 -1
- data/spec/functional/assets/yumrepo-empty/repodata/01a3b489a465bcac22a43492163df43451dc6ce47d27f66de289756b91635523-filelists.sqlite.bz2 +0 -0
- data/spec/functional/assets/yumrepo-empty/repodata/401dc19bda88c82c403423fb835844d64345f7e95f5b9835888189c03834cc93-filelists.xml.gz +0 -0
- data/spec/functional/assets/yumrepo-empty/repodata/5dc1e6e73c84803f059bb3065e684e56adfc289a7e398946574d79dac6643945-primary.sqlite.bz2 +0 -0
- data/spec/functional/assets/yumrepo-empty/repodata/6bf9672d0862e8ef8b8ff05a2fd0208a922b1f5978e6589d87944c88259cb670-other.xml.gz +0 -0
- data/spec/functional/assets/yumrepo-empty/repodata/7c36572015e075add2b38b900837bcdbb8a504130ddff49b2351a7fc0affa3d4-other.sqlite.bz2 +0 -0
- data/spec/functional/assets/yumrepo-empty/repodata/dabe2ce5481d23de1f4f52bdcfee0f9af98316c9e0de2ce8123adeefa0dd08b9-primary.xml.gz +0 -0
- data/spec/functional/assets/yumrepo-empty/repodata/repomd.xml +55 -0
- data/spec/functional/resource/yum_package_spec.rb +16 -0
- data/spec/integration/client/fips_spec.rb +20 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/platform_helpers.rb +4 -0
- data/spec/unit/chef_fs/file_system_spec.rb +2 -0
- data/spec/unit/property/validation_spec.rb +30 -0
- data/spec/unit/resource/yum_repository_spec.rb +4 -0
- metadata +14 -7
- data/distro/powershell/chef/chef.psm1 +0 -459
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 448a7d27ab27f9a0c39566270e5d99dfa5717ba32bd893505fd3f1d9d50ad339
|
4
|
+
data.tar.gz: be60df259d416a70dc1c6447edab19ec1d4b9fb32f1429a4fc09c62c4cb8e022
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 833f265e523ce7924016ee802f599548361c94ec5e837f85b1263a39935f5a8443953b06d9b753fe2cbc154d0d9a6f1d5fd363caaaf2a14ccab08f6d952344ee
|
7
|
+
data.tar.gz: 25c72dc0a3d5e6e4a6c414ecea9260a363b033a657d1626cdf1cdd6be683a8f51968655715b5b693e643bbf44b605c99d27d98d6cdf6a58d0d1481f43e687300
|
@@ -140,17 +140,18 @@ class Chef
|
|
140
140
|
def self.copy_to(pattern, src_root, dest_root, recurse_depth, options, ui = nil, format_path = nil)
|
141
141
|
found_result = false
|
142
142
|
error = false
|
143
|
+
result = {}
|
143
144
|
list_pairs(pattern, src_root, dest_root).parallel_each do |src, dest|
|
144
145
|
found_result = true
|
145
146
|
new_dest_parent = get_or_create_parent(dest, options, ui, format_path)
|
146
|
-
child_error = copy_entries(src, dest, new_dest_parent, recurse_depth, options, ui, format_path)
|
147
|
+
child_error, result = copy_entries(src, dest, new_dest_parent, recurse_depth, options, ui, format_path)
|
147
148
|
error ||= child_error
|
148
149
|
end
|
149
150
|
if !found_result && pattern.exact_path
|
150
151
|
ui.error "#{pattern}: No such file or directory on remote or local" if ui
|
151
152
|
error = true
|
152
153
|
end
|
153
|
-
error
|
154
|
+
[error, result]
|
154
155
|
end
|
155
156
|
|
156
157
|
# Yield entries for children that are in either +a_root+ or +b_root+, with
|
@@ -275,6 +276,7 @@ class Chef
|
|
275
276
|
# case we shouldn't waste time trying PUT if we know the file doesn't
|
276
277
|
# exist.
|
277
278
|
# Will need to decide how that works with checksums, though.
|
279
|
+
result = { "total" => 0, "success_count" => 0, "failed" => [] }
|
278
280
|
error = false
|
279
281
|
begin
|
280
282
|
dest_path = format_path.call(dest_entry) if ui
|
@@ -290,6 +292,8 @@ class Chef
|
|
290
292
|
dest_entry.delete(true)
|
291
293
|
ui.output "Deleted extra entry #{dest_path} (purge is on)" if ui
|
292
294
|
rescue Chef::ChefFS::FileSystem::NotFoundError
|
295
|
+
failure = { "src_path" => src_path, "reason" => "Entry #{dest_path} does not exist" }
|
296
|
+
result["failed"].append(failure)
|
293
297
|
ui.output "Entry #{dest_path} does not exist. Nothing to do. (purge is on)" if ui
|
294
298
|
end
|
295
299
|
end
|
@@ -323,7 +327,7 @@ class Chef
|
|
323
327
|
if recurse_depth != 0
|
324
328
|
src_entry.children.parallel_each do |src_child|
|
325
329
|
new_dest_child = new_dest_dir.child(src_child.name)
|
326
|
-
child_error = copy_entries(src_child, new_dest_child, new_dest_dir, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path)
|
330
|
+
child_error, result = copy_entries(src_child, new_dest_child, new_dest_dir, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path)
|
327
331
|
error ||= child_error
|
328
332
|
end
|
329
333
|
end
|
@@ -339,14 +343,15 @@ class Chef
|
|
339
343
|
|
340
344
|
else
|
341
345
|
# Both exist.
|
342
|
-
|
343
346
|
# If the entry can do a copy directly, do that.
|
344
347
|
if dest_entry.respond_to?(:copy_from)
|
345
348
|
if options[:force] || compare(src_entry, dest_entry)[0] == false
|
346
349
|
if options[:dry_run]
|
347
350
|
ui.output "Would update #{dest_path}" if ui
|
348
351
|
else
|
352
|
+
result["total"] += 1
|
349
353
|
dest_entry.copy_from(src_entry, options)
|
354
|
+
result["success_count"] += 1
|
350
355
|
ui.output "Updated #{dest_path}" if ui
|
351
356
|
end
|
352
357
|
end
|
@@ -359,7 +364,7 @@ class Chef
|
|
359
364
|
# If both are directories, recurse into their children
|
360
365
|
if recurse_depth != 0
|
361
366
|
child_pairs(src_entry, dest_entry).parallel_each do |src_child, dest_child|
|
362
|
-
child_error = copy_entries(src_child, dest_child, dest_entry, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path)
|
367
|
+
child_error, result = copy_entries(src_child, dest_child, dest_entry, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path)
|
363
368
|
error ||= child_error
|
364
369
|
end
|
365
370
|
end
|
@@ -373,7 +378,6 @@ class Chef
|
|
373
378
|
ui.error("File #{src_path} is a regular file while file #{dest_path} is a directory\n") if ui
|
374
379
|
return
|
375
380
|
else
|
376
|
-
|
377
381
|
# Both are files! Copy them unless we're sure they are the same.'
|
378
382
|
if options[:diff] == false
|
379
383
|
should_copy = false
|
@@ -389,7 +393,9 @@ class Chef
|
|
389
393
|
ui.output "Would update #{dest_path}" if ui
|
390
394
|
else
|
391
395
|
src_value = src_entry.read if src_value.nil?
|
396
|
+
result["total"] += 1
|
392
397
|
dest_entry.write(src_value)
|
398
|
+
result["success_count"] += 1
|
393
399
|
ui.output "Updated #{dest_path}" if ui
|
394
400
|
end
|
395
401
|
end
|
@@ -397,17 +403,25 @@ class Chef
|
|
397
403
|
end
|
398
404
|
end
|
399
405
|
rescue RubyFileError => e
|
406
|
+
failure = { "src_path" => src_path, "reason" => e.reason }
|
407
|
+
result["failed"].append(failure)
|
400
408
|
ui.warn "#{format_path.call(e.entry)} #{e.reason}." if ui
|
401
409
|
rescue DefaultEnvironmentCannotBeModifiedError => e
|
410
|
+
failure = { "src_path" => src_path, "reason" => e.reason }
|
411
|
+
result["failed"].append(failure)
|
402
412
|
ui.warn "#{format_path.call(e.entry)} #{e.reason}." if ui
|
403
413
|
rescue OperationFailedError => e
|
414
|
+
failure = { "src_path" => src_path, "reason" => e.reason }
|
415
|
+
result["failed"].append(failure)
|
404
416
|
ui.error "#{format_path.call(e.entry)} failed to #{e.operation}: #{e.message}" if ui
|
405
417
|
error = true
|
406
418
|
rescue OperationNotAllowedError => e
|
419
|
+
failure = { "src_path" => src_path, "reason" => e.reason }
|
420
|
+
result["failed"].append(failure)
|
407
421
|
ui.error "#{format_path.call(e.entry)} #{e.reason}." if ui
|
408
422
|
error = true
|
409
423
|
end
|
410
|
-
error
|
424
|
+
[error, result]
|
411
425
|
end
|
412
426
|
|
413
427
|
def get_or_create_parent(entry, options, ui, format_path)
|
data/lib/chef/property.rb
CHANGED
@@ -307,7 +307,7 @@ class Chef
|
|
307
307
|
#
|
308
308
|
def required?(action = nil)
|
309
309
|
if !action.nil? && options[:required].is_a?(Array)
|
310
|
-
options[:required]
|
310
|
+
(options[:required] & Array(action)).any?
|
311
311
|
else
|
312
312
|
!!options[:required]
|
313
313
|
end
|
@@ -426,7 +426,7 @@ class Chef
|
|
426
426
|
end
|
427
427
|
end
|
428
428
|
|
429
|
-
if value.nil? && required?
|
429
|
+
if value.nil? && required?(resource_action(resource))
|
430
430
|
raise Chef::Exceptions::ValidationFailed, "#{name} is a required property"
|
431
431
|
else
|
432
432
|
value
|
@@ -455,7 +455,7 @@ class Chef
|
|
455
455
|
Chef.deprecated(:property, options[:deprecated])
|
456
456
|
end
|
457
457
|
|
458
|
-
if value.nil? && required?
|
458
|
+
if value.nil? && required?(resource_action(resource))
|
459
459
|
raise Chef::Exceptions::ValidationFailed, "#{name} is a required property"
|
460
460
|
else
|
461
461
|
value
|
@@ -768,5 +768,10 @@ class Chef
|
|
768
768
|
end
|
769
769
|
visitor.call(value)
|
770
770
|
end
|
771
|
+
|
772
|
+
# action from resource, if available
|
773
|
+
def resource_action(resource)
|
774
|
+
resource.action if resource.respond_to?(:action)
|
775
|
+
end
|
771
776
|
end
|
772
777
|
end
|
@@ -153,6 +153,7 @@ class Chef
|
|
153
153
|
"program" => "Program",
|
154
154
|
"program_arguments" => "ProgramArguments",
|
155
155
|
"abandon_process_group" => "AbandonProcessGroup",
|
156
|
+
"associated_bundle_identifiers" => "AssociatedBundleIdentifiers",
|
156
157
|
"debug" => "Debug",
|
157
158
|
"disabled" => "Disabled",
|
158
159
|
"enable_globbing" => "EnableGlobbing",
|
@@ -53,16 +53,14 @@ def install_only_packages(base, name):
|
|
53
53
|
outpipe.flush()
|
54
54
|
|
55
55
|
def query(base, command):
|
56
|
-
enabled_repos = base.repos.listEnabled()
|
57
|
-
|
58
56
|
# Handle any repocontrols passed in with our options
|
59
57
|
|
60
58
|
if 'repos' in command:
|
61
59
|
for repo in command['repos']:
|
62
60
|
if 'enable' in repo:
|
63
61
|
base.repos.enableRepo(repo['enable'])
|
64
|
-
|
65
|
-
|
62
|
+
if 'disable' in repo:
|
63
|
+
base.repos.disableRepo(repo['disable'])
|
66
64
|
|
67
65
|
args = { 'name': command['provides'] }
|
68
66
|
do_nevra = False
|
@@ -94,8 +92,8 @@ def query(base, command):
|
|
94
92
|
# then the result was searchNevra'd. please be extremely careful if attempting to fix that
|
95
93
|
# since searchNevra does not support prco tuples.
|
96
94
|
if bool(re.search('\\s+', command['provides'])):
|
97
|
-
# handles flags (<, >, =, etc) and versions, but no
|
98
|
-
# raises error for any invalid input like: 'FOO BAR BAZ'
|
95
|
+
# handles flags (<, >, =, etc) and versions, but no wildcards
|
96
|
+
# raises error for any invalid input like: 'FOO BAR BAZ'
|
99
97
|
pkgs = obj.getProvides(*string_to_prco_tuple(command['provides']))
|
100
98
|
elif do_nevra:
|
101
99
|
# now if we're given version or arch properties explicitly, then we do a SearchNevra.
|
@@ -123,16 +121,6 @@ def query(base, command):
|
|
123
121
|
outpipe.write("%(n)s %(e)s:%(v)s-%(r)s %(a)s\n" % { 'n': pkg.name, 'e': pkg.epoch, 'v': pkg.version, 'r': pkg.release, 'a': pkg.arch })
|
124
122
|
outpipe.flush()
|
125
123
|
|
126
|
-
# Reset any repos we were passed in enablerepo/disablerepo to the original state in enabled_repos
|
127
|
-
if 'repos' in command:
|
128
|
-
for repo in command['repos']:
|
129
|
-
if 'enable' in repo:
|
130
|
-
if base.repos.getRepo(repo['enable']) not in enabled_repos:
|
131
|
-
base.repos.disableRepo(repo['enable'])
|
132
|
-
if 'disable' in repo:
|
133
|
-
if base.repos.getRepo(repo['disable']) in enabled_repos:
|
134
|
-
base.repos.enableRepo(repo['disable'])
|
135
|
-
|
136
124
|
# the design of this helper is that it should try to be 'brittle' and fail hard and exit in order
|
137
125
|
# to keep process tables clean. additional error handling should probably be added to the retry loop
|
138
126
|
# on the ruby side.
|
@@ -178,7 +166,7 @@ try:
|
|
178
166
|
|
179
167
|
try:
|
180
168
|
command = json.loads(line)
|
181
|
-
except ValueError
|
169
|
+
except ValueError as e:
|
182
170
|
raise RuntimeError("bad json parse")
|
183
171
|
|
184
172
|
if base is None:
|
@@ -44,7 +44,12 @@ class Chef
|
|
44
44
|
mode new_resource.mode
|
45
45
|
if new_resource.make_cache
|
46
46
|
notifies :run, "execute[yum clean metadata #{new_resource.repositoryid}]", :immediately if new_resource.clean_metadata || new_resource.clean_headers
|
47
|
-
|
47
|
+
# makecache fast only works on non-dnf systems.
|
48
|
+
if !which "dnf" && new_resource.makecache_fast
|
49
|
+
notifies :run, "execute[yum-makecache-fast-#{new_resource.repositoryid}]", :immediately
|
50
|
+
else
|
51
|
+
notifies :run, "execute[yum-makecache-#{new_resource.repositoryid}]", :immediately
|
52
|
+
end
|
48
53
|
notifies :flush_cache, "package[package-cache-reload-#{new_resource.repositoryid}]", :immediately
|
49
54
|
end
|
50
55
|
end
|
@@ -63,6 +68,13 @@ class Chef
|
|
63
68
|
only_if { new_resource.enabled }
|
64
69
|
end
|
65
70
|
|
71
|
+
# download only the minimum required metadata
|
72
|
+
execute "yum-makecache-fast-#{new_resource.repositoryid}" do
|
73
|
+
command "yum -q -y makecache fast --disablerepo=* --enablerepo=#{new_resource.repositoryid}"
|
74
|
+
action :nothing
|
75
|
+
only_if { new_resource.enabled }
|
76
|
+
end
|
77
|
+
|
66
78
|
package "package-cache-reload-#{new_resource.repositoryid}" do
|
67
79
|
action :nothing
|
68
80
|
end
|
@@ -129,6 +129,9 @@ class Chef
|
|
129
129
|
property :abandon_process_group, [ TrueClass, FalseClass ],
|
130
130
|
description: "If a job dies, all remaining processes with the same process ID may be kept running. Set to true to kill all remaining processes."
|
131
131
|
|
132
|
+
property :associated_bundle_identifiers, Hash,
|
133
|
+
description: "This optional key indicates which bundles the Login Items Added by Apps panel associates with the helper executable."
|
134
|
+
|
132
135
|
property :debug, [ TrueClass, FalseClass ],
|
133
136
|
description: "Sets the log mask to `LOG_DEBUG` for this job."
|
134
137
|
|
@@ -69,7 +69,7 @@ class Chef
|
|
69
69
|
|
70
70
|
property :global, [TrueClass, FalseClass],
|
71
71
|
description: "Determines whether or not the domain is global.",
|
72
|
-
deprecated:
|
72
|
+
deprecated: "As of Chef Infra Client 17.8 the `global` property is no longer necessary.",
|
73
73
|
default: false,
|
74
74
|
desired_state: false
|
75
75
|
|
@@ -90,7 +90,7 @@ class Chef
|
|
90
90
|
description: "The value type of the preference key.",
|
91
91
|
equal_to: %w{bool string int float array dict},
|
92
92
|
desired_state: false,
|
93
|
-
deprecated:
|
93
|
+
deprecated: "As of Chef Infra Client 17.8 the `type` property is no longer necessary."
|
94
94
|
|
95
95
|
property :user, [String, Symbol],
|
96
96
|
description: "The system user that the default will be applied to. Set :current for current user, :all for all users or pass a valid username",
|
@@ -100,7 +100,7 @@ class Chef
|
|
100
100
|
description: "Set to true if the setting you wish to modify requires privileged access. This requires passwordless sudo for the `/usr/bin/defaults` command to be setup for the user running #{ChefUtils::Dist::Infra::PRODUCT}.",
|
101
101
|
default: false,
|
102
102
|
desired_state: false,
|
103
|
-
deprecated:
|
103
|
+
deprecated: "As of Chef Infra Client 17.8 the `sudo` property is no longer necessary."
|
104
104
|
|
105
105
|
load_current_value do |new_resource|
|
106
106
|
Chef::Log.debug "#load_current_value: attempting to read \"#{new_resource.domain}\" value from preferences to determine state"
|
@@ -92,7 +92,7 @@ class Chef
|
|
92
92
|
|
93
93
|
property :release,
|
94
94
|
[Float, String],
|
95
|
-
description: "Sets the operating system minor release to use for subscriptions for the system. Products and updates are limited to the specified minor release version. This is used
|
95
|
+
description: "Sets the operating system minor release to use for subscriptions for the system. Products and updates are limited to the specified minor release version. This is used with the `auto_attach` option, it may also be used with activation keys. For example, `release '6.4'` will append `--release=6.4` to the register command.",
|
96
96
|
introduced: "17.8"
|
97
97
|
|
98
98
|
action :register, description: "Register the node with RHSM." do
|
@@ -205,6 +205,7 @@ class Chef
|
|
205
205
|
command << "--name=#{Shellwords.shellescape(new_resource.system_name)}" if new_resource.system_name
|
206
206
|
command << "--serverurl=#{Shellwords.shellescape(new_resource.server_url)}" if new_resource.server_url
|
207
207
|
command << "--baseurl=#{Shellwords.shellescape(new_resource.base_url)}" if new_resource.base_url
|
208
|
+
command << "--release=#{Shellwords.shellescape(new_resource.release)}" if new_resource.release
|
208
209
|
command << "--force" if new_resource.force
|
209
210
|
|
210
211
|
return command.join(" ")
|
@@ -114,6 +114,10 @@ class Chef
|
|
114
114
|
description: "Determines whether package files downloaded by Yum stay in cache directories. By using cached data, you can carry out certain operations without a network connection.",
|
115
115
|
default: true
|
116
116
|
|
117
|
+
property :makecache_fast, [TrueClass, FalseClass],
|
118
|
+
description: "if make_cache is true, uses `yum makecache fast`, which downloads only the minimum amount of data required. Useful over slower connections and when disk space is at a premium.",
|
119
|
+
default: false
|
120
|
+
|
117
121
|
property :max_retries, [String, Integer],
|
118
122
|
description: "Number of times any attempt to retrieve a file should retry before returning an error. Setting this to `0` makes Yum try forever."
|
119
123
|
|
data/lib/chef/version.rb
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<repomd xmlns="http://linux.duke.edu/metadata/repo" xmlns:rpm="http://linux.duke.edu/metadata/rpm">
|
3
|
+
<revision>1667508211</revision>
|
4
|
+
<data type="filelists">
|
5
|
+
<checksum type="sha256">401dc19bda88c82c403423fb835844d64345f7e95f5b9835888189c03834cc93</checksum>
|
6
|
+
<open-checksum type="sha256">bf9808b81cb2dbc54b4b8e35adc584ddcaa73bd81f7088d73bf7dbbada961310</open-checksum>
|
7
|
+
<location href="repodata/401dc19bda88c82c403423fb835844d64345f7e95f5b9835888189c03834cc93-filelists.xml.gz"/>
|
8
|
+
<timestamp>1667508211</timestamp>
|
9
|
+
<size>123</size>
|
10
|
+
<open-size>125</open-size>
|
11
|
+
</data>
|
12
|
+
<data type="primary">
|
13
|
+
<checksum type="sha256">dabe2ce5481d23de1f4f52bdcfee0f9af98316c9e0de2ce8123adeefa0dd08b9</checksum>
|
14
|
+
<open-checksum type="sha256">e1e2ffd2fb1ee76f87b70750d00ca5677a252b397ab6c2389137a0c33e7b359f</open-checksum>
|
15
|
+
<location href="repodata/dabe2ce5481d23de1f4f52bdcfee0f9af98316c9e0de2ce8123adeefa0dd08b9-primary.xml.gz"/>
|
16
|
+
<timestamp>1667508211</timestamp>
|
17
|
+
<size>134</size>
|
18
|
+
<open-size>167</open-size>
|
19
|
+
</data>
|
20
|
+
<data type="primary_db">
|
21
|
+
<checksum type="sha256">5dc1e6e73c84803f059bb3065e684e56adfc289a7e398946574d79dac6643945</checksum>
|
22
|
+
<open-checksum type="sha256">f0d550414e8f2e960e82e704549364299ca9e3e8664ad4faffd208262c3b6d12</open-checksum>
|
23
|
+
<location href="repodata/5dc1e6e73c84803f059bb3065e684e56adfc289a7e398946574d79dac6643945-primary.sqlite.bz2"/>
|
24
|
+
<timestamp>1667508211</timestamp>
|
25
|
+
<database_version>10</database_version>
|
26
|
+
<size>1131</size>
|
27
|
+
<open-size>21504</open-size>
|
28
|
+
</data>
|
29
|
+
<data type="other_db">
|
30
|
+
<checksum type="sha256">7c36572015e075add2b38b900837bcdbb8a504130ddff49b2351a7fc0affa3d4</checksum>
|
31
|
+
<open-checksum type="sha256">4de0fe7c5dd2674849a7c63c326e42f33af0a0f46219bc6dd59f51dfa2ac8c68</open-checksum>
|
32
|
+
<location href="repodata/7c36572015e075add2b38b900837bcdbb8a504130ddff49b2351a7fc0affa3d4-other.sqlite.bz2"/>
|
33
|
+
<timestamp>1667508211</timestamp>
|
34
|
+
<database_version>10</database_version>
|
35
|
+
<size>575</size>
|
36
|
+
<open-size>6144</open-size>
|
37
|
+
</data>
|
38
|
+
<data type="other">
|
39
|
+
<checksum type="sha256">6bf9672d0862e8ef8b8ff05a2fd0208a922b1f5978e6589d87944c88259cb670</checksum>
|
40
|
+
<open-checksum type="sha256">e0ed5e0054194df036cf09c1a911e15bf2a4e7f26f2a788b6f47d53e80717ccc</open-checksum>
|
41
|
+
<location href="repodata/6bf9672d0862e8ef8b8ff05a2fd0208a922b1f5978e6589d87944c88259cb670-other.xml.gz"/>
|
42
|
+
<timestamp>1667508211</timestamp>
|
43
|
+
<size>123</size>
|
44
|
+
<open-size>121</open-size>
|
45
|
+
</data>
|
46
|
+
<data type="filelists_db">
|
47
|
+
<checksum type="sha256">01a3b489a465bcac22a43492163df43451dc6ce47d27f66de289756b91635523</checksum>
|
48
|
+
<open-checksum type="sha256">c4211f57bdcbb142c9f93a6d32401539f775eb6a670ab7a423e13f435ce94689</open-checksum>
|
49
|
+
<location href="repodata/01a3b489a465bcac22a43492163df43451dc6ce47d27f66de289756b91635523-filelists.sqlite.bz2"/>
|
50
|
+
<timestamp>1667508211</timestamp>
|
51
|
+
<database_version>10</database_version>
|
52
|
+
<size>586</size>
|
53
|
+
<open-size>7168</open-size>
|
54
|
+
</data>
|
55
|
+
</repomd>
|
@@ -57,6 +57,12 @@ describe Chef::Resource::YumPackage, :requires_root, external: exclude_test do
|
|
57
57
|
baseurl=file://#{CHEF_SPEC_ASSETS}/yumrepo
|
58
58
|
enable=1
|
59
59
|
gpgcheck=0
|
60
|
+
[chef-yum-empty]
|
61
|
+
name=Chef DNF spec empty repo
|
62
|
+
baseurl=file://#{CHEF_SPEC_ASSETS}/yumrepo-empty
|
63
|
+
enable=1
|
64
|
+
gpgcheck=0
|
65
|
+
|
60
66
|
EOF
|
61
67
|
end
|
62
68
|
# ensure we don't have any stray chef_rpms installed
|
@@ -1095,6 +1101,16 @@ describe Chef::Resource::YumPackage, :requires_root, external: exclude_test do
|
|
1095
1101
|
end.should_not_be_updated
|
1096
1102
|
end
|
1097
1103
|
|
1104
|
+
it "should work to disable a repo" do
|
1105
|
+
flush_cache
|
1106
|
+
expect {
|
1107
|
+
yum_package "chef_rpm" do
|
1108
|
+
options "--disablerepo=chef-yum-localtesting --enablerepo=chef-yum-empty"
|
1109
|
+
action :install
|
1110
|
+
end
|
1111
|
+
}.to raise_error(Chef::Exceptions::Package, /No candidate version available/)
|
1112
|
+
end
|
1113
|
+
|
1098
1114
|
it "when an idempotent install action is run, does not leave repos disabled" do
|
1099
1115
|
flush_cache
|
1100
1116
|
# this is a bit tricky -- we need this action to be idempotent, so that it doesn't recycle any
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "chef-client fips" do
|
4
|
+
def enable_fips
|
5
|
+
OpenSSL.fips_mode = true
|
6
|
+
end
|
7
|
+
|
8
|
+
# All tests assume fips mode is off at present
|
9
|
+
after { OpenSSL.fips_mode = false }
|
10
|
+
|
11
|
+
# For non-FIPS OSes/builds of Ruby, enabling FIPS should error
|
12
|
+
example "Error enabling fips_mode if FIPS not linked", fips_mode: false do
|
13
|
+
expect { enable_fips }.to raise_error(OpenSSL::OpenSSLError)
|
14
|
+
end
|
15
|
+
|
16
|
+
# For FIPS OSes/builds of Ruby, enabling FIPS should not error
|
17
|
+
example "Do not error enabling fips_mode if FIPS linked", fips_mode: true do
|
18
|
+
expect { enable_fips }.not_to raise_error
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -138,6 +138,10 @@ RSpec.configure do |config|
|
|
138
138
|
|
139
139
|
config.filter_run_excluding skip_buildkite: true if ENV["BUILDKITE"]
|
140
140
|
|
141
|
+
config.filter_run_excluding fips_mode: !fips_mode_build? unless opensuse?
|
142
|
+
# RubyDistros OpenSUSE docker images have a broken fips
|
143
|
+
config.filter_run_excluding :fips_mode if opensuse?
|
144
|
+
|
141
145
|
config.filter_run_excluding windows_only: true unless windows?
|
142
146
|
config.filter_run_excluding not_supported_on_windows: true if windows?
|
143
147
|
config.filter_run_excluding not_supported_on_macos: true if macos?
|
@@ -600,6 +600,36 @@ describe "Chef::Resource.property validation" do
|
|
600
600
|
it "does not fail if it is not specified, on running the doit2 action" do
|
601
601
|
expect { resource.run_action(:doit2) }.not_to raise_error
|
602
602
|
end
|
603
|
+
|
604
|
+
context "when an action does not require it" do
|
605
|
+
before do
|
606
|
+
resource.action(:doit2)
|
607
|
+
end
|
608
|
+
|
609
|
+
it "retrieval succeeds if x is not set when resource uses the doit2 action" do
|
610
|
+
expect { resource.x }.not_to raise_error
|
611
|
+
end
|
612
|
+
|
613
|
+
it "succeeds with set to nil when resource uses the doit2 action" do
|
614
|
+
expect { resource.x nil }.not_to raise_error
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
context "when an action requires it" do
|
619
|
+
before do
|
620
|
+
# NOTE: this is already the default action, but it doesn't
|
621
|
+
# hurt to be clear about the situation.
|
622
|
+
resource.action(:doit)
|
623
|
+
end
|
624
|
+
|
625
|
+
it "if x is not specified, retrieval fails for the doit action" do
|
626
|
+
expect { resource.x }.to raise_error Chef::Exceptions::ValidationFailed
|
627
|
+
end
|
628
|
+
|
629
|
+
it "value nil is not valid for the doit action (required means 'not nil')" do
|
630
|
+
expect { resource.x nil }.to raise_error Chef::Exceptions::ValidationFailed
|
631
|
+
end
|
632
|
+
end
|
603
633
|
end
|
604
634
|
|
605
635
|
with_property ":x, String, required: true" do
|
@@ -68,6 +68,10 @@ describe Chef::Resource::YumRepository do
|
|
68
68
|
expect(resource.make_cache).to eql(true)
|
69
69
|
end
|
70
70
|
|
71
|
+
it "makecache_fast property defaults to false" do
|
72
|
+
expect(resource.makecache_fast).to eql(false)
|
73
|
+
end
|
74
|
+
|
71
75
|
it "mode property defaults to '0644'" do
|
72
76
|
expect(resource.mode).to eql("0644")
|
73
77
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 18.0
|
4
|
+
version: 18.1.0
|
5
5
|
platform: x64-mingw-ucrt
|
6
6
|
authors:
|
7
7
|
- Adam Jacob
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-config
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 18.0
|
19
|
+
version: 18.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 18.0
|
26
|
+
version: 18.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: chef-utils
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 18.0
|
33
|
+
version: 18.1.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 18.0
|
40
|
+
version: 18.1.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: train-core
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -734,7 +734,6 @@ files:
|
|
734
734
|
- Rakefile
|
735
735
|
- chef-universal-mingw-ucrt.gemspec
|
736
736
|
- chef.gemspec
|
737
|
-
- distro/powershell/chef/chef.psm1
|
738
737
|
- distro/ruby_bin_folder/AMD64/Chef.PowerShell.Wrapper.dll
|
739
738
|
- distro/ruby_bin_folder/AMD64/Chef.PowerShell.dll
|
740
739
|
- distro/ruby_bin_folder/AMD64/Ijwhost.dll
|
@@ -2515,6 +2514,13 @@ files:
|
|
2515
2514
|
- spec/functional/assets/mytest-1.0-1.noarch.rpm
|
2516
2515
|
- spec/functional/assets/mytest-2.0-1.noarch.rpm
|
2517
2516
|
- spec/functional/assets/testchefsubsys
|
2517
|
+
- spec/functional/assets/yumrepo-empty/repodata/01a3b489a465bcac22a43492163df43451dc6ce47d27f66de289756b91635523-filelists.sqlite.bz2
|
2518
|
+
- spec/functional/assets/yumrepo-empty/repodata/401dc19bda88c82c403423fb835844d64345f7e95f5b9835888189c03834cc93-filelists.xml.gz
|
2519
|
+
- spec/functional/assets/yumrepo-empty/repodata/5dc1e6e73c84803f059bb3065e684e56adfc289a7e398946574d79dac6643945-primary.sqlite.bz2
|
2520
|
+
- spec/functional/assets/yumrepo-empty/repodata/6bf9672d0862e8ef8b8ff05a2fd0208a922b1f5978e6589d87944c88259cb670-other.xml.gz
|
2521
|
+
- spec/functional/assets/yumrepo-empty/repodata/7c36572015e075add2b38b900837bcdbb8a504130ddff49b2351a7fc0affa3d4-other.sqlite.bz2
|
2522
|
+
- spec/functional/assets/yumrepo-empty/repodata/dabe2ce5481d23de1f4f52bdcfee0f9af98316c9e0de2ce8123adeefa0dd08b9-primary.xml.gz
|
2523
|
+
- spec/functional/assets/yumrepo-empty/repodata/repomd.xml
|
2518
2524
|
- spec/functional/assets/yumrepo/chef_rpm-1.10-1.aarch64.rpm
|
2519
2525
|
- spec/functional/assets/yumrepo/chef_rpm-1.10-1.i686.rpm
|
2520
2526
|
- spec/functional/assets/yumrepo/chef_rpm-1.10-1.ppc64.rpm
|
@@ -2635,6 +2641,7 @@ files:
|
|
2635
2641
|
- spec/functional/win32/versions_spec.rb
|
2636
2642
|
- spec/integration/client/client_spec.rb
|
2637
2643
|
- spec/integration/client/exit_code_spec.rb
|
2644
|
+
- spec/integration/client/fips_spec.rb
|
2638
2645
|
- spec/integration/client/ipv6_spec.rb
|
2639
2646
|
- spec/integration/compliance/compliance_spec.rb
|
2640
2647
|
- spec/integration/ohai/ohai_spec.rb
|
@@ -1,459 +0,0 @@
|
|
1
|
-
|
2
|
-
function Load-Win32Bindings {
|
3
|
-
Add-Type -TypeDefinition @"
|
4
|
-
using System;
|
5
|
-
using System.Diagnostics;
|
6
|
-
using System.Runtime.InteropServices;
|
7
|
-
|
8
|
-
namespace Chef
|
9
|
-
{
|
10
|
-
|
11
|
-
[StructLayout(LayoutKind.Sequential)]
|
12
|
-
public struct PROCESS_INFORMATION
|
13
|
-
{
|
14
|
-
public IntPtr hProcess;
|
15
|
-
public IntPtr hThread;
|
16
|
-
public uint dwProcessId;
|
17
|
-
public uint dwThreadId;
|
18
|
-
}
|
19
|
-
|
20
|
-
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
21
|
-
public struct STARTUPINFO
|
22
|
-
{
|
23
|
-
public uint cb;
|
24
|
-
public string lpReserved;
|
25
|
-
public string lpDesktop;
|
26
|
-
public string lpTitle;
|
27
|
-
public uint dwX;
|
28
|
-
public uint dwY;
|
29
|
-
public uint dwXSize;
|
30
|
-
public uint dwYSize;
|
31
|
-
public uint dwXCountChars;
|
32
|
-
public uint dwYCountChars;
|
33
|
-
public uint dwFillAttribute;
|
34
|
-
public STARTF dwFlags;
|
35
|
-
public ShowWindow wShowWindow;
|
36
|
-
public short cbReserved2;
|
37
|
-
public IntPtr lpReserved2;
|
38
|
-
public IntPtr hStdInput;
|
39
|
-
public IntPtr hStdOutput;
|
40
|
-
public IntPtr hStdError;
|
41
|
-
}
|
42
|
-
|
43
|
-
[StructLayout(LayoutKind.Sequential)]
|
44
|
-
public struct SECURITY_ATTRIBUTES
|
45
|
-
{
|
46
|
-
public int length;
|
47
|
-
public IntPtr lpSecurityDescriptor;
|
48
|
-
public bool bInheritHandle;
|
49
|
-
}
|
50
|
-
|
51
|
-
[Flags]
|
52
|
-
public enum CreationFlags : int
|
53
|
-
{
|
54
|
-
NONE = 0,
|
55
|
-
DEBUG_PROCESS = 0x00000001,
|
56
|
-
DEBUG_ONLY_THIS_PROCESS = 0x00000002,
|
57
|
-
CREATE_SUSPENDED = 0x00000004,
|
58
|
-
DETACHED_PROCESS = 0x00000008,
|
59
|
-
CREATE_NEW_CONSOLE = 0x00000010,
|
60
|
-
CREATE_NEW_PROCESS_GROUP = 0x00000200,
|
61
|
-
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
|
62
|
-
CREATE_SEPARATE_WOW_VDM = 0x00000800,
|
63
|
-
CREATE_SHARED_WOW_VDM = 0x00001000,
|
64
|
-
CREATE_PROTECTED_PROCESS = 0x00040000,
|
65
|
-
EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
|
66
|
-
CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
|
67
|
-
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
|
68
|
-
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
|
69
|
-
CREATE_NO_WINDOW = 0x08000000,
|
70
|
-
}
|
71
|
-
|
72
|
-
[Flags]
|
73
|
-
public enum STARTF : uint
|
74
|
-
{
|
75
|
-
STARTF_USESHOWWINDOW = 0x00000001,
|
76
|
-
STARTF_USESIZE = 0x00000002,
|
77
|
-
STARTF_USEPOSITION = 0x00000004,
|
78
|
-
STARTF_USECOUNTCHARS = 0x00000008,
|
79
|
-
STARTF_USEFILLATTRIBUTE = 0x00000010,
|
80
|
-
STARTF_RUNFULLSCREEN = 0x00000020, // ignored for non-x86 platforms
|
81
|
-
STARTF_FORCEONFEEDBACK = 0x00000040,
|
82
|
-
STARTF_FORCEOFFFEEDBACK = 0x00000080,
|
83
|
-
STARTF_USESTDHANDLES = 0x00000100,
|
84
|
-
}
|
85
|
-
|
86
|
-
public enum ShowWindow : short
|
87
|
-
{
|
88
|
-
SW_HIDE = 0,
|
89
|
-
SW_SHOWNORMAL = 1,
|
90
|
-
SW_NORMAL = 1,
|
91
|
-
SW_SHOWMINIMIZED = 2,
|
92
|
-
SW_SHOWMAXIMIZED = 3,
|
93
|
-
SW_MAXIMIZE = 3,
|
94
|
-
SW_SHOWNOACTIVATE = 4,
|
95
|
-
SW_SHOW = 5,
|
96
|
-
SW_MINIMIZE = 6,
|
97
|
-
SW_SHOWMINNOACTIVE = 7,
|
98
|
-
SW_SHOWNA = 8,
|
99
|
-
SW_RESTORE = 9,
|
100
|
-
SW_SHOWDEFAULT = 10,
|
101
|
-
SW_FORCEMINIMIZE = 11,
|
102
|
-
SW_MAX = 11
|
103
|
-
}
|
104
|
-
|
105
|
-
public enum StandardHandle : int
|
106
|
-
{
|
107
|
-
Input = -10,
|
108
|
-
Output = -11,
|
109
|
-
Error = -12
|
110
|
-
}
|
111
|
-
|
112
|
-
public enum HandleFlags : int
|
113
|
-
{
|
114
|
-
HANDLE_FLAG_INHERIT = 0x00000001,
|
115
|
-
HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002
|
116
|
-
}
|
117
|
-
|
118
|
-
public static class Kernel32
|
119
|
-
{
|
120
|
-
[DllImport("kernel32.dll", SetLastError=true)]
|
121
|
-
[return: MarshalAs(UnmanagedType.Bool)]
|
122
|
-
public static extern bool CreateProcess(
|
123
|
-
string lpApplicationName,
|
124
|
-
string lpCommandLine,
|
125
|
-
ref SECURITY_ATTRIBUTES lpProcessAttributes,
|
126
|
-
ref SECURITY_ATTRIBUTES lpThreadAttributes,
|
127
|
-
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandles,
|
128
|
-
CreationFlags dwCreationFlags,
|
129
|
-
IntPtr lpEnvironment,
|
130
|
-
string lpCurrentDirectory,
|
131
|
-
ref STARTUPINFO lpStartupInfo,
|
132
|
-
out PROCESS_INFORMATION lpProcessInformation);
|
133
|
-
|
134
|
-
[DllImport("kernel32.dll", SetLastError=true)]
|
135
|
-
public static extern IntPtr GetStdHandle(
|
136
|
-
StandardHandle nStdHandle);
|
137
|
-
|
138
|
-
[DllImport("kernel32.dll")]
|
139
|
-
public static extern bool SetHandleInformation(
|
140
|
-
IntPtr hObject,
|
141
|
-
int dwMask,
|
142
|
-
uint dwFlags);
|
143
|
-
|
144
|
-
[DllImport("kernel32", SetLastError=true)]
|
145
|
-
[return: MarshalAs(UnmanagedType.Bool)]
|
146
|
-
public static extern bool CloseHandle(
|
147
|
-
IntPtr hObject);
|
148
|
-
|
149
|
-
[DllImport("kernel32", SetLastError=true)]
|
150
|
-
[return: MarshalAs(UnmanagedType.Bool)]
|
151
|
-
public static extern bool GetExitCodeProcess(
|
152
|
-
IntPtr hProcess,
|
153
|
-
out int lpExitCode);
|
154
|
-
|
155
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
156
|
-
public static extern bool CreatePipe(
|
157
|
-
out IntPtr phReadPipe,
|
158
|
-
out IntPtr phWritePipe,
|
159
|
-
IntPtr lpPipeAttributes,
|
160
|
-
uint nSize);
|
161
|
-
|
162
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
163
|
-
public static extern bool ReadFile(
|
164
|
-
IntPtr hFile,
|
165
|
-
[Out] byte[] lpBuffer,
|
166
|
-
uint nNumberOfBytesToRead,
|
167
|
-
ref int lpNumberOfBytesRead,
|
168
|
-
IntPtr lpOverlapped);
|
169
|
-
|
170
|
-
[DllImport("kernel32.dll", SetLastError = true)]
|
171
|
-
public static extern bool PeekNamedPipe(
|
172
|
-
IntPtr handle,
|
173
|
-
byte[] buffer,
|
174
|
-
uint nBufferSize,
|
175
|
-
ref uint bytesRead,
|
176
|
-
ref uint bytesAvail,
|
177
|
-
ref uint BytesLeftThisMessage);
|
178
|
-
|
179
|
-
public const int STILL_ACTIVE = 259;
|
180
|
-
}
|
181
|
-
}
|
182
|
-
"@
|
183
|
-
}
|
184
|
-
|
185
|
-
function Run-ExecutableAndWait($AppPath, $ArgumentString) {
|
186
|
-
# Use the Win32 API to create a new process and wait for it to terminate.
|
187
|
-
$null = Load-Win32Bindings
|
188
|
-
|
189
|
-
$si = New-Object Chef.STARTUPINFO
|
190
|
-
$pi = New-Object Chef.PROCESS_INFORMATION
|
191
|
-
|
192
|
-
$pSec = New-Object Chef.SECURITY_ATTRIBUTES
|
193
|
-
$pSec.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($pSec)
|
194
|
-
$pSec.bInheritHandle = $true
|
195
|
-
$tSec = New-Object Chef.SECURITY_ATTRIBUTES
|
196
|
-
$tSec.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($tSec)
|
197
|
-
$tSec.bInheritHandle = $true
|
198
|
-
|
199
|
-
# Create pipe for process stdout
|
200
|
-
$ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([System.Runtime.InteropServices.Marshal]::SizeOf($si))
|
201
|
-
[System.Runtime.InteropServices.Marshal]::StructureToPtr($pSec, $ptr, $true)
|
202
|
-
$hReadOut = [IntPtr]::Zero
|
203
|
-
$hWriteOut = [IntPtr]::Zero
|
204
|
-
$success = [Chef.Kernel32]::CreatePipe([ref] $hReadOut, [ref] $hWriteOut, $ptr, 0)
|
205
|
-
if (-Not $success) {
|
206
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
207
|
-
throw "Unable to create output pipe. Error code $reason."
|
208
|
-
}
|
209
|
-
$success = [Chef.Kernel32]::SetHandleInformation($hReadOut, [Chef.HandleFlags]::HANDLE_FLAG_INHERIT, 0)
|
210
|
-
if (-Not $success) {
|
211
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
212
|
-
throw "Unable to set output pipe handle information. Error code $reason."
|
213
|
-
}
|
214
|
-
|
215
|
-
$si.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($si)
|
216
|
-
$si.wShowWindow = [Chef.ShowWindow]::SW_SHOW
|
217
|
-
$si.dwFlags = [Chef.STARTF]::STARTF_USESTDHANDLES
|
218
|
-
$si.hStdOutput = $hWriteOut
|
219
|
-
$si.hStdError = $hWriteOut
|
220
|
-
$si.hStdInput = [Chef.Kernel32]::GetStdHandle([Chef.StandardHandle]::Input)
|
221
|
-
|
222
|
-
$success = [Chef.Kernel32]::CreateProcess(
|
223
|
-
$AppPath,
|
224
|
-
$ArgumentString,
|
225
|
-
[ref] $pSec,
|
226
|
-
[ref] $tSec,
|
227
|
-
$true,
|
228
|
-
[Chef.CreationFlags]::NONE,
|
229
|
-
[IntPtr]::Zero,
|
230
|
-
$pwd,
|
231
|
-
[ref] $si,
|
232
|
-
[ref] $pi
|
233
|
-
)
|
234
|
-
if (-Not $success) {
|
235
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
236
|
-
throw "Unable to create process [$ArgumentString]. Error code $reason."
|
237
|
-
}
|
238
|
-
|
239
|
-
$buffer = New-Object byte[] 1024
|
240
|
-
|
241
|
-
# Initialize reference variables
|
242
|
-
$bytesRead = 0
|
243
|
-
$bytesAvailable = 0
|
244
|
-
$bytesLeftThisMsg = 0
|
245
|
-
$global:LASTEXITCODE = [Chef.Kernel32]::STILL_ACTIVE
|
246
|
-
|
247
|
-
$isActive = $true
|
248
|
-
while ($isActive) {
|
249
|
-
$success = [Chef.Kernel32]::GetExitCodeProcess($pi.hProcess, [ref] $global:LASTEXITCODE)
|
250
|
-
if (-Not $success) {
|
251
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
252
|
-
throw "Process exit code unavailable. Error code $reason."
|
253
|
-
}
|
254
|
-
|
255
|
-
$success = [Chef.Kernel32]::PeekNamedPipe(
|
256
|
-
$hReadOut,
|
257
|
-
$null,
|
258
|
-
$buffer.Length,
|
259
|
-
[ref] $bytesRead,
|
260
|
-
[ref] $bytesAvailable,
|
261
|
-
[ref] $bytesLeftThisMsg
|
262
|
-
)
|
263
|
-
if (-Not $success) {
|
264
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
265
|
-
throw "Output pipe unavailable for peeking. Error code $reason."
|
266
|
-
}
|
267
|
-
|
268
|
-
if ($bytesRead -gt 0) {
|
269
|
-
while ([Chef.Kernel32]::ReadFile($hReadOut, $buffer, $buffer.Length, [ref] $bytesRead, 0)) {
|
270
|
-
$output = [Text.Encoding]::UTF8.GetString($buffer, 0, $bytesRead)
|
271
|
-
if ($output) {
|
272
|
-
$output
|
273
|
-
}
|
274
|
-
if ($bytesRead -lt $buffer.Length) {
|
275
|
-
# Partial buffer indicating the end of stream, break out of ReadFile loop
|
276
|
-
# ReadFile will block until:
|
277
|
-
# The number of bytes requested is read.
|
278
|
-
# A write operation completes on the write end of the pipe.
|
279
|
-
# An asynchronous handle is being used and the read is occurring asynchronously.
|
280
|
-
# An error occurs.
|
281
|
-
break
|
282
|
-
}
|
283
|
-
}
|
284
|
-
} else {
|
285
|
-
# For some reason, you can't read from the read-end of the read-pipe before the write end has started
|
286
|
-
# to write. Otherwise the process just blocks forever and never returns from the read. So we peek
|
287
|
-
# at the pipe until there is something. But don't peek too eagerly. This is stupid stupid stupid.
|
288
|
-
# There must be a way to do this without having to peek at a pipe first but I have not found it.
|
289
|
-
#
|
290
|
-
# Note to the future intrepid soul who wants to fix this:
|
291
|
-
# 0) This is related to unreasonable CPU usage by the wrapper PS script on a 1 VCPU VM (either Hyper-V
|
292
|
-
# or VirtualBox) running a consumer Windows SKU (Windows 10 for example...). Test it there.
|
293
|
-
# 1) Maybe this entire script is unnecessary and the bugs mentioned below have been fixed or don't need
|
294
|
-
# to be supported.
|
295
|
-
# 2) The server and consumer windows schedulers have different defaults. I had a hard time reproducing
|
296
|
-
# any issue on a win 2008 on win 2012 server default setup. See the "foreground application scheduler
|
297
|
-
# priority" setting to see if it's relevant.
|
298
|
-
# 3) This entire endeavor is silly anyway - why are we reimplementing process forking all over? Maybe try
|
299
|
-
# to get the folks above to accept patches instead of extending this crazy script.
|
300
|
-
Start-Sleep -s 1
|
301
|
-
# Start-Sleep -m 100
|
302
|
-
}
|
303
|
-
|
304
|
-
if ($global:LASTEXITCODE -ne [Chef.Kernel32]::STILL_ACTIVE) {
|
305
|
-
$isActive = $false
|
306
|
-
}
|
307
|
-
}
|
308
|
-
|
309
|
-
# Cleanup handles
|
310
|
-
$success = [Chef.Kernel32]::CloseHandle($pi.hProcess)
|
311
|
-
if (-Not $success) {
|
312
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
313
|
-
throw "Unable to release process handle. Error code $reason."
|
314
|
-
}
|
315
|
-
$success = [Chef.Kernel32]::CloseHandle($pi.hThread)
|
316
|
-
if (-Not $success) {
|
317
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
318
|
-
throw "Unable to release thread handle. Error code $reason."
|
319
|
-
}
|
320
|
-
$success = [Chef.Kernel32]::CloseHandle($hWriteOut)
|
321
|
-
if (-Not $success) {
|
322
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
323
|
-
throw "Unable to release output write handle. Error code $reason."
|
324
|
-
}
|
325
|
-
$success = [Chef.Kernel32]::CloseHandle($hReadOut)
|
326
|
-
if (-Not $success) {
|
327
|
-
$reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
328
|
-
throw "Unable to release output read handle. Error code $reason."
|
329
|
-
}
|
330
|
-
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptr)
|
331
|
-
}
|
332
|
-
|
333
|
-
function Get-ScriptDirectory {
|
334
|
-
if (!$PSScriptRoot) {
|
335
|
-
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
|
336
|
-
$PSScriptRoot = Split-Path $Invocation.MyCommand.Path
|
337
|
-
}
|
338
|
-
$PSScriptRoot
|
339
|
-
}
|
340
|
-
|
341
|
-
function Run-RubyCommand($command, $argList) {
|
342
|
-
# This method exists to take the given list of arguments and get it past ruby's command-line
|
343
|
-
# interpreter unscathed and untampered. See https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L1582
|
344
|
-
# for a list of transformations that ruby attempts to perform with your command-line arguments
|
345
|
-
# before passing it onto a script. The most important task is to defeat the globbing
|
346
|
-
# and wild-card expansion that ruby performs. Note that ruby does not use MSVCRT's argc/argv
|
347
|
-
# and deliberately reparses the raw command-line instead.
|
348
|
-
#
|
349
|
-
# To stop ruby from interpreting command-line arguments as globs, they need to be enclosed in '
|
350
|
-
# Ruby doesn't allow any escape characters inside '. This unfortunately prevents us from sending
|
351
|
-
# any strings which themselves contain '. Ruby does allow multi-fragment arguments though.
|
352
|
-
# "foo bar"'baz qux'123"foo" is interpreted as 1 argument because there are no un-escaped
|
353
|
-
# whitespace there. The argument would be interpreted as the string "foo barbaz qux123foo".
|
354
|
-
# This lets us escape ' characters by exiting the ' quoted string, injecting a "'" fragment and
|
355
|
-
# then resuming the ' quoted string again.
|
356
|
-
#
|
357
|
-
# In the process of defeating ruby, one must also defeat the helpfulness of powershell.
|
358
|
-
# When arguments come into this method, the standard PS rules for interpreting cmdlet arguments
|
359
|
-
# apply. When using & (call operator) and providing an array of arguments, powershell (verified
|
360
|
-
# on PS 4.0 on Windows Server 2012R2) will not evaluate them but (contrary to documentation),
|
361
|
-
# it will still marginally interpret them. The behavior of PS 5.0 seems to be different but
|
362
|
-
# ignore that for now. If any of the provided arguments has a space in it, powershell checks
|
363
|
-
# the first and last character to ensure that they are " characters (and that's all it checks).
|
364
|
-
# If they are not, it will blindly surround that argument with " characters. It won't do this
|
365
|
-
# operation if no space is present, even if other special characters are present. If it notices
|
366
|
-
# leading and trailing " characters, it won't actually check to see if there are other "
|
367
|
-
# characters in the string. Since PS 5.0 changes this behavior, we could consider using the --%
|
368
|
-
# "stop screwing up my arguments" operator, which is available since PS 3.0. When encountered
|
369
|
-
# --% indicates that the rest of line is to be sent literally... except if the parser encounters
|
370
|
-
# %FOO% cmd style environment variables. Because reasons. And there is no way to escape the
|
371
|
-
# % character in *any* waym shape or form.
|
372
|
-
# https://connect.microsoft.com/PowerShell/feedback/details/376207/executing-commands-which-require-quotes-and-variables-is-practically-impossible
|
373
|
-
#
|
374
|
-
# In case you think that you're either reading this incorrectly or that I'm full of shit, here
|
375
|
-
# are some examples. These use EchoArgs.exe from the PowerShell Community Extensions package.
|
376
|
-
# I have not included the argument parsing output from EchoArgs.exe to prevent confusing you with
|
377
|
-
# more details about MSVCRT's parsing algorithm.
|
378
|
-
#
|
379
|
-
# $x = "foo '' bar `"baz`""
|
380
|
-
# & EchoArgs @($x, $x)
|
381
|
-
# Command line:
|
382
|
-
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" "foo '' bar "baz"" "foo '' bar "baz""
|
383
|
-
#
|
384
|
-
# $x = "abc'123'nospace`"lol`"!!!"
|
385
|
-
# & EchoArgs @($x, $x)
|
386
|
-
# Command line:
|
387
|
-
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" abc'123'nospace"lol"!!! abc'123'nospace"lol"!!!
|
388
|
-
#
|
389
|
-
# $x = "`"`"Look ma! Tonnes of spaces! 'foo' 'bar'`"`""
|
390
|
-
# & EchoArgs @($x, $x)
|
391
|
-
# Command line:
|
392
|
-
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" ""Look ma! Tonnes of spaces! 'foo' 'bar'"" ""Look ma! Tonnes of spaces! 'foo' 'bar'""
|
393
|
-
#
|
394
|
-
# Given all this, we can now device a strategy to work around all these immensely helpful, well
|
395
|
-
# documented and useful tools by looking at each incoming argument, escaping any ' characters
|
396
|
-
# with a '"'"' sequence, surrounding each argument with ' & joining them with a space separating
|
397
|
-
# them.
|
398
|
-
# There is another bug (https://bugs.ruby-lang.org/issues/11142) that causes ruby to mangle any
|
399
|
-
# "" two-character double quote sequence but since we always emit our strings inside ' except for
|
400
|
-
# ' characters, this should be ok. Just remember that an argument '' should get translated to
|
401
|
-
# ''"'"''"'"'' on the command line. If those intervening empty ''s are not present, the presence
|
402
|
-
# of "" will cause ruby to mangle that argument.
|
403
|
-
$transformedList = $argList | foreach { "'" + ( $_ -replace "'","'`"'`"'" ) + "'" }
|
404
|
-
$fortifiedArgString = $transformedList -join ' '
|
405
|
-
|
406
|
-
# Use the correct embedded ruby path. We'll be deployed at a path that looks like
|
407
|
-
# [C:\opscode or some other prefix]\chef\modules\chef
|
408
|
-
$ruby = Join-Path (Get-ScriptDirectory) "..\..\embedded\bin\ruby.exe"
|
409
|
-
$commandPath = Join-Path (Get-ScriptDirectory) "..\..\bin\$command"
|
410
|
-
|
411
|
-
Run-ExecutableAndWait $ruby """$ruby"" '$commandPath' $fortifiedArgString"
|
412
|
-
}
|
413
|
-
|
414
|
-
|
415
|
-
function chef-apply {
|
416
|
-
Run-RubyCommand 'chef-apply' $args
|
417
|
-
}
|
418
|
-
|
419
|
-
function chef-client {
|
420
|
-
Run-RubyCommand 'chef-client' $args
|
421
|
-
}
|
422
|
-
|
423
|
-
function chef-service-manager {
|
424
|
-
Run-RubyCommand 'chef-service-manager' $args
|
425
|
-
}
|
426
|
-
|
427
|
-
function chef-shell {
|
428
|
-
Run-RubyCommand 'chef-shell' $args
|
429
|
-
}
|
430
|
-
|
431
|
-
function chef-solo {
|
432
|
-
Run-RubyCommand 'chef-solo' $args
|
433
|
-
}
|
434
|
-
|
435
|
-
function chef-windows-service {
|
436
|
-
Run-RubyCommand 'chef-windows-service' $args
|
437
|
-
}
|
438
|
-
|
439
|
-
function knife {
|
440
|
-
Run-RubyCommand 'knife' $args
|
441
|
-
}
|
442
|
-
|
443
|
-
Export-ModuleMember -function chef-apply
|
444
|
-
Export-ModuleMember -function chef-client
|
445
|
-
Export-ModuleMember -function chef-service-manager
|
446
|
-
Export-ModuleMember -function chef-shell
|
447
|
-
Export-ModuleMember -function chef-solo
|
448
|
-
Export-ModuleMember -function chef-windows-service
|
449
|
-
Export-ModuleMember -function knife
|
450
|
-
|
451
|
-
# To debug this module, uncomment the line below
|
452
|
-
# Export-ModuleMember -function Run-RubyCommand
|
453
|
-
|
454
|
-
# Then run the following to reload the module. Use puts_argv as a helpful debug executable.
|
455
|
-
# Remove-Module chef
|
456
|
-
# Import-Module chef
|
457
|
-
# "puts ARGV" | Out-File C:\opscode\chef\bin\puts_args -Encoding ASCII
|
458
|
-
# Copy-Item C:\opscode\chef\bin\ohai.bat C:\opscode\chef\bin\puts_args.bat
|
459
|
-
# Run-RubyCommand puts_args 'Here' "are" some '"very interesting"' 'arguments[to]' "`"try out`""
|