inspec-core 5.22.40 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Chef-EULA +9 -0
  3. data/Gemfile +10 -5
  4. data/etc/features.sig +6 -0
  5. data/etc/features.yaml +94 -0
  6. data/inspec-core.gemspec +14 -5
  7. data/lib/inspec/backend.rb +2 -0
  8. data/lib/inspec/base_cli.rb +80 -4
  9. data/lib/inspec/cached_fetcher.rb +24 -3
  10. data/lib/inspec/cli.rb +292 -235
  11. data/lib/inspec/config.rb +24 -11
  12. data/lib/inspec/dependencies/cache.rb +33 -0
  13. data/lib/inspec/dependencies/dependency_set.rb +2 -2
  14. data/lib/inspec/dsl.rb +1 -1
  15. data/lib/inspec/enhanced_outcomes.rb +1 -0
  16. data/lib/inspec/errors.rb +5 -0
  17. data/lib/inspec/exceptions.rb +2 -0
  18. data/lib/inspec/feature/config.rb +75 -0
  19. data/lib/inspec/feature/runner.rb +26 -0
  20. data/lib/inspec/feature.rb +34 -0
  21. data/lib/inspec/fetcher/git.rb +5 -0
  22. data/lib/inspec/globals.rb +6 -0
  23. data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +7 -0
  24. data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +30 -2
  25. data/lib/inspec/profile.rb +46 -3
  26. data/lib/inspec/reporters/cli.rb +1 -1
  27. data/lib/inspec/reporters.rb +67 -54
  28. data/lib/inspec/rule.rb +9 -14
  29. data/lib/inspec/run_data.rb +7 -5
  30. data/lib/inspec/runner.rb +35 -6
  31. data/lib/inspec/runner_rspec.rb +12 -9
  32. data/lib/inspec/secrets/yaml.rb +9 -3
  33. data/lib/inspec/shell.rb +10 -0
  34. data/lib/inspec/ui.rb +4 -0
  35. data/lib/inspec/utils/licensing_config.rb +9 -0
  36. data/lib/inspec/utils/waivers/csv_file_reader.rb +1 -1
  37. data/lib/inspec/utils/waivers/excel_file_reader.rb +1 -1
  38. data/lib/inspec/version.rb +1 -1
  39. data/lib/inspec/waiver_file_reader.rb +68 -27
  40. data/lib/inspec.rb +2 -1
  41. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +189 -168
  42. data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +10 -3
  43. data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
  44. data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +23 -21
  45. data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +15 -13
  46. data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +15 -13
  47. data/lib/plugins/inspec-license/README.md +16 -0
  48. data/lib/plugins/inspec-license/inspec-license.gemspec +6 -0
  49. data/lib/plugins/inspec-license/lib/inspec-license/cli.rb +26 -0
  50. data/lib/plugins/inspec-license/lib/inspec-license.rb +14 -0
  51. data/lib/plugins/inspec-parallel/README.md +27 -0
  52. data/lib/plugins/inspec-parallel/inspec-parallel.gemspec +6 -0
  53. data/lib/plugins/inspec-parallel/lib/inspec-parallel/child_status_reporter.rb +61 -0
  54. data/lib/plugins/inspec-parallel/lib/inspec-parallel/cli.rb +39 -0
  55. data/lib/plugins/inspec-parallel/lib/inspec-parallel/command.rb +219 -0
  56. data/lib/plugins/inspec-parallel/lib/inspec-parallel/runner.rb +265 -0
  57. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/base.rb +24 -0
  58. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/silent.rb +7 -0
  59. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/status.rb +124 -0
  60. data/lib/plugins/inspec-parallel/lib/inspec-parallel/super_reporter/text.rb +23 -0
  61. data/lib/plugins/inspec-parallel/lib/inspec-parallel/validator.rb +170 -0
  62. data/lib/plugins/inspec-parallel/lib/inspec-parallel.rb +18 -0
  63. data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +6 -2
  64. data/lib/plugins/inspec-sign/lib/inspec-sign/cli.rb +11 -4
  65. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +6 -13
  66. metadata +53 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a95805ac2a4faab83d1826792a5d838caa5f1808fcc884e061cf3f7070ab6ef2
4
- data.tar.gz: 984dfca55efec04f1e9b98ddfebf5be636b96a91c7fe7dc97f9ffb9789c60af3
3
+ metadata.gz: 2e2d81ddee4b440d4bcb0d00b586707400b189e833942dd65e677bd7f75df0a4
4
+ data.tar.gz: 69905f313a3303d2e385fe603c6d808970aca2efc7d37498d74ca12727583608
5
5
  SHA512:
6
- metadata.gz: fb6e20f346e0e5ab27878931b1396c10a633b99767472774299d92fce3ae2ccf01399cb100e5ae4566456039a3d814ac4148670da65b41563e72139d29551ed7
7
- data.tar.gz: 0c9c665c3afb6d90121bf40ac00736a900955e0ea5955af58f7e56378d18eecfd7560f40e2cce049afd7156ecb495c77b1c58765c0e69f82bfd03e976c2f367f
6
+ metadata.gz: 754812b73f047d377cdcdfd1c409a15a916ae69d529bded4ace7993b638f1ab6783c7a4394107d538a2df5523887d782a251cfbbf7923a2084961372de1ab12d
7
+ data.tar.gz: 2ccb38f332159f8af419ef0c343710271d32328198354327489d492ca66c7bad921a5271310f984e844f12eddfa0a70664024be9dac2bdabbf96a0974fc97c74
data/Chef-EULA ADDED
@@ -0,0 +1,9 @@
1
+ Packaged distributions of Progress® Chef® products obtained from RubyGems
2
+ are made available pursuant to the Progress Chef EULA at
3
+ https://www.chef.io/end-user-license-agreement, unless there is an executed
4
+ agreement in effect between you and Progress that covers the Progress Chef
5
+ products ("Master Agreement"), in which case the Master Agreement shall govern.
6
+
7
+ Source code obtained from the Chef GitHub repository is made available
8
+ under Apache-2.0, a copy of which can be found in
9
+ http://www.apache.org/licenses/LICENSE-2.0
data/Gemfile CHANGED
@@ -1,3 +1,12 @@
1
+ # For Chef internal builds, allows preview versions of gems if available.
2
+ if ENV["ARTIFACTORY_BASE_URL"]
3
+ source ENV["ARTIFACTORY_BASE_URL"] + "/artifactory/api/gems/omnibus-gems-local/" do
4
+ # TODO: either fully populate this list, or revert back to non-block format
5
+ # to sweep all Chef gems from Artifactory.
6
+ gem "chef-licensing"
7
+ end
8
+ end
9
+
1
10
  source "https://rubygems.org"
2
11
 
3
12
  gem "inspec", path: "."
@@ -11,10 +20,6 @@ gem "inspec-bin", path: "./inspec-bin"
11
20
 
12
21
  gem "ffi", ">= 1.9.14", "!= 1.13.0", "!= 1.14.2"
13
22
 
14
- # We have a build issue 2023-11-13 with unf_ext 0.0.9 so we are pinning to 0.0.8.2
15
- # See https://github.com/knu/ruby-unf_ext/issues/74 https://buildkite.com/chef/inspec-inspec-inspec-5-omnibus-release/builds/22
16
- gem "unf_ext", "= 0.0.8.2"
17
-
18
23
  # inspec tests depend text output that changed in the 3.10 release
19
24
  # but our runtime dep is still 3.9+
20
25
  gem "rspec", ">= 3.10"
@@ -33,7 +38,7 @@ group :test do
33
38
  gem "m"
34
39
  gem "minitest-sprint", "~> 1.0"
35
40
  gem "minitest", "5.15.0"
36
- gem "mocha", "~> 2.1"
41
+ gem "mocha", "~> 1.1"
37
42
  gem "nokogiri", "~> 1.9"
38
43
  gem "pry-byebug"
39
44
  gem "pry", "~> 0.10"
data/etc/features.sig ADDED
@@ -0,0 +1,6 @@
1
+ LoJePRrMIqFz6d1uu5n3QBqQAPD8wLuLM8PfvdDerFjuX/TFJDFdwdcNZ8b8
2
+ KBxFjR5qUTMZizjIUp5Jd6FFI4gSm0RIMKa4UeJCQQAWKJGo/tIbSKLPLWlV
3
+ m1X1Z869AkvQSJxyaXvS2oKPck/znCbRKEDhuk2kqSyDJlC2BILTVa0sx3nd
4
+ 4W2J2CwFBlqmYWI1FARkZCMGlfzkjcUqrVrCb3RcZ7bcEYOT5ebIm9zZlbuV
5
+ n2Di29KFZhl8paEoGq3EYJvxEC7rVtLccei8UteNQcSOWihG61dtPGhHnpS+
6
+ /7RNGjrS8s4i/dQHjZlZgV6guki6EqB+DIirVek9PQ==
data/etc/features.yaml ADDED
@@ -0,0 +1,94 @@
1
+ ---
2
+ features:
3
+ inspec-cli-exec:
4
+ description: Run InSpec profile code at the command line.
5
+ inspec-cli-shell:
6
+ description: Experiment with InSpec Language interactively.
7
+ inspec-cli-check:
8
+ description: Examine a profile for problems.
9
+ inspec-cli-json:
10
+ description: Generate JSON summary for inspec profile/s.
11
+ inspec-cli-export:
12
+ description: Generate summary in specified formats for profile/s.
13
+ inspec-cli-vendor:
14
+ description: Download all profile dependencies and generate a lockfile in vendor directory.
15
+ inspec-cli-archive:
16
+ description: Archive a profile to tar.gz (default) or zip.
17
+ inspec-cli-detect:
18
+ description: Detect the target OS.
19
+ inspec-cli-env:
20
+ description: Output shell-appropriate completion configuration.
21
+ inspec-cli-schema:
22
+ description: Print the JSON schema.
23
+ inspec-cli-run-context:
24
+ description: Test run-context detection.
25
+ inspec-cli-version:
26
+ description: Print the version of InSpec.
27
+ inspec-cli-clear-cache:
28
+ description: Clear InSpec cache stored in ~/.inspec/cache or specific vendor cache path.
29
+ inspec-cli-compliance-login:
30
+ description: Login to Automate Server using InSpec.
31
+ inspec-cli-compliance-profiles:
32
+ description: Lists all uploaded profiles from automate server.
33
+ inspec-cli-compliance-exec:
34
+ description: Run InSpec profile from a list of profiles in automate server.
35
+ inspec-cli-compliance-download:
36
+ description: Download the InSpec profile from automate server.
37
+ inspec-cli-compliance-upload:
38
+ description: Upload InSpec profile to automate server.
39
+ inspec-cli-compliance-version:
40
+ description: Print the version of Automate Server.
41
+ inspec-cli-compliance-logout:
42
+ description: Logout from Automate Server.
43
+ inspec-cli-habitat-profile-create:
44
+ description: Create Habitat Artifact for the InSpec profile.
45
+ inspec-cli-habitat-profile-setup:
46
+ description: Configure Habitat Artifact.
47
+ inspec-cli-habitat-profile-upload:
48
+ description: Upload Habitat Artifact for the InSpec profile to Habitat Builder Depot.
49
+ inspec-cli-init-profile:
50
+ description: Generate a new InSpec profile.
51
+ inspec-cli-init-plugin:
52
+ description: Generate a new InSpec plugin.
53
+ inspec-cli-init-resource:
54
+ description: Generate a new InSpec resource.
55
+ inspec-cli-parallel-exec:
56
+ description: Run list of InSpec exec operations parallely.
57
+ inspec-cli-sign-generate-keys:
58
+ description: Generate a RSA key pair for signing and verification.
59
+ inspec-cli-sign-profile:
60
+ description: Sign InSpec profile and generate .iaf artifact.
61
+ inspec-cli-sign-verify:
62
+ description: Verify a signed profile .iaf artifact.
63
+ inspec-enhanced-outcomes:
64
+ description: Use enhanced outcomes in reporters
65
+ inspec-waivers:
66
+ description: Use waivers mechanism with one or more waiver files.
67
+ inspec-reporter-cli:
68
+ description: Use CLI reporter.
69
+ inspec-reporter-json:
70
+ description: Use JSON reporter.
71
+ inspec-reporter-json-automate:
72
+ description: Use JSON automate reporter.
73
+ inspec-reporter-automate:
74
+ description: Use automate reporter.
75
+ inspec-reporter-yaml:
76
+ description: Use YAML reporter.
77
+ inspec-reporter-json-min:
78
+ description: Use JSON min reporter for minimal JSON output.
79
+ inspec-reporter-junit:
80
+ description: Use JUnit reporter.
81
+ inspec-reporter-junit2:
82
+ description: Use JUnit2 reporter.
83
+ inspec-reporter-html2:
84
+ description: Use HTML reporter.
85
+ inspec-reporter-progress-bar:
86
+ description: Use progress bar streaming reporter
87
+ inspec-reporter-child-status:
88
+ description: Child status reporter used in inspec parallel reporting.
89
+ inspec-mandatory-profile-signing:
90
+ description: Required to use a signed Inspec profile by default with inspec commands
91
+ env_preview: true
92
+ inspec-audit-logging:
93
+ description: Use audit logging.
94
+ env_preview: true
data/inspec-core.gemspec CHANGED
@@ -8,16 +8,24 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Chef InSpec Team"]
9
9
  spec.email = ["inspec@chef.io"]
10
10
  spec.summary = "Infrastructure and compliance testing. Core library."
11
- spec.description = "InSpec provides a framework for creating end-to-end infrastructure tests. You can use it for integration or even compliance testing. Create fully portable test profiles and use them in your workflow to ensure stability and security. Integrate InSpec in your change lifecycle for local testing, CI/CD, and deployment verification. This has local support only. See the `inspec` gem for full support."
11
+ spec.description = <<-EOT
12
+ InSpec provides a framework for creating end-to-end infrastructure tests. You can use it for integration or even compliance testing. Create fully portable test profiles and use them in your workflow to ensure stability and security. Integrate InSpec in your change lifecycle for local testing, CI/CD, and deployment verification.
13
+ This has local support only. See the `inspec` gem for full support.
14
+
15
+ Packaged distributions of Progress® Chef® products obtained from RubyGems are made available pursuant to the Progress Chef EULA at https://www.chef.io/end-user-license-agreement, unless there is an executed agreement in effect between you and Progress that covers the Progress Chef products ("Master Agreement"), in which case the Master Agreement shall govern.
16
+
17
+ Source code obtained from the Chef GitHub repository is made available under Apache-2.0, a copy of which is included.
18
+
19
+ EOT
12
20
  spec.homepage = "https://github.com/inspec/inspec"
13
- spec.license = "Apache-2.0"
21
+ spec.license = "LicenseRef-Chef-EULA"
14
22
  spec.require_paths = ["lib"]
15
23
 
16
24
  spec.required_ruby_version = ">= 2.7"
17
25
 
18
26
  # the gemfile and gemspec are necessary for appbundler so don't remove it
19
27
  spec.files =
20
- Dir.glob("{{lib,etc}/**/*,LICENSE,Gemfile,inspec-core.gemspec}")
28
+ Dir.glob("{{lib,etc}/**/*,LICENSE,Chef-EULA,Gemfile,inspec-core.gemspec}")
21
29
  .grep_v(%r{(?<!inspec-init/templates/profiles/)(aws|azure|gcp|alicloud)})
22
30
  .grep_v(%r{lib/plugins/.*/test/})
23
31
  .reject { |f| File.directory?(f) }
@@ -43,9 +51,10 @@ Gem::Specification.new do |spec|
43
51
  spec.add_dependency "tty-prompt", "~> 0.17"
44
52
  spec.add_dependency "tomlrb", ">= 1.2", "< 2.1"
45
53
  spec.add_dependency "addressable", "~> 2.4"
46
- spec.add_dependency "parslet", ">= 1.5", "< 3.0" # Pinned < 2.0, see #5389
54
+ spec.add_dependency "parslet", ">= 1.5", "< 2.0" # Pinned < 2.0, see #5389
47
55
  spec.add_dependency "semverse", "~> 3.0"
48
56
  spec.add_dependency "multipart-post", "~> 2.0"
49
57
 
50
- spec.add_dependency "train-core", "~> 3.10"
58
+ spec.add_dependency "train-core", ">= 3.11.0"
59
+ spec.add_dependency "chef-licensing", ">= 0.7.5"
51
60
  end
@@ -61,6 +61,8 @@ module Inspec
61
61
  raise "Client error, can't connect to '#{transport_name}' backend: #{e.message}"
62
62
  rescue Train::TransportError => e
63
63
  raise "Transport error, can't connect to '#{transport_name}' backend: #{e.message}"
64
+ rescue Errno::ENOENT => e
65
+ raise "#{e.message}"
64
66
  end
65
67
 
66
68
  def initialize(backend)
@@ -1,9 +1,11 @@
1
1
  require "thor" # rubocop:disable Chef/Ruby/UnlessDefinedRequire
2
+ require "chef-licensing"
2
3
  require "inspec/log"
3
4
  require "inspec/ui"
4
5
  require "inspec/config"
5
6
  require "inspec/dist"
6
7
  require "inspec/utils/deprecation/global_method"
8
+ require "inspec/utils/licensing_config"
7
9
 
8
10
  # Allow end of options during array type parsing
9
11
  # https://github.com/erikhuda/thor/issues/631
@@ -30,11 +32,34 @@ module Inspec
30
32
  end
31
33
 
32
34
  def self.start(given_args = ARGV, config = {})
33
- check_license! if config[:enforce_license] || config[:enforce_license].nil?
35
+ if Inspec::Dist::EXEC_NAME == "inspec"
36
+ check_license! if config[:enforce_license] || config[:enforce_license].nil?
37
+ fetch_and_persist_license
38
+ end
34
39
 
35
40
  super(given_args, config)
36
41
  end
37
42
 
43
+ def self.fetch_and_persist_license
44
+ allowed_commands = ["-h", "--help", "help", "-v", "--version", "version", "license"]
45
+ begin
46
+ if (allowed_commands & ARGV.map(&:downcase)).empty? && !ARGV.empty?
47
+ license_keys = ChefLicensing.fetch_and_persist
48
+
49
+ # Only if EULA acceptance or license key args are present. And licenses are successfully persisted, do clean exit.
50
+ if ARGV.select { |arg| !(arg.include? "--chef-license") }.empty? && !license_keys.blank?
51
+ Inspec::UI.new.exit
52
+ end
53
+ end
54
+ rescue ChefLicensing::LicenseKeyFetcher::LicenseKeyNotFetchedError
55
+ Inspec::Log.error "#{Inspec::Dist::PRODUCT_NAME} cannot execute without valid licenses."
56
+ Inspec::UI.new.exit(:license_not_set)
57
+ rescue ChefLicensing::Error => e
58
+ Inspec::Log.error e.message
59
+ Inspec::UI.new.exit(:usage_error)
60
+ end
61
+ end
62
+
38
63
  # EULA acceptance
39
64
  def self.check_license!
40
65
  allowed_commands = ["-h", "--help", "help", "-v", "--version", "version"]
@@ -48,9 +73,6 @@ module Inspec
48
73
  Inspec::VERSION,
49
74
  logger: Inspec::Log
50
75
  )
51
- if license_acceptor_output && ARGV.count == 1 && (ARGV.first.include? "--chef-license")
52
- Inspec::UI.new.exit
53
- end
54
76
  license_acceptor_output
55
77
  end
56
78
  rescue LicenseAcceptance::LicenseNotAcceptedError
@@ -149,6 +171,8 @@ module Inspec
149
171
  desc: "Use the given path for caching dependencies, (default: ~/.inspec/cache)."
150
172
  option :auto_install_gems, type: :boolean, default: false,
151
173
  desc: "Auto installs gem dependencies of the profile or resource pack."
174
+ option :allow_unsigned_profiles, type: :boolean, default: false,
175
+ desc: "Allow unsigned profiles to be used in InSpec command."
152
176
  end
153
177
 
154
178
  def self.supermarket_options
@@ -209,8 +233,37 @@ module Inspec
209
233
  desc: "Show enhanced outcomes in output"
210
234
  end
211
235
 
236
+ def self.audit_log_options
237
+ option :audit_log_location, type: :string,
238
+ desc: "Audit log location to send diagnostic log messages to. (default: '~/.inspec/logs/inspec-audit.log')"
239
+ end
240
+
212
241
  def self.help(*args)
213
242
  super(*args)
243
+ if Inspec::Dist::EXEC_NAME == "inspec"
244
+ puts <<~CHEF_LICENSE_HELP
245
+ Chef Compliance has three tiers of licensing:
246
+
247
+ * Free-Tier
248
+ Users are limited to audit maximum of 10 targets
249
+ Entitled for personal or non-commercial use
250
+
251
+ * Trial
252
+ Entitled for unlimited number of targets
253
+ Entitled for 30 days only
254
+ Entitled for commercial use
255
+
256
+ * Commercial
257
+ Entitled for purchased number of targets
258
+ Entitled for period of subscription purchased
259
+ Entitled for commercial use
260
+
261
+ inspec license add: This command helps users to generate or add an additional license (not applicable to local licensing service)
262
+
263
+ For more information please visit:
264
+ www.chef.io/licensing/faqs
265
+ CHEF_LICENSE_HELP
266
+ end
214
267
  puts "\nAbout #{Inspec::Dist::PRODUCT_NAME}:"
215
268
  puts " Patents: chef.io/patents\n\n"
216
269
  end
@@ -327,6 +380,9 @@ module Inspec
327
380
 
328
381
  def pretty_handle_exception(exception)
329
382
  case exception
383
+ when Inspec::ProfileSignatureRequired
384
+ $stderr.puts exception.message
385
+ Inspec::UI.new.exit(:signature_required)
330
386
  when Inspec::InvalidProfileSignature
331
387
  $stderr.puts exception.message
332
388
  Inspec::UI.new.exit(:bad_signature)
@@ -379,5 +435,25 @@ module Inspec
379
435
  end
380
436
  o[:logger].level = get_log_level(o["log_level"])
381
437
  end
438
+
439
+ # This method is currenlty under feature preview flag and audit log will only be enabeld when CHEF_PREVIEW_AUDIT_LOGGING is set in the env variable
440
+ def set_and_validate_audit_log_options(opts)
441
+ err = []
442
+ opts[:enable_audit_log] ||= true
443
+ if opts[:audit_log_location].nil?
444
+ opts[:audit_log_location] = "#{Inspec.log_dir}/inspec-audit-#{Time.now.strftime("%Y%m%dT%H%M%S")}-#{Process.pid}.log"
445
+ elsif File.directory?(File.dirname(opts[:audit_log_location]))
446
+ file_path = opts[:audit_log_location]
447
+ # suffix the timestamp and pid to the audit log file name if log location is set through cli option
448
+ filename = "#{File.basename(file_path, ".*")}-#{Time.now.strftime("%Y%m%dT%H%M%S")}-#{Process.pid}"
449
+ opts[:audit_log_location] = File.join( File.dirname(file_path), "#{filename}#{File.extname(file_path)}" )
450
+ else
451
+ err << "Audit log location directory #{opts[:audit_log_location]} does not exist."
452
+ end
453
+ opts[:audit_log_app_name] = Inspec::Dist::EXEC_NAME
454
+ unless err.empty?
455
+ raise Inspec::Exceptions::InvalidAuditLogOption, err.join("\n")
456
+ end
457
+ end
382
458
  end
383
459
  end
@@ -39,12 +39,33 @@ module Inspec
39
39
  end
40
40
 
41
41
  def fetch
42
- if cache.exists?(cache_key)
42
+ if cache.exists?(cache_key) && cache.locked?(cache_key)
43
+ Inspec::Log.debug "Waiting for lock to be released on the cache dir ...."
44
+ counter = 0
45
+ until cache.locked?(cache_key) == false
46
+ if (counter += 1) > 300
47
+ Inspec::Log.warn "Giving up waiting on cache lock at #{cache_key}"
48
+ exit 1
49
+ end
50
+ sleep 0.1
51
+ end
52
+ fetch
53
+ elsif cache.exists?(cache_key) && !cache.locked?(cache_key)
43
54
  Inspec::Log.debug "Using cached dependency for #{target}"
44
55
  [cache.prefered_entry_for(cache_key), false]
45
56
  else
46
- Inspec::Log.debug "Dependency does not exist in the cache #{target}"
47
- fetcher.fetch(cache.base_path_for(fetcher.cache_key))
57
+ begin
58
+ Inspec::Log.debug "Dependency does not exist in the cache #{target}"
59
+ cache.lock(cache.base_path_for(fetcher.cache_key)) if fetcher.requires_locking?
60
+ fetcher.fetch(cache.base_path_for(fetcher.cache_key))
61
+ rescue SystemExit => e
62
+ exit_code = e.status || 1
63
+ Inspec::Log.error "Error while creating cache for dependency ... #{e.message}"
64
+ FileUtils.rm_rf(cache.base_path_for(fetcher.cache_key))
65
+ exit(exit_code)
66
+ ensure
67
+ cache.unlock(cache.base_path_for(fetcher.cache_key)) if fetcher.requires_locking?
68
+ end
48
69
  assert_cache_sanity!
49
70
  [fetcher.archive_path, fetcher.writable?]
50
71
  end