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,41 @@
|
|
|
1
|
+
require 'support/shared/integration/integration_helper'
|
|
2
|
+
require 'chef/mixin/shell_out'
|
|
3
|
+
|
|
4
|
+
describe "chef-solo" do
|
|
5
|
+
extend IntegrationSupport
|
|
6
|
+
include Chef::Mixin::ShellOut
|
|
7
|
+
|
|
8
|
+
context "with a no-op recipe in the run_list" do
|
|
9
|
+
|
|
10
|
+
when_the_repository "has a cookbook with a no-op recipe" do
|
|
11
|
+
directory 'cookbooks'
|
|
12
|
+
directory 'cookbooks/x'
|
|
13
|
+
directory 'cookbooks/x/recipes'
|
|
14
|
+
file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
|
|
15
|
+
file 'cookbooks/x/recipes/default.rb', ''
|
|
16
|
+
|
|
17
|
+
before do
|
|
18
|
+
@chef_file_cache = Dir.mktmpdir('file_cache')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
after do
|
|
22
|
+
FileUtils.rm_rf(@chef_file_cache) if @chef_file_cache
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should complete with success" do
|
|
26
|
+
# prepare the solo config
|
|
27
|
+
directory 'config'
|
|
28
|
+
file 'config/solo.rb', <<EOM
|
|
29
|
+
cookbook_path "#{File.join(@repository_dir, 'cookbooks')}"
|
|
30
|
+
file_cache_path "#{@chef_file_cache}"
|
|
31
|
+
EOM
|
|
32
|
+
config_file = canonicalize_path(File.join(@repository_dir, 'config', 'solo.rb'))
|
|
33
|
+
|
|
34
|
+
chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
|
|
35
|
+
result = shell_out("chef-solo -c \"#{config_file}\" -o 'x::default' -l debug", :cwd => chef_dir)
|
|
36
|
+
result.error!
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -40,9 +40,25 @@ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
|
40
40
|
$:.unshift(File.expand_path("../lib", __FILE__))
|
|
41
41
|
$:.unshift(File.dirname(__FILE__))
|
|
42
42
|
|
|
43
|
+
if ENV["COVERAGE"]
|
|
44
|
+
require 'simplecov'
|
|
45
|
+
SimpleCov.start do
|
|
46
|
+
add_filter "/spec/"
|
|
47
|
+
add_group "Remote File", "remote_file"
|
|
48
|
+
add_group "Resources", "/resource/"
|
|
49
|
+
add_group "Providers", "/provider/"
|
|
50
|
+
add_group "Knife", "knife"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
43
54
|
require 'chef'
|
|
44
55
|
require 'chef/knife'
|
|
45
|
-
|
|
56
|
+
|
|
57
|
+
Dir['lib/chef/knife/**/*.rb'].
|
|
58
|
+
map {|f| f.gsub('lib/', '') }.
|
|
59
|
+
map {|f| f.gsub(%r[\.rb$], '') }.
|
|
60
|
+
each {|f| require f }
|
|
61
|
+
|
|
46
62
|
require 'chef/mixins'
|
|
47
63
|
require 'chef/dsl'
|
|
48
64
|
require 'chef/application'
|
|
@@ -64,8 +80,16 @@ require 'spec/support/platform_helpers'
|
|
|
64
80
|
Dir["spec/support/**/*.rb"].
|
|
65
81
|
reject { |f| f =~ %r{^spec/support/platforms} }.
|
|
66
82
|
map { |f| f.gsub(%r{.rb$}, '') }.
|
|
83
|
+
map { |f| f.gsub(%r[spec/], '')}.
|
|
67
84
|
each { |f| require f }
|
|
68
85
|
|
|
86
|
+
|
|
87
|
+
OHAI_SYSTEM = Ohai::System.new
|
|
88
|
+
OHAI_SYSTEM.require_plugin("os")
|
|
89
|
+
OHAI_SYSTEM.require_plugin("platform")
|
|
90
|
+
TEST_PLATFORM = OHAI_SYSTEM["platform"].dup.freeze
|
|
91
|
+
TEST_PLATFORM_VERSION = OHAI_SYSTEM["platform_version"].dup.freeze
|
|
92
|
+
|
|
69
93
|
RSpec.configure do |config|
|
|
70
94
|
config.include(Matchers)
|
|
71
95
|
config.filter_run :focus => true
|
|
@@ -77,15 +101,45 @@ RSpec.configure do |config|
|
|
|
77
101
|
# Add jruby filters here
|
|
78
102
|
config.filter_run_excluding :windows_only => true unless windows?
|
|
79
103
|
config.filter_run_excluding :not_supported_on_win2k3 => true if windows_win2k3?
|
|
104
|
+
config.filter_run_excluding :not_supported_on_solaris => true if solaris?
|
|
105
|
+
config.filter_run_excluding :win2k3_only => true unless windows_win2k3?
|
|
80
106
|
config.filter_run_excluding :windows64_only => true unless windows64?
|
|
81
107
|
config.filter_run_excluding :windows32_only => true unless windows32?
|
|
108
|
+
config.filter_run_excluding :system_windows_service_gem_only => true unless system_windows_service_gem?
|
|
82
109
|
config.filter_run_excluding :unix_only => true unless unix?
|
|
110
|
+
config.filter_run_excluding :supports_cloexec => true unless supports_cloexec?
|
|
111
|
+
config.filter_run_excluding :selinux_only => true unless selinux_enabled?
|
|
83
112
|
config.filter_run_excluding :ruby_18_only => true unless ruby_18?
|
|
84
113
|
config.filter_run_excluding :ruby_19_only => true unless ruby_19?
|
|
114
|
+
config.filter_run_excluding :ruby_gte_19_only => true unless ruby_gte_19?
|
|
115
|
+
config.filter_run_excluding :ruby_20_only => true unless ruby_20?
|
|
116
|
+
config.filter_run_excluding :ruby_gte_20_only => true unless ruby_gte_20?
|
|
85
117
|
config.filter_run_excluding :requires_root => true unless ENV['USER'] == 'root'
|
|
86
118
|
config.filter_run_excluding :requires_unprivileged_user => true if ENV['USER'] == 'root'
|
|
87
119
|
config.filter_run_excluding :uses_diff => true unless has_diff?
|
|
88
120
|
|
|
121
|
+
running_platform_arch = `uname -m`.strip
|
|
122
|
+
|
|
123
|
+
config.filter_run_excluding :arch => lambda {|target_arch|
|
|
124
|
+
running_platform_arch != target_arch
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Functional Resource tests that are provider-specific:
|
|
128
|
+
# context "on platforms that use useradd", :provider => {:user => Chef::Provider::User::Useradd}} do #...
|
|
129
|
+
config.filter_run_excluding :provider => lambda {|criteria|
|
|
130
|
+
type, target_provider = criteria.first
|
|
131
|
+
|
|
132
|
+
platform = TEST_PLATFORM.dup
|
|
133
|
+
platform_version = TEST_PLATFORM_VERSION.dup
|
|
134
|
+
|
|
135
|
+
begin
|
|
136
|
+
provider_for_running_platform = Chef::Platform.find_provider(platform, platform_version, type)
|
|
137
|
+
provider_for_running_platform != target_provider
|
|
138
|
+
rescue ArgumentError # no provider for platform
|
|
139
|
+
true
|
|
140
|
+
end
|
|
141
|
+
}
|
|
142
|
+
|
|
89
143
|
config.run_all_when_everything_filtered = true
|
|
90
144
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
91
145
|
end
|
|
@@ -61,3 +61,35 @@ def has_diff?
|
|
|
61
61
|
false
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
|
+
|
|
65
|
+
# This is a helper to determine if the ruby in the PATH contains
|
|
66
|
+
# win32/service gem. windows_service_manager tests create a windows
|
|
67
|
+
# service that starts with the system ruby and requires this gem.
|
|
68
|
+
def system_windows_service_gem?
|
|
69
|
+
windows_service_gem_check_command = "ruby -e 'require \"win32/daemon\"' > /dev/null 2>&1"
|
|
70
|
+
if defined?(Bundler)
|
|
71
|
+
Bundler.with_clean_env do
|
|
72
|
+
# This returns true if the gem can be loaded
|
|
73
|
+
system windows_service_gem_check_command
|
|
74
|
+
end
|
|
75
|
+
else
|
|
76
|
+
# This returns true if the gem can be loaded
|
|
77
|
+
system windows_service_gem_check_command
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# This is a helper to canonicalize paths that we're using in the file
|
|
82
|
+
# tests.
|
|
83
|
+
def canonicalize_path(path)
|
|
84
|
+
windows? ? path.gsub('/', '\\') : path
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Check if a cmd exists on the PATH
|
|
88
|
+
def which(cmd)
|
|
89
|
+
paths = ENV['PATH'].split(File::PATH_SEPARATOR) + [ '/bin', '/usr/bin', '/sbin', '/usr/sbin' ]
|
|
90
|
+
paths.each do |path|
|
|
91
|
+
filename = File.join(path, cmd)
|
|
92
|
+
return filename if File.executable?(filename)
|
|
93
|
+
end
|
|
94
|
+
false
|
|
95
|
+
end
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
require 'fcntl'
|
|
2
|
+
|
|
3
|
+
def ruby_gte_20?
|
|
4
|
+
RUBY_VERSION.to_f >= 2.0
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def ruby_gte_19?
|
|
8
|
+
RUBY_VERSION.to_f >= 1.9
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def ruby_20?
|
|
12
|
+
!!(RUBY_VERSION =~ /^2.0/)
|
|
13
|
+
end
|
|
14
|
+
|
|
1
15
|
def ruby_19?
|
|
2
16
|
!!(RUBY_VERSION =~ /^1.9/)
|
|
3
17
|
end
|
|
@@ -46,4 +60,30 @@ def freebsd?
|
|
|
46
60
|
!!(RUBY_PLATFORM =~ /freebsd/)
|
|
47
61
|
end
|
|
48
62
|
|
|
63
|
+
def supports_cloexec?
|
|
64
|
+
Fcntl.const_defined?('F_SETFD') && Fcntl.const_defined?('FD_CLOEXEC')
|
|
65
|
+
end
|
|
66
|
+
|
|
49
67
|
DEV_NULL = windows? ? 'NUL' : '/dev/null'
|
|
68
|
+
|
|
69
|
+
def selinux_enabled?
|
|
70
|
+
# This code is currently copied from lib/chef/util/selinux to make
|
|
71
|
+
# specs independent of product.
|
|
72
|
+
selinuxenabled_path = which("selinuxenabled")
|
|
73
|
+
if selinuxenabled_path
|
|
74
|
+
cmd = Mixlib::ShellOut.new(selinuxenabled_path, :returns => [0,1])
|
|
75
|
+
cmd_result = cmd.run_command
|
|
76
|
+
case cmd_result.exitstatus
|
|
77
|
+
when 1
|
|
78
|
+
return false
|
|
79
|
+
when 0
|
|
80
|
+
return true
|
|
81
|
+
else
|
|
82
|
+
raise RuntimeError, "Unknown exit code from command #{selinuxenabled_path}: #{cmd.exitstatus}"
|
|
83
|
+
end
|
|
84
|
+
else
|
|
85
|
+
# We assume selinux is not enabled if selinux utils are not
|
|
86
|
+
# installed.
|
|
87
|
+
return false
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Serdar Sutay (<serdar@lambda.local>)
|
|
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 'win32/daemon'
|
|
20
|
+
|
|
21
|
+
class SpecService < ::Win32::Daemon
|
|
22
|
+
def service_init
|
|
23
|
+
@test_service_file = "#{ENV['TMP']}/spec_service_file"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def service_main(*startup_parameters)
|
|
27
|
+
while running? do
|
|
28
|
+
if !File.exists?(@test_service_file)
|
|
29
|
+
File.open(@test_service_file, 'wb') do |f|
|
|
30
|
+
f.write("This file is created by SpecService")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
sleep 1
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
################################################################################
|
|
39
|
+
# Control Signal Callback Methods
|
|
40
|
+
################################################################################
|
|
41
|
+
|
|
42
|
+
def service_stop
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def service_pause
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def service_resume
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def service_shutdown
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# To run this file as a service, it must be called as a script from within
|
|
56
|
+
# the Windows Service framework. In that case, kick off the main loop!
|
|
57
|
+
if __FILE__ == $0
|
|
58
|
+
SpecService.mainloop
|
|
59
|
+
end
|
|
@@ -63,6 +63,31 @@ shared_examples_for "a directory resource" do
|
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
|
+
|
|
67
|
+
# Set up the context for security tests
|
|
68
|
+
def allowed_acl(sid, expected_perms)
|
|
69
|
+
[
|
|
70
|
+
ACE.access_allowed(sid, expected_perms[:specific]),
|
|
71
|
+
ACE.access_allowed(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE))
|
|
72
|
+
]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def denied_acl(sid, expected_perms)
|
|
76
|
+
[
|
|
77
|
+
ACE.access_denied(sid, expected_perms[:specific]),
|
|
78
|
+
ACE.access_denied(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE))
|
|
79
|
+
]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def parent_inheritable_acls
|
|
83
|
+
dummy_directory_path = File.join(test_file_dir, "dummy_directory")
|
|
84
|
+
dummy_directory = FileUtils.mkdir_p(dummy_directory_path)
|
|
85
|
+
dummy_desc = get_security_descriptor(dummy_directory_path)
|
|
86
|
+
FileUtils.rm_rf(dummy_directory_path)
|
|
87
|
+
dummy_desc
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it_behaves_like "a securable resource without existing target"
|
|
66
91
|
end
|
|
67
92
|
|
|
68
93
|
context "when the target directory exists" do
|
|
@@ -120,27 +145,29 @@ shared_examples_for "a directory resource" do
|
|
|
120
145
|
end
|
|
121
146
|
end
|
|
122
147
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
shared_context Chef::Resource::Directory do
|
|
151
|
+
# We create the directory than tmp to exercise different file
|
|
152
|
+
# deployment strategies more completely.
|
|
153
|
+
let(:test_file_dir) do
|
|
154
|
+
if windows?
|
|
155
|
+
File.join(ENV['systemdrive'], "test-dir")
|
|
156
|
+
else
|
|
157
|
+
File.join(CHEF_SPEC_DATA, "test-dir")
|
|
158
|
+
end
|
|
129
159
|
end
|
|
130
160
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
ACE.access_denied(sid, expected_perms[:specific]),
|
|
134
|
-
ACE.access_denied(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE))
|
|
135
|
-
]
|
|
161
|
+
let(:path) do
|
|
162
|
+
File.join(test_file_dir, make_tmpname(directory_base))
|
|
136
163
|
end
|
|
137
164
|
|
|
138
|
-
|
|
139
|
-
|
|
165
|
+
before do
|
|
166
|
+
FileUtils::mkdir_p(test_file_dir)
|
|
167
|
+
end
|
|
140
168
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
File.join(Dir.tmpdir, make_tmpname(directory_base))
|
|
169
|
+
after do
|
|
170
|
+
FileUtils::rm_rf(test_file_dir)
|
|
144
171
|
end
|
|
145
172
|
|
|
146
173
|
after(:each) do
|
|
@@ -16,6 +16,51 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#
|
|
18
18
|
|
|
19
|
+
shared_context "deploying with move" do
|
|
20
|
+
before do
|
|
21
|
+
@original_atomic_update = Chef::Config[:file_atomic_update]
|
|
22
|
+
Chef::Config[:file_atomic_update] = true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after do
|
|
26
|
+
Chef::Config[:file_atomic_update] = @original_atomic_update
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
shared_context "deploying with copy" do
|
|
31
|
+
before do
|
|
32
|
+
@original_atomic_update = Chef::Config[:file_atomic_update]
|
|
33
|
+
Chef::Config[:file_atomic_update] = false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
after do
|
|
37
|
+
Chef::Config[:file_atomic_update] = @original_atomic_update
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
shared_context "deploying via tmpdir" do
|
|
42
|
+
before do
|
|
43
|
+
@original_stage_via = Chef::Config[:file_staging_uses_destdir]
|
|
44
|
+
Chef::Config[:file_staging_uses_destdir] = false
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
after do
|
|
48
|
+
Chef::Config[:file_staging_uses_destdir] = @original_stage_via
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
shared_context "deploying via destdir" do
|
|
53
|
+
before do
|
|
54
|
+
@original_stage_via = Chef::Config[:file_staging_uses_destdir]
|
|
55
|
+
Chef::Config[:file_staging_uses_destdir] = true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
after do
|
|
59
|
+
Chef::Config[:file_staging_uses_destdir] = @original_stage_via
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
19
64
|
shared_examples_for "a file with the wrong content" do
|
|
20
65
|
before do
|
|
21
66
|
# Assert starting state is as expected
|
|
@@ -46,6 +91,10 @@ shared_examples_for "a file with the wrong content" do
|
|
|
46
91
|
it "is marked as updated by last action" do
|
|
47
92
|
resource.should be_updated_by_last_action
|
|
48
93
|
end
|
|
94
|
+
|
|
95
|
+
it "should restore the security contexts on selinux", :selinux_only do
|
|
96
|
+
selinux_security_context_restored?(path).should be_true
|
|
97
|
+
end
|
|
49
98
|
end
|
|
50
99
|
|
|
51
100
|
context "with backups disabled" do
|
|
@@ -58,6 +107,10 @@ shared_examples_for "a file with the wrong content" do
|
|
|
58
107
|
it "should not attempt to backup the existing file if :backup == 0" do
|
|
59
108
|
Dir.glob(backup_glob).size.should equal(0)
|
|
60
109
|
end
|
|
110
|
+
|
|
111
|
+
it "should restore the security contexts on selinux", :selinux_only do
|
|
112
|
+
selinux_security_context_restored?(path).should be_true
|
|
113
|
+
end
|
|
61
114
|
end
|
|
62
115
|
end
|
|
63
116
|
|
|
@@ -74,6 +127,10 @@ shared_examples_for "a file with the wrong content" do
|
|
|
74
127
|
it "is not marked as updated" do
|
|
75
128
|
resource.should_not be_updated_by_last_action
|
|
76
129
|
end
|
|
130
|
+
|
|
131
|
+
it "should restore the security contexts on selinux", :selinux_only do
|
|
132
|
+
selinux_security_context_restored?(path).should be_true
|
|
133
|
+
end
|
|
77
134
|
end
|
|
78
135
|
|
|
79
136
|
describe "when running action :delete" do
|
|
@@ -115,6 +172,10 @@ shared_examples_for "a file with the correct content" do
|
|
|
115
172
|
it "is not marked as updated by last action" do
|
|
116
173
|
resource.should_not be_updated_by_last_action
|
|
117
174
|
end
|
|
175
|
+
|
|
176
|
+
it "should restore the security contexts on selinux", :selinux_only do
|
|
177
|
+
selinux_security_context_restored?(path).should be_true
|
|
178
|
+
end
|
|
118
179
|
end
|
|
119
180
|
|
|
120
181
|
describe "when running action :create_if_missing" do
|
|
@@ -129,6 +190,10 @@ shared_examples_for "a file with the correct content" do
|
|
|
129
190
|
it "is not marked as updated by last action" do
|
|
130
191
|
resource.should_not be_updated_by_last_action
|
|
131
192
|
end
|
|
193
|
+
|
|
194
|
+
it "should restore the security contexts on selinux", :selinux_only do
|
|
195
|
+
selinux_security_context_restored?(path).should be_true
|
|
196
|
+
end
|
|
132
197
|
end
|
|
133
198
|
|
|
134
199
|
describe "when running action :delete" do
|
|
@@ -147,6 +212,122 @@ shared_examples_for "a file with the correct content" do
|
|
|
147
212
|
end
|
|
148
213
|
|
|
149
214
|
shared_examples_for "a file resource" do
|
|
215
|
+
describe "when deploying with :move" do
|
|
216
|
+
|
|
217
|
+
include_context "deploying with move"
|
|
218
|
+
|
|
219
|
+
describe "when deploying via tmpdir" do
|
|
220
|
+
|
|
221
|
+
include_context "deploying via tmpdir"
|
|
222
|
+
|
|
223
|
+
it_behaves_like "a configured file resource"
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
describe "when deploying via destdir" do
|
|
227
|
+
|
|
228
|
+
include_context "deploying via destdir"
|
|
229
|
+
|
|
230
|
+
it_behaves_like "a configured file resource"
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
describe "when deploying with :copy" do
|
|
235
|
+
|
|
236
|
+
include_context "deploying with copy"
|
|
237
|
+
|
|
238
|
+
describe "when deploying via tmpdir" do
|
|
239
|
+
|
|
240
|
+
include_context "deploying via tmpdir"
|
|
241
|
+
|
|
242
|
+
it_behaves_like "a configured file resource"
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
describe "when deploying via destdir" do
|
|
246
|
+
|
|
247
|
+
include_context "deploying via destdir"
|
|
248
|
+
|
|
249
|
+
it_behaves_like "a configured file resource"
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
describe "when running under why run" do
|
|
254
|
+
|
|
255
|
+
before do
|
|
256
|
+
Chef::Config[:why_run] = true
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
after do
|
|
260
|
+
Chef::Config[:why_run] = false
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
context "and the resource has a path with a missing intermediate directory" do
|
|
264
|
+
# CHEF-3978
|
|
265
|
+
|
|
266
|
+
let(:path) do
|
|
267
|
+
File.join(test_file_dir, "intermediate_dir", make_tmpname(file_base))
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "successfully doesn't create the file" do
|
|
271
|
+
resource.run_action(:create) # should not raise
|
|
272
|
+
File.should_not exist(path)
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
describe "when setting atomic_update" do
|
|
279
|
+
it "booleans should work" do
|
|
280
|
+
lambda {resource.atomic_update(true)}.should_not raise_error
|
|
281
|
+
lambda {resource.atomic_update(false)}.should_not raise_error
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
it "anything else should raise an error" do
|
|
285
|
+
lambda {resource.atomic_update(:copy)}.should raise_error(ArgumentError)
|
|
286
|
+
lambda {resource.atomic_update(:move)}.should raise_error(ArgumentError)
|
|
287
|
+
lambda {resource.atomic_update(958)}.should raise_error(ArgumentError)
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
shared_examples_for "file resource not pointing to a real file" do
|
|
294
|
+
def symlink?(file_path)
|
|
295
|
+
if windows?
|
|
296
|
+
Chef::ReservedNames::Win32::File.symlink?(file_path)
|
|
297
|
+
else
|
|
298
|
+
File.symlink?(file_path)
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def real_file?(file_path)
|
|
303
|
+
!symlink?(file_path) && File.file?(file_path)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
describe "when force_unlink is set to true" do
|
|
307
|
+
it ":create unlinks the target" do
|
|
308
|
+
real_file?(path).should be_false
|
|
309
|
+
resource.force_unlink(true)
|
|
310
|
+
resource.run_action(:create)
|
|
311
|
+
real_file?(path).should be_true
|
|
312
|
+
binread(path).should == expected_content
|
|
313
|
+
resource.should be_updated_by_last_action
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
describe "when force_unlink is set to false" do
|
|
318
|
+
it ":create raises an error" do
|
|
319
|
+
lambda {resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
describe "when force_unlink is not set (default)" do
|
|
324
|
+
it ":create raises an error" do
|
|
325
|
+
lambda {resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
shared_examples_for "a configured file resource" do
|
|
150
331
|
|
|
151
332
|
include_context "diff disabled"
|
|
152
333
|
|
|
@@ -155,7 +336,7 @@ shared_examples_for "a file resource" do
|
|
|
155
336
|
end
|
|
156
337
|
|
|
157
338
|
# note the stripping of the drive letter from the tmpdir on windows
|
|
158
|
-
let(:backup_glob) { File.join(CHEF_SPEC_BACKUP_PATH,
|
|
339
|
+
let(:backup_glob) { File.join(CHEF_SPEC_BACKUP_PATH, test_file_dir.sub(/^([A-Za-z]:)/, ""), "#{file_base}*") }
|
|
159
340
|
|
|
160
341
|
# Most tests update the resource, but a few do not. We need to test that the
|
|
161
342
|
# resource is marked updated or not correctly, but the test contexts are
|
|
@@ -164,6 +345,17 @@ shared_examples_for "a file resource" do
|
|
|
164
345
|
# and permissions are correct.
|
|
165
346
|
let(:expect_updated?) { true }
|
|
166
347
|
|
|
348
|
+
include Chef::Mixin::ShellOut
|
|
349
|
+
|
|
350
|
+
def selinux_security_context_restored?(path)
|
|
351
|
+
@restorecon_path = which("restorecon") if @restorecon_path.nil?
|
|
352
|
+
restorecon_test_command = "#{@restorecon_path} -n -v #{path}"
|
|
353
|
+
cmdresult = shell_out(restorecon_test_command)
|
|
354
|
+
# restorecon will print the required changes to stdout if any is
|
|
355
|
+
# needed
|
|
356
|
+
cmdresult.stdout.empty?
|
|
357
|
+
end
|
|
358
|
+
|
|
167
359
|
def binread(file)
|
|
168
360
|
content = File.open(file, "rb") do |f|
|
|
169
361
|
f.read
|
|
@@ -172,6 +364,398 @@ shared_examples_for "a file resource" do
|
|
|
172
364
|
content
|
|
173
365
|
end
|
|
174
366
|
|
|
367
|
+
context "when the target file is a symlink", :not_supported_on_win2k3 do
|
|
368
|
+
let(:symlink_target) {
|
|
369
|
+
File.join(CHEF_SPEC_DATA, "file-test-target")
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
describe "when configured not to manage symlink's target" do
|
|
374
|
+
before(:each) do
|
|
375
|
+
# configure not to manage symlink source
|
|
376
|
+
resource.manage_symlink_source(false)
|
|
377
|
+
|
|
378
|
+
# create symlinks for test context
|
|
379
|
+
FileUtils.touch(symlink_target)
|
|
380
|
+
|
|
381
|
+
if windows?
|
|
382
|
+
Chef::ReservedNames::Win32::File.symlink(symlink_target, path)
|
|
383
|
+
else
|
|
384
|
+
File.symlink(symlink_target, path)
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
after(:each) do
|
|
389
|
+
FileUtils.rm_rf(symlink_target)
|
|
390
|
+
FileUtils.rm_rf(path)
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
describe "when symlink target has correct content" do
|
|
394
|
+
before(:each) do
|
|
395
|
+
File.open(symlink_target, "wb") { |f| f.print expected_content }
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
it_behaves_like "file resource not pointing to a real file"
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
describe "when symlink target has the wrong content" do
|
|
402
|
+
before(:each) do
|
|
403
|
+
File.open(symlink_target, "wb") { |f| f.print "This is so wrong!!!" }
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
after(:each) do
|
|
407
|
+
# symlink should never be followed
|
|
408
|
+
binread(symlink_target).should == "This is so wrong!!!"
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
it_behaves_like "file resource not pointing to a real file"
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# Unix-only for now. Windows behavior may differ because of how ACL
|
|
416
|
+
# management handles symlinks. Since symlinks are rare on Windows and this
|
|
417
|
+
# feature primarily exists to support the case where a well-known file
|
|
418
|
+
# (e.g., resolv.conf) has been converted to a symlink, we're okay with the
|
|
419
|
+
# discrepancy.
|
|
420
|
+
context "when configured to manage the symlink source", :unix_only do
|
|
421
|
+
|
|
422
|
+
before do
|
|
423
|
+
resource.manage_symlink_source(true)
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
context "but the symlink is part of a loop" do
|
|
427
|
+
let(:link1_path) { File.join(CHEF_SPEC_DATA, "points-to-link2") }
|
|
428
|
+
let(:link2_path) { File.join(CHEF_SPEC_DATA, "points-to-link1") }
|
|
429
|
+
|
|
430
|
+
before do
|
|
431
|
+
# point resource at link1:
|
|
432
|
+
resource.path(link1_path)
|
|
433
|
+
# create symlinks for test context
|
|
434
|
+
File.symlink(link1_path, link2_path)
|
|
435
|
+
File.symlink(link2_path, link1_path)
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
after(:each) do
|
|
439
|
+
FileUtils.rm_rf(link1_path)
|
|
440
|
+
FileUtils.rm_rf(link2_path)
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
it "raises an InvalidSymlink error" do
|
|
444
|
+
lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::InvalidSymlink)
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
it "issues a warning/assumption in whyrun mode" do
|
|
448
|
+
begin
|
|
449
|
+
Chef::Config[:why_run] = true
|
|
450
|
+
resource.run_action(:create) # should not raise
|
|
451
|
+
ensure
|
|
452
|
+
Chef::Config[:why_run] = false
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
context "but the symlink points to a nonexistent file" do
|
|
458
|
+
let(:link_path) { File.join(CHEF_SPEC_DATA, "points-to-nothing") }
|
|
459
|
+
let(:not_existent_source) { File.join(CHEF_SPEC_DATA, "i-am-not-here") }
|
|
460
|
+
|
|
461
|
+
before do
|
|
462
|
+
resource.path(link_path)
|
|
463
|
+
# create symlinks for test context
|
|
464
|
+
File.symlink(not_existent_source, link_path)
|
|
465
|
+
FileUtils.rm_rf(not_existent_source)
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
after(:each) do
|
|
469
|
+
FileUtils.rm_rf(link_path)
|
|
470
|
+
end
|
|
471
|
+
it "raises an InvalidSymlink error" do
|
|
472
|
+
lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::InvalidSymlink)
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
it "issues a warning/assumption in whyrun mode" do
|
|
476
|
+
begin
|
|
477
|
+
Chef::Config[:why_run] = true
|
|
478
|
+
resource.run_action(:create) # should not raise
|
|
479
|
+
ensure
|
|
480
|
+
Chef::Config[:why_run] = false
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
context "but the symlink is points to a non-file fs entry" do
|
|
486
|
+
let(:link_path) { File.join(CHEF_SPEC_DATA, "points-to-dir") }
|
|
487
|
+
let(:not_a_file_path) { File.join(CHEF_SPEC_DATA, "dir-at-end-of-symlink") }
|
|
488
|
+
|
|
489
|
+
before do
|
|
490
|
+
# point resource at link1:
|
|
491
|
+
resource.path(link_path)
|
|
492
|
+
# create symlinks for test context
|
|
493
|
+
File.symlink(not_a_file_path, link_path)
|
|
494
|
+
Dir.mkdir(not_a_file_path)
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
after(:each) do
|
|
498
|
+
FileUtils.rm_rf(link_path)
|
|
499
|
+
FileUtils.rm_rf(not_a_file_path)
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
it "raises an InvalidSymlink error" do
|
|
503
|
+
lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
it "issues a warning/assumption in whyrun mode" do
|
|
507
|
+
begin
|
|
508
|
+
Chef::Config[:why_run] = true
|
|
509
|
+
resource.run_action(:create) # should not raise
|
|
510
|
+
ensure
|
|
511
|
+
Chef::Config[:why_run] = false
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
context "when the symlink source is a real file" do
|
|
517
|
+
|
|
518
|
+
let(:wrong_content) { "this is the wrong content" }
|
|
519
|
+
let(:link_path) { File.join(CHEF_SPEC_DATA, "points-to-real-file") }
|
|
520
|
+
|
|
521
|
+
before do
|
|
522
|
+
# point resource at link:
|
|
523
|
+
resource.path(link_path)
|
|
524
|
+
# create symlinks for test context
|
|
525
|
+
File.symlink(path, link_path)
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
after(:each) do
|
|
529
|
+
# shared examples should not change our test setup of a file resource
|
|
530
|
+
# pointing at a symlink:
|
|
531
|
+
resource.path.should == link_path
|
|
532
|
+
FileUtils.rm_rf(link_path)
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
context "and the permissions are incorrect" do
|
|
536
|
+
before do
|
|
537
|
+
# Create source (real) file
|
|
538
|
+
File.open(path, "wb") { |f| f.write(expected_content) }
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
include_context "setup broken permissions"
|
|
543
|
+
|
|
544
|
+
include_examples "a securable resource with existing target"
|
|
545
|
+
|
|
546
|
+
it "does not replace the symlink with a real file" do
|
|
547
|
+
resource.run_action(:create)
|
|
548
|
+
File.should be_symlink(link_path)
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
context "and the content is incorrect" do
|
|
554
|
+
before do
|
|
555
|
+
# Create source (real) file
|
|
556
|
+
File.open(path, "wb") { |f| f.write(wrong_content) }
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
it "updates the source file content" do
|
|
560
|
+
pending
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
it "marks the resource as updated" do
|
|
564
|
+
resource.run_action(:create)
|
|
565
|
+
resource.should be_updated_by_last_action
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
it "does not replace the symlink with a real file" do
|
|
569
|
+
resource.run_action(:create)
|
|
570
|
+
File.should be_symlink(link_path)
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
context "and the content and permissions are correct" do
|
|
575
|
+
let(:expect_updated?) { false }
|
|
576
|
+
|
|
577
|
+
before do
|
|
578
|
+
# Create source (real) file
|
|
579
|
+
File.open(path, "wb") { |f| f.write(expected_content) }
|
|
580
|
+
end
|
|
581
|
+
include_context "setup correct permissions"
|
|
582
|
+
|
|
583
|
+
include_examples "a securable resource with existing target"
|
|
584
|
+
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
context "when the symlink points to a symlink which points to a real file" do
|
|
590
|
+
|
|
591
|
+
let(:wrong_content) { "this is the wrong content" }
|
|
592
|
+
let(:link_to_file_path) { File.join(CHEF_SPEC_DATA, "points-to-real-file") }
|
|
593
|
+
let(:link_to_link_path) { File.join(CHEF_SPEC_DATA, "points-to-next-link") }
|
|
594
|
+
|
|
595
|
+
before do
|
|
596
|
+
# point resource at link:
|
|
597
|
+
resource.path(link_to_link_path)
|
|
598
|
+
# create symlinks for test context
|
|
599
|
+
File.symlink(path, link_to_file_path)
|
|
600
|
+
File.symlink(link_to_file_path, link_to_link_path)
|
|
601
|
+
|
|
602
|
+
# Create source (real) file
|
|
603
|
+
File.open(path, "wb") { |f| f.write(wrong_content) }
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
include_context "setup broken permissions"
|
|
607
|
+
|
|
608
|
+
include_examples "a securable resource with existing target"
|
|
609
|
+
|
|
610
|
+
after(:each) do
|
|
611
|
+
# shared examples should not change our test setup of a file resource
|
|
612
|
+
# pointing at a symlink:
|
|
613
|
+
resource.path.should == link_to_link_path
|
|
614
|
+
FileUtils.rm_rf(link_to_file_path)
|
|
615
|
+
FileUtils.rm_rf(link_to_link_path)
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
it "does not replace the symlink with a real file" do
|
|
619
|
+
resource.run_action(:create)
|
|
620
|
+
File.should be_symlink(link_to_link_path)
|
|
621
|
+
File.should be_symlink(link_to_file_path)
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
context "when the target file is a directory" do
|
|
629
|
+
before(:each) do
|
|
630
|
+
FileUtils.mkdir_p(path)
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
after(:each) do
|
|
634
|
+
FileUtils.rm_rf(path)
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
it_behaves_like "file resource not pointing to a real file"
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
context "when the target file is a blockdev",:unix_only, :requires_root, :not_supported_on_solaris do
|
|
641
|
+
include Chef::Mixin::ShellOut
|
|
642
|
+
let(:path) do
|
|
643
|
+
File.join(CHEF_SPEC_DATA, "testdev")
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
before(:each) do
|
|
647
|
+
result = shell_out("mknod #{path} b 1 2")
|
|
648
|
+
result.stderr.empty?
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
after(:each) do
|
|
652
|
+
FileUtils.rm_rf(path)
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
it_behaves_like "file resource not pointing to a real file"
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
context "when the target file is a chardev",:unix_only, :requires_root, :not_supported_on_solaris do
|
|
659
|
+
include Chef::Mixin::ShellOut
|
|
660
|
+
let(:path) do
|
|
661
|
+
File.join(CHEF_SPEC_DATA, "testdev")
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
before(:each) do
|
|
665
|
+
result = shell_out("mknod #{path} c 1 2")
|
|
666
|
+
result.stderr.empty?
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
after(:each) do
|
|
670
|
+
FileUtils.rm_rf(path)
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
it_behaves_like "file resource not pointing to a real file"
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
context "when the target file is a pipe",:unix_only do
|
|
677
|
+
include Chef::Mixin::ShellOut
|
|
678
|
+
let(:path) do
|
|
679
|
+
File.join(CHEF_SPEC_DATA, "testpipe")
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
before(:each) do
|
|
683
|
+
result = shell_out("mkfifo #{path}")
|
|
684
|
+
result.stderr.empty?
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
after(:each) do
|
|
688
|
+
FileUtils.rm_rf(path)
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
it_behaves_like "file resource not pointing to a real file"
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
context "when the target file is a socket",:unix_only do
|
|
695
|
+
require 'socket'
|
|
696
|
+
|
|
697
|
+
# It turns out that the path to a socket can have at most ~104
|
|
698
|
+
# bytes. Therefore we are creating our sockets in tmpdir so that
|
|
699
|
+
# they have a shorter path.
|
|
700
|
+
let(:test_socket_dir) { File.join(Dir.tmpdir, "sockets") }
|
|
701
|
+
|
|
702
|
+
before do
|
|
703
|
+
FileUtils::mkdir_p(test_socket_dir)
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
after do
|
|
707
|
+
FileUtils::rm_rf(test_socket_dir)
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
let(:path) do
|
|
711
|
+
File.join(test_socket_dir, "testsocket")
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
before(:each) do
|
|
715
|
+
path.bytesize.should <= 104
|
|
716
|
+
UNIXServer.new(path)
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
after(:each) do
|
|
720
|
+
FileUtils.rm_rf(path)
|
|
721
|
+
end
|
|
722
|
+
|
|
723
|
+
it_behaves_like "file resource not pointing to a real file"
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
# Regression test for http://tickets.opscode.com/browse/CHEF-4082
|
|
727
|
+
context "when notification is configured" do
|
|
728
|
+
describe "when path is specified with normal seperator" do
|
|
729
|
+
before do
|
|
730
|
+
@notified_resource = Chef::Resource.new("punk", resource.run_context)
|
|
731
|
+
resource.notifies(:run, @notified_resource, :immediately)
|
|
732
|
+
resource.run_action(:create)
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
it "should notify the other resources correctly" do
|
|
736
|
+
resource.should be_updated_by_last_action
|
|
737
|
+
resource.run_context.immediate_notifications(resource).length.should == 1
|
|
738
|
+
end
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
describe "when path is specified with windows seperator", :windows_only do
|
|
742
|
+
let(:path) {
|
|
743
|
+
File.join(test_file_dir, make_tmpname(file_base)).gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR)
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
before do
|
|
747
|
+
@notified_resource = Chef::Resource.new("punk", resource.run_context)
|
|
748
|
+
resource.notifies(:run, @notified_resource, :immediately)
|
|
749
|
+
resource.run_action(:create)
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
it "should notify the other resources correctly" do
|
|
753
|
+
resource.should be_updated_by_last_action
|
|
754
|
+
resource.run_context.immediate_notifications(resource).length.should == 1
|
|
755
|
+
end
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
|
|
175
759
|
context "when the target file does not exist" do
|
|
176
760
|
before do
|
|
177
761
|
# Assert starting state is expected
|
|
@@ -194,6 +778,10 @@ shared_examples_for "a file resource" do
|
|
|
194
778
|
it "is marked as updated by last action" do
|
|
195
779
|
resource.should be_updated_by_last_action
|
|
196
780
|
end
|
|
781
|
+
|
|
782
|
+
it "should restore the security contexts on selinux", :selinux_only do
|
|
783
|
+
selinux_security_context_restored?(path).should be_true
|
|
784
|
+
end
|
|
197
785
|
end
|
|
198
786
|
|
|
199
787
|
describe "when running action :create_if_missing" do
|
|
@@ -208,6 +796,10 @@ shared_examples_for "a file resource" do
|
|
|
208
796
|
it "is marked as updated by last action" do
|
|
209
797
|
resource.should be_updated_by_last_action
|
|
210
798
|
end
|
|
799
|
+
|
|
800
|
+
it "should restore the security contexts on selinux", :selinux_only do
|
|
801
|
+
selinux_security_context_restored?(path).should be_true
|
|
802
|
+
end
|
|
211
803
|
end
|
|
212
804
|
|
|
213
805
|
describe "when running action :delete" do
|
|
@@ -234,6 +826,15 @@ shared_examples_for "a file resource" do
|
|
|
234
826
|
[ ACE.access_denied(sid, expected_perms[:specific]) ]
|
|
235
827
|
end
|
|
236
828
|
|
|
829
|
+
def parent_inheritable_acls
|
|
830
|
+
dummy_file_path = File.join(test_file_dir, "dummy_file")
|
|
831
|
+
FileUtils.touch(dummy_file_path)
|
|
832
|
+
dummy_desc = get_security_descriptor(dummy_file_path)
|
|
833
|
+
FileUtils.rm_rf(dummy_file_path)
|
|
834
|
+
dummy_desc
|
|
835
|
+
end
|
|
836
|
+
|
|
837
|
+
it_behaves_like "a securable resource without existing target"
|
|
237
838
|
|
|
238
839
|
context "when the target file has the wrong content" do
|
|
239
840
|
before(:each) do
|
|
@@ -250,7 +851,7 @@ shared_examples_for "a file resource" do
|
|
|
250
851
|
|
|
251
852
|
it_behaves_like "a file with the wrong content"
|
|
252
853
|
|
|
253
|
-
it_behaves_like "a securable resource"
|
|
854
|
+
it_behaves_like "a securable resource with existing target"
|
|
254
855
|
end
|
|
255
856
|
|
|
256
857
|
context "and the target file has incorrect permissions" do
|
|
@@ -258,7 +859,7 @@ shared_examples_for "a file resource" do
|
|
|
258
859
|
|
|
259
860
|
it_behaves_like "a file with the wrong content"
|
|
260
861
|
|
|
261
|
-
it_behaves_like "a securable resource"
|
|
862
|
+
it_behaves_like "a securable resource with existing target"
|
|
262
863
|
end
|
|
263
864
|
end
|
|
264
865
|
|
|
@@ -282,46 +883,86 @@ shared_examples_for "a file resource" do
|
|
|
282
883
|
|
|
283
884
|
it_behaves_like "a file with the correct content"
|
|
284
885
|
|
|
285
|
-
it_behaves_like "a securable resource"
|
|
886
|
+
it_behaves_like "a securable resource with existing target"
|
|
286
887
|
end
|
|
287
888
|
|
|
288
889
|
context "and the target file has incorrect permissions" do
|
|
289
890
|
include_context "setup broken permissions"
|
|
290
891
|
|
|
291
892
|
it_behaves_like "a file with the correct content"
|
|
292
|
-
|
|
293
|
-
it_behaves_like "a securable resource"
|
|
893
|
+
|
|
894
|
+
it_behaves_like "a securable resource with existing target"
|
|
294
895
|
end
|
|
295
896
|
end
|
|
296
897
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
898
|
+
# Regression test for http://tickets.opscode.com/browse/CHEF-4419
|
|
899
|
+
context "when the path starts with '/' and target file exists", :windows_only do
|
|
900
|
+
let(:path) do
|
|
901
|
+
File.join(test_file_dir[2..test_file_dir.length], make_tmpname(file_base))
|
|
902
|
+
end
|
|
300
903
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
it "has only inherited aces if no explicit aces were specified" do
|
|
306
|
-
File.exist?(path).should == false
|
|
904
|
+
before do
|
|
905
|
+
File.open(path, "wb") { |f| f.print expected_content }
|
|
906
|
+
now = Time.now.to_i
|
|
907
|
+
File.utime(now - 9000, now - 9000, path)
|
|
307
908
|
|
|
308
|
-
|
|
909
|
+
@expected_mtime = File.stat(path).mtime
|
|
910
|
+
@expected_checksum = sha256_checksum(path)
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
describe ":create action should run without any updates" do
|
|
914
|
+
before do
|
|
915
|
+
# Assert starting state is as expected
|
|
916
|
+
File.should exist(path)
|
|
917
|
+
sha256_checksum(path).should == @expected_checksum
|
|
918
|
+
resource.run_action(:create)
|
|
919
|
+
end
|
|
309
920
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
921
|
+
it "does not overwrite the original when the :create action is run" do
|
|
922
|
+
sha256_checksum(path).should == @expected_checksum
|
|
923
|
+
end
|
|
924
|
+
|
|
925
|
+
it "does not update the mtime of the file when the :create action is run" do
|
|
926
|
+
File.stat(path).mtime.should == @expected_mtime
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
it "is not marked as updated by last action" do
|
|
930
|
+
resource.should_not be_updated_by_last_action
|
|
313
931
|
end
|
|
314
932
|
end
|
|
315
933
|
end
|
|
934
|
+
|
|
316
935
|
end
|
|
317
936
|
|
|
318
937
|
shared_context Chef::Resource::File do
|
|
938
|
+
if windows?
|
|
939
|
+
require 'chef/win32/file'
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
# We create the files in a different directory than tmp to exercise
|
|
943
|
+
# different file deployment strategies more completely.
|
|
944
|
+
let(:test_file_dir) do
|
|
945
|
+
if windows?
|
|
946
|
+
File.join(ENV['systemdrive'], "test-dir")
|
|
947
|
+
else
|
|
948
|
+
File.join(CHEF_SPEC_DATA, "test-dir")
|
|
949
|
+
end
|
|
950
|
+
end
|
|
951
|
+
|
|
319
952
|
let(:path) do
|
|
320
|
-
File.join(
|
|
953
|
+
File.join(test_file_dir, make_tmpname(file_base))
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
before do
|
|
957
|
+
FileUtils::mkdir_p(test_file_dir)
|
|
321
958
|
end
|
|
322
959
|
|
|
323
960
|
after(:each) do
|
|
324
961
|
FileUtils.rm_r(path) if File.exists?(path)
|
|
325
962
|
FileUtils.rm_r(CHEF_SPEC_BACKUP_PATH) if File.exists?(CHEF_SPEC_BACKUP_PATH)
|
|
326
963
|
end
|
|
964
|
+
|
|
965
|
+
after do
|
|
966
|
+
FileUtils::rm_rf(test_file_dir)
|
|
967
|
+
end
|
|
327
968
|
end
|