chef 10.28.2-x86-mingw32
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 +7 -0
- data/LICENSE +201 -0
- data/README.rdoc +177 -0
- data/Rakefile +128 -0
- data/bin/chef-client +26 -0
- data/bin/chef-solo +25 -0
- data/bin/knife +26 -0
- data/bin/shef +34 -0
- data/distro/README +2 -0
- data/distro/arch/etc/conf.d/chef-client.conf +5 -0
- data/distro/arch/etc/conf.d/chef-expander.conf +8 -0
- data/distro/arch/etc/conf.d/chef-server-webui.conf +10 -0
- data/distro/arch/etc/conf.d/chef-server.conf +10 -0
- data/distro/arch/etc/conf.d/chef-solr.conf +8 -0
- data/distro/arch/etc/rc.d/chef-client +90 -0
- data/distro/arch/etc/rc.d/chef-expander +78 -0
- data/distro/arch/etc/rc.d/chef-server +78 -0
- data/distro/arch/etc/rc.d/chef-server-webui +78 -0
- data/distro/arch/etc/rc.d/chef-solr +78 -0
- data/distro/common/html/chef-client.8.html +145 -0
- data/distro/common/html/chef-expander.8.html +164 -0
- data/distro/common/html/chef-expanderctl.8.html +146 -0
- data/distro/common/html/chef-server-webui.8.html +185 -0
- data/distro/common/html/chef-server.8.html +182 -0
- data/distro/common/html/chef-solo.8.html +185 -0
- data/distro/common/html/chef-solr.8.html +165 -0
- data/distro/common/html/knife-bootstrap.1.html +241 -0
- data/distro/common/html/knife-client.1.html +219 -0
- data/distro/common/html/knife-configure.1.html +170 -0
- data/distro/common/html/knife-cookbook-site.1.html +241 -0
- data/distro/common/html/knife-cookbook.1.html +381 -0
- data/distro/common/html/knife-data-bag.1.html +235 -0
- data/distro/common/html/knife-environment.1.html +265 -0
- data/distro/common/html/knife-exec.1.html +134 -0
- data/distro/common/html/knife-index.1.html +125 -0
- data/distro/common/html/knife-node.1.html +250 -0
- data/distro/common/html/knife-recipe.1.html +92 -0
- data/distro/common/html/knife-role.1.html +200 -0
- data/distro/common/html/knife-search.1.html +288 -0
- data/distro/common/html/knife-ssh.1.html +156 -0
- data/distro/common/html/knife-status.1.html +128 -0
- data/distro/common/html/knife-tag.1.html +137 -0
- data/distro/common/html/knife.1.html +320 -0
- data/distro/common/html/shef.1.html +283 -0
- data/distro/common/man/man1/knife-bootstrap.1 +201 -0
- data/distro/common/man/man1/knife-client.1 +99 -0
- data/distro/common/man/man1/knife-configure.1 +88 -0
- data/distro/common/man/man1/knife-cookbook-site.1 +145 -0
- data/distro/common/man/man1/knife-cookbook.1 +332 -0
- data/distro/common/man/man1/knife-data-bag.1 +123 -0
- data/distro/common/man/man1/knife-environment.1 +168 -0
- data/distro/common/man/man1/knife-exec.1 +46 -0
- data/distro/common/man/man1/knife-index.1 +29 -0
- data/distro/common/man/man1/knife-node.1 +134 -0
- data/distro/common/man/man1/knife-role.1 +88 -0
- data/distro/common/man/man1/knife-search.1 +280 -0
- data/distro/common/man/man1/knife-ssh.1 +79 -0
- data/distro/common/man/man1/knife-status.1 +29 -0
- data/distro/common/man/man1/knife-tag.1 +43 -0
- data/distro/common/man/man1/knife.1 +288 -0
- data/distro/common/man/man1/shef.1 +256 -0
- data/distro/common/man/man8/chef-client.8 +104 -0
- data/distro/common/man/man8/chef-expander.8 +97 -0
- data/distro/common/man/man8/chef-expanderctl.8 +62 -0
- data/distro/common/man/man8/chef-server-webui.8 +155 -0
- data/distro/common/man/man8/chef-server.8 +147 -0
- data/distro/common/man/man8/chef-solo.8 +126 -0
- data/distro/common/man/man8/chef-solr.8 +122 -0
- data/distro/common/markdown/README +3 -0
- data/distro/common/markdown/man1/knife-bootstrap.mkd +141 -0
- data/distro/common/markdown/man1/knife-client.mkd +103 -0
- data/distro/common/markdown/man1/knife-configure.mkd +70 -0
- data/distro/common/markdown/man1/knife-cookbook-site.mkd +123 -0
- data/distro/common/markdown/man1/knife-cookbook.mkd +263 -0
- data/distro/common/markdown/man1/knife-data-bag.mkd +121 -0
- data/distro/common/markdown/man1/knife-environment.mkd +151 -0
- data/distro/common/markdown/man1/knife-exec.mkd +37 -0
- data/distro/common/markdown/man1/knife-index.mkd +30 -0
- data/distro/common/markdown/man1/knife-node.mkd +130 -0
- data/distro/common/markdown/man1/knife-role.mkd +85 -0
- data/distro/common/markdown/man1/knife-search.mkd +180 -0
- data/distro/common/markdown/man1/knife-ssh.mkd +69 -0
- data/distro/common/markdown/man1/knife-status.mkd +36 -0
- data/distro/common/markdown/man1/knife-tag.mkd +39 -0
- data/distro/common/markdown/man1/knife.mkd +218 -0
- data/distro/common/markdown/man1/shef.mkd +189 -0
- data/distro/common/markdown/man8/chef-client.mkd +74 -0
- data/distro/common/markdown/man8/chef-expander.mkd +82 -0
- data/distro/common/markdown/man8/chef-expanderctl.mkd +58 -0
- data/distro/common/markdown/man8/chef-server-webui.mkd +121 -0
- data/distro/common/markdown/man8/chef-server.mkd +121 -0
- data/distro/common/markdown/man8/chef-solo.mkd +107 -0
- data/distro/common/markdown/man8/chef-solr.mkd +89 -0
- data/distro/debian/etc/default/chef-client +5 -0
- data/distro/debian/etc/default/chef-expander +8 -0
- data/distro/debian/etc/default/chef-server +9 -0
- data/distro/debian/etc/default/chef-server-webui +9 -0
- data/distro/debian/etc/default/chef-solr +8 -0
- data/distro/debian/etc/init.d/chef-client +210 -0
- data/distro/debian/etc/init.d/chef-expander +176 -0
- data/distro/debian/etc/init.d/chef-server +122 -0
- data/distro/debian/etc/init.d/chef-server-webui +123 -0
- data/distro/debian/etc/init.d/chef-solr +176 -0
- data/distro/debian/etc/init/chef-client.conf +17 -0
- data/distro/debian/etc/init/chef-expander.conf +17 -0
- data/distro/debian/etc/init/chef-server-webui.conf +17 -0
- data/distro/debian/etc/init/chef-server.conf +17 -0
- data/distro/debian/etc/init/chef-solr.conf +17 -0
- data/distro/redhat/etc/init.d/chef-client +121 -0
- data/distro/redhat/etc/init.d/chef-expander +104 -0
- data/distro/redhat/etc/init.d/chef-server +112 -0
- data/distro/redhat/etc/init.d/chef-server-webui +112 -0
- data/distro/redhat/etc/init.d/chef-solr +104 -0
- data/distro/redhat/etc/logrotate.d/chef-client +8 -0
- data/distro/redhat/etc/logrotate.d/chef-expander +8 -0
- data/distro/redhat/etc/logrotate.d/chef-server +8 -0
- data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
- data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
- data/distro/redhat/etc/sysconfig/chef-client +15 -0
- data/distro/redhat/etc/sysconfig/chef-expander +7 -0
- data/distro/redhat/etc/sysconfig/chef-server +14 -0
- data/distro/redhat/etc/sysconfig/chef-server-webui +14 -0
- data/distro/redhat/etc/sysconfig/chef-solr +8 -0
- data/distro/windows/service_manager.rb +164 -0
- data/lib/chef.rb +41 -0
- data/lib/chef/api_client.rb +293 -0
- data/lib/chef/application.rb +168 -0
- data/lib/chef/application/agent.rb +18 -0
- data/lib/chef/application/client.rb +322 -0
- data/lib/chef/application/knife.rb +183 -0
- data/lib/chef/application/solo.rb +248 -0
- data/lib/chef/application/windows_service.rb +227 -0
- data/lib/chef/applications.rb +4 -0
- data/lib/chef/certificate.rb +161 -0
- data/lib/chef/checksum.rb +167 -0
- data/lib/chef/checksum/storage.rb +18 -0
- data/lib/chef/checksum/storage/filesystem.rb +56 -0
- data/lib/chef/checksum_cache.rb +190 -0
- data/lib/chef/client.rb +499 -0
- data/lib/chef/config.rb +330 -0
- data/lib/chef/cookbook/chefignore.rb +66 -0
- data/lib/chef/cookbook/cookbook_collection.rb +45 -0
- data/lib/chef/cookbook/cookbook_version_loader.rb +171 -0
- data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
- data/lib/chef/cookbook/file_vendor.rb +48 -0
- data/lib/chef/cookbook/metadata.rb +629 -0
- data/lib/chef/cookbook/remote_file_vendor.rb +84 -0
- data/lib/chef/cookbook/synchronizer.rb +218 -0
- data/lib/chef/cookbook/syntax_check.rb +136 -0
- data/lib/chef/cookbook_loader.rb +121 -0
- data/lib/chef/cookbook_site_streaming_uploader.rb +244 -0
- data/lib/chef/cookbook_uploader.rb +173 -0
- data/lib/chef/cookbook_version.rb +1081 -0
- data/lib/chef/cookbook_version_selector.rb +168 -0
- data/lib/chef/couchdb.rb +246 -0
- data/lib/chef/daemon.rb +187 -0
- data/lib/chef/data_bag.rb +239 -0
- data/lib/chef/data_bag_item.rb +277 -0
- data/lib/chef/encrypted_data_bag_item.rb +268 -0
- data/lib/chef/environment.rb +458 -0
- data/lib/chef/event_dispatch/base.rb +311 -0
- data/lib/chef/event_dispatch/dispatcher.rb +42 -0
- data/lib/chef/exceptions.rb +192 -0
- data/lib/chef/file_access_control.rb +75 -0
- data/lib/chef/file_access_control/unix.rb +216 -0
- data/lib/chef/file_access_control/windows.rb +310 -0
- data/lib/chef/file_cache.rb +220 -0
- data/lib/chef/formatters/base.rb +247 -0
- data/lib/chef/formatters/doc.rb +236 -0
- data/lib/chef/formatters/error_descriptor.rb +66 -0
- data/lib/chef/formatters/error_inspectors.rb +19 -0
- data/lib/chef/formatters/error_inspectors/api_error_formatting.rb +111 -0
- data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +106 -0
- data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +146 -0
- data/lib/chef/formatters/error_inspectors/cookbook_sync_error_inspector.rb +80 -0
- data/lib/chef/formatters/error_inspectors/node_load_error_inspector.rb +125 -0
- data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +137 -0
- data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +109 -0
- data/lib/chef/formatters/error_inspectors/run_list_expansion_error_inspector.rb +118 -0
- data/lib/chef/formatters/error_mapper.rb +85 -0
- data/lib/chef/formatters/minimal.rb +235 -0
- data/lib/chef/handler.rb +235 -0
- data/lib/chef/handler/error_report.rb +33 -0
- data/lib/chef/handler/json_file.rb +64 -0
- data/lib/chef/index_queue.rb +29 -0
- data/lib/chef/index_queue/amqp_client.rb +116 -0
- data/lib/chef/index_queue/consumer.rb +76 -0
- data/lib/chef/index_queue/indexable.rb +109 -0
- data/lib/chef/json_compat.rb +149 -0
- data/lib/chef/knife.rb +537 -0
- data/lib/chef/knife/bootstrap.rb +233 -0
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +62 -0
- data/lib/chef/knife/bootstrap/centos5-gems.erb +62 -0
- data/lib/chef/knife/bootstrap/chef-full.erb +60 -0
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +44 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +53 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +48 -0
- data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +46 -0
- data/lib/chef/knife/bootstrap/ubuntu12.10-gems.erb +60 -0
- data/lib/chef/knife/client_bulk_delete.rb +65 -0
- data/lib/chef/knife/client_create.rb +80 -0
- data/lib/chef/knife/client_delete.rb +46 -0
- data/lib/chef/knife/client_edit.rb +45 -0
- data/lib/chef/knife/client_list.rb +42 -0
- data/lib/chef/knife/client_reregister.rb +59 -0
- data/lib/chef/knife/client_show.rb +52 -0
- data/lib/chef/knife/configure.rb +168 -0
- data/lib/chef/knife/configure_client.rb +50 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +72 -0
- data/lib/chef/knife/cookbook_create.rb +447 -0
- data/lib/chef/knife/cookbook_delete.rb +151 -0
- data/lib/chef/knife/cookbook_download.rb +137 -0
- data/lib/chef/knife/cookbook_list.rb +47 -0
- data/lib/chef/knife/cookbook_metadata.rb +107 -0
- data/lib/chef/knife/cookbook_metadata_from_file.rb +44 -0
- data/lib/chef/knife/cookbook_show.rb +102 -0
- data/lib/chef/knife/cookbook_site_download.rb +109 -0
- data/lib/chef/knife/cookbook_site_install.rb +164 -0
- data/lib/chef/knife/cookbook_site_list.rb +62 -0
- data/lib/chef/knife/cookbook_site_search.rb +51 -0
- data/lib/chef/knife/cookbook_site_share.rb +114 -0
- data/lib/chef/knife/cookbook_site_show.rb +60 -0
- data/lib/chef/knife/cookbook_site_unshare.rb +56 -0
- data/lib/chef/knife/cookbook_site_vendor.rb +46 -0
- data/lib/chef/knife/cookbook_test.rb +93 -0
- data/lib/chef/knife/cookbook_upload.rb +290 -0
- data/lib/chef/knife/core/bootstrap_context.rb +106 -0
- data/lib/chef/knife/core/cookbook_scm_repo.rb +160 -0
- data/lib/chef/knife/core/generic_presenter.rb +191 -0
- data/lib/chef/knife/core/node_editor.rb +130 -0
- data/lib/chef/knife/core/node_presenter.rb +137 -0
- data/lib/chef/knife/core/object_loader.rb +112 -0
- data/lib/chef/knife/core/subcommand_loader.rb +112 -0
- data/lib/chef/knife/core/text_formatter.rb +100 -0
- data/lib/chef/knife/core/ui.rb +217 -0
- data/lib/chef/knife/data_bag_create.rb +93 -0
- data/lib/chef/knife/data_bag_delete.rb +51 -0
- data/lib/chef/knife/data_bag_edit.rb +94 -0
- data/lib/chef/knife/data_bag_from_file.rb +136 -0
- data/lib/chef/knife/data_bag_list.rb +46 -0
- data/lib/chef/knife/data_bag_show.rb +81 -0
- data/lib/chef/knife/environment_create.rb +53 -0
- data/lib/chef/knife/environment_delete.rb +45 -0
- data/lib/chef/knife/environment_edit.rb +45 -0
- data/lib/chef/knife/environment_from_file.rb +83 -0
- data/lib/chef/knife/environment_list.rb +42 -0
- data/lib/chef/knife/environment_show.rb +46 -0
- data/lib/chef/knife/exec.rb +86 -0
- data/lib/chef/knife/help.rb +103 -0
- data/lib/chef/knife/help_topics.rb +4 -0
- data/lib/chef/knife/index_rebuild.rb +50 -0
- data/lib/chef/knife/node_bulk_delete.rb +80 -0
- data/lib/chef/knife/node_create.rb +50 -0
- data/lib/chef/knife/node_delete.rb +47 -0
- data/lib/chef/knife/node_edit.rb +72 -0
- data/lib/chef/knife/node_from_file.rb +50 -0
- data/lib/chef/knife/node_list.rb +46 -0
- data/lib/chef/knife/node_run_list_add.rb +75 -0
- data/lib/chef/knife/node_run_list_remove.rb +48 -0
- data/lib/chef/knife/node_show.rb +73 -0
- data/lib/chef/knife/recipe_list.rb +32 -0
- data/lib/chef/knife/role_bulk_delete.rb +70 -0
- data/lib/chef/knife/role_create.rb +55 -0
- data/lib/chef/knife/role_delete.rb +47 -0
- data/lib/chef/knife/role_edit.rb +48 -0
- data/lib/chef/knife/role_from_file.rb +56 -0
- data/lib/chef/knife/role_list.rb +43 -0
- data/lib/chef/knife/role_show.rb +54 -0
- data/lib/chef/knife/search.rb +141 -0
- data/lib/chef/knife/ssh.rb +459 -0
- data/lib/chef/knife/status.rb +119 -0
- data/lib/chef/knife/tag_create.rb +52 -0
- data/lib/chef/knife/tag_delete.rb +60 -0
- data/lib/chef/knife/tag_list.rb +47 -0
- data/lib/chef/log.rb +39 -0
- data/lib/chef/mash.rb +225 -0
- data/lib/chef/mixin/check_helper.rb +31 -0
- data/lib/chef/mixin/checksum.rb +32 -0
- data/lib/chef/mixin/command.rb +164 -0
- data/lib/chef/mixin/command/unix.rb +220 -0
- data/lib/chef/mixin/command/windows.rb +76 -0
- data/lib/chef/mixin/convert_to_class_name.rb +65 -0
- data/lib/chef/mixin/create_path.rb +57 -0
- data/lib/chef/mixin/deep_merge.rb +247 -0
- data/lib/chef/mixin/deprecation.rb +65 -0
- data/lib/chef/mixin/enforce_ownership_and_permissions.rb +39 -0
- data/lib/chef/mixin/file_class.rb +46 -0
- data/lib/chef/mixin/from_file.rb +50 -0
- data/lib/chef/mixin/get_source_from_package.rb +42 -0
- data/lib/chef/mixin/language.rb +249 -0
- data/lib/chef/mixin/language_include_attribute.rb +61 -0
- data/lib/chef/mixin/language_include_recipe.rb +58 -0
- data/lib/chef/mixin/params_validate.rb +238 -0
- data/lib/chef/mixin/path_sanity.rb +67 -0
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +86 -0
- data/lib/chef/mixin/securable.rb +180 -0
- data/lib/chef/mixin/shell_out.rb +69 -0
- data/lib/chef/mixin/template.rb +100 -0
- data/lib/chef/mixin/why_run.rb +332 -0
- data/lib/chef/mixin/xml_escape.rb +140 -0
- data/lib/chef/mixins.rb +18 -0
- data/lib/chef/monkey_patches/dir.rb +36 -0
- data/lib/chef/monkey_patches/fileutils.rb +65 -0
- data/lib/chef/monkey_patches/moneta.rb +50 -0
- data/lib/chef/monkey_patches/net_http.rb +22 -0
- data/lib/chef/monkey_patches/numeric.rb +15 -0
- data/lib/chef/monkey_patches/object.rb +9 -0
- data/lib/chef/monkey_patches/regexp.rb +34 -0
- data/lib/chef/monkey_patches/string.rb +49 -0
- data/lib/chef/monkey_patches/tempfile.rb +64 -0
- data/lib/chef/nil_argument.rb +3 -0
- data/lib/chef/node.rb +682 -0
- data/lib/chef/node/attribute.rb +504 -0
- data/lib/chef/openid_registration.rb +187 -0
- data/lib/chef/platform.rb +520 -0
- data/lib/chef/provider.rb +223 -0
- data/lib/chef/provider/breakpoint.rb +36 -0
- data/lib/chef/provider/cookbook_file.rb +105 -0
- data/lib/chef/provider/cron.rb +214 -0
- data/lib/chef/provider/cron/solaris.rb +56 -0
- data/lib/chef/provider/deploy.rb +474 -0
- data/lib/chef/provider/deploy/revision.rb +80 -0
- data/lib/chef/provider/deploy/timestamped.rb +32 -0
- data/lib/chef/provider/directory.rb +128 -0
- data/lib/chef/provider/env.rb +152 -0
- data/lib/chef/provider/env/windows.rb +75 -0
- data/lib/chef/provider/erl_call.rb +106 -0
- data/lib/chef/provider/execute.rb +68 -0
- data/lib/chef/provider/file.rb +355 -0
- data/lib/chef/provider/git.rb +260 -0
- data/lib/chef/provider/group.rb +159 -0
- data/lib/chef/provider/group/aix.rb +70 -0
- data/lib/chef/provider/group/dscl.rb +129 -0
- data/lib/chef/provider/group/gpasswd.rb +65 -0
- data/lib/chef/provider/group/groupadd.rb +96 -0
- data/lib/chef/provider/group/groupmod.rb +120 -0
- data/lib/chef/provider/group/pw.rb +93 -0
- data/lib/chef/provider/group/suse.rb +60 -0
- data/lib/chef/provider/group/usermod.rb +68 -0
- data/lib/chef/provider/group/windows.rb +79 -0
- data/lib/chef/provider/http_request.rb +136 -0
- data/lib/chef/provider/ifconfig.rb +214 -0
- data/lib/chef/provider/link.rb +130 -0
- data/lib/chef/provider/log.rb +54 -0
- data/lib/chef/provider/mdadm.rb +92 -0
- data/lib/chef/provider/mount.rb +128 -0
- data/lib/chef/provider/mount/mount.rb +252 -0
- data/lib/chef/provider/mount/windows.rb +81 -0
- data/lib/chef/provider/ohai.rb +47 -0
- data/lib/chef/provider/package.rb +229 -0
- data/lib/chef/provider/package/apt.rb +147 -0
- data/lib/chef/provider/package/dpkg.rb +128 -0
- data/lib/chef/provider/package/easy_install.rb +136 -0
- data/lib/chef/provider/package/freebsd.rb +149 -0
- data/lib/chef/provider/package/ips.rb +101 -0
- data/lib/chef/provider/package/macports.rb +105 -0
- data/lib/chef/provider/package/pacman.rb +111 -0
- data/lib/chef/provider/package/portage.rb +143 -0
- data/lib/chef/provider/package/rpm.rb +121 -0
- data/lib/chef/provider/package/rubygems.rb +580 -0
- data/lib/chef/provider/package/smartos.rb +84 -0
- data/lib/chef/provider/package/solaris.rb +139 -0
- data/lib/chef/provider/package/yum-dump.py +307 -0
- data/lib/chef/provider/package/yum.rb +1261 -0
- data/lib/chef/provider/package/zypper.rb +144 -0
- data/lib/chef/provider/remote_directory.rb +178 -0
- data/lib/chef/provider/remote_file.rb +126 -0
- data/lib/chef/provider/resource_update.rb +55 -0
- data/lib/chef/provider/route.rb +223 -0
- data/lib/chef/provider/ruby_block.rb +39 -0
- data/lib/chef/provider/script.rb +57 -0
- data/lib/chef/provider/service.rb +158 -0
- data/lib/chef/provider/service/arch.rb +113 -0
- data/lib/chef/provider/service/debian.rb +152 -0
- data/lib/chef/provider/service/freebsd.rb +175 -0
- data/lib/chef/provider/service/gentoo.rb +67 -0
- data/lib/chef/provider/service/init.rb +87 -0
- data/lib/chef/provider/service/insserv.rb +52 -0
- data/lib/chef/provider/service/invokercd.rb +35 -0
- data/lib/chef/provider/service/macosx.rb +144 -0
- data/lib/chef/provider/service/redhat.rb +77 -0
- data/lib/chef/provider/service/simple.rb +172 -0
- data/lib/chef/provider/service/solaris.rb +86 -0
- data/lib/chef/provider/service/systemd.rb +115 -0
- data/lib/chef/provider/service/upstart.rb +232 -0
- data/lib/chef/provider/service/windows.rb +163 -0
- data/lib/chef/provider/subversion.rb +214 -0
- data/lib/chef/provider/template.rb +117 -0
- data/lib/chef/provider/user.rb +207 -0
- data/lib/chef/provider/user/dscl.rb +280 -0
- data/lib/chef/provider/user/pw.rb +113 -0
- data/lib/chef/provider/user/solaris.rb +90 -0
- data/lib/chef/provider/user/useradd.rb +153 -0
- data/lib/chef/provider/user/windows.rb +124 -0
- data/lib/chef/providers.rb +101 -0
- data/lib/chef/recipe.rb +129 -0
- data/lib/chef/reserved_names.rb +9 -0
- data/lib/chef/resource.rb +912 -0
- data/lib/chef/resource/apt_package.rb +43 -0
- data/lib/chef/resource/bash.rb +33 -0
- data/lib/chef/resource/breakpoint.rb +35 -0
- data/lib/chef/resource/chef_gem.rb +53 -0
- data/lib/chef/resource/conditional.rb +101 -0
- data/lib/chef/resource/cookbook_file.rb +52 -0
- data/lib/chef/resource/cron.rb +202 -0
- data/lib/chef/resource/csh.rb +33 -0
- data/lib/chef/resource/deploy.rb +403 -0
- data/lib/chef/resource/deploy_revision.rb +40 -0
- data/lib/chef/resource/directory.rb +65 -0
- data/lib/chef/resource/dpkg_package.rb +34 -0
- data/lib/chef/resource/easy_install_package.rb +57 -0
- data/lib/chef/resource/env.rb +63 -0
- data/lib/chef/resource/erl_call.rb +86 -0
- data/lib/chef/resource/execute.rb +132 -0
- data/lib/chef/resource/file.rb +96 -0
- data/lib/chef/resource/freebsd_package.rb +35 -0
- data/lib/chef/resource/gem_package.rb +53 -0
- data/lib/chef/resource/git.rb +46 -0
- data/lib/chef/resource/group.rb +83 -0
- data/lib/chef/resource/http_request.rb +64 -0
- data/lib/chef/resource/ifconfig.rb +149 -0
- data/lib/chef/resource/ips_package.rb +42 -0
- data/lib/chef/resource/link.rb +92 -0
- data/lib/chef/resource/log.rb +74 -0
- data/lib/chef/resource/macports_package.rb +29 -0
- data/lib/chef/resource/mdadm.rb +105 -0
- data/lib/chef/resource/mount.rb +139 -0
- data/lib/chef/resource/ohai.rb +54 -0
- data/lib/chef/resource/package.rb +84 -0
- data/lib/chef/resource/pacman_package.rb +33 -0
- data/lib/chef/resource/perl.rb +33 -0
- data/lib/chef/resource/portage_package.rb +33 -0
- data/lib/chef/resource/python.rb +33 -0
- data/lib/chef/resource/remote_directory.rb +125 -0
- data/lib/chef/resource/remote_file.rb +90 -0
- data/lib/chef/resource/route.rb +140 -0
- data/lib/chef/resource/rpm_package.rb +34 -0
- data/lib/chef/resource/ruby.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +51 -0
- data/lib/chef/resource/scm.rb +151 -0
- data/lib/chef/resource/script.rb +63 -0
- data/lib/chef/resource/service.rb +164 -0
- data/lib/chef/resource/smartos_package.rb +36 -0
- data/lib/chef/resource/solaris_package.rb +36 -0
- data/lib/chef/resource/subversion.rb +37 -0
- data/lib/chef/resource/template.rb +76 -0
- data/lib/chef/resource/timestamped_deploy.rb +31 -0
- data/lib/chef/resource/user.rb +134 -0
- data/lib/chef/resource/yum_package.rb +63 -0
- data/lib/chef/resource_collection.rb +217 -0
- data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
- data/lib/chef/resource_definition.rb +67 -0
- data/lib/chef/resource_definition_list.rb +38 -0
- data/lib/chef/resource_platform_map.rb +151 -0
- data/lib/chef/resource_reporter.rb +281 -0
- data/lib/chef/resources.rb +67 -0
- data/lib/chef/rest.rb +510 -0
- data/lib/chef/rest/auth_credentials.rb +73 -0
- data/lib/chef/rest/cookie_jar.rb +31 -0
- data/lib/chef/rest/rest_request.rb +229 -0
- data/lib/chef/role.rb +349 -0
- data/lib/chef/run_context.rb +236 -0
- data/lib/chef/run_list.rb +165 -0
- data/lib/chef/run_list/run_list_expansion.rb +206 -0
- data/lib/chef/run_list/run_list_item.rb +99 -0
- data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
- data/lib/chef/run_status.rb +124 -0
- data/lib/chef/runner.rb +95 -0
- data/lib/chef/sandbox.rb +153 -0
- data/lib/chef/scan_access_control.rb +135 -0
- data/lib/chef/search/query.rb +65 -0
- data/lib/chef/shef.rb +327 -0
- data/lib/chef/shef/ext.rb +591 -0
- data/lib/chef/shef/model_wrapper.rb +120 -0
- data/lib/chef/shef/shef_rest.rb +28 -0
- data/lib/chef/shef/shef_session.rb +296 -0
- data/lib/chef/shell_out.rb +6 -0
- data/lib/chef/solr_query.rb +187 -0
- data/lib/chef/solr_query/lucene.treetop +150 -0
- data/lib/chef/solr_query/lucene_nodes.rb +285 -0
- data/lib/chef/solr_query/query_transform.rb +65 -0
- data/lib/chef/solr_query/solr_http_request.rb +132 -0
- data/lib/chef/streaming_cookbook_uploader.rb +201 -0
- data/lib/chef/tasks/chef_repo.rake +334 -0
- data/lib/chef/util/file_edit.rb +132 -0
- data/lib/chef/util/windows.rb +56 -0
- data/lib/chef/util/windows/net_group.rb +101 -0
- data/lib/chef/util/windows/net_use.rb +121 -0
- data/lib/chef/util/windows/net_user.rb +198 -0
- data/lib/chef/util/windows/volume.rb +59 -0
- data/lib/chef/version.rb +23 -0
- data/lib/chef/version_class.rb +70 -0
- data/lib/chef/version_constraint.rb +116 -0
- data/lib/chef/webui_user.rb +231 -0
- data/lib/chef/win32/api.rb +364 -0
- data/lib/chef/win32/api/error.rb +921 -0
- data/lib/chef/win32/api/file.rb +535 -0
- data/lib/chef/win32/api/memory.rb +105 -0
- data/lib/chef/win32/api/process.rb +41 -0
- data/lib/chef/win32/api/psapi.rb +51 -0
- data/lib/chef/win32/api/security.rb +341 -0
- data/lib/chef/win32/api/system.rb +192 -0
- data/lib/chef/win32/api/unicode.rb +178 -0
- data/lib/chef/win32/error.rb +73 -0
- data/lib/chef/win32/file.rb +167 -0
- data/lib/chef/win32/file/info.rb +100 -0
- data/lib/chef/win32/handle.rb +55 -0
- data/lib/chef/win32/memory.rb +101 -0
- data/lib/chef/win32/process.rb +84 -0
- data/lib/chef/win32/security.rb +489 -0
- data/lib/chef/win32/security/ace.rb +125 -0
- data/lib/chef/win32/security/acl.rb +101 -0
- data/lib/chef/win32/security/securable_object.rb +109 -0
- data/lib/chef/win32/security/security_descriptor.rb +93 -0
- data/lib/chef/win32/security/sid.rb +199 -0
- data/lib/chef/win32/security/token.rb +64 -0
- data/lib/chef/win32/unicode.rb +43 -0
- data/lib/chef/win32/version.rb +119 -0
- data/spec/data/bad-config.rb +1 -0
- data/spec/data/big_json.json +2 -0
- data/spec/data/big_json_plus_one.json +2 -0
- data/spec/data/bootstrap/test-hints.erb +12 -0
- data/spec/data/bootstrap/test.erb +1 -0
- data/spec/data/cb_version_cookbooks/tatft/README.rdoc +3 -0
- data/spec/data/cb_version_cookbooks/tatft/attributes/default.rb +1 -0
- data/spec/data/cb_version_cookbooks/tatft/definitions/runit_service.rb +1 -0
- data/spec/data/cb_version_cookbooks/tatft/files/default/giant_blob.tgz +1 -0
- data/spec/data/cb_version_cookbooks/tatft/libraries/ownage.rb +1 -0
- data/spec/data/cb_version_cookbooks/tatft/providers/lwp.rb +1 -0
- data/spec/data/cb_version_cookbooks/tatft/recipes/default.rb +1 -0
- data/spec/data/cb_version_cookbooks/tatft/resources/lwr.rb +1 -0
- data/spec/data/cb_version_cookbooks/tatft/templates/default/configuration.erb +0 -0
- data/spec/data/checksum/random.txt +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-600hhz-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-6m8zdk-0 +0 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-ahd2gq-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-api8ux-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-b0r1m1-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-bfygsi-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-el14l6-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-ivrl3y-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-kkbs85-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-ory1ux-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-pgsq76-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-ra8uim-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-t7k1g-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-t8g0sv-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-ufy6g3-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-x2d6j9-0 +1 -0
- data/spec/data/checksum_cache/chef-file--tmp-chef-rendered-template20100929-10863-xi0l6h-0 +1 -0
- data/spec/data/config.rb +6 -0
- data/spec/data/cookbooks/angrybash/recipes/default.rb +8 -0
- data/spec/data/cookbooks/apache2/files/default/apache2_module_conf_generate.pl +2 -0
- data/spec/data/cookbooks/apache2/recipes/default.rb +3 -0
- data/spec/data/cookbooks/borken/recipes/default.rb +2 -0
- data/spec/data/cookbooks/borken/templates/default/borken.erb +2 -0
- data/spec/data/cookbooks/chefignore +8 -0
- data/spec/data/cookbooks/java/files/default/java.response +2 -0
- data/spec/data/cookbooks/openldap/attributes/default.rb +15 -0
- data/spec/data/cookbooks/openldap/attributes/smokey.rb +1 -0
- data/spec/data/cookbooks/openldap/definitions/client.rb +5 -0
- data/spec/data/cookbooks/openldap/definitions/server.rb +5 -0
- data/spec/data/cookbooks/openldap/files/default/.dotfile +1 -0
- data/spec/data/cookbooks/openldap/files/default/.ssh/id_rsa +1 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/.a_dotdir/.a_dotfile_in_a_dotdir +1 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/remote_dir_file1.txt +3 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/remote_dir_file2.txt +3 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/.a_dotfile +1 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/remote_subdir_file1.txt +3 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/remote_subdir_file2.txt +3 -0
- data/spec/data/cookbooks/openldap/files/default/remotedir/subdir_with_no_file_just_a_subsubdir/the_subsubdir/some_file.txt +3 -0
- data/spec/data/cookbooks/openldap/recipes/default.rb +3 -0
- data/spec/data/cookbooks/openldap/recipes/gigantor.rb +3 -0
- data/spec/data/cookbooks/openldap/recipes/one.rb +15 -0
- data/spec/data/cookbooks/openldap/templates/default/openldap_stuff.conf.erb +1 -0
- data/spec/data/cookbooks/openldap/templates/default/openldap_variable_stuff.conf.erb +1 -0
- data/spec/data/cookbooks/openldap/templates/default/test.erb +1 -0
- data/spec/data/definitions/test.rb +5 -0
- data/spec/data/environment-config.rb +5 -0
- data/spec/data/fileedit/blank +0 -0
- data/spec/data/fileedit/hosts +4 -0
- data/spec/data/gems/chef-integration-test-0.1.0.gem +0 -0
- data/spec/data/git_bundles/sinatra-test-app-with-callback-files.gitbundle +0 -0
- data/spec/data/git_bundles/sinatra-test-app-with-symlinks.gitbundle +0 -0
- data/spec/data/git_bundles/sinatra-test-app.gitbundle +0 -0
- data/spec/data/kitchen/chefignore +6 -0
- data/spec/data/kitchen/openldap/attributes/default.rb +3 -0
- data/spec/data/kitchen/openldap/attributes/robinson.rb +3 -0
- data/spec/data/kitchen/openldap/definitions/client.rb +3 -0
- data/spec/data/kitchen/openldap/definitions/drewbarrymore.rb +3 -0
- data/spec/data/kitchen/openldap/recipes/gigantor.rb +3 -0
- data/spec/data/kitchen/openldap/recipes/ignoreme.rb +3 -0
- data/spec/data/kitchen/openldap/recipes/woot.rb +3 -0
- data/spec/data/knife-home/.chef/plugins/knife/example_home_subcommand.rb +0 -0
- data/spec/data/knife-site-subcommands/plugins/knife/example_subcommand.rb +0 -0
- data/spec/data/knife_subcommand/test_explicit_category.rb +7 -0
- data/spec/data/knife_subcommand/test_name_mapping.rb +4 -0
- data/spec/data/knife_subcommand/test_yourself.rb +13 -0
- data/spec/data/lwrp/providers/buck_passer.rb +3 -0
- data/spec/data/lwrp/providers/buck_passer_2.rb +10 -0
- data/spec/data/lwrp/providers/embedded_resource_accesses_providers_scope.rb +16 -0
- data/spec/data/lwrp/providers/monkey_name_printer.rb +5 -0
- data/spec/data/lwrp/providers/paint_drying_watcher.rb +7 -0
- data/spec/data/lwrp/providers/thumb_twiddler.rb +7 -0
- data/spec/data/lwrp/resources/bar.rb +1 -0
- data/spec/data/lwrp/resources/foo.rb +3 -0
- data/spec/data/lwrp/resources_with_default_attributes/nodeattr.rb +1 -0
- data/spec/data/lwrp_const_scoping/resources/conflict.rb +0 -0
- data/spec/data/lwrp_override/providers/buck_passer.rb +10 -0
- data/spec/data/lwrp_override/resources/foo.rb +4 -0
- data/spec/data/metadata/quick_start/metadata.rb +19 -0
- data/spec/data/nodes/default.rb +15 -0
- data/spec/data/nodes/test.example.com.rb +17 -0
- data/spec/data/nodes/test.rb +15 -0
- data/spec/data/object_loader/environments/test.json +5 -0
- data/spec/data/object_loader/environments/test.rb +2 -0
- data/spec/data/object_loader/environments/test_json_class.json +6 -0
- data/spec/data/object_loader/nodes/test.json +5 -0
- data/spec/data/object_loader/nodes/test.rb +2 -0
- data/spec/data/object_loader/nodes/test_json_class.json +6 -0
- data/spec/data/object_loader/roles/test.json +5 -0
- data/spec/data/object_loader/roles/test.rb +2 -0
- data/spec/data/object_loader/roles/test_json_class.json +6 -0
- data/spec/data/old_home_dir/my-dot-emacs +0 -0
- data/spec/data/old_home_dir/my-dot-vim +0 -0
- data/spec/data/recipes/test.rb +7 -0
- data/spec/data/remote_directory_data/remote_dir_file.txt +1 -0
- data/spec/data/remote_directory_data/remote_subdirectory/remote_subdir_file.txt +1 -0
- data/spec/data/remote_file/nyan_cat.png +0 -0
- data/spec/data/run_context/cookbooks/test/attributes/george.rb +1 -0
- data/spec/data/run_context/cookbooks/test/definitions/new_animals.rb +9 -0
- data/spec/data/run_context/cookbooks/test/definitions/new_cat.rb +5 -0
- data/spec/data/run_context/cookbooks/test/recipes/default.rb +5 -0
- data/spec/data/run_context/cookbooks/test/recipes/one.rb +7 -0
- data/spec/data/run_context/cookbooks/test/recipes/two.rb +7 -0
- data/spec/data/run_context/nodes/run_context.rb +5 -0
- data/spec/data/search_queries_to_transform.txt +98 -0
- data/spec/data/ssl/5e707473.0 +18 -0
- data/spec/data/ssl/chef-rspec.cert +27 -0
- data/spec/data/ssl/chef-rspec.key +27 -0
- data/spec/data/ssl/key.pem +15 -0
- data/spec/data/ssl/private_key.pem +27 -0
- data/spec/data/ssl/private_key_with_whitespace.pem +32 -0
- data/spec/data/templates/seattle.txt +1 -0
- data/spec/functional/knife/cookbook_delete_spec.rb +160 -0
- data/spec/functional/knife/exec_spec.rb +60 -0
- data/spec/functional/knife/ssh_spec.rb +268 -0
- data/spec/functional/resource/cookbook_file_spec.rb +75 -0
- data/spec/functional/resource/deploy_revision_spec.rb +515 -0
- data/spec/functional/resource/directory_spec.rb +39 -0
- data/spec/functional/resource/file_spec.rb +69 -0
- data/spec/functional/resource/link_spec.rb +572 -0
- data/spec/functional/resource/remote_directory_spec.rb +114 -0
- data/spec/functional/resource/remote_file_spec.rb +65 -0
- data/spec/functional/resource/template_spec.rb +68 -0
- data/spec/functional/tiny_server_spec.rb +78 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec_helper.rb +82 -0
- data/spec/stress/win32/file_spec.rb +37 -0
- data/spec/stress/win32/memory_spec.rb +22 -0
- data/spec/stress/win32/security_spec.rb +69 -0
- data/spec/support/chef_helpers.rb +65 -0
- data/spec/support/lib/chef/provider/easy.rb +35 -0
- data/spec/support/lib/chef/provider/snakeoil.rb +40 -0
- data/spec/support/lib/chef/resource/cat.rb +41 -0
- data/spec/support/lib/chef/resource/one_two_three_four.rb +43 -0
- data/spec/support/lib/chef/resource/zen_master.rb +46 -0
- data/spec/support/matchers/leak.rb +96 -0
- data/spec/support/mock/constant.rb +52 -0
- data/spec/support/mock/platform.rb +18 -0
- data/spec/support/platform_helpers.rb +39 -0
- data/spec/support/platforms/prof/gc.rb +54 -0
- data/spec/support/platforms/prof/win32.rb +46 -0
- data/spec/support/shared/functional/directory_resource.rb +85 -0
- data/spec/support/shared/functional/file_resource.rb +202 -0
- data/spec/support/shared/functional/knife.rb +37 -0
- data/spec/support/shared/functional/securable_resource.rb +402 -0
- data/spec/support/shared/unit/api_error_inspector.rb +192 -0
- data/spec/tiny_server.rb +202 -0
- data/spec/unit/api_client_spec.rb +257 -0
- data/spec/unit/application/agent_spec.rb +0 -0
- data/spec/unit/application/client_spec.rb +171 -0
- data/spec/unit/application/knife_spec.rb +152 -0
- data/spec/unit/application/server_spec.rb +0 -0
- data/spec/unit/application/solo_spec.rb +167 -0
- data/spec/unit/application_spec.rb +239 -0
- data/spec/unit/certificate_spec.rb +76 -0
- data/spec/unit/checksum/storage/filesystem_spec.rb +69 -0
- data/spec/unit/checksum_cache_spec.rb +209 -0
- data/spec/unit/checksum_spec.rb +94 -0
- data/spec/unit/chef_spec.rb +25 -0
- data/spec/unit/client_spec.rb +290 -0
- data/spec/unit/config_spec.rb +223 -0
- data/spec/unit/cookbook/chefignore_spec.rb +39 -0
- data/spec/unit/cookbook/metadata_spec.rb +627 -0
- data/spec/unit/cookbook/synchronizer_spec.rb +306 -0
- data/spec/unit/cookbook/syntax_check_spec.rb +211 -0
- data/spec/unit/cookbook_loader_spec.rb +145 -0
- data/spec/unit/cookbook_manifest_spec.rb +554 -0
- data/spec/unit/cookbook_spec.rb +101 -0
- data/spec/unit/cookbook_version_spec.rb +406 -0
- data/spec/unit/couchdb_spec.rb +274 -0
- data/spec/unit/daemon_spec.rb +302 -0
- data/spec/unit/data_bag_item_spec.rb +280 -0
- data/spec/unit/data_bag_spec.rb +169 -0
- data/spec/unit/encrypted_data_bag_item_spec.rb +293 -0
- data/spec/unit/environment_spec.rb +492 -0
- data/spec/unit/exceptions_spec.rb +74 -0
- data/spec/unit/file_access_control_spec.rb +282 -0
- data/spec/unit/file_cache_spec.rb +114 -0
- data/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb +202 -0
- data/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb +93 -0
- data/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb +43 -0
- data/spec/unit/formatters/error_inspectors/node_load_error_inspector_spec.rb +27 -0
- data/spec/unit/formatters/error_inspectors/registration_error_inspector_spec.rb +27 -0
- data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +182 -0
- data/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb +93 -0
- data/spec/unit/handler/json_file_spec.rb +64 -0
- data/spec/unit/handler_spec.rb +216 -0
- data/spec/unit/index_queue_spec.rb +391 -0
- data/spec/unit/json_compat_spec.rb +61 -0
- data/spec/unit/knife/bootstrap_spec.rb +265 -0
- data/spec/unit/knife/client_bulk_delete_spec.rb +78 -0
- data/spec/unit/knife/client_create_spec.rb +74 -0
- data/spec/unit/knife/client_delete_spec.rb +40 -0
- data/spec/unit/knife/client_edit_spec.rb +40 -0
- data/spec/unit/knife/client_list_spec.rb +34 -0
- data/spec/unit/knife/client_reregister_spec.rb +62 -0
- data/spec/unit/knife/client_show_spec.rb +42 -0
- data/spec/unit/knife/config_file_selection_spec.rb +118 -0
- data/spec/unit/knife/configure_client_spec.rb +83 -0
- data/spec/unit/knife/configure_spec.rb +229 -0
- data/spec/unit/knife/cookbook_bulk_delete_spec.rb +87 -0
- data/spec/unit/knife/cookbook_create_spec.rb +271 -0
- data/spec/unit/knife/cookbook_delete_spec.rb +239 -0
- data/spec/unit/knife/cookbook_download_spec.rb +217 -0
- data/spec/unit/knife/cookbook_list_spec.rb +88 -0
- data/spec/unit/knife/cookbook_metadata_from_file_spec.rb +65 -0
- data/spec/unit/knife/cookbook_metadata_spec.rb +172 -0
- data/spec/unit/knife/cookbook_show_spec.rb +223 -0
- data/spec/unit/knife/cookbook_site_download_spec.rb +151 -0
- data/spec/unit/knife/cookbook_site_install_spec.rb +148 -0
- data/spec/unit/knife/cookbook_site_share_spec.rb +146 -0
- data/spec/unit/knife/cookbook_site_unshare_spec.rb +77 -0
- data/spec/unit/knife/cookbook_test_spec.rb +83 -0
- data/spec/unit/knife/cookbook_upload_spec.rb +148 -0
- data/spec/unit/knife/core/bootstrap_context_spec.rb +135 -0
- data/spec/unit/knife/core/cookbook_scm_repo_spec.rb +187 -0
- data/spec/unit/knife/core/object_loader_spec.rb +81 -0
- data/spec/unit/knife/core/subcommand_loader_spec.rb +54 -0
- data/spec/unit/knife/core/ui_spec.rb +160 -0
- data/spec/unit/knife/data_bag_create_spec.rb +101 -0
- data/spec/unit/knife/data_bag_edit_spec.rb +96 -0
- data/spec/unit/knife/data_bag_from_file_spec.rb +198 -0
- data/spec/unit/knife/data_bag_show_spec.rb +105 -0
- data/spec/unit/knife/environment_create_spec.rb +91 -0
- data/spec/unit/knife/environment_delete_spec.rb +71 -0
- data/spec/unit/knife/environment_edit_spec.rb +79 -0
- data/spec/unit/knife/environment_from_file_spec.rb +89 -0
- data/spec/unit/knife/environment_list_spec.rb +54 -0
- data/spec/unit/knife/environment_show_spec.rb +52 -0
- data/spec/unit/knife/index_rebuild_spec.rb +65 -0
- data/spec/unit/knife/knife_help.rb +92 -0
- data/spec/unit/knife/node_bulk_delete_spec.rb +97 -0
- data/spec/unit/knife/node_delete_spec.rb +68 -0
- data/spec/unit/knife/node_edit_spec.rb +88 -0
- data/spec/unit/knife/node_from_file_spec.rb +59 -0
- data/spec/unit/knife/node_list_spec.rb +63 -0
- data/spec/unit/knife/node_run_list_add_spec.rb +125 -0
- data/spec/unit/knife/node_run_list_remove_spec.rb +73 -0
- data/spec/unit/knife/node_show_spec.rb +48 -0
- data/spec/unit/knife/role_bulk_delete_spec.rb +80 -0
- data/spec/unit/knife/role_create_spec.rb +80 -0
- data/spec/unit/knife/role_delete_spec.rb +67 -0
- data/spec/unit/knife/role_edit_spec.rb +79 -0
- data/spec/unit/knife/role_from_file_spec.rb +69 -0
- data/spec/unit/knife/role_list_spec.rb +56 -0
- data/spec/unit/knife/ssh_spec.rb +293 -0
- data/spec/unit/knife/status_spec.rb +43 -0
- data/spec/unit/knife/tag_create_spec.rb +23 -0
- data/spec/unit/knife/tag_delete_spec.rb +25 -0
- data/spec/unit/knife/tag_list_spec.rb +23 -0
- data/spec/unit/knife_spec.rb +295 -0
- data/spec/unit/log_spec.rb +24 -0
- data/spec/unit/lwrp_spec.rb +256 -0
- data/spec/unit/mash_spec.rb +51 -0
- data/spec/unit/mixin/checksum_spec.rb +41 -0
- data/spec/unit/mixin/command_spec.rb +105 -0
- data/spec/unit/mixin/convert_to_class_name_spec.rb +50 -0
- data/spec/unit/mixin/deep_merge_spec.rb +786 -0
- data/spec/unit/mixin/deprecation_spec.rb +34 -0
- data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +90 -0
- data/spec/unit/mixin/language_spec.rb +305 -0
- data/spec/unit/mixin/params_validate_spec.rb +405 -0
- data/spec/unit/mixin/path_sanity_spec.rb +80 -0
- data/spec/unit/mixin/securable_spec.rb +254 -0
- data/spec/unit/mixin/shell_out_spec.rb +109 -0
- data/spec/unit/mixin/template_spec.rb +104 -0
- data/spec/unit/mixin/xml_escape_spec.rb +54 -0
- data/spec/unit/monkey_patches/string_spec.rb +37 -0
- data/spec/unit/node/attribute_spec.rb +1033 -0
- data/spec/unit/node_spec.rb +744 -0
- data/spec/unit/openid_registration_spec.rb +153 -0
- data/spec/unit/platform_spec.rb +241 -0
- data/spec/unit/provider/breakpoint_spec.rb +54 -0
- data/spec/unit/provider/cookbook_file_spec.rb +218 -0
- data/spec/unit/provider/cron/solaris_spec.rb +121 -0
- data/spec/unit/provider/cron_spec.rb +812 -0
- data/spec/unit/provider/deploy/revision_spec.rb +103 -0
- data/spec/unit/provider/deploy/timestamped_spec.rb +40 -0
- data/spec/unit/provider/deploy_spec.rb +620 -0
- data/spec/unit/provider/directory_spec.rb +156 -0
- data/spec/unit/provider/env_spec.rb +232 -0
- data/spec/unit/provider/erl_call_spec.rb +86 -0
- data/spec/unit/provider/execute_spec.rb +63 -0
- data/spec/unit/provider/file_spec.rb +505 -0
- data/spec/unit/provider/git_spec.rb +342 -0
- data/spec/unit/provider/group/dscl_spec.rb +294 -0
- data/spec/unit/provider/group/gpasswd_spec.rb +108 -0
- data/spec/unit/provider/group/groupadd_spec.rb +161 -0
- data/spec/unit/provider/group/groupmod_spec.rb +134 -0
- data/spec/unit/provider/group/pw_spec.rb +140 -0
- data/spec/unit/provider/group/usermod_spec.rb +95 -0
- data/spec/unit/provider/group/windows_spec.rb +94 -0
- data/spec/unit/provider/group_spec.rb +259 -0
- data/spec/unit/provider/http_request_spec.rb +178 -0
- data/spec/unit/provider/ifconfig_spec.rb +213 -0
- data/spec/unit/provider/link_spec.rb +252 -0
- data/spec/unit/provider/log_spec.rb +81 -0
- data/spec/unit/provider/mdadm_spec.rb +128 -0
- data/spec/unit/provider/mount/mount_spec.rb +398 -0
- data/spec/unit/provider/mount/windows_spec.rb +134 -0
- data/spec/unit/provider/mount_spec.rb +160 -0
- data/spec/unit/provider/ohai_spec.rb +85 -0
- data/spec/unit/provider/package/apt_spec.rb +352 -0
- data/spec/unit/provider/package/dpkg_spec.rb +216 -0
- data/spec/unit/provider/package/easy_install_spec.rb +112 -0
- data/spec/unit/provider/package/freebsd_spec.rb +259 -0
- data/spec/unit/provider/package/ips_spec.rb +210 -0
- data/spec/unit/provider/package/macports_spec.rb +203 -0
- data/spec/unit/provider/package/pacman_spec.rb +206 -0
- data/spec/unit/provider/package/portage_spec.rb +320 -0
- data/spec/unit/provider/package/rpm_spec.rb +152 -0
- data/spec/unit/provider/package/rubygems_spec.rb +639 -0
- data/spec/unit/provider/package/smartos_spec.rb +83 -0
- data/spec/unit/provider/package/solaris_spec.rb +181 -0
- data/spec/unit/provider/package/yum_spec.rb +1856 -0
- data/spec/unit/provider/package/zypper_spec.rb +159 -0
- data/spec/unit/provider/package_spec.rb +427 -0
- data/spec/unit/provider/remote_directory_spec.rb +222 -0
- data/spec/unit/provider/remote_file_spec.rb +288 -0
- data/spec/unit/provider/route_spec.rb +226 -0
- data/spec/unit/provider/ruby_block_spec.rb +38 -0
- data/spec/unit/provider/script_spec.rb +96 -0
- data/spec/unit/provider/service/arch_service_spec.rb +330 -0
- data/spec/unit/provider/service/debian_service_spec.rb +254 -0
- data/spec/unit/provider/service/freebsd_service_spec.rb +379 -0
- data/spec/unit/provider/service/gentoo_service_spec.rb +144 -0
- data/spec/unit/provider/service/init_service_spec.rb +212 -0
- data/spec/unit/provider/service/insserv_service_spec.rb +76 -0
- data/spec/unit/provider/service/invokercd_service_spec.rb +212 -0
- data/spec/unit/provider/service/macosx_spec.rb +229 -0
- data/spec/unit/provider/service/redhat_spec.rb +156 -0
- data/spec/unit/provider/service/simple_service_spec.rb +171 -0
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +140 -0
- data/spec/unit/provider/service/systemd_service_spec.rb +239 -0
- data/spec/unit/provider/service/upstart_service_spec.rb +314 -0
- data/spec/unit/provider/service/windows_spec.rb +235 -0
- data/spec/unit/provider/service_spec.rb +169 -0
- data/spec/unit/provider/subversion_spec.rb +281 -0
- data/spec/unit/provider/template_spec.rb +196 -0
- data/spec/unit/provider/user/dscl_spec.rb +454 -0
- data/spec/unit/provider/user/pw_spec.rb +235 -0
- data/spec/unit/provider/user/solaris_spec.rb +414 -0
- data/spec/unit/provider/user/useradd_spec.rb +386 -0
- data/spec/unit/provider/user/windows_spec.rb +178 -0
- data/spec/unit/provider/user_spec.rb +468 -0
- data/spec/unit/provider_spec.rb +169 -0
- data/spec/unit/recipe_spec.rb +268 -0
- data/spec/unit/resource/apt_package_spec.rb +43 -0
- data/spec/unit/resource/bash_spec.rb +40 -0
- data/spec/unit/resource/breakpoint_spec.rb +43 -0
- data/spec/unit/resource/chef_gem_spec.rb +49 -0
- data/spec/unit/resource/conditional_spec.rb +147 -0
- data/spec/unit/resource/cookbook_file_spec.rb +89 -0
- data/spec/unit/resource/cron_spec.rb +181 -0
- data/spec/unit/resource/csh_spec.rb +40 -0
- data/spec/unit/resource/deploy_revision_spec.rb +47 -0
- data/spec/unit/resource/deploy_spec.rb +259 -0
- data/spec/unit/resource/directory_spec.rb +82 -0
- data/spec/unit/resource/dpkg_package_spec.rb +38 -0
- data/spec/unit/resource/easy_install_package_spec.rb +48 -0
- data/spec/unit/resource/env_spec.rb +85 -0
- data/spec/unit/resource/erl_call_spec.rb +81 -0
- data/spec/unit/resource/execute_spec.rb +124 -0
- data/spec/unit/resource/file_spec.rb +121 -0
- data/spec/unit/resource/freebsd_package_spec.rb +39 -0
- data/spec/unit/resource/gem_package_spec.rb +49 -0
- data/spec/unit/resource/git_spec.rb +46 -0
- data/spec/unit/resource/group_spec.rb +148 -0
- data/spec/unit/resource/http_request_spec.rb +59 -0
- data/spec/unit/resource/ifconfig_spec.rb +46 -0
- data/spec/unit/resource/ips_package_spec.rb +43 -0
- data/spec/unit/resource/link_spec.rb +118 -0
- data/spec/unit/resource/log_spec.rb +70 -0
- data/spec/unit/resource/macports_package_spec.rb +37 -0
- data/spec/unit/resource/mdadm_spec.rb +102 -0
- data/spec/unit/resource/mount_spec.rb +158 -0
- data/spec/unit/resource/ohai_spec.rb +62 -0
- data/spec/unit/resource/package_spec.rb +80 -0
- data/spec/unit/resource/pacman_package_spec.rb +38 -0
- data/spec/unit/resource/perl_spec.rb +40 -0
- data/spec/unit/resource/portage_package_spec.rb +38 -0
- data/spec/unit/resource/python_spec.rb +40 -0
- data/spec/unit/resource/remote_directory_spec.rb +97 -0
- data/spec/unit/resource/remote_file_spec.rb +125 -0
- data/spec/unit/resource/route_spec.rb +107 -0
- data/spec/unit/resource/rpm_package_spec.rb +38 -0
- data/spec/unit/resource/ruby_block_spec.rb +57 -0
- data/spec/unit/resource/ruby_spec.rb +40 -0
- data/spec/unit/resource/scm_spec.rb +159 -0
- data/spec/unit/resource/script_spec.rb +69 -0
- data/spec/unit/resource/service_spec.rb +165 -0
- data/spec/unit/resource/smartos_package_spec.rb +38 -0
- data/spec/unit/resource/subversion_spec.rb +58 -0
- data/spec/unit/resource/template_spec.rb +108 -0
- data/spec/unit/resource/timestamped_deploy_spec.rb +28 -0
- data/spec/unit/resource/user_spec.rb +122 -0
- data/spec/unit/resource/yum_package_spec.rb +85 -0
- data/spec/unit/resource_collection/stepable_iterator_spec.rb +144 -0
- data/spec/unit/resource_collection_spec.rb +257 -0
- data/spec/unit/resource_definition_spec.rb +119 -0
- data/spec/unit/resource_platform_map_spec.rb +164 -0
- data/spec/unit/resource_reporter_spec.rb +591 -0
- data/spec/unit/resource_spec.rb +721 -0
- data/spec/unit/rest/auth_credentials_spec.rb +431 -0
- data/spec/unit/rest_spec.rb +644 -0
- data/spec/unit/role_spec.rb +275 -0
- data/spec/unit/run_context_spec.rb +64 -0
- data/spec/unit/run_list/run_list_expansion_spec.rb +129 -0
- data/spec/unit/run_list/run_list_item_spec.rb +117 -0
- data/spec/unit/run_list/versioned_recipe_list_spec.rb +123 -0
- data/spec/unit/run_list_spec.rb +521 -0
- data/spec/unit/run_status_spec.rb +145 -0
- data/spec/unit/runner_spec.rb +303 -0
- data/spec/unit/scan_access_control_spec.rb +182 -0
- data/spec/unit/search/query_spec.rb +99 -0
- data/spec/unit/shef/model_wrapper_spec.rb +97 -0
- data/spec/unit/shef/shef_ext_spec.rb +153 -0
- data/spec/unit/shef/shef_session_spec.rb +154 -0
- data/spec/unit/shef_spec.rb +161 -0
- data/spec/unit/solr_query/query_transform_spec.rb +454 -0
- data/spec/unit/solr_query/solr_http_request_spec.rb +244 -0
- data/spec/unit/solr_query_spec.rb +203 -0
- data/spec/unit/util/file_edit_spec.rb +135 -0
- data/spec/unit/version_class_spec.rb +172 -0
- data/spec/unit/version_constraint_spec.rb +134 -0
- data/spec/unit/webui_user_spec.rb +238 -0
- data/tasks/rspec.rb +75 -0
- metadata +1548 -0
@@ -0,0 +1,244 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Stanislav Vitvitskiy
|
3
|
+
# Author:: Nuo Yan (nuo@opscode.com)
|
4
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
5
|
+
# Copyright:: Copyright (c) 2009, 2010 Opscode, Inc.
|
6
|
+
# License:: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'net/http'
|
22
|
+
require 'mixlib/authentication/signedheaderauth'
|
23
|
+
require 'openssl'
|
24
|
+
|
25
|
+
class Chef
|
26
|
+
# == Chef::CookbookSiteStreamingUploader
|
27
|
+
# A streaming multipart HTTP upload implementation. Used to upload cookbooks
|
28
|
+
# (in tarball form) to http://cookbooks.opscode.com
|
29
|
+
#
|
30
|
+
# inspired by http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html
|
31
|
+
class CookbookSiteStreamingUploader
|
32
|
+
|
33
|
+
DefaultHeaders = { 'accept' => 'application/json', 'x-chef-version' => ::Chef::VERSION }
|
34
|
+
|
35
|
+
class << self
|
36
|
+
|
37
|
+
def create_build_dir(cookbook)
|
38
|
+
tmp_cookbook_path = Tempfile.new("chef-#{cookbook.name}-build")
|
39
|
+
tmp_cookbook_path.close
|
40
|
+
tmp_cookbook_dir = tmp_cookbook_path.path
|
41
|
+
File.unlink(tmp_cookbook_dir)
|
42
|
+
FileUtils.mkdir_p(tmp_cookbook_dir)
|
43
|
+
Chef::Log.debug("Staging at #{tmp_cookbook_dir}")
|
44
|
+
checksums_to_on_disk_paths = cookbook.checksums
|
45
|
+
Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
|
46
|
+
cookbook.manifest[segment].each do |manifest_record|
|
47
|
+
path_in_cookbook = manifest_record[:path]
|
48
|
+
on_disk_path = checksums_to_on_disk_paths[manifest_record[:checksum]]
|
49
|
+
dest = File.join(tmp_cookbook_dir, cookbook.name.to_s, path_in_cookbook)
|
50
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
51
|
+
Chef::Log.debug("Staging #{on_disk_path} to #{dest}")
|
52
|
+
FileUtils.cp(on_disk_path, dest)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# First, generate metadata
|
57
|
+
Chef::Log.debug("Generating metadata")
|
58
|
+
kcm = Chef::Knife::CookbookMetadata.new
|
59
|
+
kcm.config[:cookbook_path] = [ tmp_cookbook_dir ]
|
60
|
+
kcm.name_args = [ cookbook.name.to_s ]
|
61
|
+
kcm.run
|
62
|
+
|
63
|
+
tmp_cookbook_dir
|
64
|
+
end
|
65
|
+
|
66
|
+
def post(to_url, user_id, secret_key_filename, params = {}, headers = {})
|
67
|
+
make_request(:post, to_url, user_id, secret_key_filename, params, headers)
|
68
|
+
end
|
69
|
+
|
70
|
+
def put(to_url, user_id, secret_key_filename, params = {}, headers = {})
|
71
|
+
make_request(:put, to_url, user_id, secret_key_filename, params, headers)
|
72
|
+
end
|
73
|
+
|
74
|
+
def make_request(http_verb, to_url, user_id, secret_key_filename, params = {}, headers = {})
|
75
|
+
boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
|
76
|
+
parts = []
|
77
|
+
content_file = nil
|
78
|
+
|
79
|
+
timestamp = Time.now.utc.iso8601
|
80
|
+
secret_key = OpenSSL::PKey::RSA.new(File.read(secret_key_filename))
|
81
|
+
|
82
|
+
unless params.nil? || params.empty?
|
83
|
+
params.each do |key, value|
|
84
|
+
if value.kind_of?(File)
|
85
|
+
content_file = value
|
86
|
+
filepath = value.path
|
87
|
+
filename = File.basename(filepath)
|
88
|
+
parts << StringPart.new( "--" + boundary + "\r\n" +
|
89
|
+
"Content-Disposition: form-data; name=\"" + key.to_s + "\"; filename=\"" + filename + "\"\r\n" +
|
90
|
+
"Content-Type: application/octet-stream\r\n\r\n")
|
91
|
+
parts << StreamPart.new(value, File.size(filepath))
|
92
|
+
parts << StringPart.new("\r\n")
|
93
|
+
else
|
94
|
+
parts << StringPart.new( "--" + boundary + "\r\n" +
|
95
|
+
"Content-Disposition: form-data; name=\"" + key.to_s + "\"\r\n\r\n")
|
96
|
+
parts << StringPart.new(value.to_s + "\r\n")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
parts << StringPart.new("--" + boundary + "--\r\n")
|
100
|
+
end
|
101
|
+
|
102
|
+
body_stream = MultipartStream.new(parts)
|
103
|
+
|
104
|
+
timestamp = Time.now.utc.iso8601
|
105
|
+
|
106
|
+
url = URI.parse(to_url)
|
107
|
+
|
108
|
+
Chef::Log.logger.debug("Signing: method: #{http_verb}, path: #{url.path}, file: #{content_file}, User-id: #{user_id}, Timestamp: #{timestamp}")
|
109
|
+
|
110
|
+
# We use the body for signing the request if the file parameter
|
111
|
+
# wasn't a valid file or wasn't included. Extract the body (with
|
112
|
+
# multi-part delimiters intact) to sign the request.
|
113
|
+
# TODO: tim: 2009-12-28: It'd be nice to remove this special case, and
|
114
|
+
# always hash the entire request body. In the file case it would just be
|
115
|
+
# expanded multipart text - the entire body of the POST.
|
116
|
+
content_body = parts.inject("") { |result,part| result + part.read(0, part.size) }
|
117
|
+
content_file.rewind if content_file # we consumed the file for the above operation, so rewind it.
|
118
|
+
|
119
|
+
signing_options = {
|
120
|
+
:http_method=>http_verb,
|
121
|
+
:path=>url.path,
|
122
|
+
:user_id=>user_id,
|
123
|
+
:timestamp=>timestamp}
|
124
|
+
(content_file && signing_options[:file] = content_file) || (signing_options[:body] = (content_body || ""))
|
125
|
+
|
126
|
+
headers.merge!(Mixlib::Authentication::SignedHeaderAuth.signing_object(signing_options).sign(secret_key))
|
127
|
+
|
128
|
+
content_file.rewind if content_file
|
129
|
+
|
130
|
+
# net/http doesn't like symbols for header keys, so we'll to_s each one just in case
|
131
|
+
headers = DefaultHeaders.merge(Hash[*headers.map{ |k,v| [k.to_s, v] }.flatten])
|
132
|
+
|
133
|
+
req = case http_verb
|
134
|
+
when :put
|
135
|
+
Net::HTTP::Put.new(url.path, headers)
|
136
|
+
when :post
|
137
|
+
Net::HTTP::Post.new(url.path, headers)
|
138
|
+
end
|
139
|
+
req.content_length = body_stream.size
|
140
|
+
req.content_type = 'multipart/form-data; boundary=' + boundary unless parts.empty?
|
141
|
+
req.body_stream = body_stream
|
142
|
+
|
143
|
+
http = Net::HTTP.new(url.host, url.port)
|
144
|
+
if url.scheme == "https"
|
145
|
+
http.use_ssl = true
|
146
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
147
|
+
end
|
148
|
+
res = http.request(req)
|
149
|
+
#res = http.start {|http_proc| http_proc.request(req) }
|
150
|
+
|
151
|
+
# alias status to code and to_s to body for test purposes
|
152
|
+
# TODO: stop the following madness!
|
153
|
+
class << res
|
154
|
+
alias :to_s :body
|
155
|
+
|
156
|
+
# BUGBUG this makes the response compatible with what respsonse_steps expects to test headers (response.headers[] -> response[])
|
157
|
+
def headers
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
def status
|
162
|
+
code.to_i
|
163
|
+
end
|
164
|
+
end
|
165
|
+
res
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
class StreamPart
|
171
|
+
def initialize(stream, size)
|
172
|
+
@stream, @size = stream, size
|
173
|
+
end
|
174
|
+
|
175
|
+
def size
|
176
|
+
@size
|
177
|
+
end
|
178
|
+
|
179
|
+
# read the specified amount from the stream
|
180
|
+
def read(offset, how_much)
|
181
|
+
@stream.read(how_much)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class StringPart
|
186
|
+
def initialize(str)
|
187
|
+
@str = str
|
188
|
+
end
|
189
|
+
|
190
|
+
def size
|
191
|
+
@str.length
|
192
|
+
end
|
193
|
+
|
194
|
+
# read the specified amount from the string startiung at the offset
|
195
|
+
def read(offset, how_much)
|
196
|
+
@str[offset, how_much]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
class MultipartStream
|
201
|
+
def initialize(parts)
|
202
|
+
@parts = parts
|
203
|
+
@part_no = 0
|
204
|
+
@part_offset = 0
|
205
|
+
end
|
206
|
+
|
207
|
+
def size
|
208
|
+
@parts.inject(0) {|size, part| size + part.size}
|
209
|
+
end
|
210
|
+
|
211
|
+
def read(how_much)
|
212
|
+
return nil if @part_no >= @parts.size
|
213
|
+
|
214
|
+
how_much_current_part = @parts[@part_no].size - @part_offset
|
215
|
+
|
216
|
+
how_much_current_part = if how_much_current_part > how_much
|
217
|
+
how_much
|
218
|
+
else
|
219
|
+
how_much_current_part
|
220
|
+
end
|
221
|
+
|
222
|
+
how_much_next_part = how_much - how_much_current_part
|
223
|
+
|
224
|
+
current_part = @parts[@part_no].read(@part_offset, how_much_current_part)
|
225
|
+
|
226
|
+
# recurse into the next part if the current one was not large enough
|
227
|
+
if how_much_next_part > 0
|
228
|
+
@part_no += 1
|
229
|
+
@part_offset = 0
|
230
|
+
next_part = read(how_much_next_part)
|
231
|
+
current_part + if next_part
|
232
|
+
next_part
|
233
|
+
else
|
234
|
+
''
|
235
|
+
end
|
236
|
+
else
|
237
|
+
@part_offset += how_much_current_part
|
238
|
+
current_part
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
|
2
|
+
require 'set'
|
3
|
+
require 'rest_client'
|
4
|
+
require 'chef/exceptions'
|
5
|
+
require 'chef/knife/cookbook_metadata'
|
6
|
+
require 'chef/checksum_cache'
|
7
|
+
require 'chef/sandbox'
|
8
|
+
require 'chef/cookbook_version'
|
9
|
+
require 'chef/cookbook/syntax_check'
|
10
|
+
require 'chef/cookbook/file_system_file_vendor'
|
11
|
+
|
12
|
+
class Chef
|
13
|
+
class CookbookUploader
|
14
|
+
|
15
|
+
def self.work_queue
|
16
|
+
@work_queue ||= Queue.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.setup_worker_threads
|
20
|
+
@worker_threads ||= begin
|
21
|
+
work_queue
|
22
|
+
(1...10).map do
|
23
|
+
Thread.new do
|
24
|
+
loop do
|
25
|
+
work_queue.pop.call
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :cookbooks
|
33
|
+
attr_reader :path
|
34
|
+
attr_reader :opts
|
35
|
+
attr_reader :rest
|
36
|
+
|
37
|
+
# Creates a new CookbookUploader.
|
38
|
+
# ===Arguments:
|
39
|
+
# * cookbooks::: A Chef::CookbookVersion or array of them describing the
|
40
|
+
# cookbook(s) to be uploaded
|
41
|
+
# * path::: A String or Array of Strings representing the base paths to the
|
42
|
+
# cookbook repositories.
|
43
|
+
# * opts::: (optional) An options Hash
|
44
|
+
# ===Options:
|
45
|
+
# * :force indicates that the uploader should set the force option when
|
46
|
+
# uploading the cookbook. This allows frozen CookbookVersion
|
47
|
+
# documents on the server to be overwritten (otherwise a 409 is
|
48
|
+
# returned by the server)
|
49
|
+
# * :rest A Chef::REST object that you have configured the way you like it.
|
50
|
+
# If you don't provide this, one will be created using the values
|
51
|
+
# in Chef::Config.
|
52
|
+
def initialize(cookbooks, path, opts={})
|
53
|
+
@path, @opts = path, opts
|
54
|
+
@cookbooks = Array(cookbooks)
|
55
|
+
@rest = opts[:rest] || Chef::REST.new(Chef::Config[:chef_server_url])
|
56
|
+
end
|
57
|
+
|
58
|
+
def upload_cookbooks
|
59
|
+
Thread.abort_on_exception = true
|
60
|
+
|
61
|
+
# Syntax Check
|
62
|
+
validate_cookbooks
|
63
|
+
# generate checksums of cookbook files and create a sandbox
|
64
|
+
checksum_files = {}
|
65
|
+
cookbooks.each do |cb|
|
66
|
+
Chef::Log.info("Saving #{cb.name}")
|
67
|
+
checksum_files.merge!(cb.checksums)
|
68
|
+
end
|
69
|
+
|
70
|
+
checksums = checksum_files.inject({}){|memo,elt| memo[elt.first]=nil ; memo}
|
71
|
+
new_sandbox = rest.post_rest("sandboxes", { :checksums => checksums })
|
72
|
+
|
73
|
+
Chef::Log.info("Uploading files")
|
74
|
+
|
75
|
+
self.class.setup_worker_threads
|
76
|
+
|
77
|
+
checksums_to_upload = Set.new
|
78
|
+
|
79
|
+
# upload the new checksums and commit the sandbox
|
80
|
+
new_sandbox['checksums'].each do |checksum, info|
|
81
|
+
if info['needs_upload'] == true
|
82
|
+
checksums_to_upload << checksum
|
83
|
+
Chef::Log.info("Uploading #{checksum_files[checksum]} (checksum hex = #{checksum}) to #{info['url']}")
|
84
|
+
self.class.work_queue << uploader_function_for(checksum_files[checksum], checksum, info['url'], checksums_to_upload)
|
85
|
+
else
|
86
|
+
Chef::Log.debug("#{checksum_files[checksum]} has not changed")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
until checksums_to_upload.empty?
|
91
|
+
sleep 0.1
|
92
|
+
end
|
93
|
+
|
94
|
+
sandbox_url = new_sandbox['uri']
|
95
|
+
Chef::Log.debug("Committing sandbox")
|
96
|
+
# Retry if S3 is claims a checksum doesn't exist (the eventual
|
97
|
+
# in eventual consistency)
|
98
|
+
retries = 0
|
99
|
+
begin
|
100
|
+
rest.put_rest(sandbox_url, {:is_completed => true})
|
101
|
+
rescue Net::HTTPServerException => e
|
102
|
+
if e.message =~ /^400/ && (retries += 1) <= 5
|
103
|
+
sleep 2
|
104
|
+
retry
|
105
|
+
else
|
106
|
+
raise
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# files are uploaded, so save the manifest
|
111
|
+
cookbooks.each do |cb|
|
112
|
+
save_url = opts[:force] ? cb.force_save_url : cb.save_url
|
113
|
+
begin
|
114
|
+
rest.put_rest(save_url, cb)
|
115
|
+
rescue Net::HTTPServerException => e
|
116
|
+
case e.response.code
|
117
|
+
when "409"
|
118
|
+
raise Chef::Exceptions::CookbookFrozen, "Version #{cb.version} of cookbook #{cb.name} is frozen. Use --force to override."
|
119
|
+
else
|
120
|
+
raise
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
Chef::Log.info("Upload complete!")
|
126
|
+
end
|
127
|
+
|
128
|
+
def worker_thread(work_queue)
|
129
|
+
end
|
130
|
+
|
131
|
+
def uploader_function_for(file, checksum, url, checksums_to_upload)
|
132
|
+
lambda do
|
133
|
+
# Checksum is the hexadecimal representation of the md5,
|
134
|
+
# but we need the base64 encoding for the content-md5
|
135
|
+
# header
|
136
|
+
checksum64 = Base64.encode64([checksum].pack("H*")).strip
|
137
|
+
timestamp = Time.now.utc.iso8601
|
138
|
+
file_contents = File.open(file, "rb") {|f| f.read}
|
139
|
+
# TODO - 5/28/2010, cw: make signing and sending the request streaming
|
140
|
+
sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(
|
141
|
+
:http_method => :put,
|
142
|
+
:path => URI.parse(url).path,
|
143
|
+
:body => file_contents,
|
144
|
+
:timestamp => timestamp,
|
145
|
+
:user_id => rest.client_name
|
146
|
+
)
|
147
|
+
headers = { 'content-type' => 'application/x-binary', 'content-md5' => checksum64, :accept => 'application/json' }
|
148
|
+
headers.merge!(sign_obj.sign(OpenSSL::PKey::RSA.new(rest.signing_key)))
|
149
|
+
|
150
|
+
begin
|
151
|
+
RestClient::Resource.new(url, :headers=>headers, :timeout=>1800, :open_timeout=>1800).put(file_contents)
|
152
|
+
checksums_to_upload.delete(checksum)
|
153
|
+
rescue RestClient::Exception => e
|
154
|
+
Chef::Knife.ui.error("Failed to upload #@cookbook : #{e.message}\n#{e.response.body}")
|
155
|
+
raise
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def validate_cookbooks
|
161
|
+
cookbooks.each do |cb|
|
162
|
+
syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cb.name, @user_cookbook_path)
|
163
|
+
Chef::Log.info("Validating ruby files")
|
164
|
+
exit(1) unless syntax_checker.validate_ruby_files
|
165
|
+
Chef::Log.info("Validating templates")
|
166
|
+
exit(1) unless syntax_checker.validate_templates
|
167
|
+
Chef::Log.info("Syntax OK")
|
168
|
+
true
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,1081 @@
|
|
1
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
2
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
3
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
4
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
5
|
+
# Author:: Seth Falcon (<seth@opscode.com>)
|
6
|
+
# Author:: Daniel DeLeo (<dan@opscode.com>)
|
7
|
+
# Copyright:: Copyright 2008-2011 Opscode, Inc.
|
8
|
+
# License:: Apache License, Version 2.0
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at
|
13
|
+
#
|
14
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
15
|
+
#
|
16
|
+
# Unless required by applicable law or agreed to in writing, software
|
17
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
18
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
19
|
+
# See the License for the specific language governing permissions and
|
20
|
+
# limitations under the License.
|
21
|
+
|
22
|
+
require 'chef/log'
|
23
|
+
require 'chef/node'
|
24
|
+
require 'chef/resource_definition_list'
|
25
|
+
require 'chef/recipe'
|
26
|
+
require 'chef/cookbook/file_vendor'
|
27
|
+
require 'chef/checksum'
|
28
|
+
require 'chef/cookbook/metadata'
|
29
|
+
require 'chef/version_class'
|
30
|
+
|
31
|
+
class Chef
|
32
|
+
|
33
|
+
#== Chef::MinimalCookbookVersion
|
34
|
+
# MinimalCookbookVersion is a duck type of CookbookVersion, used
|
35
|
+
# internally by Chef Server as an optimization when determining the
|
36
|
+
# optimal cookbook set for a chef-client.
|
37
|
+
#
|
38
|
+
# MinimalCookbookVersion objects contain only enough information to
|
39
|
+
# solve the cookbook collection for a given run list. They *do not*
|
40
|
+
# contain enough information to generate the response.
|
41
|
+
#
|
42
|
+
# See also: Chef::CookbookVersionSelector
|
43
|
+
class MinimalCookbookVersion
|
44
|
+
|
45
|
+
include Comparable
|
46
|
+
|
47
|
+
ID = "id".freeze
|
48
|
+
NAME = 'name'.freeze
|
49
|
+
KEY = 'key'.freeze
|
50
|
+
VERSION = 'version'.freeze
|
51
|
+
VALUE = 'value'.freeze
|
52
|
+
DEPS = 'deps'.freeze
|
53
|
+
|
54
|
+
DEPENDENCIES = 'dependencies'.freeze
|
55
|
+
|
56
|
+
# Loads the full list of cookbooks, using a couchdb view to fetch
|
57
|
+
# only the id, name, version, and dependency constraints. This is
|
58
|
+
# enough information to solve for the cookbook collection for a
|
59
|
+
# given run list. After solving for the cookbook collection, you
|
60
|
+
# need to call +load_full_versions_of+ to convert
|
61
|
+
# MinimalCookbookVersion objects to their non-minimal counterparts
|
62
|
+
def self.load_all(couchdb)
|
63
|
+
# Example:
|
64
|
+
# {"id"=>"1a806f1c-b409-4d8e-abab-fa414ff5b96d", "key"=>"activemq", "value"=>{"version"=>"0.3.3", "deps"=>{"java"=>">= 0.0.0", "runit"=>">= 0.0.0"}}}
|
65
|
+
couchdb ||= Chef::CouchDB.new
|
66
|
+
couchdb.get_view("cookbooks", "all_with_version_and_deps")["rows"].map {|params| self.new(params) }
|
67
|
+
end
|
68
|
+
|
69
|
+
# Loads the non-minimal CookbookVersion objects corresponding to
|
70
|
+
# +minimal_cookbook_versions+ from couchdb using a bulk GET.
|
71
|
+
def self.load_full_versions_of(minimal_cookbook_versions, couchdb)
|
72
|
+
database_ids = Array(minimal_cookbook_versions).map {|mcv| mcv.couchdb_id }
|
73
|
+
couchdb ||= Chef::CouchDB.new
|
74
|
+
couchdb.bulk_get(*database_ids)
|
75
|
+
end
|
76
|
+
|
77
|
+
attr_reader :couchdb_id
|
78
|
+
attr_reader :name
|
79
|
+
attr_reader :version
|
80
|
+
attr_reader :deps
|
81
|
+
|
82
|
+
def initialize(params)
|
83
|
+
@couchdb_id = params[ID]
|
84
|
+
@name = params[KEY]
|
85
|
+
@version = params[VALUE][VERSION]
|
86
|
+
@deps = params[VALUE][DEPS]
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns the Cookbook::MinimalMetadata object for this cookbook
|
90
|
+
# version.
|
91
|
+
def metadata
|
92
|
+
@metadata ||= Cookbook::MinimalMetadata.new(@name, DEPENDENCIES => @deps)
|
93
|
+
end
|
94
|
+
|
95
|
+
def legit_version
|
96
|
+
@legit_version ||= Chef::Version.new(@version)
|
97
|
+
end
|
98
|
+
|
99
|
+
def <=>(o)
|
100
|
+
raise Chef::Exceptions::CookbookVersionNameMismatch if self.name != o.name
|
101
|
+
raise "Unexpected comparison to #{o}" unless o.respond_to?(:legit_version)
|
102
|
+
legit_version <=> o.legit_version
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# == Chef::CookbookVersion
|
108
|
+
# CookbookVersion is a model object encapsulating the data about a Chef
|
109
|
+
# cookbook. Chef supports maintaining multiple versions of a cookbook on a
|
110
|
+
# single server; each version is represented by a distinct instance of this
|
111
|
+
# class.
|
112
|
+
#--
|
113
|
+
# TODO: timh/cw: 5-24-2010: mutators for files (e.g., recipe_filenames=,
|
114
|
+
# recipe_filenames.insert) should dirty the manifest so it gets regenerated.
|
115
|
+
class CookbookVersion
|
116
|
+
include Chef::IndexQueue::Indexable
|
117
|
+
include Comparable
|
118
|
+
|
119
|
+
COOKBOOK_SEGMENTS = [ :resources, :providers, :recipes, :definitions, :libraries, :attributes, :files, :templates, :root_files ]
|
120
|
+
|
121
|
+
DESIGN_DOCUMENT = {
|
122
|
+
"version" => 8,
|
123
|
+
"language" => "javascript",
|
124
|
+
"views" => {
|
125
|
+
"all" => {
|
126
|
+
"map" => <<-EOJS
|
127
|
+
function(doc) {
|
128
|
+
if (doc.chef_type == "cookbook_version") {
|
129
|
+
emit(doc.name, doc);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
EOJS
|
133
|
+
},
|
134
|
+
"all_id" => {
|
135
|
+
"map" => <<-EOJS
|
136
|
+
function(doc) {
|
137
|
+
if (doc.chef_type == "cookbook_version") {
|
138
|
+
emit(doc.name, doc.name);
|
139
|
+
}
|
140
|
+
}
|
141
|
+
EOJS
|
142
|
+
},
|
143
|
+
"all_with_version" => {
|
144
|
+
"map" => <<-EOJS
|
145
|
+
function(doc) {
|
146
|
+
if (doc.chef_type == "cookbook_version") {
|
147
|
+
emit(doc.cookbook_name, doc.version);
|
148
|
+
}
|
149
|
+
}
|
150
|
+
EOJS
|
151
|
+
},
|
152
|
+
"all_with_version_and_deps" => {
|
153
|
+
"map" => <<-JS
|
154
|
+
function(doc) {
|
155
|
+
if (doc.chef_type == "cookbook_version") {
|
156
|
+
emit(doc.cookbook_name, {version: doc.version, deps: doc.metadata.dependencies});
|
157
|
+
}
|
158
|
+
}
|
159
|
+
JS
|
160
|
+
},
|
161
|
+
"all_latest_version" => {
|
162
|
+
"map" => %q@
|
163
|
+
function(doc) {
|
164
|
+
if (doc.chef_type == "cookbook_version") {
|
165
|
+
emit(doc.cookbook_name, doc.version);
|
166
|
+
}
|
167
|
+
}
|
168
|
+
@,
|
169
|
+
"reduce" => %q@
|
170
|
+
function(keys, values, rereduce) {
|
171
|
+
var result = null;
|
172
|
+
|
173
|
+
for (var idx in values) {
|
174
|
+
var value = values[idx];
|
175
|
+
|
176
|
+
if (idx == 0) {
|
177
|
+
result = value;
|
178
|
+
continue;
|
179
|
+
}
|
180
|
+
|
181
|
+
var valueParts = value.split('.').map(function(v) { return parseInt(v); });
|
182
|
+
var resultParts = result.split('.').map(function(v) { return parseInt(v); });
|
183
|
+
|
184
|
+
if (valueParts[0] != resultParts[0]) {
|
185
|
+
if (valueParts[0] > resultParts[0]) {
|
186
|
+
result = value;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
else if (valueParts[1] != resultParts[1]) {
|
190
|
+
if (valueParts[1] > resultParts[1]) {
|
191
|
+
result = value;
|
192
|
+
}
|
193
|
+
}
|
194
|
+
else if (valueParts[2] != resultParts[2]) {
|
195
|
+
if (valueParts[2] > resultParts[2]) {
|
196
|
+
result = value;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
}
|
200
|
+
return result;
|
201
|
+
}
|
202
|
+
@
|
203
|
+
},
|
204
|
+
"all_latest_version_by_id" => {
|
205
|
+
"map" => %q@
|
206
|
+
function(doc) {
|
207
|
+
if (doc.chef_type == "cookbook_version") {
|
208
|
+
emit(doc.cookbook_name, {version: doc.version, id:doc._id});
|
209
|
+
}
|
210
|
+
}
|
211
|
+
@,
|
212
|
+
"reduce" => %q@
|
213
|
+
function(keys, values, rereduce) {
|
214
|
+
var result = null;
|
215
|
+
|
216
|
+
for (var idx in values) {
|
217
|
+
var value = values[idx];
|
218
|
+
|
219
|
+
if (idx == 0) {
|
220
|
+
result = value;
|
221
|
+
continue;
|
222
|
+
}
|
223
|
+
|
224
|
+
var valueParts = value.version.split('.').map(function(v) { return parseInt(v); });
|
225
|
+
var resultParts = result.version.split('.').map(function(v) { return parseInt(v); });
|
226
|
+
|
227
|
+
if (valueParts[0] != resultParts[0]) {
|
228
|
+
if (valueParts[0] > resultParts[0]) {
|
229
|
+
result = value;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
else if (valueParts[1] != resultParts[1]) {
|
233
|
+
if (valueParts[1] > resultParts[1]) {
|
234
|
+
result = value;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
else if (valueParts[2] != resultParts[2]) {
|
238
|
+
if (valueParts[2] > resultParts[2]) {
|
239
|
+
result = value;
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
return result;
|
244
|
+
}
|
245
|
+
@
|
246
|
+
},
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
attr_accessor :root_dir
|
251
|
+
attr_accessor :definition_filenames
|
252
|
+
attr_accessor :template_filenames
|
253
|
+
attr_accessor :file_filenames
|
254
|
+
attr_accessor :library_filenames
|
255
|
+
attr_accessor :resource_filenames
|
256
|
+
attr_accessor :provider_filenames
|
257
|
+
attr_accessor :root_filenames
|
258
|
+
attr_accessor :name
|
259
|
+
attr_accessor :metadata
|
260
|
+
attr_accessor :metadata_filenames
|
261
|
+
attr_accessor :status
|
262
|
+
attr_accessor :couchdb_rev
|
263
|
+
attr_accessor :couchdb
|
264
|
+
|
265
|
+
attr_reader :couchdb_id
|
266
|
+
|
267
|
+
# attribute_filenames also has a setter that has non-default
|
268
|
+
# functionality.
|
269
|
+
attr_reader :attribute_filenames
|
270
|
+
|
271
|
+
# recipe_filenames also has a setter that has non-default
|
272
|
+
# functionality.
|
273
|
+
attr_reader :recipe_filenames
|
274
|
+
|
275
|
+
attr_reader :recipe_filenames_by_name
|
276
|
+
attr_reader :attribute_filenames_by_short_filename
|
277
|
+
|
278
|
+
# This is the one and only method that knows how cookbook files'
|
279
|
+
# checksums are generated.
|
280
|
+
def self.checksum_cookbook_file(filepath)
|
281
|
+
Chef::ChecksumCache.generate_md5_checksum_for_file(filepath)
|
282
|
+
rescue Errno::ENOENT
|
283
|
+
Chef::Log.debug("File #{filepath} does not exist, so there is no checksum to generate")
|
284
|
+
nil
|
285
|
+
end
|
286
|
+
|
287
|
+
def self.cache
|
288
|
+
Chef::FileCache
|
289
|
+
end
|
290
|
+
|
291
|
+
# Synchronizes all the cookbooks from the chef-server.
|
292
|
+
#
|
293
|
+
# === Returns
|
294
|
+
# true:: Always returns true
|
295
|
+
def self.sync_cookbooks(cookbook_hash)
|
296
|
+
Chef::Log.info("Loading cookbooks [#{cookbook_hash.keys.sort.join(', ')}]")
|
297
|
+
Chef::Log.debug("Cookbooks detail: #{cookbook_hash.inspect}")
|
298
|
+
|
299
|
+
clear_obsoleted_cookbooks(cookbook_hash)
|
300
|
+
|
301
|
+
# Synchronize each of the node's cookbooks, and add to the
|
302
|
+
# valid_cache_entries hash.
|
303
|
+
cookbook_hash.values.each do |cookbook|
|
304
|
+
sync_cookbook_file_cache(cookbook)
|
305
|
+
end
|
306
|
+
|
307
|
+
true
|
308
|
+
end
|
309
|
+
|
310
|
+
# Iterates over cached cookbooks' files, removing files belonging to
|
311
|
+
# cookbooks that don't appear in +cookbook_hash+
|
312
|
+
def self.clear_obsoleted_cookbooks(cookbook_hash)
|
313
|
+
# Remove all cookbooks no longer relevant to this node
|
314
|
+
cache.find(File.join(%w{cookbooks ** *})).each do |cache_file|
|
315
|
+
cache_file =~ /^cookbooks\/([^\/]+)\//
|
316
|
+
unless cookbook_hash.has_key?($1)
|
317
|
+
Chef::Log.info("Removing #{cache_file} from the cache; its cookbook is no longer needed on this client.")
|
318
|
+
cache.delete(cache_file)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
# Update the file caches for a given cache segment. Takes a segment name
|
324
|
+
# and a hash that matches one of the cookbooks/_attribute_files style
|
325
|
+
# remote file listings.
|
326
|
+
#
|
327
|
+
# === Parameters
|
328
|
+
# cookbook<Chef::Cookbook>:: The cookbook to update
|
329
|
+
# valid_cache_entries<Hash>:: Out-param; Added to this hash are the files that
|
330
|
+
# were referred to by this cookbook
|
331
|
+
def self.sync_cookbook_file_cache(cookbook)
|
332
|
+
Chef::Log.debug("Synchronizing cookbook #{cookbook.name}")
|
333
|
+
|
334
|
+
# files and templates are lazily loaded, and will be done later.
|
335
|
+
eager_segments = COOKBOOK_SEGMENTS.dup
|
336
|
+
|
337
|
+
unless Chef::Config[:no_lazy_load] then
|
338
|
+
eager_segments.delete(:files)
|
339
|
+
eager_segments.delete(:templates)
|
340
|
+
end
|
341
|
+
|
342
|
+
eager_segments.each do |segment|
|
343
|
+
segment_filenames = Array.new
|
344
|
+
cookbook.manifest[segment].each do |manifest_record|
|
345
|
+
# segment = cookbook segment
|
346
|
+
# remote_list = list of file hashes
|
347
|
+
#
|
348
|
+
# We need the list of known good attribute files, so we can delete any that are
|
349
|
+
# just laying about.
|
350
|
+
|
351
|
+
cache_filename = File.join("cookbooks", cookbook.name, manifest_record['path'])
|
352
|
+
valid_cache_entries[cache_filename] = true
|
353
|
+
|
354
|
+
current_checksum = nil
|
355
|
+
if cache.has_key?(cache_filename)
|
356
|
+
current_checksum = checksum_cookbook_file(cache.load(cache_filename, false))
|
357
|
+
end
|
358
|
+
|
359
|
+
# If the checksums are different between on-disk (current) and on-server
|
360
|
+
# (remote, per manifest), do the update. This will also execute if there
|
361
|
+
# is no current checksum.
|
362
|
+
if current_checksum != manifest_record['checksum']
|
363
|
+
raw_file = chef_server_rest.get_rest(manifest_record[:url], true)
|
364
|
+
|
365
|
+
Chef::Log.info("Storing updated #{cache_filename} in the cache.")
|
366
|
+
cache.move_to(raw_file.path, cache_filename)
|
367
|
+
else
|
368
|
+
Chef::Log.debug("Not storing #{cache_filename}, as the cache is up to date.")
|
369
|
+
end
|
370
|
+
|
371
|
+
# make the segment filenames a full path.
|
372
|
+
full_path_cache_filename = cache.load(cache_filename, false)
|
373
|
+
segment_filenames << full_path_cache_filename
|
374
|
+
end
|
375
|
+
|
376
|
+
# replace segment filenames with a full-path one.
|
377
|
+
if segment.to_sym == :recipes
|
378
|
+
cookbook.recipe_filenames = segment_filenames
|
379
|
+
elsif segment.to_sym == :attributes
|
380
|
+
cookbook.attribute_filenames = segment_filenames
|
381
|
+
else
|
382
|
+
cookbook.segment_filenames(segment).replace(segment_filenames)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
def self.cleanup_file_cache
|
388
|
+
unless Chef::Config[:solo]
|
389
|
+
# Delete each file in the cache that we didn't encounter in the
|
390
|
+
# manifest.
|
391
|
+
cache.find(File.join(%w{cookbooks ** *})).each do |cache_filename|
|
392
|
+
unless valid_cache_entries[cache_filename]
|
393
|
+
Chef::Log.info("Removing #{cache_filename} from the cache; it is no longer needed by chef-client.")
|
394
|
+
cache.delete(cache_filename)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
# Creates a new Chef::CookbookVersion object.
|
401
|
+
#
|
402
|
+
# === Returns
|
403
|
+
# object<Chef::CookbookVersion>:: Duh. :)
|
404
|
+
def initialize(name, couchdb=nil)
|
405
|
+
@name = name
|
406
|
+
@frozen = false
|
407
|
+
@attribute_filenames = Array.new
|
408
|
+
@definition_filenames = Array.new
|
409
|
+
@template_filenames = Array.new
|
410
|
+
@file_filenames = Array.new
|
411
|
+
@recipe_filenames = Array.new
|
412
|
+
@recipe_filenames_by_name = Hash.new
|
413
|
+
@library_filenames = Array.new
|
414
|
+
@resource_filenames = Array.new
|
415
|
+
@provider_filenames = Array.new
|
416
|
+
@metadata_filenames = Array.new
|
417
|
+
@root_dir = nil
|
418
|
+
@root_filenames = Array.new
|
419
|
+
@couchdb_id = nil
|
420
|
+
@couchdb = couchdb || Chef::CouchDB.new
|
421
|
+
@couchdb_rev = nil
|
422
|
+
@status = :ready
|
423
|
+
@manifest = nil
|
424
|
+
@file_vendor = nil
|
425
|
+
@metadata = Chef::Cookbook::Metadata.new
|
426
|
+
end
|
427
|
+
|
428
|
+
def version
|
429
|
+
metadata.version
|
430
|
+
end
|
431
|
+
|
432
|
+
# Indicates if this version is frozen or not. Freezing a coobkook version
|
433
|
+
# indicates that a new cookbook with the same name and version number
|
434
|
+
# shoule
|
435
|
+
def frozen_version?
|
436
|
+
@frozen
|
437
|
+
end
|
438
|
+
|
439
|
+
def freeze_version
|
440
|
+
@frozen = true
|
441
|
+
end
|
442
|
+
|
443
|
+
def version=(new_version)
|
444
|
+
manifest["version"] = new_version
|
445
|
+
metadata.version(new_version)
|
446
|
+
end
|
447
|
+
|
448
|
+
# A manifest is a Mash that maps segment names to arrays of manifest
|
449
|
+
# records (see #preferred_manifest_record for format of manifest records),
|
450
|
+
# as well as describing cookbook metadata. The manifest follows a form
|
451
|
+
# like the following:
|
452
|
+
#
|
453
|
+
# {
|
454
|
+
# :cookbook_name = "apache2",
|
455
|
+
# :version = "1.0",
|
456
|
+
# :name = "Apache 2"
|
457
|
+
# :metadata = ???TODO: timh/cw: 5-24-2010: describe this format,
|
458
|
+
#
|
459
|
+
# :files => [
|
460
|
+
# {
|
461
|
+
# :name => "afile.rb",
|
462
|
+
# :path => "files/ubuntu-9.10/afile.rb",
|
463
|
+
# :checksum => "2222",
|
464
|
+
# :specificity => "ubuntu-9.10"
|
465
|
+
# },
|
466
|
+
# ],
|
467
|
+
# :templates => [ manifest_record1, ... ],
|
468
|
+
# ...
|
469
|
+
# }
|
470
|
+
def manifest
|
471
|
+
unless @manifest
|
472
|
+
generate_manifest
|
473
|
+
end
|
474
|
+
@manifest
|
475
|
+
end
|
476
|
+
|
477
|
+
def manifest=(new_manifest)
|
478
|
+
@manifest = Mash.new new_manifest
|
479
|
+
@checksums = extract_checksums_from_manifest(@manifest)
|
480
|
+
@manifest_records_by_path = extract_manifest_records_by_path(@manifest)
|
481
|
+
|
482
|
+
COOKBOOK_SEGMENTS.each do |segment|
|
483
|
+
next unless @manifest.has_key?(segment)
|
484
|
+
filenames = @manifest[segment].map{|manifest_record| manifest_record['name']}
|
485
|
+
|
486
|
+
if segment == :recipes
|
487
|
+
self.recipe_filenames = filenames
|
488
|
+
elsif segment == :attributes
|
489
|
+
self.attribute_filenames = filenames
|
490
|
+
else
|
491
|
+
segment_filenames(segment).clear
|
492
|
+
filenames.each { |filename| segment_filenames(segment) << filename }
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
# Returns a hash of checksums to either nil or the on disk path (which is
|
498
|
+
# done by generate_manifest).
|
499
|
+
def checksums
|
500
|
+
unless @checksums
|
501
|
+
generate_manifest
|
502
|
+
end
|
503
|
+
@checksums
|
504
|
+
end
|
505
|
+
|
506
|
+
def manifest_records_by_path
|
507
|
+
@manifest_records_by_path || generate_manifest
|
508
|
+
@manifest_records_by_path
|
509
|
+
end
|
510
|
+
|
511
|
+
def full_name
|
512
|
+
"#{name}-#{version}"
|
513
|
+
end
|
514
|
+
|
515
|
+
def attribute_filenames=(*filenames)
|
516
|
+
@attribute_filenames = filenames.flatten
|
517
|
+
@attribute_filenames_by_short_filename = filenames_by_name(attribute_filenames)
|
518
|
+
attribute_filenames
|
519
|
+
end
|
520
|
+
|
521
|
+
## BACKCOMPAT/DEPRECATED - Remove these and fix breakage before release [DAN - 5/20/2010]##
|
522
|
+
alias :attribute_files :attribute_filenames
|
523
|
+
alias :attribute_files= :attribute_filenames=
|
524
|
+
|
525
|
+
# Return recipe names in the form of cookbook_name::recipe_name
|
526
|
+
def fully_qualified_recipe_names
|
527
|
+
results = Array.new
|
528
|
+
recipe_filenames_by_name.each_key do |rname|
|
529
|
+
results << "#{name}::#{rname}"
|
530
|
+
end
|
531
|
+
results
|
532
|
+
end
|
533
|
+
|
534
|
+
def recipe_filenames=(*filenames)
|
535
|
+
@recipe_filenames = filenames.flatten
|
536
|
+
@recipe_filenames_by_name = filenames_by_name(recipe_filenames)
|
537
|
+
recipe_filenames
|
538
|
+
end
|
539
|
+
|
540
|
+
## BACKCOMPAT/DEPRECATED - Remove these and fix breakage before release [DAN - 5/20/2010]##
|
541
|
+
alias :recipe_files :recipe_filenames
|
542
|
+
alias :recipe_files= :recipe_filenames=
|
543
|
+
|
544
|
+
# called from DSL
|
545
|
+
def load_recipe(recipe_name, run_context)
|
546
|
+
unless recipe_filenames_by_name.has_key?(recipe_name)
|
547
|
+
raise Chef::Exceptions::RecipeNotFound, "could not find recipe #{recipe_name} for cookbook #{name}"
|
548
|
+
end
|
549
|
+
|
550
|
+
Chef::Log.debug("Found recipe #{recipe_name} in cookbook #{name}")
|
551
|
+
recipe = Chef::Recipe.new(name, recipe_name, run_context)
|
552
|
+
recipe_filename = recipe_filenames_by_name[recipe_name]
|
553
|
+
|
554
|
+
unless recipe_filename
|
555
|
+
raise Chef::Exceptions::RecipeNotFound, "could not find #{recipe_name} files for cookbook #{name}"
|
556
|
+
end
|
557
|
+
|
558
|
+
recipe.from_file(recipe_filename)
|
559
|
+
recipe
|
560
|
+
end
|
561
|
+
|
562
|
+
def segment_filenames(segment)
|
563
|
+
unless COOKBOOK_SEGMENTS.include?(segment)
|
564
|
+
raise ArgumentError, "invalid segment #{segment}: must be one of #{COOKBOOK_SEGMENTS.join(', ')}"
|
565
|
+
end
|
566
|
+
|
567
|
+
case segment.to_sym
|
568
|
+
when :resources
|
569
|
+
@resource_filenames
|
570
|
+
when :providers
|
571
|
+
@provider_filenames
|
572
|
+
when :recipes
|
573
|
+
@recipe_filenames
|
574
|
+
when :libraries
|
575
|
+
@library_filenames
|
576
|
+
when :definitions
|
577
|
+
@definition_filenames
|
578
|
+
when :attributes
|
579
|
+
@attribute_filenames
|
580
|
+
when :files
|
581
|
+
@file_filenames
|
582
|
+
when :templates
|
583
|
+
@template_filenames
|
584
|
+
when :root_files
|
585
|
+
@root_filenames
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
589
|
+
# Determine the most specific manifest record for the given
|
590
|
+
# segment/filename, given information in the node. Throws
|
591
|
+
# FileNotFound if there is no such segment and filename in the
|
592
|
+
# manifest.
|
593
|
+
#
|
594
|
+
# A manifest record is a Mash that follows the following form:
|
595
|
+
# {
|
596
|
+
# :name => "example.rb",
|
597
|
+
# :path => "files/default/example.rb",
|
598
|
+
# :specificity => "default",
|
599
|
+
# :checksum => "1234"
|
600
|
+
# }
|
601
|
+
def preferred_manifest_record(node, segment, filename)
|
602
|
+
preferences = preferences_for_path(node, segment, filename)
|
603
|
+
|
604
|
+
# ensure that we generate the manifest, which will also generate
|
605
|
+
# @manifest_records_by_path
|
606
|
+
manifest
|
607
|
+
|
608
|
+
# in order of prefernce, look for the filename in the manifest
|
609
|
+
found_pref = preferences.find {|preferred_filename| @manifest_records_by_path[preferred_filename] }
|
610
|
+
if found_pref
|
611
|
+
@manifest_records_by_path[found_pref]
|
612
|
+
else
|
613
|
+
if segment == :files || segment == :templates
|
614
|
+
error_message = "Cookbook '#{name}' (#{version}) does not contain a file at any of these locations:\n"
|
615
|
+
error_locations = [
|
616
|
+
" #{segment}/#{node[:platform]}-#{node[:platform_version]}/#{filename}",
|
617
|
+
" #{segment}/#{node[:platform]}/#{filename}",
|
618
|
+
" #{segment}/default/#{filename}",
|
619
|
+
]
|
620
|
+
error_message << error_locations.join("\n")
|
621
|
+
existing_files = segment_filenames(segment)
|
622
|
+
# Show the files that the cookbook does have. If the user made a typo,
|
623
|
+
# hopefully they'll see it here.
|
624
|
+
unless existing_files.empty?
|
625
|
+
error_message << "\n\nThis cookbook _does_ contain: ['#{existing_files.join("','")}']"
|
626
|
+
end
|
627
|
+
raise Chef::Exceptions::FileNotFound, error_message
|
628
|
+
else
|
629
|
+
raise Chef::Exceptions::FileNotFound, "cookbook #{name} does not contain file #{segment}/#{filename}"
|
630
|
+
end
|
631
|
+
end
|
632
|
+
end
|
633
|
+
|
634
|
+
def preferred_filename_on_disk_location(node, segment, filename, current_filepath=nil)
|
635
|
+
manifest_record = preferred_manifest_record(node, segment, filename)
|
636
|
+
if current_filepath && (manifest_record['checksum'] == self.class.checksum_cookbook_file(current_filepath))
|
637
|
+
nil
|
638
|
+
else
|
639
|
+
file_vendor.get_filename(manifest_record['path'])
|
640
|
+
end
|
641
|
+
end
|
642
|
+
|
643
|
+
def relative_filenames_in_preferred_directory(node, segment, dirname)
|
644
|
+
preferences = preferences_for_path(node, segment, dirname)
|
645
|
+
filenames_by_pref = Hash.new
|
646
|
+
preferences.each { |pref| filenames_by_pref[pref] = Array.new }
|
647
|
+
|
648
|
+
manifest[segment].each do |manifest_record|
|
649
|
+
manifest_record_path = manifest_record[:path]
|
650
|
+
|
651
|
+
# find the NON SPECIFIC filenames, but prefer them by filespecificity.
|
652
|
+
# For example, if we have a file:
|
653
|
+
# 'files/default/somedir/somefile.conf' we only keep
|
654
|
+
# 'somedir/somefile.conf'. If there is also
|
655
|
+
# 'files/$hostspecific/somedir/otherfiles' that matches the requested
|
656
|
+
# hostname specificity, that directory will win, as it is more specific.
|
657
|
+
#
|
658
|
+
# This is clearly ugly b/c the use case is for remote directory, where
|
659
|
+
# we're just going to make cookbook_files out of these and make the
|
660
|
+
# cookbook find them by filespecificity again. but it's the shortest
|
661
|
+
# path to "success" for now.
|
662
|
+
if manifest_record_path =~ /(#{Regexp.escape(segment.to_s)}\/[^\/]+\/#{Regexp.escape(dirname)})\/.+$/
|
663
|
+
specificity_dirname = $1
|
664
|
+
non_specific_path = manifest_record_path[/#{Regexp.escape(segment.to_s)}\/[^\/]+\/#{Regexp.escape(dirname)}\/(.+)$/, 1]
|
665
|
+
# Record the specificity_dirname only if it's in the list of
|
666
|
+
# valid preferences
|
667
|
+
if filenames_by_pref[specificity_dirname]
|
668
|
+
filenames_by_pref[specificity_dirname] << non_specific_path
|
669
|
+
end
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
best_pref = preferences.find { |pref| !filenames_by_pref[pref].empty? }
|
674
|
+
|
675
|
+
raise Chef::Exceptions::FileNotFound, "cookbook #{name} has no directory #{segment}/default/#{dirname}" unless best_pref
|
676
|
+
|
677
|
+
filenames_by_pref[best_pref]
|
678
|
+
|
679
|
+
end
|
680
|
+
|
681
|
+
# Determine the manifest records from the most specific directory
|
682
|
+
# for the given node. See #preferred_manifest_record for a
|
683
|
+
# description of entries of the returned Array.
|
684
|
+
def preferred_manifest_records_for_directory(node, segment, dirname)
|
685
|
+
preferences = preferences_for_path(node, segment, dirname)
|
686
|
+
records_by_pref = Hash.new
|
687
|
+
preferences.each { |pref| records_by_pref[pref] = Array.new }
|
688
|
+
|
689
|
+
manifest[segment].each do |manifest_record|
|
690
|
+
manifest_record_path = manifest_record[:path]
|
691
|
+
|
692
|
+
# extract the preference part from the path.
|
693
|
+
if manifest_record_path =~ /(#{Regexp.escape(segment.to_s)}\/[^\/]+\/#{Regexp.escape(dirname)})\/.+$/
|
694
|
+
# Note the specificy_dirname includes the segment and
|
695
|
+
# dirname argument as above, which is what
|
696
|
+
# preferences_for_path returns. It could be
|
697
|
+
# "files/ubuntu-9.10/dirname", for example.
|
698
|
+
specificity_dirname = $1
|
699
|
+
|
700
|
+
# Record the specificity_dirname only if it's in the list of
|
701
|
+
# valid preferences
|
702
|
+
if records_by_pref[specificity_dirname]
|
703
|
+
records_by_pref[specificity_dirname] << manifest_record
|
704
|
+
end
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
best_pref = preferences.find { |pref| !records_by_pref[pref].empty? }
|
709
|
+
|
710
|
+
raise Chef::Exceptions::FileNotFound, "cookbook #{name} (#{version}) has no directory #{segment}/default/#{dirname}" unless best_pref
|
711
|
+
|
712
|
+
records_by_pref[best_pref]
|
713
|
+
end
|
714
|
+
|
715
|
+
|
716
|
+
# Given a node, segment and path (filename or directory name),
|
717
|
+
# return the priority-ordered list of preference locations to
|
718
|
+
# look.
|
719
|
+
def preferences_for_path(node, segment, path)
|
720
|
+
# only files and templates can be platform-specific
|
721
|
+
if segment.to_sym == :files || segment.to_sym == :templates
|
722
|
+
begin
|
723
|
+
platform, version = Chef::Platform.find_platform_and_version(node)
|
724
|
+
rescue ArgumentError => e
|
725
|
+
# Skip platform/version if they were not found by find_platform_and_version
|
726
|
+
if e.message =~ /Cannot find a (?:platform|version)/
|
727
|
+
platform = "/unknown_platform/"
|
728
|
+
version = "/unknown_platform_version/"
|
729
|
+
else
|
730
|
+
raise
|
731
|
+
end
|
732
|
+
end
|
733
|
+
|
734
|
+
fqdn = node[:fqdn]
|
735
|
+
|
736
|
+
# Break version into components, eg: "5.7.1" => [ "5.7.1", "5.7", "5" ]
|
737
|
+
search_versions = []
|
738
|
+
parts = version.to_s.split('.')
|
739
|
+
|
740
|
+
parts.size.times do
|
741
|
+
search_versions << parts.join('.')
|
742
|
+
parts.pop
|
743
|
+
end
|
744
|
+
|
745
|
+
# Most specific to least specific places to find the path
|
746
|
+
search_path = [ File.join(segment.to_s, "host-#{fqdn}", path) ]
|
747
|
+
search_versions.each do |v|
|
748
|
+
search_path << File.join(segment.to_s, "#{platform}-#{v}", path)
|
749
|
+
end
|
750
|
+
search_path << File.join(segment.to_s, platform.to_s, path)
|
751
|
+
search_path << File.join(segment.to_s, "default", path)
|
752
|
+
|
753
|
+
search_path
|
754
|
+
else
|
755
|
+
[File.join(segment, path)]
|
756
|
+
end
|
757
|
+
end
|
758
|
+
private :preferences_for_path
|
759
|
+
|
760
|
+
def to_hash
|
761
|
+
result = manifest.dup
|
762
|
+
result['frozen?'] = frozen_version?
|
763
|
+
result['chef_type'] = 'cookbook_version'
|
764
|
+
result["_rev"] = couchdb_rev if couchdb_rev
|
765
|
+
result.to_hash
|
766
|
+
end
|
767
|
+
|
768
|
+
def to_json(*a)
|
769
|
+
result = self.to_hash
|
770
|
+
result['json_class'] = self.class.name
|
771
|
+
result.to_json(*a)
|
772
|
+
end
|
773
|
+
|
774
|
+
def self.json_create(o)
|
775
|
+
cookbook_version = new(o["cookbook_name"])
|
776
|
+
if o.has_key?('_rev')
|
777
|
+
cookbook_version.couchdb_rev = o["_rev"] if o.has_key?("_rev")
|
778
|
+
o.delete("_rev")
|
779
|
+
end
|
780
|
+
if o.has_key?("_id")
|
781
|
+
cookbook_version.couchdb_id = o["_id"] if o.has_key?("_id")
|
782
|
+
cookbook_version.index_id = cookbook_version.couchdb_id
|
783
|
+
o.delete("_id")
|
784
|
+
end
|
785
|
+
# We want the Chef::Cookbook::Metadata object to always be inflated
|
786
|
+
cookbook_version.metadata = Chef::Cookbook::Metadata.from_hash(o["metadata"])
|
787
|
+
cookbook_version.manifest = o
|
788
|
+
|
789
|
+
# We don't need the following step when we decide to stop supporting deprecated operators in the metadata (e.g. <<, >>)
|
790
|
+
cookbook_version.manifest["metadata"] = Chef::JSONCompat.from_json(cookbook_version.metadata.to_json)
|
791
|
+
|
792
|
+
cookbook_version.freeze_version if o["frozen?"]
|
793
|
+
cookbook_version
|
794
|
+
end
|
795
|
+
|
796
|
+
def generate_manifest_with_urls(&url_generator)
|
797
|
+
rendered_manifest = manifest.dup
|
798
|
+
COOKBOOK_SEGMENTS.each do |segment|
|
799
|
+
if rendered_manifest.has_key?(segment)
|
800
|
+
rendered_manifest[segment].each do |manifest_record|
|
801
|
+
url_options = { :cookbook_name => name.to_s, :cookbook_version => version, :checksum => manifest_record["checksum"] }
|
802
|
+
manifest_record["url"] = url_generator.call(url_options)
|
803
|
+
end
|
804
|
+
end
|
805
|
+
end
|
806
|
+
rendered_manifest
|
807
|
+
end
|
808
|
+
|
809
|
+
def metadata_json_file
|
810
|
+
File.join(root_dir, "metadata.json")
|
811
|
+
end
|
812
|
+
|
813
|
+
def metadata_rb_file
|
814
|
+
File.join(root_dir, "metadata.rb")
|
815
|
+
end
|
816
|
+
|
817
|
+
def reload_metadata!
|
818
|
+
if File.exists?(metadata_json_file)
|
819
|
+
metadata.from_json(IO.read(metadata_json_file))
|
820
|
+
end
|
821
|
+
end
|
822
|
+
|
823
|
+
##
|
824
|
+
# REST API
|
825
|
+
##
|
826
|
+
def self.chef_server_rest
|
827
|
+
Chef::REST.new(Chef::Config[:chef_server_url])
|
828
|
+
end
|
829
|
+
|
830
|
+
def chef_server_rest
|
831
|
+
self.class.chef_server_rest
|
832
|
+
end
|
833
|
+
|
834
|
+
# Return the URL to save (PUT) this object to the server via the
|
835
|
+
# REST api. If there is an existing document on the server and it
|
836
|
+
# is marked frozen, a PUT will result in a 409 Conflict.
|
837
|
+
def save_url
|
838
|
+
"cookbooks/#{name}/#{version}"
|
839
|
+
end
|
840
|
+
|
841
|
+
# Adds the `force=true` parameter to the upload URL. This allows
|
842
|
+
# the user to overwrite a frozen cookbook (a PUT against the
|
843
|
+
# normal #save_url raises a 409 Conflict in this case).
|
844
|
+
def force_save_url
|
845
|
+
"cookbooks/#{name}/#{version}?force=true"
|
846
|
+
end
|
847
|
+
|
848
|
+
def destroy
|
849
|
+
chef_server_rest.delete_rest("cookbooks/#{name}/#{version}")
|
850
|
+
self
|
851
|
+
end
|
852
|
+
|
853
|
+
def self.load(name, version="_latest")
|
854
|
+
version = "_latest" if version == "latest"
|
855
|
+
chef_server_rest.get_rest("cookbooks/#{name}/#{version}")
|
856
|
+
end
|
857
|
+
|
858
|
+
# The API returns only a single version of each cookbook in the result from the cookbooks method
|
859
|
+
def self.list
|
860
|
+
chef_server_rest.get_rest('cookbooks')
|
861
|
+
end
|
862
|
+
|
863
|
+
def self.list_all_versions
|
864
|
+
chef_server_rest.get_rest('cookbooks?num_versions=all')
|
865
|
+
end
|
866
|
+
|
867
|
+
##
|
868
|
+
# Given a +cookbook_name+, get a list of all versions that exist on the
|
869
|
+
# server.
|
870
|
+
# ===Returns
|
871
|
+
# [String]:: Array of cookbook versions, which are strings like 'x.y.z'
|
872
|
+
# nil:: if the cookbook doesn't exist. an error will also be logged.
|
873
|
+
def self.available_versions(cookbook_name)
|
874
|
+
chef_server_rest.get_rest("cookbooks/#{cookbook_name}")[cookbook_name]["versions"].map do |cb|
|
875
|
+
cb["version"]
|
876
|
+
end
|
877
|
+
rescue Net::HTTPServerException => e
|
878
|
+
if e.to_s =~ /^404/
|
879
|
+
Chef::Log.error("Cannot find a cookbook named #{cookbook_name}")
|
880
|
+
nil
|
881
|
+
else
|
882
|
+
raise
|
883
|
+
end
|
884
|
+
end
|
885
|
+
|
886
|
+
# Get the newest version of all cookbooks
|
887
|
+
def self.latest_cookbooks
|
888
|
+
chef_server_rest.get_rest('cookbooks/_latest')
|
889
|
+
end
|
890
|
+
|
891
|
+
##
|
892
|
+
# Couchdb
|
893
|
+
##
|
894
|
+
|
895
|
+
def self.cdb_by_name(cookbook_name, couchdb=nil)
|
896
|
+
cdb = (couchdb || Chef::CouchDB.new)
|
897
|
+
options = { :startkey => cookbook_name, :endkey => cookbook_name }
|
898
|
+
rs = cdb.get_view("cookbooks", "all_with_version", options)
|
899
|
+
rs["rows"].inject({}) { |memo, row| memo.has_key?(row["key"]) ? memo[row["key"]] << row["value"] : memo[row["key"]] = [ row["value"] ]; memo }
|
900
|
+
end
|
901
|
+
|
902
|
+
def self.create_design_document(couchdb=nil)
|
903
|
+
(couchdb || Chef::CouchDB.new).create_design_document("cookbooks", DESIGN_DOCUMENT)
|
904
|
+
end
|
905
|
+
|
906
|
+
def self.cdb_list_latest(inflate=false, couchdb=nil)
|
907
|
+
couchdb ||= Chef::CouchDB.new
|
908
|
+
if inflate
|
909
|
+
doc_ids = cdb_list_latest_ids.map {|i|i["id"]}
|
910
|
+
couchdb.bulk_get(doc_ids)
|
911
|
+
else
|
912
|
+
results = couchdb.get_view("cookbooks", "all_latest_version", :group=>true)["rows"]
|
913
|
+
results.inject({}) { |mapped, row| mapped[row["key"]] = row["value"]; mapped}
|
914
|
+
end
|
915
|
+
end
|
916
|
+
|
917
|
+
def self.cdb_list_latest_ids(inflate=false, couchdb=nil)
|
918
|
+
couchdb ||= Chef::CouchDB.new
|
919
|
+
results = couchdb.get_view("cookbooks", "all_latest_version_by_id", :group=>true)["rows"]
|
920
|
+
results.map { |name_and_id| name_and_id["value"]}
|
921
|
+
end
|
922
|
+
|
923
|
+
def self.cdb_list(inflate=false, couchdb=nil)
|
924
|
+
couchdb ||= Chef::CouchDB.new
|
925
|
+
if inflate
|
926
|
+
couchdb.list("cookbooks", true)["rows"].collect{|r| r["value"]}
|
927
|
+
else
|
928
|
+
# If you modify this, please make sure the desc sorted order on the versions doesn't get broken.
|
929
|
+
couchdb.get_view("cookbooks", "all_with_version")["rows"].inject({}) { |mapped, row| mapped[row["key"]]||=Array.new; mapped[row["key"]].push(Chef::Version.new(row["value"])); mapped[row["key"]].sort!.reverse!; mapped}
|
930
|
+
end
|
931
|
+
end
|
932
|
+
|
933
|
+
def self.cdb_load(name, version='latest', couchdb=nil)
|
934
|
+
cdb = couchdb || Chef::CouchDB.new
|
935
|
+
if version == "latest" || version == "_latest"
|
936
|
+
rs = cdb.get_view("cookbooks", "all_latest_version", :key => name, :descending => true, :group => true, :reduce => true)["rows"].first
|
937
|
+
cdb.load("cookbook_version", "#{rs["key"]}-#{rs["value"]}")
|
938
|
+
else
|
939
|
+
cdb.load("cookbook_version", "#{name}-#{version}")
|
940
|
+
end
|
941
|
+
end
|
942
|
+
|
943
|
+
def cdb_destroy
|
944
|
+
(couchdb || Chef::CouchDB.new).delete("cookbook_version", full_name, couchdb_rev)
|
945
|
+
end
|
946
|
+
|
947
|
+
# Runs on Chef Server (API); deletes the cookbook from couchdb and also destroys associated
|
948
|
+
# checksum documents
|
949
|
+
def purge
|
950
|
+
checksums.keys.each do |checksum|
|
951
|
+
begin
|
952
|
+
Chef::Checksum.cdb_load(checksum, couchdb).purge
|
953
|
+
rescue Chef::Exceptions::CouchDBNotFound
|
954
|
+
end
|
955
|
+
end
|
956
|
+
cdb_destroy
|
957
|
+
end
|
958
|
+
|
959
|
+
def cdb_save
|
960
|
+
@couchdb_rev = couchdb.store("cookbook_version", full_name, self)["rev"]
|
961
|
+
end
|
962
|
+
|
963
|
+
def couchdb_id=(value)
|
964
|
+
@couchdb_id = value
|
965
|
+
@index_id = value
|
966
|
+
end
|
967
|
+
|
968
|
+
def <=>(o)
|
969
|
+
raise Chef::Exceptions::CookbookVersionNameMismatch if self.name != o.name
|
970
|
+
# FIXME: can we change the interface to the Metadata class such
|
971
|
+
# that metadata.version returns a Chef::Version instance instead
|
972
|
+
# of a string?
|
973
|
+
Chef::Version.new(self.version) <=> Chef::Version.new(o.version)
|
974
|
+
end
|
975
|
+
|
976
|
+
private
|
977
|
+
|
978
|
+
# For each filename, produce a mapping of base filename (i.e. recipe name
|
979
|
+
# or attribute file) to on disk location
|
980
|
+
def filenames_by_name(filenames)
|
981
|
+
filenames.select{|filename| filename =~ /\.rb$/}.inject({}){|memo, filename| memo[File.basename(filename, '.rb')] = filename ; memo }
|
982
|
+
end
|
983
|
+
|
984
|
+
# See #manifest for a description of the manifest return value.
|
985
|
+
# See #preferred_manifest_record for a description an individual manifest record.
|
986
|
+
def generate_manifest
|
987
|
+
manifest = Mash.new({
|
988
|
+
:recipes => Array.new,
|
989
|
+
:definitions => Array.new,
|
990
|
+
:libraries => Array.new,
|
991
|
+
:attributes => Array.new,
|
992
|
+
:files => Array.new,
|
993
|
+
:templates => Array.new,
|
994
|
+
:resources => Array.new,
|
995
|
+
:providers => Array.new,
|
996
|
+
:root_files => Array.new
|
997
|
+
})
|
998
|
+
checksums_to_on_disk_paths = {}
|
999
|
+
|
1000
|
+
COOKBOOK_SEGMENTS.each do |segment|
|
1001
|
+
segment_filenames(segment).each do |segment_file|
|
1002
|
+
next if File.directory?(segment_file)
|
1003
|
+
|
1004
|
+
file_name = nil
|
1005
|
+
path = nil
|
1006
|
+
specificity = "default"
|
1007
|
+
|
1008
|
+
if segment == :root_files
|
1009
|
+
matcher = segment_file.match(".+/#{Regexp.escape(name.to_s)}/(.+)")
|
1010
|
+
file_name = matcher[1]
|
1011
|
+
path = file_name
|
1012
|
+
elsif segment == :templates || segment == :files
|
1013
|
+
matcher = segment_file.match("/#{Regexp.escape(name.to_s)}/(#{Regexp.escape(segment.to_s)}/(.+?)/(.+))")
|
1014
|
+
unless matcher
|
1015
|
+
Chef::Log.debug("Skipping file #{segment_file}, as it isn't in any of the proper directories (platform-version, platform or default)")
|
1016
|
+
Chef::Log.debug("You probably need to move #{segment_file} into the 'default' sub-directory")
|
1017
|
+
next
|
1018
|
+
end
|
1019
|
+
path = matcher[1]
|
1020
|
+
specificity = matcher[2]
|
1021
|
+
file_name = matcher[3]
|
1022
|
+
else
|
1023
|
+
matcher = segment_file.match("/#{Regexp.escape(name.to_s)}/(#{Regexp.escape(segment.to_s)}/(.+))")
|
1024
|
+
path = matcher[1]
|
1025
|
+
file_name = matcher[2]
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
csum = self.class.checksum_cookbook_file(segment_file)
|
1029
|
+
checksums_to_on_disk_paths[csum] = segment_file
|
1030
|
+
rs = Mash.new({
|
1031
|
+
:name => file_name,
|
1032
|
+
:path => path,
|
1033
|
+
:checksum => csum
|
1034
|
+
})
|
1035
|
+
rs[:specificity] = specificity
|
1036
|
+
|
1037
|
+
manifest[segment] << rs
|
1038
|
+
end
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
manifest[:cookbook_name] = name.to_s
|
1042
|
+
manifest[:metadata] = metadata
|
1043
|
+
manifest[:version] = metadata.version
|
1044
|
+
manifest[:name] = full_name
|
1045
|
+
|
1046
|
+
@checksums = checksums_to_on_disk_paths
|
1047
|
+
@manifest = manifest
|
1048
|
+
@manifest_records_by_path = extract_manifest_records_by_path(manifest)
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
def file_vendor
|
1052
|
+
unless @file_vendor
|
1053
|
+
@file_vendor = Chef::Cookbook::FileVendor.create_from_manifest(manifest)
|
1054
|
+
end
|
1055
|
+
@file_vendor
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
def extract_checksums_from_manifest(manifest)
|
1059
|
+
checksums = {}
|
1060
|
+
COOKBOOK_SEGMENTS.each do |segment|
|
1061
|
+
next unless manifest.has_key?(segment)
|
1062
|
+
manifest[segment].each do |manifest_record|
|
1063
|
+
checksums[manifest_record[:checksum]] = nil
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
checksums
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
def extract_manifest_records_by_path(manifest)
|
1070
|
+
manifest_records_by_path = {}
|
1071
|
+
COOKBOOK_SEGMENTS.each do |segment|
|
1072
|
+
next unless manifest.has_key?(segment)
|
1073
|
+
manifest[segment].each do |manifest_record|
|
1074
|
+
manifest_records_by_path[manifest_record[:path]] = manifest_record
|
1075
|
+
end
|
1076
|
+
end
|
1077
|
+
manifest_records_by_path
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
end
|
1081
|
+
end
|