chef-dk 2.4.17 → 2.5.3
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 +5 -5
- data/Gemfile +121 -119
- data/Gemfile.lock +802 -817
- data/LICENSE +201 -201
- data/README.md +333 -333
- data/Rakefile +74 -74
- data/acceptance/.shared/kitchen_acceptance/.kitchen.digitalocean.yml +27 -27
- data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +287 -287
- data/acceptance/.shared/kitchen_acceptance/.kitchen.vagrant.yml +52 -52
- data/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +51 -51
- data/acceptance/.shared/kitchen_acceptance/metadata.rb +1 -1
- data/acceptance/Gemfile +21 -20
- data/acceptance/Gemfile.lock +334 -334
- data/acceptance/README.md +132 -132
- data/acceptance/trivial/.acceptance/acceptance-cookbook/.gitignore +2 -2
- data/acceptance/trivial/.acceptance/acceptance-cookbook/metadata.rb +2 -2
- data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/destroy.rb +1 -1
- data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -1
- data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/verify.rb +1 -1
- data/acceptance/trivial/.kitchen.yml +7 -7
- data/acceptance/trivial/test/integration/chefdk-current-install/inspec/chef_client_spec.rb +5 -5
- data/bin/chef +25 -25
- data/chef-dk.gemspec +60 -60
- data/lib/chef-dk.rb +19 -19
- data/lib/chef-dk/authenticated_http.rb +22 -22
- data/lib/chef-dk/builtin_commands.rb +59 -59
- data/lib/chef-dk/chef_runner.rb +114 -114
- data/lib/chef-dk/chef_server_api_multi.rb +73 -73
- data/lib/chef-dk/cli.rb +201 -201
- data/lib/chef-dk/command/base.rb +79 -79
- data/lib/chef-dk/command/clean_policy_cookbooks.rb +114 -114
- data/lib/chef-dk/command/clean_policy_revisions.rb +111 -111
- data/lib/chef-dk/command/delete_policy.rb +120 -120
- data/lib/chef-dk/command/delete_policy_group.rb +120 -120
- data/lib/chef-dk/command/diff.rb +315 -315
- data/lib/chef-dk/command/env.rb +89 -89
- data/lib/chef-dk/command/exec.rb +44 -44
- data/lib/chef-dk/command/export.rb +155 -155
- data/lib/chef-dk/command/gem.rb +47 -47
- data/lib/chef-dk/command/generate.rb +125 -125
- data/lib/chef-dk/command/generator_commands.rb +83 -83
- data/lib/chef-dk/command/generator_commands/app.rb +106 -106
- data/lib/chef-dk/command/generator_commands/attribute.rb +36 -36
- data/lib/chef-dk/command/generator_commands/base.rb +157 -157
- data/lib/chef-dk/command/generator_commands/build_cookbook.rb +125 -125
- data/lib/chef-dk/command/generator_commands/chef_exts/generator_desc_resource.rb +85 -85
- data/lib/chef-dk/command/generator_commands/chef_exts/quieter_doc_formatter.rb +38 -38
- data/lib/chef-dk/command/generator_commands/chef_exts/recipe_dsl_ext.rb +39 -39
- data/lib/chef-dk/command/generator_commands/cookbook.rb +241 -241
- data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
- data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
- data/lib/chef-dk/command/generator_commands/generator_generator.rb +174 -174
- data/lib/chef-dk/command/generator_commands/helpers.rb +36 -36
- data/lib/chef-dk/command/generator_commands/policyfile.rb +126 -126
- data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
- data/lib/chef-dk/command/generator_commands/repo.rb +123 -123
- data/lib/chef-dk/command/generator_commands/resource.rb +36 -36
- data/lib/chef-dk/command/generator_commands/template.rb +46 -46
- data/lib/chef-dk/command/install.rb +120 -120
- data/lib/chef-dk/command/provision.rb +436 -436
- data/lib/chef-dk/command/push.rb +117 -117
- data/lib/chef-dk/command/push_archive.rb +125 -125
- data/lib/chef-dk/command/shell_init.rb +179 -179
- data/lib/chef-dk/command/show_policy.rb +163 -163
- data/lib/chef-dk/command/undelete.rb +154 -154
- data/lib/chef-dk/command/update.rb +133 -133
- data/lib/chef-dk/command/verify.rb +629 -629
- data/lib/chef-dk/commands_map.rb +113 -113
- data/lib/chef-dk/completions/bash.sh.erb +5 -5
- data/lib/chef-dk/completions/chef.fish.erb +10 -10
- data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
- data/lib/chef-dk/component_test.rb +227 -227
- data/lib/chef-dk/configurable.rb +88 -88
- data/lib/chef-dk/cookbook_metadata.rb +45 -45
- data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
- data/lib/chef-dk/cookbook_profiler/git.rb +151 -151
- data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
- data/lib/chef-dk/cookbook_profiler/null_scm.rb +31 -31
- data/lib/chef-dk/exceptions.rb +150 -150
- data/lib/chef-dk/generator.rb +165 -165
- data/lib/chef-dk/helpers.rb +176 -176
- data/lib/chef-dk/pager.rb +105 -105
- data/lib/chef-dk/policyfile/artifactory_cookbook_source.rb +102 -102
- data/lib/chef-dk/policyfile/attribute_merge_checker.rb +110 -110
- data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
- data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +99 -99
- data/lib/chef-dk/policyfile/chef_server_lock_fetcher.rb +164 -164
- data/lib/chef-dk/policyfile/community_cookbook_source.rb +95 -95
- data/lib/chef-dk/policyfile/comparison_base.rb +123 -123
- data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
- data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
- data/lib/chef-dk/policyfile/cookbook_sources.rb +23 -23
- data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +89 -89
- data/lib/chef-dk/policyfile/differ.rb +263 -263
- data/lib/chef-dk/policyfile/dsl.rb +288 -288
- data/lib/chef-dk/policyfile/included_policies_cookbook_source.rb +156 -156
- data/lib/chef-dk/policyfile/lister.rb +229 -229
- data/lib/chef-dk/policyfile/local_lock_fetcher.rb +123 -122
- data/lib/chef-dk/policyfile/lock_applier.rb +80 -80
- data/lib/chef-dk/policyfile/null_cookbook_source.rb +49 -49
- data/lib/chef-dk/policyfile/policyfile_location_specification.rb +122 -122
- data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
- data/lib/chef-dk/policyfile/reports/install.rb +69 -69
- data/lib/chef-dk/policyfile/reports/table_printer.rb +57 -57
- data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
- data/lib/chef-dk/policyfile/solution_dependencies.rb +312 -312
- data/lib/chef-dk/policyfile/source_uri.rb +57 -57
- data/lib/chef-dk/policyfile/storage_config.rb +102 -102
- data/lib/chef-dk/policyfile/undo_record.rb +139 -139
- data/lib/chef-dk/policyfile/undo_stack.rb +128 -128
- data/lib/chef-dk/policyfile/uploader.rb +213 -213
- data/lib/chef-dk/policyfile_compiler.rb +528 -528
- data/lib/chef-dk/policyfile_lock.rb +581 -581
- data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
- data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +123 -123
- data/lib/chef-dk/policyfile_services/export_repo.rb +420 -420
- data/lib/chef-dk/policyfile_services/install.rb +162 -162
- data/lib/chef-dk/policyfile_services/push.rb +112 -112
- data/lib/chef-dk/policyfile_services/push_archive.rb +200 -200
- data/lib/chef-dk/policyfile_services/rm_policy.rb +141 -141
- data/lib/chef-dk/policyfile_services/rm_policy_group.rb +85 -85
- data/lib/chef-dk/policyfile_services/show_policy.rb +236 -236
- data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
- data/lib/chef-dk/policyfile_services/update_attributes.rb +110 -110
- data/lib/chef-dk/service_exception_inspectors.rb +24 -24
- data/lib/chef-dk/service_exception_inspectors/base.rb +39 -39
- data/lib/chef-dk/service_exception_inspectors/http.rb +119 -119
- data/lib/chef-dk/service_exceptions.rb +142 -142
- data/lib/chef-dk/shell_out.rb +36 -36
- data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +4 -4
- data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/.kitchen.yml +21 -21
- data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/README.md +146 -146
- data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/test-fixture-recipe.rb +9 -9
- data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +107 -107
- data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
- data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -54
- data/lib/chef-dk/skeletons/code_generator/files/default/delivery-config.json +17 -17
- data/lib/chef-dk/skeletons/code_generator/files/default/delivery-project.toml +36 -36
- data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +22 -22
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +24 -24
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +8 -8
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +7 -7
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +9 -9
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +56 -56
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -24
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
- data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +3 -3
- data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +3 -3
- data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
- data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +89 -89
- data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +13 -13
- data/lib/chef-dk/skeletons/code_generator/recipes/build_cookbook.rb +177 -177
- data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +152 -152
- data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +25 -25
- data/lib/chef-dk/skeletons/code_generator/recipes/helpers.rb +21 -21
- data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +9 -9
- data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +52 -52
- data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +68 -68
- data/lib/chef-dk/skeletons/code_generator/recipes/resource.rb +13 -13
- data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apachev2.erb +201 -201
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
- data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
- data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
- data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
- data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/Berksfile.erb +7 -7
- data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/metadata.rb.erb +10 -10
- data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/recipe.rb.erb +8 -8
- data/lib/chef-dk/skeletons/code_generator/templates/default/helpers.rb.erb +39 -39
- data/lib/chef-dk/skeletons/code_generator/templates/default/inspec_default_test.rb.erb +18 -18
- data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +26 -26
- data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +33 -33
- data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +20 -20
- data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
- data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +35 -35
- data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +128 -128
- data/lib/chef-dk/skeletons/code_generator/templates/default/resource.rb.erb +1 -1
- data/lib/chef-dk/ui.rb +57 -57
- data/lib/chef-dk/version.rb +20 -20
- data/lib/kitchen/provisioner/policyfile_zero.rb +195 -195
- data/omnibus_overrides.rb +22 -22
- data/spec/shared/a_file_generator.rb +125 -125
- data/spec/shared/a_generated_file.rb +12 -12
- data/spec/shared/command_with_ui_object.rb +11 -11
- data/spec/shared/custom_generator_cookbook.rb +136 -136
- data/spec/shared/fixture_cookbook_checksums.rb +46 -46
- data/spec/shared/setup_git_committer_config.rb +54 -54
- data/spec/shared/setup_git_cookbooks.rb +53 -53
- data/spec/spec_helper.rb +51 -51
- data/spec/test_helpers.rb +84 -84
- data/spec/unit/chef_runner_spec.rb +139 -139
- data/spec/unit/chef_server_api_multi_spec.rb +120 -120
- data/spec/unit/cli_spec.rb +377 -377
- data/spec/unit/command/base_spec.rb +172 -172
- data/spec/unit/command/clean_policy_cookbooks_spec.rb +180 -180
- data/spec/unit/command/clean_policy_revisions_spec.rb +180 -180
- data/spec/unit/command/delete_policy_group_spec.rb +206 -206
- data/spec/unit/command/delete_policy_spec.rb +206 -206
- data/spec/unit/command/diff_spec.rb +311 -311
- data/spec/unit/command/env_spec.rb +52 -52
- data/spec/unit/command/exec_spec.rb +178 -178
- data/spec/unit/command/export_spec.rb +199 -199
- data/spec/unit/command/generate_spec.rb +142 -142
- data/spec/unit/command/generator_commands/app_spec.rb +166 -166
- data/spec/unit/command/generator_commands/attribute_spec.rb +31 -31
- data/spec/unit/command/generator_commands/base_spec.rb +181 -181
- data/spec/unit/command/generator_commands/build_cookbook_spec.rb +377 -377
- data/spec/unit/command/generator_commands/chef_exts/generator_desc_resource_spec.rb +97 -97
- data/spec/unit/command/generator_commands/chef_exts/recipe_dsl_ext_spec.rb +111 -111
- data/spec/unit/command/generator_commands/cookbook_file_spec.rb +31 -31
- data/spec/unit/command/generator_commands/cookbook_spec.rb +756 -756
- data/spec/unit/command/generator_commands/generator_generator_spec.rb +227 -227
- data/spec/unit/command/generator_commands/helpers_spec.rb +31 -31
- data/spec/unit/command/generator_commands/policyfile_spec.rb +223 -223
- data/spec/unit/command/generator_commands/recipe_spec.rb +37 -37
- data/spec/unit/command/generator_commands/repo_spec.rb +374 -374
- data/spec/unit/command/generator_commands/resource_spec.rb +31 -31
- data/spec/unit/command/generator_commands/template_spec.rb +31 -31
- data/spec/unit/command/install_spec.rb +179 -179
- data/spec/unit/command/provision_spec.rb +589 -589
- data/spec/unit/command/push_archive_spec.rb +153 -153
- data/spec/unit/command/push_spec.rb +198 -198
- data/spec/unit/command/shell_init_spec.rb +339 -339
- data/spec/unit/command/show_policy_spec.rb +234 -234
- data/spec/unit/command/undelete_spec.rb +244 -244
- data/spec/unit/command/update_spec.rb +283 -283
- data/spec/unit/command/verify_spec.rb +341 -341
- data/spec/unit/commands_map_spec.rb +57 -57
- data/spec/unit/component_test_spec.rb +128 -128
- data/spec/unit/configurable_spec.rb +68 -68
- data/spec/unit/cookbook_metadata_spec.rb +96 -96
- data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
- data/spec/unit/cookbook_profiler/identifiers_spec.rb +81 -81
- data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
- data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
- data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
- data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
- data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
- data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
- data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
- data/spec/unit/fixtures/cookbooks_api/chef_server_universe.json +56 -56
- data/spec/unit/fixtures/cookbooks_api/pruned_chef_server_universe.json +30 -30
- data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
- data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
- data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
- data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +33 -33
- data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
- data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
- data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
- data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
- data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
- data/spec/unit/fixtures/example_cookbook/README.md +4 -4
- data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
- data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
- data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
- data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
- data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
- data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
- data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
- data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
- data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
- data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
- data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
- data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
- data/spec/unit/generator_spec.rb +119 -119
- data/spec/unit/pager_spec.rb +117 -117
- data/spec/unit/policyfile/artifactory_cookbook_source_spec.rb +59 -59
- data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -80
- data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
- data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +55 -55
- data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -161
- data/spec/unit/policyfile/community_cookbook_source_spec.rb +83 -83
- data/spec/unit/policyfile/comparison_base_spec.rb +340 -340
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +347 -347
- data/spec/unit/policyfile/cookbook_locks_spec.rb +527 -527
- data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +129 -129
- data/spec/unit/policyfile/differ_spec.rb +686 -686
- data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -242
- data/spec/unit/policyfile/lister_spec.rb +268 -268
- data/spec/unit/policyfile/local_lock_fetcher_spec.rb +173 -161
- data/spec/unit/policyfile/lock_applier_spec.rb +100 -100
- data/spec/unit/policyfile/null_cookbook_source_spec.rb +34 -34
- data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
- data/spec/unit/policyfile/reports/install_spec.rb +114 -114
- data/spec/unit/policyfile/reports/upload_spec.rb +94 -94
- data/spec/unit/policyfile/solution_dependencies_spec.rb +170 -170
- data/spec/unit/policyfile/source_uri_spec.rb +36 -36
- data/spec/unit/policyfile/storage_config_spec.rb +180 -180
- data/spec/unit/policyfile/undo_record_spec.rb +258 -258
- data/spec/unit/policyfile/undo_stack_spec.rb +265 -265
- data/spec/unit/policyfile/uploader_spec.rb +409 -409
- data/spec/unit/policyfile_demands_spec.rb +1197 -1197
- data/spec/unit/policyfile_evaluation_spec.rb +638 -638
- data/spec/unit/policyfile_includes_dsl_spec.rb +159 -159
- data/spec/unit/policyfile_includes_spec.rb +720 -720
- data/spec/unit/policyfile_install_with_includes_spec.rb +232 -232
- data/spec/unit/policyfile_lock_build_spec.rb +1065 -1065
- data/spec/unit/policyfile_lock_install_spec.rb +137 -137
- data/spec/unit/policyfile_lock_serialization_spec.rb +424 -424
- data/spec/unit/policyfile_lock_validation_spec.rb +608 -608
- data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
- data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +272 -272
- data/spec/unit/policyfile_services/export_repo_spec.rb +478 -478
- data/spec/unit/policyfile_services/install_spec.rb +209 -209
- data/spec/unit/policyfile_services/push_archive_spec.rb +374 -374
- data/spec/unit/policyfile_services/push_spec.rb +249 -249
- data/spec/unit/policyfile_services/rm_policy_group_spec.rb +237 -237
- data/spec/unit/policyfile_services/rm_policy_spec.rb +263 -263
- data/spec/unit/policyfile_services/show_policy_spec.rb +887 -887
- data/spec/unit/policyfile_services/undelete_spec.rb +302 -302
- data/spec/unit/policyfile_services/update_attributes_spec.rb +229 -229
- data/spec/unit/policyfile_services/update_spec.rb +140 -140
- data/spec/unit/service_exception_inspectors/base_spec.rb +41 -41
- data/spec/unit/service_exception_inspectors/http_spec.rb +138 -138
- data/spec/unit/shell_out_spec.rb +34 -34
- data/tasks/announce.rb +57 -57
- data/tasks/bin/bundle-platform.bat +2 -2
- data/tasks/dependencies.rb +89 -89
- data/tasks/templates/prerelease.md.erb +35 -35
- data/tasks/templates/release.md.erb +34 -34
- data/warning.txt +9 -9
- metadata +5 -5
|
@@ -1,478 +1,478 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
|
3
|
-
# License:: Apache License, Version 2.0
|
|
4
|
-
#
|
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
# you may not use this file except in compliance with the License.
|
|
7
|
-
# You may obtain a copy of the License at
|
|
8
|
-
#
|
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
#
|
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
# See the License for the specific language governing permissions and
|
|
15
|
-
# limitations under the License.
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
require "spec_helper"
|
|
19
|
-
require "chef-dk/policyfile_services/export_repo"
|
|
20
|
-
|
|
21
|
-
describe ChefDK::PolicyfileServices::ExportRepo do
|
|
22
|
-
|
|
23
|
-
let(:working_dir) do
|
|
24
|
-
path = File.join(tempdir, "policyfile_services_test_working_dir")
|
|
25
|
-
Dir.mkdir(path)
|
|
26
|
-
path
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
let(:export_dir) { File.join(tempdir, "export_repo_export_dir") }
|
|
30
|
-
|
|
31
|
-
let(:policyfile_rb_explicit_name) { nil }
|
|
32
|
-
|
|
33
|
-
let(:policyfile_rb_name) { policyfile_rb_explicit_name || "Policyfile.rb" }
|
|
34
|
-
|
|
35
|
-
let(:expanded_policyfile_path) { File.join(working_dir, policyfile_rb_name) }
|
|
36
|
-
|
|
37
|
-
let(:policyfile_lock_name) { "Policyfile.lock.json" }
|
|
38
|
-
|
|
39
|
-
let(:policyfile_lock_path) { File.join(working_dir, policyfile_lock_name) }
|
|
40
|
-
|
|
41
|
-
let(:force_export) { false }
|
|
42
|
-
|
|
43
|
-
let(:archive) { false }
|
|
44
|
-
|
|
45
|
-
subject(:export_service) do
|
|
46
|
-
described_class.new(policyfile: policyfile_rb_explicit_name,
|
|
47
|
-
root_dir: working_dir,
|
|
48
|
-
export_dir: export_dir,
|
|
49
|
-
archive: archive,
|
|
50
|
-
force: force_export)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "uses Policyfile.rb as the default Policyfile name" do
|
|
54
|
-
expect(export_service.policyfile_filename).to eq(expanded_policyfile_path)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
context "when given an explicit Policyfile name" do
|
|
58
|
-
|
|
59
|
-
let(:policyfile_rb_explicit_name) { "MyPolicy.rb" }
|
|
60
|
-
|
|
61
|
-
it "uses the given Policyfile name" do
|
|
62
|
-
expect(export_service.policyfile_filename).to eq(expanded_policyfile_path)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it "has a destination directory for the export" do
|
|
68
|
-
expect(export_service.export_dir).to eq(export_dir)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
context "when the policyfile lock is missing" do
|
|
72
|
-
|
|
73
|
-
it "raises an error that suggests you run `chef install'" do
|
|
74
|
-
expect { export_service.run }.to raise_error(ChefDK::LockfileNotFound)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
context "when a lockfile is present" do
|
|
80
|
-
|
|
81
|
-
before do
|
|
82
|
-
File.open(policyfile_lock_path, "w+") { |f| f.print(lockfile_content) }
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
context "and the lockfile has invalid JSON" do
|
|
86
|
-
|
|
87
|
-
let(:lockfile_content) { ":::" }
|
|
88
|
-
|
|
89
|
-
it "errors out" do
|
|
90
|
-
expect { export_service.run }.to raise_error(ChefDK::PolicyfileExportRepoError, /Error reading lockfile/)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
context "and the lockfile is semantically invalid" do
|
|
96
|
-
|
|
97
|
-
let(:lockfile_content) { "{ }" }
|
|
98
|
-
|
|
99
|
-
it "errors out" do
|
|
100
|
-
expect { export_service.run }.to raise_error(ChefDK::PolicyfileExportRepoError, /Invalid lockfile data/)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
context "and the lockfile is valid" do
|
|
106
|
-
|
|
107
|
-
let(:local_cookbook_path) { File.join(fixtures_path, "local_path_cookbooks/local-cookbook") }
|
|
108
|
-
|
|
109
|
-
let(:revision_id) { "7da81d2c7bb97f904637f97e7f8b487fa4bb1ed682edea7087743dec84c254ec" }
|
|
110
|
-
|
|
111
|
-
let(:lockfile_content) do
|
|
112
|
-
<<-E
|
|
113
|
-
{
|
|
114
|
-
"revision_id": "#{revision_id}",
|
|
115
|
-
"name": "install-example",
|
|
116
|
-
"run_list": [
|
|
117
|
-
"recipe[local-cookbook::default]"
|
|
118
|
-
],
|
|
119
|
-
"cookbook_locks": {
|
|
120
|
-
"local-cookbook": {
|
|
121
|
-
"version": "2.3.4",
|
|
122
|
-
"identifier": "1e9dfd1134735385b425c056cb5decef9081b92c",
|
|
123
|
-
"dotted_decimal_identifier": "42704157235437826.6970356709321892.63549625984142",
|
|
124
|
-
"source": "#{local_cookbook_path}",
|
|
125
|
-
"cache_key": null,
|
|
126
|
-
"scm_info": null,
|
|
127
|
-
"source_options": {
|
|
128
|
-
"path": "#{local_cookbook_path}"
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
"default_attributes": {},
|
|
133
|
-
"override_attributes": {},
|
|
134
|
-
"solution_dependencies": {
|
|
135
|
-
"Policyfile": [
|
|
136
|
-
[
|
|
137
|
-
"local-cookbook",
|
|
138
|
-
">= 0.0.0"
|
|
139
|
-
]
|
|
140
|
-
],
|
|
141
|
-
"dependencies": {
|
|
142
|
-
"local-cookbook (2.3.4)": [
|
|
143
|
-
|
|
144
|
-
]
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
E
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
it "reads the lockfile data" do
|
|
152
|
-
lock = export_service.policyfile_lock
|
|
153
|
-
expect(lock).to be_an_instance_of(ChefDK::PolicyfileLock)
|
|
154
|
-
expect(lock.name).to eq("install-example")
|
|
155
|
-
expect(lock.cookbook_locks.size).to eq(1)
|
|
156
|
-
expect(lock.cookbook_locks).to have_key("local-cookbook")
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it "delegates #policy_name to the lockfile" do
|
|
160
|
-
expect(export_service.policy_name).to eq("install-example")
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
context "when using archive mode" do
|
|
164
|
-
|
|
165
|
-
let(:archive) { true }
|
|
166
|
-
|
|
167
|
-
# TODO: also support a full file name
|
|
168
|
-
context "when the given 'export_dir' is a directory" do
|
|
169
|
-
|
|
170
|
-
it "sets the archive file location to $policy_name-$revision.tgz" do
|
|
171
|
-
expected = File.join(export_dir, "install-example-7da81d2c7bb97f904637f97e7f8b487fa4bb1ed682edea7087743dec84c254ec.tgz")
|
|
172
|
-
expect(export_service.archive_file_location).to eq(expected)
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
describe "writing updates to the policyfile lock" do
|
|
180
|
-
|
|
181
|
-
let(:updated_lockfile_io) { StringIO.new }
|
|
182
|
-
|
|
183
|
-
it "validates the lockfile and writes updates to disk" do
|
|
184
|
-
allow(File).to receive(:open).and_call_original
|
|
185
|
-
expect(File).to receive(:open).with(policyfile_lock_path, "wb+").and_yield(updated_lockfile_io)
|
|
186
|
-
|
|
187
|
-
export_service.run
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
context "copying the cookbooks to the export dir" do
|
|
193
|
-
|
|
194
|
-
shared_examples_for "successful_export" do
|
|
195
|
-
before do
|
|
196
|
-
allow(export_service.policyfile_lock).to receive(:validate_cookbooks!).and_return(true)
|
|
197
|
-
export_service.run
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
let(:cookbook_files) do
|
|
201
|
-
base_pathname = Pathname.new(local_cookbook_path)
|
|
202
|
-
Dir.glob("#{local_cookbook_path}/**/*").map do |full_path|
|
|
203
|
-
Pathname.new(full_path).relative_path_from(base_pathname)
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
let(:expected_files_relative) do
|
|
208
|
-
metadata_rb = Pathname.new("metadata.rb")
|
|
209
|
-
expected = cookbook_files.delete_if { |p| p == metadata_rb }
|
|
210
|
-
|
|
211
|
-
# Berksfile is chefignored
|
|
212
|
-
berksfile = Pathname.new("Berksfile")
|
|
213
|
-
expected = expected.delete_if { |p| p == berksfile }
|
|
214
|
-
|
|
215
|
-
expected << Pathname.new("metadata.json")
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
let(:cookbook_with_version) { "local-cookbook-1e9dfd1134735385b425c056cb5decef9081b92c" }
|
|
219
|
-
|
|
220
|
-
let(:exported_cookbook_root) { Pathname.new(File.join(export_dir, "cookbook_artifacts", cookbook_with_version)) }
|
|
221
|
-
|
|
222
|
-
let(:expected_files) do
|
|
223
|
-
expected_files_relative.map do |file_rel_path|
|
|
224
|
-
exported_cookbook_root + file_rel_path
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
it "copies cookbooks to the target dir in versioned_cookbooks format" do
|
|
229
|
-
expected_files.each do |expected_file|
|
|
230
|
-
expect(expected_file).to exist
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
# Using JSON form of metadata ensures that we don't rely on anything
|
|
235
|
-
# in the ruby code in metadata.rb; commonly folks will do things like
|
|
236
|
-
# shell out to git for the version number, etc.
|
|
237
|
-
it "writes metadata.json in the exported cookbook, removing metadata.rb" do
|
|
238
|
-
metadata_json_path = File.join(exported_cookbook_root, "metadata.json")
|
|
239
|
-
metadata_json = FFI_Yajl::Parser.parse(IO.read(metadata_json_path))
|
|
240
|
-
expect(metadata_json["version"]).to eq("2.3.4")
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
it "copies the policyfile lock to policies/POLICY_NAME.json" do
|
|
244
|
-
exported_policy_path = File.join(export_dir, "policies", "install-example-#{revision_id}.json")
|
|
245
|
-
exported_policy_json = IO.read(exported_policy_path)
|
|
246
|
-
expect(exported_policy_json).to eq(FFI_Yajl::Encoder.encode(export_service.policyfile_lock.to_lock, pretty: true))
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
it "creates a policy_group file for the local policy group with the revision id of the exported policy" do
|
|
250
|
-
exported_policy_group_path = File.join(export_dir, "policy_groups", "local.json")
|
|
251
|
-
exported_policy_group_data = FFI_Yajl::Parser.parse(IO.read(exported_policy_group_path))
|
|
252
|
-
|
|
253
|
-
expected_data = { "policies" => { "install-example" => { "revision_id" => revision_id } } }
|
|
254
|
-
|
|
255
|
-
expect(exported_policy_group_data).to eq(expected_data)
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
it "copies the policyfile lock in standard format to Policyfile.lock.json" do
|
|
259
|
-
policyfile_lock_path = File.join(export_dir, "Policyfile.lock.json")
|
|
260
|
-
policyfile_lock_data = FFI_Yajl::Parser.parse(IO.read(policyfile_lock_path))
|
|
261
|
-
expected_lock_data = export_service.policyfile_lock.to_lock
|
|
262
|
-
|
|
263
|
-
# stringify keys in source_options
|
|
264
|
-
path = expected_lock_data["cookbook_locks"]["local-cookbook"]["source_options"].delete(:path)
|
|
265
|
-
expected_lock_data["cookbook_locks"]["local-cookbook"]["source_options"]["path"] = path
|
|
266
|
-
|
|
267
|
-
expect(policyfile_lock_data).to eq(expected_lock_data)
|
|
268
|
-
end
|
|
269
|
-
|
|
270
|
-
it "creates a working local mode configuration file" do
|
|
271
|
-
expected_config_text = <<-CONFIG
|
|
272
|
-
### Chef Client Configuration ###
|
|
273
|
-
# The settings in this file will configure chef to apply the exported policy in
|
|
274
|
-
# this directory. To use it, run:
|
|
275
|
-
#
|
|
276
|
-
# chef-client -z
|
|
277
|
-
#
|
|
278
|
-
|
|
279
|
-
policy_name 'install-example'
|
|
280
|
-
policy_group 'local'
|
|
281
|
-
|
|
282
|
-
use_policyfile true
|
|
283
|
-
policy_document_native_api true
|
|
284
|
-
|
|
285
|
-
# In order to use this repo, you need a version of Chef Client and Chef Zero
|
|
286
|
-
# that supports policyfile "native mode" APIs:
|
|
287
|
-
current_version = Gem::Version.new(Chef::VERSION)
|
|
288
|
-
unless Gem::Requirement.new(">= 12.7").satisfied_by?(current_version)
|
|
289
|
-
puts("!" * 80)
|
|
290
|
-
puts(<<-MESSAGE)
|
|
291
|
-
This Chef Repo requires features introduced in Chef 12.7, but you are using
|
|
292
|
-
Chef \#{Chef::VERSION}. Please upgrade to Chef 12.7 or later.
|
|
293
|
-
MESSAGE
|
|
294
|
-
puts("!" * 80)
|
|
295
|
-
exit!(1)
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
CONFIG
|
|
299
|
-
config_path = File.join(export_dir, ".chef", "config.rb")
|
|
300
|
-
expect(File).to exist(config_path)
|
|
301
|
-
expect(IO.read(config_path)).to eq(expected_config_text)
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
it "generates a README.md in the exported repo" do
|
|
305
|
-
readme_path = File.join(export_dir, "README.md")
|
|
306
|
-
expect(File).to exist(readme_path)
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
context "when the export dir is empty" do
|
|
312
|
-
|
|
313
|
-
include_examples "successful_export"
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
context "When an error occurs creating the export" do
|
|
317
|
-
|
|
318
|
-
before do
|
|
319
|
-
allow(export_service.policyfile_lock).to receive(:validate_cookbooks!).and_return(true)
|
|
320
|
-
expect(export_service).to receive(:create_repo_structure).
|
|
321
|
-
and_raise(Errno::EACCES.new("Permission denied @ rb_sysopen - /etc/foobarbaz.txt"))
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
it "wraps the error in a custom error class" do
|
|
325
|
-
message = "Failed to export policy (in #{expanded_policyfile_path}) to #{export_dir}"
|
|
326
|
-
expect { export_service.run }.to raise_error(ChefDK::PolicyfileExportRepoError, message)
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
context "When the export dir has non-conflicting content" do
|
|
332
|
-
|
|
333
|
-
let(:file_in_export_dir) { File.join(export_dir, "some_random_cruft") }
|
|
334
|
-
|
|
335
|
-
let(:extra_data_bag_dir) { File.join(export_dir, "data_bags", "extraneous") }
|
|
336
|
-
|
|
337
|
-
let(:extra_data_bag_item) { File.join(extra_data_bag_dir, "an_item.json") }
|
|
338
|
-
|
|
339
|
-
before do
|
|
340
|
-
FileUtils.mkdir_p(export_dir)
|
|
341
|
-
File.open(file_in_export_dir, "wb+") { |f| f.print "some random cruft" }
|
|
342
|
-
FileUtils.mkdir_p(extra_data_bag_dir)
|
|
343
|
-
File.open(extra_data_bag_item, "wb+") { |f| f.print "some random cruft" }
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
it "ignores the non-conflicting content and exports" do
|
|
347
|
-
expect(File).to exist(file_in_export_dir)
|
|
348
|
-
expect(File).to exist(extra_data_bag_item)
|
|
349
|
-
|
|
350
|
-
expect(File).to be_directory(File.join(export_dir, "cookbook_artifacts"))
|
|
351
|
-
expect(File).to be_directory(File.join(export_dir, "policies"))
|
|
352
|
-
expect(File).to be_directory(File.join(export_dir, "policy_groups"))
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
include_examples "successful_export"
|
|
356
|
-
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
context "When the export dir has conflicting content" do
|
|
360
|
-
|
|
361
|
-
let(:non_conflicting_file_in_export_dir) { File.join(export_dir, "some_random_cruft") }
|
|
362
|
-
|
|
363
|
-
let(:cookbook_artifacts_dir) { File.join(export_dir, "cookbook_artifacts") }
|
|
364
|
-
|
|
365
|
-
let(:file_in_cookbook_artifacts_dir) { File.join(cookbook_artifacts_dir, "some_random_cruft") }
|
|
366
|
-
|
|
367
|
-
let(:policies_dir) { File.join(export_dir, "policies") }
|
|
368
|
-
|
|
369
|
-
let(:policy_groups_dir) { File.join(export_dir, "policy_groups") }
|
|
370
|
-
|
|
371
|
-
let(:extra_policy_item) { File.join(policies_dir, "leftover-policy.json") }
|
|
372
|
-
|
|
373
|
-
let(:extra_policy_group_item) { File.join(policy_groups_dir, "leftover-policy-group.json") }
|
|
374
|
-
|
|
375
|
-
let(:conflicting_policyfile_lock) { File.join(export_dir, "Policyfile.lock.json") }
|
|
376
|
-
|
|
377
|
-
before do
|
|
378
|
-
FileUtils.mkdir_p(export_dir)
|
|
379
|
-
FileUtils.mkdir_p(cookbook_artifacts_dir)
|
|
380
|
-
FileUtils.mkdir_p(policies_dir)
|
|
381
|
-
FileUtils.mkdir_p(policy_groups_dir)
|
|
382
|
-
File.open(non_conflicting_file_in_export_dir, "wb+") { |f| f.print "some random cruft" }
|
|
383
|
-
File.open(file_in_cookbook_artifacts_dir, "wb+") { |f| f.print "some random cruft" }
|
|
384
|
-
File.open(extra_policy_item, "wb+") { |f| f.print "some random cruft" }
|
|
385
|
-
File.open(extra_policy_group_item, "wb+") { |f| f.print "some random cruft" }
|
|
386
|
-
File.open(conflicting_policyfile_lock, "wb+") { |f| f.print "some random cruft" }
|
|
387
|
-
end
|
|
388
|
-
|
|
389
|
-
it "raises a PolicyfileExportRepoError" do
|
|
390
|
-
message = "Export dir (#{export_dir}) not clean. Refusing to export. (Conflicting files: #{file_in_cookbook_artifacts_dir}, #{extra_policy_item}, #{extra_policy_group_item}, #{conflicting_policyfile_lock})"
|
|
391
|
-
expect { export_service.run }.to raise_error(ChefDK::ExportDirNotEmpty, message)
|
|
392
|
-
expect(File).to exist(non_conflicting_file_in_export_dir)
|
|
393
|
-
expect(File).to exist(file_in_cookbook_artifacts_dir)
|
|
394
|
-
expect(File).to exist(extra_policy_item)
|
|
395
|
-
expect(File).to exist(extra_policy_group_item)
|
|
396
|
-
end
|
|
397
|
-
|
|
398
|
-
context "and the force option is set" do
|
|
399
|
-
|
|
400
|
-
let(:force_export) { true }
|
|
401
|
-
|
|
402
|
-
it "clears the export dir and exports" do
|
|
403
|
-
export_service.run
|
|
404
|
-
|
|
405
|
-
expect(File).to_not exist(file_in_cookbook_artifacts_dir)
|
|
406
|
-
expect(File).to_not exist(extra_policy_item)
|
|
407
|
-
expect(File).to_not exist(extra_policy_group_item)
|
|
408
|
-
|
|
409
|
-
expect(File).to exist(non_conflicting_file_in_export_dir)
|
|
410
|
-
|
|
411
|
-
expect(File).to be_directory(File.join(export_dir, "cookbook_artifacts"))
|
|
412
|
-
expect(File).to be_directory(File.join(export_dir, "policies"))
|
|
413
|
-
expect(File).to be_directory(File.join(export_dir, "policy_groups"))
|
|
414
|
-
end
|
|
415
|
-
|
|
416
|
-
end
|
|
417
|
-
|
|
418
|
-
end # When the export dir has conflicting content
|
|
419
|
-
|
|
420
|
-
context "when archive mode is enabled" do
|
|
421
|
-
|
|
422
|
-
let(:archive) { true }
|
|
423
|
-
|
|
424
|
-
let(:expected_archive_path) do
|
|
425
|
-
File.join(export_dir, "install-example-7da81d2c7bb97f904637f97e7f8b487fa4bb1ed682edea7087743dec84c254ec.tgz")
|
|
426
|
-
end
|
|
427
|
-
|
|
428
|
-
it "exports the repo as a tgz archive" do
|
|
429
|
-
expect(File).to exist(expected_archive_path)
|
|
430
|
-
end
|
|
431
|
-
|
|
432
|
-
include_examples "successful_export" do
|
|
433
|
-
|
|
434
|
-
# explode the tarball so the assertions can find the files
|
|
435
|
-
before do
|
|
436
|
-
Zlib::GzipReader.open(expected_archive_path) do |gz_file|
|
|
437
|
-
tar = Archive::Tar::Minitar::Input.new(gz_file)
|
|
438
|
-
tar.each do |e|
|
|
439
|
-
tar.extract_entry(export_dir, e)
|
|
440
|
-
end
|
|
441
|
-
end
|
|
442
|
-
end
|
|
443
|
-
|
|
444
|
-
end
|
|
445
|
-
|
|
446
|
-
context "when the target dir has a cookbooks or data_bags dir" do
|
|
447
|
-
|
|
448
|
-
let(:cookbooks_dir) { File.join(export_dir, "cookbooks") }
|
|
449
|
-
|
|
450
|
-
let(:file_in_cookbooks_dir) { File.join(cookbooks_dir, "some_random_cruft") }
|
|
451
|
-
|
|
452
|
-
let(:policyfiles_data_bag_dir) { File.join(export_dir, "data_bags", "policyfiles") }
|
|
453
|
-
|
|
454
|
-
let(:extra_policyfile_data_item) { File.join(policyfiles_data_bag_dir, "leftover-policy.json") }
|
|
455
|
-
|
|
456
|
-
before do
|
|
457
|
-
FileUtils.mkdir_p(export_dir)
|
|
458
|
-
FileUtils.mkdir_p(cookbooks_dir)
|
|
459
|
-
FileUtils.mkdir_p(policyfiles_data_bag_dir)
|
|
460
|
-
File.open(file_in_cookbooks_dir, "wb+") { |f| f.print "some random cruft" }
|
|
461
|
-
File.open(extra_policyfile_data_item, "wb+") { |f| f.print "some random cruft" }
|
|
462
|
-
end
|
|
463
|
-
|
|
464
|
-
it "exports successfully" do
|
|
465
|
-
expect { export_service.run }.to_not raise_error
|
|
466
|
-
expect(File).to exist(expected_archive_path)
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
end
|
|
470
|
-
|
|
471
|
-
end # when archive mode is enabled
|
|
472
|
-
|
|
473
|
-
end # copying the cookbooks to the export dir
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
end
|
|
477
|
-
|
|
478
|
-
end
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: Copyright (c) 2014 Chef Software Inc.
|
|
3
|
+
# License:: Apache License, Version 2.0
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
require "spec_helper"
|
|
19
|
+
require "chef-dk/policyfile_services/export_repo"
|
|
20
|
+
|
|
21
|
+
describe ChefDK::PolicyfileServices::ExportRepo do
|
|
22
|
+
|
|
23
|
+
let(:working_dir) do
|
|
24
|
+
path = File.join(tempdir, "policyfile_services_test_working_dir")
|
|
25
|
+
Dir.mkdir(path)
|
|
26
|
+
path
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
let(:export_dir) { File.join(tempdir, "export_repo_export_dir") }
|
|
30
|
+
|
|
31
|
+
let(:policyfile_rb_explicit_name) { nil }
|
|
32
|
+
|
|
33
|
+
let(:policyfile_rb_name) { policyfile_rb_explicit_name || "Policyfile.rb" }
|
|
34
|
+
|
|
35
|
+
let(:expanded_policyfile_path) { File.join(working_dir, policyfile_rb_name) }
|
|
36
|
+
|
|
37
|
+
let(:policyfile_lock_name) { "Policyfile.lock.json" }
|
|
38
|
+
|
|
39
|
+
let(:policyfile_lock_path) { File.join(working_dir, policyfile_lock_name) }
|
|
40
|
+
|
|
41
|
+
let(:force_export) { false }
|
|
42
|
+
|
|
43
|
+
let(:archive) { false }
|
|
44
|
+
|
|
45
|
+
subject(:export_service) do
|
|
46
|
+
described_class.new(policyfile: policyfile_rb_explicit_name,
|
|
47
|
+
root_dir: working_dir,
|
|
48
|
+
export_dir: export_dir,
|
|
49
|
+
archive: archive,
|
|
50
|
+
force: force_export)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "uses Policyfile.rb as the default Policyfile name" do
|
|
54
|
+
expect(export_service.policyfile_filename).to eq(expanded_policyfile_path)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "when given an explicit Policyfile name" do
|
|
58
|
+
|
|
59
|
+
let(:policyfile_rb_explicit_name) { "MyPolicy.rb" }
|
|
60
|
+
|
|
61
|
+
it "uses the given Policyfile name" do
|
|
62
|
+
expect(export_service.policyfile_filename).to eq(expanded_policyfile_path)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "has a destination directory for the export" do
|
|
68
|
+
expect(export_service.export_dir).to eq(export_dir)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context "when the policyfile lock is missing" do
|
|
72
|
+
|
|
73
|
+
it "raises an error that suggests you run `chef install'" do
|
|
74
|
+
expect { export_service.run }.to raise_error(ChefDK::LockfileNotFound)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "when a lockfile is present" do
|
|
80
|
+
|
|
81
|
+
before do
|
|
82
|
+
File.open(policyfile_lock_path, "w+") { |f| f.print(lockfile_content) }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context "and the lockfile has invalid JSON" do
|
|
86
|
+
|
|
87
|
+
let(:lockfile_content) { ":::" }
|
|
88
|
+
|
|
89
|
+
it "errors out" do
|
|
90
|
+
expect { export_service.run }.to raise_error(ChefDK::PolicyfileExportRepoError, /Error reading lockfile/)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "and the lockfile is semantically invalid" do
|
|
96
|
+
|
|
97
|
+
let(:lockfile_content) { "{ }" }
|
|
98
|
+
|
|
99
|
+
it "errors out" do
|
|
100
|
+
expect { export_service.run }.to raise_error(ChefDK::PolicyfileExportRepoError, /Invalid lockfile data/)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context "and the lockfile is valid" do
|
|
106
|
+
|
|
107
|
+
let(:local_cookbook_path) { File.join(fixtures_path, "local_path_cookbooks/local-cookbook") }
|
|
108
|
+
|
|
109
|
+
let(:revision_id) { "7da81d2c7bb97f904637f97e7f8b487fa4bb1ed682edea7087743dec84c254ec" }
|
|
110
|
+
|
|
111
|
+
let(:lockfile_content) do
|
|
112
|
+
<<-E
|
|
113
|
+
{
|
|
114
|
+
"revision_id": "#{revision_id}",
|
|
115
|
+
"name": "install-example",
|
|
116
|
+
"run_list": [
|
|
117
|
+
"recipe[local-cookbook::default]"
|
|
118
|
+
],
|
|
119
|
+
"cookbook_locks": {
|
|
120
|
+
"local-cookbook": {
|
|
121
|
+
"version": "2.3.4",
|
|
122
|
+
"identifier": "1e9dfd1134735385b425c056cb5decef9081b92c",
|
|
123
|
+
"dotted_decimal_identifier": "42704157235437826.6970356709321892.63549625984142",
|
|
124
|
+
"source": "#{local_cookbook_path}",
|
|
125
|
+
"cache_key": null,
|
|
126
|
+
"scm_info": null,
|
|
127
|
+
"source_options": {
|
|
128
|
+
"path": "#{local_cookbook_path}"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
"default_attributes": {},
|
|
133
|
+
"override_attributes": {},
|
|
134
|
+
"solution_dependencies": {
|
|
135
|
+
"Policyfile": [
|
|
136
|
+
[
|
|
137
|
+
"local-cookbook",
|
|
138
|
+
">= 0.0.0"
|
|
139
|
+
]
|
|
140
|
+
],
|
|
141
|
+
"dependencies": {
|
|
142
|
+
"local-cookbook (2.3.4)": [
|
|
143
|
+
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
E
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "reads the lockfile data" do
|
|
152
|
+
lock = export_service.policyfile_lock
|
|
153
|
+
expect(lock).to be_an_instance_of(ChefDK::PolicyfileLock)
|
|
154
|
+
expect(lock.name).to eq("install-example")
|
|
155
|
+
expect(lock.cookbook_locks.size).to eq(1)
|
|
156
|
+
expect(lock.cookbook_locks).to have_key("local-cookbook")
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "delegates #policy_name to the lockfile" do
|
|
160
|
+
expect(export_service.policy_name).to eq("install-example")
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context "when using archive mode" do
|
|
164
|
+
|
|
165
|
+
let(:archive) { true }
|
|
166
|
+
|
|
167
|
+
# TODO: also support a full file name
|
|
168
|
+
context "when the given 'export_dir' is a directory" do
|
|
169
|
+
|
|
170
|
+
it "sets the archive file location to $policy_name-$revision.tgz" do
|
|
171
|
+
expected = File.join(export_dir, "install-example-7da81d2c7bb97f904637f97e7f8b487fa4bb1ed682edea7087743dec84c254ec.tgz")
|
|
172
|
+
expect(export_service.archive_file_location).to eq(expected)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
describe "writing updates to the policyfile lock" do
|
|
180
|
+
|
|
181
|
+
let(:updated_lockfile_io) { StringIO.new }
|
|
182
|
+
|
|
183
|
+
it "validates the lockfile and writes updates to disk" do
|
|
184
|
+
allow(File).to receive(:open).and_call_original
|
|
185
|
+
expect(File).to receive(:open).with(policyfile_lock_path, "wb+").and_yield(updated_lockfile_io)
|
|
186
|
+
|
|
187
|
+
export_service.run
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
context "copying the cookbooks to the export dir" do
|
|
193
|
+
|
|
194
|
+
shared_examples_for "successful_export" do
|
|
195
|
+
before do
|
|
196
|
+
allow(export_service.policyfile_lock).to receive(:validate_cookbooks!).and_return(true)
|
|
197
|
+
export_service.run
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
let(:cookbook_files) do
|
|
201
|
+
base_pathname = Pathname.new(local_cookbook_path)
|
|
202
|
+
Dir.glob("#{local_cookbook_path}/**/*").map do |full_path|
|
|
203
|
+
Pathname.new(full_path).relative_path_from(base_pathname)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
let(:expected_files_relative) do
|
|
208
|
+
metadata_rb = Pathname.new("metadata.rb")
|
|
209
|
+
expected = cookbook_files.delete_if { |p| p == metadata_rb }
|
|
210
|
+
|
|
211
|
+
# Berksfile is chefignored
|
|
212
|
+
berksfile = Pathname.new("Berksfile")
|
|
213
|
+
expected = expected.delete_if { |p| p == berksfile }
|
|
214
|
+
|
|
215
|
+
expected << Pathname.new("metadata.json")
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
let(:cookbook_with_version) { "local-cookbook-1e9dfd1134735385b425c056cb5decef9081b92c" }
|
|
219
|
+
|
|
220
|
+
let(:exported_cookbook_root) { Pathname.new(File.join(export_dir, "cookbook_artifacts", cookbook_with_version)) }
|
|
221
|
+
|
|
222
|
+
let(:expected_files) do
|
|
223
|
+
expected_files_relative.map do |file_rel_path|
|
|
224
|
+
exported_cookbook_root + file_rel_path
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "copies cookbooks to the target dir in versioned_cookbooks format" do
|
|
229
|
+
expected_files.each do |expected_file|
|
|
230
|
+
expect(expected_file).to exist
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Using JSON form of metadata ensures that we don't rely on anything
|
|
235
|
+
# in the ruby code in metadata.rb; commonly folks will do things like
|
|
236
|
+
# shell out to git for the version number, etc.
|
|
237
|
+
it "writes metadata.json in the exported cookbook, removing metadata.rb" do
|
|
238
|
+
metadata_json_path = File.join(exported_cookbook_root, "metadata.json")
|
|
239
|
+
metadata_json = FFI_Yajl::Parser.parse(IO.read(metadata_json_path))
|
|
240
|
+
expect(metadata_json["version"]).to eq("2.3.4")
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
it "copies the policyfile lock to policies/POLICY_NAME.json" do
|
|
244
|
+
exported_policy_path = File.join(export_dir, "policies", "install-example-#{revision_id}.json")
|
|
245
|
+
exported_policy_json = IO.read(exported_policy_path)
|
|
246
|
+
expect(exported_policy_json).to eq(FFI_Yajl::Encoder.encode(export_service.policyfile_lock.to_lock, pretty: true))
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it "creates a policy_group file for the local policy group with the revision id of the exported policy" do
|
|
250
|
+
exported_policy_group_path = File.join(export_dir, "policy_groups", "local.json")
|
|
251
|
+
exported_policy_group_data = FFI_Yajl::Parser.parse(IO.read(exported_policy_group_path))
|
|
252
|
+
|
|
253
|
+
expected_data = { "policies" => { "install-example" => { "revision_id" => revision_id } } }
|
|
254
|
+
|
|
255
|
+
expect(exported_policy_group_data).to eq(expected_data)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "copies the policyfile lock in standard format to Policyfile.lock.json" do
|
|
259
|
+
policyfile_lock_path = File.join(export_dir, "Policyfile.lock.json")
|
|
260
|
+
policyfile_lock_data = FFI_Yajl::Parser.parse(IO.read(policyfile_lock_path))
|
|
261
|
+
expected_lock_data = export_service.policyfile_lock.to_lock
|
|
262
|
+
|
|
263
|
+
# stringify keys in source_options
|
|
264
|
+
path = expected_lock_data["cookbook_locks"]["local-cookbook"]["source_options"].delete(:path)
|
|
265
|
+
expected_lock_data["cookbook_locks"]["local-cookbook"]["source_options"]["path"] = path
|
|
266
|
+
|
|
267
|
+
expect(policyfile_lock_data).to eq(expected_lock_data)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "creates a working local mode configuration file" do
|
|
271
|
+
expected_config_text = <<-CONFIG
|
|
272
|
+
### Chef Client Configuration ###
|
|
273
|
+
# The settings in this file will configure chef to apply the exported policy in
|
|
274
|
+
# this directory. To use it, run:
|
|
275
|
+
#
|
|
276
|
+
# chef-client -z
|
|
277
|
+
#
|
|
278
|
+
|
|
279
|
+
policy_name 'install-example'
|
|
280
|
+
policy_group 'local'
|
|
281
|
+
|
|
282
|
+
use_policyfile true
|
|
283
|
+
policy_document_native_api true
|
|
284
|
+
|
|
285
|
+
# In order to use this repo, you need a version of Chef Client and Chef Zero
|
|
286
|
+
# that supports policyfile "native mode" APIs:
|
|
287
|
+
current_version = Gem::Version.new(Chef::VERSION)
|
|
288
|
+
unless Gem::Requirement.new(">= 12.7").satisfied_by?(current_version)
|
|
289
|
+
puts("!" * 80)
|
|
290
|
+
puts(<<-MESSAGE)
|
|
291
|
+
This Chef Repo requires features introduced in Chef 12.7, but you are using
|
|
292
|
+
Chef \#{Chef::VERSION}. Please upgrade to Chef 12.7 or later.
|
|
293
|
+
MESSAGE
|
|
294
|
+
puts("!" * 80)
|
|
295
|
+
exit!(1)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
CONFIG
|
|
299
|
+
config_path = File.join(export_dir, ".chef", "config.rb")
|
|
300
|
+
expect(File).to exist(config_path)
|
|
301
|
+
expect(IO.read(config_path)).to eq(expected_config_text)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it "generates a README.md in the exported repo" do
|
|
305
|
+
readme_path = File.join(export_dir, "README.md")
|
|
306
|
+
expect(File).to exist(readme_path)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
context "when the export dir is empty" do
|
|
312
|
+
|
|
313
|
+
include_examples "successful_export"
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
context "When an error occurs creating the export" do
|
|
317
|
+
|
|
318
|
+
before do
|
|
319
|
+
allow(export_service.policyfile_lock).to receive(:validate_cookbooks!).and_return(true)
|
|
320
|
+
expect(export_service).to receive(:create_repo_structure).
|
|
321
|
+
and_raise(Errno::EACCES.new("Permission denied @ rb_sysopen - /etc/foobarbaz.txt"))
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "wraps the error in a custom error class" do
|
|
325
|
+
message = "Failed to export policy (in #{expanded_policyfile_path}) to #{export_dir}"
|
|
326
|
+
expect { export_service.run }.to raise_error(ChefDK::PolicyfileExportRepoError, message)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
context "When the export dir has non-conflicting content" do
|
|
332
|
+
|
|
333
|
+
let(:file_in_export_dir) { File.join(export_dir, "some_random_cruft") }
|
|
334
|
+
|
|
335
|
+
let(:extra_data_bag_dir) { File.join(export_dir, "data_bags", "extraneous") }
|
|
336
|
+
|
|
337
|
+
let(:extra_data_bag_item) { File.join(extra_data_bag_dir, "an_item.json") }
|
|
338
|
+
|
|
339
|
+
before do
|
|
340
|
+
FileUtils.mkdir_p(export_dir)
|
|
341
|
+
File.open(file_in_export_dir, "wb+") { |f| f.print "some random cruft" }
|
|
342
|
+
FileUtils.mkdir_p(extra_data_bag_dir)
|
|
343
|
+
File.open(extra_data_bag_item, "wb+") { |f| f.print "some random cruft" }
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it "ignores the non-conflicting content and exports" do
|
|
347
|
+
expect(File).to exist(file_in_export_dir)
|
|
348
|
+
expect(File).to exist(extra_data_bag_item)
|
|
349
|
+
|
|
350
|
+
expect(File).to be_directory(File.join(export_dir, "cookbook_artifacts"))
|
|
351
|
+
expect(File).to be_directory(File.join(export_dir, "policies"))
|
|
352
|
+
expect(File).to be_directory(File.join(export_dir, "policy_groups"))
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
include_examples "successful_export"
|
|
356
|
+
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
context "When the export dir has conflicting content" do
|
|
360
|
+
|
|
361
|
+
let(:non_conflicting_file_in_export_dir) { File.join(export_dir, "some_random_cruft") }
|
|
362
|
+
|
|
363
|
+
let(:cookbook_artifacts_dir) { File.join(export_dir, "cookbook_artifacts") }
|
|
364
|
+
|
|
365
|
+
let(:file_in_cookbook_artifacts_dir) { File.join(cookbook_artifacts_dir, "some_random_cruft") }
|
|
366
|
+
|
|
367
|
+
let(:policies_dir) { File.join(export_dir, "policies") }
|
|
368
|
+
|
|
369
|
+
let(:policy_groups_dir) { File.join(export_dir, "policy_groups") }
|
|
370
|
+
|
|
371
|
+
let(:extra_policy_item) { File.join(policies_dir, "leftover-policy.json") }
|
|
372
|
+
|
|
373
|
+
let(:extra_policy_group_item) { File.join(policy_groups_dir, "leftover-policy-group.json") }
|
|
374
|
+
|
|
375
|
+
let(:conflicting_policyfile_lock) { File.join(export_dir, "Policyfile.lock.json") }
|
|
376
|
+
|
|
377
|
+
before do
|
|
378
|
+
FileUtils.mkdir_p(export_dir)
|
|
379
|
+
FileUtils.mkdir_p(cookbook_artifacts_dir)
|
|
380
|
+
FileUtils.mkdir_p(policies_dir)
|
|
381
|
+
FileUtils.mkdir_p(policy_groups_dir)
|
|
382
|
+
File.open(non_conflicting_file_in_export_dir, "wb+") { |f| f.print "some random cruft" }
|
|
383
|
+
File.open(file_in_cookbook_artifacts_dir, "wb+") { |f| f.print "some random cruft" }
|
|
384
|
+
File.open(extra_policy_item, "wb+") { |f| f.print "some random cruft" }
|
|
385
|
+
File.open(extra_policy_group_item, "wb+") { |f| f.print "some random cruft" }
|
|
386
|
+
File.open(conflicting_policyfile_lock, "wb+") { |f| f.print "some random cruft" }
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it "raises a PolicyfileExportRepoError" do
|
|
390
|
+
message = "Export dir (#{export_dir}) not clean. Refusing to export. (Conflicting files: #{file_in_cookbook_artifacts_dir}, #{extra_policy_item}, #{extra_policy_group_item}, #{conflicting_policyfile_lock})"
|
|
391
|
+
expect { export_service.run }.to raise_error(ChefDK::ExportDirNotEmpty, message)
|
|
392
|
+
expect(File).to exist(non_conflicting_file_in_export_dir)
|
|
393
|
+
expect(File).to exist(file_in_cookbook_artifacts_dir)
|
|
394
|
+
expect(File).to exist(extra_policy_item)
|
|
395
|
+
expect(File).to exist(extra_policy_group_item)
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
context "and the force option is set" do
|
|
399
|
+
|
|
400
|
+
let(:force_export) { true }
|
|
401
|
+
|
|
402
|
+
it "clears the export dir and exports" do
|
|
403
|
+
export_service.run
|
|
404
|
+
|
|
405
|
+
expect(File).to_not exist(file_in_cookbook_artifacts_dir)
|
|
406
|
+
expect(File).to_not exist(extra_policy_item)
|
|
407
|
+
expect(File).to_not exist(extra_policy_group_item)
|
|
408
|
+
|
|
409
|
+
expect(File).to exist(non_conflicting_file_in_export_dir)
|
|
410
|
+
|
|
411
|
+
expect(File).to be_directory(File.join(export_dir, "cookbook_artifacts"))
|
|
412
|
+
expect(File).to be_directory(File.join(export_dir, "policies"))
|
|
413
|
+
expect(File).to be_directory(File.join(export_dir, "policy_groups"))
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
end # When the export dir has conflicting content
|
|
419
|
+
|
|
420
|
+
context "when archive mode is enabled" do
|
|
421
|
+
|
|
422
|
+
let(:archive) { true }
|
|
423
|
+
|
|
424
|
+
let(:expected_archive_path) do
|
|
425
|
+
File.join(export_dir, "install-example-7da81d2c7bb97f904637f97e7f8b487fa4bb1ed682edea7087743dec84c254ec.tgz")
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
it "exports the repo as a tgz archive" do
|
|
429
|
+
expect(File).to exist(expected_archive_path)
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
include_examples "successful_export" do
|
|
433
|
+
|
|
434
|
+
# explode the tarball so the assertions can find the files
|
|
435
|
+
before do
|
|
436
|
+
Zlib::GzipReader.open(expected_archive_path) do |gz_file|
|
|
437
|
+
tar = Archive::Tar::Minitar::Input.new(gz_file)
|
|
438
|
+
tar.each do |e|
|
|
439
|
+
tar.extract_entry(export_dir, e)
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
context "when the target dir has a cookbooks or data_bags dir" do
|
|
447
|
+
|
|
448
|
+
let(:cookbooks_dir) { File.join(export_dir, "cookbooks") }
|
|
449
|
+
|
|
450
|
+
let(:file_in_cookbooks_dir) { File.join(cookbooks_dir, "some_random_cruft") }
|
|
451
|
+
|
|
452
|
+
let(:policyfiles_data_bag_dir) { File.join(export_dir, "data_bags", "policyfiles") }
|
|
453
|
+
|
|
454
|
+
let(:extra_policyfile_data_item) { File.join(policyfiles_data_bag_dir, "leftover-policy.json") }
|
|
455
|
+
|
|
456
|
+
before do
|
|
457
|
+
FileUtils.mkdir_p(export_dir)
|
|
458
|
+
FileUtils.mkdir_p(cookbooks_dir)
|
|
459
|
+
FileUtils.mkdir_p(policyfiles_data_bag_dir)
|
|
460
|
+
File.open(file_in_cookbooks_dir, "wb+") { |f| f.print "some random cruft" }
|
|
461
|
+
File.open(extra_policyfile_data_item, "wb+") { |f| f.print "some random cruft" }
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it "exports successfully" do
|
|
465
|
+
expect { export_service.run }.to_not raise_error
|
|
466
|
+
expect(File).to exist(expected_archive_path)
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
end # when archive mode is enabled
|
|
472
|
+
|
|
473
|
+
end # copying the cookbooks to the export dir
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
end
|