summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsersut <serdar@opscode.com>2013-10-17 15:28:23 -0700
committersersut <serdar@opscode.com>2013-10-17 15:28:23 -0700
commit180e9c1ec6cc324c598b3575a6ba2a209df44a24 (patch)
tree09bfce4f8c4e8f29a7c6c740f7ed86cec11d5737
parentc995e37339f37be82d7e5b1b7866bef64c1bd05a (diff)
parent05ba3e301794bd09173c5c3f13a62c2530d8b403 (diff)
downloadchef-180e9c1ec6cc324c598b3575a6ba2a209df44a24.tar.gz
Merge branch 'master' into 11-stable
-rw-r--r--.travis.yml8
-rw-r--r--CONTRIBUTING.md24
-rw-r--r--Gemfile21
-rw-r--r--NOTICE2
-rw-r--r--Rakefile26
-rwxr-xr-xbin/chef-apply4
-rwxr-xr-xbin/chef-client4
-rwxr-xr-xbin/chef-service-manager4
-rwxr-xr-xbin/chef-shell3
-rwxr-xr-xbin/chef-solo4
-rwxr-xr-xbin/knife6
-rw-r--r--chef-x86-mingw32.gemspec20
-rw-r--r--chef.gemspec24
-rwxr-xr-xci/jenkins_run_tests.sh2
-rw-r--r--distro/arch/etc/rc.d/chef-client4
-rw-r--r--distro/arch/etc/rc.d/chef-server4
-rw-r--r--distro/arch/etc/rc.d/chef-server-webui4
-rw-r--r--distro/arch/etc/rc.d/chef-solr4
-rw-r--r--distro/common/html/chef-client.8.html8
-rw-r--r--distro/common/html/chef-expander.8.html8
-rw-r--r--distro/common/html/chef-expanderctl.8.html8
-rw-r--r--distro/common/html/chef-server-webui.8.html8
-rw-r--r--distro/common/html/chef-server.8.html8
-rw-r--r--distro/common/html/chef-shell.1.html8
-rw-r--r--distro/common/html/chef-solo.8.html8
-rw-r--r--distro/common/html/chef-solr.8.html10
-rw-r--r--distro/common/html/knife-bootstrap.1.html8
-rw-r--r--distro/common/html/knife-client.1.html8
-rw-r--r--distro/common/html/knife-configure.1.html8
-rw-r--r--distro/common/html/knife-cookbook-site.1.html8
-rw-r--r--distro/common/html/knife-cookbook.1.html16
-rw-r--r--distro/common/html/knife-data-bag.1.html8
-rw-r--r--distro/common/html/knife-environment.1.html8
-rw-r--r--distro/common/html/knife-exec.1.html8
-rw-r--r--distro/common/html/knife-index.1.html8
-rw-r--r--distro/common/html/knife-node.1.html8
-rw-r--r--distro/common/html/knife-role.1.html8
-rw-r--r--distro/common/html/knife-search.1.html8
-rw-r--r--distro/common/html/knife-ssh.1.html8
-rw-r--r--distro/common/html/knife-status.1.html8
-rw-r--r--distro/common/html/knife-tag.1.html8
-rw-r--r--distro/common/html/knife.1.html8
-rw-r--r--distro/common/man/man1/README.md58
-rw-r--r--distro/common/man/man1/chef-shell.12
-rw-r--r--distro/common/man/man1/knife-bootstrap.1358
-rw-r--r--distro/common/man/man1/knife-client.1451
-rw-r--r--distro/common/man/man1/knife-configure.1234
-rw-r--r--distro/common/man/man1/knife-cookbook-site.1600
-rw-r--r--distro/common/man/man1/knife-cookbook.1920
-rw-r--r--distro/common/man/man1/knife-data-bag.1591
-rw-r--r--distro/common/man/man1/knife-delete.1134
-rw-r--r--distro/common/man/man1/knife-deps.1221
-rw-r--r--distro/common/man/man1/knife-diff.1214
-rw-r--r--distro/common/man/man1/knife-download.1222
-rw-r--r--distro/common/man/man1/knife-edit.1128
-rw-r--r--distro/common/man/man1/knife-environment.1466
-rw-r--r--distro/common/man/man1/knife-exec.1354
-rw-r--r--distro/common/man/man1/knife-index-rebuild.1117
-rw-r--r--distro/common/man/man1/knife-index.12
-rw-r--r--distro/common/man/man1/knife-list.1169
-rw-r--r--distro/common/man/man1/knife-node.1692
-rw-r--r--distro/common/man/man1/knife-raw.1172
-rw-r--r--distro/common/man/man1/knife-recipe-list.1135
-rw-r--r--distro/common/man/man1/knife-role.1450
-rw-r--r--distro/common/man/man1/knife-search.1512
-rw-r--r--distro/common/man/man1/knife-show.1140
-rw-r--r--distro/common/man/man1/knife-ssh.1303
-rw-r--r--distro/common/man/man1/knife-status.1228
-rw-r--r--distro/common/man/man1/knife-tag.1217
-rw-r--r--distro/common/man/man1/knife-upload.1241
-rw-r--r--distro/common/man/man1/knife-user.1319
-rw-r--r--distro/common/man/man1/knife-xargs.1168
-rw-r--r--distro/common/man/man1/knife.12
-rw-r--r--distro/common/man/man8/chef-client.82
-rw-r--r--distro/common/man/man8/chef-expander.82
-rw-r--r--distro/common/man/man8/chef-expanderctl.82
-rw-r--r--distro/common/man/man8/chef-server-webui.82
-rw-r--r--distro/common/man/man8/chef-server.82
-rw-r--r--distro/common/man/man8/chef-solo.82
-rw-r--r--distro/common/man/man8/chef-solr.82
-rw-r--r--distro/common/markdown/man1/knife-bootstrap.mkd2
-rw-r--r--distro/common/markdown/man1/knife-configure.mkd22
-rw-r--r--distro/common/markdown/man1/knife-cookbook.mkd8
-rw-r--r--distro/common/markdown/man8/chef-expander.mkd2
-rw-r--r--distro/common/markdown/man8/chef-expanderctl.mkd2
-rwxr-xr-xdistro/debian/etc/init.d/chef-client2
-rwxr-xr-xdistro/debian/etc/init.d/chef-expander2
-rwxr-xr-xdistro/debian/etc/init.d/chef-server2
-rwxr-xr-xdistro/debian/etc/init.d/chef-server-webui2
-rwxr-xr-xdistro/debian/etc/init.d/chef-solr2
-rw-r--r--distro/debian/etc/init/chef-client.conf2
-rw-r--r--distro/debian/etc/init/chef-expander.conf2
-rw-r--r--distro/debian/etc/init/chef-server-webui.conf2
-rw-r--r--distro/debian/etc/init/chef-server.conf2
-rw-r--r--distro/debian/etc/init/chef-solr.conf2
-rw-r--r--distro/redhat/etc/init.d/chef-client2
-rw-r--r--distro/redhat/etc/init.d/chef-server4
-rw-r--r--distro/redhat/etc/init.d/chef-server-webui4
-rw-r--r--distro/redhat/etc/init.d/chef-solr4
-rw-r--r--lib/chef/api_client.rb25
-rw-r--r--lib/chef/application.rb75
-rw-r--r--lib/chef/application/agent.rb4
-rw-r--r--lib/chef/application/client.rb58
-rw-r--r--lib/chef/application/knife.rb10
-rw-r--r--lib/chef/application/solo.rb36
-rw-r--r--lib/chef/application/windows_service.rb34
-rw-r--r--lib/chef/application/windows_service_manager.rb8
-rw-r--r--lib/chef/checksum/storage.rb4
-rw-r--r--lib/chef/checksum/storage/filesystem.rb4
-rw-r--r--lib/chef/chef_fs/chef_fs_data_store.rb2
-rw-r--r--lib/chef/chef_fs/command_line.rb3
-rw-r--r--lib/chef/chef_fs/config.rb83
-rw-r--r--lib/chef/chef_fs/data_handler/client_data_handler.rb3
-rw-r--r--lib/chef/chef_fs/file_system.rb4
-rw-r--r--lib/chef/chef_fs/file_system/acl_entry.rb2
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_acls_dir.rb37
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb24
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb23
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb39
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb34
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb17
-rw-r--r--lib/chef/chef_fs/file_system/chef_server_root_dir.rb14
-rw-r--r--lib/chef/chef_fs/file_system/cookbook_dir.rb5
-rw-r--r--lib/chef/chef_fs/file_system/cookbook_file.rb7
-rw-r--r--lib/chef/chef_fs/file_system/cookbooks_dir.rb27
-rw-r--r--lib/chef/chef_fs/file_system/data_bag_dir.rb2
-rw-r--r--lib/chef/chef_fs/file_system/data_bags_dir.rb5
-rw-r--r--lib/chef/chef_fs/file_system/file_system_entry.rb20
-rw-r--r--lib/chef/chef_fs/file_system/multiplexed_dir.rb3
-rw-r--r--lib/chef/chef_fs/file_system/nodes_dir.rb2
-rw-r--r--lib/chef/chef_fs/file_system/operation_failed_error.rb8
-rw-r--r--lib/chef/chef_fs/file_system/rest_list_dir.rb6
-rw-r--r--lib/chef/chef_fs/file_system/rest_list_entry.rb10
-rw-r--r--lib/chef/chef_fs/knife.rb61
-rw-r--r--lib/chef/chef_fs/path_utils.rb5
-rw-r--r--lib/chef/chef_fs/raw_request.rb79
-rw-r--r--lib/chef/client.rb12
-rw-r--r--lib/chef/config.rb393
-rw-r--r--lib/chef/config_fetcher.rb79
-rw-r--r--lib/chef/cookbook/file_vendor.rb10
-rw-r--r--lib/chef/cookbook/metadata.rb4
-rw-r--r--lib/chef/cookbook/syntax_check.rb22
-rw-r--r--lib/chef/cookbook_site_streaming_uploader.rb12
-rw-r--r--lib/chef/cookbook_uploader.rb18
-rw-r--r--lib/chef/cookbook_version.rb32
-rw-r--r--lib/chef/daemon.rb89
-rw-r--r--lib/chef/data_bag.rb5
-rw-r--r--lib/chef/dsl/include_recipe.rb4
-rw-r--r--lib/chef/event_dispatch/base.rb2
-rw-r--r--lib/chef/event_dispatch/dispatcher.rb2
-rw-r--r--lib/chef/file_access_control/windows.rb2
-rw-r--r--lib/chef/formatters/doc.rb10
-rw-r--r--lib/chef/formatters/error_inspectors/api_error_formatting.rb4
-rw-r--r--lib/chef/formatters/error_inspectors/compile_error_inspector.rb4
-rw-r--r--lib/chef/formatters/error_inspectors/cookbook_sync_error_inspector.rb4
-rw-r--r--lib/chef/formatters/error_inspectors/node_load_error_inspector.rb4
-rw-r--r--lib/chef/formatters/error_inspectors/resource_failure_inspector.rb4
-rw-r--r--lib/chef/handler/json_file.rb4
-rw-r--r--lib/chef/http.rb386
-rw-r--r--lib/chef/http/auth_credentials.rb (renamed from lib/chef/rest/auth_credentials.rb)2
-rw-r--r--lib/chef/http/authenticator.rb89
-rw-r--r--lib/chef/http/basic_client.rb114
-rw-r--r--lib/chef/http/cookie_jar.rb (renamed from lib/chef/rest/cookie_jar.rb)2
-rw-r--r--lib/chef/http/cookie_manager.rb56
-rw-r--r--lib/chef/http/decompressor.rb137
-rw-r--r--lib/chef/http/http_request.rb (renamed from lib/chef/rest/rest_request.rb)87
-rw-r--r--lib/chef/http/json_input.rb53
-rw-r--r--lib/chef/http/json_output.rb69
-rw-r--r--lib/chef/http/json_to_model_output.rb34
-rw-r--r--lib/chef/http/simple.rb16
-rw-r--r--lib/chef/http/ssl_policies.rb121
-rw-r--r--lib/chef/knife.rb68
-rw-r--r--lib/chef/knife/bootstrap.rb13
-rw-r--r--lib/chef/knife/bootstrap/chef-full.erb10
-rw-r--r--lib/chef/knife/client_create.rb2
-rw-r--r--lib/chef/knife/configure.rb2
-rw-r--r--lib/chef/knife/cookbook_create.rb14
-rw-r--r--lib/chef/knife/cookbook_download.rb4
-rw-r--r--lib/chef/knife/cookbook_metadata_from_file.rb4
-rw-r--r--lib/chef/knife/cookbook_show.rb6
-rw-r--r--lib/chef/knife/cookbook_site_install.rb4
-rw-r--r--lib/chef/knife/cookbook_site_list.rb4
-rw-r--r--lib/chef/knife/cookbook_site_search.rb6
-rw-r--r--lib/chef/knife/cookbook_site_show.rb10
-rw-r--r--lib/chef/knife/core/bootstrap_context.rb10
-rw-r--r--lib/chef/knife/core/node_presenter.rb2
-rw-r--r--lib/chef/knife/core/subcommand_loader.rb10
-rw-r--r--lib/chef/knife/core/ui.rb2
-rw-r--r--lib/chef/knife/data_bag_create.rb12
-rw-r--r--lib/chef/knife/data_bag_delete.rb6
-rw-r--r--lib/chef/knife/data_bag_edit.rb16
-rw-r--r--lib/chef/knife/data_bag_from_file.rb18
-rw-r--r--lib/chef/knife/data_bag_list.rb4
-rw-r--r--lib/chef/knife/data_bag_show.rb16
-rw-r--r--lib/chef/knife/delete.rb2
-rw-r--r--lib/chef/knife/deps.rb2
-rw-r--r--lib/chef/knife/diff.rb6
-rw-r--r--lib/chef/knife/download.rb6
-rw-r--r--lib/chef/knife/edit.rb2
-rw-r--r--lib/chef/knife/environment_from_file.rb4
-rw-r--r--lib/chef/knife/index_rebuild.rb4
-rw-r--r--lib/chef/knife/list.rb2
-rw-r--r--lib/chef/knife/raw.rb36
-rw-r--r--lib/chef/knife/show.rb2
-rw-r--r--lib/chef/knife/ssh.rb28
-rw-r--r--lib/chef/knife/status.rb2
-rw-r--r--lib/chef/knife/upload.rb2
-rw-r--r--lib/chef/knife/xargs.rb2
-rw-r--r--lib/chef/mixin/checksum.rb4
-rw-r--r--lib/chef/mixin/command.rb43
-rw-r--r--lib/chef/mixin/convert_to_class_name.rb16
-rw-r--r--lib/chef/mixin/create_path.rb18
-rw-r--r--lib/chef/mixin/deep_merge.rb4
-rw-r--r--lib/chef/mixin/from_file.rb12
-rw-r--r--lib/chef/mixin/language_include_recipe.rb4
-rw-r--r--lib/chef/mixin/params_validate.rb42
-rw-r--r--lib/chef/mixin/shell_out.rb9
-rw-r--r--lib/chef/mixin/template.rb29
-rw-r--r--lib/chef/mixin/why_run.rb32
-rw-r--r--lib/chef/mixin/windows_architecture_helper.rb10
-rw-r--r--lib/chef/mixin/xml_escape.rb20
-rw-r--r--lib/chef/monkey_patches/numeric.rb2
-rw-r--r--lib/chef/monkey_patches/regexp.rb8
-rw-r--r--lib/chef/monkey_patches/string.rb6
-rw-r--r--lib/chef/monkey_patches/tempfile.rb4
-rw-r--r--lib/chef/node.rb8
-rw-r--r--lib/chef/node/attribute.rb2
-rw-r--r--lib/chef/platform/provider_mapping.rb27
-rw-r--r--lib/chef/provider/batch.rb6
-rw-r--r--lib/chef/provider/cron.rb40
-rw-r--r--lib/chef/provider/cron/aix.rb48
-rw-r--r--lib/chef/provider/cron/solaris.rb46
-rw-r--r--lib/chef/provider/cron/unix.rb76
-rw-r--r--lib/chef/provider/deploy/timestamped.rb8
-rw-r--r--lib/chef/provider/erl_call.rb2
-rw-r--r--lib/chef/provider/execute.rb4
-rw-r--r--lib/chef/provider/git.rb1
-rw-r--r--lib/chef/provider/group.rb42
-rw-r--r--lib/chef/provider/group/dscl.rb18
-rw-r--r--lib/chef/provider/group/gpasswd.rb10
-rw-r--r--lib/chef/provider/group/groupadd.rb21
-rw-r--r--lib/chef/provider/group/pw.rb22
-rw-r--r--lib/chef/provider/group/suse.rb8
-rw-r--r--lib/chef/provider/group/usermod.rb16
-rw-r--r--lib/chef/provider/group/windows.rb18
-rw-r--r--lib/chef/provider/http_request.rb16
-rw-r--r--lib/chef/provider/ifconfig.rb94
-rw-r--r--lib/chef/provider/ifconfig/aix.rb99
-rw-r--r--lib/chef/provider/log.rb6
-rw-r--r--lib/chef/provider/mdadm.rb9
-rw-r--r--lib/chef/provider/mount.rb24
-rw-r--r--lib/chef/provider/mount/aix.rb179
-rw-r--r--lib/chef/provider/mount/mount.rb44
-rw-r--r--lib/chef/provider/package.rb42
-rw-r--r--lib/chef/provider/package/aix.rb146
-rw-r--r--lib/chef/provider/package/apt.rb47
-rw-r--r--lib/chef/provider/package/dpkg.rb18
-rw-r--r--lib/chef/provider/package/freebsd.rb4
-rw-r--r--lib/chef/provider/package/ips.rb6
-rw-r--r--lib/chef/provider/package/macports.rb2
-rw-r--r--lib/chef/provider/package/pacman.rb16
-rw-r--r--lib/chef/provider/package/rpm.rb28
-rw-r--r--lib/chef/provider/package/rubygems.rb2
-rw-r--r--lib/chef/provider/package/smartos.rb6
-rw-r--r--lib/chef/provider/package/solaris.rb22
-rw-r--r--lib/chef/provider/package/yum-dump.py8
-rw-r--r--lib/chef/provider/package/yum.rb6
-rw-r--r--lib/chef/provider/powershell_script.rb14
-rw-r--r--lib/chef/provider/remote_file/ftp.rb1
-rw-r--r--lib/chef/provider/remote_file/http.rb10
-rw-r--r--lib/chef/provider/remote_file/local_file.rb1
-rw-r--r--lib/chef/provider/resource_update.rb18
-rw-r--r--lib/chef/provider/ruby_block.rb6
-rw-r--r--lib/chef/provider/script.rb2
-rw-r--r--lib/chef/provider/service.rb4
-rw-r--r--lib/chef/provider/service/debian.rb50
-rw-r--r--lib/chef/provider/service/freebsd.rb18
-rw-r--r--lib/chef/provider/service/gentoo.rb8
-rw-r--r--lib/chef/provider/service/init.rb2
-rw-r--r--lib/chef/provider/service/insserv.rb4
-rw-r--r--lib/chef/provider/service/invokercd.rb2
-rw-r--r--lib/chef/provider/service/redhat.rb4
-rw-r--r--lib/chef/provider/service/simple.rb12
-rw-r--r--lib/chef/provider/service/solaris.rb2
-rw-r--r--lib/chef/provider/service/systemd.rb6
-rw-r--r--lib/chef/provider/service/upstart.rb30
-rw-r--r--lib/chef/provider/subversion.rb11
-rw-r--r--lib/chef/provider/user.rb22
-rw-r--r--lib/chef/provider/user/dscl.rb56
-rw-r--r--lib/chef/provider/user/pw.rb22
-rw-r--r--lib/chef/provider/user/useradd.rb2
-rw-r--r--lib/chef/provider/user/windows.rb14
-rw-r--r--lib/chef/provider/windows_script.rb14
-rw-r--r--lib/chef/providers.rb4
-rw-r--r--lib/chef/recipe.rb21
-rw-r--r--lib/chef/resource/apt_package.rb6
-rw-r--r--lib/chef/resource/bash.rb6
-rw-r--r--lib/chef/resource/batch.rb8
-rw-r--r--lib/chef/resource/bff_package.rb36
-rw-r--r--lib/chef/resource/breakpoint.rb6
-rw-r--r--lib/chef/resource/cron.rb10
-rw-r--r--lib/chef/resource/csh.rb6
-rw-r--r--lib/chef/resource/deploy.rb19
-rw-r--r--lib/chef/resource/deploy_revision.rb12
-rw-r--r--lib/chef/resource/directory.rb4
-rw-r--r--lib/chef/resource/dpkg_package.rb8
-rw-r--r--lib/chef/resource/easy_install_package.rb2
-rw-r--r--lib/chef/resource/erl_call.rb2
-rw-r--r--lib/chef/resource/freebsd_package.rb8
-rw-r--r--lib/chef/resource/group.rb21
-rw-r--r--lib/chef/resource/http_request.rb12
-rw-r--r--lib/chef/resource/ifconfig.rb8
-rw-r--r--lib/chef/resource/ips_package.rb4
-rw-r--r--lib/chef/resource/log.rb23
-rw-r--r--lib/chef/resource/macports_package.rb4
-rw-r--r--lib/chef/resource/mount.rb23
-rw-r--r--lib/chef/resource/ohai.rb6
-rw-r--r--lib/chef/resource/pacman_package.rb8
-rw-r--r--lib/chef/resource/perl.rb6
-rw-r--r--lib/chef/resource/portage_package.rb8
-rw-r--r--lib/chef/resource/powershell_script.rb6
-rw-r--r--lib/chef/resource/python.rb6
-rw-r--r--lib/chef/resource/route.rb8
-rw-r--r--lib/chef/resource/rpm_package.rb4
-rw-r--r--lib/chef/resource/ruby.rb6
-rw-r--r--lib/chef/resource/ruby_block.rb6
-rw-r--r--lib/chef/resource/scm.rb12
-rw-r--r--lib/chef/resource/script.rb10
-rw-r--r--lib/chef/resource/service.rb10
-rw-r--r--lib/chef/resource/smartos_package.rb14
-rw-r--r--lib/chef/resource/solaris_package.rb15
-rw-r--r--lib/chef/resource/subversion.rb6
-rw-r--r--lib/chef/resource/timestamped_deploy.rb8
-rw-r--r--lib/chef/resource/user.rb26
-rw-r--r--lib/chef/resource/windows_script.rb12
-rw-r--r--lib/chef/resource/yum_package.rb4
-rw-r--r--lib/chef/resource_collection.rb2
-rw-r--r--lib/chef/resource_collection/stepable_iterator.rb44
-rw-r--r--lib/chef/resource_definition.rb16
-rw-r--r--lib/chef/resource_definition_list.rb4
-rw-r--r--lib/chef/resource_reporter.rb10
-rw-r--r--lib/chef/resources.rb2
-rw-r--r--lib/chef/rest.rb404
-rw-r--r--lib/chef/role.rb30
-rw-r--r--lib/chef/run_context.rb14
-rw-r--r--lib/chef/run_context/cookbook_compiler.rb6
-rw-r--r--lib/chef/run_lock.rb93
-rw-r--r--lib/chef/server_api.rb41
-rw-r--r--lib/chef/shell.rb22
-rw-r--r--lib/chef/shell/shell_session.rb2
-rw-r--r--lib/chef/streaming_cookbook_uploader.rb56
-rw-r--r--lib/chef/tasks/chef_repo.rake34
-rw-r--r--lib/chef/util/backup.rb3
-rw-r--r--lib/chef/util/diff.rb109
-rw-r--r--lib/chef/util/windows.rb4
-rw-r--r--lib/chef/util/windows/net_group.rb4
-rw-r--r--lib/chef/util/windows/net_use.rb4
-rw-r--r--lib/chef/util/windows/net_user.rb6
-rw-r--r--lib/chef/util/windows/volume.rb6
-rw-r--r--lib/chef/version.rb6
-rw-r--r--lib/chef/win32/api/file.rb2
-rw-r--r--lib/chef/win32/api/synchronization.rb89
-rw-r--r--lib/chef/win32/handle.rb2
-rw-r--r--lib/chef/win32/mutex.rb94
-rw-r--r--lib/chef/win32/security/ace.rb2
-rw-r--r--lib/chef/win32/security/sid.rb2
-rw-r--r--lib/chef/win32/version.rb8
-rw-r--r--spec/data/bootstrap/no_proxy.erb2
-rw-r--r--spec/data/cookbooks/openldap/metadata.rb8
-rw-r--r--spec/data/cookbooks/preseed/files/default/preseed-template.seed4
-rw-r--r--spec/data/trusted_certs/example.crt22
-rw-r--r--spec/data/trusted_certs/intermediate.pem27
-rw-r--r--spec/data/trusted_certs/opscode.pem38
-rw-r--r--spec/data/trusted_certs/root.pem22
-rw-r--r--spec/functional/assets/PkgA.1.0.0.0.bffbin0 -> 3584 bytes
-rw-r--r--spec/functional/assets/PkgA.2.0.0.0.bffbin0 -> 3584 bytes
-rw-r--r--spec/functional/assets/dummy-1-0.aix6.1.noarch.rpmbin0 -> 972 bytes
-rw-r--r--spec/functional/assets/dummy-2-0.aix6.1.noarch.rpmbin0 -> 972 bytes
-rw-r--r--spec/functional/assets/mytest-1.0-1.noarch.rpmbin0 -> 2126 bytes
-rw-r--r--spec/functional/assets/mytest-2.0-1.noarch.rpmbin0 -> 2149 bytes
-rw-r--r--spec/functional/knife/cookbook_delete_spec.rb11
-rw-r--r--spec/functional/knife/exec_spec.rb3
-rw-r--r--spec/functional/knife/ssh_spec.rb8
-rw-r--r--spec/functional/resource/base.rb41
-rw-r--r--spec/functional/resource/batch_spec.rb39
-rw-r--r--spec/functional/resource/bff_spec.rb122
-rw-r--r--spec/functional/resource/cron_spec.rb147
-rw-r--r--spec/functional/resource/group_spec.rb204
-rw-r--r--spec/functional/resource/ifconfig_spec.rb163
-rw-r--r--spec/functional/resource/link_spec.rb8
-rw-r--r--spec/functional/resource/mount_spec.rb207
-rw-r--r--spec/functional/resource/package_spec.rb112
-rw-r--r--spec/functional/resource/powershell_spec.rb43
-rw-r--r--spec/functional/resource/registry_spec.rb24
-rw-r--r--spec/functional/resource/rpm_spec.rb122
-rw-r--r--spec/functional/resource/template_spec.rb55
-rw-r--r--spec/functional/resource/user_spec.rb3
-rw-r--r--spec/functional/run_lock_spec.rb53
-rw-r--r--spec/functional/shell_spec.rb72
-rw-r--r--spec/functional/tiny_server_spec.rb4
-rw-r--r--spec/functional/win32/versions_spec.rb6
-rw-r--r--spec/integration/client/client_spec.rb146
-rw-r--r--spec/integration/knife/chef_fs_data_store_spec.rb353
-rw-r--r--spec/integration/knife/chef_repo_path_spec.rb91
-rw-r--r--spec/integration/knife/common_options_spec.rb103
-rw-r--r--spec/integration/knife/download_spec.rb40
-rw-r--r--spec/integration/knife/raw_spec.rb63
-rw-r--r--spec/integration/knife/upload_spec.rb24
-rw-r--r--spec/integration/solo/solo_spec.rb103
-rw-r--r--spec/spec_helper.rb36
-rw-r--r--spec/support/lib/chef/provider/easy.rb8
-rw-r--r--spec/support/lib/chef/provider/snakeoil.rb8
-rw-r--r--spec/support/lib/chef/resource/cat.rb10
-rw-r--r--spec/support/lib/chef/resource/with_state.rb37
-rw-r--r--spec/support/lib/library_load_order.rb22
-rw-r--r--spec/support/platform_helpers.rb8
-rw-r--r--spec/support/shared/functional/file_resource.rb26
-rw-r--r--spec/support/shared/functional/windows_script.rb48
-rw-r--r--spec/support/shared/integration/integration_helper.rb27
-rw-r--r--spec/support/shared/integration/knife_support.rb6
-rw-r--r--spec/support/shared/unit/script_resource.rb14
-rw-r--r--spec/support/shared/unit/windows_script_resource.rb14
-rw-r--r--spec/tiny_server.rb4
-rw-r--r--spec/unit/api_client/registration_spec.rb2
-rw-r--r--spec/unit/api_client_spec.rb27
-rw-r--r--spec/unit/application/apply.rb10
-rw-r--r--spec/unit/application/client_spec.rb63
-rw-r--r--spec/unit/application/solo_spec.rb60
-rw-r--r--spec/unit/application_spec.rb131
-rw-r--r--spec/unit/checksum/storage/filesystem_spec.rb5
-rw-r--r--spec/unit/chef_fs/file_system/operation_failed_error_spec.rb47
-rw-r--r--spec/unit/chef_spec.rb4
-rw-r--r--spec/unit/client_spec.rb20
-rw-r--r--spec/unit/config_fetcher_spec.rb98
-rw-r--r--spec/unit/config_spec.rb96
-rw-r--r--spec/unit/cookbook/metadata_spec.rb100
-rw-r--r--spec/unit/cookbook/synchronizer_spec.rb6
-rw-r--r--spec/unit/cookbook/syntax_check_spec.rb3
-rw-r--r--spec/unit/cookbook_loader_spec.rb40
-rw-r--r--spec/unit/cookbook_manifest_spec.rb22
-rw-r--r--spec/unit/cookbook_site_streaming_uploader.rb200
-rw-r--r--spec/unit/cookbook_version_spec.rb16
-rw-r--r--spec/unit/daemon_spec.rb132
-rw-r--r--spec/unit/data_bag_item_spec.rb12
-rw-r--r--spec/unit/data_bag_spec.rb14
-rw-r--r--spec/unit/digester_spec.rb4
-rw-r--r--spec/unit/encrypted_data_bag_item_spec.rb15
-rw-r--r--spec/unit/file_cache_spec.rb2
-rw-r--r--spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb8
-rw-r--r--spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb4
-rw-r--r--spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb4
-rw-r--r--spec/unit/formatters/error_inspectors/node_load_error_inspector_spec.rb4
-rw-r--r--spec/unit/formatters/error_inspectors/registration_error_inspector_spec.rb4
-rw-r--r--spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb8
-rw-r--r--spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb4
-rw-r--r--spec/unit/handler_spec.rb10
-rw-r--r--spec/unit/http/ssl_policies_spec.rb161
-rw-r--r--spec/unit/knife/bootstrap_spec.rb45
-rw-r--r--spec/unit/knife/client_bulk_delete_spec.rb16
-rw-r--r--spec/unit/knife/client_create_spec.rb4
-rw-r--r--spec/unit/knife/client_delete_spec.rb4
-rw-r--r--spec/unit/knife/client_edit_spec.rb4
-rw-r--r--spec/unit/knife/client_list_spec.rb4
-rw-r--r--spec/unit/knife/client_reregister_spec.rb4
-rw-r--r--spec/unit/knife/client_show_spec.rb4
-rw-r--r--spec/unit/knife/config_file_selection_spec.rb89
-rw-r--r--spec/unit/knife/configure_spec.rb6
-rw-r--r--spec/unit/knife/cookbook_create_spec.rb13
-rw-r--r--spec/unit/knife/cookbook_metadata_from_file_spec.rb4
-rw-r--r--spec/unit/knife/cookbook_show_spec.rb6
-rw-r--r--spec/unit/knife/cookbook_site_install_spec.rb2
-rw-r--r--spec/unit/knife/core/bootstrap_context_spec.rb12
-rw-r--r--spec/unit/knife/data_bag_show_spec.rb4
-rw-r--r--spec/unit/knife/environment_from_file_spec.rb4
-rw-r--r--spec/unit/knife/index_rebuild_spec.rb2
-rw-r--r--spec/unit/knife/node_delete_spec.rb6
-rw-r--r--spec/unit/knife/node_edit_spec.rb4
-rw-r--r--spec/unit/knife/node_list_spec.rb6
-rw-r--r--spec/unit/knife/node_run_list_add_spec.rb6
-rw-r--r--spec/unit/knife/node_show_spec.rb6
-rw-r--r--spec/unit/knife/role_create_spec.rb6
-rw-r--r--spec/unit/knife/role_delete_spec.rb6
-rw-r--r--spec/unit/knife/role_list_spec.rb4
-rw-r--r--spec/unit/knife/ssh_spec.rb9
-rw-r--r--spec/unit/knife_spec.rb2
-rw-r--r--spec/unit/log_spec.rb4
-rw-r--r--spec/unit/mash_spec.rb4
-rw-r--r--spec/unit/mixin/checksum_spec.rb6
-rw-r--r--spec/unit/mixin/convert_to_class_name_spec.rb14
-rw-r--r--spec/unit/mixin/deprecation_spec.rb4
-rw-r--r--spec/unit/mixin/params_validate_spec.rb144
-rw-r--r--spec/unit/mixin/securable_spec.rb14
-rw-r--r--spec/unit/mixin/shell_out_spec.rb2
-rw-r--r--spec/unit/mixin/template_spec.rb34
-rw-r--r--spec/unit/mixin/windows_architecture_helper_spec.rb10
-rw-r--r--spec/unit/mixin/xml_escape_spec.rb4
-rw-r--r--spec/unit/node/attribute_spec.rb22
-rw-r--r--spec/unit/node/immutable_collections_spec.rb4
-rw-r--r--spec/unit/node_spec.rb5
-rw-r--r--spec/unit/platform_spec.rb71
-rw-r--r--spec/unit/provider/cron/unix_spec.rb (renamed from spec/unit/provider/cron/solaris_spec.rb)12
-rw-r--r--spec/unit/provider/cron_spec.rb24
-rw-r--r--spec/unit/provider/deploy/timestamped_spec.rb10
-rw-r--r--spec/unit/provider/deploy_spec.rb28
-rw-r--r--spec/unit/provider/env_spec.rb4
-rw-r--r--spec/unit/provider/execute_spec.rb4
-rw-r--r--spec/unit/provider/file/content_spec.rb8
-rw-r--r--spec/unit/provider/git_spec.rb38
-rw-r--r--spec/unit/provider/group/dscl_spec.rb24
-rw-r--r--spec/unit/provider/group/gpasswd_spec.rb4
-rw-r--r--spec/unit/provider/group/groupadd_spec.rb14
-rw-r--r--spec/unit/provider/group/groupmod_spec.rb26
-rw-r--r--spec/unit/provider/group/pw_spec.rb32
-rw-r--r--spec/unit/provider/group/usermod_spec.rb19
-rw-r--r--spec/unit/provider/group/windows_spec.rb14
-rw-r--r--spec/unit/provider/group_spec.rb58
-rw-r--r--spec/unit/provider/http_request_spec.rb30
-rw-r--r--spec/unit/provider/ifconfig/aix_spec.rb180
-rw-r--r--spec/unit/provider/ifconfig_spec.rb18
-rw-r--r--spec/unit/provider/link_spec.rb4
-rw-r--r--spec/unit/provider/log_spec.rb16
-rw-r--r--spec/unit/provider/mdadm_spec.rb25
-rw-r--r--spec/unit/provider/mount/aix_spec.rb237
-rw-r--r--spec/unit/provider/mount/mount_spec.rb2
-rw-r--r--spec/unit/provider/mount/windows_spec.rb4
-rw-r--r--spec/unit/provider/mount_spec.rb12
-rw-r--r--spec/unit/provider/package/aix_spec.rb171
-rw-r--r--spec/unit/provider/package/apt_spec.rb301
-rw-r--r--spec/unit/provider/package/dpkg_spec.rb6
-rw-r--r--spec/unit/provider/package/freebsd_spec.rb28
-rw-r--r--spec/unit/provider/package/ips_spec.rb2
-rw-r--r--spec/unit/provider/package/rpm_spec.rb30
-rw-r--r--spec/unit/provider/package/smartos_spec.rb24
-rw-r--r--spec/unit/provider/package_spec.rb6
-rw-r--r--spec/unit/provider/powershell_spec.rb6
-rw-r--r--spec/unit/provider/remote_directory_spec.rb4
-rw-r--r--spec/unit/provider/remote_file/ftp_spec.rb5
-rw-r--r--spec/unit/provider/remote_file/http_spec.rb20
-rw-r--r--spec/unit/provider/remote_file/local_file_spec.rb3
-rw-r--r--spec/unit/provider/route_spec.rb4
-rw-r--r--spec/unit/provider/ruby_block_spec.rb4
-rw-r--r--spec/unit/provider/service/arch_service_spec.rb34
-rw-r--r--spec/unit/provider/service/debian_service_spec.rb394
-rw-r--r--spec/unit/provider/service/freebsd_service_spec.rb18
-rw-r--r--spec/unit/provider/service/gentoo_service_spec.rb18
-rw-r--r--spec/unit/provider/service/init_service_spec.rb22
-rw-r--r--spec/unit/provider/service/insserv_service_spec.rb10
-rw-r--r--spec/unit/provider/service/invokercd_service_spec.rb20
-rw-r--r--spec/unit/provider/service/redhat_spec.rb12
-rw-r--r--spec/unit/provider/service/simple_service_spec.rb12
-rw-r--r--spec/unit/provider/service/solaris_smf_service_spec.rb8
-rw-r--r--spec/unit/provider/service/systemd_service_spec.rb6
-rw-r--r--spec/unit/provider/service/upstart_service_spec.rb10
-rw-r--r--spec/unit/provider/service/windows_spec.rb14
-rw-r--r--spec/unit/provider/subversion_spec.rb2
-rw-r--r--spec/unit/provider/user/dscl_spec.rb42
-rw-r--r--spec/unit/provider/user/pw_spec.rb4
-rw-r--r--spec/unit/provider/user/windows_spec.rb10
-rw-r--r--spec/unit/provider/user_spec.rb86
-rw-r--r--spec/unit/resource/apt_package_spec.rb12
-rw-r--r--spec/unit/resource/bash_spec.rb10
-rw-r--r--spec/unit/resource/batch_spec.rb14
-rw-r--r--spec/unit/resource/breakpoint_spec.rb16
-rw-r--r--spec/unit/resource/chef_gem_spec.rb12
-rw-r--r--spec/unit/resource/cookbook_file_spec.rb22
-rw-r--r--spec/unit/resource/cron_spec.rb30
-rw-r--r--spec/unit/resource/csh_spec.rb10
-rw-r--r--spec/unit/resource/deploy_revision_spec.rb12
-rw-r--r--spec/unit/resource/deploy_spec.rb86
-rw-r--r--spec/unit/resource/directory_spec.rb2
-rw-r--r--spec/unit/resource/dpkg_package_spec.rb12
-rw-r--r--spec/unit/resource/env_spec.rb2
-rw-r--r--spec/unit/resource/erl_call_spec.rb2
-rw-r--r--spec/unit/resource/freebsd_package_spec.rb12
-rw-r--r--spec/unit/resource/gem_package_spec.rb12
-rw-r--r--spec/unit/resource/git_spec.rb16
-rw-r--r--spec/unit/resource/group_spec.rb22
-rw-r--r--spec/unit/resource/http_request_spec.rb14
-rw-r--r--spec/unit/resource/ifconfig_spec.rb2
-rw-r--r--spec/unit/resource/ips_package_spec.rb12
-rw-r--r--spec/unit/resource/link_spec.rb2
-rw-r--r--spec/unit/resource/log_spec.rb23
-rw-r--r--spec/unit/resource/macports_package_spec.rb4
-rw-r--r--spec/unit/resource/mdadm_spec.rb6
-rw-r--r--spec/unit/resource/mount_spec.rb26
-rw-r--r--spec/unit/resource/ohai_spec.rb2
-rw-r--r--spec/unit/resource/package_spec.rb12
-rw-r--r--spec/unit/resource/pacman_package_spec.rb12
-rw-r--r--spec/unit/resource/perl_spec.rb10
-rw-r--r--spec/unit/resource/portage_package_spec.rb12
-rw-r--r--spec/unit/resource/powershell_spec.rb10
-rw-r--r--spec/unit/resource/python_spec.rb10
-rw-r--r--spec/unit/resource/registry_key_spec.rb4
-rw-r--r--spec/unit/resource/remote_directory_spec.rb18
-rw-r--r--spec/unit/resource/remote_file_spec.rb8
-rw-r--r--spec/unit/resource/route_spec.rb26
-rw-r--r--spec/unit/resource/rpm_package_spec.rb4
-rw-r--r--spec/unit/resource/ruby_block_spec.rb8
-rw-r--r--spec/unit/resource/ruby_spec.rb10
-rw-r--r--spec/unit/resource/scm_spec.rb15
-rw-r--r--spec/unit/resource/script_spec.rb10
-rw-r--r--spec/unit/resource/service_spec.rb36
-rw-r--r--spec/unit/resource/smartos_package_spec.rb12
-rw-r--r--spec/unit/resource/solaris_package_spec.rb57
-rw-r--r--spec/unit/resource/subversion_spec.rb12
-rw-r--r--spec/unit/resource/timestamped_deploy_spec.rb8
-rw-r--r--spec/unit/resource/user_spec.rb26
-rw-r--r--spec/unit/resource/yum_package_spec.rb14
-rw-r--r--spec/unit/resource_collection/stepable_iterator_spec.rb42
-rw-r--r--spec/unit/resource_definition_spec.rb46
-rw-r--r--spec/unit/resource_reporter_spec.rb27
-rw-r--r--spec/unit/rest/auth_credentials_spec.rb94
-rw-r--r--spec/unit/rest_spec.rb209
-rw-r--r--spec/unit/role_spec.rb61
-rw-r--r--spec/unit/run_context/cookbook_compiler_spec.rb24
-rw-r--r--spec/unit/run_context_spec.rb47
-rw-r--r--spec/unit/run_list/run_list_item_spec.rb2
-rw-r--r--spec/unit/run_lock_spec.rb9
-rw-r--r--spec/unit/scan_access_control_spec.rb4
-rw-r--r--spec/unit/search/query_spec.rb6
-rw-r--r--spec/unit/util/backup_spec.rb19
-rw-r--r--spec/unit/util/diff_spec.rb39
-rw-r--r--spec/unit/version/platform_spec.rb6
-rw-r--r--spec/unit/version_class_spec.rb10
-rw-r--r--spec/unit/version_constraint/platform_spec.rb4
-rw-r--r--spec/unit/windows_service_spec.rb54
626 files changed, 17562 insertions, 6460 deletions
diff --git a/.travis.yml b/.travis.yml
index bda8c79211..6468f54d57 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,12 @@
rvm:
- 1.8.7
-# - 1.9.2
- 1.9.3
- 2.0.0
-script: bundle exec rake spec
+branches:
+ only:
+ - master
+ - 10-stable
+ - 11-stable
+script: bundle exec rspec --color --format progress
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4744593eeb..523fadc45f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,7 +8,7 @@ You can find the answers to additional frequently asked questions [on the wiki](
* Create an account on our [bug tracker](http://tickets.opscode.com)
* Sign our contributor agreement (CLA) [
-online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L)
+online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L)
(keep reading if you're contributing on behalf of your employer)
* Create a ticket for your change on the [bug tracker](http://tickets.opscode.com)
* Link to your patch as a rebased git branch or pull request from the ticket
@@ -19,7 +19,7 @@ We regularly review contributions and will get back to you if we have any sugges
## The Apache License and the CLA/CCLA
Licensing is very important to open source projects, it helps ensure the software continues to be available under the terms that the author desired.
-Chef uses the Apache 2.0 license to strike a balance between open contribution and allowing you to use the software however you would like to.
+Chef uses the Apache 2.0 license to strike a balance between open contribution and allowing you to use the software however you would like to.
The license tells you what rights you have that are provided by the copyright holder. It is important that the contributor fully understands what rights
they are licensing and agrees to them. Sometimes the copyright holder isn't the contributor, most often when the contributor is doing work for a company.
@@ -43,26 +43,26 @@ such as:
* Discussion regarding the design and merits of features
* Error output to aid in finding similar bugs
-Each ticket should aim to fix one bug or add one feature.
+Each ticket should aim to fix one bug or add one feature.
## Using git
-You can get a quick copy of the chef repository by running `git clone git://github.com/opscode/chef.git`.
+You can get a quick copy of the chef repository by running `git clone git://github.com/opscode/chef.git`.
-For collaboration purposes, it is best if you create a Github account and fork the repository to your own account.
+For collaboration purposes, it is best if you create a Github account and fork the repository to your own account.
Once you do this you will be able to push your changes to your Github repository for others to see and use.
### Branches and Commits
You should submit your patch as a git branch named after the ticket, such as CHEF-1337.
-This is called a _topic branch_ and allows users to associate a branch of code with the ticket.
+This is called a _topic branch_ and allows users to associate a branch of code with the ticket.
It is a best practice to have your commit message have a _summary line_ that includes the ticket number,
followed by an empty line and then a brief description of the commit. This also helps other contributors
understand the purpose of changes to the code.
CHEF-3435: Create deploy dirs before calling scm_provider
-
+
The SCM providers have an assertation that requires the deploy directory to
exist. The deploy provider will create missing directories, we don't converge
the actions before we call run_action against the SCM provider, so it is not
@@ -76,7 +76,7 @@ helpful to be clear about your use case and change so they can understand it eve
All of Opscode's open source projects are available on [Github](http://www.github.com/opscode).
-We don't require you to use Github, and we will even take patch diffs attached to tickets on the tracker.
+We don't require you to use Github, and we will even take patch diffs attached to tickets on the tracker.
However Github has a lot of convenient features, such as being able to see a diff of changes between a
pull request and the main repository quickly without downloading the branch.
@@ -92,14 +92,14 @@ Additional help with git is available on the [Working with Git](http://wiki.opsc
There are rspec unit tests in the 'spec' directory. If you don't have rspec already installed, you can use the 'bundler'
gem to help you get the necessary prerequisites by running `sudo gem install bundler` and then `bundle install` from
-the chef respository. You can run the chef client spec tests by running `rspec spec/*` or `rake spec` from the chef
+the chef respository. You can run the chef client spec tests by running `rspec spec/*` or `rake spec` from the chef
directory of the chef repository.
-These tests should pass successfully on Ruby 1.8 and 1.9 on all of the platforms that Chef runs on. It is good to run the tests
+These tests should pass successfully on Ruby 1.8 and 1.9 on all of the platforms that Chef runs on. It is good to run the tests
once on your system before you get started to ensure they all pass so you have a valid baseline. After you write your patch,
run the tests again to see if they all pass.
-If any don't pass, investigate them before submitting your patch.
+If any don't pass, investigate them before submitting your patch.
These tests don't modify your system, and sometimes tests fail because a command that would be run has changed because of your
patch. This should be a simple fix. Other times the failure can show you that an important feature no longer works because of
@@ -136,7 +136,7 @@ The versioning for the Chef project is X.Y.Z.
Major releases and have historically been once a year. Minor releases for Chef average every two months and patch releases come as needed.
-There are usually beta releases and release candidates (RC) of major and minor releases announced on
+There are usually beta releases and release candidates (RC) of major and minor releases announced on
the [chef-dev mailing list](http://lists.opscode.com/sympa/info/chef-dev). Once an RC is released, we wait at least three
days to allow for testing for regressions before the final release. If a blocking regression is found then another RC is made containing
the fix and the timer is reset.
diff --git a/Gemfile b/Gemfile
index 371406cfde..1fe4580c0b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,6 +1,5 @@
source "https://rubygems.org"
-
-gemspec
+gemspec :name => "chef"
gem "activesupport", "< 4.0.0", :group => :compat_testing, :platform => "ruby"
@@ -18,24 +17,6 @@ group(:development, :test) do
# gem 'pry'
end
-platforms :mswin, :mingw do
- gem "systemu", "2.2.0" # CHEF-3718
- gem "ffi", "1.0.9"
- gem "rdp-ruby-wmi", "0.3.1"
- gem "windows-api", "0.4.0"
- gem "windows-pr", "1.2.1"
- gem "win32-api", "1.4.8"
- gem "win32-dir", "0.3.7"
- gem "win32-event", "0.5.2"
- gem "win32-mutex", "0.3.1"
- gem "win32-process", "0.6.5"
- gem "win32-service", "0.7.2"
-end
-
-platforms :mingw_18 do
- gem "win32-open3", "0.3.2"
-end
-
# If you want to load debugging tools into the bundle exec sandbox,
# add these additional dependencies into chef/Gemfile.local
eval(IO.read(__FILE__ + '.local'), binding) if File.exists?(__FILE__ + '.local')
diff --git a/NOTICE b/NOTICE
index 8e9418538d..5bca08f99f 100644
--- a/NOTICE
+++ b/NOTICE
@@ -17,3 +17,5 @@ Contributors and Copyright holders:
Chef incorporates code modified from Open4 (http://www.codeforpeople.com/lib/ruby/open4/), which was written by Ara T. Howard.
Chef incorporates code modified from deep_merge (http://trac.misuse.org/science/wiki/DeepMerge), which is Copyright (c) 2008 Steve Midgley
+
+Chef incorporates code modified from diff-lcs (http://diff-lcs.rubyforge.org/), which is Copyright (c) 2004–2013 Austin Ziegler
diff --git a/Rakefile b/Rakefile
index 085887fab5..eb48b8e389 100644
--- a/Rakefile
+++ b/Rakefile
@@ -26,13 +26,12 @@ require './tasks/rspec.rb'
GEM_NAME = "chef"
-spec = eval(File.read("chef.gemspec"))
-
# This has to be here or else the docs get generated *after* the gem is created
task :gem => 'docs:all'
-Gem::PackageTask.new(spec) do |pkg|
- pkg.gem_spec = spec
+Dir[File.expand_path("../*gemspec", __FILE__)].reverse.each do |gemspec_path|
+ gemspec = eval(IO.read(gemspec_path))
+ Gem::PackageTask.new(gemspec).define
end
begin
@@ -60,6 +59,15 @@ task :uninstall do
sh %{gem uninstall #{GEM_NAME} -x -v #{Chef::VERSION} }
end
+desc "Build it, tag it and ship it"
+task :ship => :gem do
+ sh("git tag #{Chef::VERSION}")
+ sh("git push opscode --tags")
+ Dir[File.expand_path("../pkg/*.gem", __FILE__)].reverse.each do |built_gem|
+ sh("gem push #{built_gem}")
+ end
+end
+
RONN_OPTS = "--manual='Chef Manual' --organization='Chef #{Chef::VERSION}' --date='#{Time.new.strftime('%Y-%m-%d')}'"
namespace :docs do
@@ -85,7 +93,15 @@ namespace :docs do
end
end
- if system('which ronn > /dev/null')
+ # we can have ronn in the path, but not in the bundle, require both
+ ronn_in_bundle = true
+ begin
+ require 'ronn'
+ rescue LoadError
+ ronn_in_bundle = false
+ end
+
+ if ronn_in_bundle && system('which ronn > /dev/null')
['distro/common/markdown/man1/*.mkd', 'distro/common/markdown/man8/*.mkd'].each do |dir|
Dir[dir].each do |mkd|
basename = File.basename(mkd, '.mkd')
diff --git a/bin/chef-apply b/bin/chef-apply
index 54ce230582..c617129aa3 100755
--- a/bin/chef-apply
+++ b/bin/chef-apply
@@ -9,9 +9,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/bin/chef-client b/bin/chef-client
index bfd5544319..5b2b058f91 100755
--- a/bin/chef-client
+++ b/bin/chef-client
@@ -9,9 +9,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/bin/chef-service-manager b/bin/chef-service-manager
index 781fd116de..3d48f203cb 100755
--- a/bin/chef-service-manager
+++ b/bin/chef-service-manager
@@ -9,9 +9,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/bin/chef-shell b/bin/chef-shell
index 90598d665d..f334635742 100755
--- a/bin/chef-shell
+++ b/bin/chef-shell
@@ -31,4 +31,7 @@ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
require "chef/shell"
+# On Windows only, enable irb --noreadline because of input problems --
+# See CHEF-3284.
+IRB.conf[:USE_READLINE] = false if Chef::Platform::windows?
Shell.start
diff --git a/bin/chef-solo b/bin/chef-solo
index 69891acb73..958ab21a41 100755
--- a/bin/chef-solo
+++ b/bin/chef-solo
@@ -9,9 +9,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/bin/knife b/bin/knife
index 1e2769906c..6173aadd86 100755
--- a/bin/knife
+++ b/bin/knife
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
#
-# ./knife - Chef CLI interface
+# ./knife - Chef CLI interface
#
# Author:: Adam Jacob (<adam@opscode.com>)
# Copyright:: Copyright (c) 2009 Opscode, Inc.
@@ -9,9 +9,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/chef-x86-mingw32.gemspec b/chef-x86-mingw32.gemspec
new file mode 100644
index 0000000000..8e59f8257f
--- /dev/null
+++ b/chef-x86-mingw32.gemspec
@@ -0,0 +1,20 @@
+# x86-mingw32 Gemspec #
+gemspec = eval(IO.read(File.expand_path("../chef.gemspec", __FILE__)))
+
+gemspec.platform = "x86-mingw32"
+
+gemspec.add_dependency "mixlib-shellout", "1.2.0"
+gemspec.add_dependency "systemu", "2.5.2" # CHEF-3718
+gemspec.add_dependency "ffi", "1.3.1"
+gemspec.add_dependency "rdp-ruby-wmi", "0.3.1"
+gemspec.add_dependency "windows-api", "0.4.2"
+gemspec.add_dependency "windows-pr", "1.2.2"
+gemspec.add_dependency "win32-api", "1.4.8"
+gemspec.add_dependency "win32-dir", "0.4.5"
+gemspec.add_dependency "win32-event", "0.6.1"
+gemspec.add_dependency "win32-mutex", "0.4.1"
+gemspec.add_dependency "win32-process", "0.7.3"
+gemspec.add_dependency "win32-service", "0.8.2"
+gemspec.add_dependency "win32-mmap", "0.4.0"
+
+gemspec
diff --git a/chef.gemspec b/chef.gemspec
index caf2e4cffc..2837dabe35 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -12,12 +12,12 @@ Gem::Specification.new do |s|
s.email = "adam@opscode.com"
s.homepage = "http://wiki.opscode.com/display/chef"
- s.add_dependency "mixlib-config", ">= 1.1.2"
- s.add_dependency "mixlib-cli", "~> 1.3.0"
- s.add_dependency "mixlib-log", ">= 1.3.0"
- s.add_dependency "mixlib-authentication", ">= 1.3.0"
- s.add_dependency "mixlib-shellout"
- s.add_dependency "ohai", ">= 0.6.0"
+ s.add_dependency "mixlib-config", "~> 2.0"
+ s.add_dependency "mixlib-cli", "~> 1.3"
+ s.add_dependency "mixlib-log", "~> 1.3"
+ s.add_dependency "mixlib-authentication", "~> 1.3"
+ s.add_dependency "mixlib-shellout", "~> 1.2"
+ s.add_dependency "ohai", "~> 6.0"
s.add_dependency "rest-client", ">= 1.0.4", "< 1.7.0"
@@ -27,13 +27,15 @@ Gem::Specification.new do |s|
s.add_dependency "net-ssh", "~> 2.6"
s.add_dependency "net-ssh-multi", "~> 1.1.0"
# CHEF-3027: The knife-cloud plugins require newer features from highline, core chef should not.
- s.add_dependency "highline", ">= 1.6.9"
- s.add_dependency "erubis"
+ s.add_dependency "highline", "~> 1.6", ">= 1.6.9"
+ s.add_dependency "erubis", "~> 2.7"
+ s.add_dependency "diff-lcs", "~> 1.2", ">= 1.2.4"
+ s.add_dependency "chef-zero", "~> 1.6", ">= 1.6.2"
+ s.add_dependency "puma", "~> 1.6"
+
%w(rdoc sdoc rake rack rspec_junit_formatter).each { |gem| s.add_development_dependency gem }
- %w(rspec-core rspec-expectations rspec-mocks).each { |gem| s.add_development_dependency gem, "~> 2.12.0" }
- s.add_development_dependency "chef-zero", "~> 1.4"
- s.add_development_dependency "puma", "~> 1.6"
+ %w(rspec-core rspec-expectations rspec-mocks).each { |gem| s.add_development_dependency gem, "~> 2.13.0" }
s.bindir = "bin"
# chef-service-manager is a windows only executable.
diff --git a/ci/jenkins_run_tests.sh b/ci/jenkins_run_tests.sh
index 9330d7cd07..5bf7def062 100755
--- a/ci/jenkins_run_tests.sh
+++ b/ci/jenkins_run_tests.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-export PATH=/usr/local/bin:$PATH
+export PATH=$PATH:/usr/local/bin
ruby -v;
# remove the Gemfile.lock and try again if bundler fails.
diff --git a/distro/arch/etc/rc.d/chef-client b/distro/arch/etc/rc.d/chef-client
index 36f00bad6a..6e2feb2e52 100644
--- a/distro/arch/etc/rc.d/chef-client
+++ b/distro/arch/etc/rc.d/chef-client
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/distro/arch/etc/rc.d/chef-server b/distro/arch/etc/rc.d/chef-server
index 59f926c2c9..1ffbf8dce5 100644
--- a/distro/arch/etc/rc.d/chef-server
+++ b/distro/arch/etc/rc.d/chef-server
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/distro/arch/etc/rc.d/chef-server-webui b/distro/arch/etc/rc.d/chef-server-webui
index 79a9b77c1c..bec185151f 100644
--- a/distro/arch/etc/rc.d/chef-server-webui
+++ b/distro/arch/etc/rc.d/chef-server-webui
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/distro/arch/etc/rc.d/chef-solr b/distro/arch/etc/rc.d/chef-solr
index a3682a495a..10bd15ea08 100644
--- a/distro/arch/etc/rc.d/chef-solr
+++ b/distro/arch/etc/rc.d/chef-solr
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/distro/common/html/chef-client.8.html b/distro/common/html/chef-client.8.html
index 17a80768d9..5e7eee7861 100644
--- a/distro/common/html/chef-client.8.html
+++ b/distro/common/html/chef-client.8.html
@@ -124,9 +124,9 @@ wiki, http://wiki.opscode.com/display/chef/Home.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p>Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#108;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#109;&#x40;&#x6f;&#x73;&#x70;&#x63;&#x6f;&#100;&#101;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#x6f;&#x73;&#x70;&#99;&#x6f;&#x64;&#101;&#46;&#x63;&#x6f;&#x6d;</a> of Opscode
+<p>Chef was written by Adam Jacob <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#58;&#x61;&#x64;&#97;&#x6d;&#64;&#x6f;&#x73;&#x70;&#x63;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#115;&#x70;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#x6d;</a> of Opscode
(http://www.opscode.com), with contributions from the community. This
-manual page was written by Joshua Timberman <a href="&#109;&#97;&#x69;&#x6c;&#x74;&#x6f;&#58;&#106;&#111;&#x73;&#104;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#99;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#106;&#x6f;&#115;&#x68;&#117;&#x61;&#64;&#111;&#x70;&#x73;&#x63;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#109;</a> with
+manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#108;&#116;&#x6f;&#x3a;&#106;&#111;&#115;&#x68;&#x75;&#x61;&#64;&#x6f;&#112;&#x73;&#99;&#x6f;&#x64;&#101;&#46;&#99;&#111;&#109;" data-bare-link="true">&#106;&#x6f;&#115;&#104;&#117;&#x61;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#109;</a> with
help2man. Permission is granted to copy, distribute and / or modify
this document under the terms of the Apache 2.0 License.</p>
@@ -135,8 +135,8 @@ found in /usr/share/common-licenses/Apache-2.0.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>chef-client(8)</li>
</ol>
diff --git a/distro/common/html/chef-expander.8.html b/distro/common/html/chef-expander.8.html
index b025cdb89d..b4117034d3 100644
--- a/distro/common/html/chef-expander.8.html
+++ b/distro/common/html/chef-expander.8.html
@@ -143,9 +143,9 @@ wiki, http://wiki.opscode.com/display/chef/Home.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p>Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#108;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#109;&#x40;&#x6f;&#x73;&#x70;&#x63;&#x6f;&#100;&#101;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#x6f;&#x73;&#x70;&#99;&#x6f;&#x64;&#101;&#46;&#x63;&#x6f;&#x6d;</a> of Opscode
+<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#108;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#x61;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#111;&#100;&#101;&#x2e;&#x63;&#111;&#x6d;</a> of Opscode
(http://www.opscode.com), with contributions from the community. This
-manual page was created by Nuo Yan <a href="&#109;&#97;&#x69;&#x6c;&#x74;&#x6f;&#58;&#110;&#117;&#x6f;&#64;&#111;&#112;&#x73;&#x63;&#x6f;&#x64;&#101;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#110;&#x75;&#111;&#64;&#x6f;&#112;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#109;</a>. Permission is
+manual page was created by Nuo Yan <a href="&#x6d;&#x61;&#x69;&#108;&#x74;&#111;&#x3a;&#110;&#x75;&#111;&#x40;&#x6f;&#112;&#115;&#x63;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#110;&#x75;&#111;&#64;&#x6f;&#x70;&#x73;&#99;&#111;&#x64;&#x65;&#x2e;&#x63;&#x6f;&#x6d;</a>. Permission is
granted to copy, distribute and / or modify this document under the
terms of the Apache 2.0 License.</p>
@@ -154,8 +154,8 @@ found in /usr/share/common-licenses/Apache-2.0.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>chef-expander(8)</li>
</ol>
diff --git a/distro/common/html/chef-expanderctl.8.html b/distro/common/html/chef-expanderctl.8.html
index ddedce711b..2d93233feb 100644
--- a/distro/common/html/chef-expanderctl.8.html
+++ b/distro/common/html/chef-expanderctl.8.html
@@ -125,9 +125,9 @@ wiki, http://wiki.opscode.com/display/chef/Home.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p>Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#108;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#109;&#x40;&#x6f;&#x73;&#x70;&#x63;&#x6f;&#100;&#101;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#x6f;&#x73;&#x70;&#99;&#x6f;&#x64;&#101;&#46;&#x63;&#x6f;&#x6d;</a> of Opscode
+<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#108;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#x61;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#111;&#100;&#101;&#x2e;&#x63;&#111;&#x6d;</a> of Opscode
(http://www.opscode.com), with contributions from the community. This
-manual page was created by Nuo Yan <a href="&#109;&#97;&#x69;&#x6c;&#x74;&#x6f;&#58;&#110;&#117;&#x6f;&#64;&#111;&#112;&#x73;&#x63;&#x6f;&#x64;&#101;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#110;&#x75;&#111;&#64;&#x6f;&#112;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#109;</a>. Permission is
+manual page was created by Nuo Yan <a href="&#x6d;&#x61;&#x69;&#108;&#x74;&#111;&#x3a;&#110;&#x75;&#111;&#x40;&#x6f;&#112;&#115;&#x63;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#110;&#x75;&#111;&#64;&#x6f;&#x70;&#x73;&#99;&#111;&#x64;&#x65;&#x2e;&#x63;&#x6f;&#x6d;</a>. Permission is
granted to copy, distribute and / or modify this document under the
terms of the Apache 2.0 License.</p>
@@ -136,8 +136,8 @@ found in /usr/share/common-licenses/Apache-2.0.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>chef-expanderctl(8)</li>
</ol>
diff --git a/distro/common/html/chef-server-webui.8.html b/distro/common/html/chef-server-webui.8.html
index 2da387b735..f498e36302 100644
--- a/distro/common/html/chef-server-webui.8.html
+++ b/distro/common/html/chef-server-webui.8.html
@@ -163,9 +163,9 @@ is located on the Chef wiki, http://wiki.opscode.com/display/chef/Home.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#58;&#x61;&#100;&#x61;&#109;&#x40;&#x6f;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#100;&#97;&#109;&#64;&#x6f;&#115;&#x70;&#x63;&#x6f;&#x64;&#101;&#46;&#x63;&#111;&#x6d;</a> of Opscode
+<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#108;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#x61;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#111;&#100;&#101;&#x2e;&#x63;&#111;&#x6d;</a> of Opscode
(http://www.opscode.com), with contributions from the community. This
-manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#x6f;&#58;&#x6a;&#111;&#115;&#104;&#x75;&#97;&#x40;&#x6f;&#112;&#x73;&#x63;&#111;&#x64;&#x65;&#46;&#99;&#111;&#109;" data-bare-link="true">&#106;&#111;&#115;&#x68;&#x75;&#x61;&#x40;&#x6f;&#x70;&#x73;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a> with
+manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#x69;&#108;&#x74;&#111;&#x3a;&#106;&#x6f;&#115;&#x68;&#x75;&#97;&#64;&#x6f;&#112;&#115;&#x63;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#106;&#x6f;&#x73;&#x68;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#x63;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;</a> with
help2man for the Debian project (but may be used by others). Permission
is granted to copy, distribute and / or modify this document under the
terms of the Apache 2.0 License.</p>
@@ -175,8 +175,8 @@ found in /usr/share/common-licenses/Apache-2.0.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>chef-server-webui(8)</li>
</ol>
diff --git a/distro/common/html/chef-server.8.html b/distro/common/html/chef-server.8.html
index a183114aaf..ed59f0f62c 100644
--- a/distro/common/html/chef-server.8.html
+++ b/distro/common/html/chef-server.8.html
@@ -161,9 +161,9 @@ wiki, http://wiki.opscode.com/display/chef/Home.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#58;&#x61;&#100;&#x61;&#109;&#x40;&#x6f;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#100;&#97;&#109;&#64;&#x6f;&#115;&#x70;&#x63;&#x6f;&#x64;&#101;&#46;&#x63;&#111;&#x6d;</a> of Opscode
+<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#108;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#x61;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#111;&#100;&#101;&#x2e;&#x63;&#111;&#x6d;</a> of Opscode
(http://www.opscode.com), with contributions from the community. This
-manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#x6f;&#58;&#x6a;&#111;&#115;&#104;&#x75;&#97;&#x40;&#x6f;&#112;&#x73;&#x63;&#111;&#x64;&#x65;&#46;&#99;&#111;&#109;" data-bare-link="true">&#106;&#111;&#115;&#x68;&#x75;&#x61;&#x40;&#x6f;&#x70;&#x73;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a> with
+manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#x69;&#108;&#x74;&#111;&#x3a;&#106;&#x6f;&#115;&#x68;&#x75;&#97;&#64;&#x6f;&#112;&#115;&#x63;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#106;&#x6f;&#x73;&#x68;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#x63;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;</a> with
help2man. Permission is granted to copy, distribute and / or modify
this document under the terms of the Apache 2.0 License.</p>
@@ -172,8 +172,8 @@ found in /usr/share/common-licenses/Apache-2.0.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>chef-server(8)</li>
</ol>
diff --git a/distro/common/html/chef-shell.1.html b/distro/common/html/chef-shell.1.html
index 56f548d305..a77e2b9060 100644
--- a/distro/common/html/chef-shell.1.html
+++ b/distro/common/html/chef-shell.1.html
@@ -260,13 +260,13 @@ libraries.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#58;&#97;&#x64;&#97;&#109;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#111;&#109;" data-bare-link="true">&#x61;&#x64;&#97;&#x6d;&#x40;&#111;&#x70;&#115;&#99;&#x6f;&#100;&#101;&#46;&#99;&#x6f;&#109;</a> with many
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#97;&#100;&#97;&#x6d;&#64;&#x6f;&#x70;&#x73;&#x63;&#x6f;&#x64;&#x65;&#46;&#99;&#111;&#109;" data-bare-link="true">&#x61;&#100;&#97;&#x6d;&#x40;&#111;&#112;&#x73;&#x63;&#111;&#x64;&#101;&#46;&#x63;&#111;&#109;</a> with many
contributions from the community. chef-shell was written by Daniel
DeLeo.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Daniel DeLeo <a href="&#x6d;&#x61;&#105;&#108;&#x74;&#111;&#58;&#x64;&#x61;&#x6e;&#x40;&#x6f;&#112;&#x73;&#x63;&#x6f;&#100;&#101;&#46;&#x63;&#111;&#109;" data-bare-link="true">&#100;&#97;&#x6e;&#64;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#x6d;</a>.
+<p> This manual page was written by Daniel DeLeo <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#58;&#x64;&#97;&#x6e;&#64;&#111;&#x70;&#x73;&#x63;&#x6f;&#x64;&#x65;&#46;&#99;&#x6f;&#x6d;" data-bare-link="true">&#x64;&#x61;&#x6e;&#x40;&#x6f;&#112;&#115;&#x63;&#111;&#100;&#101;&#46;&#x63;&#111;&#x6d;</a>.
Permission is granted to copy, distribute and / or modify this
document under the terms of the Apache 2.0 License.</p>
@@ -276,8 +276,8 @@ libraries.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>chef-shell(1)</li>
</ol>
diff --git a/distro/common/html/chef-solo.8.html b/distro/common/html/chef-solo.8.html
index a97c84a0fc..3356c32bed 100644
--- a/distro/common/html/chef-solo.8.html
+++ b/distro/common/html/chef-solo.8.html
@@ -164,9 +164,9 @@ http://wiki.opscode.com/display/chef/Home.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#58;&#x61;&#100;&#x61;&#109;&#x40;&#x6f;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#100;&#97;&#109;&#64;&#x6f;&#115;&#x70;&#x63;&#x6f;&#x64;&#101;&#46;&#x63;&#111;&#x6d;</a> of Opscode
+<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#108;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#x61;&#100;&#x61;&#109;&#64;&#111;&#x73;&#x70;&#99;&#111;&#100;&#101;&#x2e;&#x63;&#111;&#x6d;</a> of Opscode
(http://www.opscode.com), with contributions from the community. This
-manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#x6f;&#58;&#x6a;&#111;&#115;&#104;&#x75;&#97;&#x40;&#x6f;&#112;&#x73;&#x63;&#111;&#x64;&#x65;&#46;&#99;&#111;&#109;" data-bare-link="true">&#106;&#111;&#115;&#x68;&#x75;&#x61;&#x40;&#x6f;&#x70;&#x73;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a> with
+manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#x69;&#108;&#x74;&#111;&#x3a;&#106;&#x6f;&#115;&#x68;&#x75;&#97;&#64;&#x6f;&#112;&#115;&#x63;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#106;&#x6f;&#x73;&#x68;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#x63;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;</a> with
help2man. Permission is granted to copy, distribute and / or modify
this document under the terms of the Apache 2.0 License.</p>
@@ -175,8 +175,8 @@ found in /usr/share/common-licenses/Apache-2.0.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>chef-solo(8)</li>
</ol>
diff --git a/distro/common/html/chef-solr.8.html b/distro/common/html/chef-solr.8.html
index d930b8011d..3ef7108ad0 100644
--- a/distro/common/html/chef-solr.8.html
+++ b/distro/common/html/chef-solr.8.html
@@ -3,7 +3,7 @@
<head>
<meta http-equiv='content-type' value='text/html;charset=utf8'>
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
- <title>chef-solr(8) - Runs as Chef's search server</title>
+ <title>chef-solr(8) - Runs as Chef&#39;s search server</title>
<style type='text/css' media='all'>
/* style: man */
body#manpage {margin:0}
@@ -144,9 +144,9 @@ wiki, http://wiki.opscode.com/display/chef/Home.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p>Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#58;&#x61;&#100;&#x61;&#109;&#x40;&#x6f;&#x73;&#x70;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#100;&#97;&#109;&#64;&#x6f;&#115;&#x70;&#x63;&#x6f;&#x64;&#101;&#46;&#x63;&#111;&#x6d;</a> of Opscode
+<p>Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#x61;&#100;&#x61;&#x6d;&#64;&#111;&#x73;&#112;&#99;&#x6f;&#x64;&#101;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#97;&#x6d;&#x40;&#111;&#x73;&#112;&#x63;&#111;&#100;&#101;&#46;&#99;&#x6f;&#x6d;</a> of Opscode
(http://www.opscode.com), with contributions from the community. This
-manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#x6f;&#58;&#x6a;&#111;&#115;&#104;&#x75;&#97;&#x40;&#x6f;&#112;&#x73;&#x63;&#111;&#x64;&#x65;&#46;&#99;&#111;&#109;" data-bare-link="true">&#106;&#111;&#115;&#x68;&#x75;&#x61;&#x40;&#x6f;&#x70;&#x73;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a> with
+manual page was written by Joshua Timberman <a href="&#109;&#97;&#x69;&#108;&#x74;&#111;&#x3a;&#x6a;&#111;&#115;&#x68;&#x75;&#97;&#64;&#x6f;&#112;&#x73;&#x63;&#111;&#100;&#x65;&#x2e;&#x63;&#111;&#x6d;" data-bare-link="true">&#x6a;&#111;&#115;&#104;&#117;&#x61;&#64;&#111;&#112;&#x73;&#x63;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;</a> with
help2man. Permission is granted to copy, distribute and / or modify
this document under the terms of the Apache 2.0 License.</p>
@@ -155,8 +155,8 @@ found in /usr/share/common-licenses/Apache-2.0.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>chef-solr(8)</li>
</ol>
diff --git a/distro/common/html/knife-bootstrap.1.html b/distro/common/html/knife-bootstrap.1.html
index cfb32f4bb5..f2bf638895 100644
--- a/distro/common/html/knife-bootstrap.1.html
+++ b/distro/common/html/knife-bootstrap.1.html
@@ -218,11 +218,11 @@ to other users via the process list using tools such as <span class="man-ref">ps
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#58;&#97;&#x64;&#97;&#109;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#111;&#109;" data-bare-link="true">&#x61;&#x64;&#97;&#x6d;&#x40;&#111;&#x70;&#115;&#99;&#x6f;&#100;&#101;&#46;&#99;&#x6f;&#109;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#97;&#100;&#97;&#x6d;&#64;&#x6f;&#x70;&#x73;&#x63;&#x6f;&#x64;&#x65;&#46;&#99;&#111;&#109;" data-bare-link="true">&#x61;&#100;&#97;&#x6d;&#x40;&#111;&#112;&#x73;&#x63;&#111;&#x64;&#101;&#46;&#x63;&#111;&#109;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#108;&#x74;&#111;&#58;&#x6a;&#x6f;&#x73;&#x68;&#x75;&#97;&#x40;&#x6f;&#x70;&#115;&#99;&#111;&#x64;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#106;&#111;&#x73;&#x68;&#x75;&#x61;&#64;&#x6f;&#x70;&#115;&#99;&#x6f;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#58;&#x6a;&#111;&#x73;&#104;&#117;&#x61;&#x40;&#x6f;&#x70;&#x73;&#x63;&#111;&#100;&#x65;&#x2e;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x6a;&#x6f;&#115;&#104;&#x75;&#97;&#64;&#111;&#112;&#x73;&#99;&#x6f;&#100;&#x65;&#x2e;&#x63;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -231,8 +231,8 @@ to other users via the process list using tools such as <span class="man-ref">ps
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-bootstrap(1)</li>
</ol>
diff --git a/distro/common/html/knife-client.1.html b/distro/common/html/knife-client.1.html
index b696bf22a2..f306e9fd53 100644
--- a/distro/common/html/knife-client.1.html
+++ b/distro/common/html/knife-client.1.html
@@ -196,11 +196,11 @@ setting up a host for management with Chef.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#58;&#97;&#x64;&#97;&#109;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#111;&#109;" data-bare-link="true">&#x61;&#x64;&#97;&#x6d;&#x40;&#111;&#x70;&#115;&#99;&#x6f;&#100;&#101;&#46;&#99;&#x6f;&#109;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#x6d;&#x40;&#111;&#x70;&#x73;&#99;&#111;&#100;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#108;&#x74;&#111;&#58;&#x6a;&#x6f;&#x73;&#x68;&#x75;&#97;&#x40;&#x6f;&#x70;&#115;&#99;&#111;&#x64;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#106;&#111;&#x73;&#x68;&#x75;&#x61;&#64;&#x6f;&#x70;&#115;&#99;&#x6f;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#105;&#108;&#116;&#x6f;&#x3a;&#x6a;&#x6f;&#x73;&#x68;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#x68;&#117;&#x61;&#64;&#111;&#x70;&#115;&#x63;&#111;&#100;&#101;&#46;&#x63;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -209,8 +209,8 @@ setting up a host for management with Chef.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-client(1)</li>
</ol>
diff --git a/distro/common/html/knife-configure.1.html b/distro/common/html/knife-configure.1.html
index 54450ce11a..fe66789054 100644
--- a/distro/common/html/knife-configure.1.html
+++ b/distro/common/html/knife-configure.1.html
@@ -147,11 +147,11 @@ may need to modify that setting after copying to a remote host.</p></li>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#58;&#97;&#x64;&#97;&#109;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#111;&#109;" data-bare-link="true">&#x61;&#x64;&#97;&#x6d;&#x40;&#111;&#x70;&#115;&#99;&#x6f;&#100;&#101;&#46;&#99;&#x6f;&#109;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#x6d;&#x40;&#111;&#x70;&#x73;&#99;&#111;&#100;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#108;&#x74;&#111;&#58;&#x6a;&#x6f;&#x73;&#x68;&#x75;&#97;&#x40;&#x6f;&#x70;&#115;&#99;&#111;&#x64;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#106;&#111;&#x73;&#x68;&#x75;&#x61;&#64;&#x6f;&#x70;&#115;&#99;&#x6f;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#105;&#108;&#116;&#x6f;&#x3a;&#x6a;&#x6f;&#x73;&#x68;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#x68;&#117;&#x61;&#64;&#111;&#x70;&#115;&#x63;&#111;&#100;&#101;&#46;&#x63;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -160,8 +160,8 @@ may need to modify that setting after copying to a remote host.</p></li>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-configure(1)</li>
</ol>
diff --git a/distro/common/html/knife-cookbook-site.1.html b/distro/common/html/knife-cookbook-site.1.html
index 60f82a79dd..8b093b5671 100644
--- a/distro/common/html/knife-cookbook-site.1.html
+++ b/distro/common/html/knife-cookbook-site.1.html
@@ -218,11 +218,11 @@ configuration file.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#x6c;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#x40;&#x6f;&#112;&#x73;&#x63;&#x6f;&#x64;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#97;&#x6d;&#64;&#x6f;&#112;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#99;&#111;&#x6d;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#x6d;&#x40;&#111;&#x70;&#x73;&#99;&#111;&#100;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#x3a;&#106;&#x6f;&#115;&#x68;&#x75;&#x61;&#64;&#111;&#x70;&#x73;&#99;&#111;&#x64;&#101;&#46;&#99;&#x6f;&#x6d;" data-bare-link="true">&#x6a;&#x6f;&#x73;&#x68;&#117;&#97;&#64;&#x6f;&#112;&#115;&#99;&#x6f;&#x64;&#101;&#46;&#99;&#111;&#x6d;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#105;&#108;&#116;&#x6f;&#x3a;&#x6a;&#x6f;&#x73;&#x68;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#x68;&#117;&#x61;&#64;&#111;&#x70;&#115;&#x63;&#111;&#100;&#101;&#46;&#x63;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -231,8 +231,8 @@ configuration file.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-cookbook-site(1)</li>
</ol>
diff --git a/distro/common/html/knife-cookbook.1.html b/distro/common/html/knife-cookbook.1.html
index 1b4d53a5f9..e044adfa1c 100644
--- a/distro/common/html/knife-cookbook.1.html
+++ b/distro/common/html/knife-cookbook.1.html
@@ -217,9 +217,9 @@ regular expression (<em>regex</em>) should be in quotes, not in //'s.</p>
<dl>
<dt><code>-o</code>, <code>--cookbook-path path</code></dt><dd>the directory where the cookbook will be created</dd>
<dt><code>-r</code>, <code>--readme-format format</code></dt><dd>format of the readme file md, mkd, txt, rdoc</dd>
-<dt><code>-c</code>, <code>--copyright copyright</code></dt><dd>name of copyright holder</dd>
+<dt><code>-C</code>, <code>--copyright copyright</code></dt><dd>name of copyright holder</dd>
<dt><code>-i</code>, <code>--license license</code></dt><dd>license for cookbook, apachev2 or none</dd>
-<dt><code>-e</code>, <code>--email email</code></dt><dd>email address of cookbook maintainer</dd>
+<dt><code>-m</code>, <code>--email email</code></dt><dd>email address of cookbook maintainer</dd>
</dl>
@@ -245,7 +245,7 @@ named cookbook.</p>
readme file will be written with the specified extension and a set of
helpful starting headers.</p>
-<p>specify <code>-c</code> or <code>--copyright</code> with the name of the copyright holder as
+<p>specify <code>-C</code> or <code>--copyright</code> with the name of the copyright holder as
your name or your company/organization name in a quoted string. if this
value is not specified an all-caps string <code>your_company_name</code> is used
which can be easily changed with find/replace.</p>
@@ -258,7 +258,7 @@ the cookbook and follow any restrictions they describe. when using
are pre-filled. the <code>none</code> license will be treated as
non-redistributable.</p>
-<p>specify <code>-e</code> or <code>--email</code> with the email address of the cookbook's
+<p>specify <code>-m</code> or <code>--email</code> with the email address of the cookbook's
maintainer. if this value is not specified, an all-caps string
<code>your_email</code> is used which can easily be changed with find/replace.</p>
@@ -358,11 +358,11 @@ cookbook.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#x6c;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#x40;&#x6f;&#112;&#x73;&#x63;&#x6f;&#x64;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#97;&#x6d;&#64;&#x6f;&#112;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#99;&#111;&#x6d;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#x6d;&#x40;&#111;&#x70;&#x73;&#99;&#111;&#100;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#x3a;&#106;&#x6f;&#115;&#x68;&#x75;&#x61;&#64;&#111;&#x70;&#x73;&#99;&#111;&#x64;&#101;&#46;&#99;&#x6f;&#x6d;" data-bare-link="true">&#x6a;&#x6f;&#x73;&#x68;&#117;&#97;&#64;&#x6f;&#112;&#115;&#99;&#x6f;&#x64;&#101;&#46;&#99;&#111;&#x6d;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#105;&#108;&#116;&#x6f;&#x3a;&#x6a;&#x6f;&#x73;&#x68;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#x68;&#117;&#x61;&#64;&#111;&#x70;&#115;&#x63;&#111;&#100;&#101;&#46;&#x63;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -371,8 +371,8 @@ cookbook.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-cookbook(1)</li>
</ol>
diff --git a/distro/common/html/knife-data-bag.1.html b/distro/common/html/knife-data-bag.1.html
index 749f405fb3..058088fe3c 100644
--- a/distro/common/html/knife-data-bag.1.html
+++ b/distro/common/html/knife-data-bag.1.html
@@ -212,11 +212,11 @@ encryption keys.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#x6c;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#x40;&#x6f;&#112;&#x73;&#x63;&#x6f;&#x64;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#97;&#x6d;&#64;&#x6f;&#112;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#99;&#111;&#x6d;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#x6d;&#x40;&#111;&#x70;&#x73;&#99;&#111;&#100;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#x3a;&#106;&#x6f;&#115;&#x68;&#x75;&#x61;&#64;&#111;&#x70;&#x73;&#99;&#111;&#x64;&#101;&#46;&#99;&#x6f;&#x6d;" data-bare-link="true">&#x6a;&#x6f;&#x73;&#x68;&#117;&#97;&#64;&#x6f;&#112;&#115;&#99;&#x6f;&#x64;&#101;&#46;&#99;&#111;&#x6d;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#97;&#105;&#108;&#116;&#x6f;&#x3a;&#x6a;&#x6f;&#x73;&#x68;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#x68;&#117;&#x61;&#64;&#111;&#x70;&#115;&#x63;&#111;&#100;&#101;&#46;&#x63;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -225,8 +225,8 @@ encryption keys.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-data-bag(1)</li>
</ol>
diff --git a/distro/common/html/knife-environment.1.html b/distro/common/html/knife-environment.1.html
index 972597b9d6..dce5bebe02 100644
--- a/distro/common/html/knife-environment.1.html
+++ b/distro/common/html/knife-environment.1.html
@@ -242,11 +242,11 @@ override_attributes "aws_s3_bucket" =&gt; "production"
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#x69;&#x6c;&#116;&#111;&#58;&#97;&#100;&#x61;&#109;&#x40;&#x6f;&#112;&#x73;&#x63;&#x6f;&#x64;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#97;&#x6d;&#64;&#x6f;&#112;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#99;&#111;&#x6d;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#x6d;&#x40;&#111;&#x70;&#x73;&#99;&#111;&#100;&#101;&#46;&#99;&#111;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#111;&#112;&#115;&#x63;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Daniel DeLeo <a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#x3a;&#100;&#x61;&#110;&#x40;&#x6f;&#x70;&#115;&#99;&#x6f;&#x64;&#101;&#46;&#x63;&#111;&#109;" data-bare-link="true">&#100;&#x61;&#x6e;&#x40;&#x6f;&#x70;&#x73;&#99;&#111;&#100;&#x65;&#46;&#99;&#111;&#x6d;</a>.
+<p> This manual page was written by Daniel DeLeo <a href="&#x6d;&#97;&#105;&#108;&#116;&#x6f;&#x3a;&#x64;&#x61;&#x6e;&#x40;&#111;&#112;&#x73;&#x63;&#x6f;&#x64;&#101;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#100;&#x61;&#110;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -255,8 +255,8 @@ override_attributes "aws_s3_bucket" =&gt; "production"
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-environment(1)</li>
</ol>
diff --git a/distro/common/html/knife-exec.1.html b/distro/common/html/knife-exec.1.html
index c57b8d0dd7..80b94ef63f 100644
--- a/distro/common/html/knife-exec.1.html
+++ b/distro/common/html/knife-exec.1.html
@@ -111,11 +111,11 @@ description of the commands available.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#x69;&#x6c;&#x74;&#111;&#58;&#97;&#x64;&#97;&#109;&#x40;&#111;&#112;&#115;&#99;&#x6f;&#100;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#112;&#x73;&#x63;&#111;&#100;&#101;&#x2e;&#99;&#111;&#109;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#x6f;&#x3a;&#97;&#100;&#97;&#109;&#64;&#x6f;&#112;&#115;&#x63;&#111;&#100;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#x70;&#115;&#99;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#109;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#x3a;&#x6a;&#111;&#x73;&#104;&#117;&#97;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x6a;&#x6f;&#x73;&#104;&#117;&#x61;&#64;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#x3a;&#106;&#111;&#x73;&#x68;&#117;&#x61;&#64;&#x6f;&#x70;&#x73;&#99;&#x6f;&#x64;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#104;&#117;&#97;&#x40;&#x6f;&#x70;&#115;&#x63;&#x6f;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -124,8 +124,8 @@ description of the commands available.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-exec(1)</li>
</ol>
diff --git a/distro/common/html/knife-index.1.html b/distro/common/html/knife-index.1.html
index fad4e94356..30ed0f5342 100644
--- a/distro/common/html/knife-index.1.html
+++ b/distro/common/html/knife-index.1.html
@@ -102,11 +102,11 @@ time for all objects to be indexed and available for search.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#x69;&#x6c;&#x74;&#111;&#58;&#97;&#x64;&#97;&#109;&#x40;&#111;&#112;&#115;&#99;&#x6f;&#100;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#112;&#x73;&#x63;&#111;&#100;&#101;&#x2e;&#99;&#111;&#109;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#x6f;&#x3a;&#97;&#100;&#97;&#109;&#64;&#x6f;&#112;&#115;&#x63;&#111;&#100;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#x70;&#115;&#99;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#109;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#x3a;&#x6a;&#111;&#x73;&#104;&#117;&#97;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x6a;&#x6f;&#x73;&#104;&#117;&#x61;&#64;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#x3a;&#106;&#111;&#x73;&#x68;&#117;&#x61;&#64;&#x6f;&#x70;&#x73;&#99;&#x6f;&#x64;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#104;&#117;&#97;&#x40;&#x6f;&#x70;&#115;&#x63;&#x6f;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -115,8 +115,8 @@ time for all objects to be indexed and available for search.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-index(1)</li>
</ol>
diff --git a/distro/common/html/knife-node.1.html b/distro/common/html/knife-node.1.html
index f5b865d400..4e18fdc9c3 100644
--- a/distro/common/html/knife-node.1.html
+++ b/distro/common/html/knife-node.1.html
@@ -227,11 +227,11 @@ run list, the correct syntax is "role[ROLE_NAME]"</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#x69;&#x6c;&#x74;&#111;&#58;&#97;&#x64;&#97;&#109;&#x40;&#111;&#112;&#115;&#99;&#x6f;&#100;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#112;&#x73;&#x63;&#111;&#100;&#101;&#x2e;&#99;&#111;&#109;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#x6f;&#x3a;&#97;&#100;&#97;&#109;&#64;&#x6f;&#112;&#115;&#x63;&#111;&#100;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#x70;&#115;&#99;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#109;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#x3a;&#x6a;&#111;&#x73;&#104;&#117;&#97;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x6a;&#x6f;&#x73;&#104;&#117;&#x61;&#64;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#x3a;&#106;&#111;&#x73;&#x68;&#117;&#x61;&#64;&#x6f;&#x70;&#x73;&#99;&#x6f;&#x64;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#104;&#117;&#97;&#x40;&#x6f;&#x70;&#115;&#x63;&#x6f;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -240,8 +240,8 @@ run list, the correct syntax is "role[ROLE_NAME]"</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-node(1)</li>
</ol>
diff --git a/distro/common/html/knife-role.1.html b/distro/common/html/knife-role.1.html
index c522a519d1..87a6082c69 100644
--- a/distro/common/html/knife-role.1.html
+++ b/distro/common/html/knife-role.1.html
@@ -177,11 +177,11 @@ run_list.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#x69;&#x6c;&#x74;&#111;&#58;&#97;&#x64;&#97;&#109;&#x40;&#111;&#112;&#115;&#99;&#x6f;&#100;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#112;&#x73;&#x63;&#111;&#100;&#101;&#x2e;&#99;&#111;&#109;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#x6f;&#x3a;&#97;&#100;&#97;&#109;&#64;&#x6f;&#112;&#115;&#x63;&#111;&#100;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#x70;&#115;&#99;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#109;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#x3a;&#x6a;&#111;&#x73;&#104;&#117;&#97;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x6a;&#x6f;&#x73;&#104;&#117;&#x61;&#64;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#99;&#x6f;&#109;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#x3a;&#106;&#111;&#x73;&#x68;&#117;&#x61;&#64;&#x6f;&#x70;&#x73;&#99;&#x6f;&#x64;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#104;&#117;&#97;&#x40;&#x6f;&#x70;&#115;&#x63;&#x6f;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -190,8 +190,8 @@ run_list.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-role(1)</li>
</ol>
diff --git a/distro/common/html/knife-search.1.html b/distro/common/html/knife-search.1.html
index 9c0192416b..323928fe80 100644
--- a/distro/common/html/knife-search.1.html
+++ b/distro/common/html/knife-search.1.html
@@ -265,11 +265,11 @@ www.example.com:</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#x61;&#x64;&#97;&#109;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#97;&#x64;&#x61;&#109;&#x40;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#x6f;&#x3a;&#97;&#100;&#97;&#109;&#64;&#x6f;&#112;&#115;&#x63;&#111;&#100;&#x65;&#x2e;&#99;&#111;&#x6d;" data-bare-link="true">&#97;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#x70;&#115;&#99;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#109;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#x61;&#x69;&#x6c;&#116;&#111;&#x3a;&#x6a;&#111;&#x73;&#104;&#x75;&#x61;&#64;&#x6f;&#x70;&#115;&#99;&#111;&#x64;&#101;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#106;&#x6f;&#x73;&#x68;&#117;&#97;&#64;&#x6f;&#112;&#x73;&#99;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#x6d;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#x3a;&#106;&#111;&#x73;&#x68;&#117;&#x61;&#64;&#x6f;&#x70;&#x73;&#99;&#x6f;&#x64;&#x65;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#x6a;&#x6f;&#115;&#104;&#117;&#97;&#x40;&#x6f;&#x70;&#115;&#x63;&#x6f;&#x64;&#x65;&#46;&#99;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -278,8 +278,8 @@ www.example.com:</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-search(1)</li>
</ol>
diff --git a/distro/common/html/knife-ssh.1.html b/distro/common/html/knife-ssh.1.html
index 64fda20128..926876c4c5 100644
--- a/distro/common/html/knife-ssh.1.html
+++ b/distro/common/html/knife-ssh.1.html
@@ -133,11 +133,11 @@ option.</dd>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#x61;&#x64;&#97;&#109;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#97;&#x64;&#x61;&#109;&#x40;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#58;&#x61;&#x64;&#97;&#x6d;&#64;&#x6f;&#x70;&#x73;&#x63;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#112;&#x73;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#x61;&#x69;&#x6c;&#116;&#111;&#x3a;&#x6a;&#111;&#x73;&#104;&#x75;&#x61;&#64;&#x6f;&#x70;&#115;&#99;&#111;&#x64;&#101;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#106;&#x6f;&#x73;&#x68;&#117;&#97;&#64;&#x6f;&#112;&#x73;&#99;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#x6d;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#108;&#116;&#x6f;&#x3a;&#106;&#111;&#115;&#x68;&#x75;&#x61;&#64;&#x6f;&#112;&#x73;&#99;&#x6f;&#x64;&#101;&#46;&#99;&#111;&#109;" data-bare-link="true">&#106;&#x6f;&#115;&#104;&#117;&#x61;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -146,8 +146,8 @@ option.</dd>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-ssh(1)</li>
</ol>
diff --git a/distro/common/html/knife-status.1.html b/distro/common/html/knife-status.1.html
index a30eb37743..b2c13bc1fb 100644
--- a/distro/common/html/knife-status.1.html
+++ b/distro/common/html/knife-status.1.html
@@ -105,11 +105,11 @@ may not be publicly reachable.</p>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#x61;&#x64;&#97;&#109;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#97;&#x64;&#x61;&#109;&#x40;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#58;&#x61;&#x64;&#97;&#x6d;&#64;&#x6f;&#x70;&#x73;&#x63;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#112;&#x73;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#x61;&#x69;&#x6c;&#116;&#111;&#x3a;&#x6a;&#111;&#x73;&#104;&#x75;&#x61;&#64;&#x6f;&#x70;&#115;&#99;&#111;&#x64;&#101;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#106;&#x6f;&#x73;&#x68;&#117;&#97;&#64;&#x6f;&#112;&#x73;&#99;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#x6d;</a>.
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#108;&#116;&#x6f;&#x3a;&#106;&#111;&#115;&#x68;&#x75;&#x61;&#64;&#x6f;&#112;&#x73;&#99;&#x6f;&#x64;&#101;&#46;&#99;&#111;&#109;" data-bare-link="true">&#106;&#x6f;&#115;&#104;&#117;&#x61;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#109;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -118,8 +118,8 @@ may not be publicly reachable.</p>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-status(1)</li>
</ol>
diff --git a/distro/common/html/knife-tag.1.html b/distro/common/html/knife-tag.1.html
index bc219db597..becdb07bcf 100644
--- a/distro/common/html/knife-tag.1.html
+++ b/distro/common/html/knife-tag.1.html
@@ -114,11 +114,11 @@
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#x69;&#108;&#116;&#111;&#x3a;&#x61;&#x64;&#97;&#109;&#x40;&#x6f;&#x70;&#x73;&#99;&#x6f;&#100;&#x65;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#97;&#x64;&#x61;&#109;&#x40;&#111;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#x2e;&#x63;&#x6f;&#x6d;</a> with many contributions from the community.</p>
+<p> Chef was written by Adam Jacob <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#58;&#x61;&#x64;&#97;&#x6d;&#64;&#x6f;&#x70;&#x73;&#x63;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#112;&#x73;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#x6d;</a> with many contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Daniel DeLeo <a href="&#109;&#x61;&#x69;&#x6c;&#116;&#111;&#x3a;&#x64;&#97;&#x6e;&#64;&#x6f;&#x70;&#115;&#x63;&#x6f;&#100;&#101;&#46;&#x63;&#111;&#x6d;" data-bare-link="true">&#100;&#x61;&#110;&#64;&#x6f;&#x70;&#x73;&#99;&#111;&#100;&#x65;&#46;&#x63;&#111;&#109;</a>.
+<p> This manual page was written by Daniel DeLeo <a href="&#x6d;&#x61;&#105;&#108;&#116;&#x6f;&#x3a;&#100;&#97;&#110;&#x40;&#x6f;&#x70;&#115;&#x63;&#111;&#x64;&#101;&#x2e;&#x63;&#111;&#109;" data-bare-link="true">&#100;&#97;&#110;&#64;&#x6f;&#112;&#115;&#99;&#x6f;&#x64;&#x65;&#46;&#x63;&#111;&#x6d;</a>.
Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2.0 License.</p>
<h2 id="CHEF">CHEF</h2>
@@ -127,8 +127,8 @@
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife-tag(1)</li>
</ol>
diff --git a/distro/common/html/knife.1.html b/distro/common/html/knife.1.html
index 9be0f41754..6f3758323d 100644
--- a/distro/common/html/knife.1.html
+++ b/distro/common/html/knife.1.html
@@ -286,12 +286,12 @@ data editing entirely.</dd>
<h2 id="AUTHOR">AUTHOR</h2>
-<p> Chef was written by Adam Jacob <a href="&#x6d;&#97;&#105;&#108;&#116;&#111;&#x3a;&#x61;&#x64;&#x61;&#109;&#x40;&#x6f;&#x70;&#x73;&#x63;&#x6f;&#100;&#101;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x61;&#100;&#x61;&#x6d;&#64;&#x6f;&#x70;&#x73;&#99;&#x6f;&#x64;&#101;&#46;&#x63;&#x6f;&#x6d;</a> of Opscode
+<p> Chef was written by Adam Jacob <a href="&#109;&#97;&#105;&#x6c;&#x74;&#111;&#58;&#x61;&#x64;&#97;&#x6d;&#64;&#x6f;&#x70;&#x73;&#x63;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x61;&#x64;&#x61;&#x6d;&#x40;&#x6f;&#112;&#x73;&#99;&#111;&#x64;&#x65;&#46;&#99;&#x6f;&#x6d;</a> of Opscode
(<a href="http://www.opscode.com" data-bare-link="true">http://www.opscode.com</a>), with contributions from the community.</p>
<h2 id="DOCUMENTATION">DOCUMENTATION</h2>
-<p> This manual page was written by Joshua Timberman <a href="&#109;&#97;&#x69;&#x6c;&#x74;&#x6f;&#58;&#106;&#111;&#x73;&#104;&#117;&#97;&#x40;&#x6f;&#x70;&#x73;&#99;&#111;&#x64;&#x65;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#106;&#x6f;&#115;&#x68;&#117;&#x61;&#64;&#111;&#x70;&#x73;&#x63;&#111;&#100;&#x65;&#46;&#x63;&#x6f;&#109;</a>.</p>
+<p> This manual page was written by Joshua Timberman <a href="&#x6d;&#x61;&#105;&#108;&#116;&#x6f;&#x3a;&#106;&#111;&#115;&#x68;&#x75;&#x61;&#64;&#x6f;&#112;&#x73;&#99;&#x6f;&#x64;&#101;&#46;&#99;&#111;&#109;" data-bare-link="true">&#106;&#x6f;&#115;&#104;&#117;&#x61;&#x40;&#x6f;&#112;&#x73;&#99;&#x6f;&#x64;&#101;&#x2e;&#x63;&#x6f;&#109;</a>.</p>
<h2 id="LICENSE">LICENSE</h2>
@@ -305,8 +305,8 @@ data editing entirely.</dd>
<ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.6.0.hotfix.1</li>
- <li class='tc'>August 2013</li>
+ <li class='tl'>Chef 11.8.0.alpha.0</li>
+ <li class='tc'>July 2013</li>
<li class='tr'>knife(1)</li>
</ol>
diff --git a/distro/common/man/man1/README.md b/distro/common/man/man1/README.md
new file mode 100644
index 0000000000..9a915fb4cc
--- /dev/null
+++ b/distro/common/man/man1/README.md
@@ -0,0 +1,58 @@
+# Man pages for Knife
+
+The source of the Chef Documentation is located at
+http://docs.opscode.com/.
+
+This README documents how the man pages for all of the Knife subcommands
+that are built into the chef-client are managed.
+
+## Source Files
+
+The source files are located in the chef-docs repository:
+https://github.com/opscode/chef-docs
+
+Each Knife subcommand has its own source folder. The folder naming
+pattern begins with man_.
+
+Each man page is a single file called index.html.
+
+In the conf.py file, the following settings are unique to each man page:
+
+`today` setting is used to define the Chef version. This is because we
+don't want an arbitrary date populated in the file, yet we still need a
+version number. For example: `today = 'Chef 11.8`.
+
+`project` setting is set to be the same as the name of the subcommand.
+For example: `project = u'knife-foo'`.
+
+`Options for man page output` settings are set to be similar across all
+man pages, but each one needs to be tailored specifically for the name
+of the man page.
+
+All of the other settings in the General Configuration section should be
+left alone. These exist to ensure that all of the doc builds are sharing
+the right common elements and have the same overall presentation.
+
+## Building Docs
+
+The docs are built using Sphinx and must be set to the `-b man` output.
+Currently, the man pages are built locally and then added to the Chef
+builds in chef-master.
+
+## Editing
+
+These files should never be edited. All of the content is pulled in from
+elsewhere in the chef-docs repo at build time. If changes need to be
+made, those changes are done elsewhere and then the man pages must be
+rebuilt. This is to help ensure that all of the changes are made across
+all of the locations in which these documents need to live. For example,
+by design, every Knife subcommand with a man page also has an HTML doc
+at docs.opscode.com/knife_foo.html.
+
+## License
+
+[Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/)
+
+## Questions?
+
+Open an [Issue](https://github.com/opscode/chef-docs/issues) and ask.
diff --git a/distro/common/man/man1/chef-shell.1 b/distro/common/man/man1/chef-shell.1
index 1e2b55f34c..095e8623c0 100644
--- a/distro/common/man/man1/chef-shell.1
+++ b/distro/common/man/man1/chef-shell.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "CHEF\-SHELL" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "CHEF\-SHELL" "1" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBchef\-shell\fR \- Interactive Chef Console
diff --git a/distro/common/man/man1/knife-bootstrap.1 b/distro/common/man/man1/knife-bootstrap.1
index 651a75b9e2..57afe45343 100644
--- a/distro/common/man/man1/knife-bootstrap.1
+++ b/distro/common/man/man1/knife-bootstrap.1
@@ -1,201 +1,199 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-BOOTSTRAP" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\-bootstrap\fR \- Install Chef Client on a remote host
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBbootstrap\fR \fI(options)\fR
-.
+.TH "KNIFE-BOOTSTRAP" "1" "Chef 11.8" "" "knife bootstrap"
+.SH NAME
+knife-bootstrap \- The man page for the knife bootstrap subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+A bootstrap is a process that installs the chef\-client on a target system so that it can run as a chef\-client and communicate with a server.
+.sp
+The \fBknife bootstrap\fP subcommand is used run a bootstrap operation that installs the chef\-client on the target system. The bootstrap operation must specify the IP address or FQDN of the target system.
+.IP Note
+To bootstrap the chef\-client on Microsoft Windows machines, the \fI\%knife-windows\fP plugins is required, which includes the necessary bootstrap scripts that are used to do the actual installation.
+.RE
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-i\fR, \fB\-\-identity\-file IDENTITY_FILE\fR
-The SSH identity file used for authentication
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-N\fR, \fB\-\-node\-name NAME\fR
-The Chef node name for your new node
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-P\fR, \fB\-\-ssh\-password PASSWORD\fR
-The ssh password
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-x\fR, \fB\-\-ssh\-user USERNAME\fR
-The ssh username
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-p\fR, \fB\-\-ssh\-port PORT\fR
-The ssh port
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB\-\-bootstrap\-version VERSION\fR
-The version of Chef to install
-.
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
.TP
-\fB\-\-bootstrap\-proxy PROXY_URL\fR
-\fBThe proxy server for the node being bootstrapped\fR
-.
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
.TP
-\fB\-\-prerelease\fR
-Install pre\-release Chef gems
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-\fB\-r\fR, \fB\-\-run\-list RUN_LIST\fR
-Comma separated list of roles/recipes to apply
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.TP
-\fB\-\-template\-file TEMPLATE\fR
-Full path to location of template to use
-.
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
.TP
-\fB\-\-sudo\fR
-Execute the bootstrap via sudo
-.
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
.TP
-\fB\-d\fR, \fB\-\-distro DISTRO\fR
-Bootstrap a distro using a template
-.
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
.TP
-\fB\-\-[no\-]host\-key\-verify\fR
-Enable host key verification, which is the default behavior\.
-.
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
.TP
-\fB\-\-hint HINT_NAME[=HINT_FILE]\fR
-Provide the name of a hint (with option JSON file) to set for use by Ohai plugins\.
-.
-.SH "DESCRIPTION"
-Performs a Chef Bootstrap on the target node\. The goal of the bootstrap is to get Chef installed on the target system so it can run Chef Client with a Chef Server\. The main assumption is a baseline OS installation exists\. This sub\-command is used internally by some cloud computing plugins\.
-.
-.P
-The bootstrap sub\-command supports supplying a template to perform the bootstrap steps\. If the distro is not specified (via \fB\-d\fR or \fB\-\-distro\fR option), an Ubuntu 10\.04 host bootstrapped with RubyGems is assumed\. The \fBDISTRO\fR value corresponds to the base filename of the template, in other words \fBDISTRO\fR\.erb\. A template file can be specified with the \fB\-\-template\-file\fR option in which case the \fBDISTRO\fR is not used\. The sub\-command looks in the following locations for the template to use:
-.
-.IP "\(bu" 4
-\fBbootstrap\fR directory in the installed Chef Knife library\.
-.
-.IP "\(bu" 4
-\fBbootstrap\fR directory in the \fB$PWD/\.chef\fR\.
-.
-.IP "\(bu" 4
-\fBbootstrap\fR directory in the users \fB$HOME/\.chef\fR\.
-.
-.IP "" 0
-.
-.P
-The default bootstrap templates are scripts that get copied to the target node (FQDN)\. The following distros are supported:
-.
-.IP "\(bu" 4
-centos5\-gems
-.
-.IP "\(bu" 4
-fedora13\-gems
-.
-.IP "\(bu" 4
-ubuntu10\.04\-gems
-.
-.IP "\(bu" 4
-ubuntu10\.04\-apt
-.
-.IP "" 0
-.
-.P
-The gems installations will use RubyGems 1\.3\.6 and Chef installed as a gem\. The apt installation will use the Opscode APT repository\.
-.
-.P
-In addition to handling the software installation, these bootstrap templates do the following:
-.
-.IP "\(bu" 4
-Write the validation\.pem per the local knife configuration\.
-.
-.IP "\(bu" 4
-Write a default config file for Chef (\fB/etc/chef/client\.rb\fR) using values from the \fBknife\.rb\fR\.
-.
-.IP "\(bu" 4
-Create a JSON attributes file containing the specified run list and run Chef\.
-.
-.IP "" 0
-.
-.P
-In the case of the RubyGems, the \fBclient\.rb\fR will be written from scratch with a minimal set of values; see \fBEXAMPLES\fR\. In the case of APT Package installation, \fBclient\.rb\fR will have the \fBvalidation_client_name\fR appended if it is not set to \fBchef\-validator\fR (default config value), and the \fBnode_name\fR will be added if \fBchef_node_name\fR option is specified\.
-.
-.P
-When this is complete, the bootstrapped node will have:
-.
-.IP "\(bu" 4
-Latest Chef version installed from RubyGems or APT Packages from Opscode\. This may be a later version than the local system\.
-.
-.IP "\(bu" 4
-Be validated with the configured Chef Server\.
-.
-.IP "\(bu" 4
-Have run Chef with its default run list if one is specfied\.
-.
-.IP "" 0
-.
-.P
-Additional custom bootstrap templates can be created and stored in \fB\.chef/bootstrap/DISTRO\.erb\fR, replacing \fBDISTRO\fR with the value passed with the \fB\-d\fR or \fB\-\-distro\fR option\. See \fBEXAMPLES\fR for more information\.
-.
-.SH "EXAMPLES"
-Setting up a custom bootstrap is fairly straightforward\. Create a \fB\.chef/bootstrap\fR directory in your Chef Repository or in \fB$HOME/\.chef/bootstrap\fR\. Then create the ERB template file\.
-.
-.IP "" 4
-.
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
.nf
-
-mkdir ~/\.chef/bootstrap
-vi ~/\.chef/bootstrap/debian5\.0\-apt\.erb
-.
+.ft C
+$ knife bootstrap FQDN_or_IP_ADDRESS (options)
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-For example, to create a new bootstrap template that should be used when setting up a new Debian node\. Edit the template to run the commands, set up the validation certificate and the client configuration file, and finally to run chef\-client on completion\. The bootstrap template can be called with:
-.
-.IP "" 4
-.
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-A\fP, \fB\-\-forward\-agent\fP
+Indicates that SSH agent forwarding is enabled.
+.TP
+.B \fB\-\-bootstrap\-proxy PROXY_URL\fP
+The proxy server for the node that is the target of a bootstrap operation.
+.TP
+.B \fB\-\-bootstrap\-version VERSION\fP
+The version of the chef\-client to install.
+.TP
+.B \fB\-d DISTRO\fP, \fB\-\-distro DISTRO\fP
+The template file to be used during a bootstrap operation. The following distributions are supported: \fBchef\-full\fP (the default bootstrap), \fBcentos5\-gems\fP, \fBfedora13\-gems\fP, \fBubuntu10.04\-gems\fP, \fBubuntu10.04\-apt\fP, \fBubuntu12.04\-gems\fP, and the name of a custom bootstrap template file. When this option is used, Knife will search for the template file in the following order: the \fBbootstrap/\fP folder in the current working directory, the \fBbootstrap/\fP folder in the chef\-repo, the \fBbootstrap/\fP folder in the \fB~/.chef/\fP directory, or a default bootstrap file. Do not use the \fB\-\-template\-file\fP option when \fB\-\-distro\fP is specified.
+.TP
+.B \fB\-G GATEWAY\fP, \fB\-\-ssh\-gateway GATEWAY\fP
+The SSH tunnel or gateway that is used to run a bootstrap action on a machine that is not accessible from the workstation.
+.TP
+.B \fB\-\-hint HINT_NAME[=HINT_FILE]\fP
+An Ohai hint to be set on the target of the bootstrap. The hint is contained in a file and is formatted as JSON: \fB{"attribute":"value","attribute":"value"...}\fP. \fBHINT_NAME\fP is the name of the hint and \fBHINT_FILE\fP is the name of the hint file located at \fB/etc/chef/ohai/hints/HINT_FILE.json\fP. Use multiple \fB\-\-hint\fP options in the command to specify multiple hints.
+.TP
+.B \fB\-i IDENTITY_FILE\fP, \fB\-\-identity\-file IDENTITY_FILE\fP
+The SSH identity file used for authentication. Key\-based authentication is recommended.
+.TP
+.B \fB\-j JSON_ATTRIBS\fP, \fB\-\-json\-attributes JSON_ATTRIBS\fP
+A JSON string that is added to the first run of a chef\-client.
+.TP
+.B \fB\-N NAME\fP, \fB\-\-node\-name NAME\fP
+The name of the node.
+.TP
+.B \fB\-\-[no\-]host\-key\-verify\fP
+Use \fB\-\-no\-host\-key\-verify\fP to disable host key verification. Default setting: \fB\-\-host\-key\-verify\fP.
+.TP
+.B \fB\-p PORT\fP, \fB\-\-ssh\-port PORT\fP
+The SSH port.
+.TP
+.B \fB\-P PASSWORD\fP, \fB\-\-ssh\-password PASSWORD\fP
+The SSH password. This can be used to pass the password directly on the command line. If this option is not specified (and a password is required) Knife will prompt for the password.
+.TP
+.B \fB\-\-prerelease\fP
+Indicates that pre\-release gems should be installed.
+.TP
+.B \fB\-r RUN_LIST\fP, \fB\-\-run\-list RUN_LIST\fP
+A comma\-separated list of roles and/or recipes to be applied.
+.TP
+.B \fB\-\-secret SECRET\fP
+The encryption key that is used for values contained within a data bag.
+.TP
+.B \fB\-\-secret\-file FILE\fP
+The path to the file that contains the encryption key.
+.TP
+.B \fB\-\-sudo\fP
+Indicates that a bootstrap operation should be executed using sudo.
+.TP
+.B \fB\-\-template\-file TEMPLATE\fP
+The path to a template file that will be used during a bootstrap operation. Do not use the \fB\-\-distro\fP option when \fB\-\-template\-file\fP is specified.
+.TP
+.B \fB\-\-use\-sudo\-password\fP
+Indicates that a bootstrap operation is done using sudo, with the password specified by the \fB\-P\fP (or \fB\-\-ssh\-password\fP) option.
+.TP
+.B \fB\-x USERNAME\fP, \fB\-\-ssh\-user USERNAME\fP
+The SSH user name.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To pass an SSH password as part of the command:
+.sp
.nf
-
-knife bootstrap mynode\.example\.com \-\-template\-file ~/\.chef/bootstrap/debian5\.0\-apt\.erb
-.
+.ft C
+$ knife bootstrap 192.168.1.1 \-x username \-P PASSWORD \-\-sudo
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-Or,
-.
-.IP "" 4
-.
+.sp
+To use a file that contains a private key:
+.sp
.nf
-
-knife bootstrap mynode\.example\.com \-\-distro debian5\.0\-apt
-.
+.ft C
+$ knife bootstrap 192.168.1.1 \-x username \-i ~/.ssh/id_rsa \-\-sudo
+.ft P
.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.IP "" 0
-.
-.P
-The \fB\-\-distro\fR parameter will automatically look in the \fB~/\.chef/bootstrap\fR directory for a file named \fBdebian5\.0\-apt\.erb\fR\.
-.
-.P
-Templates provided by the Chef installation are located in \fBBASEDIR/lib/chef/knife/bootstrap/*\.erb\fR, where \fIBASEDIR\fR is the location where the package or Gem installed the Chef client libraries\.
-.
-.SH "BUGS"
-\fBknife bootstrap\fR is not capable of bootstrapping multiple hosts in parallel\.
-.
-.P
-The bootstrap script is passed as an argument to sh(1) on the remote system, so sensitive information contained in the script will be visible to other users via the process list using tools such as ps(1)\.
-.
-.SH "SEE ALSO"
-\fBknife\-ssh\fR(1)
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-client.1 b/distro/common/man/man1/knife-client.1
index 4479856b9f..50b42c759b 100644
--- a/distro/common/man/man1/knife-client.1
+++ b/distro/common/man/man1/knife-client.1
@@ -1,99 +1,370 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-CLIENT" "1" "Chef 11.8" "" "knife client"
+.SH NAME
+knife-client \- The man page for the knife client subcommand.
.
-.TH "KNIFE\-CLIENT" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.nr rst2man-indent-level 0
.
-.SH "NAME"
-\fBknife\-client\fR \- Manage Chef API Clients
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBclient\fR \fIsub\-command\fR \fI(options)\fR
-.
-.SH "SUB\-COMMANDS"
-Client subcommands follow a basic create, read, update, delete (CRUD) pattern\. The Following subcommands are available:
-.
-.SH "BULK DELETE"
-\fBknife client bulk delete\fR \fIregex\fR \fI(options)\fR
-.
-.P
-Delete clients where the client name matches the regular expression \fIregex\fR on the Chef Server\. The regular expression should be given as a quoted string, and not surrounded by forward slashes\.
-.
-.SH "CREATE"
-\fBknife client create\fR \fIclient name\fR \fI(options)\fR
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
.
+.sp
+When a node runs the chef\-client for the first time, it generally does not yet have an API client identity, and so it cannot make authenticated requests to the server. This is where the validation client\-\-\-known as the chef\-validator\-\-\-comes in. When the chef\-client runs, it checks if it has a client key. If the client key does not exist, it then attempts to borrow the identity of the chef\-validator to register itself with the server. In order to register with the server, the private key for the chef\-validator needs to be copied to the host and placed in /etc/chef/validation.pem.
+.sp
+Once the chef\-client has registered itself with the server, it no longer uses the validation client for anything. It is recommended that you delete the private key for the chef\-validator from the host after the host has registered or use the \fBdelete_validation\fP recipe that can be found in the \fBchef\-client\fP cookbook (\fI\%https://github.com/opscode-cookbooks/chef-client\fP).
+.sp
+The \fBknife client\fP subcommand is used to manage an API client list and their associated RSA public key\-pairs. This allows authentication requests to be made to the server by any entity that uses the Chef Server API, such as the chef\-client and Knife.
+.sp
+This subcommand has the following syntax:
+.sp
+.nf
+.ft C
+$ knife client [ARGUMENT] (options)
+.ft P
+.fi
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-a\fR, \fB\-\-admin\fR
-Create the client as an admin
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-f\fR, \fB\-\-file FILE\fR
-Write the key to a file
-.
-.P
-Create a new client\. This generates an RSA keypair\. The private key will be displayed on \fISTDOUT\fR or written to the named file\. The public half will be stored on the Server\. For \fIchef\-client\fR systems, the private key should be copied to the system as \fB/etc/chef/client\.pem\fR\.
-.
-.P
-Admin clients should be created for users that will use \fIknife\fR to access the API as an administrator\. The private key will generally be copied to \fB~/\.chef/client\e_name\.pem\fR and referenced in the \fBknife\.rb\fR configuration file\.
-.
-.SH "DELETE"
-\fBknife client delete\fR \fIclient name\fR \fI(options)\fR
-.
-.P
-Deletes a registered client\.
-.
-.SH "EDIT"
-\fBclient edit\fR \fIclient name\fR \fI(options)\fR
-.
-.P
-Edit a registered client\.
-.
-.SH "LIST"
-\fBclient list\fR \fI(options)\fR
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-w\fR, \fB\-\-with\-uri\fR
-Show corresponding URIs
-.
-.P
-List all registered clients\.
-.
-.SH "REREGISTER"
-\fBclient reregister\fR \fIclient name\fR \fI(options)\fR
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-f\fR, \fB\-\-file FILE\fR
-Write the key to a file
-.
-.P
-Regenerate the RSA keypair for a client\. The public half will be stored on the server and the private key displayed on \fISTDOUT\fR or written to the named file\. This operation will invalidate the previous keypair used by the client, preventing it from authenticating with the Chef Server\. Use care when reregistering the validator client\.
-.
-.SH "SHOW"
-\fBclient show\fR \fIclient name\fR \fI(options)\fR
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-a\fR, \fB\-\-attribute ATTR\fR
-Show only one attribute
-.
-.P
-Show a client\. Output format is determined by the \-\-format option\.
-.
-.SH "DESCRIPTION"
-Clients are identities used for communication with the Chef Server API, roughly equivalent to user accounts on the Chef Server, except that clients only communicate with the Chef Server API and are authenticated via request signatures\.
-.
-.P
-In the typical case, there will be one client object on the server for each node, and the corresponding client and node will have identical names\.
-.
-.P
-In the Chef authorization model, there is one special client, the "validator", which is authorized to create new non\-administrative clients but has minimal privileges otherwise\. This identity is used as a sort of "guest account" to create a client identity when initially setting up a host for management with Chef\.
-.
-.SH "SEE ALSO"
-\fBknife\-node\fR(1)
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH BULK DELETE
+.sp
+The \fBbulk delete\fP argument is used to delete any API client that matches a pattern defined by a regular expression. The regular expression must be within quotes and not be surrounded by forward slashes (/).
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife client bulk delete REGEX
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.SH CREATE
+.sp
+The \fBcreate\fP argument is used to create a new API client. This process will generate an RSA key pair for the named API client. The public key will be stored on the server and the private key will be displayed on \fBSTDOUT\fP or written to a named file.
+.INDENT 0.0
+.IP \(bu 2
+For the chef\-client, the private key should be copied to the system as /etc/chef/client.pem.
+.IP \(bu 2
+For Knife, the private key is typically copied to ~/.chef/client_name.pem and referenced in the knife.rb configuration file.
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife client create CLIENT_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-admin\fP
+Indicates that a client will be created as an admin client. This is required when users of the open source server need to access the Chef Server API as an administrator. This option only works when used with the open source server and will have no effect when used with Hosted Chef or Private Chef.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To create a Chef Admin client with the name "exampleorg" and save its private key to a file, enter:
+.sp
+.nf
+.ft C
+$ knife client create exampleorg \-a \-f "/etc/chef/client.pem"
+.ft P
+.fi
+.sp
+When running the \fBcreate\fP argument on Hosted Chef or Private Chef, be sure to omit the \fB\-a\fP option:
+.sp
+.nf
+.ft C
+$ knife client create exampleorg \-f "/etc/chef/client.pem"
+.ft P
+.fi
+.SH DELETE
+.sp
+The \fBdelete\fP argument is used to delete a registered API client.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife client delete CLIENT_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To delete a client with the name "client_foo", enter:
+.sp
+.nf
+.ft C
+$ knife client delete client_foo
+.ft P
+.fi
+.sp
+Type \fBY\fP to confirm a deletion.
+.SH EDIT
+.sp
+The \fBedit\fP argument is used to edit the details of a registered API client. When this argument is run, Knife will open $EDITOR to enable editing of the \fBadmin\fP attribute. (None of the other attributes should be changed using this argument.) When finished, Knife will update the server with those changes.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife client edit CLIENT_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To edit a client with the name "exampleorg", enter:
+.sp
+.nf
+.ft C
+$ knife client edit exampleorg
+.ft P
+.fi
+.SH LIST
+.sp
+The \fBlist\fP argument is used to view a list of registered API client.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife client list (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To verify the API client list for the server, enter:
+.sp
+.nf
+.ft C
+$ knife client list
+.ft P
+.fi
+.sp
+to return something similar to:
+.sp
+.nf
+.ft C
+exampleorg
+i\-12345678
+rs\-123456
+.ft P
+.fi
+.sp
+To verify that an API client can authenticate to the
+server correctly, try getting a list of clients using \fB\-u\fP and \fB\-k\fP options to specify its name and private key:
+.sp
+.nf
+.ft C
+$ knife client list \-u ORGNAME \-k .chef/ORGNAME.pem
+.ft P
+.fi
+.SH REREGISTER
+.sp
+The \fBreregister\fP argument is used to regenerate an RSA key pair for an API client. The public key will be stored on the server and the private key will be displayed on \fBSTDOUT\fP or written to a named file.
+.IP Note
+Running this argument will invalidate the previous RSA key pair, making it unusable during authentication to the server.
+.RE
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife client reregister CLIENT_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To regenerate the RSA key pair for a client named "testclient" and save it to a file named "rsa_key", enter:
+.sp
+.nf
+.ft C
+$ knife client regenerate testclient \-f rsa_key
+.ft P
+.fi
+.SH SHOW
+.sp
+The \fBshow\fP argument is used to show the details of an API client.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife client show CLIENT_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a ATTR\fP, \fB\-\-attribute ATTR\fP
+The attribute (or attributes) to show.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view a client named "testclient", enter:
+.sp
+.nf
+.ft C
+$ knife client show testclient
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+admin: false
+chef_type: client
+json_class: Chef::ApiClient
+name: testclient
+public_key:
+.ft P
+.fi
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife role show devops \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-configure.1 b/distro/common/man/man1/knife-configure.1
index 1c3d793364..8ca138f3d4 100644
--- a/distro/common/man/man1/knife-configure.1
+++ b/distro/common/man/man1/knife-configure.1
@@ -1,88 +1,152 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-CONFIGURE" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\-configure\fR \- Generate configuration files for knife or Chef Client
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBconfigure\fR [client] \fI(options)\fR
-.
-.SH "DESCRIPTION"
-Generates a knife\.rb configuration file interactively\. When given the \-\-initial option, also creates a new administrative user\.
-.
-.SH "CONFIGURE SUBCOMMANDS"
-\fBknife configure\fR \fI(options)\fR
-.
+.TH "KNIFE-CONFIGURE" "1" "Chef 11.8" "" "knife configure"
+.SH NAME
+knife-configure \- The man page for the knife configure subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife configure\fP subcommand is used to create the knife.rb and client.rb files so that they can be distributed to workstations and nodes.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-i\fR, \fB\-\-initial\fR
-Create an initial API Client
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-r\fR, \fB\-\-repository REPO\fR
-The path to your chef\-repo
-.
-.P
-Create a configuration file for knife\. This will prompt for values to enter into the file\. Default values are listed in square brackets if no other entry is typed\. See \fBknife\fR(1) for a description of configuration options\.
-.
-.P
-\fBknife configure client\fR \fIdirectory\fR
-.
-.P
-Read the \fIknife\.rb\fR config file and generate a config file suitable for use in \fI/etc/chef/client\.rb\fR and copy the validation certificate into the specified \fIdirectory\fR\.
-.
-.SH "EXAMPLES"
-.
-.IP "\(bu" 4
-On a freshly installed Chef Server, use \fIknife configure \-i\fR to create an administrator and knife configuration file\. Leave the field blank to accept the default value\. On most systems, the default values are acceptable\.
-.
-.IP
-user@host$ knife configure \-i
-.
-.br
-Please enter the chef server URL: [http://localhost:4000]
-.
-.br
-Please enter a clientname for the new client: [username]
-.
-.br
-Please enter the existing admin clientname: [chef\-webui]
-.
-.br
-Please enter the location of the existing admin client\'s private key: [/etc/chef/webui\.pem]
-.
-.br
-Please enter the validation clientname: [chef\-validator]
-.
-.br
-Please enter the location of the validation key: [/etc/chef/validation\.pem]
-.
-.br
-Please enter the path to a chef repository (or leave blank):
-.
-.br
-Creating initial API user\.\.\.
-.
-.br
-Created (or updated) client[username]
-.
-.br
-Configuration file written to /home/username/\.chef/knife\.rb
-.
-.IP
-This creates a new administrator client named \fIusername\fR, writes a configuration file to \fI/home/username/\.chef/knife\.rb\fR, and the private key to \fI/home/username/\.chef/username\.pem\fR\. The configuration file and private key may be copied to another system to facilitate administration of the Chef Server from a remote system\. Depending on the value given for the Chef Server URL, you may need to modify that setting after copying to a remote host\.
-.
-.IP "" 0
-.
-.SH "SEE ALSO"
-\fBknife\fR(1) \fBknife\-client\fR(1)
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife configure (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-admin\-client\-name NAME\fP
+The name of the client, typically the name of the admin client.
+.TP
+.B \fB\-\-admin\-client\-key PATH\fP
+The path to the private key used by the client, typically a file named \fBadmin.pem\fP.
+.TP
+.B \fB\-i\fP, \fB\-\-initial\fP
+Use to create a API client, typically an administrator client on a freshly\-installed server.
+.TP
+.B \fB\-r REPO\fP, \fB\-\-repository REPO\fP
+The path to the chef\-repo.
+.TP
+.B \fB\-\-validation\-client\-name NAME\fP
+The name of the validation client.
+.TP
+.B \fB\-\-validation\-key PATH\fP
+The path to the validation key used by the client, typically a file named \fBvalidation.pem\fP.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To create a knife.rb file, enter:
+.sp
+.nf
+.ft C
+$ knife configure
+.ft P
+.fi
+.sp
+To configure a client.rb, enter:
+.sp
+.nf
+.ft C
+$ knife configure client \(aq/directory\(aq
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-cookbook-site.1 b/distro/common/man/man1/knife-cookbook-site.1
index 6a0d7a61bd..049900fce8 100644
--- a/distro/common/man/man1/knife-cookbook-site.1
+++ b/distro/common/man/man1/knife-cookbook-site.1
@@ -1,145 +1,479 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-COOKBOOK\-SITE" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\-cookbook\-site\fR \- Install and update open source cookbooks
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBcookbook site\fR \fIsub\-command\fR \fI(options)\fR
-.
-.SH "COOKBOOK SITE SUB\-COMMANDS"
-\fBknife cookbook site\fR provides the following subcommands:
-.
-.SH "INSTALL"
-\fBcookbook site install COOKBOOK [VERSION]\fR \fI(options)\fR
-.
+.TH "KNIFE-COOKBOOK-SITE" "1" "Chef 11.8" "" "knife cookbook site"
+.SH NAME
+knife-cookbook-site \- The man page for the knife cookbook site subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The Cookbooks Site API is used to provide access to the cookbooks community hosted at \fI\%https://cookbooks.opscode.com\fP. All of the cookbooks in the community are accessible through a REST API located at \fI\%https://cookbooks.opscode.com/api/v1/\fP by using any of the supported endpoints. In most cases, using Knife and the \fBknife cookbook site\fP sub\-command (and any of its arguments) is the recommended method of interacting with these cookbooks, but in some cases, using the REST API directly may make sense.
+.sp
+The \fBknife cookbook site\fP subcommand is used to interact with cookbooks that are located at \fI\%https://cookbooks.opscode.com\fP. A user account is required for any community actions that write data to this site. The following arguments do not require a user account: \fBdownload\fP, \fBsearch\fP, \fBinstall\fP, and \fBlist\fP.
+.sp
+This subcommand has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook site [ARGUMENT] (options)
+.ft P
+.fi
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-D\fR, \fB\-\-skip\-dependencies\fR
-Skip automatic installation of dependencies\.
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-o\fR, \fB\-\-cookbook\-path PATH\fR
-Install cookbooks to PATH
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-B\fR, \fB\-\-branch BRANCH\fR
-Default branch to work with [defaults to master]
-.
-.P
-Uses git(1) version control in conjunction with the cookbook site to install community contributed cookbooks to your local cookbook repository\. Running \fBknife cookbook site install\fR does the following:
-.
-.IP "1." 4
-A new "pristine copy" branch is created in git for tracking the upstream;
-.
-.IP "2." 4
-All existing cookbooks are removed from the branch;
-.
-.IP "3." 4
-The cookbook is downloaded from the cookbook site in tarball form;
-.
-.IP "4." 4
-The downloaded cookbook is untarred, and its contents commited via git;
-.
-.IP "5." 4
-The pristine copy branch is merged into the master branch\.
-.
-.IP "" 0
-.
-.P
-By installing cookbook with this process, you can locally modify the upstream cookbook in your master branch and let git maintain your changes as a separate patch\. When an updated upstream version becomes available, you will be able to merge the upstream changes while maintaining your local modifications\.
-.
-.P
-Unless \fI\-\-skip\-dependencies\fR is specified, the process is applied recursively to all the cookbooks \fICOOKBOOK\fR depends on (via metadata \fIdependencies\fR)\.
-.
-.SH "DOWNLOAD"
-\fBknife cookbook site download COOKBOOK [VERSION]\fR \fI(options)\fR
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-f\fR, \fB\-\-file FILE\fR
-The filename to write to
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-\-force\fR
-Force download deprecated cookbook
-.
-.P
-Downloads a specific cookbook from the Community site, optionally specifying a certain version\.
-.
-.SH "LIST"
-\fBknife cookbook site list\fR \fI(options)\fR
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB\-w\fR, \fB\-\-with\-uri\fR
-Show corresponding URIs
-.
-.P
-Lists available cookbooks from the Community site\.
-.
-.SH "SEARCH"
-\fBknife cookbook site search QUERY\fR \fI(options)\fR
-.
-.P
-Searches for available cookbooks matching the specified query\.
-.
-.SH "SHARE"
-\fBknife cookbook site share COOKBOOK CATEGORY\fR \fI(options)\fR
-.
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
.TP
-\fB\-k\fR, \fB\-\-key KEY\fR
-API Client Key
-.
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
.TP
-\fB\-u\fR, \fB\-\-user USER\fR
-API Client Username
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-\fB\-o\fR, \fB\-\-cookbook\-path PATH:PATH\fR
-A colon\-separated path to look for cookbooks in
-.
-.P
-Uploads the specified cookbook using the given category to the Opscode cookbooks site\. Requires a login user and certificate for the Opscode Cookbooks site\. By default, knife will use the username and API key you\'ve configured in your configuration file; otherwise you must explicitly set these values on the command line or use an alternate configuration file\.
-.
-.SH "UNSHARE"
-\fBknife cookbook site unshare COOKBOOK\fR
-.
-.P
-Stops sharing the specified cookbook on the Opscode cookbooks site\.
-.
-.SH "SHOW"
-\fBknife cookbook site show COOKBOOK [VERSION]\fR \fI(options)\fR
-.
-.P
-Shows information from the site about a particular cookbook\.
-.
-.SH "DESCRIPTION"
-The cookbook site, \fIhttp://community\.opscode\.com/\fR, is a cookbook distribution service operated by Opscode\. This service provides users with a central location to publish cookbooks for sharing with other community members\.
-.
-.P
-\fBknife cookbook site\fR commands provide an interface to the cookbook site\'s HTTP API\. For commands that read data from the API, no account is required\. In order to upload cookbooks using the \fBknife cookbook site share\fR command, you must create an account on the cookbook site and configure your credentials via command line option or in your knife configuration file\.
-.
-.SH "EXAMPLES"
-Uploading cookbooks to the Opscode cookbooks site:
-.
-.IP "" 4
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH DOWNLOAD
+.sp
+The \fBdownload\fP argument is used to download a cookbook from the community website. A cookbook will be downloaded as a tar.gz archive and placed in the current working directory. If a cookbook (or cookbook version) has been deprecated and the \fB\-\-force\fP option is not used, Knife will alert the user that the cookbook is deprecated and then will provide the name of the most recent non\-deprecated version of that cookbook.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
.nf
-
-knife cookbook site share example Other \-k ~/\.chef/USERNAME\.pem \-u USERNAME
-.
+.ft C
+$ knife cookbook site download COOKBOOK_NAME [COOKBOOK_VERSION] (options)
+.ft P
.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fBCOOKBOOK_VERSION\fP
+The version of a cookbook to be downloaded. If a cookbook has only one version, this option does not need to be specified. If a cookbook has more than one version and this option is not specified, Knife will prompt for a version.
+.TP
+.B \fB\-f\fP, \fB\-\-force\fP
+Indicates that an existing directory will be overwritten.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To download the cookbook "getting\-started", enter:
+.sp
+.nf
+.ft C
+$ knife cookbook site download getting\-started
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+Downloading getting\-started from the cookbooks site at version 0.3.0 to
+ /Users/sdanna/opscodesupport/getting\-started\-0.3.0.tar.gz
+Cookbook saved: /Users/sdanna/opscodesupport/getting\-started\-0.3.0.tar.gz
+.ft P
+.fi
+.SH INSTALL
+.sp
+The \fBinstall\fP argument is used to install a cookbook that has been downloaded from the community site to a local git repository . This action uses the git version control system in conjunction with the \fI\%https://cookbooks.opscode.com\fP site to install community\-contributed cookbooks to the local chef\-repo. Using this argument does the following:
+.INDENT 0.0
+.INDENT 3.5
+.INDENT 0.0
+.IP 1. 3
+A new "pristine copy" branch is created in git for tracking the upstream.
+.IP 2. 3
+All existing versions of a cookbook are removed from the branch.
+.IP 3. 3
+The cookbook is downloaded from \fI\%https://cookbooks.opscode.com\fP in the tar.gz format.
+.IP 4. 3
+The downloaded cookbook is untarred and its contents are committed to git and a tag is created.
+.IP 5. 3
+The "pristine copy" branch is merged into the master branch.
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.sp
+This process allows the upstream cookbook in the master branch to be modified while letting git maintain changes as a separate patch. When an updated upstream version becomes available, those changes can be merged while maintaining any local modifications.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook site install COOKBOOK_NAME [COOKBOOK_VERSION] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-b\fP, \fB\-\-use\-current\-branch\fP
+Indicates that the current branch will be used.
+.TP
+.B \fB\-B BRANCH\fP, \fB\-\-branch BRANCH\fP
+The name of the default branch. This will default to the master branch.
+.TP
+.B \fBCOOKBOOK_VERSION\fP
+The version of the cookbook to be installed. If a version is not specified, the most recent version of the cookbook will be installed.
+.TP
+.B \fB\-D\fP, \fB\-\-skip\-dependencies\fP
+Indicates that all cookbooks to which the installed cookbook has a dependency will not be installed.
+.TP
+.B \fB\-o PATH:PATH\fP, \fB\-\-cookbook\-path PATH:PATH\fP
+The directory in which cookbook are created. This can be a colon\-separated path.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To install the cookbook "getting\-started", enter:
+.sp
+.nf
+.ft C
+$ knife cookbook site install getting\-started
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+Installing getting\-started to /Users/sdanna/opscodesupport/.chef/../cookbooks
+Checking out the master branch.
+Creating pristine copy branch chef\-vendor\-getting\-started
+Downloading getting\-started from the cookbooks site at version 0.3.0 to
+ /Users/sdanna/opscodesupport/.chef/../cookbooks/getting\-started.tar.gz
+Cookbook saved: /Users/sdanna/opscodesupport/.chef/../cookbooks/getting\-started.tar.gz
+Removing pre\-existing version.
+Uncompressing getting\-started version /Users/sdanna/opscodesupport/.chef/../cookbooks.
+removing downloaded tarball
+1 files updated, committing changes
+Creating tag cookbook\-site\-imported\-getting\-started\-0.3.0
+Checking out the master branch.
+Updating 4d44b5b..b4c32f2
+Fast\-forward
+ cookbooks/getting\-started/README.rdoc | 4 +++
+ cookbooks/getting\-started/attributes/default.rb | 1 +
+ cookbooks/getting\-started/metadata.json | 29 ++++++++++++++++++++
+ cookbooks/getting\-started/metadata.rb | 6 ++++
+ cookbooks/getting\-started/recipes/default.rb | 23 +++++++++++++++
+ .../templates/default/chef\-getting\-started.txt.erb | 5 +++
+ 6 files changed, 68 insertions(+), 0 deletions(\-)
+ create mode 100644 cookbooks/getting\-started/README.rdoc
+ create mode 100644 cookbooks/getting\-started/attributes/default.rb
+ create mode 100644 cookbooks/getting\-started/metadata.json
+ create mode 100644 cookbooks/getting\-started/metadata.rb
+ create mode 100644 cookbooks/getting\-started/recipes/default.rb
+ create mode 100644 cookbooks/getting\-started/templates/default/chef\-getting\-started.txt.erb
+Cookbook getting\-started version 0.3.0 successfully installed
+.ft P
+.fi
+.SH LIST
+.sp
+The \fBlist\fP argument is used to view a list of cookbooks that are currently available at \fI\%https://cookbooks.opscode.com\fP.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook site list
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view a list of cookbooks at \fI\%https://cookbooks.opscode.com\fP server, enter:
+.sp
+.nf
+.ft C
+$ knife cookbook site list
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+1password homesick rabbitmq
+7\-zip hostname rabbitmq\-management
+AmazonEC2Tag hosts rabbitmq_chef
+R hosts\-awareness rackspaceknife
+accounts htop radiant
+ack\-grep hudson rails
+activemq icinga rails_enterprise
+ad id3lib redis\-package
+ad\-likewise iftop redis2
+ant iis redmine
+[...truncated...]
+.ft P
+.fi
+.SH SEARCH
+.sp
+The \fBsearch\fP argument is used to search for a cookbook at \fI\%https://cookbooks.opscode.com\fP. A search query is used to return a list of cookbooks at \fI\%https://cookbooks.opscode.com\fP and uses the same syntax as the \fBknife search\fP sub\-command.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook site search SEARCH_QUERY (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To search for all of the cookbooks that can be used with Apache, enter:
+.sp
+.nf
+.ft C
+$ knife cookbook site search apache*
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+apache2:
+ cookbook: http://cookbooks.opscode.com/api/v1/cookbooks/apache2
+ cookbook_description: Installs and configures apache2 using Debian symlinks with helper definitions
+ cookbook_maintainer: opscode
+ cookbook_name: apache2
+instiki:
+ cookbook: http://cookbooks.opscode.com/api/v1/cookbooks/instiki
+ cookbook_description: Installs instiki, a Ruby on Rails wiki server under passenger+Apache2.
+ cookbook_maintainer: jtimberman
+ cookbook_name: instiki
+kickstart:
+ cookbook: http://cookbooks.opscode.com/api/v1/cookbooks/kickstart
+ cookbook_description: Creates apache2 vhost and serves a kickstart file.
+ cookbook_maintainer: opscode
+ cookbook_name: kickstart
+[...truncated...]
+.ft P
+.fi
+.SH SHARE
+.sp
+The \fBshare\fP argument is used to add a cookbook to \fI\%https://cookbooks.opscode.com\fP. This action will require a user account and a certificate for \fI\%http://community.opscode.com\fP. By default, Knife will use the user name and API key that is identified in the configuration file used during the upload; otherwise these values must be specified on the command line or in an alternate configuration file. If a cookbook already exists on \fI\%https://cookbooks.opscode.com\fP, then only an owner or maintainer of that cookbook can make updates.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook site share COOKBOOK_NAME CATEGORY (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fBCATEGORY\fP
+The cookbook category: \fBDatabases\fP, \fBWeb Servers\fP, \fBProcess Management\fP, \fBMonitoring and Trending\fP, \fBProgramming Languages\fP, \fBPackage Management\fP, \fBApplications\fP, \fBNetworking\fP, \fBOperations Systems and Virtualization\fP, \fBUtilities\fP, or \fBOther\fP.
+.TP
+.B \fB\-o PATH:PATH\fP, \fB\-\-cookbook\-path PATH:PATH\fP
+The directory in which cookbook are created. This can be a colon\-separated path.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To share a cookbook named "apache2":
+.sp
+.nf
+.ft C
+$ knife cookbook site share "apache2" "Web Servers"
+.ft P
+.fi
+.SH SHOW
+.sp
+The \fBshow\fP argument is used to view information about a cookbook on \fI\%https://cookbooks.opscode.com\fP.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook site show COOKBOOK_NAME [COOKBOOK_VERSION]
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fBCOOKBOOK_VERSION\fP
+The version of a cookbook to be shown. If a cookbook has only one version, this option does not need to be specified. If a cookbook has more than one version and this option is not specified, a list of cookbook versions will be returned.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To show the details for a cookbook named "haproxy":
+.sp
+.nf
+.ft C
+$ knife cookbook site show haproxy
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+average_rating:
+category: Networking
+created_at: 2009\-10\-25T23:51:07Z
+description: Installs and configures haproxy
+external_url:
+latest_version: http://cookbooks.opscode.com/api/v1/cookbooks/haproxy/versions/1_0_3
+maintainer: opscode
+name: haproxy
+updated_at: 2011\-06\-30T21:53:25Z
+versions:
+ http://cookbooks.opscode.com/api/v1/cookbooks/haproxy/versions/1_0_3
+ http://cookbooks.opscode.com/api/v1/cookbooks/haproxy/versions/1_0_2
+ http://cookbooks.opscode.com/api/v1/cookbooks/haproxy/versions/1_0_1
+ http://cookbooks.opscode.com/api/v1/cookbooks/haproxy/versions/1_0_0
+ http://cookbooks.opscode.com/api/v1/cookbooks/haproxy/versions/0_8_1
+ http://cookbooks.opscode.com/api/v1/cookbooks/haproxy/versions/0_8_0
+ http://cookbooks.opscode.com/api/v1/cookbooks/haproxy/versions/0_7_0
+.ft P
+.fi
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife role show devops \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.SH UNSHARE
+.sp
+The \fBunshare\fP argument is used to stop the sharing of a cookbook at \fI\%https://cookbooks.opscode.com\fP. Only the maintainer of a cookbook may perform this action.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook site unshare COOKBOOK_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To unshare a cookbook named "getting\-started", enter:
+.sp
+.nf
+.ft C
+$ knife cookbook site unshare getting\-started
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.IP "" 0
-.
-.SH "SEE ALSO"
-\fBknife\-cookbook(1)\fR \fIhttp://community\.opscode\.com/cookbooks\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-cookbook.1 b/distro/common/man/man1/knife-cookbook.1
index 60931f37c6..82e991687c 100644
--- a/distro/common/man/man1/knife-cookbook.1
+++ b/distro/common/man/man1/knife-cookbook.1
@@ -1,332 +1,644 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-COOKBOOK" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\-cookbook\fR \- upload and manage chef cookbooks
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBcookbook\fR \fIsub\-command\fR \fI(options)\fR
-.
-.SH "SUB\-COMMANDS"
-\fBknife cookbook\fR supports the following sub commands:
-.
-.SH "LIST"
-\fBknife cookbook list\fR \fI(options)\fR
-.
-.TP
-\fB\-a\fR, \fB\-\-all\fR
-show all versions of a cookbook instead of just the most recent
-.
-.TP
-\fB\-w\fR, \fB\-\-with\-uri\fR
-show corresponding uris
-.
-.P
-Lists the cookbooks available on the Chef server\.
-.
-.SH "SHOW"
-\fBknife cookbook show cookbook [version] [part] [filename]\fR \fI(options)\fR
-.
-.TP
-\fB\-f\fR, \fB\-\-fqdn fqdn\fR
-the fqdn of the host to see the file for
-.
-.TP
-\fB\-p\fR, \fB\-\-platform platform\fR
-the platform to see the file for
-.
-.TP
-\fB\-v\fR, \fB\-\-platform\-version version\fR
-the platform version to see the file for
-.
+.TH "KNIFE-COOKBOOK" "1" "Chef 11.8" "" "knife cookbook"
+.SH NAME
+knife-cookbook \- The man page for the knife cookbook subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+A cookbook is the fundamental unit of configuration and policy distribution. Each cookbook defines a scenario, such as everything needed to install and configure MySQL, and then it contains all of the components that are required to support that scenario, including:
+.INDENT 0.0
+.IP \(bu 2
+Attribute values that are set on nodes
+.IP \(bu 2
+Definitions that allow the creation of reusable collections of resources
+.IP \(bu 2
+File distributions
+.IP \(bu 2
+Libraries that extend the chef\-client and/or provide helpers to Ruby code
+.IP \(bu 2
+Recipes that specify which resources to manage and the order in which those resources will be applied
+.IP \(bu 2
+Custom resources and providers
+.IP \(bu 2
+Templates
+.IP \(bu 2
+Versions
+.IP \(bu 2
+Metadata about recipes (including dependencies), version constraints, supported platforms, and so on
+.UNINDENT
+.sp
+The \fBknife cookbook\fP subcommand is used to interact with cookbooks that are located on the server or the local chef\-repo.
+.sp
+This subcommand has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook [ARGUMENT] (options)
+.ft P
+.fi
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-w\fR, \fB\-\-with\-uri\fR
-Show corresponding URIs
-.
-.P
-show a particular part of a \fIcookbook\fR for the specified \fIversion\fR\. \fIpart\fR can be one of:
-.
-.IP "\(bu" 4
-\fIattributes\fR
-.
-.IP "\(bu" 4
-\fIdefinitions\fR
-.
-.IP "\(bu" 4
-\fIfiles\fR
-.
-.IP "\(bu" 4
-\fIlibraries\fR
-.
-.IP "\(bu" 4
-\fIproviders\fR
-.
-.IP "\(bu" 4
-\fIrecipes\fR
-.
-.IP "\(bu" 4
-\fIresources\fR
-.
-.IP "\(bu" 4
-\fItemplates\fR
-.
-.IP "" 0
-.
-.SH "UPLOAD"
-\fBknife cookbook upload [cookbooks\.\.\.]\fR \fI(options)\fR
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-a\fR, \fB\-\-all\fR
-upload all cookbooks, rather than just a single cookbook
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-o\fR, \fB\-\-cookbook\-path path:path\fR
-a colon\-separated path to look for cookbooks in
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-d\fR, \fB\-\-upload\-dependencies\fR
-Uploads additional cookbooks that this cookbook lists in as dependencies in its metadata\.
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-E\fR, \fB\-\-environment ENVIRONMENT\fR
-An \fIENVIRONMENT\fR to apply the uploaded cookbooks to\. Specifying this option will cause knife to edit the \fIENVIRONMENT\fR to place a strict version constraint on the cookbook version(s) uploaded\.
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB\-\-freeze\fR
-Sets the frozen flag on the uploaded cookbook(s) Any future attempt to modify the cookbook without changing the version number will return an error unless \-\-force is specified\.
-.
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
.TP
-\fB\-\-force\fR
-Overrides the frozen flag on a cookbook, allowing you to overwrite a cookbook version that has previously been uploaded with the \-\-freeze option\.
-.
-.P
-Uploads one or more cookbooks from your local cookbook repository(ies) to the Chef Server\. Only files that don\'t yet exist on the server will be uploaded\.
-.
-.P
-As the command parses the name args as 1\.\.n cookbook names: \fBknife cookbook upload COOKBOOK COOKBOOK \.\.\.\fR works for one to many cookbooks\.
-.
-.SH "DOWNLOAD"
-\fBknife cookbook download cookbook [version]\fR \fI(options)\fR
-.
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
.TP
-\fB\-d\fR, \fB\-\-dir download_directory\fR
-the directory to download the cookbook into
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-\fB\-f\fR, \fB\-\-force\fR
-overwrite an existing directory with the download
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.TP
-\fB\-n\fR, \fB\-\-latest\fR
-download the latest version of the cookbook
-.
-.P
-download a cookbook from the chef server\. if no version is specified and only one version exists on the server, that version will be downloaded\. if no version is specified and multiple versions are available on the server, you will be prompted for a version to download\.
-.
-.SH "DELETE"
-\fBknife cookbook delete cookbook [version]\fR \fI(options)\fR
-.
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
.TP
-\fB\-a\fR, \fB\-\-all\fR
-delete all versions
-.
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
.TP
-\fB\-p\fR, \fB\-\-purge\fR
-purge files from backing store\. this will disable any cookbook that contains any of the same files as the cookbook being purged\.
-.
-.P
-delete the specified \fIversion\fR of the named \fIcookbook\fR\. if no version is specified, and only one version exists on the server, that version will be deleted\. if multiple versions are available on the server, you will be prompted for a version to delete\.
-.
-.SH "BULK DELETE"
-\fBknife cookbook bulk delete regex\fR \fI(options)\fR
-.
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
.TP
-\fB\-p\fR, \fB\-\-purge\fR
-purge files from backing store\. this will disable any cookbook that contains any of the same files as the cookbook being purged\.
-.
-.P
-delete cookbooks on the chef server based on a regular expression\. the regular expression (\fIregex\fR) should be in quotes, not in //\'s\.
-.
-.SH "COOKBOOK CREATE"
-\fBknife cookbook create cookbook\fR \fI(options)\fR
-.
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
.TP
-\fB\-o\fR, \fB\-\-cookbook\-path path\fR
-the directory where the cookbook will be created
-.
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
.TP
-\fB\-r\fR, \fB\-\-readme\-format format\fR
-format of the readme file md, mkd, txt, rdoc
-.
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
.TP
-\fB\-c\fR, \fB\-\-copyright copyright\fR
-name of copyright holder
-.
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
.TP
-\fB\-i\fR, \fB\-\-license license\fR
-license for cookbook, apachev2 or none
-.
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
.TP
-\fB\-e\fR, \fB\-\-email email\fR
-email address of cookbook maintainer
-.
-.P
-this is a helper command that creates a new cookbook directory in the \fBcookbook_path\fR\. the following directories and files are created for the named cookbook\.
-.
-.IP "\(bu" 4
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH BULK DELETE
+.sp
+The \fBbulk delete\fP argument is used to delete cookbook files that match a pattern defined by a regular expression. The regular expression must be within quotes and not be surrounded by forward slashes (/).
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook bulk delete REGEX (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-p\fP, \fB\-\-purge\fP
+Indicates that a cookbook (or cookbook version) will be removed entirely from the server. This action should be used carefully because only one copy of any single file is stored on the server. Consequently, purging a cookbook will disable any other cookbook that references one or more files from a cookbook that has been purged.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To bulk delete many cookbooks, use a regular expression to define the pattern:
+.sp
+.nf
+.ft C
+$ knife cookbook bulk delete "^[0\-9]{3}$" \-p
+.ft P
+.fi
+.SH CREATE
+.sp
+The \fBcreate\fP argument is used to create a new cookbook directory on the local machine, including the following directories and files:
+.INDENT 0.0
+.INDENT 3.5
+.INDENT 0.0
+.IP \(bu 2
cookbook/attributes
-.
-.IP "\(bu" 4
+.IP \(bu 2
+cookbook/CHANGELOG.md
+.IP \(bu 2
cookbook/definitions
-.
-.IP "\(bu" 4
+.IP \(bu 2
cookbook/files/default
-.
-.IP "\(bu" 4
+.IP \(bu 2
cookbook/libraries
-.
-.IP "\(bu" 4
-cookbook/metadata\.rb
-.
-.IP "\(bu" 4
+.IP \(bu 2
+cookbook/metadata.rb
+.IP \(bu 2
cookbook/providers
-.
-.IP "\(bu" 4
-cookbook/readme\.md
-.
-.IP "\(bu" 4
-cookbook/recipes/default\.rb
-.
-.IP "\(bu" 4
+.IP \(bu 2
+cookbook/README.md (or .rdoc)
+.IP \(bu 2
+cookbook/recipes/default.rb
+.IP \(bu 2
cookbook/resources
-.
-.IP "\(bu" 4
+.IP \(bu 2
cookbook/templates/default
-.
-.IP "" 0
-.
-.P
-supported readme formats are \'md\' (default), \'mkd\', \'txt\', \'rdoc\'\. the readme file will be written with the specified extension and a set of helpful starting headers\.
-.
-.P
-specify \fB\-c\fR or \fB\-\-copyright\fR with the name of the copyright holder as your name or your company/organization name in a quoted string\. if this value is not specified an all\-caps string \fByour_company_name\fR is used which can be easily changed with find/replace\.
-.
-.P
-specify \fB\-i\fR or \fB\-\-license\fR with the license that the cookbook is distributed under for sharing with other people or posting to the opscode cookbooks site\. be aware of the licenses of files you put inside the cookbook and follow any restrictions they describe\. when using \fBnone\fR (default) or \fBapachev2\fR, comment header text and metadata file are pre\-filled\. the \fBnone\fR license will be treated as non\-redistributable\.
-.
-.P
-specify \fB\-e\fR or \fB\-\-email\fR with the email address of the cookbook\'s maintainer\. if this value is not specified, an all\-caps string \fByour_email\fR is used which can easily be changed with find/replace\.
-.
-.P
-the cookbook copyright, license, email and readme_format settings can be filled in the \fBknife\.rb\fR, for example with default values:
-.
-.IP "" 4
-.
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.sp
+After the cookbook is created, it can be uploaded to the server using the \fBknife upload\fP argument.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
.nf
-
-cookbook_copyright "your_company_name"
-cookbook_license "none"
-cookbook_email "your_email"
-readme_format "md"
-.
+.ft C
+$ knife cookbook create COOKBOOK_NAME (options)
+.ft P
.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-C COPYRIGHT_HOLDER\fP, \fB\-\-copyright COPYRIGHT_HOLDER\fP
+The name of the copyright holder. This option will place a copyright notice that contains the name of the copyright holder in each of the pre\-created files. If this option is not specified, a copyright name of "your_company_name" will be used instead; it can be easily modified later.
+.TP
+.B \fB\-I LICENSE\fP, \fB\-\-license LICENSE\fP
+The type of license under which a cookbook is distributed: \fBapachev2\fP, \fBgplv2\fP, \fBgplv3\fP, \fBmit\fP, or \fBnone\fP (default). This option will place the appropriate license notice in the pre\-created files. Be aware of the licenses for files inside of a cookbook and be sure to follow any restrictions they describe.
+.TP
+.B \fB\-m EMAIL\fP, \fB\-\-email EMAIL\fP
+The email address for the individual who maintains the cookbook. This option will place an email address in each of the pre\-created files. If this option is not specified, an email name of "your_email" will be used instead; it can be easily modified later.
+.TP
+.B \fB\-o PATH\fP, \fB\-\-cookbook\-path PATH\fP
+The directory in which cookbook are created. This can be a colon\-separated path.
+.TP
+.B \fB\-r FORMAT\fP, \fB\-\-readme\-format FORMAT\fP
+The document format of the readme file: \fBmd\fP (markdown) and \fBrdoc\fP (Ruby docs).
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To create a cookbook named "my_cookbook" with copyright, email, license, and readme format options specified, enter:
+.sp
+.nf
+.ft C
+$ knife cookbook create my_cookbook \-C "My Name" \-m "my@email.com" \-I apachev2 \-r md
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+** Creating cookbook my_cookbook
+** Creating README for cookbook: my_cookbook
+** Creating metadata for cookbook: my_cookbook
+.ft P
+.fi
+.SH DELETE
+.sp
+The \fBdelete\fP argument is used to delete a specified cookbook or cookbook version on the server (and not locally).
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook delete COOKBOOK_NAME [COOKBOOK_VERSION] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-all\fP
+Indicates that a cookbook and every version of that cookbook will be deleted.
+.TP
+.B \fBCOOKBOOK_VERSION\fP
+The version of a cookbook to be deleted. If a cookbook has only one version, this option does not need to be specified. If a cookbook has more than one version and this option is not specified, Knife will prompt for a version.
+.TP
+.B \fB\-p\fP, \fB\-\-purge\fP
+Indicates that a cookbook (or cookbook version) will be removed entirely from the server. This action should be used carefully because only one copy of any single file is stored on the server. Consequently, purging a cookbook will disable any other cookbook that references one or more files from a cookbook that has been purged.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To delete version "0.8" from a cookbook named "smartmon", enter:
+.sp
+.nf
+.ft C
+$ knife cookbook delete smartmon 0.8
+.ft P
+.fi
+.sp
+Type \fBY\fP to confirm a deletion.
+.SH DOWNLOAD
+.sp
+The \fBdownload\fP argument is used to download a cookbook from the server to the current working directory.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook download COOKBOOK_NAME [COOKBOOK_VERSION] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-d DOWNLOAD_DIRECTORY\fP, \fB\-\-dir DOWNLOAD_DIRECTORY\fP
+The directory into which a cookbook will be downloaded.
+.TP
+.B \fB\-f\fP, \fB\-\-force\fP
+Indicates that an existing directory will be overwritten.
+.TP
+.B \fB\-N\fP, \fB\-\-latest\fP
+Indicates that the most recent version of a cookbook will be downloaded.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To download a cookbook named "smartmon", enter:
+.sp
+.nf
+.ft C
+$ knife cookbook download smartmon
+.ft P
+.fi
+.SH LIST
+.sp
+The \fBlist\fP argument is used to view a list of cookbooks that are currently available on the server. The list will contain only the most recent version for each cookbook by default.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook list (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-all\fP
+Indicates that all available versions of each cookbook will be returned.
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view a list of cookbooks:
+.sp
+.nf
+.ft C
+$ knife cookbook list
+.ft P
+.fi
+.SH METADATA
+.sp
+The \fBmetadata\fP argument is used to generate the metadata for one or more cookbooks.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook metadata (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-all\fP
+Indicates that metadata should be generated for all cookbooks, and not just for a specified cookbook.
+.TP
+.B \fB\-o PATH:PATH\fP, \fB\-\-cookbook\-path PATH:PATH\fP
+The directory in which cookbook are created. This can be a colon\-separated path.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To generate metadata for all cookbooks:
+.sp
+.nf
+.ft C
+$ knife cookbook metadata \-a
+.ft P
+.fi
+.SH METADATA FROM FILE
+.sp
+The \fBmetadata from file\fP argument is used to load the metadata for a cookbook from a file.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook metadata from file FILE
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To view cookbook metadata from a JSON file:
+.sp
+.nf
+.ft C
+$ knife cookbook metadta from file /path/to/file
+.ft P
+.fi
+.SH SHOW
+.sp
+The \fBshow\fP argument is used to view information about a cookbook, parts of a cookbook (attributes, definitions, files, libraries, providers, recipes, resources, and templates), or a file that is associated with a cookbook (including attributes such as checksum or specificity).
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook show COOKBOOK_NAME [COOKBOOK_VERSION] [PART...] [FILE_NAME] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fBCOOKBOOK_VERSION\fP
+The version of a cookbook to be shown. If a cookbook has only one version, this option does not need to be specified. If a cookbook has more than one version and this option is not specified, a list of cookbook versions will be returned.
+.TP
+.B \fB\-f FQDN\fP, \fB\-\-fqdn FQDN\fP
+The FQDN of the host.
+.TP
+.B \fBFILE_NAME\fP
+The name of a file that is associated with a cookbook.
+.TP
+.B \fB\-p PLATFORM\fP, \fB\-\-platform PLATFORM\fP
+The platform for which a cookbook is designed.
+.TP
+.B \fBPART\fP
+The part of the cookbook to show: \fBattributes\fP, \fBdefinitions\fP, \fBfiles\fP, \fBlibraries\fP, \fBproviders\fP, \fBrecipes\fP, \fBresources\fP, or \fBtemplates\fP. More than one part can be specified.
+.TP
+.B \fB\-V PLATFORM_VERSION\fP, \fB\-\-platform\-version PLATFORM_VERSION\fP
+The version of the platform.
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To get the list of available versions of a cookbook named "getting\-started", enter:
+.sp
+.nf
+.ft C
+$ knife cookbook show getting\-started
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+getting\-started 0.3.0 0.2.0
+.ft P
+.fi
+.sp
+To show a list of data about a cookbook using the name of the cookbook and the version, enter:
+.sp
+.nf
+.ft C
+$ knife cookbook show getting\-started 0.3.0
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+attributes:
+ checksum: fa0fc4abf3f6787aeb5c3c5c35de667c
+ name: default.rb
+ path: attributes/default.rb
+ specificity: default
+ url: https://somelongurlhere.com
+chef_type: cookbook_version
+cookbook_name: getting\-started
+definitions: []
+files: []
+frozen?: false
+json_class: Chef::CookbookVersion
+libraries: []
+.ft P
+.fi
+.sp
+To only view data about "templates", enter:
+.sp
+.nf
+.ft C
+$ knife cookbook show getting\-started 0.3.0 templates
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+checksum: a29d6f254577b830091f140c3a78b1fe
+name: chef\-getting\-started.txt.erb
+path: templates/default/chef\-getting\-started.txt.erb
+specificity: default
+url: https://someurlhere.com
+.ft P
+.fi
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife role show devops \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.SH TEST
+.sp
+The \fBtest\fP argument is used to test a cookbook for syntax errors. This argument uses Ruby syntax checking to verify every file in a cookbook that ends in .rb and erb.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook test COOKBOOK_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-all\fP
+Indicates that all cookbooks will be tested.
+.TP
+.B \fB\-o PATH:PATH\fP, \fB\-\-cookbook\-path PATH:PATH\fP
+The directory in which cookbook are created. This can be a colon\-separated path.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To test a cookbook named "getting\-started", enter:
+.sp
+.nf
+.ft C
+$ knife cookbook test getting\-started
+.ft P
+.fi
+.SH UPLOAD
+.sp
+The \fBupload\fP argument is used to upload one or more cookbooks (and any files that are associated with those cookbooks) from a local repository to the server. Only files that do not already exist on the server will be uploaded.
+.IP Note
+Use a chefignore file to prevent the upload of specific files and file types, such as temporary files or files placed in folders by version control systems. The chefignore file must be located in the root of the cookbook repository and must use rules similar to filename globbing (as defined by the Ruby \fBFile.fnmatch\fP syntax).
+.RE
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife cookbook upload [COOKBOOK_NAME...] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-all\fP
+Indicates that all cookbooks will be uploaded.
+.TP
+.B \fB\-d\fP, \fB\-\-include\-dependencies\fP
+Indicates that when a cookbook has a dependency on one (or more) cookbooks, those cookbooks will also be uploaded.
+.TP
+.B \fB\-\-force\fP
+Indicates that a cookbook should be updated even if the \fB\-\-freeze\fP flag has been set.
+.TP
+.B \fB\-\-freeze\fP
+Indicates that a cookbook cannot be modified; any changes to this cookbook must be included as a new version. Only the \fB\-\-force\fP option can override this setting.
+.TP
+.B \fB\-o PATH:PATH\fP, \fB\-\-cookbook\-path PATH:PATH\fP
+The directory in which cookbook are created. This can be a colon\-separated path.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To upload a cookbook named "getting\-started":
+.sp
+.nf
+.ft C
+$ knife cookbook upload getting\-started
+.ft P
+.fi
+.sp
+To upload a cookbook, and then prevent other users from being able to make changes to it, enter:
+.sp
+.nf
+.ft C
+$ knife cookbook upload redis \-\-freeze
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+Uploading redis...
+Upload completed
+.ft P
+.fi
+.sp
+If a cookbook is frozen and the \fB\-\-force\fP option is not specified, Knife will return an error message similar to the following:
+.sp
+.nf
+.ft C
+Uploading redis...
+ERROR: Version 0.1.6 of cookbook redis is frozen. Use \-\-force to override.
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.IP "" 0
-.
-.SH "METADATA"
-\fBknife cookbook metadata cookbook\fR \fI(options)\fR
-.
-.TP
-\fB\-a\fR, \fB\-\-all\fR
-generate metadata for all cookbooks, rather than just a single cookbook
-.
-.TP
-\fB\-o\fR, \fB\-\-cookbook\-path path:path\fR
-a colon\-separated path to look for cookbooks in
-.
-.P
-generate cookbook metadata for the named \fIcookbook\fR\. the \fIpath\fR used here specifies where the cookbooks directory is located and corresponds to the \fBcookbook_path\fR configuration option\.
-.
-.SH "METADATA FROM FILE"
-\fBknife cookbook metadata from file\fR \fI(options)\fR
-.
-.P
-load the cookbook metadata from a specified file\.
-.
-.SH "TEST"
-\fBknife cookbook test [cookbooks\.\.\.]\fR \fI(options)\fR
-.
-.TP
-\fB\-a\fR, \fB\-\-all\fR
-test all cookbooks, rather than just a single cookbook
-.
-.TP
-\fB\-o\fR, \fB\-\-cookbook\-path path:path\fR
-a colon\-separated path to look for cookbooks in
-.
-.P
-test the specified cookbooks for syntax errors\. this uses the built\-in ruby syntax checking option for files in the cookbook ending in \fB\.rb\fR, and the erb syntax check for files ending in \fB\.erb\fR (templates)\.
-.
-.SH "RECIPE LIST"
-\fBknife recipe list [PATTERN]\fR
-.
-.P
-List available recipes from the server\. Specify \fIPATTERN\fR as a regular expression to limit the results\.
-.
-.SH "DESCRIPTION"
-Cookbooks are the fundamental unit of distribution in Chef\. They encapsulate all recipes of resources and assets used to configure a particular aspect of the infrastructure\. The following sub\-commands can be used to manipulate the cookbooks stored on the Chef Server\.
-.
-.P
-On disk, cookbooks are directories with a defined structure\. The following directories may appear within a cookbook:
-.
-.TP
-COOKBOOK/attributes/
-Ruby files that define default parameters to be used in recipes
-.
-.TP
-COOKBOOK/definitions/
-Ruby files that contain \fIresource definitions\fR
-.
-.TP
-COOKBOOK/files/SPECIFICITY
-Files of arbitrary type\. These files may be downloaded by chef\-client(8) when configuring a host\.
-.
-.TP
-COOKBOOK/libraries/
-Ruby files that contain library code needed for recipes
-.
-.TP
-COOKBOOK/providers/
-Ruby files that contain Lightweight Provider definitions
-.
-.TP
-COOKBOOK/recipes/
-Ruby files that use Chef\'s recipe DSL to describe the desired configuration of a system
-.
-.TP
-COOKBOOK/resources/
-Ruby files that contain Lightweight Resource definitions
-.
-.TP
-COOKBOOK/templates/SPECIFICITY
-ERuby (ERb) template files\. These are referenced by \fIrecipes\fR and evaluated to dynamically generate configuration files\.
-.
-.P
-\fBSPECIFICITY\fR is a feature of \fIfiles\fR and \fItemplates\fR that allow you to specify alternate files to be used on a specific OS platform or host\. The default specificity setting is \fIdefault\fR, that is files in \fBCOOKBOOK/files/default\fR will be used when a more specific copy is not available\. Further documentation for this feature is available on the Chef wiki: \fIhttp://wiki\.opscode\.com/display/chef/File+Distribution#FileDistribution\-FileSpecificity\fR
-.
-.P
-Cookbooks also contain a metadata file that defines various properties of the cookbook\. The most important of these are the \fIversion\fR and the \fIdependencies\fR\. The \fIversion\fR is used in combination with environments to select which copy of a given cookbook is distributed to a node\. The \fIdependencies\fR are used by the server to determine which additional cookbooks must be distributed to a given host when it requires a cookbook\.
-.
-.SH "SEE ALSO"
-\fBknife\-environment(1)\fR \fBknife\-cookbook\-site(1)\fR \fIhttp://wiki\.opscode\.com/display/chef/Cookbooks\fR \fIhttp://wiki\.opscode\.com/display/chef/Metadata\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-data-bag.1 b/distro/common/man/man1/knife-data-bag.1
index 0f1c0cc0fd..df44979710 100644
--- a/distro/common/man/man1/knife-data-bag.1
+++ b/distro/common/man/man1/knife-data-bag.1
@@ -1,123 +1,488 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-DATA\-BAG" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\-data\-bag\fR \- Store arbitrary data on a Chef Server
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBdata bag\fR \fIsub\-command\fR \fI(options)\fR
-.
-.SH "DESCRIPTION"
-Data bags are stores of arbitrary JSON data\. Each data bag is a collection that may contain many items\. Data Bag Items are indexed by the Chef Server and can be searched via \fBknife\-search\fR(1)\.
-.
-.P
-Data bags are available to all nodes configured by \fBchef\-client\fR(8), and are therefore a convenient mechanism to store global information, such as lists of administrative accounts that should be configured on all hosts\.
-.
-.SH "DATA BAG SUB\-COMMANDS"
-.
-.SH "CREATE"
-\fBknife data bag create\fR \fIbag name\fR [item id] \fI(options)\fR
-.
+.TH "KNIFE-DATA-BAG" "1" "Chef 11.8" "" "knife data bag"
+.SH NAME
+knife-data-bag \- The man page for the knife data bag subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+A data bag is a global variable that is stored as JSON data and is accessible from a server. A data bag is indexed for searching and can be loaded by a recipe or accessed during a search. The contents of a data bag can vary, but they often include sensitive information (such as database passwords).
+.sp
+The contents of a data bag can be encrypted using \fI\%shared secret encryption\fP. This allows a data bag to store confidential information (such as a database password) or to be managed in a source control system (without plain\-text data appearing in revision history).
+.sp
+The \fBknife data bag\fP subcommand is used to manage arbitrary stores of globally available JSON data.
+.sp
+This subcommand has the following syntax:
+.sp
+.nf
+.ft C
+$ knife data bag [ARGUMENT] (options)
+.ft P
+.fi
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-s\fR, \fB\-\-secret SECRET\fR
-A secret key used to encrypt the data bag item\. See \fBencryption support\fR below\.
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-\-secret\-file SECRET_FILE\fR
-The path to a file containing the secret key to be used to encrypt the data bag item\.
-.
-.P
-If \fIitem id\fR is given, creates a new, empty data bag item and opens it for editing in your editor\. The data bag will be created if it does not exist\.
-.
-.P
-If \fIitem id\fR is not given, the data bag will be created\.
-.
-.SH "DELETE"
-\fBknife data bag delete\fR \fIbag name\fR [item id] \fI(options)\fR
-.
-.P
-Delete a data bag, or an item from a data bag\.
-.
-.SH "EDIT"
-\fBknife data bag edit\fR \fIbag name\fR \fIitem id\fR \fI(options)\fR
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-s\fR, \fB\-\-secret SECRET\fR
-A secret key used to encrypt the data bag item\. See \fBencryption support\fR below\.
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-\-secret\-file SECRET_FILE\fR
-The path to a file containing the secret key to be used to encrypt the data bag item\.
-.
-.P
-Edit an item in a data bag\.
-.
-.SH "FROM FILE"
-\fBknife data bag from file\fR \fIbag name\fR \fIfile\fR \fI(options)\fR
-.
-.P
-\fBknife data bag from file\fR \fIbag name\fR \fIfile1\fR \fIfile2\fR \fIfile3\fR \fI(options)\fR
-.
-.P
-\fBknife data bag from file\fR \fIbag name\fR \fIfolder\fR \fI(options)\fR
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-s\fR, \fB\-\-secret SECRET\fR
-A secret key used to encrypt the data bag item\. See \fBencryption support\fR below\.
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB\-\-secret\-file SECRET_FILE\fR
-The path to a file containing the secret key to be used to encrypt the data bag item\.
-.
-.P
-Load a data bag item from a JSON file\. If \fIfile\fR is a relative or absolute path to the file, that file will be used\. Otherwise, the \fIfile\fR parameter is treated as the base name of a data bag file in a Chef repository, and \fBknife\fR will search for the file in \fB\./data_bags/bag_name/file\fR\. For example \fBknife data bag from file users dan\.json\fR would attempt to load the file \fB\./data_bags/users/dan\.json\fR\.
-.
-.SH "LIST"
-\fBknife data bag list\fR \fI(options)\fR
-.
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
.TP
-\fB\-w\fR, \fB\-\-with\-uri\fR
-Show corresponding URIs
-.
-.P
-Lists the data bags that exist on the Chef Server\.
-.
-.SH "SHOW"
-\fBknife data bag show BAG [ITEM]\fR \fI(options)\fR
-.
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
.TP
-\fB\-s\fR, \fB\-\-secret SECRET\fR
-A secret key used to encrypt the data bag item\. See \fBencryption support\fR below\.
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-\fB\-\-secret\-file SECRET_FILE\fR
-The path to a file containing the secret key to be used to encrypt the data bag item\.
-.
-.P
-Show a specific data bag or an item in a data bag\. The output will be formatted according to the \-\-format option\.
-.
-.SH "ENCRYPTION SUPPORT"
-Data Bag Items may be encrypted to keep their contents secret\. This may be desireable when storing sensitive information such as database passwords, API keys, etc\.
-.
-.P
-Data Bag Item encryption uses the AES\-256 CBC symmetric key algorithm\.
-.
-.P
-\fBCAVEATS:\fR Keys are not encrypted; only values are encrypted\. The "id" of a Data Bag Item is not encrypted, since it is used by Chef Server to store the item in its database\. For example, given the following data bag item: {"id": "important_passwords", "secret_password": "opensesame"} The key "secret_password" will be visible to an evesdropper, but the value "opensesame" will be protected\. Both the key "id" and its value "important_passwords" will be visible to an evesdropper\.
-.
-.P
-Chef Server does not provide a secure mechanism for distributing encryption keys\.
-.
-.SH "SEE ALSO"
-\fBknife\-search\fR(1)
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH CREATE
+.sp
+The \fBcreate\fP argument is used to add a data bag to the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife data bag create DATA_BAG_NAME [DATA_BAG_ITEM] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fBDATA_BAG_ITEM\fP
+The name of a specific item within a data bag.
+.TP
+.B \fB\-\-secret SECRET\fP
+The encryption key that is used for values contained within a data bag.
+.TP
+.B \fB\-\-secret\-file FILE\fP
+The path to the file that contains the encryption key.
+.UNINDENT
+.IP Note
+For encrypted data bag items, use \fIeither\fP \fB\-\-secret\fP or \fB\-\-secret\-file\fP, not both.
+.RE
+.sp
+\fBExamples\fP
+.sp
+To create a data bag named "admins", enter:
+.sp
+.nf
+.ft C
+$ knife data bag create admins
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+Created data_bag[admins]
+.ft P
+.fi
+.SH DELETE
+.sp
+The \fBdelete\fP argument is used to delete a data bag or a data bag item from a server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife data bag delete DATA_BAG_NAME [DATA_BAG_ITEM] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fBDATA_BAG_ITEM\fP
+The name of a specific item within a data bag.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To a data bag named "admins", enter:
+.sp
+.nf
+.ft C
+$ knife data bag delete admins
+.ft P
+.fi
+.sp
+To delete an item named "charlie", enter:
+.sp
+.nf
+.ft C
+$ knife data bag delete admins charlie
+.ft P
+.fi
+.sp
+Type \fBY\fP to confirm a deletion.
+.SH EDIT
+.sp
+The \fBedit\fP argument is used to edit the data contained in a data bag. If encryption is being used, the data bag will be decrypted, the data will be made available in the $EDITOR, and then encrypted again before saving it to the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife data bag edit DATA_BAG_NAME [DATA_BAG_ITEM] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fBDATA_BAG_ITEM\fP
+The name of a specific item within a data bag.
+.TP
+.B \fB\-\-secret SECRET\fP
+The encryption key that is used for values contained within a data bag.
+.TP
+.B \fB\-\-secret\-file FILE\fP
+The path to the file that contains the encryption key.
+.UNINDENT
+.IP Note
+For encrypted data bag items, use \fIeither\fP \fB\-\-secret\fP or \fB\-\-secret\-file\fP, not both.
+.RE
+.sp
+\fBExamples\fP
+.sp
+To edit the contents of a data bag, enter:
+.sp
+.nf
+.ft C
+$ knife data bag edit admins
+.ft P
+.fi
+.sp
+To edit an item named "charlie" that is contained in a data bag named "admins", enter:
+.sp
+.nf
+.ft C
+$ knife data bag edit admins charlie
+.ft P
+.fi
+.sp
+to open the $EDITOR. Once opened, you can update the data before saving it to the server. For example, by changing:
+.sp
+.nf
+.ft C
+{
+ "id": "charlie"
+}
+.ft P
+.fi
+.sp
+to:
+.sp
+.nf
+.ft C
+{
+ "id": "charlie",
+ "uid": 1005,
+ "gid":"ops",
+ "shell":"/bin/zsh",
+ "comment":"Crazy Charlie"
+}
+.ft P
+.fi
+.SH FROM FILE
+.sp
+The \fBfrom file\fP argument is used to create a data bag on the server from a file. The path to the data bag file must specify one of the following:
+.INDENT 0.0
+.IP \(bu 2
+the name of a data bag
+.IP \(bu 2
+a relative or absolute path to a file
+.UNINDENT
+.sp
+If the name of a data bag is specified, Knife will search for the data bag in \fB./data_bags/bag_name/file\fP. Once opened, the JSON file should be a hash that contains at least an ID key which represents the name of the data bag item.
+.IP Warning
+A chef\-client must be version 11.6 (or higher) when using the \fBknife data bag from file\fP argument with the Enterprise Chef or Open Source Chef version 11 servers.
+.RE
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife data bag from file DATA_BAG_NAME_or_PATH
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-all\fP
+Indicates that all data bags found at the specified path will be uploaded.
+.TP
+.B \fB\-\-secret SECRET\fP
+The encryption key that is used for values contained within a data bag.
+.TP
+.B \fB\-\-secret\-file FILE\fP
+The path to the file that contains the encryption key.
+.UNINDENT
+.IP Note
+For encrypted data bag items, use \fIeither\fP \fB\-\-secret\fP or \fB\-\-secret\-file\fP, not both.
+.RE
+.sp
+\fBExamples\fP
+.sp
+To create a data bag on the server from a file:
+.sp
+.nf
+.ft C
+$ knife data bag from file "path to JSON file"
+.ft P
+.fi
+.sp
+To create a data bag named "devops_data" that contains encrypted data, enter:
+.sp
+.nf
+.ft C
+$ knife data bag from file devops_data \-\-secret\-file "path to decryption file"
+.ft P
+.fi
+.SH LIST
+.sp
+The \fBlist\fP argument is used to view a list of data bags that are currently available on the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife data bag list
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+For example, to view a list of data bags on the server, enter:
+.sp
+.nf
+.ft C
+$ knife data bag list
+.ft P
+.fi
+.SH SHOW
+.sp
+The \fBshow\fP argument is used to view the contents of a data bag.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife data bag show DATA_BAG_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fBDATA_BAG_ITEM\fP
+The name of a specific item within a data bag.
+.TP
+.B \fB\-\-secret SECRET\fP
+The encryption key that is used for values contained within a data bag.
+.TP
+.B \fB\-\-secret\-file FILE\fP
+The path to the file that contains the encryption key.
+.UNINDENT
+.IP Note
+For encrypted data bag items, use \fIeither\fP \fB\-\-secret\fP or \fB\-\-secret\-file\fP, not both.
+.RE
+.sp
+\fBExamples\fP
+.sp
+To show the contents of a data bag, enter:
+.sp
+.nf
+.ft C
+$ knife data bag show admins
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+charlie
+.ft P
+.fi
+.sp
+To show the contents of a specific item within data bag, enter:
+.sp
+.nf
+.ft C
+$ knife data bag show admins charlie
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+comment: Crazy Charlie
+gid: ops
+id: charlie
+shell: /bin/zsh
+uid: 1005
+.ft P
+.fi
+.sp
+To show the contents of a data bag named "passwords" with an item that contains encrypted data named "mysql", enter:
+.sp
+.nf
+.ft C
+$ knife data bag show passwords mysql
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+## sample:
+{
+ "id": "mysql",
+ "pass": "trywgFA6R70NO28PNhMpGhEvKBZuxouemnbnAUQsUyo=\en",
+ "user": "e/p+8WJYVHY9fHcEgAAReg==\en"
+}
+.ft P
+.fi
+.sp
+To show the decrypted contents of the same data bag, enter:
+.sp
+.nf
+.ft C
+$ knife data bag show \-\-secret\-file /path/to/decryption/file passwords mysql
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+## sample:
+{
+ "id": "mysql",
+ "pass": "thesecret123",
+ "user": "fred"
+}
+.ft P
+.fi
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife data bag show admins \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "CHEF"
-Knife is distributed with Chef\. http://wiki\.opscode\.com/display/chef/Home
diff --git a/distro/common/man/man1/knife-delete.1 b/distro/common/man/man1/knife-delete.1
new file mode 100644
index 0000000000..9b9bb51dce
--- /dev/null
+++ b/distro/common/man/man1/knife-delete.1
@@ -0,0 +1,134 @@
+.TH "KNIFE-DELETE" "1" "Chef 11.8" "" "knife delete"
+.SH NAME
+knife-delete \- The man page for the knife delete subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife delete\fP subcommand is used to delete an object from a server. This subcommand works similar to \fBknife cookbook delete\fP, \fBknife data bag delete\fP, \fBknife environment delete\fP, \fBknife node delete\fP, and \fBknife role delete\fP, but with a single verb (and a single action).
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife delete [PATTERN...] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-both\fP
+Indicates that both local and remote copies of an object should be deleted. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-\-local\fP
+Indicates that only the local copy of an object should be deleted. (The remote copy will not be deleted.) Default: \fBfalse\fP.
+.TP
+.B \fB\-r\fP, \fB\-\-[no\-]recurse\fP
+Use \fB\-\-recurse\fP to delete directories recursively. Default: \fB\-\-no\-recurse\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default: \fBeverything\fP / \fBhosted_everything\fP.
+.UNINDENT
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-deps.1 b/distro/common/man/man1/knife-deps.1
new file mode 100644
index 0000000000..8879ed536c
--- /dev/null
+++ b/distro/common/man/man1/knife-deps.1
@@ -0,0 +1,221 @@
+.TH "KNIFE-DEPS" "1" "Chef 11.8" "" "knife deps"
+.SH NAME
+knife-deps \- The man page for the knife deps subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife deps\fP subcommand is used to identify dependencies for a node, role, or cookbook.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife deps (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-\-[no\-]recurse\fP
+Use \fB\-\-recurse\fP to list dependencies recursively. This option can only be used when \fB\-\-tree\fP is set to \fBtrue\fP. Default: \fB\-\-no\-recurse\fP.
+.TP
+.B \fB\-\-remote\fP
+Indicates that dependencies will be determined from objects located on the server instead of the local chef\-repo. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default: \fBeverything\fP / \fBhosted_everything\fP.
+.TP
+.B \fB\-\-tree\fP
+Indicates that dependencies are shown in a visual tree structure (including duplicates, if they exist). Default: \fBfalse\fP.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To find the dependencies for a node:
+.sp
+.nf
+.ft C
+$ knife deps nodes/node_name.json
+.ft P
+.fi
+.sp
+To find the dependencies for a role:
+.sp
+.nf
+.ft C
+$ knife deps roles/role_name.json
+.ft P
+.fi
+.sp
+To find the dependencies for a cookbook:
+.sp
+.nf
+.ft C
+$ knife deps cookbooks/cookbook_name.json
+.ft P
+.fi
+.sp
+To find the dependencies for an environment:
+.sp
+.nf
+.ft C
+$ knife deps environments/environment_name.json
+.ft P
+.fi
+.sp
+To find the dependencies for a combination of nodes, cookbooks, roles, and/or environments:
+.sp
+.nf
+.ft C
+$ knife deps cookbooks/git.json cookbooks/github.json roles/base.json environments/desert.json nodes/mynode.json
+.ft P
+.fi
+.sp
+To use a wildcard to return all the child nodes:
+.sp
+.nf
+.ft C
+$ knife deps environments/*.json
+.ft P
+.fi
+.sp
+Use the \fB\-\-tree\fP option to view the results with structure:
+.sp
+.nf
+.ft C
+$ knife deps roles/webserver.json
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+roles/webserver.json
+ roles/base.json
+ cookbooks/github
+ cookbooks/git
+ cookbooks/users
+ cookbooks/apache2
+.ft P
+.fi
+.sp
+To pass the output of \fBknife deps\fP to \fBknife upload\fP, do something like the following:
+.sp
+.nf
+.ft C
+$ knife upload \(gaknife deps nodes/*.json
+.ft P
+.fi
+.sp
+To pass the output of \fBknife deps\fP to \fBknife xargs\fP:
+.sp
+.nf
+.ft C
+$ knife deps nodes/*.json | xargs knife upload
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-diff.1 b/distro/common/man/man1/knife-diff.1
new file mode 100644
index 0000000000..cc83401863
--- /dev/null
+++ b/distro/common/man/man1/knife-diff.1
@@ -0,0 +1,214 @@
+.TH "KNIFE-DIFF" "1" "Chef 11.8" "" "knife diff"
+.SH NAME
+knife-diff \- The man page for the knife diff subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife diff\fP subcommand is used to compare the differences between files and directories on the server and in the chef\-repo. For example, to compare files on the server prior to an uploading or downloading files using the \fBknife download\fP and \fBknife upload\fP subcommands, or to ensure that certain files in multiple production environments are the same. This subcommand is similar to the \fBgit diff\fP command that can be used to diff what is in the chef\-repo with what is synced to a git repository.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife diff [PATTERN...] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-\-diff\-filter=[(A|D|M|T)...[*]]\fP
+Indicates that files will be selected that have been added (\fBA\fP), deleted (\fBD\fP), modified (\fBM\fP), and/or have had their type changed (\fBT\fP). Any combination of filter characters may be used, including no filter characters. Use \fB*\fP to select all paths if a file matches other criteria in the comparison. Default value: \fBnil\fP.
+.TP
+.B \fB\-\-name\-only\fP
+Indicates that only the names of modified files will be shown.
+.TP
+.B \fB\-\-name\-status\fP
+Indicates that only the names of files with a status of \fBAdded\fP, \fBDeleted\fP, \fBModified\fP, or \fBType Changed\fP will be shown.
+.TP
+.B \fB\-\-no\-recurse\fP
+Use \fB\-\-no\-recurse\fP to disable listing a directory recursively. Default: \fB\-\-recurse\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default: \fBeverything\fP / \fBhosted_everything\fP.
+.UNINDENT
+.sp
+\fBknife.rb File Settings\fP
+.sp
+In addition to the default settings in a knife.rb file, there are other subcommand\-specific settings that can be added. When a subcommand is run, Knife will use:
+.INDENT 0.0
+.IP 1. 3
+A value passed via the command\-line
+.IP 2. 3
+A value contained in the knife.rb file
+.IP 3. 3
+The default value
+.UNINDENT
+.sp
+A value passed via the command line will override a value in the knife.rb file; a value in a knife.rb file will override a default value.
+.sp
+The following \fBknife diff\fP settings can be added to the knife.rb file:
+.INDENT 0.0
+.TP
+.B \fBknife[:chef_repo_path]\fP
+Use to add the \fB\-\-chef\-repo\-path\fP option.
+.TP
+.B \fBknife[:concurrency]\fP
+Use to add the \fB\-\-concurrency\fP option.
+.TP
+.B \fBknife[:name_only]\fP
+Use to add the \fB\-\-name\-only\fP option.
+.TP
+.B \fBknife[:name_status]\fP
+Use to add the \fB\-\-name\-status\fP option.
+.TP
+.B \fBknife[:recurse]\fP
+Use to add the \fB\-\-recurse\fP option.
+.TP
+.B \fBknife[:repo_mode]\fP
+Use to add the \fB\-\-repo\-mode\fP option.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To compare the "base.json" role to a "webserver.json" role, enter:
+.sp
+.nf
+.ft C
+$ knife diff roles/base.json roles/webserver.json
+.ft P
+.fi
+.sp
+To compare the differences between the local chef\-repo and the files that are on the server, enter:
+.sp
+.nf
+.ft C
+$ knife diff
+.ft P
+.fi
+.sp
+To diff a node named \fBnode\-lb\fP and then only return files that have been added, deleted, modified, or changed, enter:
+.sp
+.nf
+.ft C
+$ knife diff \-\-name\-status node\-lb
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+node\-lb/recipes/eip.rb
+node\-lb/recipes/heartbeat\-int.rb
+node\-lb/templates/default/corpsite.conf.erb
+node\-lb/files/default/wildcard.node.com.crt
+node\-lb/files/default/wildcard.node.com.crt\-2009
+node\-lb/files/default/wildcard.node.com.key
+node\-lb/.gitignore
+node\-lb/Rakefile
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-download.1 b/distro/common/man/man1/knife-download.1
new file mode 100644
index 0000000000..71eafe15a0
--- /dev/null
+++ b/distro/common/man/man1/knife-download.1
@@ -0,0 +1,222 @@
+.TH "KNIFE-DOWNLOAD" "1" "Chef 11.8" "" "knife download"
+.SH NAME
+knife-download \- The man page for the knife download subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife download\fP subcommand is used to download roles, cookbooks, environments, nodes, and data bags from the server to the current working directory.. It can be used to back up data on the server, inspect the state of one or more files, or to extract out\-of\-process changes users may have made to files on the server, such as if a user made a change that bypassed version source control. This subcommand is often used in conjunction with \fBknife diff\fP, which can be used to see exactly what changes will be downloaded, and then \fBknife upload\fP, which does the opposite of \fBknife download\fP.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife download [PATTERN...] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-\-force\fP
+Use \fB\-\-force\fP to download files even when the file on the hard drive is identical to the object on the server (role, cookbook, etc.). By default, files are compared to see if they have equivalent content, and local files are only overwritten if they are different. Default: \fB\-\-no\-force\fP.
+.TP
+.B \fB\-n\fP, \fB\-\-dry\-run\fP
+Indicates that no action is taken and that results are only printed out. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-[no\-]diff\fP
+Indicates that only new and modified files will be downloaded. Set to \fBfalse\fP to download all files. Default: \fB\-\-diff\fP.
+.TP
+.B \fB\-\-[no\-]recurse\fP
+Use \fB\-\-no\-recurse\fP to disable downloading a directory recursively. Default: \fB\-\-recurse\fP.
+.TP
+.B \fB\-\-purge\fP
+Use \fB\-\-purge\fP to delete local files and directories that do not exist on the server. By default, if a role, cookbook, etc. does not exist on the server, the local file for said role will be left alone and NOT deleted. Default: \fB\-\-no\-purge\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default: \fBeverything\fP / \fBhosted_everything\fP.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To download the entire chef\-repo from the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife download /
+.ft P
+.fi
+.sp
+To download the \fBcookbooks/\fP directory from the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife download cookbooks
+.ft P
+.fi
+.sp
+or from anywhere in the chef\-repo, enter:
+.sp
+.nf
+.ft C
+$ knife download /cookbooks
+.ft P
+.fi
+.sp
+To download the \fBenvironments/\fP directory from the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife download environments
+.ft P
+.fi
+.sp
+or from anywhere in the chef\-repo, enter:
+.sp
+.nf
+.ft C
+$ knife download /environments
+.ft P
+.fi
+.sp
+To download an environment named "production" from the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife download environments/production.json
+.ft P
+.fi
+.sp
+or from the \fBenvironments/\fP directory, enter:
+.sp
+.nf
+.ft C
+$ knife download production.json
+.ft P
+.fi
+.sp
+To download the \fBroles/\fP directory from the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife download roles
+.ft P
+.fi
+.sp
+or from anywhere in the chef\-repo, enter:
+.sp
+.nf
+.ft C
+$ knife download /roles
+.ft P
+.fi
+.sp
+To download all cookbooks that start with "apache" and belong to the "webserver" role, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife download cookbooks/apache\e* roles/webserver.json
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-edit.1 b/distro/common/man/man1/knife-edit.1
new file mode 100644
index 0000000000..e1a0a45424
--- /dev/null
+++ b/distro/common/man/man1/knife-edit.1
@@ -0,0 +1,128 @@
+.TH "KNIFE-EDIT" "1" "Chef 11.8" "" "knife edit"
+.SH NAME
+knife-edit \- The man page for the knife edit subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife edit\fP subcommand is used to edit objects on the server. This subcommand works similar to \fBknife cookbook edit\fP, \fBknife data bag edit\fP, \fBknife environment edit\fP, \fBknife node edit\fP, and \fBknife role edit\fP, but with a single verb (and a single action).
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife edit (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-\-local\fP
+Use to show files in the local chef\-repo instead of a remote location. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default: \fBeverything\fP / \fBhosted_everything\fP.
+.UNINDENT
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-environment.1 b/distro/common/man/man1/knife-environment.1
index dbb42a9c9e..ed272e3892 100644
--- a/distro/common/man/man1/knife-environment.1
+++ b/distro/common/man/man1/knife-environment.1
@@ -1,168 +1,326 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-ENVIRONMENT" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\-environment\fR \- Define cookbook policies for the environments in your infrastructure
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBenvironment\fR \fIsub\-command\fR \fI(options)\fR
-.
-.SH "SUBCOMMANDS"
-Environment subcommands follow a basic create, read, update, delete (CRUD) pattern\. The following subcommands are available:
-.
-.SH "CREATE"
-\fBknife environment create\fR \fIenvironment\fR \fI(options)\fR
-.
-.TP
-\fB\-d\fR, \fB\-\-description DESCRIPTION\fR
-The value of the description field\.
-.
-.P
-Create a new environment object on the Chef Server\. The envrionment will be opened in the text editor for editing prior to creation if the \-n option is not present\.
-.
-.SH "DELETE"
-\fBknife environment delete\fR \fIenvironment\fR \fI(options)\fR
-.
-.P
-Destroy an environment on the Chef Server\. A prompt for confirmation will be displayed if the \-y options is not given\.
-.
-.SH "EDIT"
-\fBknife environment edit\fR \fIenvironment\fR \fI(options)\fR
-.
-.P
-Fetch \fIenvironment\fR and display it in the text editor for editing\. The environment will be saved to the Chef Server when the editing session exits\.
-.
-.SH "FROM FILE"
-\fBknife environment from file\fR \fIfile\fR \fI(options)\fR
-.
-.P
-Create or update an environment from the JSON or Ruby format \fIfile\fR\. See \fBformat\fR for the proper format of this file\.
-.
-.SH "LIST"
-\fBknife environment list\fR \fI(options)\fR * \fB\-w\fR, \fB\-\-with\-uri\fR: Show the resource URI for each environment
-.
-.SH "SHOW"
-\fBknife environment show\fR \fIenvironment\fR \fI(options)\fR
-.
-.SH "DESCRIPTION"
-Environments provide a means to apply policies to hosts in your infrastructure based on business function\. For example, you may have a separate copy of your infrastructure called "dev" that runs the latest version of your application and should use the newest versions of your cookbooks when configuring systems, and a production instance of your infrastructure where you wish to update code and cookbooks in a more controlled fashion\. In Chef, this function is implemented with \fIenvironments\fR\.
-.
-.P
-Environments contain two major components: a set of cookbook version constraints and environment attributes\.
-.
-.SH "SYNTAX"
-A cookbook version constraint is comprised of a \fIcookbook name\fR and a \fIversion constraint\fR\. The \fIcookbook name\fR is the name of a cookbook in your system, and the \fIversion constraint\fR is a String describing the version(s) of that cookbook allowed in the environment\. Only one \fIversion constraint\fR is supported for a given \fIcookbook name\fR\.
-.
-.P
-The exact syntax used to define a cookbook version constraint varies depending on whether you use the JSON format or the Ruby format\. In the JSON format, the cookbook version constraints for an environment are represented as a single JSON object, like this:
-.
-.IP "" 4
-.
-.nf
-
-{"apache2": ">= 1\.5\.0"}
-.
-.fi
-.
-.IP "" 0
-.
-.P
-In the Ruby format, the cookbook version contraints for an environment are represented as a Ruby Hash, like this:
-.
-.IP "" 4
-.
+.TH "KNIFE-ENVIRONMENT" "1" "Chef 11.8" "" "knife environment"
+.SH NAME
+knife-environment \- The man page for the knife environment subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+An environment is a way to map an organization\(aqs real\-life workflow to what can be configured and managed when using server. Every organization begins with a single environment called the \fB_default\fP environment, which cannot be modified (or deleted). Additional environments can be created to reflect each organization\(aqs patterns and workflow. For example, creating \fBproduction\fP, \fBstaging\fP, \fBtesting\fP, and \fBdevelopment\fP environments. Generally, an environment is also associated with one (or more) cookbook versions.
+.sp
+The \fBknife environment\fP subcommand is used to manage environments within a single organization on the server.
+.sp
+This subcommand has the following syntax:
+.sp
.nf
-
-{"apache2" => ">= 1\.5\.0"}
-.
+.ft C
+$ knife environment [ARGUMENT] (options)
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-A \fIversion number\fR is a String comprised of two or three digits separated by a dot (\.) character, or in other words, strings of the form "major\.minor" or "major\.minor\.patch"\. "1\.2" and "1\.2\.3" are examples of valid version numbers\. Version numbers containing more than three digits or alphabetic characters are not supported\.
-.
-.P
-A \fIversion constraint\fR String is composed of an \fIoperator\fR and a \fIversion number\fR\. The following operators are available:
-.
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB= VERSION\fR
-Equality\. Only the exact version specified may be used\.
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB> VERSION\fR
-Greater than\. Only versions greater than \fBVERSION\fR may be used\.
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB>= VERSION\fR
-Greater than or equal to\. Only versions equal to VERSION or greater may be used\.
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB< VERSION\fR
-Less than\. Only versions less than VERSION may be used\.
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB<= VERSION\fR
-Less than or equal to\. Only versions lesser or equal to VERSION may be used\.
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB~> VERSION\fR
-Pessimistic greater than\. Depending on the number of components in the given VERSION, the constraint will be optimistic about future minor or patch revisions only\. For example, \fB~> 1\.1\fR will match any version less than \fB2\.0\fR and greater than or equal to \fB1\.1\.0\fR, whereas \fB~> 2\.0\.5\fR will match any version less than \fB2\.1\.0\fR and greater than or equal to \fB2\.0\.5\fR\.
-.
-.SH "FORMAT"
-The JSON format of an envioronment is as follows:
-.
-.IP "" 4
-.
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH CREATE
+.sp
+The \fBcreate\fP argument is used to add an environment object to the server. When this argument is run, Knife will open $EDITOR to enable editing of the \fBENVIRONMENT\fP description field (unless a description is specified as part of the command). When finished, Knife will add the environment to the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
.nf
-
-{
- "name": "dev",
- "description": "The development environment",
- "cookbook_versions": {
- "couchdb": "= 11\.0\.0"
- },
- "json_class": "Chef::Environment",
- "chef_type": "environment",
- "default_attributes": {
- "apache2": { "listen_ports": [ "80", "443" ] }
- },
- "override_attributes": {
- "aws_s3_bucket": "production"
- }
-}
-.
+.ft C
+$ knife environment create ENVIRONMENT_NAME \-d DESCRIPTION
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-The Ruby format of an environment is as follows:
-.
-.IP "" 4
-.
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-d DESCRIPTION\fP, \fB\-\-description DESCRIPTION\fP
+The description of the environment. This value will populate the description field for the environment on the server.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To create an environment named "dev" with a description of "The development environment.":
+.sp
+.nf
+.ft C
+$ knife environment create dev \-d "The development environment."
+.ft P
+.fi
+.SH DELETE
+.sp
+The \fBdelete\fP argument is used to delete an environment from a server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife environment delete ENVIRONMENT_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To delete an environment named "dev", enter:
+.sp
+.nf
+.ft C
+$ knife environment delete dev
+.ft P
+.fi
+.sp
+Type \fBY\fP to confirm a deletion.
+.SH EDIT
+.sp
+The \fBedit\fP argument is used to edit the attributes of an environment. When this argument is run, Knife will open $EDITOR to enable editing of \fBENVIRONMENT\fP attributes. When finished, Knife will update the server with those changes.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife environment edit ENVIRONMENT_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To edit an environment named "devops", enter:
+.sp
+.nf
+.ft C
+$ knife environment edit devops
+.ft P
+.fi
+.SH FROM FILE
+.sp
+The \fBfrom file\fP argument is used to add or update an environment using a JSON or Ruby DSL description. It must be run with the \fBcreate\fP or \fBedit\fP arguments.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife environment [create | edit] from file FILE (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-all\fP
+Indicates that all environments found at the specified path will be uploaded.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To add an environment using data contained in a JSON file:
+.sp
+.nf
+.ft C
+$ knife environment create devops from file "path to JSON file"
+.ft P
+.fi
+.sp
+or:
+.sp
+.nf
+.ft C
+$ knife environment edit devops from file "path to JSON file"
+.ft P
+.fi
+.SH LIST
+.sp
+The \fBlist\fP argument is used to list all of the environments that are currently available on the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife environment list \-w
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view a list of environments:
+.sp
+.nf
+.ft C
+$ knife environment list \-w
+.ft P
+.fi
+.SH SHOW
+.sp
+The \fBshow\fP argument is used to display information about the specified environment.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife environment show ENVIRONMENT_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To view information about the "dev" environment enter:
+.sp
.nf
+.ft C
+$ knife environment show dev
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+% knife environment show dev
+chef_type: environment
+cookbook_versions:
+default_attributes:
+description:
+json_class: Chef::Environment
+name: dev
+override_attributes:
-name "dev"
-description "The development environment"
-cookbook_versions "couchdb" => "= 11\.0\.0"
-default_attributes "apache2" => { "listen_ports" => [ "80", "443" ] }
-override_attributes "aws_s3_bucket" => "production"
-.
+\e\e
+\e\e
+\e\e
+\e\e
+.ft P
.fi
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife role show devops \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.IP "" 0
-.
-.SH "SEE ALSO"
-\fBknife\-node(1)\fR \fBknife\-cookbook(1)\fR \fBknife\-role(1)\fR \fIhttp://wiki\.opscode\.com/display/chef/Environments\fR \fIhttp://wiki\.opscode\.com/display/chef/Version+Constraints\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Daniel DeLeo \fIdan@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-exec.1 b/distro/common/man/man1/knife-exec.1
index e8769e69f0..3f9e6fc47b 100644
--- a/distro/common/man/man1/knife-exec.1
+++ b/distro/common/man/man1/knife-exec.1
@@ -1,43 +1,327 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-EXEC" "1" "Chef 11.8" "" "knife exec"
+.SH NAME
+knife-exec \- The man page for the knife exec subcommand.
.
-.TH "KNIFE\-EXEC" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.nr rst2man-indent-level 0
.
-.SH "NAME"
-\fBknife\-exec\fR \- Run user scripts using the Chef API DSL
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBexec\fR \fI(options)\fR
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
.
+.sp
+The \fBknife exec\fP subcommand uses the Knife configuration file to execute Ruby scripts in the context of a fully configured chef\-client. This subcommand is most often used to run scripts that will only access server one time (or otherwise very infrequently). Use this subcommand any time that an operation does not warrant full usage of the Knife subcommand library.
+.sp
+For Ruby scripts that will be run using the \fBexec\fP subcommand, note the following:
+.INDENT 0.0
+.INDENT 3.5
+.INDENT 0.0
+.IP \(bu 2
+The Ruby script must be located on the system from which Knife is run (and not be located on any of the systems that Knife will be managing).
+.IP \(bu 2
+Shell commands will be run from a management workstation. For example, something like \fB%x[ls \-lash /opt/only\-on\-a\-node]\fP would give you the directory listing for the "opt/only\-on\-a\-node" directory or a "No such file or directory" error if the file does not already exist locally.
+.IP \(bu 2
+When the chef\-shell DSL is available, the chef\-client DSL will not be (unless the management workstation is also a chef\-client). Without the chef\-client DSL, a bash block cannot be used to run bash commands.
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-E\fR, \fB\-\-exec CODE\fR
-Provide a snippet of code to evaluate on the command line
-.
-.SH "DESCRIPTION"
-\fBknife exec\fR runs arbitrary ruby scripts in a context similar to that of the chef\-shell(1) DSL\. See the chef\-shell documentation for a description of the commands available\.
-.
-.SH "EXAMPLES"
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-Make an API call against an arbitrary endpoint
-knife exec \-E \'api\.get("nodes/fluke\.localdomain/cookbooks")\' => list of cookbooks for the node \fIfluke\.localdomain\fR
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-Remove the role \fIobsolete\fR from all nodes
-knife exec \-E \'nodes\.transform(:all){|n| n\.run_list\.delete("role[obsolete]")}\'
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-Generate the expanded run list for hosts in the \fBwebserver\fR role
-knife exec \-E \'nodes\.find(:roles => "webserver") {|n| n\.expand!; n[:recipes]}\'
-.
-.SH "SEE ALSO"
-\fBchef\-shell(1)\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBAuthenticated API Requests\fP
+.sp
+The \fBknife exec\fP subcommand can be used to make authenticated API requests to the server using the following methods:
+.TS
+center;
+|l|l|.
+_
+T{
+Method
+T} T{
+Description
+T}
+_
+T{
+\fBapi.delete\fP
+T} T{
+Use to delete an object from the server.
+T}
+_
+T{
+\fBapi.get\fP
+T} T{
+Use to get the details of an object on the server.
+T}
+_
+T{
+\fBapi.post\fP
+T} T{
+Use to add an object to the server.
+T}
+_
+T{
+\fBapi.put\fP
+T} T{
+Use to update an object on the server.
+T}
+_
+.TE
+.sp
+These methods are used with the \fB\-E\fP option, which executes that string locally on the workstation using chef\-shell. These methods have the following syntax:
+.sp
+.nf
+.ft C
+$ knife exec \-E \(aqapi.method(/endpoint)\(aq
+.ft P
+.fi
+.sp
+where:
+.INDENT 0.0
+.IP \(bu 2
+\fBapi.method\fP is the corresponding authentication method \-\-\- \fBapi.delete\fP, \fBapi.get\fP, \fBapi.post\fP, or \fBapi.put\fP
+.IP \(bu 2
+\fB/endpoint\fP is an endpoint in the Chef Server API
+.UNINDENT
+.sp
+For example, to get the data for a node named "Example_Node":
+.sp
+.nf
+.ft C
+$ knife exec \-E \(aqputs api.get("/nodes/Example_Node")\(aq
+.ft P
+.fi
+.sp
+and to ensure that the output is visible in the console, add the \fBputs\fP in front of the API authorization request:
+.sp
+.nf
+.ft C
+$ knife exec \-E \(aqputs api.get("/nodes/Example_Node")\(aq
+.ft P
+.fi
+.sp
+where \fBputs\fP is the shorter version of the \fB$stdout.puts\fP predefined variable in Ruby.
+.sp
+The following example shows how to add a client named "IBM305RAMAC" and the \fB/clients\fP endpoint, and then return the private key for that user in the console:
+.sp
+.nf
+.ft C
+$ client_desc = {
+ "name" => "IBM305RAMAC",
+ "admin" => false
+ }
+
+ new_client = api.post("/clients", client_desc)
+ puts new_client["private_key"]
+.ft P
+.fi
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife exec SCRIPT (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-E CODE\fP, \fB\-\-exec CODE\fP
+A string of code that will be executed.
+.TP
+.B \fB\-p PATH:PATH\fP, \fB\-\-script\-path PATH:PATH\fP
+A colon\-separated path at which Ruby scripts are located.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+There are three ways to use \fBknife exec\fP to run Ruby script files. For example:
+.sp
+.nf
+.ft C
+$ knife exec /path/to/script_file
+.ft P
+.fi
+.sp
+Or:
+.sp
+.nf
+.ft C
+$ knife exec \-E \(aqRUBY CODE\(aq
+.ft P
+.fi
+.sp
+Or:
+.sp
+.nf
+.ft C
+$ knife exec
+RUBY CODE
+^D
+.ft P
+.fi
+.sp
+To check the status of Knife using a Ruby script named "status.rb" (which looks like):
+.sp
+.nf
+.ft C
+printf "%\-5s %\-12s %\-8s %s\en", "Check In", "Name", "Ruby", "Recipes"
+nodes.all do |n|
+ checkin = Time.at(n[\(aqohai_time\(aq]).strftime("%F %R")
+ rubyver = n[\(aqlanguages\(aq][\(aqruby\(aq][\(aqversion\(aq]
+ recipes = n.run_list.expand(_default).recipes.join(", ")
+ printf "%\-20s %\-12s %\-8s %s\en", checkin, n.name, rubyver, recipes
+end
+.ft P
+.fi
+.sp
+and is located in a directory named "scripts", enter:
+.sp
+.nf
+.ft C
+$ knife exec scripts/status.rb
+.ft P
+.fi
+.sp
+To show the available free memory for all nodes, enter:
+.sp
+.nf
+.ft C
+$ knife exec \-E \(aqnodes.all {|n| puts "#{n.name} has #{n.memory.total} free memory"}\(aq
+.ft P
+.fi
+.sp
+To list all of the available search indexes, enter:
+.sp
+.nf
+.ft C
+$ knife exec \-E \(aqputs api.get("search").keys\(aq
+.ft P
+.fi
+.sp
+To query a node for multiple attributes using a Ruby script named \fBsearch_attributes.rb\fP (which looks like):
+.sp
+.nf
+.ft C
+% cat scripts/search_attributes.rb
+query = ARGV[2]
+attributes = ARGV[3].split(",")
+puts "Your query: #{query}"
+puts "Your attributes: #{attributes.join(" ")}"
+results = {}
+search(:node, query) do |n|
+ results[n.name] = {}
+ attributes.each {|a| results[n.name][a] = n[a]}
+end
+
+puts results
+exit 0
+.ft P
+.fi
+.sp
+enter:
+.sp
+.nf
+.ft C
+% knife exec scripts/search_attributes.rb "hostname:test_system" ipaddress,fqdn
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+Your query: hostname:test_system
+Your attributes: ipaddress fqdn
+{"test_system.example.com"=>{"ipaddress"=>"10.1.1.200", "fqdn"=>"test_system.example.com"}}
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-index-rebuild.1 b/distro/common/man/man1/knife-index-rebuild.1
new file mode 100644
index 0000000000..2bacf68619
--- /dev/null
+++ b/distro/common/man/man1/knife-index-rebuild.1
@@ -0,0 +1,117 @@
+.TH "KNIFE-INDEX-REBUILD" "1" "Chef 11.8" "" "knife index rebuild"
+.SH NAME
+knife-index-rebuild \- The man page for the knife index rebuild subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife index rebuild\fP subcommand is used to rebuild the search indexes for the open source server. This operation is destructive and may take some time.
+.IP Note
+This subcommand ONLY works when run against the open source server version 10.x. This subcommand will NOT run against open source server 11, Enterprise Chef (including hosted Enterprise Chef), or Private Chef.
+.RE
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife index rebuild
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-index.1 b/distro/common/man/man1/knife-index.1
index b715619112..ac7c5b2655 100644
--- a/distro/common/man/man1/knife-index.1
+++ b/distro/common/man/man1/knife-index.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "KNIFE\-INDEX" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "KNIFE\-INDEX" "1" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBknife\-index\fR \- Rebuild the search index on a Chef Server
diff --git a/distro/common/man/man1/knife-list.1 b/distro/common/man/man1/knife-list.1
new file mode 100644
index 0000000000..e4cfb6710d
--- /dev/null
+++ b/distro/common/man/man1/knife-list.1
@@ -0,0 +1,169 @@
+.TH "KNIFE-LIST" "1" "Chef 11.8" "" "knife list"
+.SH NAME
+knife-list \- The man page for the knife list subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife list\fP subcommand is used to view a list of objects on the server. This subcommand works similar to \fBknife cookbook list\fP, \fBknife data bag list\fP, \fBknife environment list\fP, \fBknife node list\fP, and \fBknife role list\fP, but with a single verb (and a single action).
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife list [PATTERN...] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-d\fP
+Indicates that a directory\(aqs children will not be shown when a directory matches a pattern. Default value: \fBfalse\fP.
+.TP
+.B \fB\-f\fP, \fB\-\-flat\fP
+Indicates that a list of file names will be shown. Set to \fBfalse\fP to view ls\-like output. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-local\fP
+Indicates that only contents of the local directory will be returned. Default: \fBfalse\fP.
+.TP
+.B \fB\-1\fP
+Indicates that only one column of results will be shown. Default: \fBfalse\fP.
+.TP
+.B \fB\-p\fP
+Indicates that trailing slashes (/) will be shown for directories. Default: \fBfalse\fP.
+.TP
+.B \fB\-R\fP
+Indicates that directories will be listed recursively. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default: \fBeverything\fP / \fBhosted_everything\fP.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+For example, to view a list of roles on the server:
+.sp
+.nf
+.ft C
+$ knife list roles/
+.ft P
+.fi
+.sp
+To view a list of roles and environments on the server:
+.sp
+.nf
+.ft C
+$ knife list roles/ environments/
+.ft P
+.fi
+.sp
+To view a list of absolutely everything on the server:
+.sp
+.nf
+.ft C
+$ knife list \-R /
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-node.1 b/distro/common/man/man1/knife-node.1
index 145fbd8374..9b36a04228 100644
--- a/distro/common/man/man1/knife-node.1
+++ b/distro/common/man/man1/knife-node.1
@@ -1,134 +1,580 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-NODE" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\-node\fR \- Manage the hosts in your infrastructure
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBnode\fR \fIsub\-command\fR \fI(options)\fR
-.
-.SH "DESCRIPTION"
-Nodes are data structures that represent hosts configured with Chef\. Nodes have a \fBname\fR, a String that uniquely identifies the node, \fBattributes\fR, a nested Hash of properties that describe how the host should be configured, a \fBchef_environment\fR, a String representing the environment to which the node belongs, and a \fBrun_list\fR, an ordered list of \fBrecipes\fR or \fBroles\fR that chef\-client should apply when configuring a host\.
-.
-.P
-When a host communicates with a Chef Server, it authenticates using its \fBnode_name\fR for identification and signs its reqests with a private key\. The Server validates the request by looking up a \fBclient\fR object with a name identical to the \fBnode_name\fR submitted with the request and verifes the signature using the public key for that \fBclient\fR object\. \fBNOTE\fR that the \fBclient\fR is a different object in the system\. It is associated with a node by virtue of having a matching name\.
-.
-.P
-By default \fBchef\-client\fR(8) will create a node using the FQDN of the host for the node name, though this may be overridden by configuration settings\.
-.
-.SH "NODE SUB\-COMMANDS"
-The following \fBnode\fR subcommands are available:
-.
-.SH "BULK DELETE"
-\fBknife node bulk delete\fR \fIregex\fR \fI(options)\fR
-.
-.P
-Deletes nodes for which the name matches the regular expression \fIregex\fR on the Chef Server\. The regular expression should be given in quotes, and should not be surrounded with forward slashes (as is typical of regular expression literals in scripting languages)\.
-.
-.SH "CREATE"
-\fBknife node create\fR \fIname\fR \fI(options)\fR
-.
-.P
-Create a new node\. Unless the \-\-disable\-editing option is given, an empty node object will be created and displayed in your text editor\. If the editor exits with a successful exit status, the node data will be posted to the Chef Server to create the node\.
-.
-.SH "DELETE"
-\fBknife node delete\fR \fIname\fR \fI(options)\fR
-.
-.P
-Deletes the node identified by \fIname\fR on the Chef Server\.
-.
-.SH "EDIT"
-\fBknife node edit\fR \fIname\fR \fI(options)\fR
-.
+.TH "KNIFE-NODE" "1" "Chef 11.8" "" "knife node"
+.SH NAME
+knife-node \- The man page for the knife node subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+A node is any physical, virtual, or cloud machine that is configured to be maintained by a chef\-client.
+.sp
+The \fBknife node\fP subcommand is used to manage the nodes that exist on a server.
+.sp
+This subcommand has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node [ARGUMENT] (options)
+.ft P
+.fi
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-a\fR, \fB\-\-all\fR
-Display all node data in the editor\. By default, default, override, and automatic attributes are not shown\.
-.
-.P
-Edit the node identified by \fIname\fR\. Like \fBknife node create\fR, the node will be displayed in your text editor unless the \-n option is present\.
-.
-.SH "FROM FILE"
-\fBknife node from file\fR \fIfile\fR \fI(options)\fR
-.
-.P
-Create a node from a JSON format \fIfile\fR\.
-.
-.SH "LIST"
-\fBknife node list\fR \fI(options)\fR
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-w\fR, \fB\-\-with\-uri\fR
-Show corresponding URIs
-.
-.P
-List all nodes\.
-.
-.SH "RUN_LIST ADD"
-\fBknife node run_list add\fR \fIname\fR \fIrun list item\fR \fI(options)\fR
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-a\fR, \fB\-\-after ITEM\fR
-Place the ENTRY in the run list after ITEM
-.
-.P
-Add the \fIrun list item\fR to the node\'s \fBrun_list\fR\. See Run list
-.
-.SH "RUN_LIST REMOVE"
-\fBknife node run_list remove\fR \fInode name\fR \fIrun list item\fR \fI(options)\fR
-.
-.P
-Remove the \fIrun list item\fR from the node\'s \fBrun_list\fR\.
-.
-.SH "SHOW"
-\fBknife node show\fR \fInode name\fR \fI(options)\fR
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-a\fR, \fB\-\-attribute [ATTR]\fR
-Show only one attribute
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-r\fR, \fB\-\-run\-list\fR
-Show only the run list
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB\-F\fR, \fB\-\-format FORMAT\fR
-Display the node in a different format\.
-.
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
.TP
-\fB\-m\fR, \fB\-\-medium\fR
-Display more, but not all, of the node\'s data when using the default \fIsummary\fR format
-.
-.P
-Displays the node identified by \fInode name\fR on stdout\.
-.
-.SH "RUN LIST ITEM FORMAT"
-Run list items may be either roles or recipes\. When adding a role to a run list, the correct syntax is "role[ROLE_NAME]"
-.
-.P
-When adding a recipe to a run list, there are several valid formats:
-.
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
.TP
-Fully Qualified Format
-"recipe[COOKBOOK::RECIPE_NAME]", for example, "recipe[chef::client]"
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-Cookbook Recipe Format
-For brevity, the recipe part of the fully qualified format may be omitted, and recipes specified as "COOKBOOK::RECIPE_NAME", e\.g\., "chef::client"
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.TP
-Default Recipe Format
-When adding the default recipe of a cookbook to a run list, the recipe name may be omitted as well, e\.g\., "chef::default" may be written as just "chef"
-.
-.SH "SEE ALSO"
-\fBknife\-client\fR(1) \fBknife\-search\fR(1) \fBknife\-role\fR(1)
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH BULK DELETE
+.sp
+The \fBbulk delete\fP argument is used to delete one or more nodes that match a pattern defined by a regular expression. The regular expression must be within quotes and not be surrounded by forward slashes (/).
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node bulk delete REGEX
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To bulk delete many nodes, use a regular expression to define the pattern:
+.sp
+.nf
+.ft C
+$ knife node bulk delete "^[0\-9]{3}$"
+.ft P
+.fi
+.sp
+Type \fBY\fP to confirm a deletion.
+.SH CREATE
+.sp
+The \fBcreate\fP argument is used to add a node to the server. Node data is stored as JSON on the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node create NODE_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To add a node, enter:
+.sp
+.nf
+.ft C
+$ knife node create node1
+.ft P
+.fi
+.sp
+In the $EDITOR enter the node data in JSON:
+.sp
+.nf
+.ft C
+## sample:
+{
+ "normal": {
+ },
+ "name": "foobar",
+ "override": {
+ },
+ "default": {
+ },
+ "json_class": "Chef::Node",
+ "automatic": {
+ },
+ "run_list": [
+ "recipe[zsh]",
+ "role[webserver]"
+ ],
+ "chef_type": "node"
+}
+.ft P
+.fi
+.sp
+When finished, save it.
+.SH DELETE
+.sp
+The \fBdelete\fP argument is used to delete a node from the server.
+.IP Note
+Deleting a node will not delete any corresponding API clients.
+.RE
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node delete NODE_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To delete a node called "dev", enter:
+.sp
+.nf
+.ft C
+$ knife node delete dev
+.ft P
+.fi
+.SH EDIT
+.sp
+The \fBedit\fP argument is used to edit the details of a node on a server. Node data is stored as JSON on the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node edit NODE_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-all\fP
+Displays a node in the $EDITOR. By default, attributes that are default, override, or automatic are not shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To edit the data for a node named "node1", enter:
+.sp
+.nf
+.ft C
+$ knife node edit node1 \-a
+.ft P
+.fi
+.sp
+Update the role data in JSON:
+.sp
+.nf
+.ft C
+## sample:
+{
+ "normal": {
+ },
+ "name": "node1",
+ "override": {
+ },
+ "default": {
+ },
+ "json_class": "Chef::Node",
+ "automatic": {
+ },
+ "run_list": [
+ "recipe[devops]",
+ "role[webserver]"
+ ],
+ "chef_type": "node"
+}
+.ft P
+.fi
+.sp
+When finished, save it.
+.SH FROM FILE
+.sp
+The \fBfrom file\fP argument is used to create a node using existing node data as a template.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node from file FILE
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To add a node using data contained in a JSON file:
+.sp
+.nf
+.ft C
+$ knife node from file "path to JSON file"
+.ft P
+.fi
+.SH LIST
+.sp
+The \fBlist\fP argument is used to view all of the nodes that exist on a server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node list (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To verify the list of nodes that are registered with the server, enter:
+.sp
+.nf
+.ft C
+$ knife node list
+.ft P
+.fi
+.sp
+to return something similar to:
+.sp
+.nf
+.ft C
+i\-12345678
+rs\-123456
+.ft P
+.fi
+.SH RUN_LIST ADD
+.sp
+The \fBrun_list add\fP argument is used to add run list items (roles or recipes) to a node. A recipe must be in one of the following formats: fully qualified, cookbook, or default. Both roles and recipes must be in quotes, for example: \fB\(aqrole[ROLE_NAME]\(aq\fP or \fB\(aqrecipe[COOKBOOK::RECIPE_NAME]\(aq\fP. Use a comma to separate roles and recipes when adding more than one, like this: \fB\(aqrecipe[COOKBOOK::RECIPE_NAME],COOKBOOK::RECIPE_NAME,role[ROLE_NAME]\(aq\fP.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node run_list add NODE_NAME RUN_LIST_ITEM (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a ITEM\fP, \fB\-\-after ITEM\fP
+Use this to add the run list item after the specified run list item.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To add a role to a run list, enter:
+.sp
+.nf
+.ft C
+$ knife node run_list add node \(aqrole[ROLE_NAME]\(aq
+.ft P
+.fi
+.sp
+To add roles and recipes to a run list, enter:
+.sp
+.nf
+.ft C
+$ knife node run_list add node \(aqrecipe[COOKBOOK::RECIPE_NAME],recipe[COOKBOOK::RECIPE_NAME],role[ROLE_NAME]\(aq
+.ft P
+.fi
+.sp
+To add a recipe to a run list using the fully qualified format, enter:
+.sp
+.nf
+.ft C
+$ knife node run_list add node \(aqrecipe[COOKBOOK::RECIPE_NAME]\(aq
+.ft P
+.fi
+.sp
+To add a recipe to a run list using the cookbook format, enter:
+.sp
+.nf
+.ft C
+$ knife node run_list add node \(aqCOOKBOOK::RECIPE_NAME\(aq
+.ft P
+.fi
+.sp
+To add the default recipe of a cookbook to a run list, enter:
+.sp
+.nf
+.ft C
+$ knife node run_list add node \(aqCOOKBOOK\(aq
+.ft P
+.fi
+.SH RUN_LIST REMOVE
+.sp
+The \fBrun_list remove\fP argument is used to remove run list items (roles or recipes) from a node. A recipe must be in one of the following formats: fully qualified, cookbook, or default. Both roles and recipes must be in quotes, for example: \fB\(aqrole[ROLE_NAME]\(aq\fP or \fB\(aqrecipe[COOKBOOK::RECIPE_NAME]\(aq\fP. Use a comma to separate roles and recipes when removing more than one, like this: \fB\(aqrecipe[COOKBOOK::RECIPE_NAME],COOKBOOK::RECIPE_NAME,role[ROLE_NAME]\(aq\fP.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node run_list remove NODE_NAME RUN_LIST_ITEM
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To remove a role from a run list, enter:
+.sp
+.nf
+.ft C
+$ knife node run_list remove node \(aqrole[ROLE_NAME]\(aq
+.ft P
+.fi
+.sp
+To remove a recipe from a run list using the fully qualified format, enter:
+.sp
+.nf
+.ft C
+$ knife node run_list remove node \(aqrecipe[COOKBOOK::RECIPE_NAME]\(aq
+.ft P
+.fi
+.SH SHOW
+.sp
+The \fBshow\fP argument is used to display information about a node.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife node show NODE_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a ATTR\fP, \fB\-\-attribute ATTR\fP
+The attribute (or attributes) to show.
+.TP
+.B \fB\-l\fP, \fB\-\-long\fP
+Display long output when searching nodes while using the default summary format.
+.TP
+.B \fB\-m\fP, \fB\-\-medium\fP
+Display more, but not all, of a node\(aqs data when searching using the default summary format.
+.TP
+.B \fB\-r\fP, \fB\-\-run\-list\fP
+Indicates that only the run\-list will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view all data for a node named "build", enter:
+.sp
+.nf
+.ft C
+$ knife node show build
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+Node Name: build
+Environment: _default
+FQDN:
+IP:
+Run List:
+Roles:
+Recipes:
+Platform:
+.ft P
+.fi
+.sp
+To show basic information about a node, truncated and nicely formatted:
+.sp
+.nf
+.ft C
+knife node show <node_name>
+.ft P
+.fi
+.sp
+To show all information about a node, nicely formatted:
+.sp
+.nf
+.ft C
+knife node show \-l <node_name>
+.ft P
+.fi
+.sp
+To list a single node attribute:
+.sp
+.nf
+.ft C
+knife node show <node_name> \-a <attribute_name>
+.ft P
+.fi
+.sp
+where \fB<attribute_name>\fP is something like kernel or platform. (This doesn\(aqt work for nested attributes like \fBnode[kernel][machine]\fP because \fBknife node show\fP doesn\(aqt understand nested attributes.)
+.sp
+To view the FQDN for a node named "i\-12345678", enter:
+.sp
+.nf
+.ft C
+$ knife node show i\-12345678 \-a fqdn
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+fqdn: ip\-10\-251\-75\-20.ec2.internal
+.ft P
+.fi
+.sp
+To view the run list for a node named "dev", enter:
+.sp
+.nf
+.ft C
+$ knife node show dev \-r
+.ft P
+.fi
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife role show devops \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.sp
+To view node information in raw JSON, use the \fB\-l\fP or \fB\-\-long\fP option:
+.sp
+.nf
+.ft C
+knife node show \-l \-F json <node_name>
+.ft P
+.fi
+.sp
+and/or:
+.sp
+.nf
+.ft C
+knife node show \-l \-\-format=json <node_name>
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-raw.1 b/distro/common/man/man1/knife-raw.1
new file mode 100644
index 0000000000..5053006c0b
--- /dev/null
+++ b/distro/common/man/man1/knife-raw.1
@@ -0,0 +1,172 @@
+.TH "KNIFE-RAW" "1" "Chef 11.8" "" "knife raw"
+.SH NAME
+knife-raw \- The man page for the knife raw subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife raw\fP subcommand is used to send a REST request to a specified path using the Chef Server API.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife raw REQUEST_PATH (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-i FILE\fP, \fB\-\-input FILE\fP
+The name of a file to be used with the \fBPUT\fP or a \fBPOST\fP request.
+.TP
+.B \fB\-\-[no\-]pretty\fP
+Use \fB\-\-no\-pretty\fP to disable pretty\-print output for JSON. Default: \fB\-\-pretty\fP.
+.TP
+.B \fB\-m METHOD\fP, \fB\-\-method METHOD\fP
+The request method: \fBDELETE\fP, \fBGET\fP, \fBPOST\fP, or \fBPUT\fP. Default value: \fBGET\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default: \fBeverything\fP / \fBhosted_everything\fP.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view information about a client:
+.sp
+.nf
+.ft C
+knife raw /clients/<client_name>
+.ft P
+.fi
+.sp
+To view information about a node:
+.sp
+.nf
+.ft C
+knife raw /nodes/<node_name>
+.ft P
+.fi
+.sp
+To delete a data bag, enter a command similar to:
+.sp
+.nf
+.ft C
+$ knife raw \-m DELETE /data/foo
+.ft P
+.fi
+.sp
+to return something similar to:
+.sp
+.nf
+.ft C
+{
+ "name":"foo",
+ "json_class":"Chef::DataBag",
+ "chef_type":"data_bag"
+}
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-recipe-list.1 b/distro/common/man/man1/knife-recipe-list.1
new file mode 100644
index 0000000000..d8cca9edec
--- /dev/null
+++ b/distro/common/man/man1/knife-recipe-list.1
@@ -0,0 +1,135 @@
+.TH "KNIFE-RECIPE-LIST" "1" "Chef 11.8" "" "knife recipe list"
+.SH NAME
+knife-recipe-list \- The man page for the knife recipe list subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife recipe list\fP subcommand is used to view all of the recipes that are on a server. A regular expression can be used to limit the results to recipes that match a specific pattern. The regular expression must be within quotes and not be surrounded by forward slashes (/).
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife recipe list REGEX
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To view a list of recipes:
+.sp
+.nf
+.ft C
+$ knife recipe list \(aqcouchdb::*\(aq
+.ft P
+.fi
+.sp
+to return:
+.sp
+.nf
+.ft C
+couchdb::main_monitors
+couchdb::master
+couchdb::default
+couchdb::org_cleanu
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-role.1 b/distro/common/man/man1/knife-role.1
index 57ff2143ad..cbf736ebf7 100644
--- a/distro/common/man/man1/knife-role.1
+++ b/distro/common/man/man1/knife-role.1
@@ -1,88 +1,376 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-ROLE" "1" "Chef 11.8" "" "knife role"
+.SH NAME
+knife-role \- The man page for the knife role subcommand.
.
-.TH "KNIFE\-ROLE" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.nr rst2man-indent-level 0
.
-.SH "NAME"
-\fBknife\-role\fR \- Group common configuration settings
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBrole\fR \fIsub\-command\fR \fI(options)\fR
-.
-.SH "ROLE SUB\-COMMANDS"
-The following \fBrole\fR subcommands are available:
-.
-.SH "LIST"
-\fBknife role list\fR \fI(options)\fR
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
.
+.sp
+A role is a way to define certain patterns and processes that exist across nodes in an organization as belonging to a single job function. Each role consists of zero (or more) attributes and a run list. Each node can have zero (or more) roles assigned to it. When a role is run against a node, the configuration details of that node are compared against the attributes of the role, and then the contents of that role\(aqs run list are applied to the node\(aqs configuration details. When a chef\-client runs, it merges its own attributes and run lists with those contained within each assigned role.
+.sp
+The \fBknife role\fP subcommand is used to manage the roles that are associated with one or more nodes on a server.
+.sp
+This subcommand has the following syntax:
+.sp
+.nf
+.ft C
+$ knife role [ARGUMENT] (options)
+.ft P
+.fi
+.IP Note
+Use the \fBknife node\fP subcommand (and the \fBrun_list add node\fP argument) to add a role to a node on the server.
+.RE
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-w\fR, \fB\-\-with\-uri\fR
-Show corresponding URIs
-.
-.P
-List roles\.
-.
-.SH "SHOW"
-\fBknife role show ROLE\fR \fI(options)\fR
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-a\fR, \fB\-\-attribute ATTR\fR
-Show only one attribute
-.
-.P
-Show a specific role\.
-.
-.SH "CREATE"
-\fBknife role create ROLE\fR \fI(options)\fR
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-d\fR, \fB\-\-description\fR
-The role description
-.
-.P
-Create a new role\.
-.
-.SH "EDIT"
-\fBknife role edit ROLE\fR \fI(options)\fR
-.
-.P
-Edit a role\.
-.
-.SH "FROM FILE"
-\fBknife role from file FILE\fR \fI(options)\fR
-.
-.P
-Create or update a role from a role Ruby DSL (\fB\.rb\fR) or JSON file\.
-.
-.SH "DELETE"
-\fBknife role delete ROLE\fR \fI(options)\fR
-.
-.P
-Delete a role\.
-.
-.SH "BULK DELETE"
-\fBknife role bulk delete REGEX\fR \fI(options)\fR
-.
-.P
-Delete roles on the Chef Server based on a regular expression\. The regular expression (\fIREGEX\fR) should be in quotes, not in //\'s\.
-.
-.SH "DESCRIPTION"
-Roles provide a mechanism to group repeated configuration settings\. Roles are data structures that contain \fBdefault_attributes\fR, and \fBoverride_attributes\fR, which are nested hashes of configuration settings, and a \fBrun_list\fR, which is an ordered list of recipes and roles that should be applied to a host by chef\-client\.
-.
-.P
-\fBdefault_attributes\fR will be overridden if they conflict with a value on a node that includes the role\. Conversely, \fBoverride_attributes\fR will override any values set on nodes that apply them\.
-.
-.P
-When \fBchef\-client\fR(8) configures a host, it will "expand" the \fBrun_list\fR included in that host\'s node data\. The expansion process will recursively replace any roles in the run_list with that role\'s run_list\.
-.
-.SH "SEE ALSO"
-\fBknife\-node(1)\fR \fBknife\-environment(1)\fR \fIhttp://wiki\.opscode\.com/display/chef/Roles\fR \fIhttp://wiki\.opscode\.com/display/chef/Attributes\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH BULK DELETE
+.sp
+The \fBbulk delete\fP argument is used to delete one or more roles that match a pattern defined by a regular expression. The regular expression must be within quotes and not be surrounded by forward slashes (/).
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife role bulk delete REGEX
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To bulk delete roles using a regular expression:
+.sp
+.nf
+.ft C
+$ knife role bulk delete "^[0\-9]{3}$"
+.ft P
+.fi
+.SH CREATE
+.sp
+The \fBcreate\fP argument is used to add a role to the server. To add a role to a node, you must use the \fBnode\fP sub\-command and the \fBrun\-list add\fP argument. Role data is saved as JSON on the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife role create ROLE_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-d DESCRIPTION\fP, \fB\-\-description DESCRIPTION\fP
+The description of the role. This value will populate the description field for the role on the server.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To add a role named "role1", enter:
+.sp
+.nf
+.ft C
+$ knife role create role1
+.ft P
+.fi
+.sp
+In the $EDITOR enter the role data in JSON:
+.sp
+.nf
+.ft C
+## sample:
+{
+ "name": "role1",
+ "default_attributes": {
+ },
+ "json_class": "Chef::Role",
+ "run_list": [
+
+ ],
+ "description": "",
+ "chef_type": "role",
+ "override_attributes": {
+ }
+}
+.ft P
+.fi
+.sp
+When finished, save it.
+.SH DELETE
+.sp
+The \fBdelete\fP argument is used to delete a role from the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife role delete ROLE_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To delete a role:
+.sp
+.nf
+.ft C
+$ knife role delete devops
+.ft P
+.fi
+.sp
+Type \fBY\fP to confirm a deletion.
+.SH EDIT
+.sp
+The \fBedit\fP argument is used to edit role details on the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife role edit ROLE_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To edit the data for a role named "role1", enter:
+.sp
+.nf
+.ft C
+$ knife role edit role1
+.ft P
+.fi
+.sp
+Update the role data in JSON:
+.sp
+.nf
+.ft C
+## sample:
+{
+ "name": "role1",
+ "default_attributes": {
+ },
+ "json_class": "Chef::Role",
+ "run_list": [
+
+ ],
+ "description": "This is the description for the role1 role.",
+ "chef_type": "role",
+ "override_attributes": {
+ }
+}
+.ft P
+.fi
+.sp
+When finished, save it.
+.SH FROM FILE
+.sp
+The \fBfrom file\fP argument is used to create a role using existing JSON data as a template.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife role from file FILE
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To view role details based on the values contained in a JSON file:
+.sp
+.nf
+.ft C
+$ knife role from file "path to JSON file"
+.ft P
+.fi
+.SH LIST
+.sp
+The \fBlist\fP argument is used to view a list of roles that are currently available on the server.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife role list
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view a list of roles on the server and display the URI for each role returned, enter:
+.sp
+.nf
+.ft C
+$ knife role list \-w
+.ft P
+.fi
+.SH SHOW
+.sp
+The \fBshow\fP argument is used to view the details of a role.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife role show ROLE_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a ATTR\fP, \fB\-\-attribute ATTR\fP
+The attribute (or attributes) to show.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife role show devops \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife role show devops \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-search.1 b/distro/common/man/man1/knife-search.1
index c8ea316d8c..6f4edebe1f 100644
--- a/distro/common/man/man1/knife-search.1
+++ b/distro/common/man/man1/knife-search.1
@@ -1,280 +1,306 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-SEARCH" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\-search\fR \- Find objects on a Chef Server by query
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBsearch INDEX QUERY\fR \fI(options)\fR
-.
+.TH "KNIFE-SEARCH" "1" "Chef 11.8" "" "knife search"
+.SH NAME
+knife-search \- The man page for the knife search subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+Search indexes allow queries to be made for any type of data that is indexed by the server, including data bags (and data bag items), environments, nodes, and roles. A defined query syntax is used to support search patterns like exact, wildcard, range, and fuzzy. A search is a full\-text query that can be done from several locations, including from within a recipe, by using the \fBsearch\fP subcommand in Knife, by using the search functionality in the Management Console, or by using the \fB/search\fP or \fB/search/INDEX\fP endpoints in the Chef Server API. The search engine is based on Apache Solr and is run from the server.
+.sp
+The \fBknife search\fP subcommand is used run a search query for information that is indexed on a server.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-a\fR, \fB\-\-attribute ATTR\fR
-Show only one attribute
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-i\fR, \fB\-\-id\-only\fR
-Show only the ID of matching objects
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-q\fR, \fB\-\-query QUERY\fR
-The search query; useful to protect queries starting with \-
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-R\fR, \fB\-\-rows INT\fR
-The number of rows to return
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-r\fR, \fB\-\-run\-list\fR
-Show only the run list
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB\-o\fR, \fB\-\-sort SORT\fR
-The order to sort the results in
-.
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
.TP
-\fB\-b\fR, \fB\-\-start ROW\fR
-The row to start returning results at
-.
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
.TP
-\fB\-m\fR, \fB\-\-medium\fR
-Display medium sized output when searching nodes using the default summary format
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-\fB\-l\fR, \fB\-\-long\fR
-Display long output when searching nodes using the default summary format
-.
-.SH "DESCRIPTION"
-Search is a feature of the Chef Server that allows you to use a full\-text search engine to query information about your infrastructure and applications\. You can utilize this service via search calls in a recipe or the knife search command\. The search syntax is based on Lucene\.
-.
-.SH "INDEXES"
-Search indexes are a feature of the Chef Server and the search sub\-command allows querying any of the available indexes using SOLR query syntax\. The following data types are indexed for search:
-.
-.IP "\(bu" 4
-\fInode\fR
-.
-.IP "\(bu" 4
-\fIrole\fR
-.
-.IP "\(bu" 4
-\fIenvironment\fR
-.
-.IP "\(bu" 4
-\fIclients\fR
-.
-.IP "\(bu" 4
-\fIdata bag\fR
-.
-.IP "" 0
-.
-.P
-Data bags are indexed by the data bag\'s name\. For example, to search a data bag named "admins":
-.
-.IP "" 4
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
.nf
-
-knife search admins "field:search_pattern"
-.
+.ft C
+$ knife search INDEX SEARCH_QUERY
+.ft P
.fi
-.
-.IP "" 0
-.
-.SH "QUERY SYNTAX"
-Queries have the form \fBfield:search_pattern\fR where \fBfield\fR is a key in the JSON description of the relevant objects (nodes, roles, environments, or data bags)\. Both \fBfield\fR and \fBsearch_pattern\fR are case\-sensitive\. \fBsearch_pattern\fR can be an exact, wildcard, range, or fuzzy match (see below)\. The \fBfield\fR supports exact matching and limited wildcard matching\.
-.
-.P
-Searches will return the relevant objects (nodes, roles, environments, or data bags) where the \fBsearch_pattern\fR matches the object\'s value of \fBfield\fR\.
-.
-.SS "FIELD NAMES"
-Field names are the keys within the JSON description of the object being searched\. Nested Keys can be searched by placing an underscore ("_") between key names\.
-.
-.SS "WILDCARD MATCHING FOR FIELD NAMES"
-The field name also has limited support for wildcard matching\. Both the "*" and "?" wildcards (see below) can be used within a field name; however, they cannot be the first character of the field name\.
-.
-.SS "EXACT MATCHES"
-Without any search modifiers, a search returns those fields for which the \fBsearch_pattern\fR exactly matches the value of \fBfield\fR in the JSON description of the object\.
-.
-.SS "WILDCARD MATCHES"
-Search support both single\- and multi\-character wildcard searches within a search pattern\.
-.
-.P
-\'?\' matches exactly one character\.
-.
-.P
-\'*\' matches zero or more characters\.
-.
-.SS "RANGE MATCHES"
-Range searches allows one to match values between two given values\. To match values between X and Y, inclusively, use square brackets:
-.
-.IP "" 4
-.
+.sp
+where \fBINDEX\fP is one of \fBclient\fP, \fBenvironment\fP, \fBnode\fP, \fBrole\fP, or the name of a data bag and \fBSEARCH_QUERY\fP is the search query syntax for the query that will be executed.
+.sp
+\fBINDEX\fP is implied if omitted, and will default to \fBnode\fP. For example:
+.sp
.nf
-
-knife search INDEX \'field:[X TO Y]
-.
+.ft C
+$ knife search \(aq*:*\(aq \-i
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-To match values between X and Y, exclusively, use curly brackets:
-.
-.IP "" 4
-.
+.sp
+will return something similar to:
+.sp
.nf
+.ft C
+8 items found
-knife search INDEX \'field:{X TO Y}\'
-.
+centos\-62\-dev
+opensuse\-1203
+ubuntu\-1304\-dev
+ubuntu\-1304\-orgtest
+ubuntu\-1204\-ohai\-test
+ubuntu\-1304\-ifcfg\-test
+ohai\-test
+win2k8\-dev
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-Values are sorted in lexicographic order\.
-.
-.SS "FUZZY MATCHES"
-Fuzzy searches allows one to match values based on the Levenshtein Distance algorithm\. To perform a fuzzy match, append a tilda (~) to the search term:
-.
-.IP "" 4
-.
+.sp
+and is the same search as:
+.sp
.nf
-
-knife search INDEX \'field:term~\'
-.
+.ft C
+$ knife node search \(aq*:*" \-i
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-This search would return nodes whose \fBfield\fR was \'perm\' or \'germ\'\.
-.
-.SS "BOOLEAN OPERATORS"
-The boolean operators NOT, AND, and OR are supported\. To find values of \fBfield\fR that are not X:
-.
-.IP "" 4
-.
+.sp
+If the \fBSEARCH_QUERY\fP does not contain a colon character (\fB:\fP), then the default query pattern is \fBtags:*#{@query}* OR roles:*#{@query}* OR fqdn:*#{@query}* OR addresses:*#{@query}*\fP, which means the following two search queries are effectively the same:
+.sp
.nf
-
-knife search INDEX \'field:(NOT X)\'
-.
+.ft C
+$ knife search ubuntu
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-To find records where \fBfield1\fR is X and \fBfield2\fR is Y:
-.
-.IP "" 4
-.
+.sp
+or:
+.sp
.nf
-
-knife search INDEX \'field1:X AND field2:Y\'
-.
+.ft C
+$ knife search node "tags:*ubuntu* OR roles:*ubuntu* OR fqdn:*ubuntu* (etc.)"
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-To find records where \fBfield\fR is X or Y:
-.
-.IP "" 4
-.
+.sp
+\fBOptions\fP
+.sp
+This sub\-command has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a ATTR\fP, \fB\-\-attribute ATTR\fP
+The attribute (or attributes) to show.
+.TP
+.B \fB\-b ROW\fP, \fB\-\-start ROW\fP
+The row at which return results will begin.
+.TP
+.B \fB\-i\fP, \fB\-\-id\-only\fP
+Indicates that only matching object IDs will be shown.
+.TP
+.B \fBINDEX\fP
+The name of the index to be queried: \fBclient\fP, \fBenvironment\fP, \fBnode\fP, \fBrole\fP, or \fBDATA_BAG_NAME\fP. Default index: \fBnode\fP.
+.TP
+.B \fB\-l\fP, \fB\-\-long\fP
+Display long output when searching nodes while using the default summary format.
+.TP
+.B \fB\-m\fP, \fB\-\-medium\fP
+Display more, but not all, of a node\(aqs data when searching using the default summary format.
+.TP
+.B \fB\-o SORT\fP, \fB\-\-sort SORT\fP
+The order in which search results will be sorted.
+.TP
+.B \fB\-q SEARCH_QUERY\fP, \fB\-\-query SEARCH_QUERY\fP
+Use to protect search queries that start with a hyphen (\-). A \fB\-q\fP query may be specified as an argument or an option, but not both.
+.TP
+.B \fB\-r\fP, \fB\-\-run\-list\fP
+Indicates that only the run\-list will be shown.
+.TP
+.B \fB\-R INT\fP, \fB\-\-rows INT\fP
+The number of rows to be returned.
+.TP
+.B \fBSEARCH_QUERY\fP
+The search query used to identify a a list of items on a server. This option uses the same syntax as the \fBsearch\fP sub\-command.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To search for the IDs of all nodes running on the Amazon EC2 platform, enter:
+.sp
.nf
-
-knife search INDEX \'field:X OR field:Y\'
-.
+.ft C
+$ knife search node \(aqec2:*\(aq \-i
+.ft P
.fi
-.
-.IP "" 0
-.
-.SS "QUOTING AND SPECIAL CHARACTERS"
-In order to avoid having special characters and escape sequences within your search term interpreted by either Ruby or the shell, enclose them in single quotes\.
-.
-.P
-Search terms that include spaces should be enclosed in double\-quotes:
-.
-.IP "" 4
-.
+.sp
+to return something like:
+.sp
.nf
+.ft C
+4 items found
-knife search INDEX \'field:"term with spaces"\'
-.
+ip\-0A7CA19F.ec2.internal
+
+ip\-0A58CF8E.ec2.internal
+
+ip\-0A58E134.ec2.internal
+
+ip\-0A7CFFD5.ec2.internal
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-The following characters must be escaped:
-.
-.IP "" 4
-.
+.sp
+To search for the instance type (flavor) of all nodes running on the Amazon EC2 platform, enter:
+.sp
.nf
-
-+ \- && || ! ( ) { } [ ] ^ " ~ * ? : \e
-.
+.ft C
+$ knife search node \(aqec2:*\(aq \-a ec2.instance_type
+.ft P
.fi
-.
-.IP "" 0
-.
-.SH "EXAMPLES"
-Find the nodes with the fully\-qualified domain name (FQDN) www\.example\.com:
-.
-.IP "" 4
-.
+.sp
+to return something like:
+.sp
.nf
+.ft C
+4 items found
-knife search node \'fqdn:www\.example\.com\'
-.
+ec2.instance_type: m1.large
+id: ip\-0A7CA19F.ec2.internal
+
+ec2.instance_type: m1.large
+id: ip\-0A58CF8E.ec2.internal
+
+ec2.instance_type: m1.large
+id: ip\-0A58E134.ec2.internal
+
+ec2.instance_type: m1.large
+id: ip\-0A7CFFD5.ec2.internal
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-Find the nodes running a version of Ubuntu:
-.
-.IP "" 4
-.
+.sp
+To search for all nodes running Ubuntu, enter:
+.sp
.nf
-
-knife search node \'platform:ubuntu*\'
-.
+.ft C
+$ knife search node \(aqplatform:ubuntu\(aq
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-Find all nodes running CentOS in the production environment:
-.
-.IP "" 4
-.
+.sp
+To search for all nodes running CentOS in the production environment, enter:
+.sp
.nf
-
-knife search node \'chef_environment:production AND platform:centos\'
-.
+.ft C
+$ knife search node \(aqchef_environment:production AND platform:centos\(aq
+.ft P
.fi
+.sp
+To find a nested attribute, use a pattern similar to the following:
+.sp
+.nf
+.ft C
+$ knife search node <query_to_run> \-a <main_attribute>.<nested_attribute>
+.ft P
+.fi
+.sp
+To build a search query to use more than one attribute, use an underscore ( _ ) to separate each attribute. For example, the following query will search for all nodes running a specific version of Ruby:
+.sp
+.nf
+.ft C
+$ knife search node "languages_ruby_version:1.9.3"
+.ft P
+.fi
+.sp
+To build a search query that can find a nested attribute:
+.sp
+.nf
+.ft C
+$ knife search node name:<node_name> \-a kernel.machine
+.ft P
+.fi
+.sp
+To test a search query that will be used in a \fBknife ssh\fP command:
+.sp
+.nf
+.ft C
+$ knife search node "role:web AND NOT name:web03"
+.ft P
+.fi
+.sp
+where the query in the previous example will search all servers that have the \fBweb\fP role, but not on the server named \fBweb03\fP.
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.IP "" 0
-.
-.SH "KNOWN BUGS"
-.
-.IP "\(bu" 4
-Searches against the client index return no results in most cases\. (CHEF\-2477)
-.
-.IP "\(bu" 4
-Searches using the fuzzy match operator (~) produce an error\. (CHEF\-2478)
-.
-.IP "" 0
-.
-.SH "SEE ALSO"
-\fBknife\-ssh\fR(1) \fIhttp://wiki\.opscode\.com/display/chef/Attributes\fR Lucene Query Parser Syntax \fIhttp://lucene\.apache\.org/java/2_3_2/queryparsersyntax\.html\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-show.1 b/distro/common/man/man1/knife-show.1
new file mode 100644
index 0000000000..da0aff8511
--- /dev/null
+++ b/distro/common/man/man1/knife-show.1
@@ -0,0 +1,140 @@
+.TH "KNIFE-SHOW" "1" "Chef 11.8" "" "knife show"
+.SH NAME
+knife-show \- The man page for the knife show subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife show\fP subcommand is used to view the details of one (or more) objects on the server. This subcommand works similar to \fBknife cookbook show\fP, \fBknife data bag show\fP, \fBknife environment show\fP, \fBknife node show\fP, and \fBknife role show\fP, but with a single verb (and a single action).
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife show [PATTERN...] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To show all cookbooks in the \fBcookbooks/\fP directory:
+.sp
+.nf
+.ft C
+$ knife show cookbooks/
+.ft P
+.fi
+.sp
+or, (if already in the \fBcookbooks/\fP directory in the local chef\-repo):
+.sp
+.nf
+.ft C
+$ knife show
+.ft P
+.fi
+.sp
+To show roles and environments:
+.sp
+.nf
+.ft C
+$ knife show roles/ environments/
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-ssh.1 b/distro/common/man/man1/knife-ssh.1
index af41e3ccf5..ea755c9769 100644
--- a/distro/common/man/man1/knife-ssh.1
+++ b/distro/common/man/man1/knife-ssh.1
@@ -1,79 +1,256 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-SSH" "1" "Chef 11.8" "" "knife ssh"
+.SH NAME
+knife-ssh \- The man page for the knife ssh subcommand.
.
-.TH "KNIFE\-SSH" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.nr rst2man-indent-level 0
.
-.SH "NAME"
-\fBknife\-ssh\fR \- Run a command or interactive session on multiple remote hosts
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBssh QUERY COMMAND\fR \fI(options)\fR
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
.
+.sp
+The \fBknife ssh\fP subcommand is used to invoke SSH commands (in parallel) on a subset of nodes within an organization, based on the results of a search query.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-a\fR, \fB\-\-attribute ATTR\fR
-The attribute to use for opening the connection \- default is fqdn
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-C\fR, \fB\-\-concurrency NUM\fR
-The number of concurrent connections
-.
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
.TP
-\fB\-m\fR, \fB\-\-manual\-list\fR
-QUERY is a space separated list of servers
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-P\fR, \fB\-\-ssh\-password PASSWORD\fR
-The ssh password
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-x\fR, \fB\-\-ssh\-user USERNAME\fR
-The ssh username
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB\-i\fR, \fB\-\-identity\-file IDENTITY_FILE\fR
-The SSH identity file used for authentication
-.
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
.TP
-\fB\-p\fR, \fB\-\-ssh\-port PORT\fR
-The ssh port
-.
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
.TP
-\fB\-\-[no\-]host\-key\-verify\fR
-Verify host key, enabled by default\.
-.
-.SH "DESCRIPTION"
-The \fIssh\fR sub\-command opens an ssh session to each of the nodes in the search results of the \fIQUERY\fR\. This sub\-command requires that the net\-ssh\-multi and highline Ruby libraries are installed\. On Debian systems, these are the libnet\-ssh\-multi\-ruby and libhighline\-ruby packages\. They can also be installed as RubyGems (net\-ssh\-multi and highline, respectively)\.
-.
-.SH "TERMINAL MULTIPLEXING AND TERMINAL TAB SUPPORT"
-\fBknife ssh\fR integrates with several terminal multiplexer programs to provide a more convenient means of managing multiple ssh sessions\. When the \fICOMMAND\fR option matches one of these, \fBknife ssh\fR will create multiple interactive ssh sessions running locally in the terminal multiplexer instead of invoking the command on the remote host\.
-.
-.P
-The available multiplexers are:
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-\fBinteractive\fR
-A built\-in multiplexer\. \fBinteractive\fR supports running commands on a subset of the connected hosts in parallel
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.TP
-\fBscreen\fR(1)
-Runs ssh interactively inside \fBscreen\fR\. ~/\.screenrc will be sourced if it exists\.
-.
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
.TP
-\fBtmux\fR(1)
-Runs ssh interactively inside tmux\.
-.
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
.TP
-\fBmacterm\fR (Mac OS X only)
-Opens a Terminal\.app window and creates a tab for each ssh session\. You must install the rb\-appscript gem before you can use this option\.
-.
-.SH "SEE ALSO"
-\fBknife\-search\fR(1)
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife ssh SEARCH_QUERY SSH_COMMAND (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a SSH_ATTR\fP, \fB\-\-attribute SSH_ATTR\fP
+The attribute that is used when opening the SSH connection. The default attribute is the FQDN of the host. Other possible values include a public IP address, a private IP address, or a hostname.
+.TP
+.B \fB\-C NUM\fP, \fB\-\-concurrency NUM\fP
+The number of allowed concurrent connections.
+.TP
+.B \fB\-G GATEWAY\fP, \fB\-\-ssh\-gateway GATEWAY\fP
+The SSH tunnel or gateway that is used to run a bootstrap action on a machine that is not accessible from the workstation.
+.TP
+.B \fB\-i IDENTITY_FILE\fP, \fB\-\-identity\-file IDENTIFY_FILE\fP
+The SSH identity file used for authentication. Key\-based authentication is recommended.
+.TP
+.B \fB\-m\fP, \fB\-\-manual\-list\fP
+Indicates that a search query is a space\-separated list of servers. If there is more than one item in the list, put quotes around the entire list. For example: \fB\-\-manual\-list "server01 server 02 server 03"\fP
+.TP
+.B \fB\-\-[no\-]host\-key\-verify\fP
+Use \fB\-\-no\-host\-key\-verify\fP to disable host key verification. Default setting: \fB\-\-host\-key\-verify\fP.
+.TP
+.B \fBOTHER\fP
+The shell type. Possible values: \fBinteractive\fP, \fBscreen\fP, \fBtmux\fP, \fBmacterm\fP, or \fBcssh\fP. (\fBcsshx\fP is deprecated in favor of \fBcssh\fP.)
+.TP
+.B \fB\-p PORT\fP, \fB\-\-ssh\-port PORT\fP
+The SSH port.
+.TP
+.B \fB\-P PASSWORD\fP, \fB\-\-ssh\-password PASSWORD\fP
+The SSH password. This can be used to pass the password directly on the command line. If this option is not specified (and a password is required) Knife will prompt for the password.
+.TP
+.B \fBSEARCH_QUERY\fP
+The search query used to return a list of servers to be accessed using SSH and the specified \fBSSH_COMMAND\fP. This option uses the same syntax as the search sub\-command.
+.TP
+.B \fBSSH_COMMAND\fP
+The command that will be run against the results of a search query.
+.TP
+.B \fB\-x USER_NAME\fP, \fB\-\-ssh\-user USER_NAME\fP
+The SSH user name.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To find the uptime of all of web servers running Ubuntu on the Amazon EC2 platform, enter:
+.sp
+.nf
+.ft C
+$ knife ssh "role:web" "uptime" \-x ubuntu \-a ec2.public_hostname
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+ec2\-174\-129\-127\-206.compute\-1.amazonaws.com 13:50:47 up 1 day, 23:26, 1 user, load average: 0.25, 0.18, 0.11
+ec2\-67\-202\-63\-102.compute\-1.amazonaws.com 13:50:47 up 1 day, 23:33, 1 user, load average: 0.12, 0.13, 0.10
+ec2\-184\-73\-9\-250.compute\-1.amazonaws.com 13:50:48 up 16:45, 1 user, load average: 0.30, 0.22, 0.13
+ec2\-75\-101\-240\-230.compute\-1.amazonaws.com 13:50:48 up 1 day, 22:59, 1 user, load average: 0.24, 0.17, 0.11
+ec2\-184\-73\-60\-141.compute\-1.amazonaws.com 13:50:48 up 1 day, 23:30, 1 user, load average: 0.32, 0.17, 0.15
+.ft P
+.fi
+.sp
+To run the chef\-client on all nodes, enter:
+.sp
+.nf
+.ft C
+$ knife ssh \(aqname:*\(aq \(aqsudo chef\-client\(aq
+.ft P
+.fi
+.sp
+To force a chef\-client run on all of the web servers running Ubuntu on the Amazon EC2 platform, enter:
+.sp
+.nf
+.ft C
+$ knife ssh "role:web" "sudo chef\-client" \-x ubuntu \-a ec2.public_hostname
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+ec2\-67\-202\-63\-102.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:37 +0000] INFO: Starting Chef Run (Version 0.9.10)
+ec2\-174\-129\-127\-206.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:37 +0000] INFO: Starting Chef Run (Version 0.9.10)
+ec2\-184\-73\-9\-250.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:38 +0000] INFO: Starting Chef Run (Version 0.9.10)
+ec2\-75\-101\-240\-230.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:38 +0000] INFO: Starting Chef Run (Version 0.9.10)
+ec2\-184\-73\-60\-141.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:38 +0000] INFO: Starting Chef Run (Version 0.9.10)
+ec2\-174\-129\-127\-206.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:39 +0000] INFO: Chef Run complete in 1.419243 seconds
+ec2\-174\-129\-127\-206.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:39 +0000] INFO: cleaning the checksum cache
+ec2\-174\-129\-127\-206.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:39 +0000] INFO: Running report handlers
+ec2\-174\-129\-127\-206.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:39 +0000] INFO: Report handlers complete
+ec2\-67\-202\-63\-102.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:39 +0000] INFO: Chef Run complete in 1.578265 seconds
+ec2\-67\-202\-63\-102.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:39 +0000] INFO: cleaning the checksum cache
+ec2\-67\-202\-63\-102.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:39 +0000] INFO: Running report handlers
+ec2\-67\-202\-63\-102.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:39 +0000] INFO: Report handlers complete
+ec2\-184\-73\-9\-250.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Chef Run complete in 1.638884 seconds
+ec2\-184\-73\-9\-250.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: cleaning the checksum cache
+ec2\-184\-73\-9\-250.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Running report handlers
+ec2\-184\-73\-9\-250.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Report handlers complete
+ec2\-75\-101\-240\-230.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Chef Run complete in 1.540257 seconds
+ec2\-75\-101\-240\-230.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: cleaning the checksum cache
+ec2\-75\-101\-240\-230.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Running report handlers
+ec2\-75\-101\-240\-230.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Report handlers complete
+ec2\-184\-73\-60\-141.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Chef Run complete in 1.502489 seconds
+ec2\-184\-73\-60\-141.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: cleaning the checksum cache
+ec2\-184\-73\-60\-141.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Running report handlers
+ec2\-184\-73\-60\-141.compute\-1.amazonaws.com [Fri, 22 Oct 2010 14:18:40 +0000] INFO: Report handlers complete
+.ft P
+.fi
+.sp
+To query for all nodes that have the "webserver" role and then use SSH to run the command "sudo chef\-client", enter:
+.sp
+.nf
+.ft C
+$ knife ssh "role:webserver" "sudo chef\-client"
+.ft P
+.fi
+.sp
+To upgrade all nodes, enter:
+.sp
+.nf
+.ft C
+$ knife ssh name:* "sudo aptitude upgrade \-y"
+.ft P
+.fi
+.sp
+To specify the shell type used on the nodes returned by a search query:
+.sp
+.nf
+.ft C
+$ knife ssh roles:opscode\-omnitruck macterm
+.ft P
+.fi
+.sp
+where \fBscreen\fP is one of the following values: \fBcssh\fP, \fBinteractive\fP, \fBmacterm\fP, \fBscreen\fP, or \fBtmux\fP. If the node does not have the shell type installed, Knife will return an error similar to the following:
+.sp
+.nf
+.ft C
+you need the rb\-appscript gem to use knife ssh macterm.
+\(ga(sudo) gem install rb\-appscript\(ga to install
+ERROR: LoadError: cannot load such file \-\- appscript
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-status.1 b/distro/common/man/man1/knife-status.1
index e658e6179a..b61f877b71 100644
--- a/distro/common/man/man1/knife-status.1
+++ b/distro/common/man/man1/knife-status.1
@@ -1,29 +1,209 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-STATUS" "1" "Chef 11.8" "" "knife status"
+.SH NAME
+knife-status \- The man page for the knife status subcommand.
.
-.TH "KNIFE\-STATUS" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.nr rst2man-indent-level 0
.
-.SH "NAME"
-\fBknife\-status\fR \- Display status information for the nodes in your infrastructure
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBstatus\fR \fI(options)\fR
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
.
+.sp
+The \fBknife status\fP subcommand is used to display a brief summary of the nodes on a server, including the time of the most recent successful chef\-client run.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
.TP
-\fB\-r\fR, \fB\-\-run\-list RUN_LIST\fR
-Show the run list
-.
-.SH "DESCRIPTION"
-The \fIstatus\fR sub\-command searches the Chef Server for all nodes and displays information about the last time the node checked into the server and executed a \fBnode\.save\fR\. The fields displayed are the relative checkin time, the node name, it\'s operating system platform and version, the fully\-qualified domain name and the default IP address\. If the \fB\-r\fR option is given, the node\'s run list will also be displayed\. Note that depending on the configuration of the nodes, the FQDN and IP displayed may not be publicly reachable\.
-.
-.SH "SEE ALSO"
-\fBknife\-search\fR(1)
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife status (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fBQUERY\fP
+The search query used to identify a a list of items on a server. This option uses the same syntax as the \fBsearch\fP sub\-command.
+.TP
+.B \fB\-H\fP, \fB\-\-hide\-healthy\fP
+Indicates that nodes on which a chef\-client run has occurred within the previous hour will be hidden.
+.TP
+.B \fB\-r RUN_LIST\fP, \fB\-\-run\-list RUN_LIST\fP
+A comma\-separated list of roles and/or recipes to be applied.
+.TP
+.B \fB\-s\fP, \fB\-\-sort\-reverse\fP
+Indicates that the list will be sorted by last run time, descending.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To include run lists in the status, enter:
+.sp
+.nf
+.ft C
+$ knife status \-\-run\-list
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+20 hours ago, dev\-vm.chisamore.com, ubuntu 10.04, dev\-vm.chisamore.com, 10.66.44.126, role[lb].
+3 hours ago, i\-225f954f, ubuntu 10.04, ec2\-67\-202\-63\-102.compute\-1.amazonaws.com, 67.202.63.102, role[web].
+3 hours ago, i\-a45298c9, ubuntu 10.04, ec2\-174\-129\-127\-206.compute\-1.amazonaws.com, 174.129.127.206, role[web].
+3 hours ago, i\-5272a43f, ubuntu 10.04, ec2\-184\-73\-9\-250.compute\-1.amazonaws.com, 184.73.9.250, role[web].
+3 hours ago, i\-226ca64f, ubuntu 10.04, ec2\-75\-101\-240\-230.compute\-1.amazonaws.com, 75.101.240.230, role[web].
+3 hours ago, i\-f65c969b, ubuntu 10.04, ec2\-184\-73\-60\-141.compute\-1.amazonaws.com, 184.73.60.141, role[web].
+.ft P
+.fi
+.sp
+To show only the status nodes on which the chef\-client ran within the past hour, enter:
+.sp
+.nf
+.ft C
+$ knife status \-\-hide\-healthy
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+1 hour ago, i\-256f884f, ubuntu 12.04, ec2\-67\-202\-63\-102.compute\-1.amazonaws.com, 67.202.63.102, role[web].
+1 hour ago, i\-a47823c9, ubuntu 10.04, ec2\-174\-129\-127\-206.compute\-1.amazonaws.com, 184.129.143.111, role[lb].
+.ft P
+.fi
+.sp
+To show the status of a subset of nodes that are returned by a specific query, enter:
+.sp
+.nf
+.ft C
+$ knife status "role:web" \-\-run\-list
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+3 hours ago, i\-225f954f, ubuntu 10.04, ec2\-67\-202\-63\-102.compute\-1.amazonaws.com, 67.202.63.102, role[web].
+3 hours ago, i\-a45298c9, ubuntu 10.04, ec2\-174\-129\-127\-206.compute\-1.amazonaws.com, 174.129.127.206, role[web].
+3 hours ago, i\-5272a43f, ubuntu 10.04, ec2\-184\-73\-9\-250.compute\-1.amazonaws.com, 184.73.9.250, role[web].
+3 hours ago, i\-226ca64f, ubuntu 10.04, ec2\-75\-101\-240\-230.compute\-1.amazonaws.com, 75.101.240.230, role[web].
+3 hours ago, i\-f65c969b, ubuntu 10.04, ec2\-184\-73\-60\-141.compute\-1.amazonaws.com, 184.73.60.141, role[web].
+.ft P
+.fi
+.sp
+To view the status of all nodes in the organization, enter:
+.sp
+.nf
+.ft C
+$ knife status
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+20 hours ago, dev\-vm.chisamore.com, ubuntu 10.04, dev\-vm.chisamore.com, 10.66.44.126
+3 hours ago, i\-225f954f, ubuntu 10.04, ec2\-67\-202\-63\-102.compute\-1.amazonaws.com, 67.202.63.102
+3 hours ago, i\-a45298c9, ubuntu 10.04, ec2\-174\-129\-127\-206.compute\-1.amazonaws.com, 174.129.127.206
+3 hours ago, i\-5272a43f, ubuntu 10.04, ec2\-184\-73\-9\-250.compute\-1.amazonaws.com, 184.73.9.250
+3 hours ago, i\-226ca64f, ubuntu 10.04, ec2\-75\-101\-240\-230.compute\-1.amazonaws.com, 75.101.240.230
+3 hours ago, i\-f65c969b, ubuntu 10.04, ec2\-184\-73\-60\-141.compute\-1.amazonaws.com, 184.73.60.141
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-tag.1 b/distro/common/man/man1/knife-tag.1
index eccccaeb26..135969b393 100644
--- a/distro/common/man/man1/knife-tag.1
+++ b/distro/common/man/man1/knife-tag.1
@@ -1,43 +1,182 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-TAG" "1" "Chef 11.8" "" "knife tag"
+.SH NAME
+knife-tag \- The man page for the knife tag subcommand.
.
-.TH "KNIFE\-TAG" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.nr rst2man-indent-level 0
.
-.SH "NAME"
-\fBknife\-tag\fR \- Apply tags to nodes on a Chef Server
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
.
-.SH "SYNOPSIS"
-\fBknife\fR \fBtag\fR \fIsubcommand\fR \fI(options)\fR
+.sp
+A tag is a custom description that is applied to a node. A tag, once applied, can be helpful when managing nodes using Knife or when building recipes by providing alternate methods of grouping similar types of information.
+.sp
+The \fBknife tag\fP subcommand is used to apply tags to nodes on a server.
+.sp
+This subcommand has the following syntax:
+.sp
+.nf
+.ft C
+$ knife tag [ARGUMENT]
+.ft P
+.fi
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH CREATE
+.sp
+The \fBcreate\fP argument is used to add one or more tags to a node.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife tag create NODE_NAME [TAG...]
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To create tags named "seattle", "portland", and "vancouver", enter:
+.sp
+.nf
+.ft C
+$ knife tag create node seattle portland vancouver
+.ft P
+.fi
+.SH DELETE
+.sp
+The \fBdelete\fP argument is used to delete one or more tags from a node.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife tag delete NODE_NAME [TAG...]
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To delete tags named "denver" and "phoenix", enter:
+.sp
+.nf
+.ft C
+$ knife tag delete node denver phoenix
+.ft P
+.fi
+.sp
+Type \fBY\fP to confirm a deletion.
+.SH LIST
+.sp
+The \fBlist\fP argument is used to list all of the tags that have been applied to a node.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife tag list [NODE_NAME...]
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
.
-.SH "TAG SUBCOMMANDS"
-The following \fBtag\fR subcommands are available:
-.
-.SH "CREATE"
-\fBknife tag create\fR \fInode\fR \fItag\fR [\fI\.\.\.\fR]
-.
-.P
-Adds one or more tags to \fInode\fR
-.
-.SH "DELETE"
-\fBknife tag delete\fR \fInode\fR \fItag\fR [\fI\.\.\.\fR]
-.
-.P
-Removes one or more tags from \fInode\fR
-.
-.SH "LIST"
-\fBknife tag list\fR \fInode\fR
-.
-.P
-Lists the tags applied to \fInode\fR
-.
-.SH "SEE ALSO"
-\fBknife\-node(1)\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Daniel DeLeo \fIdan@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-upload.1 b/distro/common/man/man1/knife-upload.1
new file mode 100644
index 0000000000..91ebb198d5
--- /dev/null
+++ b/distro/common/man/man1/knife-upload.1
@@ -0,0 +1,241 @@
+.TH "KNIFE-UPLOAD" "1" "Chef 11.8" "" "knife upload"
+.SH NAME
+knife-upload \- The man page for the knife upload subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife upload\fP subcommand is used to upload roles, cookbooks, environments, and data bags to the server from the current working directory in the chef\-repo. This subcommand is often used in conjunction with \fBknife diff\fP, which can be used to see exactly what changes will be uploaded, and then \fBknife download\fP, which does the opposite of \fBknife upload\fP.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife upload [PATTERN...] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-\-[no\-]force\fP
+Use \fB\-\-force\fP to upload roles, cookbooks, etc. even if the file in the directory is identical (by default, no \fBPOST\fP or \fBPUT\fP is performed unless an actual change would be made). Default: \fB\-\-no\-force\fP.
+.TP
+.B \fB\-n\fP, \fB\-\-dry\-run\fP
+Indicates that no action is taken and that results are only printed out. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-[no\-]diff\fP
+Indicates that only new and modified files will be uploaded. Set to \fBfalse\fP to upload all files. Default: \fBtrue\fP.
+.TP
+.B \fB\-\-[no\-]freeze\fP
+Indicates that a cookbook cannot be modified; any changes to this cookbook must be included as a new version. Only the \fB\-\-force\fP option can override this setting. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-[no\-]purge\fP
+Use \fB\-\-purge\fP to delete roles, cookbooks, etc. from the server if their corresponding files do not exist in the chef\-repo. By default, such objects are left alone and NOT purged. Default: \fB\-\-no\-purge\fP.
+.TP
+.B \fB\-\-[no\-]recurse\fP
+Use \fB\-\-no\-recurse\fP to disable uploading a directory recursively. Default: \fB\-\-recurse\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default: \fBeverything\fP / \fBhosted_everything\fP.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To upload the entire chef\-repo to the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife upload
+.ft P
+.fi
+.sp
+or from anywhere in the chef\-repo, enter:
+.sp
+.nf
+.ft C
+$ knife upload /
+.ft P
+.fi
+.sp
+To upload the \fBcookbooks/\fP directory to the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife upload cookbooks
+.ft P
+.fi
+.sp
+or from anywhere in the chef\-repo, enter:
+.sp
+.nf
+.ft C
+$ knife upload /cookbooks
+.ft P
+.fi
+.sp
+To upload the \fBenvironments/\fP directory to the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife upload environments
+.ft P
+.fi
+.sp
+or from anywhere in the chef\-repo, enter:
+.sp
+.nf
+.ft C
+$ knife upload /environments
+.ft P
+.fi
+.sp
+To upload an environment named "production" to the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife upload environments/production.json
+.ft P
+.fi
+.sp
+or from the \fBenvironments/\fP directory, enter:
+.sp
+.nf
+.ft C
+$ knife upload production.json
+.ft P
+.fi
+.sp
+To upload the \fBroles/\fP directory to the server, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife upload roles
+.ft P
+.fi
+.sp
+or from anywhere in the chef\-repo, enter:
+.sp
+.nf
+.ft C
+$ knife upload /roles
+.ft P
+.fi
+.sp
+To upload all cookbooks that start with "apache" and belong to the "webserver" role, browse to the top level of the chef\-repo and enter:
+.sp
+.nf
+.ft C
+$ knife upload cookbooks/apache\e* roles/webserver.json
+.ft P
+.fi
+.sp
+Use the output of \fBknife deps\fP to pass a command to \fBknife upload\fP. For example:
+.sp
+.nf
+.ft C
+$ knife upload \(gaknife deps nodes/*.json\(ga
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-user.1 b/distro/common/man/man1/knife-user.1
new file mode 100644
index 0000000000..7d6fada5ce
--- /dev/null
+++ b/distro/common/man/man1/knife-user.1
@@ -0,0 +1,319 @@
+.TH "KNIFE-USER" "1" "Chef 11.8" "" "knife user"
+.SH NAME
+knife-user \- The man page for the knife user subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife user\fP subcommand is used to manage the list of users and their associated RSA public key\-pairs.
+.IP Note
+This subcommand ONLY works when run against the open source server and will not run against Enterprise Chef (including hosted Enterprise Chef), or Private Chef.
+.RE
+.sp
+This subcommand has the following syntax:
+.sp
+.nf
+.ft C
+$ knife user [ARGUMENT] (options)
+.ft P
+.fi
+.SH COMMON OPTIONS
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.SH CREATE
+.sp
+The \fBcreate\fP argument is used to create a user. This process will generate an RSA key pair for the named user. The public key will be stored on the server and the private key will be displayed on \fBSTDOUT\fP or written to a named file.
+.INDENT 0.0
+.IP \(bu 2
+For the user, the private key should be copied to the system as /etc/chef/client.pem.
+.IP \(bu 2
+For Knife, the private key is typically copied to ~/.chef/client_name.pem and referenced in the knife.rb configuration file.
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife user create USER_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-admin\fP
+Indicates that a client will be created as an admin client. This is required when users of the open source server need to access the Chef Server API as an administrator. This option only works when used with the open source server and will have no effect when used with Hosted Chef or Private Chef.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-user\-key FILE_NAME\fP
+All users are assigned a public key. Use to write the public key to a file.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To create a new user named "Radio Birdman" with a private key saved to "/keys/user_name", enter:
+.sp
+.nf
+.ft C
+$ knife user create "Radio Birdman" \-f /keys/user_name
+.ft P
+.fi
+.SH DELETE
+.sp
+The \fBdelete\fP argument is used to delete a registered user.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife user delete USER_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+To delete a user named "Steve Danno", enter:
+.sp
+.nf
+.ft C
+$ knife user delete "Steve Danno"
+.ft P
+.fi
+.SH EDIT
+.sp
+The \fBedit\fP argument is used to edit the details of a user. When this argument is run, Knife will open $EDITOR. When finished, Knife will update the server with those changes.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife user edit USER_NAME
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This command does not have any specific options.
+.sp
+\fBExamples\fP
+.sp
+None.
+.SH LIST
+.sp
+The \fBlist\fP argument is used to view a list of registered users.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife user list (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-w\fP, \fB\-\-with\-uri\fP
+Indicates that the corresponding URIs will be shown.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+None.
+.SH REREGISTER
+.sp
+The \fBreregister\fP argument is used to regenerate an RSA key pair for a user. The public key will be stored on the server and the private key will be displayed on \fBSTDOUT\fP or written to a named file.
+.IP Note
+Running this argument will invalidate the previous RSA key pair, making it unusable during authentication to the server.
+.RE
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife user reregister USER_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To regenerate the RSA key pair for a user named "Robert Younger", enter:
+.sp
+.nf
+.ft C
+$ knife user reregister "Robert Younger"
+.ft P
+.fi
+.SH SHOW
+.sp
+The \fBshow\fP argument is used to show the details of a user.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife user show USER_NAME (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a ATTR\fP, \fB\-\-attribute ATTR\fP
+The attribute (or attributes) to show.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To view a user named "Dennis Teck", enter:
+.sp
+.nf
+.ft C
+$ knife user show "Dennis Teck"
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+chef_type: user
+json_class: Chef::User
+name: Dennis Teck
+public_key:
+.ft P
+.fi
+.sp
+To view information in JSON format, use the \fB\-F\fP common option as part of the command like this:
+.sp
+.nf
+.ft C
+$ knife user show "Dennis Teck" \-F json
+.ft P
+.fi
+.sp
+Other formats available include \fBtext\fP, \fByaml\fP, and \fBpp\fP.
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-xargs.1 b/distro/common/man/man1/knife-xargs.1
new file mode 100644
index 0000000000..68710a19df
--- /dev/null
+++ b/distro/common/man/man1/knife-xargs.1
@@ -0,0 +1,168 @@
+.TH "KNIFE-XARGS" "1" "Chef 11.8" "" "knife xargs"
+.SH NAME
+knife-xargs \- The man page for the knife xargs subcommand.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.\" Man page generated from reStructuredText.
+.
+.sp
+The \fBknife xargs\fP subcommand is used to build and execute command lines against objects on a server using standard input.
+.sp
+\fBCommon Options\fP
+.sp
+The following options can be run with all Knife sub\-commands and plug\-ins:
+.INDENT 0.0
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-\-color\fP
+Indicates that colored output will be used.
+.TP
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.TP
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
+The name of the environment. When this option is added to a command, the command will run only against the named environment.
+.TP
+.B \fB\-f FILE_NAME\fP, \fB\-\-file FILE_NAME\fP
+Indicates that the private key will be saved to a specified file name.
+.TP
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
+The private key that Knife will use to sign requests made by the API client to the server.
+.TP
+.B \fB\-\-no\-color\fP
+Indicates that color will not be used in the output.
+.TP
+.B \fB\-p PASSWORD\fP, \fB\-\-password PASSWORD\fP
+The user password.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user name used by Knife to sign requests made by the API client to the server. Authentication will fail if the user name does not match the private key.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-V\fP, \fB\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-y\fP, \fB\-\-yes\fP
+Indicates that the response to all confirmation prompts will be "Yes" (and that Knife will not ask for confirmation).
+.UNINDENT
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife xargs [PATTERN...] (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-repo\-path PATH\fP
+The path to the chef\-repo. This setting will override the default path to the chef\-repo. Default: same as specified by \fBchef_repo_path\fP in config.rb.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-\-[no\-]diff\fP
+Use to show a diff when a file changes. Default: \fB\-\-diff\fP.
+.TP
+.B \fB\-\-dry\-run\fP
+Use to prevent changes from being uploaded to the server. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-[no\-]force\fP
+Use to force the upload of files even if they haven\(aqt been changed. Default: \fB\-\-no\-force\fP.
+.TP
+.B \fB\-\-local\fP
+Indicates that a command line will be built or executed against a local file. Set to \fBfalse\fP to build or execute against a remote file. Default: \fBfalse\fP.
+.TP
+.B \fB\-n MAX_ARGS\fP, \fB\-\-max\-args MAX_ARGS\fP
+The maximum number of arguments per command line. Default: \fBnil\fP.
+.TP
+.B \fB\-s LENGTH\fP, \fB\-\-max\-chars LENGTH\fP
+The maximum size (in characters) for a command line. Default: \fBnil\fP.
+.TP
+.B \fB\-0\fP
+Indicates that a \fBNULL\fP character (\fB\e0\fP) will be used as a separator, instead of white space. Default: \fBfalse\fP.
+.TP
+.B \fB\-p [PATTERN...]\fP, \fB\-\-pattern [PATTERN...]\fP
+One (or more) patterns for a command line. If this option is not specified, a list of patterns may be expected on standard input. Default: \fBnil\fP.
+.TP
+.B \fB\-I REPLACE_STRING\fP, \fB\-\-replace REPLACE_STRING\fP
+Use to define a string that will be used to replace all occurrences of a file name. Default: \fBnil\fP.
+.TP
+.B \fB\-J REPLACE_STRING\fP, \fB\-\-replace\-first REPLACE_STRING\fP
+Use to define a string that will be used to replace the first occurrence of a file name. Default: \fBnil\fP.
+.TP
+.B \fB\-\-repo\-mode MODE\fP
+The layout of the local chef\-repo. Possible values: \fBstatic\fP, \fBeverything\fP, or \fBhosted_everything\fP. Use \fBstatic\fP for just roles, environments, cookbooks, and data bags. By default, \fBeverything\fP and \fBhosted_everything\fP are dynamically selected depending on the server type. Default value: \fBdefault\fP.
+.TP
+.B \fB\-t\fP
+Indicates that the print command will be run on the command line. Default: \fBnil\fP.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To use the output of \fBknife deps\fP to pass a command to \fBknife xargs\fP. For example:
+.sp
+.nf
+.ft C
+$ knife deps nodes/*.json | xargs knife upload
+.ft P
+.fi
+.SH AUTHOR
+Opscode
+.SH COPYRIGHT
+This work is licensed under a Creative Commons Attribution 3.0 Unported License
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife.1 b/distro/common/man/man1/knife.1
index 5a84ef966c..a8ce1c10fd 100644
--- a/distro/common/man/man1/knife.1
+++ b/distro/common/man/man1/knife.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "KNIFE" "1" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "KNIFE" "1" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBknife\fR \- Chef Server API client utility
diff --git a/distro/common/man/man8/chef-client.8 b/distro/common/man/man8/chef-client.8
index 1a36e88260..b0e8eac533 100644
--- a/distro/common/man/man8/chef-client.8
+++ b/distro/common/man/man8/chef-client.8
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "CHEF\-CLIENT" "8" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "CHEF\-CLIENT" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBchef\-client\fR \- Runs a client node connecting to a chef\-server\.
diff --git a/distro/common/man/man8/chef-expander.8 b/distro/common/man/man8/chef-expander.8
index 10bc7a635d..6ab31d46c4 100644
--- a/distro/common/man/man8/chef-expander.8
+++ b/distro/common/man/man8/chef-expander.8
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "CHEF\-EXPANDER" "8" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "CHEF\-EXPANDER" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBchef\-expander\fR \- fetches messages from RabbitMQ, processes, and loads into chef\-solr
diff --git a/distro/common/man/man8/chef-expanderctl.8 b/distro/common/man/man8/chef-expanderctl.8
index 50d2938e08..f2e88a426f 100644
--- a/distro/common/man/man8/chef-expanderctl.8
+++ b/distro/common/man/man8/chef-expanderctl.8
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "CHEF\-EXPANDERCTL" "8" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "CHEF\-EXPANDERCTL" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBchef\-expanderctl\fR \- management program for chef\-expander
diff --git a/distro/common/man/man8/chef-server-webui.8 b/distro/common/man/man8/chef-server-webui.8
index d6a29454dc..3f2157216c 100644
--- a/distro/common/man/man8/chef-server-webui.8
+++ b/distro/common/man/man8/chef-server-webui.8
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "CHEF\-SERVER\-WEBUI" "8" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "CHEF\-SERVER\-WEBUI" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBchef\-server\-webui\fR \- Start the Chef Server merb application slice providing Web User Interface (Management Console)\.
diff --git a/distro/common/man/man8/chef-server.8 b/distro/common/man/man8/chef-server.8
index d83e9797be..ce928d6f63 100644
--- a/distro/common/man/man8/chef-server.8
+++ b/distro/common/man/man8/chef-server.8
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "CHEF\-SERVER" "8" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "CHEF\-SERVER" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBchef\-server\fR \- Start the Chef Server merb application slice\.
diff --git a/distro/common/man/man8/chef-solo.8 b/distro/common/man/man8/chef-solo.8
index b239963372..30c5956825 100644
--- a/distro/common/man/man8/chef-solo.8
+++ b/distro/common/man/man8/chef-solo.8
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "CHEF\-SOLO" "8" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "CHEF\-SOLO" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBchef\-solo\fR \- Runs chef in solo mode against a specified cookbook location\.
diff --git a/distro/common/man/man8/chef-solr.8 b/distro/common/man/man8/chef-solr.8
index ee7208c9de..28c8e92cf3 100644
--- a/distro/common/man/man8/chef-solr.8
+++ b/distro/common/man/man8/chef-solr.8
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "CHEF\-SOLR" "8" "August 2013" "Chef 11.6.0.hotfix.1" "Chef Manual"
+.TH "CHEF\-SOLR" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
.
.SH "NAME"
\fBchef\-solr\fR \- Runs as Chef\'s search server
diff --git a/distro/common/markdown/man1/knife-bootstrap.mkd b/distro/common/markdown/man1/knife-bootstrap.mkd
index c466fc7f7f..5c5e456023 100644
--- a/distro/common/markdown/man1/knife-bootstrap.mkd
+++ b/distro/common/markdown/man1/knife-bootstrap.mkd
@@ -32,7 +32,7 @@ __knife__ __bootstrap__ _(options)_
* `--[no-]host-key-verify`:
Enable host key verification, which is the default behavior.
* `--hint HINT_NAME[=HINT_FILE]`:
- Provide the name of a hint (with option JSON file) to set for use by
+ Provide the name of a hint (with option JSON file) to set for use by
Ohai plugins.
## DESCRIPTION
diff --git a/distro/common/markdown/man1/knife-configure.mkd b/distro/common/markdown/man1/knife-configure.mkd
index cc7dd1d96e..507d30db4e 100644
--- a/distro/common/markdown/man1/knife-configure.mkd
+++ b/distro/common/markdown/man1/knife-configure.mkd
@@ -35,17 +35,17 @@ the specified _directory_.
field blank to accept the default value. On most systems, the
default values are acceptable.
- user@host$ knife configure -i
- Please enter the chef server URL: [http://localhost:4000]
- Please enter a clientname for the new client: [username]
- Please enter the existing admin clientname: [chef-webui]
- Please enter the location of the existing admin client's private key: [/etc/chef/webui.pem]
- Please enter the validation clientname: [chef-validator]
- Please enter the location of the validation key: [/etc/chef/validation.pem]
- Please enter the path to a chef repository (or leave blank):
- Creating initial API user...
- Created (or updated) client[username]
- Configuration file written to /home/username/.chef/knife.rb
+ user@host$ knife configure -i
+ Please enter the chef server URL: [http://localhost:4000]
+ Please enter a clientname for the new client: [username]
+ Please enter the existing admin clientname: [chef-webui]
+ Please enter the location of the existing admin client's private key: [/etc/chef/webui.pem]
+ Please enter the validation clientname: [chef-validator]
+ Please enter the location of the validation key: [/etc/chef/validation.pem]
+ Please enter the path to a chef repository (or leave blank):
+ Creating initial API user...
+ Created (or updated) client[username]
+ Configuration file written to /home/username/.chef/knife.rb
This creates a new administrator client named _username_, writes
a configuration file to _/home/username/.chef/knife.rb_, and the
diff --git a/distro/common/markdown/man1/knife-cookbook.mkd b/distro/common/markdown/man1/knife-cookbook.mkd
index 4f714c52f6..deaf00447a 100644
--- a/distro/common/markdown/man1/knife-cookbook.mkd
+++ b/distro/common/markdown/man1/knife-cookbook.mkd
@@ -117,11 +117,11 @@ __knife cookbook create cookbook__ _(options)_
the directory where the cookbook will be created
* `-r`, `--readme-format format`:
format of the readme file md, mkd, txt, rdoc
- * `-c`, `--copyright copyright`:
+ * `-C`, `--copyright copyright`:
name of copyright holder
* `-i`, `--license license`:
license for cookbook, apachev2 or none
- * `-e`, `--email email`:
+ * `-m`, `--email email`:
email address of cookbook maintainer
this is a helper command that creates a new cookbook directory in the
@@ -143,7 +143,7 @@ supported readme formats are 'md' (default), 'mkd', 'txt', 'rdoc'. the
readme file will be written with the specified extension and a set of
helpful starting headers.
-specify `-c` or `--copyright` with the name of the copyright holder as
+specify `-C` or `--copyright` with the name of the copyright holder as
your name or your company/organization name in a quoted string. if this
value is not specified an all-caps string `your_company_name` is used
which can be easily changed with find/replace.
@@ -156,7 +156,7 @@ the cookbook and follow any restrictions they describe. when using
are pre-filled. the `none` license will be treated as
non-redistributable.
-specify `-e` or `--email` with the email address of the cookbook's
+specify `-m` or `--email` with the email address of the cookbook's
maintainer. if this value is not specified, an all-caps string
`your_email` is used which can easily be changed with find/replace.
diff --git a/distro/common/markdown/man8/chef-expander.mkd b/distro/common/markdown/man8/chef-expander.mkd
index d72ee1df9f..9190a9aebb 100644
--- a/distro/common/markdown/man8/chef-expander.mkd
+++ b/distro/common/markdown/man8/chef-expander.mkd
@@ -79,4 +79,4 @@ granted to copy, distribute and / or modify this document under the
terms of the Apache 2.0 License.
On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0. \ No newline at end of file
+found in /usr/share/common-licenses/Apache-2.0.
diff --git a/distro/common/markdown/man8/chef-expanderctl.mkd b/distro/common/markdown/man8/chef-expanderctl.mkd
index 00b34e7734..03ce6af8ac 100644
--- a/distro/common/markdown/man8/chef-expanderctl.mkd
+++ b/distro/common/markdown/man8/chef-expanderctl.mkd
@@ -55,4 +55,4 @@ granted to copy, distribute and / or modify this document under the
terms of the Apache 2.0 License.
On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0. \ No newline at end of file
+found in /usr/share/common-licenses/Apache-2.0.
diff --git a/distro/debian/etc/init.d/chef-client b/distro/debian/etc/init.d/chef-client
index c5dfea06fb..b74f6d914b 100755
--- a/distro/debian/etc/init.d/chef-client
+++ b/distro/debian/etc/init.d/chef-client
@@ -20,7 +20,7 @@ NAME=chef-client
DESC=chef-client
PIDFILE=/var/run/chef/client.pid
-test -x $DAEMON || exit 0
+test -x $DAEMON || exit 1
. /lib/lsb/init-functions
diff --git a/distro/debian/etc/init.d/chef-expander b/distro/debian/etc/init.d/chef-expander
index 7fea0e9118..fdf6e40678 100755
--- a/distro/debian/etc/init.d/chef-expander
+++ b/distro/debian/etc/init.d/chef-expander
@@ -20,7 +20,7 @@ NAME=chef-expander
DESC=chef-expander
PIDFILE=/var/run/chef/expander.pid
-test -x $DAEMON || exit 0
+test -x $DAEMON || exit 1
. /lib/lsb/init-functions
diff --git a/distro/debian/etc/init.d/chef-server b/distro/debian/etc/init.d/chef-server
index f7c1ede583..0b94fc7fc7 100755
--- a/distro/debian/etc/init.d/chef-server
+++ b/distro/debian/etc/init.d/chef-server
@@ -21,7 +21,7 @@ MAINPID=/var/run/chef/server.main.pid
NAME=chef-server
DESC=chef-server
-test -x $DAEMON || exit 0
+test -x $DAEMON || exit 1
. /lib/lsb/init-functions
diff --git a/distro/debian/etc/init.d/chef-server-webui b/distro/debian/etc/init.d/chef-server-webui
index c82171cedb..e2db8a49b7 100755
--- a/distro/debian/etc/init.d/chef-server-webui
+++ b/distro/debian/etc/init.d/chef-server-webui
@@ -21,7 +21,7 @@ MAINPID=/var/run/chef/server-webui.main.pid
NAME=chef-server-webui
DESC=chef-server-webui
-test -x $DAEMON || exit 0
+test -x $DAEMON || exit 1
. /lib/lsb/init-functions
diff --git a/distro/debian/etc/init.d/chef-solr b/distro/debian/etc/init.d/chef-solr
index 1e4c0b8b51..2cc93b5fd2 100755
--- a/distro/debian/etc/init.d/chef-solr
+++ b/distro/debian/etc/init.d/chef-solr
@@ -21,7 +21,7 @@ NAME=chef-solr
DESC=chef-solr
PIDFILE=/var/run/chef/solr.pid
-test -x $DAEMON || exit 0
+test -x $DAEMON || exit 1
. /lib/lsb/init-functions
diff --git a/distro/debian/etc/init/chef-client.conf b/distro/debian/etc/init/chef-client.conf
index 1f8c6d0d9b..5f246b140c 100644
--- a/distro/debian/etc/init/chef-client.conf
+++ b/distro/debian/etc/init/chef-client.conf
@@ -11,7 +11,7 @@ respawn
respawn limit 5 30
pre-start script
- test -x /usr/bin/chef-client || { stop; exit 0; }
+ test -x /usr/bin/chef-client || { stop; exit 1; }
end script
exec /usr/bin/chef-client -i 1800 -L /var/log/chef/client.log
diff --git a/distro/debian/etc/init/chef-expander.conf b/distro/debian/etc/init/chef-expander.conf
index 21ff246307..2c08f6cecc 100644
--- a/distro/debian/etc/init/chef-expander.conf
+++ b/distro/debian/etc/init/chef-expander.conf
@@ -11,7 +11,7 @@ respawn
respawn limit 5 30
pre-start script
- test -x /usr/bin/chef-expander || { stop; exit 0; }
+ test -x /usr/bin/chef-expander || { stop; exit 1; }
end script
exec /usr/bin/chef-expander -c /etc/chef/solr.rb -L /var/log/chef/expander.log -n 1 -i 1
diff --git a/distro/debian/etc/init/chef-server-webui.conf b/distro/debian/etc/init/chef-server-webui.conf
index 8b443c51f5..8ba25877e4 100644
--- a/distro/debian/etc/init/chef-server-webui.conf
+++ b/distro/debian/etc/init/chef-server-webui.conf
@@ -11,7 +11,7 @@ respawn
respawn limit 5 30
pre-start script
- test -x /usr/bin/chef-server-webui || { stop; exit 0; }
+ test -x /usr/bin/chef-server-webui || { stop; exit 1; }
end script
exec /usr/bin/chef-server-webui -e production -p 4040 -L /var/log/chef/server-webui.log
diff --git a/distro/debian/etc/init/chef-server.conf b/distro/debian/etc/init/chef-server.conf
index 1eebd8f0cb..a372e50ea3 100644
--- a/distro/debian/etc/init/chef-server.conf
+++ b/distro/debian/etc/init/chef-server.conf
@@ -11,7 +11,7 @@ respawn
respawn limit 5 30
pre-start script
- test -x /usr/bin/chef-server || { stop; exit 0; }
+ test -x /usr/bin/chef-server || { stop; exit 1; }
end script
exec /usr/bin/chef-server -e production -p 4000 -L /var/log/chef/server.log
diff --git a/distro/debian/etc/init/chef-solr.conf b/distro/debian/etc/init/chef-solr.conf
index 4ca885e28d..edca5e3f80 100644
--- a/distro/debian/etc/init/chef-solr.conf
+++ b/distro/debian/etc/init/chef-solr.conf
@@ -11,7 +11,7 @@ respawn
respawn limit 5 30
pre-start script
- test -x /usr/bin/chef-solr || { stop; exit 0; }
+ test -x /usr/bin/chef-solr || { stop; exit 1; }
end script
exec /usr/bin/chef-solr -c /etc/chef/solr.rb -L /var/log/chef/solr.log
diff --git a/distro/redhat/etc/init.d/chef-client b/distro/redhat/etc/init.d/chef-client
index fbeaa395c0..b41150e7a1 100644
--- a/distro/redhat/etc/init.d/chef-client
+++ b/distro/redhat/etc/init.d/chef-client
@@ -61,7 +61,7 @@ reload() {
killproc -p $pidfile chef-client -HUP
retval=$?
echo
- return $retval
+ return $retval
}
run() {
diff --git a/distro/redhat/etc/init.d/chef-server b/distro/redhat/etc/init.d/chef-server
index 44247178b5..f956dd4e45 100644
--- a/distro/redhat/etc/init.d/chef-server
+++ b/distro/redhat/etc/init.d/chef-server
@@ -11,7 +11,7 @@
# Required-Stop: $local_fs $network $remote_fs chef-solr chef-expander
# Should-Start: $named $time
# Should-Stop: $named $time
-# Short-Description: Startup script for chef-server
+# Short-Description: Startup script for chef-server
# Description: Server component of the Chef systems integration framework.
### END INIT INFO
@@ -50,7 +50,7 @@ start() {
stop() {
echo -n $"Stopping $prog: "
- killproc -p $pidfile $prog
+ killproc -p $pidfile $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
diff --git a/distro/redhat/etc/init.d/chef-server-webui b/distro/redhat/etc/init.d/chef-server-webui
index f26f9c1f9a..65498bf723 100644
--- a/distro/redhat/etc/init.d/chef-server-webui
+++ b/distro/redhat/etc/init.d/chef-server-webui
@@ -11,7 +11,7 @@
# Required-Stop: $local_fs $network $remote_fs chef-server
# Should-Start: $named $time
# Should-Stop: $named $time
-# Short-Description: Startup script for chef-server-webui
+# Short-Description: Startup script for chef-server-webui
# Description: Server WebUI component of the Chef systems integration framework.
### END INIT INFO
@@ -50,7 +50,7 @@ start() {
stop() {
echo -n $"Stopping $prog: "
- killproc -p $pidfile $prog
+ killproc -p $pidfile $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
diff --git a/distro/redhat/etc/init.d/chef-solr b/distro/redhat/etc/init.d/chef-solr
index b75c40f53f..9223173276 100644
--- a/distro/redhat/etc/init.d/chef-solr
+++ b/distro/redhat/etc/init.d/chef-solr
@@ -1,5 +1,5 @@
#!/bin/bash
-#
+#
# chef-solr Startup script for the SOLR search engine
#
# chkconfig: - 94 06
@@ -42,7 +42,7 @@ start() {
stop() {
echo -n $"Stopping $prog: "
- killproc -p $pidfile $prog
+ killproc -p $pidfile $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
diff --git a/lib/chef/api_client.rb b/lib/chef/api_client.rb
index 32e1eee017..66cbd3f30e 100644
--- a/lib/chef/api_client.rb
+++ b/lib/chef/api_client.rb
@@ -36,6 +36,7 @@ class Chef
@public_key = nil
@private_key = nil
@admin = false
+ @validator = false
end
# Gets or sets the client name.
@@ -74,6 +75,19 @@ class Chef
)
end
+ # Gets or sets whether this client is a validator.
+ #
+ # @params [Boolean] whether or not the client is a validator. If
+ # `nil`, retrieves the already-set value.
+ # @return [Boolean] The current value
+ def validator(arg=nil)
+ set_or_return(
+ :validator,
+ arg,
+ :kind_of => [TrueClass, FalseClass]
+ )
+ end
+
# Gets or sets the private key.
#
# @params [Optional String] The string representation of the private key.
@@ -94,6 +108,7 @@ class Chef
result = {
"name" => @name,
"public_key" => @public_key,
+ "validator" => @validator,
"admin" => @admin,
'json_class' => self.class.name,
"chef_type" => "client"
@@ -115,6 +130,7 @@ class Chef
client.private_key(o["private_key"]) if o.key?("private_key")
client.public_key(o["public_key"])
client.admin(o["admin"])
+ client.validator(o["validator"])
client
end
@@ -160,11 +176,11 @@ class Chef
# Save this client via the REST API, returns a hash including the private key
def save
begin
- http_api.put("clients/#{name}", { :name => self.name, :admin => self.admin})
+ http_api.put("clients/#{name}", { :name => self.name, :admin => self.admin, :validator => self.validator})
rescue Net::HTTPServerException => e
# If that fails, go ahead and try and update it
if e.response.code == "404"
- http_api.post("clients", {:name => self.name, :admin => self.admin })
+ http_api.post("clients", {:name => self.name, :admin => self.admin, :validator => self.validator })
else
raise e
end
@@ -172,7 +188,7 @@ class Chef
end
def reregister
- reregistered_self = http_api.put("clients/#{name}", { :name => name, :admin => admin, :private_key => true })
+ reregistered_self = http_api.put("clients/#{name}", { :name => name, :admin => admin, :validator => validator, :private_key => true })
if reregistered_self.respond_to?(:[])
private_key(reregistered_self["private_key"])
else
@@ -192,7 +208,7 @@ class Chef
end
def inspect
- "Chef::ApiClient name:'#{name}' admin:'#{admin.inspect}' " +
+ "Chef::ApiClient name:'#{name}' admin:'#{admin.inspect}' validator:'#{validator}' " +
"public_key:'#{public_key}' private_key:'#{private_key}'"
end
@@ -202,4 +218,3 @@ class Chef
end
end
-
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index 6522ba6e64..c1fc3a78a4 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -66,31 +66,26 @@ class Chef::Application
run_application
end
- # Parse the configuration file
+ # Parse configuration (options and config file)
def configure_chef
parse_options
+ load_config_file
+ end
- begin
- case config[:config_file]
- when /^(http|https):\/\//
- Chef::REST.new("", nil, nil).fetch(config[:config_file]) { |f| apply_config(f.path) }
- else
- ::File::open(config[:config_file]) { |f| apply_config(f.path) }
- end
- rescue Errno::ENOENT => error
+ # Parse the config file
+ def load_config_file
+ config_fetcher = Chef::ConfigFetcher.new(config[:config_file], Chef::Config.config_file_jail)
+ if config[:config_file].nil?
+ Chef::Log.warn("No config file found or specified on command line, using command line options.")
+ elsif config_fetcher.config_missing?
Chef::Log.warn("*****************************************")
Chef::Log.warn("Did not find config file: #{config[:config_file]}, using command line options.")
Chef::Log.warn("*****************************************")
-
- Chef::Config.merge!(config)
- rescue SocketError => error
- Chef::Application.fatal!("Error getting config file #{config[:config_file]}", 2)
- rescue Chef::Exceptions::ConfigurationError => error
- Chef::Application.fatal!("Error processing config file #{config[:config_file]} with error #{error.message}", 2)
- rescue Exception => error
- Chef::Application.fatal!("Unknown error processing config file #{config[:config_file]} with error #{error.message}", 2)
+ else
+ config_content = config_fetcher.read_config
+ apply_config(config_content, config[:config_file])
end
-
+ Chef::Config.merge!(config)
end
# Initialize and configure the logger.
@@ -172,23 +167,59 @@ class Chef::Application
raise Chef::Exceptions::Application, "#{self.to_s}: you must override run_application"
end
+ def self.setup_server_connectivity
+ if Chef::Config.chef_zero.enabled
+ destroy_server_connectivity
+
+ require 'chef_zero/server'
+ require 'chef/chef_fs/chef_fs_data_store'
+ require 'chef/chef_fs/config'
+
+ chef_fs = Chef::ChefFS::Config.new.local_fs
+ chef_fs.write_pretty_json = true
+ server_options = {}
+ server_options[:data_store] = Chef::ChefFS::ChefFSDataStore.new(chef_fs)
+ server_options[:log_level] = Chef::Log.level
+ server_options[:port] = Chef::Config.chef_zero.port
+ Chef::Log.info("Starting chef-zero on port #{Chef::Config.chef_zero.port} with repository at #{server_options[:data_store].chef_fs.fs_description}")
+ @chef_zero_server = ChefZero::Server.new(server_options)
+ @chef_zero_server.start_background
+ Chef::Config.chef_server_url = @chef_zero_server.url
+ end
+ end
+
+ def self.destroy_server_connectivity
+ if @chef_zero_server
+ @chef_zero_server.stop
+ @chef_zero_server = nil
+ end
+ end
+
# Initializes Chef::Client instance and runs it
def run_chef_client
+ Chef::Application.setup_server_connectivity
+
@chef_client = Chef::Client.new(
- @chef_client_json,
+ @chef_client_json,
:override_runlist => config[:override_runlist]
)
@chef_client_json = nil
@chef_client.run
@chef_client = nil
+
+ Chef::Application.destroy_server_connectivity
end
private
- def apply_config(config_file_path)
- Chef::Config.from_file(config_file_path)
- Chef::Config.merge!(config)
+ def apply_config(config_content, config_file_path)
+ Chef::Config.from_string(config_content, config_file_path)
+ rescue Exception => error
+ Chef::Log.fatal("Configuration error #{error.class}: #{error.message}")
+ filtered_trace = error.backtrace.grep(/#{Regexp.escape(config_file_path)}/)
+ filtered_trace.each {|line| Chef::Log.fatal(" " + line )}
+ Chef::Application.fatal!("Aborting due to error in '#{config_file_path}'", 2)
end
class << self
diff --git a/lib/chef/application/agent.rb b/lib/chef/application/agent.rb
index 353d45252e..66b0c25cbf 100644
--- a/lib/chef/application/agent.rb
+++ b/lib/chef/application/agent.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index b08a795697..a04b4f1cf6 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -22,7 +22,7 @@ require 'chef/client'
require 'chef/config'
require 'chef/daemon'
require 'chef/log'
-require 'chef/rest'
+require 'chef/config_fetcher'
require 'chef/handler/error_report'
@@ -34,7 +34,6 @@ class Chef::Application::Client < Chef::Application
option :config_file,
:short => "-c CONFIG",
:long => "--config CONFIG",
- :default => Chef::Config.platform_specific_path("/etc/chef/client.rb"),
:description => "The configuration file to use"
option :formatter,
@@ -197,6 +196,20 @@ class Chef::Application::Client < Chef::Application
:description => "Enable reporting data collection for chef runs",
:boolean => true
+ option :local_mode,
+ :short => "-z",
+ :long => "--local-mode",
+ :description => "Point chef-client at local repository",
+ :boolean => true
+
+ option :chef_zero_port,
+ :long => "--chef-zero-port PORT",
+ :description => "Port to start chef-zero on"
+
+ option :config_file_jail,
+ :long => "--config-file-jail PATH",
+ :description => "Directory under which config files are allowed to be loaded (no client.rb or knife.rb outside this path will be loaded)."
+
if Chef::Platform.windows?
option :fatal_windows_admin_check,
:short => "-A",
@@ -219,6 +232,12 @@ class Chef::Application::Client < Chef::Application
Chef::Config[:chef_server_url] = config[:chef_server_url] if config.has_key? :chef_server_url
+ Chef::Config.local_mode = config[:local_mode] if config.has_key?(:local_mode)
+ if Chef::Config.local_mode && !Chef::Config.has_key?(:cookbook_path) && !Chef::Config.has_key?(:chef_repo_path)
+ Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Dir.pwd)
+ end
+ Chef::Config.chef_zero.port = config[:chef_zero_port] if config[:chef_zero_port]
+
if Chef::Config[:daemonize]
Chef::Config[:interval] ||= 1800
end
@@ -229,31 +248,22 @@ class Chef::Application::Client < Chef::Application
end
if Chef::Config[:json_attribs]
- begin
- json_io = case Chef::Config[:json_attribs]
- when /^(http|https):\/\//
- @rest = Chef::REST.new(Chef::Config[:json_attribs], nil, nil)
- @rest.get_rest(Chef::Config[:json_attribs], true).open
- else
- open(Chef::Config[:json_attribs])
- end
- rescue SocketError => error
- Chef::Application.fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2)
- rescue Errno::ENOENT => error
- Chef::Application.fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2)
- rescue Errno::EACCES => error
- Chef::Application.fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2)
- rescue Exception => error
- Chef::Application.fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2)
- end
+ config_fetcher = Chef::ConfigFetcher.new(Chef::Config[:json_attribs])
+ @chef_client_json = config_fetcher.fetch_json
+ end
+ end
- begin
- @chef_client_json = Chef::JSONCompat.from_json(json_io.read)
- json_io.close unless json_io.closed?
- rescue JSON::ParserError => error
- Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2)
+ def load_config_file
+ Chef::Config.config_file_jail = config[:config_file_jail] if config[:config_file_jail]
+ if !config.has_key?(:config_file)
+ if config[:local_mode]
+ require 'chef/knife'
+ config[:config_file] = Chef::Knife.locate_config_file
+ else
+ config[:config_file] = Chef::Config.platform_specific_path("/etc/chef/client.rb")
end
end
+ super
end
def configure_logging
diff --git a/lib/chef/application/knife.rb b/lib/chef/application/knife.rb
index 13612a4bf3..3a9cd4e870 100644
--- a/lib/chef/application/knife.rb
+++ b/lib/chef/application/knife.rb
@@ -106,6 +106,16 @@ class Chef::Application::Knife < Chef::Application
:description => "Which format to use for output",
:default => "summary"
+ option :local_mode,
+ :short => "-z",
+ :long => "--local-mode",
+ :description => "Point knife commands at local repository instead of server",
+ :boolean => true
+
+ option :chef_zero_port,
+ :long => "--chef-zero-port PORT",
+ :description => "Port to start chef-zero on"
+
option :version,
:short => "-v",
:long => "--version",
diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb
index 5e3fe90607..ba563ce3a8 100644
--- a/lib/chef/application/solo.rb
+++ b/lib/chef/application/solo.rb
@@ -23,7 +23,7 @@ require 'chef/config'
require 'chef/daemon'
require 'chef/log'
require 'chef/rest'
-require 'open-uri'
+require 'chef/config_fetcher'
require 'fileutils'
class Chef::Application::Solo < Chef::Application
@@ -31,7 +31,7 @@ class Chef::Application::Solo < Chef::Application
option :config_file,
:short => "-c CONFIG",
:long => "--config CONFIG",
- :default => Chef::Config.platform_specfic_path('/etc/chef/solo.rb'),
+ :default => Chef::Config.platform_specific_path('/etc/chef/solo.rb'),
:description => "The configuration file to use"
option :formatter,
@@ -160,6 +160,11 @@ class Chef::Application::Solo < Chef::Application
:description => 'Enable whyrun mode',
:boolean => true
+ option :environment,
+ :short => '-E ENVIRONMENT',
+ :long => '--environment ENVIRONMENT',
+ :description => 'Set the Chef Environment on the node'
+
attr_reader :chef_solo_json
def initialize
@@ -176,36 +181,13 @@ class Chef::Application::Solo < Chef::Application
end
if Chef::Config[:json_attribs]
- begin
- json_io = case Chef::Config[:json_attribs]
- when /^(http|https):\/\//
- @rest = Chef::REST.new(Chef::Config[:json_attribs], nil, nil)
- @rest.get_rest(Chef::Config[:json_attribs], true).open
- else
- open(Chef::Config[:json_attribs])
- end
- rescue SocketError => error
- Chef::Application.fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2)
- rescue Errno::ENOENT => error
- Chef::Application.fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2)
- rescue Errno::EACCES => error
- Chef::Application.fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2)
- rescue Exception => error
- Chef::Application.fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2)
- end
-
- begin
- @chef_client_json = Chef::JSONCompat.from_json(json_io.read)
- json_io.close unless json_io.closed?
- rescue JSON::ParserError => error
- Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2)
- end
+ config_fetcher = Chef::ConfigFetcher.new(Chef::Config[:json_attribs])
+ @chef_solo_json = config_fetcher.fetch_json
end
if Chef::Config[:recipe_url]
cookbooks_path = Array(Chef::Config[:cookbook_path]).detect{|e| e =~ /\/cookbooks\/*$/ }
recipes_path = File.expand_path(File.join(cookbooks_path, '..'))
- target_file = File.join(recipes_path, 'recipes.tgz')
Chef::Log.debug "Creating path #{recipes_path} to extract recipes into"
FileUtils.mkdir_p recipes_path
diff --git a/lib/chef/application/windows_service.rb b/lib/chef/application/windows_service.rb
index 85a18c7a17..08403c7aa2 100644
--- a/lib/chef/application/windows_service.rb
+++ b/lib/chef/application/windows_service.rb
@@ -27,11 +27,13 @@ require 'chef/rest'
require 'mixlib/cli'
require 'socket'
require 'win32/daemon'
+require 'chef/mixin/shell_out'
class Chef
class Application
class WindowsService < ::Win32::Daemon
include Mixlib::CLI
+ include Chef::Mixin::ShellOut
option :config_file,
:short => "-c CONFIG",
@@ -160,17 +162,29 @@ class Chef
# Initializes Chef::Client instance and runs it
def run_chef_client
- @chef_client = Chef::Client.new(
- @chef_client_json,
- :override_runlist => config[:override_runlist]
- )
- @chef_client_json = nil
-
- @chef_client.run
- @chef_client = nil
+ # The chef client will be started in a new process. We have used shell_out to start the chef-client.
+ # The log_location and config_file of the parent process is passed to the new chef-client process.
+ # We need to add the --no-fork, as by default it is set to fork=true.
+ begin
+ Chef::Log.info "Starting chef-client in a new process"
+ # Pass config params to the new process
+ config_params = " --no-fork"
+ config_params += " -c #{Chef::Config[:config_file]}" unless Chef::Config[:config_file].nil?
+ config_params += " -L #{Chef::Config[:log_location]}" unless Chef::Config[:log_location] == STDOUT
+ # Starts a new process and waits till the process exits
+ result = shell_out("chef-client #{config_params}")
+ Chef::Log.debug "#{result.stdout}"
+ Chef::Log.debug "#{result.stderr}"
+ rescue Mixlib::ShellOut::ShellCommandFailed => e
+ Chef::Log.warn "Not able to start chef-client in new process (#{e})"
+ rescue => e
+ Chef::Log.error e
+ ensure
+ # Once process exits, we log the current process' pid
+ Chef::Log.info "Child process exited (pid: #{Process.pid})"
+ end
end
-
def apply_config(config_file_path)
Chef::Config.from_file(config_file_path)
Chef::Config.merge!(config)
@@ -241,7 +255,7 @@ class Chef
def configure_chef(startup_parameters)
# Bit of a hack ahead:
# It is possible to specify a service's binary_path_name with arguments, like "foo.exe -x argX".
- # It is also possible to specify startup parameters separately, either via the the Services manager
+ # It is also possible to specify startup parameters separately, either via the Services manager
# or by using the registry (I think).
# In order to accommodate all possible sources of parameterization, we first parse any command line
diff --git a/lib/chef/application/windows_service_manager.rb b/lib/chef/application/windows_service_manager.rb
index 13bd2c5cd6..493f0dfc62 100644
--- a/lib/chef/application/windows_service_manager.rb
+++ b/lib/chef/application/windows_service_manager.rb
@@ -61,6 +61,14 @@ class Chef
:show_options => true,
:exit => 0
+ option :version,
+ :short => "-v",
+ :long => "--version",
+ :description => "Show chef version",
+ :boolean => true,
+ :proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"},
+ :exit => 0
+
def initialize(service_options)
# having to call super in initialize is the most annoying
# anti-pattern :(
diff --git a/lib/chef/checksum/storage.rb b/lib/chef/checksum/storage.rb
index 90aef57081..4a1b3d38df 100644
--- a/lib/chef/checksum/storage.rb
+++ b/lib/chef/checksum/storage.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/checksum/storage/filesystem.rb b/lib/chef/checksum/storage/filesystem.rb
index 7500a5ad85..94257f518b 100644
--- a/lib/chef/checksum/storage/filesystem.rb
+++ b/lib/chef/checksum/storage/filesystem.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/chef_fs/chef_fs_data_store.rb b/lib/chef/chef_fs/chef_fs_data_store.rb
index c1c5a81e04..1fedc98380 100644
--- a/lib/chef/chef_fs/chef_fs_data_store.rb
+++ b/lib/chef/chef_fs/chef_fs_data_store.rb
@@ -135,7 +135,7 @@ class Chef
if path[0] == 'cookbooks' && path.length >= 3
entry.delete(true)
else
- entry.delete
+ entry.delete(false)
end
end
end
diff --git a/lib/chef/chef_fs/command_line.rb b/lib/chef/chef_fs/command_line.rb
index dd5e62b755..d0183a5a2a 100644
--- a/lib/chef/chef_fs/command_line.rb
+++ b/lib/chef/chef_fs/command_line.rb
@@ -19,6 +19,7 @@
require 'chef/chef_fs/file_system'
require 'chef/chef_fs/file_system/operation_failed_error'
require 'chef/chef_fs/file_system/operation_not_allowed_error'
+require 'chef/util/diff'
class Chef
module ChefFS
@@ -268,7 +269,7 @@ class Chef
old_tempfile.write(old_value)
old_tempfile.close
- result = `diff -u #{old_tempfile.path} #{new_tempfile.path}`
+ result = Chef::Util::Diff.new.udiff(old_tempfile.path, new_tempfile.path)
result = result.gsub(/^--- #{old_tempfile.path}/, "--- #{old_path}")
result = result.gsub(/^\+\+\+ #{new_tempfile.path}/, "+++ #{new_path}")
result
diff --git a/lib/chef/chef_fs/config.rb b/lib/chef/chef_fs/config.rb
index ab4cea89f2..e08b976961 100644
--- a/lib/chef/chef_fs/config.rb
+++ b/lib/chef/chef_fs/config.rb
@@ -25,13 +25,24 @@ class Chef
# Helpers to take Chef::Config and create chef_fs and local_fs from it
#
class Config
- def initialize(chef_config = Chef::Config, cwd = Dir.pwd)
+ def initialize(chef_config = Chef::Config, cwd = Dir.pwd, options = {})
@chef_config = chef_config
@cwd = cwd
- configure_repo_paths
+ @cookbook_version = options[:cookbook_version]
+
+ # Default to getting *everything* from the server.
+ if !@chef_config[:repo_mode]
+ if @chef_config[:chef_server_url] =~ /\/+organizations\/.+/
+ @chef_config[:repo_mode] = 'hosted_everything'
+ else
+ @chef_config[:repo_mode] = 'everything'
+ end
+ end
end
- PATH_VARIABLES = %w(acl_path client_path cookbook_path container_path data_bag_path environment_path group_path node_path role_path user_path)
+ attr_reader :chef_config
+ attr_reader :cwd
+ attr_reader :cookbook_version
def chef_fs
@chef_fs ||= create_chef_fs
@@ -39,7 +50,7 @@ class Chef
def create_chef_fs
require 'chef/chef_fs/file_system/chef_server_root_dir'
- Chef::ChefFS::FileSystem::ChefServerRootDir.new("remote", @chef_config)
+ Chef::ChefFS::FileSystem::ChefServerRootDir.new("remote", @chef_config, :cookbook_version => @cookbook_version)
end
def local_fs
@@ -73,16 +84,14 @@ class Chef
# If the path does not reach into ANY specified directory, nil is returned.
def server_path(file_path)
pwd = File.expand_path(Dir.pwd)
- absolute_path = Chef::ChefFS::PathUtils.realest_path(File.expand_path(file_path, pwd))
+ absolute_pwd = Chef::ChefFS::PathUtils.realest_path(File.expand_path(file_path, pwd))
# Check all object paths (cookbooks_dir, data_bags_dir, etc.)
object_paths.each_pair do |name, paths|
paths.each do |path|
realest_path = Chef::ChefFS::PathUtils.realest_path(path)
- if absolute_path[0,realest_path.length] == realest_path &&
- (absolute_path.length == realest_path.length ||
- absolute_path[realest_path.length,1] =~ /#{PathUtils.regexp_path_separator}/)
- relative_path = Chef::ChefFS::PathUtils::relative_to(absolute_path, realest_path)
+ if PathUtils.descendant_of?(absolute_pwd, realest_path)
+ relative_path = Chef::ChefFS::PathUtils::relative_to(absolute_pwd, realest_path)
return relative_path == '.' ? "/#{name}" : "/#{name}/#{relative_path}"
end
end
@@ -91,7 +100,7 @@ class Chef
# Check chef_repo_path
Array(@chef_config[:chef_repo_path]).flatten.each do |chef_repo_path|
realest_chef_repo_path = Chef::ChefFS::PathUtils.realest_path(chef_repo_path)
- if absolute_path == realest_chef_repo_path
+ if absolute_pwd == realest_chef_repo_path
return '/'
end
end
@@ -125,19 +134,10 @@ class Chef
server_path
end
- def require_chef_repo_path
- if !@chef_config[:chef_repo_path]
- Chef::Log.error("Must specify either chef_repo_path or cookbook_path in Chef config file")
- exit(1)
- end
- end
-
private
def object_paths
@object_paths ||= begin
- require_chef_repo_path
-
result = {}
case @chef_config[:repo_mode]
when 'static'
@@ -155,51 +155,6 @@ class Chef
result
end
end
-
- def configure_repo_paths
- # Smooth out some (for now) inappropriate defaults set by Chef
- if @chef_config[:cookbook_path] == [ @chef_config.platform_specific_path("/var/chef/cookbooks"),
- @chef_config.platform_specific_path("/var/chef/site-cookbooks") ]
- @chef_config[:cookbook_path] = nil
- end
- if @chef_config[:data_bag_path] == @chef_config.platform_specific_path('/var/chef/data_bags')
- @chef_config[:data_bag_path] = nil
- end
- if @chef_config[:node_path] == '/var/chef/node'
- @chef_config[:node_path] = nil
- end
- if @chef_config[:role_path] == @chef_config.platform_specific_path('/var/chef/roles')
- @chef_config[:role_path] = nil
- end
-
- # Infer chef_repo_path from cookbook_path if not speciifed
- if !@chef_config[:chef_repo_path]
- if @chef_config[:cookbook_path]
- @chef_config[:chef_repo_path] = Array(@chef_config[:cookbook_path]).flatten.map { |path| File.expand_path('..', path) }
- end
- end
-
- # Default to getting *everything* from the server.
- if !@chef_config[:repo_mode]
- if @chef_config[:chef_server_url] =~ /\/+organizations\/.+/
- @chef_config[:repo_mode] = 'hosted_everything'
- else
- @chef_config[:repo_mode] = 'everything'
- end
- end
-
- # Infer any *_path variables that are not specified
- if @chef_config[:chef_repo_path]
- PATH_VARIABLES.each do |variable_name|
- chef_repo_paths = Array(@chef_config[:chef_repo_path]).flatten
- variable = variable_name.to_sym
- if !@chef_config[variable]
- # cookbook_path -> cookbooks
- @chef_config[variable] = chef_repo_paths.map { |path| File.join(path, "#{variable_name[0..-6]}s") }
- end
- end
- end
- end
end
end
end
diff --git a/lib/chef/chef_fs/data_handler/client_data_handler.rb b/lib/chef/chef_fs/data_handler/client_data_handler.rb
index 2db3fa897f..4b6b8f5c79 100644
--- a/lib/chef/chef_fs/data_handler/client_data_handler.rb
+++ b/lib/chef/chef_fs/data_handler/client_data_handler.rb
@@ -9,12 +9,11 @@ class Chef
defaults = {
'name' => remove_dot_json(entry.name),
'clientname' => remove_dot_json(entry.name),
- 'orgname' => entry.org,
'admin' => false,
'validator' => false,
'chef_type' => 'client'
}
- if entry.org
+ if entry.respond_to?(:org) && entry.org
defaults['orgname'] = entry.org
end
result = normalize_hash(client, defaults)
diff --git a/lib/chef/chef_fs/file_system.rb b/lib/chef/chef_fs/file_system.rb
index a6e14e548c..f2478c4680 100644
--- a/lib/chef/chef_fs/file_system.rb
+++ b/lib/chef/chef_fs/file_system.rb
@@ -289,7 +289,7 @@ class Chef
ui.output "Deleted extra entry #{dest_path} (purge is on)" if ui
end
else
- Chef::Log.info("Not deleting extra entry #{dest_path} (purge is off)") if ui
+ ui.output ("Not deleting extra entry #{dest_path} (purge is off)") if ui
end
end
@@ -407,7 +407,7 @@ class Chef
parent = entry.parent
if parent && !parent.exists?
parent_path = format_path.call(parent) if ui
- parent_parent = get_or_create_parent(entry.parent, options, ui, format_path)
+ parent_parent = get_or_create_parent(parent, options, ui, format_path)
if options[:dry_run]
ui.output "Would create #{parent_path}" if ui
else
diff --git a/lib/chef/chef_fs/file_system/acl_entry.rb b/lib/chef/chef_fs/file_system/acl_entry.rb
index 0be9076038..8edc02d5c5 100644
--- a/lib/chef/chef_fs/file_system/acl_entry.rb
+++ b/lib/chef/chef_fs/file_system/acl_entry.rb
@@ -40,7 +40,7 @@ class Chef
acls = data_handler.normalize(JSON.parse(file_contents, :create_additions => false), self)
PERMISSIONS.each do |permission|
begin
- rest.put_rest("#{api_path}/#{permission}", { permission => acls[permission] })
+ rest.put("#{api_path}/#{permission}", { permission => acls[permission] })
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Timeout writing: #{e}"
rescue Net::HTTPServerException => e
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_acls_dir.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_acls_dir.rb
new file mode 100644
index 0000000000..7d2a930633
--- /dev/null
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_acls_dir.rb
@@ -0,0 +1,37 @@
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/chef_fs/file_system/chef_repository_file_system_entry'
+require 'chef/chef_fs/file_system/acls_dir'
+require 'chef/chef_fs/data_handler/acl_data_handler'
+
+class Chef
+ module ChefFS
+ module FileSystem
+ class ChefRepositoryFileSystemAclsDir < ChefRepositoryFileSystemEntry
+ def initialize(name, parent, path = nil)
+ super(name, parent, path, Chef::ChefFS::DataHandler::AclDataHandler.new)
+ end
+
+ def can_have_child?(name, is_dir)
+ is_dir ? Chef::ChefFS::FileSystem::AclsDir::ENTITY_TYPES.include?(name) : name == 'organization.json'
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb
index e3d8e47cf2..5203637012 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb
@@ -18,6 +18,7 @@
require 'chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry'
require 'chef/chef_fs/file_system/cookbook_dir'
+require 'chef/chef_fs/file_system/not_found_error'
require 'chef/cookbook/chefignore'
require 'chef/cookbook/cookbook_version_loader'
@@ -51,13 +52,14 @@ class Chef
end
def children
- Dir.entries(file_path).sort.
- select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
- map do |child_name|
- segment_info = CookbookDir::COOKBOOK_SEGMENT_INFO[child_name.to_sym] || {}
- ChefRepositoryFileSystemCookbookEntry.new(child_name, self, nil, segment_info[:ruby_only], segment_info[:recursive])
- end.
- select { |entry| !(entry.dir? && entry.children.size == 0) }
+ begin
+ Dir.entries(file_path).sort.
+ select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
+ map { |child_name| make_child(child_name) }.
+ select { |entry| !(entry.dir? && entry.children.size == 0) }
+ rescue Errno::ENOENT
+ raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ end
end
def can_have_child?(name, is_dir)
@@ -65,7 +67,6 @@ class Chef
# Only the given directories will be uploaded.
return CookbookDir::COOKBOOK_SEGMENT_INFO.keys.include?(name.to_sym) && name != 'root_files'
end
-
super(name, is_dir)
end
@@ -79,6 +80,13 @@ class Chef
def canonical_cookbook_name(entry_name)
self.class.canonical_cookbook_name(entry_name)
end
+
+ protected
+
+ def make_child(child_name)
+ segment_info = CookbookDir::COOKBOOK_SEGMENT_INFO[child_name.to_sym] || {}
+ ChefRepositoryFileSystemCookbookEntry.new(child_name, self, nil, segment_info[:ruby_only], segment_info[:recursive])
+ end
end
end
end
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb
index d2fe3ed5f6..6541b07065 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb
@@ -18,6 +18,7 @@
require 'chef/chef_fs/file_system/chef_repository_file_system_entry'
require 'chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir'
+require 'chef/chef_fs/file_system/not_found_error'
class Chef
module ChefFS
@@ -33,10 +34,14 @@ class Chef
attr_reader :recursive
def children
- Dir.entries(file_path).sort.
- select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
- map { |child_name| ChefRepositoryFileSystemCookbookEntry.new(child_name, self, nil, ruby_only, recursive) }.
- select { |entry| !(entry.dir? && entry.children.size == 0) }
+ begin
+ Dir.entries(file_path).sort.
+ select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
+ map { |child_name| make_child(child_name) }.
+ select { |entry| !(entry.dir? && entry.children.size == 0) }
+ rescue Errno::ENOENT
+ raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ end
end
def can_have_child?(name, is_dir)
@@ -65,6 +70,16 @@ class Chef
true
end
+
+ def write_pretty_json
+ false
+ end
+
+ protected
+
+ def make_child(child_name)
+ ChefRepositoryFileSystemCookbookEntry.new(child_name, self, nil, ruby_only, recursive)
+ end
end
end
end
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb
index ba4ea0bd1f..6e16f18f24 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb
@@ -26,29 +26,44 @@ class Chef
class ChefRepositoryFileSystemCookbooksDir < ChefRepositoryFileSystemEntry
def initialize(name, parent, file_path)
super(name, parent, file_path)
- @chefignore = Chef::Cookbook::Chefignore.new(self.file_path)
+ begin
+ @chefignore = Chef::Cookbook::Chefignore.new(self.file_path)
+ rescue Errno::EISDIR
+ rescue Errno::EACCES
+ # Work around a bug in Chefignore when chefignore is a directory
+ end
end
attr_reader :chefignore
def children
- Dir.entries(file_path).sort.
- select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
- map { |child_name| ChefRepositoryFileSystemCookbookDir.new(child_name, self) }.
- select do |entry|
- # empty cookbooks and cookbook directories are ignored
- if entry.children.size == 0
- Chef::Log.warn("Cookbook '#{entry.name}' is empty or entirely chefignored at #{entry.path_for_printing}")
- false
- else
- true
+ begin
+ Dir.entries(file_path).sort.
+ select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
+ map { |child_name| make_child(child_name) }.
+ select do |entry|
+ # empty cookbooks and cookbook directories are ignored
+ if entry.children.size == 0
+ Chef::Log.warn("Cookbook '#{entry.name}' is empty or entirely chefignored at #{entry.path_for_printing}")
+ false
+ else
+ true
+ end
end
- end
+ rescue Errno::ENOENT
+ raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ end
end
def can_have_child?(name, is_dir)
is_dir && !name.start_with?('.')
end
+
+ protected
+
+ def make_child(child_name)
+ ChefRepositoryFileSystemCookbookDir.new(child_name, self)
+ end
end
end
end
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb
index fa4fda4eb6..3d3f58201e 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb
@@ -18,6 +18,7 @@
#
require 'chef/chef_fs/file_system/file_system_entry'
+require 'chef/chef_fs/file_system/not_found_error'
class Chef
module ChefFS
@@ -30,6 +31,10 @@ class Chef
@data_handler = data_handler
end
+ def write_pretty_json
+ root.write_pretty_json
+ end
+
def data_handler
@data_handler || parent.data_handler
end
@@ -47,13 +52,36 @@ class Chef
!is_dir && name[-5..-1] == '.json'
end
+ def write(file_contents)
+ if file_contents && write_pretty_json && name[-5..-1] == '.json'
+ file_contents = minimize(file_contents, self)
+ end
+ super(file_contents)
+ end
+
+ def minimize(file_contents, entry)
+ object = JSONCompat.from_json(file_contents, :create_additions => false)
+ object = data_handler.normalize(object, entry)
+ object = data_handler.minimize(object, entry)
+ JSONCompat.to_json_pretty(object)
+ end
+
def children
# Except cookbooks and data bag dirs, all things must be json files
- Dir.entries(file_path).sort.
- select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
- map { |child_name| ChefRepositoryFileSystemEntry.new(child_name, self) }
+ begin
+ Dir.entries(file_path).sort.
+ select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
+ map { |child_name| make_child(child_name) }
+ rescue Errno::ENOENT
+ raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
+ end
end
+ protected
+
+ def make_child(child_name)
+ ChefRepositoryFileSystemEntry.new(child_name, self)
+ end
end
end
end
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
index 3523d85a4e..d615e0f415 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
@@ -18,6 +18,7 @@
require 'chef/chef_fs/file_system/base_fs_dir'
require 'chef/chef_fs/file_system/chef_repository_file_system_entry'
+require 'chef/chef_fs/file_system/chef_repository_file_system_acls_dir'
require 'chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir'
require 'chef/chef_fs/file_system/chef_repository_file_system_data_bags_dir'
require 'chef/chef_fs/file_system/multiplexed_dir'
@@ -28,7 +29,6 @@ require 'chef/chef_fs/data_handler/role_data_handler'
require 'chef/chef_fs/data_handler/user_data_handler'
require 'chef/chef_fs/data_handler/group_data_handler'
require 'chef/chef_fs/data_handler/container_data_handler'
-require 'chef/chef_fs/data_handler/acl_data_handler'
class Chef
module ChefFS
@@ -39,6 +39,8 @@ class Chef
@child_paths = child_paths
end
+ attr_accessor :write_pretty_json
+
attr_reader :child_paths
def children
@@ -51,9 +53,14 @@ class Chef
def create_child(name, file_contents = nil)
child_paths[name].each do |path|
- Dir.mkdir(path)
+ begin
+ Dir.mkdir(path)
+ rescue Errno::EEXIST
+ end
end
- make_child_entry(name)
+ child = make_child_entry(name)
+ @children = nil
+ child
end
def json_class
@@ -90,6 +97,8 @@ class Chef
dirs = paths.map { |path| ChefRepositoryFileSystemCookbooksDir.new(name, self, path) }
elsif name == 'data_bags'
dirs = paths.map { |path| ChefRepositoryFileSystemDataBagsDir.new(name, self, path) }
+ elsif name == 'acls'
+ dirs = paths.map { |path| ChefRepositoryFileSystemAclsDir.new(name, self, path) }
else
data_handler = case name
when 'clients'
@@ -106,8 +115,6 @@ class Chef
Chef::ChefFS::DataHandler::GroupDataHandler.new
when 'containers'
Chef::ChefFS::DataHandler::ContainerDataHandler.new
- when 'acls'
- Chef::ChefFS::DataHandler::AclDataHandler.new
else
raise "Unknown top level path #{name}"
end
diff --git a/lib/chef/chef_fs/file_system/chef_server_root_dir.rb b/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
index 5eb72657c5..0083ee4cfa 100644
--- a/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_server_root_dir.rb
@@ -16,6 +16,7 @@
# limitations under the License.
#
+require 'chef/server_api'
require 'chef/chef_fs/file_system/acls_dir'
require 'chef/chef_fs/file_system/base_fs_dir'
require 'chef/chef_fs/file_system/rest_list_dir'
@@ -23,7 +24,6 @@ require 'chef/chef_fs/file_system/cookbooks_dir'
require 'chef/chef_fs/file_system/data_bags_dir'
require 'chef/chef_fs/file_system/nodes_dir'
require 'chef/chef_fs/file_system/environments_dir'
-require 'chef/rest'
require 'chef/chef_fs/data_handler/client_data_handler'
require 'chef/chef_fs/data_handler/role_data_handler'
require 'chef/chef_fs/data_handler/user_data_handler'
@@ -34,7 +34,7 @@ class Chef
module ChefFS
module FileSystem
class ChefServerRootDir < BaseFSDir
- def initialize(root_name, chef_config)
+ def initialize(root_name, chef_config, options = {})
super("", nil)
@chef_server_url = chef_config[:chef_server_url]
@chef_username = chef_config[:node_name]
@@ -42,6 +42,7 @@ class Chef
@environment = chef_config[:environment]
@repo_mode = chef_config[:repo_mode]
@root_name = root_name
+ @cookbook_version = options[:cookbook_version] # Used in knife diff and download for server cookbook version
end
attr_reader :chef_server_url
@@ -49,12 +50,21 @@ class Chef
attr_reader :chef_private_key
attr_reader :environment
attr_reader :repo_mode
+ attr_reader :cookbook_version
def fs_description
"Chef server at #{chef_server_url} (user #{chef_username}), repo_mode = #{repo_mode}"
end
def rest
+ Chef::ServerAPI.new(chef_server_url, :client_name => chef_username, :signing_key_filename => chef_private_key, :raw_output => true)
+ end
+
+ def get_json(path)
+ Chef::ServerAPI.new(chef_server_url, :client_name => chef_username, :signing_key_filename => chef_private_key).get(path)
+ end
+
+ def chef_rest
Chef::REST.new(chef_server_url, chef_username, chef_private_key)
end
diff --git a/lib/chef/chef_fs/file_system/cookbook_dir.rb b/lib/chef/chef_fs/file_system/cookbook_dir.rb
index cae29a1690..d7411e1c74 100644
--- a/lib/chef/chef_fs/file_system/cookbook_dir.rb
+++ b/lib/chef/chef_fs/file_system/cookbook_dir.rb
@@ -41,6 +41,7 @@ class Chef
end
else
@cookbook_name = name
+ @version = root.cookbook_version # nil unless --cookbook-version specified in download/diff
end
end
@@ -125,7 +126,7 @@ class Chef
def delete(recurse)
if recurse
begin
- rest.delete_rest(api_path)
+ rest.delete(api_path)
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "Timeout deleting: #{e}"
rescue Net::HTTPServerException
@@ -190,7 +191,7 @@ class Chef
old_retry_count = Chef::Config[:http_retry_count]
begin
Chef::Config[:http_retry_count] = 0
- @chef_object ||= Chef::CookbookVersion.json_create(Chef::ChefFS::RawRequest.raw_json(rest, api_path))
+ @chef_object ||= Chef::CookbookVersion.json_create(root.get_json(api_path))
ensure
Chef::Config[:http_retry_count] = old_retry_count
end
diff --git a/lib/chef/chef_fs/file_system/cookbook_file.rb b/lib/chef/chef_fs/file_system/cookbook_file.rb
index e05c4aa614..7868322590 100644
--- a/lib/chef/chef_fs/file_system/cookbook_file.rb
+++ b/lib/chef/chef_fs/file_system/cookbook_file.rb
@@ -17,6 +17,7 @@
#
require 'chef/chef_fs/file_system/base_fs_object'
+require 'chef/http/simple'
require 'digest/md5'
class Chef
@@ -35,16 +36,12 @@ class Chef
end
def read
- old_sign_on_redirect = rest.sign_on_redirect
- rest.sign_on_redirect = false
begin
- tmpfile = rest.get_rest(file[:url], true)
+ tmpfile = rest.streaming_request(file[:url])
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "Timeout reading #{file[:url]}: #{e}"
rescue Net::HTTPServerException => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "#{e.message} retrieving #{file[:url]}"
- ensure
- rest.sign_on_redirect = old_sign_on_redirect
end
begin
diff --git a/lib/chef/chef_fs/file_system/cookbooks_dir.rb b/lib/chef/chef_fs/file_system/cookbooks_dir.rb
index c6af933290..a58bfdd1f2 100644
--- a/lib/chef/chef_fs/file_system/cookbooks_dir.rb
+++ b/lib/chef/chef_fs/file_system/cookbooks_dir.rb
@@ -18,10 +18,10 @@
require 'chef/chef_fs/file_system/rest_list_dir'
require 'chef/chef_fs/file_system/cookbook_dir'
-require 'chef/chef_fs/raw_request'
require 'chef/chef_fs/file_system/operation_failed_error'
require 'chef/chef_fs/file_system/cookbook_frozen_error'
require 'chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir'
+require 'chef/mixin/file_class'
require 'tmpdir'
@@ -29,6 +29,9 @@ class Chef
module ChefFS
module FileSystem
class CookbooksDir < RestListDir
+
+ include Chef::Mixin::FileClass
+
def initialize(parent)
super("cookbooks", parent)
end
@@ -50,19 +53,20 @@ class Chef
@children ||= begin
if Chef::Config[:versioned_cookbooks]
result = []
- Chef::ChefFS::RawRequest.raw_json(rest, "#{api_path}/?num_versions=all").each_pair do |cookbook_name, cookbooks|
+ root.get_json("#{api_path}/?num_versions=all").each_pair do |cookbook_name, cookbooks|
cookbooks['versions'].each do |cookbook_version|
result << CookbookDir.new("#{cookbook_name}-#{cookbook_version['version']}", self, :exists => true)
end
end
else
- result = Chef::ChefFS::RawRequest.raw_json(rest, api_path).keys.map { |cookbook_name| CookbookDir.new(cookbook_name, self, :exists => true) }
+ result = root.get_json(api_path).keys.map { |cookbook_name| CookbookDir.new(cookbook_name, self, :exists => true) }
end
result.sort_by(&:name)
end
end
def create_child_from(other, options = {})
+ @children = nil
upload_cookbook_from(other, options)
end
@@ -92,7 +96,7 @@ class Chef
proxy_cookbook_path = "#{temp_cookbooks_path}/#{cookbook_name}"
# Make a symlink
- File.symlink other.file_path, proxy_cookbook_path
+ file_class.symlink other.file_path, proxy_cookbook_path
# Instantiate a proxy loader using the temporary symlink
proxy_loader = Chef::Cookbook::CookbookVersionLoader.new(proxy_cookbook_path, other.parent.chefignore)
@@ -102,18 +106,29 @@ class Chef
cookbook_to_upload.freeze_version if options[:freeze]
# Instantiate a new uploader based on the proxy loader
- uploader = Chef::CookbookUploader.new(cookbook_to_upload, proxy_cookbook_path, :force => options[:force], :rest => rest)
+ uploader = Chef::CookbookUploader.new(cookbook_to_upload, proxy_cookbook_path, :force => options[:force], :rest => root.chef_rest)
with_actual_cookbooks_dir(temp_cookbooks_path) do
upload_cookbook!(uploader)
end
+
+ #
+ # When the temporary directory is being deleted on
+ # windows, the contents of the symlink under that
+ # directory is also deleted. So explicitly remove
+ # the symlink without removing the original contents if we
+ # are running on windows
+ #
+ if Chef::Platform.windows?
+ Dir.rmdir proxy_cookbook_path
+ end
end
end
def upload_unversioned_cookbook(other, options)
cookbook_to_upload = other.chef_object
cookbook_to_upload.freeze_version if options[:freeze]
- uploader = Chef::CookbookUploader.new(cookbook_to_upload, other.parent.file_path, :force => options[:force], :rest => rest)
+ uploader = Chef::CookbookUploader.new(cookbook_to_upload, other.parent.file_path, :force => options[:force], :rest => root.chef_rest)
with_actual_cookbooks_dir(other.parent.file_path) do
upload_cookbook!(uploader)
diff --git a/lib/chef/chef_fs/file_system/data_bag_dir.rb b/lib/chef/chef_fs/file_system/data_bag_dir.rb
index 3814b94fac..212f76fdb9 100644
--- a/lib/chef/chef_fs/file_system/data_bag_dir.rb
+++ b/lib/chef/chef_fs/file_system/data_bag_dir.rb
@@ -52,7 +52,7 @@ class Chef
raise MustDeleteRecursivelyError.new(self), "#{path_for_printing} must be deleted recursively"
end
begin
- rest.delete_rest(api_path)
+ rest.delete(api_path)
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "Timeout deleting: #{e}"
rescue Net::HTTPServerException => e
diff --git a/lib/chef/chef_fs/file_system/data_bags_dir.rb b/lib/chef/chef_fs/file_system/data_bags_dir.rb
index 46c3c21cf6..6d0685d3b7 100644
--- a/lib/chef/chef_fs/file_system/data_bags_dir.rb
+++ b/lib/chef/chef_fs/file_system/data_bags_dir.rb
@@ -34,7 +34,7 @@ class Chef
def children
begin
- @children ||= Chef::ChefFS::RawRequest.raw_json(rest, api_path).keys.sort.map do |entry|
+ @children ||= root.get_json(api_path).keys.sort.map do |entry|
DataBagDir.new(entry, self, true)
end
rescue Timeout::Error => e
@@ -54,7 +54,7 @@ class Chef
def create_child(name, file_contents)
begin
- rest.post_rest(api_path, { 'name' => name })
+ rest.post(api_path, { 'name' => name })
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "Timeout creating child '#{name}': #{e}"
rescue Net::HTTPServerException => e
@@ -64,6 +64,7 @@ class Chef
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "HTTP error creating child '#{name}': #{e}"
end
end
+ @children = nil
DataBagDir.new(name, self, true)
end
end
diff --git a/lib/chef/chef_fs/file_system/file_system_entry.rb b/lib/chef/chef_fs/file_system/file_system_entry.rb
index 82c52deae8..46d4eb5538 100644
--- a/lib/chef/chef_fs/file_system/file_system_entry.rb
+++ b/lib/chef/chef_fs/file_system/file_system_entry.rb
@@ -40,20 +40,24 @@ class Chef
def children
begin
- @children ||= Dir.entries(file_path).sort.select { |entry| entry != '.' && entry != '..' }.map { |entry| FileSystemEntry.new(entry, self) }
+ Dir.entries(file_path).sort.select { |entry| entry != '.' && entry != '..' }.map { |entry| make_child(entry) }
rescue Errno::ENOENT
raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!)
end
end
def create_child(child_name, file_contents=nil)
- result = FileSystemEntry.new(child_name, self)
+ child = make_child(child_name)
if file_contents
- result.write(file_contents)
+ child.write(file_contents)
else
- Dir.mkdir(result.file_path)
+ begin
+ Dir.mkdir(child.file_path)
+ rescue Errno::EEXIST
+ end
end
- result
+ @children = nil
+ child
end
def dir?
@@ -84,6 +88,12 @@ class Chef
file.write(content)
end
end
+
+ protected
+
+ def make_child(child_name)
+ FileSystemEntry.new(child_name, self)
+ end
end
end
end
diff --git a/lib/chef/chef_fs/file_system/multiplexed_dir.rb b/lib/chef/chef_fs/file_system/multiplexed_dir.rb
index a7a901e304..06d4af705d 100644
--- a/lib/chef/chef_fs/file_system/multiplexed_dir.rb
+++ b/lib/chef/chef_fs/file_system/multiplexed_dir.rb
@@ -17,7 +17,7 @@ class Chef
end
def children
- @children ||= begin
+ begin
result = []
seen = {}
# If multiple things have the same name, the first one wins.
@@ -40,6 +40,7 @@ class Chef
end
def create_child(name, file_contents = nil)
+ @children = nil
write_dir.create_child(name, file_contents)
end
end
diff --git a/lib/chef/chef_fs/file_system/nodes_dir.rb b/lib/chef/chef_fs/file_system/nodes_dir.rb
index 82683e81ac..c3c48377cd 100644
--- a/lib/chef/chef_fs/file_system/nodes_dir.rb
+++ b/lib/chef/chef_fs/file_system/nodes_dir.rb
@@ -32,7 +32,7 @@ class Chef
# Identical to RestListDir.children, except supports environments
def children
begin
- @children ||= Chef::ChefFS::RawRequest.raw_json(rest, env_api_path).keys.sort.map do |key|
+ @children ||= root.get_json(env_api_path).keys.sort.map do |key|
_make_child_entry("#{key}.json", true)
end
rescue Timeout::Error => e
diff --git a/lib/chef/chef_fs/file_system/operation_failed_error.rb b/lib/chef/chef_fs/file_system/operation_failed_error.rb
index 1af2d2dcff..28d170d628 100644
--- a/lib/chef/chef_fs/file_system/operation_failed_error.rb
+++ b/lib/chef/chef_fs/file_system/operation_failed_error.rb
@@ -27,6 +27,14 @@ class Chef
@operation = operation
end
+ def message
+ if cause && cause.is_a?(Net::HTTPExceptions) && cause.response.code == "400"
+ "#{super} cause: #{cause.response.body}"
+ else
+ super
+ end
+ end
+
attr_reader :operation
end
end
diff --git a/lib/chef/chef_fs/file_system/rest_list_dir.rb b/lib/chef/chef_fs/file_system/rest_list_dir.rb
index 594fec8ab6..b7ee51d284 100644
--- a/lib/chef/chef_fs/file_system/rest_list_dir.rb
+++ b/lib/chef/chef_fs/file_system/rest_list_dir.rb
@@ -45,7 +45,7 @@ class Chef
def children
begin
- @children ||= Chef::ChefFS::RawRequest.raw_json(rest, api_path).keys.sort.map do |key|
+ @children ||= root.get_json(api_path).keys.sort.map do |key|
_make_child_entry("#{key}.json", true)
end
rescue Timeout::Error => e
@@ -76,7 +76,7 @@ class Chef
end
begin
- rest.post_rest(api_path, object)
+ rest.post(api_path, object)
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "Timeout creating '#{name}': #{e}"
rescue Net::HTTPServerException => e
@@ -89,6 +89,8 @@ class Chef
end
end
+ @children = nil
+
result
end
diff --git a/lib/chef/chef_fs/file_system/rest_list_entry.rb b/lib/chef/chef_fs/file_system/rest_list_entry.rb
index 6e6ad12438..0d5557de1d 100644
--- a/lib/chef/chef_fs/file_system/rest_list_entry.rb
+++ b/lib/chef/chef_fs/file_system/rest_list_entry.rb
@@ -19,7 +19,6 @@
require 'chef/chef_fs/file_system/base_fs_object'
require 'chef/chef_fs/file_system/not_found_error'
require 'chef/chef_fs/file_system/operation_failed_error'
-require 'chef/chef_fs/raw_request'
require 'chef/role'
require 'chef/node'
@@ -68,7 +67,7 @@ class Chef
def delete(recurse)
begin
- rest.delete_rest(api_path)
+ rest.delete(api_path)
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:delete, self, e), "Timeout deleting: #{e}"
rescue Net::HTTPServerException => e
@@ -86,7 +85,8 @@ class Chef
def _read_hash
begin
- json = Chef::ChefFS::RawRequest.raw_request(rest, api_path)
+ # Minimize the value (get rid of defaults) so the results don't look terrible
+ minimize_value(root.get_json(api_path))
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "Timeout reading: #{e}"
rescue Net::HTTPServerException => e
@@ -96,8 +96,6 @@ class Chef
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:read, self, e), "HTTP error reading: #{e}"
end
end
- # Minimize the value (get rid of defaults) so the results don't look terrible
- minimize_value(JSON.parse(json, :create_additions => false))
end
def chef_object
@@ -160,7 +158,7 @@ class Chef
end
begin
- rest.put_rest(api_path, object)
+ rest.put(api_path, object)
rescue Timeout::Error => e
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Timeout writing: #{e}"
rescue Net::HTTPServerException => e
diff --git a/lib/chef/chef_fs/knife.rb b/lib/chef/chef_fs/knife.rb
index 5900c29f61..652c728550 100644
--- a/lib/chef/chef_fs/knife.rb
+++ b/lib/chef/chef_fs/knife.rb
@@ -35,37 +35,40 @@ class Chef
def self.inherited(c)
super
+
# Ensure we always get to do our includes, whether subclass calls deps or not
c.deps do
end
- option :repo_mode,
- :long => '--repo-mode MODE',
- :description => "Specifies the local repository layout. Values: static, everything, hosted_everything. Default: everything/hosted_everything"
+ c.options.merge!(options)
+ end
- option :chef_repo_path,
- :long => '--chef-repo-path PATH',
- :description => 'Overrides the location of chef repo. Default is specified by chef_repo_path in the config'
+ option :repo_mode,
+ :long => '--repo-mode MODE',
+ :description => "Specifies the local repository layout. Values: static, everything, hosted_everything. Default: everything/hosted_everything"
- option :concurrency,
- :long => '--concurrency THREADS',
- :description => 'Maximum number of simultaneous requests to send (default: 10)'
- end
+ option :chef_repo_path,
+ :long => '--chef-repo-path PATH',
+ :description => 'Overrides the location of chef repo. Default is specified by chef_repo_path in the config'
+
+ option :concurrency,
+ :long => '--concurrency THREADS',
+ :description => 'Maximum number of simultaneous requests to send (default: 10)'
def configure_chef
super
Chef::Config[:repo_mode] = config[:repo_mode] if config[:repo_mode]
Chef::Config[:concurrency] = config[:concurrency].to_i if config[:concurrency]
- # --chef-repo-path overrides all other paths
+ # --chef-repo-path forcibly overrides all other paths
if config[:chef_repo_path]
Chef::Config[:chef_repo_path] = config[:chef_repo_path]
- Chef::ChefFS::Config::PATH_VARIABLES.each do |variable_name|
- Chef::Config[variable_name.to_sym] = chef_repo_paths.map { |path| File.join(path, "#{variable_name[0..-6]}s") }
+ %w(acl client cookbook container data_bag environment group node role user).each do |variable_name|
+ Chef::Config.delete("#{variable_name}_path".to_sym)
end
end
- @chef_fs_config = Chef::ChefFS::Config.new(Chef::Config)
+ @chef_fs_config = Chef::ChefFS::Config.new(Chef::Config, Dir.pwd, config)
Chef::ChefFS::Parallelizer.threads = (Chef::Config[:concurrency] || 10) - 1
end
@@ -91,17 +94,18 @@ class Chef
end
def pattern_args_from(args)
+ args.map { |arg| pattern_arg_from(arg) }
+ end
+
+ def pattern_arg_from(arg)
# TODO support absolute file paths and not just patterns? Too much?
# Could be super useful in a world with multiple repo paths
- args.map do |arg|
- if !@chef_fs_config.base_path && !Chef::ChefFS::PathUtils.is_absolute?(arg)
- # Check if chef repo path is specified to give a better error message
- @chef_fs_config.require_chef_repo_path
- ui.error("Attempt to use relative path '#{arg}' when current directory is outside the repository path")
- exit(1)
- end
- Chef::ChefFS::FilePattern.relative_to(@chef_fs_config.base_path, arg)
+ if !@chef_fs_config.base_path && !Chef::ChefFS::PathUtils.is_absolute?(arg)
+ # Check if chef repo path is specified to give a better error message
+ ui.error("Attempt to use relative path '#{arg}' when current directory is outside the repository path")
+ exit(1)
end
+ Chef::ChefFS::FilePattern.relative_to(@chef_fs_config.base_path, arg)
end
def format_path(entry)
@@ -111,6 +115,19 @@ class Chef
def parallelize(inputs, options = {}, &block)
Chef::ChefFS::Parallelizer.parallelize(inputs, options, &block)
end
+
+ def discover_repo_dir(dir)
+ %w(.chef cookbooks data_bags environments roles).each do |subdir|
+ return dir if File.directory?(File.join(dir, subdir))
+ end
+ # If this isn't it, check the parent
+ parent = File.dirname(dir)
+ if parent && parent != dir
+ discover_repo_dir(parent)
+ else
+ nil
+ end
+ end
end
end
end
diff --git a/lib/chef/chef_fs/path_utils.rb b/lib/chef/chef_fs/path_utils.rb
index 805b092b3a..9ef75ce2e5 100644
--- a/lib/chef/chef_fs/path_utils.rb
+++ b/lib/chef/chef_fs/path_utils.rb
@@ -82,6 +82,11 @@ class Chef
end
end
+ def self.descendant_of?(path, ancestor)
+ path[0,ancestor.length] == ancestor &&
+ (ancestor.length == path.length || path[ancestor.length,1] =~ /#{PathUtils.regexp_path_separator}/)
+ end
+
def self.is_absolute?(path)
path =~ /^#{regexp_path_separator}/
end
diff --git a/lib/chef/chef_fs/raw_request.rb b/lib/chef/chef_fs/raw_request.rb
deleted file mode 100644
index 43907282f6..0000000000
--- a/lib/chef/chef_fs/raw_request.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-class Chef
- module ChefFS
- module RawRequest
- def self.raw_json(chef_rest, api_path)
- JSON.parse(raw_request(chef_rest, api_path), :create_additions => false)
- end
-
- def self.raw_request(chef_rest, api_path)
- api_request(chef_rest, :GET, chef_rest.create_url(api_path), {}, false)
- end
-
- def self.api_request(chef_rest, method, url, headers={}, data=false)
- json_body = data
- # json_body = data ? Chef::JSONCompat.to_json(data) : nil
- # Force encoding to binary to fix SSL related EOFErrors
- # cf. http://tickets.opscode.com/browse/CHEF-2363
- # http://redmine.ruby-lang.org/issues/5233
- # json_body.force_encoding(Encoding::BINARY) if json_body.respond_to?(:force_encoding)
- headers = build_headers(chef_rest, method, url, headers, json_body)
-
- chef_rest.retriable_rest_request(method, url, json_body, headers) do |rest_request|
- response = rest_request.call {|r| r.read_body}
-
- response_body = chef_rest.decompress_body(response)
-
- if response.kind_of?(Net::HTTPSuccess)
- response_body
- elsif redirect_location = redirected_to(response)
- if [:GET, :HEAD].include?(method)
- chef_rest.follow_redirect do
- api_request(chef_rest, method, chef_rest.create_url(redirect_location))
- end
- else
- raise Exceptions::InvalidRedirect, "#{method} request was redirected from #{url} to #{redirect_location}. Only GET and HEAD support redirects."
- end
- else
- # have to decompress the body before making an exception for it. But the body could be nil.
- response.body.replace(chef_rest.decompress_body(response)) if response.body.respond_to?(:replace)
-
- if response['content-type'] =~ /json/
- exception = response_body
- msg = "HTTP Request Returned #{response.code} #{response.message}: "
- msg << (exception["error"].respond_to?(:join) ? exception["error"].join(", ") : exception["error"].to_s)
- Chef::Log.info(msg)
- end
- response.error!
- end
- end
- end
-
- private
-
- # Copied so that it does not automatically inflate an object
- # This is also used by knife raw_essentials
-
- ACCEPT_ENCODING = "Accept-Encoding".freeze
- ENCODING_GZIP_DEFLATE = "gzip;q=1.0,deflate;q=0.6,identity;q=0.3".freeze
-
- def self.redirected_to(response)
- return nil unless response.kind_of?(Net::HTTPRedirection)
- # Net::HTTPNotModified is undesired subclass of Net::HTTPRedirection so test for this
- return nil if response.kind_of?(Net::HTTPNotModified)
- response['location']
- end
-
- def self.build_headers(chef_rest, method, url, headers={}, json_body=false, raw=false)
- # headers = @default_headers.merge(headers)
- #headers['Accept'] = "application/json" unless raw
- headers['Accept'] = "application/json" unless raw
- headers["Content-Type"] = 'application/json' if json_body
- headers['Content-Length'] = json_body.bytesize.to_s if json_body
- headers[Chef::REST::RESTRequest::ACCEPT_ENCODING] = Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE
- headers.merge!(chef_rest.authentication_headers(method, url, json_body)) if chef_rest.sign_requests?
- headers.merge!(Chef::Config[:custom_http_headers]) if Chef::Config[:custom_http_headers]
- headers
- end
- end
- end
-end
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index ceb0873079..04d6799988 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -198,6 +198,7 @@ class Chef
Chef::Log.debug "Forked instance now converging"
do_run
rescue Exception
+ Chef::Log.error $!
exit 1
else
exit 0
@@ -206,7 +207,7 @@ class Chef
Chef::Log.debug "Fork successful. Waiting for new chef pid: #{pid}"
result = Process.waitpid2(pid)
handle_child_exit(result)
- Chef::Log.debug "Forked child successfully reaped (pid: #{pid})"
+ Chef::Log.debug "Forked instance successfully reaped (pid: #{pid})"
true
else
do_run
@@ -367,7 +368,10 @@ class Chef
# === Returns
# rest<Chef::REST>:: returns Chef::REST connection object
def register(client_name=node_name, config=Chef::Config)
- if File.exists?(config[:client_key])
+ if !config[:client_key]
+ @events.skipping_registration(client_name, config)
+ Chef::Log.debug("Client key is unspecified - skipping registration")
+ elsif File.exists?(config[:client_key])
@events.skipping_registration(client_name, config)
Chef::Log.debug("Client key #{config[:client_key]} is present - skipping registration")
else
@@ -467,13 +471,15 @@ class Chef
# === Returns
# true:: Always returns true.
def do_run
- runlock = RunLock.new(Chef::Config)
+ runlock = RunLock.new(Chef::Config.lockfile)
runlock.acquire
# don't add code that may fail before entering this section to be sure to release lock
begin
+ runlock.save_pid
run_context = nil
@events.run_start(Chef::VERSION)
Chef::Log.info("*** Chef #{Chef::VERSION} ***")
+ Chef::Log.info "Chef-client pid: #{Process.pid}"
enforce_path_sanity
run_ohai
@events.ohai_completed(node)
diff --git a/lib/chef/config.rb b/lib/chef/config.rb
index e3211d232e..feb7e4ea94 100644
--- a/lib/chef/config.rb
+++ b/lib/chef/config.rb
@@ -29,6 +29,13 @@ class Chef
extend Mixlib::Config
+ # Evaluates the given string as config.
+ #
+ # +filename+ is used for context in stacktraces, but doesn't need to be the name of an actual file.
+ def self.from_string(string, filename)
+ self.instance_eval(string, filename, 1)
+ end
+
# Manages the chef secret session key
# === Returns
# <newkey>:: A new or retrieved session key
@@ -50,8 +57,32 @@ class Chef
configuration.inspect
end
+ def self.on_windows?
+ RUBY_PLATFORM =~ /mswin|mingw|windows/
+ end
+
+ BACKSLASH = '\\'.freeze
+
+ def self.platform_path_separator
+ if on_windows?
+ File::ALT_SEPARATOR || BACKSLASH
+ else
+ File::SEPARATOR
+ end
+ end
+
+ def self.path_join(*args)
+ args = args.flatten
+ args.inject do |joined_path, component|
+ unless joined_path[-1,1] == platform_path_separator
+ joined_path += platform_path_separator
+ end
+ joined_path += component
+ end
+ end
+
def self.platform_specific_path(path)
- if RUBY_PLATFORM =~ /mswin|mingw|windows/
+ if on_windows?
# turns /etc/chef/client.rb into C:/chef/client.rb
system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : ""
path = File.join(system_drive, path.split('/')[2..-1])
@@ -65,32 +96,35 @@ class Chef
formatters << [name, file_path]
end
- def self.formatters
- @formatters ||= []
+ # Config file to load (client.rb, knife.rb, etc. defaults set differently in knife, chef-client, etc.)
+ configurable(:config_file)
+
+ default(:config_dir) do
+ if local_mode
+ path_join(user_home, ".chef#{platform_path_separator}")
+ else
+ config_file && ::File.dirname(config_file)
+ end
end
+ # No config file (client.rb / knife.rb / etc.) will be loaded outside this path.
+ # Major use case is tests, where we don't want to load the user's config files.
+ configurable(:config_file_jail)
+
+ default :formatters, []
+
# Override the config dispatch to set the value of multiple server options simultaneously
#
# === Parameters
# url<String>:: String to be set for all of the chef-server-api URL's
#
- config_attr_writer :chef_server_url do |url|
- url = url.strip
- configure do |c|
- c[:chef_server_url] = url
- end
- url
- end
+ configurable(:chef_server_url).writes_value { |url| url.strip }
# When you are using ActiveSupport, they monkey-patch 'daemonize' into Kernel.
# So while this is basically identical to what method_missing would do, we pull
# it up here and get a real method written so that things get dispatched
# properly.
- config_attr_writer :daemonize do |v|
- configure do |c|
- c[:daemonize] = v
- end
- end
+ configurable(:daemonize).writes_value { |v| v }
# Override the config dispatch to set the value of log_location configuration option
#
@@ -108,50 +142,148 @@ class Chef
rescue Errno::ENOENT
raise Chef::Exceptions::ConfigurationError, "Failed to open or create log file at #{location.to_str}"
end
- f
+ f
+ end
+ end
+
+ # The root where all local chef object data is stored. cookbooks, data bags,
+ # environments are all assumed to be in separate directories under this.
+ # chef-solo uses these directories for input data. knife commands
+ # that upload or download files (such as knife upload, knife role from file,
+ # etc.) work.
+ default :chef_repo_path do
+ if self.configuration[:cookbook_path]
+ if self.configuration[:cookbook_path].kind_of?(String)
+ File.expand_path('..', self.configuration[:cookbook_path])
+ else
+ self.configuration[:cookbook_path].map do |path|
+ File.expand_path('..', path)
+ end
+ end
+ else
+ platform_specific_path("/var/chef")
+ end
+ end
+
+ def self.find_chef_repo_path(cwd)
+ # In local mode, we auto-discover the repo root by looking for a path with "cookbooks" under it.
+ # This allows us to run config-free.
+ path = cwd
+ until File.directory?(path_join(path, "cookbooks"))
+ new_path = File.expand_path('..', path)
+ if new_path == path
+ Chef::Log.warn("No cookbooks directory found at or above current directory. Assuming #{Dir.pwd}.")
+ return Dir.pwd
+ end
+ path = new_path
+ end
+ Chef::Log.info("Auto-discovered chef repository at #{path}")
+ path
+ end
+
+ def self.derive_path_from_chef_repo_path(child_path)
+ if chef_repo_path.kind_of?(String)
+ path_join(chef_repo_path, child_path)
+ else
+ chef_repo_path.map { |path| path_join(path, child_path)}
end
end
+ # Location of acls on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/acls.
+ # Only applies to Enterprise Chef commands.
+ default(:acl_path) { derive_path_from_chef_repo_path('acls') }
+
+ # Location of clients on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/acls.
+ default(:client_path) { derive_path_from_chef_repo_path('clients') }
+
+ # Location of cookbooks on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/cookbooks. If chef_repo_path
+ # is not specified, this is set to [/var/chef/cookbooks, /var/chef/site-cookbooks]).
+ default(:cookbook_path) do
+ if self.configuration[:chef_repo_path]
+ derive_path_from_chef_repo_path('cookbooks')
+ else
+ Array(derive_path_from_chef_repo_path('cookbooks')).flatten +
+ Array(derive_path_from_chef_repo_path('site-cookbooks')).flatten
+ end
+ end
+
+ # Location of containers on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/containers.
+ # Only applies to Enterprise Chef commands.
+ default(:container_path) { derive_path_from_chef_repo_path('containers') }
+
+ # Location of data bags on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/data_bags.
+ default(:data_bag_path) { derive_path_from_chef_repo_path('data_bags') }
+
+ # Location of environments on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/environments.
+ default(:environment_path) { derive_path_from_chef_repo_path('environments') }
+
+ # Location of groups on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/groups.
+ # Only applies to Enterprise Chef commands.
+ default(:group_path) { derive_path_from_chef_repo_path('groups') }
+
+ # Location of nodes on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/nodes.
+ default(:node_path) { derive_path_from_chef_repo_path('nodes') }
+
+ # Location of roles on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/roles.
+ default(:role_path) { derive_path_from_chef_repo_path('roles') }
+
+ # Location of users on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/users.
+ # Does not apply to Enterprise Chef commands.
+ default(:user_path) { derive_path_from_chef_repo_path('users') }
+
# Turn on "path sanity" by default. See also: http://wiki.opscode.com/display/chef/User+Environment+PATH+Sanity
- enforce_path_sanity(true)
+ default :enforce_path_sanity, true
# Formatted Chef Client output is a beta feature, disabled by default:
- formatter "null"
+ default :formatter, "null"
# The number of times the client should retry when registering with the server
- client_registration_retries 5
-
- # Where the cookbooks are located. Meaning is somewhat context dependent between
- # knife, chef-client, and chef-solo.
- cookbook_path [ platform_specific_path("/var/chef/cookbooks"),
- platform_specific_path("/var/chef/site-cookbooks") ]
+ default :client_registration_retries, 5
# An array of paths to search for knife exec scripts if they aren't in the current directory
- script_path []
+ default :script_path, []
+
+ # The root of all caches (checksums, cache and backup). If local mode is on,
+ # this is under the user's home directory.
+ default(:cache_path) do
+ if local_mode
+ "#{config_dir}local-mode-cache"
+ else
+ platform_specific_path("/var/chef")
+ end
+ end
# Where cookbook files are stored on the server (by content checksum)
- checksum_path "/var/chef/checksums"
+ default(:checksum_path) { path_join(cache_path, "checksums") }
# Where chef's cache files should be stored
- file_cache_path platform_specific_path("/var/chef/cache")
+ default(:file_cache_path) { path_join(cache_path, "cache") }
- # By default, chef-client (or solo) creates a lockfile in
- # `file_cache_path`/chef-client-running.pid
- # If `lockfile` is explicitly set, this path will be used instead.
+ # Where backups of chef-managed files should go
+ default(:file_backup_path) { path_join(cache_path, "backup") }
+
+ # The chef-client (or solo) lockfile.
#
# If your `file_cache_path` resides on a NFS (or non-flock()-supporting
# fs), it's recommended to set this to something like
# '/tmp/chef-client-running.pid'
- lockfile nil
-
- # Where backups of chef-managed files should go
- file_backup_path platform_specific_path("/var/chef/backup")
+ default(:lockfile) { path_join(file_cache_path, "chef-client-running.pid") }
## Daemonization Settings ##
# What user should Chef run as?
- user nil
- group nil
- umask 0022
+ default :user, nil
+ default :group, nil
+ default :umask, 0022
# Valid log_levels are:
# * :debug
@@ -164,57 +296,76 @@ class Chef
# in a console), the log level is set to :warn, and output formatters are
# used as the primary mode of output. When a tty is not available, the
# logger is the primary mode of output, and the log level is set to :info
- log_level :auto
+ default :log_level, :auto
# Using `force_formatter` causes chef to default to formatter output when STDOUT is not a tty
- force_formatter false
+ default :force_formatter, false
# Using `force_logger` causes chef to default to logger output when STDOUT is a tty
- force_logger false
-
- http_retry_count 5
- http_retry_delay 5
- interval nil
- json_attribs nil
- log_location STDOUT
+ default :force_logger, false
+
+ default :http_retry_count, 5
+ default :http_retry_delay, 5
+ default :interval, nil
+ default :once, nil
+ default :json_attribs, nil
+ default :log_location, STDOUT
# toggle info level log items that can create a lot of output
- verbose_logging true
- node_name nil
- diff_disabled false
- diff_filesize_threshold 10000000
- diff_output_threshold 1000000
-
- pid_file nil
-
- chef_server_url "https://localhost:443"
-
- rest_timeout 300
- yum_timeout 900
- solo false
- splay nil
- why_run false
- color false
- client_fork true
- enable_reporting true
- enable_reporting_url_fatals false
+ default :verbose_logging, true
+ default :node_name, nil
+ default :diff_disabled, false
+ default :diff_filesize_threshold, 10000000
+ default :diff_output_threshold, 1000000
+ default :local_mode, false
+
+ default :pid_file, nil
+
+ config_context :chef_zero do
+ config_strict_mode true
+ default(:enabled) { Chef::Config.local_mode }
+ default :port, 8889
+ end
+ default :chef_server_url, "https://localhost:443"
+
+ default :rest_timeout, 300
+ default :yum_timeout, 900
+ default :solo, false
+ default :splay, nil
+ default :why_run, false
+ default :color, false
+ default :client_fork, true
+ default :enable_reporting, true
+ default :enable_reporting_url_fatals, false
# Set these to enable SSL authentication / mutual-authentication
# with the server
- ssl_client_cert nil
- ssl_client_key nil
- ssl_verify_mode :verify_none
- ssl_ca_path nil
- ssl_ca_file nil
- # Where should chef-solo look for role files?
- role_path platform_specific_path("/var/chef/roles")
+ # Client side SSL cert/key for mutual auth
+ default :ssl_client_cert, nil
+ default :ssl_client_key, nil
+
+ # Whether or not to verify the SSL cert for all HTTPS requests. If set to
+ # :verify_peer, all HTTPS requests will be validated regardless of other
+ # SSL verification settings.
+ default :ssl_verify_mode, :verify_none
- data_bag_path platform_specific_path("/var/chef/data_bags")
+ # Whether or not to verify the SSL cert for HTTPS requests to the Chef
+ # server API. If set to `true`, the server's cert will be validated
+ # regardless of the :ssl_verify_mode setting.
+ default :verify_api_cert, false
- environment_path platform_specific_path("/var/chef/environments")
+ # Path to the default CA bundle files.
+ default :ssl_ca_path, nil
+ default :ssl_ca_file, nil
+
+ # A directory that contains additional SSL certificates to trust. Any
+ # certificates in this directory will be added to whatever CA bundle ruby
+ # is using. Use this to add self-signed certs for your Chef Server or local
+ # HTTP file servers.
+ default(:trusted_certs_dir) { config_dir && path_join(config_dir, "trusted_certs") }
# Where should chef-solo download recipes from?
- recipe_url nil
+ default :recipe_url, nil
# Sets the version of the signed header authentication protocol to use (see
# the 'mixlib-authorization' project for more detail). Currently, versions
@@ -230,7 +381,7 @@ class Chef
#
# In the future, this configuration option may be replaced with an
# automatic negotiation scheme.
- authentication_protocol_version "1.0"
+ default :authentication_protocol_version, "1.0"
# This key will be used to sign requests to the Chef server. This location
# must be writable by Chef during initial setup when generating a client
@@ -238,17 +389,21 @@ class Chef
#
# The chef-server will look up the public key for the client using the
# `node_name` of the client.
- client_key platform_specific_path("/etc/chef/client.pem")
+ #
+ # If chef-zero is enabled, this defaults to nil (no authentication).
+ default(:client_key) { chef_zero.enabled ? nil : platform_specific_path("/etc/chef/client.pem") }
# This secret is used to decrypt encrypted data bag items.
- encrypted_data_bag_secret platform_specific_path("/etc/chef/encrypted_data_bag_secret")
-
- # We have to check for the existence of the default file before setting it
- # since +Chef::Config[:encrypted_data_bag_secret]+ is read by older
- # bootstrap templates to determine if the local secret should be uploaded to
- # node being bootstrapped. This should be removed in Chef 12.
- unless File.exist?(platform_specific_path("/etc/chef/encrypted_data_bag_secret"))
- encrypted_data_bag_secret(nil)
+ default(:encrypted_data_bag_secret) do
+ # We have to check for the existence of the default file before setting it
+ # since +Chef::Config[:encrypted_data_bag_secret]+ is read by older
+ # bootstrap templates to determine if the local secret should be uploaded to
+ # node being bootstrapped. This should be removed in Chef 12.
+ if File.exist?(platform_specific_path("/etc/chef/encrypted_data_bag_secret"))
+ platform_specific_path("/etc/chef/encrypted_data_bag_secret")
+ else
+ nil
+ end
end
# As of Chef 11.0, version "1" is the default encrypted data bag item
@@ -256,7 +411,7 @@ class Chef
# To maintain compatibility, versions other than 1 must be opt-in.
#
# Set this to `2` if you have chef-client 11.6.0+ in your infrastructure:
- data_bag_encrypt_version 1
+ default :data_bag_encrypt_version, 1
# When reading data bag items, any supported version is accepted. However,
# if all encrypted data bags have been generated with the version 2 format,
@@ -264,7 +419,7 @@ class Chef
# security. For example, the version 2 format is identical to version 1
# except for the addition of an HMAC, so an attacker with MITM capability
# could downgrade an encrypted data bag to version 1 as part of an attack.
- data_bag_decrypt_minimum_version 0
+ default :data_bag_decrypt_minimum_version, 0
# If there is no file in the location given by `client_key`, chef-client
# will temporarily use the "validator" identity to generate one. If the
@@ -272,43 +427,53 @@ class Chef
# chef-client will not be able to authenticate to the server.
#
# The `validation_key` is never used if the `client_key` exists.
- validation_key platform_specific_path("/etc/chef/validation.pem")
- validation_client_name "chef-validator"
+ #
+ # If chef-zero is enabled, this defaults to nil (no authentication).
+ default(:validation_key) { chef_zero.enabled ? nil : platform_specific_path("/etc/chef/validation.pem") }
+ default :validation_client_name, "chef-validator"
# Zypper package provider gpg checks. Set to true to enable package
# gpg signature checking. This will be default in the
# future. Setting to false disables the warnings.
# Leaving this set to nil or false is a security hazard!
- zypper_check_gpg nil
+ default :zypper_check_gpg, nil
# Report Handlers
- report_handlers []
+ default :report_handlers, []
# Exception Handlers
- exception_handlers []
+ default :exception_handlers, []
# Start handlers
- start_handlers []
+ default :start_handlers, []
# Syntax Check Cache. Knife keeps track of files that is has already syntax
# checked by storing files in this directory. `syntax_check_cache_path` is
# the new (and preferred) configuration setting. If not set, knife will
- # fall back to using cache_options[:path].
- #
- # Because many users will have knife configs with cache_options (generated
- # by `knife configure`), the default for now is to *not* set
- # syntax_check_cache_path, and thus fallback to cache_options[:path]. We
- # leave that value to the same default as was previously set.
- syntax_check_cache_path nil
+ # fall back to using cache_options[:path], which is deprecated but exists in
+ # many client configs generated by pre-Chef-11 bootstrappers.
+ default(:syntax_check_cache_path) { cache_options[:path] }
# Deprecated:
- cache_options({ :path => platform_specific_path("/var/chef/cache/checksums") })
+ default(:cache_options) { { :path => path_join(file_cache_path, "checksums") } }
# Set to false to silence Chef 11 deprecation warnings:
- chef11_deprecation_warnings true
-
- # Arbitrary knife configuration data
- knife Hash.new
+ default :chef11_deprecation_warnings, true
+
+ # knife configuration data
+ config_context :knife do
+ default :ssh_port, nil
+ default :ssh_user, nil
+ default :ssh_attribute, nil
+ default :ssh_gateway, nil
+ default :bootstrap_version, nil
+ default :bootstrap_proxy, nil
+ default :identity_file, nil
+ default :host_key_verify, nil
+ default :forward_agent, nil
+ default :sort_status_reverse, nil
+ default :hints, {}
+ end
# Those lists of regular expressions define what chef considers a
# valid user and group name
@@ -316,31 +481,31 @@ class Chef
# From http://technet.microsoft.com/en-us/library/cc776019(WS.10).aspx
principal_valid_regex_part = '[^"\/\\\\\[\]\:;|=,+*?<>]+'
- user_valid_regex [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
- group_valid_regex [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
+ default :user_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
+ default :group_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
- fatal_windows_admin_check false
+ default :fatal_windows_admin_check, false
else
- user_valid_regex [ /^([-a-zA-Z0-9_.]+[\\@]?[-a-zA-Z0-9_.]+)$/, /^\d+$/ ]
- group_valid_regex [ /^([-a-zA-Z0-9_.\\@^ ]+)$/, /^\d+$/ ]
+ default :user_valid_regex, [ /^([-a-zA-Z0-9_.]+[\\@]?[-a-zA-Z0-9_.]+)$/, /^\d+$/ ]
+ default :group_valid_regex, [ /^([-a-zA-Z0-9_.\\@^ ]+)$/, /^\d+$/ ]
end
# returns a platform specific path to the user home dir
windows_home_path = ENV['SYSTEMDRIVE'] + ENV['HOMEPATH'] if ENV['SYSTEMDRIVE'] && ENV['HOMEPATH']
- user_home(ENV['HOME'] || windows_home_path || ENV['USERPROFILE'])
+ default :user_home, (ENV['HOME'] || windows_home_path || ENV['USERPROFILE'])
# Enable file permission fixup for selinux. Fixup will be done
# only if selinux is enabled in the system.
- enable_selinux_file_permission_fixup true
+ default :enable_selinux_file_permission_fixup, true
# Use atomic updates (i.e. move operation) while updating contents
# of the files resources. When set to false copy operation is
# used to update files.
- file_atomic_update true
+ default :file_atomic_update, true
# If false file staging is will be done via tempfiles that are
# created under ENV['TMP'] otherwise tempfiles will be created in
# the directory that files are going to reside.
- file_staging_uses_destdir false
+ default :file_staging_uses_destdir, false
end
end
diff --git a/lib/chef/config_fetcher.rb b/lib/chef/config_fetcher.rb
new file mode 100644
index 0000000000..80a313590b
--- /dev/null
+++ b/lib/chef/config_fetcher.rb
@@ -0,0 +1,79 @@
+require 'chef/application'
+require 'chef/chef_fs/path_utils'
+require 'chef/http/simple'
+require 'chef/json_compat'
+
+class Chef
+ class ConfigFetcher
+
+ attr_reader :config_location
+ attr_reader :config_file_jail
+
+ def initialize(config_location, config_file_jail)
+ @config_location = config_location
+ @config_file_jail = config_file_jail
+ end
+
+ def fetch_json
+ config_data = read_config
+ begin
+ Chef::JSONCompat.from_json(config_data)
+ rescue JSON::ParserError => error
+ Chef::Application.fatal!("Could not parse the provided JSON file (#{config_location}): " + error.message, 2)
+ end
+ end
+
+ def read_config
+ if remote_config?
+ fetch_remote_config
+ else
+ read_local_config
+ end
+ end
+
+ def fetch_remote_config
+ http.get("")
+ rescue SocketError, SystemCallError, Net::HTTPServerException => error
+ Chef::Application.fatal!("Cannot fetch config '#{config_location}': '#{error.class}: #{error.message}", 2)
+ end
+
+ def read_local_config
+ ::File.read(config_location)
+ rescue Errno::ENOENT => error
+ Chef::Application.fatal!("Cannot load configuration from #{config_location}", 2)
+ rescue Errno::EACCES => error
+ Chef::Application.fatal!("Permissions are incorrect on #{config_location}. Please chmod a+r #{config_location}", 2)
+ end
+
+ def config_missing?
+ return false if remote_config?
+
+ # Check if the config file exists, and check if it is underneath the config file jail
+ begin
+ real_config_file = Pathname.new(config_location).realpath.to_s
+ rescue Errno::ENOENT
+ return true
+ end
+
+ # If realpath succeeded, the file exists
+ return false if !config_file_jail
+
+ begin
+ real_jail = Pathname.new(config_file_jail).realpath.to_s
+ rescue Errno::ENOENT
+ Chef::Log.warn("Config file jail #{config_file_jail} does not exist: will not load any config file.")
+ return true
+ end
+
+ !Chef::ChefFS::PathUtils.descendant_of?(real_config_file, real_jail)
+ end
+
+ def http
+ Chef::HTTP::Simple.new(config_location)
+ end
+
+ def remote_config?
+ !!(config_location =~ %r{^(http|https)://})
+ end
+ end
+end
diff --git a/lib/chef/cookbook/file_vendor.rb b/lib/chef/cookbook/file_vendor.rb
index 38eab185ca..406f23ca25 100644
--- a/lib/chef/cookbook/file_vendor.rb
+++ b/lib/chef/cookbook/file_vendor.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,14 +27,14 @@ class Chef
def self.on_create(&block)
@instance_creator = block
end
-
+
# Factory method that creates the appropriate kind of
# Cookbook::FileVendor to serve the contents of the manifest
def self.create_from_manifest(manifest)
raise "Must call Chef::Cookbook::FileVendor.on_create before calling create_from_manifest factory" unless defined?(@instance_creator)
@instance_creator.call(manifest)
end
-
+
# Gets the on-disk location for the given cookbook file.
#
# Subclasses are responsible for determining exactly how the
@@ -42,7 +42,7 @@ class Chef
def get_filename(filename)
raise NotImplemented, "Subclasses must implement this method"
end
-
+
end
end
end
diff --git a/lib/chef/cookbook/metadata.rb b/lib/chef/cookbook/metadata.rb
index 18368bd99f..b9b32c8224 100644
--- a/lib/chef/cookbook/metadata.rb
+++ b/lib/chef/cookbook/metadata.rb
@@ -110,8 +110,8 @@ class Chef
@version = Version.new "0.0.0"
if cookbook
@recipes = cookbook.fully_qualified_recipe_names.inject({}) do |r, e|
- e = self.name if e =~ /::default$/
- r[e] = ""
+ e = self.name.to_s if e =~ /::default$/
+ r[e] ||= ""
self.provides e
r
end
diff --git a/lib/chef/cookbook/syntax_check.rb b/lib/chef/cookbook/syntax_check.rb
index 0e757074e3..59888e2ba3 100644
--- a/lib/chef/cookbook/syntax_check.rb
+++ b/lib/chef/cookbook/syntax_check.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -39,19 +39,9 @@ class Chef
attr_reader :cache_path
# Create a new PersistentSet. Values in the set are persisted by
- # creating a file in the +cache_path+ directory. If not given, the
- # value of Chef::Config[:syntax_check_cache_path] is used; if that
- # value is not configured, the value of
- # Chef::Config[:cache_options][:path] is used.
- #--
- # history: prior to Chef 11, the cache implementation was based on
- # moneta and configured via cache_options[:path]. Knife configs
- # generated with Chef 11 will have `syntax_check_cache_path`, but older
- # configs will have `cache_options[:path]`. `cache_options` is marked
- # deprecated in chef/config.rb but doesn't currently trigger a warning.
- # See also: CHEF-3715
- def initialize(cache_path=nil)
- @cache_path = cache_path || Chef::Config[:syntax_check_cache_path] || Chef::Config[:cache_options][:path]
+ # creating a file in the +cache_path+ directory.
+ def initialize(cache_path=Chef::Config[:syntax_check_cache_path])
+ @cache_path = cache_path
@cache_path_created = false
end
@@ -137,7 +127,7 @@ class Chef
end
def untested_template_files
- template_files.reject do |file|
+ template_files.reject do |file|
if validated?(file)
Chef::Log.debug("Template #{file} is unchanged, skipping syntax check")
true
diff --git a/lib/chef/cookbook_site_streaming_uploader.rb b/lib/chef/cookbook_site_streaming_uploader.rb
index abb5499042..92193fee33 100644
--- a/lib/chef/cookbook_site_streaming_uploader.rb
+++ b/lib/chef/cookbook_site_streaming_uploader.rb
@@ -208,8 +208,11 @@ class Chef
@parts.inject(0) {|size, part| size + part.size}
end
- def read(how_much)
- return nil if @part_no >= @parts.size
+ def read(how_much, dst_buf = nil)
+ if @part_no >= @parts.size
+ dst_buf.replace('') if dst_buf
+ return dst_buf
+ end
how_much_current_part = @parts[@part_no].size - @part_offset
@@ -228,15 +231,16 @@ class Chef
@part_no += 1
@part_offset = 0
next_part = read(how_much_next_part)
- current_part + if next_part
+ result = current_part + if next_part
next_part
else
''
end
else
@part_offset += how_much_current_part
- current_part
+ result = current_part
end
+ dst_buf ? dst_buf.replace(result || '') : result
end
end
diff --git a/lib/chef/cookbook_uploader.rb b/lib/chef/cookbook_uploader.rb
index 9ba5b2bd8b..3ead26e56d 100644
--- a/lib/chef/cookbook_uploader.rb
+++ b/lib/chef/cookbook_uploader.rb
@@ -137,15 +137,17 @@ class Chef
timestamp = Time.now.utc.iso8601
file_contents = File.open(file, "rb") {|f| f.read}
# TODO - 5/28/2010, cw: make signing and sending the request streaming
- sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(
- :http_method => :put,
- :path => URI.parse(url).path,
- :body => file_contents,
- :timestamp => timestamp,
- :user_id => rest.client_name
- )
headers = { 'content-type' => 'application/x-binary', 'content-md5' => checksum64, :accept => 'application/json' }
- headers.merge!(sign_obj.sign(OpenSSL::PKey::RSA.new(rest.signing_key)))
+ if rest.signing_key
+ sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(
+ :http_method => :put,
+ :path => URI.parse(url).path,
+ :body => file_contents,
+ :timestamp => timestamp,
+ :user_id => rest.client_name
+ )
+ headers.merge!(sign_obj.sign(OpenSSL::PKey::RSA.new(rest.signing_key)))
+ end
begin
RestClient::Resource.new(url, :headers=>headers, :timeout=>1800, :open_timeout=>1800).put(file_contents)
diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb
index 4e8b2a048e..5bd0ca064c 100644
--- a/lib/chef/cookbook_version.rb
+++ b/lib/chef/cookbook_version.rb
@@ -265,6 +265,18 @@ class Chef
end
end
+ # Query whether a template file +template_filename+ is available. File
+ # specificity for the given +node+ is obeyed in the lookup.
+ def has_template_for_node?(node, template_filename)
+ !!find_preferred_manifest_record(node, :templates, template_filename)
+ end
+
+ # Query whether a cookbook_file file +cookbook_filename+ is available. File
+ # specificity for the given +node+ is obeyed in the lookup.
+ def has_cookbook_file_for_node?(node, cookbook_filename)
+ !!find_preferred_manifest_record(node, :files, cookbook_filename)
+ end
+
# Determine the most specific manifest record for the given
# segment/filename, given information in the node. Throws
# FileNotFound if there is no such segment and filename in the
@@ -278,14 +290,7 @@ class Chef
# :checksum => "1234"
# }
def preferred_manifest_record(node, segment, filename)
- preferences = preferences_for_path(node, segment, filename)
-
- # ensure that we generate the manifest, which will also generate
- # @manifest_records_by_path
- manifest
-
- # in order of prefernce, look for the filename in the manifest
- found_pref = preferences.find {|preferred_filename| @manifest_records_by_path[preferred_filename] }
+ found_pref = find_preferred_manifest_record(node, segment, filename)
if found_pref
@manifest_records_by_path[found_pref]
else
@@ -567,6 +572,17 @@ class Chef
private
+ def find_preferred_manifest_record(node, segment, filename)
+ preferences = preferences_for_path(node, segment, filename)
+
+ # ensure that we generate the manifest, which will also generate
+ # @manifest_records_by_path
+ manifest
+
+ # in order of prefernce, look for the filename in the manifest
+ preferences.find {|preferred_filename| @manifest_records_by_path[preferred_filename] }
+ end
+
# For each filename, produce a mapping of base filename (i.e. recipe name
# or attribute file) to on disk location
def filenames_by_name(filenames)
diff --git a/lib/chef/daemon.rb b/lib/chef/daemon.rb
index 9a3d5a884a..e5abca29d8 100644
--- a/lib/chef/daemon.rb
+++ b/lib/chef/daemon.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,12 +18,14 @@
# I love you Merb (lib/merb-core/server.rb)
require 'chef/config'
+require 'chef/run_lock'
require 'etc'
class Chef
class Daemon
class << self
attr_accessor :name
+ attr_accessor :runlock
# Daemonize the current process, managing pidfiles and process uid/gid
#
@@ -32,9 +34,9 @@ class Chef
#
def daemonize(name)
@name = name
- pid = pid_from_file
- unless running?
- remove_pid_file()
+ @runlock = RunLock.new(pid_file)
+ if runlock.test
+ # We've acquired the daemon lock. Now daemonize.
Chef::Log.info("Daemonizing..")
begin
exit if fork
@@ -45,53 +47,15 @@ class Chef
$stdin.reopen("/dev/null")
$stdout.reopen("/dev/null", "a")
$stderr.reopen($stdout)
- save_pid_file
- at_exit { remove_pid_file }
+ runlock.save_pid
rescue NotImplementedError => e
Chef::Application.fatal!("There is no fork: #{e.message}")
end
else
- Chef::Application.fatal!("Chef is already running pid #{pid}")
- end
- end
-
- # Check if Chef is running based on the pid_file
- # ==== Returns
- # Boolean::
- # True if Chef is running
- # False if Chef is not running
- #
- def running?
- if pid_from_file.nil?
- false
- else
- Process.kill(0, pid_from_file)
- true
- end
- rescue Errno::ESRCH, Errno::ENOENT
- false
- rescue Errno::EACCES => e
- Chef::Application.fatal!("You don't have access to the PID file at #{pid_file}: #{e.message}")
- end
-
- # Check if this process if forked from a Chef daemon
- # ==== Returns
- # Boolean::
- # True if this process is forked
- # False if this process is not forked
- #
- def forked?
- if running? and Process.ppid == pid_from_file.to_i
- # chef daemon is running and this process is a child of it
- true
- elsif not running? and Process.ppid == 1
- # an orphaned fork, its parent becomes init, launchd, etc. after chef daemon dies
- true
- else
- false
+ Chef::Application.fatal!("Chef is already running pid #{pid_from_file}")
end
end
-
+
# Gets the pid file for @name
# ==== Returns
# String::
@@ -99,7 +63,7 @@ class Chef
def pid_file
Chef::Config[:pid_file] or "/tmp/#{@name}.pid"
end
-
+
# Suck the pid out of pid_file
# ==== Returns
# Integer::
@@ -112,31 +76,6 @@ class Chef
rescue Errno::ENOENT, Errno::EACCES
nil
end
-
- # Store the PID on the filesystem
- # This uses the Chef::Config[:pid_file] option, or "/tmp/name.pid" otherwise
- #
- def save_pid_file
- file = pid_file
- begin
- FileUtils.mkdir_p(File.dirname(file))
- rescue Errno::EACCES => e
- Chef::Application.fatal!("Failed store pid in #{File.dirname(file)}, permission denied: #{e.message}")
- end
-
- begin
- File.open(file, "w") { |f| f.write(Process.pid.to_s) }
- rescue Errno::EACCES => e
- Chef::Application.fatal!("Couldn't write to pidfile #{file}, permission denied: #{e.message}")
- end
- end
-
- # Delete the PID from the filesystem
- def remove_pid_file
- if not forked? then
- FileUtils.rm(pid_file) if File.exists?(pid_file)
- end
- end
# Change process user/group to those specified in Chef::Config
#
@@ -151,7 +90,7 @@ class Chef
_change_privilege(Chef::Config[:user])
end
end
-
+
# Change privileges of the process to be the specified user and group
#
# ==== Parameters
@@ -170,14 +109,14 @@ class Chef
Chef::Application.fatal!("Failed to get UID for user #{user}, does it exist? #{e.message}")
return false
end
-
+
begin
target_gid = Etc.getgrnam(group).gid
rescue ArgumentError => e
Chef::Application.fatal!("Failed to get GID for group #{group}, does it exist? #{e.message}")
return false
end
-
+
if (uid != target_uid) or (gid != target_gid)
Process.initgroups(user, target_gid)
Process::GID.change_privilege(target_gid)
diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb
index dcc01ec743..5994e6f8d1 100644
--- a/lib/chef/data_bag.rb
+++ b/lib/chef/data_bag.rb
@@ -129,11 +129,10 @@ class Chef
if Chef::Config[:why_run]
Chef::Log.warn("In whyrun mode, so NOT performing data bag save.")
else
- chef_server_rest.put_rest("data/#{@name}", self)
+ create
end
rescue Net::HTTPServerException => e
- raise e unless e.response.code == "404"
- chef_server_rest.post_rest("data", self)
+ raise e unless e.response.code == "409"
end
self
end
diff --git a/lib/chef/dsl/include_recipe.rb b/lib/chef/dsl/include_recipe.rb
index b4d076da10..fc95e38c75 100644
--- a/lib/chef/dsl/include_recipe.rb
+++ b/lib/chef/dsl/include_recipe.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb
index 494d3cee79..82beefeec9 100644
--- a/lib/chef/event_dispatch/base.rb
+++ b/lib/chef/event_dispatch/base.rb
@@ -295,7 +295,7 @@ class Chef
# Called when a provider makes an assumption after a failed assertion
# in whyrun mode, in order to allow execution to continue
- def whyrun_assumption(action, resource, message)
+ def whyrun_assumption(action, resource, message)
end
## TODO: deprecation warning. this way we can queue them up and present
diff --git a/lib/chef/event_dispatch/dispatcher.rb b/lib/chef/event_dispatch/dispatcher.rb
index 82da69a60c..c172a406d8 100644
--- a/lib/chef/event_dispatch/dispatcher.rb
+++ b/lib/chef/event_dispatch/dispatcher.rb
@@ -23,7 +23,7 @@ class Chef
# define the forwarding in one go:
#
- # Define a method that will be forwarded to all
+ # Define a method that will be forwarded to all
def self.def_forwarding_method(method_name)
class_eval(<<-END_OF_METHOD, __FILE__, __LINE__)
def #{method_name}(*args)
diff --git a/lib/chef/file_access_control/windows.rb b/lib/chef/file_access_control/windows.rb
index 35a16337ab..32ac2996bd 100644
--- a/lib/chef/file_access_control/windows.rb
+++ b/lib/chef/file_access_control/windows.rb
@@ -220,7 +220,7 @@ class Chef
flags = 0
#
- # Configure child inheritence only if the the resource is some
+ # Configure child inheritence only if the resource is some
# type of a directory.
#
if resource.is_a? Chef::Resource::Directory
diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb
index 300311819f..e403ed9f5b 100644
--- a/lib/chef/formatters/doc.rb
+++ b/lib/chef/formatters/doc.rb
@@ -188,13 +188,13 @@ class Chef
def resource_update_applied(resource, action, update)
prefix = Chef::Config[:why_run] ? "Would " : ""
Array(update).each do |line|
- next if line.nil?
+ next if line.nil?
output_record line
if line.kind_of? String
@output.color "\n - #{prefix}#{line}", :green
- elsif line.kind_of? Array
- # Expanded output - delta
- # @todo should we have a resource_update_delta callback?
+ elsif line.kind_of? Array
+ # Expanded output - delta
+ # @todo should we have a resource_update_delta callback?
line.each do |detail|
@output.color "\n #{detail}", :white
end
@@ -216,7 +216,7 @@ class Chef
# Called when a provider makes an assumption after a failed assertion
# in whyrun mode, in order to allow execution to continue
- def whyrun_assumption(action, resource, message)
+ def whyrun_assumption(action, resource, message)
return unless message
[ message ].flatten.each do |line|
@output.color("\n * #{line}", :yellow)
diff --git a/lib/chef/formatters/error_inspectors/api_error_formatting.rb b/lib/chef/formatters/error_inspectors/api_error_formatting.rb
index bb5379ed3f..cb64955961 100644
--- a/lib/chef/formatters/error_inspectors/api_error_formatting.rb
+++ b/lib/chef/formatters/error_inspectors/api_error_formatting.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/formatters/error_inspectors/compile_error_inspector.rb b/lib/chef/formatters/error_inspectors/compile_error_inspector.rb
index 1fa8a70b52..93328adbe3 100644
--- a/lib/chef/formatters/error_inspectors/compile_error_inspector.rb
+++ b/lib/chef/formatters/error_inspectors/compile_error_inspector.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/formatters/error_inspectors/cookbook_sync_error_inspector.rb b/lib/chef/formatters/error_inspectors/cookbook_sync_error_inspector.rb
index 054984a50e..56a55a296b 100644
--- a/lib/chef/formatters/error_inspectors/cookbook_sync_error_inspector.rb
+++ b/lib/chef/formatters/error_inspectors/cookbook_sync_error_inspector.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/formatters/error_inspectors/node_load_error_inspector.rb b/lib/chef/formatters/error_inspectors/node_load_error_inspector.rb
index 7168ac0edb..e257ee30c0 100644
--- a/lib/chef/formatters/error_inspectors/node_load_error_inspector.rb
+++ b/lib/chef/formatters/error_inspectors/node_load_error_inspector.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb b/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb
index 9ad56bb70b..6f1f71b8f9 100644
--- a/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb
+++ b/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/handler/json_file.rb b/lib/chef/handler/json_file.rb
index 977c5a2c92..3473db1838 100644
--- a/lib/chef/handler/json_file.rb
+++ b/lib/chef/handler/json_file.rb
@@ -41,11 +41,11 @@ class Chef
build_report_dir
savetime = Time.now.strftime("%Y%m%d%H%M%S")
File.open(File.join(config[:path], "chef-run-report-#{savetime}.json"), "w") do |file|
-
+
#ensure start time and end time are output in the json properly in the event activesupport happens to be on the system
run_data = data
run_data[:start_time] = run_data[:start_time].to_s
- run_data[:end_time] = run_data[:end_time].to_s
+ run_data[:end_time] = run_data[:end_time].to_s
file.puts Chef::JSONCompat.to_json_pretty(run_data)
end
diff --git a/lib/chef/http.rb b/lib/chef/http.rb
new file mode 100644
index 0000000000..2b2466843e
--- /dev/null
+++ b/lib/chef/http.rb
@@ -0,0 +1,386 @@
+#--
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Thom May (<thom@clearairturbulence.org>)
+# Author:: Nuo Yan (<nuo@opscode.com>)
+# Author:: Christopher Brown (<cb@opscode.com>)
+# Author:: Christopher Walters (<cw@opscode.com>)
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2009, 2010, 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'net/https'
+require 'uri'
+require 'chef/http/basic_client'
+require 'chef/monkey_patches/string'
+require 'chef/monkey_patches/net_http'
+require 'chef/config'
+require 'chef/exceptions'
+
+class Chef
+
+ # == Chef::HTTP
+ # Basic HTTP client, with support for adding features via middleware
+ class HTTP
+
+ # Class for applying middleware behaviors to streaming
+ # responses. Collects stream handlers (if any) from each
+ # middleware. When #handle_chunk is called, the chunk gets
+ # passed to all handlers in turn for processing.
+ class StreamHandler
+ def initialize(middlewares, response)
+ middlewares = middlewares.flatten
+ @stream_handlers = []
+ middlewares.each do |middleware|
+ stream_handler = middleware.stream_response_handler(response)
+ @stream_handlers << stream_handler unless stream_handler.nil?
+ end
+ end
+
+ def handle_chunk(next_chunk)
+ @stream_handlers.inject(next_chunk) do |chunk, handler|
+ handler.handle_chunk(chunk)
+ end
+ end
+
+ end
+
+
+ def self.middlewares
+ @middlewares ||= []
+ end
+
+ def self.use(middleware_class)
+ middlewares << middleware_class
+ end
+
+ attr_reader :url
+ attr_reader :sign_on_redirect
+ attr_reader :redirect_limit
+
+ attr_reader :middlewares
+
+ # Create a HTTP client object. The supplied +url+ is used as the base for
+ # all subsequent requests. For example, when initialized with a base url
+ # http://localhost:4000, a call to +get+ with 'nodes' will make an
+ # HTTP GET request to http://localhost:4000/nodes
+ def initialize(url, options={})
+ @url = url
+ @default_headers = options[:headers] || {}
+ @sign_on_redirect = true
+ @redirects_followed = 0
+ @redirect_limit = 10
+
+ @middlewares = []
+ self.class.middlewares.each do |middleware_class|
+ @middlewares << middleware_class.new(options)
+ end
+ end
+
+ # Send an HTTP HEAD request to the path
+ #
+ # === Parameters
+ # path:: path part of the request URL
+ def head(path, headers={})
+ request(:HEAD, path, headers)
+ end
+
+ # Send an HTTP GET request to the path
+ #
+ # === Parameters
+ # path:: The path to GET
+ def get(path, headers={})
+ request(:GET, path, headers)
+ end
+
+ # Send an HTTP PUT request to the path
+ #
+ # === Parameters
+ # path:: path part of the request URL
+ def put(path, json, headers={})
+ request(:PUT, path, headers, json)
+ end
+
+ # Send an HTTP POST request to the path
+ #
+ # === Parameters
+ # path:: path part of the request URL
+ def post(path, json, headers={})
+ request(:POST, path, headers, json)
+ end
+
+ # Send an HTTP DELETE request to the path
+ #
+ # === Parameters
+ # path:: path part of the request URL
+ def delete(path, headers={})
+ request(:DELETE, path, headers)
+ end
+
+ # Makes an HTTP request to +path+ with the given +method+, +headers+, and
+ # +data+ (if applicable).
+ def request(method, path, headers={}, data=false)
+ url = create_url(path)
+ method, url, headers, data = apply_request_middleware(method, url, headers, data)
+
+ response, rest_request, return_value = send_http_request(method, url, headers, data)
+ response, rest_request, return_value = apply_response_middleware(response, rest_request, return_value)
+ response.error! unless success_response?(response)
+ return_value
+ rescue Exception => exception
+ log_failed_request(response, return_value) unless response.nil?
+
+ if exception.respond_to?(:chef_rest_request=)
+ exception.chef_rest_request = rest_request
+ end
+ raise
+ end
+
+ # Makes a streaming download request, streaming the response body to a
+ # tempfile. If a block is given, the tempfile is passed to the block and
+ # the tempfile will automatically be unlinked after the block is executed.
+ #
+ # If no block is given, the tempfile is returned, which means it's up to
+ # you to unlink the tempfile when you're done with it.
+ def streaming_request(path, headers={}, &block)
+ url = create_url(path)
+ response, rest_request, return_value = nil, nil, nil
+ tempfile = nil
+
+ method = :GET
+ method, url, headers, data = apply_request_middleware(method, url, headers, data)
+
+ response, rest_request, return_value = send_http_request(method, url, headers, data) do |http_response|
+ if http_response.kind_of?(Net::HTTPSuccess)
+ tempfile = stream_to_tempfile(url, http_response)
+ if block_given?
+ begin
+ yield tempfile
+ ensure
+ tempfile && tempfile.close!
+ end
+ end
+ end
+ end
+ unless response.kind_of?(Net::HTTPSuccess) or response.kind_of?(Net::HTTPRedirection)
+ response.error!
+ end
+ tempfile
+ rescue Exception => e
+ log_failed_request(response, return_value) unless response.nil?
+ if e.respond_to?(:chef_rest_request=)
+ e.chef_rest_request = rest_request
+ end
+ raise
+ end
+
+ def http_client(base_url=nil)
+ base_url ||= url
+ BasicClient.new(base_url)
+ end
+
+ protected
+
+ def create_url(path)
+ return path if path.is_a?(URI)
+ if path =~ /^(http|https):\/\//
+ URI.parse(path)
+ elsif path.nil? or path.empty?
+ URI.parse(@url)
+ else
+ URI.parse("#{@url}/#{path}")
+ end
+ end
+
+ def apply_request_middleware(method, url, headers, data)
+ middlewares.inject([method, url, headers, data]) do |req_data, middleware|
+ middleware.handle_request(*req_data)
+ end
+ end
+
+ def apply_response_middleware(response, rest_request, return_value)
+ middlewares.reverse.inject([response, rest_request, return_value]) do |res_data, middleware|
+ middleware.handle_response(*res_data)
+ end
+ end
+
+ def log_failed_request(response, return_value)
+ return_value ||= {}
+ error_message = "HTTP Request Returned #{response.code} #{response.message}: "
+ error_message << (return_value["error"].respond_to?(:join) ? return_value["error"].join(", ") : return_value["error"].to_s)
+ Chef::Log.info(error_message)
+ end
+
+ def success_response?(response)
+ response.kind_of?(Net::HTTPSuccess) || response.kind_of?(Net::HTTPRedirection)
+ end
+
+ # Runs a synchronous HTTP request, with no middleware applied (use #request
+ # to have the middleware applied). The entire response will be loaded into memory.
+ def send_http_request(method, url, headers, body, &response_handler)
+ headers = build_headers(method, url, headers, body)
+
+ retrying_http_errors(url) do
+ client = http_client(url)
+ return_value = nil
+ if block_given?
+ request, response = client.request(method, url, body, headers, &response_handler)
+ else
+ request, response = client.request(method, url, body, headers) {|r| r.read_body }
+ return_value = response.read_body
+ end
+ @last_response = response
+
+ Chef::Log.debug("---- HTTP Status and Header Data: ----")
+ Chef::Log.debug("HTTP #{response.http_version} #{response.code} #{response.msg}")
+
+ response.each do |header, value|
+ Chef::Log.debug("#{header}: #{value}")
+ end
+ Chef::Log.debug("---- End HTTP Status/Header Data ----")
+
+ if response.kind_of?(Net::HTTPSuccess)
+ [response, request, return_value]
+ elsif response.kind_of?(Net::HTTPNotModified) # Must be tested before Net::HTTPRedirection because it's subclass.
+ [response, request, false]
+ elsif redirect_location = redirected_to(response)
+ if [:GET, :HEAD].include?(method)
+ follow_redirect do
+ send_http_request(method, create_url(redirect_location), headers, body, &response_handler)
+ end
+ else
+ raise Exceptions::InvalidRedirect, "#{method} request was redirected from #{url} to #{redirect_location}. Only GET and HEAD support redirects."
+ end
+ else
+ [response, request, nil]
+ end
+ end
+ end
+
+
+ # Wraps an HTTP request with retry logic.
+ # === Arguments
+ # url:: URL of the request, used for error messages
+ def retrying_http_errors(url)
+ http_attempts = 0
+ begin
+ http_attempts += 1
+
+ yield
+
+ rescue SocketError, Errno::ETIMEDOUT => e
+ e.message.replace "Error connecting to #{url} - #{e.message}"
+ raise e
+ rescue Errno::ECONNREFUSED
+ if http_retry_count - http_attempts + 1 > 0
+ Chef::Log.error("Connection refused connecting to #{url}, retry #{http_attempts}/#{http_retry_count}")
+ sleep(http_retry_delay)
+ retry
+ end
+ raise Errno::ECONNREFUSED, "Connection refused connecting to #{url}, giving up"
+ rescue Timeout::Error
+ if http_retry_count - http_attempts + 1 > 0
+ Chef::Log.error("Timeout connecting to #{url}, retry #{http_attempts}/#{http_retry_count}")
+ sleep(http_retry_delay)
+ retry
+ end
+ raise Timeout::Error, "Timeout connecting to #{url}, giving up"
+ rescue Net::HTTPFatalError => e
+ if http_retry_count - http_attempts + 1 > 0
+ sleep_time = 1 + (2 ** http_attempts) + rand(2 ** http_attempts)
+ Chef::Log.error("Server returned error for #{url}, retrying #{http_attempts}/#{http_retry_count} in #{sleep_time}s")
+ sleep(sleep_time)
+ retry
+ end
+ raise
+ end
+ end
+
+ def http_retry_delay
+ config[:http_retry_delay]
+ end
+
+ def http_retry_count
+ config[:http_retry_count]
+ end
+
+ def config
+ Chef::Config
+ end
+
+ def follow_redirect
+ raise Chef::Exceptions::RedirectLimitExceeded if @redirects_followed >= redirect_limit
+ @redirects_followed += 1
+ Chef::Log.debug("Following redirect #{@redirects_followed}/#{redirect_limit}")
+
+ yield
+ ensure
+ @redirects_followed = 0
+ end
+
+ private
+
+ def redirected_to(response)
+ return nil unless response.kind_of?(Net::HTTPRedirection)
+ # Net::HTTPNotModified is undesired subclass of Net::HTTPRedirection so test for this
+ return nil if response.kind_of?(Net::HTTPNotModified)
+ response['location']
+ end
+
+ def build_headers(method, url, headers={}, json_body=false)
+ headers = @default_headers.merge(headers)
+ headers['Content-Length'] = json_body.bytesize.to_s if json_body
+ headers.merge!(Chef::Config[:custom_http_headers]) if Chef::Config[:custom_http_headers]
+ headers
+ end
+
+ def stream_to_tempfile(url, response)
+ tf = Tempfile.open("chef-rest")
+ if Chef::Platform.windows?
+ tf.binmode # required for binary files on Windows platforms
+ end
+ Chef::Log.debug("Streaming download from #{url.to_s} to tempfile #{tf.path}")
+ # Stolen from http://www.ruby-forum.com/topic/166423
+ # Kudos to _why!
+
+ stream_handler = StreamHandler.new(middlewares, response)
+
+ response.read_body do |chunk|
+ tf.write(stream_handler.handle_chunk(chunk))
+ end
+ tf.close
+ tf
+ rescue Exception
+ tf.close!
+ raise
+ end
+
+
+ public
+
+ ############################################################################
+ # DEPRECATED
+ ############################################################################
+
+ # This is only kept around to provide access to cache control data in
+ # lib/chef/provider/remote_file/http.rb
+ # Find a better API.
+ def last_response
+ @last_response
+ end
+
+ end
+end
+
diff --git a/lib/chef/rest/auth_credentials.rb b/lib/chef/http/auth_credentials.rb
index 00711c960d..bd73524b1f 100644
--- a/lib/chef/rest/auth_credentials.rb
+++ b/lib/chef/http/auth_credentials.rb
@@ -24,7 +24,7 @@ require 'chef/log'
require 'mixlib/authentication/signedheaderauth'
class Chef
- class REST
+ class HTTP
class AuthCredentials
attr_reader :client_name, :key
diff --git a/lib/chef/http/authenticator.rb b/lib/chef/http/authenticator.rb
new file mode 100644
index 0000000000..489675ad66
--- /dev/null
+++ b/lib/chef/http/authenticator.rb
@@ -0,0 +1,89 @@
+#--
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/http/auth_credentials'
+require 'chef/exceptions'
+require 'openssl'
+
+class Chef
+ class HTTP
+ class Authenticator
+
+ attr_reader :signing_key_filename
+ attr_reader :raw_key
+ attr_reader :attr_names
+ attr_reader :auth_credentials
+
+ attr_accessor :sign_request
+
+ def initialize(opts={})
+ @raw_key = nil
+ @sign_request = true
+ @signing_key_filename = opts[:signing_key_filename]
+ @key = load_signing_key(opts[:signing_key_filename], opts[:raw_key])
+ @auth_credentials = AuthCredentials.new(opts[:client_name], @key)
+ end
+
+ def handle_request(method, url, headers={}, data=false)
+ headers.merge!(authentication_headers(method, url, data)) if sign_requests?
+ [method, url, headers, data]
+ end
+
+ def handle_response(http_response, rest_request, return_value)
+ [http_response, rest_request, return_value]
+ end
+
+ def stream_response_handler(response)
+ nil
+ end
+
+ def sign_requests?
+ auth_credentials.sign_requests? && @sign_request
+ end
+
+ def client_name
+ @auth_credentials.client_name
+ end
+
+ def load_signing_key(key_file, raw_key = nil)
+ if (!!key_file)
+ @raw_key = IO.read(key_file).strip
+ elsif (!!raw_key)
+ @raw_key = raw_key.strip
+ else
+ return nil
+ end
+ @key = OpenSSL::PKey::RSA.new(@raw_key)
+ rescue SystemCallError, IOError => e
+ Chef::Log.warn "Failed to read the private key #{key_file}: #{e.inspect}"
+ raise Chef::Exceptions::PrivateKeyMissing, "I cannot read #{key_file}, which you told me to use to sign requests!"
+ rescue OpenSSL::PKey::RSAError
+ msg = "The file #{key_file} or :raw_key option does not contain a correctly formatted private key.\n"
+ msg << "The key file should begin with '-----BEGIN RSA PRIVATE KEY-----' and end with '-----END RSA PRIVATE KEY-----'"
+ raise Chef::Exceptions::InvalidPrivateKey, msg
+ end
+
+ def authentication_headers(method, url, json_body=nil)
+ request_params = {:http_method => method, :path => url.path, :body => json_body, :host => "#{url.host}:#{url.port}"}
+ request_params[:body] ||= ""
+ auth_credentials.signature_headers(request_params)
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/http/basic_client.rb b/lib/chef/http/basic_client.rb
new file mode 100644
index 0000000000..5ee0fbf88d
--- /dev/null
+++ b/lib/chef/http/basic_client.rb
@@ -0,0 +1,114 @@
+#--
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Thom May (<thom@clearairturbulence.org>)
+# Author:: Nuo Yan (<nuo@opscode.com>)
+# Author:: Christopher Brown (<cb@opscode.com>)
+# Author:: Christopher Walters (<cw@opscode.com>)
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2009, 2010 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+require 'uri'
+require 'net/http'
+require 'chef/http/ssl_policies'
+require 'chef/http/http_request'
+
+class Chef
+ class HTTP
+ class BasicClient
+
+ HTTPS = "https".freeze
+
+ attr_reader :url
+ attr_reader :http_client
+ attr_reader :ssl_policy
+
+ # Instantiate a BasicClient.
+ # === Arguments:
+ # url:: An URI for the remote server.
+ # === Options:
+ # ssl_policy:: The SSL Policy to use, defaults to DefaultSSLPolicy
+ def initialize(url, opts={})
+ @url = url
+ @ssl_policy = opts[:ssl_policy] || DefaultSSLPolicy
+ @http_client = build_http_client
+ end
+
+ def host
+ @url.host
+ end
+
+ def port
+ @url.port
+ end
+
+ def request(method, url, req_body, base_headers={})
+ http_request = HTTPRequest.new(method, url, req_body, base_headers).http_request
+ Chef::Log.debug("Initiating #{method} to #{url}")
+ http_client.request(http_request) do |response|
+ yield response if block_given?
+ # http_client.request may not have the return signature we want, so
+ # force the issue:
+ return [http_request, response]
+ end
+ rescue OpenSSL::SSL::SSLError => e
+ Chef::Log.error("SSL Validation failure connecting to host: #{host} - #{e.message}")
+ raise
+ end
+
+ #adapted from buildr/lib/buildr/core/transports.rb
+ def proxy_uri
+ proxy = Chef::Config["#{url.scheme}_proxy"]
+ proxy = URI.parse(proxy) if String === proxy
+ excludes = Chef::Config[:no_proxy].to_s.split(/\s*,\s*/).compact
+ excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
+ return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
+ end
+
+ def build_http_client
+ http_client = http_client_builder.new(host, port)
+
+ if url.scheme == HTTPS
+ configure_ssl(http_client)
+ end
+
+ http_client.read_timeout = config[:rest_timeout]
+ http_client
+ end
+
+ def config
+ Chef::Config
+ end
+
+ def http_client_builder
+ http_proxy = proxy_uri
+ if http_proxy.nil?
+ Net::HTTP
+ else
+ Chef::Log.debug("Using #{http_proxy.host}:#{http_proxy.port} for proxy")
+ user = Chef::Config["#{url.scheme}_proxy_user"]
+ pass = Chef::Config["#{url.scheme}_proxy_pass"]
+ Net::HTTP.Proxy(http_proxy.host, http_proxy.port, user, pass)
+ end
+ end
+
+ def configure_ssl(http_client)
+ http_client.use_ssl = true
+ ssl_policy.apply_to(http_client)
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/rest/cookie_jar.rb b/lib/chef/http/cookie_jar.rb
index e3137708a2..418fb1d352 100644
--- a/lib/chef/rest/cookie_jar.rb
+++ b/lib/chef/http/cookie_jar.rb
@@ -23,7 +23,7 @@
require 'singleton'
class Chef
- class REST
+ class HTTP
class CookieJar < Hash
include Singleton
end
diff --git a/lib/chef/http/cookie_manager.rb b/lib/chef/http/cookie_manager.rb
new file mode 100644
index 0000000000..f6dcf9aa32
--- /dev/null
+++ b/lib/chef/http/cookie_manager.rb
@@ -0,0 +1,56 @@
+#--
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/http/cookie_jar'
+
+class Chef
+ class HTTP
+
+ # An HTTP middleware to manage storing/sending cookies in HTTP requests.
+ # Most HTTP communication in Chef does not need cookies, it was originally
+ # implemented to support OpenID, but it's not known who might be relying on
+ # it, so it's included with Chef::REST
+ class CookieManager
+
+ def initialize(options={})
+ @cookies = CookieJar.instance
+ end
+
+ def handle_request(method, url, headers={}, data=false)
+ @host, @port = url.host, url.port
+ if @cookies.has_key?("#{@host}:#{@port}")
+ headers['Cookie'] = @cookies["#{@host}:#{@port}"]
+ end
+ [method, url, headers, data]
+ end
+
+ def handle_response(http_response, rest_request, return_value)
+ if http_response['set-cookie']
+ @cookies["#{@host}:#{@port}"] = http_response['set-cookie']
+ end
+ [http_response, rest_request, return_value]
+ end
+
+ def stream_response_handler(response)
+ nil
+ end
+
+
+ end
+ end
+end
diff --git a/lib/chef/http/decompressor.rb b/lib/chef/http/decompressor.rb
new file mode 100644
index 0000000000..6010ffa698
--- /dev/null
+++ b/lib/chef/http/decompressor.rb
@@ -0,0 +1,137 @@
+#--
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'zlib'
+require 'chef/http/http_request'
+
+class Chef
+ class HTTP
+
+ # Middleware-esque class for handling compression in HTTP responses.
+ class Decompressor
+ class NoopInflater
+ def inflate(chunk)
+ chunk
+ end
+ alias :handle_chunk :inflate
+ end
+
+ class GzipInflater < Zlib::Inflate
+ def initialize
+ super(Zlib::MAX_WBITS + 16)
+ end
+ alias :handle_chunk :inflate
+ end
+
+ class DeflateInflater < Zlib::Inflate
+ def initialize
+ super
+ end
+ alias :handle_chunk :inflate
+ end
+
+ CONTENT_ENCODING = "content-encoding".freeze
+ GZIP = "gzip".freeze
+ DEFLATE = "deflate".freeze
+ IDENTITY = "identity".freeze
+
+ def initialize(opts={})
+ @disable_gzip = false
+ handle_options(opts)
+ end
+
+ def handle_request(method, url, headers={}, data=false)
+ headers[HTTPRequest::ACCEPT_ENCODING] = HTTPRequest::ENCODING_GZIP_DEFLATE unless gzip_disabled?
+ [method, url, headers, data]
+ end
+
+ def handle_response(http_response, rest_request, return_value)
+ # temporary hack, skip processing if return_value is false
+ # needed to keep conditional get stuff working correctly.
+ return [http_response, rest_request, return_value] if return_value == false
+ response_body = decompress_body(http_response)
+ http_response.body.replace(response_body) if http_response.body.respond_to?(:replace)
+ [http_response, rest_request, return_value]
+ end
+
+ def decompress_body(response)
+ if gzip_disabled? || response.body.nil?
+ response.body
+ else
+ case response[CONTENT_ENCODING]
+ when GZIP
+ Chef::Log.debug "decompressing gzip response"
+ Zlib::Inflate.new(Zlib::MAX_WBITS + 16).inflate(response.body)
+ when DEFLATE
+ Chef::Log.debug "decompressing deflate response"
+ Zlib::Inflate.inflate(response.body)
+ else
+ response.body
+ end
+ end
+ end
+
+ # This isn't used when this class is used as middleware; it returns an
+ # object you can use to unzip/inflate a streaming response.
+ def stream_response_handler(response)
+ if gzip_disabled?
+ NoopInflater.new
+ else
+ case response[CONTENT_ENCODING]
+ when GZIP
+ Chef::Log.debug "decompressing gzip stream"
+ GzipInflater.new
+ when DEFLATE
+ Chef::Log.debug "decompressing inflate stream"
+ DeflateInflater.new
+ else
+ NoopInflater.new
+ end
+ end
+ end
+
+
+ # gzip is disabled using the disable_gzip => true option in the
+ # constructor. When gzip is disabled, no 'Accept-Encoding' header will be
+ # set, and the response will not be decompressed, no matter what the
+ # Content-Encoding header of the response is. The intended use case for
+ # this is to work around situations where you request +file.tar.gz+, but
+ # the server responds with a content type of tar and a content encoding of
+ # gzip, tricking the client into decompressing the response so you end up
+ # with a tar archive (no gzip) named file.tar.gz
+ def gzip_disabled?
+ @disable_gzip
+ end
+
+ private
+
+ def handle_options(opts)
+ opts.each do |name, value|
+ case name.to_s
+ when 'disable_gzip'
+ @disable_gzip = value
+ end
+ end
+ end
+
+
+ end
+ end
+end
+
+
diff --git a/lib/chef/rest/rest_request.rb b/lib/chef/http/http_request.rb
index ff9738de99..ec837f13f2 100644
--- a/lib/chef/rest/rest_request.rb
+++ b/lib/chef/http/http_request.rb
@@ -22,7 +22,6 @@
#
require 'uri'
require 'net/http'
-require 'chef/rest/cookie_jar'
# To load faster, we only want ohai's version string.
# However, in ohai before 0.6.0, the version is defined
@@ -36,8 +35,8 @@ end
require 'chef/version'
class Chef
- class REST
- class RESTRequest
+ class HTTP
+ class HTTPRequest
engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
@@ -72,8 +71,6 @@ class Chef
def initialize(method, url, req_body, base_headers={})
@method, @url = method, url
@request_body = nil
- @cookies = CookieJar.instance
- configure_http_client
build_headers(base_headers)
configure_http_request(req_body)
end
@@ -94,10 +91,10 @@ class Chef
@url.path.empty? ? SLASH : @url.path
end
+ # DEPRECATED. Call request on an HTTP client object instead.
def call
hide_net_http_bug do
http_client.request(http_request) do |response|
- store_cookie(response)
yield response if block_given?
response
end
@@ -108,6 +105,11 @@ class Chef
Chef::Config
end
+ # DEPRECATED. Call request on an HTTP client object instead.
+ def http_client
+ @http_client ||= BasicClient.new(url).http_client
+ end
+
private
def hide_net_http_bug
@@ -125,77 +127,12 @@ class Chef
end
end
- def store_cookie(response)
- if response['set-cookie']
- @cookies["#{host}:#{port}"] = response['set-cookie']
- end
- end
-
def build_headers(headers)
@headers = headers.dup
- # TODO: need to set accept somewhere else
- # headers.merge!('Accept' => "application/json") unless raw
+ # No response compression unless we asked for it explicitly:
+ @headers[HTTPRequest::ACCEPT_ENCODING] ||= "identity"
@headers['X-Chef-Version'] = ::Chef::VERSION
- @headers[ACCEPT_ENCODING] = ENCODING_GZIP_DEFLATE
-
- if @cookies.has_key?("#{host}:#{port}")
- @headers['Cookie'] = @cookies["#{host}:#{port}"]
- end
- end
-
- #adapted from buildr/lib/buildr/core/transports.rb
- def proxy_uri
- proxy = Chef::Config["#{url.scheme}_proxy"]
- proxy = URI.parse(proxy) if String === proxy
- excludes = Chef::Config[:no_proxy].to_s.split(/\s*,\s*/).compact
- excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
- return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
- end
-
- def configure_http_client
- http_proxy = proxy_uri
- if http_proxy.nil?
- @http_client = Net::HTTP.new(host, port)
- else
- Chef::Log.debug("Using #{http_proxy.host}:#{http_proxy.port} for proxy")
- user = Chef::Config["#{url.scheme}_proxy_user"]
- pass = Chef::Config["#{url.scheme}_proxy_pass"]
- @http_client = Net::HTTP.Proxy(http_proxy.host, http_proxy.port, user, pass).new(host, port)
- end
- if url.scheme == HTTPS
- @http_client.use_ssl = true
- if config[:ssl_verify_mode] == :verify_none
- @http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
- elsif config[:ssl_verify_mode] == :verify_peer
- @http_client.verify_mode = OpenSSL::SSL::VERIFY_PEER
- end
- if config[:ssl_ca_path]
- unless ::File.exist?(config[:ssl_ca_path])
- raise Chef::Exceptions::ConfigurationError, "The configured ssl_ca_path #{config[:ssl_ca_path]} does not exist"
- end
- @http_client.ca_path = config[:ssl_ca_path]
- elsif config[:ssl_ca_file]
- unless ::File.exist?(config[:ssl_ca_file])
- raise Chef::Exceptions::ConfigurationError, "The configured ssl_ca_file #{config[:ssl_ca_file]} does not exist"
- end
- @http_client.ca_file = config[:ssl_ca_file]
- end
- if (config[:ssl_client_cert] || config[:ssl_client_key])
- unless (config[:ssl_client_cert] && config[:ssl_client_key])
- raise Chef::Exceptions::ConfigurationError, "You must configure ssl_client_cert and ssl_client_key together"
- end
- unless ::File.exists?(config[:ssl_client_cert])
- raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_cert #{config[:ssl_client_cert]} does not exist"
- end
- unless ::File.exists?(config[:ssl_client_key])
- raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_key #{config[:ssl_client_key]} does not exist"
- end
- @http_client.cert = OpenSSL::X509::Certificate.new(::File.read(config[:ssl_client_cert]))
- @http_client.key = OpenSSL::PKey::RSA.new(::File.read(config[:ssl_client_key]))
- end
- end
-
- @http_client.read_timeout = config[:rest_timeout]
+ @headers
end
@@ -225,6 +162,8 @@ class Chef
password = URI.unescape(url.password) if url.password
@http_request.basic_auth(user, password)
end
+
+ # Overwrite default UA
@http_request[USER_AGENT] = self.class.user_agent
end
diff --git a/lib/chef/http/json_input.rb b/lib/chef/http/json_input.rb
new file mode 100644
index 0000000000..741c48f5f6
--- /dev/null
+++ b/lib/chef/http/json_input.rb
@@ -0,0 +1,53 @@
+#--
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/json_compat'
+
+class Chef
+ class HTTP
+
+ # Middleware that takes json input and turns it into raw text
+ class JSONInput
+
+ def initialize(opts={})
+ end
+
+ def handle_request(method, url, headers={}, data=false)
+ if data
+ headers["Content-Type"] = 'application/json'
+ data = Chef::JSONCompat.to_json(data)
+ # Force encoding to binary to fix SSL related EOFErrors
+ # cf. http://tickets.opscode.com/browse/CHEF-2363
+ # http://redmine.ruby-lang.org/issues/5233
+ data.force_encoding(Encoding::BINARY) if data.respond_to?(:force_encoding)
+ end
+ [method, url, headers, data]
+ end
+
+ def handle_response(http_response, rest_request, return_value)
+ [http_response, rest_request, return_value]
+ end
+
+ def stream_response_handler(response)
+ nil
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/http/json_output.rb b/lib/chef/http/json_output.rb
new file mode 100644
index 0000000000..48407d933f
--- /dev/null
+++ b/lib/chef/http/json_output.rb
@@ -0,0 +1,69 @@
+#--
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/json_compat'
+require 'chef/log'
+
+class Chef
+ class HTTP
+
+ # Middleware that takes an HTTP response, parses it as JSON if possible.
+ class JSONOutput
+
+ def initialize(opts={})
+ @raw_output = opts[:raw_output]
+ @inflate_json_class = opts[:inflate_json_class]
+ end
+
+ def handle_request(method, url, headers={}, data=false)
+ # Ideally this should always set Accept to application/json, but
+ # Chef::REST is sometimes used to make non-JSON requests, so it sets
+ # Accept to the desired value before middlewares get called.
+ headers['Accept'] ||= 'application/json'
+ [method, url, headers, data]
+ end
+
+ def handle_response(http_response, rest_request, return_value)
+ # temporary hack, skip processing if return_value is false
+ # needed to keep conditional get stuff working correctly.
+ return [http_response, rest_request, return_value] if return_value == false
+ if http_response['content-type'] =~ /json/
+ if @raw_output
+ return_value = http_response.body.to_s
+ else
+ if @inflate_json_class
+ return_value = Chef::JSONCompat.from_json(http_response.body.chomp)
+ else
+ return_value = Chef::JSONCompat.from_json(http_response.body.chomp, :create_additions => false)
+ end
+ end
+ [http_response, rest_request, return_value]
+ else
+ Chef::Log.warn("Expected JSON response, but got content-type '#{http_response['content-type']}'")
+ return [http_response, rest_request, http_response.body.to_s]
+ end
+ end
+
+ def stream_response_handler(response)
+ nil
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/http/json_to_model_output.rb b/lib/chef/http/json_to_model_output.rb
new file mode 100644
index 0000000000..9bc90a52ae
--- /dev/null
+++ b/lib/chef/http/json_to_model_output.rb
@@ -0,0 +1,34 @@
+#--
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/http/json_output'
+
+class Chef
+ class HTTP
+
+ # A Middleware-ish thing that takes an HTTP response, parses it as JSON if
+ # possible, and converts it into an appropriate model object if it contains
+ # a `json_class` key.
+ class JSONToModelOutput < JSONOutput
+ def initialize(opts={})
+ opts[:inflate_json_class] = true if !opts.has_key?(:inflate_json_class)
+ super
+ end
+ end
+ end
+end
diff --git a/lib/chef/http/simple.rb b/lib/chef/http/simple.rb
new file mode 100644
index 0000000000..0ecb28846c
--- /dev/null
+++ b/lib/chef/http/simple.rb
@@ -0,0 +1,16 @@
+require 'chef/http'
+require 'chef/http/authenticator'
+require 'chef/http/decompressor'
+
+
+class Chef
+ class HTTP
+
+ class Simple < HTTP
+
+ use Decompressor
+ use CookieManager
+
+ end
+ end
+end
diff --git a/lib/chef/http/ssl_policies.rb b/lib/chef/http/ssl_policies.rb
new file mode 100644
index 0000000000..17b46a6762
--- /dev/null
+++ b/lib/chef/http/ssl_policies.rb
@@ -0,0 +1,121 @@
+#--
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Thom May (<thom@clearairturbulence.org>)
+# Author:: Nuo Yan (<nuo@opscode.com>)
+# Author:: Christopher Brown (<cb@opscode.com>)
+# Author:: Christopher Walters (<cw@opscode.com>)
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2009, 2010, 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'openssl'
+
+class Chef
+ class HTTP
+
+ # == Chef::HTTP::DefaultSSLPolicy
+ # Configures SSL behavior on an HTTP object via visitor pattern.
+ class DefaultSSLPolicy
+
+ def self.apply_to(http_client)
+ new(http_client).apply
+ http_client
+ end
+
+ attr_reader :http_client
+
+ def initialize(http_client)
+ @http_client = http_client
+ end
+
+ def apply
+ set_verify_mode
+ set_ca_store
+ set_custom_certs
+ set_client_credentials
+ end
+
+ def set_verify_mode
+ if config[:ssl_verify_mode] == :verify_none
+ http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ elsif config[:ssl_verify_mode] == :verify_peer
+ http_client.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ end
+ end
+
+ def set_ca_store
+ if config[:ssl_ca_path]
+ unless ::File.exist?(config[:ssl_ca_path])
+ raise Chef::Exceptions::ConfigurationError, "The configured ssl_ca_path #{config[:ssl_ca_path]} does not exist"
+ end
+ http_client.ca_path = config[:ssl_ca_path]
+ elsif config[:ssl_ca_file]
+ unless ::File.exist?(config[:ssl_ca_file])
+ raise Chef::Exceptions::ConfigurationError, "The configured ssl_ca_file #{config[:ssl_ca_file]} does not exist"
+ end
+ http_client.ca_file = config[:ssl_ca_file]
+ end
+ end
+
+ def set_custom_certs
+ unless http_client.cert_store
+ http_client.cert_store = OpenSSL::X509::Store.new
+ http_client.cert_store.set_default_paths
+ end
+ if config.trusted_certs_dir
+ certs = Dir.glob(File.join(config.trusted_certs_dir, "*.{crt,pem}"))
+ certs.each do |cert_file|
+ cert = OpenSSL::X509::Certificate.new(File.read(cert_file))
+ http_client.cert_store.add_cert(cert)
+ end
+ end
+ end
+
+ def set_client_credentials
+ if (config[:ssl_client_cert] || config[:ssl_client_key])
+ unless (config[:ssl_client_cert] && config[:ssl_client_key])
+ raise Chef::Exceptions::ConfigurationError, "You must configure ssl_client_cert and ssl_client_key together"
+ end
+ unless ::File.exists?(config[:ssl_client_cert])
+ raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_cert #{config[:ssl_client_cert]} does not exist"
+ end
+ unless ::File.exists?(config[:ssl_client_key])
+ raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_key #{config[:ssl_client_key]} does not exist"
+ end
+ http_client.cert = OpenSSL::X509::Certificate.new(::File.read(config[:ssl_client_cert]))
+ http_client.key = OpenSSL::PKey::RSA.new(::File.read(config[:ssl_client_key]))
+ end
+ end
+
+ def config
+ Chef::Config
+ end
+
+ end
+
+ class APISSLPolicy < DefaultSSLPolicy
+
+ def set_verify_mode
+ if config[:ssl_verify_mode] == :verify_peer or config[:verify_api_cert]
+ http_client.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ elsif config[:ssl_verify_mode] == :verify_none
+ http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ end
+ end
+ end
+
+ end
+end
diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb
index 9c48925216..341402242e 100644
--- a/lib/chef/knife.rb
+++ b/lib/chef/knife.rb
@@ -20,6 +20,7 @@
require 'forwardable'
require 'chef/version'
require 'mixlib/cli'
+require 'chef/config_fetcher'
require 'chef/mixin/convert_to_class_name'
require 'chef/mixin/path_sanity'
require 'chef/knife/core/subcommand_loader'
@@ -314,7 +315,11 @@ class Chef
config_file_settings
end
- def locate_config_file
+ def self.config_fetcher(candidate_config)
+ Chef::ConfigFetcher.new(candidate_config, Chef::Config.config_file_jail)
+ end
+
+ def self.locate_config_file
candidate_configs = []
# Look for $KNIFE_HOME/knife.rb (allow multiple knives config on same machine)
@@ -326,8 +331,8 @@ class Chef
candidate_configs << File.join(Dir.pwd, 'knife.rb')
end
# Look for $UPWARD/.chef/knife.rb
- if self.class.chef_config_dir
- candidate_configs << File.join(self.class.chef_config_dir, 'knife.rb')
+ if chef_config_dir
+ candidate_configs << File.join(chef_config_dir, 'knife.rb')
end
# Look for $HOME/.chef/knife.rb
if ENV['HOME']
@@ -335,12 +340,12 @@ class Chef
end
candidate_configs.each do | candidate_config |
- candidate_config = File.expand_path(candidate_config)
- if File.exist?(candidate_config)
- config[:config_file] = candidate_config
- break
+ fetcher = config_fetcher(candidate_config)
+ if !fetcher.config_missing?
+ return candidate_config
end
end
+ return nil
end
# Apply Config in this order:
@@ -379,6 +384,12 @@ class Chef
Chef::Config[:chef_server_url] = config[:chef_server_url] if config[:chef_server_url]
Chef::Config[:environment] = config[:environment] if config[:environment]
+ Chef::Config.local_mode = config[:local_mode] if config.has_key?(:local_mode)
+ if Chef::Config.local_mode && !Chef::Config.has_key?(:cookbook_path) && !Chef::Config.has_key?(:chef_repo_path)
+ Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Dir.pwd)
+ end
+ Chef::Config.chef_zero.port = config[:chef_zero_port] if config[:chef_zero_port]
+
# Expand a relative path from the config directory. Config from command
# line should already be expanded, and absolute paths will be unchanged.
if Chef::Config[:client_key] && config[:config_file]
@@ -397,14 +408,20 @@ class Chef
end
def configure_chef
- unless config[:config_file]
- locate_config_file
+ if !config[:config_file]
+ located_config_file = self.class.locate_config_file
+ config[:config_file] = located_config_file if located_config_file
end
- # Don't try to load a knife.rb if it doesn't exist.
+ # Don't try to load a knife.rb if it wasn't specified.
if config[:config_file]
+ fetcher = Chef::ConfigFetcher.new(config[:config_file], Chef::Config.config_file_jail)
+ if fetcher.config_missing?
+ ui.error("Specified config file #{config[:config_file]} does not exist#{Chef::Config.config_file_jail ? " or is not under config file jail #{Chef::Config.config_file_jail}" : ""}!")
+ exit 1
+ end
Chef::Log.debug("Using configuration from #{config[:config_file]}")
- read_config_file(config[:config_file])
+ read_config(fetcher.read_config, config[:config_file])
else
# ...but do log a message if no config was found.
Chef::Config[:color] = config[:color]
@@ -415,24 +432,24 @@ class Chef
apply_computed_config
end
- def read_config_file(file)
- Chef::Config.from_file(file)
+ def read_config(config_content, config_file_path)
+ Chef::Config.from_string(config_content, config_file_path)
rescue SyntaxError => e
- ui.error "You have invalid ruby syntax in your config file #{file}"
+ ui.error "You have invalid ruby syntax in your config file #{config_file_path}"
ui.info(ui.color(e.message, :red))
- if file_line = e.message[/#{Regexp.escape(file)}:[\d]+/]
+ if file_line = e.message[/#{Regexp.escape(config_file_path)}:[\d]+/]
line = file_line[/:([\d]+)$/, 1].to_i
- highlight_config_error(file, line)
+ highlight_config_error(config_file_path, line)
end
exit 1
rescue Exception => e
- ui.error "You have an error in your config file #{file}"
+ ui.error "You have an error in your config file #{config_file_path}"
ui.info "#{e.class.name}: #{e.message}"
- filtered_trace = e.backtrace.grep(/#{Regexp.escape(file)}/)
+ filtered_trace = e.backtrace.grep(/#{Regexp.escape(config_file_path)}/)
filtered_trace.each {|line| ui.msg(" " + ui.color(line, :red))}
if !filtered_trace.empty?
- line_nr = filtered_trace.first[/#{Regexp.escape(file)}:([\d]+)/, 1]
- highlight_config_error(file, line_nr.to_i)
+ line_nr = filtered_trace.first[/#{Regexp.escape(config_file_path)}:([\d]+)/, 1]
+ highlight_config_error(config_file_path, line_nr.to_i)
end
exit 1
@@ -458,14 +475,19 @@ class Chef
stdout.puts("USAGE: " + self.opt_parser.to_s)
end
- def run_with_pretty_exceptions
+ def run_with_pretty_exceptions(raise_exception = false)
unless self.respond_to?(:run)
ui.error "You need to add a #run method to your knife command before you can use it"
end
enforce_path_sanity
- run
+ Chef::Application.setup_server_connectivity
+ begin
+ run
+ ensure
+ Chef::Application.destroy_server_connectivity
+ end
rescue Exception => e
- raise if Chef::Config[:verbosity] == 2
+ raise if raise_exception || Chef::Config[:verbosity] == 2
humanize_exception(e)
exit 100
end
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index 942a5681b8..e88bbc1f19 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -89,6 +89,11 @@ class Chef
:description => "The proxy server for the node being bootstrapped",
:proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
+ option :bootstrap_no_proxy,
+ :long => "--bootstrap-no-proxy [NO_PROXY_URL|NO_PROXY_IP]",
+ :description => "Do not proxy locations for the node being bootstrapped",
+ :proc => Proc.new { |np| Chef::Config[:knife][:bootstrap_no_proxy] = np }
+
option :distro,
:short => "-d DISTRO",
:long => "--distro DISTRO",
@@ -141,11 +146,13 @@ class Chef
option :secret,
:short => "-s SECRET",
:long => "--secret ",
- :description => "The secret key to use to encrypt data bag item values"
+ :description => "The secret key to use to encrypt data bag item values",
+ :proc => Proc.new { |s| Chef::Config[:knife][:secret] = s }
option :secret_file,
:long => "--secret-file SECRET_FILE",
- :description => "A file containing the secret key to use to encrypt data bag item values"
+ :description => "A file containing the secret key to use to encrypt data bag item values",
+ :proc => Proc.new { |sf| Chef::Config[:knife][:secret_file] = sf }
def find_template(template=nil)
# Are we bootstrapping using an already shipped template?
@@ -244,7 +251,7 @@ class Chef
command = render_template(read_template)
if config[:use_sudo]
- command = config[:use_sudo_password] ? "echo #{config[:ssh_password]} | sudo -S #{command}" : "sudo #{command}"
+ command = config[:use_sudo_password] ? "echo '#{config[:ssh_password]}' | sudo -S #{command}" : "sudo #{command}"
end
command
diff --git a/lib/chef/knife/bootstrap/chef-full.erb b/lib/chef/knife/bootstrap/chef-full.erb
index 974b522653..549ffaea8c 100644
--- a/lib/chef/knife/bootstrap/chef-full.erb
+++ b/lib/chef/knife/bootstrap/chef-full.erb
@@ -1,5 +1,13 @@
bash -c '
-<%= "export http_proxy=\"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] -%>
+<%= "export https_proxy=\"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] -%>
+
+distro=`uname -s`
+
+if [ "X$distro" == "XSunOS" ]; then
+ if [ -e "/usr/sfw/bin" ]; then
+ export PATH=/usr/sfw/bin:$PATH
+ fi
+fi
exists() {
if command -v $1 &>/dev/null
diff --git a/lib/chef/knife/client_create.rb b/lib/chef/knife/client_create.rb
index 5b5078b574..285254aef0 100644
--- a/lib/chef/knife/client_create.rb
+++ b/lib/chef/knife/client_create.rb
@@ -61,7 +61,7 @@ class Chef
# We only get a private_key on client creation, not on client update.
if client['private_key']
ui.info("Created #{output}")
-
+
if config[:file]
File.open(config[:file], "w") do |f|
f.print(client['private_key'])
diff --git a/lib/chef/knife/configure.rb b/lib/chef/knife/configure.rb
index 8e725952b4..3ad4fac970 100644
--- a/lib/chef/knife/configure.rb
+++ b/lib/chef/knife/configure.rb
@@ -57,7 +57,7 @@ class Chef
option :validation_key,
:long => "--validation-key PATH",
- :description => "The location of the location of the validation key (usually a file named validation.pem)"
+ :description => "The location of the validation key (usually a file named validation.pem)"
def configure_chef
# We are just faking out the system so that you can do this without a key specified
diff --git a/lib/chef/knife/cookbook_create.rb b/lib/chef/knife/cookbook_create.rb
index 4e6b8d0c1f..01bd8293f3 100644
--- a/lib/chef/knife/cookbook_create.rb
+++ b/lib/chef/knife/cookbook_create.rb
@@ -214,7 +214,7 @@ EOH
TODO: Enter the cookbook description here.
e.g.
-This cookbook makes your favorite breakfast sandwhich.
+This cookbook makes your favorite breakfast sandwich.
== Requirements
TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc.
@@ -224,7 +224,7 @@ e.g.
- +toaster+ - #{cookbook_name} needs toaster to brown your bagel.
== Attributes
-TODO: List you cookbook attributes here.
+TODO: List your cookbook attributes here.
e.g.
==== #{cookbook_name}::default
@@ -263,7 +263,7 @@ TODO: (optional) If this is a public cookbook, detail the process for contributi
e.g.
1. Fork the repository on Github
2. Create a named feature branch (like `add_component_x`)
-3. Write you change
+3. Write your change
4. Write tests for your change (if applicable)
5. Run the tests, ensuring they all pass
6. Submit a Pull Request using Github
@@ -278,7 +278,7 @@ EOH
TODO: Enter the cookbook description here.
e.g.
-This cookbook makes your favorite breakfast sandwhich.
+This cookbook makes your favorite breakfast sandwich.
Requirements
------------
@@ -333,7 +333,7 @@ TODO: (optional) If this is a public cookbook, detail the process for contributi
e.g.
1. Fork the repository on Github
2. Create a named feature branch (like `add_component_x`)
-3. Write you change
+3. Write your change
4. Write tests for your change (if applicable)
5. Run the tests, ensuring they all pass
6. Submit a Pull Request using Github
@@ -349,7 +349,7 @@ EOH
TODO: Enter the cookbook description here.
e.g.
- This cookbook makes your favorite breakfast sandwhich.
+ This cookbook makes your favorite breakfast sandwich.
Requirements
TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc.
@@ -386,7 +386,7 @@ Contributing
e.g.
1. Fork the repository on Github
2. Create a named feature branch (like `add_component_x`)
- 3. Write you change
+ 3. Write your change
4. Write tests for your change (if applicable)
5. Run the tests, ensuring they all pass
6. Submit a Pull Request using Github
diff --git a/lib/chef/knife/cookbook_download.rb b/lib/chef/knife/cookbook_download.rb
index 6132c9dca0..cb8eeb8edf 100644
--- a/lib/chef/knife/cookbook_download.rb
+++ b/lib/chef/knife/cookbook_download.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/knife/cookbook_metadata_from_file.rb b/lib/chef/knife/cookbook_metadata_from_file.rb
index eb1afa8b11..8e26251d6e 100644
--- a/lib/chef/knife/cookbook_metadata_from_file.rb
+++ b/lib/chef/knife/cookbook_metadata_from_file.rb
@@ -9,9 +9,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/knife/cookbook_show.rb b/lib/chef/knife/cookbook_show.rb
index 3545d20817..7c9cbebdb1 100644
--- a/lib/chef/knife/cookbook_show.rb
+++ b/lib/chef/knife/cookbook_show.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -50,7 +50,7 @@ class Chef
:long => "--with-uri",
:description => "Show corresponding URIs"
- def run
+ def run
case @name_args.length
when 4 # We are showing a specific file
node = Hash.new
diff --git a/lib/chef/knife/cookbook_site_install.rb b/lib/chef/knife/cookbook_site_install.rb
index d7a3bfd62c..913d171b3c 100644
--- a/lib/chef/knife/cookbook_site_install.rb
+++ b/lib/chef/knife/cookbook_site_install.rb
@@ -151,11 +151,11 @@ class Chef
ui.info("Removing pre-existing version.")
FileUtils.rmtree(cookbook_path) if File.directory?(cookbook_path)
end
-
+
def convert_path(upstream_file)
if ENV['MSYSTEM'] == 'MINGW32'
return upstream_file.sub(/^([[:alpha:]]):/, '/\1')
- else
+ else
return Shellwords.escape upstream_file
end
end
diff --git a/lib/chef/knife/cookbook_site_list.rb b/lib/chef/knife/cookbook_site_list.rb
index 96c4ef0eed..fe83b71388 100644
--- a/lib/chef/knife/cookbook_site_list.rb
+++ b/lib/chef/knife/cookbook_site_list.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/knife/cookbook_site_search.rb b/lib/chef/knife/cookbook_site_search.rb
index 5df7d67327..b636276cba 100644
--- a/lib/chef/knife/cookbook_site_search.rb
+++ b/lib/chef/knife/cookbook_site_search.rb
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -36,7 +36,7 @@ class Chef
end
new_start = start + cr["items"].length
if new_start < cr["total"]
- search_cookbook(query, items, new_start, cookbook_collection)
+ search_cookbook(query, items, new_start, cookbook_collection)
else
cookbook_collection
end
diff --git a/lib/chef/knife/cookbook_site_show.rb b/lib/chef/knife/cookbook_site_show.rb
index a02dd61fc8..d15098e915 100644
--- a/lib/chef/knife/cookbook_site_show.rb
+++ b/lib/chef/knife/cookbook_site_show.rb
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,10 +27,10 @@ class Chef
def run
output(format_for_display(get_cookbook_data))
end
-
+
def get_cookbook_data
case @name_args.length
- when 1
+ when 1
noauth_rest.get_rest("http://cookbooks.opscode.com/api/v1/cookbooks/#{@name_args[0]}")
when 2
noauth_rest.get_rest("http://cookbooks.opscode.com/api/v1/cookbooks/#{@name_args[0]}/versions/#{name_args[1].gsub('.', '_')}")
@@ -45,7 +45,7 @@ class Chef
end
new_start = start + cr["items"].length
if new_start < cr["total"]
- get_cookbook_list(items, new_start, cookbook_collection)
+ get_cookbook_list(items, new_start, cookbook_collection)
else
cookbook_collection
end
diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb
index 248d7c7a64..e1ad606c80 100644
--- a/lib/chef/knife/core/bootstrap_context.rb
+++ b/lib/chef/knife/core/bootstrap_context.rb
@@ -51,9 +51,9 @@ class Chef
end
def encrypted_data_bag_secret
- @config[:secret] || begin
- if @config[:secret_file] && File.exist?(@config[:secret_file])
- IO.read(File.expand_path(@config[:secret_file]))
+ knife_config[:secret] || begin
+ if knife_config[:secret_file] && File.exist?(knife_config[:secret_file])
+ IO.read(File.expand_path(knife_config[:secret_file]))
elsif @chef_config[:encrypted_data_bag_secret] && File.exist?(@chef_config[:encrypted_data_bag_secret])
IO.read(File.expand_path(@chef_config[:encrypted_data_bag_secret]))
end
@@ -78,6 +78,10 @@ CONFIG
client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n}
end
+ if knife_config[:bootstrap_no_proxy]
+ client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n}
+ end
+
if encrypted_data_bag_secret
client_rb << %Q{encrypted_data_bag_secret "/etc/chef/encrypted_data_bag_secret"\n}
end
diff --git a/lib/chef/knife/core/node_presenter.rb b/lib/chef/knife/core/node_presenter.rb
index a35baf2264..d1aab592ef 100644
--- a/lib/chef/knife/core/node_presenter.rb
+++ b/lib/chef/knife/core/node_presenter.rb
@@ -86,7 +86,7 @@ class Chef
# Converts a Chef::Node object to a string suitable for output to a
# terminal. If config[:medium_output] or config[:long_output] are set
# the volume of output is adjusted accordingly. Uses colors if enabled
- # in the the ui object.
+ # in the ui object.
def summarize(data)
if data.kind_of?(Chef::Node)
node = data
diff --git a/lib/chef/knife/core/subcommand_loader.rb b/lib/chef/knife/core/subcommand_loader.rb
index 2475717441..91c0590121 100644
--- a/lib/chef/knife/core/subcommand_loader.rb
+++ b/lib/chef/knife/core/subcommand_loader.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -112,7 +112,7 @@ class Chef
check_spec_for_glob(spec, glob)
end
end.flatten
-
+
files.concat gem_files
files.uniq! if check_load_path
@@ -133,9 +133,9 @@ class Chef
else
spec.require_paths.first
end
-
+
glob = File.join("#{spec.full_gem_path}/#{dirs}", glob)
-
+
Dir[glob].map { |f| f.untaint }
end
end
diff --git a/lib/chef/knife/core/ui.rb b/lib/chef/knife/core/ui.rb
index f18d30a039..d0bdaa7ac0 100644
--- a/lib/chef/knife/core/ui.rb
+++ b/lib/chef/knife/core/ui.rb
@@ -167,7 +167,7 @@ class Chef
if (!config[:disable_editing])
filename = "knife-edit-"
0.upto(20) { filename += rand(9).to_s }
- filename << ".js"
+ filename << ".json"
filename = File.join(Dir.tmpdir, filename)
tf = File.open(filename, "w")
tf.sync = true
diff --git a/lib/chef/knife/data_bag_create.rb b/lib/chef/knife/data_bag_create.rb
index e644ab78d3..55c1c71798 100644
--- a/lib/chef/knife/data_bag_create.rb
+++ b/lib/chef/knife/data_bag_create.rb
@@ -32,13 +32,15 @@ class Chef
category "data bag"
option :secret,
- :short => "-s SECRET",
- :long => "--secret ",
- :description => "The secret key to use to encrypt data bag item values"
+ :short => "-s SECRET",
+ :long => "--secret ",
+ :description => "The secret key to use to encrypt data bag item values",
+ :proc => Proc.new { |s| Chef::Config[:knife][:secret] = s }
option :secret_file,
- :long => "--secret-file SECRET_FILE",
- :description => "A file containing the secret key to use to encrypt data bag item values"
+ :long => "--secret-file SECRET_FILE",
+ :description => "A file containing the secret key to use to encrypt data bag item values",
+ :proc => Proc.new { |sf| Chef::Config[:knife][:secret_file] = sf }
def read_secret
if config[:secret]
diff --git a/lib/chef/knife/data_bag_delete.rb b/lib/chef/knife/data_bag_delete.rb
index f8e52018a6..575e9d604d 100644
--- a/lib/chef/knife/data_bag_delete.rb
+++ b/lib/chef/knife/data_bag_delete.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,7 +29,7 @@ class Chef
banner "knife data bag delete BAG [ITEM] (options)"
category "data bag"
- def run
+ def run
if @name_args.length == 2
delete_object(Chef::DataBagItem, @name_args[1], "data_bag_item") do
rest.delete_rest("data/#{@name_args[0]}/#{@name_args[1]}")
diff --git a/lib/chef/knife/data_bag_edit.rb b/lib/chef/knife/data_bag_edit.rb
index 234c77177d..b3f53af919 100644
--- a/lib/chef/knife/data_bag_edit.rb
+++ b/lib/chef/knife/data_bag_edit.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -32,13 +32,15 @@ class Chef
category "data bag"
option :secret,
- :short => "-s SECRET",
- :long => "--secret ",
- :description => "The secret key to use to encrypt data bag item values"
+ :short => "-s SECRET",
+ :long => "--secret ",
+ :description => "The secret key to use to encrypt data bag item values",
+ :proc => Proc.new { |s| Chef::Config[:knife][:secret] = s }
option :secret_file,
- :long => "--secret-file SECRET_FILE",
- :description => "A file containing the secret key to use to encrypt data bag item values"
+ :long => "--secret-file SECRET_FILE",
+ :description => "A file containing the secret key to use to encrypt data bag item values",
+ :proc => Proc.new { |sf| Chef::Config[:knife][:secret_file] = sf }
def read_secret
if config[:secret]
diff --git a/lib/chef/knife/data_bag_from_file.rb b/lib/chef/knife/data_bag_from_file.rb
index 275cbeac52..4c90fe6c6c 100644
--- a/lib/chef/knife/data_bag_from_file.rb
+++ b/lib/chef/knife/data_bag_from_file.rb
@@ -35,18 +35,20 @@ class Chef
category "data bag"
option :secret,
- :short => "-s SECRET",
- :long => "--secret ",
- :description => "The secret key to use to encrypt data bag item values"
+ :short => "-s SECRET",
+ :long => "--secret ",
+ :description => "The secret key to use to encrypt data bag item values",
+ :proc => Proc.new { |s| Chef::Config[:knife][:secret] = s }
option :secret_file,
- :long => "--secret-file SECRET_FILE",
- :description => "A file containing the secret key to use to encrypt data bag item values"
+ :long => "--secret-file SECRET_FILE",
+ :description => "A file containing the secret key to use to encrypt data bag item values",
+ :proc => Proc.new { |sf| Chef::Config[:knife][:secret_file] = sf }
option :all,
- :short => "-a",
- :long => "--all",
- :description => "Upload all data bags or all items for specified data bags"
+ :short => "-a",
+ :long => "--all",
+ :description => "Upload all data bags or all items for specified data bags"
def read_secret
if config[:secret]
diff --git a/lib/chef/knife/data_bag_list.rb b/lib/chef/knife/data_bag_list.rb
index 31dcf984f6..5e556b60bc 100644
--- a/lib/chef/knife/data_bag_list.rb
+++ b/lib/chef/knife/data_bag_list.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/knife/data_bag_show.rb b/lib/chef/knife/data_bag_show.rb
index 81b1425f78..519859ca2d 100644
--- a/lib/chef/knife/data_bag_show.rb
+++ b/lib/chef/knife/data_bag_show.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -32,13 +32,15 @@ class Chef
category "data bag"
option :secret,
- :short => "-s SECRET",
- :long => "--secret ",
- :description => "The secret key to use to decrypt data bag item values"
+ :short => "-s SECRET",
+ :long => "--secret ",
+ :description => "The secret key to use to decrypt data bag item values",
+ :proc => Proc.new { |s| Chef::Config[:knife][:secret] = s }
option :secret_file,
- :long => "--secret-file SECRET_FILE",
- :description => "A file containing the secret key to use to decrypt data bag item values"
+ :long => "--secret-file SECRET_FILE",
+ :description => "A file containing the secret key to use to decrypt data bag item values",
+ :proc => Proc.new { |sf| Chef::Config[:knife][:secret_file] = sf }
def read_secret
if config[:secret]
diff --git a/lib/chef/knife/delete.rb b/lib/chef/knife/delete.rb
index fb26b9ea35..0030c45026 100644
--- a/lib/chef/knife/delete.rb
+++ b/lib/chef/knife/delete.rb
@@ -5,6 +5,8 @@ class Chef
class Delete < Chef::ChefFS::Knife
banner "knife delete [PATTERN1 ... PATTERNn]"
+ category "path-based"
+
deps do
require 'chef/chef_fs/file_system'
end
diff --git a/lib/chef/knife/deps.rb b/lib/chef/knife/deps.rb
index c4b3678ff8..b2a39a0725 100644
--- a/lib/chef/knife/deps.rb
+++ b/lib/chef/knife/deps.rb
@@ -5,6 +5,8 @@ class Chef
class Deps < Chef::ChefFS::Knife
banner "knife deps PATTERN1 [PATTERNn]"
+ category "path-based"
+
deps do
require 'chef/chef_fs/file_system'
require 'chef/run_list'
diff --git a/lib/chef/knife/diff.rb b/lib/chef/knife/diff.rb
index 5a3a80544d..e5eda5228c 100644
--- a/lib/chef/knife/diff.rb
+++ b/lib/chef/knife/diff.rb
@@ -5,6 +5,8 @@ class Chef
class Diff < Chef::ChefFS::Knife
banner "knife diff PATTERNS"
+ category "path-based"
+
deps do
require 'chef/chef_fs/command_line'
end
@@ -30,6 +32,10 @@ class Chef
:description => "Select only files that are Added (A), Deleted (D), Modified (M), or have their type (i.e. regular file, directory) changed (T). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if
there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected."
+ option :cookbook_version,
+ :long => '--cookbook-version VERSION',
+ :description => 'Version of cookbook to download (if there are multiple versions and cookbook_versions is false)'
+
def run
if config[:name_only]
output_mode = :name_only
diff --git a/lib/chef/knife/download.rb b/lib/chef/knife/download.rb
index e8f26a74aa..5a432afd47 100644
--- a/lib/chef/knife/download.rb
+++ b/lib/chef/knife/download.rb
@@ -5,6 +5,8 @@ class Chef
class Download < Chef::ChefFS::Knife
banner "knife download PATTERNS"
+ category "path-based"
+
deps do
require 'chef/chef_fs/command_line'
end
@@ -40,6 +42,10 @@ class Chef
:default => true,
:description => 'Turn off to avoid uploading existing files; only new (and possibly deleted) files with --no-diff'
+ option :cookbook_version,
+ :long => '--cookbook-version VERSION',
+ :description => 'Version of cookbook to download (if there are multiple versions and cookbook_versions is false)'
+
def run
if name_args.length == 0
show_usage
diff --git a/lib/chef/knife/edit.rb b/lib/chef/knife/edit.rb
index ea068cb250..830da84a12 100644
--- a/lib/chef/knife/edit.rb
+++ b/lib/chef/knife/edit.rb
@@ -5,6 +5,8 @@ class Chef
class Edit < Chef::ChefFS::Knife
banner "knife edit [PATTERN1 ... PATTERNn]"
+ category "path-based"
+
deps do
require 'chef/chef_fs/file_system'
require 'chef/chef_fs/file_system/not_found_error'
diff --git a/lib/chef/knife/environment_from_file.rb b/lib/chef/knife/environment_from_file.rb
index af72f84622..3812024c9c 100644
--- a/lib/chef/knife/environment_from_file.rb
+++ b/lib/chef/knife/environment_from_file.rb
@@ -62,7 +62,7 @@ class Chef
ui.info("Updated Environment #{updated.name}")
end
-
+
def run
if config[:all] == true
load_all_environments
@@ -72,7 +72,7 @@ class Chef
ui.fatal("You must specify a file to load")
exit 1
end
-
+
@name_args.each do |arg|
load_environment(arg)
end
diff --git a/lib/chef/knife/index_rebuild.rb b/lib/chef/knife/index_rebuild.rb
index 3e97c7751b..4b9fcdd159 100644
--- a/lib/chef/knife/index_rebuild.rb
+++ b/lib/chef/knife/index_rebuild.rb
@@ -40,7 +40,7 @@ class Chef
nag
output rest.post_rest("/search/reindex", {})
end
-
+
end
def grab_api_info
@@ -55,7 +55,7 @@ class Chef
r = exception.response
parse_api_info(r)
end
-
+
# Only Chef 11+ servers will have version information in their
# headers, and only those servers will lack an API endpoint for
# index rebuilding.
diff --git a/lib/chef/knife/list.rb b/lib/chef/knife/list.rb
index 83d5c5a8c4..4338e195bd 100644
--- a/lib/chef/knife/list.rb
+++ b/lib/chef/knife/list.rb
@@ -5,6 +5,8 @@ class Chef
class List < Chef::ChefFS::Knife
banner "knife list [-dfR1p] [PATTERN1 ... PATTERNn]"
+ category "path-based"
+
deps do
require 'chef/chef_fs/file_system'
require 'highline'
diff --git a/lib/chef/knife/raw.rb b/lib/chef/knife/raw.rb
index ee22d1ade5..2756de1a5a 100644
--- a/lib/chef/knife/raw.rb
+++ b/lib/chef/knife/raw.rb
@@ -6,10 +6,13 @@ class Chef
banner "knife raw REQUEST_PATH"
deps do
- require 'json'
- require 'chef/rest'
+ require 'chef/json_compat'
require 'chef/config'
- require 'chef/chef_fs/raw_request'
+ require 'chef/http'
+ require 'chef/http/authenticator'
+ require 'chef/http/cookie_manager'
+ require 'chef/http/decompressor'
+ require 'chef/http/json_output'
end
option :method,
@@ -29,6 +32,18 @@ class Chef
:short => '-i FILE',
:description => "Name of file to use for PUT or POST"
+ class RawInputServerAPI < Chef::HTTP
+ def initialize(options = {})
+ options[:client_name] ||= Chef::Config[:node_name]
+ options[:signing_key_filename] ||= Chef::Config[:client_key]
+ super(Chef::Config[:chef_server_url], options)
+ end
+ use Chef::HTTP::JSONOutput
+ use Chef::HTTP::CookieManager
+ use Chef::HTTP::Decompressor
+ use Chef::HTTP::Authenticator
+ end
+
def run
if name_args.length == 0
show_usage
@@ -45,9 +60,20 @@ class Chef
if config[:input]
data = IO.read(config[:input])
end
- chef_rest = Chef::REST.new(Chef::Config[:chef_server_url])
begin
- output Chef::ChefFS::RawRequest.api_request(chef_rest, config[:method].to_sym, chef_rest.create_url(name_args[0]), {}, data)
+ method = config[:method].to_sym
+
+ if config[:pretty]
+ chef_rest = RawInputServerAPI.new
+ result = chef_rest.request(method, name_args[0], {'Content-Type' => 'application/json'}, data)
+ unless result.is_a?(String)
+ result = Chef::JSONCompat.to_json_pretty(result)
+ end
+ else
+ chef_rest = RawInputServerAPI.new(:raw_output => true)
+ result = chef_rest.request(method, name_args[0], {'Content-Type' => 'application/json'}, data)
+ end
+ output result
rescue Timeout::Error => e
ui.error "Server timeout"
exit 1
diff --git a/lib/chef/knife/show.rb b/lib/chef/knife/show.rb
index b5e8aa9882..acf1996e96 100644
--- a/lib/chef/knife/show.rb
+++ b/lib/chef/knife/show.rb
@@ -5,6 +5,8 @@ class Chef
class Show < Chef::ChefFS::Knife
banner "knife show [PATTERN1 ... PATTERNn]"
+ category "path-based"
+
deps do
require 'chef/chef_fs/file_system'
require 'chef/chef_fs/file_system/not_found_error'
diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb
index 8cc05bd433..e1090fcca0 100644
--- a/lib/chef/knife/ssh.rb
+++ b/lib/chef/knife/ssh.rb
@@ -147,7 +147,7 @@ class Chef
@action_nodes = q.search(:node, @name_args[0])[0]
@action_nodes.each do |item|
# we should skip the loop to next iteration if the item returned by the search is nil
- next if item.nil?
+ next if item.nil?
# if a command line attribute was not passed, and we have a cloud public_hostname, use that.
# see #configure_attribute for the source of config[:attribute] and config[:override_attribute]
if !config[:override_attribute] && item[:cloud] and item[:cloud][:public_hostname]
@@ -211,15 +211,28 @@ class Chef
end
def print_data(host, data)
- if data =~ /\n/
- data.split(/\n/).each { |d| print_data(host, d) }
+ @buffers ||= {}
+ if leftover = @buffers[host]
+ @buffers[host] = nil
+ print_data(host, leftover + data)
else
- padding = @longest - host.length
- str = ui.color(host, :cyan) + (" " * (padding + 1)) + data
- ui.msg(str)
+ if newline_index = data.index("\n")
+ line = data.slice!(0...newline_index)
+ data.slice!(0)
+ print_line(host, line)
+ print_data(host, data)
+ else
+ @buffers[host] = data
+ end
end
end
+ def print_line(host, data)
+ padding = @longest - host.length
+ str = ui.color(host, :cyan) + (" " * (padding + 1)) + data
+ ui.msg(str)
+ end
+
def ssh_command(command, subsession=nil)
exit_status = 0
subsession ||= session
@@ -232,6 +245,7 @@ class Chef
ch.on_data do |ichannel, data|
print_data(ichannel[:host], data)
if data =~ /^knife sudo password: /
+ print_data(ichannel[:host], "\n")
ichannel.send_data("#{get_password}\n")
end
end
@@ -383,7 +397,7 @@ class Chef
# Thus we can differentiate between a config file value and a command line override at this point by checking config[:attribute]
# We can tell here if fqdn was passed from the command line, rather than being the default, by checking config[:attribute]
# However, after here, we cannot tell these things, so we must preserve config[:attribute]
- config[:override_attribute] = config[:attribute] || Chef::Config[:knife][:ssh_attribute]
+ config[:override_attribute] = config[:attribute] || Chef::Config[:knife][:ssh_attribute]
config[:attribute] = (Chef::Config[:knife][:ssh_attribute] ||
config[:attribute] ||
"fqdn").strip
diff --git a/lib/chef/knife/status.rb b/lib/chef/knife/status.rb
index ceb394ce3a..5906a4a624 100644
--- a/lib/chef/knife/status.rb
+++ b/lib/chef/knife/status.rb
@@ -72,7 +72,7 @@ class Chef
hours, minutes, seconds = time_difference_in_hms(node["ohai_time"])
hours_text = "#{hours} hour#{hours == 1 ? ' ' : 's'}"
minutes_text = "#{minutes} minute#{minutes == 1 ? ' ' : 's'}"
- run_list = ", #{node.run_list}." if config[:run_list]
+ run_list = "#{node.run_list}" if config[:run_list]
if hours > 24
color = :red
text = hours_text
diff --git a/lib/chef/knife/upload.rb b/lib/chef/knife/upload.rb
index f72b6ea616..8abd22b4dd 100644
--- a/lib/chef/knife/upload.rb
+++ b/lib/chef/knife/upload.rb
@@ -5,6 +5,8 @@ class Chef
class Upload < Chef::ChefFS::Knife
banner "knife upload PATTERNS"
+ category "path-based"
+
deps do
require 'chef/chef_fs/command_line'
end
diff --git a/lib/chef/knife/xargs.rb b/lib/chef/knife/xargs.rb
index be6db9d64f..dd8e848058 100644
--- a/lib/chef/knife/xargs.rb
+++ b/lib/chef/knife/xargs.rb
@@ -5,6 +5,8 @@ class Chef
class Xargs < Chef::ChefFS::Knife
banner "knife xargs [COMMAND]"
+ category "path-based"
+
deps do
require 'chef/chef_fs/file_system'
require 'chef/chef_fs/file_system/not_found_error'
diff --git a/lib/chef/mixin/checksum.rb b/lib/chef/mixin/checksum.rb
index 8217296915..1d9c99ec7e 100644
--- a/lib/chef/mixin/checksum.rb
+++ b/lib/chef/mixin/checksum.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/mixin/command.rb b/lib/chef/mixin/command.rb
index 55c028ff5f..2cc25e149e 100644
--- a/lib/chef/mixin/command.rb
+++ b/lib/chef/mixin/command.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -41,23 +41,32 @@ class Chef
# === Parameters
# args<Hash>: A number of required and optional arguments
- # command<String>, <Array>: A complete command with options to execute or a command and options as an Array
+ # command<String>, <Array>: A complete command with options to execute or a command and options as an Array
# creates<String>: The absolute path to a file that prevents the command from running if it exists
# cwd<String>: Working directory to execute command in, defaults to Dir.tmpdir
# timeout<String>: How many seconds to wait for the command to execute before timing out
# returns<String>: The single exit value command is expected to return, otherwise causes an exception
# ignore_failure<Boolean>: Whether to raise an exception on failure, or just return the status
# output_on_failure<Boolean>: Return output in raised exception regardless of Log.level
- #
+ #
# user<String>: The UID or user name of the user to execute the command as
# group<String>: The GID or group name of the group to execute the command as
# environment<Hash>: Pairs of environment variable names and their values to set before execution
#
# === Returns
# Returns the exit status of args[:command]
- def run_command(args={})
+ def run_command(args={})
+ status, stdout, stderr = run_command_and_return_stdout_stderr(args)
+
+ status
+ end
+
+ # works same as above, except that it returns stdout and stderr
+ # requirement => platforms like solaris 9,10 has wierd issues where
+ # even in command failure the exit code is zero, so we need to lookup stderr.
+ def run_command_and_return_stdout_stderr(args={})
command_output = ""
-
+
args[:ignore_failure] ||= false
args[:output_on_failure] ||= false
@@ -68,28 +77,28 @@ class Chef
return false
end
end
-
+
status, stdout, stderr = output_of_command(args[:command], args)
command_output << "STDOUT: #{stdout}"
command_output << "STDERR: #{stderr}"
handle_command_failures(status, command_output, args)
-
- status
+
+ return status, stdout, stderr
end
-
+
def output_of_command(command, args)
Chef::Log.debug("Executing #{command}")
stderr_string, stdout_string, status = "", "", nil
-
+
exec_processing_block = lambda do |pid, stdin, stdout, stderr|
stdout_string, stderr_string = stdout.string.chomp, stderr.string.chomp
end
-
+
args[:cwd] ||= Dir.tmpdir
unless ::File.directory?(args[:cwd])
raise Chef::Exceptions::Exec, "#{args[:cwd]} does not exist or is not a directory"
end
-
+
Dir.chdir(args[:cwd]) do
if args[:timeout]
begin
@@ -103,17 +112,17 @@ class Chef
else
status = popen4(command, args, &exec_processing_block)
end
-
+
Chef::Log.debug("---- Begin output of #{command} ----")
Chef::Log.debug("STDOUT: #{stdout_string}")
Chef::Log.debug("STDERR: #{stderr_string}")
Chef::Log.debug("---- End output of #{command} ----")
Chef::Log.debug("Ran #{command} returned #{status.exitstatus}")
end
-
+
return status, stdout_string, stderr_string
end
-
+
def handle_command_failures(status, command_output, opts={})
unless opts[:ignore_failure]
opts[:returns] ||= 0
@@ -129,7 +138,7 @@ class Chef
end
end
end
-
+
# Call #run_command but set LC_ALL to the system's current environment so it doesn't get changed to C.
#
# === Parameters
diff --git a/lib/chef/mixin/convert_to_class_name.rb b/lib/chef/mixin/convert_to_class_name.rb
index 7b4ec7ad3f..ece16990a1 100644
--- a/lib/chef/mixin/convert_to_class_name.rb
+++ b/lib/chef/mixin/convert_to_class_name.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,20 +27,20 @@ class Chef
str.gsub!(/[^A-Za-z0-9_]/,'_')
rname = nil
regexp = %r{^(.+?)(_(.+))?$}
-
+
mn = str.match(regexp)
if mn
rname = mn[1].capitalize
while mn && mn[3]
- mn = mn[3].match(regexp)
+ mn = mn[3].match(regexp)
rname << mn[1].capitalize if mn
end
end
rname
end
-
+
def convert_to_snake_case(str, namespace=nil)
str = str.dup
str.sub!(/^#{namespace}(\:\:)?/, '') if namespace
@@ -49,17 +49,17 @@ class Chef
str.sub!(/^\_/, "")
str
end
-
+
def snake_case_basename(str)
with_namespace = convert_to_snake_case(str)
with_namespace.split("::").last.sub(/^_/, '')
end
-
+
def filename_to_qualified_string(base, filename)
file_base = File.basename(filename, ".rb")
base.to_s + (file_base == 'default' ? '' : "_#{file_base}")
end
-
+
end
end
end
diff --git a/lib/chef/mixin/create_path.rb b/lib/chef/mixin/create_path.rb
index 9b5dba14f2..9d1248e907 100644
--- a/lib/chef/mixin/create_path.rb
+++ b/lib/chef/mixin/create_path.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,21 +18,21 @@
class Chef
module Mixin
module CreatePath
-
+
# Creates a given path, including all directories that lead up to it.
# Like mkdir_p, but without the leaking.
#
# === Parameters
- # file_path<String, Array>:: A string that represents the path to create,
+ # file_path<String, Array>:: A string that represents the path to create,
# or an Array with the path-parts.
#
# === Returns
# The created file_path.
def create_path(file_path)
unless file_path.kind_of?(String) || file_path.kind_of?(Array)
- raise ArgumentError, "file_path must be a string or an array!"
+ raise ArgumentError, "file_path must be a string or an array!"
end
-
+
if file_path.kind_of?(String)
file_path = File.expand_path(file_path).split(File::SEPARATOR)
file_path.shift if file_path[0] == ''
@@ -41,17 +41,17 @@ class Chef
file_path[0] = "#{File::SEPARATOR}#{file_path[0]}"
end
end
-
+
file_path.each_index do |i|
create_path = File.join(file_path[0, i + 1])
unless File.directory?(create_path)
Chef::Log.debug("Creating directory #{create_path}")
Dir.mkdir(create_path)
- end
+ end
end
File.expand_path(File.join(file_path))
end
-
+
end
end
end
diff --git a/lib/chef/mixin/deep_merge.rb b/lib/chef/mixin/deep_merge.rb
index 1f2125be01..9fa86948b6 100644
--- a/lib/chef/mixin/deep_merge.rb
+++ b/lib/chef/mixin/deep_merge.rb
@@ -8,9 +8,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/mixin/from_file.rb b/lib/chef/mixin/from_file.rb
index 609fe1de55..0d1ddca4fa 100644
--- a/lib/chef/mixin/from_file.rb
+++ b/lib/chef/mixin/from_file.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,9 +20,9 @@
class Chef
module Mixin
module FromFile
-
- # Loads a given ruby file, and runs instance_eval against it in the context of the current
- # object.
+
+ # Loads a given ruby file, and runs instance_eval against it in the context of the current
+ # object.
#
# Raises an IOError if the file cannot be found, or is not readable.
def from_file(filename)
@@ -33,7 +33,7 @@ class Chef
end
end
- # Loads a given ruby file, and runs class_eval against it in the context of the current
+ # Loads a given ruby file, and runs class_eval against it in the context of the current
# object.
#
# Raises an IOError if the file cannot be found, or is not readable.
diff --git a/lib/chef/mixin/language_include_recipe.rb b/lib/chef/mixin/language_include_recipe.rb
index b534b6628f..d85e5c682d 100644
--- a/lib/chef/mixin/language_include_recipe.rb
+++ b/lib/chef/mixin/language_include_recipe.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/mixin/params_validate.rb b/lib/chef/mixin/params_validate.rb
index a9822df134..a9799f749c 100644
--- a/lib/chef/mixin/params_validate.rb
+++ b/lib/chef/mixin/params_validate.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@ class Chef
end
module Mixin
module ParamsValidate
-
+
# Takes a hash of options, along with a map to validate them. Returns the original
# options hash, plus any changes that might have been made (through things like setting
# default values in the validation map)
@@ -28,19 +28,19 @@ class Chef
# For example:
#
# validate({ :one => "neat" }, { :one => { :kind_of => String }})
- #
+ #
# Would raise an exception if the value of :one above is not a kind_of? string. Valid
# map options are:
#
# :default:: Sets the default value for this parameter.
- # :callbacks:: Takes a hash of Procs, which should return true if the argument is valid.
+ # :callbacks:: Takes a hash of Procs, which should return true if the argument is valid.
# The key will be inserted into the error message if the Proc does not return true:
# "Option #{key}'s value #{value} #{message}!"
- # :kind_of:: Ensure that the value is a kind_of?(Whatever). If passed an array, it will ensure
+ # :kind_of:: Ensure that the value is a kind_of?(Whatever). If passed an array, it will ensure
# that the value is one of those types.
# :respond_to:: Ensure that the value has a given method. Takes one method name or an array of
# method names.
- # :required:: Raise an exception if this parameter is missing. Valid values are true or false,
+ # :required:: Raise an exception if this parameter is missing. Valid values are true or false,
# by default, options are not required.
# :regex:: Match the value of the paramater against a regular expression.
# :equal_to:: Match the value of the paramater with ==. An array means it can be equal to any
@@ -48,12 +48,12 @@ class Chef
def validate(opts, map)
#--
# validate works by taking the keys in the validation map, assuming it's a hash, and
- # looking for _pv_:symbol as methods. Assuming it find them, it calls the right
- # one.
+ # looking for _pv_:symbol as methods. Assuming it find them, it calls the right
+ # one.
#++
raise ArgumentError, "Options must be a hash" unless opts.kind_of?(Hash)
- raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash)
-
+ raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash)
+
map.each do |key, validation|
unless key.kind_of?(Symbol) || key.kind_of?(String)
raise ArgumentError, "Validation map keys must be symbols or strings!"
@@ -76,7 +76,7 @@ class Chef
end
opts
end
-
+
def lazy(&block)
DelayedEvaluator.new(&block)
end
@@ -99,9 +99,9 @@ class Chef
self.instance_variable_set(iv_symbol, val)
end
end
-
+
private
-
+
# Return the value of a parameter, or nil if it doesn't exist.
def _pv_opts_lookup(opts, key)
if opts.has_key?(key.to_s)
@@ -112,7 +112,7 @@ class Chef
nil
end
end
-
+
# Raise an exception if the parameter is not found.
def _pv_required(opts, key, is_required=true)
if is_required
@@ -124,7 +124,7 @@ class Chef
end
end
end
-
+
def _pv_equal_to(opts, key, to_be)
value = _pv_opts_lookup(opts, key)
unless value.nil?
@@ -137,7 +137,7 @@ class Chef
end
end
end
-
+
# Raise an exception if the parameter is not a kind_of?(to_be)
def _pv_kind_of(opts, key, to_be)
value = _pv_opts_lookup(opts, key)
@@ -151,7 +151,7 @@ class Chef
end
end
end
-
+
# Raise an exception if the parameter does not respond to a given set of methods.
def _pv_respond_to(opts, key, method_name_list)
value = _pv_opts_lookup(opts, key)
@@ -181,7 +181,7 @@ class Chef
end
end
end
-
+
# Assign a default value to a parameter.
def _pv_default(opts, key, default_value)
value = _pv_opts_lookup(opts, key)
@@ -189,7 +189,7 @@ class Chef
opts[key] = default_value
end
end
-
+
# Check a parameter against a regular expression.
def _pv_regex(opts, key, regex)
value = _pv_opts_lookup(opts, key)
@@ -207,7 +207,7 @@ class Chef
end
end
end
-
+
# Check a parameter against a hash of proc's.
def _pv_callbacks(opts, key, callbacks)
raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash)
diff --git a/lib/chef/mixin/shell_out.rb b/lib/chef/mixin/shell_out.rb
index 4eaa509f8b..f0c2ba2000 100644
--- a/lib/chef/mixin/shell_out.rb
+++ b/lib/chef/mixin/shell_out.rb
@@ -15,13 +15,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# chef/shell_out has been deprecated in favor of mixlib/shellout
+# chef/shell_out is still required here to ensure backward compatibility
require 'chef/shell_out'
+
+require 'mixlib/shellout'
require 'chef/config'
class Chef
module Mixin
module ShellOut
+ # shell_out! runs a command on the system and will raise an error if the command fails, which is what you want
+ # for debugging, shell_out and shell_out! both will display command output to the tty when the log level is debug
+ # Generally speaking, 'extend Chef::Mixin::ShellOut' in your recipes and include 'Chef::Mixin::ShellOut' in your LWRPs
+ # You can also call Mixlib::Shellout.new directly, but you lose all of the above functionality
+
def shell_out(*command_args)
cmd = Mixlib::ShellOut.new(*run_command_compatible_options(command_args))
if STDOUT.tty? && !Chef::Config[:daemon] && Chef::Log.debug?
diff --git a/lib/chef/mixin/template.rb b/lib/chef/mixin/template.rb
index 9208ce057e..ae23336581 100644
--- a/lib/chef/mixin/template.rb
+++ b/lib/chef/mixin/template.rb
@@ -121,17 +121,6 @@ class Chef
###
def _render_template(template, context)
- # CHEF-2991
- # Erubis always emits unix line endings during template
- # rendering. This results in automatic conversion of windows
- # line endings to linux line endings if the original template
- # contains windows line endings. In order to fix this we
- # determine the line ending style of the template before
- # rendering and convert the line endings of the output if needed
- # If template contains any windows line endings we emit
- # the template result with windows line endings.
- windows_line_endings = template.include? "\r\n"
-
begin
eruby = Erubis::Eruby.new(template)
output = eruby.evaluate(context)
@@ -139,11 +128,19 @@ class Chef
raise TemplateError.new(e, template, context)
end
- if windows_line_endings
- # Convert line endings from "\n" -> "\r\n". Also converts
- # "\r\n" -> "\r\n".
- # This makes the regex match on all of "\r\n", so we don't
- # accidentally convert "\r\n" -> "\r\r\n".
+ # CHEF-4399
+ # Erubis always emits unix line endings during template
+ # rendering. Chef used to convert line endings to the
+ # original line endings in the template. However this
+ # created problems in cases when cookbook developer is
+ # coding the cookbook on windows but using it on non-windows
+ # platforms.
+ # The safest solution is to make sure that native to the
+ # platform we are running on is used in order to minimize
+ # potential issues for the applications that will consume
+ # this template.
+
+ if Chef::Platform.windows?
output = output.gsub(/\r?\n/,"\r\n")
end
diff --git a/lib/chef/mixin/why_run.rb b/lib/chef/mixin/why_run.rb
index 788e2fe2bc..d650e3332f 100644
--- a/lib/chef/mixin/why_run.rb
+++ b/lib/chef/mixin/why_run.rb
@@ -178,8 +178,8 @@ class Chef
# when the requirement is not met and Chef is executing in why run
# mode
#
- # If no failure_message is provided (above), then execution
- # will be allowed to continue in both whyrun an dnon-whyrun
+ # If no failure_message is provided (above), then execution
+ # will be allowed to continue in both whyrun and non-whyrun
# mode
#
# With a service resource that requires /etc/init.d/service-name to exist:
@@ -196,16 +196,16 @@ class Chef
@resource_modifier = resource_modifier
end
- # Prevents associated actions from being invoked in whyrun mode.
- # This will also stop further processing of assertions for a given action.
- #
- # An example from the template provider: if the source template doesn't exist
- # we can't parse it in the action_create block of template - something that we do
- # even in whyrun mode. Because the soruce template may have been created in an earlier
+ # Prevents associated actions from being invoked in whyrun mode.
+ # This will also stop further processing of assertions for a given action.
+ #
+ # An example from the template provider: if the source template doesn't exist
+ # we can't parse it in the action_create block of template - something that we do
+ # even in whyrun mode. Because the source template may have been created in an earlier
# step, we still want to keep going in whyrun mode.
- #
+ #
# assert(:create, :create_if_missing) do |a|
- # a.assertion { File::exists?(@new_resource.source) }
+ # a.assertion { File::exists?(@new_resource.source) }
# a.whyrun "Template source file does not exist, assuming it would have been created."
# a.block_action!
# end
@@ -214,7 +214,7 @@ class Chef
@block_action = true
end
- def block_action?
+ def block_action?
@block_action
end
@@ -258,7 +258,7 @@ class Chef
# Check to see if a given action is blocked by a failed assertion
#
# Takes the action name to be verified.
- def action_blocked?(action)
+ def action_blocked?(action)
@blocked_actions.include?(action)
end
@@ -296,9 +296,9 @@ class Chef
# "You don't have sufficient privileges to delete #{@new_resource.path}")
# end
#
- # A Template provider that will prevent action execution but continue the run in
+ # A Template provider that will prevent action execution but continue the run in
# whyrun mode if the template source is not available.
- # assert(:create, :create_if_missing) do |a|
+ # assert(:create, :create_if_missing) do |a|
# a.assertion { File::exist?(@new_resource.source) }
# a.failure_message Chef::Exceptions::TemplateError, "Template #{@new_resource.source} could not be found exist."
# a.whyrun "Template source #{@new_resource.source} does not exist. Assuming it would have been created."
@@ -318,9 +318,9 @@ class Chef
# Run the assertion and assumption logic.
def run(action)
- @assertions[action.to_sym].each do |a|
+ @assertions[action.to_sym].each do |a|
a.run(action, events, @resource)
- if a.assertion_failed? and a.block_action?
+ if a.assertion_failed? and a.block_action?
@blocked_actions << action
return
end
diff --git a/lib/chef/mixin/windows_architecture_helper.rb b/lib/chef/mixin/windows_architecture_helper.rb
index 38c08e236d..c13278693f 100644
--- a/lib/chef/mixin/windows_architecture_helper.rb
+++ b/lib/chef/mixin/windows_architecture_helper.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,7 @@
#
-require 'chef/exceptions'
+require 'chef/exceptions'
require 'win32/api' if Chef::Platform.windows?
class Chef
@@ -32,7 +32,7 @@ class Chef
is_i386_windows_process? &&
node_windows_architecture(node) == :x86_64 &&
desired_architecture == :x86_64
- end
+ end
def node_supports_windows_architecture?(node, desired_architecture)
assert_valid_windows_architecture!(desired_architecture)
@@ -85,7 +85,7 @@ class Chef
end
end
end
-
+
end
end
end
diff --git a/lib/chef/mixin/xml_escape.rb b/lib/chef/mixin/xml_escape.rb
index dac2f0c6af..ceb45df3e6 100644
--- a/lib/chef/mixin/xml_escape.rb
+++ b/lib/chef/mixin/xml_escape.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,26 +18,26 @@
#--
# Portions of this code are adapted from Sam Ruby's xchar.rb
-# http://intertwingly.net/stories/2005/09/28/xchar.rb
+# http://intertwingly.net/stories/2005/09/28/xchar.rb
#
# Such code appears here under Sam's original MIT license, while portions of
# this file are covered by the above Apache License. For a completely MIT
# licensed version, please see Sam's original.
#
# Thanks, Sam!
-#
-# Copyright (c) 2005, Sam Ruby
-#
+#
+# Copyright (c) 2005, Sam Ruby
+#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
-#
+#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
-#
+#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -99,7 +99,7 @@ class Chef
}
# http://www.w3.org/TR/REC-xml/#charsets
- VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF),
+ VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF),
(0xE000..0xFFFD), (0x10000..0x10FFFF)]
def xml_escape(unescaped_str)
@@ -118,7 +118,7 @@ class Chef
char = PREDEFINED[char] || (char<128 ? char.chr : "&##{char};")
end
end
-
+
module FastXS
extend self
diff --git a/lib/chef/monkey_patches/numeric.rb b/lib/chef/monkey_patches/numeric.rb
index 1f5ff14209..f4612fdbf3 100644
--- a/lib/chef/monkey_patches/numeric.rb
+++ b/lib/chef/monkey_patches/numeric.rb
@@ -8,7 +8,7 @@ end
# String elements referenced with [] <= 1.8.6 return a Fixnum. Cheat to allow
# for the simpler "test"[2].ord construct
-class Numeric
+class Numeric
def ord
return self
end
diff --git a/lib/chef/monkey_patches/regexp.rb b/lib/chef/monkey_patches/regexp.rb
index 9304209edf..8a7ee77cb5 100644
--- a/lib/chef/monkey_patches/regexp.rb
+++ b/lib/chef/monkey_patches/regexp.rb
@@ -1,5 +1,5 @@
# Copyright (c) 2009 Marc-Andre Lafortune
-#
+#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
-#
+#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
-#
+#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -31,4 +31,4 @@ class Regexp
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/chef/monkey_patches/string.rb b/lib/chef/monkey_patches/string.rb
index c77c5c8816..f91e27ddc5 100644
--- a/lib/chef/monkey_patches/string.rb
+++ b/lib/chef/monkey_patches/string.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -39,7 +39,7 @@ class String
end
end
-# <= 1.8.6 needs some ord!
+# <= 1.8.6 needs some ord!
class String
unless method_defined?(:ord)
def ord
diff --git a/lib/chef/monkey_patches/tempfile.rb b/lib/chef/monkey_patches/tempfile.rb
index 3135fb1a00..b9179f182b 100644
--- a/lib/chef/monkey_patches/tempfile.rb
+++ b/lib/chef/monkey_patches/tempfile.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 6bd2226ac8..007bd3c560 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -290,6 +290,14 @@ class Chef
normal[:tags]
end
+ def tag(*tags)
+ tags.each do |tag|
+ self.normal[:tags].push(tag.to_s) unless self[:tags].include? tag.to_s
+ end
+
+ self[:tags]
+ end
+
# Extracts the run list from +attrs+ and applies it. Returns the remaining attributes
def consume_run_list(attrs)
attrs = attrs ? attrs.dup : {}
diff --git a/lib/chef/node/attribute.rb b/lib/chef/node/attribute.rb
index a417406721..66569cf0e1 100644
--- a/lib/chef/node/attribute.rb
+++ b/lib/chef/node/attribute.rb
@@ -243,7 +243,7 @@ class Chef
end
# Clears merged_attributes, which will cause it to be recomputed on the
- # next access.
+ # next access.
def reset_cache
@merged_attributes = nil
@combined_default = nil
diff --git a/lib/chef/platform/provider_mapping.rb b/lib/chef/platform/provider_mapping.rb
index 1a282624c8..a252bdc100 100644
--- a/lib/chef/platform/provider_mapping.rb
+++ b/lib/chef/platform/provider_mapping.rb
@@ -173,6 +173,17 @@ class Chef
:ifconfig => Chef::Provider::Ifconfig::Redhat
}
},
+ :opensuse => {
+ :default => {
+ :service => Chef::Provider::Service::Redhat,
+ :cron => Chef::Provider::Cron,
+ :package => Chef::Provider::Package::Zypper,
+ :group => Chef::Provider::Group::Suse
+ },
+ ">= 12.3" => {
+ :group => Chef::Provider::Group::Usermod
+ }
+ },
:suse => {
:default => {
:service => Chef::Provider::Service::Redhat,
@@ -180,6 +191,16 @@ class Chef
:package => Chef::Provider::Package::Zypper,
:group => Chef::Provider::Group::Suse
},
+ ###############################################
+ # TODO: Remove this after ohai update is released.
+ # Only OpenSuSE 12.3+ should use the Usermod group provider:
+ # Ohai before OHAI-339 is applied reports both OpenSuSE and SuSE
+ # Enterprise as "suse", Ohai after OHAI-339 will report OpenSuSE as
+ # "opensuse".
+ #
+ # In order to support OpenSuSE both before and after the Ohai
+ # change, I'm leaving this here. It needs to get removed before
+ # SuSE enterprise 12.3 ships.
">= 12.3" => {
:group => Chef::Provider::Group::Usermod
}
@@ -320,7 +341,11 @@ class Chef
},
:aix => {
:default => {
- :group => Chef::Provider::Group::Aix
+ :group => Chef::Provider::Group::Aix,
+ :mount => Chef::Provider::Mount::Aix,
+ :ifconfig => Chef::Provider::Ifconfig::Aix,
+ :cron => Chef::Provider::Cron::Aix,
+ :package => Chef::Provider::Package::Aix
}
},
:default => {
diff --git a/lib/chef/provider/batch.rb b/lib/chef/provider/batch.rb
index e4b35b64f3..354a640e59 100644
--- a/lib/chef/provider/batch.rb
+++ b/lib/chef/provider/batch.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,7 +29,7 @@ class Chef
def flags
@new_resource.flags.nil? ? '/c' : new_resource.flags + ' /c'
end
-
+
end
end
end
diff --git a/lib/chef/provider/cron.rb b/lib/chef/provider/cron.rb
index a7218fea5a..f6f062a410 100644
--- a/lib/chef/provider/cron.rb
+++ b/lib/chef/provider/cron.rb
@@ -40,11 +40,12 @@ class Chef
def whyrun_supported?
true
end
-
+
def load_current_resource
crontab_lines = []
@current_resource = Chef::Resource::Cron.new(@new_resource.name)
@current_resource.user(@new_resource.user)
+ @cron_exists = false
if crontab = read_crontab
cron_found = false
crontab.each_line do |line|
@@ -81,7 +82,7 @@ class Chef
@current_resource
end
-
+
def cron_different?
CRON_ATTRIBUTES.any? do |cron_var|
!@new_resource.send(cron_var).nil? && @new_resource.send(cron_var) != @current_resource.send(cron_var)
@@ -93,14 +94,7 @@ class Chef
newcron = String.new
cron_found = false
- newcron << "# Chef Name: #{new_resource.name}\n"
- [ :mailto, :path, :shell, :home ].each do |v|
- newcron << "#{v.to_s.upcase}=#{@new_resource.send(v)}\n" if @new_resource.send(v)
- end
- @new_resource.environment.each do |name, value|
- newcron << "#{name}=#{value}\n"
- end
- newcron << "#{@new_resource.minute} #{@new_resource.hour} #{@new_resource.day} #{@new_resource.month} #{@new_resource.weekday} #{@new_resource.command}\n"
+ newcron = get_crontab_entry
if @cron_exists
unless cron_different?
@@ -171,7 +165,7 @@ class Chef
end
crontab << line
end
- description = cron_found ? "remove #{@new_resource.name} from crontab" :
+ description = cron_found ? "remove #{@new_resource.name} from crontab" :
"save unmodified crontab"
converge_by(description) do
write_crontab crontab
@@ -202,13 +196,33 @@ class Chef
end
def write_crontab(crontab)
+ write_exception = false
status = popen4("crontab -u #{@new_resource.user} -", :waitlast => true) do |pid, stdin, stdout, stderr|
- stdin.write crontab
+ begin
+ stdin.write crontab
+ rescue Errno::EPIPE => e
+ # popen4 could yield while child has already died.
+ write_exception = true
+ Chef::Log.debug("#{e.message}")
+ end
end
- if status.exitstatus > 0
+ if status.exitstatus > 0 || write_exception
raise Chef::Exceptions::Cron, "Error updating state of #{@new_resource.name}, exit: #{status.exitstatus}"
end
end
+
+ def get_crontab_entry
+ newcron = ""
+ newcron << "# Chef Name: #{new_resource.name}\n"
+ [ :mailto, :path, :shell, :home ].each do |v|
+ newcron << "#{v.to_s.upcase}=#{@new_resource.send(v)}\n" if @new_resource.send(v)
+ end
+ @new_resource.environment.each do |name, value|
+ newcron << "#{name}=#{value}\n"
+ end
+ newcron << "#{@new_resource.minute} #{@new_resource.hour} #{@new_resource.day} #{@new_resource.month} #{@new_resource.weekday} #{@new_resource.command}\n"
+ newcron
+ end
end
end
end
diff --git a/lib/chef/provider/cron/aix.rb b/lib/chef/provider/cron/aix.rb
new file mode 100644
index 0000000000..473700bf2f
--- /dev/null
+++ b/lib/chef/provider/cron/aix.rb
@@ -0,0 +1,48 @@
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "chef/provider/cron/unix"
+
+class Chef
+ class Provider
+ class Cron
+ class Aix < Chef::Provider::Cron::Unix
+
+ private
+
+ # For AIX we ignore env vars/[ :mailto, :path, :shell, :home ]
+ def get_crontab_entry
+ if env_vars_are_set?
+ raise Chef::Exceptions::Cron, "Aix cron entry does not support environment variables. Please set them in script and use script in cron."
+ end
+
+ newcron = ""
+ newcron << "# Chef Name: #{new_resource.name}\n"
+ newcron << "#{@new_resource.minute} #{@new_resource.hour} #{@new_resource.day} #{@new_resource.month} #{@new_resource.weekday}"
+
+ newcron << " #{@new_resource.command}\n"
+ newcron
+ end
+
+ def env_vars_are_set?
+ @new_resource.environment.length > 0 || !@new_resource.mailto.nil? || !@new_resource.path.nil? || !@new_resource.shell.nil? || !@new_resource.home.nil?
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/cron/solaris.rb b/lib/chef/provider/cron/solaris.rb
index e0811ba0ac..20fa7abcce 100644
--- a/lib/chef/provider/cron/solaris.rb
+++ b/lib/chef/provider/cron/solaris.rb
@@ -1,15 +1,13 @@
#
-# Author:: Bryan McLellan (btm@loftninjas.org)
-# Author:: Toomas Pelberg (toomasp@gmx.net)
-# Copyright:: Copyright (c) 2009 Bryan McLellan
-# Copyright:: Copyright (c) 2010 Toomas Pelberg
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,39 +16,7 @@
# limitations under the License.
#
-require 'chef/log'
-require 'chef/provider'
+require "chef/provider/cron/unix"
-class Chef
- class Provider
- class Cron
- class Solaris < Chef::Provider::Cron
-
- private
-
- def read_crontab
- crontab = nil
- status = popen4("crontab -l #{@new_resource.user}") do |pid, stdin, stdout, stderr|
- crontab = stdout.read
- end
- if status.exitstatus > 1
- raise Chef::Exceptions::Cron, "Error determining state of #{@new_resource.name}, exit: #{status.exitstatus}"
- end
- crontab
- end
-
- def write_crontab(crontab)
- tempcron = Tempfile.new("chef-cron")
- tempcron << crontab
- tempcron.flush
- tempcron.chmod(0644)
- status = run_command(:command => "/usr/bin/crontab #{tempcron.path}",:user => @new_resource.user)
- tempcron.close!
- if status.exitstatus > 0
- raise Chef::Exceptions::Cron, "Error updating state of #{@new_resource.name}, exit: #{status.exitstatus}"
- end
- end
- end
- end
- end
-end
+# Just to create an alias so 'Chef::Provider::Cron::Solaris' is exposed and accessible to existing consumers of class.
+Chef::Provider::Cron::Solaris = Chef::Provider::Cron::Unix
diff --git a/lib/chef/provider/cron/unix.rb b/lib/chef/provider/cron/unix.rb
new file mode 100644
index 0000000000..5cb1bcda41
--- /dev/null
+++ b/lib/chef/provider/cron/unix.rb
@@ -0,0 +1,76 @@
+#
+# Author:: Bryan McLellan (btm@loftninjas.org)
+# Author:: Toomas Pelberg (toomasp@gmx.net)
+# Copyright:: Copyright (c) 2009 Bryan McLellan
+# Copyright:: Copyright (c) 2010 Toomas Pelberg
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/log'
+require 'chef/provider'
+
+class Chef
+ class Provider
+ class Cron
+ class Unix < Chef::Provider::Cron
+
+ private
+
+ def read_crontab
+ crontab = nil
+ status = popen4("crontab -l #{@new_resource.user}") do |pid, stdin, stdout, stderr|
+ crontab = stdout.read
+ end
+ if status.exitstatus > 1
+ raise Chef::Exceptions::Cron, "Error determining state of #{@new_resource.name}, exit: #{status.exitstatus}"
+ end
+ crontab
+ end
+
+ def write_crontab(crontab)
+ tempcron = Tempfile.new("chef-cron")
+ tempcron << crontab
+ tempcron.flush
+ tempcron.chmod(0644)
+ exit_status = 0
+ error_message = ""
+ begin
+ status, stdout, stderr = run_command_and_return_stdout_stderr(:command => "/usr/bin/crontab #{tempcron.path}",:user => @new_resource.user)
+ exit_status = status.exitstatus
+ # solaris9, 10 on some failures for example invalid 'mins' in crontab fails with exit code of zero :(
+ if stderr && stderr.include?("errors detected in input, no crontab file generated")
+ error_message = stderr
+ exit_status = 1
+ end
+ rescue Chef::Exceptions::Exec => e
+ Chef::Log.debug(e.message)
+ exit_status = 1
+ error_message = e.message
+ rescue ArgumentError => e
+ # usually raised on invalid user.
+ Chef::Log.debug(e.message)
+ exit_status = 1
+ error_message = e.message
+ end
+ tempcron.close!
+ if exit_status > 0
+ raise Chef::Exceptions::Cron, "Error updating state of #{@new_resource.name}, exit: #{exit_status}, message: #{error_message}"
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/deploy/timestamped.rb b/lib/chef/provider/deploy/timestamped.rb
index 9c2d55b490..ce921161e0 100644
--- a/lib/chef/provider/deploy/timestamped.rb
+++ b/lib/chef/provider/deploy/timestamped.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,9 +20,9 @@ class Chef
class Provider
class Deploy
class Timestamped < Chef::Provider::Deploy
-
+
protected
-
+
def release_slug
Time.now.utc.strftime("%Y%m%d%H%M%S")
end
diff --git a/lib/chef/provider/erl_call.rb b/lib/chef/provider/erl_call.rb
index 1ee1da500c..cdd494a243 100644
--- a/lib/chef/provider/erl_call.rb
+++ b/lib/chef/provider/erl_call.rb
@@ -32,7 +32,7 @@ class Chef
def whyrun_supported?
true
end
-
+
def load_current_resource
true
end
diff --git a/lib/chef/provider/execute.rb b/lib/chef/provider/execute.rb
index 8d2a7d997d..2907688e88 100644
--- a/lib/chef/provider/execute.rb
+++ b/lib/chef/provider/execute.rb
@@ -29,7 +29,7 @@ class Chef
def load_current_resource
true
end
-
+
def whyrun_supported?
true
end
@@ -56,7 +56,7 @@ class Chef
if STDOUT.tty? && !Chef::Config[:daemon] && Chef::Log.info?
opts[:live_stream] = STDOUT
end
- converge_by("execute #{@new_resource.command}") do
+ converge_by("execute #{@new_resource.command}") do
result = shell_out!(@new_resource.command, opts)
Chef::Log.info("#{@new_resource} ran successfully")
end
diff --git a/lib/chef/provider/git.rb b/lib/chef/provider/git.rb
index 7cda1a873a..b22004eda0 100644
--- a/lib/chef/provider/git.rb
+++ b/lib/chef/provider/git.rb
@@ -273,6 +273,7 @@ class Chef
run_opts[:group] = @new_resource.group if @new_resource.group
run_opts[:environment] = {"GIT_SSH" => @new_resource.ssh_wrapper} if @new_resource.ssh_wrapper
run_opts[:log_tag] = @new_resource.to_s
+ run_opts[:timeout] = @new_resource.timeout if @new_resource.timeout
run_opts
end
diff --git a/lib/chef/provider/group.rb b/lib/chef/provider/group.rb
index c941ed72bd..eacb033492 100644
--- a/lib/chef/provider/group.rb
+++ b/lib/chef/provider/group.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -35,11 +35,11 @@ class Chef
super
@group_exists = true
end
-
+
def load_current_resource
@current_resource = Chef::Resource::Group.new(@new_resource.name)
@current_resource.group_name(@new_resource.group_name)
-
+
group_info = nil
begin
group_info = Etc.getgrnam(@new_resource.group_name)
@@ -47,26 +47,26 @@ class Chef
@group_exists = false
Chef::Log.debug("#{@new_resource} group does not exist")
end
-
+
if group_info
@new_resource.gid(group_info.gid) unless @new_resource.gid
@current_resource.gid(group_info.gid)
@current_resource.members(group_info.mem)
end
-
+
@current_resource
end
def define_resource_requirements
- requirements.assert(:modify) do |a|
- a.assertion { @group_exists }
+ requirements.assert(:modify) do |a|
+ a.assertion { @group_exists }
a.failure_message(Chef::Exceptions::Group, "Cannot modify #{@new_resource} - group does not exist!")
a.whyrun("Group #{@new_resource} does not exist. Unless it would have been created earlier in this run, this attempt to modify it would fail.")
end
end
-
- # Check to see if a group needs any changes. Populate
- # @change_desc with a description of why a change must occur
+
+ # Check to see if a group needs any changes. Populate
+ # @change_desc with a description of why a change must occur
#
# ==== Returns
# <true>:: If a change is required
@@ -77,7 +77,7 @@ class Chef
@change_desc = "change gid #{@current_resource.gid} to #{@new_resource.gid}"
return true
end
-
+
if(@new_resource.append)
missing_members = []
@new_resource.members.each do |member|
@@ -96,24 +96,24 @@ class Chef
end
return false
end
-
+
def action_create
case @group_exists
when false
- converge_by("create #{@new_resource}") do
+ converge_by("create #{@new_resource}") do
create_group
Chef::Log.info("#{@new_resource} created")
end
- else
+ else
if compare_group
- converge_by(["alter group #{@new_resource}", @change_desc ]) do
+ converge_by(["alter group #{@new_resource}", @change_desc ]) do
manage_group
Chef::Log.info("#{@new_resource} altered")
end
end
end
end
-
+
def action_remove
if @group_exists
converge_by("remove group #{@new_resource}") do
@@ -122,16 +122,16 @@ class Chef
end
end
end
-
+
def action_manage
if @group_exists && compare_group
converge_by(["manage group #{@new_resource}", @change_desc]) do
- manage_group
+ manage_group
Chef::Log.info("#{@new_resource} managed")
end
end
end
-
+
def action_modify
if compare_group
converge_by(["modify group #{@new_resource}", @change_desc]) do
@@ -140,7 +140,7 @@ class Chef
end
end
end
-
+
def create_group
raise NotImplementedError, "subclasses of Chef::Provider::Group should define #create_group"
end
diff --git a/lib/chef/provider/group/dscl.rb b/lib/chef/provider/group/dscl.rb
index a8ba32641c..d0b2a4d499 100644
--- a/lib/chef/provider/group/dscl.rb
+++ b/lib/chef/provider/group/dscl.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -38,7 +38,7 @@ class Chef
raise(Chef::Exceptions::Group,"dscl error: #{result.inspect}") if result[2] =~ /No such key: /
return result[2]
end
-
+
# This is handled in providers/group.rb by Etc.getgrnam()
# def group_exists?(group)
# groups = safe_dscl("list /Groups")
@@ -86,8 +86,8 @@ class Chef
def define_resource_requirements
super
- requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/bin/dscl") }
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/bin/dscl") }
a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/dscl for #{@new_resource.name}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
@@ -96,13 +96,13 @@ class Chef
def load_current_resource
super
end
-
+
def create_group
dscl_create_group
set_gid
set_members
end
-
+
def manage_group
if @new_resource.group_name && (@current_resource.group_name != @new_resource.group_name)
dscl_create_group
@@ -114,12 +114,12 @@ class Chef
set_members
end
end
-
+
def dscl_create_group
safe_dscl("create /Groups/#{@new_resource.group_name}")
safe_dscl("create /Groups/#{@new_resource.group_name} Password '*'")
end
-
+
def remove_group
safe_dscl("delete /Groups/#{@new_resource.group_name}")
end
diff --git a/lib/chef/provider/group/gpasswd.rb b/lib/chef/provider/group/gpasswd.rb
index 7fb27a7777..2638b82383 100644
--- a/lib/chef/provider/group/gpasswd.rb
+++ b/lib/chef/provider/group/gpasswd.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -32,9 +32,9 @@ class Chef
def define_resource_requirements
super
- requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/bin/gpasswd") }
- a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/gpasswd for #{@new_resource}"
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/bin/gpasswd") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/gpasswd for #{@new_resource}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
end
diff --git a/lib/chef/provider/group/groupadd.rb b/lib/chef/provider/group/groupadd.rb
index 544fee4304..45ae308612 100644
--- a/lib/chef/provider/group/groupadd.rb
+++ b/lib/chef/provider/group/groupadd.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@ class Chef
class Provider
class Group
class Groupadd < Chef::Provider::Group
-
+
def required_binaries
[ "/usr/sbin/groupadd",
"/usr/sbin/groupmod",
@@ -34,9 +34,9 @@ class Chef
def define_resource_requirements
super
required_binaries.each do |required_binary|
- requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?(required_binary) }
- a.failure_message Chef::Exceptions::Group, "Could not find binary #{required_binary} for #{@new_resource}"
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?(required_binary) }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary #{required_binary} for #{@new_resource}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
end
@@ -48,9 +48,9 @@ class Chef
command << set_options
command << groupadd_options
run_command(:command => command)
- modify_group_members
+ modify_group_members
end
-
+
# Manage the group when it already exists
def manage_group
command = "groupmod"
@@ -58,12 +58,12 @@ class Chef
run_command(:command => command)
modify_group_members
end
-
+
# Remove the group
def remove_group
run_command(:command => "groupdel #{@new_resource.group_name}")
end
-
+
def modify_group_members
raise Chef::Exceptions::Group, "you must override modify_group_members in #{self.to_s}"
end
@@ -87,6 +87,7 @@ class Chef
def groupadd_options
opts = ''
opts << " -r" if @new_resource.system
+ opts << " -o" if @new_resource.non_unique
opts
end
diff --git a/lib/chef/provider/group/pw.rb b/lib/chef/provider/group/pw.rb
index 3bf67a515a..66da8281be 100644
--- a/lib/chef/provider/group/pw.rb
+++ b/lib/chef/provider/group/pw.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,21 +20,21 @@ class Chef
class Provider
class Group
class Pw < Chef::Provider::Group
-
+
def load_current_resource
super
end
-
+
def define_resource_requirements
super
- requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/sbin/pw") }
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/sbin/pw") }
a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/pw for #{@new_resource}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
end
-
+
# Create the group
def create_group
command = "pw groupadd"
@@ -42,7 +42,7 @@ class Chef
command << set_members_option
run_command(:command => command)
end
-
+
# Manage the group when it already exists
def manage_group
command = "pw groupmod"
@@ -50,12 +50,12 @@ class Chef
command << set_members_option
run_command(:command => command)
end
-
+
# Remove the group
def remove_group
run_command(:command => "pw groupdel #{@new_resource.group_name}")
end
-
+
# Little bit of magic as per Adam's useradd provider to pull and assign the command line flags
#
# ==== Returns
@@ -86,7 +86,7 @@ class Chef
end
opt
end
-
+
end
end
end
diff --git a/lib/chef/provider/group/suse.rb b/lib/chef/provider/group/suse.rb
index 0b66c1f912..4c343bddf9 100644
--- a/lib/chef/provider/group/suse.rb
+++ b/lib/chef/provider/group/suse.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -32,8 +32,8 @@ class Chef
def define_resource_requirements
super
- requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/sbin/groupmod") }
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/sbin/groupmod") }
a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/groupmod for #{@new_resource.name}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
diff --git a/lib/chef/provider/group/usermod.rb b/lib/chef/provider/group/usermod.rb
index 0d44d3940f..5788ac8fad 100644
--- a/lib/chef/provider/group/usermod.rb
+++ b/lib/chef/provider/group/usermod.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ class Chef
class Provider
class Group
class Usermod < Chef::Provider::Group::Groupadd
-
+
def load_current_resource
super
end
@@ -30,24 +30,24 @@ class Chef
def define_resource_requirements
super
- requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/usr/sbin/usermod") }
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/sbin/usermod") }
a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/usermod for #{@new_resource}"
# No whyrun alternative: this component should be available in the base install of any given system that uses it
end
requirements.assert(:modify, :create) do |a|
- a.assertion { @new_resource.members.empty? || @new_resource.append }
+ a.assertion { @new_resource.members.empty? || @new_resource.append }
a.failure_message Chef::Exceptions::Group, "setting group members directly is not supported by #{self.to_s}, must set append true in group"
# No whyrun alternative - this action is simply not supported.
end
end
-
+
def modify_group_members
case node[:platform]
when "openbsd", "netbsd", "aix", "solaris2", "smartos"
append_flags = "-G"
- when "solaris", "suse"
+ when "solaris", "suse", "opensuse"
append_flags = "-a -G"
end
diff --git a/lib/chef/provider/group/windows.rb b/lib/chef/provider/group/windows.rb
index 88280408cd..da12366329 100644
--- a/lib/chef/provider/group/windows.rb
+++ b/lib/chef/provider/group/windows.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,16 +25,16 @@ class Chef
class Provider
class Group
class Windows < Chef::Provider::Group
-
+
def initialize(new_resource,run_context)
super
- @net_group = Chef::Util::Windows::NetGroup.new(@new_resource.name)
+ @net_group = Chef::Util::Windows::NetGroup.new(@new_resource.group_name)
end
def load_current_resource
@current_resource = Chef::Resource::Group.new(@new_resource.name)
@current_resource.group_name(@new_resource.group_name)
-
+
members = nil
begin
members = @net_group.local_get_members
@@ -49,12 +49,12 @@ class Chef
@current_resource
end
-
+
def create_group
@net_group.local_add
manage_group
end
-
+
def manage_group
if @new_resource.append
begin
@@ -68,11 +68,11 @@ class Chef
@net_group.local_set_members(@new_resource.members)
end
end
-
+
def remove_group
@net_group.local_delete
end
-
+
end
end
end
diff --git a/lib/chef/provider/http_request.rb b/lib/chef/provider/http_request.rb
index a5bc3b5e04..1e0aa8b4a0 100644
--- a/lib/chef/provider/http_request.rb
+++ b/lib/chef/provider/http_request.rb
@@ -17,26 +17,27 @@
#
require 'tempfile'
+require 'chef/http/simple'
class Chef
class Provider
class HttpRequest < Chef::Provider
- attr_accessor :rest
+ attr_accessor :http
def whyrun_supported?
true
end
def load_current_resource
- @rest = Chef::REST.new(@new_resource.url, nil, nil)
+ @http = Chef::HTTP::Simple.new(@new_resource.url)
end
# Send a HEAD request to @new_resource.url, with ?message=@new_resource.message
def action_head
message = check_message(@new_resource.message)
# returns true from Chef::REST if returns 2XX (Net::HTTPSuccess)
- modified = @rest.head(
+ modified = @http.head(
"#{@new_resource.url}?message=#{message}",
@new_resource.headers
)
@@ -53,9 +54,8 @@ class Chef
converge_by("#{@new_resource} GET to #{@new_resource.url}") do
message = check_message(@new_resource.message)
- body = @rest.get(
+ body = @http.get(
"#{@new_resource.url}?message=#{message}",
- false,
@new_resource.headers
)
Chef::Log.info("#{@new_resource} GET to #{@new_resource.url} successful")
@@ -67,7 +67,7 @@ class Chef
def action_put
converge_by("#{@new_resource} PUT to #{@new_resource.url}") do
message = check_message(@new_resource.message)
- body = @rest.put(
+ body = @http.put(
"#{@new_resource.url}",
message,
@new_resource.headers
@@ -81,7 +81,7 @@ class Chef
def action_post
converge_by("#{@new_resource} POST to #{@new_resource.url}") do
message = check_message(@new_resource.message)
- body = @rest.post(
+ body = @http.post(
"#{@new_resource.url}",
message,
@new_resource.headers
@@ -94,7 +94,7 @@ class Chef
# Send a DELETE request to @new_resource.url
def action_delete
converge_by("#{@new_resource} DELETE to #{@new_resource.url}") do
- body = @rest.delete(
+ body = @http.delete(
"#{@new_resource.url}",
@new_resource.headers
)
diff --git a/lib/chef/provider/ifconfig.rb b/lib/chef/provider/ifconfig.rb
index 0aacc9e616..31f88e5406 100644
--- a/lib/chef/provider/ifconfig.rb
+++ b/lib/chef/provider/ifconfig.rb
@@ -26,11 +26,11 @@ require 'erb'
#
# int = {Hash with your network settings...}
#
-# ifconfig int['ip'] do
-# ignore_failure true
-# device int['dev']
-# mask int['mask']
-# gateway int['gateway']
+# ifconfig int['ip'] do
+# ignore_failure true
+# device int['dev']
+# mask int['mask']
+# gateway int['gateway']
# mtu int['mtu']
# end
@@ -76,7 +76,7 @@ class Chef
@interface = @interfaces.fetch(@new_resource.device)
@current_resource.target(@new_resource.target)
- @current_resource.device(@int_name)
+ @current_resource.device(@new_resource.device)
@current_resource.inet_addr(@interface["inet_addr"])
@current_resource.hwaddr(@interface["hwaddr"])
@current_resource.bcast(@interface["bcast"])
@@ -89,12 +89,12 @@ class Chef
@current_resource
end
- def define_resource_requirements
- requirements.assert(:all_actions) do |a|
+ def define_resource_requirements
+ requirements.assert(:all_actions) do |a|
a.assertion { @status.exitstatus == 0 }
a.failure_message Chef::Exceptions::Ifconfig, "ifconfig failed - #{@status.inspect}!"
# no whyrun - if the base ifconfig used in load_current_resource fails
- # there's no reasonable action that could have been taken in the course of
+ # there's no reasonable action that could have been taken in the course of
# a chef run to fix it.
end
end
@@ -102,40 +102,32 @@ class Chef
def action_add
# check to see if load_current_resource found interface in ifconfig
unless @current_resource.inet_addr
- unless @new_resource.device == "lo"
- command = "ifconfig #{@new_resource.device} #{@new_resource.name}"
- command << " netmask #{@new_resource.mask}" if @new_resource.mask
- command << " metric #{@new_resource.metric}" if @new_resource.metric
- command << " mtu #{@new_resource.mtu}" if @new_resource.mtu
- end
- converge_by ("run #{command} to add #{@new_resource}") do
- run_command(
- :command => command
- )
- Chef::Log.info("#{@new_resource} added")
+ unless @new_resource.device == loopback_device
+ command = add_command
+ converge_by ("run #{command} to add #{@new_resource}") do
+ run_command(
+ :command => command
+ )
+ Chef::Log.info("#{@new_resource} added")
+ # Write out the config files
+ generate_config
+ end
end
end
-
- # Write out the config files
- generate_config
end
def action_enable
# check to see if load_current_resource found ifconfig
# enables, but does not manage config files
unless @current_resource.inet_addr
- unless @new_resource.device == "lo"
- command = "ifconfig #{@new_resource.device} #{@new_resource.name}"
- command << " netmask #{@new_resource.mask}" if @new_resource.mask
- command << " metric #{@new_resource.metric}" if @new_resource.metric
- command << " mtu #{@new_resource.mtu}" if @new_resource.mtu
- end
-
- converge_by ("run #{command} to enable #{@new_resource}") do
- run_command(
- :command => command
- )
- Chef::Log.info("#{@new_resource} enabled")
+ unless @new_resource.device == loopback_device
+ command = enable_command
+ converge_by ("run #{command} to enable #{@new_resource}") do
+ run_command(
+ :command => command
+ )
+ Chef::Log.info("#{@new_resource} enabled")
+ end
end
end
end
@@ -143,7 +135,7 @@ class Chef
def action_delete
# check to see if load_current_resource found the interface
if @current_resource.device
- command = "ifconfig #{@new_resource.device} down"
+ command = delete_command
converge_by ("run #{command} to delete #{@new_resource}") do
run_command(
:command => command
@@ -160,7 +152,7 @@ class Chef
# check to see if load_current_resource found the interface
# disables, but leaves config files in place.
if @current_resource.device
- command = "ifconfig #{@new_resource.device} down"
+ command = disable_command
converge_by ("run #{command} to disable #{@new_resource}") do
run_command(
:command => command
@@ -199,6 +191,34 @@ class Chef
Chef::Log.info("#{@new_resource} deleted configuration file")
end
+ private
+ def add_command
+ command = "ifconfig #{@new_resource.device} #{@new_resource.name}"
+ command << " netmask #{@new_resource.mask}" if @new_resource.mask
+ command << " metric #{@new_resource.metric}" if @new_resource.metric
+ command << " mtu #{@new_resource.mtu}" if @new_resource.mtu
+ command
+ end
+
+ def enable_command
+ command = "ifconfig #{@new_resource.device} #{@new_resource.name}"
+ command << " netmask #{@new_resource.mask}" if @new_resource.mask
+ command << " metric #{@new_resource.metric}" if @new_resource.metric
+ command << " mtu #{@new_resource.mtu}" if @new_resource.mtu
+ command
+ end
+
+ def disable_command
+ "ifconfig #{@new_resource.device} down"
+ end
+
+ def delete_command
+ "ifconfig #{@new_resource.device} down"
+ end
+
+ def loopback_device
+ 'lo'
+ end
end
end
end
diff --git a/lib/chef/provider/ifconfig/aix.rb b/lib/chef/provider/ifconfig/aix.rb
new file mode 100644
index 0000000000..460b1ba7f2
--- /dev/null
+++ b/lib/chef/provider/ifconfig/aix.rb
@@ -0,0 +1,99 @@
+#
+# Author:: Kaustubh Deorukhkar (kaustubh@clogeny.com)
+# Copyright:: Copyright (c) 2013 Opscode, Inc
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/ifconfig'
+
+class Chef
+ class Provider
+ class Ifconfig
+ class Aix < Chef::Provider::Ifconfig
+
+ def load_current_resource
+ @current_resource = Chef::Resource::Ifconfig.new(@new_resource.name)
+
+ @interface_exists = false
+ found_interface = false
+ interface = {}
+
+ @status = popen4("ifconfig -a") do |pid, stdin, stdout, stderr|
+ stdout.each do |line|
+
+ if !found_interface
+ if line =~ /^(\S+):\sflags=(\S+)/
+ # We have interface name, if this is the interface for @current_resource, load info else skip till next interface is found.
+ if $1 == @new_resource.device
+ # Found interface
+ found_interface = true
+ @interface_exists = true
+ @current_resource.target(@new_resource.target)
+ @current_resource.device($1)
+ interface[:flags] = $2
+ @current_resource.metric($1) if line =~ /metric\s(\S+)/
+ end
+ end
+ else
+ # parse interface related information, stop when next interface is found.
+ if line =~ /^(\S+):\sflags=(\S+)/
+ # we are done parsing interface info and hit another one, so stop.
+ found_interface = false
+ break
+ else
+ if found_interface
+ # read up interface info
+ @current_resource.inet_addr($1) if line =~ /inet\s(\S+)\s/
+ @current_resource.bcast($1) if line =~ /broadcast\s(\S+)/
+ @current_resource.mask(hex_to_dec_netmask($1)) if line =~ /netmask\s(\S+)\s/
+ end
+ end
+ end
+ end
+ end
+
+ @current_resource
+ end
+
+ private
+ def add_command
+ # ifconfig changes are temporary, chdev persist across reboots.
+ raise Chef::Exceptions::Ifconfig, "interface metric attribute cannot be set for :add action" if @new_resource.metric
+ command = "chdev -l #{@new_resource.device} -a netaddr=#{@new_resource.name}"
+ command << " -a netmask=#{@new_resource.mask}" if @new_resource.mask
+ command << " -a mtu=#{@new_resource.mtu}" if @new_resource.mtu
+ command
+ end
+
+ def delete_command
+ # ifconfig changes are temporary, chdev persist across reboots.
+ "chdev -l #{@new_resource.device} -a state=down"
+ end
+
+ def loopback_device
+ "lo0"
+ end
+
+ def hex_to_dec_netmask(netmask)
+ # example '0xffff0000' -> '255.255.0.0'
+ dec = netmask[2..3].to_i(16).to_s(10)
+ [4,6,8].each { |n| dec = dec + "." + netmask[n..n+1].to_i(16).to_s(10) }
+ dec
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/log.rb b/lib/chef/provider/log.rb
index 927ee72fcc..1c970cc888 100644
--- a/lib/chef/provider/log.rb
+++ b/lib/chef/provider/log.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -32,7 +32,7 @@ class Chef
def load_current_resource
true
end
-
+
# Write the log to Chef's log
#
# === Return
diff --git a/lib/chef/provider/mdadm.rb b/lib/chef/provider/mdadm.rb
index d93ff69c13..51c9b8d3c6 100644
--- a/lib/chef/provider/mdadm.rb
+++ b/lib/chef/provider/mdadm.rb
@@ -47,8 +47,9 @@ class Chef
def action_create
unless @current_resource.exists
- converge_by("create RAID device #{new_resource.raid_device}") do
- command = "yes | mdadm --create #{@new_resource.raid_device} --chunk=#{@new_resource.chunk} --level #{@new_resource.level}"
+ converge_by("create RAID device #{new_resource.raid_device}") do
+ command = "yes | mdadm --create #{@new_resource.raid_device} --level #{@new_resource.level}"
+ command << " --chunk=#{@new_resource.chunk}" unless @new_resource.level == 1
command << " --metadata=#{@new_resource.metadata}"
command << " --bitmap=#{@new_resource.bitmap}" if @new_resource.bitmap
command << " --raid-devices #{@new_resource.devices.length} #{@new_resource.devices.join(" ")}"
@@ -63,7 +64,7 @@ class Chef
def action_assemble
unless @current_resource.exists
- converge_by("assemble RAID device #{new_resource.raid_device}") do
+ converge_by("assemble RAID device #{new_resource.raid_device}") do
command = "yes | mdadm --assemble #{@new_resource.raid_device} #{@new_resource.devices.join(" ")}"
Chef::Log.debug("#{@new_resource} mdadm command: #{command}")
shell_out!(command)
@@ -76,7 +77,7 @@ class Chef
def action_stop
if @current_resource.exists
- converge_by("stop RAID device #{new_resource.raid_device}") do
+ converge_by("stop RAID device #{new_resource.raid_device}") do
command = "yes | mdadm --stop #{@new_resource.raid_device}"
Chef::Log.debug("#{@new_resource} mdadm command: #{command}")
shell_out!(command)
diff --git a/lib/chef/provider/mount.rb b/lib/chef/provider/mount.rb
index 6b9dd91ac8..5f58baa396 100644
--- a/lib/chef/provider/mount.rb
+++ b/lib/chef/provider/mount.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -37,7 +37,7 @@ class Chef
def action_mount
unless @current_resource.mounted
- converge_by("mount #{@current_resource.device} to #{@current_resource.mount_point}") do
+ converge_by("mount #{@current_resource.device} to #{@current_resource.mount_point}") do
status = mount_fs()
if status
Chef::Log.info("#{@new_resource} mounted")
@@ -50,7 +50,7 @@ class Chef
def action_umount
if @current_resource.mounted
- converge_by("unmount #{@current_resource.device}") do
+ converge_by("unmount #{@current_resource.device}") do
status = umount_fs()
if status
Chef::Log.info("#{@new_resource} unmounted")
@@ -66,7 +66,7 @@ class Chef
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remount"
else
if @current_resource.mounted
- converge_by("remount #{@current_resource.device}") do
+ converge_by("remount #{@current_resource.device}") do
status = remount_fs()
if status
Chef::Log.info("#{@new_resource} remounted")
@@ -80,7 +80,7 @@ class Chef
def action_enable
unless @current_resource.enabled && mount_options_unchanged?
- converge_by("remount #{@current_resource.device}") do
+ converge_by("remount #{@current_resource.device}") do
status = enable_fs
if status
Chef::Log.info("#{@new_resource} enabled")
@@ -93,7 +93,7 @@ class Chef
def action_disable
if @current_resource.enabled
- converge_by("remount #{@current_resource.device}") do
+ converge_by("remount #{@current_resource.device}") do
status = disable_fs
if status
Chef::Log.info("#{@new_resource} disabled")
@@ -115,14 +115,14 @@ class Chef
def remount_fs
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :remount"
end
-
+
def enable_fs
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :enable"
+ raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :enable"
end
-
+
def disable_fs
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :disable"
- end
+ raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :disable"
+ end
end
end
end
diff --git a/lib/chef/provider/mount/aix.rb b/lib/chef/provider/mount/aix.rb
new file mode 100644
index 0000000000..0d7e11a1b8
--- /dev/null
+++ b/lib/chef/provider/mount/aix.rb
@@ -0,0 +1,179 @@
+#
+# Author::
+# Copyright:: Copyright (c) 2009 Opscode, Inc
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/mount'
+
+class Chef
+ class Provider
+ class Mount
+ class Aix < Chef::Provider::Mount::Mount
+
+ # Override for aix specific handling
+ def initialize(new_resource, run_context)
+ super
+ # options and fstype are set to "defaults" and "auto" respectively in the Mount Resource class. These options are not valid for AIX, override them.
+ if @new_resource.options[0] == "defaults"
+ @new_resource.options.clear
+ end
+ if @new_resource.fstype == "auto"
+ @new_resource.fstype = nil
+ end
+ end
+
+ def enabled?
+ # Check to see if there is an entry in /etc/filesystems. Last entry for a volume wins. Using command "lsfs" to fetch entries.
+ enabled = false
+
+ # lsfs o/p = #MountPoint:Device:Vfs:Nodename:Type:Size:Options:AutoMount:Acct
+ # search only for current mount point
+ shell_out("lsfs -c #{@new_resource.mount_point}").stdout.each_line do | line |
+ case line
+ when /^#\s/
+ next
+ when /^#{Regexp.escape(@new_resource.mount_point)}:#{device_fstab_regex}:(\S+):(\[\S+\])?:(\S+)?:(\S+):(\S+):(\S+):(\S+)/
+ # mount point entry with ipv6 address for nodename (ipv6 address use ':')
+ enabled = true
+ @current_resource.fstype($1)
+ @current_resource.options($5)
+ Chef::Log.debug("Found mount #{device_fstab} to #{@new_resource.mount_point} in /etc/filesystems")
+ next
+ when /^#{Regexp.escape(@new_resource.mount_point)}:#{device_fstab_regex}::(\S+):(\S+)?:(\S+)?:(\S+):(\S+):(\S+):(\S+)/
+ # mount point entry with hostname or ipv4 address
+ enabled = true
+ @current_resource.fstype($1)
+ @current_resource.options($5)
+ Chef::Log.debug("Found mount #{device_fstab} to #{@new_resource.mount_point} in /etc/filesystems")
+ next
+ when /^#{Regexp.escape(@new_resource.mount_point)}/
+ enabled=false
+ Chef::Log.debug("Found conflicting mount point #{@new_resource.mount_point} in /etc/filesystems")
+ end
+ end
+ @current_resource.enabled(enabled)
+ end
+
+ def mounted?
+ mounted = false
+ shell_out!("mount").stdout.each_line do |line|
+ if network_device?
+ device_details = device_fstab.split(":")
+ search_device = device_details[1]
+ else
+ search_device = device_fstab_regex
+ end
+ case line
+ when /#{search_device}\s+#{Regexp.escape(@new_resource.mount_point)}/
+ mounted = true
+ Chef::Log.debug("Special device #{device_logstring} mounted as #{@new_resource.mount_point}")
+ when /^[\/\w]+\s+#{Regexp.escape(@new_resource.mount_point)}\s+/
+ mounted = false
+ Chef::Log.debug("Found conflicting mount point #{@new_resource.mount_point} in /etc/fstab")
+ end
+ end
+ @current_resource.mounted(mounted)
+ end
+
+ def mount_fs
+ unless @current_resource.mounted
+ mountable?
+ command = "mount -v #{@new_resource.fstype}"
+
+ if !(@new_resource.options.nil? || @new_resource.options.empty?)
+ command << " -o #{@new_resource.options.join(',')}"
+ end
+
+ command << case @new_resource.device_type
+ when :device
+ " #{device_real}"
+ when :label
+ " -L #{@new_resource.device}"
+ when :uuid
+ " -U #{@new_resource.device}"
+ end
+ command << " #{@new_resource.mount_point}"
+ shell_out!(command)
+ Chef::Log.debug("#{@new_resource} is mounted at #{@new_resource.mount_point}")
+ else
+ Chef::Log.debug("#{@new_resource} is already mounted at #{@new_resource.mount_point}")
+ end
+ end
+
+ def remount_command
+ if !(@new_resource.options.nil? || @new_resource.options.empty?)
+ return "mount -o remount,#{@new_resource.options.join(',')} #{@new_resource.device} #{@new_resource.mount_point}"
+ else
+ return "mount -o remount #{@new_resource.device} #{@new_resource.mount_point}"
+ end
+ end
+
+ def enable_fs
+ if @current_resource.enabled && mount_options_unchanged?
+ Chef::Log.debug("#{@new_resource} is already enabled - nothing to do")
+ return nil
+ end
+
+ if @current_resource.enabled
+ # The current options don't match what we have, so
+ # disable, then enable.
+ disable_fs
+ end
+ ::File.open("/etc/filesystems", "a") do |fstab|
+ fstab.puts("#{@new_resource.mount_point}:")
+ if network_device?
+ device_details = device_fstab.split(":")
+ fstab.puts("\tdev\t\t= #{device_details[1]}")
+ fstab.puts("\tnodename\t\t= #{device_details[0]}")
+ else
+ fstab.puts("\tdev\t\t= #{device_fstab}")
+ end
+ fstab.puts("\tvfs\t\t= #{@new_resource.fstype}")
+ fstab.puts("\tmount\t\t= false")
+ fstab.puts "\toptions\t\t= #{@new_resource.options.join(',')}" unless @new_resource.options.nil? || @new_resource.options.empty?
+ Chef::Log.debug("#{@new_resource} is enabled at #{@new_resource.mount_point}")
+ end
+ end
+
+ def disable_fs
+ contents = []
+ if @current_resource.enabled
+ found_device = false
+ ::File.open("/etc/filesystems", "r").each_line do |line|
+ case line
+ when /^\/.+:\s*$/
+ if line =~ /#{Regexp.escape(@new_resource.mount_point)}+:/
+ found_device = true
+ else
+ found_device = false
+ end
+ end
+ if !found_device
+ contents << line
+ end
+ end
+ ::File.open("/etc/filesystems", "w") do |fstab|
+ contents.each { |line| fstab.puts line}
+ end
+ else
+ Chef::Log.debug("#{@new_resource} is not enabled - nothing to do")
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb
index ec54831017..25dfd42725 100644
--- a/lib/chef/provider/mount/mount.rb
+++ b/lib/chef/provider/mount/mount.rb
@@ -39,7 +39,7 @@ class Chef
mounted?
enabled?
end
-
+
def mountable?
# only check for existence of non-remote devices
if (device_should_exist? && !::File.exists?(device_real) )
@@ -49,7 +49,7 @@ class Chef
end
return true
end
-
+
def enabled?
# Check to see if there is a entry in /etc/fstab. Last entry for a volume wins.
enabled = false
@@ -72,17 +72,27 @@ class Chef
end
@current_resource.enabled(enabled)
end
-
+
def mounted?
mounted = false
+
+ # "mount" outputs the mount points as real paths. Convert
+ # the mount_point of the resource to a real path in case it
+ # contains symlinks in its parents dirs.
+ real_mount_point = if ::File.exists? @new_resource.mount_point
+ ::File.realpath(@new_resource.mount_point)
+ else
+ @new_resource.mount_point
+ end
+
shell_out!("mount").stdout.each_line do |line|
case line
- when /^#{device_mount_regex}\s+on\s+#{Regexp.escape(@new_resource.mount_point)}/
+ when /^#{device_mount_regex}\s+on\s+#{Regexp.escape(real_mount_point)}/
mounted = true
- Chef::Log.debug("Special device #{device_logstring} mounted as #{@new_resource.mount_point}")
- when /^([\/\w])+\son\s#{Regexp.escape(@new_resource.mount_point)}\s+/
+ Chef::Log.debug("Special device #{device_logstring} mounted as #{real_mount_point}")
+ when /^([\/\w])+\son\s#{Regexp.escape(real_mount_point)}\s+/
mounted = false
- Chef::Log.debug("Special device #{$~[1]} mounted as #{@new_resource.mount_point}")
+ Chef::Log.debug("Special device #{$~[1]} mounted as #{real_mount_point}")
end
end
@current_resource.mounted(mounted)
@@ -118,9 +128,13 @@ class Chef
end
end
+ def remount_command
+ return "mount -o remount #{@new_resource.mount_point}"
+ end
+
def remount_fs
if @current_resource.mounted and @new_resource.supports[:remount]
- shell_out!("mount -o remount #{@new_resource.mount_point}")
+ shell_out!(remount_command)
@new_resource.updated_by_last_action(true)
Chef::Log.debug("#{@new_resource} is remounted at #{@new_resource.mount_point}")
elsif @current_resource.mounted
@@ -137,7 +151,7 @@ class Chef
Chef::Log.debug("#{@new_resource} is already enabled - nothing to do")
return nil
end
-
+
if @current_resource.enabled
# The current options don't match what we have, so
# disable, then enable.
@@ -152,7 +166,7 @@ class Chef
def disable_fs
if @current_resource.enabled
contents = []
-
+
found = false
::File.readlines("/etc/fstab").reverse_each do |line|
if !found && line =~ /^#{device_fstab_regex}\s+#{Regexp.escape(@new_resource.mount_point)}/
@@ -163,7 +177,7 @@ class Chef
contents << line
end
end
-
+
::File.open("/etc/fstab", "w") do |fstab|
contents.reverse_each { |line| fstab.puts line}
end
@@ -177,7 +191,7 @@ class Chef
end
def device_should_exist?
- ( @new_resource.device != "none" ) &&
+ ( @new_resource.device != "none" ) &&
( not network_device? ) &&
( not %w[ tmpfs fuse ].include? @new_resource.fstype )
end
@@ -196,7 +210,7 @@ class Chef
end
def device_real
- if @real_device == nil
+ if @real_device == nil
if @new_resource.device_type == :device
@real_device = @new_resource.device
else
@@ -243,14 +257,14 @@ class Chef
device_fstab
end
end
-
+
def mount_options_unchanged?
@current_resource.fstype == @new_resource.fstype and
@current_resource.options == @new_resource.options and
@current_resource.dump == @new_resource.dump and
@current_resource.pass == @new_resource.pass
end
-
+
end
end
end
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index a28a6f93fb..c7692a9746 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -50,7 +50,7 @@ class Chef
requirements.assert(:upgrade) do |a|
# Can't upgrade what we don't have
- a.assertion { !(@current_resource.version.nil? && candidate_version.nil?) }
+ a.assertion { !(@current_resource.version.nil? && candidate_version.nil?) }
a.failure_message(Chef::Exceptions::Package, "No candidate version available for #{@new_resource.package_name}")
a.whyrun("Assuming a repository that offers #{@new_resource.package_name} would have been configured")
end
@@ -71,9 +71,9 @@ class Chef
# We need to make sure we handle the preseed file
if @new_resource.response_file
if preseed_file = get_preseed_file(@new_resource.package_name, install_version)
- converge_by("preseed package #{@new_resource.package_name}") do
+ converge_by("preseed package #{@new_resource.package_name}") do
preseed_package(preseed_file)
- end
+ end
end
end
description = install_version ? "version #{install_version} of" : ""
@@ -92,7 +92,7 @@ class Chef
@new_resource.version(candidate_version)
orig_version = @current_resource.version || "uninstalled"
converge_by("upgrade package #{@new_resource.package_name} from #{orig_version} to #{candidate_version}") do
- status = upgrade_package(@new_resource.package_name, candidate_version)
+ upgrade_package(@new_resource.package_name, candidate_version)
Chef::Log.info("#{@new_resource} upgraded from #{orig_version} to #{candidate_version}")
end
end
@@ -146,7 +146,7 @@ class Chef
if preseed_file = get_preseed_file(@new_resource.package_name, @current_resource.version)
converge_by("reconfigure package #{@new_resource.package_name}") do
preseed_package(preseed_file)
- status = reconfig_package(@new_resource.package_name, @current_resource.version)
+ reconfig_package(@new_resource.package_name, @current_resource.version)
Chef::Log.info("#{@new_resource} reconfigured")
end
else
@@ -198,21 +198,21 @@ class Chef
Chef::Log.debug("#{@new_resource} fetching preseed file to #{cache_seed_to}")
- begin
+
+ if template_available?(@new_resource.response_file)
+ Chef::Log.debug("#{@new_resource} fetching preseed file via Template")
remote_file = Chef::Resource::Template.new(cache_seed_to, run_context)
- remote_file.cookbook_name = @new_resource.cookbook_name
- remote_file.source(@new_resource.response_file)
- remote_file.backup(false)
- provider = Chef::Platform.provider_for_resource(remote_file, :create)
- provider.template_location
- rescue
- Chef::Log.debug("#{@new_resource} fetching preseed file via Template resource failed, fallback to CookbookFile resource")
+ elsif cookbook_file_available?(@new_resource.response_file)
+ Chef::Log.debug("#{@new_resource} fetching preseed file via cookbook_file")
remote_file = Chef::Resource::CookbookFile.new(cache_seed_to, run_context)
- remote_file.cookbook_name = @new_resource.cookbook_name
- remote_file.source(@new_resource.response_file)
- remote_file.backup(false)
+ else
+ message = "No template or cookbook file found for response file #{@new_resource.response_file}"
+ raise Chef::Exceptions::FileNotFound, message
end
+ remote_file.cookbook_name = @new_resource.cookbook_name
+ remote_file.source(@new_resource.response_file)
+ remote_file.backup(false)
remote_file
end
@@ -224,6 +224,16 @@ class Chef
@new_resource.version == @current_resource.version
end
+ private
+
+ def template_available?(path)
+ run_context.has_template_in_cookbook?(@new_resource.cookbook_name, path)
+ end
+
+ def cookbook_file_available?(path)
+ run_context.has_cookbook_file_in_cookbook?(@new_resource.cookbook_name, path)
+ end
+
end
end
end
diff --git a/lib/chef/provider/package/aix.rb b/lib/chef/provider/package/aix.rb
new file mode 100644
index 0000000000..4df0ea7a33
--- /dev/null
+++ b/lib/chef/provider/package/aix.rb
@@ -0,0 +1,146 @@
+#
+# Author:: Deepali Jagtap
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+require 'chef/provider/package'
+require 'chef/mixin/command'
+require 'chef/resource/package'
+require 'chef/mixin/get_source_from_package'
+
+class Chef
+ class Provider
+ class Package
+ class Aix < Chef::Provider::Package
+
+ include Chef::Mixin::GetSourceFromPackage
+
+ def define_resource_requirements
+ super
+ requirements.assert(:install) do |a|
+ a.assertion { @new_resource.source }
+ a.failure_message Chef::Exceptions::Package, "Source for package #{@new_resource.name} required for action install"
+ end
+ requirements.assert(:all_actions) do |a|
+ a.assertion { !@new_resource.source || @package_source_found }
+ a.failure_message Chef::Exceptions::Package, "Package #{@new_resource.name} not found: #{@new_resource.source}"
+ a.whyrun "would assume #{@new_resource.source} would be have previously been made available"
+ end
+ end
+
+ def load_current_resource
+ @current_resource = Chef::Resource::Package.new(@new_resource.name)
+ @current_resource.package_name(@new_resource.package_name)
+ @new_resource.version(nil)
+
+ if @new_resource.source
+ @package_source_found = ::File.exists?(@new_resource.source)
+ if @package_source_found
+ Chef::Log.debug("#{@new_resource} checking pkg status")
+ status = popen4("installp -L -d #{@new_resource.source}") do |pid, stdin, stdout, stderr|
+ package_found = false
+ stdout.each do |line|
+ case line
+ when /#{@new_resource.package_name}:/
+ package_found = true
+ fields = line.split(":")
+ @new_resource.version(fields[2])
+ end
+ end
+ end
+ end
+ end
+
+ Chef::Log.debug("#{@new_resource} checking install state")
+ status = popen4("lslpp -lcq #{@current_resource.package_name}") do |pid, stdin, stdout, stderr|
+ stdout.each do |line|
+ case line
+ when /#{@current_resource.package_name}/
+ fields = line.split(":")
+ Chef::Log.debug("#{@new_resource} version #{fields[2]} is already installed")
+ @current_resource.version(fields[2])
+ end
+ end
+ end
+
+ unless status.exitstatus == 0 || status.exitstatus == 1
+ raise Chef::Exceptions::Package, "lslpp failed - #{status.inspect}!"
+ end
+
+ @current_resource
+ end
+
+ def candidate_version
+ return @candidate_version if @candidate_version
+ status = popen4("installp -L -d #{@new_resource.source}") do |pid, stdin, stdout, stderr|
+ stdout.each_line do |line|
+ case line
+ when /\w:{Regexp.escape(@new_resource.package_name)}:(.*)/
+ fields = line.split(":")
+ @candidate_version = fields[2]
+ @new_resource.version(fields[2])
+ Chef::Log.debug("#{@new_resource} setting install candidate version to #{@candidate_version}")
+ end
+ end
+ end
+ unless status.exitstatus == 0
+ raise Chef::Exceptions::Package, "installp -L -d #{@new_resource.source} - #{status.inspect}!"
+ end
+ @candidate_version
+ end
+
+ #
+ # The install/update action needs to be tested with various kinds of packages
+ # on AIX viz. packages with or without licensing file dependencies, packages
+ # with dependencies on other packages which will help to test additional
+ # options of installp.
+ # So far, the code has been tested only with standalone packages.
+ #
+ def install_package(name, version)
+ Chef::Log.debug("#{@new_resource} package install options: #{@new_resource.options}")
+ if @new_resource.options.nil?
+ run_command_with_systems_locale(
+ :command => "installp -aYF -d #{@new_resource.source} #{@new_resource.package_name}"
+ )
+ Chef::Log.debug("#{@new_resource} installed version #{@new_resource.version} from: #{@new_resource.source}")
+ else
+ run_command_with_systems_locale(
+ :command => "installp -aYF #{expand_options(@new_resource.options)} -d #{@new_resource.source} #{@new_resource.package_name}"
+ )
+ Chef::Log.debug("#{@new_resource} installed version #{@new_resource.version} from: #{@new_resource.source}")
+ end
+ end
+
+ alias_method :upgrade_package, :install_package
+
+ def remove_package(name, version)
+ if @new_resource.options.nil?
+ run_command_with_systems_locale(
+ :command => "installp -u #{name}"
+ )
+ Chef::Log.debug("#{@new_resource} removed version #{@new_resource.version}")
+ else
+ run_command_with_systems_locale(
+ :command => "installp -u #{expand_options(@new_resource.options)} #{name}"
+ )
+ Chef::Log.debug("#{@new_resource} removed version #{@new_resource.version}")
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/apt.rb b/lib/chef/provider/package/apt.rb
index e8939b494e..dc7b3f2086 100644
--- a/lib/chef/provider/package/apt.rb
+++ b/lib/chef/provider/package/apt.rb
@@ -65,7 +65,8 @@ class Chef
@is_virtual_package = true
showpkg = shell_out!("apt-cache showpkg #{package}").stdout
providers = Hash.new
- showpkg.rpartition(/Reverse Provides:? #{$/}/)[2].each_line do |line|
+ # Returns all lines after 'Reverse Provides:'
+ showpkg.rpartition(/Reverse Provides:\s*#{$/}/)[2].each_line do |line|
provider, version = line.split
providers[provider] = version
end
@@ -90,12 +91,7 @@ class Chef
def install_package(name, version)
package_name = "#{name}=#{version}"
package_name = name if @is_virtual_package
- run_command_with_systems_locale(
- :command => "apt-get -q -y#{expand_options(default_release_options)}#{expand_options(@new_resource.options)} install #{package_name}",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- )
+ run_noninteractive("apt-get -q -y#{expand_options(default_release_options)}#{expand_options(@new_resource.options)} install #{package_name}")
end
def upgrade_package(name, version)
@@ -104,41 +100,30 @@ class Chef
def remove_package(name, version)
package_name = "#{name}"
- run_command_with_systems_locale(
- :command => "apt-get -q -y#{expand_options(@new_resource.options)} remove #{package_name}",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- )
+ run_noninteractive("apt-get -q -y#{expand_options(@new_resource.options)} remove #{package_name}")
end
def purge_package(name, version)
- run_command_with_systems_locale(
- :command => "apt-get -q -y#{expand_options(@new_resource.options)} purge #{@new_resource.package_name}",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- )
+ run_noninteractive("apt-get -q -y#{expand_options(@new_resource.options)} purge #{@new_resource.package_name}")
end
def preseed_package(preseed_file)
Chef::Log.info("#{@new_resource} pre-seeding package installation instructions")
- run_command_with_systems_locale(
- :command => "debconf-set-selections #{preseed_file}",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- )
+ run_noninteractive("debconf-set-selections #{preseed_file}")
end
def reconfig_package(name, version)
Chef::Log.info("#{@new_resource} reconfiguring")
- run_command_with_systems_locale(
- :command => "dpkg-reconfigure #{name}",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- )
+ run_noninteractive("dpkg-reconfigure #{name}")
+ end
+
+ private
+
+ # Runs command via shell_out with magic environment to disable
+ # interactive prompts. Command is run with default localization rather
+ # than forcing locale to "C", so command output may not be stable.
+ def run_noninteractive(command)
+ shell_out!(command, :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil })
end
end
diff --git a/lib/chef/provider/package/dpkg.rb b/lib/chef/provider/package/dpkg.rb
index 795a7b308b..8ec1ad5878 100644
--- a/lib/chef/provider/package/dpkg.rb
+++ b/lib/chef/provider/package/dpkg.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -32,14 +32,14 @@ class Chef
include Chef::Mixin::GetSourceFromPackage
def define_resource_requirements
super
- requirements.assert(:install) do |a|
+ requirements.assert(:install) do |a|
a.assertion{ not @new_resource.source.nil? }
a.failure_message Chef::Exceptions::Package, "Source for package #{@new_resource.name} required for action install"
end
# TODO this was originally written for any action in which .source is provided
# but would it make more sense to only look at source if the action is :install?
- requirements.assert(:all_actions) do |a|
+ requirements.assert(:all_actions) do |a|
a.assertion { @source_exists }
a.failure_message Chef::Exceptions::Package, "Package #{@new_resource.name} not found: #{@new_resource.source}"
a.whyrun "Assuming it would have been previously downloaded."
@@ -53,7 +53,7 @@ class Chef
@new_resource.version(nil)
if @new_resource.source
- @source_exists = ::File.exists?(@new_resource.source)
+ @source_exists = ::File.exists?(@new_resource.source)
if @source_exists
# Get information from the package if supplied
Chef::Log.debug("#{@new_resource} checking dpkg status")
@@ -71,7 +71,7 @@ class Chef
end
end
-
+
# Check to see if it is installed
package_installed = nil
Chef::Log.debug("#{@new_resource} checking install state")
@@ -92,10 +92,10 @@ class Chef
unless status.exitstatus == 0 || status.exitstatus == 1
raise Chef::Exceptions::Package, "dpkg failed - #{status.inspect}!"
end
-
+
@current_resource
end
-
+
def install_package(name, version)
run_command_with_systems_locale(
:command => "dpkg -i#{expand_options(@new_resource.options)} #{@new_resource.source}",
@@ -113,7 +113,7 @@ class Chef
}
)
end
-
+
def purge_package(name, version)
run_command_with_systems_locale(
:command => "dpkg -P#{expand_options(@new_resource.options)} #{@new_resource.package_name}",
diff --git a/lib/chef/provider/package/freebsd.rb b/lib/chef/provider/package/freebsd.rb
index afdd0d812e..f9cb5eb422 100644
--- a/lib/chef/provider/package/freebsd.rb
+++ b/lib/chef/provider/package/freebsd.rb
@@ -37,7 +37,7 @@ class Chef
def current_installed_version
pkg_info = shell_out!("pkg_info -E \"#{package_name}*\"", :env => nil, :returns => [0,1])
- pkg_info.stdout[/^#{package_name}-(.+)/, 1]
+ pkg_info.stdout[/^#{Regexp.escape(package_name)}-(.+)/, 1]
end
def port_path
@@ -52,7 +52,7 @@ class Chef
# Otherwise look up the path to the ports directory using 'whereis'
else
whereis = shell_out!("whereis -s #{@new_resource.package_name}", :env => nil)
- unless path = whereis.stdout[/^#{@new_resource.package_name}:\s+(.+)$/, 1]
+ unless path = whereis.stdout[/^#{Regexp.escape(@new_resource.package_name)}:\s+(.+)$/, 1]
raise Chef::Exceptions::Package, "Could not find port with the name #{@new_resource.package_name}"
end
path
diff --git a/lib/chef/provider/package/ips.rb b/lib/chef/provider/package/ips.rb
index 5beb46a20a..2c6d98d81a 100644
--- a/lib/chef/provider/package/ips.rb
+++ b/lib/chef/provider/package/ips.rb
@@ -33,12 +33,12 @@ class Chef
def define_resource_requirements
super
-
+
requirements.assert(:all_actions) do |a|
a.assertion { ! @candidate_version.nil? }
a.failure_message Chef::Exceptions::Package, "Package #{@new_resource.package_name} not found"
a.whyrun "Assuming package #{@new_resource.package_name} would have been made available."
- end
+ end
end
def load_current_resource
@@ -52,7 +52,7 @@ class Chef
Chef::Log.debug("Checking package status for #{package}")
installed = false
depends = false
-
+
shell_out!("pkg info -r #{package}").stdout.each_line do |line|
case line
when /^\s+State: Installed/
diff --git a/lib/chef/provider/package/macports.rb b/lib/chef/provider/package/macports.rb
index fd33788944..6ef303ee4f 100644
--- a/lib/chef/provider/package/macports.rb
+++ b/lib/chef/provider/package/macports.rb
@@ -44,7 +44,7 @@ class Chef
def install_package(name, version)
unless @current_resource.version == version
command = "port#{expand_options(@new_resource.options)} install #{name}"
- command << " @#{version}" if version and !version.empty?
+ command << " @#{version}" if version and !version.empty?
run_command_with_systems_locale(
:command => command
)
diff --git a/lib/chef/provider/package/pacman.rb b/lib/chef/provider/package/pacman.rb
index f81486ae84..2e8bb7850b 100644
--- a/lib/chef/provider/package/pacman.rb
+++ b/lib/chef/provider/package/pacman.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,7 +24,7 @@ class Chef
class Provider
class Package
class Pacman < Chef::Provider::Package
-
+
def load_current_resource
@current_resource = Chef::Resource::Package.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
@@ -84,27 +84,27 @@ class Chef
@candidate_version
end
-
+
def install_package(name, version)
run_command_with_systems_locale(
:command => "pacman --sync --noconfirm --noprogressbar#{expand_options(@new_resource.options)} #{name}"
)
end
-
+
def upgrade_package(name, version)
install_package(name, version)
end
-
+
def remove_package(name, version)
run_command_with_systems_locale(
:command => "pacman --remove --noconfirm --noprogressbar#{expand_options(@new_resource.options)} #{name}"
)
end
-
+
def purge_package(name, version)
remove_package(name, version)
end
-
+
end
end
end
diff --git a/lib/chef/provider/package/rpm.rb b/lib/chef/provider/package/rpm.rb
index 033ce8efb9..616a78a2f5 100644
--- a/lib/chef/provider/package/rpm.rb
+++ b/lib/chef/provider/package/rpm.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,18 +30,18 @@ class Chef
def define_resource_requirements
super
- requirements.assert(:all_actions) do |a|
+ requirements.assert(:all_actions) do |a|
a.assertion { @package_source_exists }
a.failure_message Chef::Exceptions::Package, "Package #{@new_resource.name} not found: #{@new_resource.source}"
a.whyrun "Assuming package #{@new_resource.name} would have been made available."
end
- requirements.assert(:all_actions) do |a|
- a.assertion { !@rpm_status.nil? && (@rpm_status.exitstatus == 0 || @rpm_status.exitstatus == 1) }
+ requirements.assert(:all_actions) do |a|
+ a.assertion { !@rpm_status.nil? && (@rpm_status.exitstatus == 0 || @rpm_status.exitstatus == 1) }
a.failure_message Chef::Exceptions::Package, "Unable to determine current version due to RPM failure. Detail: #{@rpm_status.inspect}"
a.whyrun "Assuming current version would have been determined for package#{@new_resource.name}."
end
end
-
+
def load_current_resource
@package_source_provided = true
@package_source_exists = true
@@ -49,13 +49,13 @@ class Chef
@current_resource = Chef::Resource::Package.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
@new_resource.version(nil)
-
+
if @new_resource.source
unless ::File.exists?(@new_resource.source)
@package_source_exists = false
return
end
-
+
Chef::Log.debug("#{@new_resource} checking rpm status")
status = popen4("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@new_resource.source}") do |pid, stdin, stdout, stderr|
stdout.each do |line|
@@ -72,7 +72,7 @@ class Chef
return
end
end
-
+
Chef::Log.debug("#{@new_resource} checking install state")
@rpm_status = popen4("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@current_resource.package_name}") do |pid, stdin, stdout, stderr|
stdout.each do |line|
@@ -83,11 +83,11 @@ class Chef
end
end
end
-
-
+
+
@current_resource
end
-
+
def install_package(name, version)
unless @current_resource.version
run_command_with_systems_locale(
@@ -99,9 +99,9 @@ class Chef
)
end
end
-
+
alias_method :upgrade_package, :install_package
-
+
def remove_package(name, version)
if version
run_command_with_systems_locale(
diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb
index 28d332420b..b423c199a0 100644
--- a/lib/chef/provider/package/rubygems.rb
+++ b/lib/chef/provider/package/rubygems.rb
@@ -72,7 +72,7 @@ class Chef
raise NotImplementedError
end
- ##
+ ##
# A rubygems specification object containing the list of gemspecs for all
# available gems in the gem installation.
# Implemented by subclasses
diff --git a/lib/chef/provider/package/smartos.rb b/lib/chef/provider/package/smartos.rb
index b17f6f2564..28d56ddc2c 100644
--- a/lib/chef/provider/package/smartos.rb
+++ b/lib/chef/provider/package/smartos.rb
@@ -64,14 +64,14 @@ class Chef
pkg = shell_out!("/opt/local/bin/pkgin se #{new_resource.package_name}", :env => nil, :returns => [0,1])
pkg.stdout.each_line do |line|
case line
- when /^#{name}/
+ when /^#{new_resource.package_name}/
name, version = line.split[0].split(/-([^-]+)$/)
end
end
@candidate_version = version
version
end
-
+
def install_package(name, version)
Chef::Log.debug("#{@new_resource} installing package #{name} version #{version}")
package = "#{name}-#{version}"
@@ -84,7 +84,7 @@ class Chef
end
def remove_package(name, version)
- Chef::Log.debug("#{@new_resource} removing package #{name} version #{version}")
+ Chef::Log.debug("#{@new_resource} removing package #{name} version #{version}")
package = "#{name}"
out = shell_out!("/opt/local/bin/pkgin -y remove #{package}", :env => nil)
end
diff --git a/lib/chef/provider/package/solaris.rb b/lib/chef/provider/package/solaris.rb
index f502a0dc96..0f45b61e18 100644
--- a/lib/chef/provider/package/solaris.rb
+++ b/lib/chef/provider/package/solaris.rb
@@ -33,12 +33,12 @@ class Chef
# end
def define_resource_requirements
super
- requirements.assert(:install) do |a|
+ requirements.assert(:install) do |a|
a.assertion { @new_resource.source }
a.failure_message Chef::Exceptions::Package, "Source for package #{@new_resource.name} required for action install"
end
- requirements.assert(:all_actions) do |a|
- a.assertion { !@new_resource.source || @package_source_found }
+ requirements.assert(:all_actions) do |a|
+ a.assertion { !@new_resource.source || @package_source_found }
a.failure_message Chef::Exceptions::Package, "Package #{@new_resource.name} not found: #{@new_resource.source}"
a.whyrun "would assume #{@new_resource.source} would be have previously been made available"
end
@@ -51,7 +51,7 @@ class Chef
if @new_resource.source
@package_source_found = ::File.exists?(@new_resource.source)
- if @package_source_found
+ if @package_source_found
Chef::Log.debug("#{@new_resource} checking pkg status")
status = popen4("pkginfo -l -d #{@new_resource.source} #{@new_resource.package_name}") do |pid, stdin, stdout, stderr|
stdout.each do |line|
@@ -107,13 +107,23 @@ class Chef
def install_package(name, version)
Chef::Log.debug("#{@new_resource} package install options: #{@new_resource.options}")
if @new_resource.options.nil?
+ if ::File.directory?(@new_resource.source) # CHEF-4469
+ command = "pkgadd -n -d #{@new_resource.source} #{@new_resource.package_name}"
+ else
+ command = "pkgadd -n -d #{@new_resource.source} all"
+ end
run_command_with_systems_locale(
- :command => "pkgadd -n -d #{@new_resource.source} all"
+ :command => command
)
Chef::Log.debug("#{@new_resource} installed version #{@new_resource.version} from: #{@new_resource.source}")
else
+ if ::File.directory?(@new_resource.source) # CHEF-4469
+ command = "pkgadd -n#{expand_options(@new_resource.options)} -d #{@new_resource.source} #{@new_resource.package_name}"
+ else
+ command = "pkgadd -n#{expand_options(@new_resource.options)} -d #{@new_resource.source} all"
+ end
run_command_with_systems_locale(
- :command => "pkgadd -n#{expand_options(@new_resource.options)} -d #{@new_resource.source} all"
+ :command => command
)
Chef::Log.debug("#{@new_resource} installed version #{@new_resource.version} from: #{@new_resource.source}")
end
diff --git a/lib/chef/provider/package/yum-dump.py b/lib/chef/provider/package/yum-dump.py
index 407eb8f408..a8f3995e8c 100644
--- a/lib/chef/provider/package/yum-dump.py
+++ b/lib/chef/provider/package/yum-dump.py
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -249,8 +249,8 @@ def yum_dump(options):
# Preserve order of enable/disable repo args like yum does
def gather_repo_opts(option, opt, value, parser):
- if getattr(parser.values, option.dest, None) is None:
- setattr(parser.values, option.dest, [])
+ if getattr(parser.values, option.dest, None) is None:
+ setattr(parser.values, option.dest, [])
getattr(parser.values, option.dest).append((opt, value.split(',')))
def main():
diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb
index 233e949e12..f56d3140b6 100644
--- a/lib/chef/provider/package/yum.rb
+++ b/lib/chef/provider/package/yum.rb
@@ -667,7 +667,7 @@ class Chef
@allow_multi_install = []
- @extra_repo_control = nil
+ @extra_repo_control = nil
# these are for subsequent runs if we are on an interval
Chef::Client.when_run_starts do
@@ -1046,7 +1046,7 @@ class Chef
end
# At this point package_name could be:
- #
+ #
# 1) a package name, eg: "foo"
# 2) a package name.arch, eg: "foo.i386"
# 3) or a dependency, eg: "foo >= 1.1"
@@ -1154,7 +1154,7 @@ class Chef
# Hacky - better overall solution? Custom compare in Package provider?
def action_upgrade
# Could be uninstalled or have no candidate
- if @current_resource.version.nil? || candidate_version.nil?
+ if @current_resource.version.nil? || candidate_version.nil?
super
# Ensure the candidate is newer
elsif RPMVersion.parse(candidate_version) > RPMVersion.parse(@current_resource.version)
diff --git a/lib/chef/provider/powershell_script.rb b/lib/chef/provider/powershell_script.rb
index 700eb88c11..c459cdf678 100644
--- a/lib/chef/provider/powershell_script.rb
+++ b/lib/chef/provider/powershell_script.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,7 +23,7 @@ class Chef
class PowershellScript < Chef::Provider::WindowsScript
protected
-
+
EXIT_STATUS_NORMALIZATION_SCRIPT = "\nif ($? -eq $true) {exit 0} elseif ( $LASTEXITCODE -ne 0) {exit $LASTEXITCODE} else { exit 1 }"
EXIT_STATUS_RESET_SCRIPT = "$LASTEXITCODE=0\n"
@@ -41,12 +41,12 @@ class Chef
end
public
-
+
def initialize (new_resource, run_context)
super(new_resource, run_context, '.ps1')
NormalizeScriptExitStatus(new_resource.code)
end
-
+
def flags
default_flags = [
"-NoLogo",
@@ -60,8 +60,8 @@ class Chef
# file created by the base class that contains the script
# code -- otherwise, powershell.exe does not propagate the
# error status of a failed Windows process that ran at the
- # end of the script, it gets changed to '1'.
- "-File"
+ # end of the script, it gets changed to '1'.
+ "-File"
]
interpreter_flags = default_flags.join(' ')
diff --git a/lib/chef/provider/remote_file/ftp.rb b/lib/chef/provider/remote_file/ftp.rb
index d75fb7a52c..7f3fdbf383 100644
--- a/lib/chef/provider/remote_file/ftp.rb
+++ b/lib/chef/provider/remote_file/ftp.rb
@@ -143,6 +143,7 @@ class Chef
ftp.voidcmd("TYPE #{typecode.upcase}")
end
ftp.getbinaryfile(filename, tempfile.path)
+ tempfile.close if tempfile
tempfile
end
diff --git a/lib/chef/provider/remote_file/http.rb b/lib/chef/provider/remote_file/http.rb
index 6ffd83f438..8949e6ab04 100644
--- a/lib/chef/provider/remote_file/http.rb
+++ b/lib/chef/provider/remote_file/http.rb
@@ -17,7 +17,7 @@
# limitations under the License.
#
-require 'chef/rest'
+require 'chef/http/simple'
require 'chef/digester'
require 'chef/provider/remote_file'
require 'chef/provider/remote_file/cache_control_data'
@@ -58,9 +58,9 @@ class Chef
def fetch
tempfile = nil
begin
- rest = Chef::REST.new(uri, nil, nil, http_client_opts)
- tempfile = rest.streaming_request(uri, headers)
- update_cache_control_data(tempfile, rest.last_response)
+ http = Chef::HTTP::Simple.new(uri, http_client_opts)
+ tempfile = http.streaming_request(uri, headers)
+ update_cache_control_data(tempfile, http.last_response)
rescue Net::HTTPRetriableError => e
if e.response.is_a? Net::HTTPNotModified
tempfile = nil
@@ -68,7 +68,7 @@ class Chef
raise e
end
end
-
+ tempfile.close if tempfile
tempfile
end
diff --git a/lib/chef/provider/remote_file/local_file.rb b/lib/chef/provider/remote_file/local_file.rb
index 87f498e053..b3b2301b81 100644
--- a/lib/chef/provider/remote_file/local_file.rb
+++ b/lib/chef/provider/remote_file/local_file.rb
@@ -38,6 +38,7 @@ class Chef
tempfile = Chef::FileContentManagement::Tempfile.new(new_resource).tempfile
Chef::Log.debug("#{new_resource} staging #{uri.path} to #{tempfile.path}")
FileUtils.cp(uri.path, tempfile.path)
+ tempfile.close if tempfile
tempfile
end
diff --git a/lib/chef/provider/resource_update.rb b/lib/chef/provider/resource_update.rb
index e2c6bffca4..54f25738ed 100644
--- a/lib/chef/provider/resource_update.rb
+++ b/lib/chef/provider/resource_update.rb
@@ -4,27 +4,27 @@ class Chef
# {
# "run_id" : "1000",
- # "resource" : {
+ # "resource" : {
# "type" : "file",
- # "name" : "/etc/passwd",
+ # "name" : "/etc/passwd",
# "start_time" : "2012-01-09T08:15:30-05:00",
# "end_time" : "2012-01-09T08:15:30-05:00",
# "status" : "modified",
- # "initial_state" : "exists",
- # "final_state" : "modified",
- # "before" : {
- # "group" : "root",
+ # "initial_state" : "exists",
+ # "final_state" : "modified",
+ # "before" : {
+ # "group" : "root",
# "owner" : "root",
# "checksum" : "xyz"
# },
- # "after" : {
- # "group" : "root",
+ # "after" : {
+ # "group" : "root",
# "owner" : "root",
# "checksum" : "abc"
# },
# "delta" : "escaped delta goes here"
# },
- # "event_data" : ""
+ # "event_data" : ""
# }
class ResourceUpdate
diff --git a/lib/chef/provider/ruby_block.rb b/lib/chef/provider/ruby_block.rb
index 16908b0eff..b0d94a3f8d 100644
--- a/lib/chef/provider/ruby_block.rb
+++ b/lib/chef/provider/ruby_block.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,7 +29,7 @@ class Chef
end
def action_run
- converge_by("execute the ruby block #{@new_resource.name}") do
+ converge_by("execute the ruby block #{@new_resource.name}") do
@new_resource.block.call
Chef::Log.info("#{@new_resource} called")
end
diff --git a/lib/chef/provider/script.rb b/lib/chef/provider/script.rb
index 1b459f36cf..4aacf4f524 100644
--- a/lib/chef/provider/script.rb
+++ b/lib/chef/provider/script.rb
@@ -27,7 +27,7 @@ class Chef
super
@code = @new_resource.code
end
-
+
def action_run
script_file.puts(@code)
script_file.close
diff --git a/lib/chef/provider/service.rb b/lib/chef/provider/service.rb
index 8d76927676..968f9bff9c 100644
--- a/lib/chef/provider/service.rb
+++ b/lib/chef/provider/service.rb
@@ -35,7 +35,7 @@ class Chef
end
def load_new_resource_state
- # If the user didn't specify a change in enabled state,
+ # If the user didn't specify a change in enabled state,
# it will be the same as the old resource
if ( @new_resource.enabled.nil? )
@new_resource.enabled(@current_resource.enabled)
@@ -54,7 +54,7 @@ class Chef
a.failure_message Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reload"
# if a service is not declared to support reload, that won't
# typically change during the course of a run - so no whyrun
- # alternative here.
+ # alternative here.
end
end
diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb
index e2a0f60d91..d788d58c00 100644
--- a/lib/chef/provider/service/debian.rb
+++ b/lib/chef/provider/service/debian.rb
@@ -41,17 +41,17 @@ class Chef
shared_resource_requirements
requirements.assert(:all_actions) do |a|
update_rcd = "/usr/sbin/update-rc.d"
- a.assertion { ::File.exists? update_rcd }
+ a.assertion { ::File.exists? update_rcd }
a.failure_message Chef::Exceptions::Service, "#{update_rcd} does not exist!"
# no whyrun recovery - this is a base system component of debian
- # distros and must be present
- end
+ # distros and must be present
+ end
requirements.assert(:all_actions) do |a|
- a.assertion { @priority_success }
+ a.assertion { @priority_success }
a.failure_message Chef::Exceptions::Service, "/usr/sbin/update-rc.d -n -f #{@current_resource.service_name} failed - #{@rcd_status.inspect}"
- # This can happen if the service is not yet installed,so we'll fake it.
- a.whyrun ["Unable to determine priority of service, assuming service would have been correctly installed earlier in the run.",
+ # This can happen if the service is not yet installed,so we'll fake it.
+ a.whyrun ["Unable to determine priority of service, assuming service would have been correctly installed earlier in the run.",
"Assigning temporary priorities to continue.",
"If this service is not properly installed prior to this point, this will fail."] do
temp_priorities = {"6"=>[:stop, "20"],
@@ -74,7 +74,7 @@ class Chef
[stdout, stderr].each do |iop|
iop.each_line do |line|
if UPDATE_RC_D_PRIORITIES =~ line
- # priority[runlevel] = [ S|K, priority ]
+ # priority[runlevel] = [ S|K, priority ]
# S = Start, K = Kill
# debian runlevels: 0 Halt, 1 Singleuser, 2 Multiuser, 3-5 == 2, 6 Reboot
priority[$1] = [($2 == "S" ? :start : :stop), $3]
@@ -86,6 +86,12 @@ class Chef
end
end
+ # Reduce existing priority back to an integer if appropriate, picking
+ # runlevel 2 as a baseline
+ if priority[2] && [2..5].all? { |runlevel| priority[runlevel] == priority[2] }
+ priority = priority[2].last
+ end
+
unless @rcd_status.exitstatus == 0
@priority_success = false
end
@@ -105,14 +111,28 @@ class Chef
enabled
end
- def enable_service()
+ # Override method from parent to ensure priority is up-to-date
+ def action_enable
+ if @current_resource.enabled && @current_resource.priority == @new_resource.priority
+ Chef::Log.debug("#{@new_resource} already enabled - nothing to do")
+ else
+ converge_by("enable service #{@new_resource}") do
+ enable_service
+ Chef::Log.info("#{@new_resource} enabled")
+ end
+ end
+ load_new_resource_state
+ @new_resource.enabled(true)
+ end
+
+ def enable_service
if @new_resource.priority.is_a? Integer
run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
run_command(:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} defaults #{@new_resource.priority} #{100 - @new_resource.priority}")
elsif @new_resource.priority.is_a? Hash
- # we call the same command regardless of we're enabling or disabling
+ # we call the same command regardless of we're enabling or disabling
# users passing a Hash are responsible for setting their own start priorities
- set_priority()
+ set_priority
else # No priority, go with update-rc.d defaults
run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
run_command(:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} defaults")
@@ -120,23 +140,23 @@ class Chef
end
- def disable_service()
+ def disable_service
if @new_resource.priority.is_a? Integer
# Stop processes in reverse order of start using '100 - start_priority'
run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop #{100 - @new_resource.priority} 2 3 4 5 .")
elsif @new_resource.priority.is_a? Hash
- # we call the same command regardless of we're enabling or disabling
+ # we call the same command regardless of we're enabling or disabling
# users passing a Hash are responsible for setting their own stop priorities
- set_priority()
- else
+ set_priority
+ else
# no priority, using '100 - 20 (update-rc.d default)' to stop in reverse order of start
run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove")
run_command(:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop 80 2 3 4 5 .")
end
end
- def set_priority()
+ def set_priority
args = ""
@new_resource.priority.each do |level, o|
action = o[0]
diff --git a/lib/chef/provider/service/freebsd.rb b/lib/chef/provider/service/freebsd.rb
index b875838ec2..cb0f6b0fc4 100644
--- a/lib/chef/provider/service/freebsd.rb
+++ b/lib/chef/provider/service/freebsd.rb
@@ -38,13 +38,13 @@ class Chef
elsif ::File.exists?("/usr/local/etc/rc.d/#{current_resource.service_name}")
@init_command = "/usr/local/etc/rc.d/#{current_resource.service_name}"
else
- @rcd_script_found = false
+ @rcd_script_found = false
return
end
Chef::Log.debug("#{@current_resource} found at #{@init_command}")
determine_current_status!
# Default to disabled if the service doesn't currently exist
- # at all
+ # at all
var_name = service_enable_variable_name
if ::File.exists?("/etc/rc.conf") && var_name
read_rc_conf.each do |line|
@@ -70,19 +70,19 @@ class Chef
def define_resource_requirements
shared_resource_requirements
requirements.assert(:start, :enable, :reload, :restart) do |a|
- a.assertion { @rcd_script_found }
+ a.assertion { @rcd_script_found }
a.failure_message Chef::Exceptions::Service, "#{@new_resource}: unable to locate the rc.d script"
end
- requirements.assert(:all_actions) do |a|
- a.assertion { @enabled_state_found }
- # for consistentcy with original behavior, this will not fail in non-whyrun mode;
+ requirements.assert(:all_actions) do |a|
+ a.assertion { @enabled_state_found }
+ # for consistentcy with original behavior, this will not fail in non-whyrun mode;
# rather it will silently set enabled state=>false
- a.whyrun "Unable to determine enabled/disabled state, assuming this will be correct for an actual run. Assuming disabled."
+ a.whyrun "Unable to determine enabled/disabled state, assuming this will be correct for an actual run. Assuming disabled."
end
requirements.assert(:start, :enable, :reload, :restart) do |a|
- a.assertion { @rcd_script_found && service_enable_variable_name != nil }
+ a.assertion { @rcd_script_found && service_enable_variable_name != nil }
a.failure_message Chef::Exceptions::Service, "Could not find the service name in #{@init_command} and rcvar"
# No recovery in whyrun mode - the init file is present but not correct.
end
@@ -133,7 +133,7 @@ class Chef
# corresponding to this service
# For example: to enable the service mysql-server with the init command /usr/local/etc/rc.d/mysql-server, you need
# to set mysql_enable="YES" in /etc/rc.conf$
- if @rcd_script_found
+ if @rcd_script_found
::File.open(@init_command) do |rcscript|
rcscript.each_line do |line|
if line =~ /^name="?(\w+)"?/
diff --git a/lib/chef/provider/service/gentoo.rb b/lib/chef/provider/service/gentoo.rb
index 45b5a21f9b..ba4edc5807 100644
--- a/lib/chef/provider/service/gentoo.rb
+++ b/lib/chef/provider/service/gentoo.rb
@@ -44,7 +44,7 @@ class Chef::Provider::Service::Gentoo < Chef::Provider::Service::Init
def define_resource_requirements
requirements.assert(:all_actions) do |a|
- a.assertion { ::File.exists?("/sbin/rc-update") }
+ a.assertion { ::File.exists?("/sbin/rc-update") }
a.failure_message Chef::Exceptions::Service, "/sbin/rc-update does not exist"
# no whyrun recovery -t his is a core component whose presence is
# unlikely to be affected by what we do in the course of a chef run
@@ -52,15 +52,15 @@ class Chef::Provider::Service::Gentoo < Chef::Provider::Service::Init
requirements.assert(:all_actions) do |a|
a.assertion { @found_script }
- # No failure, just informational output from whyrun
+ # No failure, just informational output from whyrun
a.whyrun "Could not find service #{@new_resource.service_name} under any runlevel"
end
end
-
+
def enable_service()
run_command(:command => "/sbin/rc-update add #{@new_resource.service_name} default")
end
-
+
def disable_service()
run_command(:command => "/sbin/rc-update del #{@new_resource.service_name} default")
end
diff --git a/lib/chef/provider/service/init.rb b/lib/chef/provider/service/init.rb
index 09f47e866f..63ba8fa6ab 100644
--- a/lib/chef/provider/service/init.rb
+++ b/lib/chef/provider/service/init.rb
@@ -47,7 +47,7 @@ class Chef
end
end
end
-
+
def start_service
if @new_resource.start_command
super
diff --git a/lib/chef/provider/service/insserv.rb b/lib/chef/provider/service/insserv.rb
index 32152376ee..cb9c28e17e 100644
--- a/lib/chef/provider/service/insserv.rb
+++ b/lib/chef/provider/service/insserv.rb
@@ -32,9 +32,9 @@ class Chef
if Dir.glob("/etc/rc**/S*#{@current_resource.service_name}").empty?
@current_resource.enabled false
else
- @current_resource.enabled true
+ @current_resource.enabled true
end
-
+
@current_resource
end
diff --git a/lib/chef/provider/service/invokercd.rb b/lib/chef/provider/service/invokercd.rb
index 69a17bb4fb..ee2719d75a 100644
--- a/lib/chef/provider/service/invokercd.rb
+++ b/lib/chef/provider/service/invokercd.rb
@@ -24,7 +24,7 @@ class Chef
class Provider
class Service
class Invokercd < Chef::Provider::Service::Init
-
+
def initialize(new_resource, run_context)
super
@init_command = "/usr/sbin/invoke-rc.d #{@new_resource.service_name}"
diff --git a/lib/chef/provider/service/redhat.rb b/lib/chef/provider/service/redhat.rb
index 629e4ee0c3..06be9f3207 100644
--- a/lib/chef/provider/service/redhat.rb
+++ b/lib/chef/provider/service/redhat.rb
@@ -48,7 +48,7 @@ class Chef
requirements.assert(:start, :enable, :reload, :restart) do |a|
a.assertion { !@service_missing }
a.failure_message Chef::Exceptions::Service, "#{@new_resource}: unable to locate the init.d script!"
- a.whyrun "Assuming service would be disabled. The init script is not presently installed."
+ a.whyrun "Assuming service would be disabled. The init script is not presently installed."
end
end
@@ -59,7 +59,7 @@ class Chef
chkconfig = shell_out!("/sbin/chkconfig --list #{@current_resource.service_name}", :returns => [0,1])
@current_resource.enabled(!!(chkconfig.stdout =~ CHKCONFIG_ON))
@service_missing = !!(chkconfig.stderr =~ CHKCONFIG_MISSING)
- end
+ end
@current_resource
end
diff --git a/lib/chef/provider/service/simple.rb b/lib/chef/provider/service/simple.rb
index bcb85230d0..288b5f5456 100644
--- a/lib/chef/provider/service/simple.rb
+++ b/lib/chef/provider/service/simple.rb
@@ -45,8 +45,8 @@ class Chef
def shared_resource_requirements
super
- requirements.assert(:all_actions) do |a|
- a.assertion { @status_load_success }
+ requirements.assert(:all_actions) do |a|
+ a.assertion { @status_load_success }
a.whyrun ["Service status not available. Assuming a prior action would have installed the service.", "Assuming status of not running."]
end
end
@@ -74,12 +74,12 @@ class Chef
end
requirements.assert(:all_actions) do |a|
- a.assertion { @new_resource.status_command or @new_resource.supports[:status] or
- (!ps_cmd.nil? and !ps_cmd.empty?) }
+ a.assertion { @new_resource.status_command or @new_resource.supports[:status] or
+ (!ps_cmd.nil? and !ps_cmd.empty?) }
a.failure_message Chef::Exceptions::Service, "#{@new_resource} could not determine how to inspect the process table, please set this node's 'command.ps' attribute"
end
- requirements.assert(:all_actions) do |a|
- a.assertion { !@ps_command_failed }
+ requirements.assert(:all_actions) do |a|
+ a.assertion { !@ps_command_failed }
a.failure_message Chef::Exceptions::Service, "Command #{ps_cmd} failed to execute, cannot determine service current status"
end
end
diff --git a/lib/chef/provider/service/solaris.rb b/lib/chef/provider/service/solaris.rb
index 33a29da109..4bdb6fbfd1 100644
--- a/lib/chef/provider/service/solaris.rb
+++ b/lib/chef/provider/service/solaris.rb
@@ -31,7 +31,7 @@ class Chef
@init_command = "/usr/sbin/svcadm"
@status_command = "/bin/svcs -l"
end
-
+
def load_current_resource
@current_resource = Chef::Resource::Service.new(@new_resource.name)
diff --git a/lib/chef/provider/service/systemd.rb b/lib/chef/provider/service/systemd.rb
index 59b4fe1564..89077c5feb 100644
--- a/lib/chef/provider/service/systemd.rb
+++ b/lib/chef/provider/service/systemd.rb
@@ -50,7 +50,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
def define_resource_requirements
shared_resource_requirements
requirements.assert(:all_actions) do |a|
- a.assertion { @status_check_success }
+ a.assertion { @status_check_success }
# We won't stop in any case, but in whyrun warn and tell what we're doing.
a.whyrun ["Failed to determine status of #{@new_resource}, using command #{@new_resource.status_command}.",
"Assuming service would have been installed and is disabled"]
@@ -99,11 +99,11 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
def enable_service
run_command_with_systems_locale(:command => "/bin/systemctl enable #{@new_resource.service_name}")
- end
+ end
def disable_service
run_command_with_systems_locale(:command => "/bin/systemctl disable #{@new_resource.service_name}")
- end
+ end
def is_active?
run_command_with_systems_locale({:command => "/bin/systemctl is-active #{@new_resource.service_name}", :ignore_failure => true}) == 0
diff --git a/lib/chef/provider/service/upstart.rb b/lib/chef/provider/service/upstart.rb
index 763a2aa92b..67ca649b6d 100644
--- a/lib/chef/provider/service/upstart.rb
+++ b/lib/chef/provider/service/upstart.rb
@@ -26,7 +26,7 @@ class Chef
class Service
class Upstart < Chef::Provider::Service::Simple
UPSTART_STATE_FORMAT = /\w+ \(?(\w+)\)?[\/ ](\w+)/
-
+
# Upstart does more than start or stop a service, creating multiple 'states' [1] that a service can be in.
# In chef, when we ask a service to start, we expect it to have started before performing the next step
# since we have top down dependencies. Which is to say we may follow witha resource next that requires
@@ -40,17 +40,17 @@ class Chef
# TODO: re-evaluate if this is needed after integrating cookbook fix
raise ArgumentError, "run_context cannot be nil" unless run_context
super
-
+
run_context.node
-
+
@job = @new_resource.service_name
-
+
if @new_resource.parameters
@new_resource.parameters.each do |key, value|
@job << " #{key}=#{value}"
end
end
-
+
platform, version = Chef::Platform.find_platform_and_version(run_context.node)
if platform == "ubuntu" && (8.04..9.04).include?(version.to_f)
@upstart_job_dir = "/etc/event.d"
@@ -60,8 +60,8 @@ class Chef
@upstart_conf_suffix = ".conf"
end
- @command_success = true # new_resource.status_command= false, means upstart used
- @config_file_found = true
+ @command_success = true # new_resource.status_command= false, means upstart used
+ @config_file_found = true
@upstart_command_success = true
end
@@ -70,18 +70,18 @@ class Chef
shared_resource_requirements
requirements.assert(:all_actions) do |a|
if !@command_success
- whyrun_msg = @new_resource.status_command ? "Provided status command #{@new_resource.status_command} failed." :
+ whyrun_msg = @new_resource.status_command ? "Provided status command #{@new_resource.status_command} failed." :
"Could not determine upstart state for service"
end
a.assertion { @command_success }
- # no failure here, just document the assumptions made.
- a.whyrun "#{whyrun_msg} Assuming service installed and not running."
+ # no failure here, just document the assumptions made.
+ a.whyrun "#{whyrun_msg} Assuming service installed and not running."
end
- requirements.assert(:all_actions) do |a|
- a.assertion { @config_file_found }
- # no failure here, just document the assumptions made.
- a.whyrun "Could not find #{@upstart_job_dir}/#{@new_resource.service_name}#{@upstart_conf_suffix}. Assuming service is disabled."
+ requirements.assert(:all_actions) do |a|
+ a.assertion { @config_file_found }
+ # no failure here, just document the assumptions made.
+ a.whyrun "Could not find #{@upstart_job_dir}/#{@new_resource.service_name}#{@upstart_conf_suffix}. Assuming service is disabled."
end
end
@@ -176,7 +176,7 @@ class Chef
super
# Upstart always provides restart functionality so we don't need to mimic it with stop/sleep/start.
# Older versions of upstart would fail on restart if the service was currently stopped, check for that. LP:430883
- else @new_resource.supports[:restart]
+ else
if @current_resource.running
run_command_with_systems_locale(:command => "/sbin/restart #{@job}")
else
diff --git a/lib/chef/provider/subversion.rb b/lib/chef/provider/subversion.rb
index e1f87b4dd8..6ceb3e592a 100644
--- a/lib/chef/provider/subversion.rb
+++ b/lib/chef/provider/subversion.rb
@@ -17,7 +17,7 @@
#
-#TODO subversion and git should both extend from a base SCM provider.
+#TODO subversion and git should both extend from a base SCM provider.
require 'chef/log'
require 'chef/provider'
@@ -52,7 +52,7 @@ class Chef
# for why run, print a message explaining the potential error.
parent_directory = ::File.dirname(@new_resource.destination)
a.assertion { ::File.directory?(parent_directory) }
- a.failure_message(Chef::Exceptions::MissingParentDirectory,
+ a.failure_message(Chef::Exceptions::MissingParentDirectory,
"Cannot clone #{@new_resource} to #{@new_resource.destination}, the enclosing directory #{parent_directory} does not exist")
a.whyrun("Directory #{parent_directory} does not exist, assuming it would have been created")
end
@@ -91,13 +91,13 @@ class Chef
converge_by("sync #{@new_resource.destination} from #{@new_resource.repository}") do
run_command(run_options(:command => sync_command))
Chef::Log.info "#{@new_resource} updated to revision: #{revision_int}"
- end
+ end
end
else
action_checkout
end
end
-
+
def sync_command
c = scm :update, @new_resource.svn_arguments, verbose, authentication, "-r#{revision_int}", @new_resource.destination
Chef::Log.debug "#{@new_resource} updated working copy #{@new_resource.destination} to revision #{@new_resource.revision}"
@@ -156,6 +156,7 @@ class Chef
def run_options(run_opts={})
run_opts[:user] = @new_resource.user if @new_resource.user
run_opts[:group] = @new_resource.group if @new_resource.group
+ run_opts[:timeout] = @new_resource.timeout if @new_resource.timeout
run_opts
end
@@ -197,7 +198,7 @@ class Chef
def scm(*args)
['svn', *args].compact.join(" ")
end
-
+
def target_dir_non_existent_or_empty?
!::File.exist?(@new_resource.destination) || Dir.entries(@new_resource.destination).sort == ['.','..']
diff --git a/lib/chef/provider/user.rb b/lib/chef/provider/user.rb
index e815ba9c9e..738f7660f8 100644
--- a/lib/chef/provider/user.rb
+++ b/lib/chef/provider/user.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -79,9 +79,7 @@ class Chef
end
end
- if @new_resource.gid
- convert_group_name
- end
+ convert_group_name if @new_resource.gid
end
@current_resource
@@ -89,14 +87,14 @@ class Chef
def define_resource_requirements
requirements.assert(:all_actions) do |a|
- a.assertion { @group_name_resolved }
+ a.assertion { @group_name_resolved }
a.failure_message Chef::Exceptions::User, "Couldn't lookup integer GID for group name #{@new_resource.gid}"
a.whyrun "group name #{@new_resource.gid} does not exist. This will cause group assignment to fail. Assuming this group will have been created previously."
end
requirements.assert(:all_actions) do |a|
- a.assertion { @shadow_lib_ok }
+ a.assertion { @shadow_lib_ok }
a.failure_message Chef::Exceptions::MissingLibrary, "You must have ruby-shadow installed for password support!"
- a.whyrun "ruby-shadow is not installed. Attempts to set user password will cause failure. Assuming that this gem will have been previously installed." +
+ a.whyrun "ruby-shadow is not installed. Attempts to set user password will cause failure. Assuming that this gem will have been previously installed." +
"Note that user update converge may report false-positive on the basis of mismatched password. "
end
requirements.assert(:modify, :lock, :unlock) do |a|
@@ -112,9 +110,15 @@ class Chef
# <true>:: If a change is required
# <false>:: If the users are identical
def compare_user
- [ :uid, :gid, :comment, :home, :shell, :password ].any? do |user_attrib|
+ changed = [ :comment, :home, :shell, :password ].select do |user_attrib|
!@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib) != @current_resource.send(user_attrib)
end
+
+ changed += [ :uid, :gid ].select do |user_attrib|
+ !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib).to_s != @current_resource.send(user_attrib).to_s
+ end
+
+ changed.any?
end
def action_create
diff --git a/lib/chef/provider/user/dscl.rb b/lib/chef/provider/user/dscl.rb
index 94e8420c43..b01931609e 100644
--- a/lib/chef/provider/user/dscl.rb
+++ b/lib/chef/provider/user/dscl.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,10 +25,10 @@ class Chef
class User
class Dscl < Chef::Provider::User
include Chef::Mixin::ShellOut
-
+
NFS_HOME_DIRECTORY = %r{^NFSHomeDirectory: (.*)$}
AUTHENTICATION_AUTHORITY = %r{^AuthenticationAuthority: (.*)$}
-
+
def dscl(*args)
shell_out("dscl . -#{args.join(' ')}")
end
@@ -80,7 +80,7 @@ class Chef
return safe_dscl("delete /Users/#{@new_resource.username} NFSHomeDirectory") if (@new_resource.home.nil? || @new_resource.home.empty?)
if @new_resource.supports[:manage_home]
validate_home_dir_specification!
-
+
if (@current_resource.home == @new_resource.home) && !new_home_exists?
ditto_home
elsif !current_home_exists? && !new_home_exists?
@@ -105,7 +105,7 @@ class Chef
end
def shadow_hash_set?
- user_data = safe_dscl("read /Users/#{@new_resource.username}")
+ user_data = safe_dscl("read /Users/#{@new_resource.username}")
if user_data =~ /AuthenticationAuthority: / && user_data =~ /ShadowHash/
true
else
@@ -116,7 +116,7 @@ class Chef
def modify_password
if @new_resource.password
shadow_hash = nil
-
+
Chef::Log.debug("#{new_resource} updating password")
if osx_shadow_hash?(@new_resource.password)
shadow_hash = @new_resource.password.upcase
@@ -134,11 +134,11 @@ class Chef
shadow_hash = String.new("00000000"*155)
shadow_hash[168] = salted_sha1
end
-
+
::File.open("/var/db/shadow/hash/#{guid}",'w',0600) do |output|
output.puts shadow_hash
end
-
+
unless shadow_hash_set?
safe_dscl("append /Users/#{@new_resource.username} AuthenticationAuthority ';ShadowHash;'")
end
@@ -159,7 +159,7 @@ class Chef
dscl_set_shell
modify_password
end
-
+
def manage_user
dscl_create_user if diverged?(:username)
dscl_create_comment if diverged?(:comment)
@@ -169,15 +169,15 @@ class Chef
dscl_set_shell if diverged?(:shell)
modify_password if diverged?(:password)
end
-
+
def dscl_create_user
- safe_dscl("create /Users/#{@new_resource.username}")
+ safe_dscl("create /Users/#{@new_resource.username}")
end
-
+
def dscl_create_comment
safe_dscl("create /Users/#{@new_resource.username} RealName '#{@new_resource.comment}'")
end
-
+
def dscl_set_gid
unless @new_resource.gid && @new_resource.gid.to_s.match(/^\d+$/)
begin
@@ -189,7 +189,7 @@ class Chef
end
safe_dscl("create /Users/#{@new_resource.username} PrimaryGroupID '#{@new_resource.gid}'")
end
-
+
def dscl_set_shell
if @new_resource.password || ::File.exists?("#{@new_resource.shell}")
safe_dscl("create /Users/#{@new_resource.username} UserShell '#{@new_resource.shell}'")
@@ -197,10 +197,10 @@ class Chef
safe_dscl("create /Users/#{@new_resource.username} UserShell '/usr/bin/false'")
end
end
-
+
def remove_user
if @new_resource.supports[:manage_home]
- user_info = safe_dscl("read /Users/#{@new_resource.username}")
+ user_info = safe_dscl("read /Users/#{@new_resource.username}")
if nfs_home_match = user_info.match(NFS_HOME_DIRECTORY)
#nfs_home = safe_dscl("read /Users/#{@new_resource.username} NFSHomeDirectory")
#nfs_home.gsub!(/NFSHomeDirectory: /,"").gsub!(/\n$/,"")
@@ -228,7 +228,7 @@ class Chef
false
end
end
-
+
def check_lock
return @locked = locked?
end
@@ -236,27 +236,27 @@ class Chef
def lock_user
safe_dscl("append /Users/#{@new_resource.username} AuthenticationAuthority ';DisabledUser;'")
end
-
+
def unlock_user
auth_info = safe_dscl("read /Users/#{@new_resource.username} AuthenticationAuthority")
auth_string = auth_info.gsub(/AuthenticationAuthority: /,"").gsub(/;DisabledUser;/,"").strip#.gsub!(/[; ]*$/,"")
safe_dscl("create /Users/#{@new_resource.username} AuthenticationAuthority '#{auth_string}'")
end
-
+
def validate_home_dir_specification!
unless @new_resource.home =~ /^\//
- raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{@new_resource.username}', home directory: '#{@new_resource.home}'")
+ raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{@new_resource.username}', home directory: '#{@new_resource.home}'")
end
end
-
+
def current_home_exists?
::File.exist?("#{@current_resource.home}")
end
-
+
def new_home_exists?
- ::File.exist?("#{@new_resource.home}")
+ ::File.exist?("#{@new_resource.home}")
end
-
+
def ditto_home
skel = "/System/Library/User Template/English.lproj"
raise(Chef::Exceptions::User,"can't find skel at: #{skel}") unless ::File.exists?(skel)
@@ -266,7 +266,7 @@ class Chef
def move_home
Chef::Log.debug("#{@new_resource} moving #{self} home from #{@current_resource.home} to #{@new_resource.home}")
-
+
src = @current_resource.home
FileUtils.mkdir_p(@new_resource.home)
files = ::Dir.glob("#{src}/*", ::File::FNM_DOTMATCH) - ["#{src}/.","#{src}/.."]
@@ -274,11 +274,11 @@ class Chef
::FileUtils.rmdir(src)
::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
end
-
+
def diverged?(parameter)
parameter_updated?(parameter) && (not @new_resource.send(parameter).nil?)
end
-
+
def parameter_updated?(parameter)
not (@new_resource.send(parameter) == @current_resource.send(parameter))
end
diff --git a/lib/chef/provider/user/pw.rb b/lib/chef/provider/user/pw.rb
index 4f6393da89..9f7a169892 100644
--- a/lib/chef/provider/user/pw.rb
+++ b/lib/chef/provider/user/pw.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -34,20 +34,20 @@ class Chef
run_command(:command => command)
modify_password
end
-
+
def manage_user
command = "pw usermod"
command << set_options
run_command(:command => command)
modify_password
end
-
+
def remove_user
command = "pw userdel #{@new_resource.username}"
command << " -r" if @new_resource.supports[:manage_home]
run_command(:command => command)
end
-
+
def check_lock
case @current_resource.password
when /^\*LOCKED\*/
@@ -57,18 +57,18 @@ class Chef
end
@locked
end
-
+
def lock_user
run_command(:command => "pw lock #{@new_resource.username}")
end
-
+
def unlock_user
run_command(:command => "pw unlock #{@new_resource.username}")
end
-
+
def set_options
opts = " #{@new_resource.username}"
-
+
field_list = {
'comment' => "-c",
'home' => "-d",
@@ -91,7 +91,7 @@ class Chef
end
opts
end
-
+
def modify_password
if @current_resource.password != @new_resource.password
Chef::Log.debug("#{new_resource} updating password")
@@ -99,7 +99,7 @@ class Chef
status = popen4(command, :waitlast => true) do |pid, stdin, stdout, stderr|
stdin.puts "#{@new_resource.password}"
end
-
+
unless status.exitstatus == 0
raise Chef::Exceptions::User, "pw failed - #{status.inspect}!"
end
diff --git a/lib/chef/provider/user/useradd.rb b/lib/chef/provider/user/useradd.rb
index 41455007dc..1789a4e5ff 100644
--- a/lib/chef/provider/user/useradd.rb
+++ b/lib/chef/provider/user/useradd.rb
@@ -124,7 +124,7 @@ class Chef
end
def update_options(field, option, opts)
- if @current_resource.send(field) != new_resource.send(field)
+ if @current_resource.send(field).to_s != new_resource.send(field).to_s
if new_resource.send(field)
Chef::Log.debug("#{new_resource} setting #{field} to #{new_resource.send(field)}")
opts << option << new_resource.send(field).to_s
diff --git a/lib/chef/provider/user/windows.rb b/lib/chef/provider/user/windows.rb
index 6bbb2a088c..350f3ff4c0 100644
--- a/lib/chef/provider/user/windows.rb
+++ b/lib/chef/provider/user/windows.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -71,23 +71,23 @@ class Chef
def create_user
@net_user.add(set_options)
end
-
+
def manage_user
@net_user.update(set_options)
end
-
+
def remove_user
@net_user.delete
end
-
+
def check_lock
@net_user.check_enabled
end
-
+
def lock_user
@net_user.disable_account
end
-
+
def unlock_user
@net_user.enable_account
end
diff --git a/lib/chef/provider/windows_script.rb b/lib/chef/provider/windows_script.rb
index 398e1aee6e..08a2ea74df 100644
--- a/lib/chef/provider/windows_script.rb
+++ b/lib/chef/provider/windows_script.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,7 +24,7 @@ class Chef
class WindowsScript < Chef::Provider::Script
protected
-
+
include Chef::Mixin::WindowsArchitectureHelper
def initialize( new_resource, run_context, script_extension='')
@@ -43,14 +43,14 @@ class Chef
end
public
-
+
def action_run
wow64_redirection_state = nil
if @is_wow64
wow64_redirection_state = disable_wow64_file_redirection(@run_context.node)
end
-
+
begin
super
rescue
@@ -61,11 +61,11 @@ class Chef
end
end
end
-
+
def script_file
base_script_name = "chef-script"
temp_file_arguments = [ base_script_name, @script_extension ]
-
+
@script_file ||= Tempfile.open(temp_file_arguments)
end
end
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index e0039428f2..50099e8afc 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -21,6 +21,7 @@ require 'chef/provider/breakpoint'
require 'chef/provider/cookbook_file'
require 'chef/provider/cron'
require 'chef/provider/cron/solaris'
+require 'chef/provider/cron/aix'
require 'chef/provider/deploy'
require 'chef/provider/directory'
require 'chef/provider/env'
@@ -64,6 +65,7 @@ require 'chef/provider/package/yum'
require 'chef/provider/package/zypper'
require 'chef/provider/package/solaris'
require 'chef/provider/package/smartos'
+require 'chef/provider/package/aix'
require 'chef/provider/service/arch'
require 'chef/provider/service/debian'
@@ -97,6 +99,7 @@ require 'chef/provider/group/usermod'
require 'chef/provider/group/windows'
require 'chef/provider/mount/mount'
+require 'chef/provider/mount/aix'
require 'chef/provider/mount/windows'
require 'chef/provider/deploy/revision'
@@ -117,3 +120,4 @@ require 'chef/provider/template/content'
require 'chef/provider/ifconfig/redhat'
require 'chef/provider/ifconfig/debian'
+require 'chef/provider/ifconfig/aix'
diff --git a/lib/chef/recipe.rb b/lib/chef/recipe.rb
index 6ea69360b8..0c688cb5f8 100644
--- a/lib/chef/recipe.rb
+++ b/lib/chef/recipe.rb
@@ -81,26 +81,9 @@ class Chef
run_context.resource_collection.find(*args)
end
- # Sets a tag, or list of tags, for this node. Syntactic sugar for
- # run_context.node[:tags].
- #
- # With no arguments, returns the list of tags.
- #
- # === Parameters
- # tags<Array>:: A list of tags to add - can be a single string
- #
- # === Returns
- # tags<Array>:: The contents of run_context.node[:tags]
+ # This was moved to Chef::Node#tag, redirecting here for compatability
def tag(*tags)
- if tags.length > 0
- tags.each do |tag|
- tag = tag.to_s
- run_context.node.normal[:tags] << tag unless run_context.node[:tags].include?(tag)
- end
- run_context.node[:tags]
- else
- run_context.node[:tags]
- end
+ run_context.node.tag(*tags)
end
# Returns true if the node is tagged with *all* of the supplied +tags+.
diff --git a/lib/chef/resource/apt_package.rb b/lib/chef/resource/apt_package.rb
index 524abbb370..050cf838ae 100644
--- a/lib/chef/resource/apt_package.rb
+++ b/lib/chef/resource/apt_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'chef/provider/package/apt'
class Chef
class Resource
class AptPackage < Chef::Resource::Package
-
+
def initialize(name, run_context=nil)
super
@resource_name = :apt_package
diff --git a/lib/chef/resource/bash.rb b/lib/chef/resource/bash.rb
index 374bca9e11..c56de5fe20 100644
--- a/lib/chef/resource/bash.rb
+++ b/lib/chef/resource/bash.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,7 +21,7 @@ require 'chef/resource/script'
class Chef
class Resource
class Bash < Chef::Resource::Script
-
+
def initialize(name, run_context=nil)
super
@resource_name = :bash
diff --git a/lib/chef/resource/batch.rb b/lib/chef/resource/batch.rb
index 705260bbce..576e6b4c6b 100644
--- a/lib/chef/resource/batch.rb
+++ b/lib/chef/resource/batch.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,11 +21,11 @@ require 'chef/resource/windows_script'
class Chef
class Resource
class Batch < Chef::Resource::WindowsScript
-
+
def initialize(name, run_context=nil)
super(name, run_context, :batch, "cmd.exe")
end
-
+
end
end
end
diff --git a/lib/chef/resource/bff_package.rb b/lib/chef/resource/bff_package.rb
new file mode 100644
index 0000000000..2d78483e4b
--- /dev/null
+++ b/lib/chef/resource/bff_package.rb
@@ -0,0 +1,36 @@
+#
+# Author:: Deepali Jagtap (<deepali.jagtap@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/resource/package'
+require 'chef/provider/package/aix'
+
+class Chef
+ class Resource
+ class BffPackage < Chef::Resource::Package
+
+ def initialize(name, run_context=nil)
+ super
+ @resource_name = :bff_package
+ @provider = Chef::Provider::Package::Aix
+ end
+
+ end
+ end
+end
+
+
diff --git a/lib/chef/resource/breakpoint.rb b/lib/chef/resource/breakpoint.rb
index 34aeae6b47..83c397bd5b 100644
--- a/lib/chef/resource/breakpoint.rb
+++ b/lib/chef/resource/breakpoint.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'chef/resource'
class Chef
class Resource
class Breakpoint < Chef::Resource
-
+
def initialize(action="break", *args)
@name = caller.first
super(@name, *args)
diff --git a/lib/chef/resource/cron.rb b/lib/chef/resource/cron.rb
index 5f858cec81..dfbb91f80c 100644
--- a/lib/chef/resource/cron.rb
+++ b/lib/chef/resource/cron.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'chef/resource'
class Chef
class Resource
class Cron < Chef::Resource
-
+
identity_attr :command
state_attrs :minute, :hour, :day, :month, :weekday, :user
@@ -186,9 +186,9 @@ class Chef
:kind_of => Hash
)
end
-
+
private
-
+
# On Ruby 1.8, Kernel#Integer will happily do this for you. On 1.9, no.
def integerize(integerish)
Integer(integerish)
diff --git a/lib/chef/resource/csh.rb b/lib/chef/resource/csh.rb
index 6e871e8605..95aa8afd7a 100644
--- a/lib/chef/resource/csh.rb
+++ b/lib/chef/resource/csh.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,7 +21,7 @@ require 'chef/resource/script'
class Chef
class Resource
class Csh < Chef::Resource::Script
-
+
def initialize(name, run_context=nil)
super
@resource_name = :csh
diff --git a/lib/chef/resource/deploy.rb b/lib/chef/resource/deploy.rb
index 8b614028bf..76478ed07c 100644
--- a/lib/chef/resource/deploy.rb
+++ b/lib/chef/resource/deploy.rb
@@ -50,9 +50,9 @@ class Chef
# release directory. Callback files can contain chef code (resources, etc.)
#
class Deploy < Chef::Resource
-
+
provider_base Chef::Provider::Deploy
-
+
identity_attr :repository
state_attrs :deploy_to, :revision
@@ -389,7 +389,7 @@ class Chef
arg ||= block
set_or_return(:after_restart, arg, :kind_of => [Proc, String])
end
-
+
def additional_remotes(arg=nil)
set_or_return(
:additional_remotes,
@@ -398,6 +398,19 @@ class Chef
)
end
+ # FIXME The Deploy resource may be passed to an SCM provider as its
+ # resource. The SCM provider knows that SCM resources can specify a
+ # timeout for SCM operations. The deploy resource must therefore support
+ # a timeout method, but the timeout it describes is for SCM operations,
+ # not the overall deployment. This is potentially confusing.
+ def timeout(arg=nil)
+ set_or_return(
+ :timeout,
+ arg,
+ :kind_of => Integer
+ )
+ end
+
end
end
end
diff --git a/lib/chef/resource/deploy_revision.rb b/lib/chef/resource/deploy_revision.rb
index 55a3e38130..ceac26e91a 100644
--- a/lib/chef/resource/deploy_revision.rb
+++ b/lib/chef/resource/deploy_revision.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,9 +18,9 @@
class Chef
class Resource
-
+
# Convenience class for using the deploy resource with the revision
- # deployment strategy (provider)
+ # deployment strategy (provider)
class DeployRevision < Chef::Resource::Deploy
def initialize(*args, &block)
super
@@ -28,13 +28,13 @@ class Chef
@provider = Chef::Provider::Deploy::Revision
end
end
-
+
class DeployBranch < Chef::Resource::DeployRevision
def initialize(*args, &block)
super
@resource_name = :deploy_branch
end
end
-
+
end
end
diff --git a/lib/chef/resource/directory.rb b/lib/chef/resource/directory.rb
index a5d5ea7366..423c0bbe27 100644
--- a/lib/chef/resource/directory.rb
+++ b/lib/chef/resource/directory.rb
@@ -25,11 +25,11 @@ require 'chef/mixin/securable'
class Chef
class Resource
class Directory < Chef::Resource
-
+
identity_attr :path
state_attrs :group, :mode, :owner
-
+
include Chef::Mixin::Securable
provides :directory, :on_platforms => :all
diff --git a/lib/chef/resource/dpkg_package.rb b/lib/chef/resource/dpkg_package.rb
index 02886e8649..2fb5b5c249 100644
--- a/lib/chef/resource/dpkg_package.rb
+++ b/lib/chef/resource/dpkg_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,13 +22,13 @@ require 'chef/provider/package/dpkg'
class Chef
class Resource
class DpkgPackage < Chef::Resource::Package
-
+
def initialize(name, run_context=nil)
super
@resource_name = :dpkg_package
@provider = Chef::Provider::Package::Dpkg
end
-
+
end
end
end
diff --git a/lib/chef/resource/easy_install_package.rb b/lib/chef/resource/easy_install_package.rb
index 10e80bdd3b..f25e1ac22f 100644
--- a/lib/chef/resource/easy_install_package.rb
+++ b/lib/chef/resource/easy_install_package.rb
@@ -21,7 +21,7 @@ require 'chef/resource/package'
class Chef
class Resource
class EasyInstallPackage < Chef::Resource::Package
-
+
def initialize(name, run_context=nil)
super
@resource_name = :easy_install_package
diff --git a/lib/chef/resource/erl_call.rb b/lib/chef/resource/erl_call.rb
index e0e38926bb..959856af66 100644
--- a/lib/chef/resource/erl_call.rb
+++ b/lib/chef/resource/erl_call.rb
@@ -24,7 +24,7 @@ class Chef
class ErlCall < Chef::Resource
# erl_call : http://erlang.org/doc/man/erl_call.html
-
+
identity_attr :code
def initialize(name, run_context=nil)
diff --git a/lib/chef/resource/freebsd_package.rb b/lib/chef/resource/freebsd_package.rb
index 9a9a84900e..94286eae18 100644
--- a/lib/chef/resource/freebsd_package.rb
+++ b/lib/chef/resource/freebsd_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,13 +22,13 @@ require 'chef/provider/package/freebsd'
class Chef
class Resource
class FreebsdPackage < Chef::Resource::Package
-
+
def initialize(name, run_context=nil)
super
@resource_name = :freebsd_package
@provider = Chef::Provider::Package::Freebsd
end
-
+
end
end
end
diff --git a/lib/chef/resource/group.rb b/lib/chef/resource/group.rb
index 76f3a779ae..17f14c8387 100644
--- a/lib/chef/resource/group.rb
+++ b/lib/chef/resource/group.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@
class Chef
class Resource
class Group < Chef::Resource
-
+
identity_attr :group_name
state_attrs :members
@@ -33,9 +33,10 @@ class Chef
@members = []
@action = :create
@append = false
+ @non_unique = false
@allowed_actions.push(:create, :remove, :modify, :manage)
end
-
+
def group_name(arg=nil)
set_or_return(
:group_name,
@@ -43,7 +44,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def gid(arg=nil)
set_or_return(
:gid,
@@ -62,7 +63,7 @@ class Chef
end
alias_method :users, :members
-
+
def append(arg=nil)
set_or_return(
:append,
@@ -78,6 +79,14 @@ class Chef
:kind_of => [ TrueClass, FalseClass ]
)
end
+
+ def non_unique(arg=nil)
+ set_or_return(
+ :non_unique,
+ arg,
+ :kind_of => [ TrueClass, FalseClass ]
+ )
+ end
end
end
end
diff --git a/lib/chef/resource/http_request.rb b/lib/chef/resource/http_request.rb
index fc64121f4e..47f6286fb4 100644
--- a/lib/chef/resource/http_request.rb
+++ b/lib/chef/resource/http_request.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'chef/resource'
class Chef
class Resource
class HttpRequest < Chef::Resource
-
+
identity_attr :url
def initialize(name, run_context=nil)
@@ -34,7 +34,7 @@ class Chef
@headers = {}
@allowed_actions.push(:get, :put, :post, :delete, :head, :options)
end
-
+
def url(args=nil)
set_or_return(
:url,
@@ -42,7 +42,7 @@ class Chef
:kind_of => String
)
end
-
+
def message(args=nil, &block)
args = block if block_given?
set_or_return(
@@ -59,7 +59,7 @@ class Chef
:kind_of => Hash
)
end
-
+
end
end
end
diff --git a/lib/chef/resource/ifconfig.rb b/lib/chef/resource/ifconfig.rb
index daa8a572a0..c289ddadbe 100644
--- a/lib/chef/resource/ifconfig.rb
+++ b/lib/chef/resource/ifconfig.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'chef/resource'
class Chef
class Resource
class Ifconfig < Chef::Resource
-
+
identity_attr :device
state_attrs :inet_addr, :mask
@@ -39,7 +39,7 @@ class Chef
@bcast = nil
@mtu = nil
@metric = nil
- @device = nil
+ @device = nil
@onboot = nil
@network = nil
@bootproto = nil
diff --git a/lib/chef/resource/ips_package.rb b/lib/chef/resource/ips_package.rb
index f82e0877df..88c6e9a538 100644
--- a/lib/chef/resource/ips_package.rb
+++ b/lib/chef/resource/ips_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/resource/log.rb b/lib/chef/resource/log.rb
index 30a5bb93c6..391c3b5393 100644
--- a/lib/chef/resource/log.rb
+++ b/lib/chef/resource/log.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,7 +19,7 @@
class Chef
class Resource
class Log < Chef::Resource
-
+
identity_attr :message
# Sends a string from a recipe to a log provider
@@ -27,16 +27,16 @@ class Chef
# log "some string to log" do
# level :info # (default) also supports :warn, :debug, and :error
# end
- #
+ #
# === Example
- # log "your string to log"
+ # log "your string to log"
#
- # or
+ # or
#
# log "a debug string" { level :debug }
#
-
- # Initialize log resource with a name as the string to log
+
+ # Initialize log resource with a name as the string to log
#
# === Parameters
# name<String>:: Message to log
@@ -47,6 +47,7 @@ class Chef
@resource_name = :log
@level = :info
@action = :write
+ @allowed_actions.push(:write)
@message = name
end
@@ -57,7 +58,7 @@ class Chef
:kind_of => String
)
end
-
+
# <Symbol> Log level, one of :debug, :info, :warn, :error or :fatal
def level(arg=nil)
set_or_return(
@@ -66,9 +67,9 @@ class Chef
:equal_to => [ :debug, :info, :warn, :error, :fatal ]
)
end
-
+
end
- end
+ end
end
diff --git a/lib/chef/resource/macports_package.rb b/lib/chef/resource/macports_package.rb
index 911d3c19cb..c9434c9e69 100644
--- a/lib/chef/resource/macports_package.rb
+++ b/lib/chef/resource/macports_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/resource/mount.rb b/lib/chef/resource/mount.rb
index ad68391fe4..49984630c0 100644
--- a/lib/chef/resource/mount.rb
+++ b/lib/chef/resource/mount.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'chef/resource'
class Chef
class Resource
class Mount < Chef::Resource
-
+
identity_attr :device
state_attrs :mount_point, :device_type, :fstype, :username, :password, :domain
@@ -46,7 +46,7 @@ class Chef
@password = nil
@domain = nil
end
-
+
def mount_point(arg=nil)
set_or_return(
:mount_point,
@@ -54,7 +54,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def device(arg=nil)
set_or_return(
:device,
@@ -62,7 +62,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def device_type(arg=nil)
real_arg = arg.kind_of?(String) ? arg.to_sym : arg
set_or_return(
@@ -79,7 +79,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def options(arg=nil)
if arg.is_a?(String)
converted_arg = arg.gsub(/,/, ' ').split(/ /)
@@ -92,7 +92,7 @@ class Chef
:kind_of => [ Array ]
)
end
-
+
def dump(arg=nil)
set_or_return(
:dump,
@@ -100,7 +100,7 @@ class Chef
:kind_of => [ Integer, FalseClass ]
)
end
-
+
def pass(arg=nil)
set_or_return(
:pass,
@@ -108,7 +108,7 @@ class Chef
:kind_of => [ Integer, FalseClass ]
)
end
-
+
def mounted(arg=nil)
set_or_return(
:mounted,
@@ -124,7 +124,7 @@ class Chef
:kind_of => [ TrueClass, FalseClass ]
)
end
-
+
def supports(args={})
if args.is_a? Array
args.each { |arg| @supports[arg] = true }
@@ -163,4 +163,3 @@ class Chef
end
end
-
diff --git a/lib/chef/resource/ohai.rb b/lib/chef/resource/ohai.rb
index 48e55e9f01..b567db40f9 100644
--- a/lib/chef/resource/ohai.rb
+++ b/lib/chef/resource/ohai.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@
class Chef
class Resource
class Ohai < Chef::Resource
-
+
identity_attr :name
state_attrs :plugin
diff --git a/lib/chef/resource/pacman_package.rb b/lib/chef/resource/pacman_package.rb
index d66c93be66..2894e415ac 100644
--- a/lib/chef/resource/pacman_package.rb
+++ b/lib/chef/resource/pacman_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,13 +21,13 @@ require 'chef/resource/package'
class Chef
class Resource
class PacmanPackage < Chef::Resource::Package
-
+
def initialize(name, run_context=nil)
super
@resource_name = :pacman_package
@provider = Chef::Provider::Package::Pacman
end
-
+
end
end
end
diff --git a/lib/chef/resource/perl.rb b/lib/chef/resource/perl.rb
index d3cf696cbb..546f639e1f 100644
--- a/lib/chef/resource/perl.rb
+++ b/lib/chef/resource/perl.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,7 +21,7 @@ require 'chef/resource/script'
class Chef
class Resource
class Perl < Chef::Resource::Script
-
+
def initialize(name, run_context=nil)
super
@resource_name = :perl
diff --git a/lib/chef/resource/portage_package.rb b/lib/chef/resource/portage_package.rb
index fc72381482..42c03560b6 100644
--- a/lib/chef/resource/portage_package.rb
+++ b/lib/chef/resource/portage_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,13 +21,13 @@ require 'chef/resource/package'
class Chef
class Resource
class PortagePackage < Chef::Resource::Package
-
+
def initialize(name, run_context=nil)
super
@resource_name = :portage_package
@provider = Chef::Provider::Package::Portage
end
-
+
end
end
end
diff --git a/lib/chef/resource/powershell_script.rb b/lib/chef/resource/powershell_script.rb
index e257eb2fb1..cbd81b1259 100644
--- a/lib/chef/resource/powershell_script.rb
+++ b/lib/chef/resource/powershell_script.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,7 +25,7 @@ class Chef
def initialize(name, run_context=nil)
super(name, run_context, :powershell_script, "powershell.exe")
end
-
+
end
end
end
diff --git a/lib/chef/resource/python.rb b/lib/chef/resource/python.rb
index 85a5348d27..f340afdb39 100644
--- a/lib/chef/resource/python.rb
+++ b/lib/chef/resource/python.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,7 +21,7 @@ require 'chef/resource/script'
class Chef
class Resource
class Python < Chef::Resource::Script
-
+
def initialize(name, run_context=nil)
super
@resource_name = :python
diff --git a/lib/chef/resource/route.rb b/lib/chef/resource/route.rb
index c8680697af..942905d138 100644
--- a/lib/chef/resource/route.rb
+++ b/lib/chef/resource/route.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -26,7 +26,7 @@ class Chef
identity_attr :target
state_attrs :netmask, :gateway
-
+
def initialize(name, run_context=nil)
super
@resource_name = :route
@@ -36,7 +36,7 @@ class Chef
@netmask = nil
@gateway = nil
@metric = nil
- @device = nil
+ @device = nil
@route_type = :host
@networking = nil
@networking_ipv6 = nil
diff --git a/lib/chef/resource/rpm_package.rb b/lib/chef/resource/rpm_package.rb
index 7ab1202ef2..200a9633ce 100644
--- a/lib/chef/resource/rpm_package.rb
+++ b/lib/chef/resource/rpm_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/resource/ruby.rb b/lib/chef/resource/ruby.rb
index 7617839bab..605d27b00d 100644
--- a/lib/chef/resource/ruby.rb
+++ b/lib/chef/resource/ruby.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,7 +21,7 @@ require 'chef/resource/script'
class Chef
class Resource
class Ruby < Chef::Resource::Script
-
+
def initialize(name, run_context=nil)
super
@resource_name = :ruby
diff --git a/lib/chef/resource/ruby_block.rb b/lib/chef/resource/ruby_block.rb
index 296345bde3..d9b8954a90 100644
--- a/lib/chef/resource/ruby_block.rb
+++ b/lib/chef/resource/ruby_block.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@
class Chef
class Resource
class RubyBlock < Chef::Resource
-
+
identity_attr :block_name
def initialize(name, run_context=nil)
diff --git a/lib/chef/resource/scm.rb b/lib/chef/resource/scm.rb
index 781e09a2c9..d9a372900e 100644
--- a/lib/chef/resource/scm.rb
+++ b/lib/chef/resource/scm.rb
@@ -23,8 +23,8 @@ class Chef
class Resource
class Scm < Chef::Resource
- identity_attr :destination
-
+ identity_attr :destination
+
state_attrs :revision
def initialize(name, run_context=nil)
@@ -146,6 +146,14 @@ class Chef
)
end
+ def timeout(arg=nil)
+ set_or_return(
+ :timeout,
+ arg,
+ :kind_of => Integer
+ )
+ end
+
end
end
end
diff --git a/lib/chef/resource/script.rb b/lib/chef/resource/script.rb
index 6a7c8e0d5e..8cc9c6f0c5 100644
--- a/lib/chef/resource/script.rb
+++ b/lib/chef/resource/script.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'chef/resource/execute'
class Chef
class Resource
class Script < Chef::Resource::Execute
-
+
identity_attr :command
def initialize(name, run_context=nil)
@@ -33,7 +33,7 @@ class Chef
@interpreter = nil
@flags = nil
end
-
+
def code(arg=nil)
set_or_return(
:code,
@@ -41,7 +41,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def interpreter(arg=nil)
set_or_return(
:interpreter,
diff --git a/lib/chef/resource/service.rb b/lib/chef/resource/service.rb
index ea43baa414..befa4be1c9 100644
--- a/lib/chef/resource/service.rb
+++ b/lib/chef/resource/service.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'chef/resource'
class Chef
class Resource
class Service < Chef::Resource
-
+
identity_attr :service_name
state_attrs :enabled, :running
@@ -47,7 +47,7 @@ class Chef
@supports = { :restart => false, :reload => false, :status => false }
@allowed_actions.push(:enable, :disable, :start, :stop, :restart, :reload)
end
-
+
def service_name(arg=nil)
set_or_return(
:service_name,
@@ -55,7 +55,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
# regex for match against ps -ef when !supports[:has_status] && status == nil
def pattern(arg=nil)
set_or_return(
diff --git a/lib/chef/resource/smartos_package.rb b/lib/chef/resource/smartos_package.rb
index 315481bd93..0f4f6d8b0a 100644
--- a/lib/chef/resource/smartos_package.rb
+++ b/lib/chef/resource/smartos_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,16 +21,18 @@ require 'chef/provider/package/smartos'
class Chef
class Resource
- class SmartOSPackage < Chef::Resource::Package
-
+ class SmartosPackage < Chef::Resource::Package
+
def initialize(name, run_context=nil)
super
@resource_name = :smartos_package
@provider = Chef::Provider::Package::SmartOS
end
-
+
end
end
end
-
+# Backwards compatability
+# @todo remove in Chef 12
+Chef::Resource::SmartOSPackage = Chef::Resource::SmartosPackage
diff --git a/lib/chef/resource/solaris_package.rb b/lib/chef/resource/solaris_package.rb
index becf0236ad..3513703076 100644
--- a/lib/chef/resource/solaris_package.rb
+++ b/lib/chef/resource/solaris_package.rb
@@ -1,14 +1,15 @@
#
# Author:: Toomas Pelberg (<toomasp@gmx.net>)
-# Copyright:: Copyright (c) 2010 Opscode, Inc.
+# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,13 +23,13 @@ require 'chef/provider/package/solaris'
class Chef
class Resource
class SolarisPackage < Chef::Resource::Package
-
- def initialize(name, collection=nil, node=nil)
- super(name, collection, node)
+
+ def initialize(name, run_context=nil)
+ super
@resource_name = :solaris_package
@provider = Chef::Provider::Package::Solaris
end
-
+
end
end
end
diff --git a/lib/chef/resource/subversion.rb b/lib/chef/resource/subversion.rb
index e3226d8b3b..04fec9b1d8 100644
--- a/lib/chef/resource/subversion.rb
+++ b/lib/chef/resource/subversion.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -31,7 +31,7 @@ class Chef
@provider = Chef::Provider::Subversion
allowed_actions << :force_export
end
-
+
end
end
end
diff --git a/lib/chef/resource/timestamped_deploy.rb b/lib/chef/resource/timestamped_deploy.rb
index d89274bb44..4032ae9854 100644
--- a/lib/chef/resource/timestamped_deploy.rb
+++ b/lib/chef/resource/timestamped_deploy.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,9 +18,9 @@
class Chef
class Resource
-
+
# Convenience class for using the deploy resource with the timestamped
- # deployment strategy (provider)
+ # deployment strategy (provider)
class TimestampedDeploy < Chef::Resource::Deploy
def initialize(*args, &block)
super(*args, &block)
diff --git a/lib/chef/resource/user.rb b/lib/chef/resource/user.rb
index 4d8c4ac11b..357d6d12ea 100644
--- a/lib/chef/resource/user.rb
+++ b/lib/chef/resource/user.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,7 +25,7 @@ class Chef
identity_attr :username
state_attrs :uid, :gid, :home
-
+
def initialize(name, run_context=nil)
super
@resource_name = :user
@@ -40,13 +40,13 @@ class Chef
@manage_home = false
@non_unique = false
@action = :create
- @supports = {
+ @supports = {
:manage_home => false,
:non_unique => false
}
@allowed_actions.push(:create, :remove, :modify, :manage, :lock, :unlock)
end
-
+
def username(arg=nil)
set_or_return(
:username,
@@ -54,7 +54,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def comment(arg=nil)
set_or_return(
:comment,
@@ -62,7 +62,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def uid(arg=nil)
set_or_return(
:uid,
@@ -70,7 +70,7 @@ class Chef
:kind_of => [ String, Integer ]
)
end
-
+
def gid(arg=nil)
set_or_return(
:gid,
@@ -78,9 +78,9 @@ class Chef
:kind_of => [ String, Integer ]
)
end
-
+
alias_method :group, :gid
-
+
def home(arg=nil)
set_or_return(
:home,
@@ -88,7 +88,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def shell(arg=nil)
set_or_return(
:shell,
@@ -96,7 +96,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def password(arg=nil)
set_or_return(
:password,
@@ -128,7 +128,7 @@ class Chef
:kind_of => [ TrueClass, FalseClass ]
)
end
-
+
end
end
end
diff --git a/lib/chef/resource/windows_script.rb b/lib/chef/resource/windows_script.rb
index 5f2311a5bb..2b563f5bec 100644
--- a/lib/chef/resource/windows_script.rb
+++ b/lib/chef/resource/windows_script.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,14 +27,14 @@ class Chef
def initialize(name, run_context, resource_name, interpreter_command)
super(name, run_context)
- @interpreter = interpreter_command
+ @interpreter = interpreter_command
@resource_name = resource_name
end
include Chef::Mixin::WindowsArchitectureHelper
public
-
+
def architecture(arg=nil)
assert_architecture_compatible!(arg) if ! arg.nil?
result = set_or_return(
@@ -43,7 +43,7 @@ class Chef
:kind_of => Symbol
)
end
-
+
protected
def assert_architecture_compatible!(desired_architecture)
@@ -56,7 +56,7 @@ class Chef
def node
run_context && run_context.node
end
-
+
end
end
end
diff --git a/lib/chef/resource/yum_package.rb b/lib/chef/resource/yum_package.rb
index bcb1f65667..dff70bcf62 100644
--- a/lib/chef/resource/yum_package.rb
+++ b/lib/chef/resource/yum_package.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/resource_collection.rb b/lib/chef/resource_collection.rb
index 7460a185b4..a528a18aed 100644
--- a/lib/chef/resource_collection.rb
+++ b/lib/chef/resource_collection.rb
@@ -183,7 +183,7 @@ class Chef
"The string `#{query_object}' is not valid for resource collection lookup. Correct syntax is `resource_type[resource_name]'"
else
raise Chef::Exceptions::InvalidResourceSpecification,
- "The object `#{query_object.inspect}' is not valid for resource collection lookup. " +
+ "The object `#{query_object.inspect}' is not valid for resource collection lookup. " +
"Use a String like `resource_type[resource_name]' or a Chef::Resource object"
end
end
diff --git a/lib/chef/resource_collection/stepable_iterator.rb b/lib/chef/resource_collection/stepable_iterator.rb
index ec1e244758..4d5fc1f497 100644
--- a/lib/chef/resource_collection/stepable_iterator.rb
+++ b/lib/chef/resource_collection/stepable_iterator.rb
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,94 +18,94 @@
class Chef
class ResourceCollection
class StepableIterator
-
+
def self.for_collection(new_collection)
instance = new(new_collection)
instance
end
-
+
attr_accessor :collection
attr_reader :position
-
+
def initialize(collection=[])
@position = 0
@paused = false
@collection = collection
end
-
+
def size
collection.size
end
-
+
def each(&block)
reset_iteration(block)
@iterator_type = :element
iterate
end
-
+
def each_index(&block)
reset_iteration(block)
@iterator_type = :index
iterate
end
-
+
def each_with_index(&block)
reset_iteration(block)
@iterator_type = :element_with_index
iterate
end
-
+
def paused?
@paused
end
-
+
def pause
@paused = true
end
-
+
def resume
@paused = false
iterate
end
-
+
def rewind
@position = 0
end
-
+
def skip_back(skips=1)
@position -= skips
end
-
+
def skip_forward(skips=1)
@position += skips
end
-
+
def step
return nil if @position == size
call_iterator_block
@position += 1
end
-
+
def iterate_on(iteration_type, &block)
@iterator_type = iteration_type
@iterator_block = block
end
-
+
private
-
+
def reset_iteration(iterator_block)
@iterator_block = iterator_block
@position = 0
@paused = false
end
-
+
def iterate
while @position < size && !paused?
step
end
collection
end
-
+
def call_iterator_block
case @iterator_type
when :element
@@ -118,7 +118,7 @@ class Chef
raise "42error: someone forgot to set @iterator_type, wtf?"
end
end
-
+
end
end
end
diff --git a/lib/chef/resource_definition.rb b/lib/chef/resource_definition.rb
index a0160c5885..278114e209 100644
--- a/lib/chef/resource_definition.rb
+++ b/lib/chef/resource_definition.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,19 +21,19 @@ require 'chef/mixin/params_validate'
class Chef
class ResourceDefinition
-
+
include Chef::Mixin::FromFile
include Chef::Mixin::ParamsValidate
-
+
attr_accessor :name, :params, :recipe, :node
-
+
def initialize(node=nil)
@name = nil
@params = Hash.new
@recipe = nil
@node = node
end
-
+
def define(resource_name, prototype_params=nil, &block)
unless resource_name.kind_of?(Symbol)
raise ArgumentError, "You must use a symbol when defining a new resource!"
@@ -52,14 +52,14 @@ class Chef
end
true
end
-
+
# When we do the resource definition, we're really just setting new values for
# the paramaters we prototyped at the top. This method missing is as simple as
# it gets.
def method_missing(symbol, *args)
@params[symbol] = args.length == 1 ? args[0] : args
end
-
+
def to_s
"#{name.to_s}"
end
diff --git a/lib/chef/resource_definition_list.rb b/lib/chef/resource_definition_list.rb
index b958624208..55014090d4 100644
--- a/lib/chef/resource_definition_list.rb
+++ b/lib/chef/resource_definition_list.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/resource_reporter.rb b/lib/chef/resource_reporter.rb
index 434150e83d..d29949086e 100644
--- a/lib/chef/resource_reporter.rb
+++ b/lib/chef/resource_reporter.rb
@@ -52,8 +52,8 @@ class Chef
as_hash["type"] = new_resource.class.dsl_name
as_hash["name"] = new_resource.name
as_hash["id"] = new_resource.identity
- as_hash["after"] = new_resource.state
- as_hash["before"] = current_resource ? current_resource.state : {}
+ as_hash["after"] = state(new_resource)
+ as_hash["before"] = current_resource ? state(current_resource) : {}
as_hash["duration"] = (elapsed_time * 1000).to_i.to_s
as_hash["delta"] = new_resource.diff if new_resource.respond_to?("diff")
as_hash["delta"] = "" if as_hash["delta"].nil?
@@ -80,6 +80,12 @@ class Chef
!self.exception
end
+ def state(r)
+ r.class.state_attrs.inject({}) do |state_attrs, attr_name|
+ state_attrs[attr_name] = r.send(attr_name)
+ state_attrs
+ end
+ end
end # End class ResouceReport
attr_reader :updated_resources
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 55c6a0dbf3..d0a27d8922 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -56,6 +56,7 @@ require 'chef/resource/registry_key'
require 'chef/resource/remote_directory'
require 'chef/resource/remote_file'
require 'chef/resource/rpm_package'
+require 'chef/resource/solaris_package'
require 'chef/resource/route'
require 'chef/resource/ruby'
require 'chef/resource/ruby_block'
@@ -69,3 +70,4 @@ require 'chef/resource/timestamped_deploy'
require 'chef/resource/user'
require 'chef/resource/yum_package'
require 'chef/resource/lwrp_base'
+require 'chef/resource/bff_package'
diff --git a/lib/chef/rest.rb b/lib/chef/rest.rb
index 6c74412839..4168cd63be 100644
--- a/lib/chef/rest.rb
+++ b/lib/chef/rest.rb
@@ -20,15 +20,18 @@
# limitations under the License.
#
-require 'zlib'
-require 'net/https'
-require 'uri'
-require 'chef/json_compat'
require 'tempfile'
-require 'chef/rest/auth_credentials'
-require 'chef/rest/rest_request'
-require 'chef/monkey_patches/string'
-require 'chef/monkey_patches/net_http'
+require 'chef/http'
+class Chef
+ class HTTP; end
+ class REST < HTTP; end
+end
+
+require 'chef/http/authenticator'
+require 'chef/http/decompressor'
+require 'chef/http/json_input'
+require 'chef/http/json_to_model_output'
+require 'chef/http/cookie_manager'
require 'chef/config'
require 'chef/exceptions'
require 'chef/platform/query_helpers'
@@ -37,54 +40,53 @@ class Chef
# == Chef::REST
# Chef's custom REST client with built-in JSON support and RSA signed header
# authentication.
- class REST
+ class REST < HTTP
- class NoopInflater
- def inflate(chunk)
- chunk
- end
- end
+ # Backwards compatibility for things that use
+ # Chef::REST::RESTRequest or its constants
+ RESTRequest = HTTP::HTTPRequest
- attr_reader :auth_credentials
attr_accessor :url, :cookies, :sign_on_redirect, :redirect_limit
- CONTENT_ENCODING = "content-encoding".freeze
- GZIP = "gzip".freeze
- DEFLATE = "deflate".freeze
- IDENTITY = "identity".freeze
+ attr_reader :authenticator
# Create a REST client object. The supplied +url+ is used as the base for
# all subsequent requests. For example, when initialized with a base url
# http://localhost:4000, a call to +get_rest+ with 'nodes' will make an
# HTTP GET request to http://localhost:4000/nodes
def initialize(url, client_name=Chef::Config[:node_name], signing_key_filename=Chef::Config[:client_key], options={})
- @url = url
- @cookies = CookieJar.instance
- @default_headers = options[:headers] || {}
- @signing_key_filename = signing_key_filename
- @key = load_signing_key(@signing_key_filename, options[:raw_key])
- @auth_credentials = AuthCredentials.new(client_name, @key)
- @sign_on_redirect, @sign_request = true, true
- @redirects_followed = 0
- @redirect_limit = 10
- @disable_gzip = false
- handle_options(options)
+ options[:client_name] = client_name
+ options[:signing_key_filename] = signing_key_filename
+ super(url, options)
+
+ @decompressor = Decompressor.new(options)
+ @authenticator = Authenticator.new(options)
+
+ @middlewares << JSONInput.new(options)
+ @middlewares << JSONToModelOutput.new(options)
+ @middlewares << CookieManager.new(options)
+ @middlewares << @decompressor
+ @middlewares << @authenticator
end
def signing_key_filename
- @signing_key_filename
+ authenticator.signing_key_filename
+ end
+
+ def auth_credentials
+ authenticator.auth_credentials
end
def client_name
- @auth_credentials.client_name
+ authenticator.client_name
end
def signing_key
- @raw_key
+ authenticator.raw_key
end
- def last_response
- @last_response
+ def sign_requests?
+ authenticator.sign_requests?
end
# Send an HTTP GET request to the path
@@ -97,37 +99,18 @@ class Chef
# to JSON inflated.
def get(path, raw=false, headers={})
if raw
- streaming_request(create_url(path), headers)
+ streaming_request(path, headers)
else
- api_request(:GET, create_url(path), headers)
+ request(:GET, path, headers)
end
end
- def head(path, headers={})
- api_request(:HEAD, create_url(path), headers)
- end
-
alias :get_rest :get
- # Send an HTTP DELETE request to the path
- def delete(path, headers={})
- api_request(:DELETE, create_url(path), headers)
- end
-
alias :delete_rest :delete
- # Send an HTTP POST request to the path
- def post(path, json, headers={})
- api_request(:POST, create_url(path), headers, json)
- end
-
alias :post_rest :post
- # Send an HTTP PUT request to the path
- def put(path, json, headers={})
- api_request(:PUT, create_url(path), headers, json)
- end
-
alias :put_rest :put
# Streams a download to a tempfile, then yields the tempfile to a block.
@@ -139,308 +122,59 @@ class Chef
streaming_request(create_url(path), headers) {|tmp_file| yield tmp_file }
end
- def create_url(path)
- if path =~ /^(http|https):\/\//
- URI.parse(path)
- else
- URI.parse("#{@url}/#{path}")
- end
- end
-
- def sign_requests?
- auth_credentials.sign_requests? && @sign_request
- end
-
- # Runs an HTTP request to a JSON API with JSON body. File Download not supported.
- def api_request(method, url, headers={}, data=false)
- json_body = data ? Chef::JSONCompat.to_json(data) : nil
- # Force encoding to binary to fix SSL related EOFErrors
- # cf. http://tickets.opscode.com/browse/CHEF-2363
- # http://redmine.ruby-lang.org/issues/5233
- json_body.force_encoding(Encoding::BINARY) if json_body.respond_to?(:force_encoding)
- raw_http_request(method, url, headers, json_body)
- end
-
- # Runs an HTTP request to a JSON API with raw body. File Download not supported.
- def raw_http_request(method, url, headers, body)
- headers = build_headers(method, url, headers, body)
- retriable_rest_request(method, url, body, headers) do |rest_request|
- begin
- response = rest_request.call {|r| r.read_body}
- @last_response = response
-
- Chef::Log.debug("---- HTTP Status and Header Data: ----")
- Chef::Log.debug("HTTP #{response.http_version} #{response.code} #{response.msg}")
-
- response.each do |header, value|
- Chef::Log.debug("#{header}: #{value}")
- end
- Chef::Log.debug("---- End HTTP Status/Header Data ----")
-
- response_body = decompress_body(response)
-
- if response.kind_of?(Net::HTTPSuccess)
- if response['content-type'] =~ /json/
- Chef::JSONCompat.from_json(response_body.chomp)
- else
- Chef::Log.warn("Expected JSON response, but got content-type '#{response['content-type']}'")
- response_body.to_s
- end
- elsif response.kind_of?(Net::HTTPNotModified) # Must be tested before Net::HTTPRedirection because it's subclass.
- false
- elsif redirect_location = redirected_to(response)
- if [:GET, :HEAD].include?(method)
- follow_redirect {api_request(method, create_url(redirect_location))}
- else
- raise Exceptions::InvalidRedirect, "#{method} request was redirected from #{url} to #{redirect_location}. Only GET and HEAD support redirects."
- end
- else
- # have to decompress the body before making an exception for it. But the body could be nil.
- response.body.replace(response_body) if response.body.respond_to?(:replace)
-
- if response['content-type'] =~ /json/
- exception = Chef::JSONCompat.from_json(response_body)
- msg = "HTTP Request Returned #{response.code} #{response.message}: "
- msg << (exception["error"].respond_to?(:join) ? exception["error"].join(", ") : exception["error"].to_s)
- Chef::Log.info(msg)
- end
- response.error!
- end
- rescue Exception => e
- if e.respond_to?(:chef_rest_request=)
- e.chef_rest_request = rest_request
- end
- raise
- end
- end
- end
-
- def decompress_body(response)
- if gzip_disabled? || response.body.nil?
- response.body
- else
- case response[CONTENT_ENCODING]
- when GZIP
- Chef::Log.debug "decompressing gzip response"
- Zlib::Inflate.new(Zlib::MAX_WBITS + 16).inflate(response.body)
- when DEFLATE
- Chef::Log.debug "decompressing deflate response"
- Zlib::Inflate.inflate(response.body)
- else
- response.body
- end
- end
- end
+ alias :api_request :request
- # Makes a streaming download request. <b>Doesn't speak JSON.</b>
- # Streams the response body to a tempfile. If a block is given, it's
- # passed to Tempfile.open(), which means that the tempfile will automatically
- # be unlinked after the block is executed.
- #
- # If no block is given, the tempfile is returned, which means it's up to
- # you to unlink the tempfile when you're done with it.
- def streaming_request(url, headers, &block)
- headers = build_headers(:GET, url, headers, nil, true)
- retriable_rest_request(:GET, url, nil, headers) do |rest_request|
- begin
- tempfile = nil
- response = rest_request.call do |r|
- if block_given? && r.kind_of?(Net::HTTPSuccess)
- begin
- tempfile = stream_to_tempfile(url, r, &block)
- yield tempfile
- ensure
- tempfile.close!
- end
- else
- tempfile = stream_to_tempfile(url, r)
- end
- end
- @last_response = response
- if response.kind_of?(Net::HTTPSuccess)
- tempfile
- elsif redirect_location = redirected_to(response)
- # TODO: test tempfile unlinked when following redirects.
- tempfile && tempfile.close!
- follow_redirect {streaming_request(create_url(redirect_location), {}, &block)}
- else
- tempfile && tempfile.close!
- response.error!
- end
- rescue Exception => e
- if e.respond_to?(:chef_rest_request=)
- e.chef_rest_request = rest_request
- end
- raise
- end
- end
- end
+ alias :raw_http_request :send_http_request
- def retriable_rest_request(method, url, req_body, headers)
- rest_request = Chef::REST::RESTRequest.new(method, url, req_body, headers)
+ # Deprecated:
+ # Responsibilities of this method have been split up. The #http_client is
+ # now responsible for making individual requests, while
+ # #retrying_http_errors handles error/retry logic.
+ def retriable_http_request(method, url, req_body, headers)
+ rest_request = Chef::HTTP::HTTPRequest.new(method, url, req_body, headers)
Chef::Log.debug("Sending HTTP Request via #{method} to #{url.host}:#{url.port}#{rest_request.path}")
- http_attempts = 0
-
- begin
- http_attempts += 1
-
+ retrying_http_errors(url) do
yield rest_request
-
- rescue SocketError, Errno::ETIMEDOUT => e
- e.message.replace "Error connecting to #{url} - #{e.message}"
- raise e
- rescue Errno::ECONNREFUSED
- if http_retry_count - http_attempts + 1 > 0
- Chef::Log.error("Connection refused connecting to #{url.host}:#{url.port} for #{rest_request.path}, retry #{http_attempts}/#{http_retry_count}")
- sleep(http_retry_delay)
- retry
- end
- raise Errno::ECONNREFUSED, "Connection refused connecting to #{url.host}:#{url.port} for #{rest_request.path}, giving up"
- rescue Timeout::Error
- if http_retry_count - http_attempts + 1 > 0
- Chef::Log.error("Timeout connecting to #{url.host}:#{url.port} for #{rest_request.path}, retry #{http_attempts}/#{http_retry_count}")
- sleep(http_retry_delay)
- retry
- end
- raise Timeout::Error, "Timeout connecting to #{url.host}:#{url.port} for #{rest_request.path}, giving up"
- rescue Net::HTTPFatalError => e
- if http_retry_count - http_attempts + 1 > 0
- sleep_time = 1 + (2 ** http_attempts) + rand(2 ** http_attempts)
- Chef::Log.error("Server returned error for #{url}, retrying #{http_attempts}/#{http_retry_count} in #{sleep_time}s")
- sleep(sleep_time)
- retry
- end
- raise
end
end
- def authentication_headers(method, url, json_body=nil)
- request_params = {:http_method => method, :path => url.path, :body => json_body, :host => "#{url.host}:#{url.port}"}
- request_params[:body] ||= ""
- auth_credentials.signature_headers(request_params)
- end
-
- def http_retry_delay
- config[:http_retry_delay]
- end
-
- def http_retry_count
- config[:http_retry_count]
+ # Customized streaming behavior; sets the accepted content type to "*/*"
+ # if not otherwise specified for compatibility purposes
+ def streaming_request(url, headers, &block)
+ headers["Accept"] ||= "*/*"
+ super
end
- def config
- Chef::Config
- end
+ alias :retriable_rest_request :retriable_http_request
def follow_redirect
- raise Chef::Exceptions::RedirectLimitExceeded if @redirects_followed >= redirect_limit
- @redirects_followed += 1
- Chef::Log.debug("Following redirect #{@redirects_followed}/#{redirect_limit}")
- if @sign_on_redirect
- yield
- else
- @sign_request = false
- yield
+ unless @sign_on_redirect
+ @authenticator.sign_request = false
end
+ super
ensure
- @redirects_followed = 0
- @sign_request = true
+ @authenticator.sign_request = true
end
- private
+ public :create_url
- def redirected_to(response)
- return nil unless response.kind_of?(Net::HTTPRedirection)
- # Net::HTTPNotModified is undesired subclass of Net::HTTPRedirection so test for this
- return nil if response.kind_of?(Net::HTTPNotModified)
- response['location']
+ def http_client(base_url=nil)
+ base_url ||= url
+ BasicClient.new(base_url, :ssl_policy => Chef::HTTP::APISSLPolicy)
end
- def build_headers(method, url, headers={}, json_body=false, raw=false)
- headers = @default_headers.merge(headers)
- #headers['Accept'] = "application/json" unless raw
- headers['Accept'] = "application/json" unless raw
- headers["Content-Type"] = 'application/json' if json_body
- headers['Content-Length'] = json_body.bytesize.to_s if json_body
- headers[RESTRequest::ACCEPT_ENCODING] = RESTRequest::ENCODING_GZIP_DEFLATE unless gzip_disabled?
- headers.merge!(authentication_headers(method, url, json_body)) if sign_requests?
- headers.merge!(Chef::Config[:custom_http_headers]) if Chef::Config[:custom_http_headers]
- headers
- end
-
- def stream_to_tempfile(url, response)
- tf = Tempfile.open("chef-rest")
- if Chef::Platform.windows?
- tf.binmode # required for binary files on Windows platforms
- end
- Chef::Log.debug("Streaming download from #{url.to_s} to tempfile #{tf.path}")
- # Stolen from http://www.ruby-forum.com/topic/166423
- # Kudos to _why!
-
- inflater = if gzip_disabled?
- NoopInflater.new
- else
- case response[CONTENT_ENCODING]
- when GZIP
- Chef::Log.debug "decompressing gzip stream"
- Zlib::Inflate.new(Zlib::MAX_WBITS + 16)
- when DEFLATE
- Chef::Log.debug "decompressing inflate stream"
- Zlib::Inflate.new
- else
- NoopInflater.new
- end
- end
+ ############################################################################
+ # DEPRECATED
+ ############################################################################
- response.read_body do |chunk|
- tf.write(inflater.inflate(chunk))
- end
- tf.close
- tf
- rescue Exception
- tf.close!
- raise
+ def decompress_body(body)
+ @decompressor.decompress_body(body)
end
- # gzip is disabled using the disable_gzip => true option in the
- # constructor. When gzip is disabled, no 'Accept-Encoding' header will be
- # set, and the response will not be decompressed, no matter what the
- # Content-Encoding header of the response is. The intended use case for
- # this is to work around situations where you request +file.tar.gz+, but
- # the server responds with a content type of tar and a content encoding of
- # gzip, tricking the client into decompressing the response so you end up
- # with a tar archive (no gzip) named file.tar.gz
- def gzip_disabled?
- @disable_gzip
- end
-
- def handle_options(opts)
- opts.each do |name, value|
- case name.to_s
- when 'disable_gzip'
- @disable_gzip = value
- end
- end
- end
-
- def load_signing_key(key_file, raw_key = nil)
- if (!!key_file)
- @raw_key = IO.read(key_file).strip
- elsif (!!raw_key)
- @raw_key = raw_key.strip
- else
- return nil
- end
- @key = OpenSSL::PKey::RSA.new(@raw_key)
- rescue SystemCallError, IOError => e
- Chef::Log.warn "Failed to read the private key #{key_file}: #{e.inspect}"
- raise Chef::Exceptions::PrivateKeyMissing, "I cannot read #{key_file}, which you told me to use to sign requests!"
- rescue OpenSSL::PKey::RSAError
- msg = "The file #{key_file} or :raw_key option does not contain a correctly formatted private key.\n"
- msg << "The key file should begin with '-----BEGIN RSA PRIVATE KEY-----' and end with '-----END RSA PRIVATE KEY-----'"
- raise Chef::Exceptions::InvalidPrivateKey, msg
+ def authentication_headers(method, url, json_body=nil)
+ authenticator.authentication_headers(method, url, json_body)
end
end
diff --git a/lib/chef/role.rb b/lib/chef/role.rb
index 78bbfadb88..6ad58b816d 100644
--- a/lib/chef/role.rb
+++ b/lib/chef/role.rb
@@ -233,20 +233,24 @@ class Chef
# Load a role from disk - prefers to load the JSON, but will happily load
# the raw rb files as well.
def self.from_disk(name, force=nil)
- js_file = File.join(Chef::Config[:role_path], "#{name}.json")
- rb_file = File.join(Chef::Config[:role_path], "#{name}.rb")
-
- if File.exists?(js_file) || force == "json"
- # from_json returns object.class => json_class in the JSON.
- Chef::JSONCompat.from_json(IO.read(js_file))
- elsif File.exists?(rb_file) || force == "ruby"
- role = Chef::Role.new
- role.name(name)
- role.from_file(rb_file)
- role
- else
- raise Chef::Exceptions::RoleNotFound, "Role '#{name}' could not be loaded from disk"
+ paths = Array(Chef::Config[:role_path])
+
+ paths.each do |p|
+ js_file = File.join(p, "#{name}.json")
+ rb_file = File.join(p, "#{name}.rb")
+
+ if File.exists?(js_file) || force == "json"
+ # from_json returns object.class => json_class in the JSON.
+ return Chef::JSONCompat.from_json(IO.read(js_file))
+ elsif File.exists?(rb_file) || force == "ruby"
+ role = Chef::Role.new
+ role.name(name)
+ role.from_file(rb_file)
+ return role
+ end
end
+
+ raise Chef::Exceptions::RoleNotFound, "Role '#{name}' could not be loaded from disk"
end
end
diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb
index 6477431967..4d431116f9 100644
--- a/lib/chef/run_context.rb
+++ b/lib/chef/run_context.rb
@@ -204,6 +204,20 @@ class Chef
@loaded_attributes["#{cookbook}::#{attribute_file}"] = true
end
+ ##
+ # Cookbook File Introspection
+
+ def has_template_in_cookbook?(cookbook, template_name)
+ cookbook = cookbook_collection[cookbook]
+ cookbook.has_template_for_node?(node, template_name)
+ end
+
+ def has_cookbook_file_in_cookbook?(cookbook, cb_file_name)
+ cookbook = cookbook_collection[cookbook]
+ cookbook.has_cookbook_file_for_node?(node, cb_file_name)
+ end
+
+
private
def loaded_recipe(cookbook, recipe)
diff --git a/lib/chef/run_context/cookbook_compiler.rb b/lib/chef/run_context/cookbook_compiler.rb
index d1b93f6652..0a05061152 100644
--- a/lib/chef/run_context/cookbook_compiler.rb
+++ b/lib/chef/run_context/cookbook_compiler.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -259,7 +259,7 @@ class Chef
cookbook_collection[cookbook].segment_filenames(segment).sort
end
- # Yields the name, as a symbol, of each cookbook depended on by
+ # Yields the name, as a symbol, of each cookbook depended on by
# +cookbook_name+ in lexical sort order.
def each_cookbook_dep(cookbook_name, &block)
cookbook = cookbook_collection[cookbook_name]
diff --git a/lib/chef/run_lock.rb b/lib/chef/run_lock.rb
index 50046c2396..972db1a4e1 100644
--- a/lib/chef/run_lock.rb
+++ b/lib/chef/run_lock.rb
@@ -17,6 +17,9 @@
require 'chef/mixin/create_path'
require 'fcntl'
+if Chef::Platform.windows?
+ require 'chef/win32/mutex'
+end
class Chef
@@ -30,20 +33,16 @@ class Chef
include Chef::Mixin::CreatePath
attr_reader :runlock
+ attr_reader :mutex
attr_reader :runlock_file
# Create a new instance of RunLock
# === Arguments
- # * config::: This will generally be the `Chef::Config`, but any Hash-like
- # object with Symbol keys will work. See 'Parameters' section.
- # === Parameters/Config
- # * :lockfile::: if set, this will be used as the full path to the lockfile.
- # * :file_cache_path::: if `:lockfile` is not set, the lock file will be
- # named "chef-client-running.pid" and be placed in the directory given by
- # `:file_cache_path`
- def initialize(config)
- @runlock_file = config[:lockfile] || "#{config[:file_cache_path]}/chef-client-running.pid"
+ # * :lockfile::: the full path to the lockfile.
+ def initialize(lockfile)
+ @runlock_file = lockfile
@runlock = nil
+ @mutex = nil
end
# Acquire the system-wide lock. Will block indefinitely if another process
@@ -52,31 +51,73 @@ class Chef
# Each call to acquire should have a corresponding call to #release.
#
# The implementation is based on File#flock (see also: flock(2)).
+ #
+ # Either acquire() or test() methods should be called in order to
+ # get the ownership of run_lock.
def acquire
+ wait unless test
+ end
+
+ #
+ # Tests and if successful acquires the system-wide lock.
+ # Returns true if the lock is acquired, false otherwise.
+ #
+ # Either acquire() or test() methods should be called in order to
+ # get the ownership of run_lock.
+ def test
# ensure the runlock_file path exists
create_path(File.dirname(runlock_file))
- @runlock = File.open(runlock_file,'w+')
- # if we support FD_CLOEXEC (linux, !windows), then use it.
- # NB: ruby-2.0.0-p195 sets FD_CLOEXEC by default, but not ruby-1.8.7/1.9.3
- if Fcntl.const_defined?('F_SETFD') && Fcntl.const_defined?('FD_CLOEXEC')
- runlock.fcntl(Fcntl::F_SETFD, runlock.fcntl(Fcntl::F_GETFD, 0) | Fcntl::FD_CLOEXEC)
+ @runlock = File.open(runlock_file,'a+')
+
+ if Chef::Platform.windows?
+ acquire_win32_mutex
+ else
+ # If we support FD_CLOEXEC, then use it.
+ # NB: ruby-2.0.0-p195 sets FD_CLOEXEC by default, but not
+ # ruby-1.8.7/1.9.3
+ if Fcntl.const_defined?('F_SETFD') && Fcntl.const_defined?('FD_CLOEXEC')
+ runlock.fcntl(Fcntl::F_SETFD, runlock.fcntl(Fcntl::F_GETFD, 0) | Fcntl::FD_CLOEXEC)
+ end
+ # Flock will return 0 if it can acquire the lock otherwise it
+ # will return false
+ if runlock.flock(File::LOCK_NB|File::LOCK_EX) == 0
+ true
+ else
+ false
+ end
end
- unless runlock.flock(File::LOCK_EX|File::LOCK_NB)
- # Another chef client running...
- runpid = runlock.read.strip.chomp
- Chef::Log.warn("Chef client #{runpid} is running, will wait for it to finish and then run.")
+ end
+
+ #
+ # Waits until acquiring the system-wide lock.
+ #
+ def wait
+ runpid = runlock.read.strip.chomp
+ Chef::Log.warn("Chef client #{runpid} is running, will wait for it to finish and then run.")
+ if Chef::Platform.windows?
+ mutex.wait
+ else
runlock.flock(File::LOCK_EX)
end
- # We grabbed the run lock. Save the pid.
+ end
+
+ def save_pid
runlock.truncate(0)
runlock.rewind # truncate doesn't reset position to 0.
runlock.write(Process.pid.to_s)
+ # flush the file fsync flushes the system buffers
+ # in addition to ruby buffers
+ runlock.fsync
end
# Release the system-wide lock.
def release
if runlock
- runlock.flock(File::LOCK_UN)
+ if Chef::Platform.windows?
+ mutex.release
+ else
+ runlock.flock(File::LOCK_UN)
+ end
runlock.close
# Don't unlink the pid file, if another chef-client was waiting, it
# won't be recreated. Better to leave a "dead" pid file than not have
@@ -89,8 +130,20 @@ class Chef
def reset
@runlock = nil
+ @mutex = nil
end
+ # Since flock mechanism doesn't exist on windows we are using
+ # platform Mutex.
+ # We are creating a "Global" mutex here so that non-admin
+ # users can not DoS chef-client by creating the same named
+ # mutex we are using locally.
+ # Mutex name is case-sensitive contrary to other things in
+ # windows. "\" is the only invalid character.
+ def acquire_win32_mutex
+ @mutex = Chef::ReservedNames::Win32::Mutex.new("Global\\#{runlock_file.gsub(/[\\]/, "/").downcase}")
+ mutex.test
+ end
end
end
diff --git a/lib/chef/server_api.rb b/lib/chef/server_api.rb
new file mode 100644
index 0000000000..e9e7593dd6
--- /dev/null
+++ b/lib/chef/server_api.rb
@@ -0,0 +1,41 @@
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2012 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/http'
+require 'chef/http/authenticator'
+require 'chef/http/cookie_manager'
+require 'chef/http/decompressor'
+require 'chef/http/json_input'
+require 'chef/http/json_output'
+
+class Chef
+ class ServerAPI < Chef::HTTP
+
+ def initialize(url = Chef::Config[:chef_server_url], options = {})
+ options[:client_name] ||= Chef::Config[:node_name]
+ options[:signing_key_filename] ||= Chef::Config[:client_key]
+ super(url, options)
+ end
+
+ use Chef::HTTP::JSONInput
+ use Chef::HTTP::JSONOutput
+ use Chef::HTTP::CookieManager
+ use Chef::HTTP::Decompressor
+ use Chef::HTTP::Authenticator
+ end
+end \ No newline at end of file
diff --git a/lib/chef/shell.rb b/lib/chef/shell.rb
index 4c86f96616..0788962e62 100644
--- a/lib/chef/shell.rb
+++ b/lib/chef/shell.rb
@@ -24,6 +24,7 @@ require 'chef'
require 'chef/version'
require 'chef/client'
require 'chef/config'
+require 'chef/config_fetcher'
require 'chef/shell/shell_session'
require 'chef/shell/ext'
@@ -151,26 +152,9 @@ module Shell
end
def self.parse_json
- # HACK: copied verbatim from chef/application/client, because it's not
- # reusable as written there :(
if Chef::Config[:json_attribs]
- begin
- json_io = open(Chef::Config[:json_attribs])
- rescue SocketError => error
- fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2)
- rescue Errno::ENOENT => error
- fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2)
- rescue Errno::EACCES => error
- fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2)
- rescue Exception => error
- fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2)
- end
-
- begin
- @json_attribs = Chef::JSONCompat.from_json(json_io.read)
- rescue JSON::ParserError => error
- fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2)
- end
+ config_fetcher = Chef::ConfigFetcher.new(Chef::Config[:json_attribs])
+ @json_attribs = config_fetcher.fetch_json
end
end
diff --git a/lib/chef/shell/shell_session.rb b/lib/chef/shell/shell_session.rb
index cf147e778d..2f4d9375eb 100644
--- a/lib/chef/shell/shell_session.rb
+++ b/lib/chef/shell/shell_session.rb
@@ -173,7 +173,7 @@ module Shell
cl = Chef::CookbookLoader.new(Chef::Config[:cookbook_path])
cl.load_cookbooks
cookbook_collection = Chef::CookbookCollection.new(cl)
- @run_context = Chef::RunContext.new(node, cookbook_collection, @events)
+ @run_context = Chef::RunContext.new(node, cookbook_collection, @events)
@run_context.load(Chef::RunList::RunListExpansionFromDisk.new("_default", []))
@run_status.run_context = run_context
end
diff --git a/lib/chef/streaming_cookbook_uploader.rb b/lib/chef/streaming_cookbook_uploader.rb
index df90e0003d..9e638f6367 100644
--- a/lib/chef/streaming_cookbook_uploader.rb
+++ b/lib/chef/streaming_cookbook_uploader.rb
@@ -15,22 +15,23 @@ class Chef
class StreamingCookbookUploader
DefaultHeaders = { 'accept' => 'application/json', 'x-chef-version' => ::Chef::VERSION }
-
+
class << self
def post(to_url, user_id, secret_key_filename, params = {}, headers = {})
make_request(:post, to_url, user_id, secret_key_filename, params, headers)
end
-
+
def put(to_url, user_id, secret_key_filename, params = {}, headers = {})
make_request(:put, to_url, user_id, secret_key_filename, params, headers)
end
-
+
def make_request(http_verb, to_url, user_id, secret_key_filename, params = {}, headers = {})
+ Chef::Log.warn('[DEPRECATED] StreamingCookbookUploader class is deprecated. It will be removed in Chef 12. Please use CookbookSiteStreamingUploader instead.')
boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
parts = []
content_file = nil
-
+
timestamp = Time.now.utc.iso8601
secret_key = OpenSSL::PKey::RSA.new(File.read(secret_key_filename))
@@ -53,31 +54,31 @@ class Chef
end
parts << StringPart.new("--" + boundary + "--\r\n")
end
-
+
body_stream = MultipartStream.new(parts)
-
+
timestamp = Time.now.utc.iso8601
-
+
url = URI.parse(to_url)
-
+
Chef::Log.logger.debug("Signing: method: #{http_verb}, path: #{url.path}, file: #{content_file}, User-id: #{user_id}, Timestamp: #{timestamp}")
-
+
# We use the body for signing the request if the file parameter
- # wasn't a valid file or wasn't included. Extract the body (with
+ # wasn't a valid file or wasn't included. Extract the body (with
# multi-part delimiters intact) to sign the request.
# TODO: tim: 2009-12-28: It'd be nice to remove this special case, and
# always hash the entire request body. In the file case it would just be
# expanded multipart text - the entire body of the POST.
content_body = parts.inject("") { |result,part| result + part.read(0, part.size) }
content_file.rewind if content_file # we consumed the file for the above operation, so rewind it.
-
+
signing_options = {
:http_method=>http_verb,
:path=>url.path,
:user_id=>user_id,
:timestamp=>timestamp}
(content_file && signing_options[:file] = content_file) || (signing_options[:body] = (content_body || ""))
-
+
headers.merge!(Mixlib::Authentication::SignedHeaderAuth.signing_object(signing_options).sign(secret_key))
content_file.rewind if content_file
@@ -90,11 +91,11 @@ class Chef
Net::HTTP::Put.new(url.path, headers)
when :post
Net::HTTP::Post.new(url.path, headers)
- end
+ end
req.content_length = body_stream.size
req.content_type = 'multipart/form-data; boundary=' + boundary unless parts.empty?
req.body_stream = body_stream
-
+
http = Net::HTTP.new(url.host, url.port)
if url.scheme == "https"
http.use_ssl = true
@@ -107,30 +108,31 @@ class Chef
# TODO: stop the following madness!
class << res
alias :to_s :body
-
+
# BUGBUG this makes the response compatible with what respsonse_steps expects to test headers (response.headers[] -> response[])
def headers
self
end
-
+
def status
code.to_i
end
end
res
end
-
+
end
class StreamPart
def initialize(stream, size)
+ Chef::Log.warn('[DEPRECATED] StreamingCookbookUploader::StreamPart class is deprecated. It will be removed in Chef 12. Please use CookbookSiteStreamingUploader::StreamPart instead.')
@stream, @size = stream, size
end
-
+
def size
@size
end
-
+
# read the specified amount from the stream
def read(offset, how_much)
@stream.read(how_much)
@@ -139,9 +141,10 @@ class Chef
class StringPart
def initialize(str)
+ Chef::Log.warn('[DEPRECATED] StreamingCookbookUploader::StringPart class is deprecated. It will be removed in Chef 12. Please use CookbookSiteStreamingUploader::StringPart instead.')
@str = str
end
-
+
def size
@str.length
end
@@ -154,30 +157,31 @@ class Chef
class MultipartStream
def initialize(parts)
+ Chef::Log.warn('[DEPRECATED] StreamingCookbookUploader::MultipartStream class is deprecated. It will be removed in Chef 12. Please use CookbookSiteStreamingUploader::MultipartStream instead.')
@parts = parts
@part_no = 0
@part_offset = 0
end
-
+
def size
@parts.inject(0) {|size, part| size + part.size}
end
-
+
def read(how_much)
return nil if @part_no >= @parts.size
how_much_current_part = @parts[@part_no].size - @part_offset
-
+
how_much_current_part = if how_much_current_part > how_much
how_much
else
how_much_current_part
end
-
+
how_much_next_part = how_much - how_much_current_part
current_part = @parts[@part_no].read(@part_offset, how_much_current_part)
-
+
# recurse into the next part if the current one was not large enough
if how_much_next_part > 0
@part_no += 1
@@ -194,7 +198,7 @@ class Chef
end
end
end
-
+
end
diff --git a/lib/chef/tasks/chef_repo.rake b/lib/chef/tasks/chef_repo.rake
index 6f839a486f..704557ebb3 100644
--- a/lib/chef/tasks/chef_repo.rake
+++ b/lib/chef/tasks/chef_repo.rake
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -51,7 +51,7 @@ task :update do
pull = true if line =~ /\[remote "origin"\]/
end
if pull
- sh %{git pull}
+ sh %{git pull}
else
puts "* Skipping git pull, no origin specified"
end
@@ -86,14 +86,14 @@ end
def create_cookbook(dir)
raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
puts "** Creating cookbook #{ENV["COOKBOOK"]}"
- sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "attributes")}"
- sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "recipes")}"
- sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "definitions")}"
- sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "libraries")}"
- sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "resources")}"
- sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "providers")}"
- sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "files", "default")}"
- sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "templates", "default")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "attributes")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "recipes")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "definitions")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "libraries")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "resources")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "providers")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "files", "default")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "templates", "default")}"
unless File.exists?(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"))
open(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"), "w") do |file|
file.puts <<-EOH
@@ -110,9 +110,9 @@ EOH
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -156,7 +156,7 @@ end
def create_metadata(dir)
raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
puts "** Creating metadata for cookbook: #{ENV["COOKBOOK"]}"
-
+
case NEW_COOKBOOK_LICENSE
when :apachev2
license = "Apache 2.0"
@@ -188,8 +188,8 @@ task :ssl_cert do
fqdn =~ /^(.+?)\.(.+)$/
hostname = $1
domain = $2
- keyfile = fqdn.gsub("*", "wildcard")
raise "Must provide FQDN!" unless fqdn && hostname && domain
+ keyfile = fqdn.gsub("*", "wildcard")
puts "** Creating self signed SSL Certificate for #{fqdn}"
sh("(cd #{CADIR} && openssl genrsa 2048 > #{keyfile}.key)")
sh("(cd #{CADIR} && chmod 644 #{keyfile}.key)")
@@ -288,7 +288,7 @@ namespace :databag do
end
end
else
- puts "ERROR: Could not find any databags, skipping it"
+ puts "ERROR: Could not find any databags, skipping it"
end
end
@@ -327,7 +327,7 @@ EOH
end
else
puts "ERROR: Could not find your databag (#{databag}), skipping it"
- end
+ end
end
end
diff --git a/lib/chef/util/backup.rb b/lib/chef/util/backup.rb
index 95c85d9751..43e3434050 100644
--- a/lib/chef/util/backup.rb
+++ b/lib/chef/util/backup.rb
@@ -47,7 +47,8 @@ class Chef
def backup_filename
@backup_filename ||= begin
time = Time.now
- savetime = time.strftime("%Y%m%d%H%M%S")
+ nanoseconds = sprintf("%6f", time.to_f).split('.')[1]
+ savetime = time.strftime("%Y%m%d%H%M%S.#{nanoseconds}")
backup_filename = "#{path}.chef-#{savetime}"
backup_filename = backup_filename.sub(/^([A-Za-z]:)/, "") #strip drive letter on Windows
end
diff --git a/lib/chef/util/diff.rb b/lib/chef/util/diff.rb
index 6f76a2fabd..7bce52d874 100644
--- a/lib/chef/util/diff.rb
+++ b/lib/chef/util/diff.rb
@@ -14,14 +14,38 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-
-require 'chef/mixin/shell_out'
+# Some portions of this file are derived from material in the diff-lcs
+# project licensed under the terms of the MIT license, provided below.
+#
+# Copyright:: Copyright (c) 2004-2013 Austin Ziegler
+# License:: MIT
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of this Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OF OTHER DEALINGS IN THE
+# SOFTWARE.
+
+require 'diff/lcs'
+require 'diff/lcs/hunk'
class Chef
class Util
class Diff
- include Chef::Mixin::ShellOut
-
# @todo: to_a, to_s, to_json, inspect defs, accessors for @diff and @error
# @todo: move coercion to UTF-8 into to_json
# @todo: replace shellout to diff -u with diff-lcs gem
@@ -58,6 +82,43 @@ class Chef
end
end
end
+
+ # produces a unified-output-format diff with 3 lines of context
+ # ChefFS uses udiff() directly
+ def udiff(old_file, new_file)
+ diff_str = ""
+ file_length_difference = 0
+
+ old_data = IO.readlines(old_file).map { |e| e.chomp }
+ new_data = IO.readlines(new_file).map { |e| e.chomp }
+ diff_data = ::Diff::LCS.diff(old_data, new_data)
+
+ return diff_str if old_data.empty? && new_data.empty?
+ return "No differences encountered\n" if diff_data.empty?
+
+ # write diff header (standard unified format)
+ ft = File.stat(old_file).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z')
+ diff_str << "--- #{old_file}\t#{ft}\n"
+ ft = File.stat(new_file).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z')
+ diff_str << "+++ #{new_file}\t#{ft}\n"
+
+ # loop over diff hunks. if a hunk overlaps with the last hunk,
+ # join them. otherwise, print out the old one.
+ old_hunk = hunk = nil
+ diff_data.each do |piece|
+ begin
+ hunk = ::Diff::LCS::Hunk.new(old_data, new_data, piece, 3, file_length_difference)
+ file_length_difference = hunk.file_length_difference
+ next unless old_hunk
+ next if hunk.merge(old_hunk)
+ diff_str << old_hunk.diff(:unified) << "\n"
+ ensure
+ old_hunk = hunk
+ end
+ end
+ diff_str << old_hunk.diff(:unified) << "\n"
+ return diff_str
+ end
private
@@ -78,13 +139,8 @@ class Chef
return "(new content is binary, diff output suppressed)" if is_binary?(new_file)
begin
- # -u: Unified diff format
- # LC_ALL: in ruby 1.9 we want to set nil which is a magic option to mixlib-shellout to
- # pass through the LC_ALL locale. in ruby 1.8 we force to 7-bit 'C' locale
- # (which is the mixlib-shellout default for all rubies all the time).
Chef::Log.debug("running: diff -u #{old_file} #{new_file}")
- locale = ( Object.const_defined? :Encoding ) ? nil : 'C'
- result = shell_out("diff -u #{old_file} #{new_file}", :env => {'LC_ALL' => locale})
+ diff_str = udiff(old_file, new_file)
rescue Exception => e
# Should *not* receive this, but in some circumstances it seems that
@@ -92,34 +148,14 @@ class Chef
return "Could not determine diff. Error: #{e.message}"
end
- # diff will set a non-zero return code even when there's
- # valid stdout results, if it encounters something unexpected
- # So as long as we have output, we'll show it.
- #
- # Also on some platforms (Solaris) diff outputs a single line
- # when there are no differences found. Look for this line
- # before analyzing diff output.
- if !result.stdout.empty? && result.stdout != "No differences encountered\n"
- if result.stdout.length > diff_output_threshold
+ if !diff_str.empty? && diff_str != "No differences encountered\n"
+ if diff_str.length > diff_output_threshold
return "(long diff of over #{diff_output_threshold} characters, diff output suppressed)"
else
- diff_str = result.stdout
- if Object.const_defined? :Encoding # ruby >= 1.9
- if ( diff_str.encoding == Encoding::ASCII_8BIT &&
- diff_str.encoding != Encoding.default_external &&
- RUBY_VERSION.to_f < 2.0 )
- # @todo mixlib-shellout under ruby 1.9 hands back an ASCII-8BIT encoded string, which needs to
- # be fixed to the default external encoding -- this should be moved into mixlib-shellout
- diff_str = diff_str.force_encoding(Encoding.default_external)
- end
- diff_str.encode!('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
- end
+ diff_str = encode_diff_for_json(diff_str)
@diff = diff_str.split("\n")
- @diff.delete("\\ No newline at end of file")
return "(diff available)"
end
- elsif !result.stderr.empty?
- return "Could not determine diff. Error: #{result.stderr}"
else
return "(no diff)"
end
@@ -139,6 +175,13 @@ class Chef
end
end
+ def encode_diff_for_json(diff_str)
+ if Object.const_defined? :Encoding
+ diff_str.encode!('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
+ end
+ return diff_str
+ end
+
end
end
end
diff --git a/lib/chef/util/windows.rb b/lib/chef/util/windows.rb
index cba2c2a1b7..777fe4adbb 100644
--- a/lib/chef/util/windows.rb
+++ b/lib/chef/util/windows.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/util/windows/net_group.rb b/lib/chef/util/windows/net_group.rb
index 9da0dc6557..817e47efa8 100644
--- a/lib/chef/util/windows/net_group.rb
+++ b/lib/chef/util/windows/net_group.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/util/windows/net_use.rb b/lib/chef/util/windows/net_use.rb
index 1979e095bd..37efc02fcc 100644
--- a/lib/chef/util/windows/net_use.rb
+++ b/lib/chef/util/windows/net_use.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/lib/chef/util/windows/net_user.rb b/lib/chef/util/windows/net_user.rb
index eb68f6cebc..5cca348c8e 100644
--- a/lib/chef/util/windows/net_user.rb
+++ b/lib/chef/util/windows/net_user.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -198,7 +198,7 @@ class Chef::Util::Windows::NetUser < Chef::Util::Windows
def enable_account
user_modify do |user|
user[:flags] &= ~UF_ACCOUNTDISABLE
- #This does not set the password to nil. It (for some reason) means to ignore updating the field.
+ #This does not set the password to nil. It (for some reason) means to ignore updating the field.
#See similar behavior for the logon_hours field documented at
#http://msdn.microsoft.com/en-us/library/windows/desktop/aa371338%28v=vs.85%29.aspx
user[:password] = nil
diff --git a/lib/chef/util/windows/volume.rb b/lib/chef/util/windows/volume.rb
index dff082e929..08c3a53793 100644
--- a/lib/chef/util/windows/volume.rb
+++ b/lib/chef/util/windows/volume.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -35,7 +35,7 @@ class Chef::Util::Windows::Volume < Chef::Util::Windows
name += "\\" unless name =~ /\\$/ #trailing slash required
@name = name
end
-
+
def device
buffer = 0.chr * 256
if GetVolumeNameForVolumeMountPoint(@name, buffer, buffer.size)
diff --git a/lib/chef/version.rb b/lib/chef/version.rb
index 70a22f7d27..259c267035 100644
--- a/lib/chef/version.rb
+++ b/lib/chef/version.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,7 @@
class Chef
CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
- VERSION = '11.6.0.hotfix.1'
+ VERSION = '11.8.0.alpha.0'
end
# NOTE: the Chef::Version class is defined in version_class.rb
diff --git a/lib/chef/win32/api/file.rb b/lib/chef/win32/api/file.rb
index afa746efce..7a8dafd8b5 100644
--- a/lib/chef/win32/api/file.rb
+++ b/lib/chef/win32/api/file.rb
@@ -474,7 +474,7 @@ BOOL WINAPI DeviceIoControl(
# Workaround for CHEF-4419:
# Make sure paths starting with "/" has a drive letter
# assigned from the current working diretory.
- # Note: In chef 11.8 and beyond this issue will be fixed with a
+ # Note: With CHEF-4427 this issue will be fixed with a
# broader fix to map all the paths starting with "/" to
# SYSTEM_DRIVE on windows.
path = ::File.expand_path(path) if path.start_with? "/"
diff --git a/lib/chef/win32/api/synchronization.rb b/lib/chef/win32/api/synchronization.rb
new file mode 100644
index 0000000000..9c148d7e2b
--- /dev/null
+++ b/lib/chef/win32/api/synchronization.rb
@@ -0,0 +1,89 @@
+#
+# Author:: Serdar Sutay (<serdar@opscode.com>)
+# Copyright:: Copyright 2011 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/win32/api'
+
+class Chef
+ module ReservedNames::Win32
+ module API
+ module Synchronization
+ extend Chef::ReservedNames::Win32::API
+
+ ffi_lib 'kernel32'
+
+ # Constant synchronization functions use to indicate wait
+ # forever.
+ INFINITE = 0xFFFFFFFF
+
+ # Return codes
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
+ WAIT_FAILED = 0xFFFFFFFF
+ WAIT_TIMEOUT = 0x00000102
+ WAIT_OBJECT_0 = 0x00000000
+ WAIT_ABANDONED = 0x00000080
+
+ # Security and access rights for synchronization objects
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/ms686670(v=vs.85).aspx
+ DELETE = 0x00010000
+ READ_CONTROL = 0x00020000
+ SYNCHRONIZE = 0x00100000
+ WRITE_DAC = 0x00040000
+ WRITE_OWNER = 0x00080000
+
+ # Mutex specific rights
+ MUTEX_ALL_ACCESS = 0x001F0001
+ MUTEX_MODIFY_STATE = 0x00000001
+
+=begin
+HANDLE WINAPI CreateMutex(
+ _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
+ _In_ BOOL bInitialOwner,
+ _In_opt_ LPCTSTR lpName
+);
+=end
+ safe_attach_function :CreateMutexW, [ :LPSECURITY_ATTRIBUTES, :BOOL, :LPCTSTR ], :HANDLE
+ safe_attach_function :CreateMutexA, [ :LPSECURITY_ATTRIBUTES, :BOOL, :LPCTSTR ], :HANDLE
+
+=begin
+DWORD WINAPI WaitForSingleObject(
+ _In_ HANDLE hHandle,
+ _In_ DWORD dwMilliseconds
+);
+=end
+ safe_attach_function :WaitForSingleObject, [ :HANDLE, :DWORD ], :DWORD
+
+=begin
+BOOL WINAPI ReleaseMutex(
+ _In_ HANDLE hMutex
+);
+=end
+ safe_attach_function :ReleaseMutex, [ :HANDLE ], :BOOL
+
+=begin
+HANDLE WINAPI OpenMutex(
+ _In_ DWORD dwDesiredAccess,
+ _In_ BOOL bInheritHandle,
+ _In_ LPCTSTR lpName
+);
+=end
+ safe_attach_function :OpenMutexW, [ :DWORD, :BOOL, :LPCTSTR ], :HANDLE
+ safe_attach_function :OpenMutexA, [ :DWORD, :BOOL, :LPCTSTR ], :HANDLE
+ end
+ end
+ end
+end
diff --git a/lib/chef/win32/handle.rb b/lib/chef/win32/handle.rb
index 3e92703db9..21a8fdf339 100644
--- a/lib/chef/win32/handle.rb
+++ b/lib/chef/win32/handle.rb
@@ -29,7 +29,7 @@ class Chef
# See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx
# The handle value returned by the GetCurrentProcess function is the pseudo handle (HANDLE)-1 (which is 0xFFFFFFFF)
CURRENT_PROCESS_HANDLE = 4294967295
-
+
def initialize(handle)
@handle = handle
ObjectSpace.define_finalizer(self, Handle.close_handle_finalizer(handle))
diff --git a/lib/chef/win32/mutex.rb b/lib/chef/win32/mutex.rb
new file mode 100644
index 0000000000..b0a9ba210e
--- /dev/null
+++ b/lib/chef/win32/mutex.rb
@@ -0,0 +1,94 @@
+#
+# Author:: Serdar Sutay (<serdar@opscode.com>)
+# Copyright:: Copyright 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/win32/api/synchronization'
+
+class Chef
+ module ReservedNames::Win32
+ class Mutex
+ include Chef::ReservedNames::Win32::API::Synchronization
+ extend Chef::ReservedNames::Win32::API::Synchronization
+
+ def initialize(name)
+ @name = name
+ # First check if there exists a mutex in the system with the
+ # given name.
+
+ # In the initial creation of the mutex initial_owner is set to
+ # false so that mutex will not be acquired until someone calls
+ # acquire.
+ # In order to call "*W" windows apis, strings needs to be
+ # encoded as wide strings.
+ @handle = CreateMutexW(nil, false, name.to_wstring)
+
+ # Fail early if we can't get a handle to the named mutex
+ if @handle == 0
+ Chef::Log.error("Failed to create system mutex with name'#{name}'")
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ end
+
+ attr_reader :handle
+ attr_reader :name
+
+ #####################################################
+ # Attempts to grab the mutex.
+ # Returns true if the mutex is grabbed or if it's already
+ # owned; false otherwise.
+ def test
+ WaitForSingleObject(handle, 0) == WAIT_OBJECT_0
+ end
+
+ #####################################################
+ # Attempts to grab the mutex and waits until it is acquired.
+ def wait
+ wait_result = WaitForSingleObject(handle, INFINITE)
+ case wait_result
+ when WAIT_ABANDONED
+ # Previous owner of the mutex died before it can release the
+ # mutex. Log a warning and continue.
+ Chef::Log.debug "Existing owner of the mutex exited prematurely."
+ when WAIT_OBJECT_0
+ # Mutex is successfully acquired.
+ else
+ Chef::Log.error("Failed to acquire system mutex '#{name}'. Return code: #{wait_result}")
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ end
+
+ #####################################################
+ # Releaes the mutex
+ def release
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685066(v=vs.85).aspx
+ # Note that release method needs to be called more than once
+ # if mutex is acquired more than once.
+ unless ReleaseMutex(handle)
+ # Don't fail things in here if we can't release the mutex.
+ # Because it will be automatically released when the owner
+ # of the process goes away and this class is only being used
+ # to synchronize chef-clients runs on a node.
+ Chef::Log.error("Can not release mutex '#{name}'. This might cause issues \
+if the mutex is attempted to be acquired by other threads.")
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ end
+ end
+ end
+end
+
+
diff --git a/lib/chef/win32/security/ace.rb b/lib/chef/win32/security/ace.rb
index efd44b1c85..3aeae35532 100644
--- a/lib/chef/win32/security/ace.rb
+++ b/lib/chef/win32/security/ace.rb
@@ -122,4 +122,4 @@ class Chef
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/chef/win32/security/sid.rb b/lib/chef/win32/security/sid.rb
index 7ca21eee79..e1b20224bb 100644
--- a/lib/chef/win32/security/sid.rb
+++ b/lib/chef/win32/security/sid.rb
@@ -196,4 +196,4 @@ class Chef
end
end
end
-end \ No newline at end of file
+end
diff --git a/lib/chef/win32/version.rb b/lib/chef/win32/version.rb
index c8c923a6f2..62f817503e 100644
--- a/lib/chef/win32/version.rb
+++ b/lib/chef/win32/version.rb
@@ -30,14 +30,16 @@ class Chef
# http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx
private
-
+
def self.get_system_metrics(n_index)
Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(n_index)
end
public
-
+
WIN_VERSIONS = {
+ "Windows 8.1" => {:major => 6, :minor => 3, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
+ "Windows Server 2012 R2" => {:major => 6, :minor => 3, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows 8" => {:major => 6, :minor => 2, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
"Windows Server 2012" => {:major => 6, :minor => 2, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows 7" => {:major => 6, :minor => 1, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
@@ -68,7 +70,7 @@ class Chef
# The get_product_info API is not supported on Win2k3,
# use an alternative to identify datacenter skus
@sku = get_datacenter_product_info_windows_server_2003(ver_info)
- end
+ end
end
marketing_names = Array.new
diff --git a/spec/data/bootstrap/no_proxy.erb b/spec/data/bootstrap/no_proxy.erb
new file mode 100644
index 0000000000..6945704386
--- /dev/null
+++ b/spec/data/bootstrap/no_proxy.erb
@@ -0,0 +1,2 @@
+bash -c '
+<%= config_content %>'
diff --git a/spec/data/cookbooks/openldap/metadata.rb b/spec/data/cookbooks/openldap/metadata.rb
new file mode 100644
index 0000000000..ab0dface9d
--- /dev/null
+++ b/spec/data/cookbooks/openldap/metadata.rb
@@ -0,0 +1,8 @@
+name "openldap"
+maintainer "Opscode, Inc."
+maintainer_email "cookbooks@opscode.com"
+license "Apache 2.0"
+description "Installs and configures all aspects of openldap using Debian style symlinks with helper definitions"
+long_description "The long description for the openldap cookbook from metadata.rb"
+version "8.9.10"
+recipe "openldap", "Main Open LDAP configuration"
diff --git a/spec/data/cookbooks/preseed/files/default/preseed-template.seed b/spec/data/cookbooks/preseed/files/default/preseed-template.seed
new file mode 100644
index 0000000000..011bc40f1b
--- /dev/null
+++ b/spec/data/cookbooks/preseed/files/default/preseed-template.seed
@@ -0,0 +1,4 @@
+# This file should never be executed by the preseeding tests
+# This is here to verify that templates are preferred over cookbook_files when
+# preseeding packages.
+chef-integration-test chef-integration-test/sample-var string "WRONG-cookbook file used instead of template!"
diff --git a/spec/data/trusted_certs/example.crt b/spec/data/trusted_certs/example.crt
new file mode 100644
index 0000000000..832aebe2ec
--- /dev/null
+++ b/spec/data/trusted_certs/example.crt
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDkjCCAnoCCQDihI8kxGYTFTANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMRAwDgYDVQQKEwdZb3VD
+b3JwMRMwEQYDVQQLEwpPcGVyYXRpb25zMRYwFAYDVQQDEw1leGFtcGxlLmxvY2Fs
+MR0wGwYJKoZIhvcNAQkBFg5tZUBleGFtcGxlLmNvbTAeFw0xMzEwMTcxODAxMzVa
+Fw0yMzEwMTUxODAxMzVaMIGKMQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAO
+BgNVBAcTB1NlYXR0bGUxEDAOBgNVBAoTB1lvdUNvcnAxEzARBgNVBAsTCk9wZXJh
+dGlvbnMxFjAUBgNVBAMTDWV4YW1wbGUubG9jYWwxHTAbBgkqhkiG9w0BCQEWDm1l
+QGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyKBo
+U+Bdni0xZK/NCzdLdi2X+TyW5eahbYMx+r1GDcVqCICvrthBCVLVFsQ8rvOHwTPi
+AxQJGxb9TLSXRgXQSlH6FLjIUceuOtpan3qYVJ1v7AxY4DgNvYBpbtJz5MQedJnT
+g2F+rXzkwaD6CWBqWHeGU0oP3r7bq1AMD6XEsK2w2/zHtG7TEnL45ARv1PsyrU5M
+ZAW/XyoMyq1k2Lpv7YR5kAvTq1+4RSt/it2RFE7R0AVbaQ0MeAnllfySiHHHlaOT
+FVd/qPSiGISxsUmmzA3Z08+0sfJwkrnJXbLscCBYndd7gMGgtczGjJtul0Ch3GFa
+/Pn5McjwF272+usJ1wIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCzPePWifWNECsG
+nL8on1AtFMkczE1/pdRS4YUl/Tc926MpezptSja8rL31+4Bom37/wYPG7HygtAQl
+R4FHpAtuqJKPOfjUmDNsIXRFnytrnflTpctDu/Nbj4PDCy01k/sTDUQt+s+lEBL8
+M8ArmfLZ8PCfAwnXmJQ5rggDFKqegjt6z1RsSglbMiASE7+KkpBnzaqH6fET6IQz
+WgAjv6WdRfwgfJjOTSX4XMpCSet9KaWmXExKrxiVng2Uu6E+ShVAyKaGMuc1B7VA
+oxnnVaVapFv5lOWucQr4KkC7EgaUZnyt8duOc8+Yvd+y3Xd2dcHUnmegRxly4jRV
+/lXbFAUb
+-----END CERTIFICATE-----
diff --git a/spec/data/trusted_certs/intermediate.pem b/spec/data/trusted_certs/intermediate.pem
new file mode 100644
index 0000000000..78148b0fcf
--- /dev/null
+++ b/spec/data/trusted_certs/intermediate.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEjzCCA3egAwIBAgIQBp4dt3/PHfupevXlyaJANzANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEgxCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxIjAgBgNVBAMTGURpZ2lDZXJ0IFNlY3Vy
+ZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7V+Qh
+qdWbYDd+jqFhf4HiGsJ1ZNmRUAvkNkQkbjDSm3on+sJqrmpwCTi5IArIZRBKiKwx
+8tyS8mOhXYBjWYCSIxzm73ZKUDXJ2HE4ue3w5kKu0zgmeTD5IpTG26Y/QXiQ2N5c
+fml9+JAVOtChoL76srIZodgr0c6/a91Jq6OS/rWryME+7gEA2KlEuEJziMNh9atK
+gygK0tRJ+mqxzd9XLJTl4sqDX7e6YlwvaKXwwLn9K9HpH9gaYhW9/z2m98vv5ttl
+LyU47PvmIGZYljQZ0hXOIdMkzNkUb9j+Vcfnb7YPGoxJvinyulqagSY3JG/XSBJs
+Lln1nBi72fZo4t9FAgMBAAGjggFaMIIBVjASBgNVHRMBAf8ECDAGAQH/AgEAMA4G
+A1UdDwEB/wQEAwIBhjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6
+Ly9vY3NwLmRpZ2ljZXJ0LmNvbTB7BgNVHR8EdDByMDegNaAzhjFodHRwOi8vY3Js
+My5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3JsMDegNaAzhjFo
+dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3Js
+MD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k
+aWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBSQcds363PI79zVHhK2NLorWqCmkjAf
+BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTANBgkqhkiG9w0BAQUFAAOC
+AQEAMM7RlVEArgYLoQ4CwBestn+PIPZAdXQczHixpE/q9NDEnaLegQcmH0CIUfAf
+z7dMQJnQ9DxxmHOIlywZ126Ej6QfnFog41FcsMWemWpPyGn3EP9OrRnZyVizM64M
+2ZYpnnGycGOjtpkWQh1l8/egHn3F1GUUsmKE1GxcCAzYbJMrtHZZitF//wPYwl24
+LyLWOPD2nGt9RuuZdPfrSg6ppgTre87wXGuYMVqYQOtpxAX0IKjKCDplbDgV9Vws
+slXkLGtB8L5cRspKKaBIXiDSRf8F3jSvcEuBOeLKB1d8tjHcISnivpcOd5AUUUDh
+v+PMGxmcJcqnBrJT3yOyzxIZow==
+-----END CERTIFICATE-----
diff --git a/spec/data/trusted_certs/opscode.pem b/spec/data/trusted_certs/opscode.pem
new file mode 100644
index 0000000000..d7d211c9da
--- /dev/null
+++ b/spec/data/trusted_certs/opscode.pem
@@ -0,0 +1,38 @@
+-----BEGIN CERTIFICATE-----
+MIIGqjCCBZKgAwIBAgIQCJlQhNSTz1z3zHZb972KvDANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSIwIAYDVQQDExlE
+aWdpQ2VydCBTZWN1cmUgU2VydmVyIENBMB4XDTEzMDQxMjAwMDAwMFoXDTE0MDYx
+NjEyMDAwMFowYzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
+BgNVBAcTB1NlYXR0bGUxFTATBgNVBAoTDE9wc2NvZGUsIEluYzEWMBQGA1UEAwwN
+Ki5vcHNjb2RlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+U
+HLAzObPRlmchlkJ2JFeReJRPXj5F27HuX8SXT+5WhVGunQf1swjASJ0utk1x9wGT
+f9tnF8fYiwJIqWJopaPiwzNw1cD6CnIfhM3z4T3EzLAWWu2ZhfuaQk9Z6jhItkm7
+upO4CsFq1xw7IjqOq09PCAklYC/Y/8Qq5Qj8VoTp0ldVv6hbqTNkezhWcKU/07si
+jAX1O+DYN6dlVNezfl4Xt5ccsu8Mp0s92IMVYLgY6bpb1b91ez9+XBE1v7zjaR0V
+EP7Ix9av/pXjqMqHgjlsg46UpLa30f4FEi2xmXpCBpOP94rCrT7g+u8UlIrJ/QK/
+/lHyKBpCm0R9ftDbppsCAwEAAaOCA3MwggNvMB8GA1UdIwQYMBaAFJBx2zfrc8jv
+3NUeErY0uitaoKaSMB0GA1UdDgQWBBTdhCU7MvQblxtWHlfHG4jPUTuh5DBLBgNV
+HREERDBCgg0qLm9wc2NvZGUuY29tggtvcHNjb2RlLmNvbYIQY29ycC5vcHNjb2Rl
+LmNvbYISKi5jb3JwLm9wc2NvZGUuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE
+FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwYQYDVR0fBFowWDAqoCigJoYkaHR0cDov
+L2NybDMuZGlnaWNlcnQuY29tL3NzY2EtZzEuY3JsMCqgKKAmhiRodHRwOi8vY3Js
+NC5kaWdpY2VydC5jb20vc3NjYS1nMS5jcmwwggHEBgNVHSAEggG7MIIBtzCCAbMG
+CWCGSAGG/WwBATCCAaQwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQu
+Y29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0wggFkBggrBgEFBQcCAjCCAVYeggFS
+AEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABpAGYAaQBj
+AGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBu
+AGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQ
+AFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQAeQAg
+AEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0ACAAbABp
+AGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwByAHAAbwBy
+AGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBl
+AC4weAYIKwYBBQUHAQEEbDBqMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
+Y2VydC5jb20wQgYIKwYBBQUHMAKGNmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv
+bS9EaWdpQ2VydFNlY3VyZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqG
+SIb3DQEBBQUAA4IBAQCNk1+7l+VlAZrKov7ugP7WuKS7IEUZRk8CVAFPtIrp+jFB
+6W0ta1qMpYyItp5enTBCGOkTfPly06hZnFRQw3ZnkSsWDKIvCRks4kZt3oHLd3nO
+G671JGRJI/qbs6F5l6c96kotlZkolYIPMhyK8Ex4LjMW6UrPWdpJrXTWPvLq4c85
+ZaN52yKu6tsLrBTPwPmK9t+zQ2drb1g8Eq9B+cuwD3Row6njsDQ1Ltry+KCnivki
+E/ptgwyCkS4brkhjHMz5l5Co0KMsHylAb2XcBxFVFSl0aJIqK5Gr0nTlg26pNG7O
+qxv6ncOHl3tmArETi36TQbTYvFc+6cNb8CqdWe95
+-----END CERTIFICATE-----
diff --git a/spec/data/trusted_certs/root.pem b/spec/data/trusted_certs/root.pem
new file mode 100644
index 0000000000..fd4341df26
--- /dev/null
+++ b/spec/data/trusted_certs/root.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
diff --git a/spec/functional/assets/PkgA.1.0.0.0.bff b/spec/functional/assets/PkgA.1.0.0.0.bff
new file mode 100644
index 0000000000..b157d080e8
--- /dev/null
+++ b/spec/functional/assets/PkgA.1.0.0.0.bff
Binary files differ
diff --git a/spec/functional/assets/PkgA.2.0.0.0.bff b/spec/functional/assets/PkgA.2.0.0.0.bff
new file mode 100644
index 0000000000..0afe7b7f12
--- /dev/null
+++ b/spec/functional/assets/PkgA.2.0.0.0.bff
Binary files differ
diff --git a/spec/functional/assets/dummy-1-0.aix6.1.noarch.rpm b/spec/functional/assets/dummy-1-0.aix6.1.noarch.rpm
new file mode 100644
index 0000000000..1c6f129a9a
--- /dev/null
+++ b/spec/functional/assets/dummy-1-0.aix6.1.noarch.rpm
Binary files differ
diff --git a/spec/functional/assets/dummy-2-0.aix6.1.noarch.rpm b/spec/functional/assets/dummy-2-0.aix6.1.noarch.rpm
new file mode 100644
index 0000000000..650b7dd9ba
--- /dev/null
+++ b/spec/functional/assets/dummy-2-0.aix6.1.noarch.rpm
Binary files differ
diff --git a/spec/functional/assets/mytest-1.0-1.noarch.rpm b/spec/functional/assets/mytest-1.0-1.noarch.rpm
new file mode 100644
index 0000000000..07334a0cc7
--- /dev/null
+++ b/spec/functional/assets/mytest-1.0-1.noarch.rpm
Binary files differ
diff --git a/spec/functional/assets/mytest-2.0-1.noarch.rpm b/spec/functional/assets/mytest-2.0-1.noarch.rpm
new file mode 100644
index 0000000000..7e7ba17839
--- /dev/null
+++ b/spec/functional/assets/mytest-2.0-1.noarch.rpm
Binary files differ
diff --git a/spec/functional/knife/cookbook_delete_spec.rb b/spec/functional/knife/cookbook_delete_spec.rb
index ef38cb2e1f..2d52fb91a3 100644
--- a/spec/functional/knife/cookbook_delete_spec.rb
+++ b/spec/functional/knife/cookbook_delete_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,8 +21,6 @@ require 'tiny_server'
describe Chef::Knife::CookbookDelete do
before(:all) do
- @original_config = Chef::Config.hash_dup
-
@server = TinyServer::Manager.new
@server.start
end
@@ -38,11 +36,10 @@ describe Chef::Knife::CookbookDelete do
end
after(:all) do
- Chef::Config.configuration = @original_config
@server.stop
end
- context "when the the cookbook doesn't exist" do
+ context "when the cookbook doesn't exist" do
before do
@log_output = StringIO.new
@@ -97,7 +94,7 @@ describe Chef::Knife::CookbookDelete do
stdout.string.should match(/#{Regexp.escape('Are you sure you want to purge files')}/)
stdout.string.should match(/#{Regexp.escape('Do you really want to delete obsolete-cookbook version 1.0.0? (Y/N)')}/)
cb100_deleted.should be_true
-
+
end
end
diff --git a/spec/functional/knife/exec_spec.rb b/spec/functional/knife/exec_spec.rb
index 1bccbdeb7a..455160fd5c 100644
--- a/spec/functional/knife/exec_spec.rb
+++ b/spec/functional/knife/exec_spec.rb
@@ -21,8 +21,6 @@ require 'tiny_server'
describe Chef::Knife::Exec do
before(:all) do
- @original_config = Chef::Config.hash_dup
-
@server = TinyServer::Manager.new#(:debug => true)
@server.start
end
@@ -40,7 +38,6 @@ describe Chef::Knife::Exec do
end
after(:all) do
- Chef::Config.configuration = @original_config
@server.stop
end
diff --git a/spec/functional/knife/ssh_spec.rb b/spec/functional/knife/ssh_spec.rb
index a853e8de19..fd8cfe0f7e 100644
--- a/spec/functional/knife/ssh_spec.rb
+++ b/spec/functional/knife/ssh_spec.rb
@@ -22,16 +22,12 @@ require 'tiny_server'
describe Chef::Knife::Ssh do
before(:all) do
- @original_config = Chef::Config.hash_dup
- @original_knife_config = Chef::Config[:knife].dup
Chef::Knife::Ssh.load_deps
@server = TinyServer::Manager.new
@server.start
end
after(:all) do
- Chef::Config.configuration = @original_config
- Chef::Config[:knife] = @original_knife_config
@server.stop
end
@@ -153,9 +149,9 @@ describe Chef::Knife::Ssh do
Chef::Config[:knife][:ssh_user] = nil
end
- it "uses the default" do
+ it "uses the default (current user)" do
@knife.run
- @knife.config[:ssh_user].should == "root"
+ @knife.config[:ssh_user].should == nil
end
end
end
diff --git a/spec/functional/resource/base.rb b/spec/functional/resource/base.rb
new file mode 100644
index 0000000000..13438c1759
--- /dev/null
+++ b/spec/functional/resource/base.rb
@@ -0,0 +1,41 @@
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+
+def ohai
+ # provider is platform-dependent, we need platform ohai data:
+ @OHAI_SYSTEM ||= begin
+ ohai = Ohai::System.new
+ ohai.require_plugin("os")
+ ohai.require_plugin("platform")
+ ohai.require_plugin("passwd")
+ ohai
+ end
+end
+
+def run_context
+ @run_context ||= begin
+ node = Chef::Node.new
+ node.default[:platform] = ohai[:platform]
+ node.default[:platform_version] = ohai[:platform_version]
+ events = Chef::EventDispatch::Dispatcher.new
+ Chef::RunContext.new(node, {}, events)
+ end
+end
+
diff --git a/spec/functional/resource/batch_spec.rb b/spec/functional/resource/batch_spec.rb
index 7f7125a91e..baa01ee5d9 100644
--- a/spec/functional/resource/batch_spec.rb
+++ b/spec/functional/resource/batch_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,47 +18,20 @@
require 'spec_helper'
-shared_context Chef::Resource::WindowsScript do
- before(:all) do
-
- ohai_reader = Ohai::System.new
- ohai_reader.require_plugin("os")
- ohai_reader.require_plugin("windows::platform")
-
- new_node = Chef::Node.new
- new_node.consume_external_attrs(ohai_reader.data,{})
-
- events = Chef::EventDispatch::Dispatcher.new
-
- @run_context = Chef::RunContext.new(new_node, {}, events)
- end
-
- let(:script_output_path) do
- File.join(Dir.tmpdir, make_tmpname("windows_script_test"))
- end
-
- before(:each) do
-k File.delete(script_output_path) if File.exists?(script_output_path)
- end
-
- after(:each) do
- File.delete(script_output_path) if File.exists?(script_output_path)
- end
-end
-
describe Chef::Resource::WindowsScript::Batch, :windows_only do
+ include_context Chef::Resource::WindowsScript
+
let(:script_content) { "whoami" }
let!(:resource) do
Chef::Resource::WindowsScript::Batch.new("Batch resource functional test", @run_context)
end
- context "when the run action is invoked on Windows" do
- include_context Chef::Resource::WindowsScript
+ describe "when the run action is invoked on Windows" do
it "executes the script code" do
resource.code(script_content + " > #{script_output_path}")
resource.returns(0)
resource.run_action(:run)
end
- end
+ end
end
diff --git a/spec/functional/resource/bff_spec.rb b/spec/functional/resource/bff_spec.rb
new file mode 100644
index 0000000000..5e7cb8a168
--- /dev/null
+++ b/spec/functional/resource/bff_spec.rb
@@ -0,0 +1,122 @@
+#
+# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'functional/resource/base'
+require 'chef/mixin/shell_out'
+
+# Run the test only for AIX platform.
+describe Chef::Resource::BffPackage, :external => ohai[:platform] != 'aix' do
+ include Chef::Mixin::ShellOut
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::BffPackage.new(@pkg_name, run_context)
+ new_resource.source @pkg_path
+ new_resource
+ end
+
+ def bff_pkg_should_be_installed(resource)
+ expect(shell_out("lslpp -L #{resource.name}").exitstatus).to eq(0)
+ ::File.exists?("/usr/PkgA/bin/acommand")
+ end
+
+ def bff_pkg_should_be_removed(resource)
+ expect(shell_out("lslpp -L #{resource.name}").exitstatus).to eq(1)
+ !::File.exists?("/usr/PkgA/bin/acommand")
+ end
+
+
+ before(:all) do
+ @pkg_name = "PkgA.rte"
+ @pkg_path = "/tmp/PkgA.1.0.0.0.bff"
+ FileUtils.cp 'spec/functional/assets/PkgA.1.0.0.0.bff' , @pkg_path
+ end
+
+ after(:all) do
+ FileUtils.rm @pkg_path
+ end
+
+ context "package install action" do
+ it "should install a package" do
+ new_resource.run_action(:install)
+ bff_pkg_should_be_installed(new_resource)
+ end
+
+ after(:each) do
+ shell_out("installp -u #{@pkg_name}")
+ end
+ end
+
+ context "package install action with options" do
+ it "should install a package" do
+ new_resource.options("-e/tmp/installp.log")
+ new_resource.run_action(:install)
+ bff_pkg_should_be_installed(new_resource)
+ end
+
+ after(:each) do
+ shell_out("installp -u #{@pkg_name}")
+ FileUtils.rm "/tmp/installp.log"
+ end
+ end
+
+ context "package upgrade action" do
+ before(:each) do
+ shell_out("installp -aYF -d #{@pkg_path} #{@pkg_name}")
+ @pkg_path = "/tmp/PkgA.2.0.0.0.bff"
+ FileUtils.cp 'spec/functional/assets/PkgA.2.0.0.0.bff' , @pkg_path
+ end
+
+ it "should upgrade package" do
+ new_resource.run_action(:install)
+ bff_pkg_should_be_installed(new_resource)
+ end
+
+ after(:each) do
+ shell_out("installp -u #{@pkg_name}")
+ FileUtils.rm @pkg_path
+ end
+ end
+
+ context "package remove action" do
+ before(:each) do
+ shell_out("installp -aYF -d #{@pkg_path} #{@pkg_name}")
+ end
+
+ it "should remove an installed package" do
+ new_resource.run_action(:remove)
+ bff_pkg_should_be_removed(new_resource)
+ end
+ end
+
+ context "package remove action with options" do
+ before(:each) do
+ shell_out("installp -aYF -d #{@pkg_path} #{@pkg_name}")
+ end
+
+ it "should remove an installed package" do
+ new_resource.options("-e/tmp/installp.log")
+ new_resource.run_action(:remove)
+ bff_pkg_should_be_removed(new_resource)
+ end
+
+ after(:each) do
+ FileUtils.rm "/tmp/installp.log"
+ end
+ end
+end
+
diff --git a/spec/functional/resource/cron_spec.rb b/spec/functional/resource/cron_spec.rb
new file mode 100644
index 0000000000..4c20023d78
--- /dev/null
+++ b/spec/functional/resource/cron_spec.rb
@@ -0,0 +1,147 @@
+# encoding: UTF-8
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'functional/resource/base'
+require 'chef/mixin/shell_out'
+
+describe Chef::Resource::Cron, :requires_root, :unix_only do
+
+ include Chef::Mixin::ShellOut
+
+ # Platform specific validation routines.
+ def cron_should_exists(cron_name, command)
+ case ohai[:platform]
+ when "aix", "solaris", "opensolaris", "solaris2", "omnios"
+ expect(shell_out("crontab -l #{new_resource.user} | grep \"#{cron_name}\"").exitstatus).to eq(0)
+ expect(shell_out("crontab -l #{new_resource.user} | grep \"#{command}\"").exitstatus).to eq(0)
+ else
+ expect(shell_out("crontab -l -u #{new_resource.user} | grep \"#{cron_name}\"").exitstatus).to eq(0)
+ expect(shell_out("crontab -l -u #{new_resource.user} | grep \"#{command}\"").exitstatus).to eq(0)
+ end
+ end
+
+ def cron_should_not_exists(cron_name)
+ case ohai[:platform]
+ when "aix", "solaris", "opensolaris", "solaris2", "omnios"
+ expect(shell_out("crontab -l #{new_resource.user} | grep \"#{cron_name}\"").exitstatus).to eq(1)
+ else
+ expect(shell_out("crontab -l -u #{new_resource.user} | grep \"#{cron_name}\"").exitstatus).to eq(1)
+ end
+ end
+
+ # Actual tests
+ let(:new_resource) do
+ new_resource = Chef::Resource::Cron.new("Chef functional test cron", run_context)
+ new_resource.user 'root'
+ new_resource.minute "30"
+ new_resource.command "/bin/true"
+ new_resource
+ end
+
+ let(:provider) do
+ provider = new_resource.provider_for_action(new_resource.action)
+ provider
+ end
+
+ describe "create action" do
+ after do
+ new_resource.run_action(:delete)
+ end
+
+ it "should create a crontab entry" do
+ new_resource.run_action(:create)
+ cron_should_exists(new_resource.name, new_resource.command)
+ end
+ end
+
+ describe "delete action" do
+ before do
+ new_resource.run_action(:create)
+ end
+
+ it "should delete a crontab entry" do
+ # Note that test cron is created by previous test
+ new_resource.run_action(:delete)
+
+ cron_should_not_exists(new_resource.name)
+ end
+ end
+
+ exclude_solaris = ["solaris", "opensolaris", "solaris2", "omnios"].include?(ohai[:platform])
+ describe "create action with various attributes", :external => exclude_solaris do
+ def create_and_validate_with_attribute(resource, attribute, value)
+ if ohai[:platform] == 'aix'
+ expect {resource.run_action(:create)}.to raise_error(Chef::Exceptions::Cron, /Aix cron entry does not support environment variables. Please set them in script and use script in cron./)
+ else
+ resource.run_action(:create)
+ # Verify if the cron is created successfully
+ cron_attribute_should_exists(resource.name, attribute, value)
+ end
+ end
+
+ def cron_attribute_should_exists(cron_name, attribute, value)
+ return if ['aix', 'solaris'].include?(ohai[:platform])
+ # Test if the attribute exists on newly created cron
+ cron_should_exists(cron_name, "")
+ expect(shell_out("crontab -l -u #{new_resource.user} | grep \"#{attribute.upcase}=#{value}\"").exitstatus).to eq(0)
+ end
+
+ after do
+ new_resource.run_action(:delete)
+ end
+
+ it "should create a crontab entry for mailto attribute" do
+ new_resource.mailto "cheftest@example.com"
+ create_and_validate_with_attribute(new_resource, "mailto", "cheftest@example.com")
+ end
+
+ it "should create a crontab entry for path attribute" do
+ new_resource.path "/usr/local/bin"
+ create_and_validate_with_attribute(new_resource, "path", "/usr/local/bin")
+ end
+
+ it "should create a crontab entry for shell attribute" do
+ new_resource.shell "/bin/bash"
+ create_and_validate_with_attribute(new_resource, "shell", "/bin/bash")
+ end
+
+ it "should create a crontab entry for home attribute" do
+ new_resource.home "/home/opscode"
+ create_and_validate_with_attribute(new_resource, "home", "/home/opscode")
+ end
+ end
+
+ describe "negative tests for create action" do
+ def cron_create_should_raise_exception
+ expect { new_resource.run_action(:create) }.to raise_error(Chef::Exceptions::Cron, /Error updating state of #{new_resource.name}, exit: 1/)
+ cron_should_not_exists(new_resource.name)
+ end
+
+ it "should not create cron with invalid minute" do
+ new_resource.minute "invalid"
+ cron_create_should_raise_exception
+ end
+
+ it "should not create cron with invalid user" do
+ new_resource.user "1-really-really-invalid-user-name"
+ cron_create_should_raise_exception
+ end
+
+ end
+end
diff --git a/spec/functional/resource/group_spec.rb b/spec/functional/resource/group_spec.rb
new file mode 100644
index 0000000000..2c9a568979
--- /dev/null
+++ b/spec/functional/resource/group_spec.rb
@@ -0,0 +1,204 @@
+#
+# Author:: Chirag Jog (<chirag@clogeny.com>)
+# Author:: Siddheshwar More (<siddheshwar.more@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+require 'functional/resource/base'
+
+describe Chef::Resource::Group, :requires_root_or_running_windows do
+
+ def group_should_exist(resource)
+ case ohai[:platform_family]
+ when "debian", "fedora", "rhel", "suse", "gentoo", "slackware", "arch"
+ expect { Etc::getgrnam(resource.name) }.to_not raise_error(ArgumentError, "can't find group for #{resource.name}")
+ expect(resource.name).to eq(Etc::getgrnam(resource.name).name)
+ when "windows"
+ expect { Chef::Util::Windows::NetGroup.new(resource.group_name).local_get_members }.to_not raise_error(ArgumentError, "The group name could not be found.")
+ end
+ end
+
+ def user_exist_in_group?(resource, user)
+ case ohai[:platform_family]
+ when "debian", "fedora", "rhel", "suse", "gentoo", "slackware", "arch"
+ Etc::getgrnam(resource.name).mem.include?(user)
+ when "windows"
+ Chef::Util::Windows::NetGroup.new(resource.group_name).local_get_members.include?(user)
+ end
+ end
+
+ def group_should_not_exist(resource)
+ case ohai[:platform_family]
+ when "debian", "fedora", "rhel", "suse", "gentoo", "slackware", "arch"
+ expect { Etc::getgrnam(resource.name) }.to raise_error(ArgumentError, "can't find group for #{resource.name}")
+ when "windows"
+ expect { Chef::Util::Windows::NetGroup.new(resource.group_name).local_get_members }.to raise_error(ArgumentError, "The group name could not be found.")
+ end
+ end
+
+ def compare_gid(resource, gid)
+ return resource.gid == Etc::getgrnam(resource.name).gid if unix?
+ end
+
+ def get_user_resource(username)
+ usr = Chef::Resource::User.new("#{username}", run_context)
+ usr.password("Jetsream123!")
+ usr
+ end
+
+ def create_user(username)
+ get_user_resource(username).run_action(:create)
+ end
+
+ def remove_user(username)
+ get_user_resource(username).run_action(:remove)
+ end
+
+ before do
+ @grp_resource = Chef::Resource::Group.new("test-group-#{SecureRandom.random_number(9999)}", run_context)
+ end
+
+ context "group create action" do
+ after(:each) do
+ @grp_resource.run_action(:remove)
+ end
+
+ it "create a group" do
+ @grp_resource.run_action(:create)
+ group_should_exist(@grp_resource)
+ end
+
+ context "group name with 256 characters", :windows_only do
+ before(:each) do
+ grp_name = "theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestree"
+ @new_grp = Chef::Resource::Group.new(grp_name, run_context)
+ end
+ after do
+ @new_grp.run_action(:remove)
+ end
+ it " create a group" do
+ @new_grp.run_action(:create)
+ group_should_exist(@new_grp)
+ end
+ end
+ context "group name with more than 256 characters", :windows_only do
+ before(:each) do
+ grp_name = "theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQQQQQQQQQQQQ"
+ @new_grp = Chef::Resource::Group.new(grp_name, run_context)
+ end
+ it " not create a group" do
+ expect { @new_grp.run_action(:create) }.to raise_error
+ group_should_not_exist(@new_grp)
+ end
+ end
+ end
+
+ context "group remove action" do
+ before(:each) do
+ @grp_resource.run_action(:create)
+ end
+
+ it "remove a group" do
+ @grp_resource.run_action(:remove)
+ group_should_not_exist(@grp_resource)
+ end
+ end
+
+ context "group modify action", :unsupported_group_provider_platform do
+ before(:each) do
+ @grp_resource.run_action(:create)
+ end
+
+ after(:each) do
+ @grp_resource.run_action(:remove)
+ end
+
+ it "add user to group" do
+ user1 = "user1-#{SecureRandom.random_number(9999)}"
+ user2 = "user2-#{SecureRandom.random_number(9999)}"
+
+ create_user(user1)
+ @grp_resource.members(user1)
+ expect(user_exist_in_group?(@grp_resource, user1)).to be_false
+ @grp_resource.run_action(:modify)
+ group_should_exist(@grp_resource)
+ expect(user_exist_in_group?(@grp_resource, user1)).to be_true
+
+ create_user(user2)
+ expect(user_exist_in_group?(@grp_resource, user2)).to be_false
+ @grp_resource.members(user2)
+ @grp_resource.run_action(:modify)
+ group_should_exist(@grp_resource)
+
+ #default append is false, so modify action remove old member user1 from group and add new member user2
+ expect(user_exist_in_group?(@grp_resource, user1)).to be_false
+ expect(user_exist_in_group?(@grp_resource, user2)).to be_true
+ remove_user(user1)
+ remove_user(user2)
+ end
+
+
+ it "append user to a group" do
+ user1 = "user1-#{SecureRandom.random_number(9999)}"
+ user2 = "user2-#{SecureRandom.random_number(9999)}"
+ create_user(user1)
+ @grp_resource.members(user1)
+ expect(user_exist_in_group?(@grp_resource, user1)).to be_false
+ #default append attribute is false
+ @grp_resource.run_action(:modify)
+ group_should_exist(@grp_resource)
+ expect(user_exist_in_group?(@grp_resource, user1)).to be_true
+ #set append attribute to true
+ @grp_resource.append(true)
+ create_user(user2)
+ expect(user_exist_in_group?(@grp_resource, user2)).to be_false
+ @grp_resource.members(user2)
+ @grp_resource.run_action(:modify)
+ group_should_exist(@grp_resource)
+ expect(user_exist_in_group?(@grp_resource, user1)).to be_true
+ expect(user_exist_in_group?(@grp_resource, user2)).to be_true
+ remove_user(user1)
+ remove_user(user2)
+ end
+
+ it "raise error on add non-existent user to group" do
+ user1 = "user1-#{SecureRandom.random_number(9999)}"
+ @grp_resource.members(user1)
+ @grp_resource.append(true)
+ expect(user_exist_in_group?(@grp_resource, user1)).to be_false
+ expect { @grp_resource.run_action(:modify) }.to raise_error
+ end
+ end
+
+ context "group manage action", :unix_only, :unsupported_group_provider_platform do
+ before(:each) do
+ @grp_resource.run_action(:create)
+ end
+
+ after(:each) do
+ @grp_resource.run_action(:remove)
+ end
+
+ it "change gid of the group" do
+ grp_id = 1234567890
+ @grp_resource.gid(grp_id)
+ @grp_resource.run_action(:manage)
+ group_should_exist(@grp_resource)
+ expect(compare_gid(@grp_resource, grp_id)).to be_true
+ end
+ end
+end
diff --git a/spec/functional/resource/ifconfig_spec.rb b/spec/functional/resource/ifconfig_spec.rb
new file mode 100644
index 0000000000..c36288498b
--- /dev/null
+++ b/spec/functional/resource/ifconfig_spec.rb
@@ -0,0 +1,163 @@
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'functional/resource/base'
+require 'chef/mixin/shell_out'
+
+# run this test only for following platforms.
+include_flag = !(['ubuntu', 'centos', 'aix'].include?(ohai[:platform]))
+
+describe Chef::Resource::Ifconfig, :requires_root, :external => include_flag do
+ include Chef::Mixin::ShellOut
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::Ifconfig.new('10.10.0.1', run_context)
+ new_resource
+ end
+
+ let(:provider) do
+ provider = new_resource.provider_for_action(new_resource.action)
+ provider
+ end
+
+ let(:current_resource) do
+ provider.load_current_resource
+ end
+
+ def lo_interface_for_test
+ # use loopback interface for tests
+ case ohai[:platform]
+ when "aix"
+ 'lo0'
+ else
+ 'lo'
+ end
+ end
+
+ # **Caution: any updates to core interfaces can be risky.
+ def en0_interface_for_test
+ case ohai[:platform]
+ when "aix"
+ 'en0'
+ else
+ 'eth0'
+ end
+ end
+
+ def network_interface_alias(interface)
+ case ohai[:platform]
+ when "aix"
+ interface
+ else
+ interface + ":10"
+ end
+ end
+
+ # platform specific test setup and validation routines
+
+ def setup_add_interface(resource)
+ resource.device network_interface_alias(en0_interface_for_test)
+ end
+
+ def setup_enable_interface(resource)
+ resource.device network_interface_alias(en0_interface_for_test)
+ end
+
+ def interface_should_exists(interface)
+ expect(shell_out("ifconfig #{@interface} | grep 10.10.0.1").exitstatus).to eq(0)
+ end
+
+ def interface_should_not_exists(interface)
+ expect(shell_out("ifconfig #{@interface} | grep 10.10.0.1").exitstatus).to eq(1)
+ end
+
+ def interface_persistence_should_exists(interface)
+ case ohai[:platform]
+ when "aix"
+ expect(shell_out("lsattr -E -l #{@interface} | grep 10.10.0.1").exitstatus).to eq(0)
+ else
+ end
+ end
+
+ def interface_persistence_should_not_exists(interface)
+ case ohai[:platform]
+ when "aix"
+ expect(shell_out("lsattr -E -l #{@interface} | grep 10.10.0.1").exitstatus).to eq(1)
+ else
+ end
+ end
+
+ # Actual tests
+
+ describe "#load_current_resource" do
+ it 'should load given interface' do
+ new_resource.device lo_interface_for_test
+ expect(current_resource.device).to eql(lo_interface_for_test)
+ expect(current_resource.inet_addr).to match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)
+ end
+ end
+
+ exclude_test = ohai[:platform] != 'ubuntu'
+ describe "#action_add", :external => exclude_test do
+ after do
+ new_resource.run_action(:delete)
+ end
+ it "should add interface (vip)" do
+ setup_add_interface(new_resource)
+ new_resource.run_action(:add)
+ interface_should_exists(network_interface_alias(en0_interface_for_test))
+ interface_persistence_should_exists(network_interface_alias(en0_interface_for_test))
+ end
+ end
+
+ describe "#action_enable", :external => exclude_test do
+ after do
+ new_resource.run_action(:disable)
+ end
+ it "should enable interface (vip)" do
+ setup_enable_interface(new_resource)
+ new_resource.run_action(:enable)
+ interface_should_exists(network_interface_alias(en0_interface_for_test))
+ end
+ end
+
+ describe "#action_disable", :external => exclude_test do
+ before do
+ setup_enable_interface(new_resource)
+ new_resource.run_action(:enable)
+ end
+ it "should disable interface (vip)" do
+ new_resource.run_action(:disable)
+ new_resource.should be_updated_by_last_action
+ interface_should_not_exists(network_interface_alias(en0_interface_for_test))
+ end
+ end
+
+ describe "#action_delete", :external => exclude_test do
+ before do
+ setup_add_interface(new_resource)
+ new_resource.run_action(:add)
+ end
+ it "should delete interface (vip)" do
+ new_resource.run_action(:delete)
+ new_resource.should be_updated_by_last_action
+ interface_should_not_exists(network_interface_alias(en0_interface_for_test))
+ interface_persistence_should_not_exists(network_interface_alias(en0_interface_for_test))
+ end
+ end
+end
diff --git a/spec/functional/resource/link_spec.rb b/spec/functional/resource/link_spec.rb
index fd13353bad..36bc858a74 100644
--- a/spec/functional/resource/link_spec.rb
+++ b/spec/functional/resource/link_spec.rb
@@ -340,7 +340,7 @@ describe Chef::Resource::Link do
it 'create errors out' do
if windows?
lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
- elsif os_x? or solaris? or freebsd?
+ elsif os_x? or solaris? or freebsd? or aix?
lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
else
lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
@@ -502,7 +502,7 @@ describe Chef::Resource::Link do
it 'errors out' do
if windows?
lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
- elsif os_x? or solaris? or freebsd?
+ elsif os_x? or solaris? or freebsd? or aix?
lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
else
lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
@@ -554,7 +554,7 @@ describe Chef::Resource::Link do
resource.run_action(:create)
File.exists?(target_file).should be_true
# OS X gets angry about this sort of link. Bug in OS X, IMO.
- pending('OS X/FreeBSD symlink? and readlink working on hard links to symlinks', :if => (os_x? or freebsd?)) do
+ pending('OS X/FreeBSD/AIX symlink? and readlink working on hard links to symlinks', :if => (os_x? or freebsd? or aix?)) do
symlink?(target_file).should be_true
readlink(target_file).should == canonicalize(@other_target)
end
@@ -571,7 +571,7 @@ describe Chef::Resource::Link do
end
context 'and the link does not yet exist' do
it 'links to the target file' do
- pending('OS X/FreeBSD fails to create hardlinks to broken symlinks', :if => (os_x? or freebsd?)) do
+ pending('OS X/FreeBSD/AIX fails to create hardlinks to broken symlinks', :if => (os_x? or freebsd? or aix?)) do
resource.run_action(:create)
# Windows and Unix have different definitions of exists? here, and that's OK.
if windows?
diff --git a/spec/functional/resource/mount_spec.rb b/spec/functional/resource/mount_spec.rb
new file mode 100644
index 0000000000..199ccbd37e
--- /dev/null
+++ b/spec/functional/resource/mount_spec.rb
@@ -0,0 +1,207 @@
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'functional/resource/base'
+require 'chef/mixin/shell_out'
+require 'tmpdir'
+
+# run this test only for following platforms.
+include_flag = !(['ubuntu', 'centos', 'aix'].include?(ohai[:platform]))
+
+describe Chef::Resource::Mount, :requires_root, :external => include_flag do
+
+ include Chef::Mixin::ShellOut
+
+ # Platform specific setup, cleanup and validation helpers.
+
+ def setup_device_for_mount
+ # use ramdisk for creating a test device for mount.
+ # This can cleaner if we have chef resource/provider for ramdisk.
+ case ohai[:platform]
+ when "aix"
+ ramdisk = shell_out!("mkramdisk 16M").stdout
+
+ # identify device, for /dev/rramdisk0 it is /dev/ramdisk0
+ device = ramdisk.tr("\n","").gsub(/\/rramdisk/, '/ramdisk')
+
+ fstype = "jfs2"
+ shell_out!("mkfs -V #{fstype} #{device}")
+ when "ubuntu", "centos"
+ device = "/dev/ram1"
+ shell_out("ls -1 /dev/ram*").stdout.each_line do |d|
+ if shell_out("mount | grep #{d}").exitstatus == "1"
+ # this device is not mounted, so use it.
+ device = d
+ break
+ end
+ end
+ fstype = "tmpfs"
+ shell_out!("mkfs -q #{device} 512")
+ else
+ end
+ [device, fstype]
+ end
+
+ def cleanup_device(device)
+ case ohai[:platform]
+ when "aix"
+ ramdisk = device.gsub(/\/ramdisk/, '/rramdisk')
+ shell_out("rmramdisk #{ramdisk}")
+ else
+ end
+ end
+
+ def cleanup_mount(mount_point)
+ shell_out("umount #{mount_point}")
+ end
+
+ # platform specific validations.
+ def mount_should_exists(mount_point, device, fstype = nil, options = nil)
+ validation_cmd = "mount | grep #{mount_point} | grep #{device} "
+ validation_cmd << " | grep #{fstype} " unless fstype.nil?
+ validation_cmd << " | grep #{options.join(',')} " unless options.nil? || options.empty?
+ puts "validation_cmd = #{validation_cmd}"
+ expect(shell_out(validation_cmd).exitstatus).to eq(0)
+ end
+
+ def mount_should_not_exists(mount_point)
+ shell_out("mount").stdout.should_not include(mount_point)
+ end
+
+ def unix_mount_config_file
+ case ohai[:platform]
+ when 'aix'
+ mount_config = "/etc/filesystems"
+ else
+ mount_config = "/etc/fstab"
+ end
+ end
+
+ def mount_should_be_enabled(mount_point, device)
+ case ohai[:platform]
+ when 'aix'
+ expect(shell_out("cat #{unix_mount_config_file} | grep \"#{mount_point}:\" ").exitstatus).to eq(0)
+ else
+ expect(shell_out("cat #{unix_mount_config_file} | grep \"#{mount_point}\" | grep \"#{device}\" ").exitstatus).to eq(0)
+ end
+ end
+
+ def mount_should_be_disabled(mount_point)
+ shell_out("cat #{unix_mount_config_file}").stdout.should_not include("#{mount_point}:")
+ end
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::Mount.new(@mount_point, run_context)
+ new_resource.device @device
+ new_resource.name @mount_point
+ new_resource.fstype @fstype
+ new_resource.options "log=NULL" if ohai[:platform] == 'aix'
+ new_resource
+ end
+
+ let(:provider) do
+ provider = new_resource.provider_for_action(new_resource.action)
+ provider
+ end
+
+ def current_resource
+ provider.load_current_resource
+ provider.current_resource
+ end
+
+ # Actual tests begin here.
+ before(:all) do
+ @device, @fstype = setup_device_for_mount
+
+ @mount_point = Dir.mktmpdir("testmount")
+
+ # Make sure all the potentially leaked mounts are cleared up
+ shell_out("mount").stdout.each_line do |line|
+ if line.include? "testmount"
+ line.split(" ").each do |section|
+ cleanup_mount(section) if section.include? "testmount"
+ end
+ end
+ end
+
+ end
+
+ after(:all) do
+ Dir.rmdir(@mount_point)
+ cleanup_device(@device)
+ end
+
+ after(:each) do
+ cleanup_mount(new_resource.mount_point)
+ end
+
+ describe "when the target state is a mounted filesystem" do
+ it "should mount the filesystem if it isn't mounted" do
+ current_resource.enabled.should be_false
+ current_resource.mounted.should be_false
+ new_resource.run_action(:mount)
+ new_resource.should be_updated
+ mount_should_exists(new_resource.mount_point, new_resource.device)
+ end
+
+ end
+
+ describe "when the filesystem should be remounted and the resource supports remounting" do
+ it "should remount the filesystem if it is mounted" do
+ new_resource.run_action(:mount)
+ mount_should_exists(new_resource.mount_point, new_resource.device)
+
+ new_resource.supports[:remount] = true
+ new_resource.options "rw,log=NULL" if ohai[:platform] == 'aix'
+ new_resource.run_action(:remount)
+
+ mount_should_exists(new_resource.mount_point, new_resource.device, nil, (ohai[:platform] == 'aix') ? new_resource.options : nil)
+ end
+ end
+
+ describe "when the target state is a unmounted filesystem" do
+ it "should umount the filesystem if it is mounted" do
+ new_resource.run_action(:mount)
+ mount_should_exists(new_resource.mount_point, new_resource.device)
+
+ new_resource.run_action(:umount)
+ mount_should_not_exists(new_resource.mount_point)
+ end
+ end
+
+ describe "when enabling the filesystem to be mounted" do
+ after do
+ new_resource.run_action(:disable)
+ end
+
+ it "should enable the mount if it isn't enable" do
+ new_resource.run_action(:mount)
+ new_resource.run_action(:enable)
+ mount_should_be_enabled(new_resource.mount_point, new_resource.device)
+ end
+ end
+
+ describe "when the target state is to disable the mount" do
+ it "should disable the mount if it is enabled" do
+ new_resource.run_action(:mount)
+ new_resource.run_action(:enable)
+ new_resource.run_action(:disable)
+ mount_should_be_disabled(new_resource.mount_point)
+ end
+ end
+end
diff --git a/spec/functional/resource/package_spec.rb b/spec/functional/resource/package_spec.rb
index b5f8e5dc66..55011271b5 100644
--- a/spec/functional/resource/package_spec.rb
+++ b/spec/functional/resource/package_spec.rb
@@ -95,15 +95,6 @@ metadata = { :unix_only => true,
describe Chef::Resource::Package, metadata do
include Chef::Mixin::ShellOut
- def chef_test_dpkg_installed?
- shell_out("dpkg -l chef-integration-test").status.success?
- end
-
- def dpkg_should_be_installed(pkg_name)
- shell_out!("dpkg -l #{pkg_name}")
- end
-
-
context "with a remote package source" do
include AptServer
@@ -166,11 +157,6 @@ describe Chef::Resource::Package, metadata do
base_resource
end
- # it "results in a usable apt server" do
- # shell_out!("apt-get install -q -y --force-yes chef-integration-test ", :env => { "DEBIAN_FRONTEND" => "noninteractive" })
- # shell_out!("dpkg -l chef-integration-test")
- # end
-
context "when the package is not yet installed" do
it "installs the package with action :install" do
package_resource.run_action(:install)
@@ -206,7 +192,7 @@ describe Chef::Resource::Package, metadata do
it "raises a reasonable error for action :install" do
expect do
package_resource.run_action(:install)
- end.to raise_error(Chef::Exceptions::Exec)
+ end.to raise_error(Mixlib::ShellOut::ShellCommandFailed)
end
end
@@ -216,7 +202,6 @@ describe Chef::Resource::Package, metadata do
let(:file_cache_path) { Dir.mktmpdir }
before do
- @old_config = Chef::Config.configuration.dup
Chef::Config[:file_cache_path] = file_cache_path
debconf_reset = 'chef-integration-test chef-integration-test/sample-var string "INVALID"'
shell_out!("echo #{debconf_reset} |debconf-set-selections")
@@ -224,7 +209,6 @@ describe Chef::Resource::Package, metadata do
after do
FileUtils.rm_rf(file_cache_path)
- Chef::Config.configuration = @old_config
end
context "with a preseed file" do
@@ -267,6 +251,10 @@ describe Chef::Resource::Package, metadata do
context "with a preseed template" do
+ # NOTE: in the fixtures, there is also a cookbook_file named
+ # "preseed-template.seed". This implicitly tests that templates are
+ # preferred over cookbook_files when both are present.
+
let(:package_resource) do
r = base_resource
r.cookbook_name = "preseed"
@@ -286,8 +274,98 @@ describe Chef::Resource::Package, metadata do
end
end
+ end # installing w/ preseed
+ end # when package not installed
+ context "and the desired version of the package is installed" do
+
+ before do
+ v_1_1_package = File.expand_path("apt/chef-integration-test_1.1-1_amd64.deb", CHEF_SPEC_DATA)
+ shell_out!("dpkg -i #{v_1_1_package}")
+ end
+
+ it "does nothing for action :install" do
+ package_resource.run_action(:install)
+ shell_out!("dpkg -l chef-integration-test", :returns => [0])
+ package_resource.should_not be_updated_by_last_action
end
+
+ it "does nothing for action :upgrade" do
+ package_resource.run_action(:upgrade)
+ shell_out!("dpkg -l chef-integration-test", :returns => [0])
+ package_resource.should_not be_updated_by_last_action
+ end
+
+ # Verify that the package is removed by running `dpkg -l PACKAGE`
+ # On Ubuntu 12.10 and newer, the command exits 1.
+ #
+ # On Ubuntu 12.04 and older, the `dpkg -l` command will exit 0 and
+ # display a package status message like this:
+ #
+ # Desired=Unknown/Install/Remove/Purge/Hold
+ # | Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
+ # |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
+ # ||/ Name Version Description
+ # +++-=================================-=========================================-============================================
+ # un chef-integration-test <none> (no description available)
+ def pkg_should_be_removed
+ # will raise if exit code != 0,1
+ pkg_check = shell_out!("dpkg -l chef-integration-test", :returns => [0,1])
+
+ if pkg_check.exitstatus == 0
+ pkg_check.stdout.should =~ /un[\s]+chef-integration-test/
+ end
+ end
+
+
+ it "removes the package for action :remove" do
+ package_resource.run_action(:remove)
+ pkg_should_be_removed
+ package_resource.should be_updated_by_last_action
+ end
+
+ it "removes the package for action :purge" do
+ package_resource.run_action(:purge)
+ pkg_should_be_removed
+ package_resource.should be_updated_by_last_action
+ end
+
+ end
+
+ context "and an older version of the package is installed" do
+ before do
+ v_1_0_package = File.expand_path("apt/chef-integration-test_1.0-1_amd64.deb", CHEF_SPEC_DATA)
+ shell_out!("dpkg -i #{v_1_0_package}")
+ end
+
+ it "does nothing for action :install" do
+ package_resource.run_action(:install)
+ shell_out!("dpkg -l chef-integration-test", :returns => [0])
+ package_resource.should_not be_updated_by_last_action
+ end
+
+ it "upgrades the package for action :upgrade" do
+ package_resource.run_action(:upgrade)
+ dpkg_l = shell_out!("dpkg -l chef-integration-test", :returns => [0])
+ dpkg_l.stdout.should =~ /chef\-integration\-test[\s]+1\.1\-1/
+ package_resource.should be_updated_by_last_action
+ end
+
+ context "and the resource specifies the new version" do
+ let(:package_resource) do
+ r = base_resource
+ r.version("1.1-1")
+ r
+ end
+
+ it "upgrades the package for action :install" do
+ package_resource.run_action(:install)
+ dpkg_l = shell_out!("dpkg -l chef-integration-test", :returns => [0])
+ dpkg_l.stdout.should =~ /chef\-integration\-test[\s]+1\.1\-1/
+ package_resource.should be_updated_by_last_action
+ end
+ end
+
end
end
diff --git a/spec/functional/resource/powershell_spec.rb b/spec/functional/resource/powershell_spec.rb
index 4d31eb3ef1..6bd3b3c1e5 100644
--- a/spec/functional/resource/powershell_spec.rb
+++ b/spec/functional/resource/powershell_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,11 +17,10 @@
#
require 'spec_helper'
-require 'functional/resource/batch_spec.rb'
describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
- include_context Chef::Resource::WindowsScript
+ include_context Chef::Resource::WindowsScript
let(:successful_executable_script_content) { "#{ENV['SystemRoot']}\\system32\\attrib.exe $env:systemroot" }
let(:failed_executable_script_content) { "#{ENV['SystemRoot']}\\system32\\attrib.exe /badargument" }
@@ -36,7 +35,7 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
let(:arbitrary_nonzero_process_exit_code) { 4193 }
let(:arbitrary_nonzero_process_exit_code_content) { "exit #{arbitrary_nonzero_process_exit_code}" }
let(:invalid_powershell_interpreter_flag) { "/thisflagisinvalid" }
- let(:valid_powershell_interpreter_flag) { "-Sta" }
+ let(:valid_powershell_interpreter_flag) { "-Sta" }
let!(:resource) do
r = Chef::Resource::WindowsScript::PowershellScript.new("Powershell resource functional test", @run_context)
r.code(successful_executable_script_content)
@@ -53,31 +52,31 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
it "returns the process exit code" do
resource.code(arbitrary_nonzero_process_exit_code_content)
resource.returns(arbitrary_nonzero_process_exit_code)
- resource.run_action(:run)
+ resource.run_action(:run)
end
it "returns 0 if the last command was a cmdlet that succeeded" do
resource.code(cmdlet_exit_code_success_content)
resource.returns(0)
- resource.run_action(:run)
+ resource.run_action(:run)
end
it "returns 0 if the last command was a cmdlet that succeeded and was preceded by a non-cmdlet Windows binary that failed" do
resource.code([windows_process_exit_code_not_found_content, cmdlet_exit_code_success_content].join(';'))
resource.returns(0)
- resource.run_action(:run)
+ resource.run_action(:run)
end
-
+
it "returns 1 if the last command was a cmdlet that failed" do
resource.code(cmdlet_exit_code_not_found_content)
resource.returns(1)
- resource.run_action(:run)
+ resource.run_action(:run)
end
it "returns 1 if the last command was a cmdlet that failed and was preceded by a successfully executed non-cmdlet Windows binary" do
resource.code([windows_process_exit_code_success_content, cmdlet_exit_code_not_found_content].join(';'))
resource.returns(1)
- resource.run_action(:run)
+ resource.run_action(:run)
end
# This somewhat ambiguous case, two failures of different types,
@@ -91,34 +90,34 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
it "returns 1 if the last command was a cmdlet that failed and was preceded by an unsuccessfully executed non-cmdlet Windows binary" do
resource.code([arbitrary_nonzero_process_exit_code_content,cmdlet_exit_code_not_found_content].join(';'))
resource.returns(arbitrary_nonzero_process_exit_code)
- resource.run_action(:run)
+ resource.run_action(:run)
end
it "returns 0 if the last command was a non-cmdlet Windows binary that succeeded and was preceded by a failed cmdlet" do
resource.code([cmdlet_exit_code_success_content, arbitrary_nonzero_process_exit_code_content].join(';'))
resource.returns(arbitrary_nonzero_process_exit_code)
- resource.run_action(:run)
+ resource.run_action(:run)
end
-
+
it "returns a specific error code if the last command was a non-cmdlet Windows binary that failed and was preceded by cmdlet that succeeded" do
resource.code([cmdlet_exit_code_success_content, arbitrary_nonzero_process_exit_code_content].join(';'))
resource.returns(arbitrary_nonzero_process_exit_code)
- resource.run_action(:run)
+ resource.run_action(:run)
end
it "returns a specific error code if the last command was a non-cmdlet Windows binary that failed and was preceded by cmdlet that failed" do
resource.code([cmdlet_exit_code_not_found_content, arbitrary_nonzero_process_exit_code_content].join(';'))
resource.returns(arbitrary_nonzero_process_exit_code)
- resource.run_action(:run)
+ resource.run_action(:run)
end
-
+
it "executes a script with a 64-bit process on a 64-bit OS, otherwise a 32-bit process" do
resource.code(processor_architecture_script_content + " | out-file -encoding ASCII #{script_output_path}")
resource.returns(0)
resource.run_action(:run)
is_64_bit = (ENV['PROCESSOR_ARCHITECTURE'] == 'AMD64') || (ENV['PROCESSOR_ARCHITEW6432'] == 'AMD64')
-
+
detected_64_bit = source_contains_case_insensitive_content?( get_script_output, 'AMD64' )
is_64_bit.should == detected_64_bit
@@ -128,15 +127,15 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
resource.code(cmdlet_exit_code_success_content)
resource.flags(invalid_powershell_interpreter_flag)
resource.returns(1)
- resource.run_action(:run)
+ resource.run_action(:run)
end
it "returns 0 if a valid flag is passed to the interpreter" do
resource.code(cmdlet_exit_code_success_content)
resource.flags(valid_powershell_interpreter_flag)
resource.returns(0)
- resource.run_action(:run)
- end
+ resource.run_action(:run)
+ end
end
context "when running on a 32-bit version of Windows", :windows32_only do
@@ -167,7 +166,7 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
source_contains_case_insensitive_content?( get_script_output, 'AMD64' ).should == true
end
-
+
it "executes a script with a 32-bit process if :i386 arch is specified" do
resource.code(processor_architecture_script_content + " | out-file -encoding ASCII #{script_output_path}")
resource.architecture(:i386)
diff --git a/spec/functional/resource/registry_spec.rb b/spec/functional/resource/registry_spec.rb
index fa52640eb7..8f3cfa9a8a 100644
--- a/spec/functional/resource/registry_spec.rb
+++ b/spec/functional/resource/registry_spec.rb
@@ -104,8 +104,6 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource = Chef::Resource::RegistryKey.new(resource_name, @run_context)
@registry = Chef::Win32::Registry.new(@run_context)
- @current_whyrun = Chef::Config[:why_run]
-
reset_registry
end
@@ -259,12 +257,9 @@ describe Chef::Resource::RegistryKey, :windows_only do
end
context "while running in whyrun mode" do
- before (:all) do
+ before (:each) do
Chef::Config[:why_run] = true
end
- after (:all) do
- Chef::Config[:why_run] = @current_whyrun
- end
it "does not throw an exception if the keys do not exist but recursive is set to false" do
@new_resource.key(reg_child + '\Slitheen\Raxicoricofallapatorius')
@@ -373,12 +368,9 @@ describe Chef::Resource::RegistryKey, :windows_only do
end
context "while running in whyrun mode" do
- before (:all) do
+ before (:each) do
Chef::Config[:why_run] = true
end
- after (:all) do
- Chef::Config[:why_run] = @current_whyrun
- end
it "does not throw an exception if the keys do not exist but recursive is set to false" do
@new_resource.key(reg_child + '\Zygons\Zygor')
@@ -469,12 +461,9 @@ describe Chef::Resource::RegistryKey, :windows_only do
end
context "while running in whyrun mode" do
- before (:all) do
+ before (:each) do
Chef::Config[:why_run] = true
end
- after (:all) do
- Chef::Config[:why_run] = @current_whyrun
- end
it "does nothing if the action is delete" do
@new_resource.key(reg_parent + '\OpscodeWhyRun')
@new_resource.values([{:name=>"BriskWalk",:type=>:string,:data=>"is good for health"}])
@@ -510,7 +499,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@registry.key_exists?(reg_parent + '\OpscodeTest').should == false
end
- it "raises an exception if the the key has subkeys and recursive == false" do
+ it "raises an exception if the key has subkeys and recursive == false" do
@new_resource.key(reg_parent)
@new_resource.recursive(false)
lambda{@new_resource.run_action(:delete_key)}.should raise_error(Chef::Exceptions::Win32RegNoRecursive)
@@ -549,12 +538,9 @@ describe Chef::Resource::RegistryKey, :windows_only do
@report["total_res_count"].should == "1"
end
context "while running in whyrun mode" do
- before (:all) do
+ before (:each) do
Chef::Config[:why_run] = true
end
- after (:all) do
- Chef::Config[:why_run] = @current_whyrun
- end
it "does not throw an exception if the key has subkeys but recursive is set to false" do
@new_resource.key(reg_parent + '\OpscodeWhyRun')
diff --git a/spec/functional/resource/rpm_spec.rb b/spec/functional/resource/rpm_spec.rb
new file mode 100644
index 0000000000..7825377c6b
--- /dev/null
+++ b/spec/functional/resource/rpm_spec.rb
@@ -0,0 +1,122 @@
+#
+# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'functional/resource/base'
+require 'chef/mixin/shell_out'
+
+# run this test only for following platforms.
+exclude_test = !['aix', 'centos', 'redhat', 'suse'].include?(ohai[:platform])
+describe Chef::Resource::RpmPackage, :requires_root, :external => exclude_test do
+ include Chef::Mixin::ShellOut
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::RpmPackage.new(@pkg_name, run_context)
+ new_resource.source @pkg_path
+ new_resource
+ end
+
+ def rpm_pkg_should_be_installed(resource)
+ case ohai[:platform]
+ # Due to dependency issues , different rpm pkgs are used in different platforms.
+ # dummy rpm package works in aix, without any dependency issues.
+ when "aix"
+ expect(shell_out("rpm -qa | grep dummy").exitstatus).to eq(0)
+ # mytest rpm package works in centos, redhat and in suse without any dependency issues.
+ when "centos", "redhat", "suse"
+ expect(shell_out("rpm -qa | grep mytest").exitstatus).to eq(0)
+ ::File.exists?("/opt/mytest/mytest.sh") # The mytest rpm package contains the mytest.sh file
+ end
+ end
+
+ def rpm_pkg_should_not_be_installed(resource)
+ case ohai[:platform]
+ when "aix"
+ expect(shell_out("rpm -qa | grep dummy").exitstatus).to eq(1)
+ when "centos", "redhat", "suse"
+ expect(shell_out("rpm -qa | grep mytest").exitstatus).to eq(1)
+ !::File.exists?("/opt/mytest/mytest.sh")
+ end
+ end
+
+ before(:all) do
+ case ohai[:platform]
+ # Due to dependency issues , different rpm pkgs are used in different platforms.
+ when "aix"
+ @pkg_name = "dummy"
+ @pkg_version = "1-0"
+ @pkg_path = "/tmp/dummy-1-0.aix6.1.noarch.rpm"
+ FileUtils.cp 'spec/functional/assets/dummy-1-0.aix6.1.noarch.rpm' , @pkg_path
+ when "centos", "redhat", "suse"
+ @pkg_name = "mytest"
+ @pkg_version = "1.0-1"
+ @pkg_path = "/tmp/mytest-1.0-1.noarch.rpm"
+ FileUtils.cp 'spec/functional/assets/mytest-1.0-1.noarch.rpm' , @pkg_path
+ end
+ end
+
+ after(:all) do
+ FileUtils.rm @pkg_path
+ end
+
+ context "package install action" do
+ it "should create a package" do
+ new_resource.run_action(:install)
+ rpm_pkg_should_be_installed(new_resource)
+ end
+
+ after(:each) do
+ shell_out("rpm -qa | grep #{@pkg_name}-#{@pkg_version} | xargs rpm -e")
+ end
+ end
+
+ context "package remove action" do
+ before(:each) do
+ shell_out("rpm -i #{@pkg_path}")
+ end
+
+ it "should remove an existing package" do
+ new_resource.run_action(:remove)
+ rpm_pkg_should_not_be_installed(new_resource)
+ end
+ end
+
+ context "package upgrade action" do
+ before(:each) do
+ shell_out("rpm -i #{@pkg_path}")
+ if ohai[:platform] == 'aix'
+ @pkg_version = "2-0"
+ @pkg_path = "/tmp/dummy-2-0.aix6.1.noarch.rpm"
+ FileUtils.cp 'spec/functional/assets/dummy-2-0.aix6.1.noarch.rpm' , @pkg_path
+ else
+ @pkg_version = "2.0-1"
+ @pkg_path = "/tmp/mytest-2.0-1.noarch.rpm"
+ FileUtils.cp 'spec/functional/assets/mytest-2.0-1.noarch.rpm' , @pkg_path
+ end
+ end
+
+ it "should upgrade a package" do
+ new_resource.run_action(:install)
+ rpm_pkg_should_be_installed(new_resource)
+ end
+
+ after(:each) do
+ shell_out("rpm -qa | grep #{@pkg_name}-#{@pkg_version} | xargs rpm -e")
+ FileUtils.rm @pkg_path
+ end
+ end
+end
diff --git a/spec/functional/resource/template_spec.rb b/spec/functional/resource/template_spec.rb
index 1882dc051c..7816d6357b 100644
--- a/spec/functional/resource/template_spec.rb
+++ b/spec/functional/resource/template_spec.rb
@@ -189,54 +189,21 @@ describe Chef::Resource::Template do
end
describe "when template source contains windows style line endings" do
-
include_context "diff disabled"
- let(:expected_content) {
- "Template rendering libraries\r\nshould support\r\ndifferent line endings\r\n\r\n"
- }
-
- context "for all lines" do
- let(:resource) do
- r = create_resource
- r.source "all_windows_line_endings.erb"
- r
- end
-
- it "output should contain windows line endings" do
- resource.run_action(:create)
- binread(path).each_line do |line|
- line.should end_with("\r\n")
- end
- end
- end
-
- context "for some lines" do
- let(:resource) do
- r = create_resource
- r.source "some_windows_line_endings.erb"
- r
- end
-
- it "output should contain windows line endings" do
- resource.run_action(:create)
- binread(path).each_line do |line|
- line.should end_with("\r\n")
+ ["all", "some", "no"].each do |test_case|
+ context "for #{test_case} lines" do
+ let(:resource) do
+ r = create_resource
+ r.source "#{test_case}_windows_line_endings.erb"
+ r
end
- end
- end
- context "for no lines" do
- let(:resource) do
- r = create_resource
- r.source "no_windows_line_endings.erb"
- r
- end
-
- it "output should not contain windows line endings" do
- resource.run_action(:create)
- IO.read(path).each_line do |line|
- line.should_not end_with("\r\n")
+ it "output should contain platform's line endings" do
+ resource.run_action(:create)
+ binread(path).each_line do |line|
+ line.should end_with(Chef::Platform.windows? ? "\r\n" : "\n")
+ end
end
end
end
diff --git a/spec/functional/resource/user_spec.rb b/spec/functional/resource/user_spec.rb
index 7a5f020de9..92248a95bb 100644
--- a/spec/functional/resource/user_spec.rb
+++ b/spec/functional/resource/user_spec.rb
@@ -54,6 +54,7 @@ describe Chef::Resource::User, metadata do
end
before do
+ pending "porting implementation for user provider in aix" if OHAI_SYSTEM[:platform] == 'aix'
# Silence shell_out live stream
Chef::Log.level = :warn
end
@@ -497,7 +498,7 @@ describe Chef::Resource::User, metadata do
context "and has no password" do
# TODO: platform_family should be setup in spec_helper w/ tags
- if OHAI_SYSTEM["platform_family"] == "suse"
+ if %w[suse opensuse].include?(OHAI_SYSTEM["platform_family"])
# suse gets this right:
it "errors out trying to unlock the user" do
@error.should be_a(Mixlib::ShellOut::ShellCommandFailed)
diff --git a/spec/functional/run_lock_spec.rb b/spec/functional/run_lock_spec.rb
index 7dc23d41fd..51645c0ae3 100644
--- a/spec/functional/run_lock_spec.rb
+++ b/spec/functional/run_lock_spec.rb
@@ -20,7 +20,7 @@ require 'chef/client'
describe Chef::RunLock do
- # This behavior is believed to work on windows, but the tests use UNIX APIs.
+ # This behavior works on windows, but the tests use fork :(
describe "when locking the chef-client run", :unix_only => true do
##
@@ -31,7 +31,6 @@ describe Chef::RunLock do
"/tmp/#{Kernel.rand(Time.now.to_i + Process.pid)}"
end
- let(:file_cache_path){ "/var/chef/cache" }
let(:lockfile){ "#{random_temp_root}/this/long/path/does/not/exist/chef-client-running.pid" }
# make sure to start with a clean slate.
@@ -161,7 +160,7 @@ describe Chef::RunLock do
##
# Run lock is the system under test
- let!(:run_lock) { Chef::RunLock.new(:file_cache_path => file_cache_path, :lockfile => lockfile) }
+ let!(:run_lock) { Chef::RunLock.new(lockfile) }
it "creates the full path to the lockfile" do
lambda { run_lock.acquire }.should_not raise_error(Errno::ENOENT)
@@ -225,7 +224,6 @@ E
Process.kill(:KILL, p1)
Process.waitpid2(p1)
-
p2 = fork do
run_lock.acquire
record "p2 has lock"
@@ -237,7 +235,52 @@ E
results.should =~ /p2 has lock\Z/
end
- end
+ it "test returns true and acquires the lock" do
+ p1 = fork do
+ run_lock.test.should == true
+ sleep 2
+ exit! 1
+ end
+
+ wait_on_lock
+
+ p2 = fork do
+ run_lock.test.should == false
+ exit! 0
+ end
+
+ Process.waitpid2(p2)
+ Process.waitpid2(p1)
+ end
+
+ it "test returns without waiting when the lock is acquired" do
+ p1 = fork do
+ run_lock.acquire
+ sleep 2
+ exit! 1
+ end
+
+ wait_on_lock
+
+ run_lock.test.should == false
+ Process.waitpid2(p1)
+ end
+
+ it "doesn't truncate the lock file so that contents can be read" do
+ p1 = fork do
+ run_lock.acquire
+ run_lock.save_pid
+ sleep 2
+ exit! 1
+ end
+
+ wait_on_lock
+ File.read(lockfile).should == p1.to_s
+
+ Process.waitpid2(p1)
+ end
+
+ end
end
diff --git a/spec/functional/shell_spec.rb b/spec/functional/shell_spec.rb
index 90f421ca11..64bd28f16c 100644
--- a/spec/functional/shell_spec.rb
+++ b/spec/functional/shell_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,9 +16,10 @@
# limitations under the License.
#
-require 'spec_helper'
+require 'functional/resource/base'
require 'chef/version'
require 'chef/shell'
+require 'chef/mixin/command/unix'
describe Shell do
@@ -26,6 +27,7 @@ describe Shell do
# not catch cases where chef-shell fails to boot because of changes in
# chef/client.rb
describe "smoke tests", :unix_only => true do
+ include Chef::Mixin::Command::Unix
def read_until(io, expected_value)
start = Time.new
@@ -59,32 +61,52 @@ describe Shell do
end
def run_chef_shell_with(options)
- # Windows ruby installs don't (always?) have PTY,
- # so hide the require here
- require 'pty'
- config = File.expand_path("shef-config.rb", CHEF_SPEC_DATA)
- path_to_chef_shell = File.expand_path("../../../bin/chef-shell", __FILE__)
- reader, writer, pid = PTY.spawn("#{path_to_chef_shell} -c #{config} #{options}")
- read_until(reader, "chef >")
- yield reader, writer if block_given?
- writer.puts('"done"')
- output = read_until(reader, '=> "done"')
- writer.print("exit\n")
- read_until(reader, "exit")
- read_until(reader, "\n")
- read_until(reader, "\n")
- writer.close
+ case ohai[:platform]
+ when "aix"
+ config = File.expand_path("shef-config.rb", CHEF_SPEC_DATA)
+ path_to_chef_shell = File.expand_path("../../../bin/chef-shell", __FILE__)
+ output = ''
+ status = popen4("#{path_to_chef_shell} -c #{config} #{options}", :waitlast => true) do |pid, stdin, stdout, stderr|
+ read_until(stdout, "chef >")
+ yield stdout, stdin if block_given?
+ stdin.write("'done'\n")
+ output = read_until(stdout, '=> "done"')
+ stdin.print("exit\n")
+ read_until(stdout, "\n")
+ end
+
+ [output, status.exitstatus]
+ else
+ # Windows ruby installs don't (always?) have PTY,
+ # so hide the require here
+ begin
+ require 'pty'
+ config = File.expand_path("shef-config.rb", CHEF_SPEC_DATA)
+ path_to_chef_shell = File.expand_path("../../../bin/chef-shell", __FILE__)
+ reader, writer, pid = PTY.spawn("#{path_to_chef_shell} -c #{config} #{options}")
+ read_until(reader, "chef >")
+ yield reader, writer if block_given?
+ writer.puts('"done"')
+ output = read_until(reader, '=> "done"')
+ writer.print("exit\n")
+ read_until(reader, "exit")
+ read_until(reader, "\n")
+ read_until(reader, "\n")
+ writer.close
- exitstatus = wait_or_die(pid)
+ exitstatus = wait_or_die(pid)
- [output, exitstatus]
- rescue PTY::ChildExited => e
- [output, e.status]
+ [output, exitstatus]
+ rescue PTY::ChildExited => e
+ [output, e.status]
+ end
+ end
end
it "boots correctly with -lauto" do
output, exitstatus = run_chef_shell_with("-lauto")
- exitstatus.should be_success
+ output.should include("done")
+ expect(exitstatus).to eq(0)
end
it "sets the log_level from the command line" do
@@ -94,9 +116,7 @@ describe Shell do
read_until(out, show_log_level_code)
end
output.should include("===fatal===")
- exitstatus.should be_success
+ expect(exitstatus).to eq(0)
end
-
end
-
end
diff --git a/spec/functional/tiny_server_spec.rb b/spec/functional/tiny_server_spec.rb
index 68ab9e7294..4262d9e536 100644
--- a/spec/functional/tiny_server_spec.rb
+++ b/spec/functional/tiny_server_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/functional/win32/versions_spec.rb b/spec/functional/win32/versions_spec.rb
index 5cf3a13fd8..acb8bb126d 100644
--- a/spec/functional/win32/versions_spec.rb
+++ b/spec/functional/win32/versions_spec.rb
@@ -44,7 +44,7 @@ describe "Chef::ReservedNames::Win32::Version", :windows_only do
# The name from WMI is actually what we want in Win2k8R2+.
# So this expectation sould continue to hold without modification
# as new versions of Windows are released.
- @current_os_version = host.caption
+ @current_os_version = host.caption
end
@version = Chef::ReservedNames::Win32::Version.new
@@ -55,10 +55,10 @@ describe "Chef::ReservedNames::Win32::Version", :windows_only do
@current_os_version.should include(@version.marketing_name)
end
end
-
+
def is_windows_server_2008?(wmi_host)
is_win2k8 = false
-
+
os_version = wmi_host.send('Version')
# The operating system version is a string in the following form
diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb
new file mode 100644
index 0000000000..839899d059
--- /dev/null
+++ b/spec/integration/client/client_spec.rb
@@ -0,0 +1,146 @@
+require 'support/shared/integration/integration_helper'
+require 'chef/mixin/shell_out'
+
+describe "chef-client" do
+ extend IntegrationSupport
+ include Chef::Mixin::ShellOut
+
+ when_the_repository "has a cookbook with a no-op recipe" do
+ file 'cookbooks/x/recipes/default.rb', ''
+
+ it "should complete with success" do
+ file 'config/client.rb', <<EOM
+local_mode true
+cookbook_path "#{path_to('cookbooks')}"
+EOM
+
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
+ result = shell_out("chef-client -c \"#{path_to('config/client.rb')}\" -o 'x::default'", :cwd => chef_dir)
+ result.error!
+ end
+
+ context 'and no config file' do
+ it 'should complete with success when cwd is just above cookbooks and paths are not specified' do
+ chef_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "bin"))
+ result = shell_out("#{chef_dir}/chef-client -z -o 'x::default' --config-file-jail \"#{path_to('')}\"", :cwd => path_to(''))
+ result.error!
+ end
+
+ it 'should complete with success when cwd is below cookbooks and paths are not specified' do
+ chef_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "bin"))
+ result = shell_out("#{chef_dir}/chef-client -z -o 'x::default' --config-file-jail \"#{path_to('')}\"", :cwd => path_to('cookbooks/x'))
+ result.error!
+ end
+
+ it 'should fail when cwd is below high above and paths are not specified' do
+ chef_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "bin"))
+ result = shell_out("#{chef_dir}/chef-client -z -o 'x::default' --config-file-jail \"#{path_to('')}\"", :cwd => File.expand_path('..', path_to('')))
+ result.exitstatus.should == 1
+ end
+ end
+
+ context 'and a config file under .chef/knife.rb' do
+ file '.chef/knife.rb', 'xxx.xxx'
+
+ it 'should load .chef/knife.rb when -z is specified' do
+ chef_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "bin"))
+ result = shell_out("#{chef_dir}/chef-client -z -o 'x::default' --config-file-jail \"#{path_to('')}\"", :cwd => path_to(''))
+ result.exitstatus.should == 2
+ end
+
+ it 'fails to load .chef/knife.rb when -z is specified and --config-file-jail does not include the .chef/knife.rb' do
+ chef_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "bin"))
+ result = shell_out("#{chef_dir}/chef-client -z -o 'x::default' --config-file-jail \"#{path_to('roles')}\"", :cwd => path_to(''))
+ result.error!
+ end
+ end
+
+ it "should complete with success" do
+ file 'config/client.rb', <<EOM
+local_mode true
+cookbook_path "#{path_to('cookbooks')}"
+EOM
+
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
+ result = shell_out("chef-client -c \"#{path_to('config/client.rb')}\" -o 'x::default'", :cwd => chef_dir)
+ result.error!
+ end
+
+ context 'and a private key' do
+ file 'mykey.pem', <<EOM
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEApubutqtYYQ5UiA9QhWP7UvSmsfHsAoPKEVVPdVW/e8Svwpyf
+0Xef6OFWVmBE+W442ZjLOe2y6p2nSnaq4y7dg99NFz6X+16mcKiCbj0RCiGqCvCk
+NftHhTgO9/RFvCbmKZ1RKNob1YzLrFpxBHaSh9po+DGWhApcd+I+op+ZzvDgXhNn
+0nauZu3rZmApI/r7EEAOjFedAXs7VPNXhhtZAiLSAVIrwU3ZajtSzgXOxbNzgj5O
+AAAMmThK+71qPdffAdO4J198H6/MY04qgtFo7vumzCq0UCaGZfmeI1UNE4+xQWwP
+HJ3pDAP61C6Ebx2snI2kAd9QMx9Y78nIedRHPwIDAQABAoIBAHssRtPM1GacWsom
+8zfeN6ZbI4KDlbetZz0vhnqDk9NVrpijWlcOP5dwZXVNitnB/HaqCqFvyPDY9JNB
+zI/pEFW4QH59FVDP42mVEt0keCTP/1wfiDDGh1vLqVBYl/ZphscDcNgDTzNkuxMx
+k+LFVxKnn3w7rGc59lALSkpeGvbbIDjp3LUMlUeCF8CIFyYZh9ZvXe4OCxYdyjxb
+i8tnMLKvJ4Psbh5jMapsu3rHQkfPdqzztQUz8vs0NYwP5vWge46FUyk+WNm/IhbJ
+G3YM22nwUS8Eu2bmTtADSJolATbCSkOwQ1D+Fybz/4obfYeGaCdOqB05ttubhenV
+ShsAb7ECgYEA20ecRVxw2S7qA7sqJ4NuYOg9TpfGooptYNA1IP971eB6SaGAelEL
+awYkGNuu2URmm5ElZpwJFFTDLGA7t2zB2xI1FeySPPIVPvJGSiZoFQOVlIg9WQzK
+7jTtFQ/tOMrF+bigEUJh5bP1/7HzqSpuOsPjEUb2aoCTp+tpiRGL7TUCgYEAwtns
+g3ysrSEcTzpSv7fQRJRk1lkBhatgNd0oc+ikzf74DaVLhBg1jvSThDhiDCdB59mr
+Jh41cnR1XqE8jmdQbCDRiFrI1Pq6TPaDZFcovDVE1gue9x86v3FOH2ukPG4d2/Xy
+HevXjThtpMMsWFi0JYXuzXuV5HOvLZiP8sN3lSMCgYANpdxdGM7RRbE9ADY0dWK2
+V14ReTLcxP7fyrWz0xLzEeCqmomzkz3BsIUoouu0DCTSw+rvAwExqcDoDylIVlWO
+fAifz7SeZHbcDxo+3TsXK7zwnLYsx7YNs2+aIv6hzUUbMNmNmXMcZ+IEwx+mRMTN
+lYmZdrA5mr0V83oDFPt/jQKBgC74RVE03pMlZiObFZNtheDiPKSG9Bz6wMh7NWMr
+c37MtZLkg52mEFMTlfPLe6ceV37CM8WOhqe+dwSGrYhOU06dYqUR7VOZ1Qr0aZvo
+fsNPu/Y0+u7rMkgv0fs1AXQnvz7kvKaF0YITVirfeXMafuKEtJoH7owRbur42cpV
+YCAtAoGAP1rHOc+w0RUcBK3sY7aErrih0OPh9U5bvJsrw1C0FIZhCEoDVA+fNIQL
+syHLXYFNy0OxMtH/bBAXBGNHd9gf5uOnqh0pYcbe/uRAxumC7Rl0cL509eURiA2T
++vFmf54y9YdnLXaqv+FhJT6B6V7WX7IpU9BMqJY1cJYXHuHG2KA=
+-----END RSA PRIVATE KEY-----
+EOM
+
+ it "should complete with success even with a client key" do
+ file 'config/client.rb', <<EOM
+local_mode true
+client_key "#{path_to('mykey.pem')}"
+cookbook_path "#{path_to('cookbooks')}"
+EOM
+
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
+ result = shell_out("chef-client -c \"#{path_to('config/client.rb')}\" -o 'x::default'", :cwd => chef_dir)
+ result.error!
+ end
+ end
+
+ it "should complete with success when passed the -z flag" do
+ file 'config/client.rb', <<EOM
+chef_server_url 'http://omg.com/blah'
+cookbook_path "#{path_to('cookbooks')}"
+EOM
+
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
+ result = shell_out("chef-client -c \"#{path_to('config/client.rb')}\" -o 'x::default' -z", :cwd => chef_dir)
+ result.error!
+ end
+
+ it "should complete with success when passed the --local-mode flag" do
+ file 'config/client.rb', <<EOM
+chef_server_url 'http://omg.com/blah'
+cookbook_path "#{path_to('cookbooks')}"
+EOM
+
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
+ result = shell_out("chef-client -c \"#{path_to('config/client.rb')}\" -o 'x::default' --local-mode", :cwd => chef_dir)
+ result.error!
+ end
+
+ it "should complete with success when passed -z and --chef-zero-port" do
+ file 'config/client.rb', <<EOM
+chef_server_url 'http://omg.com/blah'
+cookbook_path "#{path_to('cookbooks')}"
+EOM
+
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
+ result = shell_out("chef-client -c \"#{path_to('config/client.rb')}\" -o 'x::default' -z", :cwd => chef_dir)
+ result.error!
+ end
+ end
+end
diff --git a/spec/integration/knife/chef_fs_data_store_spec.rb b/spec/integration/knife/chef_fs_data_store_spec.rb
new file mode 100644
index 0000000000..255a7b66b7
--- /dev/null
+++ b/spec/integration/knife/chef_fs_data_store_spec.rb
@@ -0,0 +1,353 @@
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'support/shared/integration/integration_helper'
+require 'chef/knife/list'
+require 'chef/knife/delete'
+require 'chef/knife/show'
+require 'chef/knife/raw'
+require 'chef/knife/cookbook_upload'
+
+describe 'knife raw -z' do
+ extend IntegrationSupport
+ include KnifeSupport
+
+ when_the_repository "has one of each thing" do
+ file 'clients/x.json', {}
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
+ file 'data_bags/x/y.json', {}
+ file 'environments/x.json', {}
+ file 'nodes/x.json', {}
+ file 'roles/x.json', {}
+ file 'users/x.json', {}
+
+ context 'GET /TYPE' do
+ it 'knife list -z -R returns everything' do
+ knife('list -z -Rfp /').should_succeed <<EOM
+/clients/
+/clients/x.json
+/cookbooks/
+/cookbooks/x/
+/cookbooks/x/metadata.rb
+/data_bags/
+/data_bags/x/
+/data_bags/x/y.json
+/environments/
+/environments/x.json
+/nodes/
+/nodes/x.json
+/roles/
+/roles/x.json
+/users/
+/users/x.json
+EOM
+ end
+ end
+
+ context 'DELETE /TYPE/NAME' do
+ it 'knife delete -z /clients/x.json works' do
+ knife('delete -z /clients/x.json').should_succeed "Deleted /clients/x.json\n"
+ knife('list -z -Rfp /clients').should_succeed ''
+ end
+
+ it 'knife delete -z -r /cookbooks/x works' do
+ knife('delete -z -r /cookbooks/x').should_succeed "Deleted /cookbooks/x\n"
+ knife('list -z -Rfp /cookbooks').should_succeed ''
+ end
+
+ it 'knife delete -z -r /data_bags/x works' do
+ knife('delete -z -r /data_bags/x').should_succeed "Deleted /data_bags/x\n"
+ knife('list -z -Rfp /data_bags').should_succeed ''
+ end
+
+ it 'knife delete -z /data_bags/x/y.json works' do
+ knife('delete -z /data_bags/x/y.json').should_succeed "Deleted /data_bags/x/y.json\n"
+ knife('list -z -Rfp /data_bags').should_succeed "/data_bags/x/\n"
+ end
+
+ it 'knife delete -z /environments/x.json works' do
+ knife('delete -z /environments/x.json').should_succeed "Deleted /environments/x.json\n"
+ knife('list -z -Rfp /environments').should_succeed ''
+ end
+
+ it 'knife delete -z /nodes/x.json works' do
+ knife('delete -z /nodes/x.json').should_succeed "Deleted /nodes/x.json\n"
+ knife('list -z -Rfp /nodes').should_succeed ''
+ end
+
+ it 'knife delete -z /roles/x.json works' do
+ knife('delete -z /roles/x.json').should_succeed "Deleted /roles/x.json\n"
+ knife('list -z -Rfp /roles').should_succeed ''
+ end
+
+ it 'knife delete -z /users/x.json works' do
+ knife('delete -z /users/x.json').should_succeed "Deleted /users/x.json\n"
+ knife('list -z -Rfp /users').should_succeed ''
+ end
+ end
+
+ context 'GET /TYPE/NAME' do
+ it 'knife show -z /clients/x.json works' do
+ knife('show -z /clients/x.json').should_succeed /"x"/
+ end
+
+ it 'knife show -z /cookbooks/x/metadata.rb works' do
+ knife('show -z /cookbooks/x/metadata.rb').should_succeed "/cookbooks/x/metadata.rb:\nversion \"1.0.0\"\n"
+ end
+
+ it 'knife show -z /data_bags/x/y.json works' do
+ knife('show -z /data_bags/x/y.json').should_succeed /"y"/
+ end
+
+ it 'knife show -z /environments/x.json works' do
+ knife('show -z /environments/x.json').should_succeed /"x"/
+ end
+
+ it 'knife show -z /nodes/x.json works' do
+ knife('show -z /nodes/x.json').should_succeed /"x"/
+ end
+
+ it 'knife show -z /roles/x.json works' do
+ knife('show -z /roles/x.json').should_succeed /"x"/
+ end
+
+ it 'knife show -z /users/x.json works' do
+ knife('show -z /users/x.json').should_succeed /"x"/
+ end
+ end
+
+ context 'PUT /TYPE/NAME' do
+ file 'empty.json', {}
+ file 'rolestuff.json', '{"description":"hi there","name":"x"}'
+ file 'cookbooks_to_upload/x/metadata.rb', "version '1.0.0'\n\n"
+
+ it 'knife raw -z -i empty.json -m PUT /clients/x' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /clients/x").should_succeed /"x"/
+ knife('list --local /clients').should_succeed "/clients/x.json\n"
+ end
+
+ it 'knife cookbook upload works' do
+ knife("cookbook upload -z --cookbook-path #{path_to('cookbooks_to_upload')} x").should_succeed <<EOM
+Uploading x [1.0.0]
+Uploaded 1 cookbook.
+EOM
+ knife('list --local -Rfp /cookbooks').should_succeed "/cookbooks/x/\n/cookbooks/x/metadata.rb\n"
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /data/x/y' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /data/x/y").should_succeed /"y"/
+ knife('list --local -Rfp /data_bags').should_succeed "/data_bags/x/\n/data_bags/x/y.json\n"
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /environments/x' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /environments/x").should_succeed /"x"/
+ knife('list --local /environments').should_succeed "/environments/x.json\n"
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /nodes/x' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /nodes/x").should_succeed /"x"/
+ knife('list --local /nodes').should_succeed "/nodes/x.json\n"
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /roles/x' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /roles/x").should_succeed /"x"/
+ knife('list --local /roles').should_succeed "/roles/x.json\n"
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /users/x' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /users/x").should_succeed /"x"/
+ knife('list --local /users').should_succeed "/users/x.json\n"
+ end
+
+ it 'After knife raw -z -i rolestuff.json -m PUT /roles/x, the output is pretty', :pending => (RUBY_VERSION < "1.9") do
+ knife("raw -z -i #{path_to('rolestuff.json')} -m PUT /roles/x").should_succeed /"x"/
+ IO.read(path_to('roles/x.json')).should == <<EOM.strip
+{
+ "name": "x",
+ "description": "hi there"
+}
+EOM
+ end
+ end
+ end
+
+ when_the_repository 'is empty' do
+ context 'POST /TYPE/NAME' do
+ file 'empty.json', { 'name' => 'z' }
+ file 'empty_id.json', { 'id' => 'z' }
+ file 'rolestuff.json', '{"description":"hi there","name":"x"}'
+ file 'cookbooks_to_upload/z/metadata.rb', "version '1.0.0'"
+
+ it 'knife raw -z -i empty.json -m POST /clients' do
+ knife("raw -z -i #{path_to('empty.json')} -m POST /clients").should_succeed /uri/
+ knife('list --local /clients').should_succeed "/clients/z.json\n"
+ end
+
+ it 'knife cookbook upload works' do
+ knife("cookbook upload -z --cookbook-path #{path_to('cookbooks_to_upload')} z").should_succeed <<EOM
+Uploading z [1.0.0]
+Uploaded 1 cookbook.
+EOM
+ knife('list --local -Rfp /cookbooks').should_succeed "/cookbooks/z/\n/cookbooks/z/metadata.rb\n"
+ end
+
+ it 'knife raw -z -i empty.json -m POST /data' do
+ knife("raw -z -i #{path_to('empty.json')} -m POST /data").should_succeed /uri/
+ knife('list --local -Rfp /data_bags').should_succeed "/data_bags/z/\n"
+ end
+
+ it 'knife raw -z -i empty.json -m POST /data/x' do
+ knife("raw -z -i #{path_to('empty_id.json')} -m POST /data/x").should_succeed /"z"/
+ knife('list --local -Rfp /data_bags').should_succeed "/data_bags/x/\n/data_bags/x/z.json\n"
+ end
+
+ it 'knife raw -z -i empty.json -m POST /environments' do
+ knife("raw -z -i #{path_to('empty.json')} -m POST /environments").should_succeed /uri/
+ knife('list --local /environments').should_succeed "/environments/z.json\n"
+ end
+
+ it 'knife raw -z -i empty.json -m POST /nodes' do
+ knife("raw -z -i #{path_to('empty.json')} -m POST /nodes").should_succeed /uri/
+ knife('list --local /nodes').should_succeed "/nodes/z.json\n"
+ end
+
+ it 'knife raw -z -i empty.json -m POST /roles' do
+ knife("raw -z -i #{path_to('empty.json')} -m POST /roles").should_succeed /uri/
+ knife('list --local /roles').should_succeed "/roles/z.json\n"
+ end
+
+ it 'knife raw -z -i empty.json -m POST /users' do
+ knife("raw -z -i #{path_to('empty.json')} -m POST /users").should_succeed /uri/
+ knife('list --local /users').should_succeed "/users/z.json\n"
+ end
+
+ it 'After knife raw -z -i rolestuff.json -m POST /roles, the output is pretty', :pending => (RUBY_VERSION < "1.9") do
+ knife("raw -z -i #{path_to('rolestuff.json')} -m POST /roles").should_succeed /uri/
+ IO.read(path_to('roles/x.json')).should == <<EOM.strip
+{
+ "name": "x",
+ "description": "hi there"
+}
+EOM
+ end
+ end
+
+ it 'knife list -z -R returns nothing' do
+ knife('list -z -Rfp /').should_succeed <<EOM
+/clients/
+/cookbooks/
+/data_bags/
+/environments/
+/nodes/
+/roles/
+/users/
+EOM
+ end
+
+ context 'DELETE /TYPE/NAME' do
+ it 'knife delete -z /clients/x.json fails with an error' do
+ knife('delete -z /clients/x.json').should_fail "ERROR: /clients/x.json: No such file or directory\n"
+ end
+
+ it 'knife delete -z -r /cookbooks/x fails with an error' do
+ knife('delete -z -r /cookbooks/x').should_fail "ERROR: /cookbooks/x: No such file or directory\n"
+ end
+
+ it 'knife delete -z -r /data_bags/x fails with an error' do
+ knife('delete -z -r /data_bags/x').should_fail "ERROR: /data_bags/x: No such file or directory\n"
+ end
+
+ it 'knife delete -z /data_bags/x/y.json fails with an error' do
+ knife('delete -z /data_bags/x/y.json').should_fail "ERROR: /data_bags/x/y.json: No such file or directory\n"
+ end
+
+ it 'knife delete -z /environments/x.json fails with an error' do
+ knife('delete -z /environments/x.json').should_fail "ERROR: /environments/x.json: No such file or directory\n"
+ end
+
+ it 'knife delete -z /nodes/x.json fails with an error' do
+ knife('delete -z /nodes/x.json').should_fail "ERROR: /nodes/x.json: No such file or directory\n"
+ end
+
+ it 'knife delete -z /roles/x.json fails with an error' do
+ knife('delete -z /roles/x.json').should_fail "ERROR: /roles/x.json: No such file or directory\n"
+ end
+
+ it 'knife delete -z /users/x.json fails with an error' do
+ knife('delete -z /users/x.json').should_fail "ERROR: /users/x.json: No such file or directory\n"
+ end
+ end
+
+ context 'GET /TYPE/NAME' do
+ it 'knife show -z /clients/x.json fails with an error' do
+ knife('show -z /clients/x.json').should_fail "ERROR: /clients/x.json: No such file or directory\n"
+ end
+
+ it 'knife show -z /cookbooks/x/metadata.rb fails with an error' do
+ knife('show -z /cookbooks/x/metadata.rb').should_fail "ERROR: /cookbooks/x/metadata.rb: No such file or directory\n"
+ end
+
+ it 'knife show -z /data_bags/x/y.json fails with an error' do
+ knife('show -z /data_bags/x/y.json').should_fail "ERROR: /data_bags/x/y.json: No such file or directory\n"
+ end
+
+ it 'knife show -z /environments/x.json fails with an error' do
+ knife('show -z /environments/x.json').should_fail "ERROR: /environments/x.json: No such file or directory\n"
+ end
+
+ it 'knife show -z /nodes/x.json fails with an error' do
+ knife('show -z /nodes/x.json').should_fail "ERROR: /nodes/x.json: No such file or directory\n"
+ end
+
+ it 'knife show -z /roles/x.json fails with an error' do
+ knife('show -z /roles/x.json').should_fail "ERROR: /roles/x.json: No such file or directory\n"
+ end
+
+ it 'knife show -z /users/x.json fails with an error' do
+ knife('show -z /users/x.json').should_fail "ERROR: /users/x.json: No such file or directory\n"
+ end
+ end
+
+ context 'PUT /TYPE/NAME' do
+ file 'empty.json', {}
+
+ it 'knife raw -z -i empty.json -m PUT /clients/x fails with 404' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /clients/x").should_fail /404/
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /data/x/y fails with 404' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /data/x/y").should_fail /404/
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /environments/x fails with 404' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /environments/x").should_fail /404/
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /nodes/x fails with 404' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /nodes/x").should_fail /404/
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /roles/x fails with 404' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /roles/x").should_fail /404/
+ end
+
+ it 'knife raw -z -i empty.json -m PUT /users/x fails with 404' do
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /users/x").should_fail /404/
+ end
+ end
+ end
+end
diff --git a/spec/integration/knife/chef_repo_path_spec.rb b/spec/integration/knife/chef_repo_path_spec.rb
index 11989933a1..4ffb179a4b 100644
--- a/spec/integration/knife/chef_repo_path_spec.rb
+++ b/spec/integration/knife/chef_repo_path_spec.rb
@@ -52,6 +52,28 @@ describe 'chef_repo_path tests' do
file 'users/user3.json', {}
end
+ it 'knife list --local -Rfp --chef-repo-path chef_repo2 / grabs chef_repo2 stuff' do
+ Chef::Config.delete(:chef_repo_path)
+ knife("list --local -Rfp --chef-repo-path #{path_to('chef_repo2')} /").should_succeed <<EOM
+/clients/
+/clients/client3.json
+/cookbooks/
+/cookbooks/cookbook3/
+/cookbooks/cookbook3/metadata.rb
+/data_bags/
+/data_bags/bag3/
+/data_bags/bag3/item3.json
+/environments/
+/environments/env3.json
+/nodes/
+/nodes/node3.json
+/roles/
+/roles/role3.json
+/users/
+/users/user3.json
+EOM
+ end
+
context 'when all _paths are set to alternates' do
before :each do
%w(client cookbook data_bag environment node role user).each do |object_name|
@@ -60,6 +82,27 @@ describe 'chef_repo_path tests' do
Chef::Config.chef_repo_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2')
end
+ it 'knife list --local -Rfp --chef-repo-path chef_repo2 / grabs chef_repo2 stuff' do
+ knife("list --local -Rfp --chef-repo-path #{path_to('chef_repo2')} /").should_succeed <<EOM
+/clients/
+/clients/client3.json
+/cookbooks/
+/cookbooks/cookbook3/
+/cookbooks/cookbook3/metadata.rb
+/data_bags/
+/data_bags/bag3/
+/data_bags/bag3/item3.json
+/environments/
+/environments/env3.json
+/nodes/
+/nodes/node3.json
+/roles/
+/roles/role3.json
+/users/
+/users/user3.json
+EOM
+ end
+
context 'when cwd is at the top level' do
cwd '.'
it 'knife list --local -Rfp fails' do
@@ -171,7 +214,7 @@ EOM
context 'when only chef_repo_path is set to its alternate' do
before :each do
%w(client cookbook data_bag environment node role user).each do |object_name|
- Chef::Config["#{object_name}_path".to_sym] = nil
+ Chef::Config.delete("#{object_name}_path".to_sym)
end
Chef::Config.chef_repo_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2')
end
@@ -439,7 +482,7 @@ EOM
context 'when when chef_repo_path is set to both places and no other _path is set' do
before :each do
%w(client cookbook data_bag environment node role user).each do |object_name|
- Chef::Config["#{object_name}_path".to_sym] = nil
+ Chef::Config.delete("#{object_name}_path".to_sym)
end
Chef::Config.chef_repo_path = [
Chef::Config.chef_repo_path,
@@ -541,10 +584,10 @@ EOM
context 'when cookbook_path is set and nothing else' do
before :each do
%w(client data_bag environment node role user).each do |object_name|
- Chef::Config["#{object_name}_path".to_sym] = nil
+ Chef::Config.delete("#{object_name}_path".to_sym)
end
- Chef::Config.cookbook_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2', 'cookbooks')
- Chef::Config.chef_repo_path = nil
+ Chef::Config.delete(:chef_repo_path)
+ Chef::Config.cookbook_path = File.join(@repository_dir, 'chef_repo2', 'cookbooks')
end
context 'when cwd is at the top level' do
@@ -599,13 +642,13 @@ EOM
context 'when cookbook_path is set to multiple places and nothing else is set' do
before :each do
%w(client data_bag environment node role user).each do |object_name|
- Chef::Config["#{object_name}_path".to_sym] = nil
+ Chef::Config.delete("#{object_name}_path".to_sym)
end
+ Chef::Config.delete(:chef_repo_path)
Chef::Config.cookbook_path = [
- File.join(Chef::Config.chef_repo_path, 'cookbooks'),
- File.join(Chef::Config.chef_repo_path, 'chef_repo2', 'cookbooks')
+ File.join(@repository_dir, 'cookbooks'),
+ File.join(@repository_dir, 'chef_repo2', 'cookbooks')
]
- Chef::Config.chef_repo_path = nil
end
context 'when cwd is at the top level' do
@@ -702,7 +745,7 @@ EOM
context 'when data_bag_path and chef_repo_path are set, and nothing else' do
before :each do
%w(client cookbook environment node role user).each do |object_name|
- Chef::Config["#{object_name}_path".to_sym] = nil
+ Chef::Config.delete("#{object_name}_path".to_sym)
end
Chef::Config.data_bag_path = File.join(Chef::Config.chef_repo_path, 'data_bags')
Chef::Config.chef_repo_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2')
@@ -760,24 +803,34 @@ EOM
context 'when data_bag_path is set and nothing else' do
before :each do
%w(client cookbook environment node role user).each do |object_name|
- Chef::Config["#{object_name}_path".to_sym] = nil
+ Chef::Config.delete("#{object_name}_path".to_sym)
end
- Chef::Config.data_bag_path = File.join(Chef::Config.chef_repo_path, 'data_bags')
- Chef::Config.chef_repo_path = nil
+ Chef::Config.delete(:chef_repo_path)
+ Chef::Config.data_bag_path = File.join(@repository_dir, 'data_bags')
end
- it 'knife list --local -Rfp / fails' do
- knife('list --local -Rfp /').should_fail("ERROR: Must specify either chef_repo_path or cookbook_path in Chef config file\n")
+ it 'knife list --local -Rfp / lists data bags' do
+ knife('list --local -Rfp /').should_succeed <<EOM
+/data_bags/
+/data_bags/bag/
+/data_bags/bag/item.json
+EOM
end
- it 'knife list --local -Rfp /data_bags fails' do
- knife('list --local -Rfp /data_bags').should_fail("ERROR: Must specify either chef_repo_path or cookbook_path in Chef config file\n")
+ it 'knife list --local -Rfp /data_bags lists data bags' do
+ knife('list --local -Rfp /data_bags').should_succeed <<EOM
+/data_bags/bag/
+/data_bags/bag/item.json
+EOM
end
context 'when cwd is inside the data_bags directory' do
cwd 'data_bags'
- it 'knife list --local -Rfp fails' do
- knife('list --local -Rfp').should_fail("ERROR: Must specify either chef_repo_path or cookbook_path in Chef config file\n")
+ it 'knife list --local -Rfp lists data bags' do
+ knife('list --local -Rfp').should_succeed <<EOM
+bag/
+bag/item.json
+EOM
end
end
end
diff --git a/spec/integration/knife/common_options_spec.rb b/spec/integration/knife/common_options_spec.rb
new file mode 100644
index 0000000000..6de4d9360b
--- /dev/null
+++ b/spec/integration/knife/common_options_spec.rb
@@ -0,0 +1,103 @@
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'support/shared/integration/integration_helper'
+require 'chef/knife/raw'
+
+describe 'knife common options' do
+ extend IntegrationSupport
+ include KnifeSupport
+
+ when_the_repository "has a node" do
+ file 'nodes/x.json', {}
+
+ before(:each) do
+ if ChefZero::RSpec.server
+ ChefZero::RSpec.server.stop
+ ChefZero::RSpec.server = nil
+ end
+ end
+
+ context 'When chef_zero.enabled is true' do
+ before(:each) do
+ Chef::Config.chef_zero.enabled = true
+ end
+
+ it 'knife raw /nodes/x should retrieve the role' do
+ knife('raw /nodes/x').should_succeed /"name": "x"/
+ end
+
+ context 'And chef_zero.port is 9999' do
+ before(:each) { Chef::Config.chef_zero.port = 9999 }
+
+ it 'knife raw /nodes/x should retrieve the role' do
+ knife('raw /nodes/x').should_succeed /"name": "x"/
+ Chef::Config.chef_server_url.should == 'http://127.0.0.1:9999'
+ end
+ end
+
+ context 'and there is a private key' do
+ file 'mykey.pem', <<EOM
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEApubutqtYYQ5UiA9QhWP7UvSmsfHsAoPKEVVPdVW/e8Svwpyf
+0Xef6OFWVmBE+W442ZjLOe2y6p2nSnaq4y7dg99NFz6X+16mcKiCbj0RCiGqCvCk
+NftHhTgO9/RFvCbmKZ1RKNob1YzLrFpxBHaSh9po+DGWhApcd+I+op+ZzvDgXhNn
+0nauZu3rZmApI/r7EEAOjFedAXs7VPNXhhtZAiLSAVIrwU3ZajtSzgXOxbNzgj5O
+AAAMmThK+71qPdffAdO4J198H6/MY04qgtFo7vumzCq0UCaGZfmeI1UNE4+xQWwP
+HJ3pDAP61C6Ebx2snI2kAd9QMx9Y78nIedRHPwIDAQABAoIBAHssRtPM1GacWsom
+8zfeN6ZbI4KDlbetZz0vhnqDk9NVrpijWlcOP5dwZXVNitnB/HaqCqFvyPDY9JNB
+zI/pEFW4QH59FVDP42mVEt0keCTP/1wfiDDGh1vLqVBYl/ZphscDcNgDTzNkuxMx
+k+LFVxKnn3w7rGc59lALSkpeGvbbIDjp3LUMlUeCF8CIFyYZh9ZvXe4OCxYdyjxb
+i8tnMLKvJ4Psbh5jMapsu3rHQkfPdqzztQUz8vs0NYwP5vWge46FUyk+WNm/IhbJ
+G3YM22nwUS8Eu2bmTtADSJolATbCSkOwQ1D+Fybz/4obfYeGaCdOqB05ttubhenV
+ShsAb7ECgYEA20ecRVxw2S7qA7sqJ4NuYOg9TpfGooptYNA1IP971eB6SaGAelEL
+awYkGNuu2URmm5ElZpwJFFTDLGA7t2zB2xI1FeySPPIVPvJGSiZoFQOVlIg9WQzK
+7jTtFQ/tOMrF+bigEUJh5bP1/7HzqSpuOsPjEUb2aoCTp+tpiRGL7TUCgYEAwtns
+g3ysrSEcTzpSv7fQRJRk1lkBhatgNd0oc+ikzf74DaVLhBg1jvSThDhiDCdB59mr
+Jh41cnR1XqE8jmdQbCDRiFrI1Pq6TPaDZFcovDVE1gue9x86v3FOH2ukPG4d2/Xy
+HevXjThtpMMsWFi0JYXuzXuV5HOvLZiP8sN3lSMCgYANpdxdGM7RRbE9ADY0dWK2
+V14ReTLcxP7fyrWz0xLzEeCqmomzkz3BsIUoouu0DCTSw+rvAwExqcDoDylIVlWO
+fAifz7SeZHbcDxo+3TsXK7zwnLYsx7YNs2+aIv6hzUUbMNmNmXMcZ+IEwx+mRMTN
+lYmZdrA5mr0V83oDFPt/jQKBgC74RVE03pMlZiObFZNtheDiPKSG9Bz6wMh7NWMr
+c37MtZLkg52mEFMTlfPLe6ceV37CM8WOhqe+dwSGrYhOU06dYqUR7VOZ1Qr0aZvo
+fsNPu/Y0+u7rMkgv0fs1AXQnvz7kvKaF0YITVirfeXMafuKEtJoH7owRbur42cpV
+YCAtAoGAP1rHOc+w0RUcBK3sY7aErrih0OPh9U5bvJsrw1C0FIZhCEoDVA+fNIQL
+syHLXYFNy0OxMtH/bBAXBGNHd9gf5uOnqh0pYcbe/uRAxumC7Rl0cL509eURiA2T
++vFmf54y9YdnLXaqv+FhJT6B6V7WX7IpU9BMqJY1cJYXHuHG2KA=
+-----END RSA PRIVATE KEY-----
+EOM
+
+ it 'knife raw /nodes/x should retrieve the role' do
+ knife('raw /nodes/x').should_succeed /"name": "x"/
+ end
+ end
+ end
+
+ it 'knife raw -z /nodes/x retrieves the role' do
+ knife('raw -z /nodes/x').should_succeed /"name": "x"/
+ end
+
+ it 'knife raw --local-mode /nodes/x retrieves the role' do
+ knife('raw --local-mode /nodes/x').should_succeed /"name": "x"/
+ end
+
+ it 'knife raw -z --chef-zero-port=9999 /nodes/x retrieves the role' do
+ knife('raw -z --chef-zero-port=9999 /nodes/x').should_succeed /"name": "x"/
+ Chef::Config.chef_server_url.should == 'http://127.0.0.1:9999'
+ end
+ end
+end
diff --git a/spec/integration/knife/download_spec.rb b/spec/integration/knife/download_spec.rb
index a3b3b875a8..ce8df38bd8 100644
--- a/spec/integration/knife/download_spec.rb
+++ b/spec/integration/knife/download_spec.rb
@@ -258,6 +258,15 @@ EOM
D\t/data_bags/x/z.json
EOM
end
+
+ it 'knife download /data_bags/x /data_bags/x/y.json downloads x once' do
+ knife('download /data_bags/x /data_bags/x/y.json').should_succeed <<EOM
+Created /data_bags
+Created /data_bags/x
+Created /data_bags/x/y.json
+Created /data_bags/x/z.json
+EOM
+ end
end
end
@@ -583,7 +592,7 @@ EOM
context 'except the role file is textually different, but not ACTUALLY different' do
file 'roles/x.json', <<EOM
-{
+{
"chef_type": "role" ,
"default_attributes": {
},
@@ -595,7 +604,7 @@ EOM
"override_attributes": {
},
"run_list": [
-
+
]
}
EOM
@@ -959,4 +968,31 @@ EOM
end
end
end # with versioned cookbooks
+
+ when_the_chef_server 'has a cookbook' do
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }
+
+ when_the_repository 'is empty' do
+ it 'knife download /cookbooks/x signs all requests' do
+
+ # Check that BasicClient.request() always gets called with X-OPS-USERID
+ original_new = Chef::HTTP::BasicClient.method(:new)
+ Chef::HTTP::BasicClient.should_receive(:new) do |args|
+ new_result = original_new.call(*args)
+ original_request = new_result.method(:request)
+ new_result.should_receive(:request) do |method, url, body, headers, &response_handler|
+ headers['X-OPS-USERID'].should_not be_nil
+ original_request.call(method, url, body, headers, &response_handler)
+ end.at_least(:once)
+ new_result
+ end.at_least(:once)
+
+ knife('download /cookbooks/x').should_succeed <<EOM
+Created /cookbooks
+Created /cookbooks/x
+Created /cookbooks/x/metadata.rb
+EOM
+ end
+ end
+ end
end
diff --git a/spec/integration/knife/raw_spec.rb b/spec/integration/knife/raw_spec.rb
index 002fd4fdc4..b7412e4e8a 100644
--- a/spec/integration/knife/raw_spec.rb
+++ b/spec/integration/knife/raw_spec.rb
@@ -162,5 +162,68 @@ EOM
EOM
end
end
+
+ context 'When a server returns raw json' do
+ before :each do
+ @real_chef_server_url = Chef::Config.chef_server_url
+ Chef::Config.chef_server_url = "http://127.0.0.1:9018"
+ app = lambda do |env|
+ [200, {'Content-Type' => 'application/json' }, ['{ "x": "y", "a": "b" }'] ]
+ end
+ @raw_server = Puma::Server.new(app, Puma::Events.new(STDERR, STDOUT))
+ @raw_server.add_tcp_listener("127.0.0.1", 9018)
+ @raw_server.run
+ end
+
+ after :each do
+ Chef::Config.chef_server_url = @real_chef_server_url
+ @raw_server.stop(true)
+ end
+
+ it 'knife raw /blah returns the prettified json', :pending => (RUBY_VERSION < "1.9") do
+ knife('raw /blah').should_succeed <<EOM
+{
+ "x": "y",
+ "a": "b"
+}
+EOM
+ end
+
+ it 'knife raw --no-pretty /blah returns the raw json' do
+ knife('raw --no-pretty /blah').should_succeed <<EOM
+{ "x": "y", "a": "b" }
+EOM
+ end
+ end
+
+ context 'When a server returns text' do
+ before :each do
+ @real_chef_server_url = Chef::Config.chef_server_url
+ Chef::Config.chef_server_url = "http://127.0.0.1:9018"
+ app = lambda do |env|
+ [200, {'Content-Type' => 'text' }, ['{ "x": "y", "a": "b" }'] ]
+ end
+ @raw_server = Puma::Server.new(app, Puma::Events.new(STDERR, STDOUT))
+ @raw_server.add_tcp_listener("127.0.0.1", 9018)
+ @raw_server.run
+ end
+
+ after :each do
+ Chef::Config.chef_server_url = @real_chef_server_url
+ @raw_server.stop(true)
+ end
+
+ it 'knife raw /blah returns the raw text' do
+ knife('raw /blah').should_succeed(<<EOM, :stderr => "WARN: Expected JSON response, but got content-type 'text'\n")
+{ "x": "y", "a": "b" }
+EOM
+ end
+
+ it 'knife raw --no-pretty /blah returns the raw text' do
+ knife('raw --no-pretty /blah').should_succeed(<<EOM, :stderr => "WARN: Expected JSON response, but got content-type 'text'\n")
+{ "x": "y", "a": "b" }
+EOM
+ end
+ end
end
end
diff --git a/spec/integration/knife/upload_spec.rb b/spec/integration/knife/upload_spec.rb
index e0715f761a..46b804205f 100644
--- a/spec/integration/knife/upload_spec.rb
+++ b/spec/integration/knife/upload_spec.rb
@@ -58,10 +58,10 @@ D\t/roles/x.json
D\t/users/admin.json
D\t/users/x.json
EOM
- end
+ end
- it 'knife upload --purge deletes everything' do
- knife('upload --purge /').should_succeed(<<EOM, :stderr => "WARNING: /environments/_default.json cannot be deleted (default environment cannot be modified).\n")
+ it 'knife upload --purge deletes everything' do
+ knife('upload --purge /').should_succeed(<<EOM, :stderr => "WARNING: /environments/_default.json cannot be deleted (default environment cannot be modified).\n")
Deleted extra entry /clients/chef-validator.json (purge is on)
Deleted extra entry /clients/chef-webui.json (purge is on)
Deleted extra entry /clients/x.json (purge is on)
@@ -76,7 +76,7 @@ EOM
knife('diff --name-status /').should_succeed <<EOM
D\t/environments/_default.json
EOM
- end
+ end
end
when_the_repository 'has an identical copy of each thing' do
@@ -239,6 +239,13 @@ EOM
EOM
JSON.parse(knife('raw /data/x/y').stdout, :create_additions => false).keys.sort.should == [ 'foo', 'id' ]
end
+
+ it 'knife upload /data_bags/x /data_bags/x/y.json uploads x once' do
+ knife('upload /data_bags/x /data_bags/x/y.json').should_succeed <<EOM
+Created /data_bags/x
+Created /data_bags/x/y.json
+EOM
+ end
end
when_the_repository 'has a data bag item with keys chef_type and data_bag' do
@@ -1057,4 +1064,13 @@ EOM
end
end # with versioned cookbooks
+ when_the_chef_server 'has a user' do
+ user 'x', {}
+ when_the_repository 'has the same user with json_class in it' do
+ file 'users/x.json', { 'admin' => true, 'json_class' => 'Chef::WebUIUser' }
+ it 'knife upload /users/x.json succeeds' do
+ knife('upload /users/x.json').should_succeed "Updated /users/x.json\n"
+ end
+ end
+ end
end
diff --git a/spec/integration/solo/solo_spec.rb b/spec/integration/solo/solo_spec.rb
index 667a9ad87b..9d2a391477 100644
--- a/spec/integration/solo/solo_spec.rb
+++ b/spec/integration/solo/solo_spec.rb
@@ -1,41 +1,94 @@
require 'support/shared/integration/integration_helper'
require 'chef/mixin/shell_out'
+require 'chef/run_lock'
+require 'chef/config'
+require 'timeout'
+require 'fileutils'
describe "chef-solo" do
extend IntegrationSupport
include Chef::Mixin::ShellOut
- context "with a no-op recipe in the run_list" do
+ when_the_repository "has a cookbook with a no-op recipe" do
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
+ file 'cookbooks/x/recipes/default.rb', ''
- when_the_repository "has a cookbook with a no-op recipe" do
- directory 'cookbooks'
- directory 'cookbooks/x'
- directory 'cookbooks/x/recipes'
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
- file 'cookbooks/x/recipes/default.rb', ''
+ it "should complete with success" do
+ file 'config/solo.rb', <<EOM
+cookbook_path "#{path_to('cookbooks')}"
+file_cache_path "#{path_to('config/cache')}"
+EOM
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
+ result = shell_out("chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir)
+ result.error!
+ end
+ end
- before do
- @chef_file_cache = Dir.mktmpdir('file_cache')
- end
+ when_the_repository "has a cookbook with a recipe with sleep" do
+ directory 'logs'
+ file 'logs/runs.log', ''
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
+ file 'cookbooks/x/recipes/default.rb', <<EOM
+ruby_block "sleeping" do
+ block do
+ sleep 3
+ end
+end
+EOM
+ # Ruby 1.8.7 doesn't have Process.spawn :(
+ it "while running solo concurrently", :ruby_gte_19_only => true do
+ file 'config/solo.rb', <<EOM
+cookbook_path "#{path_to('cookbooks')}"
+file_cache_path "#{path_to('config/cache')}"
+EOM
+ # We have a timeout protection here so that if due to some bug
+ # run_lock gets stuck we can discover it.
+ lambda {
+ Timeout.timeout(120) do
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
- after do
- FileUtils.rm_rf(@chef_file_cache) if @chef_file_cache
- end
+ # Instantiate the first chef-solo run
+ s1 = Process.spawn("chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \
+-l debug -L #{path_to('logs/runs.log')}", :chdir => chef_dir)
- it "should complete with success" do
- # prepare the solo config
- directory 'config'
- file 'config/solo.rb', <<EOM
-cookbook_path "#{File.join(@repository_dir, 'cookbooks')}"
-file_cache_path "#{@chef_file_cache}"
-EOM
- config_file = canonicalize_path(File.join(@repository_dir, 'config', 'solo.rb'))
+ # Give it some time to progress
+ sleep 3
- chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
- result = shell_out("chef-solo -c \"#{config_file}\" -o 'x::default' -l debug", :cwd => chef_dir)
- result.error!
- end
+ # Instantiate the second chef-solo run
+ s2 = Process.spawn("chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \
+-l debug -L #{path_to('logs/runs.log')}", :chdir => chef_dir)
+
+ Process.waitpid(s1)
+ Process.waitpid(s2)
+ end
+ }.should_not raise_error(Timeout::Error)
+
+ # Unfortunately file / directory helpers in integration tests
+ # are implemented using before(:each) so we need to do all below
+ # checks in one example.
+ run_log = File.read(path_to('logs/runs.log'))
+ # both of the runs should succeed
+ run_log.lines.reject {|l| !l.include? "INFO: Chef Run complete in"}.length.should == 2
+
+ # second run should have a message which indicates it's waiting for the first run
+ pid_lines = run_log.lines.reject {|l| !l.include? "Chef-client pid:"}
+ pid_lines.length.should == 2
+ pids = pid_lines.map {|l| l.split(" ").last}
+ run_log.should include("Chef client #{pids[0]} is running, will wait for it to finish and then run.")
+
+ # second run should start after first run ends
+ starts = [ ]
+ ends = [ ]
+ run_log.lines.each_with_index do |line, index|
+ if line.include? "Chef-client pid:"
+ starts << index
+ elsif line.include? "INFO: Chef Run complete in"
+ ends << index
+ end
+ end
+ starts[1].should > ends[0]
end
+
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e66f320151..618f782c7c 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -67,6 +67,8 @@ require 'chef/applications'
require 'chef/shell'
require 'chef/util/file_edit'
+require 'chef/config'
+
# If you want to load anything into the testing environment
# without versioning it, add it to spec/support/local_gems.rb
require 'spec/support/local_gems.rb' if File.exists?(File.join(File.dirname(__FILE__), 'support', 'local_gems.rb'))
@@ -107,6 +109,8 @@ RSpec.configure do |config|
config.filter_run_excluding :windows32_only => true unless windows32?
config.filter_run_excluding :system_windows_service_gem_only => true unless system_windows_service_gem?
config.filter_run_excluding :unix_only => true unless unix?
+ # Remove this filter once these issues are fixed: OC-9764, OC-9765, OC-9766, OC-9767
+ config.filter_run_excluding :unsupported_group_provider_platform => true if (os_x? or solaris? or freebsd? or suse?)
config.filter_run_excluding :supports_cloexec => true unless supports_cloexec?
config.filter_run_excluding :selinux_only => true unless selinux_enabled?
config.filter_run_excluding :ruby_18_only => true unless ruby_18?
@@ -114,7 +118,8 @@ RSpec.configure do |config|
config.filter_run_excluding :ruby_gte_19_only => true unless ruby_gte_19?
config.filter_run_excluding :ruby_20_only => true unless ruby_20?
config.filter_run_excluding :ruby_gte_20_only => true unless ruby_gte_20?
- config.filter_run_excluding :requires_root => true unless ENV['USER'] == 'root'
+ config.filter_run_excluding :requires_root => true unless ENV['USER'] == 'root' || ENV['LOGIN'] == 'root'
+ config.filter_run_excluding :requires_root_or_running_windows => true unless (ENV['USER'] == 'root' or windows?)
config.filter_run_excluding :requires_unprivileged_user => true if ENV['USER'] == 'root'
config.filter_run_excluding :uses_diff => true unless has_diff?
@@ -142,4 +147,33 @@ RSpec.configure do |config|
config.run_all_when_everything_filtered = true
config.treat_symbols_as_metadata_keys_with_true_values = true
+
+ config.before(:each) do
+ Chef::Config.reset
+ end
+end
+
+require 'webrick/utils'
+
+# Webrick uses a centralized/synchronized timeout manager. It works by
+# starting a thread to check for timeouts on an interval. The timeout
+# checker thread cannot be stopped or canceled in any easy way, and it
+# makes calls to Time.new, which fail when rspec is in the process of
+# creating a method stub for that method. Since our tests don't rely on
+# any timeout behavior enforced by webrick, disable the timeout manager
+# via a monkey patch.
+#
+# Hopefully this fails loudly if the webrick code should change. As of this
+# writing, the relevant code is in webrick/utils, which can be located on
+# your system with:
+#
+# $ gem which webrick/utils
+module WEBrick
+ module Utils
+ class TimeoutHandler
+ def initialize
+ @timeout_info = Hash.new
+ end
+ end
+ end
end
diff --git a/spec/support/lib/chef/provider/easy.rb b/spec/support/lib/chef/provider/easy.rb
index 054b45256c..a4d285a838 100644
--- a/spec/support/lib/chef/provider/easy.rb
+++ b/spec/support/lib/chef/provider/easy.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,11 +22,11 @@ class Chef
def load_current_resource
true
end
-
+
def action_sell
true
end
-
+
def action_buy
true
end
diff --git a/spec/support/lib/chef/provider/snakeoil.rb b/spec/support/lib/chef/provider/snakeoil.rb
index c5d8d52a82..e9d01f654f 100644
--- a/spec/support/lib/chef/provider/snakeoil.rb
+++ b/spec/support/lib/chef/provider/snakeoil.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ class Chef
def load_current_resource
true
end
-
+
def action_purr
@new_resource.updated_by_last_action(true)
true
@@ -31,7 +31,7 @@ class Chef
def action_sell
true
end
-
+
def action_buy
true
end
diff --git a/spec/support/lib/chef/resource/cat.rb b/spec/support/lib/chef/resource/cat.rb
index 83eb9f08a3..ecca50cb53 100644
--- a/spec/support/lib/chef/resource/cat.rb
+++ b/spec/support/lib/chef/resource/cat.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,15 +19,15 @@
class Chef
class Resource
class Cat < Chef::Resource
-
+
attr_accessor :action
-
+
def initialize(name, run_context=nil)
@resource_name = :cat
super
@action = "sell"
end
-
+
def pretty_kitty(arg=nil)
if arg == true or arg == false
@pretty_kitty = arg
diff --git a/spec/support/lib/chef/resource/with_state.rb b/spec/support/lib/chef/resource/with_state.rb
new file mode 100644
index 0000000000..226de0a6d2
--- /dev/null
+++ b/spec/support/lib/chef/resource/with_state.rb
@@ -0,0 +1,37 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Copyright:: Copyright (c) 2008, 2010 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/knife'
+require 'chef/json_compat'
+
+class Chef
+ class Resource
+ class WithState < Chef::Resource
+ attr_accessor :state
+
+ def initialize(name, run_context=nil)
+ @resource_name = :with_state
+ super
+ end
+
+ def state
+ @state
+ end
+ end
+ end
+end
diff --git a/spec/support/lib/library_load_order.rb b/spec/support/lib/library_load_order.rb
new file mode 100644
index 0000000000..c47a2f2c74
--- /dev/null
+++ b/spec/support/lib/library_load_order.rb
@@ -0,0 +1,22 @@
+# Helper module to track the load order of library files.
+# Used by `cookbook_compiler_spec.rb`
+#
+# This module must be loaded for any tests that load the cookbook
+# data/run_context/cookbooks/test to succeed.
+module LibraryLoadOrder
+ extend self
+
+ def load_order
+ @load_order ||= []
+ end
+
+ def reset!
+ @load_order = nil
+ end
+
+ def record(file)
+ load_order << file
+ end
+end
+
+
diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb
index 1aea6dfad3..1501a162e0 100644
--- a/spec/support/platform_helpers.rb
+++ b/spec/support/platform_helpers.rb
@@ -60,6 +60,10 @@ def freebsd?
!!(RUBY_PLATFORM =~ /freebsd/)
end
+def aix?
+ !!(RUBY_PLATFORM =~ /aix/)
+end
+
def supports_cloexec?
Fcntl.const_defined?('F_SETFD') && Fcntl.const_defined?('FD_CLOEXEC')
end
@@ -87,3 +91,7 @@ def selinux_enabled?
return false
end
end
+
+def suse?
+ File.exists?("/etc/SuSE-release")
+end
diff --git a/spec/support/shared/functional/file_resource.rb b/spec/support/shared/functional/file_resource.rb
index bab421d18d..44048598c7 100644
--- a/spec/support/shared/functional/file_resource.rb
+++ b/spec/support/shared/functional/file_resource.rb
@@ -18,45 +18,29 @@
shared_context "deploying with move" do
before do
- @original_atomic_update = Chef::Config[:file_atomic_update]
+ Chef::Config[:file_backup_path] = CHEF_SPEC_BACKUP_PATH
Chef::Config[:file_atomic_update] = true
end
-
- after do
- Chef::Config[:file_atomic_update] = @original_atomic_update
- end
end
shared_context "deploying with copy" do
before do
- @original_atomic_update = Chef::Config[:file_atomic_update]
+ Chef::Config[:file_backup_path] = CHEF_SPEC_BACKUP_PATH
Chef::Config[:file_atomic_update] = false
end
-
- after do
- Chef::Config[:file_atomic_update] = @original_atomic_update
- end
end
shared_context "deploying via tmpdir" do
before do
- @original_stage_via = Chef::Config[:file_staging_uses_destdir]
Chef::Config[:file_staging_uses_destdir] = false
- end
-
- after do
- Chef::Config[:file_staging_uses_destdir] = @original_stage_via
+ Chef::Config[:file_backup_path] = CHEF_SPEC_BACKUP_PATH
end
end
shared_context "deploying via destdir" do
before do
- @original_stage_via = Chef::Config[:file_staging_uses_destdir]
Chef::Config[:file_staging_uses_destdir] = true
- end
-
- after do
- Chef::Config[:file_staging_uses_destdir] = @original_stage_via
+ Chef::Config[:file_backup_path] = CHEF_SPEC_BACKUP_PATH
end
end
@@ -75,7 +59,6 @@ shared_examples_for "a file with the wrong content" do
context "when running action :create" do
context "with backups enabled" do
before do
- Chef::Config[:file_backup_path] = CHEF_SPEC_BACKUP_PATH
resource.run_action(:create)
end
@@ -99,7 +82,6 @@ shared_examples_for "a file with the wrong content" do
context "with backups disabled" do
before do
- Chef::Config[:file_backup_path] = CHEF_SPEC_BACKUP_PATH
resource.backup(0)
resource.run_action(:create)
end
diff --git a/spec/support/shared/functional/windows_script.rb b/spec/support/shared/functional/windows_script.rb
new file mode 100644
index 0000000000..afeb4c029c
--- /dev/null
+++ b/spec/support/shared/functional/windows_script.rb
@@ -0,0 +1,48 @@
+#
+# Author:: Serdar Sutay (<serdar@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Shared context used by both Powershell and Batch script provider
+# tests.
+
+shared_context Chef::Resource::WindowsScript do
+ before(:all) do
+
+ ohai_reader = Ohai::System.new
+ ohai_reader.require_plugin("os")
+ ohai_reader.require_plugin("windows::platform")
+
+ new_node = Chef::Node.new
+ new_node.consume_external_attrs(ohai_reader.data,{})
+
+ events = Chef::EventDispatch::Dispatcher.new
+
+ @run_context = Chef::RunContext.new(new_node, {}, events)
+ end
+
+ let(:script_output_path) do
+ File.join(Dir.tmpdir, make_tmpname("windows_script_test"))
+ end
+
+ before(:each) do
+k File.delete(script_output_path) if File.exists?(script_output_path)
+ end
+
+ after(:each) do
+ File.delete(script_output_path) if File.exists?(script_output_path)
+ end
+end
diff --git a/spec/support/shared/integration/integration_helper.rb b/spec/support/shared/integration/integration_helper.rb
index b7b377ff6a..0c4bf990af 100644
--- a/spec/support/shared/integration/integration_helper.rb
+++ b/spec/support/shared/integration/integration_helper.rb
@@ -28,30 +28,14 @@ require 'spec_helper'
module IntegrationSupport
include ChefZero::RSpec
- def self.extended(base)
- base.before :each do
- # We mess with Chef::Config a lot. Save and restore it.
- @old_chef_config = Chef::Config.configuration
- Chef::Config.configuration = Chef::Config.configuration.dup
- Chef::Config.repo_mode = nil
- Chef::Config.versioned_cookbooks = nil
- end
- base.after :each do
- Chef::Config.configuration = @old_chef_config
- end
- end
-
def when_the_repository(description, *args, &block)
context "When the local repository #{description}", *args do
before :each do
raise "Can only create one directory per test" if @repository_dir
@repository_dir = Dir.mktmpdir('chef_repo')
- @old_chef_repo_path = Chef::Config.chef_repo_path
- @old_paths = {}
Chef::Config.chef_repo_path = @repository_dir
%w(client cookbook data_bag environment node role user).each do |object_name|
- @old_paths[object_name] = Chef::Config["#{object_name}_path".to_sym]
- Chef::Config["#{object_name}_path".to_sym] = nil
+ Chef::Config.delete("#{object_name}_path".to_sym)
end
end
@@ -59,13 +43,11 @@ module IntegrationSupport
if @repository_dir
begin
%w(client cookbook data_bag environment node role user).each do |object_name|
- Chef::Config["#{object_name}_path".to_sym] = @old_paths[object_name]
+ Chef::Config.delete("#{object_name}_path".to_sym)
end
- Chef::Config.chef_repo_path = @old_chef_repo_path
+ Chef::Config.delete(:chef_repo_path)
FileUtils.remove_entry_secure(@repository_dir)
ensure
- @old_chef_repo_path = nil
- @old_paths = nil
@repository_dir = nil
end
end
@@ -150,7 +132,7 @@ module IntegrationSupport
_m = { :versioned_cookbooks => true }.merge(_metadata)
context 'with versioned cookbooks', _m do
before(:each) { Chef::Config[:versioned_cookbooks] = true }
- after(:each) { Chef::Config[:versioned_cookbooks] = false }
+ after(:each) { Chef::Config.delete(:versioned_cookbooks) }
instance_eval(&block)
end
end
@@ -160,6 +142,7 @@ module IntegrationSupport
context 'with versioned cookbooks', _m do
# Just make sure this goes back to default
before(:each) { Chef::Config[:versioned_cookbooks] = false }
+ after(:each) { Chef::Config.delete(:versioned_cookbooks) }
instance_eval(&block)
end
end
diff --git a/spec/support/shared/integration/knife_support.rb b/spec/support/shared/integration/knife_support.rb
index d2aa153004..036972e18e 100644
--- a/spec/support/shared/integration/knife_support.rb
+++ b/spec/support/shared/integration/knife_support.rb
@@ -38,7 +38,6 @@ module KnifeSupport
# Work on machines where we can't access /var
checksums_cache_dir = Dir.mktmpdir('checksums') do |checksums_cache_dir|
- old_cache_options = Chef::Config[:cache_options]
Chef::Config[:cache_options] = {
:path => checksums_cache_dir,
:skip_expires => true
@@ -84,7 +83,7 @@ module KnifeSupport
Chef::Log.level = ( DEBUG ? :debug : :warn )
Chef::Log::Formatter.show_time = false
- instance.run
+ instance.run_with_pretty_exceptions(true)
exit_code = 0
@@ -94,7 +93,8 @@ module KnifeSupport
ensure
Chef::Log.use_log_devices(old_loggers)
Chef::Log.level = old_log_level
- Chef::Config[:cache_options] = old_cache_options
+ Chef::Config.delete(:cache_options)
+ Chef::Config.delete(:concurrency)
end
KnifeResult.new(stdout.string, stderr.string, exit_code)
diff --git a/spec/support/shared/unit/script_resource.rb b/spec/support/shared/unit/script_resource.rb
index 0451f4694a..5f37506df6 100644
--- a/spec/support/shared/unit/script_resource.rb
+++ b/spec/support/shared/unit/script_resource.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,26 +23,26 @@ shared_examples_for "a script resource" do
before(:each) do
@resource = script_resource
- end
+ end
it "should create a new Chef::Resource::Script" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Script)
end
-
+
it "should have a resource name of :script" do
@resource.resource_name.should eql(resource_name)
end
-
+
it "should set command to the argument provided to new" do
@resource.command.should eql(resource_instance_name)
end
-
+
it "should accept a string for the code" do
@resource.code "hey jude"
@resource.code.should eql("hey jude")
end
-
+
it "should accept a string for the flags" do
@resource.flags "-f"
@resource.flags.should eql("-f")
diff --git a/spec/support/shared/unit/windows_script_resource.rb b/spec/support/shared/unit/windows_script_resource.rb
index 0a0079a287..23dbfbe722 100644
--- a/spec/support/shared/unit/windows_script_resource.rb
+++ b/spec/support/shared/unit/windows_script_resource.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,10 +29,10 @@ shared_examples_for "a Windows script resource" do
node.default["kernel"][:machine] = :x86_64.to_s
run_context = Chef::RunContext.new(node, nil, nil)
-
+
@resource = resource_instance
- end
+ end
it "should be a kind of Chef::Resource::WindowsScript" do
@resource.should be_a_kind_of(Chef::Resource)
@@ -40,9 +40,9 @@ shared_examples_for "a Windows script resource" do
end
context "script" do
- let(:script_resource) { resource_instance }
- it_should_behave_like "a script resource"
+ let(:script_resource) { resource_instance }
+ it_should_behave_like "a script resource"
end
-
+
end
diff --git a/spec/tiny_server.rb b/spec/tiny_server.rb
index fb8dfc6290..340c5d5fb6 100644
--- a/spec/tiny_server.rb
+++ b/spec/tiny_server.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/api_client/registration_spec.rb b/spec/unit/api_client/registration_spec.rb
index 3efbe9914b..0d21730664 100644
--- a/spec/unit/api_client/registration_spec.rb
+++ b/spec/unit/api_client/registration_spec.rb
@@ -57,7 +57,7 @@ describe Chef::ApiClient::Registration do
end
it "creates a new ApiClient on the server using the validator identity" do
- response = {"uri" => "https://chef.local/clients/silent-bob",
+ response = {"uri" => "https://chef.local/clients/silent-bob",
"private_key" => "--begin rsa key etc--"}
http_mock.should_receive(:post).
with("clients", :name => 'silent-bob', :admin => false).
diff --git a/spec/unit/api_client_spec.rb b/spec/unit/api_client_spec.rb
index 50f22c7066..0df863cb78 100644
--- a/spec/unit/api_client_spec.rb
+++ b/spec/unit/api_client_spec.rb
@@ -53,6 +53,19 @@ describe Chef::ApiClient do
lambda { @client.admin(Hash.new) }.should raise_error(ArgumentError)
end
+ it "has a 'validator' flag attribute" do
+ @client.validator(true)
+ @client.validator.should be_true
+ end
+
+ it "defaults to non-validator" do
+ @client.validator.should be_false
+ end
+
+ it "allows only boolean values for the 'validator' flag" do
+ lambda { @client.validator(false) }.should_not raise_error
+ lambda { @client.validator(Hash.new) }.should raise_error(ArgumentError)
+ end
it "has a public key attribute" do
@client.public_key("super public")
@@ -98,6 +111,10 @@ describe Chef::ApiClient do
@json.should include(%q{"admin":false})
end
+ it "includes the 'validator' flag" do
+ @json.should include(%q{"validator":false})
+ end
+
it "includes the private key when present" do
@client.private_key("monkeypants")
@client.to_json.should include(%q{"private_key":"monkeypants"})
@@ -115,6 +132,7 @@ describe Chef::ApiClient do
"public_key" => "crowes",
"private_key" => "monkeypants",
"admin" => true,
+ "validator" => true,
"json_class" => "Chef::ApiClient"
}
@client = Chef::JSONCompat.from_json(client.to_json)
@@ -136,6 +154,10 @@ describe Chef::ApiClient do
@client.admin.should be_true
end
+ it "preserves the 'validator' status" do
+ @client.validator.should be_true
+ end
+
it "includes the private key if present" do
@client.private_key.should == "monkeypants"
end
@@ -198,7 +220,7 @@ describe Chef::ApiClient do
@api_client_with_key.name("lost-my-key")
@api_client_with_key.private_key("the new private key")
@http_client.should_receive(:put).
- with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :private_key => true).
+ with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true).
and_return(@api_client_with_key)
end
@@ -216,7 +238,7 @@ describe Chef::ApiClient do
before do
@api_client_with_key = {"name" => "lost-my-key", "private_key" => "the new private key"}
@http_client.should_receive(:put).
- with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :private_key => true).
+ with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true).
and_return(@api_client_with_key)
end
@@ -227,6 +249,7 @@ describe Chef::ApiClient do
response.private_key.should == "the new private key"
response.name.should == "lost-my-key"
response.admin.should be_false
+ response.validator.should be_false
end
end
diff --git a/spec/unit/application/apply.rb b/spec/unit/application/apply.rb
index 7038801a60..0dc24544b0 100644
--- a/spec/unit/application/apply.rb
+++ b/spec/unit/application/apply.rb
@@ -20,20 +20,12 @@ require 'spec_helper'
describe Chef::Application::Apply do
before do
- @original_config = Chef::Config.configuration
@app = Chef::Application::Recipe.new
@app.stub!(:configure_logging).and_return(true)
@recipe_text = "package 'nyancat'"
Chef::Config[:solo] = true
end
- after do
- Chef::Config[:solo] = nil
- Chef::Config.configuration.replace(@original_config)
- Chef::Config[:solo] = false
- end
-
-
describe "configuring the application" do
it "should set solo mode to true" do
@app.reconfigure
@@ -68,7 +60,7 @@ describe Chef::Application::Apply do
describe "temp_recipe_file" do
before do
@app.instance_variable_set(:@recipe_text, @recipe_text)
- @app.temp_recipe_file
+ @app.temp_recipe_file
@recipe_fh = @app.instance_variable_get(:@recipe_fh)
end
it "should open a tempfile" do
diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb
index e894b8f702..c4387890cd 100644
--- a/spec/unit/application/client_spec.rb
+++ b/spec/unit/application/client_spec.rb
@@ -19,21 +19,20 @@ require 'spec_helper'
describe Chef::Application::Client, "reconfigure" do
before do
- @original_config = Chef::Config.configuration.dup
+ @original_argv = ARGV.dup
+ ARGV.clear
@app = Chef::Application::Client.new
@app.stub!(:configure_opt_parser).and_return(true)
@app.stub!(:configure_chef).and_return(true)
@app.stub!(:configure_logging).and_return(true)
- Chef::Config[:json_attribs] = nil
Chef::Config[:interval] = 10
- Chef::Config[:splay] = nil
Chef::Config[:once] = false
end
after do
- Chef::Config.configuration.replace(@original_config)
+ ARGV.replace(@original_argv)
end
describe "when in daemonized mode and no interval has been set" do
@@ -70,49 +69,19 @@ describe Chef::Application::Client, "reconfigure" do
describe "when the json_attribs configuration option is specified" do
- describe "and the json_attribs matches a HTTP regex" do
- before do
- @json = StringIO.new({:a=>"b"}.to_json)
- @json_tempfile = mock("Tempfile for remote JSON", :open => @json)
- @rest = mock("Chef::REST", :get_rest => @json_tempfile)
-
- Chef::Config[:json_attribs] = "https://foo.com/foo.json"
- Chef::REST.stub!(:new).with("https://foo.com/foo.json", nil, nil).and_return(@rest)
- @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json)
- end
-
- it "should perform a RESTful GET on the supplied URL" do
- @app.reconfigure
- @app.chef_client_json.should == {"a" => "b"}
- end
- end
+ let(:json_attribs) { {"a" => "b"} }
+ let(:config_fetcher) { double(Chef::ConfigFetcher, :fetch_json => json_attribs) }
+ let(:json_source) { "https://foo.com/foo.json" }
- describe "and the json_attribs does not match the HTTP regex" do
- before do
- Chef::Config[:json_attribs] = "/etc/chef/dna.json"
- @json = StringIO.new({:a=>"b"}.to_json)
- @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json)
- end
-
- it "should parse the json out of the file" do
- @app.reconfigure
- @app.chef_client_json.should == {"a" => "b"}
- end
+ before do
+ Chef::Config[:json_attribs] = json_source
+ Chef::ConfigFetcher.should_receive(:new).with(json_source).
+ and_return(config_fetcher)
end
- describe "when parsing fails" do
- before do
- Chef::Config[:json_attribs] = "/etc/chef/dna.json"
- @json = mock("Tempfile", :read => {:a=>"b"}.to_json)
- @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json)
- Chef::JSONCompat.stub!(:from_json).with(@json.read).and_raise(JSON::ParserError)
- Chef::Application.stub!(:fatal!).and_return(true)
- end
-
- it "should hard fail the application" do
- Chef::Application.should_receive(:fatal!).with("Could not parse the provided JSON file (/etc/chef/dna.json)!: JSON::ParserError", 2).and_return(true)
- @app.reconfigure
- end
+ it "reads the JSON attributes from the specified source" do
+ @app.reconfigure
+ @app.chef_client_json.should == json_attribs
end
end
end
@@ -137,10 +106,16 @@ end
describe Chef::Application::Client, "configure_chef" do
before do
+ @original_argv = ARGV.dup
+ ARGV.clear
@app = Chef::Application::Client.new
@app.configure_chef
end
+ after do
+ ARGV.replace(@original_argv)
+ end
+
it "should set the colored output to false by default on windows and true otherwise" do
if windows?
Chef::Config[:color].should be_false
diff --git a/spec/unit/application/solo_spec.rb b/spec/unit/application/solo_spec.rb
index 07598dd01c..6dd8c8f147 100644
--- a/spec/unit/application/solo_spec.rb
+++ b/spec/unit/application/solo_spec.rb
@@ -19,25 +19,15 @@ require 'spec_helper'
describe Chef::Application::Solo do
before do
- @original_config = Chef::Config.configuration
-
-
@app = Chef::Application::Solo.new
@app.stub!(:configure_opt_parser).and_return(true)
@app.stub!(:configure_chef).and_return(true)
@app.stub!(:configure_logging).and_return(true)
Chef::Config[:recipe_url] = false
Chef::Config[:json_attribs] = false
- Chef::Config[:splay] = nil
Chef::Config[:solo] = true
end
- after do
- Chef::Config[:solo] = nil
- Chef::Config.configuration.replace(@original_config)
- Chef::Config[:solo] = false
- end
-
describe "configuring the application" do
it "should set solo mode to true" do
@app.reconfigure
@@ -58,49 +48,19 @@ describe Chef::Application::Solo do
describe "when the json_attribs configuration option is specified" do
- describe "and the json_attribs matches a HTTP regex" do
- before do
- @json = StringIO.new({:a=>"b"}.to_json)
- @json_tempfile = mock("Tempfile (mock)", :open => @json)
- @rest = mock("Chef::REST", :get_rest => @json_tempfile)
-
- Chef::Config[:json_attribs] = "https://foo.com/foo.json"
- Chef::REST.stub!(:new).with("https://foo.com/foo.json", nil, nil).and_return(@rest)
- @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json)
- end
-
- it "should perform a RESTful GET on the supplied URL" do
- @app.reconfigure
- @app.instance_variable_get(:@chef_client_json).should == {"a" => "b"}
- end
- end
+ let(:json_attribs) { {"a" => "b"} }
+ let(:config_fetcher) { double(Chef::ConfigFetcher, :fetch_json => json_attribs) }
+ let(:json_source) { "https://foo.com/foo.json" }
- describe "and the json_attribs does not match the HTTP regex" do
- before do
- Chef::Config[:json_attribs] = "/etc/chef/dna.json"
- @json = StringIO.new({:a=>"b"}.to_json)
- @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json)
- end
-
- it "should parse the json out of the file" do
- @app.reconfigure
- @app.instance_variable_get(:@chef_client_json).should == {"a" => "b"}
- end
+ before do
+ Chef::Config[:json_attribs] = json_source
+ Chef::ConfigFetcher.should_receive(:new).with(json_source).
+ and_return(config_fetcher)
end
- describe "when parsing fails" do
- before do
- Chef::Config[:json_attribs] = "/etc/chef/dna.json"
- @json = mock("Tempfile", :read => {:a=>"b"}.to_json)
- @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json)
- Chef::JSONCompat.stub!(:from_json).with(@json.read).and_raise(JSON::ParserError)
- Chef::Application.stub!(:fatal!).and_return(true)
- end
-
- it "should hard fail the application" do
- Chef::Application.should_receive(:fatal!).with("Could not parse the provided JSON file (/etc/chef/dna.json)!: JSON::ParserError", 2).and_return(true)
- @app.reconfigure
- end
+ it "reads the JSON attributes from the specified source" do
+ @app.reconfigure
+ @app.chef_solo_json.should == json_attribs
end
end
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index f3df8c14cd..1606c82531 100644
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -20,15 +20,17 @@ require 'spec_helper'
describe Chef::Application do
before do
- @original_conf = Chef::Config.configuration
+ @original_argv = ARGV.dup
+ ARGV.clear
Chef::Log.logger = Logger.new(StringIO.new)
@app = Chef::Application.new
Dir.stub!(:chdir).and_return(0)
@app.stub!(:reconfigure)
+ Chef::Log.init(STDERR)
end
after do
- Chef::Config.configuration.replace(@original_conf)
+ ARGV.replace(@original_argv)
end
describe "reconfigure" do
@@ -94,28 +96,30 @@ describe Chef::Application do
end
describe "when a config_file is present" do
- before do
- Chef::Config.configuration.delete('rspec_ran')
-
- @config_file = Tempfile.new("rspec-chef-config")
- @config_file.puts("rspec_ran('true')")
- @config_file.close
+ let(:config_content) { "rspec_ran('true')" }
+ let(:config_location) { "/etc/chef/default.rb" }
- @app.config[:config_file] = "/etc/chef/default.rb"
+ let(:config_location_pathname) do
+ p = Pathname.new(config_location)
+ p.stub(:realpath).and_return(config_location)
+ p
end
- after do
- @config_file.unlink
+ before do
+ @app.config[:config_file] = config_location
+ Pathname.stub(:new).with(config_location).and_return(config_location_pathname)
+ File.should_receive(:read).
+ with(config_location).
+ and_return(config_content)
end
it "should configure chef::config from a file" do
- File.should_receive(:open).with("/etc/chef/default.rb").and_yield(@config_file)
- Chef::Config.should_receive(:from_file).with(@config_file.path)
+ Chef::Config.should_receive(:from_string).with(config_content, config_location)
@app.configure_chef
end
it "should merge the local config hash into chef::config" do
- File.should_receive(:open).with("/etc/chef/default.rb").and_yield(@config_file)
+ #File.should_receive(:open).with("/etc/chef/default.rb").and_yield(@config_file)
@app.configure_chef
Chef::Config.rspec_ran.should == "true"
end
@@ -127,9 +131,9 @@ describe Chef::Application do
@app.config[:config_file] = nil
end
- it "should raise a fatal" do
+ it "should emit a warning" do
Chef::Config.should_not_receive(:from_file).with("/etc/chef/default.rb")
- Chef::Application.should_receive(:fatal!)
+ Chef::Log.should_receive(:warn).with("No config file found or specified on command line, using command line options.")
@app.configure_chef
end
end
@@ -143,36 +147,6 @@ describe Chef::Application do
@app.configure_chef
end
end
-
- describe "when the config_file is an URL" do
- before do
- Chef::Config.configuration.delete('rspec_ran')
-
- @app.config[:config_file] = "http://example.com/foo.rb"
-
- @config_file = Tempfile.new("rspec-chef-config")
- @config_file.puts("rspec_ran('true')")
- @config_file.close
-
-
- @cf = mock("cf")
- #@cf.stub!(:path).and_return("/tmp/some/path")
- #@cf.stub!(:nil?).and_return(false)
- @rest = mock("rest")
- #@rest.stub!(:get_rest).and_return(@rest)
- #@rest.stub!(:open).and_yield(@cf)
- Chef::REST.stub!(:new).and_return(@rest)
- end
-
- after {@config_file.unlink}
-
- it "should configure chef::config from an URL" do
- Chef::REST.should_receive(:new).with("", nil, nil).at_least(1).times.and_return(@rest)
- @rest.should_receive(:fetch).with("http://example.com/foo.rb").and_yield(@config_file)
- @app.configure_chef
- Chef::Config.rspec_ran.should == "true"
- end
- end
end
describe "when configuring the logger" do
@@ -189,17 +163,8 @@ describe Chef::Application do
@app.configure_logging
end
- it "should initialise the chef logger level" do
- Chef::Log.should_receive(:level=).with(Chef::Config[:log_level]).and_return(true)
- @app.configure_logging
- end
-
- context "and log_level is :auto" do
- before do
- Chef::Config[:log_level] = :auto
- end
-
- context "and STDOUT is to a tty" do
+ shared_examples_for "log_level_is_auto" do
+ context "when STDOUT is to a tty" do
before do
STDOUT.stub!(:tty?).and_return(true)
end
@@ -209,7 +174,7 @@ describe Chef::Application do
Chef::Log.level.should == :warn
end
- context "and force_logger is configured" do
+ context "when force_logger is configured" do
before do
Chef::Config[:force_logger] = true
end
@@ -221,7 +186,7 @@ describe Chef::Application do
end
end
- context "and STDOUT is not to a tty" do
+ context "when STDOUT is not to a tty" do
before do
STDOUT.stub!(:tty?).and_return(false)
end
@@ -231,7 +196,7 @@ describe Chef::Application do
Chef::Log.level.should == :info
end
- context "and force_formatter is configured" do
+ context "when force_formatter is configured" do
before do
Chef::Config[:force_formatter] = true
end
@@ -241,7 +206,18 @@ describe Chef::Application do
end
end
end
+ end
+
+ context "when log_level is not set" do
+ it_behaves_like "log_level_is_auto"
+ end
+
+ context "when log_level is :auto" do
+ before do
+ Chef::Config[:log_level] = :auto
+ end
+ it_behaves_like "log_level_is_auto"
end
end
@@ -293,34 +269,29 @@ describe Chef::Application do
end
end
- describe "configuration errors" do
- before do
- Process.stub!(:exit).and_return(true)
- end
-
- def raises_informative_fatals_on_configure_chef
- config_file_regexp = Regexp.new @app.config[:config_file]
- Chef::Log.should_receive(:fatal).with(config_file_regexp).and_return(true)
- @app.configure_chef
- end
-
- def warns_informatively_on_configure_chef
+ context "when the config file is not available" do
+ it "should warn for bad config file path" do
+ @app.config[:config_file] = "/tmp/non-existing-dir/file"
config_file_regexp = Regexp.new @app.config[:config_file]
Chef::Log.should_receive(:warn).at_least(:once).with(config_file_regexp).and_return(true)
Chef::Log.should_receive(:warn).any_number_of_times.and_return(true)
@app.configure_chef
end
+ end
- it "should warn for bad config file path" do
- @app.config[:config_file] = "/tmp/non-existing-dir/file"
- warns_informatively_on_configure_chef
+ describe "configuration errors" do
+ before do
+ Process.should_receive(:exit)
end
- it "should raise informative fatals for bad config file url" do
- non_existing_url = "http://its-stubbed.com/foo.rb"
- @app.config[:config_file] = non_existing_url
- Chef::REST.any_instance.stub(:fetch).with(non_existing_url).and_raise(SocketError)
- raises_informative_fatals_on_configure_chef
+ def raises_informative_fatals_on_configure_chef
+ config_file_regexp = Regexp.new @app.config[:config_file]
+ Chef::Log.should_receive(:fatal).
+ with(/Configuration error/)
+ Chef::Log.should_receive(:fatal).
+ with(config_file_regexp).
+ at_least(1).times
+ @app.configure_chef
end
describe "when config file exists but contains errors" do
diff --git a/spec/unit/checksum/storage/filesystem_spec.rb b/spec/unit/checksum/storage/filesystem_spec.rb
index a39644202e..144dc69ff1 100644
--- a/spec/unit/checksum/storage/filesystem_spec.rb
+++ b/spec/unit/checksum/storage/filesystem_spec.rb
@@ -27,16 +27,17 @@ describe Chef::Checksum::Storage::Filesystem do
@now = Time.now
Time.stub!(:now).and_return(@now)
+ Chef::Config.stub!(:checksum_path).and_return("/var/chef/checksums")
@checksum_of_the_file = "3fafecfb15585ede6b840158cbc2f399"
- @storage = Chef::Checksum::Storage::Filesystem.new(Chef::Config.checksum_path, @checksum_of_the_file)
+ @storage = Chef::Checksum::Storage::Filesystem.new("/not/used/path", @checksum_of_the_file)
end
it "has the path to the file in the checksum repo" do
@storage.file_location.should == "/var/chef/checksums/3f/3fafecfb15585ede6b840158cbc2f399"
end
- it "has the path the the file's subdirectory in the checksum repo" do
+ it "has the path the file's subdirectory in the checksum repo" do
@storage.checksum_repo_directory.should == "/var/chef/checksums/3f"
end
diff --git a/spec/unit/chef_fs/file_system/operation_failed_error_spec.rb b/spec/unit/chef_fs/file_system/operation_failed_error_spec.rb
new file mode 100644
index 0000000000..570246c41f
--- /dev/null
+++ b/spec/unit/chef_fs/file_system/operation_failed_error_spec.rb
@@ -0,0 +1,47 @@
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright (c) 2012 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+require 'chef/chef_fs/file_system/operation_failed_error'
+
+describe Chef::ChefFS::FileSystem::OperationFailedError do
+ context 'message' do
+ let(:error_message) { 'HTTP error writing: 400 "Bad Request"' }
+
+ context 'has a cause attribute and HTTP result code is 400' do
+ it 'include error cause' do
+ allow_message_expectations_on_nil
+ response_body = '{"error":["Invalid key test in request body"]}'
+ @response.stub(:code).and_return("400")
+ @response.stub(:body).and_return(response_body)
+ exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
+ proc {
+ raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, exception), error_message
+ }.should raise_error(Chef::ChefFS::FileSystem::OperationFailedError, "#{error_message} cause: #{response_body}")
+ end
+ end
+
+ context 'does not have a cause attribute' do
+ it 'does not include error cause' do
+ proc {
+ raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self), error_message
+ }.should raise_error(Chef::ChefFS::FileSystem::OperationFailedError, error_message)
+ end
+ end
+ end
+end
diff --git a/spec/unit/chef_spec.rb b/spec/unit/chef_spec.rb
index cf60e64629..b0f0359806 100644
--- a/spec/unit/chef_spec.rb
+++ b/spec/unit/chef_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/client_spec.rb b/spec/unit/client_spec.rb
index 6f0c2b9da5..67eb97f5c2 100644
--- a/spec/unit/client_spec.rb
+++ b/spec/unit/client_spec.rb
@@ -74,23 +74,13 @@ shared_examples_for Chef::Client do
end
describe "configuring output formatters" do
- before do
- @original_config = Chef::Config.configuration
- end
-
- after do
- Chef::Config.configuration.replace(@original_config)
- end
context "when no formatter has been configured" do
before do
- Chef::Config.formatters.clear
@client = Chef::Client.new
end
context "and STDOUT is a TTY" do
before do
- Chef::Config[:force_formatter] = false
- Chef::Config[:force_logger] = false
STDOUT.stub!(:tty?).and_return(true)
end
@@ -114,7 +104,6 @@ shared_examples_for Chef::Client do
context "and STDOUT is not a TTY" do
before do
- Chef::Config[:force_formatter] = false
STDOUT.stub!(:tty?).and_return(false)
end
@@ -137,7 +126,6 @@ shared_examples_for Chef::Client do
context "when a formatter is configured" do
context "with no output path" do
before do
- Chef::Config.formatters.clear
@client = Chef::Client.new
Chef::Config.add_formatter(:min)
end
@@ -156,7 +144,6 @@ shared_examples_for Chef::Client do
context "with an output path" do
before do
- Chef::Config.formatters.clear
@client = Chef::Client.new
@tmpout = Tempfile.open("rspec-for-client-formatter-selection-#{Process.pid}")
Chef::Config.add_formatter(:min, @tmpout.path)
@@ -226,6 +213,7 @@ shared_examples_for Chef::Client do
mock_chef_rest_for_node_save.should_receive(:put_rest).with("nodes/#{@fqdn}", @node).and_return(true)
Chef::RunLock.any_instance.should_receive(:acquire)
+ Chef::RunLock.any_instance.should_receive(:save_pid)
Chef::RunLock.any_instance.should_receive(:release)
# Post conditions: check that node has been filled in correctly
@@ -463,19 +451,15 @@ shared_examples_for Chef::Client do
end
describe Chef::Client do
+ Chef::Config[:client_fork] = false
it_behaves_like Chef::Client
end
describe "Chef::Client Forked" do
before do
- @original_config = Chef::Config.configuration
Chef::Config[:client_fork] = true
end
- after do
- Chef::Config.configuration.replace(@original_config)
- end
-
it_behaves_like Chef::Client
end
diff --git a/spec/unit/config_fetcher_spec.rb b/spec/unit/config_fetcher_spec.rb
new file mode 100644
index 0000000000..c29521806a
--- /dev/null
+++ b/spec/unit/config_fetcher_spec.rb
@@ -0,0 +1,98 @@
+require 'spec_helper'
+require 'chef/config_fetcher'
+describe Chef::ConfigFetcher do
+ let(:valid_json) { {:a=>"b"}.to_json }
+ let(:invalid_json) { %q[{"syntax-error": "missing quote}] }
+ let(:http) { double("Chef::HTTP::Simple") }
+
+ let(:config_location_regex) { Regexp.escape(config_location) }
+ let(:invalid_json_error_regex) { %r[Could not parse the provided JSON file \(#{config_location_regex}\)] }
+
+ let(:config_jail_path) { nil }
+
+ let(:fetcher) { Chef::ConfigFetcher.new(config_location, config_jail_path) }
+
+ context "when loading a local file" do
+ let(:config_location) { "/etc/chef/client.rb" }
+ let(:config_content) { "# The client.rb content" }
+
+ it "reads the file from disk" do
+ ::File.should_receive(:read).
+ with(config_location).
+ and_return(config_content)
+ fetcher.read_config.should == config_content
+ end
+
+ context "and consuming JSON" do
+
+ let(:config_location) { "/etc/chef/first-boot.json" }
+
+
+ it "returns the parsed JSON" do
+ ::File.should_receive(:read).
+ with(config_location).
+ and_return(valid_json)
+
+ fetcher.fetch_json.should == {"a" => "b"}
+ end
+
+ context "and the JSON is invalid" do
+
+ it "reports the JSON error" do
+
+
+ ::File.should_receive(:read).
+ with(config_location).
+ and_return(invalid_json)
+
+ Chef::Application.should_receive(:fatal!).
+ with(invalid_json_error_regex, 2)
+ fetcher.fetch_json
+ end
+ end
+ end
+
+ end
+
+ context "when loading a file over HTTP" do
+
+ let(:config_location) { "https://example.com/client.rb" }
+ let(:config_content) { "# The client.rb content" }
+
+ before do
+ Chef::HTTP::Simple.should_receive(:new).
+ with(config_location).
+ and_return(http)
+ end
+
+ it "reads the file over HTTP" do
+ http.should_receive(:get).
+ with("").and_return(config_content)
+ fetcher.read_config.should == config_content
+ end
+
+ context "and consuming JSON" do
+ let(:config_location) { "https://example.com/foo.json" }
+
+ it "fetches the file and parses it" do
+ http.should_receive(:get).
+ with("").and_return(valid_json)
+ fetcher.fetch_json.should == {"a" => "b"}
+ end
+
+ context "and the JSON is invalid" do
+ it "reports the JSON error" do
+ http.should_receive(:get).
+ with("").and_return(invalid_json)
+
+ Chef::Application.should_receive(:fatal!).
+ with(invalid_json_error_regex, 2)
+ fetcher.fetch_json
+ end
+ end
+ end
+
+ end
+
+
+end
diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb
index 5d10b6927b..cb48ab5bcc 100644
--- a/spec/unit/config_spec.rb
+++ b/spec/unit/config_spec.rb
@@ -22,7 +22,6 @@ require 'chef/exceptions'
describe Chef::Config do
before(:all) do
- @original_config = Chef::Config.hash_dup
@original_env = { 'HOME' => ENV['HOME'], 'SYSTEMDRIVE' => ENV['SYSTEMDRIVE'], 'HOMEPATH' => ENV['HOMEPATH'], 'USERPROFILE' => ENV['USERPROFILE'] }
end
@@ -82,22 +81,18 @@ describe Chef::Config do
# log_level = info or defualt
# end
#
- before do
- @config_class = Class.new(Chef::Config)
- end
-
it "has an empty list of formatters by default" do
- @config_class.formatters.should == []
+ Chef::Config.formatters.should == []
end
it "configures a formatter with a short name" do
- @config_class.add_formatter(:doc)
- @config_class.formatters.should == [[:doc, nil]]
+ Chef::Config.add_formatter(:doc)
+ Chef::Config.formatters.should == [[:doc, nil]]
end
it "configures a formatter with a file output" do
- @config_class.add_formatter(:doc, "/var/log/formatter.log")
- @config_class.formatters.should == [[:doc, "/var/log/formatter.log"]]
+ Chef::Config.add_formatter(:doc, "/var/log/formatter.log")
+ Chef::Config.formatters.should == [[:doc, "/var/log/formatter.log"]]
end
end
@@ -142,10 +137,6 @@ describe Chef::Config do
and_return(@mockfile)
end
- after do
- Chef::Config.log_location = STDOUT
- end
-
it "should configure itself to use a File object based upon the String" do
Chef::Config.log_location = "/var/log/chef/client.log"
Chef::Config.log_location.path.should == "/var/log/chef/client.log"
@@ -174,15 +165,6 @@ describe Chef::Config do
end
describe "default values" do
- before(:each) do
- # reload Chef::Config to ensure defaults are truely active
- load File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib", "chef", "config.rb"))
- end
-
- after(:each) do
- # reload spec helper to re-set any spec specific Chef::Config values
- load File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper.rb"))
- end
it "Chef::Config[:file_backup_path] defaults to /var/chef/backup" do
backup_path = if windows?
@@ -220,6 +202,70 @@ describe Chef::Config do
Chef::Config[:environment_path].should == environment_path
end
+
+ describe "joining platform specific paths" do
+
+ context "on UNIX" do
+ before do
+ Chef::Config.stub(:on_windows?).and_return(false)
+ end
+
+ it "joins components when some end with separators" do
+ Chef::Config.path_join("/foo/", "bar", "baz").should == "/foo/bar/baz"
+ end
+
+ it "joins components that don't end in separators" do
+ Chef::Config.path_join("/foo", "bar", "baz").should == "/foo/bar/baz"
+ end
+
+ end
+
+ context "on Windows" do
+ before do
+ Chef::Config.stub(:on_windows?).and_return(true)
+ end
+
+ it "joins components with the windows separator" do
+ Chef::Config.path_join('c:\\foo\\', 'bar', "baz").should == 'c:\\foo\\bar\\baz'
+ end
+ end
+ end
+
+ describe "setting the config dir" do
+
+ before do
+ Chef::Config.stub(:on_windows?).and_return(false)
+ Chef::Config.config_file = "/etc/chef/client.rb"
+ end
+
+ context "by default" do
+ it "is the parent dir of the config file" do
+ Chef::Config.config_dir.should == "/etc/chef"
+ end
+ end
+
+ context "when chef is running in local mode" do
+ before do
+ Chef::Config.local_mode = true
+ Chef::Config.user_home = "/home/charlie"
+ end
+
+ it "is in the user's home dir" do
+ Chef::Config.config_dir.should == "/home/charlie/.chef/"
+ end
+ end
+
+ context "when explicitly set" do
+ before do
+ Chef::Config.config_dir = "/other/config/dir/"
+ end
+
+ it "uses the explicit value" do
+ Chef::Config.config_dir.should == "/other/config/dir/"
+ end
+ end
+
+ end
end
describe "Chef::Config[:user_home]" do
@@ -278,8 +324,4 @@ describe Chef::Config do
expect{Chef::Config.log_location = missing_path}.to raise_error Chef::Exceptions::ConfigurationError
end
end
-
- after(:each) do
- Chef::Config.configuration = @original_config
- end
end
diff --git a/spec/unit/cookbook/metadata_spec.rb b/spec/unit/cookbook/metadata_spec.rb
index 2757f92506..9822146131 100644
--- a/spec/unit/cookbook/metadata_spec.rb
+++ b/spec/unit/cookbook/metadata_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@
require 'spec_helper'
require 'chef/cookbook/metadata'
-describe Chef::Cookbook::Metadata do
+describe Chef::Cookbook::Metadata do
before(:each) do
@cookbook = Chef::CookbookVersion.new('test_cookbook')
@meta = Chef::Cookbook::Metadata.new(@cookbook)
@@ -86,7 +86,7 @@ describe Chef::Cookbook::Metadata do
it "should return a Chef::Cookbook::Metadata object" do
@meta.should be_a_kind_of(Chef::Cookbook::Metadata)
end
-
+
it "should allow a cookbook as the first argument" do
lambda { Chef::Cookbook::Metadata.new(@cookbook) }.should_not raise_error
end
@@ -96,7 +96,7 @@ describe Chef::Cookbook::Metadata do
end
it "should set the maintainer name from the second argument" do
- md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown')
+ md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown')
md.maintainer.should == 'Bobo T. Clown'
end
@@ -105,7 +105,7 @@ describe Chef::Cookbook::Metadata do
end
it "should set the maintainer email from the third argument" do
- md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co')
+ md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co')
md.maintainer_email.should == 'bobo@clown.co'
end
@@ -114,10 +114,10 @@ describe Chef::Cookbook::Metadata do
end
it "should set the license from the fourth argument" do
- md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co', 'Clown License v1')
+ md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co', 'Clown License v1')
md.license.should == 'Clown License v1'
end
- end
+ end
describe "cookbook" do
it "should return the cookbook we were initialized with" do
@@ -133,7 +133,7 @@ describe Chef::Cookbook::Metadata do
describe "platforms" do
it "should return the current platform hash" do
- @meta.platforms.should be_a_kind_of(Hash)
+ @meta.platforms.should be_a_kind_of(Hash)
end
end
@@ -235,7 +235,7 @@ describe Chef::Cookbook::Metadata do
end
end
end
-
+
describe "attribute groupings" do
it "should allow you set a grouping" do
group = {
@@ -312,7 +312,7 @@ describe Chef::Cookbook::Metadata do
@meta.attribute("db/mysql/databases", {})
@meta.attributes["db/mysql/databases"][:choice].should == []
end
-
+
it "should let calculated be true or false" do
lambda {
@meta.attribute("db/mysql/databases", :calculated => true)
@@ -324,7 +324,7 @@ describe Chef::Cookbook::Metadata do
@meta.attribute("db/mysql/databases", :calculated => Hash.new)
}.should raise_error(ArgumentError)
end
-
+
it "should set calculated to false by default" do
@meta.attribute("db/mysql/databases", {})
@meta.attributes["db/mysql/databases"][:calculated].should == false
@@ -350,7 +350,7 @@ describe Chef::Cookbook::Metadata do
@meta.attribute("db/mysql/databases", :type => "symbol")
}.should_not raise_error(ArgumentError)
end
-
+
it "should let type be hash (backwards compatability only)" do
lambda {
@meta.attribute("db/mysql/databases", :type => "hash")
@@ -375,7 +375,7 @@ describe Chef::Cookbook::Metadata do
}.should_not raise_error(ArgumentError)
#attrib = @meta.attributes["db/mysql/databases"][:required].should == "required"
end
-
+
it "should convert required false to optional" do
lambda {
@meta.attribute("db/mysql/databases", :required => false)
@@ -387,7 +387,7 @@ describe Chef::Cookbook::Metadata do
@meta.attribute("db/mysql/databases", {})
@meta.attributes["db/mysql/databases"][:required].should == 'optional'
end
-
+
it "should make sure recipes is an array" do
lambda {
@meta.attribute("db/mysql/databases", :recipes => [])
@@ -399,7 +399,7 @@ describe Chef::Cookbook::Metadata do
it "should set recipes to an empty array by default" do
@meta.attribute("db/mysql/databases", {})
- @meta.attributes["db/mysql/databases"][:recipes].should == []
+ @meta.attributes["db/mysql/databases"][:recipes].should == []
end
it "should allow the default value to be a string, array, or hash" do
@@ -438,14 +438,14 @@ describe Chef::Cookbook::Metadata do
lambda {
attrs = {
:choice => [ "a", "b", "c"],
- :default => "b"
+ :default => "b"
}
@meta.attribute("db/mysql/databases", attrs)
}.should_not raise_error(ArgumentError)
lambda {
attrs = {
:choice => [ "a", "b", "c", "d", "e"],
- :default => ["b", "d"]
+ :default => ["b", "d"]
}
@meta.attribute("db/mysql/databases", attrs)
}.should_not raise_error(ArgumentError)
@@ -455,7 +455,7 @@ describe Chef::Cookbook::Metadata do
lambda {
attrs = {
:choice => [ "a", "b", "c"],
- :default => "d"
+ :default => "d"
}
@meta.attribute("db/mysql/databases", attrs)
}.should raise_error(ArgumentError)
@@ -470,11 +470,11 @@ describe Chef::Cookbook::Metadata do
end
describe "recipes" do
- before(:each) do
+ before(:each) do
@cookbook.recipe_files = [ "default.rb", "enlighten.rb" ]
@meta = Chef::Cookbook::Metadata.new(@cookbook)
end
-
+
it "should have the names of the recipes" do
@meta.recipes["test_cookbook"].should == ""
@meta.recipes["test_cookbook::enlighten"].should == ""
@@ -493,7 +493,7 @@ describe Chef::Cookbook::Metadata do
end
describe "json" do
- before(:each) do
+ before(:each) do
@cookbook.recipe_files = [ "default.rb", "enlighten.rb" ]
@meta = Chef::Cookbook::Metadata.new(@cookbook)
@meta.version "1.0"
@@ -509,8 +509,8 @@ describe Chef::Cookbook::Metadata do
@meta.provides "foo(:bar, :baz)"
@meta.replaces "snarkitron"
@meta.recipe "test_cookbook::enlighten", "is your buddy"
- @meta.attribute "bizspark/has_login",
- :display_name => "You have nothing"
+ @meta.attribute "bizspark/has_login",
+ :display_name => "You have nothing"
@meta.version "1.2.3"
end
@@ -524,23 +524,23 @@ describe Chef::Cookbook::Metadata do
end
%w{
- name
- description
- long_description
- maintainer
- maintainer_email
+ name
+ description
+ long_description
+ maintainer
+ maintainer_email
license
- platforms
- dependencies
- suggestions
- recommendations
- conflicting
+ platforms
+ dependencies
+ suggestions
+ recommendations
+ conflicting
providing
- replacing
- attributes
+ replacing
+ attributes
recipes
version
- }.each do |t|
+ }.each do |t|
it "should include '#{t}'" do
@serial[t].should == @meta.send(t.to_sym)
end
@@ -557,23 +557,23 @@ describe Chef::Cookbook::Metadata do
end
%w{
- name
- description
- long_description
- maintainer
- maintainer_email
+ name
+ description
+ long_description
+ maintainer
+ maintainer_email
license
- platforms
- dependencies
- suggestions
- recommendations
- conflicting
+ platforms
+ dependencies
+ suggestions
+ recommendations
+ conflicting
providing
- replacing
- attributes
+ replacing
+ attributes
recipes
version
- }.each do |t|
+ }.each do |t|
it "should match '#{t}'" do
@deserial.send(t.to_sym).should == @meta.send(t.to_sym)
end
diff --git a/spec/unit/cookbook/synchronizer_spec.rb b/spec/unit/cookbook/synchronizer_spec.rb
index 4c6aa0c0ed..31f30c5bf4 100644
--- a/spec/unit/cookbook/synchronizer_spec.rb
+++ b/spec/unit/cookbook/synchronizer_spec.rb
@@ -176,11 +176,11 @@ describe Chef::CookbookSynchronizer do
@cookbook_a_template_default_tempfile = mock("Tempfile for cookbook_a apache.conf.erb template",
:path => "/tmp/cookbook_a_template_default_tempfile")
end
-
+
after do
Chef::Config[:no_lazy_load] = false
end
-
+
it "fetches templates and cookbook files" do
@file_cache.should_receive(:has_key?).
with("cookbooks/cookbook_a/files/default/megaman.conf").
@@ -206,7 +206,7 @@ describe Chef::CookbookSynchronizer do
@file_cache.should_receive(:load).
with("cookbooks/cookbook_a/templates/default/apache2.conf.erb", false).
and_return("/file-cache/cookbooks/cookbook_a/templates/default/apache2.conf.erb")
-
+
@synchronizer.sync_cookbooks
end
end
diff --git a/spec/unit/cookbook/syntax_check_spec.rb b/spec/unit/cookbook/syntax_check_spec.rb
index 84cd84121b..85d6950a45 100644
--- a/spec/unit/cookbook/syntax_check_spec.rb
+++ b/spec/unit/cookbook/syntax_check_spec.rb
@@ -32,7 +32,7 @@ describe Chef::Cookbook::SyntaxCheck do
@attr_files = %w{default.rb smokey.rb}.map { |f| File.join(cookbook_path, 'attributes', f) }
@defn_files = %w{client.rb server.rb}.map { |f| File.join(cookbook_path, 'definitions', f)}
@recipes = %w{default.rb gigantor.rb one.rb}.map { |f| File.join(cookbook_path, 'recipes', f) }
- @ruby_files = @attr_files + @defn_files + @recipes
+ @ruby_files = @attr_files + @defn_files + @recipes + [File.join(cookbook_path, "metadata.rb")]
basenames = %w{ helpers_via_partial_test.erb
helper_test.erb
openldap_stuff.conf.erb
@@ -74,7 +74,6 @@ describe Chef::Cookbook::SyntaxCheck do
after do
FileUtils.rm_rf(cache_path) if File.exist?(cache_path)
- Chef::Config[:syntax_check_cache_path] = nil
end
describe "and the files have not been syntax checked previously" do
diff --git a/spec/unit/cookbook_loader_spec.rb b/spec/unit/cookbook_loader_spec.rb
index c3303dd09a..4c21c124e0 100644
--- a/spec/unit/cookbook_loader_spec.rb
+++ b/spec/unit/cookbook_loader_spec.rb
@@ -71,7 +71,7 @@ describe Chef::CookbookLoader do
seen[5].should == "openldap"
end
end
-
+
describe "load_cookbooks" do
it "should find all the cookbooks in the cookbook path" do
Chef::Config.cookbook_path << File.expand_path(File.join(CHEF_SPEC_DATA, "hidden-cookbooks"))
@@ -79,7 +79,7 @@ describe Chef::CookbookLoader do
@cookbook_loader.should have_key(:openldap)
@cookbook_loader.should have_key(:apache2)
end
-
+
it "should allow you to override an attribute file via cookbook_path" do
@cookbook_loader[:openldap].attribute_filenames.detect { |f|
f =~ /cookbooks\/openldap\/attributes\/default.rb/
@@ -88,13 +88,13 @@ describe Chef::CookbookLoader do
f =~ /kitchen\/openldap\/attributes\/default.rb/
}.should eql(nil)
end
-
+
it "should load different attribute files from deeper paths" do
@cookbook_loader[:openldap].attribute_filenames.detect { |f|
f =~ /kitchen\/openldap\/attributes\/robinson.rb/
}.should_not eql(nil)
end
-
+
it "should allow you to override a definition file via cookbook_path" do
@cookbook_loader[:openldap].definition_filenames.detect { |f|
f =~ /cookbooks\/openldap\/definitions\/client.rb/
@@ -103,13 +103,13 @@ describe Chef::CookbookLoader do
f =~ /kitchen\/openldap\/definitions\/client.rb/
}.should eql(nil)
end
-
+
it "should load definition files from deeper paths" do
@cookbook_loader[:openldap].definition_filenames.detect { |f|
f =~ /kitchen\/openldap\/definitions\/drewbarrymore.rb/
}.should_not eql(nil)
end
-
+
it "should allow you to override a recipe file via cookbook_path" do
@cookbook_loader[:openldap].recipe_filenames.detect { |f|
f =~ /cookbooks\/openldap\/recipes\/gigantor.rb/
@@ -118,19 +118,19 @@ describe Chef::CookbookLoader do
f =~ /kitchen\/openldap\/recipes\/gigantor.rb/
}.should eql(nil)
end
-
+
it "should load recipe files from deeper paths" do
@cookbook_loader[:openldap].recipe_filenames.detect { |f|
f =~ /kitchen\/openldap\/recipes\/woot.rb/
}.should_not eql(nil)
end
-
+
it "should allow you to have an 'ignore' file, which skips loading files in later cookbooks" do
@cookbook_loader[:openldap].recipe_filenames.detect { |f|
f =~ /kitchen\/openldap\/recipes\/ignoreme.rb/
}.should eql(nil)
end
-
+
it "should find files that start with a ." do
@cookbook_loader[:openldap].file_filenames.detect { |f|
f =~ /\.dotfile$/
@@ -139,9 +139,9 @@ describe Chef::CookbookLoader do
f =~ /\.ssh\/id_rsa$/
}.should =~ /\.ssh\/id_rsa$/
end
-
+
it "should load the metadata for the cookbook" do
- @cookbook_loader.metadata[:openldap].name.should == :openldap
+ @cookbook_loader.metadata[:openldap].name.to_s.should == "openldap"
@cookbook_loader.metadata[:openldap].should be_a_kind_of(Chef::Cookbook::Metadata)
end
@@ -173,6 +173,22 @@ describe Chef::CookbookLoader do
seen.should have_key("openldap")
end
+ it "should not duplicate keys when serialized to JSON" do
+ # Chef JSON serialization will generate duplicate keys if given
+ # a Hash containing matching string and symbol keys. See CHEF-4571.
+ aa = @cookbook_loader["openldap"]
+ aa.to_hash["metadata"].recipes.keys.should_not include(:openldap)
+ aa.to_hash["metadata"].recipes.keys.should include("openldap")
+ expected_desc = "Main Open LDAP configuration"
+ aa.to_hash["metadata"].recipes["openldap"].should == expected_desc
+ raw = aa.to_hash["metadata"].recipes.to_json
+ search_str = "\"openldap\":\""
+ key_idx = raw.index(search_str)
+ key_idx.should be > 0
+ dup_idx = raw[(key_idx + 1)..-1].index(search_str)
+ dup_idx.should be_nil
+ end
+
it "should not load the cookbook again when accessed" do
@cookbook_loader.should_not_receive('load_cookbook')
@cookbook_loader["openldap"]
@@ -202,7 +218,7 @@ describe Chef::CookbookLoader do
end
seen.should have_key("openldap")
seen.should have_key("apache2")
- end
+ end
end
end # loading only one cookbook
end
diff --git a/spec/unit/cookbook_manifest_spec.rb b/spec/unit/cookbook_manifest_spec.rb
index 7da87e93a5..e87b8e1e9a 100644
--- a/spec/unit/cookbook_manifest_spec.rb
+++ b/spec/unit/cookbook_manifest_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -96,7 +96,7 @@ describe "Chef::CookbookVersion manifest" do
:checksum => "csum-host-2",
:specificity => "host-examplehost.example.org"
},
-
+
{
:name => "anotherfile1.rb",
:path => "files/ubuntu-9.10/adirectory/anotherfile1.rb.platform-full-version",
@@ -122,7 +122,7 @@ describe "Chef::CookbookVersion manifest" do
:checksum => "csum-platver-partial-2",
:specificity => "nweubuntu-9"
},
-
+
{
:name => "anotherfile1.rb",
:path => "files/ubuntu/adirectory/anotherfile1.rb.platform",
@@ -135,7 +135,7 @@ describe "Chef::CookbookVersion manifest" do
:checksum => "csum-plat-2",
:specificity => "ubuntu"
},
-
+
{
:name => "anotherfile1.rb",
:path => "files/default/adirectory/anotherfile1.rb.default",
@@ -201,8 +201,8 @@ describe "Chef::CookbookVersion manifest" do
}
end
-
-
+
+
it "should return a manifest record based on priority preference: host" do
node = Chef::Node.new
node.automatic_attrs[:platform] = "ubuntu"
@@ -213,7 +213,7 @@ describe "Chef::CookbookVersion manifest" do
manifest_record.should_not be_nil
manifest_record[:checksum].should == "csum-host"
end
-
+
it "should return a manifest record based on priority preference: platform & full version" do
node = Chef::Node.new
node.automatic_attrs[:platform] = "ubuntu"
@@ -235,7 +235,7 @@ describe "Chef::CookbookVersion manifest" do
manifest_record.should_not be_nil
manifest_record[:checksum].should == "csum-platver-partial"
end
-
+
it "should return a manifest record based on priority preference: platform only" do
node = Chef::Node.new
node.automatic_attrs[:platform] = "ubuntu"
@@ -246,7 +246,7 @@ describe "Chef::CookbookVersion manifest" do
manifest_record.should_not be_nil
manifest_record[:checksum].should == "csum-plat"
end
-
+
it "should return a manifest record based on priority preference: default" do
node = Chef::Node.new
node.automatic_attrs[:platform] = "notubuntu"
@@ -301,7 +301,7 @@ describe "Chef::CookbookVersion manifest" do
manifest_record.should_not be_nil
manifest_record[:checksum].should == "csum4-platver-full"
end
-
+
describe "when fetching the contents of a directory by file specificity" do
it "should return a directory of manifest records based on priority preference: host" do
diff --git a/spec/unit/cookbook_site_streaming_uploader.rb b/spec/unit/cookbook_site_streaming_uploader.rb
new file mode 100644
index 0000000000..73a513494f
--- /dev/null
+++ b/spec/unit/cookbook_site_streaming_uploader.rb
@@ -0,0 +1,200 @@
+#
+# Author:: Xabier de Zuazo (xabier@onddo.com)
+# Copyright:: Copyright (c) 2013 Onddo Labs, SL.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+
+require 'chef/cookbook_site_streaming_uploader'
+
+class FakeTempfile
+ def initialize(basename)
+ @basename = basename
+ end
+
+ def close
+ end
+
+ def path
+ "#{@basename}.ZZZ"
+ end
+
+end
+
+describe Chef::CookbookSiteStreamingUploader do
+
+ describe "create_build_dir" do
+
+ before(:each) do
+ @cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, 'cookbooks'))
+ @loader = Chef::CookbookLoader.new(@cookbook_repo)
+ @loader.load_cookbooks
+ File.stub(:unlink).and_return()
+ end
+
+ it "should create the cookbook tmp dir" do
+ cookbook = @loader[:openldap]
+ files_count = Dir.glob(File.join(@cookbook_repo, cookbook.name.to_s, '**', '*'), File::FNM_DOTMATCH).count { |file| File.file?(file) }
+
+ Tempfile.should_receive(:new).with("chef-#{cookbook.name}-build").and_return(FakeTempfile.new("chef-#{cookbook.name}-build"))
+ FileUtils.should_receive(:mkdir_p).exactly(files_count + 1).times
+ FileUtils.should_receive(:cp).exactly(files_count).times
+ Chef::CookbookSiteStreamingUploader.create_build_dir(cookbook)
+ end
+
+ end # create_build_dir
+
+ describe "make_request" do
+
+ before(:each) do
+ @uri = "http://cookbooks.dummy.com/api/v1/cookbooks"
+ @secret_filename = File.join(CHEF_SPEC_DATA, 'ssl/private_key.pem')
+ @rsa_key = File.read(@secret_filename)
+ response = Net::HTTPResponse.new('1.0', '200', 'OK')
+ Net::HTTP.any_instance.stub(:request).and_return(response)
+ end
+
+ it "should send an http request" do
+ Net::HTTP.any_instance.should_receive(:request)
+ Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
+ end
+
+ it "should read the private key file" do
+ File.should_receive(:read).with(@secret_filename).and_return(@rsa_key)
+ Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
+ end
+
+ it "should add the authentication signed header" do
+ Mixlib::Authentication::SigningObject.any_instance.should_receive(:sign).and_return({})
+ Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
+ end
+
+ it "should be able to send post requests" do
+ post = Net::HTTP::Post.new(@uri, {})
+
+ Net::HTTP::Post.should_receive(:new).once.and_return(post)
+ Net::HTTP::Put.should_not_receive(:new)
+ Net::HTTP::Get.should_not_receive(:new)
+ Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
+ end
+
+ it "should be able to send put requests" do
+ put = Net::HTTP::Put.new(@uri, {})
+
+ Net::HTTP::Post.should_not_receive(:new)
+ Net::HTTP::Put.should_receive(:new).once.and_return(put)
+ Net::HTTP::Get.should_not_receive(:new)
+ Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, 'bill', @secret_filename)
+ end
+
+ it "should be able to receive files to attach as argument" do
+ Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, 'bill', @secret_filename, {
+ :myfile => File.new(File.join(CHEF_SPEC_DATA, 'config.rb')), # a dummy file
+ })
+ end
+
+ it "should be able to receive strings to attach as argument" do
+ Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, 'bill', @secret_filename, {
+ :mystring => 'Lorem ipsum',
+ })
+ end
+
+ it "should be able to receive strings and files as argument at the same time" do
+ Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, 'bill', @secret_filename, {
+ :myfile1 => File.new(File.join(CHEF_SPEC_DATA, 'config.rb')),
+ :mystring1 => 'Lorem ipsum',
+ :myfile2 => File.new(File.join(CHEF_SPEC_DATA, 'config.rb')),
+ :mystring2 => 'Dummy text',
+ })
+ end
+
+ end # make_request
+
+ describe "StreamPart" do
+ before(:each) do
+ @file = File.new(File.join(CHEF_SPEC_DATA, 'config.rb'))
+ @stream_part = Chef::CookbookSiteStreamingUploader::StreamPart.new(@file, File.size(@file))
+ end
+
+ it "should create a StreamPart" do
+ @stream_part.should be_instance_of(Chef::CookbookSiteStreamingUploader::StreamPart)
+ end
+
+ it "should expose its size" do
+ @stream_part.size.should eql(File.size(@file))
+ end
+
+ it "should read with offset and how_much" do
+ content = @file.read(4)
+ @file.rewind
+ @stream_part.read(0, 4).should eql(content)
+ end
+
+ end # StreamPart
+
+ describe "StringPart" do
+ before(:each) do
+ @str = 'What a boring string'
+ @string_part = Chef::CookbookSiteStreamingUploader::StringPart.new(@str)
+ end
+
+ it "should create a StringPart" do
+ @string_part.should be_instance_of(Chef::CookbookSiteStreamingUploader::StringPart)
+ end
+
+ it "should expose its size" do
+ @string_part.size.should eql(@str.size)
+ end
+
+ it "should read with offset and how_much" do
+ @string_part.read(2, 4).should eql(@str[2, 4])
+ end
+
+ end # StringPart
+
+ describe "MultipartStream" do
+ before(:each) do
+ @string1 = "stream1"
+ @string2 = "stream2"
+ @stream1 = Chef::CookbookSiteStreamingUploader::StringPart.new(@string1)
+ @stream2 = Chef::CookbookSiteStreamingUploader::StringPart.new(@string2)
+ @parts = [ @stream1, @stream2 ]
+
+ @multipart_stream = Chef::CookbookSiteStreamingUploader::MultipartStream.new(@parts)
+ end
+
+ it "should create a MultipartStream" do
+ @multipart_stream.should be_instance_of(Chef::CookbookSiteStreamingUploader::MultipartStream)
+ end
+
+ it "should expose its size" do
+ @multipart_stream.size.should eql(@stream1.size + @stream2.size)
+ end
+
+ it "should read with how_much" do
+ @multipart_stream.read(10).should eql("#{@string1}#{@string2}"[0, 10])
+ end
+
+ it "should read receiving destination buffer as second argument (CHEF-4456: Ruby 2 compat)" do
+ dst_buf = ''
+ @multipart_stream.read(10, dst_buf)
+ dst_buf.should eql("#{@string1}#{@string2}"[0, 10])
+ end
+
+ end # MultipartStream
+
+end
+
diff --git a/spec/unit/cookbook_version_spec.rb b/spec/unit/cookbook_version_spec.rb
index 85e1db1fae..d186ef01be 100644
--- a/spec/unit/cookbook_version_spec.rb
+++ b/spec/unit/cookbook_version_spec.rb
@@ -130,6 +130,12 @@ describe Chef::CookbookVersion do
@cookbook_version.provider_filenames = @cookbook[:provider_filenames]
@cookbook_version.root_filenames = @cookbook[:root_filenames]
@cookbook_version.metadata_filenames = @cookbook[:metadata_filenames]
+
+ # Used to test file-specificity related file lookups
+ @node = Chef::Node.new
+ @node.set[:platform] = "ubuntu"
+ @node.set[:platform_version] = "13.04"
+ @node.name("testing")
end
it "generates a manifest containing the cookbook's files" do
@@ -211,6 +217,16 @@ describe Chef::CookbookVersion do
readme["specificity"].should == "default"
end
+ it "determines whether a template is available for a given node" do
+ @cookbook_version.should have_template_for_node(@node, "configuration.erb")
+ @cookbook_version.should_not have_template_for_node(@node, "missing.erb")
+ end
+
+ it "determines whether a cookbook_file is available for a given node" do
+ @cookbook_version.should have_cookbook_file_for_node(@node, "giant_blob.tgz")
+ @cookbook_version.should_not have_cookbook_file_for_node(@node, "missing.txt")
+ end
+
describe "raises an error when attempting to load a missing cookbook_file and" do
before do
node = Chef::Node.new.tap do |n|
diff --git a/spec/unit/daemon_spec.rb b/spec/unit/daemon_spec.rb
index 5c0d828354..8d66e08511 100644
--- a/spec/unit/daemon_spec.rb
+++ b/spec/unit/daemon_spec.rb
@@ -20,7 +20,6 @@ require 'ostruct'
describe Chef::Daemon do
before do
- @original_config = Chef::Config.configuration
if windows?
mock_struct = #Struct::Passwd.new(nil, nil, 111, 111)
mock_struct = OpenStruct.new(:uid => 2342, :gid => 2342)
@@ -33,42 +32,6 @@ describe Chef::Daemon do
end
end
- after do
- Chef::Config.configuration.replace(@original_config)
- end
-
- describe ".running?" do
-
- before do
- Chef::Daemon.name = "spec"
- end
-
- describe "when a pid file exists" do
-
- before do
- Chef::Daemon.stub!(:pid_from_file).and_return(1337)
- end
-
- it "should check that there is a process matching the pidfile" do
- Process.should_receive(:kill).with(0, 1337)
- Chef::Daemon.running?
- end
-
- end
-
- describe "when the pid file is nonexistent" do
-
- before do
- Chef::Daemon.stub!(:pid_from_file).and_return(nil)
- end
-
- it "should return false" do
- Chef::Daemon.running?.should be_false
- end
-
- end
- end
-
describe ".pid_file" do
describe "when the pid_file option has been set" do
@@ -77,10 +40,6 @@ describe Chef::Daemon do
Chef::Config[:pid_file] = "/var/run/chef/chef-client.pid"
end
- after do
- Chef::Config.configuration.replace(@original_config)
- end
-
it "should return the supplied value" do
Chef::Daemon.pid_file.should eql("/var/run/chef/chef-client.pid")
end
@@ -89,7 +48,6 @@ describe Chef::Daemon do
describe "without the pid_file option set" do
before do
- Chef::Config[:pid_file] = nil
Chef::Daemon.name = "chef-client"
end
@@ -112,92 +70,6 @@ describe Chef::Daemon do
end
end
- describe ".save_pid_file" do
-
- before do
- Process.stub!(:pid).and_return(1337)
- Chef::Config[:pid_file] = "/var/run/chef/chef-client.pid"
- Chef::Application.stub!(:fatal!).and_return(true)
- @f_mock = mock(File, { :print => true, :close => true, :write => true })
- File.stub!(:open).with("/var/run/chef/chef-client.pid", "w").and_yield(@f_mock)
- end
-
- it "should try and create the parent directory" do
- FileUtils.should_receive(:mkdir_p).with("/var/run/chef")
- Chef::Daemon.save_pid_file
- end
-
- it "should open the pid file for writing" do
- File.should_receive(:open).with("/var/run/chef/chef-client.pid", "w")
- Chef::Daemon.save_pid_file
- end
-
- it "should write the pid, converted to string, to the pid file" do
- @f_mock.should_receive(:write).with("1337").once.and_return(true)
- Chef::Daemon.save_pid_file
- end
-
- end
-
- describe ".remove_pid_file" do
- before do
- Chef::Config[:pid_file] = "/var/run/chef/chef-client.pid"
- end
-
- describe "when the pid file exists" do
-
- before do
- File.stub!(:exists?).with("/var/run/chef/chef-client.pid").and_return(true)
- end
-
- it "should remove the file" do
- FileUtils.should_receive(:rm).with("/var/run/chef/chef-client.pid")
- Chef::Daemon.remove_pid_file
- end
-
-
- end
-
- describe "when the pid file exists and the process is forked" do
-
- before do
- File.stub!(:exists?).with("/var/run/chef/chef-client.pid").and_return(true)
- Chef::Daemon.stub!(:forked?) { true }
- end
-
- it "should not remove the file" do
- FileUtils.should_not_receive(:rm)
- Chef::Daemon.remove_pid_file
- end
-
- end
-
- describe "when the pid file exists and the process is not forked" do
- before do
- File.stub!(:exists?).with("/var/run/chef/chef-client.pid").and_return(true)
- Chef::Daemon.stub!(:forked?) { false }
- end
-
- it "should remove the file" do
- FileUtils.should_receive(:rm)
- Chef::Daemon.remove_pid_file
- end
- end
-
- describe "when the pid file does not exist" do
-
- before do
- File.stub!(:exists?).with("/var/run/chef/chef-client.pid").and_return(false)
- end
-
- it "should not remove the file" do
- FileUtils.should_not_receive(:rm)
- Chef::Daemon.remove_pid_file
- end
-
- end
- end
-
describe ".change_privilege" do
before do
@@ -230,10 +102,6 @@ describe Chef::Daemon do
end
describe "when just the user option is supplied" do
- before do
- Chef::Config[:group] = nil
- end
-
it "should log an appropriate info message" do
Chef::Log.should_receive(:info).with("About to change privilege to aj")
Chef::Daemon.change_privilege
diff --git a/spec/unit/data_bag_item_spec.rb b/spec/unit/data_bag_item_spec.rb
index 6f46c81054..6bc5954fa5 100644
--- a/spec/unit/data_bag_item_spec.rb
+++ b/spec/unit/data_bag_item_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -130,7 +130,7 @@ describe Chef::DataBagItem do
end
describe "to_hash" do
- before(:each) do
+ before(:each) do
@data_bag_item.data_bag("still_lost")
@data_bag_item.raw_data = { "id" => "whoa", "i_know" => "kung_fu" }
@to_hash = @data_bag_item.to_hash
@@ -197,7 +197,7 @@ describe Chef::DataBagItem do
before do
@rest = mock("Chef::REST")
Chef::REST.stub!(:new).and_return(@rest)
- @data_bag_item['id'] = "heart of darkness"
+ @data_bag_item['id'] = "heart of darkness"
raw_data = {"id" => "heart_of_darkness", "author" => "Conrad"}
@data_bag_item.raw_data = raw_data
@data_bag_item.data_bag("books")
@@ -207,7 +207,7 @@ describe Chef::DataBagItem do
@data_bag_item.save
end
- it "should create if the item is not found" do
+ it "should create if the item is not found" do
exception = mock("404 error", :code => "404")
@rest.should_receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
@rest.should_receive(:post_rest).with("data/books", @data_bag_item)
@@ -228,7 +228,7 @@ describe Chef::DataBagItem do
end
end
-
+
end
describe "when loading" do
diff --git a/spec/unit/data_bag_spec.rb b/spec/unit/data_bag_spec.rb
index 273ef38d9f..9fbdc64d98 100644
--- a/spec/unit/data_bag_spec.rb
+++ b/spec/unit/data_bag_spec.rb
@@ -69,24 +69,23 @@ describe Chef::DataBag do
end
- describe "when saving" do
+ describe "when saving" do
before do
@data_bag.name('piggly_wiggly')
@rest = mock("Chef::REST")
Chef::REST.stub!(:new).and_return(@rest)
end
- it "should update the data bag when it already exists" do
- @rest.should_receive(:put_rest).with("data/piggly_wiggly", @data_bag)
+ it "should silently proceed when the data bag already exists" do
+ exception = mock("409 error", :code => "409")
+ @rest.should_receive(:post_rest).and_raise(Net::HTTPServerException.new("foo", exception))
@data_bag.save
end
- it "should create the data bag when it is not found" do
- exception = mock("404 error", :code => "404")
- @rest.should_receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
+ it "should create the data bag" do
@rest.should_receive(:post_rest).with("data", @data_bag)
@data_bag.save
- end
+ end
describe "when whyrun mode is enabled" do
before do
@@ -96,7 +95,6 @@ describe Chef::DataBag do
Chef::Config[:why_run] = false
end
it "should not save" do
- @rest.should_not_receive(:put_rest)
@rest.should_not_receive(:post_rest)
@data_bag.save
end
diff --git a/spec/unit/digester_spec.rb b/spec/unit/digester_spec.rb
index 28e3e918fe..fdf20aca7c 100644
--- a/spec/unit/digester_spec.rb
+++ b/spec/unit/digester_spec.rb
@@ -8,9 +8,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/encrypted_data_bag_item_spec.rb b/spec/unit/encrypted_data_bag_item_spec.rb
index 9eda1633ab..18178d28b6 100644
--- a/spec/unit/encrypted_data_bag_item_spec.rb
+++ b/spec/unit/encrypted_data_bag_item_spec.rb
@@ -74,14 +74,9 @@ describe Chef::EncryptedDataBagItem::Encryptor do
describe "when using version 2 format" do
before do
- @original_config = Chef::Config.hash_dup
Chef::Config[:data_bag_encrypt_version] = 2
end
- after do
- Chef::Config.configuration = @original_config
- end
-
it "creates a version 2 encryptor" do
encryptor.should be_a_kind_of(Chef::EncryptedDataBagItem::Encryptor::Version2Encryptor)
end
@@ -179,14 +174,9 @@ describe Chef::EncryptedDataBagItem::Decryptor do
context "and version 2 format is required" do
before do
- @original_config = Chef::Config.hash_dup
Chef::Config[:data_bag_decrypt_minimum_version] = 2
end
- after do
- Chef::Config.configuration = @original_config
- end
-
it "raises an error attempting to decrypt" do
lambda { decryptor }.should raise_error(Chef::EncryptedDataBagItem::UnacceptableEncryptedDataBagItemFormat)
end
@@ -210,14 +200,9 @@ describe Chef::EncryptedDataBagItem::Decryptor do
context "and version 1 format is required" do
before do
- @original_config = Chef::Config.hash_dup
Chef::Config[:data_bag_decrypt_minimum_version] = 1
end
- after do
- Chef::Config.configuration = @original_config
- end
-
it "raises an error attempting to decrypt" do
lambda { decryptor }.should raise_error(Chef::EncryptedDataBagItem::UnacceptableEncryptedDataBagItemFormat)
end
diff --git a/spec/unit/file_cache_spec.rb b/spec/unit/file_cache_spec.rb
index 6596326565..7680852cb9 100644
--- a/spec/unit/file_cache_spec.rb
+++ b/spec/unit/file_cache_spec.rb
@@ -41,7 +41,7 @@ describe Chef::FileCache do
end
end
-
+
describe "when storing a file" do
before do
File.stub!(:open).and_yield(@io)
diff --git a/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb
index e1f8f28bb9..0b20b0ef86 100644
--- a/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -98,7 +98,7 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
before do
Chef::Config.stub!(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ])
recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" }
- IO.should_receive(:readlines).at_least(1).times.with(/:\/opscode\/chef\/var\/cache\/cookbooks\/foo\/recipes\/default.rb/).and_return(recipe_lines)
+ IO.should_receive(:readlines).at_least(1).times.with(/:\/opscode\/chef\/var\/cache\/cookbooks\/foo\/recipes\/default.rb/).and_return(recipe_lines)
@trace = [
"C:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb:14 in `from_file'",
"C:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:144:in `rescue in block in load_libraries'",
@@ -141,7 +141,7 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
@inspector.add_explanation(@description)
@inspector.culprit_file.should == "c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb"
end
- end
+ end
it "finds the line number of the error from the stack trace" do
@inspector.culprit_line.should == 14
diff --git a/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
index cf668fbb0d..93129eadb8 100644
--- a/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb
index 6db7aaaa0d..eb8d302e5b 100644
--- a/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/formatters/error_inspectors/node_load_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/node_load_error_inspector_spec.rb
index bd3cc6b764..d2bbffafee 100644
--- a/spec/unit/formatters/error_inspectors/node_load_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/node_load_error_inspector_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/formatters/error_inspectors/registration_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/registration_error_inspector_spec.rb
index 4fcf034d80..4c21dadd82 100644
--- a/spec/unit/formatters/error_inspectors/registration_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/registration_error_inspector_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb b/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb
index b6d48d0255..fdbb601005 100644
--- a/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -129,7 +129,7 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
@inspector.recipe_snippet.should match(/^# In \/home\/btm/)
end
-
+
context "when the recipe file does not exist" do
before do
File.stub!(:exists?).and_return(false)
@@ -141,7 +141,7 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
@inspector.recipe_snippet.should be_nil
end
-
+
it "does not raise an exception trying to load a non-existant file (CHEF-3411)" do
@resource.source_line = "/somewhere/in/space"
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
diff --git a/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb
index 4b6751a120..706ff59c06 100644
--- a/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/handler_spec.rb b/spec/unit/handler_spec.rb
index 9eeba478ac..eab98e76a2 100644
--- a/spec/unit/handler_spec.rb
+++ b/spec/unit/handler_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -126,9 +126,9 @@ describe Chef::Handler do
@end_time = @start_time + 4.2
Time.stub!(:now).and_return(@start_time, @end_time)
@run_status.start_clock
- @run_status.stop_clock
+ @run_status.stop_clock
end
-
+
it "has a shortcut for all resources" do
@handler.all_resources.should == @all_resources
end
@@ -158,7 +158,7 @@ describe Chef::Handler do
end
it "has a shortcut for the success? and failed? predicates" do
- @handler.success?.should be_true
+ @handler.success?.should be_true
@handler.failed?.should be_false
end
diff --git a/spec/unit/http/ssl_policies_spec.rb b/spec/unit/http/ssl_policies_spec.rb
new file mode 100644
index 0000000000..c80f989180
--- /dev/null
+++ b/spec/unit/http/ssl_policies_spec.rb
@@ -0,0 +1,161 @@
+#--
+# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Copyright:: Copyright (c) 2009, 2010, 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+require 'chef/http/ssl_policies'
+
+describe "HTTP SSL Policy" do
+
+ before do
+ Chef::Config[:ssl_client_cert] = nil
+ Chef::Config[:ssl_client_key] = nil
+ Chef::Config[:ssl_ca_path] = nil
+ Chef::Config[:ssl_ca_file] = nil
+ end
+
+ let(:unconfigured_http_client) { Net::HTTP.new("example.com", 443) }
+ let(:http_client) do
+ unconfigured_http_client.use_ssl = true
+ ssl_policy.apply
+ unconfigured_http_client
+ end
+
+ describe Chef::HTTP::DefaultSSLPolicy do
+
+ let(:ssl_policy) { Chef::HTTP::DefaultSSLPolicy.new(unconfigured_http_client) }
+
+ describe "when configured with :ssl_verify_mode set to :verify peer" do
+ before do
+ Chef::Config[:ssl_verify_mode] = :verify_peer
+ end
+
+ it "configures the HTTP client to use SSL when given a URL with the https protocol" do
+ http_client.use_ssl?.should be_true
+ end
+
+ it "sets the OpenSSL verify mode to verify_peer" do
+ http_client.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
+ end
+
+ it "raises a ConfigurationError if :ssl_ca_path is set to a path that doesn't exist" do
+ Chef::Config[:ssl_ca_path] = "/dev/null/nothing_here"
+ lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ end
+
+ it "should set the CA path if that is set in the configuration" do
+ Chef::Config[:ssl_ca_path] = File.join(CHEF_SPEC_DATA, "ssl")
+ http_client.ca_path.should == File.join(CHEF_SPEC_DATA, "ssl")
+ end
+
+ it "raises a ConfigurationError if :ssl_ca_file is set to a file that does not exist" do
+ Chef::Config[:ssl_ca_file] = "/dev/null/nothing_here"
+ lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ end
+
+ it "should set the CA file if that is set in the configuration" do
+ Chef::Config[:ssl_ca_file] = CHEF_SPEC_DATA + '/ssl/5e707473.0'
+ http_client.ca_file.should == CHEF_SPEC_DATA + '/ssl/5e707473.0'
+ end
+ end
+
+ describe "when configured with :ssl_verify_mode set to :verify peer" do
+ before do
+ @url = URI.parse("https://chef.example.com:4443/")
+ Chef::Config[:ssl_verify_mode] = :verify_none
+ end
+
+ it "sets the OpenSSL verify mode to :verify_none" do
+ http_client.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
+ end
+ end
+
+ describe "when configured with a client certificate" do
+ before {@url = URI.parse("https://chef.example.com:4443/")}
+
+ it "raises ConfigurationError if the certificate file doesn't exist" do
+ Chef::Config[:ssl_client_cert] = "/dev/null/nothing_here"
+ Chef::Config[:ssl_client_key] = CHEF_SPEC_DATA + '/ssl/chef-rspec.key'
+ lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ end
+
+ it "raises ConfigurationError if the certificate file doesn't exist" do
+ Chef::Config[:ssl_client_cert] = CHEF_SPEC_DATA + '/ssl/chef-rspec.cert'
+ Chef::Config[:ssl_client_key] = "/dev/null/nothing_here"
+ lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ end
+
+ it "raises a ConfigurationError if one of :ssl_client_cert and :ssl_client_key is set but not both" do
+ Chef::Config[:ssl_client_cert] = "/dev/null/nothing_here"
+ Chef::Config[:ssl_client_key] = nil
+ lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ end
+
+ it "configures the HTTP client's cert and private key" do
+ Chef::Config[:ssl_client_cert] = CHEF_SPEC_DATA + '/ssl/chef-rspec.cert'
+ Chef::Config[:ssl_client_key] = CHEF_SPEC_DATA + '/ssl/chef-rspec.key'
+ http_client.cert.to_s.should == OpenSSL::X509::Certificate.new(IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.cert')).to_s
+ http_client.key.to_s.should == IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.key')
+ end
+ end
+
+ context "when additional certs are located in the trusted_certs dir" do
+ let(:self_signed_crt_path) { File.join(CHEF_SPEC_DATA, "trusted_certs", "example.crt") }
+ let(:self_signed_crt) { OpenSSL::X509::Certificate.new(File.read(self_signed_crt_path)) }
+
+ let(:additional_pem_path) { File.join(CHEF_SPEC_DATA, "trusted_certs", "opscode.pem") }
+ let(:additional_pem) { OpenSSL::X509::Certificate.new(File.read(additional_pem_path)) }
+
+ before do
+ Chef::Config.trusted_certs_dir = File.join(CHEF_SPEC_DATA, "trusted_certs")
+ end
+
+ it "enables verification of self-signed certificates" do
+ http_client.cert_store.verify(self_signed_crt).should be_true
+ end
+
+ it "enables verification of cert chains" do
+ # This cert is signed by DigiCert so it would be valid in normal SSL usage.
+ # The chain goes:
+ # trusted root -> intermediate -> opscode.pem
+ # In this test, the intermediate has to be loaded and trusted in order
+ # for verification to work correctly.
+ # If the machine running the test doesn't have ruby SSL configured correctly,
+ # then the root cert also has to be loaded for the test to succeed.
+ # The system under test **SHOULD** do both of these things.
+ http_client.cert_store.verify(additional_pem).should be_true
+ end
+ end
+ end
+
+ describe Chef::HTTP::APISSLPolicy do
+
+ let(:ssl_policy) { Chef::HTTP::APISSLPolicy.new(unconfigured_http_client) }
+
+ context "when verify_api_cert is set" do
+ before do
+ Chef::Config[:verify_api_cert] = true
+ end
+
+ it "sets the OpenSSL verify mode to verify_peer" do
+ http_client.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
+ end
+ end
+
+ end
+end
+
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index c716896302..cc0336d8f6 100644
--- a/spec/unit/knife/bootstrap_spec.rb
+++ b/spec/unit/knife/bootstrap_spec.rb
@@ -22,16 +22,6 @@ Chef::Knife::Bootstrap.load_deps
require 'net/ssh'
describe Chef::Knife::Bootstrap do
- before(:all) do
- @original_config = Chef::Config.hash_dup
- @original_knife_config = Chef::Config[:knife].dup
- end
-
- after(:all) do
- Chef::Config.configuration = @original_config
- Chef::Config[:knife] = @original_knife_config
- end
-
before(:each) do
Chef::Log.logger = Logger.new(StringIO.new)
@knife = Chef::Knife::Bootstrap.new
@@ -133,6 +123,34 @@ describe Chef::Knife::Bootstrap do
@knife.name_args.first.should == "barf"
end
+ describe "specifying no_proxy with various entries" do
+ subject(:knife) { described_class.new }
+ let(:options){ ["--bootstrap-no-proxy", setting] }
+ let(:template_file) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "no_proxy.erb")) }
+ let(:rendered_template) do
+ knife.instance_variable_set("@template_file", template_file)
+ knife.parse_options(options)
+ template_string = knife.read_template
+ knife.render_template(template_string)
+ end
+
+ context "via --bootstrap-no-proxy" do
+ let(:setting) { "api.opscode.com" }
+
+ it "renders the client.rb with a single FQDN no_proxy entry" do
+ rendered_template.should match(%r{.*no_proxy\s*"api.opscode.com".*})
+ end
+ end
+
+ context "via --bootstrap-no-proxy multiple" do
+ let(:setting) { "api.opscode.com,172.16.10.*" }
+
+ it "renders the client.rb with comma-separated FQDN and wildcard IP address no_proxy entries" do
+ rendered_template.should match(%r{.*no_proxy\s*"api.opscode.com,172.16.10.\*".*})
+ end
+ end
+ end
+
describe "specifying the encrypted data bag secret key" do
subject(:knife) { described_class.new }
let(:secret) { "supersekret" }
@@ -182,7 +200,6 @@ describe Chef::Knife::Bootstrap do
it "renders the client.rb with an encrypted_data_bag_secret entry" do
rendered_template.should match(%r{encrypted_data_bag_secret\s*"/etc/chef/encrypted_data_bag_secret"})
end
- after(:each) { Chef::Config.configuration = @original_config }
end
end
@@ -216,7 +233,7 @@ describe Chef::Knife::Bootstrap do
it "configures the ssh port" do
@knife_ssh.config[:ssh_port].should == '4001'
end
-
+
it "configures the ssh agent forwarding" do
@knife_ssh.config[:forward_agent].should == true
end
@@ -241,7 +258,7 @@ describe Chef::Knife::Bootstrap do
it "uses the password from --ssh-password for sudo when --use-sudo-password is set" do
@knife.config[:use_sudo] = true
@knife.config[:use_sudo_password] = true
- @knife.ssh_command.should include("echo #{@knife.config[:ssh_password]} | sudo -S")
+ @knife.ssh_command.should include("echo \'#{@knife.config[:ssh_password]}\' | sudo -S")
end
it "should not honor --use-sudo-password when --use-sudo is not set" do
@@ -276,7 +293,7 @@ describe Chef::Knife::Bootstrap do
it "configures the ssh port" do
@knife_ssh.config[:ssh_port].should == '2430'
end
-
+
it "configures the ssh agent forwarding" do
@knife_ssh.config[:forward_agent].should == true
end
diff --git a/spec/unit/knife/client_bulk_delete_spec.rb b/spec/unit/knife/client_bulk_delete_spec.rb
index 55351554d1..b7864ed098 100644
--- a/spec/unit/knife/client_bulk_delete_spec.rb
+++ b/spec/unit/knife/client_bulk_delete_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -37,31 +37,31 @@ describe Chef::Knife::ClientBulkDelete do
end
Chef::ApiClient.stub!(:list).and_return(@clients)
end
-
+
describe "run" do
-
+
it "should get the list of the clients" do
Chef::ApiClient.should_receive(:list).and_return(@clients)
@knife.run
end
-
+
it "should print the clients you are about to delete" do
@knife.run
@stdout.string.should match(/#{@knife.ui.list(@clients.keys.sort, :columns_down)}/)
end
-
+
it "should confirm you really want to delete them" do
@knife.ui.should_receive(:confirm)
@knife.run
end
-
+
it "should delete each client" do
@clients.each_value do |c|
c.should_receive(:destroy)
end
@knife.run
end
-
+
it "should only delete clients that match the regex" do
@knife.name_args = ["tim"]
@clients["tim"].should_receive(:destroy)
diff --git a/spec/unit/knife/client_create_spec.rb b/spec/unit/knife/client_create_spec.rb
index c049748074..d07b6ceb17 100644
--- a/spec/unit/knife/client_create_spec.rb
+++ b/spec/unit/knife/client_create_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/client_delete_spec.rb b/spec/unit/knife/client_delete_spec.rb
index 865f19f713..9ebccbae15 100644
--- a/spec/unit/knife/client_delete_spec.rb
+++ b/spec/unit/knife/client_delete_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/client_edit_spec.rb b/spec/unit/knife/client_edit_spec.rb
index 1308d14fd5..1d7049be30 100644
--- a/spec/unit/knife/client_edit_spec.rb
+++ b/spec/unit/knife/client_edit_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/client_list_spec.rb b/spec/unit/knife/client_list_spec.rb
index 6237a0d14c..c4834ad8d1 100644
--- a/spec/unit/knife/client_list_spec.rb
+++ b/spec/unit/knife/client_list_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/client_reregister_spec.rb b/spec/unit/knife/client_reregister_spec.rb
index d9fc8ec180..d84978c497 100644
--- a/spec/unit/knife/client_reregister_spec.rb
+++ b/spec/unit/knife/client_reregister_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/client_show_spec.rb b/spec/unit/knife/client_show_spec.rb
index 5bac3b4af6..ce5f93ab5f 100644
--- a/spec/unit/knife/client_show_spec.rb
+++ b/spec/unit/knife/client_show_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/config_file_selection_spec.rb b/spec/unit/knife/config_file_selection_spec.rb
index 3ee18d82d0..127e89be9b 100644
--- a/spec/unit/knife/config_file_selection_spec.rb
+++ b/spec/unit/knife/config_file_selection_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,14 +20,38 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require 'tmpdir'
describe Chef::Knife do
+
+ let(:missing_config_fetcher) do
+ double(Chef::ConfigFetcher, :config_missing? => true)
+ end
+
+ let(:available_config_fetcher) do
+ double(Chef::ConfigFetcher, :config_missing? => false,
+ :read_config => "")
+ end
+
+ def have_config_file(path)
+ Chef::ConfigFetcher.should_receive(:new).at_least(1).times.with(path, nil).and_return(available_config_fetcher)
+ end
+
+ before do
+ # Make sure tests can run when HOME is not set...
+ @original_home = ENV["HOME"]
+ ENV["HOME"] = Dir.tmpdir
+ end
+
+ after do
+ ENV["HOME"] = @original_home
+ end
+
before :each do
Chef::Config.stub!(:from_file).and_return(true)
+ Chef::ConfigFetcher.stub(:new).and_return(missing_config_fetcher)
end
it "configure knife from KNIFE_HOME env variable" do
env_config = File.expand_path(File.join(Dir.tmpdir, 'knife.rb'))
- File.stub!(:exist?).and_return(false)
- File.stub!(:exist?).with(env_config).and_return(true)
+ have_config_file(env_config)
ENV['KNIFE_HOME'] = Dir.tmpdir
@knife = Chef::Knife.new
@@ -37,39 +61,33 @@ describe Chef::Knife do
it "configure knife from PWD" do
pwd_config = "#{Dir.pwd}/knife.rb"
- File.stub!(:exist?).and_return do | arg |
- [ pwd_config ].include? arg
- end
+ have_config_file(pwd_config)
@knife = Chef::Knife.new
@knife.configure_chef
@knife.config[:config_file].should == pwd_config
end
-
+
it "configure knife from UPWARD" do
upward_dir = File.expand_path "#{Dir.pwd}/.chef"
upward_config = File.expand_path "#{upward_dir}/knife.rb"
- File.stub!(:exist?).and_return do | arg |
- [ upward_config ].include? arg
- end
+ have_config_file(upward_config)
Chef::Knife.stub!(:chef_config_dir).and_return(upward_dir)
-
+
@knife = Chef::Knife.new
@knife.configure_chef
@knife.config[:config_file].should == upward_config
end
-
+
it "configure knife from HOME" do
home_config = File.expand_path(File.join("#{ENV['HOME']}", "/.chef/knife.rb"))
- File.stub!(:exist?).and_return do | arg |
- [ home_config ].include? arg
- end
-
+ have_config_file(home_config)
+
@knife = Chef::Knife.new
@knife.configure_chef
@knife.config[:config_file].should == home_config
end
-
+
it "configure knife from nothing" do
::File.stub!(:exist?).and_return(false)
@knife = Chef::Knife.new
@@ -77,7 +95,7 @@ describe Chef::Knife do
@knife.configure_chef
@knife.config[:config_file].should be_nil
end
-
+
it "configure knife precedence" do
env_config = File.join(Dir.tmpdir, 'knife.rb')
pwd_config = "#{Dir.pwd}/knife.rb"
@@ -85,34 +103,33 @@ describe Chef::Knife do
upward_config = File.expand_path "#{upward_dir}/knife.rb"
home_config = File.expand_path(File.join("#{ENV['HOME']}", "/.chef/knife.rb"))
configs = [ env_config, pwd_config, upward_config, home_config ]
- File.stub!(:exist?).and_return do | arg |
- configs.include? arg
- end
+
Chef::Knife.stub!(:chef_config_dir).and_return(upward_dir)
ENV['KNIFE_HOME'] = Dir.tmpdir
-
+
@knife = Chef::Knife.new
+
@knife.configure_chef
- @knife.config[:config_file].should == env_config
-
- configs.delete env_config
- @knife.config.delete :config_file
+ @knife.config[:config_file].should be_nil
+
+ have_config_file(home_config)
+ @knife = Chef::Knife.new
@knife.configure_chef
- @knife.config[:config_file].should == pwd_config
+ @knife.config[:config_file].should == home_config
- configs.delete pwd_config
- @knife.config.delete :config_file
+ have_config_file(upward_config)
+ @knife = Chef::Knife.new
@knife.configure_chef
@knife.config[:config_file].should == upward_config
- configs.delete upward_config
- @knife.config.delete :config_file
+ have_config_file(pwd_config)
+ @knife = Chef::Knife.new
@knife.configure_chef
- @knife.config[:config_file].should == home_config
+ @knife.config[:config_file].should == pwd_config
- configs.delete home_config
- @knife.config.delete :config_file
+ have_config_file(env_config)
+ @knife = Chef::Knife.new
@knife.configure_chef
- @knife.config[:config_file].should be_nil
+ @knife.config[:config_file].should == env_config
end
end
diff --git a/spec/unit/knife/configure_spec.rb b/spec/unit/knife/configure_spec.rb
index 3fe4f86eb9..7c48be6727 100644
--- a/spec/unit/knife/configure_spec.rb
+++ b/spec/unit/knife/configure_spec.rb
@@ -4,8 +4,6 @@ describe Chef::Knife::Configure do
before do
Chef::Log.logger = Logger.new(StringIO.new)
- @original_config = Chef::Config.configuration.dup
-
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::Configure.new
@rest_client = mock("null rest client", :post_rest => { :result => :true })
@@ -24,10 +22,6 @@ describe Chef::Knife::Configure do
Ohai::System.stub!(:new).and_return(ohai)
end
- after do
- Chef::Config.configuration.replace(@original_config)
- end
-
let(:fqdn) { "foo.example.org" }
diff --git a/spec/unit/knife/cookbook_create_spec.rb b/spec/unit/knife/cookbook_create_spec.rb
index dc1d7d7f79..7891115285 100644
--- a/spec/unit/knife/cookbook_create_spec.rb
+++ b/spec/unit/knife/cookbook_create_spec.rb
@@ -245,15 +245,8 @@ describe Chef::Knife::CookbookCreate do
@knife.run
end
- it "should create a CHANGELOG file" do
- @dir = Dir.tmpdir
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.run
- end
-
- context "when the cookbooks path is not specified in the config file nor supplied via parameter" do
+ context "when the cookbooks path is set to nil" do
before do
- @old_cookbook_path = Chef::Config[:cookbook_path]
Chef::Config[:cookbook_path] = nil
end
@@ -261,10 +254,6 @@ describe Chef::Knife::CookbookCreate do
@dir = Dir.tmpdir
lambda{@knife.run}.should raise_error(ArgumentError)
end
-
- after do
- Chef::Config[:cookbook_path] = @old_cookbook_path
- end
end
end
diff --git a/spec/unit/knife/cookbook_metadata_from_file_spec.rb b/spec/unit/knife/cookbook_metadata_from_file_spec.rb
index 60555d89dc..6f406de6b7 100644
--- a/spec/unit/knife/cookbook_metadata_from_file_spec.rb
+++ b/spec/unit/knife/cookbook_metadata_from_file_spec.rb
@@ -8,9 +8,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/cookbook_show_spec.rb b/spec/unit/knife/cookbook_show_spec.rb
index 2f2d841fea..96fe738b0b 100644
--- a/spec/unit/knife/cookbook_show_spec.rb
+++ b/spec/unit/knife/cookbook_show_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -171,7 +171,7 @@ describe Chef::Knife::CookbookShow do
@response = "Example recipe text"
end
-
+
describe "with --fqdn" do
it "should pass the fqdn" do
@knife.config[:platform] = "example_platform"
diff --git a/spec/unit/knife/cookbook_site_install_spec.rb b/spec/unit/knife/cookbook_site_install_spec.rb
index 43afe09f5e..f7d7a397e6 100644
--- a/spec/unit/knife/cookbook_site_install_spec.rb
+++ b/spec/unit/knife/cookbook_site_install_spec.rb
@@ -25,7 +25,7 @@ describe Chef::Knife::CookbookSiteInstall do
@knife.config = {}
if Chef::Platform.windows?
@install_path = 'C:/tmp/chef'
- else
+ else
@install_path = '/var/tmp/chef'
end
@knife.config[:cookbook_path] = [ @install_path ]
diff --git a/spec/unit/knife/core/bootstrap_context_spec.rb b/spec/unit/knife/core/bootstrap_context_spec.rb
index 808a6f27ad..47261e2068 100644
--- a/spec/unit/knife/core/bootstrap_context_spec.rb
+++ b/spec/unit/knife/core/bootstrap_context_spec.rb
@@ -118,14 +118,22 @@ EXPECTED
describe "when an encrypted_data_bag_secret is provided" do
context "via config[:secret]" do
- let(:config){ {:secret => "supersekret" }}
+ let(:chef_config) do
+ {
+ :knife => {:secret => "supersekret" }
+ }
+ end
it "reads the encrypted_data_bag_secret" do
bootstrap_context.encrypted_data_bag_secret.should eq "supersekret"
end
end
context "via config[:secret_file]" do
- let(:config){ {:secret_file => secret_file}}
+ let(:chef_config) do
+ {
+ :knife => {:secret_file => secret_file}
+ }
+ end
it "reads the encrypted_data_bag_secret" do
bootstrap_context.encrypted_data_bag_secret.should eq IO.read(secret_file)
end
diff --git a/spec/unit/knife/data_bag_show_spec.rb b/spec/unit/knife/data_bag_show_spec.rb
index 08ecfaa0a7..d64b4f286d 100644
--- a/spec/unit/knife/data_bag_show_spec.rb
+++ b/spec/unit/knife/data_bag_show_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/environment_from_file_spec.rb b/spec/unit/knife/environment_from_file_spec.rb
index d2234d9be1..7d028ae3b8 100644
--- a/spec/unit/knife/environment_from_file_spec.rb
+++ b/spec/unit/knife/environment_from_file_spec.rb
@@ -49,13 +49,13 @@ describe Chef::Knife::EnvironmentFromFile do
@env_apple.name("apple")
@knife.loader.stub!(:load_from).with("apple.rb").and_return @env_apple
end
-
+
it "loads multiple environments if given" do
@knife.name_args = [ "spec.rb", "apple.rb" ]
@environment.should_receive(:save).twice
@knife.run
end
-
+
it "loads all environments with -a" do
File.stub!(:expand_path).with("./environments/*.{json,rb}").and_return("/tmp/environments")
Dir.stub!(:glob).with("/tmp/environments").and_return(["spec.rb", "apple.rb"])
diff --git a/spec/unit/knife/index_rebuild_spec.rb b/spec/unit/knife/index_rebuild_spec.rb
index 414ec95fad..eb4e8020c8 100644
--- a/spec/unit/knife/index_rebuild_spec.rb
+++ b/spec/unit/knife/index_rebuild_spec.rb
@@ -91,7 +91,7 @@ describe Chef::Knife::IndexRebuild do
context "against a Chef 11 server" do
let(:api_info) do
- {"flavor" => "osc",
+ {"flavor" => "osc",
"version" => "11.0.0",
"erchef" => "1.2.3"
}
diff --git a/spec/unit/knife/node_delete_spec.rb b/spec/unit/knife/node_delete_spec.rb
index b1b3db1aa4..bc30ae7e83 100644
--- a/spec/unit/knife/node_delete_spec.rb
+++ b/spec/unit/knife/node_delete_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,7 +28,7 @@ describe Chef::Knife::NodeDelete do
@knife.name_args = [ "adam" ]
@knife.stub!(:output).and_return(true)
@knife.stub!(:confirm).and_return(true)
- @node = Chef::Node.new()
+ @node = Chef::Node.new()
@node.stub!(:destroy).and_return(true)
Chef::Node.stub!(:load).and_return(@node)
@stdout = StringIO.new
diff --git a/spec/unit/knife/node_edit_spec.rb b/spec/unit/knife/node_edit_spec.rb
index 0ba2e90cfe..e8f6937a31 100644
--- a/spec/unit/knife/node_edit_spec.rb
+++ b/spec/unit/knife/node_edit_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/node_list_spec.rb b/spec/unit/knife/node_list_spec.rb
index 5637d679c8..3482eab87c 100644
--- a/spec/unit/knife/node_list_spec.rb
+++ b/spec/unit/knife/node_list_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -49,7 +49,7 @@ describe Chef::Knife::NodeList do
Chef::Node.should_receive(:list_by_environment).with("prod").and_return(@list)
@knife.run
end
-
+
describe "with -w or --with-uri" do
it "should pretty print the hash" do
@knife.config[:with_uri] = true
diff --git a/spec/unit/knife/node_run_list_add_spec.rb b/spec/unit/knife/node_run_list_add_spec.rb
index ee0cfc9038..80e372c30a 100644
--- a/spec/unit/knife/node_run_list_add_spec.rb
+++ b/spec/unit/knife/node_run_list_add_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,7 +27,7 @@ describe Chef::Knife::NodeRunListAdd do
}
@knife.name_args = [ "adam", "role[monkey]" ]
@knife.stub!(:output).and_return(true)
- @node = Chef::Node.new()
+ @node = Chef::Node.new()
@node.stub!(:save).and_return(true)
Chef::Node.stub!(:load).and_return(@node)
end
diff --git a/spec/unit/knife/node_show_spec.rb b/spec/unit/knife/node_show_spec.rb
index 6600b2aa96..eb3593fea1 100644
--- a/spec/unit/knife/node_show_spec.rb
+++ b/spec/unit/knife/node_show_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,7 +29,7 @@ describe Chef::Knife::NodeShow do
}
@knife.name_args = [ "adam" ]
@knife.stub!(:output).and_return(true)
- @node = Chef::Node.new()
+ @node = Chef::Node.new()
Chef::Node.stub!(:load).and_return(@node)
end
diff --git a/spec/unit/knife/role_create_spec.rb b/spec/unit/knife/role_create_spec.rb
index af3a6bf539..39fed8fb68 100644
--- a/spec/unit/knife/role_create_spec.rb
+++ b/spec/unit/knife/role_create_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,7 +27,7 @@ describe Chef::Knife::RoleCreate do
}
@knife.name_args = [ "adam" ]
@knife.stub!(:output).and_return(true)
- @role = Chef::Role.new()
+ @role = Chef::Role.new()
@role.stub!(:save)
Chef::Role.stub!(:new).and_return(@role)
@knife.stub!(:edit_data).and_return(@role)
diff --git a/spec/unit/knife/role_delete_spec.rb b/spec/unit/knife/role_delete_spec.rb
index d2d8b889b3..37b16de7df 100644
--- a/spec/unit/knife/role_delete_spec.rb
+++ b/spec/unit/knife/role_delete_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,7 +28,7 @@ describe Chef::Knife::RoleDelete do
@knife.name_args = [ "adam" ]
@knife.stub!(:output).and_return(true)
@knife.stub!(:confirm).and_return(true)
- @role = Chef::Role.new()
+ @role = Chef::Role.new()
@role.stub!(:destroy).and_return(true)
Chef::Role.stub!(:load).and_return(@role)
@stdout = StringIO.new
diff --git a/spec/unit/knife/role_list_spec.rb b/spec/unit/knife/role_list_spec.rb
index 1a5e8e2a72..d0cd3b4413 100644
--- a/spec/unit/knife/role_list_spec.rb
+++ b/spec/unit/knife/role_list_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/knife/ssh_spec.rb b/spec/unit/knife/ssh_spec.rb
index 7f1ed0e321..0d67f33ee7 100644
--- a/spec/unit/knife/ssh_spec.rb
+++ b/spec/unit/knife/ssh_spec.rb
@@ -21,17 +21,10 @@ require 'net/ssh'
require 'net/ssh/multi'
describe Chef::Knife::Ssh do
- before(:all) do
- @original_config = Chef::Config.hash_dup
- @original_knife_config = Chef::Config[:knife].dup
+ before(:each) do
Chef::Config[:client_key] = CHEF_SPEC_DATA + "/ssl/private_key.pem"
end
- after(:all) do
- Chef::Config.configuration = @original_config
- Chef::Config[:knife] = @original_knife_config
- end
-
before do
@knife = Chef::Knife::Ssh.new
@knife.merge_configs
diff --git a/spec/unit/knife_spec.rb b/spec/unit/knife_spec.rb
index 4c5bb3e207..3edddec374 100644
--- a/spec/unit/knife_spec.rb
+++ b/spec/unit/knife_spec.rb
@@ -203,7 +203,6 @@ describe Chef::Knife do
KnifeSpecs::TestYourself.option(:opt_with_default,
:short => "-D VALUE",
:default => "default-value")
- Chef::Config[:knife] = {}
end
it "prefers the default value if no config or command line value is present" do
@@ -227,7 +226,6 @@ describe Chef::Knife do
end
end
-
end
describe "when first created" do
diff --git a/spec/unit/log_spec.rb b/spec/unit/log_spec.rb
index b91ee020bb..7be40f77e6 100644
--- a/spec/unit/log_spec.rb
+++ b/spec/unit/log_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/mash_spec.rb b/spec/unit/mash_spec.rb
index b9a7cd0932..7358781e60 100644
--- a/spec/unit/mash_spec.rb
+++ b/spec/unit/mash_spec.rb
@@ -35,7 +35,7 @@ describe Mash do
@copy = @orig.dup
@copy.to_hash.should == Mash.new(data).to_hash
@copy[:z] << 4
- @orig[:z].should == [1,2,3]
+ @orig[:z].should == [1,2,3]
end
it "should duplicate a nested mash to a new mash" do
@@ -44,7 +44,7 @@ describe Mash do
@copy = @orig.dup
@copy.to_hash.should == Mash.new(data).to_hash
@copy[:z][:a] << 4
- @orig[:z][:a].should == [1,2,3]
+ @orig[:z][:a].should == [1,2,3]
end
# add more!
diff --git a/spec/unit/mixin/checksum_spec.rb b/spec/unit/mixin/checksum_spec.rb
index 19af1c7d2b..c0f0acdeb4 100644
--- a/spec/unit/mixin/checksum_spec.rb
+++ b/spec/unit/mixin/checksum_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@ require 'spec_helper'
require 'chef/mixin/checksum'
require 'stringio'
-class Chef::CMCCheck
+class Chef::CMCCheck
include Chef::Mixin::Checksum
end
diff --git a/spec/unit/mixin/convert_to_class_name_spec.rb b/spec/unit/mixin/convert_to_class_name_spec.rb
index b78d3f9101..240decc6da 100644
--- a/spec/unit/mixin/convert_to_class_name_spec.rb
+++ b/spec/unit/mixin/convert_to_class_name_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,23 +23,23 @@ class ConvertToClassTestHarness
end
describe Chef::Mixin::ConvertToClassName do
-
+
before do
@convert = ConvertToClassTestHarness.new
end
-
+
it "converts a_snake_case_word to a CamelCaseWord" do
@convert.convert_to_class_name("now_camelized").should == "NowCamelized"
end
-
+
it "converts a CamelCaseWord to a snake_case_word" do
@convert.convert_to_snake_case("NowImASnake").should == "now_im_a_snake"
end
-
+
it "removes the base classes before snake casing" do
@convert.convert_to_snake_case("NameSpaced::Class::ThisIsWin", "NameSpaced::Class").should == "this_is_win"
end
-
+
it "removes the base classes without explicitly naming them and returns snake case" do
@convert.snake_case_basename("NameSpaced::Class::ExtraWin").should == "extra_win"
end
diff --git a/spec/unit/mixin/deprecation_spec.rb b/spec/unit/mixin/deprecation_spec.rb
index c3170007de..3ebf06e830 100644
--- a/spec/unit/mixin/deprecation_spec.rb
+++ b/spec/unit/mixin/deprecation_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/mixin/params_validate_spec.rb b/spec/unit/mixin/params_validate_spec.rb
index aa37362dc3..2947ebea4a 100644
--- a/spec/unit/mixin/params_validate_spec.rb
+++ b/spec/unit/mixin/params_validate_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@ require 'spec_helper'
class TinyClass
include Chef::Mixin::ParamsValidate
-
+
def music(is_good=true)
is_good
end
@@ -30,136 +30,136 @@ describe Chef::Mixin::ParamsValidate do
before(:each) do
@vo = TinyClass.new()
end
-
+
it "should allow a hash and a hash as arguments to validate" do
lambda { @vo.validate({:one => "two"}, {}) }.should_not raise_error(ArgumentError)
end
-
+
it "should raise an argument error if validate is called incorrectly" do
lambda { @vo.validate("one", "two") }.should raise_error(ArgumentError)
end
-
+
it "should require validation map keys to be symbols or strings" do
lambda { @vo.validate({:one => "two"}, { :one => true }) }.should_not raise_error(ArgumentError)
lambda { @vo.validate({:one => "two"}, { "one" => true }) }.should_not raise_error(ArgumentError)
lambda { @vo.validate({:one => "two"}, { Hash.new => true }) }.should raise_error(ArgumentError)
end
-
+
it "should allow options to be required with true" do
lambda { @vo.validate({:one => "two"}, { :one => true }) }.should_not raise_error(ArgumentError)
end
-
+
it "should allow options to be optional with false" do
lambda { @vo.validate({}, {:one => false})}.should_not raise_error(ArgumentError)
- end
-
+ end
+
it "should allow you to check what kind_of? thing an argument is with kind_of" do
- lambda {
+ lambda {
@vo.validate(
- {:one => "string"},
+ {:one => "string"},
{
:one => {
:kind_of => String
}
}
- )
+ )
}.should_not raise_error(ArgumentError)
-
- lambda {
+
+ lambda {
@vo.validate(
- {:one => "string"},
+ {:one => "string"},
{
:one => {
:kind_of => Array
}
}
- )
+ )
}.should raise_error(ArgumentError)
end
-
+
it "should allow you to specify an argument is required with required" do
- lambda {
+ lambda {
@vo.validate(
- {:one => "string"},
+ {:one => "string"},
{
:one => {
:required => true
}
}
- )
+ )
}.should_not raise_error(ArgumentError)
-
- lambda {
+
+ lambda {
@vo.validate(
- {:two => "string"},
+ {:two => "string"},
{
:one => {
:required => true
}
}
- )
+ )
}.should raise_error(ArgumentError)
-
- lambda {
+
+ lambda {
@vo.validate(
- {:two => "string"},
+ {:two => "string"},
{
:one => {
:required => false
}
}
- )
+ )
}.should_not raise_error(ArgumentError)
end
-
+
it "should allow you to specify whether an object has a method with respond_to" do
- lambda {
+ lambda {
@vo.validate(
- {:one => @vo},
+ {:one => @vo},
{
:one => {
:respond_to => "validate"
}
}
- )
+ )
}.should_not raise_error(ArgumentError)
-
- lambda {
+
+ lambda {
@vo.validate(
- {:one => @vo},
+ {:one => @vo},
{
:one => {
:respond_to => "monkey"
}
}
- )
+ )
}.should raise_error(ArgumentError)
end
-
+
it "should allow you to specify whether an object has all the given methods with respond_to and an array" do
- lambda {
+ lambda {
@vo.validate(
- {:one => @vo},
+ {:one => @vo},
{
:one => {
:respond_to => ["validate", "music"]
}
}
- )
+ )
}.should_not raise_error(ArgumentError)
-
- lambda {
+
+ lambda {
@vo.validate(
- {:one => @vo},
+ {:one => @vo},
{
:one => {
:respond_to => ["monkey", "validate"]
}
}
- )
+ )
}.should raise_error(ArgumentError)
end
-
+
it "should let you set a default value with default => value" do
arguments = Hash.new
@vo.validate(arguments, {
@@ -169,9 +169,9 @@ describe Chef::Mixin::ParamsValidate do
})
arguments[:one].should == "is the loneliest number"
end
-
+
it "should let you check regular expressions" do
- lambda {
+ lambda {
@vo.validate(
{ :one => "is good" },
{
@@ -181,8 +181,8 @@ describe Chef::Mixin::ParamsValidate do
}
)
}.should_not raise_error(ArgumentError)
-
- lambda {
+
+ lambda {
@vo.validate(
{ :one => "is good" },
{
@@ -193,9 +193,9 @@ describe Chef::Mixin::ParamsValidate do
)
}.should raise_error(ArgumentError)
end
-
+
it "should let you specify your own callbacks" do
- lambda {
+ lambda {
@vo.validate(
{ :one => "is good" },
{
@@ -208,9 +208,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error(ArgumentError)
-
- lambda {
+ }.should_not raise_error(ArgumentError)
+
+ lambda {
@vo.validate(
{ :one => "is bad" },
{
@@ -223,12 +223,12 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError)
end
-
+
it "should let you combine checks" do
args = { :one => "is good", :two => "is bad" }
- lambda {
+ lambda {
@vo.validate(
args,
{
@@ -276,7 +276,7 @@ describe Chef::Mixin::ParamsValidate do
)
}.should raise_error(ArgumentError)
end
-
+
it "should raise an ArgumentError if the validation map has an unknown check" do
lambda { @vo.validate(
{ :one => "two" },
@@ -288,43 +288,43 @@ describe Chef::Mixin::ParamsValidate do
)
}.should raise_error(ArgumentError)
end
-
+
it "should accept keys that are strings in the options" do
lambda {
- @vo.validate({ "one" => "two" }, { :one => { :regex => /^two$/ }})
+ @vo.validate({ "one" => "two" }, { :one => { :regex => /^two$/ }})
}.should_not raise_error(ArgumentError)
end
-
+
it "should allow an array to kind_of" do
- lambda {
+ lambda {
@vo.validate(
- {:one => "string"},
+ {:one => "string"},
{
:one => {
:kind_of => [ String, Array ]
}
}
- )
+ )
}.should_not raise_error(ArgumentError)
- lambda {
+ lambda {
@vo.validate(
- {:one => ["string"]},
+ {:one => ["string"]},
{
:one => {
:kind_of => [ String, Array ]
}
}
- )
+ )
}.should_not raise_error(ArgumentError)
- lambda {
+ lambda {
@vo.validate(
- {:one => Hash.new},
+ {:one => Hash.new},
{
:one => {
:kind_of => [ String, Array ]
}
}
- )
+ )
}.should raise_error(ArgumentError)
end
@@ -403,5 +403,5 @@ describe Chef::Mixin::ParamsValidate do
@vo.set_or_return(:test, nil, {}).object_id.should == value.object_id
@vo.set_or_return(:test, nil, {}).should be_a(Proc)
end
-
+
end
diff --git a/spec/unit/mixin/securable_spec.rb b/spec/unit/mixin/securable_spec.rb
index 764da9b1d1..fe21393c90 100644
--- a/spec/unit/mixin/securable_spec.rb
+++ b/spec/unit/mixin/securable_spec.rb
@@ -45,7 +45,6 @@ describe Chef::Mixin::Securable do
describe "unix-specific behavior" do
before(:each) do
platform_mock :unix do
- @original_config = Chef::Config.hash_dup
load File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "chef", "config.rb")
load File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "chef", "mixin", "securable.rb")
@securable = Object.new
@@ -54,10 +53,6 @@ describe Chef::Mixin::Securable do
end
end
- after(:each) do
- Chef::Config.configuration = @original_config
- end
-
it "should accept a group name or id for group with spaces and backslashes" do
lambda { @securable.group 'test\ group' }.should_not raise_error(ArgumentError)
end
@@ -109,7 +104,6 @@ describe Chef::Mixin::Securable do
describe "windows-specific behavior" do
before(:each) do
platform_mock :windows do
- @original_config = Chef::Config.hash_dup
load File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "chef", "config.rb")
load File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "chef", "mixin", "securable.rb")
SECURABLE_CLASS = Class.new do
@@ -120,14 +114,6 @@ describe Chef::Mixin::Securable do
end
end
- after(:all) do
- Chef::Config.configuration = @original_config if @original_config
- end
-
- after(:each) do
- Chef::Config.configuration = @original_config if @original_config
- end
-
it "should not accept a group name or id for group with spaces and multiple backslashes" do
lambda { @securable.group 'test\ \group' }.should raise_error(ArgumentError)
end
diff --git a/spec/unit/mixin/shell_out_spec.rb b/spec/unit/mixin/shell_out_spec.rb
index 6ca700fcdb..c7ca56fe84 100644
--- a/spec/unit/mixin/shell_out_spec.rb
+++ b/spec/unit/mixin/shell_out_spec.rb
@@ -31,7 +31,7 @@ describe Chef::Mixin::ShellOut do
let(:cmd) { "echo '#{rand(1000)}'" }
let(:output) { StringIO.new }
- let(:capture_log_output) { Chef::Log.logger = Logger.new(output) }
+ let!(:capture_log_output) { Chef::Log.logger = Logger.new(output) }
let(:assume_deprecation_log_level) { Chef::Log.stub!(:level).and_return(:warn) }
context 'without options' do
diff --git a/spec/unit/mixin/template_spec.rb b/spec/unit/mixin/template_spec.rb
index 039bc1984f..ca2c3c7318 100644
--- a/spec/unit/mixin/template_spec.rb
+++ b/spec/unit/mixin/template_spec.rb
@@ -33,6 +33,40 @@ describe Chef::Mixin::Template, "render_template" do
output.should == "bar"
end
+ template_contents = [ "Fancy\r\nTemplate\r\n\r\n",
+ "Fancy\nTemplate\n\n",
+ "Fancy\r\nTemplate\n\r\n"]
+
+ describe "when running on windows" do
+ before do
+ Chef::Platform.stub!(:windows?).and_return(true)
+ end
+
+ it "should render the templates with windows line endings" do
+ template_contents.each do |template_content|
+ output = @context.render_template_from_string(template_content)
+ output.each_line do |line|
+ line.should end_with("\r\n")
+ end
+ end
+ end
+ end
+
+ describe "when running on unix" do
+ before do
+ Chef::Platform.stub!(:windows?).and_return(false)
+ end
+
+ it "should render the templates with unix line endings" do
+ template_contents.each do |template_content|
+ output = @context.render_template_from_string(template_content)
+ output.each_line do |line|
+ line.should end_with("\n")
+ end
+ end
+ end
+ end
+
it "should provide a node method to access @node" do
@context[:node] = "tehShizzle"
output = @context.render_template_from_string("<%= @node %>")
diff --git a/spec/unit/mixin/windows_architecture_helper_spec.rb b/spec/unit/mixin/windows_architecture_helper_spec.rb
index c7813a5efc..f59602d716 100644
--- a/spec/unit/mixin/windows_architecture_helper_spec.rb
+++ b/spec/unit/mixin/windows_architecture_helper_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -32,7 +32,7 @@ describe Chef::Mixin::WindowsArchitectureHelper do
@node_i386 = Chef::Node.new
@node_x86_64 = Chef::Node.new
end
-
+
it "returns true when valid architectures are passed to valid_windows_architecture?" do
@valid_architectures.each do | architecture |
valid_windows_architecture?(architecture).should == true
@@ -67,7 +67,7 @@ describe Chef::Mixin::WindowsArchitectureHelper do
it "returns false for each unsupported desired architecture for all nodes with each valid architecture passed to node_supports_windows_architecture?" do
enumerate_architecture_node_combinations(true)
end
-
+
def enumerate_architecture_node_combinations(only_valid_combinations)
@valid_architectures.each do | node_architecture |
new_node = Chef::Node.new
@@ -76,7 +76,7 @@ describe Chef::Mixin::WindowsArchitectureHelper do
@valid_architectures.each do | supported_architecture |
node_supports_windows_architecture?(new_node, supported_architecture).should == true if only_valid_combinations && (supported_architecture != :x86_64 && node_architecture != :i386 )
- node_supports_windows_architecture?(new_node, supported_architecture).should == false if ! only_valid_combinations && (supported_architecture == :x86_64 && node_architecture == :i386 )
+ node_supports_windows_architecture?(new_node, supported_architecture).should == false if ! only_valid_combinations && (supported_architecture == :x86_64 && node_architecture == :i386 )
end
end
end
diff --git a/spec/unit/mixin/xml_escape_spec.rb b/spec/unit/mixin/xml_escape_spec.rb
index d05854ade4..83debb5907 100644
--- a/spec/unit/mixin/xml_escape_spec.rb
+++ b/spec/unit/mixin/xml_escape_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/node/attribute_spec.rb b/spec/unit/node/attribute_spec.rb
index 5aa563aedf..70905d334b 100644
--- a/spec/unit/node/attribute_spec.rb
+++ b/spec/unit/node/attribute_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,9 +20,9 @@
require 'spec_helper'
require 'chef/node/attribute'
-describe Chef::Node::Attribute do
+describe Chef::Node::Attribute do
before(:each) do
- @attribute_hash =
+ @attribute_hash =
{"dmi"=>{},
"command"=>{"ps"=>"ps -ef"},
"platform_version"=>"10.5.7",
@@ -193,7 +193,7 @@ describe Chef::Node::Attribute do
@default_hash = {
"domain" => "opscode.com",
"hot" => { "day" => "saturday" },
- "music" => {
+ "music" => {
"jimmy_eat_world" => "is fun!",
"mastodon" => "rocks",
"mars_volta" => "is loud and nutty",
@@ -225,7 +225,7 @@ describe Chef::Node::Attribute do
[ :normal, :default, :override, :automatic ].each do |accessor|
it "should set #{accessor}" do
na = Chef::Node::Attribute.new({ :normal => true }, { :default => true }, { :override => true }, { :automatic => true })
- na.send(accessor).should == { accessor.to_s => true }
+ na.send(accessor).should == { accessor.to_s => true }
end
end
@@ -520,7 +520,7 @@ describe Chef::Node::Attribute do
[:include?, :key?, :member?].each do |method|
it "should alias the method #{method} to itself" do
- @attributes.should respond_to(method)
+ @attributes.should respond_to(method)
end
it "#{method} should behave like has_key?" do
@@ -582,7 +582,7 @@ describe Chef::Node::Attribute do
collect.include?("snakes").should == true
collect.include?("snack").should == true
collect.include?("place").should == true
- collect.length.should == 5
+ collect.length.should == 5
end
it "should yield lower if we go deeper" do
@@ -593,7 +593,7 @@ describe Chef::Node::Attribute do
collect.include?("two").should == true
collect.include?("four").should == true
collect.include?("six").should == true
- collect.length.should == 3
+ collect.length.should == 3
end
it "should not raise an exception if one of the hashes has a nil value on a deep lookup" do
@@ -667,7 +667,7 @@ describe Chef::Node::Attribute do
@attributes.each_key do |k|
collect << k
end
-
+
collect.should include("one")
collect.should include("snack")
collect.should include("hut")
@@ -710,7 +710,7 @@ describe Chef::Node::Attribute do
collect["snack"].should == "cookies"
end
end
-
+
describe "each_value" do
before do
@attributes = Chef::Node::Attribute.new(
diff --git a/spec/unit/node/immutable_collections_spec.rb b/spec/unit/node/immutable_collections_spec.rb
index db4a79f21b..0c2b878cd2 100644
--- a/spec/unit/node/immutable_collections_spec.rb
+++ b/spec/unit/node/immutable_collections_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb
index 2906db34bc..bb567dbdf7 100644
--- a/spec/unit/node_spec.rb
+++ b/spec/unit/node_spec.rb
@@ -204,6 +204,11 @@ describe Chef::Node do
node.fuu.bahrr.baz.should == "qux"
end
+ it "should let you use tag as a convience method for the tags attribute" do
+ node.normal['tags'] = ['one', 'two']
+ node.tag('three', 'four')
+ node['tags'].should == ['one', 'two', 'three', 'four']
+ end
end
describe "default attributes" do
diff --git a/spec/unit/platform_spec.rb b/spec/unit/platform_spec.rb
index 21bc4298b0..3904435ea0 100644
--- a/spec/unit/platform_spec.rb
+++ b/spec/unit/platform_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,10 +28,11 @@ describe "Chef::Platform supports" do
:centos,
:fedora,
:suse,
+ :opensuse,
:redhat,
:oracle,
:gentoo,
- :arch,
+ :arch,
:solaris,
:mswin,
:mingw32,
@@ -49,11 +50,11 @@ describe Chef::Platform do
before :all do
@original_platform_map = Chef::Platform.platforms
end
-
+
after :all do ||
Chef::Platform.platforms = @original_platform_map
end
-
+
before(:each) do
Chef::Platform.platforms = {
:darwin => {
@@ -79,13 +80,13 @@ describe Chef::Platform do
}
@events = Chef::EventDispatch::Dispatcher.new
end
-
+
it "should allow you to look up a platform by name and version, returning the provider map for it" do
pmap = Chef::Platform.find("Darwin", "9.2.2")
pmap.should be_a_kind_of(Hash)
pmap[:file].should eql("darwinian")
end
-
+
it "should allow you to look up a platform by name and version using \"greater than\" style operators" do
pmap = Chef::Platform.find("Darwin", "11.1.0")
pmap.should be_a_kind_of(Hash)
@@ -97,46 +98,46 @@ describe Chef::Platform do
pmap.should be_a_kind_of(Hash)
pmap[:file].should eql("old school")
end
-
+
it "should use the default providers if the os doesn't give me a default, but does exist" do
pmap = Chef::Platform.find("mars_volta", "1")
pmap.should be_a_kind_of(Hash)
pmap[:file].should eql(Chef::Provider::File)
end
-
+
it "should use the default provider if the os does not exist" do
pmap = Chef::Platform.find("AIX", "1")
pmap.should be_a_kind_of(Hash)
pmap[:file].should eql(Chef::Provider::File)
end
-
+
it "should merge the defaults for an os with the specific version" do
pmap = Chef::Platform.find("Darwin", "9.2.2")
pmap[:file].should eql("darwinian")
pmap[:snicker].should eql("snack")
end
-
+
it "should merge the defaults for an os with the universal defaults" do
pmap = Chef::Platform.find("Darwin", "9.2.2")
pmap[:file].should eql("darwinian")
pmap[:pax].should eql("brittania")
end
-
+
it "should allow you to look up a provider for a platform directly by symbol" do
Chef::Platform.find_provider("Darwin", "9.2.2", :file).should eql("darwinian")
end
-
+
it "should raise an exception if a provider cannot be found for a resource type" do
lambda { Chef::Platform.find_provider("Darwin", "9.2.2", :coffee) }.should raise_error(ArgumentError)
end
-
+
it "should look up a provider for a resource with a Chef::Resource object" do
kitty = Chef::Resource::Cat.new("loulou")
Chef::Platform.find_provider("Darwin", "9.2.2", kitty).should eql("nice")
end
-
+
it "should look up a provider with a node and a Chef::Resource object" do
- kitty = Chef::Resource::Cat.new("loulou")
+ kitty = Chef::Resource::Cat.new("loulou")
node = Chef::Node.new
node.name("Intel")
node.automatic_attrs[:platform] = "mac_os_x"
@@ -149,7 +150,7 @@ describe Chef::Platform do
end
it "should prefer an explicit provider" do
- kitty = Chef::Resource::Cat.new("loulou")
+ kitty = Chef::Resource::Cat.new("loulou")
kitty.stub!(:provider).and_return(Chef::Provider::File)
node = Chef::Node.new
node.name("Intel")
@@ -168,7 +169,7 @@ describe Chef::Platform do
node.automatic_attrs[:platform_version] = "8.5"
Chef::Platform.find_provider_for_node(node, kitty).should eql(Chef::Provider::Cat)
end
-
+
def setup_file_resource
node = Chef::Node.new
node.automatic_attrs[:platform] = "mac_os_x"
@@ -184,7 +185,7 @@ describe Chef::Platform do
provider.new_resource.should equal(file)
provider.run_context.should equal(run_context)
end
-
+
it "returns a provider object given a Chef::Resource object which has a valid run context without an action" do
file, run_context = setup_file_resource
provider = Chef::Platform.provider_for_resource(file)
@@ -192,7 +193,7 @@ describe Chef::Platform do
provider.new_resource.should equal(file)
provider.run_context.should equal(run_context)
end
-
+
it "raises an error when trying to find the provider for a resource with no run context" do
file = Chef::Resource::File.new("whateva")
lambda {Chef::Platform.provider_for_resource(file)}.should raise_error(ArgumentError)
@@ -202,44 +203,44 @@ describe Chef::Platform do
lambda {Chef::Platform.provider_for_node('node', 'resource')}.should raise_error(NotImplementedError)
end
- it "should update the provider map with map" do
+ it "should update the provider map with map" do
Chef::Platform.set(
:platform => :darwin,
:version => "9.2.2",
- :resource => :file,
+ :resource => :file,
:provider => "masterful"
)
Chef::Platform.platforms[:darwin]["9.2.2"][:file].should eql("masterful")
Chef::Platform.set(
:platform => :darwin,
:resource => :file,
- :provider => "masterful"
+ :provider => "masterful"
)
Chef::Platform.platforms[:darwin][:default][:file].should eql("masterful")
Chef::Platform.set(
- :resource => :file,
+ :resource => :file,
:provider => "masterful"
- )
+ )
Chef::Platform.platforms[:default][:file].should eql("masterful")
-
+
Chef::Platform.set(
:platform => :hero,
:version => "9.2.2",
- :resource => :file,
+ :resource => :file,
:provider => "masterful"
)
Chef::Platform.platforms[:hero]["9.2.2"][:file].should eql("masterful")
-
+
Chef::Platform.set(
- :resource => :file,
+ :resource => :file,
:provider => "masterful"
)
Chef::Platform.platforms[:default][:file].should eql("masterful")
-
+
Chef::Platform.platforms = {}
-
+
Chef::Platform.set(
- :resource => :file,
+ :resource => :file,
:provider => "masterful"
)
Chef::Platform.platforms[:default][:file].should eql("masterful")
@@ -247,8 +248,8 @@ describe Chef::Platform do
Chef::Platform.platforms = { :neurosis => {} }
Chef::Platform.set(:platform => :neurosis, :resource => :package, :provider => "masterful")
Chef::Platform.platforms[:neurosis][:default][:package].should eql("masterful")
-
+
end
-
-
+
+
end
diff --git a/spec/unit/provider/cron/solaris_spec.rb b/spec/unit/provider/cron/unix_spec.rb
index 498d4fb1f5..ffdfa198b6 100644
--- a/spec/unit/provider/cron/solaris_spec.rb
+++ b/spec/unit/provider/cron/unix_spec.rb
@@ -20,7 +20,7 @@
require 'spec_helper'
-describe Chef::Provider::Cron::Solaris do
+describe Chef::Provider::Cron::Unix do
before do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@@ -30,7 +30,7 @@ describe Chef::Provider::Cron::Solaris do
@new_resource.minute "30"
@new_resource.command "/bin/true"
- @provider = Chef::Provider::Cron::Solaris.new(@new_resource, @run_context)
+ @provider = Chef::Provider::Cron::Unix.new(@new_resource, @run_context)
end
it "should inherit from Chef::Provider:Cron" do
@@ -86,7 +86,7 @@ CRONTAB
describe "write_crontab" do
before :each do
@status = mock("Status", :exitstatus => 0)
- @provider.stub!(:run_command).and_return(@status)
+ @provider.stub!(:run_command_and_return_stdout_stderr).and_return(@status, String.new, String.new)
@tempfile = mock("foo", :path => "/tmp/foo", :close => true)
Tempfile.stub!(:new).and_return(@tempfile)
@tempfile.should_receive(:flush)
@@ -95,13 +95,13 @@ CRONTAB
end
it "should call crontab for the user" do
- @provider.should_receive(:run_command).with(hash_including(:user => @new_resource.user))
+ @provider.should_receive(:run_command_and_return_stdout_stderr).with(hash_including(:user => @new_resource.user))
@tempfile.should_receive(:<<).with("Foo")
@provider.send(:write_crontab, "Foo")
end
it "should call crontab with a file containing the crontab" do
- @provider.should_receive(:run_command) do |args|
+ @provider.should_receive(:run_command_and_return_stdout_stderr) do |args|
(args[:command] =~ %r{\A/usr/bin/crontab (/\S+)\z}).should be_true
$1.should == "/tmp/foo"
@status
@@ -115,7 +115,7 @@ CRONTAB
@status.stub!(:exitstatus).and_return(1)
lambda do
@provider.send(:write_crontab, "Foo")
- end.should raise_error(Chef::Exceptions::Cron, "Error updating state of #{@new_resource.name}, exit: 1")
+ end.should raise_error(Chef::Exceptions::Cron, /Error updating state of #{@new_resource.name}, exit: 1/)
end
end
end
diff --git a/spec/unit/provider/cron_spec.rb b/spec/unit/provider/cron_spec.rb
index 5a848a30e6..8a819b699c 100644
--- a/spec/unit/provider/cron_spec.rb
+++ b/spec/unit/provider/cron_spec.rb
@@ -181,7 +181,7 @@ CRONTAB
before :each do
@provider.stub!(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
-
+
# Chef Name: cronhole some stuff
* 5 * Jan Mon /bin/true param1 param2
# Chef Name: something else
@@ -196,7 +196,7 @@ CRONTAB
@provider.cron_exists.should == true
@provider.cron_empty.should == false
end
-
+
it "should pull the details out of the cron line" do
cron = @provider.load_current_resource
cron.minute.should == '*'
@@ -563,7 +563,7 @@ HOME=/home/foo
@provider.stub!(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
-# Chef Name: something else
+# Chef Name: cronhole some stuff
* 5 * * * /bin/true
# Another comment
@@ -581,6 +581,7 @@ CRONTAB
end
it "should log nothing changed" do
+ Chef::Log.should_receive(:debug).with("Found cron '#{@new_resource.name}'")
Chef::Log.should_receive(:debug).with("Skipping existing cron entry '#{@new_resource.name}'")
@provider.run_action(:create)
end
@@ -808,5 +809,22 @@ MAILTO=foo@example.com
@provider.send(:write_crontab, "Foo")
end.should raise_error(Chef::Exceptions::Cron, "Error updating state of #{@new_resource.name}, exit: 1")
end
+
+ it "should raise an exception if the command die's and parent tries to write" do
+ class WriteErrPipe
+ def write(str)
+ raise Errno::EPIPE, "Test"
+ end
+ end
+ @status.stub!(:exitstatus).and_return(1)
+ @provider.stub!(:popen4).and_yield(1234, WriteErrPipe.new, StringIO.new, StringIO.new).and_return(@status)
+
+ Chef::Log.should_receive(:debug).with("Broken pipe - Test")
+
+ lambda do
+ @provider.send(:write_crontab, "Foo")
+ end.should raise_error(Chef::Exceptions::Cron, "Error updating state of #{@new_resource.name}, exit: 1")
+ end
+
end
end
diff --git a/spec/unit/provider/deploy/timestamped_spec.rb b/spec/unit/provider/deploy/timestamped_spec.rb
index b891a03ce2..a9cea1142e 100644
--- a/spec/unit/provider/deploy/timestamped_spec.rb
+++ b/spec/unit/provider/deploy/timestamped_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,7 +19,7 @@
require 'spec_helper'
describe Chef::Provider::Deploy::Timestamped do
-
+
before do
@release_time = Time.utc( 2004, 8, 15, 16, 23, 42)
Time.stub!(:now).and_return(@release_time)
@@ -32,9 +32,9 @@ describe Chef::Provider::Deploy::Timestamped do
@runner = mock("runnah")
Chef::Runner.stub!(:new).and_return(@runner)
end
-
+
it "gives a timestamp for release_slug" do
@timestamped_deploy.send(:release_slug).should == "20040815162342"
end
-
+
end
diff --git a/spec/unit/provider/deploy_spec.rb b/spec/unit/provider/deploy_spec.rb
index 56ba50b7f0..1a9fee8831 100644
--- a/spec/unit/provider/deploy_spec.rb
+++ b/spec/unit/provider/deploy_spec.rb
@@ -43,6 +43,20 @@ describe Chef::Provider::Deploy do
@provider.should respond_to(:action_rollback)
end
+ context "when the deploy resource has a timeout attribute" do
+ let(:ten_seconds) { 10 }
+ before { @resource.timeout(ten_seconds) }
+ it "relays the timeout to the scm resource" do
+ @provider.scm_provider.new_resource.timeout.should == ten_seconds
+ end
+ end
+
+ context "when the deploy resource has no timeout attribute" do
+ it "should not set a timeout on the scm resource" do
+ @provider.scm_provider.new_resource.timeout.should be_nil
+ end
+ end
+
context "when the deploy_to dir does not exist yet" do
before do
FileUtils.should_receive(:mkdir_p).with(@resource.deploy_to).ordered
@@ -149,18 +163,18 @@ describe Chef::Provider::Deploy do
@provider.stub!(:deploy).and_return{ raise "Unexpected error" }
@provider.stub!(:previous_release_path).and_return('previous_release')
@provider.should_not_receive(:rollback)
- lambda {
+ lambda {
@provider.run_action(:deploy)
}.should raise_exception(RuntimeError, "Unexpected error")
end
-
+
it "rollbacks to previous release if error happens on deploy" do
@resource.rollback_on_error true
@provider.stub!(:all_releases).and_return(['previous_release'])
@provider.stub!(:deploy).and_return{ raise "Unexpected error" }
@provider.stub!(:previous_release_path).and_return('previous_release')
@provider.should_receive(:rollback)
- lambda {
+ lambda {
@provider.run_action(:deploy)
}.should raise_exception(RuntimeError, "Unexpected error")
end
@@ -211,15 +225,15 @@ describe Chef::Provider::Deploy do
#FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342")
#@provider.run_action(:rollback)
#@provider.release_path.should eql(NIL) -- no check needed since assertions will fail
- lambda {
+ lambda {
@provider.run_action(:rollback)
}.should raise_exception(RuntimeError, "There is no release to rollback to!")
end
-
+
it "an exception is raised when there are no releases" do
all_releases = []
Dir.stub!(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
- lambda {
+ lambda {
@provider.run_action(:rollback)
}.should raise_exception(RuntimeError, "There is no release to rollback to!")
end
@@ -419,7 +433,7 @@ describe Chef::Provider::Deploy do
@provider.should_receive(:enforce_ownership)
@provider.link_tempfiles_to_current_release
end
-
+
end
it "does nothing for restart if restart_command is empty" do
diff --git a/spec/unit/provider/env_spec.rb b/spec/unit/provider/env_spec.rb
index 77aea42b43..673ba9798a 100644
--- a/spec/unit/provider/env_spec.rb
+++ b/spec/unit/provider/env_spec.rb
@@ -81,7 +81,7 @@ describe Chef::Provider::Env do
@provider.action_create
end
- it "should set the the new_resources updated flag when it creates the key" do
+ it "should set the new_resources updated flag when it creates the key" do
@provider.action_create
@new_resource.should be_updated
end
@@ -99,7 +99,7 @@ describe Chef::Provider::Env do
@provider.action_create
end
- it "should set the the new_resources updated flag when it updates an existing value" do
+ it "should set the new_resources updated flag when it updates an existing value" do
@provider.key_exists = true
@provider.stub!(:compare_value).and_return(true)
@provider.stub!(:modify_env).and_return(true)
diff --git a/spec/unit/provider/execute_spec.rb b/spec/unit/provider/execute_spec.rb
index bf913cca12..0d108f521d 100644
--- a/spec/unit/provider/execute_spec.rb
+++ b/spec/unit/provider/execute_spec.rb
@@ -31,7 +31,7 @@ describe Chef::Provider::Execute do
@provider = Chef::Provider::Execute.new(@new_resource, @run_context)
@current_resource = Chef::Resource::Ifconfig.new("foo_resource", @run_context)
@provider.current_resource = @current_resource
- Chef::Log.level = :info
+ Chef::Log.level = :info
# FIXME: There should be a test for how STDOUT.tty? changes the live_stream option being passed
STDOUT.stub!(:tty?).and_return(true)
end
@@ -73,7 +73,7 @@ describe Chef::Provider::Execute do
@provider.run_action(:run)
@new_resource.should_not be_updated
- end
+ end
it "should warn if user specified relative path without cwd" do
@new_resource.creates "foo_resource"
diff --git a/spec/unit/provider/file/content_spec.rb b/spec/unit/provider/file/content_spec.rb
index 693877760e..9262a35245 100644
--- a/spec/unit/provider/file/content_spec.rb
+++ b/spec/unit/provider/file/content_spec.rb
@@ -20,14 +20,6 @@ require 'spec_helper'
describe Chef::Provider::File::Content do
- before(:all) do
- @original_config = Chef::Config.configuration
- end
-
- after(:all) do
- Chef::Config.configuration.replace(@original_config)
- end
-
#
# mock setup
#
diff --git a/spec/unit/provider/git_spec.rb b/spec/unit/provider/git_spec.rb
index 763de240cc..2bf55930db 100644
--- a/spec/unit/provider/git_spec.rb
+++ b/spec/unit/provider/git_spec.rb
@@ -165,15 +165,35 @@ SHAS
@provider.should respond_to(:revision_slug)
end
- it "runs a clone command with default git options" do
- @resource.user "deployNinja"
- @resource.ssh_wrapper "do_it_this_way.sh"
- expected_cmd = "git clone \"git://github.com/opscode/chef.git\" \"/my/deploy/dir\""
- @provider.should_receive(:shell_out!).with(expected_cmd, :user => "deployNinja",
- :environment =>{"GIT_SSH"=>"do_it_this_way.sh"},
- :log_tag => "git[web2.0 app]" )
-
- @provider.clone
+ context "with an ssh wrapper" do
+ let(:deploy_user) { "deployNinja" }
+ let(:wrapper) { "do_it_this_way.sh" }
+ let(:expected_cmd) { 'git clone "git://github.com/opscode/chef.git" "/my/deploy/dir"' }
+ let(:default_options) do
+ {
+ :user => deploy_user,
+ :environment => { "GIT_SSH" => wrapper },
+ :log_tag => "git[web2.0 app]"
+ }
+ end
+ before do
+ @resource.user deploy_user
+ @resource.ssh_wrapper wrapper
+ end
+ context "without a timeout set" do
+ it "clones a repo with default git options" do
+ @provider.should_receive(:shell_out!).with(expected_cmd, default_options)
+ @provider.clone
+ end
+ end
+ context "with a timeout set" do
+ let (:seconds) { 10 }
+ before { @resource.timeout(seconds) }
+ it "clones a repo with amended git options" do
+ @provider.should_receive(:shell_out!).with(expected_cmd, default_options.merge(:timeout => seconds))
+ @provider.clone
+ end
+ end
end
it "runs a clone command with escaped destination" do
diff --git a/spec/unit/provider/group/dscl_spec.rb b/spec/unit/provider/group/dscl_spec.rb
index b526848dfd..28d78cbdbd 100644
--- a/spec/unit/provider/group/dscl_spec.rb
+++ b/spec/unit/provider/group/dscl_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,14 +27,14 @@ describe Chef::Provider::Group::Dscl do
@current_resource = Chef::Resource::Group.new("aj")
@provider = Chef::Provider::Group::Dscl.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
- @status = mock("Process::Status", :exitstatus => 0)
+ @status = mock("Process::Status", :exitstatus => 0)
@pid = 2342
@stdin = StringIO.new
@stdout = StringIO.new("\n")
@stderr = StringIO.new("")
@provider.stub!(:popen4).and_yield(@pid,@stdin,@stdout,@stderr).and_return(@status)
end
-
+
it "should run popen4 with the supplied array of arguments appended to the dscl command" do
@provider.should_receive(:popen4).with("dscl . -cmd /Path arg1 arg2")
@provider.dscl("cmd", "/Path", "arg1", "arg2")
@@ -52,7 +52,7 @@ describe Chef::Provider::Group::Dscl do
@provider = Chef::Provider::Group::Dscl.new(@node, @new_resource)
@provider.stub!(:dscl).and_return(["cmd", @status, "stdout", "stderr"])
end
-
+
it "should run dscl with the supplied cmd /Path args" do
@provider.should_receive(:dscl).with("cmd /Path args")
@provider.safe_dscl("cmd /Path args")
@@ -84,7 +84,7 @@ describe Chef::Provider::Group::Dscl do
lambda { @provider.safe_dscl("cmd /Path arguments") }.should raise_error(Chef::Exceptions::Group)
end
end
-
+
describe "with the dscl command returning a zero exit status" do
it "should return the third array element, the string of standard output" do
safe_dscl_retval = @provider.safe_dscl("cmd /Path args")
@@ -100,7 +100,7 @@ describe Chef::Provider::Group::Dscl do
@provider = Chef::Provider::Group::Dscl.new(@node, @new_resource)
@provider.stub!(:safe_dscl).and_return("\naj 200\njt 201\n")
end
-
+
it "should run safe_dscl with list /Groups gid" do
@provider.should_receive(:safe_dscl).with("list /Groups gid")
@provider.get_free_gid
@@ -109,7 +109,7 @@ describe Chef::Provider::Group::Dscl do
it "should return the first unused gid number on or above 200" do
@provider.get_free_gid.should equal(202)
end
-
+
it "should raise an exception when the search limit is exhausted" do
search_limit = 1
lambda { @provider.get_free_gid(search_limit) }.should raise_error(RuntimeError)
@@ -127,7 +127,7 @@ describe Chef::Provider::Group::Dscl do
@provider.should_receive(:safe_dscl).with("list /Groups gid")
@provider.gid_used?(500)
end
-
+
it "should return true for a used gid number" do
@provider.gid_used?(500).should be_true
end
@@ -151,7 +151,7 @@ describe Chef::Provider::Group::Dscl do
lambda { @provider.set_gid }.should raise_error(Chef::Exceptions::Group)
end
end
-
+
describe "with no gid number for the new resources" do
it "should run get_free_gid and return a valid, unused gid number" do
@provider.should_receive(:get_free_gid).and_return(501)
@@ -220,7 +220,7 @@ describe Chef::Provider::Group::Dscl do
@provider.set_members
end
end
-
+
describe "with no members in the new resource" do
before do
@new_resource.append(true)
@@ -276,7 +276,7 @@ describe Chef::Provider::Group::Dscl do
@provider.should_receive(:set_gid)
@provider.manage_group
end
-
+
it "should manage the members if it changed and the new resources members is not null" do
@current_resource.members(%{charlie root})
@new_resource.members(%{crab revenge})
diff --git a/spec/unit/provider/group/gpasswd_spec.rb b/spec/unit/provider/group/gpasswd_spec.rb
index 59da88e851..8889ba322e 100644
--- a/spec/unit/provider/group/gpasswd_spec.rb
+++ b/spec/unit/provider/group/gpasswd_spec.rb
@@ -36,8 +36,8 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do
@provider.define_resource_requirements
end
- # Checking for required binaries is already done in the spec
- # for Chef::Provider::Group - no need to repeat it here. We'll
+ # Checking for required binaries is already done in the spec
+ # for Chef::Provider::Group - no need to repeat it here. We'll
# include only what's specific to this provider.
it "should raise an error if the required binary /usr/bin/gpasswd doesn't exist" do
File.stub!(:exists?).and_return(true)
diff --git a/spec/unit/provider/group/groupadd_spec.rb b/spec/unit/provider/group/groupadd_spec.rb
index 5e07da59b4..0cc1167142 100644
--- a/spec/unit/provider/group/groupadd_spec.rb
+++ b/spec/unit/provider/group/groupadd_spec.rb
@@ -27,10 +27,12 @@ describe Chef::Provider::Group::Groupadd, "set_options" do
@new_resource.gid(50)
@new_resource.members(["root", "aj"])
@new_resource.system false
+ @new_resource.non_unique false
@current_resource = Chef::Resource::Group.new("aj")
@current_resource.gid(50)
@current_resource.members(["root", "aj"])
@current_resource.system false
+ @current_resource.non_unique false
@provider = Chef::Provider::Group::Groupadd.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
end
@@ -72,6 +74,18 @@ describe Chef::Provider::Group::Groupadd, "set_options" do
@provider.groupadd_options.should == " -r"
end
end
+
+ describe "when we want to create a non_unique gid group" do
+ it "should not set groupadd_options '-o' when non_unique is false" do
+ @new_resource.non_unique(false)
+ @provider.groupadd_options.should_not =~ /-o/
+ end
+
+ it "should set groupadd -o if non_unique is true" do
+ @new_resource.non_unique(true)
+ @provider.groupadd_options.should == " -o"
+ end
+ end
end
describe Chef::Provider::Group::Groupadd, "create_group" do
diff --git a/spec/unit/provider/group/groupmod_spec.rb b/spec/unit/provider/group/groupmod_spec.rb
index c9c56313b5..69b96c6edb 100644
--- a/spec/unit/provider/group/groupmod_spec.rb
+++ b/spec/unit/provider/group/groupmod_spec.rb
@@ -29,7 +29,7 @@ describe Chef::Provider::Group::Groupmod do
@new_resource.append false
@provider = Chef::Provider::Group::Groupmod.new(@new_resource, @run_context)
end
-
+
describe "manage_group" do
describe "when determining the current group state" do
it "should raise an error if the required binary /usr/sbin/group doesn't exist" do
@@ -41,25 +41,25 @@ describe Chef::Provider::Group::Groupmod do
File.should_receive(:exists?).with("/usr/sbin/user").and_return(false)
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Group)
end
-
+
it "shouldn't raise an error if the required binaries exist" do
File.stub!(:exists?).and_return(true)
lambda { @provider.load_current_resource }.should_not raise_error(Chef::Exceptions::Group)
end
end
-
+
describe "after the group's current state is known" do
before do
@current_resource = @new_resource.dup
@provider.current_resource = @current_resource
end
-
+
describe "when no group members are specified and append is not set" do
before do
@new_resource.append(false)
@new_resource.members([])
end
-
+
it "logs a message and sets group's members to 'none', then removes existing group members" do
Chef::Log.should_receive(:debug).with("group[wheel] setting group members to: none")
Chef::Log.should_receive(:debug).with("group[wheel] removing members lobster, rage, fist")
@@ -69,26 +69,26 @@ describe Chef::Provider::Group::Groupmod do
@provider.manage_group
end
end
-
+
describe "when no group members are specified and append is set" do
before do
@new_resource.append(true)
@new_resource.members([])
end
-
+
it "logs a message and does not modify group membership" do
Chef::Log.should_receive(:debug).with("group[wheel] not changing group members, the group has no members to add")
@provider.should_not_receive(:shell_out!)
@provider.manage_group
end
end
-
+
describe "when removing some group members" do
before do
@new_resource.append(false)
@new_resource.members(%w{ lobster })
end
-
+
it "updates group membership correctly" do
Chef::Log.stub!(:debug)
@provider.should_receive(:shell_out!).with("group mod -n wheel_bak wheel")
@@ -100,14 +100,14 @@ describe Chef::Provider::Group::Groupmod do
end
end
end
-
+
describe "create_group" do
describe "when creating a new group" do
before do
@current_resource = Chef::Resource::Group.new("wheel")
@provider.current_resource = @current_resource
end
-
+
it "should run a group add command and some user mod commands" do
@provider.should_receive(:shell_out!).with("group add -g '123' wheel")
@provider.should_receive(:shell_out!).with("user mod -G wheel lobster")
@@ -117,14 +117,14 @@ describe Chef::Provider::Group::Groupmod do
end
end
end
-
+
describe "remove_group" do
describe "when removing an existing group" do
before do
@current_resource = @new_resource.dup
@provider.current_resource = @current_resource
end
-
+
it "should run a group del command" do
@provider.should_receive(:shell_out!).with("group del wheel")
@provider.remove_group
diff --git a/spec/unit/provider/group/pw_spec.rb b/spec/unit/provider/group/pw_spec.rb
index a7dbdb8615..e7c38f9555 100644
--- a/spec/unit/provider/group/pw_spec.rb
+++ b/spec/unit/provider/group/pw_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,7 +23,7 @@ describe Chef::Provider::Group::Pw do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
-
+
@new_resource = Chef::Resource::Group.new("wheel")
@new_resource.gid 50
@new_resource.members [ "root", "aj"]
@@ -34,12 +34,12 @@ describe Chef::Provider::Group::Pw do
@provider = Chef::Provider::Group::Pw.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
end
-
+
describe "when setting options for the pw command" do
it "does not set the gid option if gids match or are unmanaged" do
@provider.set_options.should == " wheel"
end
-
+
it "sets the option for gid if it is not nil" do
@new_resource.gid(42)
@provider.set_options.should eql(" wheel -g '42'")
@@ -55,7 +55,7 @@ describe Chef::Provider::Group::Pw do
end
describe "when managing the group" do
-
+
it "should run pw groupmod with the return of set_options" do
@new_resource.gid(42)
@provider.should_receive(:run_command).with({ :command => "pw groupmod wheel -g '42' -M root,aj" }).and_return(true)
@@ -72,18 +72,18 @@ describe Chef::Provider::Group::Pw do
end
describe "when setting group membership" do
-
+
describe "with an empty members array in both the new and current resource" do
before do
@new_resource.stub!(:members).and_return([])
@current_resource.stub!(:members).and_return([])
end
-
+
it "should log an appropriate message" do
Chef::Log.should_receive(:debug).with("group[wheel] not changing group members, the group has no members")
@provider.set_members_option
end
-
+
it "should set no options" do
@provider.set_members_option.should eql("")
end
@@ -94,28 +94,28 @@ describe Chef::Provider::Group::Pw do
@new_resource.stub!(:members).and_return([])
@current_resource.stub!(:members).and_return(["all", "your", "base"])
end
-
+
it "should log an appropriate message" do
Chef::Log.should_receive(:debug).with("group[wheel] removing group members all, your, base")
@provider.set_members_option
end
-
+
it "should set the -d option with the members joined by ','" do
@provider.set_members_option.should eql(" -d all,your,base")
end
end
-
+
describe "with supplied members array in the new resource and an empty members array in the current resource" do
before do
@new_resource.stub!(:members).and_return(["all", "your", "base"])
@current_resource.stub!(:members).and_return([])
end
-
+
it "should log an appropriate debug message" do
Chef::Log.should_receive(:debug).with("group[wheel] setting group members to all, your, base")
@provider.set_members_option
end
-
+
it "should set the -M option with the members joined by ','" do
@provider.set_members_option.should eql(" -M all,your,base")
end
@@ -123,7 +123,7 @@ describe Chef::Provider::Group::Pw do
end
describe"load_current_resource" do
- before (:each) do
+ before (:each) do
@provider.load_current_resource
@provider.define_resource_requirements
end
@@ -131,7 +131,7 @@ describe Chef::Provider::Group::Pw do
File.should_receive(:exists?).with("/usr/sbin/pw").and_return(false)
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Group)
end
-
+
it "shouldn't raise an error if /usr/sbin/pw exists" do
File.stub!(:exists?).and_return(true)
lambda { @provider.process_resource_requirements }.should_not raise_error(Chef::Exceptions::Group)
diff --git a/spec/unit/provider/group/usermod_spec.rb b/spec/unit/provider/group/usermod_spec.rb
index 1807aaf57d..7f2931f2e2 100644
--- a/spec/unit/provider/group/usermod_spec.rb
+++ b/spec/unit/provider/group/usermod_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,26 +28,27 @@ describe Chef::Provider::Group::Usermod do
@provider = Chef::Provider::Group::Usermod.new(@new_resource, @run_context)
@provider.stub!(:run_command)
end
-
+
describe "modify_group_members" do
-
+
describe "with an empty members array" do
before do
@new_resource.stub!(:members).and_return([])
end
-
+
it "should log an appropriate message" do
Chef::Log.should_receive(:debug).with("group[wheel] not changing group members, the group has no members")
@provider.modify_group_members
end
end
-
+
describe "with supplied members" do
platforms = {
"openbsd" => "-G",
"netbsd" => "-G",
"solaris" => "-a -G",
"suse" => "-a -G",
+ "opensuse" => "-a -G",
"smartos" => "-G"
}
@@ -60,10 +61,10 @@ describe Chef::Provider::Group::Usermod do
@provider.define_resource_requirements
@provider.load_current_resource
@provider.instance_variable_set("@group_exists", true)
- @provider.action = :modify
+ @provider.action = :modify
lambda { @provider.run_action(@provider.process_resource_requirements) }.should raise_error(Chef::Exceptions::Group, "setting group members directly is not supported by #{@provider.to_s}, must set append true in group")
end
-
+
platforms.each do |platform, flags|
it "should usermod each user when the append option is set on #{platform}" do
@node.automatic_attrs[:platform] = platform
@@ -88,7 +89,7 @@ describe Chef::Provider::Group::Usermod do
File.should_receive(:exists?).with("/usr/sbin/usermod").and_return(false)
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Group)
end
-
+
it "shouldn't raise an error if the required binaries exist" do
File.stub!(:exists?).and_return(true)
lambda { @provider.process_resource_requirements }.should_not raise_error(Chef::Exceptions::Group)
diff --git a/spec/unit/provider/group/windows_spec.rb b/spec/unit/provider/group/windows_spec.rb
index 084d1d0acf..a65cfc241d 100644
--- a/spec/unit/provider/group/windows_spec.rb
+++ b/spec/unit/provider/group/windows_spec.rb
@@ -92,3 +92,17 @@ describe Chef::Provider::Group::Windows do
end
end
end
+
+describe Chef::Provider::Group::Windows, "NetGroup" do
+ before do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ @new_resource = Chef::Resource::Group.new("Creating a new group")
+ @new_resource.group_name "Remote Desktop Users"
+ end
+ it 'sets group_name correctly' do
+ Chef::Util::Windows::NetGroup.should_receive(:new).with("Remote Desktop Users")
+ Chef::Provider::Group::Windows.new(@new_resource, @run_context)
+ end
+end
diff --git a/spec/unit/provider/group_spec.rb b/spec/unit/provider/group_spec.rb
index 106a0db14c..caad9878b6 100644
--- a/spec/unit/provider/group_spec.rb
+++ b/spec/unit/provider/group_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -33,7 +33,7 @@ describe Chef::Provider::User do
@current_resource = Chef::Resource::Group.new("aj", @run_context)
@current_resource.gid 500
@current_resource.members "aj"
-
+
@provider.current_resource = @current_resource
@pw_group = mock("Struct::Group",
@@ -43,13 +43,13 @@ describe Chef::Provider::User do
)
Etc.stub!(:getgrnam).with('wheel').and_return(@pw_group)
end
-
+
it "assumes the group exists by default" do
@provider.group_exists.should be_true
end
describe "when establishing the current state of the group" do
-
+
it "sets the group name of the current resource to the group name of the new resource" do
@provider.load_current_resource
@provider.current_resource.group_name.should == 'wheel'
@@ -65,22 +65,22 @@ describe Chef::Provider::User do
@provider.load_current_resource
@new_resource.gid.should == 20
end
-
+
it "looks up the group in /etc/group with getgrnam" do
Etc.should_receive(:getgrnam).with(@new_resource.group_name).and_return(@pw_group)
@provider.load_current_resource
@provider.current_resource.gid.should == 20
@provider.current_resource.members.should == %w{root aj}
end
-
+
it "should flip the value of exists if it cannot be found in /etc/group" do
Etc.stub!(:getgrnam).and_raise(ArgumentError)
@provider.load_current_resource
@provider.group_exists.should be_false
end
-
+
it "should return the current resource" do
- @provider.load_current_resource.should equal(@provider.current_resource)
+ @provider.load_current_resource.should equal(@provider.current_resource)
end
end
@@ -91,7 +91,7 @@ describe Chef::Provider::User do
@provider.compare_group.should be_true
end
end
-
+
it "should return false if gid and members are equal" do
@provider.compare_group.should be_false
end
@@ -116,29 +116,29 @@ describe Chef::Provider::User do
@provider.should_receive(:create_group).and_return(true)
@provider.run_action(:create)
end
-
- it "should set the the new_resources updated flag when it creates the group" do
+
+ it "should set the new_resources updated flag when it creates the group" do
@provider.group_exists = false
@provider.stub!(:create_group)
@provider.run_action(:create)
@provider.new_resource.should be_updated
end
-
+
it "should check to see if the group has mismatched attributes if the group exists" do
@provider.group_exists = true
@provider.stub!(:compare_group).and_return(false)
@provider.run_action(:create)
@provider.new_resource.should_not be_updated
end
-
+
it "should call manage_group if the group exists and has mismatched attributes" do
@provider.group_exists = true
@provider.stub!(:compare_group).and_return(true)
@provider.should_receive(:manage_group).and_return(true)
@provider.run_action(:create)
end
-
- it "should set the the new_resources updated flag when it creates the group if we call manage_group" do
+
+ it "should set the new_resources updated flag when it creates the group if we call manage_group" do
@provider.group_exists = true
@provider.stub!(:compare_group).and_return(true)
@provider.stub!(:manage_group).and_return(true)
@@ -148,14 +148,14 @@ describe Chef::Provider::User do
end
describe "when removing a group" do
-
+
it "should not call remove_group if the group does not exist" do
@provider.group_exists = false
- @provider.should_not_receive(:remove_group)
+ @provider.should_not_receive(:remove_group)
@provider.run_action(:remove)
@provider.new_resource.should_not be_updated
end
-
+
it "should call remove_group if the group exists" do
@provider.group_exists = true
@provider.should_receive(:remove_group)
@@ -169,26 +169,26 @@ describe Chef::Provider::User do
@provider.group_exists = true
@provider.stub!(:manage_group).and_return(true)
end
-
+
it "should run manage_group if the group exists and has mismatched attributes" do
@provider.should_receive(:compare_group).and_return(true)
@provider.should_receive(:manage_group).and_return(true)
@provider.run_action(:manage)
end
-
+
it "should set the new resources updated flag to true if manage_group is called" do
@provider.stub!(:compare_group).and_return(true)
@provider.stub!(:manage_group).and_return(true)
@provider.run_action(:manage)
@new_resource.should be_updated
end
-
+
it "should not run manage_group if the group does not exist" do
@provider.group_exists = false
@provider.should_not_receive(:manage_group)
@provider.run_action(:manage)
end
-
+
it "should not run manage_group if the group exists but has no differing attributes" do
@provider.should_receive(:compare_group).and_return(false)
@provider.should_not_receive(:manage_group)
@@ -201,26 +201,26 @@ describe Chef::Provider::User do
@provider.group_exists = true
@provider.stub!(:manage_group).and_return(true)
end
-
+
it "should run manage_group if the group exists and has mismatched attributes" do
@provider.should_receive(:compare_group).and_return(true)
@provider.should_receive(:manage_group).and_return(true)
@provider.run_action(:modify)
end
-
+
it "should set the new resources updated flag to true if manage_group is called" do
@provider.stub!(:compare_group).and_return(true)
@provider.stub!(:manage_group).and_return(true)
@provider.run_action(:modify)
@new_resource.should be_updated
end
-
+
it "should not run manage_group if the group exists but has no differing attributes" do
@provider.should_receive(:compare_group).and_return(false)
@provider.should_not_receive(:manage_group)
@provider.run_action(:modify)
end
-
+
it "should raise a Chef::Exceptions::Group if the group doesn't exist" do
@provider.group_exists = false
lambda { @provider.run_action(:modify) }.should raise_error(Chef::Exceptions::Group)
@@ -230,7 +230,7 @@ describe Chef::Provider::User do
describe "when determining the reason for a change" do
it "should report which group members are missing if members are missing and appending to the group" do
@new_resource.members << "user1"
- @new_resource.members << "user2"
+ @new_resource.members << "user2"
@new_resource.stub!(:append).and_return true
@provider.compare_group.should be_true
@provider.change_desc.should == "add missing member(s): user1, user2"
@@ -238,7 +238,7 @@ describe Chef::Provider::User do
it "should report that the group members will be overwritten if not appending" do
@new_resource.members << "user1"
- @new_resource.stub!(:append).and_return false
+ @new_resource.stub!(:append).and_return false
@provider.compare_group.should be_true
@provider.change_desc.should == "replace group members with new list of members"
end
diff --git a/spec/unit/provider/http_request_spec.rb b/spec/unit/provider/http_request_spec.rb
index 436eaec558..e8ce5f9ae3 100644
--- a/spec/unit/provider/http_request_spec.rb
+++ b/spec/unit/provider/http_request_spec.rb
@@ -35,7 +35,7 @@ describe Chef::Provider::HttpRequest do
describe "load_current_resource" do
it "should set up a Chef::REST client, with no authentication" do
- Chef::REST.should_receive(:new).with(@new_resource.url, nil, nil)
+ Chef::HTTP::Simple.should_receive(:new).with(@new_resource.url)
@provider.load_current_resource
end
end
@@ -45,21 +45,21 @@ describe Chef::Provider::HttpRequest do
# run_action(x) forces load_current_resource to run;
# that would overwrite our supplied mock Chef::Rest # object
@provider.stub!(:load_current_resource).and_return(true)
- @rest = mock("Chef::REST")
- @provider.rest = @rest
+ @http = mock("Chef::REST")
+ @provider.http = @http
end
describe "action_get" do
it "should inflate a message block at runtime" do
@new_resource.message { "return" }
- @rest.should_receive(:get).with("http://www.opscode.com/?message=return", false, {})
+ @http.should_receive(:get).with("http://www.opscode.com/?message=return", {})
@provider.run_action(:get)
@new_resource.should be_updated
end
it "should run a GET request" do
- @rest.should_receive(:get).with("http://www.opscode.com/?message=is cool", false, {})
+ @http.should_receive(:get).with("http://www.opscode.com/?message=is cool", {})
@provider.run_action(:get)
@new_resource.should be_updated
end
@@ -67,14 +67,14 @@ describe Chef::Provider::HttpRequest do
describe "action_put" do
it "should run a PUT request with the message as the payload" do
- @rest.should_receive(:put).with("http://www.opscode.com/", @new_resource.message, {})
+ @http.should_receive(:put).with("http://www.opscode.com/", @new_resource.message, {})
@provider.run_action(:put)
@new_resource.should be_updated
end
it "should inflate a message block at runtime" do
@new_resource.stub!(:message).and_return(lambda { "return" })
- @rest.should_receive(:put).with("http://www.opscode.com/", "return", {})
+ @http.should_receive(:put).with("http://www.opscode.com/", "return", {})
@provider.run_action(:put)
@new_resource.should be_updated
end
@@ -82,14 +82,14 @@ describe Chef::Provider::HttpRequest do
describe "action_post" do
it "should run a PUT request with the message as the payload" do
- @rest.should_receive(:post).with("http://www.opscode.com/", @new_resource.message, {})
+ @http.should_receive(:post).with("http://www.opscode.com/", @new_resource.message, {})
@provider.run_action(:post)
@new_resource.should be_updated
end
it "should inflate a message block at runtime" do
@new_resource.message { "return" }
- @rest.should_receive(:post).with("http://www.opscode.com/", "return", {})
+ @http.should_receive(:post).with("http://www.opscode.com/", "return", {})
@provider.run_action(:post)
@new_resource.should be_updated
end
@@ -97,7 +97,7 @@ describe Chef::Provider::HttpRequest do
describe "action_delete" do
it "should run a DELETE request" do
- @rest.should_receive(:delete).with("http://www.opscode.com/", {})
+ @http.should_receive(:delete).with("http://www.opscode.com/", {})
@provider.run_action(:delete)
@new_resource.should be_updated
end
@@ -105,30 +105,30 @@ describe Chef::Provider::HttpRequest do
describe "action_head" do
before do
- @provider.rest = @rest
+ @provider.http = @http
end
it "should inflate a message block at runtime" do
@new_resource.message { "return" }
- @rest.should_receive(:head).with("http://www.opscode.com/?message=return", {}).and_return("")
+ @http.should_receive(:head).with("http://www.opscode.com/?message=return", {}).and_return("")
@provider.run_action(:head)
@new_resource.should be_updated
end
it "should run a HEAD request" do
- @rest.should_receive(:head).with("http://www.opscode.com/?message=is cool", {}).and_return("")
+ @http.should_receive(:head).with("http://www.opscode.com/?message=is cool", {}).and_return("")
@provider.run_action(:head)
@new_resource.should be_updated
end
it "should run a HEAD request with If-Modified-Since header" do
@new_resource.headers "If-Modified-Since" => File.mtime(__FILE__).httpdate
- @rest.should_receive(:head).with("http://www.opscode.com/?message=is cool", @new_resource.headers)
+ @http.should_receive(:head).with("http://www.opscode.com/?message=is cool", @new_resource.headers)
@provider.run_action(:head)
end
it "doesn't call converge_by if HEAD does not return modified" do
- @rest.should_receive(:head).and_return(false)
+ @http.should_receive(:head).and_return(false)
@provider.should_not_receive(:converge_by)
@provider.run_action(:head)
end
diff --git a/spec/unit/provider/ifconfig/aix_spec.rb b/spec/unit/provider/ifconfig/aix_spec.rb
new file mode 100644
index 0000000000..39e9919740
--- /dev/null
+++ b/spec/unit/provider/ifconfig/aix_spec.rb
@@ -0,0 +1,180 @@
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+require 'chef/exceptions'
+
+describe Chef::Provider::Ifconfig::Aix do
+
+ before(:all) do
+ @ifconfig_output = <<-IFCONFIG
+en1: flags=1e080863,480<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,CHECKSUM_OFFLOAD(ACTIVE),CHAIN>
+ inet 10.153.11.59 netmask 0xffff0000 broadcast 10.153.255.255
+ tcp_sendspace 262144 tcp_recvspace 262144 rfc1323 1
+en0: flags=1e080863,480<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,CHECKSUM_OFFLOAD(ACTIVE),CHAIN> metric 1
+ inet 172.29.174.58 netmask 0xffffc000 broadcast 172.29.191.255
+ tcp_sendspace 262144 tcp_recvspace 262144 rfc1323 1
+lo0: flags=e08084b,c0<UP,BROADCAST,LOOPBACK,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,LARGESEND,CHAIN>
+ inet 127.0.0.1 netmask 0xff000000 broadcast 127.255.255.255
+ inet6 ::1%1/0
+IFCONFIG
+ end
+
+
+ before(:each) do
+ @node = Chef::Node.new
+ @cookbook_collection = Chef::CookbookCollection.new([])
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
+
+ @new_resource = Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)
+
+ @provider = Chef::Provider::Ifconfig::Aix.new(@new_resource, @run_context)
+ end
+
+ describe "#load_current_resource" do
+ before do
+ status = double("Status", :exitstatus => 0)
+ @provider.should_receive(:popen4).with("ifconfig -a").and_yield(@pid,@stdin,StringIO.new(@ifconfig_output),@stderr).and_return(status)
+ @new_resource.device "en0"
+ end
+ it "should load given interface with attributes." do
+ current_resource = @provider.load_current_resource
+ expect(current_resource.inet_addr).to eq("172.29.174.58")
+ expect(current_resource.target).to eq(@new_resource.target)
+ expect(current_resource.mask).to eq("255.255.192.0")
+ expect(current_resource.bcast).to eq("172.29.191.255")
+ expect(current_resource.metric).to eq("1")
+ end
+ end
+
+ describe "#action_add" do
+
+ it "should add an interface if it does not exist" do
+ @new_resource.device "en10"
+ @provider.stub!(:load_current_resource) do
+ @provider.instance_variable_set("@status", double("Status", :exitstatus => 0))
+ @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context))
+ end
+ command = "chdev -l #{@new_resource.device} -a netaddr=#{@new_resource.name}"
+ @provider.should_receive(:run_command).with(:command => command)
+
+ @provider.run_action(:add)
+ @new_resource.should be_updated
+ end
+
+ it "should raise exception if metric attribute is set" do
+ @new_resource.device "en0"
+ @new_resource.metric "1"
+ @provider.stub!(:load_current_resource) do
+ @provider.instance_variable_set("@status", double("Status", :exitstatus => 0))
+ @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context))
+ end
+
+ expect{@provider.run_action(:add)}.to raise_error(Chef::Exceptions::Ifconfig, "interface metric attribute cannot be set for :add action")
+ end
+ end
+
+ describe "#action_enable" do
+ it "should enable an interface if it does not exist" do
+ @new_resource.device "en10"
+ @provider.stub!(:load_current_resource) do
+ @provider.instance_variable_set("@status", double("Status", :exitstatus => 0))
+ @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context))
+ end
+ command = "ifconfig #{@new_resource.device} #{@new_resource.name}"
+ @provider.should_receive(:run_command).with(:command => command)
+
+ @provider.run_action(:enable)
+ @new_resource.should be_updated
+ end
+ end
+
+ describe "#action_disable" do
+
+ it "should not disable an interface if it does not exist" do
+ @new_resource.device "en10"
+ @provider.stub!(:load_current_resource) do
+ @provider.instance_variable_set("@status", double("Status", :exitstatus => 0))
+ @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context))
+ end
+
+ @provider.should_not_receive(:run_command)
+
+ @provider.run_action(:disable)
+ @new_resource.should_not be_updated
+ end
+
+ context "interface exists" do
+ before do
+ @new_resource.device "en10"
+ @provider.stub!(:load_current_resource) do
+ @provider.instance_variable_set("@status", double("Status", :exitstatus => 0))
+ current_resource = Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)
+ current_resource.device @new_resource.device
+ @provider.instance_variable_set("@current_resource", current_resource)
+ end
+ end
+
+ it "should disable an interface if it exists" do
+ command = "ifconfig #{@new_resource.device} down"
+ @provider.should_receive(:run_command).with(:command => command)
+
+ @provider.run_action(:disable)
+ @new_resource.should be_updated
+ end
+
+ end
+ end
+
+ describe "#action_delete" do
+
+ it "should not delete an interface if it does not exist" do
+ @new_resource.device "en10"
+ @provider.stub!(:load_current_resource) do
+ @provider.instance_variable_set("@status", double("Status", :exitstatus => 0))
+ @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context))
+ end
+
+ @provider.should_not_receive(:run_command)
+
+ @provider.run_action(:delete)
+ @new_resource.should_not be_updated
+ end
+
+ context "interface exists" do
+ before do
+ @new_resource.device "en10"
+ @provider.stub!(:load_current_resource) do
+ @provider.instance_variable_set("@status", double("Status", :exitstatus => 0))
+ current_resource = Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)
+ current_resource.device @new_resource.device
+ @provider.instance_variable_set("@current_resource", current_resource)
+ end
+ end
+
+ it "should delete an interface if it exists" do
+ command = "chdev -l #{@new_resource.device} -a state=down"
+ @provider.should_receive(:run_command).with(:command => command)
+
+ @provider.run_action(:delete)
+ @new_resource.should be_updated
+ end
+ end
+ end
+end
diff --git a/spec/unit/provider/ifconfig_spec.rb b/spec/unit/provider/ifconfig_spec.rb
index 1da14fc9ac..f4fdc23353 100644
--- a/spec/unit/provider/ifconfig_spec.rb
+++ b/spec/unit/provider/ifconfig_spec.rb
@@ -38,20 +38,20 @@ describe Chef::Provider::Ifconfig do
status = mock("Status", :exitstatus => 0)
@provider.instance_variable_set("@status", status)
@provider.current_resource = @current_resource
-
+
end
- describe Chef::Provider::Ifconfig, "load_current_resource" do
- before do
+ describe Chef::Provider::Ifconfig, "load_current_resource" do
+ before do
status = mock("Status", :exitstatus => 1)
- @provider.should_receive(:popen4).and_return status
+ @provider.should_receive(:popen4).and_return status
@provider.load_current_resource
end
it "should track state of ifconfig failure." do
@provider.instance_variable_get("@status").exitstatus.should_not == 0
end
- it "should thrown an exception when ifconfig fails" do
+ it "should thrown an exception when ifconfig fails" do
@provider.define_resource_requirements
- lambda { @provider.process_resource_requirements }.should raise_error Chef::Exceptions::Ifconfig
+ lambda { @provider.process_resource_requirements }.should raise_error Chef::Exceptions::Ifconfig
end
end
describe Chef::Provider::Ifconfig, "action_add" do
@@ -72,7 +72,7 @@ describe Chef::Provider::Ifconfig do
@provider.stub!(:load_current_resource)
@provider.should_not_receive(:run_command)
@current_resource.inet_addr "10.0.0.1"
- @provider.should_receive(:generate_config)
+ @provider.should_not_receive(:generate_config)
@provider.run_action(:add)
@new_resource.should_not be_updated
@@ -84,7 +84,7 @@ describe Chef::Provider::Ifconfig do
end
describe Chef::Provider::Ifconfig, "action_enable" do
-
+
it "should enable interface if does not exist" do
@provider.stub!(:load_current_resource)
@current_resource.inet_addr nil
@@ -129,7 +129,7 @@ describe Chef::Provider::Ifconfig do
@new_resource.should_not be_updated
end
end
-
+
describe Chef::Provider::Ifconfig, "action_disable" do
it "should disable interface if it exists" do
diff --git a/spec/unit/provider/link_spec.rb b/spec/unit/provider/link_spec.rb
index 171e21171c..bd3204510b 100644
--- a/spec/unit/provider/link_spec.rb
+++ b/spec/unit/provider/link_spec.rb
@@ -241,8 +241,8 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
result
end
it 'create does no work' do
- provider.file_class.should_not_receive(:symlink)
- provider.file_class.should_not_receive(:link)
+ provider.file_class.should_not_receive(:symlink)
+ provider.file_class.should_not_receive(:link)
provider.access_controls.should_not_receive(:set_all)
provider.run_action(:create)
end
diff --git a/spec/unit/provider/log_spec.rb b/spec/unit/provider/log_spec.rb
index fe3733240a..f6ff526dd4 100644
--- a/spec/unit/provider/log_spec.rb
+++ b/spec/unit/provider/log_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,7 +25,7 @@ describe Chef::Provider::Log::ChefLog do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
- end
+ end
it "should be registered with the default platform hash" do
Chef::Platform.platforms[:default][:log].should_not be_nil
@@ -37,7 +37,7 @@ describe Chef::Provider::Log::ChefLog do
Chef::Log.should_receive(:info).with(@log_str).and_return(true)
@provider.action_write
end
-
+
it "should write the string to the Chef::Log object at debug level" do
@new_resource = Chef::Resource::Log.new(@log_str)
@new_resource.level :debug
@@ -53,7 +53,7 @@ describe Chef::Provider::Log::ChefLog do
Chef::Log.should_receive(:info).with(@log_str).and_return(true)
@provider.action_write
end
-
+
it "should write the string to the Chef::Log object at warn level" do
@new_resource = Chef::Resource::Log.new(@log_str)
@new_resource.level :warn
@@ -61,7 +61,7 @@ describe Chef::Provider::Log::ChefLog do
Chef::Log.should_receive(:warn).with(@log_str).and_return(true)
@provider.action_write
end
-
+
it "should write the string to the Chef::Log object at error level" do
@new_resource = Chef::Resource::Log.new(@log_str)
@new_resource.level :error
@@ -69,7 +69,7 @@ describe Chef::Provider::Log::ChefLog do
Chef::Log.should_receive(:error).with(@log_str).and_return(true)
@provider.action_write
end
-
+
it "should write the string to the Chef::Log object at fatal level" do
@new_resource = Chef::Resource::Log.new(@log_str)
@new_resource.level :fatal
@@ -77,5 +77,5 @@ describe Chef::Provider::Log::ChefLog do
Chef::Log.should_receive(:fatal).with(@log_str).and_return(true)
@provider.action_write
end
-
+
end
diff --git a/spec/unit/provider/mdadm_spec.rb b/spec/unit/provider/mdadm_spec.rb
index a818c37101..25991e4732 100644
--- a/spec/unit/provider/mdadm_spec.rb
+++ b/spec/unit/provider/mdadm_spec.rb
@@ -25,12 +25,8 @@ describe Chef::Provider::Mdadm do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
-
@new_resource = Chef::Resource::Mdadm.new('/dev/md1')
- @new_resource.devices ["/dev/sdz1","/dev/sdz2"]
- @new_resource.level 1
- @new_resource.chunk 256
-
+ @new_resource.devices ["/dev/sdz1","/dev/sdz2","/dev/sdz3"]
@provider = Chef::Provider::Mdadm.new(@new_resource, @run_context)
end
@@ -58,9 +54,7 @@ describe Chef::Provider::Mdadm do
describe "after the metadevice status is known" do
before(:each) do
@current_resource = Chef::Resource::Mdadm.new('/dev/md1')
- @current_resource.devices ["/dev/sdz1","/dev/sdz2"]
- @current_resource.level 1
- @current_resource.chunk 256
+ @new_resource.level 5
@provider.stub!(:load_current_resource).and_return(true)
@provider.current_resource = @current_resource
end
@@ -68,7 +62,7 @@ describe Chef::Provider::Mdadm do
describe "when creating the metadevice" do
it "should create the raid device if it doesnt exist" do
@current_resource.exists(false)
- expected_command = "yes | mdadm --create /dev/md1 --chunk=256 --level 1 --metadata=0.90 --raid-devices 2 /dev/sdz1 /dev/sdz2"
+ expected_command = "yes | mdadm --create /dev/md1 --level 5 --chunk=16 --metadata=0.90 --raid-devices 3 /dev/sdz1 /dev/sdz2 /dev/sdz3"
@provider.should_receive(:shell_out!).with(expected_command)
@provider.run_action(:create)
end
@@ -76,7 +70,16 @@ describe Chef::Provider::Mdadm do
it "should specify a bitmap only if set" do
@current_resource.exists(false)
@new_resource.bitmap('grow')
- expected_command = "yes | mdadm --create /dev/md1 --chunk=256 --level 1 --metadata=0.90 --bitmap=grow --raid-devices 2 /dev/sdz1 /dev/sdz2"
+ expected_command = "yes | mdadm --create /dev/md1 --level 5 --chunk=16 --metadata=0.90 --bitmap=grow --raid-devices 3 /dev/sdz1 /dev/sdz2 /dev/sdz3"
+ @provider.should_receive(:shell_out!).with(expected_command)
+ @provider.run_action(:create)
+ @new_resource.should be_updated_by_last_action
+ end
+
+ it "should not specify a chunksize if raid level 1" do
+ @current_resource.exists(false)
+ @new_resource.level 1
+ expected_command = "yes | mdadm --create /dev/md1 --level 1 --metadata=0.90 --raid-devices 3 /dev/sdz1 /dev/sdz2 /dev/sdz3"
@provider.should_receive(:shell_out!).with(expected_command)
@provider.run_action(:create)
@new_resource.should be_updated_by_last_action
@@ -93,7 +96,7 @@ describe Chef::Provider::Mdadm do
describe "when asembling the metadevice" do
it "should assemble the raid device if it doesnt exist" do
@current_resource.exists(false)
- expected_mdadm_cmd = "yes | mdadm --assemble /dev/md1 /dev/sdz1 /dev/sdz2"
+ expected_mdadm_cmd = "yes | mdadm --assemble /dev/md1 /dev/sdz1 /dev/sdz2 /dev/sdz3"
@provider.should_receive(:shell_out!).with(expected_mdadm_cmd)
@provider.run_action(:assemble)
@new_resource.should be_updated_by_last_action
diff --git a/spec/unit/provider/mount/aix_spec.rb b/spec/unit/provider/mount/aix_spec.rb
new file mode 100644
index 0000000000..89de47038a
--- /dev/null
+++ b/spec/unit/provider/mount/aix_spec.rb
@@ -0,0 +1,237 @@
+#
+# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
+# Copyright:: Copyright (c) 2013 OpsCode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+require 'ostruct'
+
+describe Chef::Provider::Mount::Aix do
+
+ before(:all) do
+ @mounted_output = <<-MOUNT
+ node mounted mounted over vfs date options
+-------- --------------- --------------- ------ ------------ ---------------
+ /dev/sdz1 /tmp/foo jfs2 Jul 17 13:22 rw,log=/dev/hd8
+MOUNT
+
+ @unmounted_output = <<-UNMOUNTED
+ node mounted mounted over vfs date options
+-------- --------------- --------------- ------ ------------ ---------------
+ /dev/sdz2 / jfs2 Jul 17 13:22 rw,log=/dev/hd8
+UNMOUNTED
+
+ @conflict_mounted_output = <<-MOUNT
+ node mounted mounted over vfs date options
+-------- --------------- --------------- ------ ------------ ---------------
+ /dev/sdz3 /tmp/foo jfs2 Jul 17 13:22 rw,log=/dev/hd8
+MOUNT
+
+ @enabled_output = <<-ENABLED
+#MountPoint:Device:Vfs:Nodename:Type:Size:Options:AutoMount:Acct
+/tmp/foo:/dev/sdz1:jfs2::bootfs:10485760:rw:yes:no
+ENABLED
+ end
+
+ before(:each) do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+
+ @new_resource = Chef::Resource::Mount.new("/tmp/foo")
+ @new_resource.device "/dev/sdz1"
+ @new_resource.device_type :device
+ @new_resource.fstype "jfs2"
+
+ @new_resource.supports :remount => false
+
+ @provider = Chef::Provider::Mount::Aix.new(@new_resource, @run_context)
+
+ ::File.stub!(:exists?).with("/dev/sdz1").and_return true
+ ::File.stub!(:exists?).with("/tmp/foo").and_return true
+ end
+
+ def stub_mounted(provider, mounted_output)
+ response = double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => mounted_output, :stderr => "")
+ provider.should_receive(:shell_out!).with("mount").and_return(response)
+ end
+
+ def stub_enabled(provider, enabled_output)
+ response = double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => enabled_output, :stderr => "")
+ provider.should_receive(:shell_out).with("lsfs -c #{@new_resource.mount_point}").and_return(response)
+ end
+
+ def stub_mounted_enabled(provider, mounted_output, enabled_output)
+ stub_mounted(provider, mounted_output)
+ stub_enabled(provider, enabled_output)
+ end
+
+ describe "when discovering the current fs state" do
+ it "should set current_resource.mounted to true if device is already mounted" do
+ stub_mounted_enabled(@provider, @mounted_output, "")
+ @provider.load_current_resource
+
+ expect(@provider.current_resource.mounted).to be_true
+ end
+
+ it "should set current_resource.mounted to false if device is not mounted" do
+ stub_mounted_enabled(@provider, @unmounted_output, "")
+
+ @provider.load_current_resource
+
+ expect(@provider.current_resource.mounted).to be_false
+ end
+
+ it "should set current_resource.mounted to false if the mount point is used for another device" do
+ stub_mounted_enabled(@provider, @conflict_mounted_output, "")
+
+ @provider.load_current_resource
+
+ expect(@provider.current_resource.mounted).to be_false
+ end
+ end
+
+ # tests for #enabled?
+ it "should load current_resource with properties if device is already mounted and enabled" do
+ stub_mounted_enabled(@provider, @mounted_output, @enabled_output)
+
+ @provider.load_current_resource
+
+ expect(@provider.current_resource.enabled).to be_true
+ expect(@provider.current_resource.mounted).to be_true
+ expect(@provider.current_resource.mount_point).to eql(@new_resource.mount_point)
+ expect(@provider.current_resource.fstype).to eql("jfs2")
+ expect(@provider.current_resource.options).to eql(['rw'])
+ end
+
+ describe "mount_fs" do
+ it "should mount resource if it is not mounted" do
+ stub_mounted_enabled(@provider, @unmounted_output, "")
+
+ @provider.should_receive(:shell_out!).with("mount -v #{@new_resource.fstype} #{@new_resource.device} #{@new_resource.mount_point}")
+
+ @provider.run_action(:mount)
+ end
+
+ it "should not mount resource if it is already mounted" do
+ stub_mounted_enabled(@provider, @mounted_output, "")
+
+ @provider.should_not_receive(:mount_fs)
+
+ @provider.run_action(:mount)
+ end
+ end
+
+ describe "umount_fs" do
+ it "should umount resource if it is already mounted" do
+ stub_mounted_enabled(@provider, @mounted_output, "")
+
+ @provider.should_receive(:shell_out!).with("umount #{@new_resource.mount_point}")
+
+ @provider.run_action(:umount)
+ end
+
+ it "should not umount resource if it is not mounted" do
+ stub_mounted_enabled(@provider, @unmounted_output, "")
+
+ @provider.should_not_receive(:umount_fs)
+
+ @provider.run_action(:umount)
+ end
+ end
+
+ describe "remount_fs" do
+ it "should remount resource if it is already mounted and it supports remounting" do
+ @new_resource.supports({:remount => true})
+ stub_mounted_enabled(@provider, @mounted_output, "")
+
+ @provider.should_receive(:shell_out!).with("mount -o remount #{@new_resource.device} #{@new_resource.mount_point}")
+
+ @provider.run_action(:remount)
+ end
+
+ it "should remount with new mount options if it is already mounted and it supports remounting" do
+ @new_resource.supports({:remount => true})
+ @new_resource.options("nodev,rw")
+ stub_mounted_enabled(@provider, @mounted_output, "")
+
+ @provider.should_receive(:shell_out!).with("mount -o remount,nodev,rw #{@new_resource.device} #{@new_resource.mount_point}")
+
+ @provider.run_action(:remount)
+ end
+ end
+
+ describe "enable_fs" do
+ it "should enable mount if it is mounted and not enabled" do
+ @new_resource.options("nodev,rw")
+ stub_mounted_enabled(@provider, @mounted_output, "")
+ filesystems = StringIO.new
+ ::File.stub!(:open).with("/etc/filesystems", "a").and_yield(filesystems)
+
+ @provider.run_action(:enable)
+
+ filesystems.string.should match(%r{^/tmp/foo:\n\tdev\t\t= /dev/sdz1\n\tvfs\t\t= jfs2\n\tmount\t\t= false\n\toptions\t\t= nodev,rw\n$})
+ end
+
+ it "should not enable mount if it is mounted and already enabled and mount options are unchanged" do
+ stub_mounted_enabled(@provider, @mounted_output, @enabled_output)
+ @new_resource.options "rw"
+
+ @provider.should_not_receive(:enable_fs)
+
+ @provider.run_action(:enable)
+ end
+ end
+
+ describe "disable_fs" do
+ it "should disable mount if it is mounted and enabled" do
+ stub_mounted_enabled(@provider, @mounted_output, @enabled_output)
+
+ ::File.stub!(:open).with("/etc/filesystems", "r").and_return(<<-ETCFILESYSTEMS)
+/tmp/foo:
+ dev = /dev/sdz1
+ vfs = jfs2
+ log = /dev/hd8
+ mount = true
+ check = true
+ vol = /opt
+ free = false
+ quota = no
+
+/tmp/abc:
+ dev = /dev/sdz2
+ vfs = jfs2
+ mount = true
+ options = rw
+ETCFILESYSTEMS
+
+ filesystems = StringIO.new
+ ::File.stub!(:open).with("/etc/filesystems", "w").and_yield(filesystems)
+
+ @provider.run_action(:disable)
+
+ filesystems.string.should match(%r{^/tmp/abc:\s+dev\s+= /dev/sdz2\s+vfs\s+= jfs2\s+mount\s+= true\s+options\s+= rw\n$})
+ end
+
+ it "should not disable mount if it is not mounted" do
+ stub_mounted_enabled(@provider, @unmounted_output, "")
+
+ @provider.should_not_receive(:disable_fs)
+
+ @provider.run_action(:disable)
+ end
+ end
+end
diff --git a/spec/unit/provider/mount/mount_spec.rb b/spec/unit/provider/mount/mount_spec.rb
index 00cc9a10e2..cf0e8791de 100644
--- a/spec/unit/provider/mount/mount_spec.rb
+++ b/spec/unit/provider/mount/mount_spec.rb
@@ -36,6 +36,8 @@ describe Chef::Provider::Mount::Mount do
::File.stub!(:exists?).with("/dev/sdz1").and_return true
::File.stub!(:exists?).with("/tmp/foo").and_return true
+ ::File.stub!(:realpath).with("/dev/sdz1").and_return "/dev/sdz1"
+ ::File.stub!(:realpath).with("/tmp/foo").and_return "/tmp/foo"
end
describe "when discovering the current fs state" do
diff --git a/spec/unit/provider/mount/windows_spec.rb b/spec/unit/provider/mount/windows_spec.rb
index 74579b14fe..4c9916ae87 100644
--- a/spec/unit/provider/mount/windows_spec.rb
+++ b/spec/unit/provider/mount/windows_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/provider/mount_spec.rb b/spec/unit/provider/mount_spec.rb
index 1a98f10cb0..a44f9705ee 100644
--- a/spec/unit/provider/mount_spec.rb
+++ b/spec/unit/provider/mount_spec.rb
@@ -23,13 +23,13 @@ describe Chef::Provider::Mount do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
-
+
@new_resource = Chef::Resource::Mount.new('/tmp/foo')
@new_resource.device "/dev/sdz1"
@new_resource.name "/tmp/foo"
@new_resource.mount_point "/tmp/foo"
@new_resource.fstype "ext3"
-
+
@current_resource = Chef::Resource::Mount.new('/tmp/foo')
@current_resource.device "/dev/sdz1"
@current_resource.name "/tmp/foo"
@@ -39,7 +39,7 @@ describe Chef::Provider::Mount do
@provider = Chef::Provider::Mount.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
end
-
+
describe "when the target state is a mounted filesystem" do
it "should mount the filesystem if it isn't mounted" do
@@ -78,7 +78,7 @@ describe Chef::Provider::Mount do
before do
@new_resource.supports[:remount] = true
end
-
+
it "should remount the filesystem if it is mounted" do
@current_resource.stub!(:mounted).and_return(true)
@provider.should_receive(:remount_fs).and_return(true)
@@ -93,8 +93,8 @@ describe Chef::Provider::Mount do
@new_resource.should_not be_updated_by_last_action
end
end
- describe "when the filesystem should be remounted and the resource does not support remounting" do
- before do
+ describe "when the filesystem should be remounted and the resource does not support remounting" do
+ before do
@new_resource.supports[:remount] = false
end
diff --git a/spec/unit/provider/package/aix_spec.rb b/spec/unit/provider/package/aix_spec.rb
new file mode 100644
index 0000000000..6e936156a0
--- /dev/null
+++ b/spec/unit/provider/package/aix_spec.rb
@@ -0,0 +1,171 @@
+#
+# Author:: Deepali Jagtap (deepali.jagtap@clogeny.com)
+# Author:: Prabhu Das (prabhu.das@clogeny.com)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+require 'spec_helper'
+
+describe Chef::Provider::Package::Aix do
+ before(:each) do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+
+ @new_resource = Chef::Resource::Package.new("samba.base")
+ @new_resource.source("/tmp/samba.base")
+
+ @provider = Chef::Provider::Package::Aix.new(@new_resource, @run_context)
+ ::File.stub!(:exists?).and_return(true)
+ end
+
+ describe "assessing the current package status" do
+ before do
+ @bffinfo ="/usr/lib/objrepos:samba.base:3.3.12.0::COMMITTED:I:Samba for AIX:
+ /etc/objrepos:samba.base:3.3.12.0::COMMITTED:I:Samba for AIX:"
+
+ @status = mock("Status", :exitstatus => 0)
+ end
+
+ it "should create a current resource with the name of new_resource" do
+ @provider.stub!(:popen4).and_return(@status)
+ @provider.load_current_resource
+ @provider.current_resource.name.should == "samba.base"
+ end
+
+ it "should set the current resource bff package name to the new resource bff package name" do
+ @provider.stub!(:popen4).and_return(@status)
+ @provider.load_current_resource
+ @provider.current_resource.package_name.should == "samba.base"
+ end
+
+ it "should raise an exception if a source is supplied but not found" do
+ @provider.stub!(:popen4).and_return(@status)
+ ::File.stub!(:exists?).and_return(false)
+ @provider.define_resource_requirements
+ @provider.load_current_resource
+ lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Package)
+ end
+
+
+ it "should get the source package version from lslpp if provided" do
+ @stdout = StringIO.new(@bffinfo)
+ @stdin, @stderr = StringIO.new, StringIO.new
+ @provider.should_receive(:popen4).with("installp -L -d /tmp/samba.base").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.should_receive(:popen4).with("lslpp -lcq samba.base").and_return(@status)
+ @provider.load_current_resource
+
+ @provider.current_resource.package_name.should == "samba.base"
+ @new_resource.version.should == "3.3.12.0"
+ end
+
+ it "should return the current version installed if found by lslpp" do
+ @stdout = StringIO.new(@bffinfo)
+ @stdin, @stderr = StringIO.new, StringIO.new
+ @provider.should_receive(:popen4).with("installp -L -d /tmp/samba.base").and_return(@status)
+ @provider.should_receive(:popen4).with("lslpp -lcq samba.base").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.load_current_resource
+ @provider.current_resource.version.should == "3.3.12.0"
+ end
+
+ it "should raise an exception if the source is not set but we are installing" do
+ @new_resource = Chef::Resource::Package.new("samba.base")
+ @provider = Chef::Provider::Package::Aix.new(@new_resource, @run_context)
+ @provider.stub!(:popen4).and_return(@status)
+ lambda { @provider.run_action(:install) }.should raise_error(Chef::Exceptions::Package)
+ end
+
+ it "should raise an exception if installp/lslpp fails to run" do
+ @status = mock("Status", :exitstatus => -1)
+ @provider.stub!(:popen4).and_return(@status)
+ lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package)
+ end
+
+ it "should return a current resource with a nil version if the package is not found" do
+ @stdout = StringIO.new
+ @provider.should_receive(:popen4).with("installp -L -d /tmp/samba.base").and_return(@status)
+ @provider.should_receive(:popen4).with("lslpp -lcq samba.base").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.load_current_resource
+ @provider.current_resource.version.should be_nil
+ end
+ end
+
+ describe "candidate_version" do
+ it "should return the candidate_version variable if already setup" do
+ @provider.candidate_version = "3.3.12.0"
+ @provider.should_not_receive(:popen4)
+ @provider.candidate_version
+ end
+
+ it "should lookup the candidate_version if the variable is not already set" do
+ @status = mock("Status", :exitstatus => 0)
+ @provider.should_receive(:popen4).and_return(@status)
+ @provider.candidate_version
+ end
+
+ it "should throw and exception if the exitstatus is not 0" do
+ @status = mock("Status", :exitstatus => 1)
+ @provider.stub!(:popen4).and_return(@status)
+ lambda { @provider.candidate_version }.should raise_error(Chef::Exceptions::Package)
+ end
+
+ end
+
+ describe "install and upgrade" do
+ it "should run installp -aYF -d with the package source to install" do
+ @provider.should_receive(:run_command_with_systems_locale).with({
+ :command => "installp -aYF -d /tmp/samba.base samba.base"
+ })
+ @provider.install_package("samba.base", "3.3.12.0")
+ end
+
+ it "should run when the package is a path to install" do
+ @new_resource = Chef::Resource::Package.new("/tmp/samba.base")
+ @provider = Chef::Provider::Package::Aix.new(@new_resource, @run_context)
+ @new_resource.source.should == "/tmp/samba.base"
+ @provider.should_receive(:run_command_with_systems_locale).with({
+ :command => "installp -aYF -d /tmp/samba.base /tmp/samba.base"
+ })
+ @provider.install_package("/tmp/samba.base", "3.3.12.0")
+ end
+
+ it "should run installp with -eLogfile option." do
+ @new_resource.stub!(:options).and_return("-e/tmp/installp.log")
+ @provider.should_receive(:run_command_with_systems_locale).with({
+ :command => "installp -aYF -e/tmp/installp.log -d /tmp/samba.base samba.base"
+ })
+ @provider.install_package("samba.base", "3.3.12.0")
+ end
+ end
+
+ describe "remove" do
+ it "should run installp -u samba.base to remove the package" do
+ @provider.should_receive(:run_command_with_systems_locale).with({
+ :command => "installp -u samba.base"
+ })
+ @provider.remove_package("samba.base", "3.3.12.0")
+ end
+
+ it "should run installp -u -e/tmp/installp.log with options -e/tmp/installp.log" do
+ @new_resource.stub!(:options).and_return("-e/tmp/installp.log")
+ @provider.should_receive(:run_command_with_systems_locale).with({
+ :command => "installp -u -e/tmp/installp.log samba.base"
+ })
+ @provider.remove_package("samba.base", "3.3.12.0")
+ end
+
+ end
+end
+
diff --git a/spec/unit/provider/package/apt_spec.rb b/spec/unit/provider/package/apt_spec.rb
index 06ada5189e..32b55163b4 100644
--- a/spec/unit/provider/package/apt_spec.rb
+++ b/spec/unit/provider/package/apt_spec.rb
@@ -25,11 +25,9 @@ describe Chef::Provider::Package::Apt do
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Package.new("irssi", @run_context)
- @current_resource = Chef::Resource::Package.new("irssi", @run_context)
@status = mock("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::Apt.new(@new_resource, @run_context)
- Chef::Resource::Package.stub!(:new).and_return(@current_resource)
@stdin = StringIO.new
@stdout =<<-PKG_STATUS
irssi:
@@ -39,34 +37,21 @@ irssi:
0.8.14-1ubuntu4 0
500 http://us.archive.ubuntu.com/ubuntu/ lucid/main Packages
PKG_STATUS
- @stderr = StringIO.new
- @pid = 12345
+ @stderr = ""
@shell_out = OpenStruct.new(:stdout => @stdout,:stdin => @stdin,:stderr => @stderr,:status => @status,:exitstatus => 0)
end
describe "when loading current resource" do
it "should create a current resource with the name of the new_resource" do
- @provider.should_receive(:shell_out!).and_return(@shell_out)
- Chef::Resource::Package.should_receive(:new).and_return(@current_resource)
- @provider.load_current_resource
- end
-
- it "should set the current resources package name to the new resources package name" do
- @provider.should_receive(:shell_out!).and_return(@shell_out)
- @current_resource.should_receive(:package_name).with(@new_resource.package_name)
- @provider.load_current_resource
- end
-
- it "should run apt-cache policy with the package name" do
@provider.should_receive(:shell_out!).with("apt-cache policy #{@new_resource.package_name}").and_return(@shell_out)
@provider.load_current_resource
- end
- it "should set the installed version to nil on the current resource if package state is not installed" do
- @provider.should_receive(:shell_out!).and_return(@shell_out)
- @current_resource.should_receive(:version).with(nil).and_return(true)
- @provider.load_current_resource
+ current_resource = @provider.current_resource
+ current_resource.should be_a(Chef::Resource::Package)
+ current_resource.name.should == "irssi"
+ current_resource.package_name.should == "irssi"
+ current_resource.version.should be_nil
end
it "should set the installed version if package has one" do
@@ -84,15 +69,10 @@ sudo:
INSTALLED
@provider.should_receive(:shell_out!).and_return(@shell_out)
@provider.load_current_resource
- @current_resource.version.should == "1.7.2p1-1ubuntu5.3"
+ @provider.current_resource.version.should == "1.7.2p1-1ubuntu5.3"
@provider.candidate_version.should eql("1.7.2p1-1ubuntu5.3")
end
- it "should return the current resouce" do
- @provider.should_receive(:shell_out!).and_return(@shell_out)
- @provider.load_current_resource.should eql(@current_resource)
- end
-
# libmysqlclient-dev is a real package in newer versions of debian + ubuntu
# list of virtual packages: http://www.debian.org/doc/packaging-manuals/virtual-package-names-list.txt
it "should not install the virtual package there is a single provider package and it is installed" do
@@ -107,18 +87,18 @@ VPKG_STDOUT
@provider.should_receive(:shell_out!).with("apt-cache policy libmysqlclient15-dev").and_return(virtual_package)
showpkg_out =<<-SHOWPKG_STDOUT
Package: libmysqlclient15-dev
-Versions:
+Versions:
-Reverse Depends:
+Reverse Depends:
libmysqlclient-dev,libmysqlclient15-dev
libmysqlclient-dev,libmysqlclient15-dev
libmysqlclient-dev,libmysqlclient15-dev
libmysqlclient-dev,libmysqlclient15-dev
libmysqlclient-dev,libmysqlclient15-dev
libmysqlclient-dev,libmysqlclient15-dev
-Dependencies:
-Provides:
-Reverse Provides:
+Dependencies:
+Provides:
+Reverse Provides:
libmysqlclient-dev 5.1.41-3ubuntu12.7
libmysqlclient-dev 5.1.41-3ubuntu12.10
libmysqlclient-dev 5.1.41-3ubuntu12
@@ -140,7 +120,6 @@ libmysqlclient-dev:
RPKG_STDOUT
real_package = mock(:stdout => real_package_out,:exitstatus => 0)
@provider.should_receive(:shell_out!).with("apt-cache policy libmysqlclient-dev").and_return(real_package)
- @provider.should_not_receive(:run_command_with_systems_locale)
@provider.load_current_resource
end
@@ -156,17 +135,17 @@ VPKG_STDOUT
@provider.should_receive(:shell_out!).with("apt-cache policy mp3-decoder").and_return(virtual_package)
showpkg_out=<<-SHOWPKG_STDOUT
Package: mp3-decoder
-Versions:
+Versions:
-Reverse Depends:
+Reverse Depends:
nautilus,mp3-decoder
vux,mp3-decoder
plait,mp3-decoder
ecasound,mp3-decoder
nautilus,mp3-decoder
-Dependencies:
-Provides:
-Reverse Provides:
+Dependencies:
+Provides:
+Reverse Provides:
vlc-nox 1.0.6-1ubuntu1.8
vlc 1.0.6-1ubuntu1.8
vlc-nox 1.0.6-1ubuntu1
@@ -192,160 +171,140 @@ SHOWPKG_STDOUT
end
- describe "install_package" do
- it "should run apt-get install with the package name and version" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "apt-get -q -y install irssi=0.8.12-7",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- })
- @provider.install_package("irssi", "0.8.12-7")
- end
-
- it "should run apt-get install with the package name and version and options if specified" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "apt-get -q -y --force-yes install irssi=0.8.12-7",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- })
- @new_resource.stub!(:options).and_return("--force-yes")
-
- @provider.install_package("irssi", "0.8.12-7")
- end
-
- it "should run apt-get install with the package name and version and default_release if there is one and provider is explicitly defined" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "apt-get -q -y -o APT::Default-Release=lenny-backports install irssi=0.8.12-7",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- })
- @new_resource.stub!(:default_release).and_return("lenny-backports")
- @new_resource.stub!(:provider).and_return("Chef::Provider::Package::Apt")
-
- @provider.install_package("irssi", "0.8.12-7")
- end
- end
-
- describe Chef::Provider::Package::Apt, "upgrade_package" do
-
- it "should run install_package with the name and version" do
- @provider.should_receive(:install_package).with("irssi", "0.8.12-7")
- @provider.upgrade_package("irssi", "0.8.12-7")
+ context "after loading the current resource" do
+ before do
+ @current_resource = Chef::Resource::Package.new("irssi", @run_context)
+ @provider.current_resource = @current_resource
end
- end
- describe Chef::Provider::Package::Apt, "remove_package" do
-
- it "should run apt-get remove with the package name" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "apt-get -q -y remove irssi",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- })
- @provider.remove_package("irssi", "0.8.12-7")
+ describe "install_package" do
+ it "should run apt-get install with the package name and version" do
+ @provider.should_receive(:shell_out!).
+ with("apt-get -q -y install irssi=0.8.12-7",
+ :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil})
+ @provider.install_package("irssi", "0.8.12-7")
+ end
+
+ it "should run apt-get install with the package name and version and options if specified" do
+ @provider.should_receive(:shell_out!).
+ with("apt-get -q -y --force-yes install irssi=0.8.12-7",
+ :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil })
+ @new_resource.options("--force-yes")
+ @provider.install_package("irssi", "0.8.12-7")
+ end
+
+ it "should run apt-get install with the package name and version and default_release if there is one and provider is explicitly defined" do
+ @new_resource = nil
+ @new_resource = Chef::Resource::AptPackage.new("irssi", @run_context)
+ @new_resource.default_release("lenny-backports")
+
+ @provider.new_resource = @new_resource
+
+ @provider.should_receive(:shell_out!).
+ with("apt-get -q -y -o APT::Default-Release=lenny-backports install irssi=0.8.12-7",
+ :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil })
+
+ @provider.install_package("irssi", "0.8.12-7")
+ end
end
- it "should run apt-get remove with the package name and options if specified" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "apt-get -q -y --force-yes remove irssi",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- })
- @new_resource.stub!(:options).and_return("--force-yes")
+ describe Chef::Provider::Package::Apt, "upgrade_package" do
- @provider.remove_package("irssi", "0.8.12-7")
+ it "should run install_package with the name and version" do
+ @provider.should_receive(:install_package).with("irssi", "0.8.12-7")
+ @provider.upgrade_package("irssi", "0.8.12-7")
+ end
end
- end
- describe "when purging a package" do
+ describe Chef::Provider::Package::Apt, "remove_package" do
- it "should run apt-get purge with the package name" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "apt-get -q -y purge irssi",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- })
- @provider.purge_package("irssi", "0.8.12-7")
- end
+ it "should run apt-get remove with the package name" do
+ @provider.should_receive(:shell_out!).
+ with("apt-get -q -y remove irssi",
+ :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil})
+ @provider.remove_package("irssi", "0.8.12-7")
+ end
- it "should run apt-get purge with the package name and options if specified" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "apt-get -q -y --force-yes purge irssi",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- })
- @new_resource.stub!(:options).and_return("--force-yes")
+ it "should run apt-get remove with the package name and options if specified" do
+ @provider.should_receive(:shell_out!).
+ with("apt-get -q -y --force-yes remove irssi",
+ :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil })
+ @new_resource.options("--force-yes")
- @provider.purge_package("irssi", "0.8.12-7")
+ @provider.remove_package("irssi", "0.8.12-7")
+ end
end
- end
- describe "when preseeding a package" do
- before(:each) do
- @provider.stub!(:get_preseed_file).and_return("/tmp/irssi-0.8.12-7.seed")
- @provider.stub!(:run_command_with_systems_locale).and_return(true)
- end
+ describe "when purging a package" do
- it "should get the full path to the preseed response file" do
- @provider.should_receive(:get_preseed_file).with("irssi", "0.8.12-7").and_return("/tmp/irssi-0.8.12-7.seed")
- file = @provider.get_preseed_file("irssi", "0.8.12-7")
- @provider.preseed_package(file)
- end
+ it "should run apt-get purge with the package name" do
+ @provider.should_receive(:shell_out!).
+ with("apt-get -q -y purge irssi",
+ :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil })
+ @provider.purge_package("irssi", "0.8.12-7")
+ end
- it "should run debconf-set-selections on the preseed file if it has changed" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "debconf-set-selections /tmp/irssi-0.8.12-7.seed",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- }).and_return(true)
- file = @provider.get_preseed_file("irssi", "0.8.12-7")
- @provider.preseed_package(file)
- end
+ it "should run apt-get purge with the package name and options if specified" do
+ @provider.should_receive(:shell_out!).
+ with("apt-get -q -y --force-yes purge irssi",
+ :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil })
+ @new_resource.options("--force-yes")
- it "should not run debconf-set-selections if the preseed file has not changed" do
- @provider.stub(:check_package_state)
- @current_resource.version "0.8.11"
- @new_resource.response_file "/tmp/file"
- @provider.stub!(:get_preseed_file).and_return(false)
- @provider.should_not_receive(:run_command_with_systems_locale)
- @provider.run_action(:reconfig)
+ @provider.purge_package("irssi", "0.8.12-7")
+ end
end
- end
- describe "when reconfiguring a package" do
- before(:each) do
- @provider.stub!(:run_command_with_systems_locale).and_return(true)
+ describe "when preseeding a package" do
+ before(:each) do
+ @provider.stub!(:get_preseed_file).and_return("/tmp/irssi-0.8.12-7.seed")
+ end
+
+ it "should get the full path to the preseed response file" do
+ @provider.should_receive(:get_preseed_file).with("irssi", "0.8.12-7").and_return("/tmp/irssi-0.8.12-7.seed")
+ file = @provider.get_preseed_file("irssi", "0.8.12-7")
+
+ @provider.should_receive(:shell_out!).
+ with("debconf-set-selections /tmp/irssi-0.8.12-7.seed",
+ :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil})
+
+ @provider.preseed_package(file)
+ end
+
+ it "should run debconf-set-selections on the preseed file if it has changed" do
+ @provider.should_receive(:shell_out!).
+ with("debconf-set-selections /tmp/irssi-0.8.12-7.seed",
+ :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil})
+ file = @provider.get_preseed_file("irssi", "0.8.12-7")
+ @provider.preseed_package(file)
+ end
+
+ it "should not run debconf-set-selections if the preseed file has not changed" do
+ @provider.stub(:check_package_state)
+ @current_resource.version "0.8.11"
+ @new_resource.response_file "/tmp/file"
+ @provider.stub!(:get_preseed_file).and_return(false)
+ @provider.should_not_receive(:shell_out!)
+ @provider.run_action(:reconfig)
+ end
end
- it "should run dpkg-reconfigure package" do
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "dpkg-reconfigure irssi",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- }).and_return(true)
- @provider.reconfig_package("irssi", "0.8.12-7")
+ describe "when reconfiguring a package" do
+ it "should run dpkg-reconfigure package" do
+ @provider.should_receive(:shell_out!).
+ with("dpkg-reconfigure irssi",
+ :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil })
+ @provider.reconfig_package("irssi", "0.8.12-7")
+ end
end
- end
- describe "when installing a virtual package" do
- it "should install the package without specifying a version" do
- @provider.is_virtual_package = true
- @provider.should_receive(:run_command_with_systems_locale).with({
- :command => "apt-get -q -y install libmysqlclient-dev",
- :environment => {
- "DEBIAN_FRONTEND" => "noninteractive"
- }
- })
- @provider.install_package("libmysqlclient-dev", "not_a_real_version")
+ describe "when installing a virtual package" do
+ it "should install the package without specifying a version" do
+ @provider.is_virtual_package = true
+ @provider.should_receive(:shell_out!).
+ with("apt-get -q -y install libmysqlclient-dev",
+ :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil })
+ @provider.install_package("libmysqlclient-dev", "not_a_real_version")
+ end
end
end
end
diff --git a/spec/unit/provider/package/dpkg_spec.rb b/spec/unit/provider/package/dpkg_spec.rb
index aa22e0a2a3..30021e31f3 100644
--- a/spec/unit/provider/package/dpkg_spec.rb
+++ b/spec/unit/provider/package/dpkg_spec.rb
@@ -60,15 +60,15 @@ describe Chef::Provider::Package::Dpkg do
@provider.current_resource.package_name.should == "wget"
@new_resource.version.should == version
end
-
+
it 'if short version provided' do
check_version('1.11.4')
end
-
+
it 'if extended version provided' do
check_version('1.11.4-1ubuntu1')
end
-
+
it 'if distro-specific version provided' do
check_version('1.11.4-1ubuntu1~lucid')
end
diff --git a/spec/unit/provider/package/freebsd_spec.rb b/spec/unit/provider/package/freebsd_spec.rb
index 270c85d934..2901b84f49 100644
--- a/spec/unit/provider/package/freebsd_spec.rb
+++ b/spec/unit/provider/package/freebsd_spec.rb
@@ -211,6 +211,34 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
end
end
+ # CHEF-4371
+ # There are some port names that contain special characters such as +'s. This breaks the regular expression used to determine what
+ # version of a package is currently installed and to get the port_path.
+ # Example package name: bonnie++
+
+ describe Chef::Provider::Package::Freebsd, "bonnie++ (package with a plus in the name :: CHEF-4371)" do
+ before(:each) do
+ @new_resource = Chef::Resource::Package.new("bonnie++")
+ @current_resource = Chef::Resource::Package.new("bonnie++")
+ @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ end
+
+ it "should return the port path for a valid port name" do
+ whereis = OpenStruct.new(:stdout => "bonnie++: /usr/ports/benchmarks/bonnie++")
+ @provider.should_receive(:shell_out!).with("whereis -s bonnie++", :env => nil).and_return(whereis)
+ @provider.stub!(:port_name).and_return("bonnie++")
+ @provider.port_path.should == "/usr/ports/benchmarks/bonnie++"
+ end
+
+ it "should return the version number when it is installed" do
+ pkg_info = OpenStruct.new(:stdout => "bonnie++-1.96")
+ @provider.should_receive(:shell_out!).with('pkg_info -E "bonnie++*"', :env => nil, :returns => [0,1]).and_return(pkg_info)
+ @provider.stub!(:package_name).and_return("bonnie++")
+ @provider.current_installed_version.should == "1.96"
+ end
+ end
+
# A couple of examples to show up the difficulty of determining the command to install the binary package given the port:
# PORT DIRECTORY INSTALLED PACKAGE NAME COMMAND TO INSTALL PACKAGE
# /usr/ports/lang/perl5.8 perl-5.8.8_1 pkg_add -r perl
diff --git a/spec/unit/provider/package/ips_spec.rb b/spec/unit/provider/package/ips_spec.rb
index 641a527012..95839dbe89 100644
--- a/spec/unit/provider/package/ips_spec.rb
+++ b/spec/unit/provider/package/ips_spec.rb
@@ -170,7 +170,7 @@ PKG_STATUS
before do
@new_resource.stub!(:accept_license).and_return(true)
end
-
+
it "should run pkg install with the --accept flag" do
@provider.should_receive(:run_command_with_systems_locale).with({
:command => "pkg install -q --accept crypto/gnupg@2.0.17"
diff --git a/spec/unit/provider/package/rpm_spec.rb b/spec/unit/provider/package/rpm_spec.rb
index 9dd94a7441..86327be42b 100644
--- a/spec/unit/provider/package/rpm_spec.rb
+++ b/spec/unit/provider/package/rpm_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,35 +23,35 @@ describe Chef::Provider::Package::Rpm do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
-
+
@new_resource = Chef::Resource::Package.new("emacs")
@new_resource.source "/tmp/emacs-21.4-20.el5.i386.rpm"
-
+
@provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
-
+
@status = mock("Status", :exitstatus => 0)
::File.stub!(:exists?).and_return(true)
end
-
+
describe "when determining the current state of the package" do
-
+
it "should create a current resource with the name of new_resource" do
@provider.stub!(:popen4).and_return(@status)
@provider.load_current_resource
@provider.current_resource.name.should == "emacs"
end
-
+
it "should set the current reource package name to the new resource package name" do
@provider.stub!(:popen4).and_return(@status)
@provider.load_current_resource
@provider.current_resource.package_name.should == 'emacs'
end
-
+
it "should raise an exception if a source is supplied but not found" do
::File.stub!(:exists?).and_return(false)
lambda { @provider.run_action(:any) }.should raise_error(Chef::Exceptions::Package)
end
-
+
it "should get the source package version from rpm if provided" do
@stdout = StringIO.new("emacs 21.4-20.el5")
@provider.should_receive(:popen4).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/emacs-21.4-20.el5.i386.rpm").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@@ -60,7 +60,7 @@ describe Chef::Provider::Package::Rpm do
@provider.current_resource.package_name.should == "emacs"
@provider.new_resource.version.should == "21.4-20.el5"
end
-
+
it "should return the current version installed if found by rpm" do
@stdout = StringIO.new("emacs 21.4-20.el5")
@provider.should_receive(:popen4).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/emacs-21.4-20.el5.i386.rpm").and_return(@status)
@@ -68,20 +68,20 @@ describe Chef::Provider::Package::Rpm do
@provider.load_current_resource
@provider.current_resource.version.should == "21.4-20.el5"
end
-
+
it "should raise an exception if the source is not set but we are installing" do
new_resource = Chef::Resource::Package.new("emacs")
provider = Chef::Provider::Package::Rpm.new(new_resource, @run_context)
lambda { provider.run_action(:any) }.should raise_error(Chef::Exceptions::Package)
end
-
+
it "should raise an exception if rpm fails to run" do
status = mock("Status", :exitstatus => -1)
@provider.stub!(:popen4).and_return(status)
lambda { @provider.run_action(:any) }.should raise_error(Chef::Exceptions::Package)
end
end
-
+
describe "after the current resource is loaded" do
before do
@current_resource = Chef::Resource::Package.new("emacs")
@@ -95,7 +95,7 @@ describe Chef::Provider::Package::Rpm do
})
@provider.install_package("emacs", "21.4-20.el5")
end
-
+
it "should run rpm -U with the package source to upgrade" do
@current_resource.version("21.4-19.el5")
@provider.should_receive(:run_command_with_systems_locale).with({
diff --git a/spec/unit/provider/package/smartos_spec.rb b/spec/unit/provider/package/smartos_spec.rb
index 47db00988c..e5092f69d9 100644
--- a/spec/unit/provider/package/smartos_spec.rb
+++ b/spec/unit/provider/package/smartos_spec.rb
@@ -27,8 +27,8 @@ describe Chef::Provider::Package::SmartOS, "load_current_resource" do
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Package.new("varnish")
@current_resource = Chef::Resource::Package.new("varnish")
-
-
+
+
@status = mock("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::SmartOS.new(@new_resource, @run_context)
Chef::Resource::Package.stub!(:new).and_return(@current_resource)
@@ -69,8 +69,26 @@ describe Chef::Provider::Package::SmartOS, "load_current_resource" do
end
+ describe "candidate_version" do
+ it "should return the candidate_version variable if already setup" do
+ @provider.candidate_version = "2.1.1"
+ @provider.should_not_receive(:shell_out!)
+ @provider.candidate_version
+ end
+
+ it "should lookup the candidate_version if the variable is not already set" do
+ search = mock()
+ search.should_receive(:each_line).
+ and_yield("something-varnish-1.1.1 something varnish like\n").
+ and_yield("varnish-2.3.4 actual varnish\n")
+ @shell_out = mock('shell_out!', :stdout => search)
+ @provider.should_receive(:shell_out!).with('/opt/local/bin/pkgin se varnish', :env => nil, :returns => [0,1]).and_return(@shell_out)
+ @provider.candidate_version.should == "2.3.4"
+ end
+ end
+
describe "when manipulating a resource" do
-
+
it "run pkgin and install the package" do
out = OpenStruct.new(:stdout => nil)
@provider.should_receive(:shell_out!).with("/opt/local/sbin/pkg_info -E \"varnish*\"", {:env => nil, :returns=>[0,1]}).and_return(@shell_out)
diff --git a/spec/unit/provider/package_spec.rb b/spec/unit/provider/package_spec.rb
index 6e4cf6fe16..f80eed17bd 100644
--- a/spec/unit/provider/package_spec.rb
+++ b/spec/unit/provider/package_spec.rb
@@ -286,7 +286,7 @@ describe Chef::Provider::Package do
@provider.should_not_receive(:reconfig_package)
@provider.run_action(:reconfig)
@new_resource.should_not be_updated_by_last_action
- end
+ end
it "should debug log and not reconfigure the package if no response_file is given" do
@current_resource.stub!(:version).and_return('1.0')
@@ -345,7 +345,9 @@ describe Chef::Provider::Package do
cl = Chef::CookbookLoader.new(@cookbook_repo)
cl.load_cookbooks
@cookbook_collection = Chef::CookbookCollection.new(cl)
+
@run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
+ @provider.run_context = @run_context
@node.automatic_attrs[:platform] = 'PLATFORM: just testing'
@node.automatic_attrs[:platform_version] = 'PLATFORM VERSION: just testing'
@@ -358,8 +360,8 @@ describe Chef::Provider::Package do
before do
Chef::FileCache.should_receive(:create_cache_path).with('preseed/java').and_return("/tmp/preseed/java")
end
+
it "sets the preseed resource's runcontext to its own run context" do
- Chef::FileCache.rspec_reset
Chef::FileCache.stub!(:create_cache_path).and_return("/tmp/preseed/java")
@provider.preseed_resource('java', '6').run_context.should_not be_nil
@provider.preseed_resource('java', '6').run_context.should equal(@provider.run_context)
diff --git a/spec/unit/provider/powershell_spec.rb b/spec/unit/provider/powershell_spec.rb
index ac4160080e..33c402836b 100644
--- a/spec/unit/provider/powershell_spec.rb
+++ b/spec/unit/provider/powershell_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,7 +24,7 @@ describe Chef::Provider::PowershellScript, "action_run" do
@node.default["kernel"] = Hash.new
@node.default["kernel"][:machine] = :x86_64.to_s
-
+
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::PowershellScript.new('run some powershell code', @run_context)
diff --git a/spec/unit/provider/remote_directory_spec.rb b/spec/unit/provider/remote_directory_spec.rb
index f2bb1b4a3f..d3f1438f0f 100644
--- a/spec/unit/provider/remote_directory_spec.rb
+++ b/spec/unit/provider/remote_directory_spec.rb
@@ -57,10 +57,10 @@ describe Chef::Provider::RemoteDirectory do
@provider_second_run.run_action(:create)
end
it "identifies that the state has changed the after first run" do
- @provider_second_run.new_resource.updated_by_last_action? == true
+ @provider_second_run.new_resource.updated_by_last_action? == true
end
it "identifies that the state has not changed after the second run" do
- @provider_second_run.new_resource.updated_by_last_action? == false
+ @provider_second_run.new_resource.updated_by_last_action? == false
end
end
diff --git a/spec/unit/provider/remote_file/ftp_spec.rb b/spec/unit/provider/remote_file/ftp_spec.rb
index 4022fb25d3..8dd1ef248e 100644
--- a/spec/unit/provider/remote_file/ftp_spec.rb
+++ b/spec/unit/provider/remote_file/ftp_spec.rb
@@ -200,16 +200,11 @@ describe Chef::Provider::RemoteFile::FTP do
context "and proxying is enabled" do
before do
- @original_config = Chef::Config.hash_dup
Chef::Config[:ftp_proxy] = "socks5://socks.example.com:5000"
Chef::Config[:ftp_proxy_user] = "bill"
Chef::Config[:ftp_proxy_pass] = "ted"
end
- after do
- Chef::Config.configuration = @original_config
- end
-
it "fetches the file via the proxy" do
current_socks_server = ENV["SOCKS_SERVER"]
ENV.should_receive(:[]=).with("SOCKS_SERVER", "socks5://bill:ted@socks.example.com:5000").ordered
diff --git a/spec/unit/provider/remote_file/http_spec.rb b/spec/unit/provider/remote_file/http_spec.rb
index 6ae19327eb..cb7271900d 100644
--- a/spec/unit/provider/remote_file/http_spec.rb
+++ b/spec/unit/provider/remote_file/http_spec.rb
@@ -155,16 +155,16 @@ describe Chef::Provider::RemoteFile::HTTP do
describe "when fetching the uri" do
let(:expected_http_opts) { {} }
- let(:expected_http_args) { [uri, nil, nil, expected_http_opts] }
+ let(:expected_http_args) { [uri, expected_http_opts] }
let(:tempfile_path) { "/tmp/chef-mock-tempfile-abc123" }
- let(:tempfile) { mock(Tempfile, :path => tempfile_path) }
+ let(:tempfile) { mock(Tempfile, :path => tempfile_path, :close => nil) }
let(:last_response) { {} }
let(:rest) do
- rest = mock(Chef::REST)
+ rest = mock(Chef::HTTP::Simple)
rest.stub!(:streaming_request).and_return(tempfile)
rest.stub!(:last_response).and_return(last_response)
rest
@@ -175,7 +175,7 @@ describe Chef::Provider::RemoteFile::HTTP do
new_resource.use_last_modified(false)
Chef::Provider::RemoteFile::CacheControlData.should_receive(:load_and_validate).with(uri, current_resource_checksum).and_return(cache_control_data)
- Chef::REST.should_receive(:new).with(*expected_http_args).and_return(rest)
+ Chef::HTTP::Simple.should_receive(:new).with(*expected_http_args).and_return(rest)
end
@@ -188,7 +188,7 @@ describe Chef::Provider::RemoteFile::HTTP do
lambda { fetcher.fetch }.should raise_error(Net::HTTPServerException)
end
- it "should return HTTPRetriableError when Chef::REST returns a 301" do
+ it "should return HTTPRetriableError when Chef::HTTP::Simple returns a 301" do
r = Net::HTTPMovedPermanently.new("one", "two", "three")
e = Net::HTTPRetriableError.new("301", r)
rest.stub!(:streaming_request).and_raise(e)
@@ -290,21 +290,21 @@ describe Chef::Provider::RemoteFile::HTTP do
# CHEF-3140
# Some servers return tarballs as content type tar and encoding gzip, which
- # is totally wrong. When this happens and gzip isn't disabled, Chef::REST
+ # is totally wrong. When this happens and gzip isn't disabled, Chef::HTTP::Simple
# will decompress the file for you, which is not at all what you expected
# to happen (you end up with an uncomressed tar archive instead of the
# gzipped tar archive you expected). To work around this behavior, we
# detect when users are fetching gzipped files and turn off gzip in
- # Chef::REST.
+ # Chef::HTTP::Simple.
it "should disable gzip compression in the client" do
# Before block in the parent context has set an expectation on
- # Chef::REST.new() being called with expected arguments. Here we fufil
+ # Chef::HTTP::Simple.new() being called with expected arguments. Here we fufil
# that expectation, so that we can explicitly set it for this test.
# This is intended to provide insurance that refactoring of the parent
# context does not negate the value of this particular example.
- Chef::REST.new(*expected_http_args)
- Chef::REST.should_receive(:new).once.with(*expected_http_args).and_return(rest)
+ Chef::HTTP::Simple.new(*expected_http_args)
+ Chef::HTTP::Simple.should_receive(:new).once.with(*expected_http_args).and_return(rest)
fetcher.fetch
cache_control_data.etag.should be_nil
cache_control_data.mtime.should be_nil
diff --git a/spec/unit/provider/remote_file/local_file_spec.rb b/spec/unit/provider/remote_file/local_file_spec.rb
index 6b318f972a..00634f50eb 100644
--- a/spec/unit/provider/remote_file/local_file_spec.rb
+++ b/spec/unit/provider/remote_file/local_file_spec.rb
@@ -40,7 +40,7 @@ describe Chef::Provider::RemoteFile::LocalFile do
describe "when fetching the object" do
- let(:tempfile) { mock("Tempfile", :path => "/tmp/foo/bar/nyan.png") }
+ let(:tempfile) { mock("Tempfile", :path => "/tmp/foo/bar/nyan.png", :close => nil) }
let(:chef_tempfile) { mock("Chef::FileContentManagement::Tempfile", :tempfile => tempfile) }
before do
@@ -50,6 +50,7 @@ describe Chef::Provider::RemoteFile::LocalFile do
it "stages the local file to a temporary file" do
Chef::FileContentManagement::Tempfile.should_receive(:new).with(new_resource).and_return(chef_tempfile)
::FileUtils.should_receive(:cp).with(uri.path, tempfile.path)
+ tempfile.should_receive(:close)
result = fetcher.fetch
result.should == tempfile
diff --git a/spec/unit/provider/route_spec.rb b/spec/unit/provider/route_spec.rb
index 072cb2a698..863f12641c 100644
--- a/spec/unit/provider/route_spec.rb
+++ b/spec/unit/provider/route_spec.rb
@@ -111,13 +111,13 @@ describe Chef::Provider::Route do
it "should not delete config file for :add action (CHEF-3332)" do
@node.automatic_attrs[:platform] = 'centos'
-
+
route_file = StringIO.new
File.should_receive(:new).and_return(route_file)
@resource_add = Chef::Resource::Route.new('192.168.1.0/24 via 192.168.0.1')
@run_context.resource_collection << @resource_add
@provider.stub!(:run_command).and_return(true)
-
+
@resource_add.action(:add)
@provider.run_action(:add)
route_file.string.split("\n").should have(1).items
diff --git a/spec/unit/provider/ruby_block_spec.rb b/spec/unit/provider/ruby_block_spec.rb
index 7fc58c9c70..6e5c9a638b 100644
--- a/spec/unit/provider/ruby_block_spec.rb
+++ b/spec/unit/provider/ruby_block_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/provider/service/arch_service_spec.rb b/spec/unit/provider/service/arch_service_spec.rb
index a7afa28da1..0865fdae86 100644
--- a/spec/unit/provider/service/arch_service_spec.rb
+++ b/spec/unit/provider/service/arch_service_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -61,8 +61,8 @@ describe Chef::Provider::Service::Arch, "load_current_resource" do
@provider.should_receive(:shell_out).with("/etc/rc.d/chef status").and_return(OpenStruct.new(:exitstatus => 0))
@provider.load_current_resource
end
-
- it "should set running to true if the the status command returns 0" do
+
+ it "should set running to true if the status command returns 0" do
@provider.stub!(:shell_out).with("/etc/rc.d/chef status").and_return(OpenStruct.new(:exitstatus => 0))
@provider.load_current_resource
@provider.current_resource.running.should be_true
@@ -92,7 +92,7 @@ describe Chef::Provider::Service::Arch, "load_current_resource" do
@provider.should_receive(:shell_out).with("/etc/rc.d/chefhasmonkeypants status").and_return(OpenStruct.new(:exitstatus => 0))
@provider.load_current_resource
end
-
+
end
it "should raise error if the node has a nil ps attribute and no other means to get status" do
@@ -129,7 +129,7 @@ aj 8119 6041 0 21:34 pts/3 00:00:03 vi init_service_spec.rb
DEFAULT_PS
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@provider.stub!(:shell_out!).and_return(@status)
-
+
@node.automatic_attrs[:command] = {:ps => "ps -ef"}
end
@@ -139,7 +139,7 @@ aj 7842 5057 0 21:26 pts/2 00:00:06 chef
aj 7842 5057 0 21:26 pts/2 00:00:06 poos
RUNNING_PS
@status.stub!(:stdout).and_return(@stdout)
- @provider.load_current_resource
+ @provider.load_current_resource
@provider.current_resource.running.should be_true
end
@@ -162,13 +162,13 @@ RUNNING_PS
::File.stub!(:read).with("/etc/rc.conf").and_return("DAEMONS=(network !apache ssh)")
@provider.daemons.should == ['network', '!apache', 'ssh']
end
-
+
context "when the current service status is known" do
before do
@current_resource = Chef::Resource::Service.new("chef")
@provider.current_resource = @current_resource
end
-
+
describe Chef::Provider::Service::Arch, "enable_service" do
# before(:each) do
# @new_resource = mock("Chef::Resource::Service",
@@ -178,7 +178,7 @@ RUNNING_PS
# :running => false
# )
# @new_resource.stub!(:start_command).and_return(false)
- #
+ #
# @provider = Chef::Provider::Service::Arch.new(@node, @new_resource)
# Chef::Resource::Service.stub!(:new).and_return(@current_resource)
# end
@@ -199,7 +199,7 @@ RUNNING_PS
# :running => false
# )
# @new_resource.stub!(:start_command).and_return(false)
- #
+ #
# @provider = Chef::Provider::Service::Arch.new(@node, @new_resource)
# Chef::Resource::Service.stub!(:new).and_return(@current_resource)
# end
@@ -221,11 +221,11 @@ RUNNING_PS
# :running => false
# )
# @new_resource.stub!(:start_command).and_return(false)
- #
+ #
# @provider = Chef::Provider::Service::Arch.new(@node, @new_resource)
# Chef::Resource::Service.stub!(:new).and_return(@current_resource)
# end
-
+
it "should call the start command if one is specified" do
@new_resource.stub!(:start_command).and_return("/etc/rc.d/chef startyousillysally")
@provider.should_receive(:shell_out!).with("/etc/rc.d/chef startyousillysally")
@@ -235,7 +235,7 @@ RUNNING_PS
it "should call '/etc/rc.d/service_name start' if no start command is specified" do
@provider.should_receive(:shell_out!).with("/etc/rc.d/#{@new_resource.service_name} start")
@provider.start_service()
- end
+ end
end
describe Chef::Provider::Service::Arch, "stop_service" do
@@ -247,7 +247,7 @@ RUNNING_PS
# :running => false
# )
# @new_resource.stub!(:stop_command).and_return(false)
- #
+ #
# @provider = Chef::Provider::Service::Arch.new(@node, @new_resource)
# Chef::Resource::Service.stub!(:new).and_return(@current_resource)
# end
@@ -274,7 +274,7 @@ RUNNING_PS
# )
# @new_resource.stub!(:restart_command).and_return(false)
# @new_resource.stub!(:supports).and_return({:restart => false})
- #
+ #
# @provider = Chef::Provider::Service::Arch.new(@node, @new_resource)
# Chef::Resource::Service.stub!(:new).and_return(@current_resource)
# end
@@ -309,7 +309,7 @@ RUNNING_PS
# )
# @new_resource.stub!(:reload_command).and_return(false)
# @new_resource.stub!(:supports).and_return({:reload => false})
- #
+ #
# @provider = Chef::Provider::Service::Arch.new(@node, @new_resource)
# Chef::Resource::Service.stub!(:new).and_return(@current_resource)
# end
diff --git a/spec/unit/provider/service/debian_service_spec.rb b/spec/unit/provider/service/debian_service_spec.rb
index bea9360561..ff0f4f421b 100644
--- a/spec/unit/provider/service/debian_service_spec.rb
+++ b/spec/unit/provider/service/debian_service_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,7 +18,7 @@
require 'spec_helper'
-describe Chef::Provider::Service::Debian, "load_current_resource" do
+describe Chef::Provider::Service::Debian do
before(:each) do
@node = Chef::Node.new
@node.automatic_attrs[:command] = {:ps => 'fuuuu'}
@@ -26,95 +26,41 @@ describe Chef::Provider::Service::Debian, "load_current_resource" do
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Service.new("chef")
+ @provider = Chef::Provider::Service::Debian.new(@new_resource, @run_context)
@current_resource = Chef::Resource::Service.new("chef")
-
- @provider = Chef::Provider::Service::Debian.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
@pid, @stdin, @stdout, @stderr = nil, nil, nil, nil
-
end
- it "ensures /usr/sbin/update-rc.d is available" do
- File.should_receive(:exists?).with("/usr/sbin/update-rc.d").and_return(false)
- @provider.define_resource_requirements
- lambda { @provider.process_resource_requirements } .should raise_error(Chef::Exceptions::Service)
- end
+ describe "load_current_resource" do
+ it "ensures /usr/sbin/update-rc.d is available" do
+ File.should_receive(:exists?).with("/usr/sbin/update-rc.d") .and_return(false)
- describe "when update-rc.d shows the init script linked to rc*.d/" do
- before do
- @provider.stub!(:assert_update_rcd_available)
-
- result=<<-UPDATE_RC_D_SUCCESS
-Removing any system startup links for /etc/init.d/chef ...
- /etc/rc0.d/K20chef
- /etc/rc1.d/K20chef
- /etc/rc2.d/S20chef
- /etc/rc3.d/S20chef
- /etc/rc4.d/S20chef
- /etc/rc5.d/S20chef
- /etc/rc6.d/K20chef
- UPDATE_RC_D_SUCCESS
- @stdout = StringIO.new(result)
- @stderr = StringIO.new
- @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
- @provider.stub!(:shell_out!).and_return(@status)
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- end
-
- it "says the service is enabled" do
- @provider.service_currently_enabled?(@provider.get_priority).should be_true
+ @provider.define_resource_requirements
+ lambda {
+ @provider.process_resource_requirements
+ }.should raise_error(Chef::Exceptions::Service)
end
- it "stores the 'enabled' state" do
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
- @provider.load_current_resource.should equal(@current_resource)
- @current_resource.enabled.should be_true
- end
- end
-
- {"Debian/Lenny and older" => {
- "linked" => {
- "stdout" => " Removing any system startup links for /etc/init.d/chef ...
- /etc/rc0.d/K20chef
- /etc/rc1.d/K20chef
- /etc/rc2.d/S20chef
- /etc/rc3.d/S20chef
- /etc/rc4.d/S20chef
- /etc/rc5.d/S20chef
- /etc/rc6.d/K20chef",
- "stderr" => ""
- },
- "not linked" => {
- "stdout" => " Removing any system startup links for /etc/init.d/chef ...",
- "stderr" => ""
- },
- },
- "Debian/Squeeze and earlier" => {
- "linked" => {
- "stdout" => "update-rc.d: using dependency based boot sequencing",
- "stderr" => "insserv: remove service /etc/init.d/../rc0.d/K20chef-client
-insserv: remove service /etc/init.d/../rc1.d/K20chef-client
-insserv: remove service /etc/init.d/../rc2.d/S20chef-client
-insserv: remove service /etc/init.d/../rc3.d/S20chef-client
-insserv: remove service /etc/init.d/../rc4.d/S20chef-client
-insserv: remove service /etc/init.d/../rc5.d/S20chef-client
-insserv: remove service /etc/init.d/../rc6.d/K20chef-client
-insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop"
- },
- "not linked" => {
- "stdout" => "update-rc.d: using dependency based boot sequencing",
- "stderr" => ""
- }
- }
- }.each do |model, streams|
- describe "when update-rc.d shows the init script linked to rc*.d/" do
+ context "when update-rc.d shows init linked to rc*.d/" do
before do
@provider.stub!(:assert_update_rcd_available)
- @stdout = StringIO.new(streams["linked"]["stdout"])
- @stderr = StringIO.new(streams["linked"]["stderr"])
+ result = <<-UPDATE_RC_D_SUCCESS
+ Removing any system startup links for /etc/init.d/chef ...
+ /etc/rc0.d/K20chef
+ /etc/rc1.d/K20chef
+ /etc/rc2.d/S20chef
+ /etc/rc3.d/S20chef
+ /etc/rc4.d/S20chef
+ /etc/rc5.d/S20chef
+ /etc/rc6.d/K20chef
+ UPDATE_RC_D_SUCCESS
+
+ @stdout = StringIO.new(result)
+ @stderr = StringIO.new
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@provider.stub!(:shell_out!).and_return(@status)
@provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@@ -129,25 +75,15 @@ insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop"
@provider.load_current_resource.should equal(@current_resource)
@current_resource.enabled.should be_true
end
-
- it "stores the start/stop priorities of the service" do
- @provider.load_current_resource
- expected_priorities = {"6"=>[:stop, "20"],
- "0"=>[:stop, "20"],
- "1"=>[:stop, "20"],
- "2"=>[:start, "20"],
- "3"=>[:start, "20"],
- "4"=>[:start, "20"],
- "5"=>[:start, "20"]}
- @provider.current_resource.priority.should == expected_priorities
- end
end
- describe "when using squeeze/earlier and update-rc.d shows the init script isn't linked to rc*.d" do
+ context "when update-rc.d shows init isn't linked to rc*.d/" do
before do
@provider.stub!(:assert_update_rcd_available)
- @stdout = StringIO.new(streams["not linked"]["stdout"])
- @stderr = StringIO.new(streams["not linked"]["stderr"])
+ @status = mock("Status", :exitstatus => 0)
+ @stdout = StringIO.new(
+ " Removing any system startup links for /etc/init.d/chef ...")
+ @stderr = StringIO.new
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@provider.stub!(:shell_out!).and_return(@status)
@provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@@ -163,92 +99,246 @@ insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop"
@current_resource.enabled.should be_false
end
end
- end
- describe "when update-rc.d shows the init script isn't linked to rc*.d" do
- before do
- @provider.stub!(:assert_update_rcd_available)
- @status = mock("Status", :exitstatus => 0)
- @stdout = StringIO.new(" Removing any system startup links for /etc/init.d/chef ...")
- @stderr = StringIO.new
- @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
- @provider.stub!(:shell_out!).and_return(@status)
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- end
+ context "when update-rc.d fails" do
+ before do
+ @status = mock("Status", :exitstatus => -1)
+ @provider.stub!(:popen4).and_return(@status)
+ end
- it "says the service is disabled" do
- @provider.service_currently_enabled?(@provider.get_priority).should be_false
+ it "raises an error" do
+ @provider.define_resource_requirements
+ lambda {
+ @provider.process_resource_requirements
+ }.should raise_error(Chef::Exceptions::Service)
+ end
end
- it "stores the 'disabled' state" do
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
- @provider.load_current_resource.should equal(@current_resource)
- @current_resource.enabled.should be_false
+ {"Debian/Lenny and older" => {
+ "linked" => {
+ "stdout" => <<-STDOUT,
+ Removing any system startup links for /etc/init.d/chef ...
+ /etc/rc0.d/K20chef
+ /etc/rc1.d/K20chef
+ /etc/rc2.d/S20chef
+ /etc/rc3.d/S20chef
+ /etc/rc4.d/S20chef
+ /etc/rc5.d/S20chef
+ /etc/rc6.d/K20chef
+ STDOUT
+ "stderr" => ""
+ },
+ "not linked" => {
+ "stdout" =>
+ " Removing any system startup links for /etc/init.d/chef ...",
+ "stderr" => ""
+ },
+ },
+ "Debian/Squeeze and earlier" => {
+ "linked" => {
+ "stdout" => "update-rc.d: using dependency based boot sequencing",
+ "stderr" => <<-STDERR,
+insserv: remove service /etc/init.d/../rc0.d/K20chef-client
+ insserv: remove service /etc/init.d/../rc1.d/K20chef-client
+ insserv: remove service /etc/init.d/../rc2.d/S20chef-client
+ insserv: remove service /etc/init.d/../rc3.d/S20chef-client
+ insserv: remove service /etc/init.d/../rc4.d/S20chef-client
+ insserv: remove service /etc/init.d/../rc5.d/S20chef-client
+ insserv: remove service /etc/init.d/../rc6.d/K20chef-client
+ insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop
+ STDERR
+ },
+ "not linked" => {
+ "stdout" => "update-rc.d: using dependency based boot sequencing",
+ "stderr" => ""
+ }
+ }
+ }.each do |model, streams|
+ context "on #{model}" do
+ context "when update-rc.d shows init linked to rc*.d/" do
+ before do
+ @provider.stub!(:assert_update_rcd_available)
+
+ @stdout = StringIO.new(streams["linked"]["stdout"])
+ @stderr = StringIO.new(streams["linked"]["stderr"])
+ @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
+ @provider.stub!(:shell_out!).and_return(@status)
+ @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ end
+
+ it "says the service is enabled" do
+ @provider.service_currently_enabled?(@provider.get_priority).should be_true
+ end
+
+ it "stores the 'enabled' state" do
+ Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ @provider.load_current_resource.should equal(@current_resource)
+ @current_resource.enabled.should be_true
+ end
+
+ it "stores the start/stop priorities of the service" do
+ @provider.load_current_resource
+ expected_priorities = {"6"=>[:stop, "20"],
+ "0"=>[:stop, "20"],
+ "1"=>[:stop, "20"],
+ "2"=>[:start, "20"],
+ "3"=>[:start, "20"],
+ "4"=>[:start, "20"],
+ "5"=>[:start, "20"]}
+ @provider.current_resource.priority.should == expected_priorities
+ end
+ end
+
+ context "when update-rc.d shows init isn't linked to rc*.d/" do
+ before do
+ @provider.stub!(:assert_update_rcd_available)
+ @stdout = StringIO.new(streams["not linked"]["stdout"])
+ @stderr = StringIO.new(streams["not linked"]["stderr"])
+ @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
+ @provider.stub!(:shell_out!).and_return(@status)
+ @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ end
+
+ it "says the service is disabled" do
+ @provider.service_currently_enabled?(@provider.get_priority).should be_false
+ end
+
+ it "stores the 'disabled' state" do
+ Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ @provider.load_current_resource.should equal(@current_resource)
+ @current_resource.enabled.should be_false
+ end
+ end
+ end
end
+
end
- describe "when update-rc.d fails" do
- before do
- @status = mock("Status", :exitstatus => -1)
- @provider.stub!(:popen4).and_return(@status)
+ describe "action_enable" do
+ shared_examples_for "the service is up to date" do
+ it "does not enable the service" do
+ @provider.should_not_receive(:enable_service)
+ @provider.action_enable
+ @provider.set_updated_status
+ @provider.new_resource.should_not be_updated
+ end
end
- it "raises an error" do
- @provider.define_resource_requirements
- lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
+ shared_examples_for "the service is not up to date" do
+ it "enables the service and sets the resource as updated" do
+ @provider.should_receive(:enable_service).and_return(true)
+ @provider.action_enable
+ @provider.set_updated_status
+ @provider.new_resource.should be_updated
+ end
end
- end
- describe "when enabling a service without priority" do
- it "should call update-rc.d 'service_name' defaults" do
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove"})
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} defaults"})
- @provider.enable_service()
+ context "when the service is disabled" do
+ before do
+ @current_resource.enabled(false)
+ end
+
+ it_behaves_like "the service is not up to date"
end
- end
- describe "when enabling a service with simple priority" do
- before do
- @new_resource.priority(75)
+ context "when the service is enabled" do
+ before do
+ @current_resource.enabled(true)
+ end
+
+ context "and the service sets no priority" do
+ it_behaves_like "the service is up to date"
+ end
+
+ context "and the service requests the same priority as is set" do
+ before do
+ @current_resource.priority(80)
+ @new_resource.priority(80)
+ end
+ it_behaves_like "the service is up to date"
+ end
+
+ context "and the service requests a different priority than is set" do
+ before do
+ @current_resource.priority(20)
+ @new_resource.priority(80)
+ end
+ it_behaves_like "the service is not up to date"
+ end
end
+ end
- it "should call update-rc.d 'service_name' defaults" do
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove"})
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} defaults 75 25"})
- @provider.enable_service()
+ def expect_commands(provider, commands)
+ commands.each do |command|
+ provider.should_receive(:run_command).with({:command => command})
end
end
- describe "when enabling a service with complex priorities" do
- before do
- @new_resource.priority(2 => [:start, 20], 3 => [:stop, 55])
+ describe "enable_service" do
+ let(:service_name) { @new_resource.service_name }
+ context "when the service doesn't set a priority" do
+ it "calls update-rc.d 'service_name' defaults" do
+ expect_commands(@provider, [
+ "/usr/sbin/update-rc.d -f #{service_name} remove",
+ "/usr/sbin/update-rc.d #{service_name} defaults"
+ ])
+ @provider.enable_service
+ end
end
- it "should call update-rc.d 'service_name' defaults" do
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove"})
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d #{@new_resource.service_name} start 20 2 . stop 55 3 . "})
- @provider.enable_service()
+ context "when the service sets a simple priority" do
+ before do
+ @new_resource.priority(75)
+ end
+
+ it "calls update-rc.d 'service_name' defaults" do
+ expect_commands(@provider, [
+ "/usr/sbin/update-rc.d -f #{service_name} remove",
+ "/usr/sbin/update-rc.d #{service_name} defaults 75 25"
+ ])
+ @provider.enable_service
+ end
end
- end
- describe "when disabling a service without a priority" do
+ context "when the service sets complex priorities" do
+ before do
+ @new_resource.priority(2 => [:start, 20], 3 => [:stop, 55])
+ end
- it "should call update-rc.d -f 'service_name' remove + stop with a default priority" do
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove"})
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop 80 2 3 4 5 ."})
- @provider.disable_service()
+ it "calls update-rc.d 'service_name' with those priorities" do
+ expect_commands(@provider, [
+ "/usr/sbin/update-rc.d -f #{service_name} remove",
+ "/usr/sbin/update-rc.d #{service_name} start 20 2 . stop 55 3 . "
+ ])
+ @provider.enable_service
+ end
end
end
- describe "when disabling a service with simple priority" do
- before do
- @new_resource.priority(75)
+ describe "disable_service" do
+ let(:service_name) { @new_resource.service_name }
+ context "when the service doesn't set a priority" do
+ it "calls update-rc.d -f 'service_name' remove + stop with default priority" do
+ expect_commands(@provider, [
+ "/usr/sbin/update-rc.d -f #{service_name} remove",
+ "/usr/sbin/update-rc.d -f #{service_name} stop 80 2 3 4 5 ."
+ ])
+ @provider.disable_service
+ end
end
- it "should call update-rc.d -f 'service_name' remove + stop with a specified priority" do
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} remove"})
- @provider.should_receive(:run_command).with({:command => "/usr/sbin/update-rc.d -f #{@new_resource.service_name} stop #{100 - @new_resource.priority} 2 3 4 5 ."})
- @provider.disable_service()
+ context "when the service sets a simple priority" do
+ before do
+ @new_resource.priority(75)
+ end
+
+ it "calls update-rc.d -f 'service_name' remove + stop with the specified priority" do
+ expect_commands(@provider, [
+ "/usr/sbin/update-rc.d -f #{service_name} remove",
+ "/usr/sbin/update-rc.d -f #{service_name} stop #{100 - @new_resource.priority} 2 3 4 5 ."
+ ])
+ @provider.disable_service
+ end
end
end
end
diff --git a/spec/unit/provider/service/freebsd_service_spec.rb b/spec/unit/provider/service/freebsd_service_spec.rb
index 6dd06bde2c..7861764309 100644
--- a/spec/unit/provider/service/freebsd_service_spec.rb
+++ b/spec/unit/provider/service/freebsd_service_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -88,7 +88,7 @@ RC_SAMPLE
@provider.load_current_resource
end
- it "should set running to true if the the status command returns 0" do
+ it "should set running to true if the status command returns 0" do
@provider.should_receive(:shell_out).with("/usr/local/etc/rc.d/#{@current_resource.service_name} status").and_return(@status)
@current_resource.should_receive(:running).with(true)
@provider.load_current_resource
@@ -125,7 +125,7 @@ RC_SAMPLE
@provider.define_resource_requirements
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
end
-
+
describe "when executing assertions" do
it "should verify that /etc/rc.conf exists" do
::File.should_receive(:exists?).with("/etc/rc.conf")
@@ -138,7 +138,7 @@ RC_SAMPLE
it "should raise an exception when the action is #{action}" do
::File.stub!(:exists?).and_return(false)
@provider.load_current_resource
- @provider.define_resource_requirements
+ @provider.define_resource_requirements
@provider.instance_variable_get("@rcd_script_found").should be_false
@provider.action = action
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
@@ -157,7 +157,7 @@ RC_SAMPLE
::File.should_receive(:exists?).with("/etc/rc.conf").and_return false
@provider.load_current_resource
@provider.instance_variable_get("@enabled_state_found").should be_false
- end
+ end
it "update state when current resource enabled state could be determined" do
::File.stub!(:exist?).with("/usr/local/etc/rc.d/#{@new_resource.service_name}").and_return(true)
@@ -165,10 +165,10 @@ RC_SAMPLE
@provider.load_current_resource
@provider.instance_variable_get("@enabled_state_found").should be_false
@provider.instance_variable_get("@rcd_script_found").should be_true
- @provider.define_resource_requirements
+ @provider.define_resource_requirements
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service,
"Could not find the service name in /usr/local/etc/rc.d/#{@current_resource.service_name} and rcvar")
- end
+ end
it "should throw an exception if service line is missing from rc.d script" do
pending "not implemented" do
@@ -197,7 +197,7 @@ RC_SAMPLE
it "should set running to true if the regex matches the output" do
@stdout.stub!(:each_line).and_yield("555 ?? Ss 0:05.16 /usr/sbin/cron -s").
and_yield(" 9881 ?? Ss 0:06.67 /usr/local/sbin/httpd -DNOHTTPACCEPT")
- @provider.load_current_resource
+ @provider.load_current_resource
@current_resource.running.should be_true
end
diff --git a/spec/unit/provider/service/gentoo_service_spec.rb b/spec/unit/provider/service/gentoo_service_spec.rb
index 8d4ada043b..b658cab4d8 100644
--- a/spec/unit/provider/service/gentoo_service_spec.rb
+++ b/spec/unit/provider/service/gentoo_service_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,10 +24,10 @@ describe Chef::Provider::Service::Gentoo do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
-
+
@new_resource = Chef::Resource::Service.new("chef")
@current_resource = Chef::Resource::Service.new("chef")
-
+
@provider = Chef::Provider::Service::Gentoo.new(@new_resource, @run_context)
Chef::Resource::Service.stub!(:new).and_return(@current_resource)
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@@ -39,7 +39,7 @@ describe Chef::Provider::Service::Gentoo do
end
# new test: found_enabled state
#
- describe "load_current_resource" do
+ describe "load_current_resource" do
it "should raise Chef::Exceptions::Service if /sbin/rc-update does not exist" do
File.should_receive(:exists?).with("/sbin/rc-update").and_return(false)
@provider.define_resource_requirements
@@ -79,7 +79,7 @@ describe Chef::Provider::Service::Gentoo do
File.stub!(:exists?).with("/etc/runlevels/default/chef").and_return(true)
File.stub!(:readable?).with("/etc/runlevels/default/chef").and_return(false)
end
-
+
it "should set enabled to false" do
@provider.load_current_resource
@current_resource.enabled.should be_false
@@ -101,10 +101,10 @@ describe Chef::Provider::Service::Gentoo do
end
end
-
+
it "should return the current_resource" do
@provider.load_current_resource.should == @current_resource
- end
+ end
it "should support the status command automatically" do
@provider.load_current_resource
@@ -122,7 +122,7 @@ describe Chef::Provider::Service::Gentoo do
end
end
-
+
describe "action_methods" do
before(:each) { @provider.stub!(:load_current_resource).and_return(@current_resource) }
diff --git a/spec/unit/provider/service/init_service_spec.rb b/spec/unit/provider/service/init_service_spec.rb
index 650fca8320..c7d47e6281 100644
--- a/spec/unit/provider/service/init_service_spec.rb
+++ b/spec/unit/provider/service/init_service_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -40,7 +40,7 @@ PS
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@provider.stub!(:shell_out!).and_return(@status)
end
-
+
it "should create a current resource with the name of the new resource" do
@provider.load_current_resource
@provider.current_resource.should equal(@current_resource)
@@ -60,8 +60,8 @@ PS
@provider.should_receive(:shell_out).with("/etc/init.d/#{@current_resource.service_name} status").and_return(@status)
@provider.load_current_resource
end
-
- it "should set running to true if the the status command returns 0" do
+
+ it "should set running to true if the status command returns 0" do
@provider.stub!(:shell_out).with("/etc/init.d/#{@current_resource.service_name} status").and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_true
@@ -90,9 +90,9 @@ PS
@provider.should_receive(:shell_out).with("/etc/init.d/chefhasmonkeypants status").and_return(@status)
@provider.load_current_resource
end
-
+
end
-
+
describe "when an init command has been specified" do
before do
@new_resource.stub!(:init_command).and_return("/opt/chef-server/service/erchef")
@@ -107,7 +107,7 @@ PS
end
describe "when the node has not specified a ps command" do
-
+
it "should raise an error if the node has a nil ps attribute" do
@node.automatic_attrs[:command] = {:ps => nil}
@provider.load_current_resource
@@ -123,7 +123,7 @@ PS
@provider.define_resource_requirements
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
end
-
+
end
@@ -139,7 +139,7 @@ aj 7842 5057 0 21:26 pts/2 00:00:06 chef
aj 7842 5057 0 21:26 pts/2 00:00:06 poos
RUNNING_PS
@status.stub!(:stdout).and_return(@stdout)
- @provider.load_current_resource
+ @provider.load_current_resource
@current_resource.running.should be_true
end
@@ -172,7 +172,7 @@ RUNNING_PS
it "should call '/etc/init.d/service_name start' if no start command is specified" do
@provider.should_receive(:shell_out!).with("/etc/init.d/#{@new_resource.service_name} start")
@provider.start_service()
- end
+ end
end
describe Chef::Provider::Service::Init, "stop_service" do
diff --git a/spec/unit/provider/service/insserv_service_spec.rb b/spec/unit/provider/service/insserv_service_spec.rb
index c823d511b5..8b5f09e78c 100644
--- a/spec/unit/provider/service/insserv_service_spec.rb
+++ b/spec/unit/provider/service/insserv_service_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -35,7 +35,7 @@ describe Chef::Provider::Service::Insserv do
describe "load_current_resource" do
describe "when startup links exist" do
- before do
+ before do
Dir.stub!(:glob).with("/etc/rc**/S*initgrediant").and_return(["/etc/rc5.d/S18initgrediant", "/etc/rc2.d/S18initgrediant", "/etc/rc4.d/S18initgrediant", "/etc/rc3.d/S18initgrediant"])
end
@@ -46,7 +46,7 @@ describe Chef::Provider::Service::Insserv do
end
describe "when startup links do not exist" do
- before do
+ before do
Dir.stub!(:glob).with("/etc/rc**/S*initgrediant").and_return([])
end
@@ -65,7 +65,7 @@ describe Chef::Provider::Service::Insserv do
@provider.enable_service
end
end
-
+
describe "disable_service" do
it "should call insserv and remove the links" do
@provider.should_receive(:run_command).with({:command=>"/sbin/insserv -r -f #{@new_resource.service_name}"})
diff --git a/spec/unit/provider/service/invokercd_service_spec.rb b/spec/unit/provider/service/invokercd_service_spec.rb
index ace2ad24e3..ca20657405 100644
--- a/spec/unit/provider/service/invokercd_service_spec.rb
+++ b/spec/unit/provider/service/invokercd_service_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -40,7 +40,7 @@ PS
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@provider.stub!(:shell_out!).and_return(@status)
end
-
+
it "should create a current resource with the name of the new resource" do
@provider.load_current_resource
@provider.current_resource.should equal(@current_resource)
@@ -60,8 +60,8 @@ PS
@provider.should_receive(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_return(@status)
@provider.load_current_resource
end
-
- it "should set running to true if the the status command returns 0" do
+
+ it "should set running to true if the status command returns 0" do
@provider.stub!(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_true
@@ -90,9 +90,9 @@ PS
@provider.should_receive(:shell_out).with("/usr/sbin/invoke-rc.d chefhasmonkeypants status").and_return(@status)
@provider.load_current_resource
end
-
+
end
-
+
describe "when the node has not specified a ps command" do
it "should raise error if the node has a nil ps attribute and no other means to get status" do
@node.automatic_attrs[:command] = {:ps => nil}
@@ -107,7 +107,7 @@ PS
@provider.define_resource_requirements
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
end
-
+
end
@@ -125,7 +125,7 @@ aj 7842 5057 0 21:26 pts/2 00:00:06 poos
RUNNING_PS
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@provider.should_receive(:shell_out!).and_return(@status)
- @provider.load_current_resource
+ @provider.load_current_resource
@current_resource.running.should be_true
end
@@ -159,7 +159,7 @@ RUNNING_PS
it "should call '/usr/sbin/invoke-rc.d service_name start' if no start command is specified" do
@provider.should_receive(:shell_out!).with("/usr/sbin/invoke-rc.d #{@new_resource.service_name} start")
@provider.start_service()
- end
+ end
end
describe Chef::Provider::Service::Invokercd, "stop_service" do
diff --git a/spec/unit/provider/service/redhat_spec.rb b/spec/unit/provider/service/redhat_spec.rb
index dd874a4f05..3ce4301026 100644
--- a/spec/unit/provider/service/redhat_spec.rb
+++ b/spec/unit/provider/service/redhat_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -47,7 +47,7 @@ describe "Chef::Provider::Service::Redhat" do
@node.automatic_attrs[:command] = {:ps => 'foo'}
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
-
+
@new_resource = Chef::Resource::Service.new("chef")
@current_resource = Chef::Resource::Service.new("chef")
@@ -73,7 +73,7 @@ describe "Chef::Provider::Service::Redhat" do
@provider.load_current_resource
@current_resource.enabled.should be_true
end
-
+
it "sets the current enabled status to false if the regex does not match" do
status = mock("Status", :exitstatus => 0, :stdout => "" , :stderr => "")
@provider.should_receive(:shell_out).with("/sbin/service chef status").and_return(status)
@@ -84,10 +84,10 @@ describe "Chef::Provider::Service::Redhat" do
@current_resource.enabled.should be_false
end
end
-
+
describe "define resource requirements" do
it_should_behave_like "define_resource_requirements_common"
-
+
context "when the service does not exist" do
before do
status = mock("Status", :exitstatus => 1, :stdout => "", :stderr => "chef: unrecognized service")
diff --git a/spec/unit/provider/service/simple_service_spec.rb b/spec/unit/provider/service/simple_service_spec.rb
index cc0173e246..73cb3766d2 100644
--- a/spec/unit/provider/service/simple_service_spec.rb
+++ b/spec/unit/provider/service/simple_service_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -39,7 +39,7 @@ NOMOCKINGSTRINGSPLZ
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@provider.stub!(:shell_out!).and_return(@status)
end
-
+
it "should create a current resource with the name of the new resource" do
Chef::Resource::Service.should_receive(:new).and_return(@current_resource)
@provider.load_current_resource
@@ -81,7 +81,7 @@ aj 7842 5057 0 21:26 pts/2 00:00:06 poos
NOMOCKINGSTRINGSPLZ
@status = mock("Status", :exitstatus => 0, :stdout => @stdout)
@provider.stub!(:shell_out!).and_return(@status)
- @provider.load_current_resource
+ @provider.load_current_resource
@current_resource.running.should be_true
end
@@ -117,7 +117,7 @@ NOMOCKINGSTRINGSPLZ
@provider.define_resource_requirements
@provider.action = :start
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
- end
+ end
end
describe "when stopping a service" do
@@ -144,7 +144,7 @@ NOMOCKINGSTRINGSPLZ
it "should raise an exception if the resource doesn't support restart, no restart command is provided, and no stop command is provided" do
@provider.define_resource_requirements
@provider.action = :restart
- lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
+ lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
end
it "should just call stop, then start when the resource doesn't support restart and no restart_command is specified" do
diff --git a/spec/unit/provider/service/solaris_smf_service_spec.rb b/spec/unit/provider/service/solaris_smf_service_spec.rb
index 5cda6ddb77..64afee078c 100644
--- a/spec/unit/provider/service/solaris_smf_service_spec.rb
+++ b/spec/unit/provider/service/solaris_smf_service_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -44,7 +44,7 @@ describe Chef::Provider::Service::Solaris do
it "should raise an error if /bin/svcs does not exist" do
File.should_receive(:exists?).with("/bin/svcs").and_return(false)
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Service)
- end
+ end
describe "on a host with /bin/svcs" do
@@ -63,7 +63,7 @@ describe Chef::Provider::Service::Solaris do
it "should return the current resource" do
@provider.stub!(:popen4).with("/bin/svcs -l chef").and_return(@status)
@provider.load_current_resource.should eql(@current_resource)
- end
+ end
it "should popen4 '/bin/svcs -l service_name'" do
@provider.should_receive(:popen4).with("/bin/svcs -l chef").and_return(@status)
diff --git a/spec/unit/provider/service/systemd_service_spec.rb b/spec/unit/provider/service/systemd_service_spec.rb
index bca28a2d92..a107888b0b 100644
--- a/spec/unit/provider/service/systemd_service_spec.rb
+++ b/spec/unit/provider/service/systemd_service_spec.rb
@@ -79,19 +79,19 @@ describe Chef::Provider::Service::Systemd do
@provider.load_current_resource
@provider.instance_variable_get("@status_check_success").should be_true
end
-
+
it "should set running to false if it catches a Chef::Exceptions::Exec when using a status command" do
@provider.stub!(:run_command_with_systems_locale).and_raise(Chef::Exceptions::Exec)
@current_resource.should_receive(:running).with(false)
@provider.load_current_resource
end
-
+
it "should update state to indicate status check failed when an exception is thrown using a status command" do
@provider.stub!(:run_command_with_systems_locale).and_raise(Chef::Exceptions::Exec)
@provider.load_current_resource
@provider.instance_variable_get("@status_check_success").should be_false
end
- end
+ end
it "should check if the service is enabled" do
@provider.should_receive(:is_enabled?)
diff --git a/spec/unit/provider/service/upstart_service_spec.rb b/spec/unit/provider/service/upstart_service_spec.rb
index 4604d1b697..8628a4eaf7 100644
--- a/spec/unit/provider/service/upstart_service_spec.rb
+++ b/spec/unit/provider/service/upstart_service_spec.rb
@@ -73,7 +73,7 @@ describe Chef::Provider::Service::Upstart do
@stdout = StringIO.new
@stderr = StringIO.new
@pid = mock("PID")
-
+
::File.stub!(:exists?).and_return(true)
::File.stub!(:open).and_return(true)
end
@@ -97,7 +97,7 @@ describe Chef::Provider::Service::Upstart do
before do
end
- it "should set running to true if the the status command returns 0" do
+ it "should set running to true if the status command returns 0" do
@stdout = StringIO.new("rsyslog start/running")
@provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@@ -113,7 +113,7 @@ describe Chef::Provider::Service::Upstart do
end
describe "when the status command uses the old format" do
- it "should set running to true if the the status command returns 0" do
+ it "should set running to true if the status command returns 0" do
@stdout = StringIO.new("rsyslog (start) running, process 32225")
@provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@@ -172,7 +172,7 @@ describe Chef::Provider::Service::Upstart do
@provider.load_current_resource
end
- it "should track state when the user-provided status command fails" do
+ it "should track state when the user-provided status command fails" do
@provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_raise(Chef::Exceptions::Exec)
@provider.load_current_resource
@provider.instance_variable_get("@command_success").should == false
@@ -190,7 +190,7 @@ describe Chef::Provider::Service::Upstart do
@provider.load_current_resource
@provider.instance_variable_get("@command_success").should == false
end
-
+
it "should return the current resource" do
@provider.load_current_resource.should eql(@current_resource)
end
diff --git a/spec/unit/provider/service/windows_spec.rb b/spec/unit/provider/service/windows_spec.rb
index a68e798d36..7ec4ccf96a 100644
--- a/spec/unit/provider/service/windows_spec.rb
+++ b/spec/unit/provider/service/windows_spec.rb
@@ -95,7 +95,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
end
describe Chef::Provider::Service::Windows, "stop_service" do
-
+
before(:each) do
Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
mock("StatusStruct", :current_state => "running"),
@@ -143,9 +143,9 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
it "should stop then start the service if it is running" do
Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
- mock("StatusStruct", :current_state => "running"),
- mock("StatusStruct", :current_state => "stopped"),
- mock("StatusStruct", :current_state => "stopped"),
+ mock("StatusStruct", :current_state => "running"),
+ mock("StatusStruct", :current_state => "stopped"),
+ mock("StatusStruct", :current_state => "stopped"),
mock("StatusStruct", :current_state => "running"))
Win32::Service.should_receive(:stop).with(@new_resource.service_name)
Win32::Service.should_receive(:start).with(@new_resource.service_name)
@@ -155,8 +155,8 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
it "should just start the service if it is stopped" do
Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
- mock("StatusStruct", :current_state => "stopped"),
- mock("StatusStruct", :current_state => "stopped"),
+ mock("StatusStruct", :current_state => "stopped"),
+ mock("StatusStruct", :current_state => "stopped"),
mock("StatusStruct", :current_state => "running"))
Win32::Service.should_receive(:start).with(@new_resource.service_name)
@provider.restart_service
@@ -201,7 +201,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@new_resource.updated_by_last_action?.should be_false
end
end
-
+
describe Chef::Provider::Service::Windows, "disable_service" do
before(:each) do
diff --git a/spec/unit/provider/subversion_spec.rb b/spec/unit/provider/subversion_spec.rb
index 81e5860225..dd020d4597 100644
--- a/spec/unit/provider/subversion_spec.rb
+++ b/spec/unit/provider/subversion_spec.rb
@@ -247,7 +247,7 @@ describe Chef::Provider::Subversion do
::File.stub!(:directory?).with("/my/deploy").and_return(true)
::File.should_receive(:exist?).with("/my/deploy/dir/.svn").twice.and_return(false)
@provider.should_receive(:action_checkout)
- @provider.run_action(:sync)
+ @provider.run_action(:sync)
end
it "runs the sync_command on action_sync if the deploy dir exists and isn't empty" do
diff --git a/spec/unit/provider/user/dscl_spec.rb b/spec/unit/provider/user/dscl_spec.rb
index 3894cd61b4..dd98c55bd1 100644
--- a/spec/unit/provider/user/dscl_spec.rb
+++ b/spec/unit/provider/user/dscl_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,7 +29,7 @@ describe Chef::Provider::User::Dscl do
@new_resource = Chef::Resource::User.new("toor")
@provider = Chef::Provider::User::Dscl.new(@new_resource, @run_context)
end
-
+
describe "when shelling out to dscl" do
it "should run dscl with the supplied cmd /Path args" do
shell_return = ShellCmdResult.new('stdout', 'err', 0)
@@ -66,7 +66,7 @@ describe Chef::Provider::User::Dscl do
before do
@provider.stub!(:safe_dscl).and_return("\nwheel 200\nstaff 201\n")
end
-
+
it "should run safe_dscl with list /Users uid" do
@provider.should_receive(:safe_dscl).with("list /Users uid")
@provider.get_free_uid
@@ -75,7 +75,7 @@ describe Chef::Provider::User::Dscl do
it "should return the first unused uid number on or above 200" do
@provider.get_free_uid.should == 202
end
-
+
it "should raise an exception when the search limit is exhausted" do
search_limit = 1
lambda { @provider.get_free_uid(search_limit) }.should raise_error(RuntimeError)
@@ -91,7 +91,7 @@ describe Chef::Provider::User::Dscl do
@provider.should_receive(:safe_dscl).with("list /Users uid")
@provider.uid_used?(500)
end
-
+
it "should return true for a used uid number" do
@provider.uid_used?(500).should be_true
end
@@ -111,7 +111,7 @@ describe Chef::Provider::User::Dscl do
@provider.should_receive(:get_free_uid).and_return(501)
lambda { @provider.set_uid }.should raise_error(Chef::Exceptions::RequestedUIDUnavailable)
end
-
+
it "finds a valid, unused uid when none is specified" do
@provider.should_receive(:safe_dscl).with("list /Users uid").and_return('')
@provider.should_receive(:safe_dscl).with("create /Users/toor UniqueID 501")
@@ -119,7 +119,7 @@ describe Chef::Provider::User::Dscl do
@provider.set_uid
@new_resource.uid.should == 501
end
-
+
it "sets the uid specified in the resource" do
@new_resource.uid(1000)
@provider.should_receive(:safe_dscl).with("create /Users/toor UniqueID 1000").and_return(true)
@@ -132,7 +132,7 @@ describe Chef::Provider::User::Dscl do
before do
@new_resource.supports({ :manage_home => true })
@new_resource.home('/Users/toor')
-
+
@current_resource = @new_resource.dup
@provider.current_resource = @current_resource
end
@@ -142,7 +142,7 @@ describe Chef::Provider::User::Dscl do
@provider.should_receive(:safe_dscl).with("delete /Users/toor NFSHomeDirectory").and_return(true)
@provider.modify_home
end
-
+
it "raises InvalidHomeDirectory when the resource's home directory doesn't look right" do
@new_resource.home('epic-fail')
@@ -151,20 +151,20 @@ describe Chef::Provider::User::Dscl do
it "moves the users home to the new location if it exists and the target location is different" do
@new_resource.supports(:manage_home => true)
-
+
current_home = CHEF_SPEC_DATA + '/old_home_dir'
current_home_files = [current_home + '/my-dot-emacs', current_home + '/my-dot-vim']
@current_resource.home(current_home)
@new_resource.gid(23)
::File.stub!(:exists?).with('/old/home/toor').and_return(true)
::File.stub!(:exists?).with('/Users/toor').and_return(true)
-
+
FileUtils.should_receive(:mkdir_p).with('/Users/toor').and_return(true)
FileUtils.should_receive(:rmdir).with(current_home)
::Dir.should_receive(:glob).with("#{CHEF_SPEC_DATA}/old_home_dir/*",::File::FNM_DOTMATCH).and_return(current_home_files)
FileUtils.should_receive(:mv).with(current_home_files, "/Users/toor", :force => true)
FileUtils.should_receive(:chown_R).with('toor','23','/Users/toor')
-
+
@provider.should_receive(:safe_dscl).with("create /Users/toor NFSHomeDirectory '/Users/toor'")
@provider.modify_home
end
@@ -251,7 +251,7 @@ describe Chef::Provider::User::Dscl do
before do
@new_resource.password("F"*48)
end
-
+
it "should write a shadow hash file with the expected salted sha1" do
uuid = "B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA"
File.should_receive(:open).with('/var/db/shadow/hash/B398449E-CEE0-45E0-80F8-B0B5B1BFDEAA', "w", 384).and_yield(@output)
@@ -262,7 +262,7 @@ describe Chef::Provider::User::Dscl do
expected_shadow_hash[168] = expected_salted_sha1
@provider.modify_password
@output.string.strip.should == expected_shadow_hash
- end
+ end
end
describe "when given a shadow hash file for the password" do
@@ -292,7 +292,7 @@ describe Chef::Provider::User::Dscl do
@provider.should_receive(:safe_dscl).with("read /Users/toor").and_return("\nAuthenticationAuthority: ;ShadowHash;\n")
@provider.modify_password
@output.string.strip.should match(/^0{168}(FFFFFFFF1C1AA7935D4E1190AFEC92343F31F7671FBF126D)0{1071}$/)
- end
+ end
end
it "should write the output directly to the shadow hash file at /var/db/shadow/hash/GUID" do
@@ -392,7 +392,7 @@ describe Chef::Provider::User::Dscl do
before do
@current_resource = @new_resource.dup
@provider.current_resource = @current_resource
-
+
# These are all different from @current_resource
@new_resource.username "mud"
@new_resource.uid 2342
@@ -400,7 +400,7 @@ describe Chef::Provider::User::Dscl do
@new_resource.home '/Users/death'
@new_resource.password 'goaway'
end
-
+
it "sets the user, comment field, uid, gid, moves the home directory, sets the shell, and sets the password" do
@provider.should_receive :dscl_create_user
@provider.should_receive :dscl_create_comment
@@ -417,11 +417,11 @@ describe Chef::Provider::User::Dscl do
before do
@current_resource = @new_resource.dup
@provider.current_resource = @current_resource
-
+
# This is different from @current_resource
@new_resource.gid 2342
end
-
+
it "sets the gid" do
@provider.should_receive :dscl_set_gid
@provider.manage_user
@@ -436,7 +436,7 @@ describe Chef::Provider::User::Dscl do
FileUtils.should_receive(:rm_rf).with("/Users/fuuuuuuuuuuuuu")
@provider.remove_user
end
-
+
it "removes the user from any group memberships" do
Etc.stub(:group).and_yield(OpenStruct.new(:name => 'ragefisters', :mem => 'toor'))
@provider.should_receive(:safe_dscl).with("delete /Users/toor")
diff --git a/spec/unit/provider/user/pw_spec.rb b/spec/unit/provider/user/pw_spec.rb
index b7503ea15f..ea5bcfe740 100644
--- a/spec/unit/provider/user/pw_spec.rb
+++ b/spec/unit/provider/user/pw_spec.rb
@@ -23,7 +23,7 @@ describe Chef::Provider::User::Pw do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
-
+
@new_resource = Chef::Resource::User.new("adam")
@new_resource.comment "Adam Jacob"
@new_resource.uid 1000
@@ -31,7 +31,7 @@ describe Chef::Provider::User::Pw do
@new_resource.home "/home/adam"
@new_resource.shell "/usr/bin/zsh"
@new_resource.password "abracadabra"
-
+
@new_resource.supports :manage_home => true
@current_resource = Chef::Resource::User.new("adam")
diff --git a/spec/unit/provider/user/windows_spec.rb b/spec/unit/provider/user/windows_spec.rb
index 6ede11b28c..b11eeaebe5 100644
--- a/spec/unit/provider/user/windows_spec.rb
+++ b/spec/unit/provider/user/windows_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -41,7 +41,7 @@ describe Chef::Provider::User::Windows do
@provider = Chef::Provider::User::Windows.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
end
-
+
describe "when comparing the user's current attributes to the desired attributes" do
before do
@new_resource.comment "Adam Jacob"
@@ -79,7 +79,7 @@ describe Chef::Provider::User::Windows do
end
end
-
+
describe "and the attributes do not match" do
before do
@current_resource = Chef::Resource::User.new("adam")
@@ -130,7 +130,7 @@ describe Chef::Provider::User::Windows do
before(:each) do
@provider.stub!(:set_options).and_return(:name=> "monkey")
end
-
+
it "should call @net_user.update with the return of set_options" do
@net_user.should_receive(:update).with(:name=> "monkey")
@provider.manage_user
diff --git a/spec/unit/provider/user_spec.rb b/spec/unit/provider/user_spec.rb
index 9c4e2847f7..d054fcc440 100644
--- a/spec/unit/provider/user_spec.rb
+++ b/spec/unit/provider/user_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -58,7 +58,7 @@ describe Chef::Provider::User do
describe "executing load_current_resource" do
before(:each) do
@node = Chef::Node.new
- #@new_resource = mock("Chef::Resource::User",
+ #@new_resource = mock("Chef::Resource::User",
# :null_object => true,
# :username => "adam",
# :comment => "Adam Jacob",
@@ -152,17 +152,17 @@ describe Chef::Provider::User do
@new_resource.password "some new password"
Etc.stub!(:getpwnam).and_return(user)
end
-
+
unless shadow_lib_unavail?
context "and we have the ruby-shadow gem" do
- pending "and we are not root (rerun this again as root)", :requires_unprivileged_user => true
-
+ pending "and we are not root (rerun this again as root)", :requires_unprivileged_user => true
+
context "and we are root", :requires_root => true do
it "should pass assertions when ruby-shadow can be loaded" do
@provider.action = 'create'
original_method = @provider.method(:require)
@provider.should_receive(:require) { |*args| original_method.call(*args) }
- passwd_info = Struct::PasswdEntry.new(:sp_namp => "adm ", :sp_pwdp => "$1$T0N0Q.lc$nyG6pFI3Dpqa5cxUz/57j0", :sp_lstchg => 14861, :sp_min => 0, :sp_max => 99999,
+ passwd_info = Struct::PasswdEntry.new(:sp_namp => "adm ", :sp_pwdp => "$1$T0N0Q.lc$nyG6pFI3Dpqa5cxUz/57j0", :sp_lstchg => 14861, :sp_min => 0, :sp_max => 99999,
:sp_warn => 7, :sp_inact => -1, :sp_expire => -1, :sp_flag => -1)
Shadow::Passwd.should_receive(:getspnam).with("adam").and_return(passwd_info)
@provider.load_current_resource
@@ -177,58 +177,50 @@ describe Chef::Provider::User do
@provider.should_receive(:require).with("shadow") { raise LoadError }
@provider.load_current_resource
@provider.define_resource_requirements
- lambda {@provider.process_resource_requirements}.should raise_error Chef::Exceptions::MissingLibrary
+ lambda {@provider.process_resource_requirements}.should raise_error Chef::Exceptions::MissingLibrary
end
end
end
describe "compare_user" do
- before(:each) do
- # @node = Chef::Node.new
- # @new_resource = mock("Chef::Resource::User",
- # :null_object => true,
- # :username => "adam",
- # :comment => "Adam Jacob",
- # :uid => 1000,
- # :gid => 1000,
- # :home => "/home/adam",
- # :shell => "/usr/bin/zsh",
- # :password => nil,
- # :updated => nil
- # )
- # @current_resource = mock("Chef::Resource::User",
- # :null_object => true,
- # :username => "adam",
- # :comment => "Adam Jacob",
- # :uid => 1000,
- # :gid => 1000,
- # :home => "/home/adam",
- # :shell => "/usr/bin/zsh",
- # :password => nil,
- # :updated => nil
- # )
- # @provider = Chef::Provider::User.new(@node, @new_resource)
- # @provider.current_resource = @current_resource
- end
+ let(:mapping) {
+ {
+ 'username' => ["adam", "Adam"],
+ 'comment' => ["Adam Jacob", "adam jacob"],
+ 'uid' => [1000, 1001],
+ 'gid' => [1000, 1001],
+ 'home' => ["/home/adam", "/Users/adam"],
+ 'shell'=> ["/usr/bin/zsh", "/bin/bash"],
+ 'password'=> ["abcd","12345"]
+ }
+ }
%w{uid gid comment home shell password}.each do |attribute|
it "should return true if #{attribute} doesn't match" do
- @new_resource.should_receive(attribute).exactly(2).times.and_return(true)
- @current_resource.should_receive(attribute).once.and_return(false)
+ @new_resource.send(attribute, mapping[attribute][0])
+ @current_resource.send(attribute, mapping[attribute][1])
@provider.compare_user.should eql(true)
end
end
+ %w{uid gid}.each do |attribute|
+ it "should return false if string #{attribute} matches fixnum" do
+ @new_resource.send(attribute, "100")
+ @current_resource.send(attribute, 100)
+ @provider.compare_user.should eql(false)
+ end
+ end
+
it "should return false if the objects are identical" do
@provider.compare_user.should eql(false)
- end
+ end
end
describe "action_create" do
before(:each) do
@provider.stub!(:load_current_resource)
- # @current_resource = mock("Chef::Resource::User",
+ # @current_resource = mock("Chef::Resource::User",
# :null_object => true,
# :username => "adam",
# :comment => "Adam Jacob",
@@ -261,7 +253,7 @@ describe Chef::Provider::User do
@provider.action_create
end
- it "should set the the new_resources updated flag when it creates the user if we call manage_user" do
+ it "should set the new_resources updated flag when it creates the user if we call manage_user" do
@provider.user_exists = true
@provider.stub!(:compare_user).and_return(true)
@provider.stub!(:manage_user).and_return(true)
@@ -278,7 +270,7 @@ describe Chef::Provider::User do
it "should not call remove_user if the user does not exist" do
@provider.user_exists = false
- @provider.should_not_receive(:remove_user)
+ @provider.should_not_receive(:remove_user)
@provider.action_remove
end
@@ -301,10 +293,10 @@ describe Chef::Provider::User do
before(:each) do
@provider.stub!(:load_current_resource)
# @node = Chef::Node.new
- # @new_resource = mock("Chef::Resource::User",
+ # @new_resource = mock("Chef::Resource::User",
# :null_object => true
# )
- # @current_resource = mock("Chef::Resource::User",
+ # @current_resource = mock("Chef::Resource::User",
# :null_object => true
# )
# @provider = Chef::Provider::User.new(@node, @new_resource)
@@ -344,10 +336,10 @@ describe Chef::Provider::User do
before(:each) do
@provider.stub!(:load_current_resource)
# @node = Chef::Node.new
- # @new_resource = mock("Chef::Resource::User",
+ # @new_resource = mock("Chef::Resource::User",
# :null_object => true
# )
- # @current_resource = mock("Chef::Resource::User",
+ # @current_resource = mock("Chef::Resource::User",
# :null_object => true
# )
# @provider = Chef::Provider::User.new(@node, @new_resource)
@@ -413,10 +405,10 @@ describe Chef::Provider::User do
before(:each) do
@provider.stub!(:load_current_resource)
# @node = Chef::Node.new
- # @new_resource = mock("Chef::Resource::User",
+ # @new_resource = mock("Chef::Resource::User",
# :null_object => true
# )
- # @current_resource = mock("Chef::Resource::User",
+ # @current_resource = mock("Chef::Resource::User",
# :null_object => true
# )
# @provider = Chef::Provider::User.new(@node, @new_resource)
diff --git a/spec/unit/resource/apt_package_spec.rb b/spec/unit/resource/apt_package_spec.rb
index 795ffc6fc4..58b007c327 100644
--- a/spec/unit/resource/apt_package_spec.rb
+++ b/spec/unit/resource/apt_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,19 +19,19 @@
require 'spec_helper'
describe Chef::Resource::AptPackage, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::AptPackage.new("foo")
end
-
+
it "should return a Chef::Resource::AptPackage" do
@resource.should be_a_kind_of(Chef::Resource::AptPackage)
end
-
+
it "should set the resource_name to :apt_package" do
@resource.resource_name.should eql(:apt_package)
end
-
+
it "should set the provider to Chef::Provider::Package::Apt" do
@resource.provider.should eql(Chef::Provider::Package::Apt)
end
diff --git a/spec/unit/resource/bash_spec.rb b/spec/unit/resource/bash_spec.rb
index c7f31e1de6..d729db6977 100644
--- a/spec/unit/resource/bash_spec.rb
+++ b/spec/unit/resource/bash_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,17 +22,17 @@ describe Chef::Resource::Bash do
before(:each) do
@resource = Chef::Resource::Bash.new("fakey_fakerton")
- end
+ end
it "should create a new Chef::Resource::Bash" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Bash)
end
-
+
it "should have a resource name of :bash" do
@resource.resource_name.should eql(:bash)
end
-
+
it "should have an interpreter of bash" do
@resource.interpreter.should eql("bash")
end
diff --git a/spec/unit/resource/batch_spec.rb b/spec/unit/resource/batch_spec.rb
index 91b840908e..b74c7d24a7 100644
--- a/spec/unit/resource/batch_spec.rb
+++ b/spec/unit/resource/batch_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,22 +27,22 @@ describe Chef::Resource::Batch do
node.default["kernel"][:machine] = :x86_64.to_s
run_context = Chef::RunContext.new(node, nil, nil)
-
+
@resource = Chef::Resource::Batch.new("batch_unit_test", run_context)
- end
+ end
it "should create a new Chef::Resource::Batch" do
@resource.should be_a_kind_of(Chef::Resource::Batch)
end
-
+
context "windows script" do
let(:resource_instance) { @resource }
let(:resource_instance_name ) { @resource.command }
let(:resource_name) { :batch }
let(:interpreter_file_name) { 'cmd.exe' }
- it_should_behave_like "a Windows script resource"
+ it_should_behave_like "a Windows script resource"
end
-
+
end
diff --git a/spec/unit/resource/breakpoint_spec.rb b/spec/unit/resource/breakpoint_spec.rb
index 8eaabb546d..412211a038 100644
--- a/spec/unit/resource/breakpoint_spec.rb
+++ b/spec/unit/resource/breakpoint_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,25 +19,25 @@
require 'spec_helper'
describe Chef::Resource::Breakpoint do
-
+
before do
@breakpoint = Chef::Resource::Breakpoint.new
end
-
+
it "allows the action :break" do
@breakpoint.allowed_actions.should include(:break)
end
-
+
it "defaults to the break action" do
@breakpoint.action.should == "break"
end
-
+
it "names itself after the line number of the file where it's created" do
@breakpoint.name.should match(/breakpoint_spec\.rb\:[\d]{2}\:in \`new\'$/)
end
-
+
it "uses the breakpoint provider" do
@breakpoint.provider.should == Chef::Provider::Breakpoint
end
-
+
end
diff --git a/spec/unit/resource/chef_gem_spec.rb b/spec/unit/resource/chef_gem_spec.rb
index 54def9a49d..1d7ca8a81e 100644
--- a/spec/unit/resource/chef_gem_spec.rb
+++ b/spec/unit/resource/chef_gem_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,19 +20,19 @@
require 'spec_helper'
describe Chef::Resource::ChefGem, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::ChefGem.new("foo")
end
-
+
it "should return a Chef::Resource::ChefGem" do
@resource.should be_a_kind_of(Chef::Resource::ChefGem)
end
-
+
it "should set the resource_name to :chef_gem" do
@resource.resource_name.should eql(:chef_gem)
end
-
+
it "should set the provider to Chef::Provider::Package::Rubygems" do
@resource.provider.should eql(Chef::Provider::Package::Rubygems)
end
diff --git a/spec/unit/resource/cookbook_file_spec.rb b/spec/unit/resource/cookbook_file_spec.rb
index d0408c251a..6c55c8035a 100644
--- a/spec/unit/resource/cookbook_file_spec.rb
+++ b/spec/unit/resource/cookbook_file_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,29 +23,29 @@ describe Chef::Resource::CookbookFile do
before do
@cookbook_file = Chef::Resource::CookbookFile.new('sourcecode_tarball.tgz')
end
-
+
it "uses the name parameter for the source parameter" do
@cookbook_file.name.should == 'sourcecode_tarball.tgz'
end
-
+
it "has a source parameter" do
@cookbook_file.name('config_file.conf')
@cookbook_file.name.should == 'config_file.conf'
end
-
+
it "defaults to a nil cookbook parameter (current cookbook will be used)" do
@cookbook_file.cookbook.should be_nil
end
-
+
it "has a cookbook parameter" do
@cookbook_file.cookbook("munin")
@cookbook_file.cookbook.should == 'munin'
end
-
+
it "sets the provider to Chef::Provider::CookbookFile" do
@cookbook_file.provider.should == Chef::Provider::CookbookFile
end
-
+
describe "when it has a backup number, group, mode, owner, source, checksum, and cookbook on nix or path, rights, deny_rights, checksum on windows" do
before do
if Chef::Platform.windows?
@@ -63,21 +63,21 @@ describe Chef::Resource::CookbookFile do
@cookbook_file.checksum("1" * 64)
end
-
+
it "describes the state" do
state = @cookbook_file.state
if Chef::Platform.windows?
puts state
state[:rights].should == [{:permissions => :read, :principals => "Everyone"}]
state[:deny_rights].should == [{:permissions => :full_control, :principals => "Clumsy_Sam"}]
- else
+ else
state[:group].should == "wheel"
state[:mode].should == "0664"
state[:owner].should == "root"
end
state[:checksum].should == "1" * 64
end
-
+
it "returns the path as its identity" do
if Chef::Platform.windows?
@cookbook_file.identity.should == "C:/temp/origin/file.txt"
diff --git a/spec/unit/resource/cron_spec.rb b/spec/unit/resource/cron_spec.rb
index 403ffb009b..7f294fae11 100644
--- a/spec/unit/resource/cron_spec.rb
+++ b/spec/unit/resource/cron_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,21 +23,21 @@ describe Chef::Resource::Cron do
before(:each) do
@resource = Chef::Resource::Cron.new("cronify")
- end
+ end
it "should create a new Chef::Resource::Cron" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Cron)
end
-
+
it "should have a name" do
@resource.name.should eql("cronify")
end
-
+
it "should have a default action of 'create'" do
@resource.action.should eql(:create)
end
-
+
it "should accept create or delete for action" do
lambda { @resource.action :create }.should_not raise_error(ArgumentError)
lambda { @resource.action :delete }.should_not raise_error(ArgumentError)
@@ -63,7 +63,7 @@ describe Chef::Resource::Cron do
@resource.hour "6"
@resource.hour.should eql("6")
end
-
+
it "should allow you to specify the day" do
@resource.day "10"
@resource.day.should eql("10")
@@ -110,7 +110,7 @@ describe Chef::Resource::Cron do
@resource.send(x, "*").should eql("*")
end
end
-
+
it "should allow ranges for all time and date values" do
[ "minute", "hour", "day", "month", "weekday" ].each do |x|
@resource.send(x, "1-2,5").should eql("1-2,5")
@@ -130,31 +130,31 @@ describe Chef::Resource::Cron do
it "should reject any minute over 59" do
lambda { @resource.minute "60" }.should raise_error(RangeError)
end
-
+
it "should reject any hour over 23" do
lambda { @resource.hour "24" }.should raise_error(RangeError)
end
-
+
it "should reject any day over 31" do
lambda { @resource.day "32" }.should raise_error(RangeError)
end
-
+
it "should reject any month over 12" do
lambda { @resource.month "13" }.should raise_error(RangeError)
end
-
+
it "should reject any weekday over 7" do
lambda { @resource.weekday "8" }.should raise_error(RangeError)
end
-
+
it "should convert integer schedule values to a string" do
[ "minute", "hour", "day", "month", "weekday" ].each do |x|
@resource.send(x, 5).should eql("5")
end
end
-
+
describe "when it has a time (minute, hour, day, month, weeekend) and user" do
- before do
+ before do
@resource.command("tackle")
@resource.minute("1")
@resource.hour("2")
diff --git a/spec/unit/resource/csh_spec.rb b/spec/unit/resource/csh_spec.rb
index 291c6ea745..e1534a8f5f 100644
--- a/spec/unit/resource/csh_spec.rb
+++ b/spec/unit/resource/csh_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,17 +22,17 @@ describe Chef::Resource::Csh do
before(:each) do
@resource = Chef::Resource::Csh.new("fakey_fakerton")
- end
+ end
it "should create a new Chef::Resource::Csh" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Csh)
end
-
+
it "should have a resource name of :csh" do
@resource.resource_name.should eql(:csh)
end
-
+
it "should have an interpreter of csh" do
@resource.interpreter.should eql("csh")
end
diff --git a/spec/unit/resource/deploy_revision_spec.rb b/spec/unit/resource/deploy_revision_spec.rb
index 671ba9a1f6..1f509992aa 100644
--- a/spec/unit/resource/deploy_revision_spec.rb
+++ b/spec/unit/resource/deploy_revision_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,7 +19,7 @@
require 'spec_helper'
describe Chef::Resource::DeployRevision do
-
+
it "defaults to the revision deploy provider" do
@resource = Chef::Resource::DeployRevision.new("deploy _this_!")
@resource.provider.should == Chef::Provider::Deploy::Revision
@@ -29,11 +29,11 @@ describe Chef::Resource::DeployRevision do
@resource = Chef::Resource::DeployRevision.new("deploy _this_!")
@resource.resource_name.should == :deploy_revision
end
-
+
end
describe Chef::Resource::DeployBranch do
-
+
it "defaults to the revision deploy provider" do
@resource = Chef::Resource::DeployBranch.new("deploy _this_!")
@resource.provider.should == Chef::Provider::Deploy::Revision
@@ -43,5 +43,5 @@ describe Chef::Resource::DeployBranch do
@resource = Chef::Resource::DeployBranch.new("deploy _this_!")
@resource.resource_name.should == :deploy_branch
end
-
+
end
diff --git a/spec/unit/resource/deploy_spec.rb b/spec/unit/resource/deploy_spec.rb
index 98c9fa1581..7cc25ed41c 100644
--- a/spec/unit/resource/deploy_spec.rb
+++ b/spec/unit/resource/deploy_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,7 +19,7 @@
require 'spec_helper'
describe Chef::Resource::Deploy do
-
+
class << self
def resource_has_a_string_attribute(attr_name)
it "has a String attribute for #{attr_name.to_s}" do
@@ -28,7 +28,7 @@ describe Chef::Resource::Deploy do
lambda {@resource.send(attr_name, 8675309)}.should raise_error(ArgumentError)
end
end
-
+
def resource_has_a_boolean_attribute(attr_name, opts={:defaults_to=>false})
it "has a Boolean attribute for #{attr_name.to_s}" do
@resource.send(attr_name).should eql(opts[:defaults_to])
@@ -36,7 +36,7 @@ describe Chef::Resource::Deploy do
@resource.send(attr_name).should eql( !opts[:defaults_to] )
end
end
-
+
def resource_has_a_callback_attribute(attr_name)
it "has a Callback attribute #{attr_name}" do
callback_block = lambda { :noop }
@@ -49,11 +49,11 @@ describe Chef::Resource::Deploy do
end
end
end
-
+
before do
@resource = Chef::Resource::Deploy.new("/my/deploy/dir")
end
-
+
resource_has_a_string_attribute(:repo)
resource_has_a_string_attribute(:deploy_to)
resource_has_a_string_attribute(:role)
@@ -70,15 +70,15 @@ describe Chef::Resource::Deploy do
resource_has_a_string_attribute(:svn_password)
resource_has_a_string_attribute(:svn_arguments)
resource_has_a_string_attribute(:svn_info_args)
-
+
resource_has_a_boolean_attribute(:migrate, :defaults_to=>false)
resource_has_a_boolean_attribute(:enable_submodules, :defaults_to=>false)
resource_has_a_boolean_attribute(:shallow_clone, :defaults_to=>false)
-
+
it "uses the first argument as the deploy directory" do
@resource.deploy_to.should eql("/my/deploy/dir")
end
-
+
# For git, any revision, branch, tag, whatever is resolved to a SHA1 ref.
# For svn, the branch is included in the repo URL.
# Therefore, revision and branch ARE NOT SEPARATE THINGS
@@ -86,19 +86,19 @@ describe Chef::Resource::Deploy do
@resource.branch "stable"
@resource.revision.should eql("stable")
end
-
+
it "takes the SCM resource to use as a constant, and defaults to git" do
@resource.scm_provider.should eql(Chef::Provider::Git)
@resource.scm_provider Chef::Provider::Subversion
@resource.scm_provider.should eql(Chef::Provider::Subversion)
end
-
+
it "allows scm providers to be set via symbol" do
@resource.scm_provider.should == Chef::Provider::Git
@resource.scm_provider :subversion
@resource.scm_provider.should == Chef::Provider::Subversion
end
-
+
it "allows scm providers to be set via string" do
@resource.scm_provider.should == Chef::Provider::Git
@resource.scm_provider "subversion"
@@ -111,105 +111,105 @@ describe Chef::Resource::Deploy do
@resource.svn_force_export.should be_true
lambda {@resource.svn_force_export(10053)}.should raise_error(ArgumentError)
end
-
+
it "takes arbitrary environment variables in a hash" do
@resource.environment "RAILS_ENV" => "production"
@resource.environment.should == {"RAILS_ENV" => "production"}
end
-
+
it "takes string arguments to environment for backwards compat, setting RAILS_ENV, RACK_ENV, and MERB_ENV" do
@resource.environment "production"
@resource.environment.should == {"RAILS_ENV"=>"production", "RACK_ENV"=>"production","MERB_ENV"=>"production"}
end
-
+
it "sets destination to $deploy_to/shared/$repository_cache" do
@resource.destination.should eql("/my/deploy/dir/shared/cached-copy")
end
-
+
it "sets shared_path to $deploy_to/shared" do
@resource.shared_path.should eql("/my/deploy/dir/shared")
end
-
+
it "sets current_path to $deploy_to/current" do
@resource.current_path.should eql("/my/deploy/dir/current")
end
-
+
it "gets the current_path correct even if the shared_path is set (regression test)" do
@resource.shared_path
@resource.current_path.should eql("/my/deploy/dir/current")
end
-
+
it "gives #depth as 5 if shallow clone is true, nil otherwise" do
@resource.depth.should be_nil
@resource.shallow_clone true
@resource.depth.should eql("5")
end
-
+
it "aliases repo as repository" do
@resource.repository "git@github.com/opcode/cookbooks.git"
@resource.repo.should eql("git@github.com/opcode/cookbooks.git")
end
-
+
it "aliases git_ssh_wrapper as ssh_wrapper" do
@resource.ssh_wrapper "git_my_repo.sh"
@resource.git_ssh_wrapper.should eql("git_my_repo.sh")
end
-
+
it "has an Array attribute purge_before_symlink, default: log, tmp/pids, public/system" do
@resource.purge_before_symlink.should == %w{ log tmp/pids public/system }
@resource.purge_before_symlink %w{foo bar baz}
@resource.purge_before_symlink.should == %w{foo bar baz}
end
-
+
it "has an Array attribute create_dirs_before_symlink, default: tmp, public, config" do
@resource.create_dirs_before_symlink.should == %w{tmp public config}
@resource.create_dirs_before_symlink %w{foo bar baz}
@resource.create_dirs_before_symlink.should == %w{foo bar baz}
end
-
+
it 'has a Hash attribute symlinks, default: {"system" => "public/system", "pids" => "tmp/pids", "log" => "log"}' do
default = { "system" => "public/system", "pids" => "tmp/pids", "log" => "log"}
@resource.symlinks.should == default
@resource.symlinks "foo" => "bar/baz"
@resource.symlinks.should == {"foo" => "bar/baz"}
end
-
+
it 'has a Hash attribute symlink_before_migrate, default "config/database.yml" => "config/database.yml"' do
@resource.symlink_before_migrate.should == {"config/database.yml" => "config/database.yml"}
@resource.symlink_before_migrate "wtf?" => "wtf is going on"
@resource.symlink_before_migrate.should == {"wtf?" => "wtf is going on"}
end
-
+
resource_has_a_callback_attribute :before_migrate
resource_has_a_callback_attribute :before_symlink
resource_has_a_callback_attribute :before_restart
resource_has_a_callback_attribute :after_restart
-
+
it "aliases restart_command as restart" do
@resource.restart "foobaz"
@resource.restart_command.should == "foobaz"
end
-
+
it "takes a block for the restart parameter" do
restart_like_this = lambda {p :noop}
@resource.restart(&restart_like_this)
@resource.restart.should == restart_like_this
end
-
+
it "defaults to using the Deploy::Timestamped provider" do
@resource.provider.should == Chef::Provider::Deploy::Timestamped
end
-
+
it "allows providers to be set with a full class name" do
@resource.provider Chef::Provider::Deploy::Timestamped
@resource.provider.should == Chef::Provider::Deploy::Timestamped
end
-
+
it "allows deploy providers to be set via symbol" do
@resource.provider :revision
@resource.provider.should == Chef::Provider::Deploy::Revision
end
-
+
it "allows deploy providers to be set via string" do
@resource.provider "revision"
@resource.provider.should == Chef::Provider::Deploy::Revision
@@ -229,9 +229,23 @@ describe Chef::Resource::Deploy do
@resource.keep_releases.should == 1
end
+ describe "when it has a timeout attribute" do
+ let(:ten_seconds) { 10 }
+ before { @resource.timeout(ten_seconds) }
+ it "stores this timeout" do
+ @resource.timeout.should == ten_seconds
+ end
+ end
+
+ describe "when it has no timeout attribute" do
+ it "should have no default timeout" do
+ @resource.timeout.should be_nil
+ end
+ end
+
describe "when it has meta application root, revision, user, group,
scm provider, repository cache, environment, simlinks and migrate" do
- before do
+ before do
@resource.repository("http://uri.org")
@resource.deploy_to("/")
@resource.revision("1.2.3")
@@ -242,7 +256,7 @@ describe Chef::Resource::Deploy do
@resource.environment({"SUDO" => "TRUE"})
@resource.symlinks({"system" => "public/system"})
@resource.migrate(false)
-
+
end
it "describes its state" do
@@ -255,5 +269,5 @@ describe Chef::Resource::Deploy do
@resource.identity.should == "http://uri.org"
end
end
-
+
end
diff --git a/spec/unit/resource/directory_spec.rb b/spec/unit/resource/directory_spec.rb
index 9b0c8242e6..dc042c5a77 100644
--- a/spec/unit/resource/directory_spec.rb
+++ b/spec/unit/resource/directory_spec.rb
@@ -61,7 +61,7 @@ describe Chef::Resource::Directory do
end
describe "when it has group, mode, and owner" do
- before do
+ before do
@resource.path("/tmp/foo/bar/")
@resource.group("wheel")
@resource.mode("0664")
diff --git a/spec/unit/resource/dpkg_package_spec.rb b/spec/unit/resource/dpkg_package_spec.rb
index 000908712f..9ef498a577 100644
--- a/spec/unit/resource/dpkg_package_spec.rb
+++ b/spec/unit/resource/dpkg_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,19 +19,19 @@
require 'spec_helper'
describe Chef::Resource::DpkgPackage, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::DpkgPackage.new("foo")
end
-
+
it "should return a Chef::Resource::DpkgPackage" do
@resource.should be_a_kind_of(Chef::Resource::DpkgPackage)
end
-
+
it "should set the resource_name to :dpkg_package" do
@resource.resource_name.should eql(:dpkg_package)
end
-
+
it "should set the provider to Chef::Provider::Package::Dpkg" do
@resource.provider.should eql(Chef::Provider::Package::Dpkg)
end
diff --git a/spec/unit/resource/env_spec.rb b/spec/unit/resource/env_spec.rb
index 6862c669b2..b53cbe478f 100644
--- a/spec/unit/resource/env_spec.rb
+++ b/spec/unit/resource/env_spec.rb
@@ -66,7 +66,7 @@ describe Chef::Resource::Env do
end
describe "when it has key name and value" do
- before do
+ before do
@resource.key_name("charmander")
@resource.value("level7")
@resource.delim("hi")
diff --git a/spec/unit/resource/erl_call_spec.rb b/spec/unit/resource/erl_call_spec.rb
index ccad371723..49df9639d1 100644
--- a/spec/unit/resource/erl_call_spec.rb
+++ b/spec/unit/resource/erl_call_spec.rb
@@ -68,7 +68,7 @@ describe Chef::Resource::ErlCall do
end
describe "when it has cookie and node_name" do
- before do
+ before do
@resource.code("erl-call:function()")
@resource.cookie("cookie")
@resource.node_name("raster")
diff --git a/spec/unit/resource/freebsd_package_spec.rb b/spec/unit/resource/freebsd_package_spec.rb
index 697f5fff06..b80a94f98d 100644
--- a/spec/unit/resource/freebsd_package_spec.rb
+++ b/spec/unit/resource/freebsd_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,19 +19,19 @@
require 'spec_helper'
describe Chef::Resource::FreebsdPackage, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::FreebsdPackage.new("foo")
end
-
+
it "should return a Chef::Resource::FreebsdPackage" do
@resource.should be_a_kind_of(Chef::Resource::FreebsdPackage)
end
-
+
it "should set the resource_name to :freebsd_package" do
@resource.resource_name.should eql(:freebsd_package)
end
-
+
it "should set the provider to Chef::Provider::Package::freebsd" do
@resource.provider.should eql(Chef::Provider::Package::Freebsd)
end
diff --git a/spec/unit/resource/gem_package_spec.rb b/spec/unit/resource/gem_package_spec.rb
index 2404afa03a..98703455de 100644
--- a/spec/unit/resource/gem_package_spec.rb
+++ b/spec/unit/resource/gem_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,19 +19,19 @@
require 'spec_helper'
describe Chef::Resource::GemPackage, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::GemPackage.new("foo")
end
-
+
it "should return a Chef::Resource::GemPackage" do
@resource.should be_a_kind_of(Chef::Resource::GemPackage)
end
-
+
it "should set the resource_name to :gem_package" do
@resource.resource_name.should eql(:gem_package)
end
-
+
it "should set the provider to Chef::Provider::Package::Rubygems" do
@resource.provider.should eql(Chef::Provider::Package::Rubygems)
end
diff --git a/spec/unit/resource/git_spec.rb b/spec/unit/resource/git_spec.rb
index 69b40ffd42..95a30c28a4 100644
--- a/spec/unit/resource/git_spec.rb
+++ b/spec/unit/resource/git_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,28 +19,28 @@
require 'spec_helper'
describe Chef::Resource::Git do
-
+
before(:each) do
@git = Chef::Resource::Git.new("my awesome webapp")
end
-
+
it "is a kind of Scm Resource" do
@git.should be_a_kind_of(Chef::Resource::Scm)
@git.should be_an_instance_of(Chef::Resource::Git)
end
-
+
it "uses the git provider" do
@git.provider.should eql(Chef::Provider::Git)
end
-
+
it "uses aliases revision as branch" do
@git.branch "HEAD"
@git.revision.should eql("HEAD")
end
-
+
it "aliases revision as reference" do
@git.reference "v1.0 tag"
@git.revision.should eql("v1.0 tag")
end
-
+
end
diff --git a/spec/unit/resource/group_spec.rb b/spec/unit/resource/group_spec.rb
index 4e6828ca30..df68c5691f 100644
--- a/spec/unit/resource/group_spec.rb
+++ b/spec/unit/resource/group_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ require 'spec_helper'
describe Chef::Resource::Group, "initialize" do
before(:each) do
@resource = Chef::Resource::Group.new("admin")
- end
+ end
it "should create a new Chef::Resource::Group" do
@resource.should be_a_kind_of(Chef::Resource)
@@ -32,7 +32,7 @@ describe Chef::Resource::Group, "initialize" do
it "should set the resource_name to :group" do
@resource.resource_name.should eql(:group)
end
-
+
it "should set the group_name equal to the argument to initialize" do
@resource.group_name.should eql("admin")
end
@@ -40,7 +40,7 @@ describe Chef::Resource::Group, "initialize" do
it "should default gid to nil" do
@resource.gid.should eql(nil)
end
-
+
it "should default members to an empty array" do
@resource.members.should eql([])
end
@@ -48,11 +48,11 @@ describe Chef::Resource::Group, "initialize" do
it "should alias users to members, also an empty array" do
@resource.users.should eql([])
end
-
+
it "should set action to :create" do
@resource.action.should eql(:create)
end
-
+
%w{create remove modify manage}.each do |action|
it "should allow action #{action}" do
@resource.allowed_actions.detect { |a| a == action.to_sym }.should eql(action.to_sym)
@@ -125,11 +125,11 @@ describe Chef::Resource::Group, "append" do
before(:each) do
@resource = Chef::Resource::Group.new("admin")
end
-
+
it "should default to false" do
@resource.append.should eql(false)
end
-
+
it "should allow a boolean" do
@resource.append true
@resource.append.should eql(true)
@@ -138,9 +138,9 @@ describe Chef::Resource::Group, "append" do
it "should not allow a hash" do
lambda { @resource.send(:gid, { :aj => "is freakin awesome" }) }.should raise_error(ArgumentError)
end
-
+
describe "when it has members" do
- before do
+ before do
@resource.group_name("pokemon")
@resource.members(["blastoise", "pikachu"])
end
diff --git a/spec/unit/resource/http_request_spec.rb b/spec/unit/resource/http_request_spec.rb
index 924cf66fc2..b636ca9994 100644
--- a/spec/unit/resource/http_request_spec.rb
+++ b/spec/unit/resource/http_request_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,7 +23,7 @@ describe Chef::Resource::HttpRequest do
before(:each) do
@resource = Chef::Resource::HttpRequest.new("fakey_fakerton")
- end
+ end
it "should create a new Chef::Resource::HttpRequest" do
@resource.should be_a_kind_of(Chef::Resource)
@@ -34,18 +34,18 @@ describe Chef::Resource::HttpRequest do
@resource.url "http://slashdot.org"
@resource.url.should eql("http://slashdot.org")
end
-
+
it "should set the message to the name by default" do
@resource.message.should eql("fakey_fakerton")
end
-
+
it "should set message to a string" do
@resource.message "monkeybars"
@resource.message.should eql("monkeybars")
end
describe "when it has a message and headers" do
- before do
+ before do
@resource.url("http://www.trololol.net")
@resource.message("Get sum post brah.")
@resource.headers({"head" => "tail"})
@@ -55,5 +55,5 @@ describe Chef::Resource::HttpRequest do
@resource.identity.should == "http://www.trololol.net"
end
end
-
+
end
diff --git a/spec/unit/resource/ifconfig_spec.rb b/spec/unit/resource/ifconfig_spec.rb
index 58869d5107..10a4d09982 100644
--- a/spec/unit/resource/ifconfig_spec.rb
+++ b/spec/unit/resource/ifconfig_spec.rb
@@ -28,7 +28,7 @@ describe Chef::Resource::Ifconfig do
end
describe "when it has target, hardware address, inet address, and a mask" do
- before do
+ before do
@resource.device("charmander")
@resource.target("team_rocket")
@resource.hwaddr("11.2223.223")
diff --git a/spec/unit/resource/ips_package_spec.rb b/spec/unit/resource/ips_package_spec.rb
index 92e62606de..61661922fa 100644
--- a/spec/unit/resource/ips_package_spec.rb
+++ b/spec/unit/resource/ips_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,19 +19,19 @@
require 'spec_helper'
describe Chef::Resource::IpsPackage, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::IpsPackage.new("crypto/gnupg")
end
-
+
it "should return a Chef::Resource::IpsPackage" do
@resource.should be_a_kind_of(Chef::Resource::IpsPackage)
end
-
+
it "should set the resource_name to :ips_package" do
@resource.resource_name.should eql(:ips_package)
end
-
+
it "should set the provider to Chef::Provider::Package::Ips" do
@resource.provider.should eql(Chef::Provider::Package::Ips)
end
diff --git a/spec/unit/resource/link_spec.rb b/spec/unit/resource/link_spec.rb
index bf01bce766..fc3f7ff41c 100644
--- a/spec/unit/resource/link_spec.rb
+++ b/spec/unit/resource/link_spec.rb
@@ -97,7 +97,7 @@ describe Chef::Resource::Link do
end
describe "when it has to, link_type, owner, and group" do
- before do
+ before do
@resource.target_file("/var/target.tar")
@resource.to("/to/dir/file.tar")
@resource.link_type(:symbolic)
diff --git a/spec/unit/resource/log_spec.rb b/spec/unit/resource/log_spec.rb
index 4c6b2c122d..c0201e57f3 100644
--- a/spec/unit/resource/log_spec.rb
+++ b/spec/unit/resource/log_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,12 +24,16 @@ describe Chef::Resource::Log do
before(:each) do
@log_str = "this is my string to log"
@resource = Chef::Resource::Log.new(@log_str)
- end
-
+ end
+
it "should create a new Chef::Resource::Log" do
- @resource.should be_a_kind_of(Chef::Resource)
- @resource.should be_a_kind_of(Chef::Resource::Log)
- end
+ @resource.should be_a_kind_of(Chef::Resource)
+ @resource.should be_a_kind_of(Chef::Resource::Log)
+ end
+
+ it "supports the :write actions" do
+ @resource.allowed_actions.should include(:write)
+ end
it "should have a name of log" do
@resource.resource_name.should == :log
@@ -47,7 +51,7 @@ describe Chef::Resource::Log do
@resource.message "this is different"
@resource.message.should == "this is different"
end
-
+
it "should accept a vaild level option" do
@resource.level :debug
@resource.level :info
@@ -58,7 +62,7 @@ describe Chef::Resource::Log do
end
describe "when the identity is defined" do
- before do
+ before do
@resource = Chef::Resource::Log.new("ery day I'm loggin-in")
end
@@ -67,4 +71,3 @@ describe Chef::Resource::Log do
end
end
end
-
diff --git a/spec/unit/resource/macports_package_spec.rb b/spec/unit/resource/macports_package_spec.rb
index 7420fafeb5..7e2e200487 100644
--- a/spec/unit/resource/macports_package_spec.rb
+++ b/spec/unit/resource/macports_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/resource/mdadm_spec.rb b/spec/unit/resource/mdadm_spec.rb
index c4e6704ceb..310f420659 100644
--- a/spec/unit/resource/mdadm_spec.rb
+++ b/spec/unit/resource/mdadm_spec.rb
@@ -80,13 +80,13 @@ describe Chef::Resource::Mdadm do
end
describe "when it has devices, level, and chunk" do
- before do
+ before do
@resource.raid_device("raider")
@resource.devices(["device1", "device2"])
@resource.level(1)
@resource.chunk(42)
end
-
+
it "describes its state" do
state = @resource.state
state[:devices].should eql(["device1", "device2"])
@@ -98,5 +98,5 @@ describe Chef::Resource::Mdadm do
@resource.identity.should == "raider"
end
end
-
+
end
diff --git a/spec/unit/resource/mount_spec.rb b/spec/unit/resource/mount_spec.rb
index 9f9a534a4e..fb414018ba 100644
--- a/spec/unit/resource/mount_spec.rb
+++ b/spec/unit/resource/mount_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,7 +23,7 @@ describe Chef::Resource::Mount do
before(:each) do
@resource = Chef::Resource::Mount.new("filesystem")
end
-
+
it "should create a new Chef::Resource::Mount" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Mount)
@@ -36,18 +36,18 @@ describe Chef::Resource::Mount do
it "should set mount_point to the name" do
@resource.mount_point.should eql("filesystem")
end
-
+
it "should have a default action of mount" do
@resource.action.should eql(:mount)
end
-
+
it "should accept mount, umount and remount as actions" do
lambda { @resource.action :mount }.should_not raise_error(ArgumentError)
lambda { @resource.action :umount }.should_not raise_error(ArgumentError)
lambda { @resource.action :remount }.should_not raise_error(ArgumentError)
lambda { @resource.action :brooklyn }.should raise_error(ArgumentError)
end
-
+
it "should allow you to set the device attribute" do
@resource.device "/dev/sdb3"
@resource.device.should eql("/dev/sdb3")
@@ -76,19 +76,19 @@ describe Chef::Resource::Mount do
@resource.options "rw,noexec"
@resource.options.should be_a_kind_of(Array)
end
-
+
it "should allow options attribute as an array" do
@resource.options ["ro", "nosuid"]
@resource.options.should be_a_kind_of(Array)
end
it "should accept true for mounted" do
- @resource.mounted(true)
+ @resource.mounted(true)
@resource.mounted.should eql(true)
end
it "should accept false for mounted" do
- @resource.mounted(false)
+ @resource.mounted(false)
@resource.mounted.should eql(false)
end
@@ -101,12 +101,12 @@ describe Chef::Resource::Mount do
end
it "should accept true for enabled" do
- @resource.enabled(true)
+ @resource.enabled(true)
@resource.enabled.should eql(true)
end
it "should accept false for enabled" do
- @resource.enabled(false)
+ @resource.enabled(false)
@resource.enabled.should eql(false)
end
@@ -152,7 +152,7 @@ describe Chef::Resource::Mount do
end
describe "when it has mount point, device type, and fstype" do
- before do
+ before do
@resource.device("charmander")
@resource.mount_point("123.456")
@resource.device_type(:device)
@@ -172,7 +172,7 @@ describe Chef::Resource::Mount do
end
describe "when it has username, password and domain" do
- before do
+ before do
@resource.mount_point("T:")
@resource.device("charmander")
@resource.username("Administrator")
diff --git a/spec/unit/resource/ohai_spec.rb b/spec/unit/resource/ohai_spec.rb
index 82df61e509..b8d062b4c9 100644
--- a/spec/unit/resource/ohai_spec.rb
+++ b/spec/unit/resource/ohai_spec.rb
@@ -43,7 +43,7 @@ describe Chef::Resource::Ohai do
end
describe "when it has a plugin value" do
- before do
+ before do
@resource.name("test")
@resource.plugin("passwd")
end
diff --git a/spec/unit/resource/package_spec.rb b/spec/unit/resource/package_spec.rb
index 3f9cc7a408..0f175dda12 100644
--- a/spec/unit/resource/package_spec.rb
+++ b/spec/unit/resource/package_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,7 +23,7 @@ describe Chef::Resource::Package do
before(:each) do
@resource = Chef::Resource::Package.new("emacs")
- end
+ end
it "should create a new Chef::Resource::Package" do
@resource.should be_a_kind_of(Chef::Resource)
@@ -38,12 +38,12 @@ describe Chef::Resource::Package do
@resource.package_name "something"
@resource.package_name.should eql("something")
end
-
+
it "should accept a string for the version" do
@resource.version "something"
@resource.version.should eql("something")
end
-
+
it "should accept a string for the response file" do
@resource.response_file "something"
@resource.response_file.should eql("something")
@@ -71,7 +71,7 @@ describe Chef::Resource::Package do
state[:version].should == "10.9.8"
state[:options].should == "-al"
end
-
+
it "returns the file path as its identity" do
@resource.identity.should == "tomcat"
end
diff --git a/spec/unit/resource/pacman_package_spec.rb b/spec/unit/resource/pacman_package_spec.rb
index 53ecd296c9..ec5feeb82c 100644
--- a/spec/unit/resource/pacman_package_spec.rb
+++ b/spec/unit/resource/pacman_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,19 +19,19 @@
require 'spec_helper'
describe Chef::Resource::PacmanPackage, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::PacmanPackage.new("foo")
end
-
+
it "should return a Chef::Resource::PacmanPackage" do
@resource.should be_a_kind_of(Chef::Resource::PacmanPackage)
end
-
+
it "should set the resource_name to :pacman_package" do
@resource.resource_name.should eql(:pacman_package)
end
-
+
it "should set the provider to Chef::Provider::Package::Pacman" do
@resource.provider.should eql(Chef::Provider::Package::Pacman)
end
diff --git a/spec/unit/resource/perl_spec.rb b/spec/unit/resource/perl_spec.rb
index f0313e6fb9..d25dc98563 100644
--- a/spec/unit/resource/perl_spec.rb
+++ b/spec/unit/resource/perl_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,17 +22,17 @@ describe Chef::Resource::Perl do
before(:each) do
@resource = Chef::Resource::Perl.new("fakey_fakerton")
- end
+ end
it "should create a new Chef::Resource::Perl" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Perl)
end
-
+
it "should have a resource name of :perl" do
@resource.resource_name.should eql(:perl)
end
-
+
it "should have an interpreter of perl" do
@resource.interpreter.should eql("perl")
end
diff --git a/spec/unit/resource/portage_package_spec.rb b/spec/unit/resource/portage_package_spec.rb
index da086d95ba..510f3b5864 100644
--- a/spec/unit/resource/portage_package_spec.rb
+++ b/spec/unit/resource/portage_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,19 +19,19 @@
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
describe Chef::Resource::PortagePackage, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::PortagePackage.new("foo")
end
-
+
it "should return a Chef::Resource::PortagePackage" do
@resource.should be_a_kind_of(Chef::Resource::PortagePackage)
end
-
+
it "should set the resource_name to :portage_package" do
@resource.resource_name.should eql(:portage_package)
end
-
+
it "should set the provider to Chef::Provider::Package::Portage" do
@resource.provider.should eql(Chef::Provider::Package::Portage)
end
diff --git a/spec/unit/resource/powershell_spec.rb b/spec/unit/resource/powershell_spec.rb
index 6ec37583e6..a35e37c696 100644
--- a/spec/unit/resource/powershell_spec.rb
+++ b/spec/unit/resource/powershell_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,19 +30,19 @@ describe Chef::Resource::PowershellScript do
@resource = Chef::Resource::PowershellScript.new("powershell_unit_test", run_context)
- end
+ end
it "should create a new Chef::Resource::PowershellScript" do
@resource.should be_a_kind_of(Chef::Resource::PowershellScript)
end
-
+
context "windowsscript" do
let(:resource_instance) { @resource }
let(:resource_instance_name ) { @resource.command }
let(:resource_name) { :powershell_script }
let(:interpreter_file_name) { 'powershell.exe' }
- it_should_behave_like "a Windows script resource"
+ it_should_behave_like "a Windows script resource"
end
end
diff --git a/spec/unit/resource/python_spec.rb b/spec/unit/resource/python_spec.rb
index ff9547db9a..3362b68c62 100644
--- a/spec/unit/resource/python_spec.rb
+++ b/spec/unit/resource/python_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,17 +22,17 @@ describe Chef::Resource::Python do
before(:each) do
@resource = Chef::Resource::Python.new("fakey_fakerton")
- end
+ end
it "should create a new Chef::Resource::Python" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Python)
end
-
+
it "should have a resource name of :python" do
@resource.resource_name.should eql(:python)
end
-
+
it "should have an interpreter of python" do
@resource.interpreter.should eql("python")
end
diff --git a/spec/unit/resource/registry_key_spec.rb b/spec/unit/resource/registry_key_spec.rb
index 9d7680de0c..3f227e26b6 100644
--- a/spec/unit/resource/registry_key_spec.rb
+++ b/spec/unit/resource/registry_key_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/resource/remote_directory_spec.rb b/spec/unit/resource/remote_directory_spec.rb
index e4fa8fc4e3..d3800062ae 100644
--- a/spec/unit/resource/remote_directory_spec.rb
+++ b/spec/unit/resource/remote_directory_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@ describe Chef::Resource::RemoteDirectory do
before(:each) do
@resource = Chef::Resource::RemoteDirectory.new("/etc/dunk")
- end
+ end
it "should create a new Chef::Resource::RemoteDirectory" do
@resource.should be_a_kind_of(Chef::Resource)
@@ -46,35 +46,35 @@ describe Chef::Resource::RemoteDirectory do
@resource.files_backup 1
@resource.files_backup.should eql(1)
end
-
+
it "should accept false for the remote files backup" do
@resource.files_backup false
@resource.files_backup.should eql(false)
end
-
+
it "should accept 3 or 4 digets for the files_mode" do
@resource.files_mode 100
@resource.files_mode.should eql(100)
@resource.files_mode 1000
@resource.files_mode.should eql(1000)
end
-
+
it "should accept a string or number for the files group" do
@resource.files_group "heart"
@resource.files_group.should eql("heart")
@resource.files_group 1000
@resource.files_group.should eql(1000)
end
-
+
it "should accept a string or number for the files owner" do
@resource.files_owner "heart"
@resource.files_owner.should eql("heart")
@resource.files_owner 1000
@resource.files_owner.should eql(1000)
end
-
+
describe "when it has cookbook, files owner, files mode, and source" do
- before do
+ before do
@resource.path("/var/path/")
@resource.cookbook("pokemon.rb")
@resource.files_owner("root")
diff --git a/spec/unit/resource/remote_file_spec.rb b/spec/unit/resource/remote_file_spec.rb
index 93fb3c0c36..643bc8ba21 100644
--- a/spec/unit/resource/remote_file_spec.rb
+++ b/spec/unit/resource/remote_file_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -123,7 +123,7 @@ describe Chef::Resource::RemoteFile do
end
describe "when it has group, mode, owner, source, and checksum" do
- before do
+ before do
if Chef::Platform.windows?
@resource.path("C:/temp/origin/file.txt")
@resource.rights(:read, "Everyone")
@@ -144,7 +144,7 @@ describe Chef::Resource::RemoteFile do
puts state
state[:rights].should == [{:permissions => :read, :principals => "Everyone"}]
state[:deny_rights].should == [{:permissions => :full_control, :principals => "Clumsy_Sam"}]
- else
+ else
state[:group].should == "pokemon"
state[:mode].should == "0664"
state[:owner].should == "root"
diff --git a/spec/unit/resource/route_spec.rb b/spec/unit/resource/route_spec.rb
index 966b3aed34..bca42f1101 100644
--- a/spec/unit/resource/route_spec.rb
+++ b/spec/unit/resource/route_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,31 +23,31 @@ describe Chef::Resource::Route do
before(:each) do
@resource = Chef::Resource::Route.new("10.0.0.10")
- end
+ end
it "should create a new Chef::Resource::Route" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Route)
end
-
+
it "should have a name" do
@resource.name.should eql("10.0.0.10")
end
-
+
it "should have a default action of 'add'" do
@resource.action.should eql([:add])
end
-
+
it "should accept add or delete for action" do
lambda { @resource.action :add }.should_not raise_error(ArgumentError)
lambda { @resource.action :delete }.should_not raise_error(ArgumentError)
lambda { @resource.action :lolcat }.should raise_error(ArgumentError)
end
-
+
it "should use the object name as the target by default" do
@resource.target.should eql("10.0.0.10")
end
-
+
it "should allow you to specify the netmask" do
@resource.netmask "255.255.255.0"
@resource.netmask.should eql("255.255.255.0")
@@ -72,22 +72,22 @@ describe Chef::Resource::Route do
@resource.route_type "host"
@resource.route_type.should eql(:host)
end
-
+
it "should default to a host route type" do
@resource.route_type.should eql(:host)
end
-
+
it "should accept a net route type" do
@resource.route_type :net
@resource.route_type.should eql(:net)
end
-
+
it "should reject any other route_type but :host and :net" do
lambda { @resource.route_type "lolcat" }.should raise_error(ArgumentError)
end
-
+
describe "when it has netmask, gateway, and device" do
- before do
+ before do
@resource.target("charmander")
@resource.netmask("lemask")
@resource.gateway("111.111.111")
diff --git a/spec/unit/resource/rpm_package_spec.rb b/spec/unit/resource/rpm_package_spec.rb
index d59dc6b29c..25930a5484 100644
--- a/spec/unit/resource/rpm_package_spec.rb
+++ b/spec/unit/resource/rpm_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/resource/ruby_block_spec.rb b/spec/unit/resource/ruby_block_spec.rb
index 637d4fe34d..82bbd1ffc7 100644
--- a/spec/unit/resource/ruby_block_spec.rb
+++ b/spec/unit/resource/ruby_block_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -33,7 +33,7 @@ describe Chef::Resource::RubyBlock do
it "should have a default action of 'create'" do
@resource.action.should eql("run")
end
-
+
it "should have a resource name of :ruby_block" do
@resource.resource_name.should eql(:ruby_block)
end
@@ -50,7 +50,7 @@ describe Chef::Resource::RubyBlock do
end
describe "when it has been initialized with block code" do
- before do
+ before do
@resource.block_name("puts 'harrrr'")
end
diff --git a/spec/unit/resource/ruby_spec.rb b/spec/unit/resource/ruby_spec.rb
index 48dfd90898..9bf7316e6d 100644
--- a/spec/unit/resource/ruby_spec.rb
+++ b/spec/unit/resource/ruby_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,17 +22,17 @@ describe Chef::Resource::Ruby do
before(:each) do
@resource = Chef::Resource::Ruby.new("fakey_fakerton")
- end
+ end
it "should create a new Chef::Resource::Ruby" do
@resource.should be_a_kind_of(Chef::Resource)
@resource.should be_a_kind_of(Chef::Resource::Ruby)
end
-
+
it "should have a resource name of :ruby" do
@resource.resource_name.should eql(:ruby)
end
-
+
it "should have an interpreter of ruby" do
@resource.interpreter.should eql("ruby")
end
diff --git a/spec/unit/resource/scm_spec.rb b/spec/unit/resource/scm_spec.rb
index 488d335342..8f6593a931 100644
--- a/spec/unit/resource/scm_spec.rb
+++ b/spec/unit/resource/scm_spec.rb
@@ -137,8 +137,21 @@ describe Chef::Resource::Scm do
@resource.ssh_wrapper.should be_nil
end
+ describe "when it has a timeout attribute" do
+ let(:ten_seconds) { 10 }
+ before { @resource.timeout(ten_seconds) }
+ it "stores this timeout" do
+ @resource.timeout.should == ten_seconds
+ end
+ end
+ describe "when it has no timeout attribute" do
+ it "should have no default timeout" do
+ @resource.timeout.should be_nil
+ end
+ end
+
describe "when it has repository, revision, user, and group" do
- before do
+ before do
@resource.destination("hell")
@resource.repository("apt")
@resource.revision("1.2.3")
diff --git a/spec/unit/resource/script_spec.rb b/spec/unit/resource/script_spec.rb
index 53735daf01..f100b0dc85 100644
--- a/spec/unit/resource/script_spec.rb
+++ b/spec/unit/resource/script_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@
require 'spec_helper'
describe Chef::Resource::Script do
- let(:resource_instance_name) { "fakey_fakerton" }
+ let(:resource_instance_name) { "fakey_fakerton" }
let(:script_resource) { Chef::Resource::Script.new(resource_instance_name) }
let(:resource_name) { :script }
@@ -30,7 +30,7 @@ describe Chef::Resource::Script do
end
describe "when it has interpreter and flags" do
- before do
+ before do
script_resource.command("grep")
script_resource.interpreter("gcc")
script_resource.flags("-al")
@@ -40,7 +40,7 @@ describe Chef::Resource::Script do
script_resource.identity.should == "grep"
end
end
-
+
it_behaves_like "a script resource"
end
diff --git a/spec/unit/resource/service_spec.rb b/spec/unit/resource/service_spec.rb
index c06eb9dd77..067fa7d0d3 100644
--- a/spec/unit/resource/service_spec.rb
+++ b/spec/unit/resource/service_spec.rb
@@ -7,9 +7,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,7 +23,7 @@ describe Chef::Resource::Service do
before(:each) do
@resource = Chef::Resource::Service.new("chef")
- end
+ end
it "should create a new Chef::Resource::Service" do
@resource.should be_a_kind_of(Chef::Resource)
@@ -42,7 +42,7 @@ describe Chef::Resource::Service do
@resource.service_name "something"
@resource.service_name.should eql("something")
end
-
+
it "should accept a string for the service pattern" do
@resource.pattern ".*"
@resource.pattern.should eql(".*")
@@ -53,7 +53,7 @@ describe Chef::Resource::Service do
@resource.pattern /.*/
}.should raise_error(ArgumentError)
end
-
+
it "should accept a string for the service start command" do
@resource.start_command "/etc/init.d/chef start"
@resource.start_command.should eql("/etc/init.d/chef start")
@@ -64,7 +64,7 @@ describe Chef::Resource::Service do
@resource.start_command /.*/
}.should raise_error(ArgumentError)
end
-
+
it "should accept a string for the service stop command" do
@resource.stop_command "/etc/init.d/chef stop"
@resource.stop_command.should eql("/etc/init.d/chef stop")
@@ -75,23 +75,23 @@ describe Chef::Resource::Service do
@resource.stop_command /.*/
}.should raise_error(ArgumentError)
end
-
+
it "should accept a string for the service status command" do
@resource.status_command "/etc/init.d/chef status"
@resource.status_command.should eql("/etc/init.d/chef status")
end
-
+
it "should not accept a regexp for the service status command" do
lambda {
@resource.status_command /.*/
}.should raise_error(ArgumentError)
end
-
+
it "should accept a string for the service restart command" do
@resource.restart_command "/etc/init.d/chef restart"
@resource.restart_command.should eql("/etc/init.d/chef restart")
end
-
+
it "should not accept a regexp for the service restart command" do
lambda {
@resource.restart_command /.*/
@@ -102,13 +102,13 @@ describe Chef::Resource::Service do
@resource.reload_command "/etc/init.d/chef reload"
@resource.reload_command.should eql("/etc/init.d/chef reload")
end
-
+
it "should not accept a regexp for the service reload command" do
lambda {
@resource.reload_command /.*/
}.should raise_error(ArgumentError)
end
-
+
it "should accept a string for the service init command" do
@resource.init_command "/etc/init.d/chef"
@resource.init_command.should eql("/etc/init.d/chef")
@@ -122,15 +122,15 @@ describe Chef::Resource::Service do
%w{enabled running}.each do |attrib|
it "should accept true for #{attrib}" do
- @resource.send(attrib, true)
+ @resource.send(attrib, true)
@resource.send(attrib).should eql(true)
end
-
+
it "should accept false for #{attrib}" do
@resource.send(attrib, false)
@resource.send(attrib).should eql(false)
end
-
+
it "should not accept a string for #{attrib}" do
lambda { @resource.send(attrib, "poop") }.should raise_error(ArgumentError)
end
@@ -138,7 +138,7 @@ describe Chef::Resource::Service do
it "should default all the feature support to false" do
support_hash = { :status => false, :restart => false, :reload=> false }
@resource.supports.should == support_hash
- end
+ end
it "should allow you to set what features this resource supports as a array" do
support_array = [ :status, :restart ]
@@ -155,7 +155,7 @@ describe Chef::Resource::Service do
end
describe "when it has pattern and supports" do
- before do
+ before do
@resource.service_name("superfriend")
@resource.enabled(true)
@resource.running(false)
@@ -172,5 +172,5 @@ describe Chef::Resource::Service do
end
end
-
+
end
diff --git a/spec/unit/resource/smartos_package_spec.rb b/spec/unit/resource/smartos_package_spec.rb
index ca815320ad..391713c8ff 100644
--- a/spec/unit/resource/smartos_package_spec.rb
+++ b/spec/unit/resource/smartos_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,14 +18,14 @@
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
-describe Chef::Resource::SmartOSPackage, "initialize" do
+describe Chef::Resource::SmartosPackage, "initialize" do
before(:each) do
- @resource = Chef::Resource::SmartOSPackage.new("foo")
+ @resource = Chef::Resource::SmartosPackage.new("foo")
end
- it "should return a Chef::Resource::SmartOSPackage" do
- @resource.should be_a_kind_of(Chef::Resource::SmartOSPackage)
+ it "should return a Chef::Resource::SmartosPackage" do
+ @resource.should be_a_kind_of(Chef::Resource::SmartosPackage)
end
it "should set the resource_name to :smartos_package" do
diff --git a/spec/unit/resource/solaris_package_spec.rb b/spec/unit/resource/solaris_package_spec.rb
new file mode 100644
index 0000000000..6d0260ab5a
--- /dev/null
+++ b/spec/unit/resource/solaris_package_spec.rb
@@ -0,0 +1,57 @@
+#
+# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+
+describe Chef::Resource::SolarisPackage, "initialize" do
+
+ before(:each) do
+ @resource = Chef::Resource::SolarisPackage.new("foo")
+ end
+
+ it "should return a Chef::Resource::SolarisPackage object" do
+ @resource.should be_a_kind_of(Chef::Resource::SolarisPackage)
+ end
+
+ it "should not raise any Error when valid number of arguments are provided" do
+ expect { Chef::Resource::SolarisPackage.new("foo") }.to_not raise_error
+ end
+
+ it "should raise ArgumentError when incorrect number of arguments are provided" do
+ expect { Chef::Resource::SolarisPackage.new }.to raise_error(ArgumentError)
+ end
+
+ it "should set the package_name to the name provided" do
+ @resource.package_name.should eql("foo")
+ end
+
+ it "should set the resource_name to :solaris_package" do
+ @resource.resource_name.should eql(:solaris_package)
+ end
+
+ it "should set the run_context to the run_context provided" do
+ @run_context = double()
+ @run_context.stub(:node)
+ resource = Chef::Resource::SolarisPackage.new("foo", @run_context)
+ resource.run_context.should eql(@run_context)
+ end
+
+ it "should set the provider to Chef::Provider::Package::Solaris" do
+ @resource.provider.should eql(Chef::Provider::Package::Solaris)
+ end
+end
diff --git a/spec/unit/resource/subversion_spec.rb b/spec/unit/resource/subversion_spec.rb
index 650eb010a6..67593c5a7c 100644
--- a/spec/unit/resource/subversion_spec.rb
+++ b/spec/unit/resource/subversion_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,20 +19,20 @@
require 'spec_helper'
describe Chef::Resource::Subversion do
-
+
before do
@svn = Chef::Resource::Subversion.new("ohai, svn project!")
end
-
+
it "is a subclass of Resource::Scm" do
@svn.should be_an_instance_of(Chef::Resource::Subversion)
@svn.should be_a_kind_of(Chef::Resource::Scm)
end
-
+
it "uses the subversion provider" do
@svn.provider.should eql(Chef::Provider::Subversion)
end
-
+
it "allows the force_export action" do
@svn.allowed_actions.should include(:force_export)
end
diff --git a/spec/unit/resource/timestamped_deploy_spec.rb b/spec/unit/resource/timestamped_deploy_spec.rb
index 89b881830a..f380ffca87 100644
--- a/spec/unit/resource/timestamped_deploy_spec.rb
+++ b/spec/unit/resource/timestamped_deploy_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,10 +19,10 @@
require 'spec_helper'
describe Chef::Resource::TimestampedDeploy do
-
+
it "defaults to the TimestampedDeploy provider" do
@resource = Chef::Resource::TimestampedDeploy.new("stuff")
@resource.provider.should == Chef::Provider::Deploy::Timestamped
end
-
+
end
diff --git a/spec/unit/resource/user_spec.rb b/spec/unit/resource/user_spec.rb
index 3454152367..caf12aa416 100644
--- a/spec/unit/resource/user_spec.rb
+++ b/spec/unit/resource/user_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,7 +21,7 @@ require 'spec_helper'
describe Chef::Resource::User, "initialize" do
before(:each) do
@resource = Chef::Resource::User.new("adam")
- end
+ end
it "should create a new Chef::Resource::User" do
@resource.should be_a_kind_of(Chef::Resource)
@@ -31,29 +31,29 @@ describe Chef::Resource::User, "initialize" do
it "should set the resource_name to :user" do
@resource.resource_name.should eql(:user)
end
-
+
it "should set the username equal to the argument to initialize" do
@resource.username.should eql("adam")
end
-
+
%w{comment uid gid home shell password}.each do |attrib|
it "should set #{attrib} to nil" do
@resource.send(attrib).should eql(nil)
end
end
-
+
it "should set action to :create" do
@resource.action.should eql(:create)
end
-
+
it "should set supports[:manage_home] to false" do
@resource.supports[:manage_home].should eql(false)
end
-
+
it "should set supports[:non_unique] to false" do
@resource.supports[:non_unique].should eql(false)
end
-
+
%w{create remove modify manage lock unlock}.each do |action|
it "should allow action #{action}" do
@resource.allowed_actions.detect { |a| a == action.to_sym }.should eql(action.to_sym)
@@ -72,7 +72,7 @@ end
describe Chef::Resource::User, attrib do
before(:each) do
@resource = Chef::Resource::User.new("adam")
- end
+ end
it "should allow a string" do
@resource.send(attrib, "adam")
@@ -89,13 +89,13 @@ end
describe Chef::Resource::User, attrib do
before(:each) do
@resource = Chef::Resource::User.new("adam")
- end
+ end
it "should allow a string" do
@resource.send(attrib, "100")
@resource.send(attrib).should eql("100")
end
-
+
it "should allow an integer" do
@resource.send(attrib, 100)
@resource.send(attrib).should eql(100)
@@ -105,7 +105,7 @@ end
lambda { @resource.send(attrib, { :woot => "i found it" }) }.should raise_error(ArgumentError)
end
end
-
+
describe "when it has uid, gid, and home" do
before do
@resource = Chef::Resource::User.new("root")
diff --git a/spec/unit/resource/yum_package_spec.rb b/spec/unit/resource/yum_package_spec.rb
index a0f4aaee55..783a539eb2 100644
--- a/spec/unit/resource/yum_package_spec.rb
+++ b/spec/unit/resource/yum_package_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,19 +19,19 @@
require 'spec_helper'
describe Chef::Resource::YumPackage, "initialize" do
-
+
before(:each) do
@resource = Chef::Resource::YumPackage.new("foo")
end
-
+
it "should return a Chef::Resource::YumPackage" do
@resource.should be_a_kind_of(Chef::Resource::YumPackage)
end
-
+
it "should set the resource_name to :yum_package" do
@resource.resource_name.should eql(:yum_package)
end
-
+
it "should set the provider to Chef::Provider::Package::Yum" do
@resource.provider.should eql(Chef::Provider::Package::Yum)
end
@@ -56,7 +56,7 @@ describe Chef::Resource::YumPackage, "flush_cache" do
it "should default the flush timing to false" do
flush_hash = { :before => false, :after => false }
@resource.flush_cache.should == flush_hash
- end
+ end
it "should allow you to set the flush timing with an array" do
flush_array = [ :before, :after ]
diff --git a/spec/unit/resource_collection/stepable_iterator_spec.rb b/spec/unit/resource_collection/stepable_iterator_spec.rb
index 1da9de20cc..b649f8be6e 100644
--- a/spec/unit/resource_collection/stepable_iterator_spec.rb
+++ b/spec/unit/resource_collection/stepable_iterator_spec.rb
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,17 +19,17 @@ require 'spec_helper'
describe Chef::ResourceCollection::StepableIterator do
CRSI = Chef::ResourceCollection::StepableIterator
-
+
it "has an empty array for its collection by default" do
CRSI.new.collection.should == []
end
-
+
describe "doing basic iteration" do
before do
@simple_collection = [1,2,3,4]
@iterator = CRSI.for_collection(@simple_collection)
end
-
+
it "re-initializes the instance with a collection" do
@iterator.collection.should equal(@simple_collection)
@iterator.size.should == 4
@@ -51,7 +51,7 @@ describe Chef::ResourceCollection::StepableIterator do
collected_by_index.should == @simple_collection
collected_by_index.should_not equal(@simple_collection)
end
-
+
it "iterates over the collection with index and element" do
collected = {}
@iterator.each_with_index do |element, index|
@@ -59,32 +59,32 @@ describe Chef::ResourceCollection::StepableIterator do
end
collected.should == {0=>1, 1=>2, 2=>3, 3=>4}
end
-
+
end
-
+
describe "pausing and resuming iteration" do
-
+
before do
@collection = []
@snitch_var = nil
@collection << lambda { @snitch_var = 23 }
@collection << lambda { @iterator.pause }
@collection << lambda { @snitch_var = 42 }
-
+
@iterator = CRSI.for_collection(@collection)
@iterator.each { |proc| proc.call }
end
-
+
it "allows the iteration to be paused" do
@snitch_var.should == 23
end
-
+
it "allows the iteration to be resumed" do
@snitch_var.should == 23
@iterator.resume
@snitch_var.should == 42
end
-
+
it "allows iteration to be rewound" do
@iterator.skip_back(2)
@iterator.resume
@@ -92,13 +92,13 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator.resume
@snitch_var.should == 42
end
-
+
it "allows iteration to be fast forwarded" do
@iterator.skip_forward
@iterator.resume
@snitch_var.should == 23
end
-
+
it "allows iteration to be rewound" do
@snitch_var = nil
@iterator.rewind
@@ -106,7 +106,7 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator.resume
@snitch_var.should == 23
end
-
+
it "allows iteration to be stepped" do
@snitch_var = nil
@iterator.rewind
@@ -114,13 +114,13 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator.position.should == 1
@snitch_var.should == 23
end
-
+
it "doesn't step if there are no more steps" do
@iterator.step.should == 3
lambda {@iterator.step}.should_not raise_error
@iterator.step.should be_nil
end
-
+
it "allows the iteration to start by being stepped" do
@snitch_var = nil
@iterator = CRSI.for_collection(@collection)
@@ -129,7 +129,7 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator.position.should == 1
@snitch_var.should == 23
end
-
+
it "should work correctly when elements are added to the collection during iteration" do
@collection.insert(2, lambda { @snitch_var = 815})
@collection.insert(3, lambda { @iterator.pause })
@@ -138,7 +138,7 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator.resume
@snitch_var.should == 42
end
-
+
end
-
+
end
diff --git a/spec/unit/resource_definition_spec.rb b/spec/unit/resource_definition_spec.rb
index a29c15a1e3..abac4c1163 100644
--- a/spec/unit/resource_definition_spec.rb
+++ b/spec/unit/resource_definition_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,16 +22,16 @@ describe Chef::ResourceDefinition do
before(:each) do
@def = Chef::ResourceDefinition.new()
end
-
+
describe "initialize" do
it "should be a Chef::ResourceDefinition" do
@def.should be_a_kind_of(Chef::ResourceDefinition)
end
-
+
it "should not initialize a new node if one is not provided" do
@def.node.should eql(nil)
end
-
+
it "should accept a node as an argument" do
node = Chef::Node.new
node.name("bobo")
@@ -39,7 +39,7 @@ describe Chef::ResourceDefinition do
@def.node.name.should == "bobo"
end
end
-
+
describe "node" do
it "should set the node with node=" do
node = Chef::Node.new
@@ -47,32 +47,32 @@ describe Chef::ResourceDefinition do
@def.node = node
@def.node.name.should == "bobo"
end
-
+
it "should return the node" do
@def.node = Chef::Node.new
@def.node.should be_a_kind_of(Chef::Node)
end
end
-
+
it "should accept a new definition with a symbol for a name" do
- lambda {
- @def.define :smoke do
+ lambda {
+ @def.define :smoke do
end
}.should_not raise_error(ArgumentError)
- lambda {
+ lambda {
@def.define "george washington" do
- end
+ end
}.should raise_error(ArgumentError)
@def.name.should eql(:smoke)
end
-
+
it "should accept a new definition with a hash" do
- lambda {
+ lambda {
@def.define :smoke, :cigar => "cuban", :cigarette => "marlboro" do
end
}.should_not raise_error(ArgumentError)
end
-
+
it "should expose the prototype hash params in the params hash" do
@def.define :smoke, :cigar => "cuban", :cigarette => "marlboro" do; end
@def.params[:cigar].should eql("cuban")
@@ -86,34 +86,34 @@ describe Chef::ResourceDefinition do
@def.recipe.should be_a_kind_of(Proc)
@def.recipe.call.should eql("I am what I am")
end
-
+
it "should set paramaters based on method_missing" do
@def.mind "to fly"
@def.params[:mind].should eql("to fly")
end
-
+
it "should raise an exception if prototype_params is not a hash" do
lambda {
@def.define :monkey, Array.new do
end
}.should raise_error(ArgumentError)
end
-
+
it "should raise an exception if define is called without a block" do
- lambda {
+ lambda {
@def.define :monkey
}.should raise_error(ArgumentError)
end
-
+
it "should load a description from a file" do
@def.from_file(File.join(CHEF_SPEC_DATA, "definitions", "test.rb"))
@def.name.should eql(:rico_suave)
@def.params[:rich].should eql("smooth")
- end
-
+ end
+
it "should turn itself into a string based on the name with to_s" do
@def.name = :woot
@def.to_s.should eql("woot")
end
-
+
end
diff --git a/spec/unit/resource_reporter_spec.rb b/spec/unit/resource_reporter_spec.rb
index cb4f5bce94..e2ecde212f 100644
--- a/spec/unit/resource_reporter_spec.rb
+++ b/spec/unit/resource_reporter_spec.rb
@@ -464,6 +464,33 @@ describe Chef::ResourceReporter do
end
end
+ context "when including a resource that overrides Resource#state" do
+ before do
+ @current_state_resource = Chef::Resource::WithState.new("Stateful", @run_context)
+ @current_state_resource.state = nil
+
+ @new_state_resource = Chef::Resource::WithState.new("Stateful", @run_context)
+ @new_state_resource.state = "Running"
+ @resource_reporter.resource_action_start(@new_state_resource, :create)
+ @resource_reporter.resource_current_state_loaded(@new_state_resource, :create, @current_state_resource)
+ @resource_reporter.resource_updated(@new_state_resource, :create)
+ @resource_reporter.resource_completed(@new_state_resource)
+ @run_status.stop_clock
+ @report = @resource_reporter.prepare_run_data
+ @first_update_report = @report["resources"].first
+ end
+
+ it "sets before to {} instead of nil" do
+ @first_update_report.should have_key("before")
+ @first_update_report['before'].should eq({})
+ end
+
+ it "sets after to {} instead of 'Running'" do
+ @first_update_report.should have_key("after")
+ @first_update_report['after'].should eq({})
+ end
+ end
+
end
describe "when updating resource history on the server" do
diff --git a/spec/unit/rest/auth_credentials_spec.rb b/spec/unit/rest/auth_credentials_spec.rb
index de06b2cc55..7aa68deab4 100644
--- a/spec/unit/rest/auth_credentials_spec.rb
+++ b/spec/unit/rest/auth_credentials_spec.rb
@@ -199,100 +199,6 @@ describe Chef::REST::RESTRequest do
new_request.http_client.read_timeout.should == 9001
end
- describe "for SSL" do
- before do
- Chef::Config[:ssl_client_cert] = nil
- Chef::Config[:ssl_client_key] = nil
- Chef::Config[:ssl_ca_path] = nil
- Chef::Config[:ssl_ca_file] = nil
- end
-
- after do
- Chef::Config[:ssl_client_cert] = nil
- Chef::Config[:ssl_client_key] = nil
- Chef::Config[:ssl_ca_path] = nil
- Chef::Config[:ssl_verify_mode] = :verify_none
- Chef::Config[:ssl_ca_file] = nil
- end
-
- describe "when configured with :ssl_verify_mode set to :verify peer" do
- before do
- @url = URI.parse("https://chef.example.com:4443/")
- Chef::Config[:ssl_verify_mode] = :verify_peer
- @request = new_request
- end
-
- it "configures the HTTP client to use SSL when given a URL with the https protocol" do
- @request.http_client.use_ssl?.should be_true
- end
-
- it "sets the OpenSSL verify mode to verify_peer" do
- @request.http_client.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
- end
-
- it "raises a ConfigurationError if :ssl_ca_path is set to a path that doesn't exist" do
- Chef::Config[:ssl_ca_path] = "/dev/null/nothing_here"
- lambda {new_request}.should raise_error(Chef::Exceptions::ConfigurationError)
- end
-
- it "should set the CA path if that is set in the configuration" do
- Chef::Config[:ssl_ca_path] = File.join(CHEF_SPEC_DATA, "ssl")
- new_request.http_client.ca_path.should == File.join(CHEF_SPEC_DATA, "ssl")
- end
-
- it "raises a ConfigurationError if :ssl_ca_file is set to a file that does not exist" do
- Chef::Config[:ssl_ca_file] = "/dev/null/nothing_here"
- lambda {new_request}.should raise_error(Chef::Exceptions::ConfigurationError)
- end
-
- it "should set the CA file if that is set in the configuration" do
- Chef::Config[:ssl_ca_file] = CHEF_SPEC_DATA + '/ssl/5e707473.0'
- new_request.http_client.ca_file.should == CHEF_SPEC_DATA + '/ssl/5e707473.0'
- end
- end
-
- describe "when configured with :ssl_verify_mode set to :verify peer" do
- before do
- @url = URI.parse("https://chef.example.com:4443/")
- Chef::Config[:ssl_verify_mode] = :verify_none
- end
-
- it "sets the OpenSSL verify mode to :verify_none" do
- new_request.http_client.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
- end
- end
-
- describe "when configured with a client certificate" do
- before {@url = URI.parse("https://chef.example.com:4443/")}
-
- it "raises ConfigurationError if the certificate file doesn't exist" do
- Chef::Config[:ssl_client_cert] = "/dev/null/nothing_here"
- Chef::Config[:ssl_client_key] = CHEF_SPEC_DATA + '/ssl/chef-rspec.key'
- lambda {new_request}.should raise_error(Chef::Exceptions::ConfigurationError)
- end
-
- it "raises ConfigurationError if the certificate file doesn't exist" do
- Chef::Config[:ssl_client_cert] = CHEF_SPEC_DATA + '/ssl/chef-rspec.cert'
- Chef::Config[:ssl_client_key] = "/dev/null/nothing_here"
- lambda {new_request}.should raise_error(Chef::Exceptions::ConfigurationError)
- end
-
- it "raises a ConfigurationError if one of :ssl_client_cert and :ssl_client_key is set but not both" do
- Chef::Config[:ssl_client_cert] = "/dev/null/nothing_here"
- Chef::Config[:ssl_client_key] = nil
- lambda {new_request}.should raise_error(Chef::Exceptions::ConfigurationError)
- end
-
- it "configures the HTTP client's cert and private key" do
- Chef::Config[:ssl_client_cert] = CHEF_SPEC_DATA + '/ssl/chef-rspec.cert'
- Chef::Config[:ssl_client_key] = CHEF_SPEC_DATA + '/ssl/chef-rspec.key'
- http_client = new_request.http_client
- http_client.cert.to_s.should == OpenSSL::X509::Certificate.new(IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.cert')).to_s
- http_client.key.to_s.should == IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.key')
- end
- end
- end
-
describe "for proxy" do
before do
Chef::Config[:http_proxy] = "http://proxy.example.com:3128"
diff --git a/spec/unit/rest_spec.rb b/spec/unit/rest_spec.rb
index 5ade86110c..fddb3dc407 100644
--- a/spec/unit/rest_spec.rb
+++ b/spec/unit/rest_spec.rb
@@ -57,7 +57,7 @@ describe Chef::REST do
@log_stringio = StringIO.new
Chef::Log.init(@log_stringio)
- Chef::REST::CookieJar.stub!(:instance).and_return({})
+ Chef::REST::CookieJar.stub(:instance).and_return({})
@base_url = "http://chef.example.com:4000"
@monkey_uri = URI.parse("http://chef.example.com:4000/monkey")
@rest = Chef::REST.new(@base_url, nil, nil)
@@ -76,27 +76,46 @@ describe Chef::REST do
end
it "makes a :GET request with the composed url object" do
- @rest.should_receive(:api_request).with(:GET, @monkey_uri, {})
+ @rest.should_receive(:send_http_request).
+ with(:GET, @monkey_uri, STANDARD_READ_HEADERS, false).
+ and_return([1,2,3])
+ @rest.should_receive(:apply_response_middleware).with(1,2,3).and_return([1,2,3])
+ @rest.should_receive('success_response?'.to_sym).with(1).and_return(true)
@rest.get_rest("monkey")
end
it "makes a :GET reqest for a streaming download with the composed url" do
- @rest.should_receive(:streaming_request).with(@monkey_uri, {})
+ @rest.should_receive(:streaming_request).with('monkey', {})
@rest.get_rest("monkey", true)
end
- it "makes a :DELETE request with the composed url object" do
- @rest.should_receive(:api_request).with(:DELETE, @monkey_uri, {})
+ STANDARD_READ_HEADERS = {"Accept"=>"application/json", "Accept"=>"application/json", "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3"}
+ STANDARD_WRITE_HEADERS = {"Accept"=>"application/json", "Content-Type"=>"application/json", "Accept"=>"application/json", "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3"}
+
+ it "makes a :DELETE request with the composed url object" do
+ @rest.should_receive(:send_http_request).
+ with(:DELETE, @monkey_uri, STANDARD_READ_HEADERS, false).
+ and_return([1,2,3])
+ @rest.should_receive(:apply_response_middleware).with(1,2,3).and_return([1,2,3])
+ @rest.should_receive('success_response?'.to_sym).with(1).and_return(true)
@rest.delete_rest("monkey")
end
it "makes a :POST request with the composed url object and data" do
- @rest.should_receive(:api_request).with(:POST, @monkey_uri, {}, "data")
+ @rest.should_receive(:send_http_request).
+ with(:POST, @monkey_uri, STANDARD_WRITE_HEADERS, "\"data\"").
+ and_return([1,2,3])
+ @rest.should_receive(:apply_response_middleware).with(1,2,3).and_return([1,2,3])
+ @rest.should_receive('success_response?'.to_sym).with(1).and_return(true)
@rest.post_rest("monkey", "data")
end
it "makes a :PUT request with the composed url object and data" do
- @rest.should_receive(:api_request).with(:PUT, @monkey_uri, {}, "data")
+ @rest.should_receive(:send_http_request).
+ with(:PUT, @monkey_uri, STANDARD_WRITE_HEADERS, "\"data\"").
+ and_return([1,2,3])
+ @rest.should_receive(:apply_response_middleware).with(1,2,3).and_return([1,2,3])
+ @rest.should_receive('success_response?'.to_sym).with(1).and_return(true)
@rest.put_rest("monkey", "data")
end
end
@@ -156,13 +175,13 @@ describe Chef::REST do
@url = URI.parse("https://one:80/?foo=bar")
@http_response = Net::HTTPSuccess.new("1.1", "200", "successful rest req")
- @http_response.stub!(:read_body)
- @http_response.stub!(:body).and_return("ninja")
+ @http_response.stub(:read_body)
+ @http_response.stub(:body).and_return("ninja")
@http_response.add_field("Content-Length", "5")
@http_client = Net::HTTP.new(@url.host, @url.port)
- Net::HTTP.stub!(:new).and_return(@http_client)
- @http_client.stub!(:request).and_yield(@http_response).and_return(@http_response)
+ Net::HTTP.stub(:new).and_return(@http_client)
+ @http_client.stub(:request).and_yield(@http_response).and_return(@http_response)
@base_headers = { 'Accept' => 'application/json',
'X-Chef-Version' => Chef::VERSION,
@@ -172,23 +191,18 @@ describe Chef::REST do
describe "streaming downloads to a tempfile" do
before do
- @tempfile = Tempfile.open("chef-rspec-rest_spec-line-#{__LINE__}--")
- Tempfile.stub!(:new).with("chef-rest").and_return(@tempfile)
- Tempfile.stub!(:open).and_return(@tempfile)
+ @tempfile = StringIO.new
+ @tempfile.stub(:close!)
+ @tempfile.stub(:path).and_return("/a-temporary-file")
+ Tempfile.stub(:new).with("chef-rest").and_return(@tempfile)
+ Tempfile.stub(:open).and_return(@tempfile)
@request_mock = {}
- Net::HTTP::Get.stub!(:new).and_return(@request_mock)
-
- @http_response_mock = mock("Net::HTTP Response mock")
- end
-
- after do
- @tempfile.rspec_reset
- @tempfile.close!
+ Net::HTTP::Get.stub(:new).and_return(@request_mock)
end
it "should build a new HTTP GET request without the application/json accept header" do
- expected_headers = {'X-Chef-Version' => Chef::VERSION, 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
+ expected_headers = {'Accept' => "*/*", 'X-Chef-Version' => Chef::VERSION, 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
@rest.streaming_request(@url, {})
end
@@ -203,9 +217,9 @@ describe Chef::REST do
end
it "should populate the tempfile with the value of the raw request" do
- @http_response_mock.stub!(:read_body).and_yield("ninja")
- @tempfile.should_receive(:write).with("ninja").once.and_return(true)
+ @http_response.should_receive(:read_body).and_yield("ninja")
@rest.streaming_request(@url, {})
+ #@tempfile.string.should include("ninja")
end
it "should close the tempfile if we're doing a raw request" do
@@ -214,15 +228,15 @@ describe Chef::REST do
end
it "should not raise a divide by zero exception if the size is 0" do
- @http_response_mock.stub!(:header).and_return({ 'Content-Length' => "5" })
- @http_response_mock.stub!(:read_body).and_yield('')
- lambda { @rest.streaming_request(@url, {}) }.should_not raise_error(ZeroDivisionError)
+ @http_response.stub(:header).and_return({ 'Content-Length' => "5" })
+ @http_response.stub(:read_body).and_yield('')
+ lambda { @rest.streaming_request(@url, {}) }.should_not raise_error
end
it "should not raise a divide by zero exception if the Content-Length is 0" do
- @http_response_mock.stub!(:header).and_return({ 'Content-Length' => "0" })
- @http_response_mock.stub!(:read_body).and_yield("ninja")
- lambda { @rest.streaming_request(@url, {}) }.should_not raise_error(ZeroDivisionError)
+ @http_response.stub(:header).and_return({ 'Content-Length' => "0" })
+ @http_response.stub(:read_body).and_yield("ninja")
+ lambda { @rest.streaming_request(@url, {}) }.should_not raise_error
end
end
@@ -230,7 +244,7 @@ describe Chef::REST do
describe "as JSON API requests" do
before do
@request_mock = {}
- Net::HTTP::Get.stub!(:new).and_return(@request_mock)
+ Net::HTTP::Get.stub(:new).and_return(@request_mock)
@base_headers = {"Accept" => "application/json",
"X-Chef-Version" => Chef::VERSION,
@@ -240,14 +254,14 @@ describe Chef::REST do
it "should always include the X-Chef-Version header" do
Net::HTTP::Get.should_receive(:new).with("/?foo=bar", @base_headers).and_return(@request_mock)
- @rest.api_request(:GET, @url, {})
+ @rest.request(:GET, @url, {})
end
it "sets the user agent to chef-client" do
# must reset to default b/c knife changes the UA
Chef::REST::RESTRequest.user_agent = Chef::REST::RESTRequest::DEFAULT_UA
- @rest.api_request(:GET, @url, {})
- @request_mock['User-Agent'].should match /^Chef Client\/#{Chef::VERSION}/
+ @rest.request(:GET, @url, {})
+ @request_mock['User-Agent'].should match(/^Chef Client\/#{Chef::VERSION}/)
end
# CHEF-3140
@@ -265,7 +279,7 @@ describe Chef::REST do
request = Net::HTTP::Get.new(@url.path)
Net::HTTP::Get.should_receive(:new).and_return(request)
# will raise a Zlib error if incorrect
- @rest.api_request(:GET, @url, {}).should == "ninja"
+ @rest.request(:GET, @url, {}).should == "ninja"
end
end
context "when configured with custom http headers" do
@@ -285,19 +299,19 @@ describe Chef::REST do
url_string = an_instance_of(String)
header_hash = hash_including(@custom_headers)
Net::HTTP::Get.should_receive(:new).with(url_string, header_hash)
- @rest.api_request(:GET, @url, {})
+ @rest.request(:GET, @url, {})
end
end
it "should set the cookie for this request if one exists for the given host:port" do
Chef::REST::CookieJar.instance["#{@url.host}:#{@url.port}"] = "cookie monster"
Net::HTTP::Get.should_receive(:new).with("/?foo=bar", @base_headers.merge('Cookie' => "cookie monster")).and_return(@request_mock)
- @rest.api_request(:GET, @url, {})
+ @rest.request(:GET, @url, {})
end
it "should build a new HTTP GET request" do
Net::HTTP::Get.should_receive(:new).with("/?foo=bar", @base_headers).and_return(@request_mock)
- @rest.api_request(:GET, @url, {})
+ @rest.request(:GET, @url, {})
end
it "should build a new HTTP POST request" do
@@ -305,7 +319,7 @@ describe Chef::REST do
expected_headers = @base_headers.merge("Content-Type" => 'application/json', 'Content-Length' => '13')
Net::HTTP::Post.should_receive(:new).with("/?foo=bar", expected_headers).and_return(request)
- @rest.api_request(:POST, @url, {}, {:one=>:two})
+ @rest.request(:POST, @url, {}, {:one=>:two})
request.body.should == '{"one":"two"}'
end
@@ -313,54 +327,54 @@ describe Chef::REST do
request = Net::HTTP::Put.new(@url.path)
expected_headers = @base_headers.merge("Content-Type" => 'application/json', 'Content-Length' => '13')
Net::HTTP::Put.should_receive(:new).with("/?foo=bar",expected_headers).and_return(request)
- @rest.api_request(:PUT, @url, {}, {:one=>:two})
+ @rest.request(:PUT, @url, {}, {:one=>:two})
request.body.should == '{"one":"two"}'
end
it "should build a new HTTP DELETE request" do
Net::HTTP::Delete.should_receive(:new).with("/?foo=bar", @base_headers).and_return(@request_mock)
- @rest.api_request(:DELETE, @url)
+ @rest.request(:DELETE, @url)
end
it "should raise an error if the method is not GET/PUT/POST/DELETE" do
- lambda { @rest.api_request(:MONKEY, @url) }.should raise_error(ArgumentError)
+ lambda { @rest.request(:MONKEY, @url) }.should raise_error(ArgumentError)
end
it "returns nil when the response is successful but content-type is not JSON" do
- @rest.api_request(:GET, @url).should == "ninja"
+ @rest.request(:GET, @url).should == "ninja"
end
it "should inflate the body as to an object if JSON is returned" do
@http_response.add_field('content-type', "application/json")
- @http_response.stub!(:body).and_return('{"ohai2u":"json_api"}')
- @rest.api_request(:GET, @url, {}).should == {"ohai2u"=>"json_api"}
+ @http_response.stub(:body).and_return('{"ohai2u":"json_api"}')
+ @rest.request(:GET, @url, {}).should == {"ohai2u"=>"json_api"}
end
%w[ HTTPFound HTTPMovedPermanently HTTPSeeOther HTTPUseProxy HTTPTemporaryRedirect HTTPMultipleChoice ].each do |resp_name|
- it "should call api_request again on a #{resp_name} response" do
+ it "should call request again on a #{resp_name} response" do
resp_cls = Net.const_get(resp_name)
resp_code = Net::HTTPResponse::CODE_TO_OBJ.keys.detect { |k| Net::HTTPResponse::CODE_TO_OBJ[k] == resp_cls }
http_response = Net::HTTPFound.new("1.1", resp_code, "bob is somewhere else again")
http_response.add_field("location", @url.path)
- http_response.stub!(:read_body)
+ http_response.stub(:read_body)
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
+ @http_client.stub(:request).and_yield(http_response).and_return(http_response)
- lambda { @rest.api_request(:GET, @url) }.should raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ lambda { @rest.request(:GET, @url) }.should raise_error(Chef::Exceptions::RedirectLimitExceeded)
[:PUT, :POST, :DELETE].each do |method|
- lambda { @rest.api_request(method, @url) }.should raise_error(Chef::Exceptions::InvalidRedirect)
+ lambda { @rest.request(method, @url) }.should raise_error(Chef::Exceptions::InvalidRedirect)
end
end
end
it "should return `false` when response is 304 NotModified" do
http_response = Net::HTTPNotModified.new("1.1", "304", "it's the same as when you asked 5 minutes ago")
- http_response.stub!(:read_body)
+ http_response.stub(:read_body)
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
+ @http_client.stub(:request).and_yield(http_response).and_return(http_response)
- @rest.api_request(:GET, @url).should be_false
+ @rest.request(:GET, @url).should be_false
end
describe "when the request fails" do
@@ -376,12 +390,12 @@ describe Chef::REST do
it "should show the JSON error message on an unsuccessful request" do
http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
http_response.add_field("content-type", "application/json")
- http_response.stub!(:body).and_return('{ "error":[ "Ears get sore!", "Not even four" ] }')
- http_response.stub!(:read_body)
- @rest.stub!(:sleep)
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
+ http_response.stub(:body).and_return('{ "error":[ "Ears get sore!", "Not even four" ] }')
+ http_response.stub(:read_body)
+ @rest.stub(:sleep)
+ @http_client.stub(:request).and_yield(http_response).and_return(http_response)
- lambda {@rest.api_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
+ lambda {@rest.request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
@log_stringio.string.should match(Regexp.escape('INFO: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
end
@@ -393,23 +407,23 @@ describe Chef::REST do
gzipped_body = Zlib::Deflate.deflate(unzipped_body)
gzipped_body.force_encoding(Encoding::BINARY) if "strings".respond_to?(:force_encoding)
- http_response.stub!(:body).and_return gzipped_body
- http_response.stub!(:read_body)
- @rest.stub!(:sleep)
- @rest.stub!(:http_retry_count).and_return(0)
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
+ http_response.stub(:body).and_return gzipped_body
+ http_response.stub(:read_body)
+ @rest.stub(:sleep)
+ @rest.stub(:http_retry_count).and_return(0)
+ @http_client.stub(:request).and_yield(http_response).and_return(http_response)
- lambda {@rest.api_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
+ lambda {@rest.request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
@log_stringio.string.should match(Regexp.escape('INFO: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
end
it "should raise an exception on an unsuccessful request" do
http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
- http_response.stub!(:body)
- http_response.stub!(:read_body)
- @rest.stub!(:sleep)
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
- lambda {@rest.api_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
+ http_response.stub(:body)
+ http_response.stub(:read_body)
+ @rest.stub(:sleep)
+ @http_client.stub(:request).and_yield(http_response).and_return(http_response)
+ lambda {@rest.request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
end
end
@@ -419,22 +433,21 @@ describe Chef::REST do
context "when streaming downloads to a tempfile" do
before do
@tempfile = Tempfile.open("chef-rspec-rest_spec-line-#{__LINE__}--")
- Tempfile.stub!(:new).with("chef-rest").and_return(@tempfile)
+ Tempfile.stub(:new).with("chef-rest").and_return(@tempfile)
@request_mock = {}
- Net::HTTP::Get.stub!(:new).and_return(@request_mock)
+ Net::HTTP::Get.stub(:new).and_return(@request_mock)
@http_response = Net::HTTPSuccess.new("1.1",200, "it-works")
- @http_response.stub!(:read_body)
- @http_client.stub!(:request).and_yield(@http_response).and_return(@http_response)
+ @http_response.stub(:read_body)
+ @http_client.stub(:request).and_yield(@http_response).and_return(@http_response)
end
after do
- @tempfile.rspec_reset
@tempfile.close!
end
it " build a new HTTP GET request without the application/json accept header" do
- expected_headers = {'X-Chef-Version' => Chef::VERSION, 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
+ expected_headers = {'Accept' => "*/*", 'X-Chef-Version' => Chef::VERSION, 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
@rest.streaming_request(@url, {})
end
@@ -444,7 +457,7 @@ describe Chef::REST do
end
it "writes the response body to a tempfile" do
- @http_response.stub!(:read_body).and_yield("real").and_yield("ultimate").and_yield("power")
+ @http_response.stub(:read_body).and_yield("real").and_yield("ultimate").and_yield("power")
@rest.streaming_request(@url, {})
IO.read(@tempfile.path).chomp.should == "realultimatepower"
end
@@ -455,7 +468,7 @@ describe Chef::REST do
end
it "yields the tempfile containing the streamed response body and then unlinks it when given a block" do
- @http_response.stub!(:read_body).and_yield("real").and_yield("ultimate").and_yield("power")
+ @http_response.stub(:read_body).and_yield("real").and_yield("ultimate").and_yield("power")
tempfile_path = nil
@rest.streaming_request(@url, {}) do |tempfile|
tempfile_path = tempfile.path
@@ -467,18 +480,18 @@ describe Chef::REST do
it "does not raise a divide by zero exception if the content's actual size is 0" do
@http_response.add_field('Content-Length', "5")
- @http_response.stub!(:read_body).and_yield('')
- lambda { @rest.streaming_request(@url, {}) }.should_not raise_error(ZeroDivisionError)
+ @http_response.stub(:read_body).and_yield('')
+ lambda { @rest.streaming_request(@url, {}) }.should_not raise_error
end
it "does not raise a divide by zero exception when the Content-Length is 0" do
@http_response.add_field('Content-Length', "0")
- @http_response.stub!(:read_body).and_yield("ninja")
- lambda { @rest.streaming_request(@url, {}) }.should_not raise_error(ZeroDivisionError)
+ @http_response.stub(:read_body).and_yield("ninja")
+ lambda { @rest.streaming_request(@url, {}) }.should_not raise_error
end
it "fetches a file and yields the tempfile it is streamed to" do
- @http_response.stub!(:read_body).and_yield("real").and_yield("ultimate").and_yield("power")
+ @http_response.stub(:read_body).and_yield("real").and_yield("ultimate").and_yield("power")
tempfile_path = nil
@rest.fetch("cookbooks/a_cookbook") do |tempfile|
tempfile_path = tempfile.path
@@ -490,34 +503,32 @@ describe Chef::REST do
it "closes and unlinks the tempfile if there is an error while streaming the content to the tempfile" do
path = @tempfile.path
path.should_not be_nil
- @tempfile.stub!(:write).and_raise(IOError)
+ @tempfile.stub(:write).and_raise(IOError)
@rest.fetch("cookbooks/a_cookbook") {|tmpfile| "shouldn't get here"}
File.exists?(path).should be_false
end
it "closes and unlinks the tempfile when the response is a redirect" do
- Tempfile.rspec_reset
- tempfile = mock("die", :path => "/tmp/ragefist", :close => true, :binmode => true)
- tempfile.should_receive(:close!).at_least(2).times
- Tempfile.stub!(:new).with("chef-rest").and_return(tempfile)
+ tempfile = double("A tempfile", :path => "/tmp/ragefist", :close => true, :binmode => true)
+ tempfile.should_receive(:close!).at_least(1).times
+ Tempfile.stub(:new).with("chef-rest").and_return(tempfile)
- http_response = Net::HTTPFound.new("1.1", "302", "bob is taking care of that one for me today")
- http_response.add_field("location", @url.path)
- http_response.stub!(:read_body)
+ redirect = Net::HTTPFound.new("1.1", "302", "bob is taking care of that one for me today")
+ redirect.add_field("location", @url.path)
+ redirect.stub(:read_body)
- @http_client.stub!(:request).and_yield(http_response).and_yield(@http_response).and_return(http_response, @http_response)
+ @http_client.should_receive(:request).and_yield(redirect).and_return(redirect)
+ @http_client.should_receive(:request).and_yield(@http_response).and_return(@http_response)
@rest.fetch("cookbooks/a_cookbook") {|tmpfile| "shouldn't get here"}
end
it "passes the original block to the redirected request" do
- Tempfile.rspec_reset
-
http_response = Net::HTTPFound.new("1.1", "302", "bob is taking care of that one for me today")
http_response.add_field("location","/that-thing-is-here-now")
- http_response.stub!(:read_body)
+ http_response.stub(:read_body)
block_called = false
- @http_client.stub!(:request).and_yield(@http_response).and_return(http_response, @http_response)
+ @http_client.stub(:request).and_yield(@http_response).and_return(http_response, @http_response)
@rest.fetch("cookbooks/a_cookbook") do |tmpfile|
block_called = true
end
@@ -546,9 +557,9 @@ describe Chef::REST do
redirected.call unless total_redirects >= 9
end
end
- lambda {redirected.call}.should_not raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ lambda {redirected.call}.should_not raise_error
total_redirects = 0
- lambda {redirected.call}.should_not raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ lambda {redirected.call}.should_not raise_error
end
it "does not sign the redirected request when sign_on_redirect is false" do
@@ -572,7 +583,7 @@ describe Chef::REST do
redirected.call unless total_redirects >= 9
end
end
- lambda {redirected.call}.should_not raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ lambda {redirected.call}.should_not raise_error
total_redirects = 0
@rest.redirect_limit = 3
diff --git a/spec/unit/role_spec.rb b/spec/unit/role_spec.rb
index 764d586903..f36b7f13bd 100644
--- a/spec/unit/role_spec.rb
+++ b/spec/unit/role_spec.rb
@@ -244,6 +244,11 @@ describe Chef::Role do
end
end
+ ROLE_DSL=<<-EOR
+name "ceiling_cat"
+description "like Aliens, but furry"
+EOR
+
describe "when loading from disk" do
it "should return a Chef::Role object from JSON" do
File.should_receive(:exists?).with(File.join(Chef::Config[:role_path], 'lolcat.json')).exactly(1).times.and_return(true)
@@ -256,10 +261,6 @@ describe Chef::Role do
File.should_receive(:exists?).with(File.join(Chef::Config[:role_path], 'lolcat.json')).exactly(1).times.and_return(false)
File.should_receive(:exists?).with(File.join(Chef::Config[:role_path], 'lolcat.rb')).exactly(2).times.and_return(true)
File.should_receive(:readable?).with(File.join(Chef::Config[:role_path], 'lolcat.rb')).exactly(1).times.and_return(true)
- ROLE_DSL=<<-EOR
-name "ceiling_cat"
-description "like Aliens, but furry"
-EOR
IO.should_receive(:read).with(File.join(Chef::Config[:role_path], 'lolcat.rb')).and_return(ROLE_DSL)
@role.should be_a_kind_of(Chef::Role)
@role.class.from_disk("lolcat")
@@ -271,5 +272,57 @@ EOR
lambda {@role.class.from_disk("lolcat")}.should raise_error(Chef::Exceptions::RoleNotFound)
end
end
+
+ describe "when loading from disk and role_path is an array" do
+
+ before(:each) do
+ Chef::Config[:role_path] = ['/path1', '/path/path2']
+ end
+
+ it "should return a Chef::Role object from JSON" do
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.json')).exactly(1).times.and_return(true)
+ IO.should_receive(:read).with(File.join('/path1', 'lolcat.json')).and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
+ @role.should be_a_kind_of(Chef::Role)
+ @role.class.from_disk("lolcat")
+ end
+
+ it "should return a Chef::Role object from JSON when role is in the second path" do
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.json')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.rb')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path/path2', 'lolcat.json')).exactly(1).times.and_return(true)
+ IO.should_receive(:read).with(File.join('/path/path2', 'lolcat.json')).and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
+ @role.should be_a_kind_of(Chef::Role)
+ @role.class.from_disk("lolcat")
+ end
+
+ it "should return a Chef::Role object from a Ruby DSL" do
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.json')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.rb')).exactly(2).times.and_return(true)
+ File.should_receive(:readable?).with(File.join('/path1', 'lolcat.rb')).exactly(1).times.and_return(true)
+ IO.should_receive(:read).with(File.join('/path1', 'lolcat.rb')).and_return(ROLE_DSL)
+ @role.should be_a_kind_of(Chef::Role)
+ @role.class.from_disk("lolcat")
+ end
+
+ it "should return a Chef::Role object from a Ruby DSL when role is in the second path" do
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.json')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.rb')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path/path2', 'lolcat.json')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path/path2', 'lolcat.rb')).exactly(2).times.and_return(true)
+ File.should_receive(:readable?).with(File.join('/path/path2', 'lolcat.rb')).exactly(1).times.and_return(true)
+ IO.should_receive(:read).with(File.join('/path/path2', 'lolcat.rb')).and_return(ROLE_DSL)
+ @role.should be_a_kind_of(Chef::Role)
+ @role.class.from_disk("lolcat")
+ end
+
+ it "should raise an exception if the file does not exist" do
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.json')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path1', 'lolcat.rb')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path/path2', 'lolcat.json')).exactly(1).times.and_return(false)
+ File.should_receive(:exists?).with(File.join('/path/path2', 'lolcat.rb')).exactly(1).times.and_return(false)
+ lambda {@role.class.from_disk("lolcat")}.should raise_error(Chef::Exceptions::RoleNotFound)
+ end
+
+ end
end
diff --git a/spec/unit/run_context/cookbook_compiler_spec.rb b/spec/unit/run_context/cookbook_compiler_spec.rb
index 0c5e568a13..52f4772206 100644
--- a/spec/unit/run_context/cookbook_compiler_spec.rb
+++ b/spec/unit/run_context/cookbook_compiler_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,23 +17,7 @@
#
require 'spec_helper'
-
-# Keeps track of what file got loaded in what order.
-module LibraryLoadOrder
- extend self
-
- def load_order
- @load_order ||= []
- end
-
- def reset!
- @load_order = nil
- end
-
- def record(file)
- load_order << file
- end
-end
+require 'support/lib/library_load_order'
# These tests rely on fixture data in spec/data/run_context/cookbooks.
#
@@ -178,7 +162,7 @@ describe Chef::RunContext::CookbookCompiler do
# Tests for this behavior are in RunContext's tests
end
- describe "listing cookbook order" do
+ describe "listing cookbook order" do
it "should return an array of cookbook names as symbols without duplicates" do
node.run_list("test-with-circular-deps::default", "circular-dep1::default", "circular-dep2::default")
diff --git a/spec/unit/run_context_spec.rb b/spec/unit/run_context_spec.rb
index 51fa0e81f9..8063dffc77 100644
--- a/spec/unit/run_context_spec.rb
+++ b/spec/unit/run_context_spec.rb
@@ -8,9 +8,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,6 +19,7 @@
#
require 'spec_helper'
+require 'support/lib/library_load_order'
Chef::Log.level = :debug
@@ -42,7 +43,7 @@ describe Chef::RunContext do
@run_context.node.should == @node
end
- describe "after loading the cookbooks" do
+ describe "loading cookbooks for a run list" do
before do
@run_context.load(@node.run_list.expand('_default'))
end
@@ -73,6 +74,46 @@ describe Chef::RunContext do
@node.should_not_receive(:from_file)
@node.include_attribute("test::george")
end
+
+
+ end
+
+ describe "querying the contents of cookbooks" do
+ before do
+ @chef_repo_path = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks"))
+ cl = Chef::CookbookLoader.new(@chef_repo_path)
+ cl.load_cookbooks
+ @cookbook_collection = Chef::CookbookCollection.new(cl)
+ @node = Chef::Node.new
+ @node.set[:platform] = "ubuntu"
+ @node.set[:platform_version] = "13.04"
+ @node.name("testing")
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
+ end
+
+
+ it "queries whether a given cookbook has a specific template" do
+ @run_context.should have_template_in_cookbook("openldap", "test.erb")
+ @run_context.should_not have_template_in_cookbook("openldap", "missing.erb")
+ end
+
+ it "errors when querying for a template in a not-available cookbook" do
+ expect do
+ @run_context.has_template_in_cookbook?("no-such-cookbook", "foo.erb")
+ end.to raise_error(Chef::Exceptions::CookbookNotFound)
+ end
+
+ it "queries whether a given cookbook has a specific cookbook_file" do
+ @run_context.should have_cookbook_file_in_cookbook("java", "java.response")
+ @run_context.should_not have_cookbook_file_in_cookbook("java", "missing.txt")
+ end
+
+ it "errors when querying for a cookbook_file in a not-available cookbook" do
+ expect do
+ @run_context.has_cookbook_file_in_cookbook?("no-such-cookbook", "foo.txt")
+ end.to raise_error(Chef::Exceptions::CookbookNotFound)
+ end
end
end
diff --git a/spec/unit/run_list/run_list_item_spec.rb b/spec/unit/run_list/run_list_item_spec.rb
index 62a17aa761..6b9de713da 100644
--- a/spec/unit/run_list/run_list_item_spec.rb
+++ b/spec/unit/run_list/run_list_item_spec.rb
@@ -101,7 +101,7 @@ describe Chef::RunList::RunListItem do
item2 = Chef::RunList::RunListItem.new('recipe[lobsterragefist]')
item1.should_not == item2
end
-
+
it "is not equal to another run list item with the same name and type but different version" do
item1 = Chef::RunList::RunListItem.new('recipe[lrf,0.1.0]')
item2 = Chef::RunList::RunListItem.new('recipe[lrf,0.2.0]')
diff --git a/spec/unit/run_lock_spec.rb b/spec/unit/run_lock_spec.rb
index 4e62b110b9..de302dc533 100644
--- a/spec/unit/run_lock_spec.rb
+++ b/spec/unit/run_lock_spec.rb
@@ -20,14 +20,17 @@ require 'chef/client'
describe Chef::RunLock do
+ default_pid_location = windows? ? 'C:\chef\cache\chef-client-running.pid' : '/var/chef/cache/chef-client-running.pid'
+
describe "when first created" do
it "locates the lockfile in the file cache path by default" do
- run_lock = Chef::RunLock.new(:file_cache_path => "/var/chef/cache", :lockfile => nil)
- run_lock.runlock_file.should == "/var/chef/cache/chef-client-running.pid"
+ run_lock = Chef::RunLock.new(Chef::Config.lockfile)
+ run_lock.runlock_file.should == default_pid_location
end
it "locates the lockfile in the user-configured path when set" do
- run_lock = Chef::RunLock.new(:file_cache_path => "/var/chef/cache", :lockfile => "/tmp/chef-client-running.pid")
+ Chef::Config.lockfile = "/tmp/chef-client-running.pid"
+ run_lock = Chef::RunLock.new(Chef::Config.lockfile)
run_lock.runlock_file.should == "/tmp/chef-client-running.pid"
end
end
diff --git a/spec/unit/scan_access_control_spec.rb b/spec/unit/scan_access_control_spec.rb
index c83a552626..3cfecfaa35 100644
--- a/spec/unit/scan_access_control_spec.rb
+++ b/spec/unit/scan_access_control_spec.rb
@@ -69,7 +69,7 @@ describe Chef::ScanAccessControl do
it "sets the group of the current resource to the current group as a String" do
@current_resource.group.should == Etc.getgrgid(0).name
end
-
+
it "sets the owner of the current resource to the current owner as a String" do
@current_resource.user.should == "root"
end
@@ -79,7 +79,7 @@ describe Chef::ScanAccessControl do
it "sets the group of the current resource to the current group as a String" do
@current_resource.group.should == 0
end
-
+
it "sets the owner of the current resource to the current owner as a String" do
@current_resource.user.should == 0
end
diff --git a/spec/unit/search/query_spec.rb b/spec/unit/search/query_spec.rb
index e32bed697c..3f41c142ee 100644
--- a/spec/unit/search/query_spec.rb
+++ b/spec/unit/search/query_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,7 +19,7 @@
require 'spec_helper'
require 'chef/search/query'
-describe Chef::Search::Query do
+describe Chef::Search::Query do
before(:each) do
@rest = mock("Chef::REST")
Chef::REST.stub!(:new).and_return(@rest)
diff --git a/spec/unit/util/backup_spec.rb b/spec/unit/util/backup_spec.rb
index f0e182e181..c49694f924 100644
--- a/spec/unit/util/backup_spec.rb
+++ b/spec/unit/util/backup_spec.rb
@@ -21,13 +21,6 @@ require 'spec_helper'
require 'tmpdir'
describe Chef::Util::Backup do
- before(:all) do
- @original_config = Chef::Config.configuration
- end
-
- after(:all) do
- Chef::Config.configuration.replace(@original_config)
- end
let (:tempfile) do
Tempfile.new("chef-util-backup-spec-test")
@@ -114,15 +107,15 @@ describe Chef::Util::Backup do
describe "backup_filename" do
it "should return a timestamped path" do
@backup.should_receive(:path).and_return('/a/b/c.txt')
- @backup.send(:backup_filename).should =~ %r|^/a/b/c.txt.chef-\d{14}$|
+ @backup.send(:backup_filename).should =~ %r|^/a/b/c.txt.chef-\d{14}.\d{6}$|
end
it "should strip the drive letter off for windows" do
@backup.should_receive(:path).and_return('c:\a\b\c.txt')
- @backup.send(:backup_filename).should =~ %r|^\\a\\b\\c.txt.chef-\d{14}$|
+ @backup.send(:backup_filename).should =~ %r|^\\a\\b\\c.txt.chef-\d{14}.\d{6}$|
end
it "should strip the drive letter off for windows (with forwardslashes)" do
@backup.should_receive(:path).and_return('c:/a/b/c.txt')
- @backup.send(:backup_filename).should =~ %r|^/a/b/c.txt.chef-\d{14}$|
+ @backup.send(:backup_filename).should =~ %r|^/a/b/c.txt.chef-\d{14}.\d{6}$|
end
end
@@ -130,19 +123,19 @@ describe Chef::Util::Backup do
it "uses the file's directory when Chef::Config[:file_backup_path] is nil" do
@backup.should_receive(:path).and_return('/a/b/c.txt')
Chef::Config[:file_backup_path] = nil
- @backup.send(:backup_path).should =~ %r|^/a/b/c.txt.chef-\d{14}$|
+ @backup.send(:backup_path).should =~ %r|^/a/b/c.txt.chef-\d{14}.\d{6}$|
end
it "uses the configured Chef::Config[:file_backup_path]" do
@backup.should_receive(:path).and_return('/a/b/c.txt')
Chef::Config[:file_backup_path] = '/backupdir'
- @backup.send(:backup_path).should =~ %r|^/backupdir[\\/]+a/b/c.txt.chef-\d{14}$|
+ @backup.send(:backup_path).should =~ %r|^/backupdir[\\/]+a/b/c.txt.chef-\d{14}.\d{6}$|
end
it "uses the configured Chef::Config[:file_backup_path] and strips the drive on windows" do
@backup.should_receive(:path).and_return('c:\\a\\b\\c.txt')
Chef::Config[:file_backup_path] = 'c:\backupdir'
- @backup.send(:backup_path).should =~ %r|^c:\\backupdir[\\/]+a\\b\\c.txt.chef-\d{14}$|
+ @backup.send(:backup_path).should =~ %r|^c:\\backupdir[\\/]+a\\b\\c.txt.chef-\d{14}.\d{6}$|
end
end
diff --git a/spec/unit/util/diff_spec.rb b/spec/unit/util/diff_spec.rb
index 2dadb5be56..0e3bc0a0d7 100644
--- a/spec/unit/util/diff_spec.rb
+++ b/spec/unit/util/diff_spec.rb
@@ -21,14 +21,6 @@ require 'spec_helper'
require 'tmpdir'
describe Chef::Util::Diff, :uses_diff => true do
- before(:all) do
- @original_config = Chef::Config.hash_dup
- end
-
- after(:all) do
- Chef::Config.configuration = @original_config if @original_config
- end
-
let!(:old_tempfile) { Tempfile.new("chef-util-diff-spec") }
let!(:new_tempfile) { Tempfile.new("chef-util-diff-spec") }
let!(:old_file) { old_tempfile.path }
@@ -393,37 +385,6 @@ describe Chef::Util::Diff, :uses_diff => true do
end
end
- describe "when errors are thrown from shell_out" do
- before do
- differ.stub!(:shell_out).and_raise('boom')
- differ.diff(old_file, new_file)
- end
-
- it "calling for_output should return the error message" do
- expect(differ.for_output).to eql(["Could not determine diff. Error: boom"])
- end
-
- it "calling for_reporting should be nil" do
- expect(differ.for_reporting).to be_nil
- end
- end
-
- describe "when shell_out returns stderr output" do
- before do
- @result = mock('result', :stdout => "", :stderr => "boom")
- differ.stub!(:shell_out).and_return(@result)
- differ.diff(old_file, new_file)
- end
-
- it "calling for_output should return the error message" do
- expect(differ.for_output).to eql(["Could not determine diff. Error: boom"])
- end
-
- it "calling for_reporting should be nil" do
- expect(differ.for_reporting).to be_nil
- end
- end
-
describe "when checking if files are binary or text" do
it "should identify zero-length files as text" do
diff --git a/spec/unit/version/platform_spec.rb b/spec/unit/version/platform_spec.rb
index 6245800f9d..8b5b3503dc 100644
--- a/spec/unit/version/platform_spec.rb
+++ b/spec/unit/version/platform_spec.rb
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,7 +28,7 @@ describe Chef::Version::Platform do
it "should transform 1 to 1.0.0" do
Chef::Version::Platform.new("1").to_s.should == "1.0.0"
end
-
+
describe "when creating valid Versions" do
good_versions = %w(1 1.2 1.2.3 1000.80.50000 0.300.25 001.02.00003)
good_versions.each do |v|
diff --git a/spec/unit/version_class_spec.rb b/spec/unit/version_class_spec.rb
index 285588b031..b0fcfbb3fb 100644
--- a/spec/unit/version_class_spec.rb
+++ b/spec/unit/version_class_spec.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,12 +28,12 @@ describe Chef::Version do
@v0.to_s.should == "0.0.0"
@v123.to_s.should == "1.2.3"
end
-
+
it "should make a round trip with its string representation" do
a = Chef::Version.new(@v123.to_s)
a.should == @v123
end
-
+
it "should transform 1.2 to 1.2.0" do
Chef::Version.new("1.2").to_s.should == "1.2.0"
end
@@ -118,7 +118,7 @@ describe Chef::Version do
end
describe "comparison examples" do
- [
+ [
[ "0.0.0", :>, "0.0.0", false ],
[ "0.0.0", :>=, "0.0.0", true ],
[ "0.0.0", :==, "0.0.0", true ],
diff --git a/spec/unit/version_constraint/platform_spec.rb b/spec/unit/version_constraint/platform_spec.rb
index a7749102f0..a3599aeb96 100644
--- a/spec/unit/version_constraint/platform_spec.rb
+++ b/spec/unit/version_constraint/platform_spec.rb
@@ -5,9 +5,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/spec/unit/windows_service_spec.rb b/spec/unit/windows_service_spec.rb
new file mode 100644
index 0000000000..ba3d2980df
--- /dev/null
+++ b/spec/unit/windows_service_spec.rb
@@ -0,0 +1,54 @@
+#
+# Author:: Mukta Aphale (<mukta.aphale@clogeny.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+require 'spec_helper'
+if Chef::Platform.windows?
+ require 'chef/application/windows_service'
+end
+
+describe "Chef::Application::WindowsService", :windows_only do
+ let (:instance) {Chef::Application::WindowsService.new}
+ let (:shell_out_result) {Object.new}
+ let (:tempfile) {Tempfile.new "log_file"}
+ before do
+ instance.stub(:parse_options)
+ shell_out_result.stub(:stdout)
+ shell_out_result.stub(:stderr)
+ end
+ it "runs chef-client in new process" do
+ instance.should_receive(:configure_chef).twice
+ instance.service_init
+ instance.should_receive(:run_chef_client).and_call_original
+ instance.should_receive(:shell_out).and_return(shell_out_result)
+ instance.stub(:running?).and_return(true, false)
+ instance.instance_variable_get(:@service_signal).stub(:wait)
+ instance.stub(:state).and_return(4)
+ instance.service_main
+ end
+ it "passes config params to new process" do
+ Chef::Config.merge!({:log_location => tempfile.path, :config_file => "test_config_file", :log_level => :info})
+ instance.should_receive(:configure_chef).twice
+ instance.service_init
+ instance.stub(:running?).and_return(true, false)
+ instance.instance_variable_get(:@service_signal).stub(:wait)
+ instance.stub(:state).and_return(4)
+ instance.should_receive(:run_chef_client).and_call_original
+ instance.should_receive(:shell_out).with("chef-client --no-fork -c test_config_file -L #{tempfile.path}").and_return(shell_out_result)
+ instance.service_main
+ tempfile.unlink
+ end
+end