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.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +8 -8
  3. data/.gitattributes +3 -0
  4. data/.github/ISSUE_TEMPLATE.md +55 -55
  5. data/.gitignore +28 -28
  6. data/.kitchen.ci.yml +23 -23
  7. data/.kitchen.proxy.yml +27 -27
  8. data/.rubocop.yml +3 -3
  9. data/.travis.yml +70 -70
  10. data/.yardopts +3 -3
  11. data/Berksfile +3 -3
  12. data/CHANGELOG.md +1090 -1083
  13. data/CONTRIBUTING.md +14 -14
  14. data/Gemfile +19 -19
  15. data/Gemfile.proxy_tests +4 -4
  16. data/Guardfile +42 -42
  17. data/LICENSE +15 -15
  18. data/MAINTAINERS.md +23 -23
  19. data/README.md +135 -135
  20. data/Rakefile +61 -61
  21. data/appveyor.yml +44 -44
  22. data/features/kitchen_action_commands.feature +164 -164
  23. data/features/kitchen_command.feature +16 -16
  24. data/features/kitchen_console_command.feature +34 -34
  25. data/features/kitchen_defaults.feature +38 -38
  26. data/features/kitchen_diagnose_command.feature +96 -96
  27. data/features/kitchen_driver_create_command.feature +64 -64
  28. data/features/kitchen_driver_discover_command.feature +25 -25
  29. data/features/kitchen_help_command.feature +16 -16
  30. data/features/kitchen_init_command.feature +274 -274
  31. data/features/kitchen_list_command.feature +104 -104
  32. data/features/kitchen_login_command.feature +62 -62
  33. data/features/kitchen_sink_command.feature +30 -30
  34. data/features/kitchen_test_command.feature +88 -88
  35. data/features/step_definitions/gem_steps.rb +36 -36
  36. data/features/step_definitions/git_steps.rb +5 -5
  37. data/features/step_definitions/output_steps.rb +5 -5
  38. data/features/support/env.rb +75 -75
  39. data/lib/kitchen.rb +150 -150
  40. data/lib/kitchen/base64_stream.rb +55 -55
  41. data/lib/kitchen/cli.rb +419 -419
  42. data/lib/kitchen/collection.rb +55 -55
  43. data/lib/kitchen/color.rb +65 -65
  44. data/lib/kitchen/command.rb +185 -185
  45. data/lib/kitchen/command/action.rb +45 -45
  46. data/lib/kitchen/command/console.rb +58 -58
  47. data/lib/kitchen/command/diagnose.rb +92 -92
  48. data/lib/kitchen/command/driver_discover.rb +105 -105
  49. data/lib/kitchen/command/exec.rb +41 -41
  50. data/lib/kitchen/command/list.rb +119 -119
  51. data/lib/kitchen/command/login.rb +43 -43
  52. data/lib/kitchen/command/sink.rb +54 -54
  53. data/lib/kitchen/command/test.rb +51 -51
  54. data/lib/kitchen/config.rb +322 -322
  55. data/lib/kitchen/configurable.rb +529 -529
  56. data/lib/kitchen/data_munger.rb +959 -959
  57. data/lib/kitchen/diagnostic.rb +141 -141
  58. data/lib/kitchen/driver.rb +56 -56
  59. data/lib/kitchen/driver/base.rb +134 -134
  60. data/lib/kitchen/driver/dummy.rb +108 -108
  61. data/lib/kitchen/driver/proxy.rb +72 -72
  62. data/lib/kitchen/driver/ssh_base.rb +357 -357
  63. data/lib/kitchen/errors.rb +229 -229
  64. data/lib/kitchen/generator/driver_create.rb +177 -177
  65. data/lib/kitchen/generator/init.rb +296 -296
  66. data/lib/kitchen/instance.rb +662 -662
  67. data/lib/kitchen/lazy_hash.rb +142 -142
  68. data/lib/kitchen/loader/yaml.rb +349 -349
  69. data/lib/kitchen/logger.rb +423 -423
  70. data/lib/kitchen/logging.rb +56 -56
  71. data/lib/kitchen/login_command.rb +52 -52
  72. data/lib/kitchen/metadata_chopper.rb +52 -52
  73. data/lib/kitchen/platform.rb +67 -67
  74. data/lib/kitchen/provisioner.rb +54 -54
  75. data/lib/kitchen/provisioner/base.rb +236 -236
  76. data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
  77. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
  78. data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
  79. data/lib/kitchen/provisioner/chef_apply.rb +124 -124
  80. data/lib/kitchen/provisioner/chef_base.rb +341 -341
  81. data/lib/kitchen/provisioner/chef_solo.rb +88 -88
  82. data/lib/kitchen/provisioner/chef_zero.rb +245 -245
  83. data/lib/kitchen/provisioner/dummy.rb +79 -79
  84. data/lib/kitchen/provisioner/shell.rb +138 -138
  85. data/lib/kitchen/rake_tasks.rb +63 -63
  86. data/lib/kitchen/shell_out.rb +93 -93
  87. data/lib/kitchen/ssh.rb +276 -276
  88. data/lib/kitchen/state_file.rb +120 -120
  89. data/lib/kitchen/suite.rb +51 -51
  90. data/lib/kitchen/thor_tasks.rb +66 -66
  91. data/lib/kitchen/transport.rb +54 -54
  92. data/lib/kitchen/transport/base.rb +176 -176
  93. data/lib/kitchen/transport/dummy.rb +79 -79
  94. data/lib/kitchen/transport/ssh.rb +364 -364
  95. data/lib/kitchen/transport/winrm.rb +486 -486
  96. data/lib/kitchen/util.rb +147 -147
  97. data/lib/kitchen/verifier.rb +55 -55
  98. data/lib/kitchen/verifier/base.rb +235 -235
  99. data/lib/kitchen/verifier/busser.rb +277 -277
  100. data/lib/kitchen/verifier/dummy.rb +79 -79
  101. data/lib/kitchen/verifier/shell.rb +101 -101
  102. data/lib/kitchen/version.rb +21 -21
  103. data/lib/vendor/hash_recursive_merge.rb +82 -82
  104. data/spec/kitchen/base64_stream_spec.rb +77 -77
  105. data/spec/kitchen/cli_spec.rb +56 -56
  106. data/spec/kitchen/collection_spec.rb +80 -80
  107. data/spec/kitchen/color_spec.rb +54 -54
  108. data/spec/kitchen/config_spec.rb +408 -408
  109. data/spec/kitchen/configurable_spec.rb +1095 -1095
  110. data/spec/kitchen/data_munger_spec.rb +2694 -2694
  111. data/spec/kitchen/diagnostic_spec.rb +129 -129
  112. data/spec/kitchen/driver/base_spec.rb +121 -121
  113. data/spec/kitchen/driver/dummy_spec.rb +199 -199
  114. data/spec/kitchen/driver/proxy_spec.rb +138 -138
  115. data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
  116. data/spec/kitchen/driver_spec.rb +112 -112
  117. data/spec/kitchen/errors_spec.rb +309 -309
  118. data/spec/kitchen/instance_spec.rb +1419 -1419
  119. data/spec/kitchen/lazy_hash_spec.rb +117 -117
  120. data/spec/kitchen/loader/yaml_spec.rb +774 -774
  121. data/spec/kitchen/logger_spec.rb +429 -429
  122. data/spec/kitchen/logging_spec.rb +59 -59
  123. data/spec/kitchen/login_command_spec.rb +68 -68
  124. data/spec/kitchen/metadata_chopper_spec.rb +82 -82
  125. data/spec/kitchen/platform_spec.rb +89 -89
  126. data/spec/kitchen/provisioner/base_spec.rb +386 -386
  127. data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
  128. data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1161
  129. data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
  130. data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
  131. data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
  132. data/spec/kitchen/provisioner/shell_spec.rb +566 -566
  133. data/spec/kitchen/provisioner_spec.rb +107 -107
  134. data/spec/kitchen/shell_out_spec.rb +150 -150
  135. data/spec/kitchen/ssh_spec.rb +693 -693
  136. data/spec/kitchen/state_file_spec.rb +129 -129
  137. data/spec/kitchen/suite_spec.rb +62 -62
  138. data/spec/kitchen/transport/base_spec.rb +89 -89
  139. data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
  140. data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
  141. data/spec/kitchen/transport_spec.rb +112 -112
  142. data/spec/kitchen/util_spec.rb +165 -165
  143. data/spec/kitchen/verifier/base_spec.rb +362 -362
  144. data/spec/kitchen/verifier/busser_spec.rb +610 -610
  145. data/spec/kitchen/verifier/dummy_spec.rb +99 -99
  146. data/spec/kitchen/verifier/shell_spec.rb +160 -160
  147. data/spec/kitchen/verifier_spec.rb +120 -120
  148. data/spec/kitchen_spec.rb +114 -114
  149. data/spec/spec_helper.rb +85 -85
  150. data/spec/support/powershell_max_size_spec.rb +40 -40
  151. data/support/busser_install_command.ps1 +14 -14
  152. data/support/busser_install_command.sh +14 -14
  153. data/support/chef-client-zero.rb +77 -77
  154. data/support/chef_base_init_command.ps1 +18 -18
  155. data/support/chef_base_init_command.sh +2 -2
  156. data/support/chef_base_install_command.ps1 +85 -85
  157. data/support/chef_base_install_command.sh +229 -229
  158. data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
  159. data/support/chef_zero_prepare_command_legacy.sh +10 -10
  160. data/support/download_helpers.sh +109 -109
  161. data/support/dummy-validation.pem +27 -27
  162. data/templates/driver/CHANGELOG.md.erb +3 -3
  163. data/templates/driver/Gemfile.erb +3 -3
  164. data/templates/driver/README.md.erb +64 -64
  165. data/templates/driver/Rakefile.erb +21 -21
  166. data/templates/driver/driver.rb.erb +23 -23
  167. data/templates/driver/gemspec.erb +29 -29
  168. data/templates/driver/gitignore.erb +17 -17
  169. data/templates/driver/license_apachev2.erb +15 -15
  170. data/templates/driver/license_lgplv3.erb +16 -16
  171. data/templates/driver/license_mit.erb +22 -22
  172. data/templates/driver/license_reserved.erb +5 -5
  173. data/templates/driver/tailor.erb +4 -4
  174. data/templates/driver/travis.yml.erb +11 -11
  175. data/templates/driver/version.rb.erb +12 -12
  176. data/templates/init/chefignore.erb +1 -1
  177. data/templates/init/kitchen.yml.erb +18 -18
  178. data/test-kitchen.gemspec +62 -62
  179. data/test/integration/default/default_spec.rb +3 -3
  180. data/testing_windows.md +37 -37
  181. 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