chef 15.11.8-universal-mingw32 → 15.12.22-universal-mingw32
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/Gemfile +2 -3
- data/README.md +3 -3
- data/chef.gemspec +3 -3
- data/distro/powershell/chef/chef.psm1 +3 -3
- data/distro/templates/powershell/chef/chef.psm1.erb +3 -3
- data/lib/chef/application/apply.rb +1 -1
- data/lib/chef/chef_fs/path_utils.rb +3 -3
- data/lib/chef/cookbook/file_system_file_vendor.rb +1 -1
- data/lib/chef/data_bag.rb +2 -2
- data/lib/chef/data_collector/error_handlers.rb +1 -1
- data/lib/chef/deprecated.rb +8 -0
- data/lib/chef/dsl/declare_resource.rb +1 -1
- data/lib/chef/dsl/platform_introspection.rb +2 -0
- data/lib/chef/knife/bootstrap.rb +3 -6
- data/lib/chef/knife/bootstrap/templates/chef-full.erb +9 -9
- data/lib/chef/provider/package/cab.rb +1 -1
- data/lib/chef/provider/package/chocolatey.rb +1 -1
- data/lib/chef/provider/package/msu.rb +1 -0
- data/lib/chef/provider/package/powershell.rb +5 -1
- data/lib/chef/provider/package/snap.rb +96 -27
- data/lib/chef/provider/zypper_repository.rb +30 -10
- data/lib/chef/resource/archive_file.rb +28 -8
- data/lib/chef/resource/cron_access.rb +11 -3
- data/lib/chef/resource/hostname.rb +2 -1
- data/lib/chef/resource/msu_package.rb +5 -0
- data/lib/chef/version.rb +1 -1
- data/spec/functional/resource/msu_package_spec.rb +5 -2
- data/spec/functional/resource/windows_task_spec.rb +8 -8
- data/spec/unit/application_spec.rb +7 -0
- data/spec/unit/data_bag_spec.rb +1 -1
- data/spec/unit/knife/bootstrap_spec.rb +2 -2
- data/spec/unit/mixin/user_context_spec.rb +1 -9
- data/spec/unit/property_spec.rb +1 -1
- data/spec/unit/provider/package/powershell_spec.rb +95 -86
- data/spec/unit/provider/package/snap_spec.rb +1 -1
- data/spec/unit/provider/zypper_repository_spec.rb +75 -25
- data/spec/unit/resource/archive_file_spec.rb +11 -2
- data/spec/unit/resource/msu_package_spec.rb +4 -0
- data/spec/unit/resource/windows_dns_record_spec.rb +3 -3
- data/spec/unit/resource/windows_dns_zone_spec.rb +2 -2
- data/spec/unit/resource/windows_task_spec.rb +1 -1
- data/spec/unit/resource/windows_uac_spec.rb +2 -2
- data/spec/unit/resource/yum_repository_spec.rb +21 -21
- data/spec/unit/resource_spec.rb +1 -1
- data/spec/unit/util/threaded_job_queue_spec.rb +9 -0
- metadata +22 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7d10dc56cf8158118e798321235a2e20cd396d0c271c1d8da451394f99cd5dc
|
4
|
+
data.tar.gz: d8d9d42fdfd9afe9bff18bf6cee3774518ae3633544d7b40dc8179b4bd6aaed7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7dda48107577e29a021c120368b4683a7049660d79df8a2ae45912b198d89ed0c568f80c51cd341dc35aa3801b4319ed568e66f09454f2c903bfc5d4e4100d9
|
7
|
+
data.tar.gz: ecb3de98f0e4a7c8d765a9f3bf2eebe192377120447f467ea541d9c936e284768a2f96d3ccf6fe6e3459ddcd4c66703e1f188647b02723806f3b9e0b6ef977dc
|
data/Gemfile
CHANGED
@@ -22,8 +22,7 @@ end
|
|
22
22
|
|
23
23
|
gem "cheffish", "~> 14"
|
24
24
|
|
25
|
-
|
26
|
-
gem "chef-telemetry", "=1.0.3"
|
25
|
+
gem "chef-telemetry", ">=1.0.8" # 1.0.8 removes the http dep
|
27
26
|
|
28
27
|
group(:omnibus_package) do
|
29
28
|
gem "appbundler"
|
@@ -39,7 +38,7 @@ group(:omnibus_package, :pry) do
|
|
39
38
|
gem "pry"
|
40
39
|
gem "pry-byebug"
|
41
40
|
gem "pry-remote"
|
42
|
-
gem "pry-stack_explorer"
|
41
|
+
gem "pry-stack_explorer", "~> 0.4.0" # pin to allow Ruby 2.5
|
43
42
|
end
|
44
43
|
|
45
44
|
group(:docgen) do
|
data/README.md
CHANGED
@@ -18,7 +18,7 @@ Chef Infra is a configuration management tool designed to bring automation to yo
|
|
18
18
|
|
19
19
|
### Want to try Chef Infra?
|
20
20
|
|
21
|
-
For Chef Infra usage, please refer to
|
21
|
+
For Chef Infra usage, please refer to [Learn Chef](https://learn.chef.io/), our self-paced, entirely free learning platform. Learn Chef also includes module-based training for Chef Infra, as well as Chef Automate, Chef Habitat, and Chef InSpec.
|
22
22
|
|
23
23
|
Other useful resources for Chef Infra users:
|
24
24
|
|
@@ -26,7 +26,7 @@ Other useful resources for Chef Infra users:
|
|
26
26
|
- Source: <https://github.com/chef/chef/tree/master>
|
27
27
|
- Tickets/Issues: <https://github.com/chef/chef/issues>
|
28
28
|
- Slack: [Chef Community Slack](https://community-slack.chef.io/)
|
29
|
-
- Mailing list: <https://discourse.chef.io>
|
29
|
+
- Mailing list/Forum: <https://discourse.chef.io>
|
30
30
|
|
31
31
|
## Reporting Issues
|
32
32
|
|
@@ -46,7 +46,7 @@ We'd love to have your help developing Chef Infra. See our [Contributing Documen
|
|
46
46
|
|
47
47
|
## License and Copyright
|
48
48
|
|
49
|
-
Copyright 2008-
|
49
|
+
Copyright 2008-2020, Chef Software, Inc.
|
50
50
|
|
51
51
|
```
|
52
52
|
Licensed under the Apache License, Version 2.0 (the "License");
|
data/chef.gemspec
CHANGED
@@ -30,16 +30,16 @@ Gem::Specification.new do |s|
|
|
30
30
|
|
31
31
|
s.add_dependency "ffi", "~> 1.9", ">= 1.9.25"
|
32
32
|
s.add_dependency "ffi-yajl", "~> 2.2"
|
33
|
-
s.add_dependency "net-ssh", ">= 4.2", "<
|
33
|
+
s.add_dependency "net-ssh", ">= 4.2", "< 7"
|
34
34
|
s.add_dependency "net-ssh-multi", "~> 1.2", ">= 1.2.1"
|
35
|
-
s.add_dependency "net-sftp", "
|
35
|
+
s.add_dependency "net-sftp", ">= 2.1.2", "< 4.0"
|
36
36
|
s.add_dependency "ed25519", "~> 1.2" # ed25519 ssh key support
|
37
37
|
s.add_dependency "bcrypt_pbkdf", "~> 1.0" # ed25519 ssh key support
|
38
38
|
s.add_dependency "highline", ">= 1.6.9", "< 2"
|
39
39
|
s.add_dependency "tty-screen", "~> 0.6" # knife list
|
40
40
|
s.add_dependency "erubis", "~> 2.7"
|
41
41
|
s.add_dependency "diff-lcs", "~> 1.2", ">= 1.2.4"
|
42
|
-
s.add_dependency "ffi-libarchive"
|
42
|
+
s.add_dependency "ffi-libarchive", "~> 1.0", ">= 1.0.3"
|
43
43
|
s.add_dependency "chef-zero", ">= 14.0.11"
|
44
44
|
|
45
45
|
s.add_dependency "plist", "~> 3.2"
|
@@ -358,7 +358,7 @@ function Run-RubyCommand($command, $argList) {
|
|
358
358
|
# When arguments come into this method, the standard PS rules for interpreting cmdlet arguments
|
359
359
|
# apply. When using & (call operator) and providing an array of arguments, powershell (verified
|
360
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
|
361
|
+
# it will still marginally interpret them. The behavior of PS 5.0 seems to be different but
|
362
362
|
# ignore that for now. If any of the provided arguments has a space in it, powershell checks
|
363
363
|
# the first and last character to ensure that they are " characters (and that's all it checks).
|
364
364
|
# If they are not, it will blindly surround that argument with " characters. It won't do this
|
@@ -381,10 +381,10 @@ function Run-RubyCommand($command, $argList) {
|
|
381
381
|
# Command line:
|
382
382
|
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" "foo '' bar "baz"" "foo '' bar "baz""
|
383
383
|
#
|
384
|
-
# $x = "abc'123'nospace`"
|
384
|
+
# $x = "abc'123'nospace`"lol`"!!!"
|
385
385
|
# & EchoArgs @($x, $x)
|
386
386
|
# Command line:
|
387
|
-
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" abc'123'nospace"
|
387
|
+
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" abc'123'nospace"lol"!!! abc'123'nospace"lol"!!!
|
388
388
|
#
|
389
389
|
# $x = "`"`"Look ma! Tonnes of spaces! 'foo' 'bar'`"`""
|
390
390
|
# & EchoArgs @($x, $x)
|
@@ -358,7 +358,7 @@ function Run-RubyCommand($command, $argList) {
|
|
358
358
|
# When arguments come into this method, the standard PS rules for interpreting cmdlet arguments
|
359
359
|
# apply. When using & (call operator) and providing an array of arguments, powershell (verified
|
360
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
|
361
|
+
# it will still marginally interpret them. The behavior of PS 5.0 seems to be different but
|
362
362
|
# ignore that for now. If any of the provided arguments has a space in it, powershell checks
|
363
363
|
# the first and last character to ensure that they are " characters (and that's all it checks).
|
364
364
|
# If they are not, it will blindly surround that argument with " characters. It won't do this
|
@@ -381,10 +381,10 @@ function Run-RubyCommand($command, $argList) {
|
|
381
381
|
# Command line:
|
382
382
|
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" "foo '' bar "baz"" "foo '' bar "baz""
|
383
383
|
#
|
384
|
-
# $x = "abc'123'nospace`"
|
384
|
+
# $x = "abc'123'nospace`"lol`"!!!"
|
385
385
|
# & EchoArgs @($x, $x)
|
386
386
|
# Command line:
|
387
|
-
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" abc'123'nospace"
|
387
|
+
# "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" abc'123'nospace"lol"!!! abc'123'nospace"lol"!!!
|
388
388
|
#
|
389
389
|
# $x = "`"`"Look ma! Tonnes of spaces! 'foo' 'bar'`"`""
|
390
390
|
# & EchoArgs @($x, $x)
|
@@ -71,9 +71,9 @@ class Chef
|
|
71
71
|
# part that actually exists. The paths operated on here are not Chef-FS paths.
|
72
72
|
# These are OS paths that may contain symlinks but may not also fully exist.
|
73
73
|
#
|
74
|
-
# If /x is a symlink to /
|
75
|
-
# PathUtils.realest_path('/x/y/z') == '/
|
76
|
-
# PathUtils.realest_path('/x/*/z') == '/
|
74
|
+
# If /x is a symlink to /foo_bar, and has no subdirectories, then:
|
75
|
+
# PathUtils.realest_path('/x/y/z') == '/foo_bar/y/z'
|
76
|
+
# PathUtils.realest_path('/x/*/z') == '/foo_bar/*/z'
|
77
77
|
# PathUtils.realest_path('/*/y/z') == '/*/y/z'
|
78
78
|
#
|
79
79
|
# TODO: Move this to wherever util/path_helper is these days.
|
@@ -27,7 +27,7 @@ class Chef
|
|
27
27
|
# and throws the rest away then re-builds the list of files on the
|
28
28
|
# disk. This is due to the manifest not having the on-disk file
|
29
29
|
# locations, since in the chef-client case, that information is
|
30
|
-
#
|
30
|
+
# nonsensical.
|
31
31
|
class FileSystemFileVendor < FileVendor
|
32
32
|
|
33
33
|
attr_reader :cookbook_name
|
data/lib/chef/data_bag.rb
CHANGED
@@ -94,7 +94,7 @@ class Chef
|
|
94
94
|
names = []
|
95
95
|
paths.each do |path|
|
96
96
|
unless File.directory?(path)
|
97
|
-
raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}'
|
97
|
+
raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}' not found. Please create this directory."
|
98
98
|
end
|
99
99
|
|
100
100
|
names += Dir.glob(File.join(
|
@@ -122,7 +122,7 @@ class Chef
|
|
122
122
|
data_bag = {}
|
123
123
|
paths.each do |path|
|
124
124
|
unless File.directory?(path)
|
125
|
-
raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}'
|
125
|
+
raise Chef::Exceptions::InvalidDataBagPath, "Data bag path '#{path}' not found. Please create this directory."
|
126
126
|
end
|
127
127
|
|
128
128
|
Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(path, name.to_s), "*.json")).inject({}) do |bag, f|
|
@@ -18,7 +18,7 @@
|
|
18
18
|
class Chef
|
19
19
|
class DataCollector
|
20
20
|
|
21
|
-
# This module isolates the handling of collecting error descriptions to insert into the
|
21
|
+
# This module isolates the handling of collecting error descriptions to insert into the data_collector
|
22
22
|
# report output. For very early errors it is responsible for collecting the node_name for the report
|
23
23
|
# to use. For all failure conditions that have an ErrorMapper it collects the output.
|
24
24
|
#
|
data/lib/chef/deprecated.rb
CHANGED
@@ -233,6 +233,14 @@ class Chef
|
|
233
233
|
target 28
|
234
234
|
end
|
235
235
|
|
236
|
+
class KnifeBootstrapApis < Base
|
237
|
+
target 29
|
238
|
+
end
|
239
|
+
|
240
|
+
class ArchiveFileIntegerFileMode < Base
|
241
|
+
target 30
|
242
|
+
end
|
243
|
+
|
236
244
|
class Generic < Base
|
237
245
|
def url
|
238
246
|
"https://docs.chef.io/chef_deprecations_client/"
|
@@ -151,7 +151,7 @@ class Chef
|
|
151
151
|
# source "y.txt.erb"
|
152
152
|
# variables {}
|
153
153
|
# end
|
154
|
-
# resource.variables.merge!({ home: "/home/
|
154
|
+
# resource.variables.merge!({ home: "/home/clowns" })
|
155
155
|
#
|
156
156
|
def edit_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block)
|
157
157
|
edit_resource!(type, name, created_at: created_at, run_context: run_context, &resource_attrs_block)
|
@@ -248,6 +248,8 @@ class Chef
|
|
248
248
|
end
|
249
249
|
|
250
250
|
# a simple helper to determine if we're on a windows release pre-2012 / 8
|
251
|
+
#
|
252
|
+
# @deprecated Windows releases before Windows 2012 and 8 are no longer supported
|
251
253
|
# @return [Boolean] Is the system older than Windows 8 / 2012
|
252
254
|
def older_than_win_2012_or_8?(node = run_context.nil? ? nil : run_context.node)
|
253
255
|
node["platform_version"].to_f < 6.2
|
data/lib/chef/knife/bootstrap.rb
CHANGED
@@ -597,11 +597,8 @@ class Chef
|
|
597
597
|
|
598
598
|
bootstrap_context.client_pem = client_builder.client_path
|
599
599
|
else
|
600
|
-
ui.
|
601
|
-
|
602
|
-
Delete your validation key in order to use your user credentials for client registration instead.
|
603
|
-
EOM
|
604
|
-
|
600
|
+
ui.warn "Performing legacy client registration with the validation key at #{Chef::Config[:validation_key]}..."
|
601
|
+
ui.warn "Remove the key file or remove the 'validation_key' configuration option from your config.rb (knife.rb) to use more secure user credentials for client registration."
|
605
602
|
end
|
606
603
|
end
|
607
604
|
|
@@ -619,7 +616,7 @@ class Chef
|
|
619
616
|
end
|
620
617
|
|
621
618
|
def connect!
|
622
|
-
ui.info("Connecting to #{ui.color(server_name, :bold)}")
|
619
|
+
ui.info("Connecting to #{ui.color(server_name, :bold)} using #{connection_protocol}")
|
623
620
|
opts ||= connection_opts.dup
|
624
621
|
do_connect(opts)
|
625
622
|
rescue Train::Error => e
|
@@ -185,50 +185,50 @@ if test "x$tmp_dir" != "x"; then
|
|
185
185
|
rm -r "$tmp_dir"
|
186
186
|
fi
|
187
187
|
|
188
|
-
mkdir -p
|
188
|
+
mkdir -p /etc/chef
|
189
189
|
|
190
190
|
<% if client_pem -%>
|
191
|
-
(umask 077 && (cat >
|
191
|
+
(umask 077 && (cat > /etc/chef/client.pem <<'EOP'
|
192
192
|
<%= ::File.read(::File.expand_path(client_pem)) %>
|
193
193
|
EOP
|
194
194
|
)) || exit 1
|
195
195
|
<% end -%>
|
196
196
|
|
197
197
|
<% if validation_key -%>
|
198
|
-
(umask 077 && (cat >
|
198
|
+
(umask 077 && (cat > /etc/chef/validation.pem <<'EOP'
|
199
199
|
<%= validation_key %>
|
200
200
|
EOP
|
201
201
|
)) || exit 1
|
202
202
|
<% end -%>
|
203
203
|
|
204
204
|
<% if encrypted_data_bag_secret -%>
|
205
|
-
(umask 077 && (cat >
|
205
|
+
(umask 077 && (cat > /etc/chef/encrypted_data_bag_secret <<'EOP'
|
206
206
|
<%= encrypted_data_bag_secret %>
|
207
207
|
EOP
|
208
208
|
)) || exit 1
|
209
209
|
<% end -%>
|
210
210
|
|
211
211
|
<% unless trusted_certs.empty? -%>
|
212
|
-
mkdir -p
|
212
|
+
mkdir -p /etc/chef/trusted_certs
|
213
213
|
<%= trusted_certs %>
|
214
214
|
<% end -%>
|
215
215
|
|
216
216
|
<%# Generate Ohai Hints -%>
|
217
217
|
<% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
|
218
|
-
mkdir -p
|
218
|
+
mkdir -p /etc/chef/ohai/hints
|
219
219
|
|
220
220
|
<% @chef_config[:knife][:hints].each do |name, hash| -%>
|
221
|
-
cat >
|
221
|
+
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
|
222
222
|
<%= Chef::JSONCompat.to_json(hash) %>
|
223
223
|
EOP
|
224
224
|
<% end -%>
|
225
225
|
<% end -%>
|
226
226
|
|
227
|
-
cat >
|
227
|
+
cat > /etc/chef/client.rb <<'EOP'
|
228
228
|
<%= config_content %>
|
229
229
|
EOP
|
230
230
|
|
231
|
-
cat >
|
231
|
+
cat > /etc/chef/first-boot.json <<'EOP'
|
232
232
|
<%= Chef::JSONCompat.to_json(first_boot) %>
|
233
233
|
EOP
|
234
234
|
|
@@ -94,7 +94,7 @@ class Chef
|
|
94
94
|
split_package_identity(p["package_identity"])
|
95
95
|
end
|
96
96
|
found_packages = existing_package_identities.select do |existing_package_ident|
|
97
|
-
existing_package_ident["name"] == package["name"]
|
97
|
+
existing_package_ident["version"] == package["version"].chomp && existing_package_ident["name"] == package["name"]
|
98
98
|
end
|
99
99
|
if found_packages.empty?
|
100
100
|
nil
|
@@ -251,7 +251,7 @@ class Chef
|
|
251
251
|
end
|
252
252
|
|
253
253
|
# Helper to convert choco.exe list output to a Hash
|
254
|
-
# (names are downcased for case-
|
254
|
+
# (names are downcased for case-insensitive matching)
|
255
255
|
#
|
256
256
|
# @param cmd [String] command to run
|
257
257
|
# @return [Hash] list output converted to ruby Hash
|
@@ -53,6 +53,9 @@ class Chef
|
|
53
53
|
|
54
54
|
# Installs the package specified with the version passed else latest version will be installed
|
55
55
|
def install_package(names, versions)
|
56
|
+
# To enable tls 1.2, which is disabled by default in some OS
|
57
|
+
powershell_out("[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12")
|
58
|
+
|
56
59
|
names.each_with_index do |name, index|
|
57
60
|
cmd = powershell_out(build_powershell_package_command("Install-Package '#{name}'", versions[index]), timeout: new_resource.timeout)
|
58
61
|
next if cmd.nil?
|
@@ -115,7 +118,8 @@ class Chef
|
|
115
118
|
command = [command] unless command.is_a?(Array)
|
116
119
|
cmdlet_name = command.first
|
117
120
|
command.unshift("(")
|
118
|
-
|
121
|
+
# -WarningAction SilentlyContinue is used to suppress the warnings from stdout
|
122
|
+
%w{-Force -ForceBootstrap -WarningAction SilentlyContinue}.each do |arg|
|
119
123
|
command.push(arg)
|
120
124
|
end
|
121
125
|
command.push("-RequiredVersion #{version}") if version
|
@@ -59,15 +59,14 @@ class Chef
|
|
59
59
|
def get_current_versions
|
60
60
|
package_name_array.each_with_index.map do |pkg, i|
|
61
61
|
installed_version(i)
|
62
|
-
end
|
62
|
+
end.compact
|
63
63
|
end
|
64
64
|
|
65
65
|
def install_package(names, versions)
|
66
66
|
if new_resource.source
|
67
67
|
install_snap_from_source(names, new_resource.source)
|
68
68
|
else
|
69
|
-
|
70
|
-
install_snaps(resolved_names)
|
69
|
+
install_snaps(names)
|
71
70
|
end
|
72
71
|
end
|
73
72
|
|
@@ -75,14 +74,16 @@ class Chef
|
|
75
74
|
if new_resource.source
|
76
75
|
install_snap_from_source(names, new_resource.source)
|
77
76
|
else
|
78
|
-
|
79
|
-
|
77
|
+
if get_current_versions.empty?
|
78
|
+
install_snaps(names, versions)
|
79
|
+
else
|
80
|
+
update_snaps(names)
|
81
|
+
end
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
83
85
|
def remove_package(names, versions)
|
84
|
-
|
85
|
-
uninstall_snaps(resolved_names)
|
86
|
+
uninstall_snaps(names)
|
86
87
|
end
|
87
88
|
|
88
89
|
alias purge_package remove_package
|
@@ -129,19 +130,73 @@ class Chef
|
|
129
130
|
"Accept: application/json\r\n" +
|
130
131
|
"Content-Type: application/json\r\n"
|
131
132
|
if method == "POST"
|
132
|
-
|
133
|
+
pdata = post_data.to_json.to_s
|
134
|
+
request.concat("Content-Length: #{pdata.bytesize}\r\n\r\n#{pdata}")
|
133
135
|
end
|
134
136
|
request.concat("\r\n")
|
135
|
-
|
136
|
-
#
|
137
|
-
#
|
137
|
+
|
138
|
+
# while it is expected to allow clients to connect using https over
|
139
|
+
# a tcp socket, at this point only a unix socket is supported. the
|
140
|
+
# socket is /run/snapd.socket note - unixsocket is not defined on
|
141
|
+
# windows systems
|
138
142
|
if defined?(::UNIXSocket)
|
139
143
|
UNIXSocket.open("/run/snapd.socket") do |socket|
|
140
|
-
#
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
144
|
+
# send request, read the response, split the response and parse
|
145
|
+
# the body
|
146
|
+
socket.write(request)
|
147
|
+
|
148
|
+
# WARNING!!! HERE BE DRAGONs
|
149
|
+
#
|
150
|
+
# So snapd doesn't return an EOF at the end of its body, so
|
151
|
+
# doing a normal read will just hang forever.
|
152
|
+
#
|
153
|
+
# Well, sort of. if, after it writes everything, you then send
|
154
|
+
# yet-another newline, it'll then send its EOF and promptly
|
155
|
+
# disconnect closing the pipe and preventing reading. so, you
|
156
|
+
# have to read first, and therein lies the EOF problem.
|
157
|
+
#
|
158
|
+
# So you can do non-blocking reads with selects, but it
|
159
|
+
# makes every read take about 5 seconds. If, instead, we
|
160
|
+
# read the last line char-by-char, it's about half a second.
|
161
|
+
#
|
162
|
+
# Reading a character at a time isn't efficient, and since we
|
163
|
+
# know that http headers always have a blank line after them,
|
164
|
+
# we can read lines until we find a blank line and *then* read
|
165
|
+
# a character at a time. snap returns all the json on a single
|
166
|
+
# line, so once you pass headers you must read a character a
|
167
|
+
# time.
|
168
|
+
#
|
169
|
+
# - jaymzh
|
170
|
+
|
171
|
+
Chef::Log.trace(
|
172
|
+
"snap_package[#{new_resource.package_name}]: reading headers"
|
173
|
+
)
|
174
|
+
loop do
|
175
|
+
response = socket.readline
|
176
|
+
break if response.strip.empty? # finished headers
|
177
|
+
end
|
178
|
+
Chef::Log.trace(
|
179
|
+
"snap_package[#{new_resource.package_name}]: past headers, " +
|
180
|
+
"onto the body..."
|
181
|
+
)
|
182
|
+
result = nil
|
183
|
+
body = ""
|
184
|
+
socket.each_char do |c|
|
185
|
+
body << c
|
186
|
+
# we know we're not done if we don't have a char that
|
187
|
+
# can end JSON
|
188
|
+
next unless ["}", "]"].include?(c)
|
189
|
+
|
190
|
+
begin
|
191
|
+
result = JSON.parse(body)
|
192
|
+
# if we get here, we were able to parse the json so we
|
193
|
+
# are done reading
|
194
|
+
break
|
195
|
+
rescue JSON::ParserError
|
196
|
+
next
|
197
|
+
end
|
198
|
+
end
|
199
|
+
result
|
145
200
|
end
|
146
201
|
end
|
147
202
|
end
|
@@ -211,20 +266,22 @@ class Chef
|
|
211
266
|
response.error!
|
212
267
|
end
|
213
268
|
|
214
|
-
def install_snaps(snap_names)
|
215
|
-
|
216
|
-
|
217
|
-
|
269
|
+
def install_snaps(snap_names, versions)
|
270
|
+
snap_names.each do |snap|
|
271
|
+
response = post_snap(snap, "install", new_resource.channel, new_resource.options)
|
272
|
+
id = get_id_from_async_response(response)
|
273
|
+
wait_for_completion(id)
|
274
|
+
end
|
218
275
|
end
|
219
276
|
|
220
277
|
def update_snaps(snap_names)
|
221
|
-
response = post_snaps(snap_names, "refresh",
|
278
|
+
response = post_snaps(snap_names, "refresh", nil, new_resource.options)
|
222
279
|
id = get_id_from_async_response(response)
|
223
280
|
wait_for_completion(id)
|
224
281
|
end
|
225
282
|
|
226
283
|
def uninstall_snaps(snap_names)
|
227
|
-
response = post_snaps(snap_names, "remove",
|
284
|
+
response = post_snaps(snap_names, "remove", nil, new_resource.options)
|
228
285
|
id = get_id_from_async_response(response)
|
229
286
|
wait_for_completion(id)
|
230
287
|
end
|
@@ -278,18 +335,20 @@ class Chef
|
|
278
335
|
"action" => action,
|
279
336
|
"snaps" => snap_names,
|
280
337
|
}
|
281
|
-
if %w{install refresh switch}.include?(action)
|
338
|
+
if %w{install refresh switch}.include?(action) && channel
|
282
339
|
request["channel"] = channel
|
283
340
|
end
|
284
341
|
|
285
342
|
# No defensive handling of params
|
286
343
|
# Snap will throw the proper exception if called improperly
|
287
344
|
# And we can provide that exception to the end user
|
288
|
-
|
289
|
-
|
290
|
-
|
345
|
+
if options
|
346
|
+
request["classic"] = true if options.include?("classic")
|
347
|
+
request["devmode"] = true if options.include?("devmode")
|
348
|
+
request["jailmode"] = true if options.include?("jailmode")
|
349
|
+
request["ignore_validation"] = true if options.include?("ignore-validation")
|
350
|
+
end
|
291
351
|
request["revision"] = revision unless revision.nil?
|
292
|
-
request["ignore_validation"] = true if options["ignore-validation"]
|
293
352
|
request
|
294
353
|
end
|
295
354
|
|
@@ -305,12 +364,22 @@ class Chef
|
|
305
364
|
call_snap_api("POST", "/v2/snaps", json)
|
306
365
|
end
|
307
366
|
|
367
|
+
def post_snap(snap_name, action, channel, options, revision = nil)
|
368
|
+
json = generate_snap_json(snap_name, action, channel, options, revision = nil)
|
369
|
+
json.delete("snaps")
|
370
|
+
call_snap_api("POST", "/v2/snaps/#{snap_name}", json)
|
371
|
+
end
|
372
|
+
|
308
373
|
def get_latest_package_version(name, channel)
|
309
374
|
json = call_snap_api("GET", "/v2/find?name=#{name}")
|
310
375
|
if json["status-code"] != 200
|
311
376
|
raise Chef::Exceptions::Package, json["result"], caller
|
312
377
|
end
|
313
378
|
|
379
|
+
unless json["result"][0]["channels"]["latest/#{channel}"]
|
380
|
+
raise Chef::Exceptions::Package, "No version of #{name} in channel #{channel}", caller
|
381
|
+
end
|
382
|
+
|
314
383
|
# Return the version matching the channel
|
315
384
|
json["result"][0]["channels"]["latest/#{channel}"]["version"]
|
316
385
|
end
|