chef-dk 3.0.36 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +124 -126
- data/Gemfile.lock +815 -812
- 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 -21
- 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 +124 -124
- 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 +152 -152
- 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 +151 -151
- data/lib/chef-dk/generator.rb +165 -165
- data/lib/chef-dk/helpers.rb +176 -176
- data/lib/chef-dk/pager.rb +104 -104
- 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 +167 -167
- 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/git_lock_fetcher.rb +265 -265
- 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 +129 -129
- 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 +125 -125
- 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 +311 -311
- data/lib/chef-dk/policyfile/source_uri.rb +57 -57
- data/lib/chef-dk/policyfile/storage_config.rb +112 -112
- 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 +419 -419
- 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 +164 -164
- 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 +234 -234
- 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 +104 -104
- 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 +66 -66
- 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 +158 -158
- 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/CHANGELOG.md.erb +11 -11
- 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 +25 -25
- 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 +765 -765
- 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/git_lock_fetcher_spec.rb +155 -155
- 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 -173
- 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 +628 -628
- 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 +473 -473
- data/spec/unit/policyfile_services/install_spec.rb +209 -209
- data/spec/unit/policyfile_services/push_archive_spec.rb +359 -359
- 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 +2 -2
@@ -1,528 +1,528 @@
|
|
1
|
-
#
|
2
|
-
# Copyright:: Copyright (c) 2014-2018, 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 "set"
|
19
|
-
require "forwardable"
|
20
|
-
|
21
|
-
require "solve"
|
22
|
-
require "chef/run_list"
|
23
|
-
require "chef/mixin/deep_merge"
|
24
|
-
|
25
|
-
require "chef-dk/policyfile/dsl"
|
26
|
-
require "chef-dk/policyfile/attribute_merge_checker"
|
27
|
-
require "chef-dk/policyfile/included_policies_cookbook_source"
|
28
|
-
require "chef-dk/policyfile_lock"
|
29
|
-
require "chef-dk/ui"
|
30
|
-
require "chef-dk/policyfile/reports/install"
|
31
|
-
require "chef-dk/exceptions"
|
32
|
-
|
33
|
-
module ChefDK
|
34
|
-
|
35
|
-
class PolicyfileCompiler
|
36
|
-
|
37
|
-
extend Forwardable
|
38
|
-
|
39
|
-
DEFAULT_DEMAND_CONSTRAINT = ">= 0.0.0".freeze
|
40
|
-
|
41
|
-
# Cookbooks from these sources lock that cookbook to exactly one version
|
42
|
-
SOURCE_TYPES_WITH_FIXED_VERSIONS = [:git, :path].freeze
|
43
|
-
|
44
|
-
def self.evaluate(policyfile_string, policyfile_filename, ui: nil, chef_config: nil)
|
45
|
-
compiler = new(ui: ui, chef_config: chef_config)
|
46
|
-
compiler.evaluate_policyfile(policyfile_string, policyfile_filename)
|
47
|
-
compiler
|
48
|
-
end
|
49
|
-
|
50
|
-
def_delegator :@dsl, :name
|
51
|
-
def_delegator :@dsl, :run_list
|
52
|
-
def_delegator :@dsl, :named_run_list
|
53
|
-
def_delegator :@dsl, :named_run_lists
|
54
|
-
def_delegator :@dsl, :errors
|
55
|
-
def_delegator :@dsl, :cookbook_location_specs
|
56
|
-
def_delegator :@dsl, :included_policies
|
57
|
-
|
58
|
-
attr_reader :dsl
|
59
|
-
attr_reader :storage_config
|
60
|
-
attr_reader :install_report
|
61
|
-
|
62
|
-
def initialize(ui: nil, chef_config: nil)
|
63
|
-
@storage_config = Policyfile::StorageConfig.new
|
64
|
-
@dsl = Policyfile::DSL.new(storage_config, chef_config: chef_config)
|
65
|
-
@artifact_server_cookbook_location_specs = {}
|
66
|
-
|
67
|
-
@merged_graph = nil
|
68
|
-
|
69
|
-
@ui = ui || UI.null
|
70
|
-
@install_report = Policyfile::Reports::Install.new(ui: @ui, policyfile_compiler: self)
|
71
|
-
end
|
72
|
-
|
73
|
-
def default_source(source_type = nil, source_argument = nil, &block)
|
74
|
-
if source_type.nil?
|
75
|
-
prepend_array = if included_policies.length > 0
|
76
|
-
[included_policies_cookbook_source]
|
77
|
-
else
|
78
|
-
[]
|
79
|
-
end
|
80
|
-
prepend_array + dsl.default_source
|
81
|
-
else
|
82
|
-
dsl.default_source(source_type, source_argument, &block)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def error!
|
87
|
-
unless errors.empty?
|
88
|
-
raise PolicyfileError, errors.join("\n")
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def cookbook_location_spec_for(cookbook_name)
|
93
|
-
cookbook_location_specs[cookbook_name]
|
94
|
-
end
|
95
|
-
|
96
|
-
def expanded_run_list
|
97
|
-
# doesn't support roles yet...
|
98
|
-
concated_runlist = Chef::RunList.new
|
99
|
-
included_policies.each do |policy_spec|
|
100
|
-
lock = policy_spec.policyfile_lock
|
101
|
-
lock.run_list.each do |run_list_item|
|
102
|
-
concated_runlist << run_list_item
|
103
|
-
end
|
104
|
-
end
|
105
|
-
run_list.each do |run_list_item|
|
106
|
-
concated_runlist << run_list_item
|
107
|
-
end
|
108
|
-
concated_runlist
|
109
|
-
end
|
110
|
-
|
111
|
-
# copy of the expanded_run_list, properly formatted for use in a lockfile
|
112
|
-
def normalized_run_list
|
113
|
-
expanded_run_list.map { |i| normalize_recipe(i) }
|
114
|
-
end
|
115
|
-
|
116
|
-
def expanded_named_run_lists
|
117
|
-
included_policies_named_runlists = included_policies.inject({}) do |acc, policy_spec|
|
118
|
-
lock = policy_spec.policyfile_lock
|
119
|
-
lock.named_run_lists.inject(acc) do |expanded, (name, run_list_items)|
|
120
|
-
expanded[name] ||= Chef::RunList.new
|
121
|
-
run_list_items.each do |run_list_item|
|
122
|
-
expanded[name] << run_list_item
|
123
|
-
end
|
124
|
-
expanded
|
125
|
-
end
|
126
|
-
acc
|
127
|
-
end
|
128
|
-
|
129
|
-
named_run_lists.inject(included_policies_named_runlists) do |expanded, (name, run_list_items)|
|
130
|
-
expanded[name] ||= Chef::RunList.new
|
131
|
-
run_list_items.each do |run_list_item|
|
132
|
-
expanded[name] << run_list_item
|
133
|
-
end
|
134
|
-
expanded
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def normalized_named_run_lists
|
139
|
-
expanded_named_run_lists.inject({}) do |normalized, (name, run_list)|
|
140
|
-
normalized[name] = run_list.map { |i| normalize_recipe(i) }
|
141
|
-
normalized
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def default_attributes
|
146
|
-
check_for_default_attribute_conflicts!
|
147
|
-
included_policies.map { |p| p.policyfile_lock }.inject(
|
148
|
-
dsl.node_attributes.combined_default.to_hash) do |acc, lock|
|
149
|
-
Chef::Mixin::DeepMerge.merge(acc, lock.default_attributes)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def override_attributes
|
154
|
-
check_for_override_attribute_conflicts!
|
155
|
-
included_policies.map { |p| p.policyfile_lock }.inject(
|
156
|
-
dsl.node_attributes.combined_override.to_hash) do |acc, lock|
|
157
|
-
Chef::Mixin::DeepMerge.merge(acc, lock.override_attributes)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def lock
|
162
|
-
@policyfile_lock ||= PolicyfileLock.build_from_compiler(self, storage_config)
|
163
|
-
end
|
164
|
-
|
165
|
-
def install
|
166
|
-
ensure_cache_dir_exists
|
167
|
-
|
168
|
-
cookbook_and_recipe_list = combined_run_lists.map(&:name).map do |recipe_spec|
|
169
|
-
cookbook, _separator, recipe = recipe_spec.partition("::")
|
170
|
-
recipe = "default" if recipe.empty?
|
171
|
-
[cookbook, recipe]
|
172
|
-
end
|
173
|
-
|
174
|
-
missing_recipes_by_cb_spec = {}
|
175
|
-
|
176
|
-
graph_solution.each do |cookbook_name, version|
|
177
|
-
spec = cookbook_location_spec_for(cookbook_name)
|
178
|
-
if spec.nil? || !spec.version_fixed?
|
179
|
-
spec = create_spec_for_cookbook(cookbook_name, version)
|
180
|
-
install_report.installing_cookbook(spec)
|
181
|
-
spec.ensure_cached
|
182
|
-
end
|
183
|
-
|
184
|
-
required_recipes = cookbook_and_recipe_list.select { |cb_name, _recipe| cb_name == spec.name }
|
185
|
-
missing_recipes = required_recipes.select { |_cb_name, recipe| !spec.cookbook_has_recipe?(recipe) }
|
186
|
-
|
187
|
-
unless missing_recipes.empty?
|
188
|
-
missing_recipes_by_cb_spec[spec] = missing_recipes
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
unless missing_recipes_by_cb_spec.empty?
|
193
|
-
message = "The installed cookbooks do not contain all the recipes required by your run list(s):\n"
|
194
|
-
missing_recipes_by_cb_spec.each do |spec, missing_items|
|
195
|
-
message << "#{spec}\nis missing the following required recipes:\n"
|
196
|
-
missing_items.each { |_cb, recipe| message << "* #{recipe}\n" }
|
197
|
-
end
|
198
|
-
|
199
|
-
message << "\n"
|
200
|
-
message << "You may have specified an incorrect recipe in your run list,\nor this recipe may not be available in that version of the cookbook\n"
|
201
|
-
|
202
|
-
raise CookbookDoesNotContainRequiredRecipe, message
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
def create_spec_for_cookbook(cookbook_name, version)
|
207
|
-
matching_source = best_source_for(cookbook_name)
|
208
|
-
source_options = matching_source.source_options_for(cookbook_name, version)
|
209
|
-
spec = Policyfile::CookbookLocationSpecification.new(cookbook_name, "= #{version}", source_options, storage_config)
|
210
|
-
@artifact_server_cookbook_location_specs[cookbook_name] = spec
|
211
|
-
end
|
212
|
-
|
213
|
-
def all_cookbook_location_specs
|
214
|
-
# in the installation process, we create "artifact_server_cookbook_location_specs"
|
215
|
-
# for any cookbook that isn't sourced from a single-version source (e.g.,
|
216
|
-
# path and git only support one version at a time), but we might have
|
217
|
-
# specs for them to track additional version constraint demands. Merging
|
218
|
-
# in this order ensures the artifact_server_cookbook_location_specs "win".
|
219
|
-
cookbook_location_specs.merge(@artifact_server_cookbook_location_specs)
|
220
|
-
end
|
221
|
-
|
222
|
-
##
|
223
|
-
# Compilation Methods
|
224
|
-
##
|
225
|
-
|
226
|
-
def graph_solution
|
227
|
-
return @solution if @solution
|
228
|
-
cache_fixed_version_cookbooks
|
229
|
-
@solution = Solve.it!(graph, graph_demands)
|
230
|
-
end
|
231
|
-
|
232
|
-
def graph
|
233
|
-
@graph ||= Solve::Graph.new.tap do |g|
|
234
|
-
artifacts_graph.each do |name, dependencies_by_version|
|
235
|
-
dependencies_by_version.each do |version, dependencies|
|
236
|
-
artifact = g.artifact(name, version)
|
237
|
-
dependencies.each do |dep_name, constraint|
|
238
|
-
artifact.dependency(dep_name, constraint)
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
def solution_dependencies
|
246
|
-
solution_deps = Policyfile::SolutionDependencies.new
|
247
|
-
|
248
|
-
all_cookbook_location_specs.each do |name, spec|
|
249
|
-
solution_deps.add_policyfile_dep(name, spec.version_constraint)
|
250
|
-
end
|
251
|
-
|
252
|
-
graph_solution.each do |name, version|
|
253
|
-
transitive_deps = artifacts_graph[name][version]
|
254
|
-
solution_deps.add_cookbook_dep(name, version, transitive_deps)
|
255
|
-
end
|
256
|
-
solution_deps
|
257
|
-
end
|
258
|
-
|
259
|
-
def graph_demands
|
260
|
-
## TODO: By merging cookbooks from the current policyfile and included policies,
|
261
|
-
# we lose the ability to know where a conflict came from
|
262
|
-
(cookbook_demands_from_current + cookbook_demands_from_policies)
|
263
|
-
end
|
264
|
-
|
265
|
-
def artifacts_graph
|
266
|
-
remote_artifacts_graph.merge(local_artifacts_graph)
|
267
|
-
end
|
268
|
-
|
269
|
-
# Gives a dependency graph for cookbooks that are source from an alternate
|
270
|
-
# location. These cookbooks could have a different set of dependencies
|
271
|
-
# compared to an unmodified copy upstream. For example, the community site
|
272
|
-
# may have a cookbook "apache2" at version "1.10.4", which the user has
|
273
|
-
# forked on github and modified the dependencies without changing the
|
274
|
-
# version number. To accomodate this, the local_artifacts_graph should be
|
275
|
-
# merged over the upstream's artifacts graph.
|
276
|
-
def local_artifacts_graph
|
277
|
-
cookbook_location_specs.inject({}) do |local_artifacts, (cookbook_name, cookbook_location_spec)|
|
278
|
-
if cookbook_location_spec.version_fixed?
|
279
|
-
local_artifacts[cookbook_name] = { cookbook_location_spec.version => cookbook_location_spec.dependencies }
|
280
|
-
end
|
281
|
-
local_artifacts
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
def remote_artifacts_graph
|
286
|
-
@merged_graph ||=
|
287
|
-
begin
|
288
|
-
conflicting_cb_names = []
|
289
|
-
merged = {}
|
290
|
-
default_source.each do |source|
|
291
|
-
merged.merge!(source.universe_graph) do |conflicting_cb_name, _old, _new|
|
292
|
-
if (preference = preferred_source_for_cookbook(conflicting_cb_name))
|
293
|
-
preference.universe_graph[conflicting_cb_name]
|
294
|
-
elsif cookbook_could_appear_in_solution?(conflicting_cb_name)
|
295
|
-
conflicting_cb_names << conflicting_cb_name
|
296
|
-
{} # return empty set of versions
|
297
|
-
else
|
298
|
-
{} # return empty set of versions
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|
302
|
-
handle_conflicting_cookbooks(conflicting_cb_names)
|
303
|
-
merged
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
def version_constraint_for(cookbook_name)
|
308
|
-
if (cookbook_location_spec = cookbook_location_spec_for(cookbook_name)) && cookbook_location_spec.version_fixed?
|
309
|
-
version = cookbook_location_spec.version
|
310
|
-
"= #{version}"
|
311
|
-
else
|
312
|
-
DEFAULT_DEMAND_CONSTRAINT
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
def cookbook_version_fixed?(cookbook_name)
|
317
|
-
if ( cookbook_location_spec = cookbook_location_spec_for(cookbook_name) )
|
318
|
-
cookbook_location_spec.version_fixed?
|
319
|
-
else
|
320
|
-
false
|
321
|
-
end
|
322
|
-
end
|
323
|
-
|
324
|
-
def cookbooks_in_run_list
|
325
|
-
recipes = combined_run_lists.map { |recipe| recipe.name }
|
326
|
-
recipes.map { |r| r[/^([^:]+)/, 1] }
|
327
|
-
end
|
328
|
-
|
329
|
-
def combined_run_lists
|
330
|
-
expanded_named_run_lists.values.inject(expanded_run_list.to_a) do |accum_run_lists, run_list|
|
331
|
-
accum_run_lists | run_list.to_a
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
def combined_run_lists_by_cb_name
|
336
|
-
combined_run_lists.inject({}) do |by_name_accum, run_list_item|
|
337
|
-
by_name_accum
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
def build
|
342
|
-
yield @dsl
|
343
|
-
self
|
344
|
-
end
|
345
|
-
|
346
|
-
def evaluate_policyfile(policyfile_string, policyfile_filename)
|
347
|
-
storage_config.use_policyfile(policyfile_filename)
|
348
|
-
@dsl.eval_policyfile(policyfile_string)
|
349
|
-
self
|
350
|
-
end
|
351
|
-
|
352
|
-
def fixed_version_cookbooks_specs
|
353
|
-
@fixed_version_cookbooks_specs ||= cookbook_location_specs.select do |_cookbook_name, cookbook_location_spec|
|
354
|
-
cookbook_location_spec.version_fixed?
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
private
|
359
|
-
|
360
|
-
def normalize_recipe(run_list_item)
|
361
|
-
name = run_list_item.name
|
362
|
-
name = "#{name}::default" unless name.include?("::")
|
363
|
-
"recipe[#{name}]"
|
364
|
-
end
|
365
|
-
|
366
|
-
def cookbooks_for_demands
|
367
|
-
(cookbooks_in_run_list + cookbook_location_specs.keys).uniq
|
368
|
-
end
|
369
|
-
|
370
|
-
def cache_fixed_version_cookbooks
|
371
|
-
ensure_cache_dir_exists
|
372
|
-
|
373
|
-
fixed_version_cookbooks_specs.each do |name, cookbook_location_spec|
|
374
|
-
install_report.installing_fixed_version_cookbook(cookbook_location_spec)
|
375
|
-
cookbook_location_spec.ensure_cached
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
|
-
def ensure_cache_dir_exists
|
380
|
-
unless File.exist?(cache_path)
|
381
|
-
FileUtils.mkdir_p(cache_path)
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
def cache_path
|
386
|
-
CookbookOmnifetch.storage_path
|
387
|
-
end
|
388
|
-
|
389
|
-
def best_source_for(cookbook_name)
|
390
|
-
preferred = default_source.find { |s| s.preferred_source_for?(cookbook_name) }
|
391
|
-
if preferred.nil?
|
392
|
-
default_source.find do |s|
|
393
|
-
s.universe_graph.has_key?(cookbook_name)
|
394
|
-
end
|
395
|
-
else
|
396
|
-
preferred
|
397
|
-
end
|
398
|
-
end
|
399
|
-
|
400
|
-
def preferred_source_for_cookbook(conflicting_cb_name)
|
401
|
-
default_source.find { |s| s.preferred_source_for?(conflicting_cb_name) }
|
402
|
-
end
|
403
|
-
|
404
|
-
def handle_conflicting_cookbooks(conflicting_cookbooks)
|
405
|
-
# ignore any cookbooks that have a source set.
|
406
|
-
cookbooks_wo_source = conflicting_cookbooks.select do |cookbook_name|
|
407
|
-
location_spec = cookbook_location_spec_for(cookbook_name)
|
408
|
-
location_spec.nil? || location_spec.source_options.empty?
|
409
|
-
end
|
410
|
-
|
411
|
-
if cookbooks_wo_source.empty?
|
412
|
-
nil
|
413
|
-
else
|
414
|
-
raise CookbookSourceConflict.new(cookbooks_wo_source, default_source)
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
def cookbook_could_appear_in_solution?(cookbook_name)
|
419
|
-
all_possible_dep_names.include?(cookbook_name)
|
420
|
-
end
|
421
|
-
|
422
|
-
# Traverses the dependency graph in a simple manner to find the set of
|
423
|
-
# cookbooks that could be considered in the dependency solution. Version
|
424
|
-
# constraints are not considered so this could include extra cookbooks.
|
425
|
-
def all_possible_dep_names
|
426
|
-
@all_possible_dep_names ||= cookbooks_for_demands.inject(Set.new) do |deps_set, demand_cookbook|
|
427
|
-
|
428
|
-
deps_set_for_source = default_source.inject(Set.new) do |deps_set_for_cb, source|
|
429
|
-
possible_deps = possible_dependencies_of(demand_cookbook, source)
|
430
|
-
deps_set_for_cb.merge(possible_deps)
|
431
|
-
end
|
432
|
-
|
433
|
-
deps_set.merge(deps_set_for_source)
|
434
|
-
end
|
435
|
-
end
|
436
|
-
|
437
|
-
def possible_dependencies_of(cookbook_name, source, dependency_set = Set.new)
|
438
|
-
return dependency_set if dependency_set.include?(cookbook_name)
|
439
|
-
return dependency_set unless source.universe_graph.key?(cookbook_name)
|
440
|
-
|
441
|
-
dependency_set << cookbook_name
|
442
|
-
|
443
|
-
deps_by_version = source.universe_graph[cookbook_name]
|
444
|
-
|
445
|
-
dep_cookbook_names = deps_by_version.values.inject(Set.new) do |names, constraint_list|
|
446
|
-
names.merge(constraint_list.map { |c| c.first })
|
447
|
-
end
|
448
|
-
|
449
|
-
dep_cookbook_names.each do |dep_cookbook_name|
|
450
|
-
possible_dependencies_of(dep_cookbook_name, source, dependency_set)
|
451
|
-
end
|
452
|
-
|
453
|
-
dependency_set
|
454
|
-
end
|
455
|
-
|
456
|
-
def check_for_default_attribute_conflicts!
|
457
|
-
checker = Policyfile::AttributeMergeChecker.new
|
458
|
-
checker.with_attributes("user-specified", dsl.node_attributes.combined_default)
|
459
|
-
included_policies.map do |policy_spec|
|
460
|
-
lock = policy_spec.policyfile_lock
|
461
|
-
checker.with_attributes(policy_spec.name, lock.default_attributes)
|
462
|
-
end
|
463
|
-
checker.check!
|
464
|
-
end
|
465
|
-
|
466
|
-
def check_for_override_attribute_conflicts!
|
467
|
-
checker = Policyfile::AttributeMergeChecker.new
|
468
|
-
checker.with_attributes("user-specified", dsl.node_attributes.combined_override)
|
469
|
-
included_policies.map do |policy_spec|
|
470
|
-
lock = policy_spec.policyfile_lock
|
471
|
-
checker.with_attributes(policy_spec.name, lock.override_attributes)
|
472
|
-
end
|
473
|
-
checker.check!
|
474
|
-
end
|
475
|
-
|
476
|
-
def cookbook_demands_from_policies
|
477
|
-
included_policies.flat_map do |policy_spec|
|
478
|
-
lock = policy_spec.policyfile_lock
|
479
|
-
lock.solution_dependencies.to_lock["Policyfile"]
|
480
|
-
end
|
481
|
-
end
|
482
|
-
|
483
|
-
def cookbook_demands_from_current
|
484
|
-
cookbooks_for_demands.map do |cookbook_name|
|
485
|
-
spec = cookbook_location_spec_for(cookbook_name)
|
486
|
-
if spec.nil?
|
487
|
-
[ cookbook_name, DEFAULT_DEMAND_CONSTRAINT ]
|
488
|
-
elsif spec.version_fixed?
|
489
|
-
[ cookbook_name, "= #{spec.version}" ]
|
490
|
-
else
|
491
|
-
[ cookbook_name, spec.version_constraint.to_s ]
|
492
|
-
end
|
493
|
-
end
|
494
|
-
end
|
495
|
-
|
496
|
-
def included_policies_cookbook_source
|
497
|
-
@included_policies_cookbook_source ||= begin
|
498
|
-
source = Policyfile::IncludedPoliciesCookbookSource.new(included_policies)
|
499
|
-
handle_included_policies_preferred_cookbook_conflicts(source)
|
500
|
-
source
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
def handle_included_policies_preferred_cookbook_conflicts(included_policies_source)
|
505
|
-
# All cookbooks in the included policies are preferred.
|
506
|
-
conflicting_source_messages = []
|
507
|
-
dsl.default_source.reject { |s| s.null? }.each do |source_b|
|
508
|
-
conflicting_preferences = included_policies_source.preferred_cookbooks & source_b.preferred_cookbooks
|
509
|
-
next if conflicting_preferences.empty?
|
510
|
-
next if conflicting_preferences.all? do |cookbook_name|
|
511
|
-
version = included_policies_source.universe_graph[cookbook_name].keys.first
|
512
|
-
if included_policies_source.source_options_for(cookbook_name, version) == source_b.source_options_for(cookbook_name, version)
|
513
|
-
true
|
514
|
-
else
|
515
|
-
false
|
516
|
-
end
|
517
|
-
end
|
518
|
-
conflicting_source_messages << "#{source_b.desc} sets a preferred for cookbook(s) #{conflicting_preferences.join(', ')}. This conflicts with an included policy."
|
519
|
-
end
|
520
|
-
unless conflicting_source_messages.empty?
|
521
|
-
msg = "You may not override the cookbook sources for any cookbooks required by included policies.\n"
|
522
|
-
msg << conflicting_source_messages.join("\n") << "\n"
|
523
|
-
raise IncludePolicyCookbookSourceConflict.new(msg)
|
524
|
-
end
|
525
|
-
end
|
526
|
-
|
527
|
-
end
|
528
|
-
end
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014-2018, 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 "set"
|
19
|
+
require "forwardable"
|
20
|
+
|
21
|
+
require "solve"
|
22
|
+
require "chef/run_list"
|
23
|
+
require "chef/mixin/deep_merge"
|
24
|
+
|
25
|
+
require "chef-dk/policyfile/dsl"
|
26
|
+
require "chef-dk/policyfile/attribute_merge_checker"
|
27
|
+
require "chef-dk/policyfile/included_policies_cookbook_source"
|
28
|
+
require "chef-dk/policyfile_lock"
|
29
|
+
require "chef-dk/ui"
|
30
|
+
require "chef-dk/policyfile/reports/install"
|
31
|
+
require "chef-dk/exceptions"
|
32
|
+
|
33
|
+
module ChefDK
|
34
|
+
|
35
|
+
class PolicyfileCompiler
|
36
|
+
|
37
|
+
extend Forwardable
|
38
|
+
|
39
|
+
DEFAULT_DEMAND_CONSTRAINT = ">= 0.0.0".freeze
|
40
|
+
|
41
|
+
# Cookbooks from these sources lock that cookbook to exactly one version
|
42
|
+
SOURCE_TYPES_WITH_FIXED_VERSIONS = [:git, :path].freeze
|
43
|
+
|
44
|
+
def self.evaluate(policyfile_string, policyfile_filename, ui: nil, chef_config: nil)
|
45
|
+
compiler = new(ui: ui, chef_config: chef_config)
|
46
|
+
compiler.evaluate_policyfile(policyfile_string, policyfile_filename)
|
47
|
+
compiler
|
48
|
+
end
|
49
|
+
|
50
|
+
def_delegator :@dsl, :name
|
51
|
+
def_delegator :@dsl, :run_list
|
52
|
+
def_delegator :@dsl, :named_run_list
|
53
|
+
def_delegator :@dsl, :named_run_lists
|
54
|
+
def_delegator :@dsl, :errors
|
55
|
+
def_delegator :@dsl, :cookbook_location_specs
|
56
|
+
def_delegator :@dsl, :included_policies
|
57
|
+
|
58
|
+
attr_reader :dsl
|
59
|
+
attr_reader :storage_config
|
60
|
+
attr_reader :install_report
|
61
|
+
|
62
|
+
def initialize(ui: nil, chef_config: nil)
|
63
|
+
@storage_config = Policyfile::StorageConfig.new
|
64
|
+
@dsl = Policyfile::DSL.new(storage_config, chef_config: chef_config)
|
65
|
+
@artifact_server_cookbook_location_specs = {}
|
66
|
+
|
67
|
+
@merged_graph = nil
|
68
|
+
|
69
|
+
@ui = ui || UI.null
|
70
|
+
@install_report = Policyfile::Reports::Install.new(ui: @ui, policyfile_compiler: self)
|
71
|
+
end
|
72
|
+
|
73
|
+
def default_source(source_type = nil, source_argument = nil, &block)
|
74
|
+
if source_type.nil?
|
75
|
+
prepend_array = if included_policies.length > 0
|
76
|
+
[included_policies_cookbook_source]
|
77
|
+
else
|
78
|
+
[]
|
79
|
+
end
|
80
|
+
prepend_array + dsl.default_source
|
81
|
+
else
|
82
|
+
dsl.default_source(source_type, source_argument, &block)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def error!
|
87
|
+
unless errors.empty?
|
88
|
+
raise PolicyfileError, errors.join("\n")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def cookbook_location_spec_for(cookbook_name)
|
93
|
+
cookbook_location_specs[cookbook_name]
|
94
|
+
end
|
95
|
+
|
96
|
+
def expanded_run_list
|
97
|
+
# doesn't support roles yet...
|
98
|
+
concated_runlist = Chef::RunList.new
|
99
|
+
included_policies.each do |policy_spec|
|
100
|
+
lock = policy_spec.policyfile_lock
|
101
|
+
lock.run_list.each do |run_list_item|
|
102
|
+
concated_runlist << run_list_item
|
103
|
+
end
|
104
|
+
end
|
105
|
+
run_list.each do |run_list_item|
|
106
|
+
concated_runlist << run_list_item
|
107
|
+
end
|
108
|
+
concated_runlist
|
109
|
+
end
|
110
|
+
|
111
|
+
# copy of the expanded_run_list, properly formatted for use in a lockfile
|
112
|
+
def normalized_run_list
|
113
|
+
expanded_run_list.map { |i| normalize_recipe(i) }
|
114
|
+
end
|
115
|
+
|
116
|
+
def expanded_named_run_lists
|
117
|
+
included_policies_named_runlists = included_policies.inject({}) do |acc, policy_spec|
|
118
|
+
lock = policy_spec.policyfile_lock
|
119
|
+
lock.named_run_lists.inject(acc) do |expanded, (name, run_list_items)|
|
120
|
+
expanded[name] ||= Chef::RunList.new
|
121
|
+
run_list_items.each do |run_list_item|
|
122
|
+
expanded[name] << run_list_item
|
123
|
+
end
|
124
|
+
expanded
|
125
|
+
end
|
126
|
+
acc
|
127
|
+
end
|
128
|
+
|
129
|
+
named_run_lists.inject(included_policies_named_runlists) do |expanded, (name, run_list_items)|
|
130
|
+
expanded[name] ||= Chef::RunList.new
|
131
|
+
run_list_items.each do |run_list_item|
|
132
|
+
expanded[name] << run_list_item
|
133
|
+
end
|
134
|
+
expanded
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def normalized_named_run_lists
|
139
|
+
expanded_named_run_lists.inject({}) do |normalized, (name, run_list)|
|
140
|
+
normalized[name] = run_list.map { |i| normalize_recipe(i) }
|
141
|
+
normalized
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def default_attributes
|
146
|
+
check_for_default_attribute_conflicts!
|
147
|
+
included_policies.map { |p| p.policyfile_lock }.inject(
|
148
|
+
dsl.node_attributes.combined_default.to_hash) do |acc, lock|
|
149
|
+
Chef::Mixin::DeepMerge.merge(acc, lock.default_attributes)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def override_attributes
|
154
|
+
check_for_override_attribute_conflicts!
|
155
|
+
included_policies.map { |p| p.policyfile_lock }.inject(
|
156
|
+
dsl.node_attributes.combined_override.to_hash) do |acc, lock|
|
157
|
+
Chef::Mixin::DeepMerge.merge(acc, lock.override_attributes)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def lock
|
162
|
+
@policyfile_lock ||= PolicyfileLock.build_from_compiler(self, storage_config)
|
163
|
+
end
|
164
|
+
|
165
|
+
def install
|
166
|
+
ensure_cache_dir_exists
|
167
|
+
|
168
|
+
cookbook_and_recipe_list = combined_run_lists.map(&:name).map do |recipe_spec|
|
169
|
+
cookbook, _separator, recipe = recipe_spec.partition("::")
|
170
|
+
recipe = "default" if recipe.empty?
|
171
|
+
[cookbook, recipe]
|
172
|
+
end
|
173
|
+
|
174
|
+
missing_recipes_by_cb_spec = {}
|
175
|
+
|
176
|
+
graph_solution.each do |cookbook_name, version|
|
177
|
+
spec = cookbook_location_spec_for(cookbook_name)
|
178
|
+
if spec.nil? || !spec.version_fixed?
|
179
|
+
spec = create_spec_for_cookbook(cookbook_name, version)
|
180
|
+
install_report.installing_cookbook(spec)
|
181
|
+
spec.ensure_cached
|
182
|
+
end
|
183
|
+
|
184
|
+
required_recipes = cookbook_and_recipe_list.select { |cb_name, _recipe| cb_name == spec.name }
|
185
|
+
missing_recipes = required_recipes.select { |_cb_name, recipe| !spec.cookbook_has_recipe?(recipe) }
|
186
|
+
|
187
|
+
unless missing_recipes.empty?
|
188
|
+
missing_recipes_by_cb_spec[spec] = missing_recipes
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
unless missing_recipes_by_cb_spec.empty?
|
193
|
+
message = "The installed cookbooks do not contain all the recipes required by your run list(s):\n"
|
194
|
+
missing_recipes_by_cb_spec.each do |spec, missing_items|
|
195
|
+
message << "#{spec}\nis missing the following required recipes:\n"
|
196
|
+
missing_items.each { |_cb, recipe| message << "* #{recipe}\n" }
|
197
|
+
end
|
198
|
+
|
199
|
+
message << "\n"
|
200
|
+
message << "You may have specified an incorrect recipe in your run list,\nor this recipe may not be available in that version of the cookbook\n"
|
201
|
+
|
202
|
+
raise CookbookDoesNotContainRequiredRecipe, message
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def create_spec_for_cookbook(cookbook_name, version)
|
207
|
+
matching_source = best_source_for(cookbook_name)
|
208
|
+
source_options = matching_source.source_options_for(cookbook_name, version)
|
209
|
+
spec = Policyfile::CookbookLocationSpecification.new(cookbook_name, "= #{version}", source_options, storage_config)
|
210
|
+
@artifact_server_cookbook_location_specs[cookbook_name] = spec
|
211
|
+
end
|
212
|
+
|
213
|
+
def all_cookbook_location_specs
|
214
|
+
# in the installation process, we create "artifact_server_cookbook_location_specs"
|
215
|
+
# for any cookbook that isn't sourced from a single-version source (e.g.,
|
216
|
+
# path and git only support one version at a time), but we might have
|
217
|
+
# specs for them to track additional version constraint demands. Merging
|
218
|
+
# in this order ensures the artifact_server_cookbook_location_specs "win".
|
219
|
+
cookbook_location_specs.merge(@artifact_server_cookbook_location_specs)
|
220
|
+
end
|
221
|
+
|
222
|
+
##
|
223
|
+
# Compilation Methods
|
224
|
+
##
|
225
|
+
|
226
|
+
def graph_solution
|
227
|
+
return @solution if @solution
|
228
|
+
cache_fixed_version_cookbooks
|
229
|
+
@solution = Solve.it!(graph, graph_demands)
|
230
|
+
end
|
231
|
+
|
232
|
+
def graph
|
233
|
+
@graph ||= Solve::Graph.new.tap do |g|
|
234
|
+
artifacts_graph.each do |name, dependencies_by_version|
|
235
|
+
dependencies_by_version.each do |version, dependencies|
|
236
|
+
artifact = g.artifact(name, version)
|
237
|
+
dependencies.each do |dep_name, constraint|
|
238
|
+
artifact.dependency(dep_name, constraint)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def solution_dependencies
|
246
|
+
solution_deps = Policyfile::SolutionDependencies.new
|
247
|
+
|
248
|
+
all_cookbook_location_specs.each do |name, spec|
|
249
|
+
solution_deps.add_policyfile_dep(name, spec.version_constraint)
|
250
|
+
end
|
251
|
+
|
252
|
+
graph_solution.each do |name, version|
|
253
|
+
transitive_deps = artifacts_graph[name][version]
|
254
|
+
solution_deps.add_cookbook_dep(name, version, transitive_deps)
|
255
|
+
end
|
256
|
+
solution_deps
|
257
|
+
end
|
258
|
+
|
259
|
+
def graph_demands
|
260
|
+
## TODO: By merging cookbooks from the current policyfile and included policies,
|
261
|
+
# we lose the ability to know where a conflict came from
|
262
|
+
(cookbook_demands_from_current + cookbook_demands_from_policies)
|
263
|
+
end
|
264
|
+
|
265
|
+
def artifacts_graph
|
266
|
+
remote_artifacts_graph.merge(local_artifacts_graph)
|
267
|
+
end
|
268
|
+
|
269
|
+
# Gives a dependency graph for cookbooks that are source from an alternate
|
270
|
+
# location. These cookbooks could have a different set of dependencies
|
271
|
+
# compared to an unmodified copy upstream. For example, the community site
|
272
|
+
# may have a cookbook "apache2" at version "1.10.4", which the user has
|
273
|
+
# forked on github and modified the dependencies without changing the
|
274
|
+
# version number. To accomodate this, the local_artifacts_graph should be
|
275
|
+
# merged over the upstream's artifacts graph.
|
276
|
+
def local_artifacts_graph
|
277
|
+
cookbook_location_specs.inject({}) do |local_artifacts, (cookbook_name, cookbook_location_spec)|
|
278
|
+
if cookbook_location_spec.version_fixed?
|
279
|
+
local_artifacts[cookbook_name] = { cookbook_location_spec.version => cookbook_location_spec.dependencies }
|
280
|
+
end
|
281
|
+
local_artifacts
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def remote_artifacts_graph
|
286
|
+
@merged_graph ||=
|
287
|
+
begin
|
288
|
+
conflicting_cb_names = []
|
289
|
+
merged = {}
|
290
|
+
default_source.each do |source|
|
291
|
+
merged.merge!(source.universe_graph) do |conflicting_cb_name, _old, _new|
|
292
|
+
if (preference = preferred_source_for_cookbook(conflicting_cb_name))
|
293
|
+
preference.universe_graph[conflicting_cb_name]
|
294
|
+
elsif cookbook_could_appear_in_solution?(conflicting_cb_name)
|
295
|
+
conflicting_cb_names << conflicting_cb_name
|
296
|
+
{} # return empty set of versions
|
297
|
+
else
|
298
|
+
{} # return empty set of versions
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
handle_conflicting_cookbooks(conflicting_cb_names)
|
303
|
+
merged
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def version_constraint_for(cookbook_name)
|
308
|
+
if (cookbook_location_spec = cookbook_location_spec_for(cookbook_name)) && cookbook_location_spec.version_fixed?
|
309
|
+
version = cookbook_location_spec.version
|
310
|
+
"= #{version}"
|
311
|
+
else
|
312
|
+
DEFAULT_DEMAND_CONSTRAINT
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def cookbook_version_fixed?(cookbook_name)
|
317
|
+
if ( cookbook_location_spec = cookbook_location_spec_for(cookbook_name) )
|
318
|
+
cookbook_location_spec.version_fixed?
|
319
|
+
else
|
320
|
+
false
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def cookbooks_in_run_list
|
325
|
+
recipes = combined_run_lists.map { |recipe| recipe.name }
|
326
|
+
recipes.map { |r| r[/^([^:]+)/, 1] }
|
327
|
+
end
|
328
|
+
|
329
|
+
def combined_run_lists
|
330
|
+
expanded_named_run_lists.values.inject(expanded_run_list.to_a) do |accum_run_lists, run_list|
|
331
|
+
accum_run_lists | run_list.to_a
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
def combined_run_lists_by_cb_name
|
336
|
+
combined_run_lists.inject({}) do |by_name_accum, run_list_item|
|
337
|
+
by_name_accum
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def build
|
342
|
+
yield @dsl
|
343
|
+
self
|
344
|
+
end
|
345
|
+
|
346
|
+
def evaluate_policyfile(policyfile_string, policyfile_filename)
|
347
|
+
storage_config.use_policyfile(policyfile_filename)
|
348
|
+
@dsl.eval_policyfile(policyfile_string)
|
349
|
+
self
|
350
|
+
end
|
351
|
+
|
352
|
+
def fixed_version_cookbooks_specs
|
353
|
+
@fixed_version_cookbooks_specs ||= cookbook_location_specs.select do |_cookbook_name, cookbook_location_spec|
|
354
|
+
cookbook_location_spec.version_fixed?
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
private
|
359
|
+
|
360
|
+
def normalize_recipe(run_list_item)
|
361
|
+
name = run_list_item.name
|
362
|
+
name = "#{name}::default" unless name.include?("::")
|
363
|
+
"recipe[#{name}]"
|
364
|
+
end
|
365
|
+
|
366
|
+
def cookbooks_for_demands
|
367
|
+
(cookbooks_in_run_list + cookbook_location_specs.keys).uniq
|
368
|
+
end
|
369
|
+
|
370
|
+
def cache_fixed_version_cookbooks
|
371
|
+
ensure_cache_dir_exists
|
372
|
+
|
373
|
+
fixed_version_cookbooks_specs.each do |name, cookbook_location_spec|
|
374
|
+
install_report.installing_fixed_version_cookbook(cookbook_location_spec)
|
375
|
+
cookbook_location_spec.ensure_cached
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def ensure_cache_dir_exists
|
380
|
+
unless File.exist?(cache_path)
|
381
|
+
FileUtils.mkdir_p(cache_path)
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
def cache_path
|
386
|
+
CookbookOmnifetch.storage_path
|
387
|
+
end
|
388
|
+
|
389
|
+
def best_source_for(cookbook_name)
|
390
|
+
preferred = default_source.find { |s| s.preferred_source_for?(cookbook_name) }
|
391
|
+
if preferred.nil?
|
392
|
+
default_source.find do |s|
|
393
|
+
s.universe_graph.has_key?(cookbook_name)
|
394
|
+
end
|
395
|
+
else
|
396
|
+
preferred
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
def preferred_source_for_cookbook(conflicting_cb_name)
|
401
|
+
default_source.find { |s| s.preferred_source_for?(conflicting_cb_name) }
|
402
|
+
end
|
403
|
+
|
404
|
+
def handle_conflicting_cookbooks(conflicting_cookbooks)
|
405
|
+
# ignore any cookbooks that have a source set.
|
406
|
+
cookbooks_wo_source = conflicting_cookbooks.select do |cookbook_name|
|
407
|
+
location_spec = cookbook_location_spec_for(cookbook_name)
|
408
|
+
location_spec.nil? || location_spec.source_options.empty?
|
409
|
+
end
|
410
|
+
|
411
|
+
if cookbooks_wo_source.empty?
|
412
|
+
nil
|
413
|
+
else
|
414
|
+
raise CookbookSourceConflict.new(cookbooks_wo_source, default_source)
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
def cookbook_could_appear_in_solution?(cookbook_name)
|
419
|
+
all_possible_dep_names.include?(cookbook_name)
|
420
|
+
end
|
421
|
+
|
422
|
+
# Traverses the dependency graph in a simple manner to find the set of
|
423
|
+
# cookbooks that could be considered in the dependency solution. Version
|
424
|
+
# constraints are not considered so this could include extra cookbooks.
|
425
|
+
def all_possible_dep_names
|
426
|
+
@all_possible_dep_names ||= cookbooks_for_demands.inject(Set.new) do |deps_set, demand_cookbook|
|
427
|
+
|
428
|
+
deps_set_for_source = default_source.inject(Set.new) do |deps_set_for_cb, source|
|
429
|
+
possible_deps = possible_dependencies_of(demand_cookbook, source)
|
430
|
+
deps_set_for_cb.merge(possible_deps)
|
431
|
+
end
|
432
|
+
|
433
|
+
deps_set.merge(deps_set_for_source)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
def possible_dependencies_of(cookbook_name, source, dependency_set = Set.new)
|
438
|
+
return dependency_set if dependency_set.include?(cookbook_name)
|
439
|
+
return dependency_set unless source.universe_graph.key?(cookbook_name)
|
440
|
+
|
441
|
+
dependency_set << cookbook_name
|
442
|
+
|
443
|
+
deps_by_version = source.universe_graph[cookbook_name]
|
444
|
+
|
445
|
+
dep_cookbook_names = deps_by_version.values.inject(Set.new) do |names, constraint_list|
|
446
|
+
names.merge(constraint_list.map { |c| c.first })
|
447
|
+
end
|
448
|
+
|
449
|
+
dep_cookbook_names.each do |dep_cookbook_name|
|
450
|
+
possible_dependencies_of(dep_cookbook_name, source, dependency_set)
|
451
|
+
end
|
452
|
+
|
453
|
+
dependency_set
|
454
|
+
end
|
455
|
+
|
456
|
+
def check_for_default_attribute_conflicts!
|
457
|
+
checker = Policyfile::AttributeMergeChecker.new
|
458
|
+
checker.with_attributes("user-specified", dsl.node_attributes.combined_default)
|
459
|
+
included_policies.map do |policy_spec|
|
460
|
+
lock = policy_spec.policyfile_lock
|
461
|
+
checker.with_attributes(policy_spec.name, lock.default_attributes)
|
462
|
+
end
|
463
|
+
checker.check!
|
464
|
+
end
|
465
|
+
|
466
|
+
def check_for_override_attribute_conflicts!
|
467
|
+
checker = Policyfile::AttributeMergeChecker.new
|
468
|
+
checker.with_attributes("user-specified", dsl.node_attributes.combined_override)
|
469
|
+
included_policies.map do |policy_spec|
|
470
|
+
lock = policy_spec.policyfile_lock
|
471
|
+
checker.with_attributes(policy_spec.name, lock.override_attributes)
|
472
|
+
end
|
473
|
+
checker.check!
|
474
|
+
end
|
475
|
+
|
476
|
+
def cookbook_demands_from_policies
|
477
|
+
included_policies.flat_map do |policy_spec|
|
478
|
+
lock = policy_spec.policyfile_lock
|
479
|
+
lock.solution_dependencies.to_lock["Policyfile"]
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
def cookbook_demands_from_current
|
484
|
+
cookbooks_for_demands.map do |cookbook_name|
|
485
|
+
spec = cookbook_location_spec_for(cookbook_name)
|
486
|
+
if spec.nil?
|
487
|
+
[ cookbook_name, DEFAULT_DEMAND_CONSTRAINT ]
|
488
|
+
elsif spec.version_fixed?
|
489
|
+
[ cookbook_name, "= #{spec.version}" ]
|
490
|
+
else
|
491
|
+
[ cookbook_name, spec.version_constraint.to_s ]
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
def included_policies_cookbook_source
|
497
|
+
@included_policies_cookbook_source ||= begin
|
498
|
+
source = Policyfile::IncludedPoliciesCookbookSource.new(included_policies)
|
499
|
+
handle_included_policies_preferred_cookbook_conflicts(source)
|
500
|
+
source
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
def handle_included_policies_preferred_cookbook_conflicts(included_policies_source)
|
505
|
+
# All cookbooks in the included policies are preferred.
|
506
|
+
conflicting_source_messages = []
|
507
|
+
dsl.default_source.reject { |s| s.null? }.each do |source_b|
|
508
|
+
conflicting_preferences = included_policies_source.preferred_cookbooks & source_b.preferred_cookbooks
|
509
|
+
next if conflicting_preferences.empty?
|
510
|
+
next if conflicting_preferences.all? do |cookbook_name|
|
511
|
+
version = included_policies_source.universe_graph[cookbook_name].keys.first
|
512
|
+
if included_policies_source.source_options_for(cookbook_name, version) == source_b.source_options_for(cookbook_name, version)
|
513
|
+
true
|
514
|
+
else
|
515
|
+
false
|
516
|
+
end
|
517
|
+
end
|
518
|
+
conflicting_source_messages << "#{source_b.desc} sets a preferred for cookbook(s) #{conflicting_preferences.join(', ')}. This conflicts with an included policy."
|
519
|
+
end
|
520
|
+
unless conflicting_source_messages.empty?
|
521
|
+
msg = "You may not override the cookbook sources for any cookbooks required by included policies.\n"
|
522
|
+
msg << conflicting_source_messages.join("\n") << "\n"
|
523
|
+
raise IncludePolicyCookbookSourceConflict.new(msg)
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
end
|
528
|
+
end
|