chef 11.4.4 → 11.6.0.hotfix.1
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.
- data/README.md +1 -1
- data/Rakefile +18 -1
- data/bin/chef-service-manager +37 -0
- data/distro/common/html/chef-client.8.html +4 -4
- data/distro/common/html/chef-expander.8.html +4 -4
- data/distro/common/html/chef-expanderctl.8.html +4 -4
- data/distro/common/html/chef-server-webui.8.html +4 -4
- data/distro/common/html/chef-server.8.html +4 -4
- data/distro/common/html/chef-shell.1.html +4 -4
- data/distro/common/html/chef-solo.8.html +12 -18
- data/distro/common/html/chef-solr.8.html +4 -4
- data/distro/common/html/knife-bootstrap.1.html +4 -4
- data/distro/common/html/knife-client.1.html +4 -4
- data/distro/common/html/knife-configure.1.html +4 -4
- data/distro/common/html/knife-cookbook-site.1.html +4 -4
- data/distro/common/html/knife-cookbook.1.html +7 -10
- data/distro/common/html/knife-data-bag.1.html +7 -10
- data/distro/common/html/knife-environment.1.html +6 -8
- data/distro/common/html/knife-exec.1.html +4 -4
- data/distro/common/html/knife-index.1.html +4 -4
- data/distro/common/html/knife-node.1.html +4 -4
- data/distro/common/html/knife-role.1.html +4 -4
- data/distro/common/html/knife-search.1.html +4 -4
- data/distro/common/html/knife-ssh.1.html +4 -4
- data/distro/common/html/knife-status.1.html +4 -4
- data/distro/common/html/knife-tag.1.html +4 -4
- data/distro/common/html/knife.1.html +4 -4
- data/distro/common/man/man1/chef-shell.1 +1 -1
- data/distro/common/man/man1/knife-bootstrap.1 +1 -1
- data/distro/common/man/man1/knife-client.1 +1 -1
- data/distro/common/man/man1/knife-configure.1 +1 -1
- data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
- data/distro/common/man/man1/knife-cookbook.1 +2 -15
- data/distro/common/man/man1/knife-data-bag.1 +2 -15
- data/distro/common/man/man1/knife-environment.1 +2 -12
- data/distro/common/man/man1/knife-exec.1 +1 -1
- data/distro/common/man/man1/knife-index.1 +1 -1
- data/distro/common/man/man1/knife-node.1 +1 -1
- data/distro/common/man/man1/knife-role.1 +1 -1
- data/distro/common/man/man1/knife-search.1 +1 -1
- data/distro/common/man/man1/knife-ssh.1 +1 -1
- data/distro/common/man/man1/knife-status.1 +1 -1
- data/distro/common/man/man1/knife-tag.1 +1 -1
- data/distro/common/man/man1/knife.1 +1 -1
- data/distro/common/man/man8/chef-client.8 +1 -1
- data/distro/common/man/man8/chef-expander.8 +1 -1
- data/distro/common/man/man8/chef-expanderctl.8 +1 -1
- data/distro/common/man/man8/chef-server-webui.8 +1 -1
- data/distro/common/man/man8/chef-server.8 +1 -1
- data/distro/common/man/man8/chef-solo.8 +4 -36
- data/distro/common/man/man8/chef-solr.8 +1 -1
- data/distro/debian/etc/init.d/chef-client +4 -2
- data/distro/windows/service_manager.rb +2 -146
- data/lib/chef.rb +1 -1
- data/lib/chef/application.rb +5 -12
- data/lib/chef/application/apply.rb +2 -0
- data/lib/chef/application/client.rb +12 -12
- data/lib/chef/application/knife.rb +2 -2
- data/lib/chef/application/solo.rb +4 -5
- data/lib/chef/application/windows_service.rb +113 -56
- data/lib/chef/application/windows_service_manager.rb +179 -0
- data/lib/chef/chef_fs.rb +2 -4
- data/lib/chef/chef_fs/chef_fs_data_store.rb +371 -0
- data/lib/chef/chef_fs/command_line.rb +145 -93
- data/lib/chef/chef_fs/config.rb +205 -0
- data/lib/chef/chef_fs/data_handler/acl_data_handler.rb +26 -0
- data/lib/chef/chef_fs/data_handler/client_data_handler.rb +38 -0
- data/lib/chef/chef_fs/data_handler/container_data_handler.rb +29 -0
- data/lib/chef/chef_fs/data_handler/cookbook_data_handler.rb +38 -0
- data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +56 -0
- data/lib/chef/chef_fs/data_handler/data_handler_base.rb +128 -0
- data/lib/chef/chef_fs/data_handler/environment_data_handler.rb +40 -0
- data/lib/chef/chef_fs/data_handler/group_data_handler.rb +51 -0
- data/lib/chef/chef_fs/data_handler/node_data_handler.rb +36 -0
- data/lib/chef/chef_fs/data_handler/role_data_handler.rb +40 -0
- data/lib/chef/chef_fs/data_handler/user_data_handler.rb +27 -0
- data/lib/chef/chef_fs/file_system.rb +195 -127
- data/lib/chef/chef_fs/file_system/acl_dir.rb +64 -0
- data/lib/chef/chef_fs/file_system/acl_entry.rb +58 -0
- data/lib/chef/chef_fs/file_system/acls_dir.rb +68 -0
- data/lib/chef/chef_fs/file_system/already_exists_error.rb +31 -0
- data/lib/chef/chef_fs/file_system/base_fs_object.rb +98 -39
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +85 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb +71 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +55 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_data_bags_dir.rb +36 -0
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +14 -63
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +93 -3
- data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +35 -9
- data/lib/chef/chef_fs/file_system/cookbook_dir.rb +67 -32
- data/lib/chef/chef_fs/file_system/cookbook_file.rb +13 -6
- data/lib/chef/chef_fs/file_system/cookbook_frozen_error.rb +31 -0
- data/lib/chef/chef_fs/file_system/cookbooks_acl_dir.rb +41 -0
- data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +102 -21
- data/lib/chef/chef_fs/file_system/data_bag_dir.rb +12 -21
- data/lib/chef/chef_fs/file_system/data_bags_dir.rb +14 -8
- data/lib/chef/chef_fs/file_system/default_environment_cannot_be_modified_error.rb +36 -0
- data/lib/chef/chef_fs/file_system/environments_dir.rb +60 -0
- data/lib/chef/chef_fs/file_system/file_system_entry.rb +8 -8
- data/lib/chef/chef_fs/file_system/file_system_error.rb +3 -1
- data/lib/chef/chef_fs/file_system/memory_dir.rb +52 -0
- data/lib/chef/chef_fs/file_system/memory_file.rb +17 -0
- data/lib/chef/chef_fs/file_system/memory_root.rb +21 -0
- data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +48 -0
- data/lib/chef/chef_fs/file_system/must_delete_recursively_error.rb +2 -2
- data/lib/chef/chef_fs/file_system/nodes_dir.rb +17 -9
- data/lib/chef/chef_fs/file_system/nonexistent_fs_object.rb +0 -4
- data/lib/chef/chef_fs/file_system/not_found_error.rb +2 -2
- data/lib/chef/chef_fs/file_system/operation_failed_error.rb +34 -0
- data/lib/chef/chef_fs/file_system/operation_not_allowed_error.rb +48 -0
- data/lib/chef/chef_fs/file_system/rest_list_dir.rb +42 -13
- data/lib/chef/chef_fs/file_system/rest_list_entry.rb +81 -27
- data/lib/chef/chef_fs/knife.rb +68 -29
- data/lib/chef/chef_fs/parallelizer.rb +129 -0
- data/lib/chef/chef_fs/path_utils.rb +29 -3
- data/lib/chef/chef_fs/raw_request.rb +79 -0
- data/lib/chef/client.rb +46 -20
- data/lib/chef/config.rb +59 -61
- data/lib/chef/cookbook/chefignore.rb +2 -1
- data/lib/chef/cookbook/synchronizer.rb +8 -6
- data/lib/chef/cookbook/syntax_check.rb +17 -2
- data/lib/chef/cookbook_uploader.rb +10 -1
- data/lib/chef/cookbook_version.rb +0 -109
- data/lib/chef/data_bag.rb +15 -6
- data/lib/chef/deprecation/mixin/template.rb +49 -0
- data/lib/chef/deprecation/provider/cookbook_file.rb +55 -0
- data/lib/chef/deprecation/provider/file.rb +197 -0
- data/lib/chef/deprecation/provider/remote_file.rb +86 -0
- data/lib/chef/deprecation/provider/template.rb +63 -0
- data/lib/chef/deprecation/warnings.rb +38 -0
- data/lib/chef/encrypted_data_bag_item.rb +153 -61
- data/lib/chef/environment.rb +34 -3
- data/lib/chef/event_dispatch/base.rb +3 -0
- data/lib/chef/exceptions.rb +27 -2
- data/lib/chef/file_access_control/unix.rb +64 -7
- data/lib/chef/file_access_control/windows.rb +22 -11
- data/lib/chef/file_content_management/content_base.rb +56 -0
- data/lib/chef/file_content_management/deploy.rb +38 -0
- data/lib/chef/file_content_management/deploy/cp.rb +48 -0
- data/lib/chef/file_content_management/deploy/mv_unix.rb +77 -0
- data/lib/chef/file_content_management/deploy/mv_windows.rb +95 -0
- data/lib/chef/file_content_management/tempfile.rb +61 -0
- data/lib/chef/formatters/doc.rb +1 -1
- data/lib/chef/formatters/error_descriptor.rb +5 -4
- data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +23 -3
- data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +4 -0
- data/lib/chef/json_compat.rb +3 -0
- data/lib/chef/knife.rb +12 -3
- data/lib/chef/knife/bootstrap.rb +46 -2
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +3 -3
- data/lib/chef/knife/bootstrap/centos5-gems.erb +3 -3
- data/lib/chef/knife/bootstrap/chef-full.erb +4 -4
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +3 -3
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +3 -3
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +3 -3
- data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +3 -3
- data/lib/chef/knife/client_show.rb +2 -5
- data/lib/chef/knife/configure.rb +3 -3
- data/lib/chef/knife/cookbook_create.rb +6 -5
- data/lib/chef/knife/cookbook_download.rb +13 -5
- data/lib/chef/knife/cookbook_site_share.rb +1 -0
- data/lib/chef/knife/cookbook_test.rb +1 -0
- data/lib/chef/knife/cookbook_upload.rb +4 -9
- data/lib/chef/knife/core/bootstrap_context.rb +10 -4
- data/lib/chef/knife/core/generic_presenter.rb +16 -0
- data/lib/chef/knife/core/node_editor.rb +1 -1
- data/lib/chef/knife/core/subcommand_loader.rb +43 -12
- data/lib/chef/knife/core/ui.rb +19 -4
- data/lib/chef/knife/delete.rb +76 -9
- data/lib/chef/knife/deps.rb +139 -0
- data/lib/chef/knife/diff.rb +22 -5
- data/lib/chef/knife/download.rb +16 -3
- data/lib/chef/knife/edit.rb +76 -0
- data/lib/chef/knife/environment_show.rb +2 -7
- data/lib/chef/knife/list.rb +91 -47
- data/lib/chef/knife/node_run_list_set.rb +66 -0
- data/lib/chef/knife/node_show.rb +1 -7
- data/lib/chef/knife/raw.rb +20 -64
- data/lib/chef/knife/role_show.rb +2 -4
- data/lib/chef/knife/search.rb +5 -6
- data/lib/chef/knife/show.rb +34 -11
- data/lib/chef/knife/ssh.rb +8 -0
- data/lib/chef/knife/upload.rb +23 -4
- data/lib/chef/knife/user_show.rb +2 -5
- data/lib/chef/knife/xargs.rb +265 -0
- data/lib/chef/log.rb +2 -2
- data/lib/chef/mixin/file_class.rb +0 -9
- data/lib/chef/mixin/language_include_recipe.rb +1 -1
- data/lib/chef/mixin/params_validate.rb +19 -9
- data/lib/chef/mixin/template.rb +126 -36
- data/lib/chef/mixin/windows_architecture_helper.rb +91 -0
- data/lib/chef/monkey_patches/file.rb +26 -0
- data/lib/chef/monkey_patches/net-ssh-multi.rb +140 -0
- data/lib/chef/monkey_patches/securerandom.rb +44 -0
- data/lib/chef/monologger.rb +93 -0
- data/lib/chef/node.rb +4 -0
- data/lib/chef/platform.rb +4 -490
- data/lib/chef/platform/provider_mapping.rb +529 -0
- data/lib/chef/{monkey_patches/dir.rb → platform/query_helpers.rb} +25 -19
- data/lib/chef/provider.rb +12 -9
- data/lib/chef/provider/batch.rb +35 -0
- data/lib/chef/provider/cookbook_file.rb +9 -78
- data/lib/chef/provider/cookbook_file/content.rb +49 -0
- data/lib/chef/provider/deploy.rb +24 -20
- data/lib/chef/provider/deploy/revision.rb +27 -0
- data/lib/chef/provider/directory.rb +19 -22
- data/lib/chef/provider/execute.rb +22 -5
- data/lib/chef/provider/file.rb +299 -217
- data/lib/chef/provider/file/content.rb +39 -0
- data/lib/chef/provider/git.rb +76 -43
- data/lib/chef/provider/group/usermod.rb +2 -2
- data/lib/chef/provider/ifconfig.rb +25 -35
- data/lib/chef/provider/ifconfig/debian.rb +71 -0
- data/lib/chef/provider/ifconfig/redhat.rb +47 -0
- data/lib/chef/provider/link.rb +10 -3
- data/lib/chef/provider/mount.rb +1 -1
- data/lib/chef/provider/mount/mount.rb +8 -3
- data/lib/chef/provider/mount/windows.rb +4 -1
- data/lib/chef/provider/package/portage.rb +9 -4
- data/lib/chef/provider/package/rubygems.rb +45 -10
- data/lib/chef/provider/package/smartos.rb +47 -36
- data/lib/chef/provider/package/yum.rb +19 -12
- data/lib/chef/provider/package/zypper.rb +45 -55
- data/lib/chef/provider/powershell_script.rb +77 -0
- data/lib/chef/provider/remote_directory.rb +5 -6
- data/lib/chef/provider/remote_file.rb +12 -108
- data/lib/chef/provider/remote_file/cache_control_data.rb +165 -0
- data/lib/chef/provider/remote_file/content.rb +75 -0
- data/lib/chef/provider/remote_file/fetcher.rb +43 -0
- data/lib/chef/provider/remote_file/ftp.rb +183 -0
- data/lib/chef/provider/remote_file/http.rb +124 -0
- data/lib/chef/provider/remote_file/local_file.rb +47 -0
- data/lib/chef/provider/route.rb +6 -2
- data/lib/chef/provider/script.rb +14 -2
- data/lib/chef/provider/service/macosx.rb +16 -10
- data/lib/chef/provider/service/solaris.rb +6 -5
- data/lib/chef/provider/template.rb +16 -78
- data/lib/chef/provider/template/content.rb +61 -0
- data/lib/chef/provider/user/solaris.rb +90 -0
- data/lib/chef/provider/user/useradd.rb +76 -63
- data/lib/chef/provider/windows_script.rb +73 -0
- data/lib/chef/providers.rb +16 -0
- data/lib/chef/resource.rb +23 -2
- data/lib/chef/resource/batch.rb +31 -0
- data/lib/chef/resource/conditional.rb +4 -0
- data/lib/chef/resource/conditional_action_not_nothing.rb +48 -0
- data/lib/chef/resource/file.rb +31 -3
- data/lib/chef/resource/link.rb +17 -0
- data/lib/chef/resource/lwrp_base.rb +1 -1
- data/lib/chef/resource/mount.rb +29 -2
- data/lib/chef/resource/powershell_script.rb +31 -0
- data/lib/chef/resource/remote_file.rb +47 -1
- data/lib/chef/resource/route.rb +1 -1
- data/lib/chef/resource/template.rb +145 -0
- data/lib/chef/resource/windows_script.rb +62 -0
- data/lib/chef/resource_collection.rb +45 -11
- data/lib/chef/resource_reporter.rb +81 -52
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/rest.rb +13 -4
- data/lib/chef/rest/rest_request.rb +5 -1
- data/lib/chef/run_context/cookbook_compiler.rb +3 -3
- data/lib/chef/run_list/run_list_expansion.rb +1 -1
- data/lib/chef/run_lock.rb +7 -1
- data/lib/chef/runner.rb +0 -1
- data/lib/chef/scan_access_control.rb +6 -1
- data/lib/chef/search/query.rb +2 -2
- data/lib/chef/shell/shell_session.rb +2 -2
- data/lib/chef/util/backup.rb +84 -0
- data/lib/chef/util/diff.rb +145 -0
- data/lib/chef/util/file_edit.rb +1 -1
- data/lib/chef/util/selinux.rb +100 -0
- data/lib/chef/util/windows/net_user.rb +14 -1
- data/lib/chef/util/windows/volume.rb +2 -2
- data/lib/chef/version.rb +1 -1
- data/lib/chef/version/platform.rb +42 -0
- data/lib/chef/version_class.rb +1 -1
- data/lib/chef/version_constraint.rb +6 -5
- data/lib/chef/version_constraint/platform.rb +26 -0
- data/lib/chef/win32/api/file.rb +8 -2
- data/lib/chef/win32/version.rb +25 -8
- data/spec/data/apt/chef-integration-test-1.0/debian/changelog +5 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/compat +1 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/control +13 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/copyright +34 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/files +1 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/rules +13 -0
- data/spec/data/apt/chef-integration-test-1.0/debian/source/format +1 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/changelog +11 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/compat +1 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/control +13 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/copyright +34 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/files +1 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/rules +13 -0
- data/spec/data/apt/chef-integration-test-1.1/debian/source/format +1 -0
- data/spec/data/apt/chef-integration-test_1.0-1_amd64.changes +22 -0
- data/spec/data/apt/chef-integration-test_1.0-1_amd64.deb +0 -0
- data/spec/data/apt/chef-integration-test_1.0.orig.tar.gz +0 -0
- data/spec/data/apt/chef-integration-test_1.1-1_amd64.changes +22 -0
- data/spec/data/apt/chef-integration-test_1.1-1_amd64.deb +0 -0
- data/spec/data/apt/chef-integration-test_1.1.orig.tar.gz +0 -0
- data/spec/data/apt/var/www/apt/conf/distributions +7 -0
- data/spec/data/apt/var/www/apt/conf/incoming +4 -0
- data/spec/data/apt/var/www/apt/conf/pulls +3 -0
- data/spec/data/apt/var/www/apt/db/checksums.db +0 -0
- data/spec/data/apt/var/www/apt/db/contents.cache.db +0 -0
- data/spec/data/apt/var/www/apt/db/packages.db +0 -0
- data/spec/data/apt/var/www/apt/db/references.db +0 -0
- data/spec/data/apt/var/www/apt/db/release.caches.db +0 -0
- data/spec/data/apt/var/www/apt/db/version +4 -0
- data/spec/data/apt/var/www/apt/dists/sid/Release +19 -0
- data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Packages +16 -0
- data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Packages.gz +0 -0
- data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Release +5 -0
- data/spec/data/apt/var/www/apt/dists/sid/main/binary-i386/Packages +0 -0
- data/spec/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.0-1_amd64.deb +0 -0
- data/spec/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.1-1_amd64.deb +0 -0
- data/spec/data/bootstrap/encrypted_data_bag_secret +1 -0
- data/spec/data/bootstrap/secret.erb +9 -0
- data/spec/data/cookbooks/ignorken/recipes/default.rb +1 -0
- data/spec/data/cookbooks/ignorken/recipes/ignoreme.rb +2 -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/remotesubdir/.a_dotfile +1 -0
- data/spec/data/cookbooks/openldap/templates/default/all_windows_line_endings.erb +4 -0
- data/spec/data/cookbooks/openldap/templates/default/helper_test.erb +1 -0
- data/spec/data/cookbooks/openldap/templates/default/helpers_via_partial_test.erb +1 -0
- data/spec/data/cookbooks/openldap/templates/default/no_windows_line_endings.erb +4 -0
- data/spec/data/cookbooks/openldap/templates/default/some_windows_line_endings.erb +4 -0
- data/spec/data/cookbooks/preseed/files/default/preseed-file.seed +1 -0
- data/spec/data/cookbooks/preseed/templates/default/preseed-template.seed +1 -0
- data/spec/data/file-providers-method-snapshot-chef-11-4.json +127 -0
- data/spec/data/git_bundles/example-repo.gitbundle +0 -0
- data/spec/data/knife-home/.chef/plugins/knife/example_home_subcommand.rb +0 -0
- data/spec/data/knife_subcommand/test_yourself.rb +8 -0
- data/spec/data/null_config.rb +1 -0
- data/spec/data/partial_one.erb +1 -1
- data/spec/data/remote_file/nyan_cat.png.gz +0 -0
- data/spec/functional/file_content_management/deploy_strategies_spec.rb +238 -0
- data/spec/functional/knife/exec_spec.rb +2 -2
- data/spec/functional/provider/remote_file/cache_control_data_spec.rb +101 -0
- data/spec/functional/resource/batch_spec.rb +64 -0
- data/spec/functional/resource/cookbook_file_spec.rb +2 -3
- data/spec/functional/resource/deploy_revision_spec.rb +180 -0
- data/spec/functional/resource/directory_spec.rb +2 -2
- data/spec/functional/resource/file_spec.rb +17 -1
- data/spec/functional/resource/git_spec.rb +259 -0
- data/spec/functional/resource/link_spec.rb +422 -388
- data/spec/functional/resource/package_spec.rb +297 -0
- data/spec/functional/resource/powershell_spec.rb +188 -0
- data/spec/functional/resource/registry_spec.rb +8 -4
- data/spec/functional/resource/remote_directory_spec.rb +2 -2
- data/spec/functional/resource/remote_file_spec.rb +97 -29
- data/spec/functional/resource/template_spec.rb +173 -17
- data/spec/functional/resource/user_spec.rb +547 -0
- data/spec/functional/run_lock_spec.rb +5 -0
- data/spec/functional/shell_spec.rb +2 -1
- data/spec/functional/win32/service_manager_spec.rb +269 -0
- data/spec/functional/win32/versions_spec.rb +78 -0
- data/spec/integration/knife/chef_repo_path_spec.rb +805 -0
- data/spec/integration/knife/chef_repository_file_system_spec.rb +276 -0
- data/spec/integration/knife/chefignore_spec.rb +271 -0
- data/spec/integration/knife/delete_spec.rb +944 -0
- data/spec/integration/knife/deps_spec.rb +648 -0
- data/spec/integration/knife/diff_spec.rb +536 -0
- data/spec/integration/knife/download_spec.rb +962 -0
- data/spec/integration/knife/list_spec.rb +633 -0
- data/spec/integration/knife/raw_spec.rb +166 -0
- data/spec/integration/knife/redirection_spec.rb +57 -0
- data/spec/integration/knife/show_spec.rb +158 -0
- data/spec/integration/knife/upload_spec.rb +1060 -0
- data/spec/integration/solo/solo_spec.rb +41 -0
- data/spec/spec_helper.rb +55 -1
- data/spec/support/chef_helpers.rb +32 -0
- data/spec/support/platform_helpers.rb +40 -0
- data/spec/support/platforms/win32/spec_service.rb +59 -0
- data/spec/support/shared/functional/directory_resource.rb +43 -16
- data/spec/support/shared/functional/file_resource.rb +661 -20
- data/spec/support/shared/functional/securable_resource.rb +109 -8
- data/spec/support/shared/functional/securable_resource_with_reporting.rb +39 -31
- data/spec/support/shared/integration/integration_helper.rb +166 -0
- data/spec/support/shared/integration/knife_support.rb +171 -0
- data/spec/support/shared/unit/execute_resource.rb +125 -0
- data/spec/support/shared/unit/file_system_support.rb +8 -48
- data/spec/support/shared/unit/provider/file.rb +609 -0
- data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +407 -0
- data/spec/support/shared/unit/script_resource.rb +52 -0
- data/spec/support/shared/unit/windows_script_resource.rb +48 -0
- data/spec/tiny_server.rb +13 -11
- data/spec/unit/application/client_spec.rb +39 -1
- data/spec/unit/application/knife_spec.rb +12 -0
- data/spec/unit/application/solo_spec.rb +1 -1
- data/spec/unit/application_spec.rb +57 -2
- data/spec/unit/chef_fs/diff_spec.rb +30 -31
- data/spec/unit/chef_fs/file_pattern_spec.rb +2 -2
- data/spec/unit/chef_fs/file_system_spec.rb +2 -3
- data/spec/unit/client_spec.rb +20 -1
- data/spec/unit/config_spec.rb +70 -52
- data/spec/unit/cookbook/synchronizer_spec.rb +49 -1
- data/spec/unit/cookbook/syntax_check_spec.rb +28 -3
- data/spec/unit/cookbook_loader_spec.rb +3 -2
- data/spec/unit/daemon_spec.rb +7 -7
- data/spec/unit/data_bag_spec.rb +7 -0
- data/spec/unit/deprecation_spec.rb +86 -0
- data/spec/unit/encrypted_data_bag_item_spec.rb +183 -88
- data/spec/unit/environment_spec.rb +98 -0
- data/spec/unit/exceptions_spec.rb +6 -1
- data/spec/unit/file_access_control_spec.rb +21 -1
- data/spec/unit/file_content_management/deploy/cp_spec.rb +46 -0
- data/spec/unit/file_content_management/deploy/mv_unix_spec.rb +103 -0
- data/spec/unit/file_content_management/deploy/mv_windows_spec.rb +179 -0
- data/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb +38 -2
- data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +3 -2
- data/spec/unit/knife/bootstrap_spec.rb +128 -29
- data/spec/unit/knife/configure_spec.rb +42 -26
- data/spec/unit/knife/cookbook_download_spec.rb +24 -3
- data/spec/unit/knife/cookbook_upload_spec.rb +8 -4
- data/spec/unit/knife/core/bootstrap_context_spec.rb +78 -61
- data/spec/unit/knife/core/subcommand_loader_spec.rb +20 -0
- data/spec/unit/knife/core/ui_spec.rb +41 -0
- data/spec/unit/knife/node_run_list_set_spec.rb +140 -0
- data/spec/unit/knife_spec.rb +21 -0
- data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +1 -0
- data/spec/unit/mixin/params_validate_spec.rb +35 -0
- data/spec/unit/mixin/template_spec.rb +69 -57
- data/spec/unit/mixin/windows_architecture_helper_spec.rb +83 -0
- data/spec/unit/node_spec.rb +7 -0
- data/spec/unit/platform_spec.rb +15 -1
- data/spec/unit/provider/cookbook_file/content_spec.rb +40 -0
- data/spec/unit/provider/cookbook_file_spec.rb +26 -183
- data/spec/unit/provider/cron/solaris_spec.rb +1 -1
- data/spec/unit/provider/deploy/revision_spec.rb +19 -11
- data/spec/unit/provider/deploy_spec.rb +2 -2
- data/spec/unit/provider/directory_spec.rb +23 -23
- data/spec/unit/provider/execute_spec.rb +27 -1
- data/spec/unit/provider/file/content_spec.rb +101 -0
- data/spec/unit/provider/file_spec.rb +25 -484
- data/spec/unit/provider/git_spec.rb +224 -28
- data/spec/unit/provider/group/usermod_spec.rb +3 -1
- data/spec/unit/provider/ifconfig/debian_spec.rb +89 -0
- data/spec/unit/provider/ifconfig/redhat_spec.rb +71 -0
- data/spec/unit/provider/ifconfig_spec.rb +0 -33
- data/spec/unit/provider/mount/mount_spec.rb +33 -2
- data/spec/unit/provider/mount/windows_spec.rb +4 -1
- data/spec/unit/provider/mount_spec.rb +16 -6
- data/spec/unit/provider/package/portage_spec.rb +44 -0
- data/spec/unit/provider/package/rubygems_spec.rb +44 -1
- data/spec/unit/provider/package/smartos_spec.rb +3 -2
- data/spec/unit/provider/package/yum_spec.rb +36 -39
- data/spec/unit/provider/package/zypper_spec.rb +84 -22
- data/spec/unit/provider/package_spec.rb +0 -4
- data/spec/unit/provider/powershell_spec.rb +38 -0
- data/spec/unit/provider/remote_directory_spec.rb +0 -4
- data/spec/unit/provider/remote_file/cache_control_data_spec.rb +211 -0
- data/spec/unit/provider/remote_file/content_spec.rb +230 -0
- data/spec/unit/provider/remote_file/fetcher_spec.rb +75 -0
- data/spec/unit/provider/remote_file/ftp_spec.rb +224 -0
- data/spec/unit/provider/remote_file/http_spec.rb +319 -0
- data/spec/unit/provider/remote_file/local_file_spec.rb +60 -0
- data/spec/unit/provider/remote_file_spec.rb +33 -295
- data/spec/unit/provider/route_spec.rb +25 -9
- data/spec/unit/provider/service/macosx_spec.rb +176 -152
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +21 -18
- data/spec/unit/provider/service/systemd_service_spec.rb +2 -2
- data/spec/unit/provider/service/upstart_service_spec.rb +2 -2
- data/spec/unit/provider/service_spec.rb +3 -3
- data/spec/unit/provider/template/content_spec.rb +78 -0
- data/spec/unit/provider/template_spec.rb +52 -184
- data/spec/unit/provider/user/solaris_spec.rb +80 -0
- data/spec/unit/provider/user/useradd_spec.rb +12 -358
- data/spec/unit/resource/batch_spec.rb +48 -0
- data/spec/unit/resource/conditional_action_not_nothing_spec.rb +45 -0
- data/spec/unit/resource/execute_spec.rb +3 -101
- data/spec/unit/resource/file_spec.rb +0 -5
- data/spec/unit/resource/group_spec.rb +9 -0
- data/spec/unit/resource/ifconfig_spec.rb +60 -1
- data/spec/unit/resource/link_spec.rb +1 -0
- data/spec/unit/resource/mount_spec.rb +37 -0
- data/spec/unit/resource/powershell_spec.rb +48 -0
- data/spec/unit/resource/remote_file_spec.rb +44 -4
- data/spec/unit/resource/route_spec.rb +1 -1
- data/spec/unit/resource/script_spec.rb +13 -36
- data/spec/unit/resource/template_spec.rb +111 -8
- data/spec/unit/resource/user_spec.rb +7 -0
- data/spec/unit/resource_collection_spec.rb +61 -32
- data/spec/unit/resource_reporter_spec.rb +115 -102
- data/spec/unit/resource_spec.rb +170 -1
- data/spec/unit/rest/auth_credentials_spec.rb +2 -2
- data/spec/unit/rest_spec.rb +6 -2
- data/spec/unit/run_context/cookbook_compiler_spec.rb +9 -0
- data/spec/unit/runner_spec.rb +1 -1
- data/spec/unit/scan_access_control_spec.rb +4 -2
- data/spec/unit/shell/shell_session_spec.rb +15 -2
- data/spec/unit/util/backup_spec.rb +149 -0
- data/spec/unit/util/diff_spec.rb +596 -0
- data/spec/unit/util/selinux_spec.rb +172 -0
- data/spec/unit/version/platform_spec.rb +61 -0
- data/spec/unit/version_constraint/platform_spec.rb +46 -0
- data/spec/unit/version_constraint_spec.rb +5 -0
- metadata +233 -10
- data/lib/chef/chef_fs/file_system/data_bag_item.rb +0 -59
- data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +0 -237
- data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +0 -568
- data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +0 -220
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Seth Falcon (<seth@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
|
4
|
+
# License:: Apache License, Version 2.0
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require 'spec_helper'
|
|
20
|
+
require 'chef/mixin/shell_out'
|
|
21
|
+
require 'tmpdir'
|
|
22
|
+
require 'shellwords'
|
|
23
|
+
|
|
24
|
+
# Deploy relies heavily on symlinks, so it doesn't work on windows.
|
|
25
|
+
describe Chef::Resource::Git do
|
|
26
|
+
include Chef::Mixin::ShellOut
|
|
27
|
+
let(:file_cache_path) { Dir.mktmpdir }
|
|
28
|
+
# Some versions of git complains when the deploy directory is
|
|
29
|
+
# already created. Here we intentionally don't create the deploy
|
|
30
|
+
# directory beforehand.
|
|
31
|
+
let(:base_dir_path) { Dir.mktmpdir }
|
|
32
|
+
let(:deploy_directory) { File.join(base_dir_path, make_tmpname("git_base")) }
|
|
33
|
+
|
|
34
|
+
let(:node) do
|
|
35
|
+
Chef::Node.new.tap do |n|
|
|
36
|
+
n.name "rspec-test"
|
|
37
|
+
n.consume_external_attrs(@ohai.data, {})
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
let(:event_dispatch) { Chef::EventDispatch::Dispatcher.new }
|
|
42
|
+
let(:run_context) { Chef::RunContext.new(node, {}, event_dispatch) }
|
|
43
|
+
|
|
44
|
+
# These tests use git's bundle feature, which is a way to export an entire
|
|
45
|
+
# git repo (or subset of commits) as a single file.
|
|
46
|
+
#
|
|
47
|
+
# Generally you can treat a git bundle as a regular git remote.
|
|
48
|
+
#
|
|
49
|
+
# See also: http://git-scm.com/2010/03/10/bundles.html
|
|
50
|
+
#
|
|
51
|
+
# Beware that git bundles don't behave exactly the same as real
|
|
52
|
+
# remotes. To get closer to real remotes, we'll create a local clone
|
|
53
|
+
# of the bundle to use as a remote for the tests. This at least
|
|
54
|
+
# gives the expected responses for ls-remote using git version
|
|
55
|
+
# 1.7.12.4
|
|
56
|
+
let(:git_bundle_repo) { File.expand_path("git_bundles/example-repo.gitbundle", CHEF_SPEC_DATA) }
|
|
57
|
+
let(:origin_repo_dir) { Dir.mktmpdir }
|
|
58
|
+
let(:origin_repo) { "#{origin_repo_dir}/example" }
|
|
59
|
+
|
|
60
|
+
# This is the fourth version
|
|
61
|
+
let(:v1_commit) { "bc5ec79931ae74089aeadca6edc173527613e6d9" }
|
|
62
|
+
let(:v1_tag) { "9b73fb5e316bfaff7b822b0ccb3e1e08f9885085" }
|
|
63
|
+
let(:rev_foo) { "ed181b3419b6f489bedab282348162a110d6d3a1" }
|
|
64
|
+
let(:rev_testing) { "972d153654503bccec29f630c5dd369854a561e8" }
|
|
65
|
+
let(:rev_head) { "d294fbfd05aa7709ad9a9b8ef6343b17d355bf5f"}
|
|
66
|
+
|
|
67
|
+
let(:git_user_config) do
|
|
68
|
+
<<-E
|
|
69
|
+
[user]
|
|
70
|
+
name = frodoTbaggins
|
|
71
|
+
email = frodo@shire.org
|
|
72
|
+
E
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
before(:each) do
|
|
76
|
+
Chef::Log.level = :warn # silence git command live streams
|
|
77
|
+
@old_file_cache_path = Chef::Config[:file_cache_path]
|
|
78
|
+
shell_out!("git clone \"#{git_bundle_repo}\" example", :cwd => origin_repo_dir)
|
|
79
|
+
File.open("#{origin_repo}/.git/config", "a+") {|f| f.print(git_user_config) }
|
|
80
|
+
Chef::Config[:file_cache_path] = file_cache_path
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
after(:each) do
|
|
84
|
+
Chef::Config[:file_cache_path] = @old_file_cache_path
|
|
85
|
+
FileUtils.remove_entry_secure deploy_directory if File.exist?(deploy_directory)
|
|
86
|
+
FileUtils.remove_entry_secure file_cache_path
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
after(:all) do
|
|
90
|
+
FileUtils.remove_entry_secure origin_repo_dir
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
before(:all) do
|
|
94
|
+
@ohai = Ohai::System.new
|
|
95
|
+
@ohai.require_plugin("os")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context "working with pathes with special characters" do
|
|
99
|
+
let(:path_with_spaces) { "#{origin_repo_dir}/path with spaces" }
|
|
100
|
+
|
|
101
|
+
before(:each) do
|
|
102
|
+
FileUtils.mkdir(path_with_spaces)
|
|
103
|
+
FileUtils.cp(git_bundle_repo, path_with_spaces)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "clones a repository with a space in the path" do
|
|
107
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
108
|
+
r.repository "#{path_with_spaces}/example-repo.gitbundle"
|
|
109
|
+
end.run_action(:sync)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "when deploying from an annotated tag" do
|
|
114
|
+
let(:basic_git_resource) do
|
|
115
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
116
|
+
r.repository origin_repo
|
|
117
|
+
r.revision "v1.0.0"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# We create a copy of the basic_git_resource so that we can run
|
|
122
|
+
# the resource again and verify that it doesn't update.
|
|
123
|
+
let(:copy_git_resource) do
|
|
124
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
125
|
+
r.repository origin_repo
|
|
126
|
+
r.revision "v1.0.0"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "checks out the revision pointed to by the tag commit, not the tag commit itself" do
|
|
131
|
+
basic_git_resource.run_action(:sync)
|
|
132
|
+
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
|
|
133
|
+
head_rev.should == v1_commit
|
|
134
|
+
# also verify the tag commit itself is what we expect as an extra sanity check
|
|
135
|
+
rev = shell_out!('git rev-parse v1.0.0', :cwd => deploy_directory, :returns => [0]).stdout.strip
|
|
136
|
+
rev.should == v1_tag
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "doesn't update if up-to-date" do
|
|
140
|
+
# this used to fail because we didn't resolve the annotated tag
|
|
141
|
+
# properly to the pointed to commit.
|
|
142
|
+
basic_git_resource.run_action(:sync)
|
|
143
|
+
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
|
|
144
|
+
head_rev.should == v1_commit
|
|
145
|
+
|
|
146
|
+
copy_git_resource.run_action(:sync)
|
|
147
|
+
copy_git_resource.should_not be_updated
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
context "when deploying from a SHA revision" do
|
|
152
|
+
let(:basic_git_resource) do
|
|
153
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
154
|
+
r.repository git_bundle_repo
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# We create a copy of the basic_git_resource so that we can run
|
|
159
|
+
# the resource again and verify that it doesn't update.
|
|
160
|
+
let(:copy_git_resource) do
|
|
161
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
162
|
+
r.repository origin_repo
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "checks out the expected revision ed18" do
|
|
167
|
+
basic_git_resource.revision rev_foo
|
|
168
|
+
basic_git_resource.run_action(:sync)
|
|
169
|
+
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
|
|
170
|
+
head_rev.should == rev_foo
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "doesn't update if up-to-date" do
|
|
174
|
+
basic_git_resource.revision rev_foo
|
|
175
|
+
basic_git_resource.run_action(:sync)
|
|
176
|
+
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
|
|
177
|
+
head_rev.should == rev_foo
|
|
178
|
+
|
|
179
|
+
copy_git_resource.revision rev_foo
|
|
180
|
+
copy_git_resource.run_action(:sync)
|
|
181
|
+
copy_git_resource.should_not be_updated
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "checks out the expected revision 972d" do
|
|
185
|
+
basic_git_resource.revision rev_testing
|
|
186
|
+
basic_git_resource.run_action(:sync)
|
|
187
|
+
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
|
|
188
|
+
head_rev.should == rev_testing
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
context "when deploying from a revision named 'HEAD'" do
|
|
193
|
+
let(:basic_git_resource) do
|
|
194
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
195
|
+
r.repository origin_repo
|
|
196
|
+
r.revision 'HEAD'
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "checks out the expected revision" do
|
|
201
|
+
basic_git_resource.run_action(:sync)
|
|
202
|
+
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
|
|
203
|
+
head_rev.should == rev_head
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
context "when deploying from the default revision" do
|
|
208
|
+
let(:basic_git_resource) do
|
|
209
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
210
|
+
r.repository origin_repo
|
|
211
|
+
# use default
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it "checks out HEAD as the default revision" do
|
|
216
|
+
basic_git_resource.run_action(:sync)
|
|
217
|
+
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
|
|
218
|
+
head_rev.should == rev_head
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
context "when dealing with a repo with a degenerate tag named 'HEAD'" do
|
|
223
|
+
before do
|
|
224
|
+
shell_out!("git tag -m\"degenerate tag\" HEAD ed181b3419b6f489bedab282348162a110d6d3a1",
|
|
225
|
+
:cwd => origin_repo)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
let(:basic_git_resource) do
|
|
229
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
230
|
+
r.repository origin_repo
|
|
231
|
+
r.revision 'HEAD'
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
let(:git_resource_default_rev) do
|
|
236
|
+
Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
|
|
237
|
+
r.repository origin_repo
|
|
238
|
+
# use default of revision
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "checks out the (master) HEAD revision and ignores the tag" do
|
|
243
|
+
basic_git_resource.run_action(:sync)
|
|
244
|
+
head_rev = shell_out!('git rev-parse HEAD',
|
|
245
|
+
:cwd => deploy_directory,
|
|
246
|
+
:returns => [0]).stdout.strip
|
|
247
|
+
head_rev.should == rev_head
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "checks out the (master) HEAD revision when no revision is specified (ignores tag)" do
|
|
251
|
+
git_resource_default_rev.run_action(:sync)
|
|
252
|
+
head_rev = shell_out!('git rev-parse HEAD',
|
|
253
|
+
:cwd => deploy_directory,
|
|
254
|
+
:returns => [0]).stdout.strip
|
|
255
|
+
head_rev.should == rev_head
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
end
|
|
259
|
+
end
|
|
@@ -22,37 +22,56 @@ if windows?
|
|
|
22
22
|
require 'chef/win32/file' #probably need this in spec_helper
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
describe Chef::Resource::Link
|
|
25
|
+
describe Chef::Resource::Link do
|
|
26
26
|
let(:file_base) { "file_spec" }
|
|
27
27
|
|
|
28
28
|
let(:expect_updated?) {true}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
# We create the files in a different directory than tmp to exercise
|
|
31
|
+
# different file deployment strategies more completely.
|
|
32
|
+
let(:test_file_dir) do
|
|
31
33
|
if windows?
|
|
32
|
-
|
|
34
|
+
File.join(ENV['systemdrive'], "test-dir")
|
|
33
35
|
else
|
|
34
|
-
|
|
36
|
+
File.join(CHEF_SPEC_DATA, "test-dir")
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
40
|
+
before do
|
|
41
|
+
FileUtils::mkdir_p(test_file_dir)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
after do
|
|
45
|
+
FileUtils::rm_rf(test_file_dir)
|
|
46
|
+
end
|
|
47
|
+
|
|
38
48
|
let(:to) do
|
|
39
|
-
File.join(
|
|
49
|
+
File.join(test_file_dir, make_tmpname("to_spec"))
|
|
40
50
|
end
|
|
41
51
|
let(:target_file) do
|
|
42
|
-
File.join(
|
|
52
|
+
File.join(test_file_dir, make_tmpname("from_spec"))
|
|
43
53
|
end
|
|
44
54
|
|
|
45
55
|
after(:each) do
|
|
46
|
-
# TODO Windows fails to clean up some symlinks.
|
|
47
56
|
begin
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
cleanup_link(to) if File.exists?(to)
|
|
58
|
+
cleanup_link(target_file) if File.exists?(target_file)
|
|
59
|
+
cleanup_link(CHEF_SPEC_BACKUP_PATH) if File.exists?(CHEF_SPEC_BACKUP_PATH)
|
|
51
60
|
rescue
|
|
52
61
|
puts "Could not remove a file: #{$!}"
|
|
53
62
|
end
|
|
54
63
|
end
|
|
55
64
|
|
|
65
|
+
def cleanup_link(path)
|
|
66
|
+
if windows? && File.directory?(path)
|
|
67
|
+
# If the link target is a directory rm_rf doesn't work all the
|
|
68
|
+
# time on windows.
|
|
69
|
+
system "rmdir '#{path}'"
|
|
70
|
+
else
|
|
71
|
+
FileUtils.rm_rf(path)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
56
75
|
def canonicalize(path)
|
|
57
76
|
windows? ? path.gsub('/', '\\') : path
|
|
58
77
|
end
|
|
@@ -97,478 +116,493 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
|
|
|
97
116
|
resource
|
|
98
117
|
end
|
|
99
118
|
|
|
100
|
-
let
|
|
119
|
+
let(:resource) do
|
|
101
120
|
create_resource
|
|
102
121
|
end
|
|
103
122
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
123
|
+
describe "when supported on platform", :not_supported_on_win2k3 do
|
|
124
|
+
shared_examples_for 'delete errors out' do
|
|
125
|
+
it 'delete errors out' do
|
|
126
|
+
lambda { resource.run_action(:delete) }.should raise_error(Chef::Exceptions::Link)
|
|
127
|
+
(File.exist?(target_file) || symlink?(target_file)).should be_true
|
|
128
|
+
end
|
|
108
129
|
end
|
|
109
|
-
end
|
|
110
130
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
shared_context 'delete is noop' do
|
|
132
|
+
describe 'the :delete action' do
|
|
133
|
+
before(:each) do
|
|
134
|
+
@info = []
|
|
135
|
+
Chef::Log.stub!(:info) { |msg| @info << msg }
|
|
136
|
+
resource.run_action(:delete)
|
|
137
|
+
end
|
|
118
138
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
139
|
+
it 'leaves the file deleted' do
|
|
140
|
+
File.exist?(target_file).should be_false
|
|
141
|
+
symlink?(target_file).should be_false
|
|
142
|
+
end
|
|
143
|
+
it 'does not mark the resource updated' do
|
|
144
|
+
resource.should_not be_updated
|
|
145
|
+
end
|
|
146
|
+
it 'does not log that it deleted' do
|
|
147
|
+
@info.include?("link[#{target_file}] deleted").should be_false
|
|
148
|
+
end
|
|
128
149
|
end
|
|
129
150
|
end
|
|
130
|
-
end
|
|
131
151
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
shared_context 'delete succeeds' do
|
|
153
|
+
describe 'the :delete action' do
|
|
154
|
+
before(:each) do
|
|
155
|
+
@info = []
|
|
156
|
+
Chef::Log.stub!(:info) { |msg| @info << msg }
|
|
157
|
+
resource.run_action(:delete)
|
|
158
|
+
end
|
|
139
159
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
160
|
+
it 'deletes the file' do
|
|
161
|
+
File.exist?(target_file).should be_false
|
|
162
|
+
symlink?(target_file).should be_false
|
|
163
|
+
end
|
|
164
|
+
it 'marks the resource updated' do
|
|
165
|
+
resource.should be_updated
|
|
166
|
+
end
|
|
167
|
+
it 'logs that it deleted' do
|
|
168
|
+
@info.include?("link[#{target_file}] deleted").should be_true
|
|
169
|
+
end
|
|
149
170
|
end
|
|
150
171
|
end
|
|
151
|
-
end
|
|
152
172
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
173
|
+
shared_context 'create symbolic link succeeds' do
|
|
174
|
+
describe 'the :create action' do
|
|
175
|
+
before(:each) do
|
|
176
|
+
@info = []
|
|
177
|
+
Chef::Log.stub!(:info) { |msg| @info << msg }
|
|
178
|
+
resource.run_action(:create)
|
|
179
|
+
end
|
|
160
180
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
181
|
+
it 'links to the target file' do
|
|
182
|
+
symlink?(target_file).should be_true
|
|
183
|
+
readlink(target_file).should == canonicalize(to)
|
|
184
|
+
end
|
|
185
|
+
it 'marks the resource updated' do
|
|
186
|
+
resource.should be_updated
|
|
187
|
+
end
|
|
188
|
+
it 'logs that it created' do
|
|
189
|
+
@info.include?("link[#{target_file}] created").should be_true
|
|
190
|
+
end
|
|
170
191
|
end
|
|
171
192
|
end
|
|
172
|
-
end
|
|
173
193
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
194
|
+
shared_context 'create symbolic link is noop' do
|
|
195
|
+
describe 'the :create action' do
|
|
196
|
+
before(:each) do
|
|
197
|
+
@info = []
|
|
198
|
+
Chef::Log.stub!(:info) { |msg| @info << msg }
|
|
199
|
+
resource.run_action(:create)
|
|
200
|
+
end
|
|
181
201
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
202
|
+
it 'leaves the file linked' do
|
|
203
|
+
symlink?(target_file).should be_true
|
|
204
|
+
readlink(target_file).should == canonicalize(to)
|
|
205
|
+
end
|
|
206
|
+
it 'does not mark the resource updated' do
|
|
207
|
+
resource.should_not be_updated
|
|
208
|
+
end
|
|
209
|
+
it 'does not log that it created' do
|
|
210
|
+
@info.include?("link[#{target_file}] created").should be_false
|
|
211
|
+
end
|
|
191
212
|
end
|
|
192
213
|
end
|
|
193
|
-
end
|
|
194
214
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
215
|
+
shared_context 'create hard link succeeds' do
|
|
216
|
+
describe 'the :create action' do
|
|
217
|
+
before(:each) do
|
|
218
|
+
@info = []
|
|
219
|
+
Chef::Log.stub!(:info) { |msg| @info << msg }
|
|
220
|
+
resource.run_action(:create)
|
|
221
|
+
end
|
|
222
|
+
it 'preserves the hard link' do
|
|
223
|
+
File.exists?(target_file).should be_true
|
|
224
|
+
symlink?(target_file).should be_false
|
|
225
|
+
# Writing to one hardlinked file should cause both
|
|
226
|
+
# to have the new value.
|
|
227
|
+
IO.read(to).should == IO.read(target_file)
|
|
228
|
+
File.open(to, "w") { |file| file.write('wowzers') }
|
|
229
|
+
IO.read(target_file).should == 'wowzers'
|
|
230
|
+
end
|
|
231
|
+
it 'marks the resource updated' do
|
|
232
|
+
resource.should be_updated
|
|
233
|
+
end
|
|
234
|
+
it 'logs that it created' do
|
|
235
|
+
@info.include?("link[#{target_file}] created").should be_true
|
|
236
|
+
end
|
|
216
237
|
end
|
|
217
238
|
end
|
|
218
|
-
end
|
|
219
239
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
shared_context 'create hard link is noop' do
|
|
241
|
+
describe 'the :create action' do
|
|
242
|
+
before(:each) do
|
|
243
|
+
@info = []
|
|
244
|
+
Chef::Log.stub!(:info) { |msg| @info << msg }
|
|
245
|
+
resource.run_action(:create)
|
|
246
|
+
end
|
|
247
|
+
it 'links to the target file' do
|
|
248
|
+
File.exists?(target_file).should be_true
|
|
249
|
+
symlink?(target_file).should be_false
|
|
250
|
+
# Writing to one hardlinked file should cause both
|
|
251
|
+
# to have the new value.
|
|
252
|
+
IO.read(to).should == IO.read(target_file)
|
|
253
|
+
File.open(to, "w") { |file| file.write('wowzers') }
|
|
254
|
+
IO.read(target_file).should == 'wowzers'
|
|
255
|
+
end
|
|
256
|
+
it 'does not mark the resource updated' do
|
|
257
|
+
resource.should_not be_updated
|
|
258
|
+
end
|
|
259
|
+
it 'does not log that it created' do
|
|
260
|
+
@info.include?("link[#{target_file}] created").should be_false
|
|
261
|
+
end
|
|
241
262
|
end
|
|
242
263
|
end
|
|
243
|
-
end
|
|
244
264
|
|
|
245
|
-
|
|
265
|
+
context "is symbolic" do
|
|
246
266
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
267
|
+
context 'when the link destination is a file' do
|
|
268
|
+
before(:each) do
|
|
269
|
+
File.open(to, "w") do |file|
|
|
270
|
+
file.write('woohoo')
|
|
271
|
+
end
|
|
251
272
|
end
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
273
|
+
context 'and the link does not yet exist' do
|
|
274
|
+
include_context 'create symbolic link succeeds'
|
|
275
|
+
include_context 'delete is noop'
|
|
276
|
+
end
|
|
277
|
+
context 'and the link already exists and is a symbolic link' do
|
|
278
|
+
context 'pointing at the target' do
|
|
279
|
+
before(:each) do
|
|
280
|
+
symlink(to, target_file)
|
|
281
|
+
symlink?(target_file).should be_true
|
|
282
|
+
readlink(target_file).should == canonicalize(to)
|
|
283
|
+
end
|
|
284
|
+
include_context 'create symbolic link is noop'
|
|
285
|
+
include_context 'delete succeeds'
|
|
286
|
+
it 'the :delete action does not delete the target file' do
|
|
287
|
+
resource.run_action(:delete)
|
|
288
|
+
File.exists?(to).should be_true
|
|
289
|
+
end
|
|
263
290
|
end
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
291
|
+
context 'pointing somewhere else' do
|
|
292
|
+
before(:each) do
|
|
293
|
+
@other_target = File.join(test_file_dir, make_tmpname('other_spec'))
|
|
294
|
+
File.open(@other_target, 'w') { |file| file.write('eek') }
|
|
295
|
+
symlink(@other_target, target_file)
|
|
296
|
+
symlink?(target_file).should be_true
|
|
297
|
+
readlink(target_file).should == canonicalize(@other_target)
|
|
298
|
+
end
|
|
299
|
+
after(:each) do
|
|
300
|
+
File.delete(@other_target)
|
|
301
|
+
end
|
|
302
|
+
include_context 'create symbolic link succeeds'
|
|
303
|
+
include_context 'delete succeeds'
|
|
304
|
+
it 'the :delete action does not delete the target file' do
|
|
305
|
+
resource.run_action(:delete)
|
|
306
|
+
File.exists?(to).should be_true
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
context 'pointing nowhere' do
|
|
310
|
+
before(:each) do
|
|
311
|
+
nonexistent = File.join(test_file_dir, make_tmpname('nonexistent_spec'))
|
|
312
|
+
symlink(nonexistent, target_file)
|
|
313
|
+
symlink?(target_file).should be_true
|
|
314
|
+
readlink(target_file).should == canonicalize(nonexistent)
|
|
315
|
+
end
|
|
316
|
+
include_context 'create symbolic link succeeds'
|
|
317
|
+
include_context 'delete succeeds'
|
|
269
318
|
end
|
|
270
319
|
end
|
|
271
|
-
context '
|
|
320
|
+
context 'and the link already exists and is a hard link to the file' do
|
|
272
321
|
before(:each) do
|
|
273
|
-
|
|
274
|
-
File.
|
|
275
|
-
symlink(
|
|
276
|
-
symlink?(target_file).should be_true
|
|
277
|
-
readlink(target_file).should == @other_target
|
|
278
|
-
end
|
|
279
|
-
after(:each) do
|
|
280
|
-
File.delete(@other_target)
|
|
322
|
+
link(to, target_file)
|
|
323
|
+
File.exists?(target_file).should be_true
|
|
324
|
+
symlink?(target_file).should be_false
|
|
281
325
|
end
|
|
282
326
|
include_context 'create symbolic link succeeds'
|
|
283
|
-
|
|
284
|
-
it 'the :delete action does not delete the target file' do
|
|
285
|
-
resource.run_action(:delete)
|
|
286
|
-
File.exists?(to).should be_true
|
|
287
|
-
end
|
|
327
|
+
it_behaves_like 'delete errors out'
|
|
288
328
|
end
|
|
289
|
-
context '
|
|
329
|
+
context 'and the link already exists and is a file' do
|
|
290
330
|
before(:each) do
|
|
291
|
-
|
|
292
|
-
symlink(nonexistent, target_file)
|
|
293
|
-
symlink?(target_file).should be_true
|
|
294
|
-
readlink(target_file).should == nonexistent
|
|
331
|
+
File.open(target_file, 'w') { |file| file.write('eek') }
|
|
295
332
|
end
|
|
296
333
|
include_context 'create symbolic link succeeds'
|
|
297
|
-
|
|
334
|
+
it_behaves_like 'delete errors out'
|
|
298
335
|
end
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
336
|
+
context 'and the link already exists and is a directory' do
|
|
337
|
+
before(:each) do
|
|
338
|
+
Dir.mkdir(target_file)
|
|
339
|
+
end
|
|
340
|
+
it 'create errors out' do
|
|
341
|
+
if windows?
|
|
342
|
+
lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
|
|
343
|
+
elsif os_x? or solaris? or freebsd?
|
|
344
|
+
lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
|
|
345
|
+
else
|
|
346
|
+
lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
it_behaves_like 'delete errors out'
|
|
305
350
|
end
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
351
|
+
context 'and the link already exists and is not writeable to this user', :pending do
|
|
352
|
+
end
|
|
353
|
+
it_behaves_like 'a securable resource without existing target' do
|
|
354
|
+
let(:path) { target_file }
|
|
355
|
+
def allowed_acl(sid, expected_perms)
|
|
356
|
+
[ ACE.access_allowed(sid, expected_perms[:specific]) ]
|
|
357
|
+
end
|
|
358
|
+
def denied_acl(sid, expected_perms)
|
|
359
|
+
[ ACE.access_denied(sid, expected_perms[:specific]) ]
|
|
360
|
+
end
|
|
361
|
+
def parent_inheritable_acls
|
|
362
|
+
dummy_file_path = File.join(test_file_dir, "dummy_file")
|
|
363
|
+
dummy_file = FileUtils.touch(dummy_file_path)
|
|
364
|
+
dummy_desc = get_security_descriptor(dummy_file_path)
|
|
365
|
+
FileUtils.rm_rf(dummy_file_path)
|
|
366
|
+
dummy_desc
|
|
367
|
+
end
|
|
312
368
|
end
|
|
313
|
-
include_context 'create symbolic link succeeds'
|
|
314
|
-
it_behaves_like 'delete errors out'
|
|
315
369
|
end
|
|
316
|
-
context '
|
|
370
|
+
context 'when the link destination is a directory' do
|
|
317
371
|
before(:each) do
|
|
318
|
-
Dir.mkdir(
|
|
372
|
+
Dir.mkdir(to)
|
|
319
373
|
end
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
else
|
|
326
|
-
lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
|
|
327
|
-
end
|
|
374
|
+
# On Windows, readlink fails to open the link. FILE_FLAG_OPEN_REPARSE_POINT
|
|
375
|
+
# might help, from http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
|
|
376
|
+
context 'and the link does not yet exist' do
|
|
377
|
+
include_context 'create symbolic link succeeds'
|
|
378
|
+
include_context 'delete is noop'
|
|
328
379
|
end
|
|
329
|
-
it_behaves_like 'delete errors out'
|
|
330
|
-
end
|
|
331
|
-
context 'and the link already exists and is not writeable to this user', :pending do
|
|
332
380
|
end
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
381
|
+
context "when the link destination is a symbolic link" do
|
|
382
|
+
context 'to a file that exists' do
|
|
383
|
+
before(:each) do
|
|
384
|
+
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
|
|
385
|
+
File.open(@other_target, "w") { |file| file.write("eek") }
|
|
386
|
+
symlink(@other_target, to)
|
|
387
|
+
symlink?(to).should be_true
|
|
388
|
+
readlink(to).should == canonicalize(@other_target)
|
|
389
|
+
end
|
|
390
|
+
after(:each) do
|
|
391
|
+
File.delete(@other_target)
|
|
392
|
+
end
|
|
393
|
+
context 'and the link does not yet exist' do
|
|
394
|
+
include_context 'create symbolic link succeeds'
|
|
395
|
+
include_context 'delete is noop'
|
|
396
|
+
end
|
|
337
397
|
end
|
|
338
|
-
|
|
339
|
-
|
|
398
|
+
context 'to a file that does not exist' do
|
|
399
|
+
before(:each) do
|
|
400
|
+
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
|
|
401
|
+
symlink(@other_target, to)
|
|
402
|
+
symlink?(to).should be_true
|
|
403
|
+
readlink(to).should == canonicalize(@other_target)
|
|
404
|
+
end
|
|
405
|
+
context 'and the link does not yet exist' do
|
|
406
|
+
include_context 'create symbolic link succeeds'
|
|
407
|
+
include_context 'delete is noop'
|
|
408
|
+
end
|
|
340
409
|
end
|
|
341
410
|
end
|
|
342
|
-
|
|
343
|
-
context 'when the link destination is a directory' do
|
|
344
|
-
before(:each) do
|
|
345
|
-
Dir.mkdir(to)
|
|
411
|
+
context "when the link destination is not readable to this user", :pending do
|
|
346
412
|
end
|
|
347
|
-
|
|
348
|
-
# might help, from http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
|
|
349
|
-
context 'and the link does not yet exist' do
|
|
413
|
+
context "when the link destination does not exist" do
|
|
350
414
|
include_context 'create symbolic link succeeds'
|
|
351
415
|
include_context 'delete is noop'
|
|
352
416
|
end
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
417
|
+
|
|
418
|
+
{
|
|
419
|
+
'../' => 'with a relative link destination',
|
|
420
|
+
'' => 'with a bare filename for the link destination'
|
|
421
|
+
}.each do |prefix, desc|
|
|
422
|
+
context desc do
|
|
423
|
+
let(:to) { "#{prefix}#{File.basename(absolute_to)}" }
|
|
424
|
+
let(:absolute_to) { File.join(test_file_dir, make_tmpname("to_spec")) }
|
|
425
|
+
before(:each) do
|
|
426
|
+
resource.to(to)
|
|
427
|
+
end
|
|
428
|
+
context 'when the link does not yet exist' do
|
|
429
|
+
include_context 'create symbolic link succeeds'
|
|
430
|
+
include_context 'delete is noop'
|
|
431
|
+
end
|
|
432
|
+
context 'when the link already exists and points at the target' do
|
|
433
|
+
before(:each) do
|
|
434
|
+
symlink(to, target_file)
|
|
435
|
+
symlink?(target_file).should be_true
|
|
436
|
+
readlink(target_file).should == canonicalize(to)
|
|
437
|
+
end
|
|
438
|
+
include_context 'create symbolic link is noop'
|
|
439
|
+
include_context 'delete succeeds'
|
|
440
|
+
end
|
|
441
|
+
context 'when the link already exists and points at the target with an absolute path' do
|
|
442
|
+
before(:each) do
|
|
443
|
+
symlink(absolute_to, target_file)
|
|
444
|
+
symlink?(target_file).should be_true
|
|
445
|
+
readlink(target_file).should == canonicalize(absolute_to)
|
|
446
|
+
end
|
|
447
|
+
include_context 'create symbolic link succeeds'
|
|
448
|
+
include_context 'delete succeeds'
|
|
449
|
+
end
|
|
381
450
|
end
|
|
382
451
|
end
|
|
383
452
|
end
|
|
384
|
-
context "when the link destination is not readable to this user", :pending do
|
|
385
|
-
end
|
|
386
|
-
context "when the link destination does not exist" do
|
|
387
|
-
include_context 'create symbolic link succeeds'
|
|
388
|
-
include_context 'delete is noop'
|
|
389
|
-
end
|
|
390
453
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
let(:absolute_to) { File.join(base_dir, make_tmpname("to_spec")) }
|
|
454
|
+
context "is a hard link" do
|
|
455
|
+
before(:each) do
|
|
456
|
+
resource.link_type(:hard)
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
context "when the link destination is a file" do
|
|
398
460
|
before(:each) do
|
|
399
|
-
|
|
461
|
+
File.open(to, "w") do |file|
|
|
462
|
+
file.write('woohoo')
|
|
463
|
+
end
|
|
400
464
|
end
|
|
401
|
-
context
|
|
402
|
-
include_context 'create
|
|
465
|
+
context "and the link does not yet exist" do
|
|
466
|
+
include_context 'create hard link succeeds'
|
|
403
467
|
include_context 'delete is noop'
|
|
404
468
|
end
|
|
405
|
-
context
|
|
469
|
+
context "and the link already exists and is a symbolic link pointing at the same file" do
|
|
406
470
|
before(:each) do
|
|
407
471
|
symlink(to, target_file)
|
|
408
472
|
symlink?(target_file).should be_true
|
|
409
473
|
readlink(target_file).should == canonicalize(to)
|
|
410
474
|
end
|
|
411
|
-
include_context 'create
|
|
412
|
-
|
|
475
|
+
include_context 'create hard link succeeds'
|
|
476
|
+
it_behaves_like 'delete errors out'
|
|
413
477
|
end
|
|
414
|
-
context '
|
|
478
|
+
context 'and the link already exists and is a hard link to the file' do
|
|
415
479
|
before(:each) do
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
480
|
+
link(to, target_file)
|
|
481
|
+
File.exists?(target_file).should be_true
|
|
482
|
+
symlink?(target_file).should be_false
|
|
419
483
|
end
|
|
420
|
-
include_context 'create
|
|
484
|
+
include_context 'create hard link is noop'
|
|
421
485
|
include_context 'delete succeeds'
|
|
486
|
+
it 'the :delete action does not delete the target file' do
|
|
487
|
+
resource.run_action(:delete)
|
|
488
|
+
File.exists?(to).should be_true
|
|
489
|
+
end
|
|
422
490
|
end
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
resource.link_type(:hard)
|
|
430
|
-
end
|
|
431
|
-
|
|
432
|
-
context "when the link destination is a file" do
|
|
433
|
-
before(:each) do
|
|
434
|
-
File.open(to, "w") do |file|
|
|
435
|
-
file.write('woohoo')
|
|
436
|
-
end
|
|
437
|
-
end
|
|
438
|
-
context "and the link does not yet exist" do
|
|
439
|
-
include_context 'create hard link succeeds'
|
|
440
|
-
include_context 'delete is noop'
|
|
441
|
-
end
|
|
442
|
-
context "and the link already exists and is a symbolic link pointing at the same file" do
|
|
443
|
-
before(:each) do
|
|
444
|
-
symlink(to, target_file)
|
|
445
|
-
symlink?(target_file).should be_true
|
|
446
|
-
readlink(target_file).should == to
|
|
447
|
-
end
|
|
448
|
-
include_context 'create hard link succeeds'
|
|
449
|
-
it_behaves_like 'delete errors out'
|
|
450
|
-
end
|
|
451
|
-
context 'and the link already exists and is a hard link to the file' do
|
|
452
|
-
before(:each) do
|
|
453
|
-
link(to, target_file)
|
|
454
|
-
File.exists?(target_file).should be_true
|
|
455
|
-
symlink?(target_file).should be_false
|
|
456
|
-
end
|
|
457
|
-
include_context 'create hard link is noop'
|
|
458
|
-
include_context 'delete succeeds'
|
|
459
|
-
it 'the :delete action does not delete the target file' do
|
|
460
|
-
resource.run_action(:delete)
|
|
461
|
-
File.exists?(to).should be_true
|
|
462
|
-
end
|
|
463
|
-
end
|
|
464
|
-
context "and the link already exists and is a file" do
|
|
465
|
-
before(:each) do
|
|
466
|
-
File.open(target_file, 'w') { |file| file.write('tomfoolery') }
|
|
467
|
-
end
|
|
468
|
-
include_context 'create hard link succeeds'
|
|
469
|
-
it_behaves_like 'delete errors out'
|
|
470
|
-
end
|
|
471
|
-
context "and the link already exists and is a directory" do
|
|
472
|
-
before(:each) do
|
|
473
|
-
Dir.mkdir(target_file)
|
|
491
|
+
context "and the link already exists and is a file" do
|
|
492
|
+
before(:each) do
|
|
493
|
+
File.open(target_file, 'w') { |file| file.write('tomfoolery') }
|
|
494
|
+
end
|
|
495
|
+
include_context 'create hard link succeeds'
|
|
496
|
+
it_behaves_like 'delete errors out'
|
|
474
497
|
end
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
498
|
+
context "and the link already exists and is a directory" do
|
|
499
|
+
before(:each) do
|
|
500
|
+
Dir.mkdir(target_file)
|
|
501
|
+
end
|
|
502
|
+
it 'errors out' do
|
|
503
|
+
if windows?
|
|
504
|
+
lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
|
|
505
|
+
elsif os_x? or solaris? or freebsd?
|
|
506
|
+
lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
|
|
507
|
+
else
|
|
508
|
+
lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
|
|
509
|
+
end
|
|
482
510
|
end
|
|
511
|
+
it_behaves_like 'delete errors out'
|
|
483
512
|
end
|
|
484
|
-
|
|
485
|
-
end
|
|
486
|
-
context "and the link already exists and is not writeable to this user", :pending do
|
|
487
|
-
end
|
|
488
|
-
context "and specifies security attributes" do
|
|
489
|
-
before(:each) do
|
|
490
|
-
resource.owner(windows? ? 'Guest' : 'nobody')
|
|
513
|
+
context "and the link already exists and is not writeable to this user", :pending do
|
|
491
514
|
end
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
515
|
+
context "and specifies security attributes" do
|
|
516
|
+
before(:each) do
|
|
517
|
+
resource.owner(windows? ? 'Guest' : 'nobody')
|
|
518
|
+
end
|
|
519
|
+
it 'ignores them' do
|
|
520
|
+
resource.run_action(:create)
|
|
521
|
+
if windows?
|
|
522
|
+
Chef::ReservedNames::Win32::Security.get_named_security_info(target_file).owner.should_not == SID.Guest
|
|
523
|
+
else
|
|
524
|
+
File.lstat(target_file).uid.should_not == Etc.getpwnam('nobody').uid
|
|
525
|
+
end
|
|
498
526
|
end
|
|
499
527
|
end
|
|
500
528
|
end
|
|
501
|
-
|
|
502
|
-
context "when the link destination is a directory" do
|
|
503
|
-
before(:each) do
|
|
504
|
-
Dir.mkdir(to)
|
|
505
|
-
end
|
|
506
|
-
context 'and the link does not yet exist' do
|
|
507
|
-
it 'create errors out' do
|
|
508
|
-
lambda { resource.run_action(:create) }.should raise_error(windows? ? Chef::Exceptions::Win32APIError : Errno::EPERM)
|
|
509
|
-
end
|
|
510
|
-
include_context 'delete is noop'
|
|
511
|
-
end
|
|
512
|
-
end
|
|
513
|
-
context "when the link destination is a symbolic link" do
|
|
514
|
-
context 'to a real file' do
|
|
529
|
+
context "when the link destination is a directory" do
|
|
515
530
|
before(:each) do
|
|
516
|
-
|
|
517
|
-
File.open(@other_target, "w") { |file| file.write("eek") }
|
|
518
|
-
symlink(@other_target, to)
|
|
519
|
-
symlink?(to).should be_true
|
|
520
|
-
readlink(to).should == @other_target
|
|
521
|
-
end
|
|
522
|
-
after(:each) do
|
|
523
|
-
File.delete(@other_target)
|
|
531
|
+
Dir.mkdir(to)
|
|
524
532
|
end
|
|
525
533
|
context 'and the link does not yet exist' do
|
|
526
|
-
it '
|
|
527
|
-
resource.run_action(:create)
|
|
528
|
-
File.exists?(target_file).should be_true
|
|
529
|
-
# OS X gets angry about this sort of link. Bug in OS X, IMO.
|
|
530
|
-
pending('OS X/FreeBSD symlink? and readlink working on hard links to symlinks', :if => (os_x? or freebsd?)) do
|
|
531
|
-
symlink?(target_file).should be_true
|
|
532
|
-
readlink(target_file).should == @other_target
|
|
533
|
-
end
|
|
534
|
+
it 'create errors out' do
|
|
535
|
+
lambda { resource.run_action(:create) }.should raise_error(windows? ? Chef::Exceptions::Win32APIError : Errno::EPERM)
|
|
534
536
|
end
|
|
535
537
|
include_context 'delete is noop'
|
|
536
538
|
end
|
|
537
539
|
end
|
|
538
|
-
context
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
540
|
+
context "when the link destination is a symbolic link" do
|
|
541
|
+
context 'to a real file' do
|
|
542
|
+
before(:each) do
|
|
543
|
+
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
|
|
544
|
+
File.open(@other_target, "w") { |file| file.write("eek") }
|
|
545
|
+
symlink(@other_target, to)
|
|
546
|
+
symlink?(to).should be_true
|
|
547
|
+
readlink(to).should == canonicalize(@other_target)
|
|
548
|
+
end
|
|
549
|
+
after(:each) do
|
|
550
|
+
File.delete(@other_target)
|
|
551
|
+
end
|
|
552
|
+
context 'and the link does not yet exist' do
|
|
553
|
+
it 'links to the target file' do
|
|
548
554
|
resource.run_action(:create)
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
555
|
+
File.exists?(target_file).should be_true
|
|
556
|
+
# OS X gets angry about this sort of link. Bug in OS X, IMO.
|
|
557
|
+
pending('OS X/FreeBSD symlink? and readlink working on hard links to symlinks', :if => (os_x? or freebsd?)) do
|
|
558
|
+
symlink?(target_file).should be_true
|
|
559
|
+
readlink(target_file).should == canonicalize(@other_target)
|
|
554
560
|
end
|
|
555
|
-
symlink?(target_file).should be_true
|
|
556
|
-
readlink(target_file).should == @other_target
|
|
557
561
|
end
|
|
562
|
+
include_context 'delete is noop'
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
context 'to a nonexistent file' do
|
|
566
|
+
before(:each) do
|
|
567
|
+
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
|
|
568
|
+
symlink(@other_target, to)
|
|
569
|
+
symlink?(to).should be_true
|
|
570
|
+
readlink(to).should == canonicalize(@other_target)
|
|
571
|
+
end
|
|
572
|
+
context 'and the link does not yet exist' do
|
|
573
|
+
it 'links to the target file' do
|
|
574
|
+
pending('OS X/FreeBSD fails to create hardlinks to broken symlinks', :if => (os_x? or freebsd?)) do
|
|
575
|
+
resource.run_action(:create)
|
|
576
|
+
# Windows and Unix have different definitions of exists? here, and that's OK.
|
|
577
|
+
if windows?
|
|
578
|
+
File.exists?(target_file).should be_true
|
|
579
|
+
else
|
|
580
|
+
File.exists?(target_file).should be_false
|
|
581
|
+
end
|
|
582
|
+
symlink?(target_file).should be_true
|
|
583
|
+
readlink(target_file).should == canonicalize(@other_target)
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
include_context 'delete is noop'
|
|
558
587
|
end
|
|
559
|
-
include_context 'delete is noop'
|
|
560
588
|
end
|
|
561
589
|
end
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
590
|
+
context "when the link destination is not readable to this user", :pending do
|
|
591
|
+
end
|
|
592
|
+
context "when the link destination does not exist" do
|
|
593
|
+
context 'and the link does not yet exist' do
|
|
594
|
+
it 'create errors out' do
|
|
595
|
+
lambda { resource.run_action(:create) }.should raise_error(Errno::ENOENT)
|
|
596
|
+
end
|
|
597
|
+
include_context 'delete is noop'
|
|
569
598
|
end
|
|
570
|
-
include_context 'delete is noop'
|
|
571
599
|
end
|
|
572
600
|
end
|
|
573
601
|
end
|
|
602
|
+
|
|
603
|
+
describe "when not supported on platform", :win2k3_only do
|
|
604
|
+
it "raises error" do
|
|
605
|
+
lambda {resource}.should raise_error(Chef::Exceptions::Win32APIFunctionNotImplemented)
|
|
606
|
+
end
|
|
607
|
+
end
|
|
574
608
|
end
|