test-kitchen 1.7.0 → 1.7.1.dev
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/.cane +8 -8
- data/.gitattributes +3 -0
- data/.github/ISSUE_TEMPLATE.md +55 -55
- data/.gitignore +28 -28
- data/.kitchen.ci.yml +23 -23
- data/.kitchen.proxy.yml +27 -27
- data/.rubocop.yml +3 -3
- data/.travis.yml +70 -70
- data/.yardopts +3 -3
- data/Berksfile +3 -3
- data/CHANGELOG.md +1090 -1083
- data/CONTRIBUTING.md +14 -14
- data/Gemfile +19 -19
- data/Gemfile.proxy_tests +4 -4
- data/Guardfile +42 -42
- data/LICENSE +15 -15
- data/MAINTAINERS.md +23 -23
- data/README.md +135 -135
- data/Rakefile +61 -61
- data/appveyor.yml +44 -44
- data/features/kitchen_action_commands.feature +164 -164
- data/features/kitchen_command.feature +16 -16
- data/features/kitchen_console_command.feature +34 -34
- data/features/kitchen_defaults.feature +38 -38
- data/features/kitchen_diagnose_command.feature +96 -96
- data/features/kitchen_driver_create_command.feature +64 -64
- data/features/kitchen_driver_discover_command.feature +25 -25
- data/features/kitchen_help_command.feature +16 -16
- data/features/kitchen_init_command.feature +274 -274
- data/features/kitchen_list_command.feature +104 -104
- data/features/kitchen_login_command.feature +62 -62
- data/features/kitchen_sink_command.feature +30 -30
- data/features/kitchen_test_command.feature +88 -88
- data/features/step_definitions/gem_steps.rb +36 -36
- data/features/step_definitions/git_steps.rb +5 -5
- data/features/step_definitions/output_steps.rb +5 -5
- data/features/support/env.rb +75 -75
- data/lib/kitchen.rb +150 -150
- data/lib/kitchen/base64_stream.rb +55 -55
- data/lib/kitchen/cli.rb +419 -419
- data/lib/kitchen/collection.rb +55 -55
- data/lib/kitchen/color.rb +65 -65
- data/lib/kitchen/command.rb +185 -185
- data/lib/kitchen/command/action.rb +45 -45
- data/lib/kitchen/command/console.rb +58 -58
- data/lib/kitchen/command/diagnose.rb +92 -92
- data/lib/kitchen/command/driver_discover.rb +105 -105
- data/lib/kitchen/command/exec.rb +41 -41
- data/lib/kitchen/command/list.rb +119 -119
- data/lib/kitchen/command/login.rb +43 -43
- data/lib/kitchen/command/sink.rb +54 -54
- data/lib/kitchen/command/test.rb +51 -51
- data/lib/kitchen/config.rb +322 -322
- data/lib/kitchen/configurable.rb +529 -529
- data/lib/kitchen/data_munger.rb +959 -959
- data/lib/kitchen/diagnostic.rb +141 -141
- data/lib/kitchen/driver.rb +56 -56
- data/lib/kitchen/driver/base.rb +134 -134
- data/lib/kitchen/driver/dummy.rb +108 -108
- data/lib/kitchen/driver/proxy.rb +72 -72
- data/lib/kitchen/driver/ssh_base.rb +357 -357
- data/lib/kitchen/errors.rb +229 -229
- data/lib/kitchen/generator/driver_create.rb +177 -177
- data/lib/kitchen/generator/init.rb +296 -296
- data/lib/kitchen/instance.rb +662 -662
- data/lib/kitchen/lazy_hash.rb +142 -142
- data/lib/kitchen/loader/yaml.rb +349 -349
- data/lib/kitchen/logger.rb +423 -423
- data/lib/kitchen/logging.rb +56 -56
- data/lib/kitchen/login_command.rb +52 -52
- data/lib/kitchen/metadata_chopper.rb +52 -52
- data/lib/kitchen/platform.rb +67 -67
- data/lib/kitchen/provisioner.rb +54 -54
- data/lib/kitchen/provisioner/base.rb +236 -236
- data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
- data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
- data/lib/kitchen/provisioner/chef_apply.rb +124 -124
- data/lib/kitchen/provisioner/chef_base.rb +341 -341
- data/lib/kitchen/provisioner/chef_solo.rb +88 -88
- data/lib/kitchen/provisioner/chef_zero.rb +245 -245
- data/lib/kitchen/provisioner/dummy.rb +79 -79
- data/lib/kitchen/provisioner/shell.rb +138 -138
- data/lib/kitchen/rake_tasks.rb +63 -63
- data/lib/kitchen/shell_out.rb +93 -93
- data/lib/kitchen/ssh.rb +276 -276
- data/lib/kitchen/state_file.rb +120 -120
- data/lib/kitchen/suite.rb +51 -51
- data/lib/kitchen/thor_tasks.rb +66 -66
- data/lib/kitchen/transport.rb +54 -54
- data/lib/kitchen/transport/base.rb +176 -176
- data/lib/kitchen/transport/dummy.rb +79 -79
- data/lib/kitchen/transport/ssh.rb +364 -364
- data/lib/kitchen/transport/winrm.rb +486 -486
- data/lib/kitchen/util.rb +147 -147
- data/lib/kitchen/verifier.rb +55 -55
- data/lib/kitchen/verifier/base.rb +235 -235
- data/lib/kitchen/verifier/busser.rb +277 -277
- data/lib/kitchen/verifier/dummy.rb +79 -79
- data/lib/kitchen/verifier/shell.rb +101 -101
- data/lib/kitchen/version.rb +21 -21
- data/lib/vendor/hash_recursive_merge.rb +82 -82
- data/spec/kitchen/base64_stream_spec.rb +77 -77
- data/spec/kitchen/cli_spec.rb +56 -56
- data/spec/kitchen/collection_spec.rb +80 -80
- data/spec/kitchen/color_spec.rb +54 -54
- data/spec/kitchen/config_spec.rb +408 -408
- data/spec/kitchen/configurable_spec.rb +1095 -1095
- data/spec/kitchen/data_munger_spec.rb +2694 -2694
- data/spec/kitchen/diagnostic_spec.rb +129 -129
- data/spec/kitchen/driver/base_spec.rb +121 -121
- data/spec/kitchen/driver/dummy_spec.rb +199 -199
- data/spec/kitchen/driver/proxy_spec.rb +138 -138
- data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
- data/spec/kitchen/driver_spec.rb +112 -112
- data/spec/kitchen/errors_spec.rb +309 -309
- data/spec/kitchen/instance_spec.rb +1419 -1419
- data/spec/kitchen/lazy_hash_spec.rb +117 -117
- data/spec/kitchen/loader/yaml_spec.rb +774 -774
- data/spec/kitchen/logger_spec.rb +429 -429
- data/spec/kitchen/logging_spec.rb +59 -59
- data/spec/kitchen/login_command_spec.rb +68 -68
- data/spec/kitchen/metadata_chopper_spec.rb +82 -82
- data/spec/kitchen/platform_spec.rb +89 -89
- data/spec/kitchen/provisioner/base_spec.rb +386 -386
- data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
- data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1161
- data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
- data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
- data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
- data/spec/kitchen/provisioner/shell_spec.rb +566 -566
- data/spec/kitchen/provisioner_spec.rb +107 -107
- data/spec/kitchen/shell_out_spec.rb +150 -150
- data/spec/kitchen/ssh_spec.rb +693 -693
- data/spec/kitchen/state_file_spec.rb +129 -129
- data/spec/kitchen/suite_spec.rb +62 -62
- data/spec/kitchen/transport/base_spec.rb +89 -89
- data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
- data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
- data/spec/kitchen/transport_spec.rb +112 -112
- data/spec/kitchen/util_spec.rb +165 -165
- data/spec/kitchen/verifier/base_spec.rb +362 -362
- data/spec/kitchen/verifier/busser_spec.rb +610 -610
- data/spec/kitchen/verifier/dummy_spec.rb +99 -99
- data/spec/kitchen/verifier/shell_spec.rb +160 -160
- data/spec/kitchen/verifier_spec.rb +120 -120
- data/spec/kitchen_spec.rb +114 -114
- data/spec/spec_helper.rb +85 -85
- data/spec/support/powershell_max_size_spec.rb +40 -40
- data/support/busser_install_command.ps1 +14 -14
- data/support/busser_install_command.sh +14 -14
- data/support/chef-client-zero.rb +77 -77
- data/support/chef_base_init_command.ps1 +18 -18
- data/support/chef_base_init_command.sh +2 -2
- data/support/chef_base_install_command.ps1 +85 -85
- data/support/chef_base_install_command.sh +229 -229
- data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
- data/support/chef_zero_prepare_command_legacy.sh +10 -10
- data/support/download_helpers.sh +109 -109
- data/support/dummy-validation.pem +27 -27
- data/templates/driver/CHANGELOG.md.erb +3 -3
- data/templates/driver/Gemfile.erb +3 -3
- data/templates/driver/README.md.erb +64 -64
- data/templates/driver/Rakefile.erb +21 -21
- data/templates/driver/driver.rb.erb +23 -23
- data/templates/driver/gemspec.erb +29 -29
- data/templates/driver/gitignore.erb +17 -17
- data/templates/driver/license_apachev2.erb +15 -15
- data/templates/driver/license_lgplv3.erb +16 -16
- data/templates/driver/license_mit.erb +22 -22
- data/templates/driver/license_reserved.erb +5 -5
- data/templates/driver/tailor.erb +4 -4
- data/templates/driver/travis.yml.erb +11 -11
- data/templates/driver/version.rb.erb +12 -12
- data/templates/init/chefignore.erb +1 -1
- data/templates/init/kitchen.yml.erb +18 -18
- data/test-kitchen.gemspec +62 -62
- data/test/integration/default/default_spec.rb +3 -3
- data/testing_windows.md +37 -37
- metadata +5 -4
|
@@ -1,114 +1,114 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
-
#
|
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
# you may not use this file except in compliance with the License.
|
|
9
|
-
# You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
# See the License for the specific language governing permissions and
|
|
17
|
-
# limitations under the License.
|
|
18
|
-
|
|
19
|
-
require "kitchen/errors"
|
|
20
|
-
require "kitchen/logging"
|
|
21
|
-
|
|
22
|
-
module Kitchen
|
|
23
|
-
|
|
24
|
-
module Provisioner
|
|
25
|
-
|
|
26
|
-
module Chef
|
|
27
|
-
|
|
28
|
-
# Chef cookbook resolver that uses Berkshelf and a Berksfile to calculate
|
|
29
|
-
# dependencies.
|
|
30
|
-
#
|
|
31
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
32
|
-
class Berkshelf
|
|
33
|
-
|
|
34
|
-
include Logging
|
|
35
|
-
|
|
36
|
-
# Creates a new cookbook resolver.
|
|
37
|
-
#
|
|
38
|
-
# @param berksfile [String] path to a Berksfile
|
|
39
|
-
# @param path [String] path in which to vendor the resulting
|
|
40
|
-
# cookbooks
|
|
41
|
-
# @param logger [Kitchen::Logger] a logger to use for output, defaults
|
|
42
|
-
# to `Kitchen.logger`
|
|
43
|
-
def initialize(berksfile, path, logger = Kitchen.logger)
|
|
44
|
-
@berksfile = berksfile
|
|
45
|
-
@path = path
|
|
46
|
-
@logger = logger
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Loads the library code required to use the resolver.
|
|
50
|
-
#
|
|
51
|
-
# @param logger [Kitchen::Logger] a logger to use for output, defaults
|
|
52
|
-
# to `Kitchen.logger`
|
|
53
|
-
def self.load!(logger = Kitchen.logger)
|
|
54
|
-
load_berkshelf!(logger)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Performs the cookbook resolution and vendors the resulting cookbooks
|
|
58
|
-
# in the desired path.
|
|
59
|
-
def resolve
|
|
60
|
-
version = ::Berkshelf::VERSION
|
|
61
|
-
info("Resolving cookbook dependencies with Berkshelf #{version}...")
|
|
62
|
-
debug("Using Berksfile from #{berksfile}")
|
|
63
|
-
|
|
64
|
-
::Berkshelf.ui.mute do
|
|
65
|
-
if ::Berkshelf::Berksfile.method_defined?(:vendor)
|
|
66
|
-
# Berkshelf 3.0 requires the directory to not exist
|
|
67
|
-
FileUtils.rm_rf(path)
|
|
68
|
-
::Berkshelf::Berksfile.from_file(berksfile).vendor(path)
|
|
69
|
-
else
|
|
70
|
-
::Berkshelf::Berksfile.from_file(berksfile).install(:path => path)
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
private
|
|
76
|
-
|
|
77
|
-
# @return [String] path to a Berksfile
|
|
78
|
-
# @api private
|
|
79
|
-
attr_reader :berksfile
|
|
80
|
-
|
|
81
|
-
# @return [String] path in which to vendor the resulting cookbooks
|
|
82
|
-
# @api private
|
|
83
|
-
attr_reader :path
|
|
84
|
-
|
|
85
|
-
# @return [Kitchen::Logger] a logger to use for output
|
|
86
|
-
# @api private
|
|
87
|
-
attr_reader :logger
|
|
88
|
-
|
|
89
|
-
# Load the Berkshelf-specific libary code.
|
|
90
|
-
#
|
|
91
|
-
# @param logger [Kitchen::Logger] the logger to use
|
|
92
|
-
# @raise [UserError] if the library couldn't be loaded
|
|
93
|
-
# @api private
|
|
94
|
-
def self.load_berkshelf!(logger)
|
|
95
|
-
first_load = require "berkshelf"
|
|
96
|
-
|
|
97
|
-
version = ::Berkshelf::VERSION
|
|
98
|
-
if first_load
|
|
99
|
-
logger.debug("Berkshelf #{version} library loaded")
|
|
100
|
-
else
|
|
101
|
-
logger.debug("Berkshelf #{version} previously loaded")
|
|
102
|
-
end
|
|
103
|
-
rescue LoadError => e
|
|
104
|
-
logger.fatal("The `berkshelf' gem is missing and must be installed" \
|
|
105
|
-
" or cannot be properly activated. Run" \
|
|
106
|
-
" `gem install berkshelf` or add the following to your" \
|
|
107
|
-
" Gemfile if you are using Bundler: `gem 'berkshelf'`.")
|
|
108
|
-
raise UserError,
|
|
109
|
-
"Could not load or activate Berkshelf (#{e.message})"
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2013, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
require "kitchen/errors"
|
|
20
|
+
require "kitchen/logging"
|
|
21
|
+
|
|
22
|
+
module Kitchen
|
|
23
|
+
|
|
24
|
+
module Provisioner
|
|
25
|
+
|
|
26
|
+
module Chef
|
|
27
|
+
|
|
28
|
+
# Chef cookbook resolver that uses Berkshelf and a Berksfile to calculate
|
|
29
|
+
# dependencies.
|
|
30
|
+
#
|
|
31
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
32
|
+
class Berkshelf
|
|
33
|
+
|
|
34
|
+
include Logging
|
|
35
|
+
|
|
36
|
+
# Creates a new cookbook resolver.
|
|
37
|
+
#
|
|
38
|
+
# @param berksfile [String] path to a Berksfile
|
|
39
|
+
# @param path [String] path in which to vendor the resulting
|
|
40
|
+
# cookbooks
|
|
41
|
+
# @param logger [Kitchen::Logger] a logger to use for output, defaults
|
|
42
|
+
# to `Kitchen.logger`
|
|
43
|
+
def initialize(berksfile, path, logger = Kitchen.logger)
|
|
44
|
+
@berksfile = berksfile
|
|
45
|
+
@path = path
|
|
46
|
+
@logger = logger
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Loads the library code required to use the resolver.
|
|
50
|
+
#
|
|
51
|
+
# @param logger [Kitchen::Logger] a logger to use for output, defaults
|
|
52
|
+
# to `Kitchen.logger`
|
|
53
|
+
def self.load!(logger = Kitchen.logger)
|
|
54
|
+
load_berkshelf!(logger)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Performs the cookbook resolution and vendors the resulting cookbooks
|
|
58
|
+
# in the desired path.
|
|
59
|
+
def resolve
|
|
60
|
+
version = ::Berkshelf::VERSION
|
|
61
|
+
info("Resolving cookbook dependencies with Berkshelf #{version}...")
|
|
62
|
+
debug("Using Berksfile from #{berksfile}")
|
|
63
|
+
|
|
64
|
+
::Berkshelf.ui.mute do
|
|
65
|
+
if ::Berkshelf::Berksfile.method_defined?(:vendor)
|
|
66
|
+
# Berkshelf 3.0 requires the directory to not exist
|
|
67
|
+
FileUtils.rm_rf(path)
|
|
68
|
+
::Berkshelf::Berksfile.from_file(berksfile).vendor(path)
|
|
69
|
+
else
|
|
70
|
+
::Berkshelf::Berksfile.from_file(berksfile).install(:path => path)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
# @return [String] path to a Berksfile
|
|
78
|
+
# @api private
|
|
79
|
+
attr_reader :berksfile
|
|
80
|
+
|
|
81
|
+
# @return [String] path in which to vendor the resulting cookbooks
|
|
82
|
+
# @api private
|
|
83
|
+
attr_reader :path
|
|
84
|
+
|
|
85
|
+
# @return [Kitchen::Logger] a logger to use for output
|
|
86
|
+
# @api private
|
|
87
|
+
attr_reader :logger
|
|
88
|
+
|
|
89
|
+
# Load the Berkshelf-specific libary code.
|
|
90
|
+
#
|
|
91
|
+
# @param logger [Kitchen::Logger] the logger to use
|
|
92
|
+
# @raise [UserError] if the library couldn't be loaded
|
|
93
|
+
# @api private
|
|
94
|
+
def self.load_berkshelf!(logger)
|
|
95
|
+
first_load = require "berkshelf"
|
|
96
|
+
|
|
97
|
+
version = ::Berkshelf::VERSION
|
|
98
|
+
if first_load
|
|
99
|
+
logger.debug("Berkshelf #{version} library loaded")
|
|
100
|
+
else
|
|
101
|
+
logger.debug("Berkshelf #{version} previously loaded")
|
|
102
|
+
end
|
|
103
|
+
rescue LoadError => e
|
|
104
|
+
logger.fatal("The `berkshelf' gem is missing and must be installed" \
|
|
105
|
+
" or cannot be properly activated. Run" \
|
|
106
|
+
" `gem install berkshelf` or add the following to your" \
|
|
107
|
+
" Gemfile if you are using Bundler: `gem 'berkshelf'`.")
|
|
108
|
+
raise UserError,
|
|
109
|
+
"Could not load or activate Berkshelf (#{e.message})"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -1,322 +1,322 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
-
#
|
|
5
|
-
# Copyright (C) 2015, Fletcher Nichol
|
|
6
|
-
#
|
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
# you may not use this file except in compliance with the License.
|
|
9
|
-
# You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
# See the License for the specific language governing permissions and
|
|
17
|
-
# limitations under the License.
|
|
18
|
-
|
|
19
|
-
module Kitchen
|
|
20
|
-
|
|
21
|
-
module Provisioner
|
|
22
|
-
|
|
23
|
-
module Chef
|
|
24
|
-
|
|
25
|
-
# Internal object to manage common sandbox preparation for
|
|
26
|
-
# Chef-related provisioners.
|
|
27
|
-
#
|
|
28
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
29
|
-
# @api private
|
|
30
|
-
class CommonSandbox
|
|
31
|
-
|
|
32
|
-
include Logging
|
|
33
|
-
|
|
34
|
-
# Constructs a new object, taking config, a sandbox path, and an
|
|
35
|
-
# instance.
|
|
36
|
-
#
|
|
37
|
-
# @param config [Hash] configuration hash
|
|
38
|
-
# @param sandbox_path [String] path to local sandbox directory
|
|
39
|
-
# @param instance [Instance] an instance
|
|
40
|
-
def initialize(config, sandbox_path, instance)
|
|
41
|
-
@config = config
|
|
42
|
-
@sandbox_path = sandbox_path
|
|
43
|
-
@instance = instance
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Populate the sandbox.
|
|
47
|
-
def populate
|
|
48
|
-
prepare_json
|
|
49
|
-
prepare_cache
|
|
50
|
-
prepare_cookbooks
|
|
51
|
-
prepare(:data)
|
|
52
|
-
prepare(:data_bags)
|
|
53
|
-
prepare(:environments)
|
|
54
|
-
prepare(:nodes)
|
|
55
|
-
prepare(:roles)
|
|
56
|
-
prepare(:clients)
|
|
57
|
-
prepare(
|
|
58
|
-
:secret,
|
|
59
|
-
:type => :file,
|
|
60
|
-
:dest_name => "encrypted_data_bag_secret",
|
|
61
|
-
:key_name => :encrypted_data_bag_secret_key_path
|
|
62
|
-
)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
private
|
|
66
|
-
|
|
67
|
-
# @return [Hash] configuration hash
|
|
68
|
-
# @api private
|
|
69
|
-
attr_reader :config
|
|
70
|
-
|
|
71
|
-
# @return [Instance] an instance
|
|
72
|
-
# @api private
|
|
73
|
-
attr_reader :instance
|
|
74
|
-
|
|
75
|
-
# @return [String] path to local sandbox directory
|
|
76
|
-
# @api private
|
|
77
|
-
attr_reader :sandbox_path
|
|
78
|
-
|
|
79
|
-
# Generates a list of all files in the cookbooks directory in the
|
|
80
|
-
# sandbox path.
|
|
81
|
-
#
|
|
82
|
-
# @return [Array<String>] an array of absolute paths to files
|
|
83
|
-
# @api private
|
|
84
|
-
def all_files_in_cookbooks
|
|
85
|
-
Dir.glob(File.join(tmpbooks_dir, "**/*"), File::FNM_DOTMATCH).
|
|
86
|
-
select { |fn| File.file?(fn) && ! %w[. ..].include?(fn) }
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
# @return [String] an absolute path to a Berksfile, relative to the
|
|
90
|
-
# kitchen root
|
|
91
|
-
# @api private
|
|
92
|
-
def berksfile
|
|
93
|
-
File.join(config[:kitchen_root], "Berksfile")
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# @return [String] an absolute path to a Cheffile, relative to the
|
|
97
|
-
# kitchen root
|
|
98
|
-
# @api private
|
|
99
|
-
def cheffile
|
|
100
|
-
File.join(config[:kitchen_root], "Cheffile")
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# @return [String] an absolute path to a cookbooks/ directory, relative
|
|
104
|
-
# to the kitchen root
|
|
105
|
-
# @api private
|
|
106
|
-
def cookbooks_dir
|
|
107
|
-
File.join(config[:kitchen_root], "cookbooks")
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Copies a cookbooks/ directory into the sandbox path.
|
|
111
|
-
#
|
|
112
|
-
# @api private
|
|
113
|
-
def cp_cookbooks
|
|
114
|
-
info("Preparing cookbooks from project directory")
|
|
115
|
-
debug("Using cookbooks from #{cookbooks_dir}")
|
|
116
|
-
|
|
117
|
-
FileUtils.mkdir_p(tmpbooks_dir)
|
|
118
|
-
FileUtils.cp_r(File.join(cookbooks_dir, "."), tmpbooks_dir)
|
|
119
|
-
|
|
120
|
-
cp_site_cookbooks if File.directory?(site_cookbooks_dir)
|
|
121
|
-
cp_this_cookbook if File.exist?(metadata_rb)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Copies a site-cookbooks/ directory into the sandbox path.
|
|
125
|
-
#
|
|
126
|
-
# @api private
|
|
127
|
-
def cp_site_cookbooks
|
|
128
|
-
info("Preparing site-cookbooks from project directory")
|
|
129
|
-
debug("Using cookbooks from #{site_cookbooks_dir}")
|
|
130
|
-
|
|
131
|
-
FileUtils.mkdir_p(tmpsitebooks_dir)
|
|
132
|
-
FileUtils.cp_r(File.join(site_cookbooks_dir, "."), tmpsitebooks_dir)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# Copies the current project, assumed to be a Chef cookbook into the
|
|
136
|
-
# sandbox path.
|
|
137
|
-
#
|
|
138
|
-
# @api private
|
|
139
|
-
def cp_this_cookbook
|
|
140
|
-
info("Preparing current project directory as a cookbook")
|
|
141
|
-
debug("Using metadata.rb from #{metadata_rb}")
|
|
142
|
-
|
|
143
|
-
cb_name = MetadataChopper.extract(metadata_rb).first || raise(UserError,
|
|
144
|
-
"The metadata.rb does not define the 'name' key." \
|
|
145
|
-
" Please add: `name '<cookbook_name>'` to metadata.rb and retry")
|
|
146
|
-
|
|
147
|
-
cb_path = File.join(tmpbooks_dir, cb_name)
|
|
148
|
-
|
|
149
|
-
glob = Dir.glob("#{config[:kitchen_root]}/**")
|
|
150
|
-
|
|
151
|
-
FileUtils.mkdir_p(cb_path)
|
|
152
|
-
FileUtils.cp_r(glob, cb_path)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# Removes all non-cookbook files in the sandbox path.
|
|
156
|
-
#
|
|
157
|
-
# @api private
|
|
158
|
-
def filter_only_cookbook_files
|
|
159
|
-
info("Removing non-cookbook files before transfer")
|
|
160
|
-
FileUtils.rm(all_files_in_cookbooks - only_cookbook_files)
|
|
161
|
-
Dir.glob(File.join(tmpbooks_dir, "**/"), File::FNM_PATHNAME).
|
|
162
|
-
reverse_each { |fn| FileUtils.rmdir(fn) if Dir.entries(fn).size == 2 }
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# @return [Logger] the instance's logger or Test Kitchen's common
|
|
166
|
-
# logger otherwise
|
|
167
|
-
# @api private
|
|
168
|
-
def logger
|
|
169
|
-
instance ? instance.logger : Kitchen.logger
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
# Creates a minimal, no-op cookbook in the sandbox path.
|
|
173
|
-
#
|
|
174
|
-
# @api private
|
|
175
|
-
def make_fake_cookbook
|
|
176
|
-
info("Berksfile, Cheffile, cookbooks/, or metadata.rb not found " \
|
|
177
|
-
"so Chef will run with effectively no cookbooks. Is this intended?")
|
|
178
|
-
name = File.basename(config[:kitchen_root])
|
|
179
|
-
fake_cb = File.join(tmpbooks_dir, name)
|
|
180
|
-
FileUtils.mkdir_p(fake_cb)
|
|
181
|
-
File.open(File.join(fake_cb, "metadata.rb"), "wb") do |file|
|
|
182
|
-
file.write(%{name "#{name}"\n})
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
# @return [String] an absolute path to a metadata.rb, relative to the
|
|
187
|
-
# kitchen root
|
|
188
|
-
# @api private
|
|
189
|
-
def metadata_rb
|
|
190
|
-
File.join(config[:kitchen_root], "metadata.rb")
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# Generates a list of all typical cookbook files needed in a Chef run,
|
|
194
|
-
# located in the cookbooks directory in the sandbox path.
|
|
195
|
-
#
|
|
196
|
-
# @return [Array<String>] an array of absolute paths to files
|
|
197
|
-
# @api private
|
|
198
|
-
def only_cookbook_files
|
|
199
|
-
glob = File.join(tmpbooks_dir, "*", "{#{config[:cookbook_files_glob]}}")
|
|
200
|
-
|
|
201
|
-
Dir.glob(glob, File::FNM_DOTMATCH).
|
|
202
|
-
select { |fn| File.file?(fn) && ! %w[. ..].include?(fn) }
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
# Prepares a generic Chef component source directory or file for
|
|
206
|
-
# inclusion in the sandbox path. These components might includes nodes,
|
|
207
|
-
# roles, etc.
|
|
208
|
-
#
|
|
209
|
-
# @param component [Symbol,String] a component name such as `:node`
|
|
210
|
-
# @param opts [Hash] optional configuration
|
|
211
|
-
# @option opts [Symbol] :type whether the component is a directory or
|
|
212
|
-
# file (default: `:directory`)
|
|
213
|
-
# @option opts [Symbol] :key_name the key name in the config hash from
|
|
214
|
-
# which to pull the source path (default: `"#{component}_path"`)
|
|
215
|
-
# @option opts [String] :dest_name the destination file or directory
|
|
216
|
-
# basename in the sandbox path (default: `component.to_s`)
|
|
217
|
-
# @api private
|
|
218
|
-
def prepare(component, opts = {})
|
|
219
|
-
opts = { :type => :directory }.merge(opts)
|
|
220
|
-
key_name = opts.fetch(:key_name, "#{component}_path")
|
|
221
|
-
src = config[key_name.to_sym]
|
|
222
|
-
return if src.nil?
|
|
223
|
-
|
|
224
|
-
info("Preparing #{component}")
|
|
225
|
-
debug("Using #{component} from #{src}")
|
|
226
|
-
|
|
227
|
-
dest = File.join(sandbox_path, opts.fetch(:dest_name, component.to_s))
|
|
228
|
-
|
|
229
|
-
case opts[:type]
|
|
230
|
-
when :directory
|
|
231
|
-
FileUtils.mkdir_p(dest)
|
|
232
|
-
FileUtils.cp_r(Dir.glob("#{src}/*"), dest)
|
|
233
|
-
when :file
|
|
234
|
-
FileUtils.mkdir_p(File.dirname(dest))
|
|
235
|
-
FileUtils.cp_r(src, dest)
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
# Prepares a cache directory for inclusion in the sandbox path.
|
|
240
|
-
#
|
|
241
|
-
# @api private
|
|
242
|
-
def prepare_cache
|
|
243
|
-
FileUtils.mkdir_p(File.join(sandbox_path, "cache"))
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
# Prepares Chef cookbooks for inclusion in the sandbox path.
|
|
247
|
-
#
|
|
248
|
-
# @api private
|
|
249
|
-
def prepare_cookbooks
|
|
250
|
-
if File.exist?(berksfile)
|
|
251
|
-
resolve_with_berkshelf
|
|
252
|
-
elsif File.exist?(cheffile)
|
|
253
|
-
resolve_with_librarian
|
|
254
|
-
cp_site_cookbooks if File.directory?(site_cookbooks_dir)
|
|
255
|
-
elsif File.directory?(cookbooks_dir)
|
|
256
|
-
cp_cookbooks
|
|
257
|
-
elsif File.exist?(metadata_rb)
|
|
258
|
-
cp_this_cookbook
|
|
259
|
-
else
|
|
260
|
-
make_fake_cookbook
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
filter_only_cookbook_files
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
# Prepares a Chef JSON file, sometimes called a dna.json or
|
|
267
|
-
# first-boot.json, for inclusion in the sandbox path.
|
|
268
|
-
#
|
|
269
|
-
# @api private
|
|
270
|
-
def prepare_json
|
|
271
|
-
dna = config[:attributes].merge(:run_list => config[:run_list])
|
|
272
|
-
|
|
273
|
-
info("Preparing dna.json")
|
|
274
|
-
debug("Creating dna.json from #{dna.inspect}")
|
|
275
|
-
|
|
276
|
-
File.open(File.join(sandbox_path, "dna.json"), "wb") do |file|
|
|
277
|
-
file.write(dna.to_json)
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
# Performs a Berkshelf cookbook resolution inside a common mutex.
|
|
282
|
-
#
|
|
283
|
-
# @api private
|
|
284
|
-
def resolve_with_berkshelf
|
|
285
|
-
Kitchen.mutex.synchronize do
|
|
286
|
-
Chef::Berkshelf.new(berksfile, tmpbooks_dir, logger).resolve
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
# Performs a Librarin-Chef cookbook resolution inside a common mutex.
|
|
291
|
-
#
|
|
292
|
-
# @api private
|
|
293
|
-
def resolve_with_librarian
|
|
294
|
-
Kitchen.mutex.synchronize do
|
|
295
|
-
Chef::Librarian.new(cheffile, tmpbooks_dir, logger).resolve
|
|
296
|
-
end
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
# @return [String] an absolute path to a site-cookbooks/ directory,
|
|
300
|
-
# relative to the kitchen root
|
|
301
|
-
# @api private
|
|
302
|
-
def site_cookbooks_dir
|
|
303
|
-
File.join(config[:kitchen_root], "site-cookbooks")
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
# @return [String] an absolute path to a cookbooks/ directory in the
|
|
307
|
-
# sandbox path
|
|
308
|
-
# @api private
|
|
309
|
-
def tmpbooks_dir
|
|
310
|
-
File.join(sandbox_path, "cookbooks")
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
# @return [String] an absolute path to a site cookbooks directory in the
|
|
314
|
-
# sandbox path
|
|
315
|
-
# @api private
|
|
316
|
-
def tmpsitebooks_dir
|
|
317
|
-
File.join(sandbox_path, "cookbooks")
|
|
318
|
-
end
|
|
319
|
-
end
|
|
320
|
-
end
|
|
321
|
-
end
|
|
322
|
-
end
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2015, Fletcher Nichol
|
|
6
|
+
#
|
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
# you may not use this file except in compliance with the License.
|
|
9
|
+
# You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
# See the License for the specific language governing permissions and
|
|
17
|
+
# limitations under the License.
|
|
18
|
+
|
|
19
|
+
module Kitchen
|
|
20
|
+
|
|
21
|
+
module Provisioner
|
|
22
|
+
|
|
23
|
+
module Chef
|
|
24
|
+
|
|
25
|
+
# Internal object to manage common sandbox preparation for
|
|
26
|
+
# Chef-related provisioners.
|
|
27
|
+
#
|
|
28
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
29
|
+
# @api private
|
|
30
|
+
class CommonSandbox
|
|
31
|
+
|
|
32
|
+
include Logging
|
|
33
|
+
|
|
34
|
+
# Constructs a new object, taking config, a sandbox path, and an
|
|
35
|
+
# instance.
|
|
36
|
+
#
|
|
37
|
+
# @param config [Hash] configuration hash
|
|
38
|
+
# @param sandbox_path [String] path to local sandbox directory
|
|
39
|
+
# @param instance [Instance] an instance
|
|
40
|
+
def initialize(config, sandbox_path, instance)
|
|
41
|
+
@config = config
|
|
42
|
+
@sandbox_path = sandbox_path
|
|
43
|
+
@instance = instance
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Populate the sandbox.
|
|
47
|
+
def populate
|
|
48
|
+
prepare_json
|
|
49
|
+
prepare_cache
|
|
50
|
+
prepare_cookbooks
|
|
51
|
+
prepare(:data)
|
|
52
|
+
prepare(:data_bags)
|
|
53
|
+
prepare(:environments)
|
|
54
|
+
prepare(:nodes)
|
|
55
|
+
prepare(:roles)
|
|
56
|
+
prepare(:clients)
|
|
57
|
+
prepare(
|
|
58
|
+
:secret,
|
|
59
|
+
:type => :file,
|
|
60
|
+
:dest_name => "encrypted_data_bag_secret",
|
|
61
|
+
:key_name => :encrypted_data_bag_secret_key_path
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
# @return [Hash] configuration hash
|
|
68
|
+
# @api private
|
|
69
|
+
attr_reader :config
|
|
70
|
+
|
|
71
|
+
# @return [Instance] an instance
|
|
72
|
+
# @api private
|
|
73
|
+
attr_reader :instance
|
|
74
|
+
|
|
75
|
+
# @return [String] path to local sandbox directory
|
|
76
|
+
# @api private
|
|
77
|
+
attr_reader :sandbox_path
|
|
78
|
+
|
|
79
|
+
# Generates a list of all files in the cookbooks directory in the
|
|
80
|
+
# sandbox path.
|
|
81
|
+
#
|
|
82
|
+
# @return [Array<String>] an array of absolute paths to files
|
|
83
|
+
# @api private
|
|
84
|
+
def all_files_in_cookbooks
|
|
85
|
+
Dir.glob(File.join(tmpbooks_dir, "**/*"), File::FNM_DOTMATCH).
|
|
86
|
+
select { |fn| File.file?(fn) && ! %w[. ..].include?(fn) }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# @return [String] an absolute path to a Berksfile, relative to the
|
|
90
|
+
# kitchen root
|
|
91
|
+
# @api private
|
|
92
|
+
def berksfile
|
|
93
|
+
File.join(config[:kitchen_root], "Berksfile")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# @return [String] an absolute path to a Cheffile, relative to the
|
|
97
|
+
# kitchen root
|
|
98
|
+
# @api private
|
|
99
|
+
def cheffile
|
|
100
|
+
File.join(config[:kitchen_root], "Cheffile")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @return [String] an absolute path to a cookbooks/ directory, relative
|
|
104
|
+
# to the kitchen root
|
|
105
|
+
# @api private
|
|
106
|
+
def cookbooks_dir
|
|
107
|
+
File.join(config[:kitchen_root], "cookbooks")
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Copies a cookbooks/ directory into the sandbox path.
|
|
111
|
+
#
|
|
112
|
+
# @api private
|
|
113
|
+
def cp_cookbooks
|
|
114
|
+
info("Preparing cookbooks from project directory")
|
|
115
|
+
debug("Using cookbooks from #{cookbooks_dir}")
|
|
116
|
+
|
|
117
|
+
FileUtils.mkdir_p(tmpbooks_dir)
|
|
118
|
+
FileUtils.cp_r(File.join(cookbooks_dir, "."), tmpbooks_dir)
|
|
119
|
+
|
|
120
|
+
cp_site_cookbooks if File.directory?(site_cookbooks_dir)
|
|
121
|
+
cp_this_cookbook if File.exist?(metadata_rb)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Copies a site-cookbooks/ directory into the sandbox path.
|
|
125
|
+
#
|
|
126
|
+
# @api private
|
|
127
|
+
def cp_site_cookbooks
|
|
128
|
+
info("Preparing site-cookbooks from project directory")
|
|
129
|
+
debug("Using cookbooks from #{site_cookbooks_dir}")
|
|
130
|
+
|
|
131
|
+
FileUtils.mkdir_p(tmpsitebooks_dir)
|
|
132
|
+
FileUtils.cp_r(File.join(site_cookbooks_dir, "."), tmpsitebooks_dir)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Copies the current project, assumed to be a Chef cookbook into the
|
|
136
|
+
# sandbox path.
|
|
137
|
+
#
|
|
138
|
+
# @api private
|
|
139
|
+
def cp_this_cookbook
|
|
140
|
+
info("Preparing current project directory as a cookbook")
|
|
141
|
+
debug("Using metadata.rb from #{metadata_rb}")
|
|
142
|
+
|
|
143
|
+
cb_name = MetadataChopper.extract(metadata_rb).first || raise(UserError,
|
|
144
|
+
"The metadata.rb does not define the 'name' key." \
|
|
145
|
+
" Please add: `name '<cookbook_name>'` to metadata.rb and retry")
|
|
146
|
+
|
|
147
|
+
cb_path = File.join(tmpbooks_dir, cb_name)
|
|
148
|
+
|
|
149
|
+
glob = Dir.glob("#{config[:kitchen_root]}/**")
|
|
150
|
+
|
|
151
|
+
FileUtils.mkdir_p(cb_path)
|
|
152
|
+
FileUtils.cp_r(glob, cb_path)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Removes all non-cookbook files in the sandbox path.
|
|
156
|
+
#
|
|
157
|
+
# @api private
|
|
158
|
+
def filter_only_cookbook_files
|
|
159
|
+
info("Removing non-cookbook files before transfer")
|
|
160
|
+
FileUtils.rm(all_files_in_cookbooks - only_cookbook_files)
|
|
161
|
+
Dir.glob(File.join(tmpbooks_dir, "**/"), File::FNM_PATHNAME).
|
|
162
|
+
reverse_each { |fn| FileUtils.rmdir(fn) if Dir.entries(fn).size == 2 }
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# @return [Logger] the instance's logger or Test Kitchen's common
|
|
166
|
+
# logger otherwise
|
|
167
|
+
# @api private
|
|
168
|
+
def logger
|
|
169
|
+
instance ? instance.logger : Kitchen.logger
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Creates a minimal, no-op cookbook in the sandbox path.
|
|
173
|
+
#
|
|
174
|
+
# @api private
|
|
175
|
+
def make_fake_cookbook
|
|
176
|
+
info("Berksfile, Cheffile, cookbooks/, or metadata.rb not found " \
|
|
177
|
+
"so Chef will run with effectively no cookbooks. Is this intended?")
|
|
178
|
+
name = File.basename(config[:kitchen_root])
|
|
179
|
+
fake_cb = File.join(tmpbooks_dir, name)
|
|
180
|
+
FileUtils.mkdir_p(fake_cb)
|
|
181
|
+
File.open(File.join(fake_cb, "metadata.rb"), "wb") do |file|
|
|
182
|
+
file.write(%{name "#{name}"\n})
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# @return [String] an absolute path to a metadata.rb, relative to the
|
|
187
|
+
# kitchen root
|
|
188
|
+
# @api private
|
|
189
|
+
def metadata_rb
|
|
190
|
+
File.join(config[:kitchen_root], "metadata.rb")
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Generates a list of all typical cookbook files needed in a Chef run,
|
|
194
|
+
# located in the cookbooks directory in the sandbox path.
|
|
195
|
+
#
|
|
196
|
+
# @return [Array<String>] an array of absolute paths to files
|
|
197
|
+
# @api private
|
|
198
|
+
def only_cookbook_files
|
|
199
|
+
glob = File.join(tmpbooks_dir, "*", "{#{config[:cookbook_files_glob]}}")
|
|
200
|
+
|
|
201
|
+
Dir.glob(glob, File::FNM_DOTMATCH).
|
|
202
|
+
select { |fn| File.file?(fn) && ! %w[. ..].include?(fn) }
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Prepares a generic Chef component source directory or file for
|
|
206
|
+
# inclusion in the sandbox path. These components might includes nodes,
|
|
207
|
+
# roles, etc.
|
|
208
|
+
#
|
|
209
|
+
# @param component [Symbol,String] a component name such as `:node`
|
|
210
|
+
# @param opts [Hash] optional configuration
|
|
211
|
+
# @option opts [Symbol] :type whether the component is a directory or
|
|
212
|
+
# file (default: `:directory`)
|
|
213
|
+
# @option opts [Symbol] :key_name the key name in the config hash from
|
|
214
|
+
# which to pull the source path (default: `"#{component}_path"`)
|
|
215
|
+
# @option opts [String] :dest_name the destination file or directory
|
|
216
|
+
# basename in the sandbox path (default: `component.to_s`)
|
|
217
|
+
# @api private
|
|
218
|
+
def prepare(component, opts = {})
|
|
219
|
+
opts = { :type => :directory }.merge(opts)
|
|
220
|
+
key_name = opts.fetch(:key_name, "#{component}_path")
|
|
221
|
+
src = config[key_name.to_sym]
|
|
222
|
+
return if src.nil?
|
|
223
|
+
|
|
224
|
+
info("Preparing #{component}")
|
|
225
|
+
debug("Using #{component} from #{src}")
|
|
226
|
+
|
|
227
|
+
dest = File.join(sandbox_path, opts.fetch(:dest_name, component.to_s))
|
|
228
|
+
|
|
229
|
+
case opts[:type]
|
|
230
|
+
when :directory
|
|
231
|
+
FileUtils.mkdir_p(dest)
|
|
232
|
+
FileUtils.cp_r(Dir.glob("#{src}/*"), dest)
|
|
233
|
+
when :file
|
|
234
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
235
|
+
FileUtils.cp_r(src, dest)
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Prepares a cache directory for inclusion in the sandbox path.
|
|
240
|
+
#
|
|
241
|
+
# @api private
|
|
242
|
+
def prepare_cache
|
|
243
|
+
FileUtils.mkdir_p(File.join(sandbox_path, "cache"))
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Prepares Chef cookbooks for inclusion in the sandbox path.
|
|
247
|
+
#
|
|
248
|
+
# @api private
|
|
249
|
+
def prepare_cookbooks
|
|
250
|
+
if File.exist?(berksfile)
|
|
251
|
+
resolve_with_berkshelf
|
|
252
|
+
elsif File.exist?(cheffile)
|
|
253
|
+
resolve_with_librarian
|
|
254
|
+
cp_site_cookbooks if File.directory?(site_cookbooks_dir)
|
|
255
|
+
elsif File.directory?(cookbooks_dir)
|
|
256
|
+
cp_cookbooks
|
|
257
|
+
elsif File.exist?(metadata_rb)
|
|
258
|
+
cp_this_cookbook
|
|
259
|
+
else
|
|
260
|
+
make_fake_cookbook
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
filter_only_cookbook_files
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Prepares a Chef JSON file, sometimes called a dna.json or
|
|
267
|
+
# first-boot.json, for inclusion in the sandbox path.
|
|
268
|
+
#
|
|
269
|
+
# @api private
|
|
270
|
+
def prepare_json
|
|
271
|
+
dna = config[:attributes].merge(:run_list => config[:run_list])
|
|
272
|
+
|
|
273
|
+
info("Preparing dna.json")
|
|
274
|
+
debug("Creating dna.json from #{dna.inspect}")
|
|
275
|
+
|
|
276
|
+
File.open(File.join(sandbox_path, "dna.json"), "wb") do |file|
|
|
277
|
+
file.write(dna.to_json)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Performs a Berkshelf cookbook resolution inside a common mutex.
|
|
282
|
+
#
|
|
283
|
+
# @api private
|
|
284
|
+
def resolve_with_berkshelf
|
|
285
|
+
Kitchen.mutex.synchronize do
|
|
286
|
+
Chef::Berkshelf.new(berksfile, tmpbooks_dir, logger).resolve
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Performs a Librarin-Chef cookbook resolution inside a common mutex.
|
|
291
|
+
#
|
|
292
|
+
# @api private
|
|
293
|
+
def resolve_with_librarian
|
|
294
|
+
Kitchen.mutex.synchronize do
|
|
295
|
+
Chef::Librarian.new(cheffile, tmpbooks_dir, logger).resolve
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# @return [String] an absolute path to a site-cookbooks/ directory,
|
|
300
|
+
# relative to the kitchen root
|
|
301
|
+
# @api private
|
|
302
|
+
def site_cookbooks_dir
|
|
303
|
+
File.join(config[:kitchen_root], "site-cookbooks")
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# @return [String] an absolute path to a cookbooks/ directory in the
|
|
307
|
+
# sandbox path
|
|
308
|
+
# @api private
|
|
309
|
+
def tmpbooks_dir
|
|
310
|
+
File.join(sandbox_path, "cookbooks")
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# @return [String] an absolute path to a site cookbooks directory in the
|
|
314
|
+
# sandbox path
|
|
315
|
+
# @api private
|
|
316
|
+
def tmpsitebooks_dir
|
|
317
|
+
File.join(sandbox_path, "cookbooks")
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|