chef 15.11.8-universal-mingw32 → 15.12.22-universal-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|