license-acceptance 1.0.5 → 2.1.13
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 +17 -1
- data/config/product_info.toml +23 -1
- data/lib/license_acceptance/acceptor.rb +54 -37
- data/lib/license_acceptance/cli_flags/mixlib_cli.rb +2 -2
- data/lib/license_acceptance/cli_flags/thor.rb +3 -3
- data/lib/license_acceptance/config.rb +6 -4
- data/lib/license_acceptance/logger.rb +1 -1
- data/lib/license_acceptance/product.rb +8 -6
- data/lib/license_acceptance/product_reader.rb +11 -7
- data/lib/license_acceptance/strategy/argument.rb +17 -16
- data/lib/license_acceptance/strategy/environment.rb +11 -10
- data/lib/license_acceptance/strategy/file.rb +10 -12
- data/lib/license_acceptance/strategy/prompt.rb +26 -26
- data/lib/license_acceptance/strategy/provided_value.rb +8 -5
- data/lib/license_acceptance/version.rb +1 -1
- metadata +14 -134
- data/Gemfile.lock +0 -94
- data/Rakefile +0 -6
- data/spec/license_acceptance/acceptor_spec.rb +0 -293
- data/spec/license_acceptance/cli_flags/mixlib_cli_spec.rb +0 -14
- data/spec/license_acceptance/cli_flags/thor_spec.rb +0 -14
- data/spec/license_acceptance/config_spec.rb +0 -111
- data/spec/license_acceptance/product_reader_spec.rb +0 -155
- data/spec/license_acceptance/product_spec.rb +0 -15
- data/spec/license_acceptance/strategy/argument_spec.rb +0 -82
- data/spec/license_acceptance/strategy/environment_spec.rb +0 -76
- data/spec/license_acceptance/strategy/file_spec.rb +0 -127
- data/spec/license_acceptance/strategy/prompt_spec.rb +0 -100
- data/spec/license_acceptance/strategy/provided_value_spec.rb +0 -55
- data/spec/spec_helper.rb +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19afa6b91e05cf1154cfff732b5f3087c3596a82ed06396519479e3dc1382013
|
|
4
|
+
data.tar.gz: 5ce668d4c66b2760304b5a29fba485a71be8c9001666e8df1d822b768adfcdc5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b021343e3b27845e52f9e747919441bf6770bcc118f215b0dbbe34db1b59e7a42bef47da0202db8b4eec0fe237415a0426d343d395d9691f72fdf1dd3949742a
|
|
7
|
+
data.tar.gz: 597052f9ac8275ffd6d33cf80a2ae14aa1db7d1a6976800ee330e02d343a9df6b27df7f033cc566e64a13921f9dcbc73d36dc2bc21b7880532565d09446391eb
|
data/Gemfile
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
source "https://rubygems.org"
|
|
2
2
|
|
|
3
|
-
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
4
4
|
|
|
5
5
|
# Specify your gem's dependencies in license-acceptance.gemspec
|
|
6
6
|
gemspec
|
|
7
|
+
|
|
8
|
+
group :development do
|
|
9
|
+
gem "chefstyle", "1.5.7"
|
|
10
|
+
gem "climate_control", "~> 0.2"
|
|
11
|
+
gem "mixlib-cli", "~> 2.1"
|
|
12
|
+
gem "rake", ">= 10.1.0"
|
|
13
|
+
gem "rspec", "~> 3.0"
|
|
14
|
+
gem "thor", ">= 0.20", "< 2.0" # validate 2.0 when it ships
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
group :debug do
|
|
18
|
+
gem "pry"
|
|
19
|
+
gem "pry-byebug"
|
|
20
|
+
gem "pry-stack_explorer", "~> 0.4.0" # pin until we drop ruby < 2.6
|
|
21
|
+
gem "rb-readline"
|
|
22
|
+
end
|
data/config/product_info.toml
CHANGED
|
@@ -31,7 +31,29 @@ id = "push-jobs-server"
|
|
|
31
31
|
pretty_name = "Chef Push Jobs Server"
|
|
32
32
|
filename = "push_jobs_server"
|
|
33
33
|
|
|
34
|
+
[[products]]
|
|
35
|
+
id = "push-jobs-client"
|
|
36
|
+
pretty_name = "Chef Push Jobs Client"
|
|
37
|
+
filename = "push_jobs_client"
|
|
38
|
+
|
|
39
|
+
[[products]]
|
|
40
|
+
id = "chef-dk"
|
|
41
|
+
pretty_name = "Chef Development Kit"
|
|
42
|
+
filename = "chef_dk"
|
|
43
|
+
mixlib_name = "chefdk"
|
|
44
|
+
license_required_version = "4"
|
|
45
|
+
|
|
46
|
+
[[products]]
|
|
47
|
+
id = "chef-workstation"
|
|
48
|
+
pretty_name = "Chef Workstation"
|
|
49
|
+
filename = "chef_workstation"
|
|
50
|
+
mixlib_name = "chef-workstation"
|
|
51
|
+
license_required_version = "0.4"
|
|
52
|
+
|
|
34
53
|
[relationships]
|
|
35
54
|
"infra-client" = ["inspec"]
|
|
36
|
-
"infra-server" = ["infra-client"]
|
|
55
|
+
"infra-server" = ["infra-client", "inspec"]
|
|
37
56
|
"push-jobs-server" = ["infra-client", "infra-server"]
|
|
57
|
+
"push-jobs-client" = ["infra-client"]
|
|
58
|
+
"chef-dk" = ["infra-client", "inspec"]
|
|
59
|
+
"chef-workstation" = ["infra-client", "inspec"]
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
require "forwardable"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
require "forwardable" unless defined?(Forwardable)
|
|
2
|
+
require_relative "config"
|
|
3
|
+
require_relative "logger"
|
|
4
|
+
require_relative "product_reader"
|
|
5
|
+
require_relative "product_relationship"
|
|
6
|
+
require_relative "strategy/environment"
|
|
7
|
+
require_relative "strategy/file"
|
|
8
|
+
require_relative "strategy/argument"
|
|
9
|
+
require_relative "strategy/prompt"
|
|
10
|
+
require_relative "strategy/provided_value"
|
|
11
11
|
|
|
12
12
|
module LicenseAcceptance
|
|
13
13
|
|
|
14
|
-
ACCEPT = "accept"
|
|
15
|
-
ACCEPT_SILENT = "accept-silent"
|
|
16
|
-
ACCEPT_NO_PERSIST = "accept-no-persist"
|
|
14
|
+
ACCEPT = "accept".freeze
|
|
15
|
+
ACCEPT_SILENT = "accept-silent".freeze
|
|
16
|
+
ACCEPT_NO_PERSIST = "accept-no-persist".freeze
|
|
17
17
|
|
|
18
18
|
class Acceptor
|
|
19
19
|
extend Forwardable
|
|
@@ -21,7 +21,7 @@ module LicenseAcceptance
|
|
|
21
21
|
|
|
22
22
|
attr_reader :config, :product_reader, :env_strategy, :file_strategy, :arg_strategy, :prompt_strategy, :provided_strategy
|
|
23
23
|
|
|
24
|
-
def initialize(opts={})
|
|
24
|
+
def initialize(opts = {})
|
|
25
25
|
@config = Config.new(opts)
|
|
26
26
|
Logger.initialize(config.logger)
|
|
27
27
|
@product_reader = ProductReader.new
|
|
@@ -75,36 +75,48 @@ module LicenseAcceptance
|
|
|
75
75
|
end
|
|
76
76
|
@acceptance_value = accepted_silent? ? ACCEPT_SILENT : ACCEPT
|
|
77
77
|
return true
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
else
|
|
84
|
-
@acceptance_value = ACCEPT_NO_PERSIST
|
|
85
|
-
[]
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
return true
|
|
89
|
-
else
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if acceptance_value_provided?
|
|
81
|
+
value = provided_strategy.value || env_strategy.value || arg_strategy.value
|
|
82
|
+
output.puts("Unrecognized license acceptance value '#{value}', expected one of: '#{ACCEPT}', '#{ACCEPT_SILENT}', '#{ACCEPT_NO_PERSIST}'")
|
|
90
83
|
raise LicenseNotAcceptedError.new(product_relationship.parent, missing_licenses)
|
|
91
84
|
end
|
|
85
|
+
|
|
86
|
+
return true if output.isatty && accepted_license_prompt?(product_relationship, missing_licenses)
|
|
87
|
+
|
|
88
|
+
raise LicenseNotAcceptedError.new(product_relationship.parent, missing_licenses)
|
|
92
89
|
end
|
|
93
90
|
|
|
94
|
-
def self.check_and_persist!(product_id, version, opts={})
|
|
91
|
+
def self.check_and_persist!(product_id, version, opts = {})
|
|
95
92
|
new(opts).check_and_persist!(product_id, version)
|
|
96
93
|
end
|
|
97
94
|
|
|
98
|
-
def self.check_and_persist(product_id, version, opts={})
|
|
95
|
+
def self.check_and_persist(product_id, version, opts = {})
|
|
99
96
|
new(opts).check_and_persist(product_id, version)
|
|
100
97
|
end
|
|
101
98
|
|
|
99
|
+
def accepted_license_prompt?(product_relationship, missing_licenses)
|
|
100
|
+
prompt_strategy.request(missing_licenses) do
|
|
101
|
+
# We have to infer the acceptance value if they use the prompt to accept
|
|
102
|
+
if config.persist
|
|
103
|
+
@acceptance_value = ACCEPT
|
|
104
|
+
file_strategy.persist(product_relationship, missing_licenses)
|
|
105
|
+
else
|
|
106
|
+
@acceptance_value = ACCEPT_NO_PERSIST
|
|
107
|
+
[]
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
102
112
|
# Check whether the specified product requires license acceptance for the given version.
|
|
103
113
|
def license_required?(mixlib_name, version)
|
|
104
114
|
product = product_reader.lookup_by_mixlib(mixlib_name)
|
|
105
115
|
return false if product.nil?
|
|
106
116
|
# If they don't pass a version we assume they want latest
|
|
107
|
-
|
|
117
|
+
# All versions in all channels require license acceptance
|
|
118
|
+
return true if %w{latest unstable current stable}.include?(version.to_s) || version.nil?
|
|
119
|
+
|
|
108
120
|
Gem::Version.new(version) >= Gem::Version.new(product.license_required_version)
|
|
109
121
|
end
|
|
110
122
|
|
|
@@ -113,6 +125,7 @@ module LicenseAcceptance
|
|
|
113
125
|
def id_from_mixlib(mixlib_name)
|
|
114
126
|
product = product_reader.lookup_by_mixlib(mixlib_name)
|
|
115
127
|
return nil if product.nil?
|
|
128
|
+
|
|
116
129
|
product.id
|
|
117
130
|
end
|
|
118
131
|
|
|
@@ -137,23 +150,27 @@ module LicenseAcceptance
|
|
|
137
150
|
provided_strategy.silent? || env_strategy.silent? || arg_strategy.silent?
|
|
138
151
|
end
|
|
139
152
|
|
|
153
|
+
def acceptance_value_provided?
|
|
154
|
+
provided_strategy.value? || env_strategy.value? || arg_strategy.value?
|
|
155
|
+
end
|
|
156
|
+
|
|
140
157
|
# In the case where users accept with a command line argument or environment variable
|
|
141
158
|
# we still want to output the fact that the filesystem was changed.
|
|
142
159
|
def output_num_persisted(count)
|
|
143
|
-
s = count > 1 ? "s": ""
|
|
160
|
+
s = count > 1 ? "s" : ""
|
|
144
161
|
output.puts <<~EOM
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
162
|
+
#{Strategy::Prompt::BORDER}
|
|
163
|
+
#{Strategy::Prompt::CHECK} #{count} product license#{s} accepted.
|
|
164
|
+
#{Strategy::Prompt::BORDER}
|
|
148
165
|
EOM
|
|
149
166
|
end
|
|
150
167
|
|
|
151
168
|
def output_persist_failed(errs)
|
|
152
169
|
output.puts <<~EOM
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
170
|
+
#{Strategy::Prompt::BORDER}
|
|
171
|
+
#{Strategy::Prompt::CHECK} Product license accepted.
|
|
172
|
+
Could not persist acceptance:\n\t* #{errs.map(&:message).join("\n\t* ")}
|
|
173
|
+
#{Strategy::Prompt::BORDER}
|
|
157
174
|
EOM
|
|
158
175
|
end
|
|
159
176
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
begin
|
|
2
|
-
require
|
|
3
|
-
rescue
|
|
2
|
+
require "thor" unless defined?(Thor)
|
|
3
|
+
rescue
|
|
4
4
|
raise "Must have thor gem installed to use this mixin"
|
|
5
5
|
end
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ module LicenseAcceptance
|
|
|
12
12
|
def self.included(klass)
|
|
13
13
|
klass.class_option :chef_license,
|
|
14
14
|
type: :string,
|
|
15
|
-
desc:
|
|
15
|
+
desc: "Accept the license for this product and any contained products: accept, accept-no-persist, accept-silent"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "logger"
|
|
2
2
|
|
|
3
3
|
module LicenseAcceptance
|
|
4
4
|
class Config
|
|
5
5
|
attr_accessor :output, :logger, :license_locations, :persist_location, :persist
|
|
6
6
|
|
|
7
|
-
def initialize(opts={})
|
|
7
|
+
def initialize(opts = {})
|
|
8
8
|
@output = opts.fetch(:output, $stdout)
|
|
9
9
|
@logger = opts.fetch(:logger, ::Logger.new(IO::NULL))
|
|
10
10
|
@license_locations = opts.fetch(:license_locations, default_license_locations)
|
|
@@ -21,7 +21,8 @@ module LicenseAcceptance
|
|
|
21
21
|
|
|
22
22
|
def default_license_locations
|
|
23
23
|
if windows?
|
|
24
|
-
|
|
24
|
+
root = ENV.fetch("SYSTEMDRIVE", "C:")
|
|
25
|
+
l = [ File.join(root, "chef/accepted_licenses/") ]
|
|
25
26
|
unless is_root?
|
|
26
27
|
# Look through a list of possible user locations and pick the first one that exists
|
|
27
28
|
# copied from path_helper.rb in chef-config gem
|
|
@@ -31,6 +32,7 @@ module LicenseAcceptance
|
|
|
31
32
|
possible_dirs << ENV["HOMESHARE"] + ENV["HOMEPATH"] if ENV["HOMESHARE"] && ENV["HOMEPATH"]
|
|
32
33
|
possible_dirs << ENV["USERPROFILE"] if ENV["USERPROFILE"]
|
|
33
34
|
raise NoValidEnvironmentVar if possible_dirs.empty?
|
|
35
|
+
|
|
34
36
|
possible_dirs.each do |possible_dir|
|
|
35
37
|
if Dir.exist?(possible_dir)
|
|
36
38
|
full_possible_dir = File.join(possible_dir, ".chef/accepted_licenses/")
|
|
@@ -41,7 +43,7 @@ module LicenseAcceptance
|
|
|
41
43
|
end
|
|
42
44
|
else
|
|
43
45
|
l = [ "/etc/chef/accepted_licenses/" ]
|
|
44
|
-
l << File.join(ENV[
|
|
46
|
+
l << File.join(ENV["HOME"], ".chef/accepted_licenses/") unless is_root?
|
|
45
47
|
end
|
|
46
48
|
l
|
|
47
49
|
end
|
|
@@ -14,14 +14,16 @@ module LicenseAcceptance
|
|
|
14
14
|
|
|
15
15
|
def ==(other)
|
|
16
16
|
return false if other.class != Product
|
|
17
|
+
|
|
17
18
|
if other.id == id &&
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
other.pretty_name == pretty_name &&
|
|
20
|
+
other.filename == filename &&
|
|
21
|
+
other.mixlib_name == mixlib_name &&
|
|
22
|
+
other.license_required_version == license_required_version
|
|
23
|
+
return true
|
|
23
24
|
end
|
|
24
|
-
|
|
25
|
+
|
|
26
|
+
false
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
autoload :Tomlrb, "tomlrb"
|
|
2
|
+
require_relative "logger"
|
|
3
|
+
require_relative "product"
|
|
4
|
+
require_relative "product_relationship"
|
|
5
5
|
|
|
6
6
|
module LicenseAcceptance
|
|
7
7
|
class ProductReader
|
|
@@ -18,7 +18,7 @@ module LicenseAcceptance
|
|
|
18
18
|
toml = Tomlrb.load_file(location, symbolize_keys: false)
|
|
19
19
|
raise InvalidProductInfo.new(location) if toml.empty? || toml["products"].nil? || toml["relationships"].nil?
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
toml["products"].each do |product|
|
|
22
22
|
products[product["id"]] = Product.new(
|
|
23
23
|
product["id"], product["pretty_name"],
|
|
24
24
|
product["filename"], product["mixlib_name"],
|
|
@@ -26,7 +26,7 @@ module LicenseAcceptance
|
|
|
26
26
|
)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
toml["relationships"].each do |parent_id, children|
|
|
30
30
|
parent = products[parent_id]
|
|
31
31
|
raise UnknownParent.new(parent_id) if parent.nil?
|
|
32
32
|
# Its fine to not have a relationship entry, but not fine to have
|
|
@@ -34,9 +34,11 @@ module LicenseAcceptance
|
|
|
34
34
|
if children.nil? || children.empty? || !children.is_a?(Array)
|
|
35
35
|
raise NoChildRelationships.new(parent)
|
|
36
36
|
end
|
|
37
|
+
|
|
37
38
|
children.map! do |child_id|
|
|
38
39
|
child = products[child_id]
|
|
39
40
|
raise UnknownChild.new(child_id) if child.nil?
|
|
41
|
+
|
|
40
42
|
child
|
|
41
43
|
end
|
|
42
44
|
relationships[parent] = children
|
|
@@ -52,6 +54,7 @@ module LicenseAcceptance
|
|
|
52
54
|
if ENV["CHEF_LICENSE_PRODUCT_INFO"]
|
|
53
55
|
return ENV["CHEF_LICENSE_PRODUCT_INFO"]
|
|
54
56
|
end
|
|
57
|
+
|
|
55
58
|
File.absolute_path(File.join(__FILE__, "../../../config/product_info.toml"))
|
|
56
59
|
end
|
|
57
60
|
|
|
@@ -60,9 +63,10 @@ module LicenseAcceptance
|
|
|
60
63
|
raise UnknownProduct.new(parent_id)
|
|
61
64
|
end
|
|
62
65
|
children = relationships.fetch(parent_product, [])
|
|
63
|
-
|
|
66
|
+
unless parent_version.is_a? String
|
|
64
67
|
raise ProductVersionTypeError.new(parent_version)
|
|
65
68
|
end
|
|
69
|
+
|
|
66
70
|
ProductRelationship.new(parent_product, children, parent_version)
|
|
67
71
|
end
|
|
68
72
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module LicenseAcceptance
|
|
4
4
|
module Strategy
|
|
@@ -6,6 +6,8 @@ module LicenseAcceptance
|
|
|
6
6
|
# Look for acceptance values in the ARGV
|
|
7
7
|
class Argument < Base
|
|
8
8
|
|
|
9
|
+
FLAG = "--chef-license".freeze
|
|
10
|
+
|
|
9
11
|
attr_reader :argv
|
|
10
12
|
|
|
11
13
|
def initialize(argv)
|
|
@@ -13,31 +15,30 @@ module LicenseAcceptance
|
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def accepted?
|
|
16
|
-
|
|
18
|
+
String(value).downcase == ACCEPT
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def silent?
|
|
20
|
-
|
|
22
|
+
String(value).downcase == ACCEPT_SILENT
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def no_persist?
|
|
24
|
-
|
|
26
|
+
String(value).downcase == ACCEPT_NO_PERSIST
|
|
25
27
|
end
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
def value?
|
|
30
|
+
argv.any? { |s| s == FLAG || s.start_with?("#{FLAG}=") }
|
|
31
|
+
end
|
|
28
32
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
val = argv[i+1]
|
|
36
|
-
if val != nil && val.downcase == sought
|
|
37
|
-
return true
|
|
38
|
-
end
|
|
33
|
+
def value
|
|
34
|
+
match = argv.detect { |s| s.start_with?("#{FLAG}=") }
|
|
35
|
+
return match.split("=").last if match
|
|
36
|
+
|
|
37
|
+
argv.each_cons(2) do |arg, value|
|
|
38
|
+
return value if arg == FLAG
|
|
39
39
|
end
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
nil
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module LicenseAcceptance
|
|
4
4
|
module Strategy
|
|
@@ -6,6 +6,8 @@ module LicenseAcceptance
|
|
|
6
6
|
# Look for acceptance values in the environment
|
|
7
7
|
class Environment < Base
|
|
8
8
|
|
|
9
|
+
ENV_KEY = "CHEF_LICENSE".freeze
|
|
10
|
+
|
|
9
11
|
attr_reader :env
|
|
10
12
|
|
|
11
13
|
def initialize(env)
|
|
@@ -13,24 +15,23 @@ module LicenseAcceptance
|
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def accepted?
|
|
16
|
-
|
|
18
|
+
String(value).downcase == ACCEPT
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def silent?
|
|
20
|
-
|
|
22
|
+
String(value).downcase == ACCEPT_SILENT
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def no_persist?
|
|
24
|
-
|
|
26
|
+
String(value).downcase == ACCEPT_NO_PERSIST
|
|
25
27
|
end
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
def value?
|
|
30
|
+
env.key?(ENV_KEY)
|
|
31
|
+
end
|
|
28
32
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
return true
|
|
32
|
-
end
|
|
33
|
-
return false
|
|
33
|
+
def value
|
|
34
|
+
env[ENV_KEY]
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
require
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
require "date"
|
|
2
|
+
autoload :YAML, "yaml"
|
|
3
|
+
require "fileutils" unless defined?(FileUtils)
|
|
4
|
+
require "etc" unless defined?(Etc)
|
|
5
|
+
require_relative "../logger"
|
|
6
|
+
require_relative "base"
|
|
7
7
|
|
|
8
8
|
module LicenseAcceptance
|
|
9
9
|
module Strategy
|
|
@@ -28,11 +28,9 @@ module LicenseAcceptance
|
|
|
28
28
|
logger.debug("Searching for the following licenses: #{missing_licenses.map(&:id)}")
|
|
29
29
|
|
|
30
30
|
searching.each do |product|
|
|
31
|
-
found = false
|
|
32
31
|
config.license_locations.each do |loc|
|
|
33
32
|
f = ::File.join(loc, product.filename)
|
|
34
33
|
if ::File.exist?(f)
|
|
35
|
-
found = true
|
|
36
34
|
logger.debug("Found license #{product.filename} at #{f}")
|
|
37
35
|
missing_licenses.delete(product)
|
|
38
36
|
break
|
|
@@ -49,7 +47,7 @@ module LicenseAcceptance
|
|
|
49
47
|
parent_version = product_relationship.parent_version
|
|
50
48
|
root_dir = config.persist_location
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
unless Dir.exist?(root_dir)
|
|
53
51
|
begin
|
|
54
52
|
FileUtils.mkdir_p(root_dir)
|
|
55
53
|
rescue StandardError => e
|
|
@@ -70,7 +68,7 @@ module LicenseAcceptance
|
|
|
70
68
|
errs << err unless err.nil?
|
|
71
69
|
end
|
|
72
70
|
end
|
|
73
|
-
|
|
71
|
+
errs
|
|
74
72
|
end
|
|
75
73
|
|
|
76
74
|
private
|
|
@@ -91,11 +89,11 @@ module LicenseAcceptance
|
|
|
91
89
|
contents = Hash[contents.map { |k, v| [k.to_s, v] }]
|
|
92
90
|
license_file << YAML.dump(contents)
|
|
93
91
|
end
|
|
94
|
-
|
|
92
|
+
nil
|
|
95
93
|
rescue StandardError => e
|
|
96
94
|
msg = "Could not persist license to #{path}"
|
|
97
95
|
logger.info "#{msg}\n\t#{e.message}\n\t#{e.backtrace.join("\n\t")}"
|
|
98
|
-
|
|
96
|
+
e
|
|
99
97
|
end
|
|
100
98
|
|
|
101
99
|
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
require
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
require "timeout"
|
|
1
|
+
autoload :TTY, "tty-prompt"
|
|
2
|
+
require "pastel" unless defined?(Pastel)
|
|
3
|
+
require_relative "../logger"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
require "timeout" unless defined?(Timeout)
|
|
6
6
|
|
|
7
7
|
module LicenseAcceptance
|
|
8
8
|
module Strategy
|
|
9
9
|
|
|
10
|
-
# Interactive prompt for accepting and
|
|
10
|
+
# Interactive prompt for accepting and persistence license acceptance, or failing with custom exit code
|
|
11
11
|
class Prompt < Base
|
|
12
12
|
include Logger
|
|
13
13
|
|
|
@@ -17,30 +17,30 @@ module LicenseAcceptance
|
|
|
17
17
|
@output = config.output
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
WIDTH = 50
|
|
20
|
+
WIDTH = 50
|
|
21
21
|
PASTEL = Pastel.new
|
|
22
22
|
BORDER = "+---------------------------------------------+".freeze
|
|
23
23
|
YES = PASTEL.green.bold("yes")
|
|
24
|
-
CHECK
|
|
24
|
+
CHECK = PASTEL.green("✔")
|
|
25
25
|
|
|
26
26
|
def request(missing_licenses, &persist_callback)
|
|
27
27
|
logger.debug("Requesting a license for #{missing_licenses.map(&:id)}")
|
|
28
28
|
c = missing_licenses.size
|
|
29
|
-
s = c > 1 ? "s": ""
|
|
29
|
+
s = c > 1 ? "s" : ""
|
|
30
30
|
|
|
31
31
|
acceptance_question = "Do you accept the #{c} product license#{s} (#{YES}/no)?"
|
|
32
32
|
output.puts <<~EOM
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
#{BORDER}
|
|
34
|
+
Chef License Acceptance
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
Before you can continue, #{c} product license#{s}
|
|
37
|
+
must be accepted. View the license at
|
|
38
|
+
https://www.chef.io/end-user-license-agreement/
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
License#{s} that need accepting:
|
|
41
|
+
* #{missing_licenses.map(&:pretty_name).join("\n * ")}
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
#{acceptance_question}
|
|
44
44
|
|
|
45
45
|
EOM
|
|
46
46
|
|
|
@@ -51,10 +51,10 @@ module LicenseAcceptance
|
|
|
51
51
|
|
|
52
52
|
output.puts <<~EOM
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
If you do not accept this license you will
|
|
55
|
+
not be able to use Chef products.
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
#{acceptance_question}
|
|
58
58
|
|
|
59
59
|
EOM
|
|
60
60
|
|
|
@@ -62,7 +62,7 @@ module LicenseAcceptance
|
|
|
62
62
|
if answer != "yes"
|
|
63
63
|
output.puts BORDER
|
|
64
64
|
end
|
|
65
|
-
|
|
65
|
+
answer
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
private
|
|
@@ -73,12 +73,12 @@ module LicenseAcceptance
|
|
|
73
73
|
|
|
74
74
|
answer = "no"
|
|
75
75
|
begin
|
|
76
|
-
Timeout
|
|
76
|
+
Timeout.timeout(60, PromptTimeout) do
|
|
77
77
|
answer = prompt.ask(">") do |q|
|
|
78
78
|
q.modify :down, :trim
|
|
79
79
|
q.required true
|
|
80
80
|
q.messages[:required?] = "You must enter 'yes' or 'no'"
|
|
81
|
-
q.validate
|
|
81
|
+
q.validate(/^\s*(yes|no)\s*$/i)
|
|
82
82
|
q.messages[:valid?] = "You must enter 'yes' or 'no'"
|
|
83
83
|
end
|
|
84
84
|
end
|
|
@@ -95,13 +95,13 @@ module LicenseAcceptance
|
|
|
95
95
|
output.puts "#{CHECK} #{c} product license#{s} persisted.\n\n"
|
|
96
96
|
else
|
|
97
97
|
output.puts <<~EOM
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
#{CHECK} #{c} product license#{s} accepted.
|
|
99
|
+
Could not persist acceptance:\n\t* #{errs.map(&:message).join("\n\t* ")}
|
|
100
100
|
EOM
|
|
101
101
|
end
|
|
102
102
|
return true
|
|
103
103
|
end
|
|
104
|
-
|
|
104
|
+
false
|
|
105
105
|
end
|
|
106
106
|
end
|
|
107
107
|
|