summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <tmay@expedia.com>2014-03-04 11:18:05 +0000
committerThom May <tmay@expedia.com>2014-03-04 11:18:05 +0000
commit423651d9ca1d20855fac93ca374a0f555bc70a85 (patch)
tree1b260a1b84e24de5b3a0223c6afa916451af220f
parentac7fcb41da4bbed8b2d02ae872b40639dfeb53c4 (diff)
parentad6abcc84a0bd9bd47b636f7004588510615c188 (diff)
downloadchef-423651d9ca1d20855fac93ca374a0f555bc70a85.tar.gz
Merge remote-tracking branch 'origin/master' into save-right-run-list
Conflicts: lib/chef/client.rb
-rw-r--r--.travis.yml22
-rw-r--r--CHANGELOG.md16
-rw-r--r--CHEF_MVPS.md84
-rw-r--r--CONTRIBUTING.md36
-rw-r--r--CONTRIBUTIONS.md10
-rw-r--r--DOC_CHANGES.md18
-rw-r--r--Gemfile24
-rw-r--r--README.md93
-rw-r--r--RELEASE_NOTES.md12
-rw-r--r--Rakefile88
-rwxr-xr-xbin/chef-apply4
-rwxr-xr-xbin/chef-client4
-rwxr-xr-xbin/chef-service-manager4
-rwxr-xr-xbin/chef-solo4
-rwxr-xr-xbin/knife6
-rw-r--r--chef-x86-mingw32.gemspec18
-rw-r--r--chef.gemspec41
-rw-r--r--ci/jenkins_run_tests.bat15
-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/_sources/ctl_chef_client.txt36
-rw-r--r--distro/common/html/_sources/ctl_chef_server.txt26
-rw-r--r--distro/common/html/_sources/ctl_chef_shell.txt15
-rw-r--r--distro/common/html/_sources/ctl_chef_solo.txt25
-rw-r--r--distro/common/html/_sources/index.txt126
-rw-r--r--distro/common/html/_sources/knife.txt74
-rw-r--r--distro/common/html/_sources/knife_bootstrap.txt56
-rw-r--r--distro/common/html/_sources/knife_client.txt151
-rw-r--r--distro/common/html/_sources/knife_common_options.txt6
-rw-r--r--distro/common/html/_sources/knife_configure.txt29
-rw-r--r--distro/common/html/_sources/knife_cookbook.txt236
-rw-r--r--distro/common/html/_sources/knife_cookbook_site.txt157
-rw-r--r--distro/common/html/_sources/knife_data_bag.txt160
-rw-r--r--distro/common/html/_sources/knife_delete.txt26
-rw-r--r--distro/common/html/_sources/knife_deps.txt61
-rw-r--r--distro/common/html/_sources/knife_diff.txt34
-rw-r--r--distro/common/html/_sources/knife_download.txt44
-rw-r--r--distro/common/html/_sources/knife_edit.txt26
-rw-r--r--distro/common/html/_sources/knife_environment.txt158
-rw-r--r--distro/common/html/_sources/knife_exec.txt47
-rw-r--r--distro/common/html/_sources/knife_index_rebuild.txt21
-rw-r--r--distro/common/html/_sources/knife_list.txt33
-rw-r--r--distro/common/html/_sources/knife_node.txt250
-rw-r--r--distro/common/html/_sources/knife_raw.txt35
-rw-r--r--distro/common/html/_sources/knife_recipe_list.txt23
-rw-r--r--distro/common/html/_sources/knife_role.txt157
-rw-r--r--distro/common/html/_sources/knife_search.txt53
-rw-r--r--distro/common/html/_sources/knife_show.txt27
-rw-r--r--distro/common/html/_sources/knife_ssh.txt43
-rw-r--r--distro/common/html/_sources/knife_status.txt37
-rw-r--r--distro/common/html/_sources/knife_tag.txt69
-rw-r--r--distro/common/html/_sources/knife_upload.txt49
-rw-r--r--distro/common/html/_sources/knife_user.txt127
-rw-r--r--distro/common/html/_sources/knife_using.txt43
-rw-r--r--distro/common/html/_sources/knife_xargs.txt30
-rw-r--r--distro/common/html/_static/ajax-loader.gifbin0 -> 673 bytes
-rw-r--r--distro/common/html/_static/basic.css540
-rw-r--r--distro/common/html/_static/chef.css507
-rw-r--r--distro/common/html/_static/chef.icobin0 -> 1150 bytes
-rw-r--r--distro/common/html/_static/chef_html_logo.pngbin0 -> 57548 bytes
-rw-r--r--distro/common/html/_static/chef_logo.pngbin0 -> 65882 bytes
-rw-r--r--distro/common/html/_static/comment-bright.pngbin0 -> 3500 bytes
-rw-r--r--distro/common/html/_static/comment-close.pngbin0 -> 3578 bytes
-rw-r--r--distro/common/html/_static/comment.pngbin0 -> 3445 bytes
-rw-r--r--distro/common/html/_static/contents.pngbin0 -> 202 bytes
-rw-r--r--distro/common/html/_static/doctools.js247
-rw-r--r--distro/common/html/_static/down-pressed.pngbin0 -> 368 bytes
-rw-r--r--distro/common/html/_static/down.pngbin0 -> 363 bytes
-rw-r--r--distro/common/html/_static/file.pngbin0 -> 392 bytes
-rw-r--r--distro/common/html/_static/guide.css505
-rw-r--r--distro/common/html/_static/jquery.js154
-rw-r--r--distro/common/html/_static/minus.pngbin0 -> 199 bytes
-rw-r--r--distro/common/html/_static/navigation.pngbin0 -> 218 bytes
-rw-r--r--distro/common/html/_static/plus.pngbin0 -> 199 bytes
-rw-r--r--distro/common/html/_static/pygments.css62
-rw-r--r--distro/common/html/_static/searchtools.js560
-rw-r--r--distro/common/html/_static/underscore.js23
-rw-r--r--distro/common/html/_static/up-pressed.pngbin0 -> 372 bytes
-rw-r--r--distro/common/html/_static/up.pngbin0 -> 363 bytes
-rw-r--r--distro/common/html/_static/websupport.js808
-rw-r--r--distro/common/html/chef-client.8.html145
-rw-r--r--distro/common/html/chef-expander.8.html164
-rw-r--r--distro/common/html/chef-expanderctl.8.html146
-rw-r--r--distro/common/html/chef-server-webui.8.html185
-rw-r--r--distro/common/html/chef-server.8.html182
-rw-r--r--distro/common/html/chef-shell.1.html286
-rw-r--r--distro/common/html/chef-solo.8.html185
-rw-r--r--distro/common/html/chef-solr.8.html165
-rw-r--r--distro/common/html/ctl_chef_client.html219
-rw-r--r--distro/common/html/ctl_chef_server.html111
-rw-r--r--distro/common/html/ctl_chef_shell.html120
-rw-r--r--distro/common/html/ctl_chef_solo.html144
-rw-r--r--distro/common/html/index.html185
-rw-r--r--distro/common/html/knife-bootstrap.1.html241
-rw-r--r--distro/common/html/knife-client.1.html219
-rw-r--r--distro/common/html/knife-configure.1.html170
-rw-r--r--distro/common/html/knife-cookbook-site.1.html241
-rw-r--r--distro/common/html/knife-cookbook.1.html381
-rw-r--r--distro/common/html/knife-data-bag.1.html235
-rw-r--r--distro/common/html/knife-environment.1.html265
-rw-r--r--distro/common/html/knife-exec.1.html134
-rw-r--r--distro/common/html/knife-index.1.html125
-rw-r--r--distro/common/html/knife-node.1.html250
-rw-r--r--distro/common/html/knife-role.1.html200
-rw-r--r--distro/common/html/knife-search.1.html288
-rw-r--r--distro/common/html/knife-ssh.1.html156
-rw-r--r--distro/common/html/knife-status.1.html128
-rw-r--r--distro/common/html/knife-tag.1.html137
-rw-r--r--distro/common/html/knife.1.html315
-rw-r--r--distro/common/html/knife.html172
-rw-r--r--distro/common/html/knife_bootstrap.html250
-rw-r--r--distro/common/html/knife_client.html283
-rw-r--r--distro/common/html/knife_common_options.html98
-rw-r--r--distro/common/html/knife_configure.html107
-rw-r--r--distro/common/html/knife_cookbook.html481
-rw-r--r--distro/common/html/knife_cookbook_site.html372
-rw-r--r--distro/common/html/knife_data_bag.html359
-rw-r--r--distro/common/html/knife_delete.html95
-rw-r--r--distro/common/html/knife_deps.html145
-rw-r--r--distro/common/html/knife_diff.html125
-rw-r--r--distro/common/html/knife_download.html147
-rw-r--r--distro/common/html/knife_edit.html91
-rw-r--r--distro/common/html/knife_environment.html328
-rw-r--r--distro/common/html/knife_exec.html222
-rw-r--r--distro/common/html/knife_index_rebuild.html85
-rw-r--r--distro/common/html/knife_list.html116
-rw-r--r--distro/common/html/knife_node.html450
-rw-r--r--distro/common/html/knife_raw.html112
-rw-r--r--distro/common/html/knife_recipe_list.html93
-rw-r--r--distro/common/html/knife_role.html295
-rw-r--r--distro/common/html/knife_search.html204
-rw-r--r--distro/common/html/knife_show.html106
-rw-r--r--distro/common/html/knife_ssh.html179
-rw-r--r--distro/common/html/knife_status.html142
-rw-r--r--distro/common/html/knife_tag.html140
-rw-r--r--distro/common/html/knife_upload.html155
-rw-r--r--distro/common/html/knife_user.html244
-rw-r--r--distro/common/html/knife_using.html211
-rw-r--r--distro/common/html/knife_xargs.html115
-rw-r--r--distro/common/html/objects.invbin0 -> 214 bytes
-rw-r--r--distro/common/html/search.html84
-rw-r--r--distro/common/html/searchindex.js1
-rw-r--r--distro/common/man/man1/README.md58
-rw-r--r--distro/common/man/man1/chef-shell.1333
-rw-r--r--distro/common/man/man1/knife-bootstrap.1351
-rw-r--r--distro/common/man/man1/knife-client.1438
-rw-r--r--distro/common/man/man1/knife-configure.1227
-rw-r--r--distro/common/man/man1/knife-cookbook-site.1587
-rw-r--r--distro/common/man/man1/knife-cookbook.1941
-rw-r--r--distro/common/man/man1/knife-data-bag.1572
-rw-r--r--distro/common/man/man1/knife-delete.1123
-rw-r--r--distro/common/man/man1/knife-deps.1202
-rw-r--r--distro/common/man/man1/knife-diff.1206
-rw-r--r--distro/common/man/man1/knife-download.1214
-rw-r--r--distro/common/man/man1/knife-edit.1117
-rw-r--r--distro/common/man/man1/knife-environment.1560
-rw-r--r--distro/common/man/man1/knife-exec.1329
-rw-r--r--distro/common/man/man1/knife-index-rebuild.155
-rw-r--r--distro/common/man/man1/knife-index.129
-rw-r--r--distro/common/man/man1/knife-list.1158
-rw-r--r--distro/common/man/man1/knife-node.1677
-rw-r--r--distro/common/man/man1/knife-raw.1152
-rw-r--r--distro/common/man/man1/knife-recipe-list.173
-rw-r--r--distro/common/man/man1/knife-role.1432
-rw-r--r--distro/common/man/man1/knife-search.1507
-rw-r--r--distro/common/man/man1/knife-show.1144
-rw-r--r--distro/common/man/man1/knife-ssh.1297
-rw-r--r--distro/common/man/man1/knife-status.1217
-rw-r--r--distro/common/man/man1/knife-tag.1204
-rw-r--r--distro/common/man/man1/knife-upload.1228
-rw-r--r--distro/common/man/man1/knife-user.1300
-rw-r--r--distro/common/man/man1/knife-xargs.1155
-rw-r--r--distro/common/man/man1/knife.1511
-rw-r--r--distro/common/man/man8/chef-client.8331
-rw-r--r--distro/common/man/man8/chef-expander.897
-rw-r--r--distro/common/man/man8/chef-expanderctl.862
-rw-r--r--distro/common/man/man8/chef-server-webui.8155
-rw-r--r--distro/common/man/man8/chef-server.8147
-rw-r--r--distro/common/man/man8/chef-solo.8261
-rw-r--r--distro/common/man/man8/chef-solr.8122
-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.rb2
-rw-r--r--lib/chef/api_client.rb29
-rw-r--r--lib/chef/application.rb89
-rw-r--r--lib/chef/application/agent.rb4
-rw-r--r--lib/chef/application/apply.rb6
-rw-r--r--lib/chef/application/client.rb74
-rw-r--r--lib/chef/application/knife.rb12
-rw-r--r--lib/chef/application/solo.rb35
-rw-r--r--lib/chef/application/windows_service.rb63
-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.rb261
-rw-r--r--lib/chef/config.rb444
-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.rb135
-rw-r--r--lib/chef/cookbook_site_streaming_uploader.rb12
-rw-r--r--lib/chef/cookbook_uploader.rb39
-rw-r--r--lib/chef/daemon.rb89
-rw-r--r--lib/chef/data_bag.rb7
-rw-r--r--lib/chef/data_bag_item.rb2
-rw-r--r--lib/chef/dsl/include_recipe.rb4
-rw-r--r--lib/chef/dsl/reboot_pending.rb61
-rw-r--r--lib/chef/dsl/recipe.rb146
-rw-r--r--lib/chef/encrypted_data_bag_item.rb309
-rw-r--r--lib/chef/encrypted_data_bag_item/decryption_failure.rb22
-rw-r--r--lib/chef/encrypted_data_bag_item/decryptor.rb201
-rw-r--r--lib/chef/encrypted_data_bag_item/encryptor.rb142
-rw-r--r--lib/chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format.rb22
-rw-r--r--lib/chef/encrypted_data_bag_item/unsupported_cipher.rb22
-rw-r--r--lib/chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format.rb22
-rw-r--r--lib/chef/event_dispatch/base.rb2
-rw-r--r--lib/chef/event_dispatch/dispatcher.rb2
-rw-r--r--lib/chef/exceptions.rb18
-rw-r--r--lib/chef/formatters/doc.rb47
-rw-r--r--lib/chef/formatters/error_inspectors/api_error_formatting.rb7
-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.rb396
-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.rb93
-rw-r--r--lib/chef/http/basic_client.rb118
-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.rb59
-rw-r--r--lib/chef/http/decompressor.rb141
-rw-r--r--lib/chef/http/http_request.rb (renamed from lib/chef/rest/rest_request.rb)94
-rw-r--r--lib/chef/http/json_input.rb57
-rw-r--r--lib/chef/http/json_output.rb73
-rw-r--r--lib/chef/http/json_to_model_output.rb34
-rw-r--r--lib/chef/http/remote_request_id.rb46
-rw-r--r--lib/chef/http/simple.rb16
-rw-r--r--lib/chef/http/ssl_policies.rb129
-rw-r--r--lib/chef/http/validate_content_length.rb94
-rw-r--r--lib/chef/knife.rb76
-rw-r--r--lib/chef/knife/bootstrap.rb13
-rw-r--r--lib/chef/knife/bootstrap/README.md12
-rw-r--r--lib/chef/knife/bootstrap/chef-full.erb11
-rw-r--r--lib/chef/knife/client_create.rb8
-rw-r--r--lib/chef/knife/client_delete.rb16
-rw-r--r--lib/chef/knife/configure.rb12
-rw-r--r--lib/chef/knife/cookbook_create.rb18
-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_share.rb4
-rw-r--r--lib/chef/knife/cookbook_site_show.rb10
-rw-r--r--lib/chef/knife/cookbook_upload.rb8
-rw-r--r--lib/chef/knife/core/bootstrap_context.rb10
-rw-r--r--lib/chef/knife/core/node_editor.rb52
-rw-r--r--lib/chef/knife/core/subcommand_loader.rb66
-rw-r--r--lib/chef/knife/core/ui.rb22
-rw-r--r--lib/chef/knife/data_bag_create.rb19
-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.rb13
-rw-r--r--lib/chef/knife/environment_compare.rb127
-rw-r--r--lib/chef/knife/environment_from_file.rb4
-rw-r--r--lib/chef/knife/help_topics.rb2
-rw-r--r--lib/chef/knife/index_rebuild.rb4
-rw-r--r--lib/chef/knife/list.rb2
-rw-r--r--lib/chef/knife/raw.rb37
-rw-r--r--lib/chef/knife/show.rb2
-rw-r--r--lib/chef/knife/ssh.rb42
-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.rb71
-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.rb12
-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/path_sanity.rb1
-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/net_http.rb34
-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/monkey_patches/uri.rb70
-rw-r--r--lib/chef/monologger.rb3
-rw-r--r--lib/chef/node.rb17
-rw-r--r--lib/chef/node/attribute.rb2
-rw-r--r--lib/chef/platform/provider_mapping.rb25
-rw-r--r--lib/chef/policy_builder.rb49
-rw-r--r--lib/chef/policy_builder/expand_node_object.rb237
-rw-r--r--lib/chef/policy_builder/policyfile.rb344
-rw-r--r--lib/chef/provider.rb6
-rw-r--r--lib/chef/provider/batch.rb6
-rw-r--r--lib/chef/provider/cookbook_file.rb8
-rw-r--r--lib/chef/provider/cron.rb8
-rw-r--r--lib/chef/provider/cron/solaris.rb2
-rw-r--r--lib/chef/provider/cron/unix.rb2
-rw-r--r--lib/chef/provider/deploy/timestamped.rb8
-rw-r--r--lib/chef/provider/directory.rb7
-rw-r--r--lib/chef/provider/erl_call.rb2
-rw-r--r--lib/chef/provider/execute.rb4
-rw-r--r--lib/chef/provider/file.rb42
-rw-r--r--lib/chef/provider/git.rb29
-rw-r--r--lib/chef/provider/group.rb87
-rw-r--r--lib/chef/provider/group/dscl.rb48
-rw-r--r--lib/chef/provider/group/gpasswd.rb43
-rw-r--r--lib/chef/provider/group/groupadd.rb63
-rw-r--r--lib/chef/provider/group/groupmod.rb82
-rw-r--r--lib/chef/provider/group/pw.rb97
-rw-r--r--lib/chef/provider/group/suse.rb37
-rw-r--r--lib/chef/provider/group/usermod.rb67
-rw-r--r--lib/chef/provider/group/windows.rb47
-rw-r--r--lib/chef/provider/http_request.rb21
-rw-r--r--lib/chef/provider/ifconfig.rb18
-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.rb12
-rw-r--r--lib/chef/provider/mount/mount.rb38
-rw-r--r--lib/chef/provider/package.rb7
-rw-r--r--lib/chef/provider/package/aix.rb146
-rw-r--r--lib/chef/provider/package/apt.rb3
-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.rb8
-rw-r--r--lib/chef/provider/remote_file/cache_control_data.rb5
-rw-r--r--lib/chef/provider/remote_file/ftp.rb1
-rw-r--r--lib/chef/provider/remote_file/http.rb19
-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.rb57
-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/template.rb8
-rw-r--r--lib/chef/provider/user.rb28
-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.rb9
-rw-r--r--lib/chef/provider/user/windows.rb14
-rw-r--r--lib/chef/provider/whyrun_safe_ruby_block.rb30
-rw-r--r--lib/chef/provider/windows_script.rb14
-rw-r--r--lib/chef/providers.rb2
-rw-r--r--lib/chef/recipe.rb23
-rw-r--r--lib/chef/request_id.rb37
-rw-r--r--lib/chef/resource.rb2
-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.rb37
-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/file.rb9
-rw-r--r--lib/chef/resource/freebsd_package.rb8
-rw-r--r--lib/chef/resource/group.rb32
-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/package.rb9
-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.rb30
-rw-r--r--lib/chef/resource/script.rb10
-rw-r--r--lib/chef/resource/service.rb11
-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/whyrun_safe_ruby_block.rb31
-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_platform_map.rb2
-rw-r--r--lib/chef/resource_reporter.rb25
-rw-r--r--lib/chef/resources.rb3
-rw-r--r--lib/chef/rest.rb421
-rw-r--r--lib/chef/role.rb30
-rw-r--r--lib/chef/run_context.rb13
-rw-r--r--lib/chef/run_context/cookbook_compiler.rb6
-rw-r--r--lib/chef/run_lock.rb93
-rw-r--r--lib/chef/run_status.rb5
-rw-r--r--lib/chef/server_api.rb43
-rw-r--r--lib/chef/shell.rb22
-rw-r--r--lib/chef/shell/ext.rb2
-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.rb75
-rw-r--r--lib/chef/util/file_edit.rb2
-rw-r--r--lib/chef/util/windows.rb4
-rw-r--r--lib/chef/util/windows/net_group.rb21
-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.rb7
-rw-r--r--lib/chef/win32/api/synchronization.rb89
-rw-r--r--lib/chef/win32/handle.rb2
-rw-r--r--lib/chef/win32/mutex.rb117
-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.rb53
-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/templates/default/preseed-template-variables.seed1
-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/dsl/reboot_pending_spec.rb118
-rw-r--r--spec/functional/knife/cookbook_delete_spec.rb27
-rw-r--r--spec/functional/knife/exec_spec.rb3
-rw-r--r--spec/functional/knife/ssh_spec.rb10
-rwxr-xr-xspec/functional/provider/remote_file/cache_control_data_spec.rb101
-rw-r--r--spec/functional/resource/base.rb3
-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.rb4
-rw-r--r--spec/functional/resource/file_spec.rb1
-rw-r--r--spec/functional/resource/group_spec.rb423
-rw-r--r--spec/functional/resource/link_spec.rb20
-rw-r--r--spec/functional/resource/mount_spec.rb84
-rw-r--r--spec/functional/resource/package_spec.rb19
-rw-r--r--spec/functional/resource/powershell_spec.rb43
-rw-r--r--spec/functional/resource/registry_spec.rb43
-rw-r--r--spec/functional/resource/remote_file_spec.rb14
-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.rb7
-rw-r--r--spec/functional/run_lock_spec.rb55
-rw-r--r--spec/functional/shell_spec.rb72
-rw-r--r--spec/functional/tiny_server_spec.rb4
-rw-r--r--spec/functional/version_spec.rb35
-rw-r--r--spec/functional/win32/versions_spec.rb45
-rw-r--r--spec/integration/client/client_spec.rb233
-rw-r--r--spec/integration/client/ipv6_spec.rb133
-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/cookbook_api_ipv6_spec.rb111
-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.rb119
-rw-r--r--spec/scripts/ssl-serve.rb52
-rw-r--r--spec/spec_helper.rb41
-rw-r--r--spec/stress/win32/file_spec.rb6
-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/chef/resource/zen_master.rb3
-rw-r--r--spec/support/mock/platform.rb2
-rw-r--r--spec/support/platform_helpers.rb37
-rw-r--r--spec/support/shared/functional/file_resource.rb187
-rw-r--r--spec/support/shared/functional/securable_resource.rb4
-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/api_error_inspector.rb14
-rw-r--r--spec/support/shared/unit/provider/file.rb271
-rw-r--r--spec/support/shared/unit/provider/useradd_based_user_provider.rb62
-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.rb12
-rw-r--r--spec/unit/api_client_spec.rb77
-rw-r--r--spec/unit/application/apply.rb22
-rw-r--r--spec/unit/application/client_spec.rb67
-rw-r--r--spec/unit/application/knife_spec.rb10
-rw-r--r--spec/unit/application/solo_spec.rb86
-rw-r--r--spec/unit/application_spec.rb172
-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.rb573
-rw-r--r--spec/unit/config_fetcher_spec.rb98
-rw-r--r--spec/unit/config_spec.rb184
-rw-r--r--spec/unit/cookbook/metadata_spec.rb144
-rw-r--r--spec/unit/cookbook/synchronizer_spec.rb40
-rw-r--r--spec/unit/cookbook/syntax_check_spec.rb4
-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_spec.rb1
-rw-r--r--spec/unit/daemon_spec.rb175
-rw-r--r--spec/unit/data_bag_item_spec.rb32
-rw-r--r--spec/unit/data_bag_spec.rb30
-rw-r--r--spec/unit/deprecation_spec.rb2
-rw-r--r--spec/unit/digester_spec.rb4
-rw-r--r--spec/unit/dsl/data_query_spec.rb2
-rw-r--r--spec/unit/dsl/reboot_pending_spec.rb100
-rw-r--r--spec/unit/dsl/recipe_spec.rb70
-rw-r--r--spec/unit/encrypted_data_bag_item_spec.rb65
-rw-r--r--spec/unit/environment_spec.rb10
-rw-r--r--spec/unit/file_access_control_spec.rb10
-rw-r--r--spec/unit/file_cache_spec.rb4
-rw-r--r--spec/unit/file_content_management/deploy/mv_unix_spec.rb2
-rw-r--r--spec/unit/file_content_management/deploy/mv_windows_spec.rb24
-rw-r--r--spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb16
-rw-r--r--spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb12
-rw-r--r--spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb6
-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.rb25
-rw-r--r--spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb12
-rw-r--r--spec/unit/handler/json_file_spec.rb2
-rw-r--r--spec/unit/handler_spec.rb16
-rw-r--r--spec/unit/http/ssl_policies_spec.rb170
-rw-r--r--spec/unit/http_spec.rb48
-rw-r--r--spec/unit/knife/bootstrap_spec.rb79
-rw-r--r--spec/unit/knife/client_bulk_delete_spec.rb24
-rw-r--r--spec/unit/knife/client_create_spec.rb48
-rw-r--r--spec/unit/knife/client_delete_spec.rb49
-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.rb8
-rw-r--r--spec/unit/knife/client_show_spec.rb6
-rw-r--r--spec/unit/knife/config_file_selection_spec.rb67
-rw-r--r--spec/unit/knife/configure_client_spec.rb8
-rw-r--r--spec/unit/knife/configure_spec.rb38
-rw-r--r--spec/unit/knife/cookbook_bulk_delete_spec.rb20
-rw-r--r--spec/unit/knife/cookbook_create_spec.rb23
-rw-r--r--spec/unit/knife/cookbook_delete_spec.rb12
-rw-r--r--spec/unit/knife/cookbook_download_spec.rb20
-rw-r--r--spec/unit/knife/cookbook_list_spec.rb6
-rw-r--r--spec/unit/knife/cookbook_metadata_from_file_spec.rb8
-rw-r--r--spec/unit/knife/cookbook_metadata_spec.rb16
-rw-r--r--spec/unit/knife/cookbook_show_spec.rb14
-rw-r--r--spec/unit/knife/cookbook_site_download_spec.rb6
-rw-r--r--spec/unit/knife/cookbook_site_install_spec.rb18
-rw-r--r--spec/unit/knife/cookbook_site_share_spec.rb44
-rw-r--r--spec/unit/knife/cookbook_site_unshare_spec.rb16
-rw-r--r--spec/unit/knife/cookbook_test_spec.rb14
-rw-r--r--spec/unit/knife/cookbook_upload_spec.rb48
-rw-r--r--spec/unit/knife/core/bootstrap_context_spec.rb12
-rw-r--r--spec/unit/knife/core/cookbook_scm_repo_spec.rb12
-rw-r--r--spec/unit/knife/core/object_loader_spec.rb2
-rw-r--r--spec/unit/knife/core/subcommand_loader_spec.rb82
-rw-r--r--spec/unit/knife/core/ui_spec.rb156
-rw-r--r--spec/unit/knife/data_bag_create_spec.rb15
-rw-r--r--spec/unit/knife/data_bag_edit_spec.rb14
-rw-r--r--spec/unit/knife/data_bag_from_file_spec.rb30
-rw-r--r--spec/unit/knife/data_bag_show_spec.rb14
-rw-r--r--spec/unit/knife/environment_compare_spec.rb112
-rw-r--r--spec/unit/knife/environment_create_spec.rb12
-rw-r--r--spec/unit/knife/environment_delete_spec.rb12
-rw-r--r--spec/unit/knife/environment_edit_spec.rb10
-rw-r--r--spec/unit/knife/environment_from_file_spec.rb18
-rw-r--r--spec/unit/knife/environment_list_spec.rb8
-rw-r--r--spec/unit/knife/environment_show_spec.rb8
-rw-r--r--spec/unit/knife/index_rebuild_spec.rb6
-rw-r--r--spec/unit/knife/knife_help.rb22
-rw-r--r--spec/unit/knife/node_bulk_delete_spec.rb8
-rw-r--r--spec/unit/knife/node_delete_spec.rb16
-rw-r--r--spec/unit/knife/node_edit_spec.rb45
-rw-r--r--spec/unit/knife/node_from_file_spec.rb10
-rw-r--r--spec/unit/knife/node_list_spec.rb12
-rw-r--r--spec/unit/knife/node_run_list_add_spec.rb12
-rw-r--r--spec/unit/knife/node_run_list_remove_spec.rb8
-rw-r--r--spec/unit/knife/node_run_list_set_spec.rb10
-rw-r--r--spec/unit/knife/node_show_spec.rb10
-rw-r--r--spec/unit/knife/role_bulk_delete_spec.rb8
-rw-r--r--spec/unit/knife/role_create_spec.rb16
-rw-r--r--spec/unit/knife/role_delete_spec.rb16
-rw-r--r--spec/unit/knife/role_edit_spec.rb10
-rw-r--r--spec/unit/knife/role_from_file_spec.rb10
-rw-r--r--spec/unit/knife/role_list_spec.rb8
-rw-r--r--spec/unit/knife/ssh_spec.rb128
-rw-r--r--spec/unit/knife/status_spec.rb8
-rw-r--r--spec/unit/knife/tag_create_spec.rb6
-rw-r--r--spec/unit/knife/tag_delete_spec.rb6
-rw-r--r--spec/unit/knife/tag_list_spec.rb4
-rw-r--r--spec/unit/knife/user_create_spec.rb14
-rw-r--r--spec/unit/knife/user_reregister_spec.rb6
-rw-r--r--spec/unit/knife/user_show_spec.rb2
-rw-r--r--spec/unit/knife_spec.rb122
-rw-r--r--spec/unit/log_spec.rb4
-rw-r--r--spec/unit/lwrp_spec.rb4
-rw-r--r--spec/unit/mash_spec.rb4
-rw-r--r--spec/unit/mixin/checksum_spec.rb10
-rw-r--r--spec/unit/mixin/command_spec.rb4
-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/enforce_ownership_and_permissions_spec.rb8
-rw-r--r--spec/unit/mixin/params_validate_spec.rb176
-rw-r--r--spec/unit/mixin/path_sanity_spec.rb22
-rw-r--r--spec/unit/mixin/securable_spec.rb224
-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/monkey_patches/uri_spec.rb34
-rw-r--r--spec/unit/monologger_spec.rb45
-rw-r--r--spec/unit/node/attribute_spec.rb28
-rw-r--r--spec/unit/node/immutable_collections_spec.rb4
-rw-r--r--spec/unit/node_spec.rb45
-rw-r--r--spec/unit/platform_spec.rb73
-rw-r--r--spec/unit/policy_builder/expand_node_object_spec.rb336
-rw-r--r--spec/unit/policy_builder/policyfile_spec.rb403
-rw-r--r--spec/unit/policy_builder_spec.rb26
-rw-r--r--spec/unit/provider/breakpoint_spec.rb16
-rw-r--r--spec/unit/provider/cookbook_file/content_spec.rb8
-rw-r--r--spec/unit/provider/cookbook_file_spec.rb5
-rw-r--r--spec/unit/provider/cron/unix_spec.rb22
-rw-r--r--spec/unit/provider/cron_spec.rb92
-rw-r--r--spec/unit/provider/deploy/revision_spec.rb23
-rw-r--r--spec/unit/provider/deploy/timestamped_spec.rb16
-rw-r--r--spec/unit/provider/deploy_spec.rb131
-rw-r--r--spec/unit/provider/directory_spec.rb36
-rw-r--r--spec/unit/provider/env_spec.rb30
-rw-r--r--spec/unit/provider/erl_call_spec.rb2
-rw-r--r--spec/unit/provider/execute_spec.rb14
-rw-r--r--spec/unit/provider/file/content_spec.rb18
-rw-r--r--spec/unit/provider/file_spec.rb6
-rw-r--r--spec/unit/provider/git_spec.rb146
-rw-r--r--spec/unit/provider/group/dscl_spec.rb54
-rw-r--r--spec/unit/provider/group/gpasswd_spec.rb40
-rw-r--r--spec/unit/provider/group/groupadd_spec.rb41
-rw-r--r--spec/unit/provider/group/groupmod_spec.rb33
-rw-r--r--spec/unit/provider/group/pw_spec.rb72
-rw-r--r--spec/unit/provider/group/usermod_spec.rb61
-rw-r--r--spec/unit/provider/group/windows_spec.rb41
-rw-r--r--spec/unit/provider/group_spec.rb122
-rw-r--r--spec/unit/provider/http_request_spec.rb56
-rw-r--r--spec/unit/provider/ifconfig/aix_spec.rb22
-rw-r--r--spec/unit/provider/ifconfig/debian_spec.rb122
-rw-r--r--spec/unit/provider/ifconfig/redhat_spec.rb10
-rw-r--r--spec/unit/provider/ifconfig_spec.rb42
-rw-r--r--spec/unit/provider/link_spec.rb70
-rw-r--r--spec/unit/provider/log_spec.rb16
-rw-r--r--spec/unit/provider/mdadm_spec.rb33
-rw-r--r--spec/unit/provider/mount/aix_spec.rb14
-rw-r--r--spec/unit/provider/mount/mount_spec.rb97
-rw-r--r--spec/unit/provider/mount/windows_spec.rb40
-rw-r--r--spec/unit/provider/mount_spec.rb36
-rw-r--r--spec/unit/provider/ohai_spec.rb12
-rw-r--r--spec/unit/provider/package/aix_spec.rb171
-rw-r--r--spec/unit/provider/package/apt_spec.rb40
-rw-r--r--spec/unit/provider/package/dpkg_spec.rb32
-rw-r--r--spec/unit/provider/package/easy_install_spec.rb12
-rw-r--r--spec/unit/provider/package/freebsd_spec.rb82
-rw-r--r--spec/unit/provider/package/ips_spec.rb10
-rw-r--r--spec/unit/provider/package/macports_spec.rb12
-rw-r--r--spec/unit/provider/package/pacman_spec.rb34
-rw-r--r--spec/unit/provider/package/portage_spec.rb36
-rw-r--r--spec/unit/provider/package/rpm_spec.rb44
-rw-r--r--spec/unit/provider/package/rubygems_spec.rb62
-rw-r--r--spec/unit/provider/package/smartos_spec.rb28
-rw-r--r--spec/unit/provider/package/solaris_spec.rb30
-rw-r--r--spec/unit/provider/package/yum_spec.rb200
-rw-r--r--spec/unit/provider/package/zypper_spec.rb20
-rw-r--r--spec/unit/provider/package_spec.rb44
-rw-r--r--spec/unit/provider/powershell_spec.rb6
-rw-r--r--spec/unit/provider/registry_key_spec.rb4
-rw-r--r--spec/unit/provider/remote_directory_spec.rb4
-rw-r--r--spec/unit/provider/remote_file/cache_control_data_spec.rb41
-rw-r--r--spec/unit/provider/remote_file/content_spec.rb62
-rw-r--r--spec/unit/provider/remote_file/fetcher_spec.rb16
-rw-r--r--spec/unit/provider/remote_file/ftp_spec.rb25
-rw-r--r--spec/unit/provider/remote_file/http_spec.rb44
-rw-r--r--spec/unit/provider/remote_file/local_file_spec.rb5
-rw-r--r--spec/unit/provider/remote_file_spec.rb9
-rw-r--r--spec/unit/provider/route_spec.rb50
-rw-r--r--spec/unit/provider/ruby_block_spec.rb4
-rw-r--r--spec/unit/provider/script_spec.rb10
-rw-r--r--spec/unit/provider/service/arch_service_spec.rb114
-rw-r--r--spec/unit/provider/service/debian_service_spec.rb447
-rw-r--r--spec/unit/provider/service/freebsd_service_spec.rb82
-rw-r--r--spec/unit/provider/service/gentoo_service_spec.rb50
-rw-r--r--spec/unit/provider/service/init_service_spec.rb46
-rw-r--r--spec/unit/provider/service/insserv_service_spec.rb18
-rw-r--r--spec/unit/provider/service/invokercd_service_spec.rb42
-rw-r--r--spec/unit/provider/service/macosx_spec.rb40
-rw-r--r--spec/unit/provider/service/redhat_spec.rb42
-rw-r--r--spec/unit/provider/service/simple_service_spec.rb30
-rw-r--r--spec/unit/provider/service/solaris_smf_service_spec.rb34
-rw-r--r--spec/unit/provider/service/systemd_service_spec.rb62
-rw-r--r--spec/unit/provider/service/upstart_service_spec.rb88
-rw-r--r--spec/unit/provider/service/windows_spec.rb78
-rw-r--r--spec/unit/provider/service_spec.rb18
-rw-r--r--spec/unit/provider/subversion_spec.rb74
-rw-r--r--spec/unit/provider/template/content_spec.rb16
-rw-r--r--spec/unit/provider/template_spec.rb10
-rw-r--r--spec/unit/provider/user/dscl_spec.rb60
-rw-r--r--spec/unit/provider/user/pw_spec.rb44
-rw-r--r--spec/unit/provider/user/solaris_spec.rb10
-rw-r--r--spec/unit/provider/user/windows_spec.rb26
-rw-r--r--spec/unit/provider/user_spec.rb142
-rw-r--r--spec/unit/provider/whyrun_safe_ruby_block_spec.rb47
-rw-r--r--spec/unit/provider_spec.rb6
-rw-r--r--spec/unit/recipe_spec.rb301
-rw-r--r--spec/unit/registry_helper_spec.rb4
-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.rb34
-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.rb12
-rw-r--r--spec/unit/resource/dpkg_package_spec.rb12
-rw-r--r--spec/unit/resource/env_spec.rb6
-rw-r--r--spec/unit/resource/erl_call_spec.rb4
-rw-r--r--spec/unit/resource/file_spec.rb16
-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.rb28
-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.rb18
-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.rb12
-rw-r--r--spec/unit/resource/mount_spec.rb32
-rw-r--r--spec/unit/resource/ohai_spec.rb2
-rw-r--r--spec/unit/resource/package_spec.rb17
-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.rb30
-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.rb25
-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.rb30
-rw-r--r--spec/unit/resource/yum_package_spec.rb18
-rw-r--r--spec/unit/resource_collection/stepable_iterator_spec.rb42
-rw-r--r--spec/unit/resource_collection_spec.rb2
-rw-r--r--spec/unit/resource_definition_spec.rb50
-rw-r--r--spec/unit/resource_reporter_spec.rb116
-rw-r--r--spec/unit/resource_spec.rb6
-rw-r--r--spec/unit/rest/auth_credentials_spec.rb103
-rw-r--r--spec/unit/rest_spec.rb679
-rw-r--r--spec/unit/role_spec.rb61
-rw-r--r--spec/unit/run_context/cookbook_compiler_spec.rb6
-rw-r--r--spec/unit/run_context_spec.rb8
-rw-r--r--spec/unit/run_list/run_list_expansion_spec.rb6
-rw-r--r--spec/unit/run_list/run_list_item_spec.rb2
-rw-r--r--spec/unit/run_list_spec.rb18
-rw-r--r--spec/unit/run_lock_spec.rb9
-rw-r--r--spec/unit/run_status_spec.rb2
-rw-r--r--spec/unit/runner_spec.rb16
-rw-r--r--spec/unit/scan_access_control_spec.rb10
-rw-r--r--spec/unit/search/query_spec.rb20
-rw-r--r--spec/unit/shell/model_wrapper_spec.rb4
-rw-r--r--spec/unit/shell/shell_ext_spec.rb30
-rw-r--r--spec/unit/shell/shell_session_spec.rb18
-rw-r--r--spec/unit/shell_spec.rb3
-rw-r--r--spec/unit/user_spec.rb8
-rw-r--r--spec/unit/util/backup_spec.rb21
-rw-r--r--spec/unit/util/diff_spec.rb58
-rw-r--r--spec/unit/util/file_edit_spec.rb159
-rw-r--r--spec/unit/util/selinux_spec.rb14
-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
889 files changed, 38568 insertions, 16200 deletions
diff --git a/.travis.yml b/.travis.yml
index bda8c79211..b8eb285561 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,26 @@
+# Temporary workaround for issue with rubygems 2.2.0 with bundler 1.5 on ruby
+# 1.8.7.
+#
+# A fix has been merged to rubygems but not yet released. See:
+# https://github.com/rubygems/rubygems/commit/f8e0f1d5f67cfc4e1966cc1e2db367aebf8a09e4
+#
+# See also CHEF-4916
+#
+# This workaround should be removed when that fix is released.
+before_install:
+ - gem update --system 2.1.11
+ - gem --version
+
rvm:
- 1.8.7
-# - 1.9.2
- 1.9.3
- 2.0.0
+ - 2.1.0
-script: bundle exec rake spec
+branches:
+ only:
+ - master
+ - 10-stable
+ - 11-stable
+script: bundle exec rspec --color --format progress
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000..5962ac545d
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,16 @@
+# Chef Client Changelog
+
+## Unreleased
+
+* Improves syntax check speed for Ruby 1.9+, especially when using bundler.
+* Send X-Remote-Request-Id header in order to be able to correlate actions during a single run.
+* Fix for CHEF-5048.
+* Fix for CHEF-5052.
+* Fix for CHEF-5018.
+* Add --validator option to `knife client create` to be able to create validator clients via knife.
+* Add --force option to `knife client delete` in order to prevent accidental deletion of validator clients.
+* Add -r / --runlist option to chef-client which permanently sets or changes the run_list of a node.
+
+## Last Release: 11.10.0 (02/06/2014)
+
+http://docs.opscode.com/release/11-10/release_notes.html
diff --git a/CHEF_MVPS.md b/CHEF_MVPS.md
new file mode 100644
index 0000000000..dfd0985bba
--- /dev/null
+++ b/CHEF_MVPS.md
@@ -0,0 +1,84 @@
+### Chef is proud of our community!
+
+Every release of Chef we pick someone from the community to name as the Most Valuable Player for that release. It could be someone who provided a big feature, reported a security vulnerability, or someone doing great things in the community that we want to highlight.
+
+#### Hall of Fame
+
+After receiving three MVP awards, we add someone to the hall of fame. We want to express our gratitude to their continuing participation and give newer community members the opportunity to be reconignized.
+
+* Matthew Kent
+* Doug MacEachern
+* Tollef Fog Heen
+* Thom May
+* Bryan Berry
+* Bryan McLellan
+
+#### The MVP recipients
+
+| Release | Date | MVP |
+|---------|------|-----|
+| [Client 11.10.4](http://www.getchef.com/blog/2014/02/20/chef-client-patch-release-11-10-4/) | 2014-02-20 | Jon Cowie |
+| [Client 11.10.2](http://www.getchef.com/blog/2014/02/18/chef-client-release-11-10-2-10-30-4/) | 2014-02-18 | Eric Tucker |
+| [Client 11.10.0](http://www.getchef.com/blog/2014/02/06/chef-client-11-10-0-release/) | 2014-02-06 | Nikhil Benesch |
+| [Client 11.8.2](http://www.getchef.com/blog/2013/12/06/release-chef-client-10-30-2-11-8-2-mixlib-shellout-1-3-0/) | 2013-12-06 | James Ogden |
+| [Client 11.8.0](http://www.opscode.com/blog/2013/10/31/release-chef-client-11-8-0-ohai-6-20-0/) | 2013-10-31 | Eric Saxby |
+| [Client 11.6.2](http://www.getchef.com/blog/2013/10/08/release-chef-client-11-6-2-10-28-2/) | 2013-10-08 | Jeff Blaine |
+| [Client 11.6.0](http://www.opscode.com/blog/2013/07/23/chef-client-11-6-0-ohai-6-18-0-and-more/) | 2013-07-23 | Jesse Campbell |
+| [Client 11.4.0](http://www.opscode.com/blog/2013/02/13/chef-client-11-4-0-10-22-0-released/) | 2013-02-13 | Vaidas Jablonskis |
+| [Client 11.2.0](http://www.opscode.com/blog/2013/02/07/chef-client-11-2-0-10-20-0-released/) | 2013-02-06 | Mike Javorski |
+| [Chef 11.0.0](http://www.opscode.com/blog/2013/02/04/chef-11-released/) | 2013-02-04 | Andrea Campi, Bryan Berry |
+| [Chef 10.30.4](http://www.getchef.com/blog/2014/02/18/chef-client-release-11-10-2-10-30-4/) | 2014-02-18 | Christopher Laco |
+| [Chef 10.30.2](http://www.getchef.com/blog/2013/12/06/release-chef-client-10-30-2-11-8-2-mixlib-shellout-1-3-0/) | 2013-12-06 | Phil Dibowitz |
+| [Chef 10.28.2](http://www.getchef.com/blog/2013/10/08/release-chef-client-11-6-2-10-28-2/) | 2013-10-08 | Jeff Blaine |
+| [Chef 10.28.0](http://www.opscode.com/blog/2013/09/03/chef-10-28-0-released/) | 2013-09-03 | Jeff Blaine |
+| [Chef 10.26.0](http://www.opscode.com/blog/2013/05/08/chef-10-26-0-released/) | 2013-05-08 | Ranjib Dey |
+| [Chef 10.24.0](http://www.opscode.com/blog/2013/02/15/chef-server-11-0-6-and-10-24-0-released/) | 2013-02-15 | Anthony Goddard |
+| [Chef 10.22.0](http://www.opscode.com/blog/2013/02/13/chef-client-11-4-0-10-22-0-released/) | 2013-02-13 | Brian Bianco |
+| [Chef 10.20.0](http://www.opscode.com/blog/2013/02/07/chef-client-11-2-0-10-20-0-released/) | 2013-02-06 | Chris Roberts |
+| [Chef 10.18.2](http://www.opscode.com/blog/2013/01/18/chef-10-18-2-bugfix-release/) | 2013-01-18 | Fletcher Nichol |
+| [Chef 10.18.0](http://www.opscode.com/blog/2013/01/16/chef-10-18-0-released/) | 2013-01-16 | Xabier de Zuazo |
+| [Chef 10.16.6](http://www.opscode.com/blog/2013/01/11/chef-10-16-6-security-release/) | 2013-01-11 | Dan Kubb |
+| [Chef 10.16.4](http://www.opscode.com/blog/2012/12/26/chef-10-16-4-released/) | 2012-12-26 | Avishai Ish-Shalom |
+| [Chef 10.16.2](http://www.opscode.com/blog/2012/10/26/chef-10-16-2-released/) | 2012-10-26 | Jamie Winsor |
+| [Chef 10.16.0](http://www.opscode.com/blog/2012/10/22/chef-10-16-0-released/) | 2012-10-22 | John Dewey |
+| [Chef 10.14.4](http://www.opscode.com/blog/2012/09/28/chef-10-14-4-released/) | 2012-09-27 | Kendrick Martin |
+| [Chef 10.14.2](http://www.opscode.com/blog/2012/09/11/chef-10-14-2-released/) | 2012-09-10 | Phil Dibowitz, Tim Smith |
+| [Chef 10.14.0](http://www.opscode.com/blog/2012/09/07/chef-10-14-0-released/) | 2012-09-07 | Xabier de Zuazo |
+| [Chef 10.12.0](http://www.opscode.com/blog/2012/06/19/chef-10-12-0-released/) | 2012-06-18 | Chris Roberts |
+| [Chef 0.10.10](http://www.opscode.com/blog/2012/05/11/chef-0-10-10-released/) | 2012-05-11 | Juanje Ojeda, Igor Afonov |
+| [Chef 0.10.8](http://www.opscode.com/blog/2011/12/15/chef-0-10-8-released/) | 2011-12-15 | Bryan Berry |
+| [Chef 0.10.6](http://www.opscode.com/blog/2011/12/14/chef-0-10-6-released/) | 2011-12-13 | Andrea Campi |
+| [Chef 0.10.4](http://www.opscode.com/blog/2011/08/11/chef-0-10-4-released/) | 2011-08-11 | Matthew Kent |
+| [Chef 0.10.2](http://www.opscode.com/blog/2011/06/29/chef-0-10-2-and-0-9-18-released/) | 2011-06-29 | Daniel Oliver |
+| [Chef 0.10.0](http://www.opscode.com/blog/2011/05/02/chef-0-10-0-released/) | 2011-05-02 | Grace Mollison, Darrin Eden |
+| [Chef 0.9.18](http://www.opscode.com/blog/2011/06/29/chef-0-10-2-and-0-9-18-released/) | 2011-06-29 | Jesai Langenbach |
+| [Chef 0.9.16](http://www.opscode.com/blog/2011/04/15/chef-0-9-16-released/) | 2011-04-15 | Michael Leinartas |
+| [Chef 0.9.14](http://www.opscode.com/blog/2011/03/04/chef-0-9-14-released/) | 2011-03-04 | Gilles Devaux |
+| [Chef 0.9.12](http://www.opscode.com/blog/2010/10/22/chef-0-9-12-released/) | 2010-10-22 | Laurent Désarmes |
+| [Chef 0.9.10](http://www.opscode.com/blog/2010/10/19/chef-0-9-10-ohai-0-5-8-and-mixliblog-1-2-0-released/) | 2010-10-19 | Toomas Pelberg, Tommy Bishop |
+| [Chef 0.9.8](http://www.opscode.com/blog/2010/08/05/chef-0-9-8-and-mixlib-authentication-1-1-4-released/) | 2010-08-05 | Joe Williams |
+| [Chef 0.9.6](http://www.opscode.com/blog/2010/07/03/chef-0-9-6-released/) | 2010-07-03 | Caleb Tennis |
+| [Chef 0.9.4](http://www.opscode.com/blog/2010/06/30/chef-0-9-4-released/) | 2010-06-30 | Ian Meyer |
+| [Chef 0.9.0](http://www.opscode.com/blog/2010/06/21/chef-0-9-0-and-ohai-0-5-6-released/) | 2010-06-21 | Doug MacEachern |
+| [Chef 0.8.16](http://www.opscode.com/blog/2010/05/11/chef-0-8-16-and-ohai-0-5-4-release/) | 2010-05-11 | Akzhan Abdulin |
+| [Chef 0.8.14](http://www.opscode.com/blog/2010/05/07/chef-0-8-14-release/) | 2010-05-07 | Renaud Chaput |
+| [Chef 0.8.10](http://www.opscode.com/blog/2010/04/02/chef-0-8-10-release/) | 2010-04-02 | Thom May, Tollef Fog Heen |
+| [Chef 0.8.8](http://www.opscode.com/blog/2010/03/18/chef-0-8-8-release/) | 2010-03-18 | Eric Hankins |
+| [Chef 0.8.6](http://www.opscode.com/blog/2010/03/05/chef-0-8-6-release/) | 2010-03-05 | Ian Meyer |
+| [Chef 0.8.4](http://www.opscode.com/blog/2010/03/02/chef-0-8-4-release/) | 2010-03-02 | Tollef Fog Heen |
+| [Chef 0.8.2](http://www.opscode.com/blog/2010/03/01/chef-0-8-2-release/) | 2010-03-01 | Scott M. Likens |
+| [Chef 0.7.16](http://www.opscode.com/blog/2009/12/22/chef-0-7-16-release/) | 2009-12-22 | Bryan McLellan |
+| [Chef 0.7.14](http://www.opscode.com/blog/2009/10/26/chef-0-7-14-ohai-0-3-6-releases/) | 2009-10-16 | Thom May |
+| [Chef 0.7.12](http://www.opscode.com/blog/2009/10/06/chef-0-7-12rc0-ohai-0-3-4rc0-releases/) | 2009-10-06 | Diego Algorta |
+| [Chef 0.7.10](http://www.opscode.com/blog/2009/09/04/chef-0-7-10-release/) | 2009-09-04 | Dan DeLeo |
+| [Chef 0.7.8](http://www.opscode.com/blog/2009/08/13/chef-0-7-8-release/) | 2009-08-13 | Jeppe Nejsum Madsen |
+| [Chef 0.7.6](http://www.opscode.com/blog/2009/08/08/chef-0-7-6-release/) | 2009-08-08 | Grant Zanetti |
+| [Chef 0.7.4](http://www.opscode.com/blog/2009/06/26/back-to-back-chef-0-7-2-and-chef-0-7-4-released/) | 2009-06-26 | Hongli Lai |
+| [Chef 0.7.2](http://www.opscode.com/blog/2009/06/26/back-to-back-chef-0-7-2-and-chef-0-7-4-released/) | 2009-06-26 | Joshua Sierles |
+| [Chef 0.7.0](http://www.opscode.com/blog/2009/06/10/chef-0-7-0-release/) | 2009-06-10 | Matthew Kent |
+| [Chef 0.6.2](http://www.opscode.com/blog/2009/04/29/chef-0-6-2-release/) | 2009-04-29 | David Balatero |
+| [Chef 0.6.0](http://www.opscode.com/blog/2009/04/29/chef-0-6-0-release/) | 2009-04-29 | Matthew Kent |
+| [Chef 0.5.6](http://www.opscode.com/blog/2009/03/06/chef-0-5-6/) | 2009-03-06 | Sean Cribbs |
+| [Chef 0.5.4](http://www.opscode.com/blog/2009/02/13/chef-0-5-4/) | 2009-02-13 | Arjuna Christensen |
+| [Chef 0.5.2](http://www.opscode.com/blog/2009/02/01/chef-0-5-2-and-ohai-0-1-4/) | 2009-02-01 | Bryan McLellan |
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4744593eeb..9d9839fd5c 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,12 +19,12 @@ 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.
-To make a good faith effort to ensure these criteria are met, Opscode requires a Contributor License Agreement (CLA) or a Corporate Contributor License
+To make a good faith effort to ensure these criteria are met, Chef requires a Contributor License Agreement (CLA) or a Corporate Contributor License
Agreement (CCLA) for all contributions. This is without exception due to some matters not being related to copyright and to avoid having to continually
check with our lawyers about small patches.
@@ -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
@@ -74,9 +74,9 @@ helpful to be clear about your use case and change so they can understand it eve
### Github and Pull Requests
-All of Opscode's open source projects are available on [Github](http://www.github.com/opscode).
+All of Chef'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
@@ -115,7 +115,7 @@ and accounting for it.
## Code Review
-Opscode regularly reviews code contributions and provides suggestions for improvement in the code itself or the implementation.
+Chef regularly reviews code contributions and provides suggestions for improvement in the code itself or the implementation.
We find contributions by searching the ticket tracker for _resolved_ tickets with a status of _fixed_. If we have feedback we will
reopen the ticket and you should resolve it again when you've made the changes or have a response to our feedback. When we believe
@@ -134,14 +134,14 @@ The versioning for the Chef project is X.Y.Z.
* Y is a minor release, which adds both new features and bug fixes
* Z is a patch release, which adds just bug fixes
-Major releases and have historically been once a year. Minor releases for Chef average every two months and patch releases come as needed.
+Major releases have historically been once a year. Minor releases for Chef average every three 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.
-Once the official release is made, the release notes are available on the [Opscode blog](http://www.opscode.com/blog).
+Once the official release is made, the release notes are available on the [Chef blog](http://www.getchef.com/blog).
## Working with the community
@@ -151,5 +151,5 @@ These resources will help you learn more about Chef and connect to other members
* #chef and #chef-hacking IRC channels on irc.freenode.net
* [Community Cookbook site](http://community.opscode.com)
* [Chef wiki](http://wiki.opscode.com/display/chef)
-* Opscode Chef [product page](http://www.opscode.com/chef)
+* Chef [product page](http://www.getchef.com/chef)
diff --git a/CONTRIBUTIONS.md b/CONTRIBUTIONS.md
new file mode 100644
index 0000000000..3bf6a131d7
--- /dev/null
+++ b/CONTRIBUTIONS.md
@@ -0,0 +1,10 @@
+<!---
+This file is reset every time a new release is done. The contents of this file are for the currently unreleased version.
+
+Example Contribution:
+* **kalistec**: Improved file resource greatly.
+-->
+# Chef Client Contributions:
+
+* **jonlives**: Changed the order of recipe and cookbook name setting. Fixes CHEF-5052.
+
diff --git a/DOC_CHANGES.md b/DOC_CHANGES.md
new file mode 100644
index 0000000000..e37f39510e
--- /dev/null
+++ b/DOC_CHANGES.md
@@ -0,0 +1,18 @@
+<!---
+This file is reset every time a new release is done. This file describes changes that have not yet been released.
+
+Example Doc Change:
+### Headline for the required change
+Description of the required change.
+-->
+
+# Chef Client Doc Changes:
+
+### --validator option for `knife client create`
+Boolean value. If set to true, knife creates a validator client o.w. it creates a user client. Default is false.
+
+### --force for `knife client delete`
+Option that is required to be specified if user is attempting to delete a validator client. No effect while deleting a user client.
+
+### -r / --runlist option for chef-client
+Option similar to `-o` which sets or changes the run_list of a node permanently.
diff --git a/Gemfile b/Gemfile
index a228c189c8..295f1781a0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,11 +1,9 @@
source "https://rubygems.org"
-
-gemspec
+gemspec :name => "chef"
gem "activesupport", "< 4.0.0", :group => :compat_testing, :platform => "ruby"
group(:docgen) do
- gem "ronn"
gem "yard"
end
@@ -14,26 +12,6 @@ group(:development, :test) do
gem 'rack', "~> 1.5.1"
gem 'ruby-shadow', :platforms => :ruby unless RUBY_PLATFORM.downcase.match(/(darwin|freebsd|aix)/)
-# gem 'awesome_print'
-# gem 'pry'
-end
-
-platforms :mswin, :mingw do
- gem "systemu", "2.2.0" # CHEF-3718
- gem "ffi", "1.3.1"
- gem "rdp-ruby-wmi", "0.3.1"
- gem "windows-api", "0.4.2"
- gem "windows-pr", "1.2.2"
- gem "win32-api", "1.4.8"
- gem "win32-dir", "0.4.1"
- gem "win32-event", "0.6.0"
- gem "win32-mutex", "0.4.0"
- 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,
diff --git a/README.md b/README.md
index 78328c4e1c..1c8e58d115 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# Chef
+Want to try Chef? Get started with [learnchef](https://learnchef.opscode.com)
+
* Documentation: [http://docs.opscode.com](http://docs.opscode.com)
* Source: [http://github.com/opscode/chef/tree/master](http://github.com/opscode/chef/tree/master)
* Tickets/Issues: [http://tickets.opscode.com](http://tickets.opscode.com)
@@ -9,62 +11,81 @@
Chef is a configuration management tool designed to bring automation to your
entire infrastructure.
-The [Chef Wiki](http://wiki.opscode.com/display/chef/Home) is the definitive
-source of user documentation.
+This README focuses on developers who want to modify Chef source code.
+If you just want to use Chef, check out these resources:
-This README focuses on developers who want to modify Chef source code. For
-users who just want to run the latest and greatest Chef development version in
-their environment, see the
-[Installing Chef from HEAD](http://wiki.opscode.com/display/chef/Installing+Chef+from+HEAD)
-page on the wiki.
+* [learnchef](https://learnchef.opscode.com): Getting started guide
+* [http://docs.opscode.com](http://docs.opscode.com): Comprehensive User Docs
+* [Installer Downloads](http://www.getchef.com/chef/install/): Install Chef as a complete package
-## Contributing/Development
+## Installing From Git
-Before working on the code, if you plan to contribute your changes, you need to
-read the
-[Opscode Contributing document](http://wiki.opscode.com/display/chef/How+to+Contribute).
+**NOTE:** Unless you have a specific reason to install from source (to
+try a new feature, contribute a patch, or run chef on an OS for which no
+package is available), you should head to the [installer page](http://www.getchef.com/chef/install/)
+to get a prebuilt package.
-You will also need to set up the repository with the appropriate branches. We
-document the process on the
-[Working with Git](http://wiki.opscode.com/display/chef/Working+with+git) page
-of the Chef wiki.
+### Prerequisites
-Once your repository is set up, you can start working on the code. We do use
-TDD with RSpec, so you'll need to get a development environment running.
+Install these via your platform's preferred method (apt, yum, ports,
+emerge, etc.):
-### Requirements
+* git
+* C compiler, header files, etc. On Ubuntu/debian, use the
+ `build-essential` package.
+* ruby 1.8.7 or later (1.9.3+ recommended)
+* rubygems
+* bundler
-Ruby 1.8.7+ (As of 2012-05-25 Ruby 1.8.6 should still work, except for CHEF-2329.)
+### Chef Installation
-### Environment
+Then get the source and install it:
-In order to have a development environment where changes to the Chef code can
-be tested, we'll need to install a few things after setting up the Git
-repository.
+ # Clone this repo
+ git clone https://github.com/opscode/chef.git
+
+ # cd into the source tree
+ cd chef
-#### Non-Gem Dependencies
+ # Install dependencies with bundler
+ bundle install
-Install these via your platform's preferred method; for example apt, yum,
-ports, emerge, etc.
+ # Build a gem
+ rake gem
-* [Git](http://git-scm.com/)
-* GCC and C Standard Libraries, header files, etc. (i.e., build-essential on
-debian/ubuntu)
-* Ruby development package
+ # Install the gem you just built
+ gem install pkg/chef-VERSION.gem
-#### Runtime Rubygem Dependencies
-First you'll need [bundler](http://github.com/carlhuda/bundler) which can
-be installed with a simple `gem install bundler`. Afterwords, do the following:
+## Contributing/Development
- bundle install
+Before working on the code, if you plan to contribute your changes, you need to
+read the
+[Chef Contributions document](http://docs.opscode.com/community_contributions.html).
+
+You will also need to set up the repository with the appropriate branches. We
+document the process on the
+[Working with Git](http://wiki.opscode.com/display/chef/Working+with+git) page
+of the Chef wiki.
+
+Once your repository is set up, you can start working on the code. We do use
+TDD with RSpec, so you'll need to get a development environment running.
+Follow the above procedure ("Installing from Git") to get your local
+copy of the source running.
## Testing
We use RSpec for unit/spec tests. It is not necessary to start the development
environment to run the specs--they are completely standalone.
- rake spec
+ # Run All the Tests
+ bundle exec rake spec
+
+ # Run a Single Test File
+ bundle exec rspec spec/PATH/TO/FILE_spec.rb
+
+ # Run a Subset of Tests
+ bundle exec rspec spec/PATH/TO/DIR
# License
@@ -73,7 +94,7 @@ Chef - A configuration management system
| | |
|:---------------------|:-----------------------------------------|
| **Author:** | Adam Jacob (<adam@opscode.com>)
-| **Copyright:** | Copyright (c) 2008-2012 Opscode, Inc.
+| **Copyright:** | Copyright (c) 2008-2014 Chef Software, Inc.
| **License:** | Apache License, Version 2.0
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
new file mode 100644
index 0000000000..9afa0a73ec
--- /dev/null
+++ b/RELEASE_NOTES.md
@@ -0,0 +1,12 @@
+<!---
+This file is reset every time a new release is done. The contents of this file are for the currently unreleased version.
+
+Example Note:
+
+## Example Heading
+Details about the thing that changed that needs to get included in the Release Notes in markdown.
+-->
+# Chef Client Release Notes:
+
+
+# Chef Client Breaking Changes:
diff --git a/Rakefile b/Rakefile
index 085887fab5..2e0c203b49 100644
--- a/Rakefile
+++ b/Rakefile
@@ -26,30 +26,9 @@ 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
-end
-
-begin
- require 'sdoc'
-
- Rake::RDocTask.new do |rdoc|
- rdoc.title = "Chef Ruby API Documentation"
- rdoc.main = "README.rdoc"
- rdoc.options << '--fmt' << 'shtml' # explictly set shtml generator
- rdoc.template = 'direct' # lighter template
- rdoc.rdoc_files.include("README.rdoc", "LICENSE", "spec/tiny_server.rb", "lib/**/*.rb")
- rdoc.rdoc_dir = "rdoc"
- end
-rescue LoadError
- puts "sdoc is not available. (sudo) gem install sdoc to generate rdoc documentation."
-rescue TypeError
- puts "sdoc is not working on ruby-2.0.0 and throwing an odd TypeError, rdoc generation will be disabled on ruby 2.0 until that gets fixed."
+Dir[File.expand_path("../*gemspec", __FILE__)].reverse.each do |gemspec_path|
+ gemspec = eval(IO.read(gemspec_path))
+ Gem::PackageTask.new(gemspec).define
end
task :install => :package do
@@ -60,64 +39,15 @@ task :uninstall do
sh %{gem uninstall #{GEM_NAME} -x -v #{Chef::VERSION} }
end
-RONN_OPTS = "--manual='Chef Manual' --organization='Chef #{Chef::VERSION}' --date='#{Time.new.strftime('%Y-%m-%d')}'"
-
-namespace :docs do
- desc "Regenerate manpages from markdown"
- task :man
-
- desc "Regenerate HTML manual from markdown"
- task :html
-
- desc "Regenerate help topics from man pages"
- task :list => :man do
- topics = Array.new
-
- Dir['distro/common/man/man1/*.1'].each do |man|
- topics << File.basename(man, '.1')
- end
-
- File.open('lib/chef/knife/help_topics.rb', 'w') do |f|
- f.puts "# Do not edit this file by hand"
- f.puts "# This file is autogenerated by the docs:list rake task from the available manpages\n\n"
-
- f.puts "HELP_TOPICS = #{topics.inspect}"
- end
- end
-
- if 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')
- if dir =~ /man1/
- manfile = "distro/common/man/man1/#{basename}.1"
- htmlfile = "distro/common/html/#{basename}.1.html"
- elsif dir =~ /man8/
- manfile = "distro/common/man/man8/#{basename}.8"
- htmlfile = "distro/common/html/#{basename}.8.html"
- end
-
- file(manfile => [mkd, 'lib/chef/version.rb']) do
- sh "ronn -r #{RONN_OPTS} #{mkd} --pipe > #{manfile}"
- end
- task :man => manfile
-
- file(htmlfile => [mkd, 'lib/chef/version.rb']) do
- sh "ronn -5 #{RONN_OPTS} --style=toc #{mkd} --pipe > #{htmlfile}"
- end
- task :html => htmlfile
-
- end
- end
- else
- puts "get with the program and install ronn"
+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
-
- task :all => [:man, :html]
end
-task :docs => "docs:all"
-
begin
require 'yard'
DOC_FILES = [ "README.rdoc", "LICENSE", "spec/tiny_server.rb", "lib/**/*.rb" ]
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-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..b0ff015a68
--- /dev/null
+++ b/chef-x86-mingw32.gemspec
@@ -0,0 +1,18 @@
+# x86-mingw32 Gemspec #
+gemspec = eval(IO.read(File.expand_path("../chef.gemspec", __FILE__)))
+
+gemspec.platform = "x86-mingw32"
+
+gemspec.add_dependency "ffi", "1.5.0"
+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 0be91849c7..fcc585c363 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -12,30 +12,37 @@ 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.4"
+ s.add_dependency "mixlib-log", "~> 1.3"
+ s.add_dependency "mixlib-authentication", "~> 1.3"
+ s.add_dependency "mixlib-shellout", "~> 1.3"
+ s.add_dependency "ohai", "~> 6.0"
s.add_dependency "rest-client", ">= 1.0.4", "< 1.7.0"
+ # rest-client has an unbounded dependency on mime-types.
+ # mime-types 2.0 removes support for ruby 1.8.7 (gemspec requires ruby
+ # 1.9.2+), so we have to add an additional pin. 1.16 is chosen just becuase
+ # it's the version I had when I tested.
+ s.add_dependency "mime-types", "~> 1.16"
# The JSON gem reliably releases breaking changes as a patch release
- s.add_dependency "json", ">= 1.4.4", "<= 1.7.7"
+ s.add_dependency "json", ">= 1.4.4", "<= 1.8.1"
s.add_dependency "yajl-ruby", "~> 1.1"
s.add_dependency "net-ssh", "~> 2.6"
- s.add_dependency "net-ssh-multi", "~> 1.1.0"
+ s.add_dependency "net-ssh-multi", "~> 1.1"
# 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 "diff-lcs", ">= 1.2.4"
-
- %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.13.0" }
- s.add_development_dependency "chef-zero", "~> 1.4"
- s.add_development_dependency "puma", "~> 1.6"
+ 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.7", ">= 1.7.2"
+ s.add_dependency "puma", "~> 1.6"
+
+ s.add_dependency "pry", "~> 0.9"
+
+ %w(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.14.0" }
s.bindir = "bin"
# chef-service-manager is a windows only executable.
diff --git a/ci/jenkins_run_tests.bat b/ci/jenkins_run_tests.bat
index 4d1b1d1477..ba9cedd5e2 100644
--- a/ci/jenkins_run_tests.bat
+++ b/ci/jenkins_run_tests.bat
@@ -1,9 +1,14 @@
-set PATH=C:\Ruby192\bin;%PATH%
-
ruby -v
-call bundle install --binstubs --without docgen --path vendor/bundle || ( call rm Gemfile.lock && call bundle install --binstubs --path vendor/bundle )
-ruby bin\rspec -r rspec_junit_formatter -f RspecJunitFormatter -o test.xml -f documentation spec/functional spec/unit spec/stress
-set RSPEC_ERRORLVL=%ERRORLEVEL%
+call bundle check
+
+if %ERRORLEVEL% NEQ 0 (
+ call rm Gemfile.lock
+ call bundle install --without docgen --path vendor/bundle
+)
+
+bundle exec rspec -r rspec_junit_formatter -f RspecJunitFormatter -o test.xml -f documentation spec/functional spec/unit spec/stress spec/integration
+
+set RSPEC_ERRORLVL=%ERRORLEVEL%
REM Return the error level from rspec
exit /B %RSPEC_ERRORLVL%
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/_sources/ctl_chef_client.txt b/distro/common/html/_sources/ctl_chef_client.txt
new file mode 100644
index 0000000000..99b0037154
--- /dev/null
+++ b/distro/common/html/_sources/ctl_chef_client.txt
@@ -0,0 +1,36 @@
+=====================================================
+chef-client
+=====================================================
+
+.. include:: ../../includes_chef_client/includes_chef_client.rst
+
+.. include:: ../../includes_ctl_chef_client/includes_ctl_chef_client.rst
+
+.. note:: .. include:: ../../includes_config/includes_config_rb_client.rst
+
+Options
+=====================================================
+.. include:: ../../includes_ctl_chef_client/includes_ctl_chef_client_11-8_options.rst
+
+Run with Elevated Privileges
+=====================================================
+.. include:: ../../includes_ctl_chef_client/includes_ctl_chef_client_elevated_privileges.rst
+
+Linux
+-----------------------------------------------------
+.. include:: ../../includes_ctl_chef_client/includes_ctl_chef_client_elevated_privileges_linux.rst
+
+Windows
+-----------------------------------------------------
+.. include:: ../../includes_ctl_chef_client/includes_ctl_chef_client_elevated_privileges_windows.rst
+
+Examples
+=====================================================
+
+**Start a Chef run when the chef-client is running as a daemon**
+
+.. include:: ../../step_ctl_chef_client/step_ctl_chef_client_start_chef_run_daemon.rst
+
+**Start a Chef run manually**
+
+.. include:: ../../step_ctl_chef_client/step_ctl_chef_client_start_chef_run_manual.rst \ No newline at end of file
diff --git a/distro/common/html/_sources/ctl_chef_server.txt b/distro/common/html/_sources/ctl_chef_server.txt
new file mode 100644
index 0000000000..9c38c30ef6
--- /dev/null
+++ b/distro/common/html/_sources/ctl_chef_server.txt
@@ -0,0 +1,26 @@
+=====================================================
+chef-server-ctl
+=====================================================
+
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server.rst
+
+Options
+=====================================================
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_options.rst
+
+
+Examples
+=====================================================
+The following examples show how to use |chef server ctl| to manage services.
+
+**View the status of a service**
+
+.. include:: ../../step_ctl_chef_server/step_ctl_chef_server_view_service_status.rst
+
+**Restart a service**
+
+.. include:: ../../step_ctl_chef_server/step_ctl_chef_server_restart_service.rst
+
+**Restart all services**
+
+.. include:: ../../step_ctl_chef_server/step_ctl_chef_server_restart_all_services.rst
diff --git a/distro/common/html/_sources/ctl_chef_shell.txt b/distro/common/html/_sources/ctl_chef_shell.txt
new file mode 100644
index 0000000000..75902f3141
--- /dev/null
+++ b/distro/common/html/_sources/ctl_chef_shell.txt
@@ -0,0 +1,15 @@
+=====================================================
+chef-shell
+=====================================================
+
+.. include:: ../../includes_chef_shell/includes_chef_shell.rst
+
+.. include:: ../../includes_ctl_chef_shell/includes_ctl_chef_shell.rst
+
+Modes
+=====================================================
+.. include:: ../../includes_chef_shell/includes_chef_shell_modes.rst
+
+Options
+=====================================================
+.. include:: ../../includes_ctl_chef_shell/includes_ctl_chef_shell_options.rst
diff --git a/distro/common/html/_sources/ctl_chef_solo.txt b/distro/common/html/_sources/ctl_chef_solo.txt
new file mode 100644
index 0000000000..a80c8bad3c
--- /dev/null
+++ b/distro/common/html/_sources/ctl_chef_solo.txt
@@ -0,0 +1,25 @@
+=====================================================
+chef-solo
+=====================================================
+
+.. include:: ../../includes_chef_solo/includes_chef_solo.rst
+
+.. include:: ../../includes_ctl_chef_solo/includes_ctl_chef_solo.rst
+
+Options
+=====================================================
+.. include:: ../../includes_ctl_chef_solo/includes_ctl_chef_solo_options.rst
+
+Examples
+=====================================================
+**Use a URL**
+
+.. include:: ../../step_ctl_chef_solo/step_ctl_chef_solo_use_url.rst
+
+**Use a directory**
+
+.. include:: ../../step_ctl_chef_solo/step_ctl_chef_solo_use_directory.rst
+
+**Use a URL for cookbook and JSON data**
+
+.. include:: ../../step_ctl_chef_solo/step_ctl_chef_solo_url_for_cookbook_and_json.rst
diff --git a/distro/common/html/_sources/index.txt b/distro/common/html/_sources/index.txt
new file mode 100644
index 0000000000..1600827541
--- /dev/null
+++ b/distro/common/html/_sources/index.txt
@@ -0,0 +1,126 @@
+=====================================================
+|chef client| Man Pages
+=====================================================
+
+The following command line interfaces are available in the |chef client|:
+
+* :doc:`ctl_chef_client`
+* :doc:`ctl_chef_server`
+* :doc:`ctl_chef_shell`
+* :doc:`ctl_chef_solo`
+* :doc:`knife`
+
+knife
+=====================================================
+.. include:: ../../includes_knife/includes_knife.rst
+
+The following sections describe functionality common to all |knife| subcommands:
+
+* :doc:`knife_using`
+* :doc:`knife_common_options`
+
+|knife| includes the following sub-commands:
+
+.. list-table::
+ :widths: 150 450
+ :header-rows: 1
+
+ * - Sub-command
+ - Description
+ * - :doc:`knife_bootstrap`
+ - .. include:: ../../includes_knife/includes_knife_bootstrap.rst
+ * - :doc:`knife_client`
+ - .. include:: ../../includes_knife/includes_knife_client.rst
+ * - :doc:`knife_configure`
+ - .. include:: ../../includes_knife/includes_knife_configure.rst
+ * - :doc:`knife_cookbook`
+ - .. include:: ../../includes_knife/includes_knife_cookbook.rst
+ * - :doc:`knife_cookbook_site`
+ - .. include:: ../../includes_knife/includes_knife_site_cookbook.rst
+ * - :doc:`knife_data_bag`
+ - .. include:: ../../includes_knife/includes_knife_data_bag.rst
+ * - :doc:`knife_delete`
+ - .. include:: ../../includes_knife/includes_knife_delete.rst
+ * - :doc:`knife_deps`
+ - .. include:: ../../includes_knife/includes_knife_deps.rst
+ * - :doc:`knife_diff`
+ - .. include:: ../../includes_knife/includes_knife_diff.rst
+ * - :doc:`knife_download`
+ - .. include:: ../../includes_knife/includes_knife_download.rst
+ * - :doc:`knife_edit`
+ - .. include:: ../../includes_knife/includes_knife_edit.rst
+ * - :doc:`knife_environment`
+ - .. include:: ../../includes_knife/includes_knife_environment.rst
+ * - :doc:`knife_exec`
+ - .. include:: ../../includes_knife/includes_knife_exec.rst
+ * - :doc:`knife_index_rebuild`
+ - .. include:: ../../includes_knife/includes_knife_index_rebuild.rst
+ * - :doc:`knife_list`
+ - .. include:: ../../includes_knife/includes_knife_list.rst
+ * - :doc:`knife_node`
+ - .. include:: ../../includes_knife/includes_knife_node.rst
+ * - :doc:`knife_raw`
+ - .. include:: ../../includes_knife/includes_knife_raw.rst
+ * - :doc:`knife_recipe_list`
+ - .. include:: ../../includes_knife/includes_knife_recipe_list.rst
+ * - :doc:`knife_role`
+ - .. include:: ../../includes_knife/includes_knife_role.rst
+ * - :doc:`knife_search`
+ - .. include:: ../../includes_knife/includes_knife_search.rst
+ * - :doc:`knife_show`
+ - .. include:: ../../includes_knife/includes_knife_show.rst
+ * - :doc:`knife_ssh`
+ - .. include:: ../../includes_knife/includes_knife_ssh.rst
+ * - :doc:`knife_status`
+ - .. include:: ../../includes_knife/includes_knife_status.rst
+ * - :doc:`knife_tag`
+ - .. include:: ../../includes_knife/includes_knife_tag.rst
+ * - :doc:`knife_upload`
+ - .. include:: ../../includes_knife/includes_knife_upload.rst
+ * - :doc:`knife_user`
+ - .. include:: ../../includes_knife/includes_knife_user.rst
+ * - :doc:`knife_xargs`
+ - .. include:: ../../includes_knife/includes_knife_xargs.rst
+
+
+.. Hide the TOC from this file.
+
+.. toctree::
+ :hidden:
+
+ ctl_chef_client
+ ctl_chef_server
+ ctl_chef_shell
+ ctl_chef_solo
+ knife
+ knife_common_options
+ knife_bootstrap
+ knife_client
+ knife_configure
+ knife_cookbook
+ knife_cookbook_site
+ knife_data_bag
+ knife_delete
+ knife_deps
+ knife_diff
+ knife_download
+ knife_edit
+ knife_environment
+ knife_exec
+ knife_index_rebuild
+ knife_list
+ knife_node
+ knife_raw
+ knife_recipe_list
+ knife_role
+ knife_search
+ knife_show
+ knife_ssh
+ knife_status
+ knife_tag
+ knife_upload
+ knife_user
+ knife_using
+ knife_xargs
+
+
diff --git a/distro/common/html/_sources/knife.txt b/distro/common/html/_sources/knife.txt
new file mode 100644
index 0000000000..6320825e83
--- /dev/null
+++ b/distro/common/html/_sources/knife.txt
@@ -0,0 +1,74 @@
+=====================================================
+knife
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife.rst
+
+The following sections describe functionality common to all |knife| subcommands:
+
+* :doc:`knife_using`
+* :doc:`knife_common_options`
+
+|knife| includes the following sub-commands:
+
+.. list-table::
+ :widths: 150 450
+ :header-rows: 1
+
+ * - Sub-command
+ - Description
+ * - :doc:`knife_bootstrap`
+ - .. include:: ../../includes_knife/includes_knife_bootstrap.rst
+ * - :doc:`knife_client`
+ - .. include:: ../../includes_knife/includes_knife_client.rst
+ * - :doc:`knife_configure`
+ - .. include:: ../../includes_knife/includes_knife_configure.rst
+ * - :doc:`knife_cookbook`
+ - .. include:: ../../includes_knife/includes_knife_cookbook.rst
+ * - :doc:`knife_cookbook_site`
+ - .. include:: ../../includes_knife/includes_knife_site_cookbook.rst
+ * - :doc:`knife_data_bag`
+ - .. include:: ../../includes_knife/includes_knife_data_bag.rst
+ * - :doc:`knife_delete`
+ - .. include:: ../../includes_knife/includes_knife_delete.rst
+ * - :doc:`knife_deps`
+ - .. include:: ../../includes_knife/includes_knife_deps.rst
+ * - :doc:`knife_diff`
+ - .. include:: ../../includes_knife/includes_knife_diff.rst
+ * - :doc:`knife_download`
+ - .. include:: ../../includes_knife/includes_knife_download.rst
+ * - :doc:`knife_edit`
+ - .. include:: ../../includes_knife/includes_knife_edit.rst
+ * - :doc:`knife_environment`
+ - .. include:: ../../includes_knife/includes_knife_environment.rst
+ * - :doc:`knife_exec`
+ - .. include:: ../../includes_knife/includes_knife_exec.rst
+ * - :doc:`knife_index_rebuild`
+ - .. include:: ../../includes_knife/includes_knife_index_rebuild.rst
+ * - :doc:`knife_list`
+ - .. include:: ../../includes_knife/includes_knife_list.rst
+ * - :doc:`knife_node`
+ - .. include:: ../../includes_knife/includes_knife_node.rst
+ * - :doc:`knife_raw`
+ - .. include:: ../../includes_knife/includes_knife_raw.rst
+ * - :doc:`knife_recipe_list`
+ - .. include:: ../../includes_knife/includes_knife_recipe_list.rst
+ * - :doc:`knife_role`
+ - .. include:: ../../includes_knife/includes_knife_role.rst
+ * - :doc:`knife_search`
+ - .. include:: ../../includes_knife/includes_knife_search.rst
+ * - :doc:`knife_show`
+ - .. include:: ../../includes_knife/includes_knife_show.rst
+ * - :doc:`knife_ssh`
+ - .. include:: ../../includes_knife/includes_knife_ssh.rst
+ * - :doc:`knife_status`
+ - .. include:: ../../includes_knife/includes_knife_status.rst
+ * - :doc:`knife_tag`
+ - .. include:: ../../includes_knife/includes_knife_tag.rst
+ * - :doc:`knife_upload`
+ - .. include:: ../../includes_knife/includes_knife_upload.rst
+ * - :doc:`knife_user`
+ - .. include:: ../../includes_knife/includes_knife_user.rst
+ * - :doc:`knife_xargs`
+ - .. include:: ../../includes_knife/includes_knife_xargs.rst
+
diff --git a/distro/common/html/_sources/knife_bootstrap.txt b/distro/common/html/_sources/knife_bootstrap.txt
new file mode 100644
index 0000000000..ee275b58f5
--- /dev/null
+++ b/distro/common/html/_sources/knife_bootstrap.txt
@@ -0,0 +1,56 @@
+=====================================================
+knife bootstrap
+=====================================================
+
+.. include:: ../../includes_chef/includes_chef_bootstrap.rst
+
+.. include:: ../../includes_knife/includes_knife_bootstrap.rst
+
+.. note:: To bootstrap the |chef client| on |windows| machines, the `knife-windows <http://docs.opscode.com/plugin_knife_windows.html>`_ plugins is required, which includes the necessary bootstrap scripts that are used to do the actual installation.
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_bootstrap_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_bootstrap_options.rst
+
+Custom Templates
+=====================================================
+The ``chef-full`` distribution uses the |omnibus installer|. For most bootstrap operations, regardless of the platform on which the target node is running, using the ``chef-full`` distribution is the best approach for installing the |chef client| on a target node. In some situations, using another supported distribution is necessary. And in some situations, a custom template may be required. For example, the default bootstrap operation relies on an Internet connection to get the distribution to the target node. If a target node cannot access the Internet, then a custom template can be used to define a specific location for the distribution so that the target node may access it during the bootstrap operation.
+
+A custom bootstrap template file (``template_filename.erb``) must be located in a ``bootstrap/`` directory. Use the ``--distro`` option with the ``knife bootstrap`` subcommand to specify the bootstrap template file. For example, a bootstrap template file named "british_sea_power.erb":
+
+.. code-block:: bash
+
+ $ knife bootstrap 123.456.7.8 -x username -P password --sudo --distro "british_sea_power.erb"
+
+The following examples show how a bootstrap template file can be customized for various platforms.
+
+Ubuntu 12.04
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_bootstrap_example_ubuntu.rst
+
+Debian and Apt
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_bootstrap_example_debian.rst
+
+Microsoft Windows
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_bootstrap_example_windows.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Use an SSH password**
+
+.. include:: ../../step_knife/step_knife_bootstrap_use_ssh_password.rst
+
+**Use a file that contains a private key**
+
+.. include:: ../../step_knife/step_knife_bootstrap_use_file_with_private_key.rst
+
diff --git a/distro/common/html/_sources/knife_client.txt b/distro/common/html/_sources/knife_client.txt
new file mode 100644
index 0000000000..d9d6ba62a1
--- /dev/null
+++ b/distro/common/html/_sources/knife_client.txt
@@ -0,0 +1,151 @@
+=====================================================
+knife client
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_client.rst
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+bulk delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_client_bulk_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_bulk_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+None.
+
+create
+=====================================================
+.. include:: ../../includes_knife/includes_knife_client_create.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_create_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_create_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create an admin client**
+
+.. include:: ../../step_knife/step_knife_client_create_admin.rst
+
+**Create an admin client for Enterprise Chef**
+
+.. include:: ../../step_knife/step_knife_client_create_hosted_and_private.rst
+
+delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_client_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Delete a client**
+
+.. include:: ../../step_knife/step_knife_client_delete.rst
+
+edit
+=====================================================
+.. include:: ../../includes_knife/includes_knife_client_edit.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_edit_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Edit a client**
+
+.. include:: ../../step_knife/step_knife_client_edit.rst
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_client_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_list_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_list_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View a list of clients**
+
+.. include:: ../../step_knife/step_knife_client_list_all.rst
+
+.. include:: ../../step_knife/step_knife_client_list_authenticate.rst
+
+reregister
+=====================================================
+.. include:: ../../includes_knife/includes_knife_client_reregister.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_reregister_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_reregister_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Reregister clients**
+
+.. include:: ../../step_knife/step_knife_client_reregister.rst
+
+show
+=====================================================
+.. include:: ../../includes_knife/includes_knife_client_show.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_show_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_client_show_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Show clients**
+
+.. include:: ../../step_knife/step_knife_client_show.rst
+
+.. include:: ../../step_knife/step_knife_common_view_json.rst \ No newline at end of file
diff --git a/distro/common/html/_sources/knife_common_options.txt b/distro/common/html/_sources/knife_common_options.txt
new file mode 100644
index 0000000000..154db5c1ee
--- /dev/null
+++ b/distro/common/html/_sources/knife_common_options.txt
@@ -0,0 +1,6 @@
+=====================================================
+Common Options
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_common_options.rst
+
diff --git a/distro/common/html/_sources/knife_configure.txt b/distro/common/html/_sources/knife_configure.txt
new file mode 100644
index 0000000000..1e0485e7fa
--- /dev/null
+++ b/distro/common/html/_sources/knife_configure.txt
@@ -0,0 +1,29 @@
+=====================================================
+knife configure
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_configure.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_configure_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_configure_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Configure knife.rb**
+
+.. include:: ../../step_knife/step_knife_configure_knife_rb.rst
+
+**Configure client.rb**
+
+.. include:: ../../step_knife/step_knife_configure_client_rb.rst
+
+
diff --git a/distro/common/html/_sources/knife_cookbook.txt b/distro/common/html/_sources/knife_cookbook.txt
new file mode 100644
index 0000000000..462e4dd76c
--- /dev/null
+++ b/distro/common/html/_sources/knife_cookbook.txt
@@ -0,0 +1,236 @@
+=====================================================
+knife cookbook
+=====================================================
+
+.. include:: ../../includes_cookbooks/includes_cookbooks.rst
+
+.. include:: ../../includes_knife/includes_knife_cookbook.rst
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+bulk delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_bulk_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_bulk_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_bulk_delete_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Bulk delete many cookbooks**
+
+.. include:: ../../step_knife/step_knife_cookbook_bulk_delete.rst
+
+
+create
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_create.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_create_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_create_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create a cookbook**
+
+.. include:: ../../step_knife/step_knife_cookbook_create_with_options.rst
+
+
+delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_delete_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Delete a cookbook**
+
+.. include:: ../../step_knife/step_knife_cookbook_delete.rst
+
+
+download
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_download.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_download_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_download_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Download a cookbook**
+
+.. include:: ../../step_knife/step_knife_cookbook_download.rst
+
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_list_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_list_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View a list of cookbooks**
+
+.. include:: ../../step_knife/step_knife_cookbook_list.rst
+
+
+metadata
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_metadata.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_metadata_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_metadata_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Generate metadata**
+
+.. include:: ../../step_knife/step_knife_cookbook_metadata.rst
+
+
+metadata from file
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_metadata_from_file.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_metadata_from_file_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View metadata**
+
+.. include:: ../../step_knife/step_knife_cookbook_metadata_from_file.rst
+
+
+show
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_show.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_show_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_show_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Show cookbook data**
+
+.. include:: ../../step_knife/step_knife_cookbook_show_cookbook_data.rst
+
+**Show cookbook versions**
+
+.. include:: ../../step_knife/step_knife_cookbook_show_cookbook_versions.rst
+
+**Show a cookbook version**
+
+.. include:: ../../step_knife/step_knife_cookbook_show_cookbook_version.rst
+
+**Show cookbook data as JSON**
+
+.. include:: ../../step_knife/step_knife_common_view_json.rst
+
+
+test
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_test.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_test_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_test_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Test a cookbook**
+
+.. include:: ../../step_knife/step_knife_cookbook_test.rst
+
+
+upload
+=====================================================
+.. include:: ../../includes_knife/includes_knife_cookbook_upload.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_upload_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_cookbook_upload_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Upload a cookbook**
+
+.. include:: ../../step_knife/step_knife_cookbook_upload.rst
+
+**Freeze a cookbook**
+
+.. include:: ../../step_knife/step_knife_cookbook_upload_freeze.rst
+
+.. include:: ../../step_knife/step_knife_cookbook_upload_force.rst
diff --git a/distro/common/html/_sources/knife_cookbook_site.txt b/distro/common/html/_sources/knife_cookbook_site.txt
new file mode 100644
index 0000000000..92fadaa819
--- /dev/null
+++ b/distro/common/html/_sources/knife_cookbook_site.txt
@@ -0,0 +1,157 @@
+=====================================================
+knife cookbook site
+=====================================================
+
+.. include:: ../../includes_api_cookbooks_site/includes_api_cookbooks_site.rst
+
+.. include:: ../../includes_knife/includes_knife_site_cookbook.rst
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+download
+=====================================================
+.. include:: ../../includes_knife/includes_knife_site_cookbook_download.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_download_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_download_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Download a cookbook**
+
+.. include:: ../../step_knife/step_knife_site_cookbook_download.rst
+
+install
+=====================================================
+.. include:: ../../includes_knife/includes_knife_site_cookbook_install.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_install_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_install_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Install a cookbook**
+
+.. include:: ../../step_knife/step_knife_site_cookbook_install.rst
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_site_cookbook_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_list_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_list_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View a list of cookbooks**
+
+.. include:: ../../step_knife/step_knife_site_cookbook_list.rst
+
+search
+=====================================================
+.. include:: ../../includes_knife/includes_knife_site_cookbook_search.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_search_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Search for cookbooks**
+
+.. include:: ../../step_knife/step_knife_site_cookbook_search.rst
+
+share
+=====================================================
+.. include:: ../../includes_knife/includes_knife_site_cookbook_share.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_share_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_share_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Share a cookbook**
+
+.. include:: ../../step_knife/step_knife_site_cookbook_share.rst
+
+
+show
+=====================================================
+.. include:: ../../includes_knife/includes_knife_site_cookbook_show.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_show_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_show_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Show cookbook data**
+
+.. include:: ../../step_knife/step_knife_site_cookbook_show.rst
+
+**Show cookbook data as JSON**
+
+.. include:: ../../step_knife/step_knife_common_view_json.rst
+
+
+unshare
+=====================================================
+.. include:: ../../includes_knife/includes_knife_site_cookbook_unshare.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_site_cookbook_unshare_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Unshare a cookbook**
+
+.. include:: ../../step_knife/step_knife_site_cookbook_unshare.rst
+
+
diff --git a/distro/common/html/_sources/knife_data_bag.txt b/distro/common/html/_sources/knife_data_bag.txt
new file mode 100644
index 0000000000..32888e6f8b
--- /dev/null
+++ b/distro/common/html/_sources/knife_data_bag.txt
@@ -0,0 +1,160 @@
+=====================================================
+knife data bag
+=====================================================
+
+.. include:: ../../includes_data_bag/includes_data_bag.rst
+
+.. include:: ../../includes_data_bag/includes_data_bag_encryption.rst
+
+.. include:: ../../includes_knife/includes_knife_data_bag.rst
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+create
+=====================================================
+.. include:: ../../includes_knife/includes_knife_data_bag_create.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_create_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_create_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create a data bag**
+
+.. include:: ../../step_knife/step_knife_data_bag_create.rst
+
+delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_data_bag_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_delete_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Delete a data bag**
+
+.. include:: ../../step_knife/step_knife_data_bag_delete.rst
+
+**Delete a data bag item**
+
+.. include:: ../../step_knife/step_knife_data_bag_delete_item.rst
+
+edit
+=====================================================
+.. include:: ../../includes_knife/includes_knife_data_bag_edit.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_edit_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_edit_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Edit a data bag**
+
+.. include:: ../../step_knife/step_knife_data_bag_edit.rst
+
+**Edit a data bag item**
+
+.. include:: ../../step_knife/step_knife_data_bag_edit_item.rst
+
+from file
+=====================================================
+.. include:: ../../includes_knife/includes_knife_data_bag_from_file.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_from_file_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_from_file_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create a data bag from a file**
+
+.. include:: ../../step_knife/step_knife_data_bag_from_file_create.rst
+
+**Create an encrypted data bag from a file**
+
+.. include:: ../../step_knife/step_knife_data_bag_from_file_create_encrypted.rst
+
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_data_bag_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_list_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_list_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View a list of data bags**
+
+.. include:: ../../step_knife/step_knife_data_bag_list.rst
+
+show
+=====================================================
+.. include:: ../../includes_knife/includes_knife_data_bag_show.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_show_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_data_bag_show_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Show a data bag**
+
+.. include:: ../../step_knife/step_knife_data_bag_show.rst
+
+**Show a data bag item**
+
+.. include:: ../../step_knife/step_knife_data_bag_show_item.rst
+
+**Show a data bag, encrypted**
+
+.. include:: ../../step_knife/step_knife_data_bag_show_item_encrypted.rst
+
+**Show a data bag, decrypted**
+
+.. include:: ../../step_knife/step_knife_data_bag_show_item_decrypted.rst
+
+**Show a data bag as JSON**
+
+.. include:: ../../step_knife/step_knife_data_bag_show_as_json.rst \ No newline at end of file
diff --git a/distro/common/html/_sources/knife_delete.txt b/distro/common/html/_sources/knife_delete.txt
new file mode 100644
index 0000000000..55e239792a
--- /dev/null
+++ b/distro/common/html/_sources/knife_delete.txt
@@ -0,0 +1,26 @@
+=====================================================
+knife delete
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_delete.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_delete_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_delete_options.rst
+
+Examples
+=====================================================
+None.
+
+
+
+
+
+
+
diff --git a/distro/common/html/_sources/knife_deps.txt b/distro/common/html/_sources/knife_deps.txt
new file mode 100644
index 0000000000..b9c7da5e9d
--- /dev/null
+++ b/distro/common/html/_sources/knife_deps.txt
@@ -0,0 +1,61 @@
+=====================================================
+knife deps
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_deps.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_deps_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_deps_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Find dependencies for a node**
+
+.. include:: ../../step_knife/step_knife_deps_node.rst
+
+**Find dependencies for a role**
+
+.. include:: ../../step_knife/step_knife_deps_role.rst
+
+**Find dependencies for a cookbook**
+
+.. include:: ../../step_knife/step_knife_deps_cookbook.rst
+
+**Find dependencies for an environment**
+
+.. include:: ../../step_knife/step_knife_deps_environment.rst
+
+**Find dependencies for a combination of nodes, roles, and so on**
+
+.. include:: ../../step_knife/step_knife_deps_combo.rst
+
+**Use a wildcard**
+
+.. include:: ../../step_knife/step_knife_deps_wildcard.rst
+
+**Return as tree**
+
+.. include:: ../../step_knife/step_knife_deps_return_as_tree.rst
+
+**Pass knife deps output to knife upload**
+
+.. include:: ../../step_knife/step_knife_deps_pass_output_to_knife_upload.rst
+
+**Pass knife deps output to knife xargs**
+
+.. include:: ../../step_knife/step_knife_deps_pass_output_to_knife_xargs.rst
+
+
+
+
+
+
diff --git a/distro/common/html/_sources/knife_diff.txt b/distro/common/html/_sources/knife_diff.txt
new file mode 100644
index 0000000000..de467b3887
--- /dev/null
+++ b/distro/common/html/_sources/knife_diff.txt
@@ -0,0 +1,34 @@
+=====================================================
+knife diff
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_diff.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_diff_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_diff_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Compare files that contain JSON data**
+
+.. include:: ../../step_knife/step_knife_diff_compare_json_files.rst
+
+**Compare the chef-repo and the server**
+
+.. include:: ../../step_knife/step_knife_diff_compare_repo_and_server.rst
+
+**Compare, then return results**
+
+.. include:: ../../step_knife/step_knife_diff_compare_then_return_results.rst
+
+
+
diff --git a/distro/common/html/_sources/knife_download.txt b/distro/common/html/_sources/knife_download.txt
new file mode 100644
index 0000000000..d2497b7d3a
--- /dev/null
+++ b/distro/common/html/_sources/knife_download.txt
@@ -0,0 +1,44 @@
+=====================================================
+knife download
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_download.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_download_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_download_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Download the entire chef-repo**
+
+.. include:: ../../step_knife/step_knife_download_repository.rst
+
+**Download the /cookbooks directory**
+
+.. include:: ../../step_knife/step_knife_download_directory_cookbooks.rst
+
+**Download the /environments directory**
+
+.. include:: ../../step_knife/step_knife_download_directory_environments.rst
+
+**Download an environment**
+
+.. include:: ../../step_knife/step_knife_download_directory_environment.rst
+
+**Download the /roles directory**
+
+.. include:: ../../step_knife/step_knife_download_directory_roles.rst
+
+**Download cookbooks and roles**
+
+.. include:: ../../step_knife/step_knife_download_directory_cookbooks_and_role.rst
+
diff --git a/distro/common/html/_sources/knife_edit.txt b/distro/common/html/_sources/knife_edit.txt
new file mode 100644
index 0000000000..d9e44f44bc
--- /dev/null
+++ b/distro/common/html/_sources/knife_edit.txt
@@ -0,0 +1,26 @@
+=====================================================
+knife edit
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_edit.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_edit_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_edit_options.rst
+
+Examples
+=====================================================
+None.
+
+
+
+
+
+
+
diff --git a/distro/common/html/_sources/knife_environment.txt b/distro/common/html/_sources/knife_environment.txt
new file mode 100644
index 0000000000..a16e102ea0
--- /dev/null
+++ b/distro/common/html/_sources/knife_environment.txt
@@ -0,0 +1,158 @@
+=====================================================
+knife environment
+=====================================================
+
+.. include:: ../../includes_environment/includes_environment.rst
+
+.. include:: ../../includes_knife/includes_knife_environment.rst
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+compare
+=====================================================
+.. include:: ../../includes_knife/includes_knife_environment_compare.rst
+
+**Syntax**
+
+.. include:: ../../includes_knife/includes_knife_environment_compare_syntax.rst
+
+**Options**
+
+.. include:: ../../includes_knife/includes_knife_environment_compare_options.rst
+
+**Example**
+
+.. include:: ../../step_knife/step_knife_environment_compare_single.rst
+
+.. include:: ../../step_knife/step_knife_environment_compare_multiple.rst
+
+.. include:: ../../step_knife/step_knife_environment_compare_all.rst
+
+create
+=====================================================
+.. include:: ../../includes_knife/includes_knife_environment_create.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_create_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_create_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create an environment**
+
+.. include:: ../../step_knife/step_knife_environment_create.rst
+
+
+delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_environment_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Delete an environment**
+
+.. include:: ../../step_knife/step_knife_environment_delete.rst
+
+
+edit
+=====================================================
+.. include:: ../../includes_knife/includes_knife_environment_edit.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_edit_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Edit an environment**
+
+.. include:: ../../step_knife/step_knife_environment_edit.rst
+
+
+from file
+=====================================================
+.. include:: ../../includes_knife/includes_knife_environment_from_file.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_from_file_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_from_file_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create an environment from a JSON file**
+
+.. include:: ../../step_knife/step_knife_environment_from_file.rst
+
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_environment_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_list_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_list_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View a list of environments**
+
+.. include:: ../../step_knife/step_knife_environment_list.rst
+
+
+show
+=====================================================
+.. include:: ../../includes_knife/includes_knife_environment_show.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_show_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_environment_show_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Show environments**
+
+.. include:: ../../step_knife/step_knife_environment_show.rst
+
+**Show environments as JSON**
+
+.. include:: ../../step_knife/step_knife_common_view_json.rst
diff --git a/distro/common/html/_sources/knife_exec.txt b/distro/common/html/_sources/knife_exec.txt
new file mode 100644
index 0000000000..85e7d9f628
--- /dev/null
+++ b/distro/common/html/_sources/knife_exec.txt
@@ -0,0 +1,47 @@
+=====================================================
+knife exec
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_exec.rst
+
+Authenticated API Requests
+=====================================================
+.. include:: ../../includes_knife/includes_knife_exec_authenticated_api_requests.rst
+
+|ruby| Scripts
+=====================================================
+.. include:: ../../includes_knife/includes_knife_exec_ruby.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_exec_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_exec_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Run Ruby scripts**
+
+.. include:: ../../step_knife/step_knife_exec_run_ruby_scripts.rst
+
+**Chef Knife status**
+
+.. include:: ../../step_knife/step_knife_exec_check_knife_status.rst
+
+**List available free memory**
+
+.. include:: ../../step_knife/step_knife_exec_list_available_free_memory.rst
+
+**List available search indexes**
+
+.. include:: ../../step_knife/step_knife_exec_list_available_search_indexes.rst
+
+**Query for multiple attributes**
+
+.. include:: ../../step_knife/step_knife_exec_query_for_multiple_attributes.rst
diff --git a/distro/common/html/_sources/knife_index_rebuild.txt b/distro/common/html/_sources/knife_index_rebuild.txt
new file mode 100644
index 0000000000..3107f89275
--- /dev/null
+++ b/distro/common/html/_sources/knife_index_rebuild.txt
@@ -0,0 +1,21 @@
+=====================================================
+knife index rebuild
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_index_rebuild.rst
+
+.. note:: This subcommand ONLY works when run against the open source |chef server| version 10.x. This subcommand will NOT run against open source |chef server| 11, |chef server oec| (including hosted |chef server oec|), or |chef private|.
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_index_rebuild_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+|no_options|
+
+Examples
+=====================================================
+None. \ No newline at end of file
diff --git a/distro/common/html/_sources/knife_list.txt b/distro/common/html/_sources/knife_list.txt
new file mode 100644
index 0000000000..bad0be1e09
--- /dev/null
+++ b/distro/common/html/_sources/knife_list.txt
@@ -0,0 +1,33 @@
+=====================================================
+knife list
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_list.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_list_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_list_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**List roles**
+
+.. include:: ../../step_knife/step_knife_list_roles.rst
+
+**List roles and environments**
+
+.. include:: ../../step_knife/step_knife_list_roles_and_environments.rst
+
+**List everything**
+
+.. include:: ../../step_knife/step_knife_list_everything.rst
+
+
diff --git a/distro/common/html/_sources/knife_node.txt b/distro/common/html/_sources/knife_node.txt
new file mode 100644
index 0000000000..165db5079f
--- /dev/null
+++ b/distro/common/html/_sources/knife_node.txt
@@ -0,0 +1,250 @@
+=====================================================
+knife node
+=====================================================
+
+.. include:: ../../includes_node/includes_node.rst
+
+.. include:: ../../includes_knife/includes_knife_node.rst
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+
+bulk delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_node_bulk_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_bulk_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Bulk delete nodes**
+
+.. include:: ../../step_knife/step_knife_node_bulk_delete.rst
+
+
+create
+=====================================================
+.. include:: ../../includes_knife/includes_knife_node_create.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_create_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create a node**
+
+.. include:: ../../step_knife/step_knife_node_create.rst
+
+
+delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_node_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Delete a node**
+
+.. include:: ../../step_knife/step_knife_node_delete.rst
+
+
+edit
+=====================================================
+.. include:: ../../includes_knife/includes_knife_node_edit.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_edit_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_edit_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Edit a node**
+
+.. include:: ../../step_knife/step_knife_node_edit.rst
+
+
+from file
+=====================================================
+.. include:: ../../includes_knife/includes_knife_node_from_file.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_from_file_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create a node using a JSON file**
+
+.. include:: ../../step_knife/step_knife_node_from_file.rst
+
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_node_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_list_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_list_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View a list of nodes**
+
+.. include:: ../../step_knife/step_knife_node_list_all.rst
+
+
+run_list add
+=====================================================
+.. include:: ../../includes_node/includes_node_run_list.rst
+
+.. include:: ../../includes_knife/includes_knife_node_run_list_add.rst
+
+.. include:: ../../includes_node/includes_node_run_list_format.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_run_list_add_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_run_list_add_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Add a role**
+
+.. include:: ../../step_knife/step_knife_node_run_list_add_role.rst
+
+**Add roles and recipes**
+
+.. include:: ../../step_knife/step_knife_node_run_list_add_roles_and_recipes.rst
+
+**Add a recipe with a FQDN**
+
+.. include:: ../../step_knife/step_knife_node_run_list_add_recipe_with_fqdn.rst
+
+**Add a recipe with a cookbook**
+
+.. include:: ../../step_knife/step_knife_node_run_list_add_recipe_with_cookbook.rst
+
+**Add the default recipe**
+
+.. include:: ../../step_knife/step_knife_node_run_list_add_default_recipe.rst
+
+
+run_list remove
+=====================================================
+.. include:: ../../includes_knife/includes_knife_node_run_list_remove.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_run_list_remove_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Remove a role**
+
+.. include:: ../../step_knife/step_knife_node_run_list_remove_role.rst
+
+**Remove a run-list**
+
+.. include:: ../../step_knife/step_knife_node_run_list_remove_run_list.rst
+
+
+show
+=====================================================
+.. include:: ../../includes_knife/includes_knife_node_show.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_show_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_node_show_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Show all data about nodes**
+
+.. include:: ../../step_knife/step_knife_node_show_all_data.rst
+
+**Show basic information about nodes**
+
+.. include:: ../../step_knife/step_knife_node_show_all_data_basic.rst
+
+**Show all data about nodes, truncated**
+
+.. include:: ../../step_knife/step_knife_node_show_all_data_truncated.rst
+
+**Show attributes**
+
+.. include:: ../../step_knife/step_knife_node_show_attribute.rst
+
+**Show the FQDN**
+
+.. include:: ../../step_knife/step_knife_node_show_fqdn.rst
+
+**Show a run-list**
+
+.. include:: ../../step_knife/step_knife_node_show_run_list.rst
+
+**Show as JSON data**
+
+.. include:: ../../step_knife/step_knife_common_view_json.rst
+
+**Show as raw JSON data**
+
+.. include:: ../../step_knife/step_knife_common_view_json_raw.rst
diff --git a/distro/common/html/_sources/knife_raw.txt b/distro/common/html/_sources/knife_raw.txt
new file mode 100644
index 0000000000..3a27c0456a
--- /dev/null
+++ b/distro/common/html/_sources/knife_raw.txt
@@ -0,0 +1,35 @@
+=====================================================
+knife raw
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_raw.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_raw_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_raw_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**View a client**
+
+.. include:: ../../step_knife/step_knife_raw_view_client.rst
+
+**View a node**
+
+.. include:: ../../step_knife/step_knife_raw_view_node.rst
+
+**Delete a data bag**
+
+.. include:: ../../step_knife/step_knife_raw_delete_data_bag.rst
+
+
+
+
diff --git a/distro/common/html/_sources/knife_recipe_list.txt b/distro/common/html/_sources/knife_recipe_list.txt
new file mode 100644
index 0000000000..51d8bad845
--- /dev/null
+++ b/distro/common/html/_sources/knife_recipe_list.txt
@@ -0,0 +1,23 @@
+=====================================================
+knife recipe list
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_recipe_list.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_recipe_list_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+|no_options|
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**View a list of recipes**
+
+.. include:: ../../step_knife/step_knife_recipe_list.rst
diff --git a/distro/common/html/_sources/knife_role.txt b/distro/common/html/_sources/knife_role.txt
new file mode 100644
index 0000000000..edd218ddc6
--- /dev/null
+++ b/distro/common/html/_sources/knife_role.txt
@@ -0,0 +1,157 @@
+=====================================================
+knife role
+=====================================================
+
+.. include:: ../../includes_role/includes_role.rst
+
+.. include:: ../../includes_knife/includes_knife_role.rst
+
+.. note:: To add a role to a node and then build out the run-list for that node, use the :doc:`knife node </knife_node>` sub-command and its ``run_list add`` argument.
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+bulk delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_role_bulk_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_bulk_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Bulk delete roles**
+
+.. include:: ../../step_knife/step_knife_role_bulk_delete.rst
+
+create
+=====================================================
+.. include:: ../../includes_knife/includes_knife_role_create.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_create_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_create_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create a role**
+
+.. include:: ../../step_knife/step_knife_role_create.rst
+
+delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_role_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Delete a role**
+
+.. include:: ../../step_knife/step_knife_role_delete.rst
+
+edit
+=====================================================
+.. include:: ../../includes_knife/includes_knife_role_edit.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_edit_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Edit a role**
+
+.. include:: ../../step_knife/step_knife_role_edit.rst
+
+from file
+=====================================================
+.. include:: ../../includes_knife/includes_knife_role_from_file.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_from_file_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create a role using JSON data**
+
+.. include:: ../../step_knife/step_knife_role_from_file.rst
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_role_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_list_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_list_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View a list of roles**
+
+.. include:: ../../step_knife/step_knife_role_list.rst
+
+show
+=====================================================
+.. include:: ../../includes_knife/includes_knife_role_show.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_show_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_role_show_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Show as JSON data**
+
+.. include:: ../../step_knife/step_knife_common_view_json.rst
+
+**Show as raw JSON data**
+
+.. include:: ../../step_knife/step_knife_common_view_json_raw.rst
+
+
diff --git a/distro/common/html/_sources/knife_search.txt b/distro/common/html/_sources/knife_search.txt
new file mode 100644
index 0000000000..c55ffc0308
--- /dev/null
+++ b/distro/common/html/_sources/knife_search.txt
@@ -0,0 +1,53 @@
+=====================================================
+knife search
+=====================================================
+
+.. include:: ../../includes_search/includes_search.rst
+
+.. include:: ../../includes_knife/includes_knife_search.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_search_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_search_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Search by platform ID**
+
+.. include:: ../../step_knife/step_knife_search_by_platform_ids.rst
+
+**Search by instance type**
+
+.. include:: ../../step_knife/step_knife_search_by_platform_instance_type.rst
+
+**Search by node**
+
+.. include:: ../../step_knife/step_knife_search_by_node.rst
+
+**Search by node and environment**
+
+.. include:: ../../step_knife/step_knife_search_by_node_and_environment.rst
+
+**Search for nested attributes**
+
+.. include:: ../../step_knife/step_knife_search_by_nested_attribute.rst
+
+**Search for multiple attributes**
+
+.. include:: ../../step_knife/step_knife_search_by_query_for_many_attributes.rst
+
+**Search for nested attributes using a search query**
+
+.. include:: ../../step_knife/step_knife_search_by_query_for_nested_attribute.rst
+
+**Use a test query**
+
+.. include:: ../../step_knife/step_knife_search_test_query_for_ssh.rst
diff --git a/distro/common/html/_sources/knife_show.txt b/distro/common/html/_sources/knife_show.txt
new file mode 100644
index 0000000000..c9ca6958e3
--- /dev/null
+++ b/distro/common/html/_sources/knife_show.txt
@@ -0,0 +1,27 @@
+=====================================================
+knife show
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_show.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_show_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_show_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Show all cookbooks**
+
+.. include:: ../../step_knife/step_knife_show_all_cookbooks.rst
+
+**Show roles and environments**
+
+.. include:: ../../step_knife/step_knife_show_roles_and_environments.rst \ No newline at end of file
diff --git a/distro/common/html/_sources/knife_ssh.txt b/distro/common/html/_sources/knife_ssh.txt
new file mode 100644
index 0000000000..bc7f4e5977
--- /dev/null
+++ b/distro/common/html/_sources/knife_ssh.txt
@@ -0,0 +1,43 @@
+=====================================================
+knife ssh
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_ssh.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_ssh_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_ssh_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Find server uptime**
+
+.. include:: ../../step_knife/step_knife_ssh_find_uptime.rst
+
+**Run the chef-client on all nodes**
+
+.. include:: ../../step_knife/step_knife_ssh_run_chef_client_on_all_nodes.rst
+
+**Force a chef-client run**
+
+.. include:: ../../step_knife/step_knife_ssh_force_chef_run.rst
+
+**Run a command based on search query**
+
+.. include:: ../../step_knife/step_knife_ssh_query_for_nodes.rst
+
+**Upgrade all nodes**
+
+.. include:: ../../step_knife/step_knife_ssh_upgrade_nodes.rst
+
+**Specify the shell type**
+
+.. include:: ../../step_knife/step_knife_ssh_shell_type.rst
diff --git a/distro/common/html/_sources/knife_status.txt b/distro/common/html/_sources/knife_status.txt
new file mode 100644
index 0000000000..194b985f67
--- /dev/null
+++ b/distro/common/html/_sources/knife_status.txt
@@ -0,0 +1,37 @@
+=====================================================
+knife status
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_status.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_status_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_status_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**View status, include run-lists**
+
+.. include:: ../../step_knife/step_knife_status_include_run_lists.rst
+
+**View status using a date range**
+
+.. include:: ../../step_knife/step_knife_status_past_hour.rst
+
+**View status using a query**
+
+.. include:: ../../step_knife/step_knife_status_returned_by_query.rst
+
+**View status for all nodes**
+
+.. include:: ../../step_knife/step_knife_status_view_for_all_nodes.rst
+
+
diff --git a/distro/common/html/_sources/knife_tag.txt b/distro/common/html/_sources/knife_tag.txt
new file mode 100644
index 0000000000..6fea1e321d
--- /dev/null
+++ b/distro/common/html/_sources/knife_tag.txt
@@ -0,0 +1,69 @@
+=====================================================
+knife tag
+=====================================================
+
+.. include:: ../../includes_chef/includes_chef_tags.rst
+
+.. include:: ../../includes_knife/includes_knife_tag.rst
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+create
+=====================================================
+.. include:: ../../includes_knife/includes_knife_tag_create.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_tag_create_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create tags**
+
+.. include:: ../../step_knife/step_knife_tag_create.rst
+
+delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_tag_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_tag_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Delete tags**
+
+.. include:: ../../step_knife/step_knife_tag_delete.rst
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_tag_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_tag_list_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**View a list of tags**
+
+.. include:: ../../step_knife/step_knife_tag_list.rst
diff --git a/distro/common/html/_sources/knife_upload.txt b/distro/common/html/_sources/knife_upload.txt
new file mode 100644
index 0000000000..bd37725108
--- /dev/null
+++ b/distro/common/html/_sources/knife_upload.txt
@@ -0,0 +1,49 @@
+=====================================================
+knife upload
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_upload.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_upload_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_upload_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Upload the entire chef-repo**
+
+.. include:: ../../step_knife/step_knife_upload_repository.rst
+
+**Upload the /cookbooks directory**
+
+.. include:: ../../step_knife/step_knife_upload_directory_cookbooks.rst
+
+**Upload the /environments directory**
+
+.. include:: ../../step_knife/step_knife_upload_directory_environments.rst
+
+**Upload a single environment**
+
+.. include:: ../../step_knife/step_knife_upload_directory_environment.rst
+
+**Upload the /roles directory**
+
+.. include:: ../../step_knife/step_knife_upload_directory_roles.rst
+
+**Upload cookbooks and roles**
+
+.. include:: ../../step_knife/step_knife_upload_directory_cookbooks_and_role.rst
+
+**Use output of knife deps to pass command to knife upload**
+
+.. include:: ../../step_knife/step_knife_upload_pass_to_knife_deps.rst
+
+
diff --git a/distro/common/html/_sources/knife_user.txt b/distro/common/html/_sources/knife_user.txt
new file mode 100644
index 0000000000..1642d30f7b
--- /dev/null
+++ b/distro/common/html/_sources/knife_user.txt
@@ -0,0 +1,127 @@
+=====================================================
+knife user
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_user.rst
+
+.. note:: This subcommand ONLY works when run against the open source |chef server| and will not run against |chef server oec| (including hosted |chef server oec|), or |chef private|.
+
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+create
+=====================================================
+.. include:: ../../includes_knife/includes_knife_user_create.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_create_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_create_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Create a user**
+
+.. include:: ../../step_knife/step_knife_user_create.rst
+
+delete
+=====================================================
+.. include:: ../../includes_knife/includes_knife_user_delete.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_delete_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Delete a user**
+
+.. include:: ../../step_knife/step_knife_user_delete.rst
+
+edit
+=====================================================
+.. include:: ../../includes_knife/includes_knife_user_edit.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_edit_syntax.rst
+
+Options
+-----------------------------------------------------
+|no_options|
+
+Examples
+-----------------------------------------------------
+None.
+
+
+list
+=====================================================
+.. include:: ../../includes_knife/includes_knife_user_list.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_list_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_list_options.rst
+
+Examples
+-----------------------------------------------------
+None.
+
+reregister
+=====================================================
+.. include:: ../../includes_knife/includes_knife_user_reregister.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_reregister_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_reregister_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Regenerate the RSA key-pair**
+
+.. include:: ../../step_knife/step_knife_user_reregister.rst
+
+show
+=====================================================
+.. include:: ../../includes_knife/includes_knife_user_show.rst
+
+Syntax
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_show_syntax.rst
+
+Options
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_user_show_options.rst
+
+Examples
+-----------------------------------------------------
+The following examples show how to use this |knife| subcommand:
+
+**Show user data**
+
+.. include:: ../../step_knife/step_knife_user_show.rst
+
+**Show user data as JSON**
+
+.. include:: ../../step_knife/step_knife_user_show_json.rst
+
diff --git a/distro/common/html/_sources/knife_using.txt b/distro/common/html/_sources/knife_using.txt
new file mode 100644
index 0000000000..9484b167c4
--- /dev/null
+++ b/distro/common/html/_sources/knife_using.txt
@@ -0,0 +1,43 @@
+=====================================================
+Working with Knife
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_using.rst
+
+JSON Data Format
+=====================================================
+.. include:: ../../includes_knife/includes_knife_using_json.rst
+
+Set the Text Editor
+-----------------------------------------------------
+.. include:: ../../step_knife/step_knife_common_set_editor.rst
+
+Using Quotes
+=====================================================
+.. include:: ../../includes_knife/includes_knife_using_quotes.rst
+
+Sub-commands
+=====================================================
+.. include:: ../../includes_knife/includes_knife_using_subcommands.rst
+
+Verb Sub-commands
+=====================================================
+.. include:: ../../includes_knife/includes_knife_verbs.rst
+
+Wildcard Search
+-----------------------------------------------------
+.. include:: ../../includes_knife/includes_knife_verbs_wildcard.rst
+
+Plug-ins
+=====================================================
+.. include:: ../../includes_knife/includes_knife_using_plugins.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_using_syntax.rst
+
+Many Users, Same Repo
+=====================================================
+.. include:: ../../includes_repository/includes_repository_many_users_same_repo.rst
+
+
diff --git a/distro/common/html/_sources/knife_xargs.txt b/distro/common/html/_sources/knife_xargs.txt
new file mode 100644
index 0000000000..852ba282aa
--- /dev/null
+++ b/distro/common/html/_sources/knife_xargs.txt
@@ -0,0 +1,30 @@
+=====================================================
+knife xargs
+=====================================================
+
+.. include:: ../../includes_knife/includes_knife_xargs.rst
+
+Syntax
+=====================================================
+.. include:: ../../includes_knife/includes_knife_xargs_syntax.rst
+
+Options
+=====================================================
+.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
+
+.. include:: ../../includes_knife/includes_knife_xargs_options.rst
+
+Examples
+=====================================================
+The following examples show how to use this |knife| subcommand:
+
+**Use output of knife deps to pass command to knife xargs**
+
+.. include:: ../../step_knife/step_knife_xargs_pass_command_to.rst
+
+
+
+
+
+
+
diff --git a/distro/common/html/_static/ajax-loader.gif b/distro/common/html/_static/ajax-loader.gif
new file mode 100644
index 0000000000..61faf8cab2
--- /dev/null
+++ b/distro/common/html/_static/ajax-loader.gif
Binary files differ
diff --git a/distro/common/html/_static/basic.css b/distro/common/html/_static/basic.css
new file mode 100644
index 0000000000..43e8bafaf3
--- /dev/null
+++ b/distro/common/html/_static/basic.css
@@ -0,0 +1,540 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+ width: 100%;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+ list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+ width: 170px;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+ width: 30px;
+}
+
+img {
+ border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li div.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+ width: 90%;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+div.modindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+ visibility: visible;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+.field-list ul {
+ padding-left: 1em;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.align-right {
+ text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px 7px 0 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+ border: 1px solid #ccc;
+ padding: 7px 7px 0 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+ padding: 1px 8px 1px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+ list-style: decimal;
+}
+
+ol.loweralpha {
+ list-style: lower-alpha;
+}
+
+ol.upperalpha {
+ list-style: upper-alpha;
+}
+
+ol.lowerroman {
+ list-style: lower-roman;
+}
+
+ol.upperroman {
+ list-style: upper-roman;
+}
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd p {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+dt:target, .highlighted {
+ background-color: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+.refcount {
+ color: #060;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+.footnote:target {
+ background-color: #ffa;
+}
+
+.line-block {
+ display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.line-block .line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+ font-family: sans-serif;
+}
+
+.accelerator {
+ text-decoration: underline;
+}
+
+.classifier {
+ font-style: oblique;
+}
+
+abbr, acronym {
+ border-bottom: dotted 1px;
+ cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+ overflow-y: hidden; /* fixes display issues on Chrome browsers */
+}
+
+td.linenos pre {
+ padding: 5px 0px;
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ margin-left: 0.5em;
+}
+
+table.highlighttable td {
+ padding: 0 0.5em 0 0.5em;
+}
+
+tt.descname {
+ background-color: transparent;
+ font-weight: bold;
+ font-size: 1.2em;
+}
+
+tt.descclassname {
+ background-color: transparent;
+}
+
+tt.xref, a tt {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+ background-color: transparent;
+}
+
+.viewcode-link {
+ float: right;
+}
+
+.viewcode-back {
+ float: right;
+ font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+ margin: -1px -10px;
+ padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+ vertical-align: middle;
+}
+
+div.body div.math p {
+ text-align: center;
+}
+
+span.eqno {
+ float: right;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ #top-link {
+ display: none;
+ }
+} \ No newline at end of file
diff --git a/distro/common/html/_static/chef.css b/distro/common/html/_static/chef.css
new file mode 100644
index 0000000000..62ff55d310
--- /dev/null
+++ b/distro/common/html/_static/chef.css
@@ -0,0 +1,507 @@
+/*
+ * opscode.css_t
+ * ~~~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- opscode theme. Originally created by
+ * Opscode for docs.opscode.com.
+ *
+ * :copyright: None.
+ * :license: This work is licensed under a Creative Commons
+ * Attribution 3.0 Unported License
+ *
+ */
+
+/*
+ * Colors
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * #f18a20 is Opscode orange.
+ * #212c35 is Opscode blue.
+ *
+ * #212c35 is used for text color and header colors
+ * #f18a20 for header underlines and border treatments
+ *
+ * Triads for #f18a20: #273fa4 (blue) and #18b246 (green)
+ * Triads for #212c35: #524a31 (tan) and #523a31 (salmon)
+ * Triads should only be used to accent the Opscode blue or orange
+ *
+ * For div.admonition: #6bb1e1
+ * For div.warning: #fcb614
+ *
+ * For subheaders and other treatments: #7c858c, then #b5bec6, then #d8dde3
+ * For table headers: #7c858c (with #000000 text color)
+ * For links: #4d97c6, rollover #f18a20
+ *
+ * Alternate colors in the official color palette (but try not to use): #59b6b2, #6d3528
+ *
+ * For regular text: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
+ * For monospace text: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+ *
+ * For div.related, the 8px ensures that the | is spaced evenly.
+ *
+ */
+
+@import url("basic.css");
+
+/* -- the background color for the whole page and the borders for the topic page, header, footer */
+/* -- IMPORTANT -- color is the color of the text on div.document; must be black or Opscode blue */
+
+body {
+ font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
+ font-size: 14px;
+ letter-spacing: -0.00em;
+ line-height: 150%;
+ text-align: center;
+ background-color: #7c858c;
+ color: #212c35;
+ padding: 0;
+ border: 4px solid #7c858c;
+ border-top: 0px solid #7c858c;
+ border-bottom: 0px solid #7c858c;
+ margin: 0px 80px 0px 80px;
+ min-width: 740px;
+}
+
+
+
+/* -- the actual topic background, must be white all the time no exceptions */
+
+div.document {
+ background-color: #ffffff;
+ text-align: left;
+ background-image: url(contents.png);
+ background-repeat: repeat-x;
+}
+
+
+
+/* -- the vertical line between the topics and the TOC */
+
+div.bodywrapper {
+ margin: 0 240px 0 0;
+ border-right: 4px solid #d8dde3;
+}
+
+div.body {
+ margin: 0;
+ padding: 0.5em 20px 20px 20px;
+}
+
+div.related {
+ font-size: 1em;
+}
+
+/* -- the borders above and below the header and footer */
+
+div.related ul {
+ background-color: #ffffff;
+ height: 1.8em;
+ border-top: 4px solid #d8dde3;
+ border-bottom: 4px solid #4d97c6;
+}
+
+div.related ul li {
+ margin: 0;
+ padding: 0;
+ height: 2em;
+ float: left;
+}
+
+div.related ul li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+
+
+/* -- the Sphinx-specific navigation text located just below the header and just above the footer */
+
+div.related ul li a {
+ margin: 0;
+ padding: 0 8px 0 5px;
+ line-height: 1.75em;
+ color: #212c35;
+}
+
+div.related ul li a:hover {
+ color: #f18a20;
+}
+
+
+div.sphinxsidebarwrapper {
+ padding: 0;
+}
+
+div.sphinxsidebar {
+ margin: 0;
+ padding: 0.5em 15px 15px 0;
+ width: 210px;
+ float: right;
+ font-size: 1em;
+ text-align: left;
+
+}
+
+
+
+/* -- The colors of the TOC sidebar; h3 is headers, a is the text links and both should be same color */
+
+div.sphinxsidebar h3, div.sphinxsidebar h4 {
+ margin: 1em 0 0.5em 0;
+ font-size: 1em;
+ padding: 0.1em 0 0.1em 0.5em;
+ color: #ffffff;
+ border: 1px solid #ffffff;
+ background-color: #7c858c;
+}
+
+div.sphinxsidebar a {
+ color: #212c35;
+ padding: 0.1em 0 0.1em 0.5em;
+ text-decoration: none;
+}
+
+div.sphinxsidebar h3 a {
+ color: #ffffff;
+}
+
+div.sphinxsidebar ul {
+ padding-left: 1.5em;
+ margin-top: 7px;
+ padding: 0;
+ line-height: 130%;
+}
+
+div.sphinxsidebar ul ul {
+ margin-left: 20px;
+}
+
+
+
+
+/*
+ * footer
+ * ~~~~~~~~~~~~~~~~~~~
+ *
+ */
+
+
+div.footer {
+ background-color: #ffffff;
+ color: #212c35;
+ padding: 3px 5px 3px 5px;
+ clear: both;
+ font-size: 0.8em;
+ text-align: left;
+}
+
+div.footer a {
+ color: #4d97c6;
+ text-decoration: none;
+}
+
+div.footer a:hover {
+ color: #f18a20;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+p {
+ margin: 0.8em 0 0.5em 0;
+}
+
+
+a {
+ color: #4d97c6;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #f18a20;
+}
+
+div.body a {
+ text-decoration: none;
+}
+
+em {
+ font-style: normal;
+}
+
+/* -- header styles, basically Opscode blue with colored underlines and decreasing border bottom sizes */
+
+h1 {
+ margin: 0.5;
+ padding: 0.7em 0 0.3em 0;
+ font-size: 1.75em;
+ color: #212c35;
+ border-bottom:solid 4px #f18a20;
+}
+
+h2 {
+ margin: 1.3em 0 0.2em 0;
+ font-size: 1.55em;
+ color: #212c35;
+ padding: 0.7em 0 0.3em 0;
+ border-bottom:solid 2px #7c858c;
+}
+
+h3 {
+ margin: 1em 0 -0.3em 0;
+ font-size: 1.35em;
+ color: #212c35;
+ padding: 0.7em 0 0.3em 0;
+ border-bottom:solid 1px #7c858c;
+}
+
+h4 {
+ margin: 1em 0 -0.3em 0;
+ font-size: 1.15em;
+ color: #212c35;
+ padding: 0.7em 0 0.3em 0;
+ border-bottom:solid 0px #7c858c;
+}
+
+div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
+ color: #ffffff!important;
+}
+
+h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
+ display: none;
+ margin: 0 0 0 0.3em;
+ padding: 0 0.2em 0 0.2em;
+ color: #ffffff!important;
+}
+
+h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
+h5:hover a.anchor, h6:hover a.anchor {
+ display: inline;
+}
+
+h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
+h5 a.anchor:hover, h6 a.anchor:hover {
+ color: #ffffff;
+ background-color: #ffffff;
+}
+
+
+
+
+a.headerlink {
+ color: #ffffff!important;
+ font-size: 1em;
+ margin-left: 6px;
+ padding: 0 4px 0 4px;
+ text-decoration: none!important;
+}
+
+a.headerlink:hover {
+ background-color: #ffffff;
+ color: #ffffff!important;
+}
+
+cite, code, tt {
+ font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+ font-size: 0.95em;
+ letter-spacing: 0.01em;
+}
+
+
+
+
+
+tt {
+ background-color: #ebecf1;
+ border-bottom: 1px solid #d8dde3;
+ color: #212c35;
+}
+
+tt.descname, tt.descclassname, tt.xref {
+ border: 0;
+}
+
+/* -- has Opscode orange for testing */
+
+hr {
+ border: 1px solid #f18a20;
+ margin: 2em;
+}
+
+/* -- has Opscode orange for testing */
+
+a tt {
+ border: 0;
+ color: #f18a20;
+}
+
+/* -- has Opscode orange for testing */
+
+a tt:hover {
+ color: #f18a20;
+}
+
+/* -- has Opscode orange for testing */
+
+pre {
+ font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+ font-size: 0.95em;
+ letter-spacing: 0.015em;
+ line-height: 120%;
+ padding: 0.5em;
+ border: 0.0px solid #d8dde3;
+ background-color: #ebecf1;
+}
+
+pre a {
+ color: inherit;
+ text-decoration: underline;
+}
+
+td.linenos pre {
+ padding: 0.5em 0;
+}
+
+/* -- has Opscode orange for testing */
+
+div.quotebar {
+ background-color: #f18a20;
+ max-width: 250px;
+ float: right;
+ padding: 2px 7px;
+ border: 1px solid #f18a20;
+}
+
+/* -- has Opscode orange for testing */
+
+div.topic {
+ background-color: #f18a20;
+}
+
+
+/* -- table styles */
+
+table.docutils {
+ border: 0;
+ border-collapse: separate;
+ border-spacing:4px;
+
+}
+
+table.docutils th {
+ padding: 1px 8px 1px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 0px solid #ffffff;
+ background-color: #7c858c;
+ color: #ffffff;
+}
+
+table.docutils td {
+ padding: 5px 5px 5px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px dashed #7c858c;
+}
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+
+
+
+
+
+
+div.admonition, div.warning {
+ font-size: 0.9em;
+ margin: 1em 0 1em 0;
+ border: 1px solid #6bb1e1;
+ background-color: #ffffff;
+ padding: 0;
+}
+
+div.admonition p, div.warning p {
+ margin: 0.5em 1em 0.5em 1em;
+ padding: 0;
+}
+
+div.admonition pre, div.warning pre {
+ margin: 0.4em 1em 0.4em 1em;
+}
+
+div.admonition p.admonition-title,
+div.warning p.admonition-title {
+ margin: 0;
+ padding: 0.1em 0 0.1em 0.5em;
+ color: #ffffff;
+ border-bottom: 1px solid #6bb1e1;
+ font-weight: bold;
+ background-color: #6bb1e1;
+}
+
+
+
+
+div.warning {
+ border: 1px solid #fcb614;
+}
+
+div.warning p.admonition-title {
+ background-color: #fcb614;
+ border-bottom-color: #fcb614;
+}
+
+div.admonition ul, div.admonition ol,
+div.warning ul, div.warning ol {
+ margin: 0.1em 0.5em 0.5em 3em;
+ padding: 0;
+}
+
+
+
+
+div.versioninfo {
+ margin: 1em 0 0 0;
+ border: 1px solid #ffffff;
+ background-color: #ffffff;
+ padding: 8px;
+ line-height: 1.3em;
+ font-size: 0.9em;
+}
+
+
+
+
+.viewcode-back {
+ font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
+}
+
+
+
+
+div.viewcode-block:target {
+ background-color: #ffffff;
+ border-top: 1px solid #ffffff;
+ border-bottom: 1px solid #ffffff;
+} \ No newline at end of file
diff --git a/distro/common/html/_static/chef.ico b/distro/common/html/_static/chef.ico
new file mode 100644
index 0000000000..05e0b7e41c
--- /dev/null
+++ b/distro/common/html/_static/chef.ico
Binary files differ
diff --git a/distro/common/html/_static/chef_html_logo.png b/distro/common/html/_static/chef_html_logo.png
new file mode 100644
index 0000000000..7e0389d95a
--- /dev/null
+++ b/distro/common/html/_static/chef_html_logo.png
Binary files differ
diff --git a/distro/common/html/_static/chef_logo.png b/distro/common/html/_static/chef_logo.png
new file mode 100644
index 0000000000..c711d7677b
--- /dev/null
+++ b/distro/common/html/_static/chef_logo.png
Binary files differ
diff --git a/distro/common/html/_static/comment-bright.png b/distro/common/html/_static/comment-bright.png
new file mode 100644
index 0000000000..551517b8c8
--- /dev/null
+++ b/distro/common/html/_static/comment-bright.png
Binary files differ
diff --git a/distro/common/html/_static/comment-close.png b/distro/common/html/_static/comment-close.png
new file mode 100644
index 0000000000..09b54be46d
--- /dev/null
+++ b/distro/common/html/_static/comment-close.png
Binary files differ
diff --git a/distro/common/html/_static/comment.png b/distro/common/html/_static/comment.png
new file mode 100644
index 0000000000..92feb52b88
--- /dev/null
+++ b/distro/common/html/_static/comment.png
Binary files differ
diff --git a/distro/common/html/_static/contents.png b/distro/common/html/_static/contents.png
new file mode 100644
index 0000000000..7fb82154a1
--- /dev/null
+++ b/distro/common/html/_static/contents.png
Binary files differ
diff --git a/distro/common/html/_static/doctools.js b/distro/common/html/_static/doctools.js
new file mode 100644
index 0000000000..d4619fdfb1
--- /dev/null
+++ b/distro/common/html/_static/doctools.js
@@ -0,0 +1,247 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+ "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+ "profile", "profileEnd"];
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+ return decodeURIComponent(x).replace(/\+/g, ' ');
+}
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+ if (typeof s == 'undefined')
+ s = document.location.search;
+ var parts = s.substr(s.indexOf('?') + 1).split('&');
+ var result = {};
+ for (var i = 0; i < parts.length; i++) {
+ var tmp = parts[i].split('=', 2);
+ var key = jQuery.urldecode(tmp[0]);
+ var value = jQuery.urldecode(tmp[1]);
+ if (key in result)
+ result[key].push(value);
+ else
+ result[key] = [value];
+ }
+ return result;
+};
+
+/**
+ * small function to check if an array contains
+ * a given item.
+ */
+jQuery.contains = function(arr, item) {
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] == item)
+ return true;
+ }
+ return false;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+ function highlight(node) {
+ if (node.nodeType == 3) {
+ var val = node.nodeValue;
+ var pos = val.toLowerCase().indexOf(text);
+ if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
+ var span = document.createElement("span");
+ span.className = className;
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+ document.createTextNode(val.substr(pos + text.length)),
+ node.nextSibling));
+ node.nodeValue = val.substr(0, pos);
+ }
+ }
+ else if (!jQuery(node).is("button, select, textarea")) {
+ jQuery.each(node.childNodes, function() {
+ highlight(this);
+ });
+ }
+ }
+ return this.each(function() {
+ highlight(this);
+ });
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+ init : function() {
+ this.fixFirefoxAnchorBug();
+ this.highlightSearchWords();
+ this.initIndexTable();
+ },
+
+ /**
+ * i18n support
+ */
+ TRANSLATIONS : {},
+ PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+ LOCALE : 'unknown',
+
+ // gettext and ngettext don't access this so that the functions
+ // can safely bound to a different name (_ = Documentation.gettext)
+ gettext : function(string) {
+ var translated = Documentation.TRANSLATIONS[string];
+ if (typeof translated == 'undefined')
+ return string;
+ return (typeof translated == 'string') ? translated : translated[0];
+ },
+
+ ngettext : function(singular, plural, n) {
+ var translated = Documentation.TRANSLATIONS[singular];
+ if (typeof translated == 'undefined')
+ return (n == 1) ? singular : plural;
+ return translated[Documentation.PLURALEXPR(n)];
+ },
+
+ addTranslations : function(catalog) {
+ for (var key in catalog.messages)
+ this.TRANSLATIONS[key] = catalog.messages[key];
+ this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+ this.LOCALE = catalog.locale;
+ },
+
+ /**
+ * add context elements like header anchor links
+ */
+ addContextElements : function() {
+ $('div[id] > :header:first').each(function() {
+ $('<a class="headerlink">\u00B6</a>').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this headline')).
+ appendTo(this);
+ });
+ $('dt[id]').each(function() {
+ $('<a class="headerlink">\u00B6</a>').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this definition')).
+ appendTo(this);
+ });
+ },
+
+ /**
+ * workaround a firefox stupidity
+ */
+ fixFirefoxAnchorBug : function() {
+ if (document.location.hash && $.browser.mozilla)
+ window.setTimeout(function() {
+ document.location.href += '';
+ }, 10);
+ },
+
+ /**
+ * highlight the search words provided in the url in the text
+ */
+ highlightSearchWords : function() {
+ var params = $.getQueryParameters();
+ var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+ if (terms.length) {
+ var body = $('div.body');
+ window.setTimeout(function() {
+ $.each(terms, function() {
+ body.highlightText(this.toLowerCase(), 'highlighted');
+ });
+ }, 10);
+ $('<p class="highlight-link"><a href="javascript:Documentation.' +
+ 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
+ .appendTo($('#searchbox'));
+ }
+ },
+
+ /**
+ * init the domain index toggle buttons
+ */
+ initIndexTable : function() {
+ var togglers = $('img.toggler').click(function() {
+ var src = $(this).attr('src');
+ var idnum = $(this).attr('id').substr(7);
+ $('tr.cg-' + idnum).toggle();
+ if (src.substr(-9) == 'minus.png')
+ $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+ else
+ $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+ }).css('display', '');
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+ togglers.click();
+ }
+ },
+
+ /**
+ * helper function to hide the search marks again
+ */
+ hideSearchWords : function() {
+ $('#searchbox .highlight-link').fadeOut(300);
+ $('span.highlighted').removeClass('highlighted');
+ },
+
+ /**
+ * make the url absolute
+ */
+ makeURL : function(relativeURL) {
+ return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+ },
+
+ /**
+ * get the current relative url
+ */
+ getCurrentURL : function() {
+ var path = document.location.pathname;
+ var parts = path.split(/\//);
+ $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+ if (this == '..')
+ parts.pop();
+ });
+ var url = parts.join('/');
+ return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+ }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+ Documentation.init();
+});
diff --git a/distro/common/html/_static/down-pressed.png b/distro/common/html/_static/down-pressed.png
new file mode 100644
index 0000000000..6f7ad78278
--- /dev/null
+++ b/distro/common/html/_static/down-pressed.png
Binary files differ
diff --git a/distro/common/html/_static/down.png b/distro/common/html/_static/down.png
new file mode 100644
index 0000000000..3003a88770
--- /dev/null
+++ b/distro/common/html/_static/down.png
Binary files differ
diff --git a/distro/common/html/_static/file.png b/distro/common/html/_static/file.png
new file mode 100644
index 0000000000..d18082e397
--- /dev/null
+++ b/distro/common/html/_static/file.png
Binary files differ
diff --git a/distro/common/html/_static/guide.css b/distro/common/html/_static/guide.css
new file mode 100644
index 0000000000..2163fdc4f4
--- /dev/null
+++ b/distro/common/html/_static/guide.css
@@ -0,0 +1,505 @@
+/*
+ * opscode.css_t
+ * ~~~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- opscode theme. Originally created by
+ * Opscode for docs.opscode.com.
+ *
+ * :copyright: None.
+ * :license: This work is licensed under a Creative Commons
+ * Attribution 3.0 Unported License
+ *
+ */
+
+/*
+ * Colors
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * #f18a20 is Opscode orange.
+ * #212c35 is Opscode blue.
+ *
+ * #212c35 is used for text color and header colors
+ * #f18a20 for header underlines and border treatments
+ *
+ * Triads for #f18a20: #273fa4 (blue) and #18b246 (green)
+ * Triads for #212c35: #524a31 (tan) and #523a31 (salmon)
+ * Triads should only be used to accent the Opscode blue or orange
+ *
+ * For div.admonition: #6bb1e1
+ * For div.warning: #fcb614
+ *
+ * For subheaders and other treatments: #7c858c, then #b5bec6, then #d8dde3
+ * For table headers: #7c858c (with #000000 text color)
+ * For links: #6d3528, rollover #59b6b2
+ *
+ * Alternate colors in the official color palette (but try not to use): #59b6b2, #6d3528
+ *
+ * For regular text: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
+ * For monospace text: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+ *
+ * For div.related, the 8px ensures that the | is spaced evenly.
+ *
+ */
+
+@import url("basic.css");
+
+/* -- the background color for the whole page and the borders for the topic page, header, footer */
+/* -- IMPORTANT -- color is the color of the text on div.document; must be black or Opscode blue */
+
+body {
+ font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
+ font-size: 14px;
+ letter-spacing: -0.00em;
+ line-height: 150%;
+ text-align: center;
+ background-color: #7c858c;
+ color: #212c35;
+ padding: 0;
+ border: 4px solid #7c858c;
+ border-top: 0px solid #7c858c;
+ border-bottom: 0px solid #7c858c;
+ margin: 0px 80px 0px 80px;
+ min-width: 740px;
+}
+
+
+
+/* -- the actual topic background, must be white all the time no exceptions */
+
+div.document {
+ background-color: #ffffff;
+ text-align: left;
+ background-image: url(contents.png);
+ background-repeat: repeat-x;
+}
+
+
+
+/* -- the vertical line between the topics and the TOC */
+
+div.bodywrapper {
+ margin: 0 240px 0 0;
+ border-right: 4px solid #d8dde3;
+}
+
+div.body {
+ margin: 0;
+ padding: 0.5em 20px 20px 20px;
+}
+
+div.related {
+ font-size: 1em;
+}
+
+
+
+/* -- the borders above and below the header and footer */
+
+div.related ul {
+ background-color: #ffffff;
+ height: 1.8em;
+ border-top: 4px solid #d8dde3;
+ border-bottom: 4px solid #d8dde3;
+}
+
+div.related ul li {
+ margin: 0;
+ padding: 0;
+ height: 2em;
+ float: left;
+}
+
+div.related ul li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+
+
+/* -- the Sphinx-specific navigation text located just below the header and just above the footer */
+
+div.related ul li a {
+ margin: 0;
+ padding: 0 8px 0 5px;
+ line-height: 1.75em;
+ color: #7c858c;
+}
+
+div.related ul li a:hover {
+ color: #b5bec6;
+}
+
+
+div.sphinxsidebarwrapper {
+ padding: 0;
+}
+
+div.sphinxsidebar {
+ margin: 0;
+ padding: 0.5em 15px 15px 0;
+ width: 210px;
+ float: right;
+ font-size: 1em;
+ text-align: left;
+
+}
+
+
+
+/* -- The colors of the TOC sidebar; h3 is headers, a is the text links and both should be same color */
+
+div.sphinxsidebar h3, div.sphinxsidebar h4 {
+ margin: 1em 0 0.5em 0;
+ font-size: 1em;
+ padding: 0.1em 0 0.1em 0.5em;
+ color: #ffffff;
+ border: 1px solid #ffffff;
+ background-color: #7c858c;
+}
+
+div.sphinxsidebar a {
+ color: #212c35;
+ padding: 0.1em 0 0.1em 0.5em;
+ text-decoration: none;
+}
+
+div.sphinxsidebar h3 a {
+ color: #ffffff;
+}
+
+div.sphinxsidebar ul {
+ padding-left: 1.5em;
+ margin-top: 7px;
+ padding: 0;
+ line-height: 130%;
+}
+
+div.sphinxsidebar ul ul {
+ margin-left: 20px;
+}
+
+
+
+
+/*
+ * footer
+ * ~~~~~~~~~~~~~~~~~~~
+ *
+ */
+
+
+div.footer {
+ background-color: #ffffff;
+ color: #ffffff;
+ padding: 3px 8px 3px 0;
+ clear: both;
+ font-size: 0.8em;
+ text-align: right;
+}
+
+div.footer a {
+ color: #ffffff;
+ text-decoration: none;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+p {
+ margin: 0.8em 0 0.5em 0;
+}
+
+
+a {
+ color: #4d97c6;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #7c858c;
+}
+
+div.body a {
+ text-decoration: none;
+}
+
+em {
+ font-style: normal;
+}
+
+/* -- header styles, basically Opscode blue with colored underlines and decreasing border bottom sizes */
+
+h1 {
+ margin: 0.5;
+ padding: 0.7em 0 0.3em 0;
+ font-size: 1.75em;
+ color: #212c35;
+ border-bottom:solid 4px #f18a20;
+}
+
+h2 {
+ margin: 1.3em 0 0.2em 0;
+ font-size: 1.55em;
+ color: #212c35;
+ padding: 0.7em 0 0.3em 0;
+ border-bottom:solid 2px #7c858c;
+}
+
+h3 {
+ margin: 1em 0 -0.3em 0;
+ font-size: 1.35em;
+ color: #212c35;
+ padding: 0.7em 0 0.3em 0;
+ border-bottom:solid 1px #7c858c;
+}
+
+h4 {
+ margin: 1em 0 -0.3em 0;
+ font-size: 1.15em;
+ color: #212c35;
+ padding: 0.7em 0 0.3em 0;
+ border-bottom:solid 0px #7c858c;
+}
+
+div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
+ color: #ffffff!important;
+}
+
+h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
+ display: none;
+ margin: 0 0 0 0.3em;
+ padding: 0 0.2em 0 0.2em;
+ color: #ffffff!important;
+}
+
+h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
+h5:hover a.anchor, h6:hover a.anchor {
+ display: inline;
+}
+
+h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
+h5 a.anchor:hover, h6 a.anchor:hover {
+ color: #ffffff;
+ background-color: #ffffff;
+}
+
+
+
+
+a.headerlink {
+ color: #ffffff!important;
+ font-size: 1em;
+ margin-left: 6px;
+ padding: 0 4px 0 4px;
+ text-decoration: none!important;
+}
+
+a.headerlink:hover {
+ background-color: #ffffff;
+ color: #ffffff!important;
+}
+
+cite, code, tt {
+ font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+ font-size: 0.95em;
+ letter-spacing: 0.01em;
+}
+
+
+
+
+
+tt {
+ background-color: #ebecf1;
+ border-bottom: 1px solid #d8dde3;
+ color: #212c35;
+}
+
+tt.descname, tt.descclassname, tt.xref {
+ border: 0;
+}
+
+/* -- has Opscode orange for testing */
+
+hr {
+ border: 1px solid #f18a20;
+ margin: 2em;
+}
+
+/* -- has Opscode orange for testing */
+
+a tt {
+ border: 0;
+ color: #f18a20;
+}
+
+/* -- has Opscode orange for testing */
+
+a tt:hover {
+ color: #f18a20;
+}
+
+/* -- has Opscode orange for testing */
+
+pre {
+ font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+ font-size: 0.95em;
+ letter-spacing: 0.015em;
+ line-height: 120%;
+ padding: 0.5em;
+ border: 0.0px solid #d8dde3;
+ background-color: #ebecf1;
+}
+
+pre a {
+ color: inherit;
+ text-decoration: underline;
+}
+
+td.linenos pre {
+ padding: 0.5em 0;
+}
+
+/* -- has Opscode orange for testing */
+
+div.quotebar {
+ background-color: #f18a20;
+ max-width: 250px;
+ float: right;
+ padding: 2px 7px;
+ border: 1px solid #f18a20;
+}
+
+/* -- has Opscode orange for testing */
+
+div.topic {
+ background-color: #f18a20;
+}
+
+
+/* -- table styles */
+
+table.docutils {
+ border: 0;
+ border-collapse: separate;
+ border-spacing:4px;
+
+}
+
+table.docutils th {
+ padding: 1px 8px 1px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 0px solid #ffffff;
+ background-color: #7c858c;
+ color: #ffffff;
+}
+
+table.docutils td {
+ padding: 5px 5px 5px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px dashed #7c858c;
+}
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+
+
+
+
+
+
+div.admonition, div.warning {
+ font-size: 0.9em;
+ margin: 1em 0 1em 0;
+ border: 1px solid #6bb1e1;
+ background-color: #ffffff;
+ padding: 0;
+}
+
+div.admonition p, div.warning p {
+ margin: 0.5em 1em 0.5em 1em;
+ padding: 0;
+}
+
+div.admonition pre, div.warning pre {
+ margin: 0.4em 1em 0.4em 1em;
+}
+
+div.admonition p.admonition-title,
+div.warning p.admonition-title {
+ margin: 0;
+ padding: 0.1em 0 0.1em 0.5em;
+ color: #ffffff;
+ border-bottom: 1px solid #6bb1e1;
+ font-weight: bold;
+ background-color: #6bb1e1;
+}
+
+
+
+
+div.warning {
+ border: 1px solid #fcb614;
+}
+
+div.warning p.admonition-title {
+ background-color: #fcb614;
+ border-bottom-color: #fcb614;
+}
+
+div.admonition ul, div.admonition ol,
+div.warning ul, div.warning ol {
+ margin: 0.1em 0.5em 0.5em 3em;
+ padding: 0;
+}
+
+
+
+
+div.versioninfo {
+ margin: 1em 0 0 0;
+ border: 1px solid #ffffff;
+ background-color: #ffffff;
+ padding: 8px;
+ line-height: 1.3em;
+ font-size: 0.9em;
+}
+
+
+
+
+.viewcode-back {
+ font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
+}
+
+
+
+
+div.viewcode-block:target {
+ background-color: #ffffff;
+ border-top: 1px solid #ffffff;
+ border-bottom: 1px solid #ffffff;
+} \ No newline at end of file
diff --git a/distro/common/html/_static/jquery.js b/distro/common/html/_static/jquery.js
new file mode 100644
index 0000000000..7c24308023
--- /dev/null
+++ b/distro/common/html/_static/jquery.js
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
diff --git a/distro/common/html/_static/minus.png b/distro/common/html/_static/minus.png
new file mode 100644
index 0000000000..da1c5620d1
--- /dev/null
+++ b/distro/common/html/_static/minus.png
Binary files differ
diff --git a/distro/common/html/_static/navigation.png b/distro/common/html/_static/navigation.png
new file mode 100644
index 0000000000..1081dc1439
--- /dev/null
+++ b/distro/common/html/_static/navigation.png
Binary files differ
diff --git a/distro/common/html/_static/plus.png b/distro/common/html/_static/plus.png
new file mode 100644
index 0000000000..b3cb37425e
--- /dev/null
+++ b/distro/common/html/_static/plus.png
Binary files differ
diff --git a/distro/common/html/_static/pygments.css b/distro/common/html/_static/pygments.css
new file mode 100644
index 0000000000..3965ee93a7
--- /dev/null
+++ b/distro/common/html/_static/pygments.css
@@ -0,0 +1,62 @@
+.highlight .hll { background-color: #ffffcc }
+.highlight { background: #f8f8f8; }
+.highlight .c { color: #008800; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #AA22FF; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .cm { color: #008800; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #008800 } /* Comment.Preproc */
+.highlight .c1 { color: #008800; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #008800; font-weight: bold } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #808080 } /* Generic.Output */
+.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0040D0 } /* Generic.Traceback */
+.highlight .kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #AA22FF } /* Keyword.Pseudo */
+.highlight .kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #00BB00; font-weight: bold } /* Keyword.Type */
+.highlight .m { color: #666666 } /* Literal.Number */
+.highlight .s { color: #BB4444 } /* Literal.String */
+.highlight .na { color: #BB4444 } /* Name.Attribute */
+.highlight .nb { color: #AA22FF } /* Name.Builtin */
+.highlight .nc { color: #0000FF } /* Name.Class */
+.highlight .no { color: #880000 } /* Name.Constant */
+.highlight .nd { color: #AA22FF } /* Name.Decorator */
+.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #00A000 } /* Name.Function */
+.highlight .nl { color: #A0A000 } /* Name.Label */
+.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #B8860B } /* Name.Variable */
+.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #666666 } /* Literal.Number.Float */
+.highlight .mh { color: #666666 } /* Literal.Number.Hex */
+.highlight .mi { color: #666666 } /* Literal.Number.Integer */
+.highlight .mo { color: #666666 } /* Literal.Number.Oct */
+.highlight .sb { color: #BB4444 } /* Literal.String.Backtick */
+.highlight .sc { color: #BB4444 } /* Literal.String.Char */
+.highlight .sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #BB4444 } /* Literal.String.Double */
+.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #BB4444 } /* Literal.String.Heredoc */
+.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.highlight .sx { color: #008000 } /* Literal.String.Other */
+.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
+.highlight .s1 { color: #BB4444 } /* Literal.String.Single */
+.highlight .ss { color: #B8860B } /* Literal.String.Symbol */
+.highlight .bp { color: #AA22FF } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #B8860B } /* Name.Variable.Class */
+.highlight .vg { color: #B8860B } /* Name.Variable.Global */
+.highlight .vi { color: #B8860B } /* Name.Variable.Instance */
+.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file
diff --git a/distro/common/html/_static/searchtools.js b/distro/common/html/_static/searchtools.js
new file mode 100644
index 0000000000..663be4c909
--- /dev/null
+++ b/distro/common/html/_static/searchtools.js
@@ -0,0 +1,560 @@
+/*
+ * searchtools.js_t
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilties for the full-text search.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurance, the
+ * latter for highlighting it.
+ */
+
+jQuery.makeSearchSummary = function(text, keywords, hlwords) {
+ var textLower = text.toLowerCase();
+ var start = 0;
+ $.each(keywords, function() {
+ var i = textLower.indexOf(this.toLowerCase());
+ if (i > -1)
+ start = i;
+ });
+ start = Math.max(start - 120, 0);
+ var excerpt = ((start > 0) ? '...' : '') +
+ $.trim(text.substr(start, 240)) +
+ ((start + 240 - text.length) ? '...' : '');
+ var rv = $('<div class="context"></div>').text(excerpt);
+ $.each(hlwords, function() {
+ rv = rv.highlightText(this, 'highlighted');
+ });
+ return rv;
+}
+
+
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+ var step2list = {
+ ational: 'ate',
+ tional: 'tion',
+ enci: 'ence',
+ anci: 'ance',
+ izer: 'ize',
+ bli: 'ble',
+ alli: 'al',
+ entli: 'ent',
+ eli: 'e',
+ ousli: 'ous',
+ ization: 'ize',
+ ation: 'ate',
+ ator: 'ate',
+ alism: 'al',
+ iveness: 'ive',
+ fulness: 'ful',
+ ousness: 'ous',
+ aliti: 'al',
+ iviti: 'ive',
+ biliti: 'ble',
+ logi: 'log'
+ };
+
+ var step3list = {
+ icate: 'ic',
+ ative: '',
+ alize: 'al',
+ iciti: 'ic',
+ ical: 'ic',
+ ful: '',
+ ness: ''
+ };
+
+ var c = "[^aeiou]"; // consonant
+ var v = "[aeiouy]"; // vowel
+ var C = c + "[^aeiouy]*"; // consonant sequence
+ var V = v + "[aeiou]*"; // vowel sequence
+
+ var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
+ var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
+ var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
+ var s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ this.stemWord = function (w) {
+ var stem;
+ var suffix;
+ var firstch;
+ var origword = w;
+
+ if (w.length < 3)
+ return w;
+
+ var re;
+ var re2;
+ var re3;
+ var re4;
+
+ firstch = w.substr(0,1);
+ if (firstch == "y")
+ w = firstch.toUpperCase() + w.substr(1);
+
+ // Step 1a
+ re = /^(.+?)(ss|i)es$/;
+ re2 = /^(.+?)([^s])s$/;
+
+ if (re.test(w))
+ w = w.replace(re,"$1$2");
+ else if (re2.test(w))
+ w = w.replace(re2,"$1$2");
+
+ // Step 1b
+ re = /^(.+?)eed$/;
+ re2 = /^(.+?)(ed|ing)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = new RegExp(mgr0);
+ if (re.test(fp[1])) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = new RegExp(s_v);
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = /(at|bl|iz)$/;
+ re3 = new RegExp("([^aeiouylsz])\\1$");
+ re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re2.test(w))
+ w = w + "e";
+ else if (re3.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ else if (re4.test(w))
+ w = w + "e";
+ }
+ }
+
+ // Step 1c
+ re = /^(.+?)y$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(s_v);
+ if (re.test(stem))
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step2list[suffix];
+ }
+
+ // Step 3
+ re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step3list[suffix];
+ }
+
+ // Step 4
+ re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ re2 = /^(.+?)(s|t)(ion)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ if (re.test(stem))
+ w = stem;
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = new RegExp(mgr1);
+ if (re2.test(stem))
+ w = stem;
+ }
+
+ // Step 5
+ re = /^(.+?)e$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ re2 = new RegExp(meq1);
+ re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+ w = stem;
+ }
+ re = /ll$/;
+ re2 = new RegExp(mgr1);
+ if (re.test(w) && re2.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+ if (firstch == "y")
+ w = firstch.toLowerCase() + w.substr(1);
+ return w;
+ }
+}
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+ _index : null,
+ _queued_query : null,
+ _pulse_status : -1,
+
+ init : function() {
+ var params = $.getQueryParameters();
+ if (params.q) {
+ var query = params.q[0];
+ $('input[name="q"]')[0].value = query;
+ this.performSearch(query);
+ }
+ },
+
+ loadIndex : function(url) {
+ $.ajax({type: "GET", url: url, data: null, success: null,
+ dataType: "script", cache: true});
+ },
+
+ setIndex : function(index) {
+ var q;
+ this._index = index;
+ if ((q = this._queued_query) !== null) {
+ this._queued_query = null;
+ Search.query(q);
+ }
+ },
+
+ hasIndex : function() {
+ return this._index !== null;
+ },
+
+ deferQuery : function(query) {
+ this._queued_query = query;
+ },
+
+ stopPulse : function() {
+ this._pulse_status = 0;
+ },
+
+ startPulse : function() {
+ if (this._pulse_status >= 0)
+ return;
+ function pulse() {
+ Search._pulse_status = (Search._pulse_status + 1) % 4;
+ var dotString = '';
+ for (var i = 0; i < Search._pulse_status; i++)
+ dotString += '.';
+ Search.dots.text(dotString);
+ if (Search._pulse_status > -1)
+ window.setTimeout(pulse, 500);
+ };
+ pulse();
+ },
+
+ /**
+ * perform a search for something
+ */
+ performSearch : function(query) {
+ // create the required interface elements
+ this.out = $('#search-results');
+ this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+ this.dots = $('<span></span>').appendTo(this.title);
+ this.status = $('<p style="display: none"></p>').appendTo(this.out);
+ this.output = $('<ul class="search"/>').appendTo(this.out);
+
+ $('#search-progress').text(_('Preparing search...'));
+ this.startPulse();
+
+ // index already loaded, the browser was quick!
+ if (this.hasIndex())
+ this.query(query);
+ else
+ this.deferQuery(query);
+ },
+
+ query : function(query) {
+ var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
+
+ // Stem the searchterms and add them to the correct list
+ var stemmer = new Stemmer();
+ var searchterms = [];
+ var excluded = [];
+ var hlterms = [];
+ var tmp = query.split(/\s+/);
+ var objectterms = [];
+ for (var i = 0; i < tmp.length; i++) {
+ if (tmp[i] != "") {
+ objectterms.push(tmp[i].toLowerCase());
+ }
+
+ if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
+ tmp[i] == "") {
+ // skip this "word"
+ continue;
+ }
+ // stem the word
+ var word = stemmer.stemWord(tmp[i]).toLowerCase();
+ // select the correct list
+ if (word[0] == '-') {
+ var toAppend = excluded;
+ word = word.substr(1);
+ }
+ else {
+ var toAppend = searchterms;
+ hlterms.push(tmp[i].toLowerCase());
+ }
+ // only add if not already in the list
+ if (!$.contains(toAppend, word))
+ toAppend.push(word);
+ };
+ var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+ // console.debug('SEARCH: searching for:');
+ // console.info('required: ', searchterms);
+ // console.info('excluded: ', excluded);
+
+ // prepare search
+ var filenames = this._index.filenames;
+ var titles = this._index.titles;
+ var terms = this._index.terms;
+ var fileMap = {};
+ var files = null;
+ // different result priorities
+ var importantResults = [];
+ var objectResults = [];
+ var regularResults = [];
+ var unimportantResults = [];
+ $('#search-progress').empty();
+
+ // lookup as object
+ for (var i = 0; i < objectterms.length; i++) {
+ var others = [].concat(objectterms.slice(0,i),
+ objectterms.slice(i+1, objectterms.length))
+ var results = this.performObjectSearch(objectterms[i], others);
+ // Assume first word is most likely to be the object,
+ // other words more likely to be in description.
+ // Therefore put matches for earlier words first.
+ // (Results are eventually used in reverse order).
+ objectResults = results[0].concat(objectResults);
+ importantResults = results[1].concat(importantResults);
+ unimportantResults = results[2].concat(unimportantResults);
+ }
+
+ // perform the search on the required terms
+ for (var i = 0; i < searchterms.length; i++) {
+ var word = searchterms[i];
+ // no match but word was a required one
+ if ((files = terms[word]) == null)
+ break;
+ if (files.length == undefined) {
+ files = [files];
+ }
+ // create the mapping
+ for (var j = 0; j < files.length; j++) {
+ var file = files[j];
+ if (file in fileMap)
+ fileMap[file].push(word);
+ else
+ fileMap[file] = [word];
+ }
+ }
+
+ // now check if the files don't contain excluded terms
+ for (var file in fileMap) {
+ var valid = true;
+
+ // check if all requirements are matched
+ if (fileMap[file].length != searchterms.length)
+ continue;
+
+ // ensure that none of the excluded terms is in the
+ // search result.
+ for (var i = 0; i < excluded.length; i++) {
+ if (terms[excluded[i]] == file ||
+ $.contains(terms[excluded[i]] || [], file)) {
+ valid = false;
+ break;
+ }
+ }
+
+ // if we have still a valid result we can add it
+ // to the result list
+ if (valid)
+ regularResults.push([filenames[file], titles[file], '', null]);
+ }
+
+ // delete unused variables in order to not waste
+ // memory until list is retrieved completely
+ delete filenames, titles, terms;
+
+ // now sort the regular results descending by title
+ regularResults.sort(function(a, b) {
+ var left = a[1].toLowerCase();
+ var right = b[1].toLowerCase();
+ return (left > right) ? -1 : ((left < right) ? 1 : 0);
+ });
+
+ // combine all results
+ var results = unimportantResults.concat(regularResults)
+ .concat(objectResults).concat(importantResults);
+
+ // print the results
+ var resultCount = results.length;
+ function displayNextItem() {
+ // results left, load the summary and display it
+ if (results.length) {
+ var item = results.pop();
+ var listItem = $('<li style="display:none"></li>');
+ if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') {
+ // dirhtml builder
+ var dirname = item[0] + '/';
+ if (dirname.match(/\/index\/$/)) {
+ dirname = dirname.substring(0, dirname.length-6);
+ } else if (dirname == 'index/') {
+ dirname = '';
+ }
+ listItem.append($('<a/>').attr('href',
+ DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+ highlightstring + item[2]).html(item[1]));
+ } else {
+ // normal html builders
+ listItem.append($('<a/>').attr('href',
+ item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+ highlightstring + item[2]).html(item[1]));
+ }
+ if (item[3]) {
+ listItem.append($('<span> (' + item[3] + ')</span>'));
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+ $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
+ item[0] + '.txt', function(data) {
+ if (data != '') {
+ listItem.append($.makeSearchSummary(data, searchterms, hlterms));
+ Search.output.append(listItem);
+ }
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ }, "text");
+ } else {
+ // no source available, just display title
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ }
+ }
+ // search finished, update title and status message
+ else {
+ Search.stopPulse();
+ Search.title.text(_('Search Results'));
+ if (!resultCount)
+ Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+ else
+ Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+ Search.status.fadeIn(500);
+ }
+ }
+ displayNextItem();
+ },
+
+ performObjectSearch : function(object, otherterms) {
+ var filenames = this._index.filenames;
+ var objects = this._index.objects;
+ var objnames = this._index.objnames;
+ var titles = this._index.titles;
+
+ var importantResults = [];
+ var objectResults = [];
+ var unimportantResults = [];
+
+ for (var prefix in objects) {
+ for (var name in objects[prefix]) {
+ var fullname = (prefix ? prefix + '.' : '') + name;
+ if (fullname.toLowerCase().indexOf(object) > -1) {
+ var match = objects[prefix][name];
+ var objname = objnames[match[1]][2];
+ var title = titles[match[0]];
+ // If more than one term searched for, we require other words to be
+ // found in the name/title/description
+ if (otherterms.length > 0) {
+ var haystack = (prefix + ' ' + name + ' ' +
+ objname + ' ' + title).toLowerCase();
+ var allfound = true;
+ for (var i = 0; i < otherterms.length; i++) {
+ if (haystack.indexOf(otherterms[i]) == -1) {
+ allfound = false;
+ break;
+ }
+ }
+ if (!allfound) {
+ continue;
+ }
+ }
+ var descr = objname + _(', in ') + title;
+ anchor = match[3];
+ if (anchor == '')
+ anchor = fullname;
+ else if (anchor == '-')
+ anchor = objnames[match[1]][1] + '-' + fullname;
+ result = [filenames[match[0]], fullname, '#'+anchor, descr];
+ switch (match[2]) {
+ case 1: objectResults.push(result); break;
+ case 0: importantResults.push(result); break;
+ case 2: unimportantResults.push(result); break;
+ }
+ }
+ }
+ }
+
+ // sort results descending
+ objectResults.sort(function(a, b) {
+ return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+ });
+
+ importantResults.sort(function(a, b) {
+ return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+ });
+
+ unimportantResults.sort(function(a, b) {
+ return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+ });
+
+ return [importantResults, objectResults, unimportantResults]
+ }
+}
+
+$(document).ready(function() {
+ Search.init();
+}); \ No newline at end of file
diff --git a/distro/common/html/_static/underscore.js b/distro/common/html/_static/underscore.js
new file mode 100644
index 0000000000..5d89914340
--- /dev/null
+++ b/distro/common/html/_static/underscore.js
@@ -0,0 +1,23 @@
+// Underscore.js 0.5.5
+// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the terms of the MIT license.
+// Portions of Underscore are inspired by or borrowed from Prototype.js,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore/
+(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
+a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
+var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
+d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=
+function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,
+function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a,
+0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,
+e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d=
+a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
+return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
+var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
+if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
+0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
+a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
+" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
+o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();
diff --git a/distro/common/html/_static/up-pressed.png b/distro/common/html/_static/up-pressed.png
new file mode 100644
index 0000000000..8bd587afee
--- /dev/null
+++ b/distro/common/html/_static/up-pressed.png
Binary files differ
diff --git a/distro/common/html/_static/up.png b/distro/common/html/_static/up.png
new file mode 100644
index 0000000000..b94625680b
--- /dev/null
+++ b/distro/common/html/_static/up.png
Binary files differ
diff --git a/distro/common/html/_static/websupport.js b/distro/common/html/_static/websupport.js
new file mode 100644
index 0000000000..e9bd1b851c
--- /dev/null
+++ b/distro/common/html/_static/websupport.js
@@ -0,0 +1,808 @@
+/*
+ * websupport.js
+ * ~~~~~~~~~~~~~
+ *
+ * sphinx.websupport utilties for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+(function($) {
+ $.fn.autogrow = function() {
+ return this.each(function() {
+ var textarea = this;
+
+ $.fn.autogrow.resize(textarea);
+
+ $(textarea)
+ .focus(function() {
+ textarea.interval = setInterval(function() {
+ $.fn.autogrow.resize(textarea);
+ }, 500);
+ })
+ .blur(function() {
+ clearInterval(textarea.interval);
+ });
+ });
+ };
+
+ $.fn.autogrow.resize = function(textarea) {
+ var lineHeight = parseInt($(textarea).css('line-height'), 10);
+ var lines = textarea.value.split('\n');
+ var columns = textarea.cols;
+ var lineCount = 0;
+ $.each(lines, function() {
+ lineCount += Math.ceil(this.length / columns) || 1;
+ });
+ var height = lineHeight * (lineCount + 1);
+ $(textarea).css('height', height);
+ };
+})(jQuery);
+
+(function($) {
+ var comp, by;
+
+ function init() {
+ initEvents();
+ initComparator();
+ }
+
+ function initEvents() {
+ $('a.comment-close').live("click", function(event) {
+ event.preventDefault();
+ hide($(this).attr('id').substring(2));
+ });
+ $('a.vote').live("click", function(event) {
+ event.preventDefault();
+ handleVote($(this));
+ });
+ $('a.reply').live("click", function(event) {
+ event.preventDefault();
+ openReply($(this).attr('id').substring(2));
+ });
+ $('a.close-reply').live("click", function(event) {
+ event.preventDefault();
+ closeReply($(this).attr('id').substring(2));
+ });
+ $('a.sort-option').live("click", function(event) {
+ event.preventDefault();
+ handleReSort($(this));
+ });
+ $('a.show-proposal').live("click", function(event) {
+ event.preventDefault();
+ showProposal($(this).attr('id').substring(2));
+ });
+ $('a.hide-proposal').live("click", function(event) {
+ event.preventDefault();
+ hideProposal($(this).attr('id').substring(2));
+ });
+ $('a.show-propose-change').live("click", function(event) {
+ event.preventDefault();
+ showProposeChange($(this).attr('id').substring(2));
+ });
+ $('a.hide-propose-change').live("click", function(event) {
+ event.preventDefault();
+ hideProposeChange($(this).attr('id').substring(2));
+ });
+ $('a.accept-comment').live("click", function(event) {
+ event.preventDefault();
+ acceptComment($(this).attr('id').substring(2));
+ });
+ $('a.delete-comment').live("click", function(event) {
+ event.preventDefault();
+ deleteComment($(this).attr('id').substring(2));
+ });
+ $('a.comment-markup').live("click", function(event) {
+ event.preventDefault();
+ toggleCommentMarkupBox($(this).attr('id').substring(2));
+ });
+ }
+
+ /**
+ * Set comp, which is a comparator function used for sorting and
+ * inserting comments into the list.
+ */
+ function setComparator() {
+ // If the first three letters are "asc", sort in ascending order
+ // and remove the prefix.
+ if (by.substring(0,3) == 'asc') {
+ var i = by.substring(3);
+ comp = function(a, b) { return a[i] - b[i]; };
+ } else {
+ // Otherwise sort in descending order.
+ comp = function(a, b) { return b[by] - a[by]; };
+ }
+
+ // Reset link styles and format the selected sort option.
+ $('a.sel').attr('href', '#').removeClass('sel');
+ $('a.by' + by).removeAttr('href').addClass('sel');
+ }
+
+ /**
+ * Create a comp function. If the user has preferences stored in
+ * the sortBy cookie, use those, otherwise use the default.
+ */
+ function initComparator() {
+ by = 'rating'; // Default to sort by rating.
+ // If the sortBy cookie is set, use that instead.
+ if (document.cookie.length > 0) {
+ var start = document.cookie.indexOf('sortBy=');
+ if (start != -1) {
+ start = start + 7;
+ var end = document.cookie.indexOf(";", start);
+ if (end == -1) {
+ end = document.cookie.length;
+ by = unescape(document.cookie.substring(start, end));
+ }
+ }
+ }
+ setComparator();
+ }
+
+ /**
+ * Show a comment div.
+ */
+ function show(id) {
+ $('#ao' + id).hide();
+ $('#ah' + id).show();
+ var context = $.extend({id: id}, opts);
+ var popup = $(renderTemplate(popupTemplate, context)).hide();
+ popup.find('textarea[name="proposal"]').hide();
+ popup.find('a.by' + by).addClass('sel');
+ var form = popup.find('#cf' + id);
+ form.submit(function(event) {
+ event.preventDefault();
+ addComment(form);
+ });
+ $('#s' + id).after(popup);
+ popup.slideDown('fast', function() {
+ getComments(id);
+ });
+ }
+
+ /**
+ * Hide a comment div.
+ */
+ function hide(id) {
+ $('#ah' + id).hide();
+ $('#ao' + id).show();
+ var div = $('#sc' + id);
+ div.slideUp('fast', function() {
+ div.remove();
+ });
+ }
+
+ /**
+ * Perform an ajax request to get comments for a node
+ * and insert the comments into the comments tree.
+ */
+ function getComments(id) {
+ $.ajax({
+ type: 'GET',
+ url: opts.getCommentsURL,
+ data: {node: id},
+ success: function(data, textStatus, request) {
+ var ul = $('#cl' + id);
+ var speed = 100;
+ $('#cf' + id)
+ .find('textarea[name="proposal"]')
+ .data('source', data.source);
+
+ if (data.comments.length === 0) {
+ ul.html('<li>No comments yet.</li>');
+ ul.data('empty', true);
+ } else {
+ // If there are comments, sort them and put them in the list.
+ var comments = sortComments(data.comments);
+ speed = data.comments.length * 100;
+ appendComments(comments, ul);
+ ul.data('empty', false);
+ }
+ $('#cn' + id).slideUp(speed + 200);
+ ul.slideDown(speed);
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem retrieving the comments.');
+ },
+ dataType: 'json'
+ });
+ }
+
+ /**
+ * Add a comment via ajax and insert the comment into the comment tree.
+ */
+ function addComment(form) {
+ var node_id = form.find('input[name="node"]').val();
+ var parent_id = form.find('input[name="parent"]').val();
+ var text = form.find('textarea[name="comment"]').val();
+ var proposal = form.find('textarea[name="proposal"]').val();
+
+ if (text == '') {
+ showError('Please enter a comment.');
+ return;
+ }
+
+ // Disable the form that is being submitted.
+ form.find('textarea,input').attr('disabled', 'disabled');
+
+ // Send the comment to the server.
+ $.ajax({
+ type: "POST",
+ url: opts.addCommentURL,
+ dataType: 'json',
+ data: {
+ node: node_id,
+ parent: parent_id,
+ text: text,
+ proposal: proposal
+ },
+ success: function(data, textStatus, error) {
+ // Reset the form.
+ if (node_id) {
+ hideProposeChange(node_id);
+ }
+ form.find('textarea')
+ .val('')
+ .add(form.find('input'))
+ .removeAttr('disabled');
+ var ul = $('#cl' + (node_id || parent_id));
+ if (ul.data('empty')) {
+ $(ul).empty();
+ ul.data('empty', false);
+ }
+ insertComment(data.comment);
+ var ao = $('#ao' + node_id);
+ ao.find('img').attr({'src': opts.commentBrightImage});
+ if (node_id) {
+ // if this was a "root" comment, remove the commenting box
+ // (the user can get it back by reopening the comment popup)
+ $('#ca' + node_id).slideUp();
+ }
+ },
+ error: function(request, textStatus, error) {
+ form.find('textarea,input').removeAttr('disabled');
+ showError('Oops, there was a problem adding the comment.');
+ }
+ });
+ }
+
+ /**
+ * Recursively append comments to the main comment list and children
+ * lists, creating the comment tree.
+ */
+ function appendComments(comments, ul) {
+ $.each(comments, function() {
+ var div = createCommentDiv(this);
+ ul.append($(document.createElement('li')).html(div));
+ appendComments(this.children, div.find('ul.comment-children'));
+ // To avoid stagnating data, don't store the comments children in data.
+ this.children = null;
+ div.data('comment', this);
+ });
+ }
+
+ /**
+ * After adding a new comment, it must be inserted in the correct
+ * location in the comment tree.
+ */
+ function insertComment(comment) {
+ var div = createCommentDiv(comment);
+
+ // To avoid stagnating data, don't store the comments children in data.
+ comment.children = null;
+ div.data('comment', comment);
+
+ var ul = $('#cl' + (comment.node || comment.parent));
+ var siblings = getChildren(ul);
+
+ var li = $(document.createElement('li'));
+ li.hide();
+
+ // Determine where in the parents children list to insert this comment.
+ for(i=0; i < siblings.length; i++) {
+ if (comp(comment, siblings[i]) <= 0) {
+ $('#cd' + siblings[i].id)
+ .parent()
+ .before(li.html(div));
+ li.slideDown('fast');
+ return;
+ }
+ }
+
+ // If we get here, this comment rates lower than all the others,
+ // or it is the only comment in the list.
+ ul.append(li.html(div));
+ li.slideDown('fast');
+ }
+
+ function acceptComment(id) {
+ $.ajax({
+ type: 'POST',
+ url: opts.acceptCommentURL,
+ data: {id: id},
+ success: function(data, textStatus, request) {
+ $('#cm' + id).fadeOut('fast');
+ $('#cd' + id).removeClass('moderate');
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem accepting the comment.');
+ }
+ });
+ }
+
+ function deleteComment(id) {
+ $.ajax({
+ type: 'POST',
+ url: opts.deleteCommentURL,
+ data: {id: id},
+ success: function(data, textStatus, request) {
+ var div = $('#cd' + id);
+ if (data == 'delete') {
+ // Moderator mode: remove the comment and all children immediately
+ div.slideUp('fast', function() {
+ div.remove();
+ });
+ return;
+ }
+ // User mode: only mark the comment as deleted
+ div
+ .find('span.user-id:first')
+ .text('[deleted]').end()
+ .find('div.comment-text:first')
+ .text('[deleted]').end()
+ .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
+ ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
+ .remove();
+ var comment = div.data('comment');
+ comment.username = '[deleted]';
+ comment.text = '[deleted]';
+ div.data('comment', comment);
+ },
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem deleting the comment.');
+ }
+ });
+ }
+
+ function showProposal(id) {
+ $('#sp' + id).hide();
+ $('#hp' + id).show();
+ $('#pr' + id).slideDown('fast');
+ }
+
+ function hideProposal(id) {
+ $('#hp' + id).hide();
+ $('#sp' + id).show();
+ $('#pr' + id).slideUp('fast');
+ }
+
+ function showProposeChange(id) {
+ $('#pc' + id).hide();
+ $('#hc' + id).show();
+ var textarea = $('#pt' + id);
+ textarea.val(textarea.data('source'));
+ $.fn.autogrow.resize(textarea[0]);
+ textarea.slideDown('fast');
+ }
+
+ function hideProposeChange(id) {
+ $('#hc' + id).hide();
+ $('#pc' + id).show();
+ var textarea = $('#pt' + id);
+ textarea.val('').removeAttr('disabled');
+ textarea.slideUp('fast');
+ }
+
+ function toggleCommentMarkupBox(id) {
+ $('#mb' + id).toggle();
+ }
+
+ /** Handle when the user clicks on a sort by link. */
+ function handleReSort(link) {
+ var classes = link.attr('class').split(/\s+/);
+ for (var i=0; i<classes.length; i++) {
+ if (classes[i] != 'sort-option') {
+ by = classes[i].substring(2);
+ }
+ }
+ setComparator();
+ // Save/update the sortBy cookie.
+ var expiration = new Date();
+ expiration.setDate(expiration.getDate() + 365);
+ document.cookie= 'sortBy=' + escape(by) +
+ ';expires=' + expiration.toUTCString();
+ $('ul.comment-ul').each(function(index, ul) {
+ var comments = getChildren($(ul), true);
+ comments = sortComments(comments);
+ appendComments(comments, $(ul).empty());
+ });
+ }
+
+ /**
+ * Function to process a vote when a user clicks an arrow.
+ */
+ function handleVote(link) {
+ if (!opts.voting) {
+ showError("You'll need to login to vote.");
+ return;
+ }
+
+ var id = link.attr('id');
+ if (!id) {
+ // Didn't click on one of the voting arrows.
+ return;
+ }
+ // If it is an unvote, the new vote value is 0,
+ // Otherwise it's 1 for an upvote, or -1 for a downvote.
+ var value = 0;
+ if (id.charAt(1) != 'u') {
+ value = id.charAt(0) == 'u' ? 1 : -1;
+ }
+ // The data to be sent to the server.
+ var d = {
+ comment_id: id.substring(2),
+ value: value
+ };
+
+ // Swap the vote and unvote links.
+ link.hide();
+ $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
+ .show();
+
+ // The div the comment is displayed in.
+ var div = $('div#cd' + d.comment_id);
+ var data = div.data('comment');
+
+ // If this is not an unvote, and the other vote arrow has
+ // already been pressed, unpress it.
+ if ((d.value !== 0) && (data.vote === d.value * -1)) {
+ $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
+ $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
+ }
+
+ // Update the comments rating in the local data.
+ data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
+ data.vote = d.value;
+ div.data('comment', data);
+
+ // Change the rating text.
+ div.find('.rating:first')
+ .text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
+
+ // Send the vote information to the server.
+ $.ajax({
+ type: "POST",
+ url: opts.processVoteURL,
+ data: d,
+ error: function(request, textStatus, error) {
+ showError('Oops, there was a problem casting that vote.');
+ }
+ });
+ }
+
+ /**
+ * Open a reply form used to reply to an existing comment.
+ */
+ function openReply(id) {
+ // Swap out the reply link for the hide link
+ $('#rl' + id).hide();
+ $('#cr' + id).show();
+
+ // Add the reply li to the children ul.
+ var div = $(renderTemplate(replyTemplate, {id: id})).hide();
+ $('#cl' + id)
+ .prepend(div)
+ // Setup the submit handler for the reply form.
+ .find('#rf' + id)
+ .submit(function(event) {
+ event.preventDefault();
+ addComment($('#rf' + id));
+ closeReply(id);
+ })
+ .find('input[type=button]')
+ .click(function() {
+ closeReply(id);
+ });
+ div.slideDown('fast', function() {
+ $('#rf' + id).find('textarea').focus();
+ });
+ }
+
+ /**
+ * Close the reply form opened with openReply.
+ */
+ function closeReply(id) {
+ // Remove the reply div from the DOM.
+ $('#rd' + id).slideUp('fast', function() {
+ $(this).remove();
+ });
+
+ // Swap out the hide link for the reply link
+ $('#cr' + id).hide();
+ $('#rl' + id).show();
+ }
+
+ /**
+ * Recursively sort a tree of comments using the comp comparator.
+ */
+ function sortComments(comments) {
+ comments.sort(comp);
+ $.each(comments, function() {
+ this.children = sortComments(this.children);
+ });
+ return comments;
+ }
+
+ /**
+ * Get the children comments from a ul. If recursive is true,
+ * recursively include childrens' children.
+ */
+ function getChildren(ul, recursive) {
+ var children = [];
+ ul.children().children("[id^='cd']")
+ .each(function() {
+ var comment = $(this).data('comment');
+ if (recursive)
+ comment.children = getChildren($(this).find('#cl' + comment.id), true);
+ children.push(comment);
+ });
+ return children;
+ }
+
+ /** Create a div to display a comment in. */
+ function createCommentDiv(comment) {
+ if (!comment.displayed && !opts.moderator) {
+ return $('<div class="moderate">Thank you! Your comment will show up '
+ + 'once it is has been approved by a moderator.</div>');
+ }
+ // Prettify the comment rating.
+ comment.pretty_rating = comment.rating + ' point' +
+ (comment.rating == 1 ? '' : 's');
+ // Make a class (for displaying not yet moderated comments differently)
+ comment.css_class = comment.displayed ? '' : ' moderate';
+ // Create a div for this comment.
+ var context = $.extend({}, opts, comment);
+ var div = $(renderTemplate(commentTemplate, context));
+
+ // If the user has voted on this comment, highlight the correct arrow.
+ if (comment.vote) {
+ var direction = (comment.vote == 1) ? 'u' : 'd';
+ div.find('#' + direction + 'v' + comment.id).hide();
+ div.find('#' + direction + 'u' + comment.id).show();
+ }
+
+ if (opts.moderator || comment.text != '[deleted]') {
+ div.find('a.reply').show();
+ if (comment.proposal_diff)
+ div.find('#sp' + comment.id).show();
+ if (opts.moderator && !comment.displayed)
+ div.find('#cm' + comment.id).show();
+ if (opts.moderator || (opts.username == comment.username))
+ div.find('#dc' + comment.id).show();
+ }
+ return div;
+ }
+
+ /**
+ * A simple template renderer. Placeholders such as <%id%> are replaced
+ * by context['id'] with items being escaped. Placeholders such as <#id#>
+ * are not escaped.
+ */
+ function renderTemplate(template, context) {
+ var esc = $(document.createElement('div'));
+
+ function handle(ph, escape) {
+ var cur = context;
+ $.each(ph.split('.'), function() {
+ cur = cur[this];
+ });
+ return escape ? esc.text(cur || "").html() : cur;
+ }
+
+ return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
+ return handle(arguments[2], arguments[1] == '%' ? true : false);
+ });
+ }
+
+ /** Flash an error message briefly. */
+ function showError(message) {
+ $(document.createElement('div')).attr({'class': 'popup-error'})
+ .append($(document.createElement('div'))
+ .attr({'class': 'error-message'}).text(message))
+ .appendTo('body')
+ .fadeIn("slow")
+ .delay(2000)
+ .fadeOut("slow");
+ }
+
+ /** Add a link the user uses to open the comments popup. */
+ $.fn.comment = function() {
+ return this.each(function() {
+ var id = $(this).attr('id').substring(1);
+ var count = COMMENT_METADATA[id];
+ var title = count + ' comment' + (count == 1 ? '' : 's');
+ var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
+ var addcls = count == 0 ? ' nocomment' : '';
+ $(this)
+ .append(
+ $(document.createElement('a')).attr({
+ href: '#',
+ 'class': 'sphinx-comment-open' + addcls,
+ id: 'ao' + id
+ })
+ .append($(document.createElement('img')).attr({
+ src: image,
+ alt: 'comment',
+ title: title
+ }))
+ .click(function(event) {
+ event.preventDefault();
+ show($(this).attr('id').substring(2));
+ })
+ )
+ .append(
+ $(document.createElement('a')).attr({
+ href: '#',
+ 'class': 'sphinx-comment-close hidden',
+ id: 'ah' + id
+ })
+ .append($(document.createElement('img')).attr({
+ src: opts.closeCommentImage,
+ alt: 'close',
+ title: 'close'
+ }))
+ .click(function(event) {
+ event.preventDefault();
+ hide($(this).attr('id').substring(2));
+ })
+ );
+ });
+ };
+
+ var opts = {
+ processVoteURL: '/_process_vote',
+ addCommentURL: '/_add_comment',
+ getCommentsURL: '/_get_comments',
+ acceptCommentURL: '/_accept_comment',
+ deleteCommentURL: '/_delete_comment',
+ commentImage: '/static/_static/comment.png',
+ closeCommentImage: '/static/_static/comment-close.png',
+ loadingImage: '/static/_static/ajax-loader.gif',
+ commentBrightImage: '/static/_static/comment-bright.png',
+ upArrow: '/static/_static/up.png',
+ downArrow: '/static/_static/down.png',
+ upArrowPressed: '/static/_static/up-pressed.png',
+ downArrowPressed: '/static/_static/down-pressed.png',
+ voting: false,
+ moderator: false
+ };
+
+ if (typeof COMMENT_OPTIONS != "undefined") {
+ opts = jQuery.extend(opts, COMMENT_OPTIONS);
+ }
+
+ var popupTemplate = '\
+ <div class="sphinx-comments" id="sc<%id%>">\
+ <p class="sort-options">\
+ Sort by:\
+ <a href="#" class="sort-option byrating">best rated</a>\
+ <a href="#" class="sort-option byascage">newest</a>\
+ <a href="#" class="sort-option byage">oldest</a>\
+ </p>\
+ <div class="comment-header">Comments</div>\
+ <div class="comment-loading" id="cn<%id%>">\
+ loading comments... <img src="<%loadingImage%>" alt="" /></div>\
+ <ul id="cl<%id%>" class="comment-ul"></ul>\
+ <div id="ca<%id%>">\
+ <p class="add-a-comment">Add a comment\
+ (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
+ <div class="comment-markup-box" id="mb<%id%>">\
+ reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
+ <tt>``code``</tt>, \
+ code blocks: <tt>::</tt> and an indented block after blank line</div>\
+ <form method="post" id="cf<%id%>" class="comment-form" action="">\
+ <textarea name="comment" cols="80"></textarea>\
+ <p class="propose-button">\
+ <a href="#" id="pc<%id%>" class="show-propose-change">\
+ Propose a change &#9657;\
+ </a>\
+ <a href="#" id="hc<%id%>" class="hide-propose-change">\
+ Propose a change &#9663;\
+ </a>\
+ </p>\
+ <textarea name="proposal" id="pt<%id%>" cols="80"\
+ spellcheck="false"></textarea>\
+ <input type="submit" value="Add comment" />\
+ <input type="hidden" name="node" value="<%id%>" />\
+ <input type="hidden" name="parent" value="" />\
+ </form>\
+ </div>\
+ </div>';
+
+ var commentTemplate = '\
+ <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
+ <div class="vote">\
+ <div class="arrow">\
+ <a href="#" id="uv<%id%>" class="vote" title="vote up">\
+ <img src="<%upArrow%>" />\
+ </a>\
+ <a href="#" id="uu<%id%>" class="un vote" title="vote up">\
+ <img src="<%upArrowPressed%>" />\
+ </a>\
+ </div>\
+ <div class="arrow">\
+ <a href="#" id="dv<%id%>" class="vote" title="vote down">\
+ <img src="<%downArrow%>" id="da<%id%>" />\
+ </a>\
+ <a href="#" id="du<%id%>" class="un vote" title="vote down">\
+ <img src="<%downArrowPressed%>" />\
+ </a>\
+ </div>\
+ </div>\
+ <div class="comment-content">\
+ <p class="tagline comment">\
+ <span class="user-id"><%username%></span>\
+ <span class="rating"><%pretty_rating%></span>\
+ <span class="delta"><%time.delta%></span>\
+ </p>\
+ <div class="comment-text comment"><#text#></div>\
+ <p class="comment-opts comment">\
+ <a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
+ <a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
+ <a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
+ <a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
+ <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
+ <span id="cm<%id%>" class="moderation hidden">\
+ <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
+ </span>\
+ </p>\
+ <pre class="proposal" id="pr<%id%>">\
+<#proposal_diff#>\
+ </pre>\
+ <ul class="comment-children" id="cl<%id%>"></ul>\
+ </div>\
+ <div class="clearleft"></div>\
+ </div>\
+ </div>';
+
+ var replyTemplate = '\
+ <li>\
+ <div class="reply-div" id="rd<%id%>">\
+ <form id="rf<%id%>">\
+ <textarea name="comment" cols="80"></textarea>\
+ <input type="submit" value="Add reply" />\
+ <input type="button" value="Cancel" />\
+ <input type="hidden" name="parent" value="<%id%>" />\
+ <input type="hidden" name="node" value="" />\
+ </form>\
+ </div>\
+ </li>';
+
+ $(document).ready(function() {
+ init();
+ });
+})(jQuery);
+
+$(document).ready(function() {
+ // add comment anchors for all paragraphs that are commentable
+ $('.sphinx-has-comment').comment();
+
+ // highlight search words in search results
+ $("div.context").each(function() {
+ var params = $.getQueryParameters();
+ var terms = (params.q) ? params.q[0].split(/\s+/) : [];
+ var result = $(this);
+ $.each(terms, function() {
+ result.highlightText(this.toLowerCase(), 'highlighted');
+ });
+ });
+
+ // directly open comment window if requested
+ var anchor = document.location.hash;
+ if (anchor.substring(0, 9) == '#comment-') {
+ $('#ao' + anchor.substring(9)).click();
+ document.location.hash = '#s' + anchor.substring(9);
+ }
+});
diff --git a/distro/common/html/chef-client.8.html b/distro/common/html/chef-client.8.html
deleted file mode 100644
index 5e7eee7861..0000000000
--- a/distro/common/html/chef-client.8.html
+++ /dev/null
@@ -1,145 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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-client(8) - Runs a client node connecting to a chef-server.</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>chef-client(8)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>chef-client(8)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>chef-client</code> - <span class="man-whatis">Runs a client node connecting to a chef-server.</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>chef-client</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-S</code>, <code>--server CHEFSERVERURL</code></dt><dd>The chef server URL</dd>
-<dt><code>-c</code>, <code>--config CONFIG</code></dt><dd>The configuration file to use</dd>
-<dt><code>-d</code>, <code>--daemonize</code></dt><dd>Daemonize the process</dd>
-<dt><code>-g</code>, <code>--group GROUP</code></dt><dd>Group to set privilege to</dd>
-<dt><code>-i</code>, <code>--interval SECONDS</code></dt><dd>Run chef-client periodically, in seconds</dd>
-<dt><code>-j</code>, <code>--json-attributes JSON_ATTRIBS</code></dt><dd>Load attributes from a JSON file or URL</dd>
-<dt><code>-E</code>, <code>--environment ENVIRONMENT</code></dt><dd>Set the Chef Environment on the node</dd>
-<dt><code>-l</code>, <code>--log_level LEVEL</code></dt><dd>Set the log level (debug, info, warn, error, fatal)</dd>
-<dt><code>-L</code>, <code>--logfile LOGLOCATION</code></dt><dd>Set the log file location, defaults to STDOUT - recommended for
-daemonizing</dd>
-<dt><code>-N</code>, <code>--node-name NODE_NAME</code></dt><dd>The node name for this client</dd>
-<dt><code>-o</code>, <code>--override-runlist</code></dt><dd>Replace current run list with specified items</dd>
-<dt><code>-K</code>, <code>--validation_key KEY_FILE</code></dt><dd>Set the validation key file location, used for registering new clients</dd>
-<dt><code>-k</code>, <code>--client_key KEY_FILE</code></dt><dd>Set the client key file location</dd>
-<dt><code>-s</code>, <code>--splay SECONDS</code></dt><dd>The splay time for running at intervals, in seconds</dd>
-<dt><code>-u</code>, <code>--user USER</code></dt><dd>User to set privilege to</dd>
-<dt><code>-P</code>, <code>--pid PIDFILE</code></dt><dd>Set the PID file location, defaults to /tmp/chef-client.pid</dd>
-<dt class="flush"><code>--once</code></dt><dd>Cancel any interval or splay options, run chef once and exit</dd>
-<dt><code>-v</code>, <code>--version</code></dt><dd>Show chef version</dd>
-<dt><code>-h</code>, <code>--help</code></dt><dd>Show this message</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>The Chef Client is where almost all of the work in Chef is done. It
-communicates with the Chef Server via REST, authenticates via Signed
-Header Authentication, and compiles and executes Cookbooks.</p>
-
-<p>A Chef Client does work on behalf of a Node. A single Chef Client can
-run recipes for multiple Nodes.</p>
-
-<p>Clients are where all the action happens - the Chef Server and Chef Expander
-are largely services that exist only to provide the Client with information.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p>Full documentation for Chef and chef-client 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="&#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="&#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>
-
-<p>On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0.</p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>chef-client(8)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/chef-expander.8.html b/distro/common/html/chef-expander.8.html
deleted file mode 100644
index b4117034d3..0000000000
--- a/distro/common/html/chef-expander.8.html
+++ /dev/null
@@ -1,164 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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-expander(8) - fetches messages from RabbitMQ, processes, and loads into chef-solr</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>chef-expander(8)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>chef-expander(8)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>chef-expander</code> - <span class="man-whatis">fetches messages from RabbitMQ, processes, and loads into chef-solr</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>chef-expander</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-c</code>, <code>--config CONFIG_FILE</code></dt><dd>a configuration file to use</dd>
-<dt><code>-i</code>, <code>--index INDEX</code></dt><dd>the slot this node will occupy in the ring</dd>
-<dt><code>-n</code>, <code>--node-count NUMBER</code></dt><dd>the number of nodes in the ring</dd>
-<dt><code>-l</code>, <code>--log-level LOG_LEVEL</code></dt><dd>set the log level</dd>
-<dt><code>-L</code>, <code>--logfile LOG_LOCATION</code></dt><dd>Logfile to use</dd>
-<dt><code>-d</code>, <code>--daemonize</code></dt><dd>fork into the background</dd>
-<dt><code>-P</code>, <code>--pid PIDFILE</code></dt><dd>PID file</dd>
-<dt><code>-h</code>, <code>--help</code></dt><dd>show help message</dd>
-<dt><code>-v</code>, <code>--version</code></dt><dd>show the version and exit</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Chef Expander fetches messages from RabbitMQ, processes them into the
-correct format to be loaded into Solr and loads them into Solr.</p>
-
-<p><strong>Running Chef Expander</strong></p>
-
-<p>Chef Expander is designed for clustered operation, though small
-installations will only need one worker process. To run Chef
-Expander with one worker process, run chef-expander -n 1.
-You will then have a master and worker process, which looks like
-this in ps:</p>
-
-<pre><code>your-shell&gt; ps aux|grep expander
-you 52110 0.1 0.7 2515476 62748 s003 S+ 3:49PM 0:00.80 chef-expander worker #1 (vnodes 0-1023)
-you 52108 0.1 0.5 2492880 41696 s003 S+ 3:49PM 0:00.91 ruby bin/chef-expander -n 1
-</code></pre>
-
-<p>Workers are single threaded and therefore cannot use more than 100%
-of a single CPU. If you find that your queues are getting backlogged,
-increase the number of workers</p>
-
-<p><strong>Design</strong></p>
-
-<p>Chef Expander uses 1024 queues (called vnodes in some places) to allow
-you to scale the number of Chef Expander workers to meet the needs of
-your infrastructure. When objects are saved in the API server, they are
-added to queues based on their database IDs. These queues can be assigned
-to different Chef Expander workers to distribute the load of processing
-the index updates.</p>
-
-<p><strong>Chef Expander Operation and Troubleshooting</strong></p>
-
-<p>Chef Expander includes chef-expanderctl, a management program that allows
-you to get status information or change the logging verbosity (without
-restarting).</p>
-
-<p>See <strong>chef-expanderctl</strong>(8) for details.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p><strong>chef-expanderctl</strong>(8)
-<strong>chef-solr</strong>(8)</p>
-
-<p>Full documentation for Chef and chef-server 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;&#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="&#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>
-
-<p>On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0.</p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>chef-expander(8)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/chef-expanderctl.8.html b/distro/common/html/chef-expanderctl.8.html
deleted file mode 100644
index 2d93233feb..0000000000
--- a/distro/common/html/chef-expanderctl.8.html
+++ /dev/null
@@ -1,146 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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-expanderctl(8) - management program for chef-expander</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>chef-expanderctl(8)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>chef-expanderctl(8)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>chef-expanderctl</code> - <span class="man-whatis">management program for chef-expander</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>chef-expanderctl</strong> <em>COMMAND</em></p>
-
-<p><strong>Commands:</strong></p>
-
-<dl>
-<dt class="flush"><code>help</code></dt><dd>Show help message</dd>
-<dt><code>queue-depth</code></dt><dd>display the aggregate queue backlog</dd>
-<dt><code>queue-status</code></dt><dd>show the backlog and consumer count for each vnode queue</dd>
-<dt><code>node-status</code></dt><dd>show the status of the nodes in the cluster</dd>
-<dt><code>log-level</code></dt><dd>sets the log level of all nodes in the cluster</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Chef-expanderctl is a management program that allows
-you to get status information or change the logging
-verbosity (without restarting). chef-expanderctl has
-the following commands:</p>
-
-<ul>
-<li><strong>chef-expanderctl help</strong>
-prints usage.</li>
-<li><strong>chef-expanderctl queue-depth</strong>
-Shows the total number of messages in the queues.</li>
-<li><strong>chef-expanderctl queue-status</strong>
-Show the number of messages in each queue. This is mainly of use when
-debugging a Chef Expander cluster.</li>
-<li><strong>chef-expanderctl log-level LEVEL</strong>
-Sets the log level on a running Chef Expander or cluster.
-If you suspect that a worker process is stuck, as long as you are using
-clustered operation, you can simply kill the worker process and it will
-be restarted by the master process.</li>
-</ul>
-
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p><strong>chef-expander-cluster</strong>(8)
-<strong>chef-solr</strong>(8)</p>
-
-<p>Full documentation for Chef and chef-server 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;&#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="&#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>
-
-<p>On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0.</p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>chef-expanderctl(8)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/chef-server-webui.8.html b/distro/common/html/chef-server-webui.8.html
deleted file mode 100644
index f498e36302..0000000000
--- a/distro/common/html/chef-server-webui.8.html
+++ /dev/null
@@ -1,185 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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-server-webui(8) - Start the Chef Server merb application slice providing Web User Interface (Management Console).</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>chef-server-webui(8)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>chef-server-webui(8)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>chef-server-webui</code> - <span class="man-whatis">Start the Chef Server merb application slice providing Web User Interface (Management Console).</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>chef-server-webui</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-u</code>, <code>--user USER</code></dt><dd>This flag is for having chef-server-webui run as a user other than the
-one currently logged in. Note: if you set this you must also provide a
---group option for it to take effect.</dd>
-<dt><code>-G</code>, <code>--group GROUP</code></dt><dd>This flag is for having chef-server-webui run as a group other than the
-one currently logged in. Note: if you set this you must also provide a
---user option for it to take effect.</dd>
-<dt><code>-d</code>, <code>--daemonize</code></dt><dd>This will run a single chef-server-webui in the background.</dd>
-<dt><code>-N</code>, <code>--no-daemonize</code></dt><dd>This will allow you to run a cluster in console mode.</dd>
-<dt><code>-c</code>, <code>--cluster-nodes NUM_MERBS</code></dt><dd>Number of merb daemons to run for chef-server-webui.</dd>
-<dt><code>-I</code>, <code>--init-file FILE</code></dt><dd>File to use for initialization on load, defaults to config/init.rb.</dd>
-<dt><code>-p</code>, <code>--port PORTNUM</code></dt><dd>Port to run chef-server-webui on, defaults to 4040. Additional nodes (-c)
-listen on incrementing port numbers.</dd>
-<dt><code>-o</code>, <code>--socket-file FILE</code></dt><dd>Socket file to run chef-server-webui on, defaults to
-[Merb.root]/log/merb.sock. This is for web servers, like thin, that use
-sockets. Specify this <em>only</em> if you <em>must</em>.</dd>
-<dt><code>-s</code>, <code>--socket SOCKNUM</code></dt><dd>Socket number to run chef-server-webui on, defaults to 0.</dd>
-<dt><code>-n</code>, <code>--name NAME</code></dt><dd>Set the name of the application. This is used in the process title and
-log file names.</dd>
-<dt><code>-P</code>, <code>--pid PIDFILE</code></dt><dd>PID file, defaults to [Merb.root]/log/merb.main.pid for the master
-process and[Merb.root]/log/merb.[port number].pid for worker processes.
-For clusters, use %s to specify where in the file chef-server-webui
-should place the port number. For instance: -P myapp.%s.pid.</dd>
-<dt><code>-h</code>, <code>--host HOSTNAME</code></dt><dd>Host to bind to (default is 0.0.0.0).</dd>
-<dt><code>-m</code>, <code>--merb-root PATH_TO_APP_ROOT</code></dt><dd>The path to the Merb.root for the app you want to run
-(default is current working directory).</dd>
-<dt><code>-a</code>, <code>--adapter ADAPTER</code></dt><dd>The rack adapter to use to run chef-server-webui (default is mongrel)
-[mongrel, emongrel, thin, ebb, fastcgi, webrick].</dd>
-<dt><code>-R</code>, <code>--rackup FILE</code></dt><dd>Load an alternate Rack config file (default is config/rack.rb).</dd>
-<dt><code>-i</code>, <code>--irb-console</code></dt><dd>This flag will start chef-server-webui in irb console mode. All your models
-and other classes will be available for you in an irb session.</dd>
-<dt><code>-S</code>, <code>--sandbox</code></dt><dd>This flag will enable a sandboxed irb console. If your ORM supports
-transactions, all edits will be rolled back on exit.</dd>
-<dt><code>-l</code>, <code>--log-level LEVEL</code></dt><dd>Log levels can be set to any of these options:
-debug &lt; info &lt; warn &lt; error &lt; fatal (default is info).</dd>
-<dt><code>-L</code>, <code>--log LOGFILE</code></dt><dd>A string representing the logfile to use. Defaults to
-[Merb.root]/log/merb.[main].log for the master process and
-[Merb.root]/log/merb[port number].logfor worker processes.</dd>
-<dt><code>-e</code>, <code>--environment STRING</code></dt><dd>Environment to run Merb under [development, production, testing]
-(default is development).</dd>
-<dt><code>-r</code>, <code>--script-runner ['RUBY CODE'| FULL_SCRIPT_PATH]</code></dt><dd>Command-line option to run scripts and/or code in the chef-server-webui
-app.</dd>
-<dt><code>-K</code>, <code>-graceful PORT or all</code></dt><dd>Gracefully kill chef-server-webui proceses by port number.
-Use chef-server -K all to gracefully kill all merbs.</dd>
-<dt><code>-k</code>, <code>--kill PORT</code></dt><dd>Force kill one merb worker by port number. This will cause the worker
-to be respawned.</dd>
-<dt><code>--fast-deploy</code></dt><dd>Reload the code, but not yourinit.rb or gems.</dd>
-<dt><code>-X</code>, <code>--mutex on/off</code></dt><dd>This flag is for turning the mutex lock on and off.</dd>
-<dt><code>-D</code>, <code>--debugger</code></dt><dd>Run chef-server-webui using rDebug.</dd>
-<dt><code>-V</code>, <code>--verbose</code></dt><dd>Print extra information.</dd>
-<dt><code>-C</code>, <code>--console-trap</code></dt><dd>Enter an irb console on ^C.</dd>
-<dt><code>-?</code>, <code>-H</code>, <code>--help</code></dt><dd>Show this help message.</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>The Chef Server WebUI (Management Console) is a Merb application slice.
-The default listen port is 4040.</p>
-
-<p>The Management Console is Chef Server's web interface. Nodes, roles,
-cookbooks, data bags, and API clients can be managed through the Management
-Console. Search can also be done on the console.</p>
-
-<p>In order to start using the Management Console, you need to first create
-a user or change the default password on the "admin" user.</p>
-
-<p>The default credentials are:</p>
-
-<ul>
-<li><code>Username</code>: admin</li>
-<li><code>Password</code>: p@ssw0rd1</li>
-</ul>
-
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p>Full documentation for Chef and chef-server-webui (Management Console)
-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;&#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;&#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>
-
-<p>On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0.</p>
-
-
- <ol class='man-decor man-foot man foot'>
- <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>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/chef-server.8.html b/distro/common/html/chef-server.8.html
deleted file mode 100644
index ed59f0f62c..0000000000
--- a/distro/common/html/chef-server.8.html
+++ /dev/null
@@ -1,182 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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-server(8) - Start the Chef Server merb application slice.</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>chef-server(8)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>chef-server(8)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>chef-server</code> - <span class="man-whatis">Start the Chef Server merb application slice.</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>chef-server</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-u</code>, <code>--user USER</code></dt><dd>This flag is for having chef-server-webui run as a user other than the
-one currently logged in. Note: if you set this you must also provide a
---group option for it to take effect.</dd>
-<dt><code>-G</code>, <code>--group GROUP</code></dt><dd>This flag is for having chef-server-webui run as a group other than the
-one currently logged in. Note: if you set this you must also provide a
---user option for it to take effect.</dd>
-<dt><code>-d</code>, <code>--daemonize</code></dt><dd>This will run a single chef-server-webui in the background.</dd>
-<dt><code>-N</code>, <code>--no-daemonize</code></dt><dd>This will allow you to run a cluster in console mode.</dd>
-<dt><code>-c</code>, <code>--cluster-nodes NUM_MERBS</code></dt><dd>Number of merb daemons to run for chef-server-webui.</dd>
-<dt><code>-I</code>, <code>--init-file FILE</code></dt><dd>File to use for initialization on load, defaults to config/init.rb.</dd>
-<dt><code>-p</code>, <code>--port PORTNUM</code></dt><dd>Port to run chef-server-webui on, defaults to 4040. Additional nodes (-c)
-listen on incrementing port numbers.</dd>
-<dt><code>-o</code>, <code>--socket-file FILE</code></dt><dd>Socket file to run chef-server-webui on, defaults to
-[Merb.root]/log/merb.sock. This is for web servers, like thin, that use
-sockets. Specify this <em>only</em> if you <em>must</em>.</dd>
-<dt><code>-s</code>, <code>--socket SOCKNUM</code></dt><dd>Socket number to run chef-server-webui on, defaults to 0.</dd>
-<dt><code>-n</code>, <code>--name NAME</code></dt><dd>Set the name of the application. This is used in the process title and
-log file names.</dd>
-<dt><code>-P</code>, <code>--pid PIDFILE</code></dt><dd>PID file, defaults to [Merb.root]/log/merb.main.pid for the master
-process and[Merb.root]/log/merb.[port number].pid for worker processes.
-For clusters, use %s to specify where in the file chef-server-webui
-should place the port number. For instance: -P myapp.%s.pid.</dd>
-<dt><code>-h</code>, <code>--host HOSTNAME</code></dt><dd>Host to bind to (default is 0.0.0.0).</dd>
-<dt><code>-m</code>, <code>--merb-root PATH_TO_APP_ROOT</code></dt><dd>The path to the Merb.root for the app you want to run
-(default is current working directory).</dd>
-<dt><code>-a</code>, <code>--adapter ADAPTER</code></dt><dd>The rack adapter to use to run chef-server-webui (default is mongrel)
-[mongrel, emongrel, thin, ebb, fastcgi, webrick].</dd>
-<dt><code>-R</code>, <code>--rackup FILE</code></dt><dd>Load an alternate Rack config file (default is config/rack.rb).</dd>
-<dt><code>-i</code>, <code>--irb-console</code></dt><dd>This flag will start chef-server-webui in irb console mode. All your models
-and other classes will be available for you in an irb session.</dd>
-<dt><code>-S</code>, <code>--sandbox</code></dt><dd>This flag will enable a sandboxed irb console. If your ORM supports
-transactions, all edits will be rolled back on exit.</dd>
-<dt><code>-l</code>, <code>--log-level LEVEL</code></dt><dd>Log levels can be set to any of these options:
-debug &lt; info &lt; warn &lt; error &lt; fatal (default is info).</dd>
-<dt><code>-L</code>, <code>--log LOGFILE</code></dt><dd>A string representing the logfile to use. Defaults to
-[Merb.root]/log/merb.[main].log for the master process and
-[Merb.root]/log/merb[port number].logfor worker processes.</dd>
-<dt><code>-e</code>, <code>--environment STRING</code></dt><dd>Environment to run Merb under [development, production, testing]
-(default is development).</dd>
-<dt><code>-r</code>, <code>--script-runner ['RUBY CODE'| FULL_SCRIPT_PATH]</code></dt><dd>Command-line option to run scripts and/or code in the chef-server-webui
-app.</dd>
-<dt><code>-K</code>, <code>-graceful PORT or all</code></dt><dd>Gracefully kill chef-server-webui proceses by port number.
-Use chef-server -K all to gracefully kill all merbs.</dd>
-<dt><code>-k</code>, <code>--kill PORT</code></dt><dd>Force kill one merb worker by port number. This will cause the worker
-to be respawned.</dd>
-<dt><code>--fast-deploy</code></dt><dd>Reload the code, but not yourinit.rb or gems.</dd>
-<dt><code>-X</code>, <code>--mutex on/off</code></dt><dd>This flag is for turning the mutex lock on and off.</dd>
-<dt><code>-D</code>, <code>--debugger</code></dt><dd>Run chef-server-webui using rDebug.</dd>
-<dt><code>-V</code>, <code>--verbose</code></dt><dd>Print extra information.</dd>
-<dt><code>-C</code>, <code>--console-trap</code></dt><dd>Enter an irb console on ^C.</dd>
-<dt><code>-?</code>, <code>-H</code>, <code>--help</code></dt><dd>Show this help message.</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>The Chef Server provides a central point for the distribution of Cookbooks,
-management and authentication of Nodes, and the use of Search. It provides
-a REST API.</p>
-
-<p>The API service is what clients use to interact with the server to manage
-node configuration in Chef. By default, the service is started on port 4000
-as a Merb application slice running with the thin server adapter.</p>
-
-<p>The two methods of interaction with the API for humans are the command-line
-tool Knife and the Management Console. The Chef Client library is used for
-interacting with the API for client nodes.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p><strong>chef-client</strong>(8)
-<strong>chef-server-webui</strong>(8)
-<strong>knife</strong>(1)</p>
-
-<p>Full documentation for Chef and chef-server 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;&#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;&#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>
-
-<p>On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0.</p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>chef-server(8)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/chef-shell.1.html b/distro/common/html/chef-shell.1.html
deleted file mode 100644
index a77e2b9060..0000000000
--- a/distro/common/html/chef-shell.1.html
+++ /dev/null
@@ -1,286 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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-shell(1) - Interactive Chef Console</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SYNTAX">SYNTAX</a>
- <a href="#PRIMARY-MODE">PRIMARY MODE</a>
- <a href="#RECIPE-MODE">RECIPE MODE</a>
- <a href="#EXAMPLES">EXAMPLES</a>
- <a href="#BUGS">BUGS</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>chef-shell(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>chef-shell(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>chef-shell</code> - <span class="man-whatis">Interactive Chef Console</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>chef-shell</strong> [<em>named configuration</em>] <em>(options)</em></p>
-
-<dl>
-<dt><code>-S</code>, <code>--server CHEF_SERVER_URL</code></dt><dd>The chef server URL</dd>
-<dt><code>-z</code>, <code>--client</code></dt><dd>chef-client mode</dd>
-<dt><code>-c</code>, <code>--config CONFIG</code></dt><dd>The configuration file to use</dd>
-<dt><code>-j</code>, <code>--json-attributes JSON_ATTRIBS</code></dt><dd>Load attributes from a JSON file or URL</dd>
-<dt><code>-l</code>, <code>--log-level LOG_LEVEL</code></dt><dd>Set the logging level</dd>
-<dt><code>-s</code>, <code>--solo</code></dt><dd>chef-solo session</dd>
-<dt><code>-a</code>, <code>--standalone</code></dt><dd>standalone session</dd>
-<dt><code>-v</code>, <code>--version</code></dt><dd>Show chef version</dd>
-<dt><code>-h</code>, <code>--help</code></dt><dd>Show command options</dd>
-</dl>
-
-
-<p>When no --config option is specified, chef-shell attempts to load a
-default configuration file:</p>
-
-<ul>
-<li>If a <em>named configuration</em> is given, chef-shell will load ~/.chef/<em>named
-configuration</em>/chef_shell.rb</li>
-<li>If no <em>named configuration</em> is given chef-shell will load
-~/.chef/chef_shell.rb if it exists</li>
-<li>chef-shell falls back to loading /etc/chef/client.rb or
-/etc/chef/solo.rb if -z or -s options are given and no chef_shell.rb
-can be found.</li>
-<li>The --config option takes precedence over implicit configuration
-paths.</li>
-</ul>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p><code>chef-shell</code> is an <span class="man-ref">irb<span class="s">(1)</span></span> (interactive ruby) session customized for Chef.
-<code>chef-shell</code> serves two primary functions: it provides a means to
-interact with a Chef Server interactively using a convenient DSL; it
-allows you to define and run Chef recipes interactively.</p>
-
-<h2 id="SYNTAX">SYNTAX</h2>
-
-<p>chef-shell uses irb's subsession feature to provide multiple modes of
-interaction. In addition to the primary mode which is entered on start,
-<code>recipe</code> and <code>attributes</code> modes are available.</p>
-
-<h2 id="PRIMARY-MODE">PRIMARY MODE</h2>
-
-<p>The following commands are available in the primary
-session:</p>
-
-<dl>
-<dt class="flush"><code>help</code></dt><dd>Prints a list of available commands</dd>
-<dt class="flush"><code>version</code></dt><dd>Prints the Chef version</dd>
-<dt class="flush"><code>recipe</code></dt><dd>Switches to <code>recipe</code> mode</dd>
-<dt><code>attributes</code></dt><dd>Switches to <code>attributes</code> mode</dd>
-<dt><code>run_chef</code></dt><dd>Initiates a chef run</dd>
-<dt class="flush"><code>reset</code></dt><dd>reinitializes chef-shell session</dd>
-<dt><code>echo :on|:off</code></dt><dd>Turns irb's echo function on or off. Echo is <em>on</em> by default.</dd>
-<dt><code>tracing :on|:off</code></dt><dd>Turns irb's function tracing feature on or off. Tracing is extremely
-verbose and expected to be of interest primarily to developers.</dd>
-<dt class="flush"><code>node</code></dt><dd>Returns the <em>node</em> object for the current host. See <span class="man-ref">knife-node<span class="s">(1)</span></span>
-for more information about nodes.</dd>
-<dt class="flush"><code>ohai</code></dt><dd>Prints the attributes of <em>node</em></dd>
-</dl>
-
-
-<p>In addition to these commands, chef-shell provides a DSL for accessing
-data on the Chef Server. When working with remote data in chef-shell, you
-chain method calls in the form <em>object type</em>.<em>operation</em>, where
-<em>object type</em> is in plural form. The following object types are
-available:</p>
-
-<ul>
-<li><code>nodes</code></li>
-<li><code>roles</code></li>
-<li><code>data_bags</code></li>
-<li><code>clients</code></li>
-<li><code>cookbooks</code></li>
-</ul>
-
-
-<p>For each <em>object type</em> the following operations are available:</p>
-
-<dl>
-<dt><em>object type</em>.all(<em>&amp;block</em>)</dt><dd>Loads all items from the server. If the optional code <em>block</em> is
-given, each item will be passed to the block and the results
-returned, similar to ruby's <code>Enumerable#map</code> method.</dd>
-<dt><em>object type</em>.show(<em>object name</em>)</dt><dd><p>Aliased as <em>object type</em>.load</p>
-
-<p>Loads the singular item identified by <em>object name</em>.</p></dd>
-<dt><em>object type</em>.search(<em>query</em>, <em>&amp;block</em>)</dt><dd><p>Aliased as <em>object type</em>.find</p>
-
-<p>Runs a search against the server and returns the matching items. If
-the optional code <em>block</em> is given each item will be passed to the
-block and the results returned.</p>
-
-<p>The <em>query</em> may be a Solr/Lucene format query given as a String, or
-a Hash of conditions. If a Hash is given, the options will be ANDed
-together. To join conditions with OR, use negative queries, or any
-advanced search syntax, you must provide give the query in String
-form.</p></dd>
-<dt><em>object type</em>.transform(:all|<em>query</em>, <em>&amp;block</em>)</dt><dd><p>Aliased as <em>object type</em>.bulk_edit</p>
-
-<p>Bulk edit objects by processing them with the (required) code <em>block</em>.
-You can edit all objects of the given type by passing the Symbol
-<code>:all</code> as the argument, or only a subset by passing a <em>query</em> as the
-argument. The <em>query</em> is evaluated in the same way as with
-<strong>search</strong>.</p>
-
-<p>The return value of the code <em>block</em> is used to alter the behavior
-of <code>transform</code>. If the value returned from the block is <code>nil</code> or
-<code>false</code>, the object will not be saved. Otherwise, the object is
-saved after being passed to the block. This behavior can be
-exploited to create a dry run to test a data transformation.</p></dd>
-</dl>
-
-
-<h2 id="RECIPE-MODE">RECIPE MODE</h2>
-
-<p>Recipe mode implements Chef's recipe DSL. Exhaustively documenting this
-DSL is outside the scope of this document. See the following pages in
-the Chef documentation for more information:</p>
-
-<ul>
-<li><a href="http://wiki.opscode.com/display/chef/Resources" data-bare-link="true">http://wiki.opscode.com/display/chef/Resources</a></li>
-<li><a href="http://wiki.opscode.com/display/chef/Recipes" data-bare-link="true">http://wiki.opscode.com/display/chef/Recipes</a></li>
-</ul>
-
-
-<p>Once you have defined resources in the recipe, you can trigger a
-convergence run via <code>run_chef</code></p>
-
-<h2 id="EXAMPLES">EXAMPLES</h2>
-
-<ul>
-<li><p>A "Hello World" interactive recipe</p>
-
-<p>chef > recipe
-chef:recipe > echo :off
-chef:recipe > file "/tmp/hello_world"
-chef:recipe > run_chef
-[Sat, 09 Apr 2011 08:56:56 -0700] INFO: Processing file[/tmp/hello_world] action create ((irb#1) line 2)
-[Sat, 09 Apr 2011 08:56:56 -0700] INFO: file[/tmp/hello_world] created file /tmp/hello_world
-chef:recipe > pp ls '/tmp'
-[".",
-"..",
-"hello_world"]</p></li>
-<li><p>Search for <em>nodes</em> by role, and print their IP addresses</p>
-
-<p>chef > nodes.find(:roles => 'monitoring-server') {|n| n[:ipaddress] }
-=> ["10.254.199.5"]</p></li>
-<li><p>Remove the role <em>obsolete</em> from every node in the system</p>
-
-<p>chef > nodes.transform(:all) {|n| n.run_list.delete('role[obsolete]') }
- => [node[chef098b2.opschef.com], node[ree-woot], node[graphite-dev], node[fluke.localdomain], node[ghost.local], node[kallistec]]</p></li>
-</ul>
-
-
-<h2 id="BUGS">BUGS</h2>
-
-<p><code>chef-shell</code> often does not perfectly replicate the context in which
-<span class="man-ref">chef-client<span class="s">(8)</span></span> configures a host, which may lead to discrepancies in
-observed behavior.</p>
-
-<p><code>chef-shell</code> has to duplicate much code from chef-client's internal
-libraries and may become out of sync with the behavior of those
-libraries.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <span class="man-ref">chef-client<span class="s">(8)</span></span> <span class="man-ref">knife<span class="s">(1)</span></span>
- <a href="http://wiki.opscode.com/display/chef/Chef+Shell" data-bare-link="true">http://wiki.opscode.com/display/chef/Chef+Shell</a></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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;&#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>
-
-<h2 id="CHEF">CHEF</h2>
-
-<p> chef-shell is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>chef-shell(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/chef-solo.8.html b/distro/common/html/chef-solo.8.html
deleted file mode 100644
index 3356c32bed..0000000000
--- a/distro/common/html/chef-solo.8.html
+++ /dev/null
@@ -1,185 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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-solo(8) - Runs chef in solo mode against a specified cookbook location.</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>chef-solo(8)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>chef-solo(8)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>chef-solo</code> - <span class="man-whatis">Runs chef in solo mode against a specified cookbook location.</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>chef-solo</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-c</code>, <code>--config CONFIG</code></dt><dd>The configuration file to use</dd>
-<dt><code>-d</code>, <code>--daemonize</code></dt><dd>Daemonize the process</dd>
-<dt><code>-g</code>, <code>--group GROUP</code></dt><dd>Group to set privilege to</dd>
-<dt><code>-i</code>, <code>--interval SECONDS</code></dt><dd>Run chef-client periodically, in seconds</dd>
-<dt><code>-j</code>, <code>--json-attributes JSON_ATTRIBS</code></dt><dd>Load attributes from a JSON file or URL</dd>
-<dt><code>-l</code>, <code>--log_level LEVEL</code></dt><dd>Set the log level (debug, info, warn, error, fatal)</dd>
-<dt><code>-L</code>, <code>--logfile LOGLOCATION</code></dt><dd>Set the log file location, defaults to STDOUT - recommended for
-daemonizing</dd>
-<dt><code>-N</code>, <code>--node-name NODE_NAME</code></dt><dd>The node name for this client</dd>
-<dt><code>-r</code>, <code>--recipe-url RECIPE_URL</code></dt><dd>Pull down a remote gzipped tarball of recipes and untar it to the
-cookbook cache.</dd>
-<dt><code>-s</code>, <code>--splay SECONDS</code></dt><dd>The splay time for running at intervals, in seconds</dd>
-<dt><code>-u</code>, <code>--user USER</code></dt><dd>User to set privilege to</dd>
-<dt><code>-v</code>, <code>--version</code></dt><dd>Show chef version</dd>
-<dt><code>-h</code>, <code>--help</code></dt><dd>Show this message</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Chef Solo allows you to run Chef Cookbooks in the absence of a Chef Server.
-To do this, the complete cookbook needs to be present on disk.</p>
-
-<p>By default Chef Solo will look in /etc/chef/solo.rb for its configuration.
-This configuration file has two required variables: file_cache_path and
-cookbook_path.</p>
-
-<p>For example:
- file_cache_path "/var/chef-solo"
- cookbook_path "/var/chef-solo/cookbooks"</p>
-
-<p>For your own systems, you can change this to reflect any directory you like,
-but you'll need to specify absolute paths and the cookbook_path directory
-should be a subdirectory of the file_cache_path.</p>
-
-<p>You can also specify cookbook_path as an array, passing multiple locations
-to search for cookbooks.</p>
-
-<p>For example:
- file_cache_path "/var/chef-solo"
- cookbook_path ["/var/chef-solo/cookbooks", "/var/chef-solo/site-cookbooks"]</p>
-
-<p>Note that earlier entries are now overridden by later ones.</p>
-
-<p>Since chef-solo doesn't have any interaction with a Chef Server, you'll need
-to specify node-specifc attributes in a JSON file. This can be located on the
-target system itself, or it can be stored on a remote server such as S3, or a
-web server on your network.</p>
-
-<p>Within the JSON file, you'll also specify the recipes that Chef should run in
-the "run_list". An example JSON file, which sets a resolv.conf:</p>
-
-<pre><code>{
- "resolver": {
- "nameservers": [ "10.0.0.1" ],
- "search":"int.example.com"
- },
- "run_list": [ "recipe[resolver]" ]
-}
-</code></pre>
-
-<p>Then you can run chef-solo with -j to specify the JSON file. It will look for
-cookbooks in the cookbook_path configured in the configuration file, and apply
-attributes and use the run_list from the JSON file specified.</p>
-
-<p>You can use -c to specify the path to the configuration file (if you don't want
-chef-solo to use the default). You can also specify -r for a cookbook tarball.</p>
-
-<p>For example:
- chef-solo -c ~/solo.rb -j ~/node.json -r http://www.example.com/chef-solo.tar.gz</p>
-
-<p>In the above case, chef-solo would extract the tarball to your specified
-cookbook_path, use ~/solo.rb as the configuration file, and apply attributes
-and use the run_list from ~/node.json.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p>Full documentation for Chef and chef-solo 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;&#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;&#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>
-
-<p>On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0.</p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>chef-solo(8)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/chef-solr.8.html b/distro/common/html/chef-solr.8.html
deleted file mode 100644
index 3ef7108ad0..0000000000
--- a/distro/common/html/chef-solr.8.html
+++ /dev/null
@@ -1,165 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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&#39;s search server</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>chef-solr(8)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>chef-solr(8)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>chef-solr</code> - <span class="man-whatis">Runs as Chef's search server</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>chef-solr</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-c</code>, <code>--config CONFIG</code></dt><dd>The configuration file to use</dd>
-<dt><code>-d</code>, <code>--daemonize</code></dt><dd>Daemonize the process</dd>
-<dt><code>-g</code>, <code>--group GROUP</code></dt><dd>Group to set privilege to</dd>
-<dt><code>-l</code>, <code>--log_level LEVEL</code></dt><dd>Set the log level (debug, info, warn, error, fatal)</dd>
-<dt><code>-L</code>, <code>--logfile LOGLOCATION</code></dt><dd>Set the log file location, defaults to STDOUT - recommended for daemonizing</dd>
-<dt><code>-P</code>, <code>--pid PIDFILE</code></dt><dd>Set the PID file location, defaults to /tmp/chef-solr.pid</dd>
-<dt><code>-D</code>, <code>--solr-data-dir PATH</code></dt><dd>Where the Solr data lives</dd>
-<dt><code>-x</code>, <code>--solor-heap-size SIZE</code></dt><dd>Set the size of the Java Heap</dd>
-<dt><code>-H</code>, <code>--solr-home-dir PATH</code></dt><dd>Solr home directory</dd>
-<dt><code>-j</code>, <code>--java-opts OPTS</code></dt><dd>Raw options passed to Java</dd>
-<dt><code>-x</code>, <code>--solor-heap-size</code></dt><dd>Set the size of the Java Heap</dd>
-<dt><code>-W</code>, <code>--solr-jetty-dir PATH</code></dt><dd>Where to place the Solr Jetty instance</dd>
-<dt><code>-u</code>, <code>--user USER</code></dt><dd>User to set privilege to</dd>
-<dt><code>-v</code>, <code>--version</code></dt><dd>Show chef-solr version</dd>
-<dt><code>-h</code>, <code>--help</code></dt><dd>Show this message</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Chef-solr provides search service for Chef. You need to have both
-chef-solr and chef-expander-cluster running in order for search to work.</p>
-
-<p><strong>Installation</strong></p>
-
-<p>Make sure you backed up your data if you are upgrading from a previous version.
-Run chef-solr-installer to upgrade your Chef Solr installation. Answer "yes"
-when prompted for confirmation. The process should look like this:</p>
-
-<pre><code>yourshell&gt; chef-solr-installer
-Configuration setting solr_heap_size is unknown and will be ignored
-
-Chef Solr is already installed in /var/chef/solr
-Do you want to overwrite the current install? All existing Solr data will be lost. [y/n] y
-Removing the existing Chef Solr installation
- rm -rf /var/chef/solr
- rm -rf /var/chef/solr-jetty
- rm -rf /var/chef/solr/data
-Creating Solr Home Directory
- mkdir -p /var/chef/solr
- entering /var/chef/solr
- tar zxvf /Users/ddeleo/opscode/chef/chef-solr/solr/solr-home.tar.gz
-Creating Solr Data Directory
- mkdir -p /var/chef/solr/data
-Unpacking Solr Jetty
- mkdir -p /var/chef/solr-jetty
- entering /var/chef/solr-jetty
- tar zxvf /Users/ddeleo/opscode/chef/chef-solr/solr/solr-jetty.tar.gz
-
-Successfully installed Chef Solr.
-You can restore your search index using `knife index rebuild`
-</code></pre>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p><strong>chef-expander-cluster</strong>(8)</p>
-
-<p>Full documentation for Chef and chef-server 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;&#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="&#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>
-
-<p>On Debian systems, the complete text of the Apache 2.0 License can be
-found in /usr/share/common-licenses/Apache-2.0.</p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>chef-solr(8)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/ctl_chef_client.html b/distro/common/html/ctl_chef_client.html
new file mode 100644
index 0000000000..454437bccf
--- /dev/null
+++ b/distro/common/html/ctl_chef_client.html
@@ -0,0 +1,219 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>chef-client &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="chef-client">
+<h1>chef-client<a class="headerlink" href="#chef-client" title="Permalink to this headline">¶</a></h1>
+<p>A chef-client is an agent that runs locally on every node that is registered with the server. When a chef-client is run, it will perform all of the steps that are required to bring the node into the expected state, including:</p>
+<ul class="simple">
+<li>Registering and authenticating the node with the server</li>
+<li>Building the node object</li>
+<li>Synchronizing cookbooks</li>
+<li>Compiling the resource collection by loading each of the required cookbooks, including recipes, attributes, and all other dependencies</li>
+<li>Taking the appropriate and required actions to configure the node</li>
+<li>Looking for exceptions and notifications, handling each as required</li>
+</ul>
+<p>The chef-client executable can be run as a command-line tool.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">A client.rb file is used to specify the configuration details for the chef-client. This file is the default configuration file and is loaded every time the chef-client executable is run. The chef-client executable can be run as a daemon. On UNIX- and Linux-based machines, the configuration file is located at: <tt class="docutils literal"><span class="pre">/etc/chef/client.rb</span></tt>. On Microsoft Windows machines, the configuration file is located at <tt class="docutils literal"><span class="pre">C:\chef\client.rb</span></tt>.</p>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<p>This command has the following syntax:</p>
+<div class="highlight-python"><pre>chef-client OPTION VALUE OPTION VALUE ...</pre>
+</div>
+<p>This command has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-A</span></tt>, <tt class="docutils literal"><span class="pre">--fatal-windows-admin-check</span></tt></dt>
+<dd>Indicates that a chef-client run should fail if the chef-client does not have administrator privileges in Microsoft Windows.</dd>
+<dt><tt class="docutils literal"><span class="pre">--chef-zero-port</span> <span class="pre">PORT</span></tt></dt>
+<dd>The port on which chef-zero will listen.</dd>
+<dt><tt class="docutils literal"><span class="pre">-F</span> <span class="pre">FORMAT</span></tt>, <tt class="docutils literal"><span class="pre">--format</span> <span class="pre">FORMAT</span></tt></dt>
+<dd><p class="first">The output format: <tt class="docutils literal"><span class="pre">doc</span></tt> (default) or <tt class="docutils literal"><span class="pre">min</span></tt>.</p>
+<p>Use <tt class="docutils literal"><span class="pre">doc</span></tt> to print the progress of the chef-client run using full strings that display a summary of updates as they occur.</p>
+<p>Use <tt class="docutils literal"><span class="pre">min</span></tt> to print the progress of the chef-client run using single characters. A summary of updates is printed at the end of the chef-client run. A dot (<tt class="docutils literal"><span class="pre">.</span></tt>) is printed for events that do not have meaningful status information, such as loading a file or synchronizing a cookbook. For resources, a dot (<tt class="docutils literal"><span class="pre">.</span></tt>) is printed when the resource is up to date, an <tt class="docutils literal"><span class="pre">S</span></tt> is printed when the resource is skipped by <tt class="docutils literal"><span class="pre">not_if</span></tt> or <tt class="docutils literal"><span class="pre">only_if</span></tt>, and a <tt class="docutils literal"><span class="pre">U</span></tt> is printed when the resource is updated.</p>
+<p class="last">Other formatting options are available when those formatters are configured in the client.rb file using the <tt class="docutils literal"><span class="pre">add_formatter</span></tt> option.</p>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">--force-formatter</span></tt></dt>
+<dd>Indicates that formatter output will be used instead of logger output.</dd>
+<dt><tt class="docutils literal"><span class="pre">--force-logger</span></tt></dt>
+<dd>Indicates that logger output will be used instead of formatter output.</dd>
+<dt><tt class="docutils literal"><span class="pre">-g</span> <span class="pre">GROUP</span></tt>, <tt class="docutils literal"><span class="pre">--group</span> <span class="pre">GROUP</span></tt></dt>
+<dd>The name of the group that owns a process. This is required when starting any executable as a daemon.</dd>
+<dt><tt class="docutils literal"><span class="pre">-h</span></tt>, <tt class="docutils literal"><span class="pre">--help</span></tt></dt>
+<dd>Shows help for the command.</dd>
+<dt><tt class="docutils literal"><span class="pre">-i</span> <span class="pre">SECONDS</span></tt>, <tt class="docutils literal"><span class="pre">--interval</span> <span class="pre">SECONDS</span></tt></dt>
+<dd>The frequency (in seconds) at which the chef-client runs. Default value: <tt class="docutils literal"><span class="pre">1800</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-j</span> <span class="pre">PATH</span></tt>, <tt class="docutils literal"><span class="pre">--json-attributes</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to a file that contains JSON data.</dd>
+<dt><tt class="docutils literal"><span class="pre">-k</span> <span class="pre">KEY_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--client_key</span> <span class="pre">KEY_FILE</span></tt></dt>
+<dd>The location of the file which contains the client key. Default value: <tt class="docutils literal"><span class="pre">/etc/chef/client.pem</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-K</span> <span class="pre">KEY_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--validation_key</span> <span class="pre">KEY_FILE</span></tt></dt>
+<dd>The location of the file which contains the key used when a chef-client is registered with a server. A validation key is signed using the <tt class="docutils literal"><span class="pre">validation_client_name</span></tt> for authentication. Default value: <tt class="docutils literal"><span class="pre">/etc/chef/validation.pem</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-l</span> <span class="pre">LEVEL</span></tt>, <tt class="docutils literal"><span class="pre">--log_level</span> <span class="pre">LEVEL</span></tt></dt>
+<dd>The level of logging that will be stored in a log file.</dd>
+<dt><tt class="docutils literal"><span class="pre">-L</span> <span class="pre">LOGLOCATION</span></tt>, <tt class="docutils literal"><span class="pre">--logfile</span> <span class="pre">c</span></tt></dt>
+<dd>The location in which log file output files will be saved. If this location is set to something other than <tt class="docutils literal"><span class="pre">STDOUT</span></tt>, standard output logging will still be performed (otherwise there would be no output other than to a file). This is recommended when starting any executable as a daemon. Default value: <tt class="docutils literal"><span class="pre">STDOUT</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]color</span></tt></dt>
+<dd>Indicates whether colored output will be used. Default setting: <tt class="docutils literal"><span class="pre">--color</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-N</span> <span class="pre">NODE_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--node-name</span> <span class="pre">NODE_NAME</span></tt></dt>
+<dd>The name of the node.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">RUN_LIST_ITEM</span></tt>, <tt class="docutils literal"><span class="pre">--override-runlist</span> <span class="pre">RUN_LIST_ITEM</span></tt></dt>
+<dd>Replace the current run list with the specified items.</dd>
+<dt><tt class="docutils literal"><span class="pre">--once</span></tt></dt>
+<dd>Indicates that the chef-client is run once and that interval and splay options are cancelled.</dd>
+<dt><tt class="docutils literal"><span class="pre">-P</span> <span class="pre">PID_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--pid</span> <span class="pre">PID_FILE</span></tt></dt>
+<dd>The location in which a process identification number (pid) is saved. An executable, when started as a daemon, will write the pid to the specified file. Default value: <tt class="docutils literal"><span class="pre">/tmp/name-of-executable.pid</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-R</span></tt>, <tt class="docutils literal"><span class="pre">--enable-reporting</span></tt></dt>
+<dd>Indicates that data collection reporting is enabled during a chef-client run.</dd>
+<dt><tt class="docutils literal"><span class="pre">-s</span> <span class="pre">SECONDS</span></tt>, <tt class="docutils literal"><span class="pre">--splay</span> <span class="pre">SECONDS</span></tt></dt>
+<dd>A number (in seconds) to add to the <tt class="docutils literal"><span class="pre">interval</span></tt> that is used to determine the frequency of chef-client runs. This number can help prevent server load when there are many clients running at the same time.</dd>
+<dt><tt class="docutils literal"><span class="pre">-S</span> <span class="pre">CHEF_SERVER_URL</span></tt>, <tt class="docutils literal"><span class="pre">--server</span> <span class="pre">CHEF_SERVER_URL</span></tt></dt>
+<dd>The URL for the server.</dd>
+<dt><tt class="docutils literal"><span class="pre">-u</span> <span class="pre">USER</span></tt>, <tt class="docutils literal"><span class="pre">--user</span> <span class="pre">USER</span></tt></dt>
+<dd>The user that owns a process. This is required when starting any executable as a daemon.</dd>
+<dt><tt class="docutils literal"><span class="pre">-v</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt></dt>
+<dd>The version of the chef-client.</dd>
+<dt><tt class="docutils literal"><span class="pre">-W</span></tt>, <tt class="docutils literal"><span class="pre">--why-run</span></tt></dt>
+<dd>Indicates that the executable will be run in why-run mode, which is a type of chef-client run that does everything except modify the system. Use why-run mode to understand why the chef-client makes the decisions that it makes and to learn more about the current and proposed state of the system.</dd>
+<dt><tt class="docutils literal"><span class="pre">-z</span></tt>, <tt class="docutils literal"><span class="pre">--local-mode</span></tt></dt>
+<dd>Indicates that the chef-client will be run in local mode, which allows all commands that work against the server to also work against the local chef-repo.</dd>
+</dl>
+</div>
+<div class="section" id="run-with-elevated-privileges">
+<h2>Run with Elevated Privileges<a class="headerlink" href="#run-with-elevated-privileges" title="Permalink to this headline">¶</a></h2>
+<p>The chef-client may need to be run with elevated privileges in order to get a recipe to converge correctly. On UNIX and UNIX-like operating systems this can be done by running the command as root. On Microsoft Windows this can be done by running the command prompt as an administrator.</p>
+<div class="section" id="linux">
+<h3>Linux<a class="headerlink" href="#linux" title="Permalink to this headline">¶</a></h3>
+<p>On Linux, the following error sometimes occurs when the permissions used to run the chef-client are incorrect:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-client
+<span class="o">[</span>Tue, 29 Nov 2011 19:46:17 -0800<span class="o">]</span> INFO: *** Chef 10.X.X ***
+<span class="o">[</span>Tue, 29 Nov 2011 19:46:18 -0800<span class="o">]</span> WARN: Failed to <span class="nb">read </span>the private key /etc/chef/client.pem: <span class="c">#&lt;Errno::EACCES: Permission denied - /etc/chef/client.pem&gt;</span>
+</pre></div>
+</div>
+<p>This can be resolved by running the command as root. There are a few ways this can be done:</p>
+<ul>
+<li><p class="first">Log in as root and then run the chef-client</p>
+</li>
+<li><p class="first">Use <tt class="docutils literal"><span class="pre">su</span></tt> to become the root user, and then run the chef-client. For example:</p>
+<blockquote>
+<div><div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>su
+</pre></div>
+</div>
+</div></blockquote>
+</li>
+</ul>
+<p>and then:</p>
+<blockquote>
+<div><div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-client
+</pre></div>
+</div>
+</div></blockquote>
+<ul>
+<li><p class="first">Use the sudo utility</p>
+<blockquote>
+<div><div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>sudo chef-client
+</pre></div>
+</div>
+</div></blockquote>
+</li>
+<li><p class="first">Give a user access to read <tt class="docutils literal"><span class="pre">/etc/chef</span></tt> and also the files accessed by the chef-client. This requires super user privileges and, as such, is not a recommended approach</p>
+</li>
+</ul>
+</div>
+<div class="section" id="windows">
+<h3>Windows<a class="headerlink" href="#windows" title="Permalink to this headline">¶</a></h3>
+<p>On Microsoft Windows, running without elevated privileges (when they are necessary) is an issue that fails silently. It will appear that the chef-client completed its run successfully, but the changes will not have been made. When this occurs, do one of the following to run the chef-client as the administrator:</p>
+<ul>
+<li><p class="first">Log in to the administrator account. (This is not the same as an account in the administrator&#8217;s security group.)</p>
+</li>
+<li><p class="first">Run the chef-client process from the administrator account while being logged into another account. Run the following command:</p>
+<blockquote>
+<div><div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>runas /user:Administrator <span class="s2">&quot;cmd /C chef-client&quot;</span>
+</pre></div>
+</div>
+<p>This will prompt for the administrator account password.</p>
+</div></blockquote>
+</li>
+<li><p class="first">Open a command prompt by right-clicking on the command prompt application, and then selecting <strong>Run as administrator</strong>. After the command window opens, the chef-client can be run as the administrator</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p><strong>Start a Chef run when the chef-client is running as a daemon</strong></p>
+<p>A chef-client that is running as a daemon can be woken up and started by sending the process a <tt class="docutils literal"><span class="pre">SIGUSR1</span></tt>. For example, to trigger a chef-client run on a machine running Linux:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>sudo killall -USR1 chef-client
+</pre></div>
+</div>
+<p><strong>Start a Chef run manually</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>ps auxw|grep chef-client
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>root 66066 0.9 0.0 2488880 264 s001 S+ 10:26AM 0:03.05
+/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby /usr/bin/chef-client -i 3600 -s 20
+</pre></div>
+</div>
+<p>and then enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>sudo <span class="nb">kill</span> -USR1 66066
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/ctl_chef_server.html b/distro/common/html/ctl_chef_server.html
new file mode 100644
index 0000000000..8fc86496cd
--- /dev/null
+++ b/distro/common/html/ctl_chef_server.html
@@ -0,0 +1,111 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>chef-server-ctl &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="chef-server-ctl">
+<h1>chef-server-ctl<a class="headerlink" href="#chef-server-ctl" title="Permalink to this headline">¶</a></h1>
+<p>The open source server includes a command-line utility named chef-server-ctl, which is used to start and stop individual services, reconfigure the server, and tail server log files.</p>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<p>This command has the following syntax:</p>
+<div class="highlight-python"><pre>chef-server-ctl OPTION</pre>
+</div>
+<p>This command has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">help</span></tt></dt>
+<dd>Shows help for the command.</dd>
+<dt><tt class="docutils literal"><span class="pre">reconfigure</span></tt></dt>
+<dd>Use to reconfigure the server. This option will read from the <tt class="docutils literal"><span class="pre">/etc/chef-server/chef-server.rb</span></tt> file and apply that configuration to the server. Any time changes are made to the chef-server.rb file, the chef-server-ctl command should be run with this option.</dd>
+<dt><tt class="docutils literal"><span class="pre">restart</span> <span class="pre">[SERVICE_NAME]</span></tt></dt>
+<dd>Use to restart all enabled services or to restart a single service.</dd>
+<dt><tt class="docutils literal"><span class="pre">start</span> <span class="pre">[SERVICE_NAME]</span></tt></dt>
+<dd>Use to start all enabled services or to start a single service.</dd>
+<dt><tt class="docutils literal"><span class="pre">status</span> <span class="pre">[SERVICE_NAME]</span></tt></dt>
+<dd>Use to view the status of all services or to view the status of a single service.</dd>
+<dt><tt class="docutils literal"><span class="pre">stop</span> <span class="pre">[SERVICE_NAME]</span></tt></dt>
+<dd>Use to stop all enabled services or to stop a single service.</dd>
+<dt><tt class="docutils literal"><span class="pre">tail</span> <span class="pre">[SERVICE_NAME]</span></tt></dt>
+<dd>Use to follow the server logs for all services or for a single service.</dd>
+<dt><tt class="docutils literal"><span class="pre">test</span> <span class="pre">--all</span></tt></dt>
+<dd>Use to execute chef-pedant, an integration test suite for the server installation. By default, only a subset of the available test are run. Add the <tt class="docutils literal"><span class="pre">--all</span></tt> flag to run the full test suite.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use chef-server-ctl to manage services.</p>
+<p><strong>View the status of a service</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>ctl-chef-server status name_of_service
+</pre></div>
+</div>
+<p>For example, to view the status for a service named <tt class="docutils literal"><span class="pre">erchef</span></tt>, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>ctl-chef-server status erchef
+</pre></div>
+</div>
+<p><strong>Restart a service</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>ctl-chef-server restart name_of_service
+</pre></div>
+</div>
+<p>For example, to restart a service named <tt class="docutils literal"><span class="pre">erchef</span></tt>, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>ctl-chef-server restart erchef
+</pre></div>
+</div>
+<p><strong>Restart all services</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>ctl-chef-server restart
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/ctl_chef_shell.html b/distro/common/html/ctl_chef_shell.html
new file mode 100644
index 0000000000..7aa3ef0eac
--- /dev/null
+++ b/distro/common/html/ctl_chef_shell.html
@@ -0,0 +1,120 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>chef-shell &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="chef-shell">
+<h1>chef-shell<a class="headerlink" href="#chef-shell" title="Permalink to this headline">¶</a></h1>
+<p>chef-shell is a recipe debugging tool that allows the use of breakpoints within recipes. chef-shell runs as an Interactive Ruby (IRb) session. chef-shell supports both recipe and attribute file syntax, as well as interactive debugging features.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">chef-shell is the new name for Shef as of Chef 11.x. chef-shell is backwards compatible and aside from the name change, has the same set of functionality as with previous releases.</p>
+</div>
+<p>The chef-shell executable can be run as a command-line tool.</p>
+<div class="section" id="modes">
+<h2>Modes<a class="headerlink" href="#modes" title="Permalink to this headline">¶</a></h2>
+<p>chef-shell is tool that allows Knife to be run using an Interactive Ruby (IRb) session. chef-shell currently supports recipe and attribute file syntax, as well as interactive debugging features. chef-shell has three run modes:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Mode</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>Standalone</td>
+<td>No cookbooks are loaded, and the run list is empty. This mode is the default.</td>
+</tr>
+<tr class="row-odd"><td>Solo</td>
+<td>chef-shell acts as a chef-solo client. It attempts to load the chef-solo configuration file and JSON attributes. If the JSON attributes set a run list, it will be honored. Cookbooks will be loaded in the same way that chef-solo loads them. chef-solo mode is activated with the <tt class="docutils literal"><span class="pre">-s</span></tt> or <tt class="docutils literal"><span class="pre">--solo</span></tt> command line option, and JSON attributes are specified in the same way as for chef-solo, with <tt class="docutils literal"><span class="pre">-j</span> <span class="pre">/path/to/chef-solo.json</span></tt>.</td>
+</tr>
+<tr class="row-even"><td>Client</td>
+<td>chef-shell acts as a chef-client. During startup, it reads the chef-client configuration file and contacts the server to get attributes and cookbooks. The run list will be set in the same way as normal chef-client runs. chef-client mode is activated with the <tt class="docutils literal"><span class="pre">-z</span></tt> or <tt class="docutils literal"><span class="pre">--client</span></tt> options. You can also specify the configuration file with <tt class="docutils literal"><span class="pre">-c</span> <span class="pre">CONFIG</span></tt> and the server URL with <tt class="docutils literal"><span class="pre">-S</span> <span class="pre">SERVER_URL</span></tt>.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<p>This command has the following syntax:</p>
+<div class="highlight-python"><pre>chef-shell OPTION VALUE OPTION VALUE ...</pre>
+</div>
+<p>This command has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--standalone</span></tt></dt>
+<dd>Indicates that chef-shell will be run in standalone mode.</dd>
+<dt><tt class="docutils literal"><span class="pre">-c</span> <span class="pre">CONFIG</span></tt>, <tt class="docutils literal"><span class="pre">--config</span> <span class="pre">CONFIG</span></tt></dt>
+<dd>The configuration file to use.</dd>
+<dt><tt class="docutils literal"><span class="pre">-h</span></tt>, <tt class="docutils literal"><span class="pre">--help</span></tt></dt>
+<dd>Shows help for the command.</dd>
+<dt><tt class="docutils literal"><span class="pre">-j</span> <span class="pre">PATH</span></tt>, <tt class="docutils literal"><span class="pre">--json-attributes</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to a file that contains JSON data.</dd>
+<dt><tt class="docutils literal"><span class="pre">-l</span> <span class="pre">LEVEL</span></tt>, <tt class="docutils literal"><span class="pre">--log-level</span> <span class="pre">LEVEL</span></tt></dt>
+<dd>The level of logging that will be stored in a log file.</dd>
+<dt><tt class="docutils literal"><span class="pre">-s</span></tt>, <tt class="docutils literal"><span class="pre">--solo</span></tt></dt>
+<dd>Indicates that chef-shell will be run in chef-solo mode.</dd>
+<dt><tt class="docutils literal"><span class="pre">-S</span> <span class="pre">CHEF_SERVER_URL</span></tt>, <tt class="docutils literal"><span class="pre">--server</span> <span class="pre">CHEF_SERVER_URL</span></tt></dt>
+<dd>The URL for the server.</dd>
+<dt><tt class="docutils literal"><span class="pre">-v</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt></dt>
+<dd>The version of the chef-client.</dd>
+<dt><tt class="docutils literal"><span class="pre">-z</span></tt>, <tt class="docutils literal"><span class="pre">--client</span></tt></dt>
+<dd>Indicates that chef-shell will be run in chef-client mode.</dd>
+</dl>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/ctl_chef_solo.html b/distro/common/html/ctl_chef_solo.html
new file mode 100644
index 0000000000..cc20bfb940
--- /dev/null
+++ b/distro/common/html/ctl_chef_solo.html
@@ -0,0 +1,144 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>chef-solo &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="chef-solo">
+<h1>chef-solo<a class="headerlink" href="#chef-solo" title="Permalink to this headline">¶</a></h1>
+<p>chef-solo is an open source version of the chef-client that allows using cookbooks with nodes without requiring access to a server. chef-solo runs locally and requires that a cookbook (and any of its dependencies) be on the same physical disk as the node. chef-solo is a limited-functionality version of the chef-client and <strong>does not support</strong> the following:</p>
+<ul class="simple">
+<li>Node data storage</li>
+<li>Search indexes</li>
+<li>Centralized distribution of cookbooks</li>
+<li>A centralized API that interacts with and integrates infrastructure components</li>
+<li>Authentication or authorization</li>
+<li>Persistent attributes</li>
+</ul>
+<p>The chef-solo executable can be run as a command-line tool.</p>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<p>This command has the following syntax:</p>
+<div class="highlight-python"><pre>chef-solo OPTION VALUE OPTION VALUE ...</pre>
+</div>
+<p>This command has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-c</span> <span class="pre">CONFIG</span></tt>, <tt class="docutils literal"><span class="pre">--config</span> <span class="pre">CONFIG</span></tt></dt>
+<dd>The configuration file to use.</dd>
+<dt><tt class="docutils literal"><span class="pre">-d</span></tt>, <tt class="docutils literal"><span class="pre">--daemonize</span></tt></dt>
+<dd>Indicates that the executable will be run as a daemon. This option is only available on machines that run in UNIX or Linux environments. For machines that are running Microsoft Windows that require similar functionality, use the <tt class="docutils literal"><span class="pre">chef-client::service</span></tt> recipe in the <tt class="docutils literal"><span class="pre">chef-client</span></tt> cookbook: <a class="reference external" href="http://community.opscode.com/cookbooks/chef-client">http://community.opscode.com/cookbooks/chef-client</a>. This will install a chef-client service under Microsoft Windows using the Windows Service Wrapper.</dd>
+<dt><tt class="docutils literal"><span class="pre">-E</span> <span class="pre">ENVIRONMENT_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--environment</span> <span class="pre">ENVIRONMENT_NAME</span></tt></dt>
+<dd>The name of the environment.</dd>
+<dt><tt class="docutils literal"><span class="pre">-f</span></tt>, <tt class="docutils literal"><span class="pre">--[no-]fork</span></tt></dt>
+<dd>Indicates that a chef-client run will be contained in a secondary process with dedicated RAM. When the chef-client run is complete the RAM will be returned to the master process. This option helps ensure that a chef-client will use a steady amount of RAM over time because the master process will not run recipes. This option will also help prevent memory leaks (such as those that can be introduced by the code contained within a poorly designed cookbook). Use <tt class="docutils literal"><span class="pre">--no-fork</span></tt> to disable running the chef-client in fork node. Default value: <tt class="docutils literal"><span class="pre">--fork</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-F</span> <span class="pre">FORMAT</span></tt>, <tt class="docutils literal"><span class="pre">--format</span> <span class="pre">FORMAT</span></tt></dt>
+<dd><p class="first">The output format: <tt class="docutils literal"><span class="pre">doc</span></tt> (default) or <tt class="docutils literal"><span class="pre">min</span></tt>.</p>
+<p>Use <tt class="docutils literal"><span class="pre">doc</span></tt> to print the progress of the chef-client run using full strings that display a summary of updates as they occur.</p>
+<p>Use <tt class="docutils literal"><span class="pre">min</span></tt> to print the progress of the chef-client run using single characters. A summary of updates is printed at the end of the chef-client run. A dot (<tt class="docutils literal"><span class="pre">.</span></tt>) is printed for events that do not have meaningful status information, such as loading a file or synchronizing a cookbook. For resources, a dot (<tt class="docutils literal"><span class="pre">.</span></tt>) is printed when the resource is up to date, an <tt class="docutils literal"><span class="pre">S</span></tt> is printed when the resource is skipped by <tt class="docutils literal"><span class="pre">not_if</span></tt> or <tt class="docutils literal"><span class="pre">only_if</span></tt>, and a <tt class="docutils literal"><span class="pre">U</span></tt> is printed when the resource is updated.</p>
+<p class="last">Other formatting options are available when those formatters are configured in the client.rb file using the <tt class="docutils literal"><span class="pre">add_formatter</span></tt> option.</p>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">--force-formatter</span></tt></dt>
+<dd>Indicates that formatter output will be used instead of logger output.</dd>
+<dt><tt class="docutils literal"><span class="pre">--force-logger</span></tt></dt>
+<dd>Indicates that logger output will be used instead of formatter output.</dd>
+<dt><tt class="docutils literal"><span class="pre">-g</span> <span class="pre">GROUP</span></tt>, <tt class="docutils literal"><span class="pre">--group</span> <span class="pre">GROUP</span></tt></dt>
+<dd>The name of the group that owns a process. This is required when starting any executable as a daemon.</dd>
+<dt><tt class="docutils literal"><span class="pre">-h</span></tt>, <tt class="docutils literal"><span class="pre">--help</span></tt></dt>
+<dd>Shows help for the command.</dd>
+<dt><tt class="docutils literal"><span class="pre">-i</span> <span class="pre">SECONDS</span></tt>, <tt class="docutils literal"><span class="pre">--interval</span> <span class="pre">SECONDS</span></tt></dt>
+<dd>The frequency (in seconds) at which the chef-client runs.</dd>
+<dt><tt class="docutils literal"><span class="pre">-j</span> <span class="pre">PATH</span></tt>, <tt class="docutils literal"><span class="pre">--json-attributes</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to a file that contains JSON data. Use this option to override <tt class="docutils literal"><span class="pre">normal</span></tt> attributes set elsewhere.</dd>
+<dt><tt class="docutils literal"><span class="pre">-l</span> <span class="pre">LEVEL</span></tt>, <tt class="docutils literal"><span class="pre">--log_level</span> <span class="pre">LEVEL</span></tt></dt>
+<dd>The level of logging that will be stored in a log file.</dd>
+<dt><tt class="docutils literal"><span class="pre">-L</span> <span class="pre">LOGLOCATION</span></tt>, <tt class="docutils literal"><span class="pre">--logfile</span> <span class="pre">c</span></tt></dt>
+<dd>The location in which log file output files will be saved. If this location is set to something other than <tt class="docutils literal"><span class="pre">STDOUT</span></tt>, standard output logging will still be performed (otherwise there would be no output other than to a file). This is recommended when starting any executable as a daemon.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]color</span></tt></dt>
+<dd>Indicates whether colored output will be used. Default setting: <tt class="docutils literal"><span class="pre">--color</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-N</span> <span class="pre">NODE_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--node-name</span> <span class="pre">NODE_NAME</span></tt></dt>
+<dd>The name of the node.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">RUN_LIST_ITEM</span></tt>, <tt class="docutils literal"><span class="pre">--override-runlist</span> <span class="pre">RUN_LIST_ITEM</span></tt></dt>
+<dd>Replace the current run list with the specified items.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span> <span class="pre">RECIPE_URL</span></tt>, <tt class="docutils literal"><span class="pre">--recipe-url</span> <span class="pre">RECIPE_URL</span></tt></dt>
+<dd>The URL location from which a remote cookbook tar.gz will be downloaded.</dd>
+<dt><tt class="docutils literal"><span class="pre">-s</span> <span class="pre">SECONDS</span></tt>, <tt class="docutils literal"><span class="pre">--splay</span> <span class="pre">SECONDS</span></tt></dt>
+<dd>A number (in seconds) to add to the <tt class="docutils literal"><span class="pre">interval</span></tt> that is used to determine the frequency of chef-client runs. This number can help prevent server load when there are many clients running at the same time.</dd>
+<dt><tt class="docutils literal"><span class="pre">-u</span> <span class="pre">USER</span></tt>, <tt class="docutils literal"><span class="pre">--user</span> <span class="pre">USER</span></tt></dt>
+<dd>The user that owns a process. This is required when starting any executable as a daemon.</dd>
+<dt><tt class="docutils literal"><span class="pre">-v</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt></dt>
+<dd>The version of the chef-client.</dd>
+<dt><tt class="docutils literal"><span class="pre">-W</span></tt>, <tt class="docutils literal"><span class="pre">--why-run</span></tt></dt>
+<dd>Indicates that the executable will be run in why-run mode, which is a type of chef-client run that does everything except modify the system. Use why-run mode to understand why the chef-client makes the decisions that it makes and to learn more about the current and proposed state of the system.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p><strong>Use a URL</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-solo -c ~/solo.rb -j ~/node.json -r http://www.example.com/chef-solo.tar.gz
+</pre></div>
+</div>
+<p>where <tt class="docutils literal"><span class="pre">-r</span></tt> uses the <strong>remote_file</strong> resource to retrieve the tar.gz archive into the <tt class="docutils literal"><span class="pre">file_cache_path</span></tt>, and then extract it to <tt class="docutils literal"><span class="pre">cookbooks_path</span></tt>.</p>
+<p><strong>Use a directory</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-solo -c ~/solo.rb -j ~/node.json
+</pre></div>
+</div>
+<p>where the <tt class="docutils literal"><span class="pre">-r</span> <span class="pre">URL</span></tt> option is not used. chef-solo will look in the solo.rb file to determine the directory in which cookbooks are located.</p>
+<p><strong>Use a URL for cookbook and JSON data</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-solo -c ~/solo.rb -j http://www.example.com/node.json -r http://www.example.com/chef-solo.tar.gz
+</pre></div>
+</div>
+<p>where <tt class="docutils literal"><span class="pre">-r</span></tt> corresponds to <tt class="docutils literal"><span class="pre">recipe_url</span></tt> and <tt class="docutils literal"><span class="pre">-j</span></tt> corresponds to <tt class="docutils literal"><span class="pre">json_attribs</span></tt>, both of which are configuration options in solo.rb.</p>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/index.html b/distro/common/html/index.html
new file mode 100644
index 0000000000..b26dd0c476
--- /dev/null
+++ b/distro/common/html/index.html
@@ -0,0 +1,185 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>chef-client Man Pages &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="chef-client-man-pages">
+<h1>chef-client Man Pages<a class="headerlink" href="#chef-client-man-pages" title="Permalink to this headline">¶</a></h1>
+<p>The following command line interfaces are available in the chef-client:</p>
+<ul class="simple">
+<li><a class="reference internal" href="ctl_chef_client.html"><em>chef-client</em></a></li>
+<li><a class="reference internal" href="ctl_chef_server.html"><em>chef-server-ctl</em></a></li>
+<li><a class="reference internal" href="ctl_chef_shell.html"><em>chef-shell</em></a></li>
+<li><a class="reference internal" href="ctl_chef_solo.html"><em>chef-solo</em></a></li>
+<li><a class="reference internal" href="knife.html"><em>knife</em></a></li>
+</ul>
+<div class="section" id="knife">
+<h2>knife<a class="headerlink" href="#knife" title="Permalink to this headline">¶</a></h2>
+<p>Knife is a command-line tool that provides an interface between a local chef-repo and the server. Knife helps users to manage:</p>
+<ul class="simple">
+<li>Nodes</li>
+<li>Cookbooks and recipes</li>
+<li>Roles</li>
+<li>Stores of JSON data (data bags), including encrypted data</li>
+<li>Environments</li>
+<li>Cloud resources, including provisioning</li>
+<li>The installation of the chef-client on management workstations</li>
+<li>Searching of indexed data on the server</li>
+</ul>
+<p>The following sections describe functionality common to all Knife subcommands:</p>
+<ul class="simple">
+<li><a class="reference internal" href="knife_using.html"><em>Working with Knife</em></a></li>
+<li><a class="reference internal" href="knife_common_options.html"><em>Common Options</em></a></li>
+</ul>
+<p>Knife includes the following sub-commands:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="25%" />
+<col width="75%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Sub-command</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td><a class="reference internal" href="knife_bootstrap.html"><em>knife bootstrap</em></a></td>
+<td>The <strong>knife bootstrap</strong> subcommand is used to 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.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_client.html"><em>knife client</em></a></td>
+<td>The <strong>knife client</strong> 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.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_configure.html"><em>knife configure</em></a></td>
+<td>The <strong>knife configure</strong> subcommand is used to create the knife.rb and client.rb files so that they can be distributed to workstations and nodes.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_cookbook.html"><em>knife cookbook</em></a></td>
+<td>The <strong>knife cookbook</strong> subcommand is used to interact with cookbooks that are located on the server or the local chef-repo.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_cookbook_site.html"><em>knife cookbook site</em></a></td>
+<td>The <strong>knife cookbook site</strong> subcommand is used to interact with cookbooks that are located at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>. A user account is required for any community actions that write data to this site. The following arguments do not require a user account: <tt class="docutils literal"><span class="pre">download</span></tt>, <tt class="docutils literal"><span class="pre">search</span></tt>, <tt class="docutils literal"><span class="pre">install</span></tt>, and <tt class="docutils literal"><span class="pre">list</span></tt>.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_data_bag.html"><em>knife data bag</em></a></td>
+<td>The <strong>knife data bag</strong> subcommand is used to manage arbitrary stores of globally available JSON data.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_delete.html"><em>knife delete</em></a></td>
+<td>The <strong>knife delete</strong> subcommand is used to delete an object from a server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">delete</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">delete</span></tt>, but with a single verb (and a single action).</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_deps.html"><em>knife deps</em></a></td>
+<td>The <strong>knife deps</strong> subcommand is used to identify dependencies for a node, role, or cookbook.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_diff.html"><em>knife diff</em></a></td>
+<td>The <strong>knife diff</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt> and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt> subcommands, or to ensure that certain files in multiple production environments are the same. This subcommand is similar to the <tt class="docutils literal"><span class="pre">git</span> <span class="pre">diff</span></tt> command that can be used to diff what is in the chef-repo with what is synced to a git repository.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_download.html"><em>knife download</em></a></td>
+<td>The <strong>knife download</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">diff</span></tt>, which can be used to see exactly what changes will be downloaded, and then <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt>, which does the opposite of <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt>.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_edit.html"><em>knife edit</em></a></td>
+<td>The <strong>knife edit</strong> subcommand is used to edit objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">edit</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">edit</span></tt>, but with a single verb (and a single action).</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_environment.html"><em>knife environment</em></a></td>
+<td>The <strong>knife environment</strong> subcommand is used to manage environments within a single organization on the server.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_exec.html"><em>knife exec</em></a></td>
+<td>The <strong>knife exec</strong> 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.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_index_rebuild.html"><em>knife index rebuild</em></a></td>
+<td>The <strong>knife index rebuild</strong> subcommand is used to rebuild the search indexes for the open source server. This operation is destructive and may take some time.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_list.html"><em>knife list</em></a></td>
+<td>The <strong>knife list</strong> subcommand is used to view a list of objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">list</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">list</span></tt>, but with a single verb (and a single action).</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_node.html"><em>knife node</em></a></td>
+<td>The <strong>knife node</strong> subcommand is used to manage the nodes that exist on a server.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_raw.html"><em>knife raw</em></a></td>
+<td>The <strong>knife raw</strong> subcommand is used to send a REST request to a specified path using the Chef Server API.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_recipe_list.html"><em>knife recipe list</em></a></td>
+<td>The <strong>knife recipe list</strong> 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 (/).</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_role.html"><em>knife role</em></a></td>
+<td>The <strong>knife role</strong> subcommand is used to manage the roles that are associated with one or more nodes on a server.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_search.html"><em>knife search</em></a></td>
+<td>The <strong>knife search</strong> subcommand is used run a search query for information that is indexed on a server.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_show.html"><em>knife show</em></a></td>
+<td>The <strong>knife show</strong> subcommand is used to view the details of one (or more) objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">show</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">show</span></tt>, but with a single verb (and a single action).</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_ssh.html"><em>knife ssh</em></a></td>
+<td>The <strong>knife ssh</strong> 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.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_status.html"><em>knife status</em></a></td>
+<td>The <strong>knife status</strong> 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.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_tag.html"><em>knife tag</em></a></td>
+<td>The <strong>knife tag</strong> subcommand is used to apply tags to nodes on a server.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_upload.html"><em>knife upload</em></a></td>
+<td>The <strong>knife upload</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">diff</span></tt>, which can be used to see exactly what changes will be uploaded, and then <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt>, which does the opposite of <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt>.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_user.html"><em>knife user</em></a></td>
+<td>The <strong>knife user</strong> subcommand is used to manage the list of users and their associated RSA public key-pairs.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_xargs.html"><em>knife xargs</em></a></td>
+<td>The <strong>knife xargs</strong> subcommand is used to build and execute command lines against objects on a server using standard input.</td>
+</tr>
+</tbody>
+</table>
+<div class="toctree-wrapper compound">
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife-bootstrap.1.html b/distro/common/html/knife-bootstrap.1.html
deleted file mode 100644
index f2bf638895..0000000000
--- a/distro/common/html/knife-bootstrap.1.html
+++ /dev/null
@@ -1,241 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-bootstrap(1) - Install Chef Client on a remote host</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#EXAMPLES">EXAMPLES</a>
- <a href="#BUGS">BUGS</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-bootstrap(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-bootstrap(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-bootstrap</code> - <span class="man-whatis">Install Chef Client on a remote host</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>bootstrap</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-i</code>, <code>--identity-file IDENTITY_FILE</code></dt><dd>The SSH identity file used for authentication</dd>
-<dt><code>-N</code>, <code>--node-name NAME</code></dt><dd>The Chef node name for your new node</dd>
-<dt><code>-P</code>, <code>--ssh-password PASSWORD</code></dt><dd>The ssh password</dd>
-<dt><code>-x</code>, <code>--ssh-user USERNAME</code></dt><dd>The ssh username</dd>
-<dt><code>-p</code>, <code>--ssh-port PORT</code></dt><dd>The ssh port</dd>
-<dt><code>--bootstrap-version VERSION</code></dt><dd>The version of Chef to install</dd>
-<dt><code>--bootstrap-proxy PROXY_URL</code></dt><dd><code>The proxy server for the node being bootstrapped</code></dd>
-<dt><code>--prerelease</code></dt><dd>Install pre-release Chef gems</dd>
-<dt><code>-r</code>, <code>--run-list RUN_LIST</code></dt><dd>Comma separated list of roles/recipes to apply</dd>
-<dt><code>--template-file TEMPLATE</code></dt><dd>Full path to location of template to use</dd>
-<dt class="flush"><code>--sudo</code></dt><dd>Execute the bootstrap via sudo</dd>
-<dt><code>-d</code>, <code>--distro DISTRO</code></dt><dd>Bootstrap a distro using a template</dd>
-<dt><code>--[no-]host-key-verify</code></dt><dd>Enable host key verification, which is the default behavior.</dd>
-<dt><code>--hint HINT_NAME[=HINT_FILE]</code></dt><dd>Provide the name of a hint (with option JSON file) to set for use by
-Ohai plugins.</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>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>
-
-<p>The bootstrap sub-command supports supplying a template to perform the
-bootstrap steps. If the distro is not specified (via <code>-d</code> or <code>--distro</code>
-option), an Ubuntu 10.04 host bootstrapped with RubyGems is assumed. The
-<strong>DISTRO</strong> value corresponds to the base filename of the template, in
-other words <code>DISTRO</code>.erb. A template file can be specified with the
-<code>--template-file</code> option in which case the <strong>DISTRO</strong> is not used. The
-sub-command looks in the following locations for the template to use:</p>
-
-<ul>
-<li><code>bootstrap</code> directory in the installed Chef Knife library.</li>
-<li><code>bootstrap</code> directory in the <code>$PWD/.chef</code>.</li>
-<li><code>bootstrap</code> directory in the users <code>$HOME/.chef</code>.</li>
-</ul>
-
-
-<p>The default bootstrap templates are scripts that get copied to the
-target node (FQDN). The following distros are supported:</p>
-
-<ul>
-<li>centos5-gems</li>
-<li>fedora13-gems</li>
-<li>ubuntu10.04-gems</li>
-<li>ubuntu10.04-apt</li>
-</ul>
-
-
-<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>
-
-<p>In addition to handling the software installation, these bootstrap
-templates do the following:</p>
-
-<ul>
-<li>Write the validation.pem per the local knife configuration.</li>
-<li>Write a default config file for Chef (<code>/etc/chef/client.rb</code>) using values from the <code>knife.rb</code>.</li>
-<li>Create a JSON attributes file containing the specified run list and run Chef.</li>
-</ul>
-
-
-<p>In the case of the RubyGems, the <code>client.rb</code> will be written from
-scratch with a minimal set of values; see <strong>EXAMPLES</strong>. In the case of
-APT Package installation, <code>client.rb</code> will have the
-<code>validation_client_name</code> appended if it is not set to <code>chef-validator</code>
-(default config value), and the <code>node_name</code> will be added if
-<code>chef_node_name</code> option is specified.</p>
-
-<p>When this is complete, the bootstrapped node will have:</p>
-
-<ul>
-<li>Latest Chef version installed from RubyGems or APT Packages from Opscode. This may be a later version than the local system.</li>
-<li>Be validated with the configured Chef Server.</li>
-<li>Have run Chef with its default run list if one is specfied.</li>
-</ul>
-
-
-<p>Additional custom bootstrap templates can be created and stored in
-<code>.chef/bootstrap/DISTRO.erb</code>, replacing <strong>DISTRO</strong> with the value passed
-with the <code>-d</code> or <code>--distro</code> option. See <strong>EXAMPLES</strong> for more
-information.</p>
-
-<h2 id="EXAMPLES">EXAMPLES</h2>
-
-<p>Setting up a custom bootstrap is fairly straightforward. Create a
-<code>.chef/bootstrap</code> directory in your Chef Repository or in
-<code>$HOME/.chef/bootstrap</code>. Then create the ERB template file.</p>
-
-<pre><code>mkdir ~/.chef/bootstrap
-vi ~/.chef/bootstrap/debian5.0-apt.erb
-</code></pre>
-
-<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:</p>
-
-<pre><code>knife bootstrap mynode.example.com --template-file ~/.chef/bootstrap/debian5.0-apt.erb
-</code></pre>
-
-<p>Or,</p>
-
-<pre><code>knife bootstrap mynode.example.com --distro debian5.0-apt
-</code></pre>
-
-<p>The <code>--distro</code> parameter will automatically look in the
-<code>~/.chef/bootstrap</code> directory for a file named <code>debian5.0-apt.erb</code>.</p>
-
-<p>Templates provided by the Chef installation are located in
-<code>BASEDIR/lib/chef/knife/bootstrap/*.erb</code>, where <em>BASEDIR</em> is the
-location where the package or Gem installed the Chef client libraries.</p>
-
-<h2 id="BUGS">BUGS</h2>
-
-<p><code>knife bootstrap</code> is not capable of bootstrapping multiple hosts in
-parallel.</p>
-
-<p>The bootstrap script is passed as an argument to <span class="man-ref">sh<span class="s">(1)</span></span> 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 <span class="man-ref">ps<span class="s">(1)</span></span>.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife-ssh</strong>(1)</p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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;&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-bootstrap(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-client.1.html b/distro/common/html/knife-client.1.html
deleted file mode 100644
index f306e9fd53..0000000000
--- a/distro/common/html/knife-client.1.html
+++ /dev/null
@@ -1,219 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-client(1) - Manage Chef API Clients</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#SUB-COMMANDS">SUB-COMMANDS</a>
- <a href="#BULK-DELETE">BULK DELETE</a>
- <a href="#CREATE">CREATE</a>
- <a href="#DELETE">DELETE</a>
- <a href="#EDIT">EDIT</a>
- <a href="#LIST">LIST</a>
- <a href="#REREGISTER">REREGISTER</a>
- <a href="#SHOW">SHOW</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-client(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-client(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-client</code> - <span class="man-whatis">Manage Chef API Clients</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>client</strong> <em>sub-command</em> <em>(options)</em></p>
-
-<h2 id="SUB-COMMANDS">SUB-COMMANDS</h2>
-
-<p>Client subcommands follow a basic create, read, update, delete (CRUD)
-pattern. The Following subcommands are available:</p>
-
-<h2 id="BULK-DELETE">BULK DELETE</h2>
-
-<p><strong>knife client bulk delete</strong> <em>regex</em> <em>(options)</em></p>
-
-<p>Delete clients where the client name matches the regular expression
-<em>regex</em> on the Chef Server. The regular expression should be given as a
-quoted string, and not surrounded by forward slashes.</p>
-
-<h2 id="CREATE">CREATE</h2>
-
-<p><strong>knife client create</strong> <em>client name</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--admin </code></dt><dd>Create the client as an admin</dd>
-<dt><code>-f</code>, <code>--file FILE</code></dt><dd>Write the key to a file</dd>
-</dl>
-
-
-<p>Create a new client. This generates an RSA keypair. The private key will
-be displayed on <em>STDOUT</em> or written to the named file. The public half
-will be stored on the Server. For <em>chef-client</em> systems, the private key
-should be copied to the system as <code>/etc/chef/client.pem</code>.</p>
-
-<p>Admin clients should be created for users that will use <em>knife</em> to
-access the API as an administrator. The private key will generally be
-copied to <code>~/.chef/client\_name.pem</code> and referenced in the <code>knife.rb</code>
-configuration file.</p>
-
-<h2 id="DELETE">DELETE</h2>
-
-<p><strong>knife client delete</strong> <em>client name</em> <em>(options)</em></p>
-
-<p>Deletes a registered client.</p>
-
-<h2 id="EDIT">EDIT</h2>
-
-<p><strong>client edit</strong> <em>client name</em> <em>(options)</em></p>
-
-<p>Edit a registered client.</p>
-
-<h2 id="LIST">LIST</h2>
-
-<p><strong>client list</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-w</code>, <code>--with-uri</code></dt><dd> Show corresponding URIs</dd>
-</dl>
-
-
-<p>List all registered clients.</p>
-
-<h2 id="REREGISTER">REREGISTER</h2>
-
-<p><strong>client reregister</strong> <em>client name</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-f</code>, <code>--file FILE</code></dt><dd>Write the key to a file</dd>
-</dl>
-
-
-<p>Regenerate the RSA keypair for a client. The public half will be stored
-on the server and the private key displayed on <em>STDOUT</em> 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.</p>
-
-<h2 id="SHOW">SHOW</h2>
-
-<p><strong>client show</strong> <em>client name</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--attribute ATTR</code></dt><dd>Show only one attribute</dd>
-</dl>
-
-
-<p>Show a client. Output format is determined by the --format option.</p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>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>
-
-<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>
-
-<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.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife-node</strong>(1)</p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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;&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-client(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-configure.1.html b/distro/common/html/knife-configure.1.html
deleted file mode 100644
index fe66789054..0000000000
--- a/distro/common/html/knife-configure.1.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-configure(1) - Generate configuration files for knife or Chef Client</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#CONFIGURE-SUBCOMMANDS">CONFIGURE SUBCOMMANDS</a>
- <a href="#EXAMPLES">EXAMPLES</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-configure(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-configure(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-configure</code> - <span class="man-whatis">Generate configuration files for knife or Chef Client</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>configure</strong> [client] <em>(options)</em></p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Generates a knife.rb configuration file interactively. When given the
---initial option, also creates a new administrative user.</p>
-
-<h2 id="CONFIGURE-SUBCOMMANDS">CONFIGURE SUBCOMMANDS</h2>
-
-<p><strong>knife configure</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-i</code>, <code>--initial</code></dt><dd>Create an initial API Client</dd>
-<dt><code>-r</code>, <code>--repository REPO</code></dt><dd>The path to your chef-repo</dd>
-</dl>
-
-
-<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 <strong>knife</strong>(1) for a description of
-configuration options.</p>
-
-<p><strong>knife configure client</strong> <em>directory</em></p>
-
-<p>Read the <em>knife.rb</em> config file and generate a config file suitable for
-use in <em>/etc/chef/client.rb</em> and copy the validation certificate into
-the specified <em>directory</em>.</p>
-
-<h2 id="EXAMPLES">EXAMPLES</h2>
-
-<ul>
-<li><p>On a freshly installed Chef Server, use <em>knife configure -i</em> 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.</p>
-
-<p>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</p>
-
-<p>This creates a new administrator client named <em>username</em>, writes
-a configuration file to <em>/home/username/.chef/knife.rb</em>, and the
-private key to <em>/home/username/.chef/username.pem</em>. 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.</p></li>
-</ul>
-
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife</strong>(1) <strong>knife-client</strong>(1)</p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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;&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-configure(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-cookbook-site.1.html b/distro/common/html/knife-cookbook-site.1.html
deleted file mode 100644
index 8b093b5671..0000000000
--- a/distro/common/html/knife-cookbook-site.1.html
+++ /dev/null
@@ -1,241 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-cookbook-site(1) - Install and update open source cookbooks</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#COOKBOOK-SITE-SUB-COMMANDS">COOKBOOK SITE SUB-COMMANDS</a>
- <a href="#INSTALL">INSTALL</a>
- <a href="#DOWNLOAD">DOWNLOAD</a>
- <a href="#LIST">LIST</a>
- <a href="#SEARCH">SEARCH</a>
- <a href="#SHARE">SHARE</a>
- <a href="#UNSHARE">UNSHARE</a>
- <a href="#SHOW">SHOW</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#EXAMPLES">EXAMPLES</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-cookbook-site(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-cookbook-site(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-cookbook-site</code> - <span class="man-whatis">Install and update open source cookbooks</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>cookbook site</strong> <em>sub-command</em> <em>(options)</em></p>
-
-<h2 id="COOKBOOK-SITE-SUB-COMMANDS">COOKBOOK SITE SUB-COMMANDS</h2>
-
-<p><code>knife cookbook site</code> provides the following subcommands:</p>
-
-<h2 id="INSTALL">INSTALL</h2>
-
-<p><strong>cookbook site install COOKBOOK [VERSION]</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-D</code>, <code>--skip-dependencies</code></dt><dd>Skip automatic installation of dependencies.</dd>
-<dt><code>-o</code>, <code>--cookbook-path PATH</code></dt><dd>Install cookbooks to PATH</dd>
-<dt><code>-B</code>, <code>--branch BRANCH</code></dt><dd>Default branch to work with [defaults to master]</dd>
-</dl>
-
-
-<p>Uses <span class="man-ref">git<span class="s">(1)</span></span> version control in conjunction with the cookbook site to
-install community contributed cookbooks to your local cookbook
-repository. Running <code>knife cookbook site install</code> does the following:</p>
-
-<ol>
-<li>A new "pristine copy" branch is created in git for tracking the
-upstream;</li>
-<li>All existing cookbooks are removed from the branch;</li>
-<li>The cookbook is downloaded from the cookbook site in tarball form;</li>
-<li>The downloaded cookbook is untarred, and its contents commited via git;</li>
-<li>The pristine copy branch is merged into the master branch.</li>
-</ol>
-
-
-<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>
-
-<p>Unless <em>--skip-dependencies</em> is specified, the process is applied recursively to all the
-cookbooks <em>COOKBOOK</em> depends on (via metadata <em>dependencies</em>).</p>
-
-<h2 id="DOWNLOAD">DOWNLOAD</h2>
-
-<p><strong>knife cookbook site download COOKBOOK [VERSION]</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-f</code>, <code>--file FILE</code></dt><dd>The filename to write to</dd>
-<dt class="flush"><code>--force</code></dt><dd>Force download deprecated cookbook</dd>
-</dl>
-
-
-<p>Downloads a specific cookbook from the Community site, optionally
-specifying a certain version.</p>
-
-<h2 id="LIST">LIST</h2>
-
-<p><strong>knife cookbook site list</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-w</code>, <code>--with-uri</code></dt><dd>Show corresponding URIs</dd>
-</dl>
-
-
-<p>Lists available cookbooks from the Community site.</p>
-
-<h2 id="SEARCH">SEARCH</h2>
-
-<p><strong>knife cookbook site search QUERY</strong> <em>(options)</em></p>
-
-<p>Searches for available cookbooks matching the specified query.</p>
-
-<h2 id="SHARE">SHARE</h2>
-
-<p><strong>knife cookbook site share COOKBOOK CATEGORY</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-k</code>, <code>--key KEY</code></dt><dd>API Client Key</dd>
-<dt><code>-u</code>, <code>--user USER</code></dt><dd>API Client Username</dd>
-<dt><code>-o</code>, <code>--cookbook-path PATH:PATH</code></dt><dd>A colon-separated path to look for cookbooks in</dd>
-</dl>
-
-
-<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.</p>
-
-<h2 id="UNSHARE">UNSHARE</h2>
-
-<p><strong>knife cookbook site unshare COOKBOOK</strong></p>
-
-<p>Stops sharing the specified cookbook on the Opscode cookbooks site.</p>
-
-<h2 id="SHOW">SHOW</h2>
-
-<p><strong>knife cookbook site show COOKBOOK [VERSION]</strong> <em>(options)</em></p>
-
-<p>Shows information from the site about a particular cookbook.</p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>The cookbook site, <a href="http://community.opscode.com/" data-bare-link="true">http://community.opscode.com/</a>, 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>
-
-<p><code>knife cookbook site</code> 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 <code>knife cookbook site
-share</code> command, you must create an account on the cookbook site and
-configure your credentials via command line option or in your knife
-configuration file.</p>
-
-<h2 id="EXAMPLES">EXAMPLES</h2>
-
-<p>Uploading cookbooks to the Opscode cookbooks site:</p>
-
-<pre><code>knife cookbook site share example Other -k ~/.chef/USERNAME.pem -u USERNAME
-</code></pre>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong><span class="man-ref">knife-cookbook<span class="s">(1)</span></span></strong>
- <a href="http://community.opscode.com/cookbooks" data-bare-link="true">http://community.opscode.com/cookbooks</a></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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;&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <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>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-cookbook.1.html b/distro/common/html/knife-cookbook.1.html
deleted file mode 100644
index e56d9d8e35..0000000000
--- a/distro/common/html/knife-cookbook.1.html
+++ /dev/null
@@ -1,381 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-cookbook(1) - upload and manage chef cookbooks</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#SUB-COMMANDS">SUB-COMMANDS</a>
- <a href="#LIST">LIST</a>
- <a href="#SHOW">SHOW</a>
- <a href="#UPLOAD">UPLOAD</a>
- <a href="#DOWNLOAD">DOWNLOAD</a>
- <a href="#DELETE">DELETE</a>
- <a href="#BULK-DELETE">BULK DELETE</a>
- <a href="#COOKBOOK-CREATE">COOKBOOK CREATE</a>
- <a href="#METADATA">METADATA</a>
- <a href="#METADATA-FROM-FILE">METADATA FROM FILE</a>
- <a href="#TEST">TEST</a>
- <a href="#RECIPE-LIST">RECIPE LIST</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-cookbook(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-cookbook(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-cookbook</code> - <span class="man-whatis">upload and manage chef cookbooks</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>cookbook</strong> <em>sub-command</em> <em>(options)</em></p>
-
-<h2 id="SUB-COMMANDS">SUB-COMMANDS</h2>
-
-<p><code>knife cookbook</code> supports the following sub commands:</p>
-
-<h2 id="LIST">LIST</h2>
-
-<p><strong>knife cookbook list</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--all</code></dt><dd>show all versions of a cookbook instead of just the most recent</dd>
-<dt><code>-w</code>, <code>--with-uri</code></dt><dd>show corresponding uris</dd>
-</dl>
-
-
-<p>Lists the cookbooks available on the Chef server.</p>
-
-<h2 id="SHOW">SHOW</h2>
-
-<p><strong>knife cookbook show cookbook [version] [part] [filename]</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-f</code>, <code>--fqdn fqdn </code></dt><dd>the fqdn of the host to see the file for</dd>
-<dt><code>-p</code>, <code>--platform platform </code></dt><dd>the platform to see the file for</dd>
-<dt><code>-v</code>, <code>--platform-version version</code></dt><dd>the platform version to see the file for</dd>
-<dt><code>-w</code>, <code>--with-uri</code></dt><dd>Show corresponding URIs</dd>
-</dl>
-
-
-<p>show a particular part of a <em>cookbook</em> for the specified <em>version</em>. <em>part</em> can be one of:</p>
-
-<ul>
-<li><em>attributes</em></li>
-<li><em>definitions</em></li>
-<li><em>files</em></li>
-<li><em>libraries</em></li>
-<li><em>providers</em></li>
-<li><em>recipes</em></li>
-<li><em>resources</em></li>
-<li><em>templates</em></li>
-</ul>
-
-
-<h2 id="UPLOAD">UPLOAD</h2>
-
-<p><strong>knife cookbook upload [cookbooks...]</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--all</code></dt><dd>upload all cookbooks, rather than just a single cookbook</dd>
-<dt><code>-o</code>, <code>--cookbook-path path:path</code></dt><dd>a colon-separated path to look for cookbooks in</dd>
-<dt><code>-d</code>, <code>--upload-dependencies</code></dt><dd>Uploads additional cookbooks that this cookbook lists in as
-dependencies in its metadata.</dd>
-<dt><code>-E</code>, <code>--environment ENVIRONMENT</code></dt><dd>An <em>ENVIRONMENT</em> to apply the uploaded cookbooks to. Specifying this
-option will cause knife to edit the <em>ENVIRONMENT</em> to place a strict
-version constraint on the cookbook version(s) uploaded.</dd>
-<dt><code>--freeze</code></dt><dd>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.</dd>
-<dt class="flush"><code>--force</code></dt><dd>Overrides the frozen flag on a cookbook, allowing you to overwrite a
-cookbook version that has previously been uploaded with the --freeze
-option.</dd>
-</dl>
-
-
-<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>
-
-<p>As the command parses the name args as 1..n cookbook names:
- <code>knife cookbook upload COOKBOOK COOKBOOK ...</code>
-works for one to many cookbooks.</p>
-
-<h2 id="DOWNLOAD">DOWNLOAD</h2>
-
-<p><strong>knife cookbook download cookbook [version]</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-d</code>, <code>--dir download_directory</code></dt><dd>the directory to download the cookbook into</dd>
-<dt><code>-f</code>, <code>--force</code></dt><dd>overwrite an existing directory with the download</dd>
-<dt><code>-n</code>, <code>--latest</code></dt><dd>download the latest version of the cookbook</dd>
-</dl>
-
-
-<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.</p>
-
-<h2 id="DELETE">DELETE</h2>
-
-<p><strong>knife cookbook delete cookbook [version]</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--all</code></dt><dd>delete all versions</dd>
-<dt><code>-p</code>, <code>--purge</code></dt><dd>purge files from backing store. this will disable any cookbook that contains any of the same files as the cookbook being purged.</dd>
-</dl>
-
-
-<p>delete the specified <em>version</em> of the named <em>cookbook</em>. 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.</p>
-
-<h2 id="BULK-DELETE">BULK DELETE</h2>
-
-<p><strong>knife cookbook bulk delete regex</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-p</code>, <code>--purge</code></dt><dd>purge files from backing store. this will disable any cookbook that
-contains any of the same files as the cookbook being purged.</dd>
-</dl>
-
-
-<p>delete cookbooks on the chef server based on a regular expression. the
-regular expression (<em>regex</em>) should be in quotes, not in //'s.</p>
-
-<h2 id="COOKBOOK-CREATE">COOKBOOK CREATE</h2>
-
-<p><strong>knife cookbook create cookbook</strong> <em>(options)</em></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>-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>
-</dl>
-
-
-<p>this is a helper command that creates a new cookbook directory in the
-<code>cookbook_path</code>. the following directories and files are created for the
-named cookbook.</p>
-
-<ul>
-<li>cookbook/attributes</li>
-<li>cookbook/definitions</li>
-<li>cookbook/files/default</li>
-<li>cookbook/libraries</li>
-<li>cookbook/metadata.rb</li>
-<li>cookbook/providers</li>
-<li>cookbook/readme.md</li>
-<li>cookbook/recipes/default.rb</li>
-<li>cookbook/resources</li>
-<li>cookbook/templates/default</li>
-</ul>
-
-
-<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>
-
-<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>
-
-<p>specify <code>-i</code> or <code>--license</code> 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
-<code>none</code> (default) or <code>apachev2</code>, comment header text and metadata file
-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
-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>
-
-<p>the cookbook copyright, license, email and readme_format settings can be filled in the
-<code>knife.rb</code>, for example with default values:</p>
-
-<pre><code>cookbook_copyright "your_company_name"
-cookbook_license "none"
-cookbook_email "your_email"
-readme_format "md"
-</code></pre>
-
-<h2 id="METADATA">METADATA</h2>
-
-<p><strong>knife cookbook metadata cookbook</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--all</code></dt><dd>generate metadata for all cookbooks, rather than just a single cookbook</dd>
-<dt><code>-o</code>, <code>--cookbook-path path:path</code></dt><dd>a colon-separated path to look for cookbooks in</dd>
-</dl>
-
-
-<p>generate cookbook metadata for the named <em>cookbook</em>. the <em>path</em> used here specifies where the cookbooks directory is located and corresponds to the <code>cookbook_path</code> configuration option.</p>
-
-<h2 id="METADATA-FROM-FILE">METADATA FROM FILE</h2>
-
-<p><strong>knife cookbook metadata from file</strong> <em>(options)</em></p>
-
-<p>load the cookbook metadata from a specified file.</p>
-
-<h2 id="TEST">TEST</h2>
-
-<p><strong>knife cookbook test [cookbooks...]</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--all</code></dt><dd>test all cookbooks, rather than just a single cookbook</dd>
-<dt><code>-o</code>, <code>--cookbook-path path:path</code></dt><dd>a colon-separated path to look for cookbooks in</dd>
-</dl>
-
-
-<p>test the specified cookbooks for syntax errors. this uses the built-in
-ruby syntax checking option for files in the cookbook ending in <code>.rb</code>,
-and the erb syntax check for files ending in <code>.erb</code> (templates).</p>
-
-<h2 id="RECIPE-LIST">RECIPE LIST</h2>
-
-<p><strong>knife recipe list [PATTERN]</strong></p>
-
-<p>List available recipes from the server. Specify <em>PATTERN</em> as a regular
-expression to limit the results.</p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>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>
-
-<p>On disk, cookbooks are directories with a defined structure. The
-following directories may appear within a cookbook:</p>
-
-<dl>
-<dt>COOKBOOK/attributes/</dt><dd>Ruby files that define default parameters to be used in recipes</dd>
-<dt>COOKBOOK/definitions/</dt><dd>Ruby files that contain <em>resource definitions</em></dd>
-<dt>COOKBOOK/files/SPECIFICITY</dt><dd>Files of arbitrary type. These files may be downloaded by
-<span class="man-ref">chef-client<span class="s">(8)</span></span> when configuring a host.</dd>
-<dt>COOKBOOK/libraries/</dt><dd>Ruby files that contain library code needed for recipes</dd>
-<dt>COOKBOOK/providers/</dt><dd>Ruby files that contain Lightweight Provider definitions</dd>
-<dt>COOKBOOK/recipes/</dt><dd>Ruby files that use Chef's recipe DSL to describe the desired
-configuration of a system</dd>
-<dt>COOKBOOK/resources/</dt><dd>Ruby files that contain Lightweight Resource definitions</dd>
-<dt>COOKBOOK/templates/SPECIFICITY</dt><dd>ERuby (ERb) template files. These are referenced by <em>recipes</em> and
-evaluated to dynamically generate configuration files.</dd>
-</dl>
-
-
-<p><strong>SPECIFICITY</strong> is a feature of <em>files</em> and <em>templates</em> that allow you
-to specify alternate files to be used on a specific OS platform or host.
-The default specificity setting is <em>default</em>, that is files in
-<code>COOKBOOK/files/default</code> will be used when a more specific copy is not
-available. Further documentation for this feature is available on the
-Chef wiki: <a href="http://wiki.opscode.com/display/chef/File+Distribution#FileDistribution-FileSpecificity" data-bare-link="true">http://wiki.opscode.com/display/chef/File+Distribution#FileDistribution-FileSpecificity</a></p>
-
-<p>Cookbooks also contain a metadata file that defines various properties
-of the cookbook. The most important of these are the <em>version</em> and the
-<em>dependencies</em>. The <em>version</em> is used in combination with environments
-to select which copy of a given cookbook is distributed to a node. The
-<em>dependencies</em> are used by the server to determine which additional
-cookbooks must be distributed to a given host when it requires a
-cookbook.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong><span class="man-ref">knife-environment<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-cookbook-site<span class="s">(1)</span></span></strong>
- <a href="http://wiki.opscode.com/display/chef/Cookbooks" data-bare-link="true">http://wiki.opscode.com/display/chef/Cookbooks</a>
- <a href="http://wiki.opscode.com/display/chef/Metadata" data-bare-link="true">http://wiki.opscode.com/display/chef/Metadata</a></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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;&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-cookbook(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-data-bag.1.html b/distro/common/html/knife-data-bag.1.html
deleted file mode 100644
index 058088fe3c..0000000000
--- a/distro/common/html/knife-data-bag.1.html
+++ /dev/null
@@ -1,235 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-data-bag(1) - Store arbitrary data on a Chef Server</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#DATA-BAG-SUB-COMMANDS">DATA BAG SUB-COMMANDS</a>
- <a href="#CREATE">CREATE</a>
- <a href="#DELETE">DELETE</a>
- <a href="#EDIT">EDIT</a>
- <a href="#FROM-FILE">FROM FILE</a>
- <a href="#LIST">LIST</a>
- <a href="#SHOW">SHOW</a>
- <a href="#ENCRYPTION-SUPPORT">ENCRYPTION SUPPORT</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-data-bag(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-data-bag(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-data-bag</code> - <span class="man-whatis">Store arbitrary data on a Chef Server</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>data bag</strong> <em>sub-command</em> <em>(options)</em></p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>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 <strong>knife-search</strong>(1).</p>
-
-<p>Data bags are available to all nodes configured by <strong>chef-client</strong>(8),
-and are therefore a convenient mechanism to store global information,
-such as lists of administrative accounts that should be configured on
-all hosts.</p>
-
-<h2 id="DATA-BAG-SUB-COMMANDS">DATA BAG SUB-COMMANDS</h2>
-
-<h2 id="CREATE">CREATE</h2>
-
-<p><strong>knife data bag create</strong> <em>bag name</em> [item id] <em>(options)</em></p>
-
-<dl>
-<dt><code>-s</code>, <code>--secret SECRET</code></dt><dd>A secret key used to encrypt the data bag item. See <strong>encryption support</strong> below.</dd>
-<dt><code>--secret-file SECRET_FILE</code></dt><dd>The path to a file containing the secret key to be used to encrypt
-the data bag item.</dd>
-</dl>
-
-
-<p>If <em>item id</em> 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>
-
-<p>If <em>item id</em> is not given, the data bag will be created.</p>
-
-<h2 id="DELETE">DELETE</h2>
-
-<p><strong>knife data bag delete</strong> <em>bag name</em> [item id] <em>(options)</em></p>
-
-<p>Delete a data bag, or an item from a data bag.</p>
-
-<h2 id="EDIT">EDIT</h2>
-
-<p><strong>knife data bag edit</strong> <em>bag name</em> <em>item id</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-s</code>, <code>--secret SECRET</code></dt><dd>A secret key used to encrypt the data bag item. See <strong>encryption support</strong> below.</dd>
-<dt><code>--secret-file SECRET_FILE</code></dt><dd>The path to a file containing the secret key to be used to encrypt
-the data bag item.</dd>
-</dl>
-
-
-<p>Edit an item in a data bag.</p>
-
-<h2 id="FROM-FILE">FROM FILE</h2>
-
-<p><strong>knife data bag from file</strong> <em>bag name</em> <em>file</em> <em>(options)</em></p>
-
-<p><strong>knife data bag from file</strong> <em>bag name</em> <em>file1</em> <em>file2</em> <em>file3</em> <em>(options)</em></p>
-
-<p><strong>knife data bag from file</strong> <em>bag name</em> <em>folder</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-s</code>, <code>--secret SECRET</code></dt><dd>A secret key used to encrypt the data bag item. See <strong>encryption support</strong> below.</dd>
-<dt><code>--secret-file SECRET_FILE</code></dt><dd>The path to a file containing the secret key to be used to encrypt
-the data bag item.</dd>
-</dl>
-
-
-<p>Load a data bag item from a JSON file. If <em>file</em> is a relative or
-absolute path to the file, that file will be used. Otherwise, the <em>file</em>
-parameter is treated as the base name of a data bag file in a Chef
-repository, and <code>knife</code> will search for the file in
-<code>./data_bags/bag_name/file</code>. For example <code>knife data bag from file users
-dan.json</code> would attempt to load the file <code>./data_bags/users/dan.json</code>.</p>
-
-<h2 id="LIST">LIST</h2>
-
-<p><strong>knife data bag list</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-w</code>, <code>--with-uri</code></dt><dd>Show corresponding URIs</dd>
-</dl>
-
-
-<p>Lists the data bags that exist on the Chef Server.</p>
-
-<h2 id="SHOW">SHOW</h2>
-
-<p><strong>knife data bag show BAG [ITEM]</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-s</code>, <code>--secret SECRET</code></dt><dd>A secret key used to encrypt the data bag item. See <strong>encryption support</strong> below.</dd>
-<dt><code>--secret-file SECRET_FILE</code></dt><dd>The path to a file containing the secret key to be used to encrypt
-the data bag item.</dd>
-</dl>
-
-
-<p>Show a specific data bag or an item in a data bag. The output will be
-formatted according to the --format option.</p>
-
-<h2 id="ENCRYPTION-SUPPORT">ENCRYPTION SUPPORT</h2>
-
-<p>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>
-
-<p>Data Bag Item encryption uses the AES-256 CBC symmetric key algorithm.</p>
-
-<p><strong>CAVEATS:</strong> 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>
-
-<p>Chef Server does not provide a secure mechanism for distributing
-encryption keys.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife-search</strong>(1)</p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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;&#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>
-
-<p> Knife is distributed with Chef. http://wiki.opscode.com/display/chef/Home</p>
-
-
- <ol class='man-decor man-foot man foot'>
- <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>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-environment.1.html b/distro/common/html/knife-environment.1.html
deleted file mode 100644
index dce5bebe02..0000000000
--- a/distro/common/html/knife-environment.1.html
+++ /dev/null
@@ -1,265 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-environment(1) - Define cookbook policies for the environments in your infrastructure</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#SUBCOMMANDS">SUBCOMMANDS</a>
- <a href="#CREATE">CREATE</a>
- <a href="#DELETE">DELETE</a>
- <a href="#EDIT">EDIT</a>
- <a href="#FROM-FILE">FROM FILE</a>
- <a href="#LIST">LIST</a>
- <a href="#SHOW">SHOW</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SYNTAX">SYNTAX</a>
- <a href="#FORMAT">FORMAT</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-environment(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-environment(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-environment</code> - <span class="man-whatis">Define cookbook policies for the environments in your infrastructure</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>environment</strong> <em>sub-command</em> <em>(options)</em></p>
-
-<h2 id="SUBCOMMANDS">SUBCOMMANDS</h2>
-
-<p>Environment subcommands follow a basic create, read, update, delete
-(CRUD) pattern. The following subcommands are available:</p>
-
-<h2 id="CREATE">CREATE</h2>
-
-<p><strong>knife environment create</strong> <em>environment</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-d</code>, <code>--description DESCRIPTION</code></dt><dd>The value of the description field.</dd>
-</dl>
-
-
-<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.</p>
-
-<h2 id="DELETE">DELETE</h2>
-
-<p><strong>knife environment delete</strong> <em>environment</em> <em>(options)</em></p>
-
-<p>Destroy an environment on the Chef Server. A prompt for confirmation
-will be displayed if the -y options is not given.</p>
-
-<h2 id="EDIT">EDIT</h2>
-
-<p><strong>knife environment edit</strong> <em>environment</em> <em>(options)</em></p>
-
-<p>Fetch <em>environment</em> and display it in the text editor for editing. The
-environment will be saved to the Chef Server when the editing session
-exits.</p>
-
-<h2 id="FROM-FILE">FROM FILE</h2>
-
-<p><strong>knife environment from file</strong> <em>file</em> <em>(options)</em></p>
-
-<p>Create or update an environment from the JSON or Ruby format <em>file</em>. See
-<strong>format</strong> for the proper format of this file.</p>
-
-<h2 id="LIST">LIST</h2>
-
-<p><strong>knife environment list</strong> <em>(options)</em>
- * <code>-w</code>, <code>--with-uri</code>:
- Show the resource URI for each environment</p>
-
-<h2 id="SHOW">SHOW</h2>
-
-<p><strong>knife environment show</strong> <em>environment</em> <em>(options)</em></p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>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
-<em>environments</em>.</p>
-
-<p>Environments contain two major components: a set of cookbook version
-constraints and environment attributes.</p>
-
-<h2 id="SYNTAX">SYNTAX</h2>
-
-<p>A cookbook version constraint is comprised of a <em>cookbook name</em> and a
-<em>version constraint</em>. The <em>cookbook name</em> is the name of a cookbook in
-your system, and the <em>version constraint</em> is a String describing the
-version(s) of that cookbook allowed in the environment. Only one
-<em>version constraint</em> is supported for a given <em>cookbook name</em>.</p>
-
-<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:</p>
-
-<pre><code>{"apache2": "&gt;= 1.5.0"}
-</code></pre>
-
-<p>In the Ruby format, the cookbook version contraints for an environment
-are represented as a Ruby Hash, like this:</p>
-
-<pre><code>{"apache2" =&gt; "&gt;= 1.5.0"}
-</code></pre>
-
-<p>A <em>version number</em> 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>
-
-<p>A <em>version constraint</em> String is composed of an <em>operator</em> and a
-<em>version number</em>. The following operators are available:</p>
-
-<dl>
-<dt><code>= VERSION</code></dt><dd>Equality. Only the exact version specified may be used.</dd>
-<dt><code>&gt; VERSION</code></dt><dd>Greater than. Only versions greater than <code>VERSION</code> may be used.</dd>
-<dt><code>&gt;= VERSION</code></dt><dd>Greater than or equal to. Only versions equal to VERSION or greater
-may be used.</dd>
-<dt><code>&lt; VERSION</code></dt><dd>Less than. Only versions less than VERSION may be used.</dd>
-<dt><code>&lt;= VERSION</code></dt><dd>Less than or equal to. Only versions lesser or equal to VERSION may
-be used.</dd>
-<dt><code>~&gt; VERSION</code></dt><dd>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, <code>~&gt; 1.1</code> will match any
-version less than <code>2.0</code> and greater than or equal to <code>1.1.0</code>,
-whereas <code>~&gt; 2.0.5</code> will match any version less than <code>2.1.0</code> and
-greater than or equal to <code>2.0.5</code>.</dd>
-</dl>
-
-
-<h2 id="FORMAT">FORMAT</h2>
-
-<p>The JSON format of an envioronment is as follows:</p>
-
-<pre><code>{
- "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"
- }
-}
-</code></pre>
-
-<p>The Ruby format of an environment is as follows:</p>
-
-<pre><code>name "dev"
-description "The development environment"
-cookbook_versions "couchdb" =&gt; "= 11.0.0"
-default_attributes "apache2" =&gt; { "listen_ports" =&gt; [ "80", "443" ] }
-override_attributes "aws_s3_bucket" =&gt; "production"
-</code></pre>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong><span class="man-ref">knife-node<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-cookbook<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-role<span class="s">(1)</span></span></strong>
- <a href="http://wiki.opscode.com/display/chef/Environments" data-bare-link="true">http://wiki.opscode.com/display/chef/Environments</a>
- <a href="http://wiki.opscode.com/display/chef/Version+Constraints" data-bare-link="true">http://wiki.opscode.com/display/chef/Version+Constraints</a></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-environment(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-exec.1.html b/distro/common/html/knife-exec.1.html
deleted file mode 100644
index 80b94ef63f..0000000000
--- a/distro/common/html/knife-exec.1.html
+++ /dev/null
@@ -1,134 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-exec(1) - Run user scripts using the Chef API DSL</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#EXAMPLES">EXAMPLES</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-exec(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-exec(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-exec</code> - <span class="man-whatis">Run user scripts using the Chef API DSL</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>exec</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-E</code>, <code>--exec CODE</code></dt><dd>Provide a snippet of code to evaluate on the command line</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p><code>knife exec</code> runs arbitrary ruby scripts in a context similar to that
-of the <span class="man-ref">chef-shell<span class="s">(1)</span></span> DSL. See the chef-shell documentation for a
-description of the commands available.</p>
-
-<h2 id="EXAMPLES">EXAMPLES</h2>
-
-<dl>
-<dt>Make an API call against an arbitrary endpoint</dt><dd>knife exec -E 'api.get("nodes/fluke.localdomain/cookbooks")'
-=> list of cookbooks for the node <em>fluke.localdomain</em></dd>
-<dt>Remove the role <em>obsolete</em> from all nodes</dt><dd>knife exec -E 'nodes.transform(:all){|n| n.run_list.delete("role[obsolete]")}'</dd>
-<dt>Generate the expanded run list for hosts in the <code>webserver</code> role</dt><dd>knife exec -E 'nodes.find(:roles => "webserver") {|n| n.expand!; n[:recipes]}'</dd>
-</dl>
-
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong><span class="man-ref">chef-shell<span class="s">(1)</span></span></strong></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-exec(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-index.1.html b/distro/common/html/knife-index.1.html
deleted file mode 100644
index 30ed0f5342..0000000000
--- a/distro/common/html/knife-index.1.html
+++ /dev/null
@@ -1,125 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-index(1) - Rebuild the search index on a Chef Server</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-index(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-index(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-index</code> - <span class="man-whatis">Rebuild the search index on a Chef Server</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>index rebuild</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-y</code>, <code>--yes</code></dt><dd>don't bother to ask if I'm sure</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Rebuilds all the search indexes on the server. This is accomplished by
-deleting all objects from the search index, and then forwarding each
-item in the database to <strong>chef-expander</strong>(8) via <strong>rabbitmq-server</strong>(1).
-Depending on the number of objects in the database, it may take some
-time for all objects to be indexed and available for search.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife-search</strong>(1)</p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-index(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-node.1.html b/distro/common/html/knife-node.1.html
deleted file mode 100644
index 4e18fdc9c3..0000000000
--- a/distro/common/html/knife-node.1.html
+++ /dev/null
@@ -1,250 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-node(1) - Manage the hosts in your infrastructure</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#NODE-SUB-COMMANDS">NODE SUB-COMMANDS</a>
- <a href="#BULK-DELETE">BULK DELETE</a>
- <a href="#CREATE">CREATE</a>
- <a href="#DELETE">DELETE</a>
- <a href="#EDIT">EDIT</a>
- <a href="#FROM-FILE">FROM FILE</a>
- <a href="#LIST">LIST</a>
- <a href="#RUN_LIST-ADD">RUN_LIST ADD</a>
- <a href="#RUN_LIST-REMOVE">RUN_LIST REMOVE</a>
- <a href="#SHOW">SHOW</a>
- <a href="#RUN-LIST-ITEM-FORMAT">RUN LIST ITEM FORMAT</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-node(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-node(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-node</code> - <span class="man-whatis">Manage the hosts in your infrastructure</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>node</strong> <em>sub-command</em> <em>(options)</em></p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Nodes are data structures that represent hosts configured with Chef.
-Nodes have a <strong>name</strong>, a String that uniquely identifies the node,
-<strong>attributes</strong>, a nested Hash of properties that describe how the host
-should be configured, a <strong>chef_environment</strong>, a String representing the
-environment to which the node belongs, and a <strong>run_list</strong>, an ordered
-list of <strong>recipes</strong> or <strong>roles</strong> that chef-client should apply when
-configuring a host.</p>
-
-<p>When a host communicates with a Chef Server, it authenticates using its
-<strong>node_name</strong> for identification and signs its reqests with a private
-key. The Server validates the request by looking up a <strong>client</strong> object
-with a name identical to the <strong>node_name</strong> submitted with the request
-and verifes the signature using the public key for that <strong>client</strong>
-object. <strong>NOTE</strong> that the <strong>client</strong> is a different object in the
-system. It is associated with a node by virtue of having a matching
-name.</p>
-
-<p>By default <strong>chef-client</strong>(8) will create a node using the FQDN of the
-host for the node name, though this may be overridden by configuration
-settings.</p>
-
-<h2 id="NODE-SUB-COMMANDS">NODE SUB-COMMANDS</h2>
-
-<p>The following <code>node</code> subcommands are available:</p>
-
-<h2 id="BULK-DELETE">BULK DELETE</h2>
-
-<p><strong>knife node bulk delete</strong> <em>regex</em> <em>(options)</em></p>
-
-<p>Deletes nodes for which the name matches the regular expression <em>regex</em>
-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).</p>
-
-<h2 id="CREATE">CREATE</h2>
-
-<p><strong>knife node create</strong> <em>name</em> <em>(options)</em></p>
-
-<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.</p>
-
-<h2 id="DELETE">DELETE</h2>
-
-<p><strong>knife node delete</strong> <em>name</em> <em>(options)</em></p>
-
-<p>Deletes the node identified by <em>name</em> on the Chef Server.</p>
-
-<h2 id="EDIT">EDIT</h2>
-
-<p><strong>knife node edit</strong> <em>name</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--all</code></dt><dd>Display all node data in the editor. By default, default, override,
-and automatic attributes are not shown.</dd>
-</dl>
-
-
-<p>Edit the node identified by <em>name</em>. Like <strong>knife node create</strong>, the node
-will be displayed in your text editor unless the -n option is present.</p>
-
-<h2 id="FROM-FILE">FROM FILE</h2>
-
-<p><strong>knife node from file</strong> <em>file</em> <em>(options)</em></p>
-
-<p>Create a node from a JSON format <em>file</em>.</p>
-
-<h2 id="LIST">LIST</h2>
-
-<p><strong>knife node list</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-w</code>, <code>--with-uri</code></dt><dd>Show corresponding URIs</dd>
-</dl>
-
-
-<p>List all nodes.</p>
-
-<h2 id="RUN_LIST-ADD">RUN_LIST ADD</h2>
-
-<p><strong>knife node run_list add</strong> <em>name</em> <em>run list item</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--after ITEM</code></dt><dd>Place the ENTRY in the run list after ITEM</dd>
-</dl>
-
-
-<p>Add the <em>run list item</em> to the node's <code>run_list</code>. See Run list</p>
-
-<h2 id="RUN_LIST-REMOVE">RUN_LIST REMOVE</h2>
-
-<p><strong>knife node run_list remove</strong> <em>node name</em> <em>run list item</em> <em>(options)</em></p>
-
-<p>Remove the <em>run list item</em> from the node's <code>run_list</code>.</p>
-
-<h2 id="SHOW">SHOW</h2>
-
-<p><strong>knife node show</strong> <em>node name</em> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--attribute [ATTR]</code></dt><dd>Show only one attribute</dd>
-<dt><code>-r</code>, <code>--run-list </code></dt><dd>Show only the run list</dd>
-<dt><code>-F</code>, <code>--format FORMAT</code></dt><dd>Display the node in a different format.</dd>
-<dt><code>-m</code>, <code>--medium</code></dt><dd>Display more, but not all, of the node's data when using the default
-<em>summary</em> format</dd>
-</dl>
-
-
-<p>Displays the node identified by <em>node name</em> on stdout.</p>
-
-<h2 id="RUN-LIST-ITEM-FORMAT">RUN LIST ITEM FORMAT</h2>
-
-<p>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>
-
-<p>When adding a recipe to a run list, there are several valid formats:</p>
-
-<dl>
-<dt>Fully Qualified Format</dt><dd>"recipe[COOKBOOK::RECIPE_NAME]", for example, "recipe[chef::client]"</dd>
-<dt>Cookbook Recipe Format</dt><dd>For brevity, the recipe part of the fully qualified format may be omitted, and recipes specified as "COOKBOOK::RECIPE_NAME", e.g., "chef::client"</dd>
-<dt>Default Recipe Format</dt><dd>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"</dd>
-</dl>
-
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife-client</strong>(1) <strong>knife-search</strong>(1) <strong>knife-role</strong>(1)</p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-node(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-role.1.html b/distro/common/html/knife-role.1.html
deleted file mode 100644
index 87a6082c69..0000000000
--- a/distro/common/html/knife-role.1.html
+++ /dev/null
@@ -1,200 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-role(1) - Group common configuration settings</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#ROLE-SUB-COMMANDS">ROLE SUB-COMMANDS</a>
- <a href="#LIST">LIST</a>
- <a href="#SHOW">SHOW</a>
- <a href="#CREATE">CREATE</a>
- <a href="#EDIT">EDIT</a>
- <a href="#FROM-FILE">FROM FILE</a>
- <a href="#DELETE">DELETE</a>
- <a href="#BULK-DELETE">BULK DELETE</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-role(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-role(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-role</code> - <span class="man-whatis">Group common configuration settings</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>role</strong> <em>sub-command</em> <em>(options)</em></p>
-
-<h2 id="ROLE-SUB-COMMANDS">ROLE SUB-COMMANDS</h2>
-
-<p>The following <code>role</code> subcommands are available:</p>
-
-<h2 id="LIST">LIST</h2>
-
-<p><strong>knife role list</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-w</code>, <code>--with-uri</code></dt><dd>Show corresponding URIs</dd>
-</dl>
-
-
-<p>List roles.</p>
-
-<h2 id="SHOW">SHOW</h2>
-
-<p><strong>knife role show ROLE</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--attribute ATTR</code></dt><dd>Show only one attribute</dd>
-</dl>
-
-
-<p>Show a specific role.</p>
-
-<h2 id="CREATE">CREATE</h2>
-
-<p><strong>knife role create ROLE</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-d</code>, <code>--description</code></dt><dd>The role description</dd>
-</dl>
-
-
-<p>Create a new role.</p>
-
-<h2 id="EDIT">EDIT</h2>
-
-<p><strong>knife role edit ROLE</strong> <em>(options)</em></p>
-
-<p>Edit a role.</p>
-
-<h2 id="FROM-FILE">FROM FILE</h2>
-
-<p><strong>knife role from file FILE</strong> <em>(options)</em></p>
-
-<p>Create or update a role from a role Ruby DSL (<code>.rb</code>) or JSON file.</p>
-
-<h2 id="DELETE">DELETE</h2>
-
-<p><strong>knife role delete ROLE</strong> <em>(options)</em></p>
-
-<p>Delete a role.</p>
-
-<h2 id="BULK-DELETE">BULK DELETE</h2>
-
-<p><strong>knife role bulk delete REGEX</strong> <em>(options)</em></p>
-
-<p>Delete roles on the Chef Server based on a regular expression. The regular expression (<em>REGEX</em>) should be in quotes, not in //'s.</p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Roles provide a mechanism to group repeated configuration settings.
-Roles are data structures that contain <strong>default_attributes</strong>, and
-<strong>override_attributes</strong>, which are nested hashes of configuration
-settings, and a <strong>run_list</strong>, which is an ordered list of recipes and
-roles that should be applied to a host by chef-client.</p>
-
-<p><strong>default_attributes</strong> will be overridden if they conflict with a value
-on a node that includes the role. Conversely, <strong>override_attributes</strong>
-will override any values set on nodes that apply them.</p>
-
-<p>When <strong>chef-client</strong>(8) configures a host, it will "expand" the
-<strong>run_list</strong> 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.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong><span class="man-ref">knife-node<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-environment<span class="s">(1)</span></span></strong>
- <a href="http://wiki.opscode.com/display/chef/Roles" data-bare-link="true">http://wiki.opscode.com/display/chef/Roles</a>
- <a href="http://wiki.opscode.com/display/chef/Attributes" data-bare-link="true">http://wiki.opscode.com/display/chef/Attributes</a></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-role(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-search.1.html b/distro/common/html/knife-search.1.html
deleted file mode 100644
index 323928fe80..0000000000
--- a/distro/common/html/knife-search.1.html
+++ /dev/null
@@ -1,288 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-search(1) - Find objects on a Chef Server by query</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#INDEXES">INDEXES</a>
- <a href="#QUERY-SYNTAX">QUERY SYNTAX</a>
- <a href="#EXAMPLES">EXAMPLES</a>
- <a href="#KNOWN-BUGS">KNOWN BUGS</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-search(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-search(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-search</code> - <span class="man-whatis">Find objects on a Chef Server by query</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>search INDEX QUERY</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--attribute ATTR</code></dt><dd>Show only one attribute</dd>
-<dt><code>-i</code>, <code>--id-only</code></dt><dd>Show only the ID of matching objects</dd>
-<dt><code>-q</code>, <code>--query QUERY</code></dt><dd>The search query; useful to protect queries starting with -</dd>
-<dt><code>-R</code>, <code>--rows INT</code></dt><dd>The number of rows to return</dd>
-<dt><code>-r</code>, <code>--run-list</code></dt><dd>Show only the run list</dd>
-<dt><code>-o</code>, <code>--sort SORT</code></dt><dd>The order to sort the results in</dd>
-<dt><code>-b</code>, <code>--start ROW</code></dt><dd>The row to start returning results at</dd>
-<dt><code>-m</code>, <code>--medium</code></dt><dd>Display medium sized output when searching nodes using the default
-summary format</dd>
-<dt><code>-l</code>, <code>--long</code></dt><dd>Display long output when searching nodes using the default summary
-format</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>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.</p>
-
-<h2 id="INDEXES">INDEXES</h2>
-
-<p>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:</p>
-
-<ul>
-<li><em>node</em></li>
-<li><em>role</em></li>
-<li><em>environment</em></li>
-<li><em>clients</em></li>
-<li><em>data bag</em></li>
-</ul>
-
-
-<p>Data bags are indexed by the data bag's name. For example, to search a
-data bag named "admins":</p>
-
-<pre><code>knife search admins "field:search_pattern"
-</code></pre>
-
-<h2 id="QUERY-SYNTAX">QUERY SYNTAX</h2>
-
-<p>Queries have the form <code>field:search_pattern</code> where <code>field</code> is a key in
-the JSON description of the relevant objects (nodes, roles,
-environments, or data bags). Both <code>field</code> and <code>search_pattern</code> are
-case-sensitive. <code>search_pattern</code> can be an exact, wildcard,
-range, or fuzzy match (see below). The <code>field</code> supports exact
-matching and limited wildcard matching.</p>
-
-<p>Searches will return the relevant objects (nodes, roles, environments,
-or data bags) where the <code>search_pattern</code> matches the object's value of
-<code>field</code>.</p>
-
-<h3 id="FIELD-NAMES">FIELD NAMES</h3>
-
-<p>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.</p>
-
-<h3 id="WILDCARD-MATCHING-FOR-FIELD-NAMES">WILDCARD MATCHING FOR FIELD NAMES</h3>
-
-<p>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.</p>
-
-<h3 id="EXACT-MATCHES">EXACT MATCHES</h3>
-
-<p>Without any search modifiers, a search returns those fields for which
-the <code>search_pattern</code> exactly matches the value of <code>field</code> in the JSON
-description of the object.</p>
-
-<h3 id="WILDCARD-MATCHES">WILDCARD MATCHES</h3>
-
-<p>Search support both single- and multi-character wildcard searches
-within a search pattern.</p>
-
-<p>'?' matches exactly one character.</p>
-
-<p>'*' matches zero or more characters.</p>
-
-<h3 id="RANGE-MATCHES">RANGE MATCHES</h3>
-
-<p>Range searches allows one to match values between two given values. To
-match values between X and Y, inclusively, use square brackets:</p>
-
-<pre><code>knife search INDEX 'field:[X TO Y]
-</code></pre>
-
-<p>To match values between X and Y, exclusively, use curly brackets:</p>
-
-<pre><code>knife search INDEX 'field:{X TO Y}'
-</code></pre>
-
-<p>Values are sorted in lexicographic order.</p>
-
-<h3 id="FUZZY-MATCHES">FUZZY MATCHES</h3>
-
-<p>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:</p>
-
-<pre><code>knife search INDEX 'field:term~'
-</code></pre>
-
-<p>This search would return nodes whose <code>field</code> was 'perm' or 'germ'.</p>
-
-<h3 id="BOOLEAN-OPERATORS">BOOLEAN OPERATORS</h3>
-
-<p>The boolean operators NOT, AND, and OR are supported. To find values
-of <code>field</code> that are not X:</p>
-
-<pre><code>knife search INDEX 'field:(NOT X)'
-</code></pre>
-
-<p>To find records where <code>field1</code> is X and <code>field2</code> is Y:</p>
-
-<pre><code>knife search INDEX 'field1:X AND field2:Y'
-</code></pre>
-
-<p>To find records where <code>field</code> is X or Y:</p>
-
-<pre><code>knife search INDEX 'field:X OR field:Y'
-</code></pre>
-
-<h3 id="QUOTING-AND-SPECIAL-CHARACTERS">QUOTING AND SPECIAL CHARACTERS</h3>
-
-<p>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>
-
-<p>Search terms that include spaces should be enclosed in double-quotes:</p>
-
-<pre><code>knife search INDEX 'field:"term with spaces"'
-</code></pre>
-
-<p>The following characters must be escaped:</p>
-
-<pre><code>+ - &amp;&amp; || ! ( ) { } [ ] ^ " ~ * ? : \
-</code></pre>
-
-<h2 id="EXAMPLES">EXAMPLES</h2>
-
-<p>Find the nodes with the fully-qualified domain name (FQDN)
-www.example.com:</p>
-
-<pre><code>knife search node 'fqdn:www.example.com'
-</code></pre>
-
-<p>Find the nodes running a version of Ubuntu:</p>
-
-<pre><code>knife search node 'platform:ubuntu*'
-</code></pre>
-
-<p>Find all nodes running CentOS in the production environment:</p>
-
-<pre><code>knife search node 'chef_environment:production AND platform:centos'
-</code></pre>
-
-<h2 id="KNOWN-BUGS">KNOWN BUGS</h2>
-
-<ul>
-<li>Searches against the client index return no results in most cases. (CHEF-2477)</li>
-<li>Searches using the fuzzy match operator (~) produce an error. (CHEF-2478)</li>
-</ul>
-
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife-ssh</strong>(1)
- <a href="http://wiki.opscode.com/display/chef/Attributes" data-bare-link="true">http://wiki.opscode.com/display/chef/Attributes</a>
- <a href="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Lucene Query Parser Syntax</a></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-search(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-ssh.1.html b/distro/common/html/knife-ssh.1.html
deleted file mode 100644
index 926876c4c5..0000000000
--- a/distro/common/html/knife-ssh.1.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-ssh(1) - Run a command or interactive session on multiple remote hosts</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#TERMINAL-MULTIPLEXING-AND-TERMINAL-TAB-SUPPORT">TERMINAL MULTIPLEXING AND TERMINAL TAB SUPPORT</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-ssh(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-ssh(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-ssh</code> - <span class="man-whatis">Run a command or interactive session on multiple remote hosts</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>ssh QUERY COMMAND</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-a</code>, <code>--attribute ATTR </code></dt><dd>The attribute to use for opening the connection - default is fqdn</dd>
-<dt><code>-C</code>, <code>--concurrency NUM </code></dt><dd>The number of concurrent connections</dd>
-<dt><code>-m</code>, <code>--manual-list </code></dt><dd>QUERY is a space separated list of servers</dd>
-<dt><code>-P</code>, <code>--ssh-password PASSWORD</code></dt><dd>The ssh password</dd>
-<dt><code>-x</code>, <code>--ssh-user USERNAME </code></dt><dd>The ssh username</dd>
-<dt><code>-i</code>, <code>--identity-file IDENTITY_FILE</code></dt><dd>The SSH identity file used for authentication</dd>
-<dt><code>-p</code>, <code>--ssh-port PORT</code></dt><dd>The ssh port</dd>
-<dt><code>--[no-]host-key-verify</code></dt><dd>Verify host key, enabled by default.</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>The <em>ssh</em> sub-command opens an ssh session to each of the nodes in the
-search results of the <em>QUERY</em>. 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).</p>
-
-<h2 id="TERMINAL-MULTIPLEXING-AND-TERMINAL-TAB-SUPPORT">TERMINAL MULTIPLEXING AND TERMINAL TAB SUPPORT</h2>
-
-<p><code>knife ssh</code> integrates with several terminal multiplexer programs to
-provide a more convenient means of managing multiple ssh sessions. When
-the <em>COMMAND</em> option matches one of these, <code>knife ssh</code> will create
-multiple interactive ssh sessions running locally in the terminal
-multiplexer instead of invoking the command on the remote host.</p>
-
-<p>The available multiplexers are:</p>
-
-<dl>
-<dt><code>interactive</code></dt><dd>A built-in multiplexer. <code>interactive</code> supports running commands on a
-subset of the connected hosts in parallel</dd>
-<dt><strong>screen</strong>(1)</dt><dd>Runs ssh interactively inside <code>screen</code>. ~/.screenrc will be sourced
-if it exists.</dd>
-<dt class="flush"><strong>tmux</strong>(1)</dt><dd>Runs ssh interactively inside tmux.</dd>
-<dt><code>macterm</code> (Mac OS X only)</dt><dd>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.</dd>
-</dl>
-
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife-search</strong>(1)</p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-ssh(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-status.1.html b/distro/common/html/knife-status.1.html
deleted file mode 100644
index b2c13bc1fb..0000000000
--- a/distro/common/html/knife-status.1.html
+++ /dev/null
@@ -1,128 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-status(1) - Display status information for the nodes in your infrastructure</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-status(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-status(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-status</code> - <span class="man-whatis">Display status information for the nodes in your infrastructure</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>status</strong> <em>(options)</em></p>
-
-<dl>
-<dt><code>-r</code>, <code>--run-list RUN_LIST</code></dt><dd>Show the run list</dd>
-</dl>
-
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>The <em>status</em> 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 <code>node.save</code>. 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 <code>-r</code>
-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.</p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong>knife-search</strong>(1)</p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-status(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife-tag.1.html b/distro/common/html/knife-tag.1.html
deleted file mode 100644
index becdb07bcf..0000000000
--- a/distro/common/html/knife-tag.1.html
+++ /dev/null
@@ -1,137 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife-tag(1) - Apply tags to nodes on a Chef Server</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#TAG-SUBCOMMANDS">TAG SUBCOMMANDS</a>
- <a href="#CREATE">CREATE</a>
- <a href="#DELETE">DELETE</a>
- <a href="#LIST">LIST</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife-tag(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife-tag(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife-tag</code> - <span class="man-whatis">Apply tags to nodes on a Chef Server</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <strong>tag</strong> <em>subcommand</em> <em>(options)</em></p>
-
-<h2 id="TAG-SUBCOMMANDS">TAG SUBCOMMANDS</h2>
-
-<p>The following <code>tag</code> subcommands are available:</p>
-
-<h2 id="CREATE">CREATE</h2>
-
-<p><strong>knife tag create</strong> <em>node</em> <em>tag</em> [<em>...</em>]</p>
-
-<p>Adds one or more tags to <em>node</em></p>
-
-<h2 id="DELETE">DELETE</h2>
-
-<p><strong>knife tag delete</strong> <em>node</em> <em>tag</em> [<em>...</em>]</p>
-
-<p>Removes one or more tags from <em>node</em></p>
-
-<h2 id="LIST">LIST</h2>
-
-<p><strong>knife tag list</strong> <em>node</em></p>
-
-<p>Lists the tags applied to <em>node</em></p>
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong><span class="man-ref">knife-node<span class="s">(1)</span></span></strong></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife-tag(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife.1.html b/distro/common/html/knife.1.html
deleted file mode 100644
index 6f3758323d..0000000000
--- a/distro/common/html/knife.1.html
+++ /dev/null
@@ -1,315 +0,0 @@
-<!DOCTYPE html>
-<html>
-<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>knife(1) - Chef Server API client utility</title>
- <style type='text/css' media='all'>
- /* style: man */
- body#manpage {margin:0}
- .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
- .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
- .mp h2 {margin:10px 0 0 0}
- .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
- .mp h3 {margin:0 0 0 4ex}
- .mp dt {margin:0;clear:left}
- .mp dt.flush {float:left;width:8ex}
- .mp dd {margin:0 0 0 9ex}
- .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
- .mp pre {margin-bottom:20px}
- .mp pre+h2,.mp pre+h3 {margin-top:22px}
- .mp h2+pre,.mp h3+pre {margin-top:5px}
- .mp img {display:block;margin:auto}
- .mp h1.man-title {display:none}
- .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
- .mp h2 {font-size:16px;line-height:1.25}
- .mp h1 {font-size:20px;line-height:2}
- .mp {text-align:justify;background:#fff}
- .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
- .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
- .mp u {text-decoration:underline}
- .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
- .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
- .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
- .mp b.man-ref {font-weight:normal;color:#434241}
- .mp pre {padding:0 4ex}
- .mp pre code {font-weight:normal;color:#434241}
- .mp h2+pre,h3+pre {padding-left:0}
- ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
- ol.man-decor {width:100%}
- ol.man-decor li.tl {text-align:left}
- ol.man-decor li.tc {text-align:center;letter-spacing:4px}
- ol.man-decor li.tr {text-align:right;float:right}
- </style>
- <style type='text/css' media='all'>
- /* style: toc */
- .man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
- .man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
- .man-navigation a:hover {color:#111;text-decoration:underline}
- </style>
-</head>
-<!--
- The following styles are deprecated and will be removed at some point:
- div#man, div#man ol.man, div#man ol.head, div#man ol.man.
-
- The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
- .man-navigation should be used instead.
--->
-<body id='manpage'>
- <div class='mp' id='man'>
-
- <div class='man-navigation' style='display:none'>
- <a href="#NAME">NAME</a>
- <a href="#SYNOPSIS">SYNOPSIS</a>
- <a href="#DESCRIPTION">DESCRIPTION</a>
- <a href="#OPTIONS">OPTIONS</a>
- <a href="#SUB-COMMANDS">SUB-COMMANDS</a>
- <a href="#CONFIGURATION">CONFIGURATION</a>
- <a href="#FILES">FILES</a>
- <a href="#FORMATS">FORMATS</a>
- <a href="#CHEF-WORKFLOW">CHEF WORKFLOW</a>
- <a href="#EXAMPLES">EXAMPLES</a>
- <a href="#ENVIRONMENT">ENVIRONMENT</a>
- <a href="#SEE-ALSO">SEE ALSO</a>
- <a href="#AUTHOR">AUTHOR</a>
- <a href="#DOCUMENTATION">DOCUMENTATION</a>
- <a href="#LICENSE">LICENSE</a>
- <a href="#CHEF">CHEF</a>
- </div>
-
- <ol class='man-decor man-head man head'>
- <li class='tl'>knife(1)</li>
- <li class='tc'>Chef Manual</li>
- <li class='tr'>knife(1)</li>
- </ol>
-
- <h2 id="NAME">NAME</h2>
-<p class="man-name">
- <code>knife</code> - <span class="man-whatis">Chef Server API client utility</span>
-</p>
-
-<h2 id="SYNOPSIS">SYNOPSIS</h2>
-
-<p><strong>knife</strong> <em>sub-command</em> [<em>argument</em>...] <em>(options)</em></p>
-
-<h2 id="DESCRIPTION">DESCRIPTION</h2>
-
-<p>Knife is a command-line utility used to manage data on a Chef server
-through the HTTP(S) API. Knife is organized into groups of subcommands
-centered around the various object types in Chef. Each category of
-subcommand is documented in its own manual page. Available topics are:</p>
-
-<ul>
-<li>bootstrap</li>
-<li>client</li>
-<li>configure</li>
-<li>cookbook-site</li>
-<li>cookbook</li>
-<li>data-bag</li>
-<li>environment</li>
-<li>exec</li>
-<li>index</li>
-<li>node</li>
-<li>recipe</li>
-<li>role</li>
-<li>search</li>
-<li>ssh</li>
-<li>status</li>
-<li>tag</li>
-</ul>
-
-
-<p>If the knife manuals are in your <code>MANPATH</code>, you can access help for the
-above topics using <code>man knife-TOPIC</code>; otherwise, you can view the
-documentation using <code>knife help TOPIC</code>.</p>
-
-<h2 id="OPTIONS">OPTIONS</h2>
-
-<dl>
-<dt><code>-s</code>, <code>--server-url</code> URL</dt><dd>Chef Server URL, corresponds to <code>Chef::Config</code> <code>chef_server_url</code>.</dd>
-<dt><code>-k</code>, <code>--key</code> KEY</dt><dd>API Client Key, corresponds to <code>Chef::Config</code> <code>client_key</code>.</dd>
-<dt><code>-c</code>, <code>--config</code> CONFIG</dt><dd>The configuration file to use</dd>
-<dt><code>-E</code>, <code>--environment ENVIRONMENT</code></dt><dd>Set the Chef environment</dd>
-<dt><code>-e</code>, <code>--editor</code> EDITOR</dt><dd>Set the editor to use for interactive commands</dd>
-<dt><code>-F</code>, <code>--format</code> FORMAT</dt><dd>Which format to use for output. See FORMATS for details.</dd>
-<dt><code>-d</code>, <code>--disable-editing</code></dt><dd>Do not open EDITOR, just accept the data as is</dd>
-<dt><code>-u</code>, <code>--user</code> USER</dt><dd>API Client Username, corresponds to <code>Chef::Config</code> <code>node_name</code>.</dd>
-<dt><code>-p</code>, <code>--print-after</code></dt><dd>Show the data after a destructive operation</dd>
-<dt><code>-v</code>, <code>--version</code></dt><dd>Show chef version</dd>
-<dt><code>-V</code>, <code>--verbose</code></dt><dd>More verbose output. Use twice for max verbosity.</dd>
-<dt><code>-y</code>, <code>--yes</code></dt><dd>Say yes to all prompts for confirmation</dd>
-<dt><code>--defaults</code></dt><dd>Accept default values for all questions</dd>
-<dt><code>--[no-]color</code></dt><dd>Use colored output. Color enabled by default.</dd>
-<dt><code>-h</code>, <code>--help</code></dt><dd>Show the available options for a command.</dd>
-</dl>
-
-
-<h2 id="SUB-COMMANDS">SUB-COMMANDS</h2>
-
-<p>Sub-commands that operate on the basic Chef data types are structured as
-<em>NOUN verb NOUN (options)</em>. For all data types, the following commands
-are available:</p>
-
-<ul>
-<li>create (create)</li>
-<li>list and show (read)</li>
-<li>edit (update)</li>
-<li>delete (destroy)</li>
-</ul>
-
-
-<p>Knife also includes commands that take actions other than displaying or
-modifying data on the Chef Server, such as <strong><span class="man-ref">knife-ssh<span class="s">(1)</span></span></strong>.</p>
-
-<h2 id="CONFIGURATION">CONFIGURATION</h2>
-
-<p>The knife configuration file is a Ruby DSL to set configuration
-parameters for Knife's <strong>GENERAL OPTIONS</strong>. The default location for the
-config file is <code>~/.chef/knife.rb</code>. If managing multiple Chef
-repositories, per-repository config files can be created. The file must
-be <code>.chef/knife.rb</code> in the current directory of the repository.</p>
-
-<p>If the config file exists, knife uses these settings for <strong>GENERAL OPTIONS</strong> defaults.</p>
-
-<ul>
-<li><code>node_name</code>:
-User or client identity (i.e., <em>name</em>) to use for authenticating
-requests to the Chef Server.</li>
-<li><code>client_key</code>:
-Private key file to authenticate to the Chef server. Corresponds to the
-<code>-k</code> or <code>--key</code> option.</li>
-<li><code>chef_server_url</code>:
-URL of the Chef server. Corresponds to the <code>-s</code> or <code>--server-url</code>
-option. This is requested from the user when running this sub-command.</li>
-<li><code>syntax_check_cache_path</code>:
-Specifies the path to a directory where knife caches information
-about files that it has syntax checked.</li>
-<li><code>validation_client_name</code>:
-Specifies the name of the client used to validate new clients.</li>
-<li><code>validation_key</code>:
-Specifies the private key file to use when bootstrapping new hosts.
-See <span class="man-ref">knife-client<span class="s">(1)</span></span> for more information about the validation
-client.</li>
-<li><code>cookbook_copyright</code>, <code>cookbook_email</code>, <code>cookbook_license</code>, <code>readme_format</code>
-Used by <code>knife cookbook create</code> sub-command to specify the copyright
-holder, maintainer email, license and readme format (respectively) for new cookbooks.
-The copyright holder is listed as the maintainer in the cookbook's
-metadata and as the Copyright in the comments of the default recipe. The
-maintainer email is used in the cookbook metadata. The license
-determines what preamble to put in the comment of the default recipe,
-and is listed as the license in the cookbook metadata. Currently
-supported licenses are "apachev2" and "none". Any other values will
-result in an empty license in the metadata (needs to be filled in by the
-author), and no comment preamble in the default recipe. Currently supported
-readme formats are "md", "mkd", "txt", and "rdoc". Any other value will
-result in an unformatted README.</li>
-</ul>
-
-
-<h2 id="FILES">FILES</h2>
-
-<p><em>~/.chef/knife.rb</em></p>
-
-<p>Ruby DSL configuration file for knife. See <strong>CONFIGURATION</strong>.</p>
-
-<h2 id="FORMATS">FORMATS</h2>
-
-<p>The amount of content displayed and the output format are
-modified by the <code>--format</code> option. If no alternate format is selected,
-the default is summary.</p>
-
-<p>Valid formats are:</p>
-
-<dl>
-<dt class="flush"><code>summary</code></dt><dd>displays the node in a custom, summarized format (default)</dd>
-<dt class="flush"><code>text</code></dt><dd>displays the node data in its entirety using the colorized tree display</dd>
-<dt class="flush"><code>json</code></dt><dd>displays the node in JSON format</dd>
-<dt class="flush"><code>yaml</code></dt><dd>displays the node in YAML format</dd>
-<dt class="flush"><code>pp</code></dt><dd>displays the node using Ruby's pretty printer.</dd>
-</dl>
-
-
-<p>For brevity, only the first character of the format is required, for
-example, -Fj will produce JSON format output.</p>
-
-<h2 id="CHEF-WORKFLOW">CHEF WORKFLOW</h2>
-
-<p>When working with Chef and Knife in the local repository, the recommended workflow outline looks like:</p>
-
-<ul>
-<li>Create repository. A skeleton sample is provided at <em>http://github.com/opscode/chef-repo/</em>.</li>
-<li>Configure knife, see <strong>CONFIGURATION</strong>.</li>
-<li>Download cookbooks from the Opscode cookbooks site, see <strong>COOKBOOK SITE SUB-COMMANDS</strong>.</li>
-<li>Or, create new cookbooks, see <code>cookbook create</code> sub-command.</li>
-<li>Commit changes to the version control system. See your tool's documentation.</li>
-<li>Upload cookbooks to the Chef Server, see <strong>COOKBOOK SUB-COMMANDS</strong>.</li>
-<li>Launch instances in the Cloud, OR provision new hosts; see <strong>CLOUD COMPUTING SUB-COMMANDS</strong> and <strong>BOOTSTRAP SUB-COMMANDS</strong>.</li>
-<li>Watch Chef configure systems!</li>
-</ul>
-
-
-<p>A note about git: Opscode and many folks in the Chef community use git,
-but it is not required, except in the case of the <code>cookbook site vendor</code>
-sub-command, as it uses git directly. Version control is strongly
-recommended though, and git fits with a lot of the workflow paradigms.</p>
-
-<h2 id="EXAMPLES">EXAMPLES</h2>
-
-<h2 id="ENVIRONMENT">ENVIRONMENT</h2>
-
-<dl>
-<dt class="flush"><code>EDITOR</code></dt><dd>The text editor to use for editing data. The --editor option takes
-precedence over this value, and the --disable-editing option supresses
-data editing entirely.</dd>
-</dl>
-
-
-<h2 id="SEE-ALSO">SEE ALSO</h2>
-
-<p> <strong><span class="man-ref">chef-client<span class="s">(8)</span></span></strong> <strong><span class="man-ref">chef-server<span class="s">(8)</span></span></strong> <strong><span class="man-ref">chef-shell<span class="s">(1)</span></span></strong></p>
-
-<p> <strong><span class="man-ref">knife-bootstrap<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-client<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-configure<span class="s">(1)</span></span></strong>
- <strong><span class="man-ref">knife-cookbook-site<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-cookbook<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-data-bag<span class="s">(1)</span></span></strong>
- <strong><span class="man-ref">knife-environment<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-exec<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-index<span class="s">(1)</span></span></strong>
- <strong><span class="man-ref">knife-node<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-recipe<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-role<span class="s">(1)</span></span></strong>
- <strong><span class="man-ref">knife-search<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-ssh<span class="s">(1)</span></span></strong> <strong><span class="man-ref">knife-tag<span class="s">(1)</span></span></strong></p>
-
-<p> Complete Chef documentation is available online: <a href="http://wiki.opscode.com/display/chef/Home/" data-bare-link="true">http://wiki.opscode.com/display/chef/Home/</a></p>
-
-<p> JSON is JavaScript Object Notation <a href="http://json.org/" data-bare-link="true">http://json.org/</a></p>
-
-<p> SOLR is an open source search engine. <a href="http://lucene.apache.org/solr/" data-bare-link="true">http://lucene.apache.org/solr/</a></p>
-
-<p> <strong><span class="man-ref">git<span class="s">(1)</span></span></strong> is a version control system <a href="http://git-scm.com/" data-bare-link="true">http://git-scm.com/</a></p>
-
-<p> This manual page was generated from Markdown with <strong><span class="man-ref">ronn<span class="s">(1)</span></span></strong> <a href="http://rtomayko.github.com/ronn/ronn.1.html" data-bare-link="true">http://rtomayko.github.com/ronn/ronn.1.html</a></p>
-
-<h2 id="AUTHOR">AUTHOR</h2>
-
-<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="&#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>
-
-<p> Both Chef and this documentation are released under the terms of the
- Apache 2.0 License. You may view the license online: <a href="http://www.apache.org/licenses/LICENSE-2.0.html" data-bare-link="true">http://www.apache.org/licenses/LICENSE-2.0.html</a>
- On some systems, the complete text of the Apache 2.0 License may be found in <code>/usr/share/common-licenses/Apache-2.0</code>.</p>
-
-<h2 id="CHEF">CHEF</h2>
-
-<p> Knife is distributed with Chef. <a href="http://wiki.opscode.com/display/chef/Home" data-bare-link="true">http://wiki.opscode.com/display/chef/Home</a></p>
-
-
- <ol class='man-decor man-foot man foot'>
- <li class='tl'>Chef 11.8.0.alpha.0</li>
- <li class='tc'>July 2013</li>
- <li class='tr'>knife(1)</li>
- </ol>
-
- </div>
-</body>
-</html>
diff --git a/distro/common/html/knife.html b/distro/common/html/knife.html
new file mode 100644
index 0000000000..d2f425438f
--- /dev/null
+++ b/distro/common/html/knife.html
@@ -0,0 +1,172 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife">
+<h1>knife<a class="headerlink" href="#knife" title="Permalink to this headline">¶</a></h1>
+<p>Knife is a command-line tool that provides an interface between a local chef-repo and the server. Knife helps users to manage:</p>
+<ul class="simple">
+<li>Nodes</li>
+<li>Cookbooks and recipes</li>
+<li>Roles</li>
+<li>Stores of JSON data (data bags), including encrypted data</li>
+<li>Environments</li>
+<li>Cloud resources, including provisioning</li>
+<li>The installation of the chef-client on management workstations</li>
+<li>Searching of indexed data on the server</li>
+</ul>
+<p>The following sections describe functionality common to all Knife subcommands:</p>
+<ul class="simple">
+<li><a class="reference internal" href="knife_using.html"><em>Working with Knife</em></a></li>
+<li><a class="reference internal" href="knife_common_options.html"><em>Common Options</em></a></li>
+</ul>
+<p>Knife includes the following sub-commands:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="25%" />
+<col width="75%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Sub-command</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td><a class="reference internal" href="knife_bootstrap.html"><em>knife bootstrap</em></a></td>
+<td>The <strong>knife bootstrap</strong> subcommand is used to 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.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_client.html"><em>knife client</em></a></td>
+<td>The <strong>knife client</strong> 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.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_configure.html"><em>knife configure</em></a></td>
+<td>The <strong>knife configure</strong> subcommand is used to create the knife.rb and client.rb files so that they can be distributed to workstations and nodes.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_cookbook.html"><em>knife cookbook</em></a></td>
+<td>The <strong>knife cookbook</strong> subcommand is used to interact with cookbooks that are located on the server or the local chef-repo.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_cookbook_site.html"><em>knife cookbook site</em></a></td>
+<td>The <strong>knife cookbook site</strong> subcommand is used to interact with cookbooks that are located at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>. A user account is required for any community actions that write data to this site. The following arguments do not require a user account: <tt class="docutils literal"><span class="pre">download</span></tt>, <tt class="docutils literal"><span class="pre">search</span></tt>, <tt class="docutils literal"><span class="pre">install</span></tt>, and <tt class="docutils literal"><span class="pre">list</span></tt>.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_data_bag.html"><em>knife data bag</em></a></td>
+<td>The <strong>knife data bag</strong> subcommand is used to manage arbitrary stores of globally available JSON data.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_delete.html"><em>knife delete</em></a></td>
+<td>The <strong>knife delete</strong> subcommand is used to delete an object from a server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">delete</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">delete</span></tt>, but with a single verb (and a single action).</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_deps.html"><em>knife deps</em></a></td>
+<td>The <strong>knife deps</strong> subcommand is used to identify dependencies for a node, role, or cookbook.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_diff.html"><em>knife diff</em></a></td>
+<td>The <strong>knife diff</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt> and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt> subcommands, or to ensure that certain files in multiple production environments are the same. This subcommand is similar to the <tt class="docutils literal"><span class="pre">git</span> <span class="pre">diff</span></tt> command that can be used to diff what is in the chef-repo with what is synced to a git repository.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_download.html"><em>knife download</em></a></td>
+<td>The <strong>knife download</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">diff</span></tt>, which can be used to see exactly what changes will be downloaded, and then <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt>, which does the opposite of <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt>.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_edit.html"><em>knife edit</em></a></td>
+<td>The <strong>knife edit</strong> subcommand is used to edit objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">edit</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">edit</span></tt>, but with a single verb (and a single action).</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_environment.html"><em>knife environment</em></a></td>
+<td>The <strong>knife environment</strong> subcommand is used to manage environments within a single organization on the server.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_exec.html"><em>knife exec</em></a></td>
+<td>The <strong>knife exec</strong> 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.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_index_rebuild.html"><em>knife index rebuild</em></a></td>
+<td>The <strong>knife index rebuild</strong> subcommand is used to rebuild the search indexes for the open source server. This operation is destructive and may take some time.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_list.html"><em>knife list</em></a></td>
+<td>The <strong>knife list</strong> subcommand is used to view a list of objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">list</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">list</span></tt>, but with a single verb (and a single action).</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_node.html"><em>knife node</em></a></td>
+<td>The <strong>knife node</strong> subcommand is used to manage the nodes that exist on a server.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_raw.html"><em>knife raw</em></a></td>
+<td>The <strong>knife raw</strong> subcommand is used to send a REST request to a specified path using the Chef Server API.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_recipe_list.html"><em>knife recipe list</em></a></td>
+<td>The <strong>knife recipe list</strong> 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 (/).</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_role.html"><em>knife role</em></a></td>
+<td>The <strong>knife role</strong> subcommand is used to manage the roles that are associated with one or more nodes on a server.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_search.html"><em>knife search</em></a></td>
+<td>The <strong>knife search</strong> subcommand is used run a search query for information that is indexed on a server.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_show.html"><em>knife show</em></a></td>
+<td>The <strong>knife show</strong> subcommand is used to view the details of one (or more) objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">show</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">show</span></tt>, but with a single verb (and a single action).</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_ssh.html"><em>knife ssh</em></a></td>
+<td>The <strong>knife ssh</strong> 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.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_status.html"><em>knife status</em></a></td>
+<td>The <strong>knife status</strong> 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.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_tag.html"><em>knife tag</em></a></td>
+<td>The <strong>knife tag</strong> subcommand is used to apply tags to nodes on a server.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_upload.html"><em>knife upload</em></a></td>
+<td>The <strong>knife upload</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">diff</span></tt>, which can be used to see exactly what changes will be uploaded, and then <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt>, which does the opposite of <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt>.</td>
+</tr>
+<tr class="row-odd"><td><a class="reference internal" href="knife_user.html"><em>knife user</em></a></td>
+<td>The <strong>knife user</strong> subcommand is used to manage the list of users and their associated RSA public key-pairs.</td>
+</tr>
+<tr class="row-even"><td><a class="reference internal" href="knife_xargs.html"><em>knife xargs</em></a></td>
+<td>The <strong>knife xargs</strong> subcommand is used to build and execute command lines against objects on a server using standard input.</td>
+</tr>
+</tbody>
+</table>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_bootstrap.html b/distro/common/html/knife_bootstrap.html
new file mode 100644
index 0000000000..121db9cdb0
--- /dev/null
+++ b/distro/common/html/knife_bootstrap.html
@@ -0,0 +1,250 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife bootstrap &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-bootstrap">
+<h1>knife bootstrap<a class="headerlink" href="#knife-bootstrap" title="Permalink to this headline">¶</a></h1>
+<p>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.</p>
+<p>The <strong>knife bootstrap</strong> subcommand is used to 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.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">To bootstrap the chef-client on Microsoft Windows machines, the <a class="reference external" href="http://docs.opscode.com/plugin_knife_windows.html">knife-windows</a> plugins is required, which includes the necessary bootstrap scripts that are used to do the actual installation.</p>
+</div>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife bootstrap FQDN_or_IP_ADDRESS <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-A</span></tt>, <tt class="docutils literal"><span class="pre">--forward-agent</span></tt></dt>
+<dd>Indicates that SSH agent forwarding is enabled.</dd>
+<dt><tt class="docutils literal"><span class="pre">--bootstrap-no-proxy</span> <span class="pre">NO_PROXY_URL_or_IP</span></tt></dt>
+<dd>A URL or IP address that specifies a location that should not be proxied. Note: This option is used internally by Chef to help verify bootstrap operations during testing and should never be used during an actual bootstrap operation.</dd>
+<dt><tt class="docutils literal"><span class="pre">--bootstrap-proxy</span> <span class="pre">PROXY_URL</span></tt></dt>
+<dd>The proxy server for the node that is the target of a bootstrap operation.</dd>
+<dt><tt class="docutils literal"><span class="pre">--bootstrap-version</span> <span class="pre">VERSION</span></tt></dt>
+<dd>The version of the chef-client to install.</dd>
+<dt><tt class="docutils literal"><span class="pre">-d</span> <span class="pre">DISTRO</span></tt>, <tt class="docutils literal"><span class="pre">--distro</span> <span class="pre">DISTRO</span></tt></dt>
+<dd><div class="first admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">The default bootstrap operation uses the omnibus installer, which means the default template file (<tt class="docutils literal"><span class="pre">chef-full</span></tt>) should work on all supported platforms. It is recommended to use custom bootstrap templates only when the omnibus installer cannot be used.</p>
+</div>
+<p class="last">The template file to be used during a bootstrap operation. The following distributions are supported: <tt class="docutils literal"><span class="pre">chef-full</span></tt> (the default bootstrap), <tt class="docutils literal"><span class="pre">centos5-gems</span></tt>, <tt class="docutils literal"><span class="pre">fedora13-gems</span></tt>, <tt class="docutils literal"><span class="pre">ubuntu10.04-gems</span></tt>, <tt class="docutils literal"><span class="pre">ubuntu10.04-apt</span></tt>, <tt class="docutils literal"><span class="pre">ubuntu12.04-gems</span></tt>, 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 <tt class="docutils literal"><span class="pre">bootstrap/</span></tt> folder in the current working directory, the <tt class="docutils literal"><span class="pre">bootstrap/</span></tt> folder in the chef-repo, the <tt class="docutils literal"><span class="pre">bootstrap/</span></tt> folder in the <tt class="docutils literal"><span class="pre">~/.chef/</span></tt> directory, or a default bootstrap file. Do not use the <tt class="docutils literal"><span class="pre">--template-file</span></tt> option when <tt class="docutils literal"><span class="pre">--distro</span></tt> is specified.</p>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">-G</span> <span class="pre">GATEWAY</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-gateway</span> <span class="pre">GATEWAY</span></tt></dt>
+<dd>The SSH tunnel or gateway that is used to run a bootstrap action on a machine that is not accessible from the workstation.</dd>
+<dt><tt class="docutils literal"><span class="pre">--hint</span> <span class="pre">HINT_NAME[=HINT_FILE]</span></tt></dt>
+<dd>An Ohai hint to be set on the target of the bootstrap. The hint is contained in a file and is formatted as JSON: <tt class="docutils literal"><span class="pre">{&quot;attribute&quot;:&quot;value&quot;,&quot;attribute&quot;:&quot;value&quot;...}</span></tt>. <tt class="docutils literal"><span class="pre">HINT_NAME</span></tt> is the name of the hint and <tt class="docutils literal"><span class="pre">HINT_FILE</span></tt> is the name of the hint file located at <tt class="docutils literal"><span class="pre">/etc/chef/ohai/hints/HINT_FILE.json</span></tt>. Use multiple <tt class="docutils literal"><span class="pre">--hint</span></tt> options in the command to specify multiple hints.</dd>
+<dt><tt class="docutils literal"><span class="pre">-i</span> <span class="pre">IDENTITY_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--identity-file</span> <span class="pre">IDENTITY_FILE</span></tt></dt>
+<dd>The SSH identity file used for authentication. Key-based authentication is recommended.</dd>
+<dt><tt class="docutils literal"><span class="pre">-j</span> <span class="pre">JSON_ATTRIBS</span></tt>, <tt class="docutils literal"><span class="pre">--json-attributes</span> <span class="pre">JSON_ATTRIBS</span></tt></dt>
+<dd>A JSON string that is added to the first run of a chef-client.</dd>
+<dt><tt class="docutils literal"><span class="pre">-N</span> <span class="pre">NAME</span></tt>, <tt class="docutils literal"><span class="pre">--node-name</span> <span class="pre">NAME</span></tt></dt>
+<dd>The name of the node.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]host-key-verify</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--no-host-key-verify</span></tt> to disable host key verification. Default setting: <tt class="docutils literal"><span class="pre">--host-key-verify</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-p</span> <span class="pre">PORT</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-port</span> <span class="pre">PORT</span></tt></dt>
+<dd>The SSH port.</dd>
+<dt><tt class="docutils literal"><span class="pre">-P</span> <span class="pre">PASSWORD</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-password</span> <span class="pre">PASSWORD</span></tt></dt>
+<dd>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.</dd>
+<dt><tt class="docutils literal"><span class="pre">--prerelease</span></tt></dt>
+<dd>Indicates that pre-release gems should be installed.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span> <span class="pre">RUN_LIST</span></tt>, <tt class="docutils literal"><span class="pre">--run-list</span> <span class="pre">RUN_LIST</span></tt></dt>
+<dd>A comma-separated list of roles and/or recipes to be applied.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
+<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
+<dd>The path to the file that contains the encryption key.</dd>
+<dt><tt class="docutils literal"><span class="pre">--sudo</span></tt></dt>
+<dd>Indicates that a bootstrap operation should be executed using sudo.</dd>
+<dt><tt class="docutils literal"><span class="pre">--template-file</span> <span class="pre">TEMPLATE</span></tt></dt>
+<dd>The path to a template file that will be used during a bootstrap operation. Do not use the <tt class="docutils literal"><span class="pre">--distro</span></tt> option when <tt class="docutils literal"><span class="pre">--template-file</span></tt> is specified.</dd>
+<dt><tt class="docutils literal"><span class="pre">--use-sudo-password</span></tt></dt>
+<dd>Indicates that a bootstrap operation is done using sudo, with the password specified by the <tt class="docutils literal"><span class="pre">-P</span></tt> (or <tt class="docutils literal"><span class="pre">--ssh-password</span></tt>) option.</dd>
+<dt><tt class="docutils literal"><span class="pre">-x</span> <span class="pre">USERNAME</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-user</span> <span class="pre">USERNAME</span></tt></dt>
+<dd>The SSH user name.</dd>
+</dl>
+</div>
+<div class="section" id="custom-templates">
+<h2>Custom Templates<a class="headerlink" href="#custom-templates" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">chef-full</span></tt> distribution uses the omnibus installer. For most bootstrap operations, regardless of the platform on which the target node is running, using the <tt class="docutils literal"><span class="pre">chef-full</span></tt> distribution is the best approach for installing the chef-client on a target node. In some situations, using another supported distribution is necessary. And in some situations, a custom template may be required. For example, the default bootstrap operation relies on an Internet connection to get the distribution to the target node. If a target node cannot access the Internet, then a custom template can be used to define a specific location for the distribution so that the target node may access it during the bootstrap operation.</p>
+<p>A custom bootstrap template file (<tt class="docutils literal"><span class="pre">template_filename.erb</span></tt>) must be located in a <tt class="docutils literal"><span class="pre">bootstrap/</span></tt> directory. Use the <tt class="docutils literal"><span class="pre">--distro</span></tt> option with the <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">bootstrap</span></tt> subcommand to specify the bootstrap template file. For example, a bootstrap template file named &#8220;british_sea_power.erb&#8221;:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife bootstrap 123.456.7.8 -x username -P password --sudo --distro <span class="s2">&quot;british_sea_power.erb&quot;</span>
+</pre></div>
+</div>
+<p>The following examples show how a bootstrap template file can be customized for various platforms.</p>
+<div class="section" id="ubuntu-12-04">
+<h3>Ubuntu 12.04<a class="headerlink" href="#ubuntu-12-04" title="Permalink to this headline">¶</a></h3>
+<p>The following example shows how to modify the default script for Ubuntu 12.04. First, copy the bootstrap template from the default location. If the chef-client is installed from a RubyGems, the full path can be found in the gem contents:</p>
+<div class="highlight-bash"><div class="highlight"><pre>% gem contents chef | grep ubuntu12.04-gems
+/Users/jtimberman/.rvm/gems/ruby-1.9.2-p180/gems/chef-0.10.2/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb
+</pre></div>
+</div>
+<p>Copy the template to the chef-repo in the <tt class="docutils literal"><span class="pre">.chef/bootstrap</span></tt> directory:</p>
+<div class="highlight-bash"><div class="highlight"><pre>% cp /Users/jtimberman/.rvm/gems/ruby-1.9.2-p180/gems/chef-0.10.2/
+ lib/chef/knife/bootstrap/ubuntu12.04-gems.erb ~/chef-repo/.chef/
+ bootstrap/ubuntu12.04-gems-mine.erb
+</pre></div>
+</div>
+<p>Modify the template with any editor, then use it with the <tt class="docutils literal"><span class="pre">-d</span></tt> or <tt class="docutils literal"><span class="pre">--distro</span></tt> option in the <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">bootstrap</span></tt> operation, or use any of the Knife plug-ins that support cloud computing.</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife bootstrap 192.168.1.100 -r <span class="s1">&#39;role[webserver]&#39;</span> -d ubuntu12.04-gems-mine
+</pre></div>
+</div>
+<p>Alternatively, an example bootstrap template can be found in the git source for the chef-repo: <a class="reference external" href="https://github.com/opscode/chef/blob/master/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb">https://github.com/opscode/chef/blob/master/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb</a>. Copy the template to <tt class="docutils literal"><span class="pre">~/.chef-repo/.chef/bootstrap/ubuntu12.04-apt.erb</span></tt> and modify the template appropriately.</p>
+</div>
+<div class="section" id="debian-and-apt">
+<h3>Debian and Apt<a class="headerlink" href="#debian-and-apt" title="Permalink to this headline">¶</a></h3>
+<p>The following example shows how to use the <strong>knife bootstrap</strong> sub-command to create a client configuration file (/etc/chef/client.rb) that uses Hosted Chef as the server. The configuration file will look something like:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">log_level</span> <span class="ss">:info</span>
+<span class="n">log_location</span> <span class="no">STDOUT</span>
+<span class="n">chef_server_url</span> <span class="s1">&#39;https://api.opscode.com/organizations/ORGNAME&#39;</span>
+<span class="n">validation_client_name</span> <span class="s1">&#39;ORGNAME-validator&#39;</span>
+</pre></div>
+</div>
+<p>The <strong>knife bootstrap</strong> sub-command will look in three locations for the template that is used during the bootstrap operation. The locations are:</p>
+<ol class="arabic simple">
+<li>A bootstrap directory in the installed Knife library; the actual location may vary, depending how the chef-client is installed</li>
+<li>A bootstrap directory in the <tt class="docutils literal"><span class="pre">$PWD/.chef</span></tt>, e.g. in <tt class="docutils literal"><span class="pre">~/chef-repo/.chef</span></tt></li>
+<li>A bootstrap directory in the users <tt class="docutils literal"><span class="pre">$HOME/.chef</span></tt></li>
+</ol>
+<p>If, in the example above, the second location was used, then create the <tt class="docutils literal"><span class="pre">.chef/bootstrap/</span></tt> directory in the chef-repo, and then create the Embedded Ruby (ERB) template file by running commands similar to the following:</p>
+<div class="highlight-bash"><div class="highlight"><pre>mkdir ~/.chef/bootstrap
+vi ~/.chef/bootstrap/debian5.0-apt.erb
+</pre></div>
+</div>
+<p>When finished creating the directory and the Embedded Ruby (ERB) template file, edit the template to run the SSH commands. Then set up the validation certificate and the client configuration file.</p>
+<p>Finally, run the chef-client on the node using a <strong>knife bootstrap</strong> command that specifies a run-list (the <tt class="docutils literal"><span class="pre">-r</span></tt> option). The bootstrap template can be called using a command similar to the following:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife bootstrap mynode.example.com -r <span class="s1">&#39;role[webserver]&#39;</span>,<span class="s1">&#39;role[production]&#39;</span> --distro debian5.0-apt
+</pre></div>
+</div>
+</div>
+<div class="section" id="microsoft-windows">
+<h3>Microsoft Windows<a class="headerlink" href="#microsoft-windows" title="Permalink to this headline">¶</a></h3>
+<p>The following example shows how to modify the default script for Microsoft Windows and Windows PowerShell:</p>
+<div class="highlight-bash"><div class="highlight"><pre>@setlocal
+
+&lt;%<span class="o">=</span> <span class="s2">&quot;SETX HTTP_PROXY \&quot;#{knife_config[:bootstrap_proxy]}\&quot;&quot;</span> <span class="k">if </span>knife_config<span class="o">[</span>:bootstrap_proxy<span class="o">]</span> %&gt;
+@mkdir &lt;%<span class="o">=</span> bootstrap_directory %&gt;
+
+&gt; &lt;%<span class="o">=</span> bootstrap_directory %&gt;<span class="se">\w</span>get.ps1 <span class="o">(</span>
+ &lt;%<span class="o">=</span> win_wget_ps %&gt;
+<span class="o">)</span>
+
+:install
+@rem Install Chef using chef-client MSI installer
+
+&lt;% <span class="nv">url</span><span class="o">=</span><span class="s2">&quot;http://reposerver.example.com/chef-client-11.6.0.rc.1-1.windows.msi&quot;</span> -%&gt;
+@set <span class="s2">&quot;REMOTE_SOURCE_MSI_URL=&lt;%= url %&gt;&quot;</span>
+@set <span class="s2">&quot;LOCAL_DESTINATION_MSI_PATH=&lt;%= local_download_path %&gt;&quot;</span>
+
+@powershell -ExecutionPolicy Unrestricted -NoProfile -NonInteractive <span class="s2">&quot;&amp; &#39;&lt;%= bootstrap_directory %&gt;\wget.ps1&#39; &#39;%REMOTE_SOURCE_MSI_URL%&#39; &#39;%LOCAL_DESTINATION_MSI_PATH%&#39;&quot;</span>
+
+@REM Replace install_chef from knife-windows Gem with one that has extra flags to turn on Chef service feature -- only available in Chef &gt;<span class="o">=</span> 11.6.x
+@REM &lt;%<span class="o">=</span> install_chef %&gt;
+@echo Installing Chef Client 11.6.0.rc1 with msiexec
+@msiexec /q /i <span class="s2">&quot;%LOCAL_DESTINATION_MSI_PATH%&quot;</span> <span class="nv">ADDLOCAL</span><span class="o">=</span><span class="s2">&quot;ChefClientFeature,ChefServiceFeature&quot;</span>
+@endlocal
+
+@echo Writing validation key...
+
+&gt; &lt;%<span class="o">=</span> bootstrap_directory %&gt;<span class="se">\v</span>alidation.pem <span class="o">(</span>
+ &lt;%<span class="o">=</span> validation_key %&gt;
+<span class="o">)</span>
+
+@echo Validation key written.
+
+&lt;% <span class="k">if</span> @config<span class="o">[</span>:encrypted_data_bag_secret<span class="o">]</span> -%&gt;
+&gt; &lt;%<span class="o">=</span> bootstrap_directory %&gt;<span class="se">\e</span>ncrypted_data_bag_secret <span class="o">(</span>
+ &lt;%<span class="o">=</span> encrypted_data_bag_secret %&gt;
+<span class="o">)</span>
+&lt;% end -%&gt;
+
+&gt; &lt;%<span class="o">=</span> bootstrap_directory %&gt;<span class="se">\c</span>lient.rb <span class="o">(</span>
+ &lt;%<span class="o">=</span> config_content %&gt;
+<span class="o">)</span>
+
+&gt; &lt;%<span class="o">=</span> bootstrap_directory %&gt;<span class="se">\f</span>irst-boot.json <span class="o">(</span>
+ &lt;%<span class="o">=</span> run_list %&gt;
+<span class="o">)</span>
+
+&lt;%<span class="o">=</span> start_chef %&gt;
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Use an SSH password</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife bootstrap 192.168.1.1 -x username -P PASSWORD --sudo
+</pre></div>
+</div>
+<p><strong>Use a file that contains a private key</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife bootstrap 192.168.1.1 -x username -i ~/.ssh/id_rsa --sudo
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_client.html b/distro/common/html/knife_client.html
new file mode 100644
index 0000000000..ad9df20318
--- /dev/null
+++ b/distro/common/html/knife_client.html
@@ -0,0 +1,283 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife client &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-client">
+<h1>knife client<a class="headerlink" href="#knife-client" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife client</strong> 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.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="bulk-delete">
+<h2>bulk delete<a class="headerlink" href="#bulk-delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">bulk</span> <span class="pre">delete</span></tt> 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 (/).</p>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client bulk delete REGEX
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>None.</p>
+</div>
+</div>
+<div class="section" id="create">
+<h2>create<a class="headerlink" href="#create" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">create</span></tt> 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 <tt class="docutils literal"><span class="pre">STDOUT</span></tt> or written to a named file.</p>
+<ul class="simple">
+<li>For the chef-client, the private key should be copied to the system as <tt class="docutils literal"><span class="pre">/etc/chef/client.pem</span></tt>.</li>
+<li>For Knife, the private key is typically copied to <tt class="docutils literal"><span class="pre">~/.chef/client_name.pem</span></tt> and referenced in the knife.rb configuration file.</li>
+</ul>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client create CLIENT_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--admin</span></tt></dt>
+<dd>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 Enterprise Chef.</dd>
+</dl>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create an admin client</strong></p>
+<p>To create a Chef Admin client with the name &#8220;exampleorg&#8221; and save its private key to a file, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client create exampleorg -a -f <span class="s2">&quot;/etc/chef/client.pem&quot;</span>
+</pre></div>
+</div>
+<p><strong>Create an admin client for Enterprise Chef</strong></p>
+<p>When running the <tt class="docutils literal"><span class="pre">create</span></tt> argument on Enterprise Chef, be sure to omit the <tt class="docutils literal"><span class="pre">-a</span></tt> option:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client create exampleorg -f <span class="s2">&quot;/etc/chef/client.pem&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="delete">
+<h2>delete<a class="headerlink" href="#delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">delete</span></tt> argument is used to delete a registered API client.</p>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client delete CLIENT_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Delete a client</strong></p>
+<p>To delete a client with the name &#8220;client_foo&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client delete client_foo
+</pre></div>
+</div>
+<p>Type <tt class="docutils literal"><span class="pre">Y</span></tt> to confirm a deletion.</p>
+</div>
+</div>
+<div class="section" id="edit">
+<h2>edit<a class="headerlink" href="#edit" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">edit</span></tt> 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 <tt class="docutils literal"><span class="pre">admin</span></tt> attribute. (None of the other attributes should be changed using this argument.) When finished, Knife will update the server with those changes.</p>
+<div class="section" id="id7">
+<h3>Syntax<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client edit CLIENT_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id8">
+<h3>Options<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id9">
+<h3>Examples<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Edit a client</strong></p>
+<p>To edit a client with the name &#8220;exampleorg&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client edit exampleorg
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> argument is used to view a list of registered API client.</p>
+<div class="section" id="id10">
+<h3>Syntax<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client list <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id11">
+<h3>Options<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id12">
+<h3>Examples<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of clients</strong></p>
+<p>To verify the API client list for the server, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client list
+</pre></div>
+</div>
+<p>to return something similar to:</p>
+<div class="highlight-bash"><div class="highlight"><pre>exampleorg
+i-12345678
+rs-123456
+</pre></div>
+</div>
+<p>To verify that an API client can authenticate to the
+server correctly, try getting a list of clients using <tt class="docutils literal"><span class="pre">-u</span></tt> and <tt class="docutils literal"><span class="pre">-k</span></tt> options to specify its name and private key:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client list -u ORGNAME -k .chef/ORGNAME.pem
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="reregister">
+<h2>reregister<a class="headerlink" href="#reregister" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">reregister</span></tt> 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 <tt class="docutils literal"><span class="pre">STDOUT</span></tt> or written to a named file.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Running this argument will invalidate the previous RSA key pair, making it unusable during authentication to the server.</p>
+</div>
+<div class="section" id="id13">
+<h3>Syntax<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client reregister CLIENT_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id14">
+<h3>Options<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-f</span> <span class="pre">FILE_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--file</span> <span class="pre">FILE_NAME</span></tt></dt>
+<dd>Indicates that the private key will be saved to a specified file name.</dd>
+</dl>
+</div>
+<div class="section" id="id15">
+<h3>Examples<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Reregister clients</strong></p>
+<p>To regenerate the RSA key pair for a client named &#8220;testclient&#8221; and save it to a file named &#8220;rsa_key&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client regenerate testclient -f rsa_key
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="show">
+<h2>show<a class="headerlink" href="#show" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">show</span></tt> argument is used to show the details of an API client.</p>
+<div class="section" id="id16">
+<h3>Syntax<a class="headerlink" href="#id16" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client show CLIENT_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id17">
+<h3>Options<a class="headerlink" href="#id17" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">ATTR</span></tt></dt>
+<dd>The attribute (or attributes) to show.</dd>
+</dl>
+</div>
+<div class="section" id="id18">
+<h3>Examples<a class="headerlink" href="#id18" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show clients</strong></p>
+<p>To view a client named &#8220;testclient&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife client show testclient
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>admin: <span class="nb">false</span>
+chef_type: client
+json_class: Chef::ApiClient
+name: testclient
+public_key:
+</pre></div>
+</div>
+<p>To view information in JSON format, use the <tt class="docutils literal"><span class="pre">-F</span></tt> common option as part of the command like this:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role show devops -F json
+</pre></div>
+</div>
+<p>Other formats available include <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>.</p>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_common_options.html b/distro/common/html/knife_common_options.html
new file mode 100644
index 0000000000..694e49112b
--- /dev/null
+++ b/distro/common/html/knife_common_options.html
@@ -0,0 +1,98 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Common Options &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="common-options">
+<h1>Common Options<a class="headerlink" href="#common-options" title="Permalink to this headline">¶</a></h1>
+<p>The following options can be run with all Knife sub-commands and plug-ins:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--chef-zero-port</span> <span class="pre">PORT</span></tt></dt>
+<dd>The port on which chef-zero will listen.</dd>
+<dt><tt class="docutils literal"><span class="pre">-c</span> <span class="pre">CONFIG_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--config</span> <span class="pre">CONFIG_FILE</span></tt></dt>
+<dd>The configuration file to use. For example, when Knife is run from a node that is configured to be managed by the server, this option is used to allow Knife to use the same credentials as the chef-client when communicating with the server.</dd>
+<dt><tt class="docutils literal"><span class="pre">-d</span></tt>, <tt class="docutils literal"><span class="pre">--disable-editing</span></tt></dt>
+<dd>Indicates that $EDITOR will not be opened; data will be accepted as-is.</dd>
+<dt><tt class="docutils literal"><span class="pre">--defaults</span></tt></dt>
+<dd>Indicates that Knife will use the default value, instead of asking a user to provide one.</dd>
+<dt><tt class="docutils literal"><span class="pre">-e</span> <span class="pre">EDITOR</span></tt>, <tt class="docutils literal"><span class="pre">--editor</span> <span class="pre">EDITOR</span></tt></dt>
+<dd>The $EDITOR that is used for all interactive commands.</dd>
+<dt><tt class="docutils literal"><span class="pre">-E</span> <span class="pre">ENVIRONMENT</span></tt>, <tt class="docutils literal"><span class="pre">--environment</span> <span class="pre">ENVIRONMENT</span></tt></dt>
+<dd>The name of the environment. When this option is added to a command, the command will run only against the named environment.</dd>
+<dt><tt class="docutils literal"><span class="pre">-F</span> <span class="pre">FORMAT</span></tt>, <tt class="docutils literal"><span class="pre">--format</span> <span class="pre">FORMAT</span></tt></dt>
+<dd>The output format: <tt class="docutils literal"><span class="pre">summary</span></tt> (default), <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">json</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-h</span></tt>, <tt class="docutils literal"><span class="pre">--help</span></tt></dt>
+<dd>Shows help for the command.</dd>
+<dt><tt class="docutils literal"><span class="pre">-k</span> <span class="pre">KEY</span></tt>, <tt class="docutils literal"><span class="pre">--key</span> <span class="pre">KEY</span></tt></dt>
+<dd>The private key that Knife will use to sign requests made by the API client to the server.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]color</span></tt></dt>
+<dd>Indicates whether colored output will be used.</dd>
+<dt><tt class="docutils literal"><span class="pre">--print-after</span></tt></dt>
+<dd>Indicates that data will be shown after a destructive operation.</dd>
+<dt><tt class="docutils literal"><span class="pre">-s</span> <span class="pre">URL</span></tt>, <tt class="docutils literal"><span class="pre">--server-url</span> <span class="pre">URL</span></tt></dt>
+<dd>The URL for the server.</dd>
+<dt><tt class="docutils literal"><span class="pre">-u</span> <span class="pre">USER</span></tt>, <tt class="docutils literal"><span class="pre">--user</span> <span class="pre">USER</span></tt></dt>
+<dd>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.</dd>
+<dt><tt class="docutils literal"><span class="pre">-V</span></tt>, <tt class="docutils literal"><span class="pre">--verbose</span></tt></dt>
+<dd>Set for more verbose outputs. Use <tt class="docutils literal"><span class="pre">-VV</span></tt> for maximum verbosity.</dd>
+<dt><tt class="docutils literal"><span class="pre">-v</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt></dt>
+<dd>The version of the chef-client.</dd>
+<dt><tt class="docutils literal"><span class="pre">-y</span></tt>, <tt class="docutils literal"><span class="pre">--yes</span></tt></dt>
+<dd>Indicates that the response to all confirmation prompts will be &#8220;Yes&#8221; (and that Knife will not ask for confirmation).</dd>
+<dt><tt class="docutils literal"><span class="pre">-z</span></tt>, <tt class="docutils literal"><span class="pre">--local-mode</span></tt></dt>
+<dd>Indicates that the chef-client will be run in local mode, which allows all commands that work against the server to also work against the local chef-repo.</dd>
+</dl>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_configure.html b/distro/common/html/knife_configure.html
new file mode 100644
index 0000000000..08ea58b4e0
--- /dev/null
+++ b/distro/common/html/knife_configure.html
@@ -0,0 +1,107 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife configure &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-configure">
+<h1>knife configure<a class="headerlink" href="#knife-configure" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife configure</strong> subcommand is used to create the knife.rb and client.rb files so that they can be distributed to workstations and nodes.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax when creating a knife.rb file:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife configure <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+<p>and the following syntax when creating a client.rb file:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife configure client DIRECTORY
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options for use when configuring a knife.rb file:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--admin-client-name</span> <span class="pre">NAME</span></tt></dt>
+<dd>The name of the client, typically the name of the admin client.</dd>
+<dt><tt class="docutils literal"><span class="pre">--admin-client-key</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the private key used by the client, typically a file named <tt class="docutils literal"><span class="pre">admin.pem</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-i</span></tt>, <tt class="docutils literal"><span class="pre">--initial</span></tt></dt>
+<dd>Use to create a API client, typically an administrator client on a freshly-installed server.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span> <span class="pre">REPO</span></tt>, <tt class="docutils literal"><span class="pre">--repository</span> <span class="pre">REPO</span></tt></dt>
+<dd>The path to the chef-repo.</dd>
+<dt><tt class="docutils literal"><span class="pre">--validation-client-name</span> <span class="pre">NAME</span></tt></dt>
+<dd>The name of the validation client, typically a client named chef-validator</dd>
+<dt><tt class="docutils literal"><span class="pre">--validation-key</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the validation key used by the client, typically a file named <tt class="docutils literal"><span class="pre">validation.pem</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Configure knife.rb</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife configure
+</pre></div>
+</div>
+<p><strong>Configure client.rb</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife configure client <span class="s1">&#39;/directory&#39;</span>
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_cookbook.html b/distro/common/html/knife_cookbook.html
new file mode 100644
index 0000000000..0568be98bb
--- /dev/null
+++ b/distro/common/html/knife_cookbook.html
@@ -0,0 +1,481 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife cookbook &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-cookbook">
+<h1>knife cookbook<a class="headerlink" href="#knife-cookbook" title="Permalink to this headline">¶</a></h1>
+<p>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:</p>
+<ul class="simple">
+<li>Attribute values that are set on nodes</li>
+<li>Definitions that allow the creation of reusable collections of resources</li>
+<li>File distributions</li>
+<li>Libraries that extend the chef-client and/or provide helpers to Ruby code</li>
+<li>Recipes that specify which resources to manage and the order in which those resources will be applied</li>
+<li>Custom resources and providers</li>
+<li>Templates</li>
+<li>Versions</li>
+<li>Metadata about recipes (including dependencies), version constraints, supported platforms, and so on</li>
+</ul>
+<p>The <strong>knife cookbook</strong> subcommand is used to interact with cookbooks that are located on the server or the local chef-repo.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="bulk-delete">
+<h2>bulk delete<a class="headerlink" href="#bulk-delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">bulk</span> <span class="pre">delete</span></tt> 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 (/).</p>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook bulk delete REGEX <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-p</span></tt>, <tt class="docutils literal"><span class="pre">--purge</span></tt></dt>
+<dd>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.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Bulk delete many cookbooks</strong></p>
+<p>Use a regular expression to define the pattern used to bulk delete cookbooks:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook bulk delete <span class="s2">&quot;^[0-9]{3}$&quot;</span> -p
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="create">
+<h2>create<a class="headerlink" href="#create" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">create</span></tt> argument is used to create a new cookbook directory on the local machine, including the following directories and files:</p>
+<blockquote>
+<div><ul class="simple">
+<li>cookbook/attributes</li>
+<li>cookbook/CHANGELOG.md</li>
+<li>cookbook/definitions</li>
+<li>cookbook/files/default</li>
+<li>cookbook/libraries</li>
+<li>cookbook/metadata.rb</li>
+<li>cookbook/providers</li>
+<li>cookbook/README.md (or .rdoc)</li>
+<li>cookbook/recipes/default.rb</li>
+<li>cookbook/resources</li>
+<li>cookbook/templates/default</li>
+</ul>
+</div></blockquote>
+<p>After the cookbook is created, it can be uploaded to the server using the <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt> argument.</p>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook create COOKBOOK_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-C</span> <span class="pre">COPYRIGHT_HOLDER</span></tt>, <tt class="docutils literal"><span class="pre">--copyright</span> <span class="pre">COPYRIGHT_HOLDER</span></tt></dt>
+<dd>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 &#8220;your_company_name&#8221; will be used instead; it can be easily modified later.</dd>
+<dt><tt class="docutils literal"><span class="pre">-I</span> <span class="pre">LICENSE</span></tt>, <tt class="docutils literal"><span class="pre">--license</span> <span class="pre">LICENSE</span></tt></dt>
+<dd>The type of license under which a cookbook is distributed: <tt class="docutils literal"><span class="pre">apachev2</span></tt>, <tt class="docutils literal"><span class="pre">gplv2</span></tt>, <tt class="docutils literal"><span class="pre">gplv3</span></tt>, <tt class="docutils literal"><span class="pre">mit</span></tt>, or <tt class="docutils literal"><span class="pre">none</span></tt> (default). This option will place the appropriate license notice in the pre-created files: <tt class="docutils literal"><span class="pre">Apache</span> <span class="pre">v2.0</span></tt> (for <tt class="docutils literal"><span class="pre">apachev2</span></tt>), <tt class="docutils literal"><span class="pre">GPL</span> <span class="pre">v2</span></tt> (for <tt class="docutils literal"><span class="pre">gplv2</span></tt>), <tt class="docutils literal"><span class="pre">GPL</span> <span class="pre">v3</span></tt> (for <tt class="docutils literal"><span class="pre">gplv3</span></tt>), <tt class="docutils literal"><span class="pre">MIT</span></tt> (for <tt class="docutils literal"><span class="pre">mit</span></tt>), or <tt class="docutils literal"><span class="pre">license</span> <span class="pre">'Proprietary</span> <span class="pre">-</span> <span class="pre">All</span> <span class="pre">Rights</span> <span class="pre">Reserved</span></tt> (for <tt class="docutils literal"><span class="pre">none</span></tt>). Be aware of the licenses for files inside of a cookbook and be sure to follow any restrictions they describe.</dd>
+<dt><tt class="docutils literal"><span class="pre">-m</span> <span class="pre">EMAIL</span></tt>, <tt class="docutils literal"><span class="pre">--email</span> <span class="pre">EMAIL</span></tt></dt>
+<dd>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 &#8220;your_email&#8221; will be used instead; it can be easily modified later.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">PATH</span></tt>, <tt class="docutils literal"><span class="pre">--cookbook-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The directory in which cookbook are created. This can be a colon-separated path.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span> <span class="pre">FORMAT</span></tt>, <tt class="docutils literal"><span class="pre">--readme-format</span> <span class="pre">FORMAT</span></tt></dt>
+<dd>The document format of the readme file: <tt class="docutils literal"><span class="pre">md</span></tt> (markdown) and <tt class="docutils literal"><span class="pre">rdoc</span></tt> (Ruby docs).</dd>
+</dl>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create a cookbook</strong></p>
+<p>To create a cookbook named &#8220;my_cookbook&#8221; with copyright, email, license, and readme format options specified, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook create my_cookbook -C <span class="s2">&quot;My Name&quot;</span> -m <span class="s2">&quot;my@email.com&quot;</span> -I apachev2 -r md
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>** Creating cookbook my_cookbook
+** Creating README <span class="k">for </span>cookbook: my_cookbook
+** Creating metadata <span class="k">for </span>cookbook: my_cookbook
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="delete">
+<h2>delete<a class="headerlink" href="#delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">delete</span></tt> argument is used to delete a specified cookbook or cookbook version on the server (and not locally).</p>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook delete COOKBOOK_NAME <span class="o">[</span>COOKBOOK_VERSION<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Indicates that a cookbook and every version of that cookbook will be deleted.</dd>
+<dt><tt class="docutils literal"><span class="pre">COOKBOOK_VERSION</span></tt></dt>
+<dd>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.</dd>
+<dt><tt class="docutils literal"><span class="pre">-p</span></tt>, <tt class="docutils literal"><span class="pre">--purge</span></tt></dt>
+<dd>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.</dd>
+</dl>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Delete a cookbook</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook delete cookbook_name version
+</pre></div>
+</div>
+<p>For example:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook delete smartmon 0.8
+</pre></div>
+</div>
+<p>Type <tt class="docutils literal"><span class="pre">Y</span></tt> to confirm a deletion.</p>
+</div>
+</div>
+<div class="section" id="download">
+<h2>download<a class="headerlink" href="#download" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">download</span></tt> argument is used to download a cookbook from the server to the current working directory.</p>
+<div class="section" id="id7">
+<h3>Syntax<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook download COOKBOOK_NAME <span class="o">[</span>COOKBOOK_VERSION<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id8">
+<h3>Options<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-d</span> <span class="pre">DOWNLOAD_DIRECTORY</span></tt>, <tt class="docutils literal"><span class="pre">--dir</span> <span class="pre">DOWNLOAD_DIRECTORY</span></tt></dt>
+<dd>The directory into which a cookbook will be downloaded.</dd>
+<dt><tt class="docutils literal"><span class="pre">-f</span></tt>, <tt class="docutils literal"><span class="pre">--force</span></tt></dt>
+<dd>Indicates that an existing directory will be overwritten.</dd>
+<dt><tt class="docutils literal"><span class="pre">-N</span></tt>, <tt class="docutils literal"><span class="pre">--latest</span></tt></dt>
+<dd>Indicates that the most recent version of a cookbook will be downloaded.</dd>
+</dl>
+</div>
+<div class="section" id="id9">
+<h3>Examples<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Download a cookbook</strong></p>
+<p>To download a cookbook named &#8220;smartmon&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook download smartmon
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> 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.</p>
+<div class="section" id="id10">
+<h3>Syntax<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook list <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id11">
+<h3>Options<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Indicates that all available versions of each cookbook will be returned.</dd>
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id12">
+<h3>Examples<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of cookbooks</strong></p>
+<p>To view a list of cookbooks:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook list
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="metadata">
+<h2>metadata<a class="headerlink" href="#metadata" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">metadata</span></tt> argument is used to generate the metadata for one or more cookbooks.</p>
+<div class="section" id="id13">
+<h3>Syntax<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook metadata <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id14">
+<h3>Options<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Indicates that metadata should be generated for all cookbooks, and not just for a specified cookbook.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">PATH:PATH</span></tt>, <tt class="docutils literal"><span class="pre">--cookbook-path</span> <span class="pre">PATH:PATH</span></tt></dt>
+<dd>The directory in which cookbook are created. This can be a colon-separated path.</dd>
+</dl>
+</div>
+<div class="section" id="id15">
+<h3>Examples<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Generate metadata</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook metadata -a
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="metadata-from-file">
+<h2>metadata from file<a class="headerlink" href="#metadata-from-file" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">metadata</span> <span class="pre">from</span> <span class="pre">file</span></tt> argument is used to load the metadata for a cookbook from a file.</p>
+<div class="section" id="id16">
+<h3>Syntax<a class="headerlink" href="#id16" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook metadata from file FILE
+</pre></div>
+</div>
+</div>
+<div class="section" id="id17">
+<h3>Options<a class="headerlink" href="#id17" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id18">
+<h3>Examples<a class="headerlink" href="#id18" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View metadata</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook metadta from file /path/to/file
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="show">
+<h2>show<a class="headerlink" href="#show" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">show</span></tt> 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).</p>
+<div class="section" id="id19">
+<h3>Syntax<a class="headerlink" href="#id19" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook show COOKBOOK_NAME <span class="o">[</span>COOKBOOK_VERSION<span class="o">]</span> <span class="o">[</span>PART...<span class="o">]</span> <span class="o">[</span>FILE_NAME<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id20">
+<h3>Options<a class="headerlink" href="#id20" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">COOKBOOK_VERSION</span></tt></dt>
+<dd>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.</dd>
+<dt><tt class="docutils literal"><span class="pre">-f</span> <span class="pre">FQDN</span></tt>, <tt class="docutils literal"><span class="pre">--fqdn</span> <span class="pre">FQDN</span></tt></dt>
+<dd>The FQDN of the host.</dd>
+<dt><tt class="docutils literal"><span class="pre">FILE_NAME</span></tt></dt>
+<dd>The name of a file that is associated with a cookbook.</dd>
+<dt><tt class="docutils literal"><span class="pre">-p</span> <span class="pre">PLATFORM</span></tt>, <tt class="docutils literal"><span class="pre">--platform</span> <span class="pre">PLATFORM</span></tt></dt>
+<dd>The platform for which a cookbook is designed.</dd>
+<dt><tt class="docutils literal"><span class="pre">PART</span></tt></dt>
+<dd>The part of the cookbook to show: <tt class="docutils literal"><span class="pre">attributes</span></tt>, <tt class="docutils literal"><span class="pre">definitions</span></tt>, <tt class="docutils literal"><span class="pre">files</span></tt>, <tt class="docutils literal"><span class="pre">libraries</span></tt>, <tt class="docutils literal"><span class="pre">providers</span></tt>, <tt class="docutils literal"><span class="pre">recipes</span></tt>, <tt class="docutils literal"><span class="pre">resources</span></tt>, or <tt class="docutils literal"><span class="pre">templates</span></tt>. More than one part can be specified.</dd>
+<dt><tt class="docutils literal"><span class="pre">-V</span> <span class="pre">PLATFORM_VERSION</span></tt>, <tt class="docutils literal"><span class="pre">--platform-version</span> <span class="pre">PLATFORM_VERSION</span></tt></dt>
+<dd>The version of the platform.</dd>
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id21">
+<h3>Examples<a class="headerlink" href="#id21" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show cookbook data</strong></p>
+<p>To get the list of available versions of a cookbook named &#8220;getting-started&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook show getting-started
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>getting-started 0.3.0 0.2.0
+</pre></div>
+</div>
+<p><strong>Show cookbook versions</strong></p>
+<p>To show a list of data about a cookbook using the name of the cookbook and the version, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook show getting-started 0.3.0
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>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: <span class="o">[]</span>
+files: <span class="o">[]</span>
+frozen?: <span class="nb">false</span>
+json_class: Chef::CookbookVersion
+libraries: <span class="o">[]</span>
+</pre></div>
+</div>
+<p><strong>Show a cookbook version</strong></p>
+<p>To only view data about &#8220;templates&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook show getting-started 0.3.0 templates
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>checksum: a29d6f254577b830091f140c3a78b1fe
+name: chef-getting-started.txt.erb
+path: templates/default/chef-getting-started.txt.erb
+specificity: default
+url: https://someurlhere.com
+</pre></div>
+</div>
+<p><strong>Show cookbook data as JSON</strong></p>
+<p>To view information in JSON format, use the <tt class="docutils literal"><span class="pre">-F</span></tt> common option as part of the command like this:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role show devops -F json
+</pre></div>
+</div>
+<p>Other formats available include <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>.</p>
+</div>
+</div>
+<div class="section" id="test">
+<h2>test<a class="headerlink" href="#test" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">test</span></tt> 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 Embedded Ruby (ERB).</p>
+<div class="section" id="id22">
+<h3>Syntax<a class="headerlink" href="#id22" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook <span class="nb">test </span>COOKBOOK_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id23">
+<h3>Options<a class="headerlink" href="#id23" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Indicates that all cookbooks will be tested.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">PATH:PATH</span></tt>, <tt class="docutils literal"><span class="pre">--cookbook-path</span> <span class="pre">PATH:PATH</span></tt></dt>
+<dd>The directory in which cookbook are created. This can be a colon-separated path.</dd>
+</dl>
+</div>
+<div class="section" id="id24">
+<h3>Examples<a class="headerlink" href="#id24" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Test a cookbook</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook <span class="nb">test </span>cookbook_name
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="upload">
+<h2>upload<a class="headerlink" href="#upload" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">upload</span></tt> 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.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">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 <tt class="docutils literal"><span class="pre">File.fnmatch</span></tt> syntax).</p>
+</div>
+<div class="section" id="id25">
+<h3>Syntax<a class="headerlink" href="#id25" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook upload <span class="o">[</span>COOKBOOK_NAME...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id26">
+<h3>Options<a class="headerlink" href="#id26" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Indicates that all cookbooks will be uploaded.</dd>
+<dt><tt class="docutils literal"><span class="pre">-d</span></tt>, <tt class="docutils literal"><span class="pre">--include-dependencies</span></tt></dt>
+<dd>Indicates that when a cookbook has a dependency on one (or more) cookbooks, those cookbooks will also be uploaded.</dd>
+<dt><tt class="docutils literal"><span class="pre">--force</span></tt></dt>
+<dd>Indicates that a cookbook should be updated even if the <tt class="docutils literal"><span class="pre">--freeze</span></tt> flag has been set.</dd>
+<dt><tt class="docutils literal"><span class="pre">--freeze</span></tt></dt>
+<dd>Indicates that a cookbook cannot be modified; any changes to this cookbook must be included as a new version. Only the <tt class="docutils literal"><span class="pre">--force</span></tt> option can override this setting.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">PATH:PATH</span></tt>, <tt class="docutils literal"><span class="pre">--cookbook-path</span> <span class="pre">PATH:PATH</span></tt></dt>
+<dd>The directory in which cookbook are created. This can be a colon-separated path.</dd>
+</dl>
+</div>
+<div class="section" id="id27">
+<h3>Examples<a class="headerlink" href="#id27" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Upload a cookbook</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook upload cookbook_name
+</pre></div>
+</div>
+<p><strong>Freeze a cookbook</strong></p>
+<p>To upload a cookbook, and then prevent other users from being able to make changes to it, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook upload redis --freeze
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>Uploading redis...
+Upload completed
+</pre></div>
+</div>
+<p>If a cookbook is frozen and the <tt class="docutils literal"><span class="pre">--force</span></tt> option is not specified, Knife will return an error message similar to the following:</p>
+<div class="highlight-bash"><div class="highlight"><pre>Uploading redis...
+ERROR: Version 0.1.6 of cookbook redis is frozen. Use --force to override.
+</pre></div>
+</div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_cookbook_site.html b/distro/common/html/knife_cookbook_site.html
new file mode 100644
index 0000000000..4d34dcc998
--- /dev/null
+++ b/distro/common/html/knife_cookbook_site.html
@@ -0,0 +1,372 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife cookbook site &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-cookbook-site">
+<h1>knife cookbook site<a class="headerlink" href="#knife-cookbook-site" title="Permalink to this headline">¶</a></h1>
+<p>The Cookbooks Site API is used to provide access to the cookbooks community hosted at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>. All of the cookbooks in the community are accessible through a REST API located at <a class="reference external" href="https://cookbooks.opscode.com/api/v1/">https://cookbooks.opscode.com/api/v1/</a> by using any of the supported endpoints. In most cases, using Knife and the <strong>knife cookbook site</strong> 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.</p>
+<p>The <strong>knife cookbook site</strong> subcommand is used to interact with cookbooks that are located at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>. A user account is required for any community actions that write data to this site. The following arguments do not require a user account: <tt class="docutils literal"><span class="pre">download</span></tt>, <tt class="docutils literal"><span class="pre">search</span></tt>, <tt class="docutils literal"><span class="pre">install</span></tt>, and <tt class="docutils literal"><span class="pre">list</span></tt>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="download">
+<h2>download<a class="headerlink" href="#download" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">download</span></tt> 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 <tt class="docutils literal"><span class="pre">--force</span></tt> 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.</p>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site download COOKBOOK_NAME <span class="o">[</span>COOKBOOK_VERSION<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">COOKBOOK_VERSION</span></tt></dt>
+<dd>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.</dd>
+<dt><tt class="docutils literal"><span class="pre">-f</span></tt>, <tt class="docutils literal"><span class="pre">--force</span></tt></dt>
+<dd>Indicates that an existing directory will be overwritten.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Download a cookbook</strong></p>
+<p>To download the cookbook &#8220;getting-started&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site download getting-started
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>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
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="install">
+<h2>install<a class="headerlink" href="#install" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">install</span></tt> 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 <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a> site to install community-contributed cookbooks to the local chef-repo. Using this argument does the following:</p>
+<blockquote>
+<div><ol class="arabic simple">
+<li>A new &#8220;pristine copy&#8221; branch is created in git for tracking the upstream.</li>
+<li>All existing versions of a cookbook are removed from the branch.</li>
+<li>The cookbook is downloaded from <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a> in the tar.gz format.</li>
+<li>The downloaded cookbook is untarred and its contents are committed to git and a tag is created.</li>
+<li>The &#8220;pristine copy&#8221; branch is merged into the master branch.</li>
+</ol>
+</div></blockquote>
+<p>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.</p>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site install COOKBOOK_NAME <span class="o">[</span>COOKBOOK_VERSION<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-b</span></tt>, <tt class="docutils literal"><span class="pre">--use-current-branch</span></tt></dt>
+<dd>Indicates that the current branch will be used.</dd>
+<dt><tt class="docutils literal"><span class="pre">-B</span> <span class="pre">BRANCH</span></tt>, <tt class="docutils literal"><span class="pre">--branch</span> <span class="pre">BRANCH</span></tt></dt>
+<dd>The name of the default branch. This will default to the master branch.</dd>
+<dt><tt class="docutils literal"><span class="pre">COOKBOOK_VERSION</span></tt></dt>
+<dd>The version of the cookbook to be installed. If a version is not specified, the most recent version of the cookbook will be installed.</dd>
+<dt><tt class="docutils literal"><span class="pre">-D</span></tt>, <tt class="docutils literal"><span class="pre">--skip-dependencies</span></tt></dt>
+<dd>Indicates that all cookbooks to which the installed cookbook has a dependency will not be installed.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">PATH:PATH</span></tt>, <tt class="docutils literal"><span class="pre">--cookbook-path</span> <span class="pre">PATH:PATH</span></tt></dt>
+<dd>The directory in which cookbook are created. This can be a colon-separated path.</dd>
+</dl>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Install a cookbook</strong></p>
+<p>To install the cookbook &#8220;getting-started&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site install getting-started
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>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<span class="o">(</span>+<span class="o">)</span>, 0 deletions<span class="o">(</span>-<span class="o">)</span>
+ 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
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> argument is used to view a list of cookbooks that are currently available at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>.</p>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site list
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of cookbooks</strong></p>
+<p>To view a list of cookbooks at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a> server, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site list
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-python"><pre>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...]</pre>
+</div>
+</div>
+</div>
+<div class="section" id="search">
+<h2>search<a class="headerlink" href="#search" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">search</span></tt> argument is used to search for a cookbook at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>. A search query is used to return a list of cookbooks at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a> and uses the same syntax as the <strong>knife search</strong> sub-command.</p>
+<div class="section" id="id7">
+<h3>Syntax<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site search SEARCH_QUERY <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id8">
+<h3>Options<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id9">
+<h3>Examples<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Search for cookbooks</strong></p>
+<p>To search for all of the cookbooks that can be used with Apache, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site search apache*
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>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
+<span class="o">[</span>...truncated...<span class="o">]</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="share">
+<h2>share<a class="headerlink" href="#share" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">share</span></tt> argument is used to add a cookbook to <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>. This action will require a user account and a certificate for <a class="reference external" href="http://community.opscode.com">http://community.opscode.com</a>. 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 <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>, then only an owner or maintainer of that cookbook can make updates.</p>
+<div class="section" id="id10">
+<h3>Syntax<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site share COOKBOOK_NAME CATEGORY <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id11">
+<h3>Options<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">CATEGORY</span></tt></dt>
+<dd>The cookbook category: <tt class="docutils literal"><span class="pre">Databases</span></tt>, <tt class="docutils literal"><span class="pre">Web</span> <span class="pre">Servers</span></tt>, <tt class="docutils literal"><span class="pre">Process</span> <span class="pre">Management</span></tt>, <tt class="docutils literal"><span class="pre">Monitoring</span> <span class="pre">and</span> <span class="pre">Trending</span></tt>, <tt class="docutils literal"><span class="pre">Programming</span> <span class="pre">Languages</span></tt>, <tt class="docutils literal"><span class="pre">Package</span> <span class="pre">Management</span></tt>, <tt class="docutils literal"><span class="pre">Applications</span></tt>, <tt class="docutils literal"><span class="pre">Networking</span></tt>, <tt class="docutils literal"><span class="pre">Operations</span> <span class="pre">Systems</span> <span class="pre">and</span> <span class="pre">Virtualization</span></tt>, <tt class="docutils literal"><span class="pre">Utilities</span></tt>, or <tt class="docutils literal"><span class="pre">Other</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">PATH:PATH</span></tt>, <tt class="docutils literal"><span class="pre">--cookbook-path</span> <span class="pre">PATH:PATH</span></tt></dt>
+<dd>The directory in which cookbook are created. This can be a colon-separated path.</dd>
+</dl>
+</div>
+<div class="section" id="id12">
+<h3>Examples<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Share a cookbook</strong></p>
+<p>To share a cookbook named &#8220;apache2&#8221;:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site share <span class="s2">&quot;apache2&quot;</span> <span class="s2">&quot;Web Servers&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="show">
+<h2>show<a class="headerlink" href="#show" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">show</span></tt> argument is used to view information about a cookbook on <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>.</p>
+<div class="section" id="id13">
+<h3>Syntax<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site show COOKBOOK_NAME <span class="o">[</span>COOKBOOK_VERSION<span class="o">]</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id14">
+<h3>Options<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">COOKBOOK_VERSION</span></tt></dt>
+<dd>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.</dd>
+</dl>
+</div>
+<div class="section" id="id15">
+<h3>Examples<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show cookbook data</strong></p>
+<p>To show the details for a cookbook named &#8220;haproxy&#8221;:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site show haproxy
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>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
+</pre></div>
+</div>
+<p><strong>Show cookbook data as JSON</strong></p>
+<p>To view information in JSON format, use the <tt class="docutils literal"><span class="pre">-F</span></tt> common option as part of the command like this:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role show devops -F json
+</pre></div>
+</div>
+<p>Other formats available include <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>.</p>
+</div>
+</div>
+<div class="section" id="unshare">
+<h2>unshare<a class="headerlink" href="#unshare" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">unshare</span></tt> argument is used to stop the sharing of a cookbook at <a class="reference external" href="https://cookbooks.opscode.com">https://cookbooks.opscode.com</a>. Only the maintainer of a cookbook may perform this action.</p>
+<div class="section" id="id16">
+<h3>Syntax<a class="headerlink" href="#id16" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site unshare COOKBOOK_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id17">
+<h3>Options<a class="headerlink" href="#id17" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id18">
+<h3>Examples<a class="headerlink" href="#id18" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Unshare a cookbook</strong></p>
+<p>To unshare a cookbook named &#8220;getting-started&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife cookbook site unshare getting-started
+</pre></div>
+</div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_data_bag.html b/distro/common/html/knife_data_bag.html
new file mode 100644
index 0000000000..4e888c8963
--- /dev/null
+++ b/distro/common/html/knife_data_bag.html
@@ -0,0 +1,359 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife data bag &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-data-bag">
+<h1>knife data bag<a class="headerlink" href="#knife-data-bag" title="Permalink to this headline">¶</a></h1>
+<p>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).</p>
+<p>A data bag item may be encrypted using <a class="reference external" href="https://en.wikipedia.org/wiki/Symmetric-key_algorithm">shared secret encryption</a>. This allows each data bag item 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). Each data bag item may be encrypted individually; if a data bag contains multiple encrypted data bag items, these data bag items are not required to share the same encryption keys.</p>
+<p>The <strong>knife data bag</strong> subcommand is used to manage arbitrary stores of globally available JSON data.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="create">
+<h2>create<a class="headerlink" href="#create" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">create</span></tt> argument is used to add a data bag to the server.</p>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag create DATA_BAG_NAME <span class="o">[</span>DATA_BAG_ITEM<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">DATA_BAG_ITEM</span></tt></dt>
+<dd>The name of a specific item within a data bag.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
+<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
+<dd>The path to the file that contains the encryption key.</dd>
+</dl>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">For encrypted data bag items, use <em>either</em> <tt class="docutils literal"><span class="pre">--secret</span></tt> or <tt class="docutils literal"><span class="pre">--secret-file</span></tt>, not both.</p>
+</div>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create a data bag</strong></p>
+<p>To create a data bag named &#8220;admins&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag create admins
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-bash"><div class="highlight"><pre>Created data_bag<span class="o">[</span>admins<span class="o">]</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="delete">
+<h2>delete<a class="headerlink" href="#delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">delete</span></tt> argument is used to delete a data bag or a data bag item from a server.</p>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag delete DATA_BAG_NAME <span class="o">[</span>DATA_BAG_ITEM<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">DATA_BAG_ITEM</span></tt></dt>
+<dd>The name of a specific item within a data bag.</dd>
+</dl>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Delete a data bag</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag delete data_bag_name
+</pre></div>
+</div>
+<p><strong>Delete a data bag item</strong></p>
+<p>To delete an item named &#8220;charlie&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag delete admins charlie
+</pre></div>
+</div>
+<p>Type <tt class="docutils literal"><span class="pre">Y</span></tt> to confirm a deletion.</p>
+</div>
+</div>
+<div class="section" id="edit">
+<h2>edit<a class="headerlink" href="#edit" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">edit</span></tt> 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.</p>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag edit DATA_BAG_NAME <span class="o">[</span>DATA_BAG_ITEM<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">DATA_BAG_ITEM</span></tt></dt>
+<dd>The name of a specific item within a data bag.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
+<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
+<dd>The path to the file that contains the encryption key.</dd>
+</dl>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">For encrypted data bag items, use <em>either</em> <tt class="docutils literal"><span class="pre">--secret</span></tt> or <tt class="docutils literal"><span class="pre">--secret-file</span></tt>, not both.</p>
+</div>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Edit a data bag</strong></p>
+<p>To edit the contents of a data bag, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag edit admins
+</pre></div>
+</div>
+<p><strong>Edit a data bag item</strong></p>
+<p>To edit an item named &#8220;charlie&#8221; that is contained in a data bag named &#8220;admins&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag edit admins charlie
+</pre></div>
+</div>
+<p>to open the $EDITOR. Once opened, you can update the data before saving it to the server. For example, by changing:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="o">{</span>
+ <span class="s2">&quot;id&quot;</span>: <span class="s2">&quot;charlie&quot;</span>
+<span class="o">}</span>
+</pre></div>
+</div>
+<p>to:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;id&quot;</span><span class="o">:</span> <span class="s2">&quot;charlie&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;uid&quot;</span><span class="o">:</span> <span class="mi">1005</span><span class="p">,</span>
+ <span class="s2">&quot;gid&quot;</span><span class="o">:</span><span class="s2">&quot;ops&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;shell&quot;</span><span class="o">:</span><span class="s2">&quot;/bin/zsh&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;comment&quot;</span><span class="o">:</span><span class="s2">&quot;Crazy Charlie&quot;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="from-file">
+<h2>from file<a class="headerlink" href="#from-file" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">from</span> <span class="pre">file</span></tt> 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:</p>
+<ul class="simple">
+<li>the name of a data bag</li>
+<li>a relative or absolute path to a file</li>
+</ul>
+<p>If the name of a data bag is specified, Knife will search for the data bag in <tt class="docutils literal"><span class="pre">./data_bags/bag_name/file</span></tt>. 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.</p>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">A chef-client must be version 11.6 (or higher) when using the <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">from</span> <span class="pre">file</span></tt> argument with the Enterprise Chef or Open Source Chef version 11 servers.</p>
+</div>
+<div class="section" id="id7">
+<h3>Syntax<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag from file DATA_BAG_NAME_or_PATH
+</pre></div>
+</div>
+</div>
+<div class="section" id="id8">
+<h3>Options<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Indicates that all data bags found at the specified path will be uploaded.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
+<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
+<dd>The path to the file that contains the encryption key.</dd>
+</dl>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">For encrypted data bag items, use <em>either</em> <tt class="docutils literal"><span class="pre">--secret</span></tt> or <tt class="docutils literal"><span class="pre">--secret-file</span></tt>, not both.</p>
+</div>
+</div>
+<div class="section" id="id9">
+<h3>Examples<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create a data bag from a file</strong></p>
+<p>To create a data bag on the server from a file:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag from file <span class="s2">&quot;path to JSON file&quot;</span>
+</pre></div>
+</div>
+<p><strong>Create an encrypted data bag from a file</strong></p>
+<p>To create a data bag named &#8220;devops_data&#8221; that contains encrypted data, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag from file devops_data --secret-file <span class="s2">&quot;path to decryption file&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> argument is used to view a list of data bags that are currently available on the server.</p>
+<div class="section" id="id10">
+<h3>Syntax<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag list
+</pre></div>
+</div>
+</div>
+<div class="section" id="id11">
+<h3>Options<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id12">
+<h3>Examples<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of data bags</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag list
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="show">
+<h2>show<a class="headerlink" href="#show" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">show</span></tt> argument is used to view the contents of a data bag.</p>
+<div class="section" id="id13">
+<h3>Syntax<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag show DATA_BAG_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id14">
+<h3>Options<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">DATA_BAG_ITEM</span></tt></dt>
+<dd>The name of a specific item within a data bag.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
+<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
+<dd>The path to the file that contains the encryption key.</dd>
+</dl>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">For encrypted data bag items, use <em>either</em> <tt class="docutils literal"><span class="pre">--secret</span></tt> or <tt class="docutils literal"><span class="pre">--secret-file</span></tt>, not both.</p>
+</div>
+</div>
+<div class="section" id="id15">
+<h3>Examples<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show a data bag</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag show admins
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>charlie
+</pre></div>
+</div>
+<p><strong>Show a data bag item</strong></p>
+<p>To show the contents of a specific item within data bag, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag show admins charlie
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-bash"><div class="highlight"><pre>comment: Crazy Charlie
+gid: ops
+id: charlie
+shell: /bin/zsh
+uid: 1005
+</pre></div>
+</div>
+<p><strong>Show a data bag, encrypted</strong></p>
+<p>To show the contents of a data bag named &#8220;passwords&#8221; with an item that contains encrypted data named &#8220;mysql&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag show passwords mysql
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-javascript"><pre>## sample:
+{
+ "id": "mysql",
+ "pass": "trywgFA6R70NO28PNhMpGhEvKBZuxouemnbnAUQsUyo=\n",
+ "user": "e/p+8WJYVHY9fHcEgAAReg==\n"
+}</pre>
+</div>
+<p><strong>Show a data bag, decrypted</strong></p>
+<p>To show the decrypted contents of the same data bag, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag show --secret-file /path/to/decryption/file passwords mysql
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-javascript"><pre>## sample:
+{
+ "id": "mysql",
+ "pass": "thesecret123",
+ "user": "fred"
+}</pre>
+</div>
+<p><strong>Show a data bag as JSON</strong></p>
+<p>To view information in JSON format, use the <tt class="docutils literal"><span class="pre">-F</span></tt> common option as part of the command like this:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag show admins -F json
+</pre></div>
+</div>
+<p>Other formats available include <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>.</p>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_delete.html b/distro/common/html/knife_delete.html
new file mode 100644
index 0000000000..c9424d04b2
--- /dev/null
+++ b/distro/common/html/knife_delete.html
@@ -0,0 +1,95 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife delete &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-delete">
+<h1>knife delete<a class="headerlink" href="#knife-delete" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife delete</strong> subcommand is used to delete an object from a server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">delete</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">delete</span></tt>, but with a single verb (and a single action).</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife delete <span class="o">[</span>PATTERN...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--both</span></tt></dt>
+<dd>Indicates that both local and remote copies of an object should be deleted. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--local</span></tt></dt>
+<dd>Indicates that only the local copy of an object should be deleted. (The remote copy will not be deleted.) Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span></tt>, <tt class="docutils literal"><span class="pre">--[no-]recurse</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--recurse</span></tt> to delete directories recursively. Default: <tt class="docutils literal"><span class="pre">--no-recurse</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default: <tt class="docutils literal"><span class="pre">everything</span></tt> / <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>None.</p>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_deps.html b/distro/common/html/knife_deps.html
new file mode 100644
index 0000000000..c9bbdcdd04
--- /dev/null
+++ b/distro/common/html/knife_deps.html
@@ -0,0 +1,145 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife deps &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-deps">
+<h1>knife deps<a class="headerlink" href="#knife-deps" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife deps</strong> subcommand is used to identify dependencies for a node, role, or cookbook.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]recurse</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--recurse</span></tt> to list dependencies recursively. This option can only be used when <tt class="docutils literal"><span class="pre">--tree</span></tt> is set to <tt class="docutils literal"><span class="pre">true</span></tt>. Default: <tt class="docutils literal"><span class="pre">--no-recurse</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--remote</span></tt></dt>
+<dd>Indicates that dependencies will be determined from objects located on the server instead of the local chef-repo. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default: <tt class="docutils literal"><span class="pre">everything</span></tt> / <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--tree</span></tt></dt>
+<dd>Indicates that dependencies are shown in a visual tree structure (including duplicates, if they exist). Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Find dependencies for a node</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps nodes/node_name.json
+</pre></div>
+</div>
+<p><strong>Find dependencies for a role</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps roles/role_name.json
+</pre></div>
+</div>
+<p><strong>Find dependencies for a cookbook</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps cookbooks/cookbook_name.json
+</pre></div>
+</div>
+<p><strong>Find dependencies for an environment</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps environments/environment_name.json
+</pre></div>
+</div>
+<p><strong>Find dependencies for a combination of nodes, roles, and so on</strong></p>
+<p>To find the dependencies for a combination of nodes, cookbooks, roles, and/or environments:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps cookbooks/git.json cookbooks/github.json roles/base.json environments/desert.json nodes/mynode.json
+</pre></div>
+</div>
+<p><strong>Use a wildcard</strong></p>
+<p>A wildcard can be used to return all of the child nodes. For example, all of the environments:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps environments/*.json
+</pre></div>
+</div>
+<p><strong>Return as tree</strong></p>
+<p>Use the <tt class="docutils literal"><span class="pre">--tree</span></tt> option to view the results with structure:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps roles/webserver.json
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>roles/webserver.json
+ roles/base.json
+ cookbooks/github
+ cookbooks/git
+ cookbooks/users
+ cookbooks/apache2
+</pre></div>
+</div>
+<p><strong>Pass knife deps output to knife upload</strong></p>
+<p>The output of <strong>knife deps</strong> can be passed to <strong>knife upload</strong>:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload <span class="sb">`</span>knife deps nodes/*.json
+</pre></div>
+</div>
+<p><strong>Pass knife deps output to knife xargs</strong></p>
+<p>The output of <strong>knife deps</strong> can be passed to <strong>knife xargs</strong>:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps nodes/*.json | xargs knife upload
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_diff.html b/distro/common/html/knife_diff.html
new file mode 100644
index 0000000000..db0d7c8546
--- /dev/null
+++ b/distro/common/html/knife_diff.html
@@ -0,0 +1,125 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife diff &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-diff">
+<h1>knife diff<a class="headerlink" href="#knife-diff" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife diff</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt> and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt> subcommands, or to ensure that certain files in multiple production environments are the same. This subcommand is similar to the <tt class="docutils literal"><span class="pre">git</span> <span class="pre">diff</span></tt> command that can be used to diff what is in the chef-repo with what is synced to a git repository.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife diff <span class="o">[</span>PATTERN...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--cookbook-version</span> <span class="pre">VERSION</span></tt></dt>
+<dd>The version of a cookbook to be downloaded.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--diff-filter=[(A|D|M|T)...[*]]</span></tt></dt>
+<dd>Indicates that files will be selected that have been added (<tt class="docutils literal"><span class="pre">A</span></tt>), deleted (<tt class="docutils literal"><span class="pre">D</span></tt>), modified (<tt class="docutils literal"><span class="pre">M</span></tt>), and/or have had their type changed (<tt class="docutils literal"><span class="pre">T</span></tt>). Any combination of filter characters may be used, including no filter characters. Use <tt class="docutils literal"><span class="pre">*</span></tt> to select all paths if a file matches other criteria in the comparison. Default value: <tt class="docutils literal"><span class="pre">nil</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--name-only</span></tt></dt>
+<dd>Indicates that only the names of modified files will be shown.</dd>
+<dt><tt class="docutils literal"><span class="pre">--name-status</span></tt></dt>
+<dd>Indicates that only the names of files with a status of <tt class="docutils literal"><span class="pre">Added</span></tt>, <tt class="docutils literal"><span class="pre">Deleted</span></tt>, <tt class="docutils literal"><span class="pre">Modified</span></tt>, or <tt class="docutils literal"><span class="pre">Type</span> <span class="pre">Changed</span></tt> will be shown.</dd>
+<dt><tt class="docutils literal"><span class="pre">--no-recurse</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--no-recurse</span></tt> to disable listing a directory recursively. Default: <tt class="docutils literal"><span class="pre">--recurse</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default: <tt class="docutils literal"><span class="pre">everything</span></tt> / <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Compare files that contain JSON data</strong></p>
+<p>To compare the &#8220;base.json&#8221; role to a &#8220;webserver.json&#8221; role, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife diff roles/base.json roles/webserver.json
+</pre></div>
+</div>
+<p><strong>Compare the chef-repo and the server</strong></p>
+<p>To compare the differences between the local chef-repo and the files that are on the server, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife diff
+</pre></div>
+</div>
+<p><strong>Compare, then return results</strong></p>
+<p>To diff a node named <tt class="docutils literal"><span class="pre">node-lb</span></tt> and then only return files that have been added, deleted, modified, or changed, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife diff --name-status node-lb
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>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
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_download.html b/distro/common/html/knife_download.html
new file mode 100644
index 0000000000..f77c5db277
--- /dev/null
+++ b/distro/common/html/knife_download.html
@@ -0,0 +1,147 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife download &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-download">
+<h1>knife download<a class="headerlink" href="#knife-download" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife download</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">diff</span></tt>, which can be used to see exactly what changes will be downloaded, and then <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt>, which does the opposite of <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt>.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download <span class="o">[</span>PATTERN...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--cookbook-version</span> <span class="pre">VERSION</span></tt></dt>
+<dd>The version of a cookbook to be downloaded.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]force</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--force</span></tt> 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: <tt class="docutils literal"><span class="pre">--no-force</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-n</span></tt>, <tt class="docutils literal"><span class="pre">--dry-run</span></tt></dt>
+<dd>Indicates that no action is taken and that results are only printed out. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]diff</span></tt></dt>
+<dd>Indicates that only new and modified files will be downloaded. Set to <tt class="docutils literal"><span class="pre">false</span></tt> to download all files. Default: <tt class="docutils literal"><span class="pre">--diff</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]recurse</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--no-recurse</span></tt> to disable downloading a directory recursively. Default: <tt class="docutils literal"><span class="pre">--recurse</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]purge</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--purge</span></tt> 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: <tt class="docutils literal"><span class="pre">--no-purge</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default: <tt class="docutils literal"><span class="pre">everything</span></tt> / <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Download the entire chef-repo</strong></p>
+<p>To download the entire chef-repo from the server, browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download /
+</pre></div>
+</div>
+<p><strong>Download the /cookbooks directory</strong></p>
+<p>To download the <tt class="docutils literal"><span class="pre">cookbooks/</span></tt> directory from the server, browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download cookbooks
+</pre></div>
+</div>
+<p>or from anywhere in the chef-repo, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download /cookbooks
+</pre></div>
+</div>
+<p><strong>Download the /environments directory</strong></p>
+<p>To download the <tt class="docutils literal"><span class="pre">environments/</span></tt> directory from the server, browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download environments
+</pre></div>
+</div>
+<p>or from anywhere in the chef-repo, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download /environments
+</pre></div>
+</div>
+<p><strong>Download an environment</strong></p>
+<p>To download an environment named &#8220;production&#8221; from the server, browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download environments/production.json
+</pre></div>
+</div>
+<p>or from the <tt class="docutils literal"><span class="pre">environments/</span></tt> directory, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download production.json
+</pre></div>
+</div>
+<p><strong>Download the /roles directory</strong></p>
+<p>To download the <tt class="docutils literal"><span class="pre">roles/</span></tt> directory from the server, browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download roles
+</pre></div>
+</div>
+<p>or from anywhere in the chef-repo, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife download /roles
+</pre></div>
+</div>
+<p><strong>Download cookbooks and roles</strong></p>
+<p>To download all cookbooks that start with &#8220;apache&#8221; and belong to the &#8220;webserver&#8221; role, browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span> knife download cookbooks/apache<span class="se">\*</span> roles/webserver.json
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_edit.html b/distro/common/html/knife_edit.html
new file mode 100644
index 0000000000..0c9728bd9d
--- /dev/null
+++ b/distro/common/html/knife_edit.html
@@ -0,0 +1,91 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife edit &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-edit">
+<h1>knife edit<a class="headerlink" href="#knife-edit" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife edit</strong> subcommand is used to edit objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">edit</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">edit</span></tt>, but with a single verb (and a single action).</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife edit <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--local</span></tt></dt>
+<dd>Use to show files in the local chef-repo instead of a remote location. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default: <tt class="docutils literal"><span class="pre">everything</span></tt> / <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>None.</p>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_environment.html b/distro/common/html/knife_environment.html
new file mode 100644
index 0000000000..5fcc34d4f6
--- /dev/null
+++ b/distro/common/html/knife_environment.html
@@ -0,0 +1,328 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife environment &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-environment">
+<h1>knife environment<a class="headerlink" href="#knife-environment" title="Permalink to this headline">¶</a></h1>
+<p>An environment is a way to map an organization&#8217;s real-life workflow to what can be configured and managed when using server. Every organization begins with a single environment called the <tt class="docutils literal"><span class="pre">_default</span></tt> environment, which cannot be modified (or deleted). Additional environments can be created to reflect each organization&#8217;s patterns and workflow. For example, creating <tt class="docutils literal"><span class="pre">production</span></tt>, <tt class="docutils literal"><span class="pre">staging</span></tt>, <tt class="docutils literal"><span class="pre">testing</span></tt>, and <tt class="docutils literal"><span class="pre">development</span></tt> environments. Generally, an environment is also associated with one (or more) cookbook versions.</p>
+<p>The <strong>knife environment</strong> subcommand is used to manage environments within a single organization on the server.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="compare">
+<h2>compare<a class="headerlink" href="#compare" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">compare</span></tt> argument is used to compare the cookbook version constraints that are set on one (or more) environments.</p>
+<p><strong>Syntax</strong></p>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment compare <span class="o">[</span>ENVIRONMENT_NAME...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+<p><strong>Options</strong></p>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Indicates that all environments found at the specified path will be uploaded.</dd>
+<dt><tt class="docutils literal"><span class="pre">-m</span></tt>, <tt class="docutils literal"><span class="pre">--mismatch</span></tt></dt>
+<dd>Use to show only matching versions.</dd>
+</dl>
+<p><strong>Example</strong></p>
+<p>To compare cookbook versions for a single environment:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment compare development
+</pre></div>
+</div>
+<p>to return something similar to:</p>
+<div class="highlight-bash"><div class="highlight"><pre> development
+apache 2.3.1
+windows 4.1.2
+</pre></div>
+</div>
+<p>To compare cookbook versions for multiple environments:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment compare development staging
+</pre></div>
+</div>
+<p>to return something similar to:</p>
+<div class="highlight-bash"><div class="highlight"><pre> development staging
+apache 2.3.1 1.2.2
+windows 4.1.2 1.0.0
+postgresql 1.0.0 1.0.0
+</pre></div>
+</div>
+<p>To compare all cookbook versions for all environments:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment compare --all
+</pre></div>
+</div>
+<p>to return something similar to:</p>
+<div class="highlight-bash"><div class="highlight"><pre> staging development
+<span class="nb">ulimit </span>latest latest
+redisio latest latest
+journly latest latest
+aws latest latest
+<span class="nb">test </span>latest latest
+unicorn latest latest
+sensu latest latest
+runit latest latest
+templater latest latest
+powershell latest latest
+openssl latest latest
+rbenv latest latest
+rabbitmq latest latest
+postgresql latest latest
+mysql latest latest
+ohai latest latest
+git latest latest
+erlang latest latest
+ssh_known_hosts latest latest
+nginx latest latest
+database latest latest
+yum latest latest
+xfs latest latest
+apt latest latest
+dmg latest latest
+chef_handler latest latest
+windows 1.0.0 4.1.2
+</pre></div>
+</div>
+</div>
+<div class="section" id="create">
+<h2>create<a class="headerlink" href="#create" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">create</span></tt> 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 <tt class="docutils literal"><span class="pre">ENVIRONMENT</span></tt> description field (unless a description is specified as part of the command). When finished, Knife will add the environment to the server.</p>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment create ENVIRONMENT_NAME -d DESCRIPTION
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-d</span> <span class="pre">DESCRIPTION</span></tt>, <tt class="docutils literal"><span class="pre">--description</span> <span class="pre">DESCRIPTION</span></tt></dt>
+<dd>The description of the environment. This value will populate the description field for the environment on the server.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create an environment</strong></p>
+<p>To create an environment named &#8220;dev&#8221; with a description of &#8220;The development environment.&#8221;:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment create dev -d <span class="s2">&quot;The development environment.&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="delete">
+<h2>delete<a class="headerlink" href="#delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">delete</span></tt> argument is used to delete an environment from a server.</p>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment delete ENVIRONMENT_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Delete an environment</strong></p>
+<p>To delete an environment named &#8220;dev&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment delete dev
+</pre></div>
+</div>
+<p>Type <tt class="docutils literal"><span class="pre">Y</span></tt> to confirm a deletion.</p>
+</div>
+</div>
+<div class="section" id="edit">
+<h2>edit<a class="headerlink" href="#edit" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">edit</span></tt> argument is used to edit the attributes of an environment. When this argument is run, Knife will open $EDITOR to enable editing of <tt class="docutils literal"><span class="pre">ENVIRONMENT</span></tt> attributes. When finished, Knife will update the server with those changes.</p>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment edit ENVIRONMENT_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Edit an environment</strong></p>
+<p>To edit an environment named &#8220;devops&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment edit devops
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="from-file">
+<h2>from file<a class="headerlink" href="#from-file" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">from</span> <span class="pre">file</span></tt> argument is used to add or update an environment using a JSON or Ruby DSL description. It must be run with the <tt class="docutils literal"><span class="pre">create</span></tt> or <tt class="docutils literal"><span class="pre">edit</span></tt> arguments.</p>
+<div class="section" id="id7">
+<h3>Syntax<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment <span class="o">[</span>create | edit<span class="o">]</span> from file FILE <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id8">
+<h3>Options<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Indicates that all environments found at the specified path will be uploaded.</dd>
+</dl>
+</div>
+<div class="section" id="id9">
+<h3>Examples<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create an environment from a JSON file</strong></p>
+<p>To add an environment using data contained in a JSON file:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment create devops from file <span class="s2">&quot;path to JSON file&quot;</span>
+</pre></div>
+</div>
+<p>or:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment edit devops from file <span class="s2">&quot;path to JSON file&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> argument is used to list all of the environments that are currently available on the server.</p>
+<div class="section" id="id10">
+<h3>Syntax<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment list -w
+</pre></div>
+</div>
+</div>
+<div class="section" id="id11">
+<h3>Options<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id12">
+<h3>Examples<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of environments</strong></p>
+<p>To view a list of environments:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment list -w
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="show">
+<h2>show<a class="headerlink" href="#show" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">show</span></tt> argument is used to display information about the specified environment.</p>
+<div class="section" id="id13">
+<h3>Syntax<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment show ENVIRONMENT_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id14">
+<h3>Options<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">ATTR</span></tt></dt>
+<dd>The attribute (or attributes) to show.</dd>
+</dl>
+</div>
+<div class="section" id="id15">
+<h3>Examples<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show environments</strong></p>
+<p>To view information about the &#8220;dev&#8221; environment enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife environment show dev
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-bash"><div class="highlight"><pre>% knife environment show dev
+chef_type: environment
+cookbook_versions:
+default_attributes:
+description:
+json_class: Chef::Environment
+name: dev
+override_attributes:
+
+<span class="se">\\</span>
+<span class="se">\\</span>
+<span class="se">\\</span>
+<span class="se">\\</span>
+</pre></div>
+</div>
+<p><strong>Show environments as JSON</strong></p>
+<p>To view information in JSON format, use the <tt class="docutils literal"><span class="pre">-F</span></tt> common option as part of the command like this:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role show devops -F json
+</pre></div>
+</div>
+<p>Other formats available include <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>.</p>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_exec.html b/distro/common/html/knife_exec.html
new file mode 100644
index 0000000000..e458205356
--- /dev/null
+++ b/distro/common/html/knife_exec.html
@@ -0,0 +1,222 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife exec &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-exec">
+<h1>knife exec<a class="headerlink" href="#knife-exec" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife exec</strong> 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.</p>
+<div class="section" id="authenticated-api-requests">
+<h2>Authenticated API Requests<a class="headerlink" href="#authenticated-api-requests" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">exec</span></tt> subcommand can be used to make authenticated API requests to the server using the following methods:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="13%" />
+<col width="88%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Method</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td><tt class="docutils literal"><span class="pre">api.delete</span></tt></td>
+<td>Use to delete an object from the server.</td>
+</tr>
+<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">api.get</span></tt></td>
+<td>Use to get the details of an object on the server.</td>
+</tr>
+<tr class="row-even"><td><tt class="docutils literal"><span class="pre">api.post</span></tt></td>
+<td>Use to add an object to the server.</td>
+</tr>
+<tr class="row-odd"><td><tt class="docutils literal"><span class="pre">api.put</span></tt></td>
+<td>Use to update an object on the server.</td>
+</tr>
+</tbody>
+</table>
+<p>These methods are used with the <tt class="docutils literal"><span class="pre">-E</span></tt> option, which executes that string locally on the workstation using chef-shell. These methods have the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec</span> -E <span class="s1">&#39;api.method(/endpoint)&#39;</span>
+</pre></div>
+</div>
+<p>where:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">api.method</span></tt> is the corresponding authentication method &#8212; <tt class="docutils literal"><span class="pre">api.delete</span></tt>, <tt class="docutils literal"><span class="pre">api.get</span></tt>, <tt class="docutils literal"><span class="pre">api.post</span></tt>, or <tt class="docutils literal"><span class="pre">api.put</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">/endpoint</span></tt> is an endpoint in the Chef Server API</li>
+</ul>
+<p>For example, to get the data for a node named &#8220;Example_Node&#8221;:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec</span> -E <span class="s1">&#39;puts api.get(&quot;/nodes/Example_Node&quot;)&#39;</span>
+</pre></div>
+</div>
+<p>and to ensure that the output is visible in the console, add the <tt class="docutils literal"><span class="pre">puts</span></tt> in front of the API authorization request:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec</span> -E <span class="s1">&#39;puts api.get(&quot;/nodes/Example_Node&quot;)&#39;</span>
+</pre></div>
+</div>
+<p>where <tt class="docutils literal"><span class="pre">puts</span></tt> is the shorter version of the <tt class="docutils literal"><span class="pre">$stdout.puts</span></tt> predefined variable in Ruby.</p>
+<p>The following example shows how to add a client named &#8220;IBM305RAMAC&#8221; and the <tt class="docutils literal"><span class="pre">/clients</span></tt> endpoint, and then return the private key for that user in the console:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ client_desc</span> <span class="o">=</span> <span class="o">{</span>
+ <span class="s2">&quot;name&quot;</span> <span class="o">=</span>&gt; <span class="s2">&quot;IBM305RAMAC&quot;</span>,
+ <span class="s2">&quot;admin&quot;</span> <span class="o">=</span>&gt; <span class="nb">false</span>
+ <span class="o">}</span>
+
+ <span class="nv">new_client</span> <span class="o">=</span> api.post<span class="o">(</span><span class="s2">&quot;/clients&quot;</span>, client_desc<span class="o">)</span>
+ puts new_client<span class="o">[</span><span class="s2">&quot;private_key&quot;</span><span class="o">]</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="ruby-scripts">
+<h2>Ruby Scripts<a class="headerlink" href="#ruby-scripts" title="Permalink to this headline">¶</a></h2>
+<p>For Ruby scripts that will be run using the <tt class="docutils literal"><span class="pre">exec</span></tt> subcommand, note the following:</p>
+<blockquote>
+<div><ul class="simple">
+<li>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).</li>
+<li>Shell commands will be run from a management workstation. For example, something like <tt class="docutils literal"><span class="pre">%x[ls</span> <span class="pre">-lash</span> <span class="pre">/opt/only-on-a-node]</span></tt> would give you the directory listing for the &#8220;opt/only-on-a-node&#8221; directory or a &#8220;No such file or directory&#8221; error if the file does not already exist locally.</li>
+<li>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.</li>
+</ul>
+</div></blockquote>
+</div>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec </span>SCRIPT <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-E</span> <span class="pre">CODE</span></tt>, <tt class="docutils literal"><span class="pre">--exec</span> <span class="pre">CODE</span></tt></dt>
+<dd>A string of code that will be executed.</dd>
+<dt><tt class="docutils literal"><span class="pre">-p</span> <span class="pre">PATH:PATH</span></tt>, <tt class="docutils literal"><span class="pre">--script-path</span> <span class="pre">PATH:PATH</span></tt></dt>
+<dd>A colon-separated path at which Ruby scripts are located.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Run Ruby scripts</strong></p>
+<p>There are three ways to use <strong>knife exec</strong> to run Ruby script files. For example:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec</span> /path/to/script_file
+</pre></div>
+</div>
+<p>Or:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec</span> -E <span class="s1">&#39;RUBY CODE&#39;</span>
+</pre></div>
+</div>
+<p>Or:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec</span>
+RUBY CODE
+^D
+</pre></div>
+</div>
+<p><strong>Chef Knife status</strong></p>
+<p>To check the status of Knife using a Ruby script named &#8220;status.rb&#8221; (which looks like):</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="nb">printf</span> <span class="s2">&quot;%-5s %-12s %-8s %s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot;Check In&quot;</span><span class="p">,</span> <span class="s2">&quot;Name&quot;</span><span class="p">,</span> <span class="s2">&quot;Ruby&quot;</span><span class="p">,</span> <span class="s2">&quot;Recipes&quot;</span>
+<span class="n">nodes</span><span class="o">.</span><span class="n">all</span> <span class="k">do</span> <span class="o">|</span><span class="n">n</span><span class="o">|</span>
+ <span class="n">checkin</span> <span class="o">=</span> <span class="no">Time</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="n">n</span><span class="o">[</span><span class="s1">&#39;ohai_time&#39;</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%F %R&quot;</span><span class="p">)</span>
+ <span class="n">rubyver</span> <span class="o">=</span> <span class="n">n</span><span class="o">[</span><span class="s1">&#39;languages&#39;</span><span class="o">][</span><span class="s1">&#39;ruby&#39;</span><span class="o">][</span><span class="s1">&#39;version&#39;</span><span class="o">]</span>
+ <span class="n">recipes</span> <span class="o">=</span> <span class="n">n</span><span class="o">.</span><span class="n">run_list</span><span class="o">.</span><span class="n">expand</span><span class="p">(</span><span class="n">_default</span><span class="p">)</span><span class="o">.</span><span class="n">recipes</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot;, &quot;</span><span class="p">)</span>
+ <span class="nb">printf</span> <span class="s2">&quot;%-20s %-12s %-8s %s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">checkin</span><span class="p">,</span> <span class="n">n</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">rubyver</span><span class="p">,</span> <span class="n">recipes</span>
+<span class="k">end</span>
+</pre></div>
+</div>
+<p>and is located in a directory named &#8220;scripts&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec </span>scripts/status.rb
+</pre></div>
+</div>
+<p><strong>List available free memory</strong></p>
+<p>To show the available free memory for all nodes, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec</span> -E <span class="s1">&#39;nodes.all {|n| puts &quot;#{n.name} has #{n.memory.total} free memory&quot;}&#39;</span>
+</pre></div>
+</div>
+<p><strong>List available search indexes</strong></p>
+<p>To list all of the available search indexes, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife <span class="nb">exec</span> -E <span class="s1">&#39;puts api.get(&quot;search&quot;).keys&#39;</span>
+</pre></div>
+</div>
+<p><strong>Query for multiple attributes</strong></p>
+<p>To query a node for multiple attributes using a Ruby script named <tt class="docutils literal"><span class="pre">search_attributes.rb</span></tt> (which looks like):</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="sx">% cat </span><span class="n">scripts</span><span class="o">/</span><span class="n">search_attributes</span><span class="o">.</span><span class="n">rb</span>
+<span class="n">query</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span>
+<span class="n">attributes</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">[</span><span class="mi">3</span><span class="o">].</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="p">)</span>
+<span class="nb">puts</span> <span class="s2">&quot;Your query: </span><span class="si">#{</span><span class="n">query</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="nb">puts</span> <span class="s2">&quot;Your attributes: </span><span class="si">#{</span><span class="n">attributes</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="n">results</span> <span class="o">=</span> <span class="p">{}</span>
+<span class="n">search</span><span class="p">(</span><span class="ss">:node</span><span class="p">,</span> <span class="n">query</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">n</span><span class="o">|</span>
+ <span class="n">results</span><span class="o">[</span><span class="n">n</span><span class="o">.</span><span class="n">name</span><span class="o">]</span> <span class="o">=</span> <span class="p">{}</span>
+ <span class="n">attributes</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span><span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="n">results</span><span class="o">[</span><span class="n">n</span><span class="o">.</span><span class="n">name</span><span class="o">][</span><span class="n">a</span><span class="o">]</span> <span class="o">=</span> <span class="n">n</span><span class="o">[</span><span class="n">a</span><span class="o">]</span><span class="p">}</span>
+<span class="k">end</span>
+
+<span class="nb">puts</span> <span class="n">results</span>
+<span class="nb">exit</span> <span class="mi">0</span>
+</pre></div>
+</div>
+<p>enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre>% knife <span class="nb">exec </span>scripts/search_attributes.rb <span class="s2">&quot;hostname:test_system&quot;</span> ipaddress,fqdn
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>Your query: hostname:test_system
+Your attributes: ipaddress fqdn
+<span class="o">{</span><span class="s2">&quot;test_system.example.com&quot;</span><span class="o">=</span>&gt;<span class="o">{</span><span class="s2">&quot;ipaddress&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;10.1.1.200&quot;</span>, <span class="s2">&quot;fqdn&quot;</span><span class="o">=</span>&gt;<span class="s2">&quot;test_system.example.com&quot;</span><span class="o">}}</span>
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_index_rebuild.html b/distro/common/html/knife_index_rebuild.html
new file mode 100644
index 0000000000..82dc5698da
--- /dev/null
+++ b/distro/common/html/knife_index_rebuild.html
@@ -0,0 +1,85 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife index rebuild &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-index-rebuild">
+<h1>knife index rebuild<a class="headerlink" href="#knife-index-rebuild" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife index rebuild</strong> subcommand is used to rebuild the search indexes for the open source server. This operation is destructive and may take some time.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">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.</p>
+</div>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife index rebuild
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>None.</p>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_list.html b/distro/common/html/knife_list.html
new file mode 100644
index 0000000000..51d6ff0a55
--- /dev/null
+++ b/distro/common/html/knife_list.html
@@ -0,0 +1,116 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife list &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-list">
+<h1>knife list<a class="headerlink" href="#knife-list" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife list</strong> subcommand is used to view a list of objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">list</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">list</span></tt>, but with a single verb (and a single action).</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife list <span class="o">[</span>PATTERN...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-1</span></tt></dt>
+<dd>Indicates that only one column of results will be shown. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-d</span></tt></dt>
+<dd>Indicates that a directory&#8217;s children will not be shown when a directory matches a pattern. Default value: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-f</span></tt>, <tt class="docutils literal"><span class="pre">--flat</span></tt></dt>
+<dd>Indicates that a list of file names will be shown. Set to <tt class="docutils literal"><span class="pre">false</span></tt> to view ls-like output. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--local</span></tt></dt>
+<dd>Indicates that only contents of the local directory will be returned. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-p</span></tt></dt>
+<dd>Indicates that trailing slashes (/) will be shown for directories. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-R</span></tt></dt>
+<dd>Indicates that directories will be listed recursively. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default: <tt class="docutils literal"><span class="pre">everything</span></tt> / <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>List roles</strong></p>
+<p>For example, to view a list of roles on the server:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife list roles/
+</pre></div>
+</div>
+<p><strong>List roles and environments</strong></p>
+<p>To view a list of roles and environments on the server:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife list roles/ environments/
+</pre></div>
+</div>
+<p><strong>List everything</strong></p>
+<p>To view a list of absolutely everything on the server:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife list -R /
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_node.html b/distro/common/html/knife_node.html
new file mode 100644
index 0000000000..9e90175075
--- /dev/null
+++ b/distro/common/html/knife_node.html
@@ -0,0 +1,450 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife node &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-node">
+<h1>knife node<a class="headerlink" href="#knife-node" title="Permalink to this headline">¶</a></h1>
+<p>A node is any physical, virtual, or cloud machine that is configured to be maintained by a chef-client.</p>
+<p>The <strong>knife node</strong> subcommand is used to manage the nodes that exist on a server.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="bulk-delete">
+<h2>bulk delete<a class="headerlink" href="#bulk-delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">bulk</span> <span class="pre">delete</span></tt> 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 (/).</p>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node bulk delete REGEX
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Bulk delete nodes</strong></p>
+<p>Use a regular expression to define the pattern used to bulk delete nodes:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node bulk delete <span class="s2">&quot;^[0-9]{3}$&quot;</span>
+</pre></div>
+</div>
+<p>Type <tt class="docutils literal"><span class="pre">Y</span></tt> to confirm a deletion.</p>
+</div>
+</div>
+<div class="section" id="create">
+<h2>create<a class="headerlink" href="#create" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">create</span></tt> argument is used to add a node to the server. Node data is stored as JSON on the server.</p>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node create NODE_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create a node</strong></p>
+<p>To add a node, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node create node1
+</pre></div>
+</div>
+<p>In the $EDITOR enter the node data in JSON:</p>
+<div class="highlight-javascript"><pre>## sample:
+{
+ "normal": {
+ },
+ "name": "foobar",
+ "override": {
+ },
+ "default": {
+ },
+ "json_class": "Chef::Node",
+ "automatic": {
+ },
+ "run_list": [
+ "recipe[zsh]",
+ "role[webserver]"
+ ],
+ "chef_type": "node"
+}</pre>
+</div>
+<p>When finished, save it.</p>
+</div>
+</div>
+<div class="section" id="delete">
+<h2>delete<a class="headerlink" href="#delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">delete</span></tt> argument is used to delete a node from the server.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Deleting a node will not delete any corresponding API clients.</p>
+</div>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node delete NODE_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Delete a node</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node delete node_name
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="edit">
+<h2>edit<a class="headerlink" href="#edit" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">edit</span></tt> argument is used to edit the details of a node on a server. Node data is stored as JSON on the server.</p>
+<div class="section" id="id7">
+<h3>Syntax<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node edit NODE_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id8">
+<h3>Options<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
+<dd>Displays a node in the $EDITOR. By default, attributes that are default, override, or automatic are not shown.</dd>
+</dl>
+</div>
+<div class="section" id="id9">
+<h3>Examples<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Edit a node</strong></p>
+<p>To edit the data for a node named &#8220;node1&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node edit node1 -a
+</pre></div>
+</div>
+<p>Update the role data in JSON:</p>
+<div class="highlight-javascript"><pre>## sample:
+{
+ "normal": {
+ },
+ "name": "node1",
+ "override": {
+ },
+ "default": {
+ },
+ "json_class": "Chef::Node",
+ "automatic": {
+ },
+ "run_list": [
+ "recipe[devops]",
+ "role[webserver]"
+ ],
+ "chef_type": "node"
+}</pre>
+</div>
+<p>When finished, save it.</p>
+</div>
+</div>
+<div class="section" id="from-file">
+<h2>from file<a class="headerlink" href="#from-file" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">from</span> <span class="pre">file</span></tt> argument is used to create a node using existing node data as a template.</p>
+<div class="section" id="id10">
+<h3>Syntax<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node from file FILE
+</pre></div>
+</div>
+</div>
+<div class="section" id="id11">
+<h3>Options<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id12">
+<h3>Examples<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create a node using a JSON file</strong></p>
+<p>To add a node using data contained in a JSON file:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node from file <span class="s2">&quot;path to JSON file&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> argument is used to view all of the nodes that exist on a server.</p>
+<div class="section" id="id13">
+<h3>Syntax<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node list <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id14">
+<h3>Options<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id15">
+<h3>Examples<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of nodes</strong></p>
+<p>To verify the list of nodes that are registered with the server, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node list
+</pre></div>
+</div>
+<p>to return something similar to:</p>
+<div class="highlight-bash"><div class="highlight"><pre>i-12345678
+rs-123456
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="run-list-add">
+<h2>run_list add<a class="headerlink" href="#run-list-add" title="Permalink to this headline">¶</a></h2>
+<p>A run-list is an ordered list of roles and/or recipes that are run in an exact order. A run-list is always specific to the node on which it runs, though it is possible for many nodes to have run-lists that are similar or even identical. The items within a run-list are maintained using Knife and are uploaded to the server and stored as part of the node object for each node. The chef-client always configures a node in the exact order specified by its run-list and will never run the same recipe twice.</p>
+<p>The <tt class="docutils literal"><span class="pre">run_list</span> <span class="pre">add</span></tt> argument is used to add run list items (roles or recipes) to a node.</p>
+<p>A run-list must be in one of the following formats: fully qualified, cookbook, or default. Both roles and recipes must be in quotes, for example:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="s1">&#39;role[ROLE_NAME]&#39;</span>
+</pre></div>
+</div>
+<p>or</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="s1">&#39;recipe[COOKBOOK::RECIPE_NAME]&#39;</span>
+</pre></div>
+</div>
+<p>Use a comma to separate roles and recipes when adding more than one item the run-list:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="s1">&#39;recipe[COOKBOOK::RECIPE_NAME],COOKBOOK::RECIPE_NAME,role[ROLE_NAME]&#39;</span>
+</pre></div>
+</div>
+<div class="section" id="id16">
+<h3>Syntax<a class="headerlink" href="#id16" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list add NODE_NAME RUN_LIST_ITEM <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id17">
+<h3>Options<a class="headerlink" href="#id17" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ITEM</span></tt>, <tt class="docutils literal"><span class="pre">--after</span> <span class="pre">ITEM</span></tt></dt>
+<dd>Use this to add the run list item after the specified run list item.</dd>
+</dl>
+</div>
+<div class="section" id="id18">
+<h3>Examples<a class="headerlink" href="#id18" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Add a role</strong></p>
+<p>To add a role to a run list, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list add node <span class="s1">&#39;role[ROLE_NAME]&#39;</span>
+</pre></div>
+</div>
+<p><strong>Add roles and recipes</strong></p>
+<p>To add roles and recipes to a run list, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list add node <span class="s1">&#39;recipe[COOKBOOK::RECIPE_NAME],recipe[COOKBOOK::RECIPE_NAME],role[ROLE_NAME]&#39;</span>
+</pre></div>
+</div>
+<p><strong>Add a recipe with a FQDN</strong></p>
+<p>To add a recipe to a run list using the fully qualified format, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list add node <span class="s1">&#39;recipe[COOKBOOK::RECIPE_NAME]&#39;</span>
+</pre></div>
+</div>
+<p><strong>Add a recipe with a cookbook</strong></p>
+<p>To add a recipe to a run list using the cookbook format, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list add node <span class="s1">&#39;COOKBOOK::RECIPE_NAME&#39;</span>
+</pre></div>
+</div>
+<p><strong>Add the default recipe</strong></p>
+<p>To add the default recipe of a cookbook to a run list, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list add node <span class="s1">&#39;COOKBOOK&#39;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="run-list-remove">
+<h2>run_list remove<a class="headerlink" href="#run-list-remove" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">run_list</span> <span class="pre">remove</span></tt> 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: <tt class="docutils literal"><span class="pre">'role[ROLE_NAME]'</span></tt> or <tt class="docutils literal"><span class="pre">'recipe[COOKBOOK::RECIPE_NAME]'</span></tt>. Use a comma to separate roles and recipes when removing more than one, like this: <tt class="docutils literal"><span class="pre">'recipe[COOKBOOK::RECIPE_NAME],COOKBOOK::RECIPE_NAME,role[ROLE_NAME]'</span></tt>.</p>
+<div class="section" id="id19">
+<h3>Syntax<a class="headerlink" href="#id19" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list remove NODE_NAME RUN_LIST_ITEM
+</pre></div>
+</div>
+</div>
+<div class="section" id="id20">
+<h3>Options<a class="headerlink" href="#id20" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id21">
+<h3>Examples<a class="headerlink" href="#id21" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Remove a role</strong></p>
+<p>To remove a role from a run list, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list remove node <span class="s1">&#39;role[ROLE_NAME]&#39;</span>
+</pre></div>
+</div>
+<p><strong>Remove a run-list</strong></p>
+<p>To remove a recipe from a run list using the fully qualified format, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node run_list remove node <span class="s1">&#39;recipe[COOKBOOK::RECIPE_NAME]&#39;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="show">
+<h2>show<a class="headerlink" href="#show" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">show</span></tt> argument is used to display information about a node.</p>
+<div class="section" id="id22">
+<h3>Syntax<a class="headerlink" href="#id22" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node show NODE_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id23">
+<h3>Options<a class="headerlink" href="#id23" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">ATTR</span></tt></dt>
+<dd>The attribute (or attributes) to show.</dd>
+<dt><tt class="docutils literal"><span class="pre">-l</span></tt>, <tt class="docutils literal"><span class="pre">--long</span></tt></dt>
+<dd>Display long output when searching nodes while using the default summary format.</dd>
+<dt><tt class="docutils literal"><span class="pre">-m</span></tt>, <tt class="docutils literal"><span class="pre">--medium</span></tt></dt>
+<dd>Display more, but not all, of a node&#8217;s data when searching using the default summary format.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span></tt>, <tt class="docutils literal"><span class="pre">--run-list</span></tt></dt>
+<dd>Indicates that only the run-list will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id24">
+<h3>Examples<a class="headerlink" href="#id24" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show all data about nodes</strong></p>
+<p>To view all data for a node named &#8220;build&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node show build
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-bash"><div class="highlight"><pre>Node Name: build
+Environment: _default
+FQDN:
+IP:
+Run List:
+Roles:
+Recipes:
+Platform:
+</pre></div>
+</div>
+<p><strong>Show basic information about nodes</strong></p>
+<p>To show basic information about a node, truncated and nicely formatted:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife node show &lt;node_name&gt;
+</pre></div>
+</div>
+<p><strong>Show all data about nodes, truncated</strong></p>
+<p>To show all information about a node, nicely formatted:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife node show -l &lt;node_name&gt;
+</pre></div>
+</div>
+<p><strong>Show attributes</strong></p>
+<p>To list a single node attribute:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife node show &lt;node_name&gt; -a &lt;attribute_name&gt;
+</pre></div>
+</div>
+<p>where <tt class="docutils literal"><span class="pre">&lt;attribute_name&gt;</span></tt> is something like kernel or platform. (This doesn&#8217;t work for nested attributes like <tt class="docutils literal"><span class="pre">node[kernel][machine]</span></tt> because <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">show</span></tt> doesn&#8217;t understand nested attributes.)</p>
+<p><strong>Show the FQDN</strong></p>
+<p>To view the FQDN for a node named &#8220;i-12345678&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node show i-12345678 -a fqdn
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-bash"><div class="highlight"><pre>fqdn: ip-10-251-75-20.ec2.internal
+</pre></div>
+</div>
+<p><strong>Show a run-list</strong></p>
+<p>To view the run list for a node named &#8220;dev&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife node show dev -r
+</pre></div>
+</div>
+<p><strong>Show as JSON data</strong></p>
+<p>To view information in JSON format, use the <tt class="docutils literal"><span class="pre">-F</span></tt> common option as part of the command like this:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role show devops -F json
+</pre></div>
+</div>
+<p>Other formats available include <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>.</p>
+<p><strong>Show as raw JSON data</strong></p>
+<p>To view node information in raw JSON, use the <tt class="docutils literal"><span class="pre">-l</span></tt> or <tt class="docutils literal"><span class="pre">--long</span></tt> option:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife node show -l -F json &lt;node_name&gt;
+</pre></div>
+</div>
+<p>and/or:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife node show -l --format<span class="o">=</span>json &lt;node_name&gt;
+</pre></div>
+</div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_raw.html b/distro/common/html/knife_raw.html
new file mode 100644
index 0000000000..fdca3e1fa4
--- /dev/null
+++ b/distro/common/html/knife_raw.html
@@ -0,0 +1,112 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife raw &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-raw">
+<h1>knife raw<a class="headerlink" href="#knife-raw" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife raw</strong> subcommand is used to send a REST request to a specified path using the Chef Server API.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife raw REQUEST_PATH <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-i</span> <span class="pre">FILE</span></tt>, <tt class="docutils literal"><span class="pre">--input</span> <span class="pre">FILE</span></tt></dt>
+<dd>The name of a file to be used with the <tt class="docutils literal"><span class="pre">PUT</span></tt> or a <tt class="docutils literal"><span class="pre">POST</span></tt> request.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]pretty</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--no-pretty</span></tt> to disable pretty-print output for JSON. Default: <tt class="docutils literal"><span class="pre">--pretty</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-m</span> <span class="pre">METHOD</span></tt>, <tt class="docutils literal"><span class="pre">--method</span> <span class="pre">METHOD</span></tt></dt>
+<dd>The request method: <tt class="docutils literal"><span class="pre">DELETE</span></tt>, <tt class="docutils literal"><span class="pre">GET</span></tt>, <tt class="docutils literal"><span class="pre">POST</span></tt>, or <tt class="docutils literal"><span class="pre">PUT</span></tt>. Default value: <tt class="docutils literal"><span class="pre">GET</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a client</strong></p>
+<p>To view information about a client:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife raw /clients/&lt;client_name&gt;
+</pre></div>
+</div>
+<p><strong>View a node</strong></p>
+<p>To view information about a node:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife raw /nodes/&lt;node_name&gt;
+</pre></div>
+</div>
+<p><strong>Delete a data bag</strong></p>
+<p>To delete a data bag, enter a command similar to:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife raw -m DELETE /data/foo
+</pre></div>
+</div>
+<p>to return something similar to:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="o">{</span>
+ <span class="s2">&quot;name&quot;</span>:<span class="s2">&quot;foo&quot;</span>,
+ <span class="s2">&quot;json_class&quot;</span>:<span class="s2">&quot;Chef::DataBag&quot;</span>,
+ <span class="s2">&quot;chef_type&quot;</span>:<span class="s2">&quot;data_bag&quot;</span>
+<span class="o">}</span>
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_recipe_list.html b/distro/common/html/knife_recipe_list.html
new file mode 100644
index 0000000000..b7a0d9be70
--- /dev/null
+++ b/distro/common/html/knife_recipe_list.html
@@ -0,0 +1,93 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife recipe list &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-recipe-list">
+<h1>knife recipe list<a class="headerlink" href="#knife-recipe-list" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife recipe list</strong> 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 (/).</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife recipe list REGEX
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of recipes</strong></p>
+<p>To view a list of recipes:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife recipe list <span class="s1">&#39;couchdb::*&#39;</span>
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-bash"><div class="highlight"><pre>couchdb::main_monitors
+couchdb::master
+couchdb::default
+couchdb::org_cleanu
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_role.html b/distro/common/html/knife_role.html
new file mode 100644
index 0000000000..0ed0deb624
--- /dev/null
+++ b/distro/common/html/knife_role.html
@@ -0,0 +1,295 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife role &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-role">
+<h1>knife role<a class="headerlink" href="#knife-role" title="Permalink to this headline">¶</a></h1>
+<p>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&#8217;s run list are applied to the node&#8217;s configuration details. When a chef-client runs, it merges its own attributes and run lists with those contained within each assigned role.</p>
+<p>The <strong>knife role</strong> subcommand is used to manage the roles that are associated with one or more nodes on a server.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">To add a role to a node and then build out the run-list for that node, use the <a class="reference internal" href="knife_node.html"><em>knife node</em></a> sub-command and its <tt class="docutils literal"><span class="pre">run_list</span> <span class="pre">add</span></tt> argument.</p>
+</div>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="bulk-delete">
+<h2>bulk delete<a class="headerlink" href="#bulk-delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">bulk</span> <span class="pre">delete</span></tt> 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 (/).</p>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role bulk delete REGEX
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Bulk delete roles</strong></p>
+<p>Use a regular expression to define the pattern used to bulk delete roles:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role bulk delete <span class="s2">&quot;^[0-9]{3}$&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="create">
+<h2>create<a class="headerlink" href="#create" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">create</span></tt> argument is used to add a role to the server. Role data is saved as JSON on the server.</p>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role create ROLE_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-d</span> <span class="pre">DESCRIPTION</span></tt>, <tt class="docutils literal"><span class="pre">--description</span> <span class="pre">DESCRIPTION</span></tt></dt>
+<dd>The description of the role. This value will populate the description field for the role on the server.</dd>
+</dl>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create a role</strong></p>
+<p>To add a role named &#8220;role1&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role create role1
+</pre></div>
+</div>
+<p>In the $EDITOR enter the role data in JSON:</p>
+<div class="highlight-javascript"><pre>## sample:
+{
+ "name": "role1",
+ "default_attributes": {
+ },
+ "json_class": "Chef::Role",
+ "run_list": ['recipe[cookbook_name::recipe_name],
+ role[role_name]'
+ ],
+ "description": "",
+ "chef_type": "role",
+ "override_attributes": {
+ }
+}</pre>
+</div>
+<p>When finished, save it.</p>
+</div>
+</div>
+<div class="section" id="delete">
+<h2>delete<a class="headerlink" href="#delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">delete</span></tt> argument is used to delete a role from the server.</p>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role delete ROLE_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Delete a role</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role delete devops
+</pre></div>
+</div>
+<p>Type <tt class="docutils literal"><span class="pre">Y</span></tt> to confirm a deletion.</p>
+</div>
+</div>
+<div class="section" id="edit">
+<h2>edit<a class="headerlink" href="#edit" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">edit</span></tt> argument is used to edit role details on the server.</p>
+<div class="section" id="id7">
+<h3>Syntax<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role edit ROLE_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id8">
+<h3>Options<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id9">
+<h3>Examples<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Edit a role</strong></p>
+<p>To edit the data for a role named &#8220;role1&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role edit role1
+</pre></div>
+</div>
+<p>Update the role data in JSON:</p>
+<div class="highlight-javascript"><pre>## sample:
+{
+ "name": "role1",
+ "default_attributes": {
+ },
+ "json_class": "Chef::Role",
+ "run_list": ['recipe[cookbook_name::recipe_name],
+ role[role_name]'
+ ],
+ "description": "This is the description for the role1 role.",
+ "chef_type": "role",
+ "override_attributes": {
+ }
+}</pre>
+</div>
+<p>When finished, save it.</p>
+</div>
+</div>
+<div class="section" id="from-file">
+<h2>from file<a class="headerlink" href="#from-file" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">from</span> <span class="pre">file</span></tt> argument is used to create a role using existing JSON data as a template.</p>
+<div class="section" id="id10">
+<h3>Syntax<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role from file FILE
+</pre></div>
+</div>
+</div>
+<div class="section" id="id11">
+<h3>Options<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id12">
+<h3>Examples<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create a role using JSON data</strong></p>
+<p>To view role details based on the values contained in a JSON file:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role from file <span class="s2">&quot;path to JSON file&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> argument is used to view a list of roles that are currently available on the server.</p>
+<div class="section" id="id13">
+<h3>Syntax<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role list
+</pre></div>
+</div>
+</div>
+<div class="section" id="id14">
+<h3>Options<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id15">
+<h3>Examples<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of roles</strong></p>
+<p>To view a list of roles on the server and display the URI for each role returned, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role list -w
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="show">
+<h2>show<a class="headerlink" href="#show" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">show</span></tt> argument is used to view the details of a role.</p>
+<div class="section" id="id16">
+<h3>Syntax<a class="headerlink" href="#id16" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role show ROLE_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id17">
+<h3>Options<a class="headerlink" href="#id17" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">ATTR</span></tt></dt>
+<dd>The attribute (or attributes) to show.</dd>
+</dl>
+</div>
+<div class="section" id="id18">
+<h3>Examples<a class="headerlink" href="#id18" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show as JSON data</strong></p>
+<p>To view information in JSON format, use the <tt class="docutils literal"><span class="pre">-F</span></tt> common option as part of the command like this:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife role show devops -F json
+</pre></div>
+</div>
+<p>Other formats available include <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>.</p>
+<p><strong>Show as raw JSON data</strong></p>
+<p>To view node information in raw JSON, use the <tt class="docutils literal"><span class="pre">-l</span></tt> or <tt class="docutils literal"><span class="pre">--long</span></tt> option:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife node show -l -F json &lt;node_name&gt;
+</pre></div>
+</div>
+<p>and/or:</p>
+<div class="highlight-bash"><div class="highlight"><pre>knife node show -l --format<span class="o">=</span>json &lt;node_name&gt;
+</pre></div>
+</div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_search.html b/distro/common/html/knife_search.html
new file mode 100644
index 0000000000..b4b01e306a
--- /dev/null
+++ b/distro/common/html/knife_search.html
@@ -0,0 +1,204 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife search &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-search">
+<h1>knife search<a class="headerlink" href="#knife-search" title="Permalink to this headline">¶</a></h1>
+<p>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 <tt class="docutils literal"><span class="pre">search</span></tt> subcommand in Knife, by using the search functionality in the Chef Manage, or by using the <tt class="docutils literal"><span class="pre">/search</span></tt> or <tt class="docutils literal"><span class="pre">/search/INDEX</span></tt> endpoints in the Chef Server API. The search engine is based on Apache Solr and is run from the server.</p>
+<p>The <strong>knife search</strong> subcommand is used run a search query for information that is indexed on a server.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search INDEX SEARCH_QUERY
+</pre></div>
+</div>
+<p>where <tt class="docutils literal"><span class="pre">INDEX</span></tt> is one of <tt class="docutils literal"><span class="pre">client</span></tt>, <tt class="docutils literal"><span class="pre">environment</span></tt>, <tt class="docutils literal"><span class="pre">node</span></tt>, <tt class="docutils literal"><span class="pre">role</span></tt>, or the name of a data bag and <tt class="docutils literal"><span class="pre">SEARCH_QUERY</span></tt> is the search query syntax for the query that will be executed.</p>
+<p><tt class="docutils literal"><span class="pre">INDEX</span></tt> is implied if omitted, and will default to <tt class="docutils literal"><span class="pre">node</span></tt>. For example:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search <span class="s1">&#39;*:*&#39;</span> -i
+</pre></div>
+</div>
+<p>will return something similar to:</p>
+<div class="highlight-bash"><div class="highlight"><pre>8 items found
+
+centos-62-dev
+opensuse-1203
+ubuntu-1304-dev
+ubuntu-1304-orgtest
+ubuntu-1204-ohai-test
+ubuntu-1304-ifcfg-test
+ohai-test
+win2k8-dev
+</pre></div>
+</div>
+<p>and is the same search as:</p>
+<div class="highlight-bash"><pre>$ knife search node '*:*" -i</pre>
+</div>
+<p>If the <tt class="docutils literal"><span class="pre">SEARCH_QUERY</span></tt> does not contain a colon character (<tt class="docutils literal"><span class="pre">:</span></tt>), then the default query pattern is <tt class="docutils literal"><span class="pre">tags:*#{&#64;query}*</span> <span class="pre">OR</span> <span class="pre">roles:*#{&#64;query}*</span> <span class="pre">OR</span> <span class="pre">fqdn:*#{&#64;query}*</span> <span class="pre">OR</span> <span class="pre">addresses:*#{&#64;query}*</span></tt>, which means the following two search queries are effectively the same:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search ubuntu
+</pre></div>
+</div>
+<p>or:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node <span class="s2">&quot;tags:*ubuntu* OR roles:*ubuntu* OR fqdn:*ubuntu* (etc.)&quot;</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This sub-command has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">ATTR</span></tt></dt>
+<dd>The attribute (or attributes) to show.</dd>
+<dt><tt class="docutils literal"><span class="pre">-b</span> <span class="pre">ROW</span></tt>, <tt class="docutils literal"><span class="pre">--start</span> <span class="pre">ROW</span></tt></dt>
+<dd>The row at which return results will begin.</dd>
+<dt><tt class="docutils literal"><span class="pre">-i</span></tt>, <tt class="docutils literal"><span class="pre">--id-only</span></tt></dt>
+<dd>Indicates that only matching object IDs will be shown.</dd>
+<dt><tt class="docutils literal"><span class="pre">INDEX</span></tt></dt>
+<dd>The name of the index to be queried: <tt class="docutils literal"><span class="pre">client</span></tt>, <tt class="docutils literal"><span class="pre">environment</span></tt>, <tt class="docutils literal"><span class="pre">node</span></tt>, <tt class="docutils literal"><span class="pre">role</span></tt>, or <tt class="docutils literal"><span class="pre">DATA_BAG_NAME</span></tt>. Default index: <tt class="docutils literal"><span class="pre">node</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-l</span></tt>, <tt class="docutils literal"><span class="pre">--long</span></tt></dt>
+<dd>Display long output when searching nodes while using the default summary format.</dd>
+<dt><tt class="docutils literal"><span class="pre">-m</span></tt>, <tt class="docutils literal"><span class="pre">--medium</span></tt></dt>
+<dd>Display more, but not all, of a node&#8217;s data when searching using the default summary format.</dd>
+<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">SORT</span></tt>, <tt class="docutils literal"><span class="pre">--sort</span> <span class="pre">SORT</span></tt></dt>
+<dd>The order in which search results will be sorted.</dd>
+<dt><tt class="docutils literal"><span class="pre">-q</span> <span class="pre">SEARCH_QUERY</span></tt>, <tt class="docutils literal"><span class="pre">--query</span> <span class="pre">SEARCH_QUERY</span></tt></dt>
+<dd>Use to protect search queries that start with a hyphen (-). A <tt class="docutils literal"><span class="pre">-q</span></tt> query may be specified as an argument or an option, but not both.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span></tt>, <tt class="docutils literal"><span class="pre">--run-list</span></tt></dt>
+<dd>Indicates that only the run-list will be shown.</dd>
+<dt><tt class="docutils literal"><span class="pre">-R</span> <span class="pre">INT</span></tt>, <tt class="docutils literal"><span class="pre">--rows</span> <span class="pre">INT</span></tt></dt>
+<dd>The number of rows to be returned.</dd>
+<dt><tt class="docutils literal"><span class="pre">SEARCH_QUERY</span></tt></dt>
+<dd>The search query used to identify a a list of items on a server. This option uses the same syntax as the <tt class="docutils literal"><span class="pre">search</span></tt> sub-command.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Search by platform ID</strong></p>
+<p>To search for the IDs of all nodes running on the Amazon EC2 platform, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node <span class="s1">&#39;ec2:*&#39;</span> -i
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>4 items found
+
+ip-0A7CA19F.ec2.internal
+
+ip-0A58CF8E.ec2.internal
+
+ip-0A58E134.ec2.internal
+
+ip-0A7CFFD5.ec2.internal
+</pre></div>
+</div>
+<p><strong>Search by instance type</strong></p>
+<p>To search for the instance type (flavor) of all nodes running on the Amazon EC2 platform, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node <span class="s1">&#39;ec2:*&#39;</span> -a ec2.instance_type
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>4 items found
+
+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
+</pre></div>
+</div>
+<p><strong>Search by node</strong></p>
+<p>To search for all nodes running Ubuntu, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node <span class="s1">&#39;platform:ubuntu&#39;</span>
+</pre></div>
+</div>
+<p><strong>Search by node and environment</strong></p>
+<p>To search for all nodes running CentOS in the production environment, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node <span class="s1">&#39;chef_environment:production AND platform:centos&#39;</span>
+</pre></div>
+</div>
+<p><strong>Search for nested attributes</strong></p>
+<p>To find a nested attribute, use a pattern similar to the following:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node &lt;query_to_run&gt; -a &lt;main_attribute&gt;.&lt;nested_attribute&gt;
+</pre></div>
+</div>
+<p><strong>Search for multiple attributes</strong></p>
+<p>To build a search query to use more than one attribute, use an underscore (<tt class="docutils literal"><span class="pre">_</span></tt>) to separate each attribute. For example, the following query will search for all nodes running a specific version of Ruby:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node <span class="s2">&quot;languages_ruby_version:1.9.3&quot;</span>
+</pre></div>
+</div>
+<p><strong>Search for nested attributes using a search query</strong></p>
+<p>To build a search query that can find a nested attribute:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node name:&lt;node_name&gt; -a kernel.machine
+</pre></div>
+</div>
+<p><strong>Use a test query</strong></p>
+<p>To test a search query that will be used in a <strong>knife ssh</strong> command:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife search node <span class="s2">&quot;role:web NOT name:web03&quot;</span>
+</pre></div>
+</div>
+<p>where the query in the previous example will search all servers that have the <tt class="docutils literal"><span class="pre">web</span></tt> role, but not on the server named <tt class="docutils literal"><span class="pre">web03</span></tt>.</p>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_show.html b/distro/common/html/knife_show.html
new file mode 100644
index 0000000000..acf50a2228
--- /dev/null
+++ b/distro/common/html/knife_show.html
@@ -0,0 +1,106 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife show &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-show">
+<h1>knife show<a class="headerlink" href="#knife-show" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife show</strong> subcommand is used to view the details of one (or more) objects on the server. This subcommand works similar to <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">cookbook</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">environment</span> <span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">node</span> <span class="pre">show</span></tt>, and <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">role</span> <span class="pre">show</span></tt>, but with a single verb (and a single action).</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife show <span class="o">[</span>PATTERN...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">ATTR</span></tt></dt>
+<dd>The attribute (or attributes) to show.</dd>
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--local</span></tt></dt>
+<dd>Indicates that instead of remote files, local files will be shown.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default: <tt class="docutils literal"><span class="pre">everything</span></tt> / <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show all cookbooks</strong></p>
+<p>To show all cookbooks in the <tt class="docutils literal"><span class="pre">cookbooks/</span></tt> directory:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife show cookbooks/
+</pre></div>
+</div>
+<p>or, (if already in the <tt class="docutils literal"><span class="pre">cookbooks/</span></tt> directory in the local chef-repo):</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife show
+</pre></div>
+</div>
+<p><strong>Show roles and environments</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife show roles/ environments/
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_ssh.html b/distro/common/html/knife_ssh.html
new file mode 100644
index 0000000000..a8e9f283fa
--- /dev/null
+++ b/distro/common/html/knife_ssh.html
@@ -0,0 +1,179 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife ssh &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-ssh">
+<h1>knife ssh<a class="headerlink" href="#knife-ssh" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife ssh</strong> 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.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife ssh SEARCH_QUERY SSH_COMMAND <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">SSH_ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">SSH_ATTR</span></tt></dt>
+<dd>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.</dd>
+<dt><tt class="docutils literal"><span class="pre">-A</span></tt>, <tt class="docutils literal"><span class="pre">--forward-agent</span></tt></dt>
+<dd>Indicates that SSH agent forwarding is enabled.</dd>
+<dt><tt class="docutils literal"><span class="pre">-C</span> <span class="pre">NUM</span></tt>, <tt class="docutils literal"><span class="pre">--concurrency</span> <span class="pre">NUM</span></tt></dt>
+<dd>The number of allowed concurrent connections.</dd>
+<dt><tt class="docutils literal"><span class="pre">-G</span> <span class="pre">GATEWAY</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-gateway</span> <span class="pre">GATEWAY</span></tt></dt>
+<dd>The SSH tunnel or gateway that is used to run a bootstrap action on a machine that is not accessible from the workstation.</dd>
+<dt><tt class="docutils literal"><span class="pre">-i</span> <span class="pre">IDENTITY_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--identity-file</span> <span class="pre">IDENTIFY_FILE</span></tt></dt>
+<dd>The SSH identity file used for authentication. Key-based authentication is recommended.</dd>
+<dt><tt class="docutils literal"><span class="pre">-m</span></tt>, <tt class="docutils literal"><span class="pre">--manual-list</span></tt></dt>
+<dd>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: <tt class="docutils literal"><span class="pre">--manual-list</span> <span class="pre">&quot;server01</span> <span class="pre">server</span> <span class="pre">02</span> <span class="pre">server</span> <span class="pre">03&quot;</span></tt></dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]host-key-verify</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--no-host-key-verify</span></tt> to disable host key verification. Default setting: <tt class="docutils literal"><span class="pre">--host-key-verify</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">OTHER</span></tt></dt>
+<dd>The shell type. Possible values: <tt class="docutils literal"><span class="pre">interactive</span></tt>, <tt class="docutils literal"><span class="pre">screen</span></tt>, <tt class="docutils literal"><span class="pre">tmux</span></tt>, <tt class="docutils literal"><span class="pre">macterm</span></tt>, or <tt class="docutils literal"><span class="pre">cssh</span></tt>. (<tt class="docutils literal"><span class="pre">csshx</span></tt> is deprecated in favor of <tt class="docutils literal"><span class="pre">cssh</span></tt>.)</dd>
+<dt><tt class="docutils literal"><span class="pre">-p</span> <span class="pre">PORT</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-port</span> <span class="pre">PORT</span></tt></dt>
+<dd>The SSH port.</dd>
+<dt><tt class="docutils literal"><span class="pre">-P</span> <span class="pre">PASSWORD</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-password</span> <span class="pre">PASSWORD</span></tt></dt>
+<dd>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.</dd>
+<dt><tt class="docutils literal"><span class="pre">SEARCH_QUERY</span></tt></dt>
+<dd>The search query used to return a list of servers to be accessed using SSH and the specified <tt class="docutils literal"><span class="pre">SSH_COMMAND</span></tt>. This option uses the same syntax as the search sub-command.</dd>
+<dt><tt class="docutils literal"><span class="pre">SSH_COMMAND</span></tt></dt>
+<dd>The command that will be run against the results of a search query.</dd>
+<dt><tt class="docutils literal"><span class="pre">-x</span> <span class="pre">USER_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-user</span> <span class="pre">USER_NAME</span></tt></dt>
+<dd>The SSH user name.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Find server uptime</strong></p>
+<p>To find the uptime of all of web servers running Ubuntu on the Amazon EC2 platform, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife ssh <span class="s2">&quot;role:web&quot;</span> <span class="s2">&quot;uptime&quot;</span> -x ubuntu -a ec2.public_hostname
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>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
+</pre></div>
+</div>
+<p><strong>Run the chef-client on all nodes</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife ssh <span class="s1">&#39;name:*&#39;</span> <span class="s1">&#39;sudo chef-client&#39;</span>
+</pre></div>
+</div>
+<p><strong>Force a chef-client run</strong></p>
+<p>To force a chef-client run on all of the web servers running Ubuntu on the Amazon EC2 platform, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife ssh <span class="s2">&quot;role:web&quot;</span> <span class="s2">&quot;sudo chef-client&quot;</span> -x ubuntu -a ec2.public_hostname
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>ec2-67-202-63-102.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:37 +0000<span class="o">]</span> INFO: Starting Chef Run <span class="o">(</span>Version 0.9.10<span class="o">)</span>
+ec2-174-129-127-206.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:37 +0000<span class="o">]</span> INFO: Starting Chef Run <span class="o">(</span>Version 0.9.10<span class="o">)</span>
+ec2-184-73-9-250.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:38 +0000<span class="o">]</span> INFO: Starting Chef Run <span class="o">(</span>Version 0.9.10<span class="o">)</span>
+ec2-75-101-240-230.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:38 +0000<span class="o">]</span> INFO: Starting Chef Run <span class="o">(</span>Version 0.9.10<span class="o">)</span>
+ec2-184-73-60-141.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:38 +0000<span class="o">]</span> INFO: Starting Chef Run <span class="o">(</span>Version 0.9.10<span class="o">)</span>
+ec2-174-129-127-206.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:39 +0000<span class="o">]</span> INFO: Chef Run <span class="nb">complete </span>in 1.419243 seconds
+ec2-174-129-127-206.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:39 +0000<span class="o">]</span> INFO: cleaning the checksum cache
+ec2-174-129-127-206.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:39 +0000<span class="o">]</span> INFO: Running report handlers
+ec2-174-129-127-206.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:39 +0000<span class="o">]</span> INFO: Report handlers <span class="nb">complete</span>
+ec2-67-202-63-102.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:39 +0000<span class="o">]</span> INFO: Chef Run <span class="nb">complete </span>in 1.578265 seconds
+ec2-67-202-63-102.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:39 +0000<span class="o">]</span> INFO: cleaning the checksum cache
+ec2-67-202-63-102.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:39 +0000<span class="o">]</span> INFO: Running report handlers
+ec2-67-202-63-102.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:39 +0000<span class="o">]</span> INFO: Report handlers <span class="nb">complete</span>
+ec2-184-73-9-250.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Chef Run <span class="nb">complete </span>in 1.638884 seconds
+ec2-184-73-9-250.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: cleaning the checksum cache
+ec2-184-73-9-250.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Running report handlers
+ec2-184-73-9-250.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Report handlers <span class="nb">complete</span>
+ec2-75-101-240-230.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Chef Run <span class="nb">complete </span>in 1.540257 seconds
+ec2-75-101-240-230.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: cleaning the checksum cache
+ec2-75-101-240-230.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Running report handlers
+ec2-75-101-240-230.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Report handlers <span class="nb">complete</span>
+ec2-184-73-60-141.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Chef Run <span class="nb">complete </span>in 1.502489 seconds
+ec2-184-73-60-141.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: cleaning the checksum cache
+ec2-184-73-60-141.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Running report handlers
+ec2-184-73-60-141.compute-1.amazonaws.com <span class="o">[</span>Fri, 22 Oct 2010 14:18:40 +0000<span class="o">]</span> INFO: Report handlers <span class="nb">complete</span>
+</pre></div>
+</div>
+<p><strong>Run a command based on search query</strong></p>
+<p>To query for all nodes that have the &#8220;webserver&#8221; role and then use SSH to run the command &#8220;sudo chef-client&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife ssh <span class="s2">&quot;role:webserver&quot;</span> <span class="s2">&quot;sudo chef-client&quot;</span>
+</pre></div>
+</div>
+<p><strong>Upgrade all nodes</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife ssh name:* <span class="s2">&quot;sudo aptitude upgrade -y&quot;</span>
+</pre></div>
+</div>
+<p><strong>Specify the shell type</strong></p>
+<p>To specify the shell type used on the nodes returned by a search query:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife ssh roles:opscode-omnitruck macterm
+</pre></div>
+</div>
+<p>where <tt class="docutils literal"><span class="pre">screen</span></tt> is one of the following values: <tt class="docutils literal"><span class="pre">cssh</span></tt>, <tt class="docutils literal"><span class="pre">interactive</span></tt>, <tt class="docutils literal"><span class="pre">macterm</span></tt>, <tt class="docutils literal"><span class="pre">screen</span></tt>, or <tt class="docutils literal"><span class="pre">tmux</span></tt>. If the node does not have the shell type installed, Knife will return an error similar to the following:</p>
+<div class="highlight-bash"><div class="highlight"><pre>you need the rb-appscript gem to use knife ssh macterm.
+<span class="sb">`</span><span class="o">(</span>sudo<span class="o">)</span> gem install rb-appscript<span class="sb">`</span> to install
+ERROR: LoadError: cannot load such file -- appscript
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_status.html b/distro/common/html/knife_status.html
new file mode 100644
index 0000000000..ab4e11400d
--- /dev/null
+++ b/distro/common/html/knife_status.html
@@ -0,0 +1,142 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife status &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-status">
+<h1>knife status<a class="headerlink" href="#knife-status" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife status</strong> 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.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife status <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">QUERY</span></tt></dt>
+<dd>The search query used to identify a a list of items on a server. This option uses the same syntax as the <tt class="docutils literal"><span class="pre">search</span></tt> sub-command.</dd>
+<dt><tt class="docutils literal"><span class="pre">-H</span></tt>, <tt class="docutils literal"><span class="pre">--hide-healthy</span></tt></dt>
+<dd>Indicates that nodes on which a chef-client run has occurred within the previous hour will be hidden.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span> <span class="pre">RUN_LIST</span></tt>, <tt class="docutils literal"><span class="pre">--run-list</span> <span class="pre">RUN_LIST</span></tt></dt>
+<dd>A comma-separated list of roles and/or recipes to be applied.</dd>
+<dt><tt class="docutils literal"><span class="pre">-s</span></tt>, <tt class="docutils literal"><span class="pre">--sort-reverse</span></tt></dt>
+<dd>Indicates that the list will be sorted by last run time, descending.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View status, include run-lists</strong></p>
+<p>To include run lists in the status, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife status --run-list
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>20 hours ago, dev-vm.chisamore.com, ubuntu 10.04, dev-vm.chisamore.com, 10.66.44.126, role<span class="o">[</span>lb<span class="o">]</span>.
+3 hours ago, i-225f954f, ubuntu 10.04, ec2-67-202-63-102.compute-1.amazonaws.com, 67.202.63.102, role<span class="o">[</span>web<span class="o">]</span>.
+3 hours ago, i-a45298c9, ubuntu 10.04, ec2-174-129-127-206.compute-1.amazonaws.com, 174.129.127.206, role<span class="o">[</span>web<span class="o">]</span>.
+3 hours ago, i-5272a43f, ubuntu 10.04, ec2-184-73-9-250.compute-1.amazonaws.com, 184.73.9.250, role<span class="o">[</span>web<span class="o">]</span>.
+3 hours ago, i-226ca64f, ubuntu 10.04, ec2-75-101-240-230.compute-1.amazonaws.com, 75.101.240.230, role<span class="o">[</span>web<span class="o">]</span>.
+3 hours ago, i-f65c969b, ubuntu 10.04, ec2-184-73-60-141.compute-1.amazonaws.com, 184.73.60.141, role<span class="o">[</span>web<span class="o">]</span>.
+</pre></div>
+</div>
+<p><strong>View status using a date range</strong></p>
+<p>To show the status for nodes on which the chef-client did not run successfully within the past hour, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife status --hide-healthy
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>1 hour ago, i-256f884f, ubuntu 12.04, ec2-67-202-63-102.compute-1.amazonaws.com, 67.202.63.102, role<span class="o">[</span>web<span class="o">]</span>.
+1 hour ago, i-a47823c9, ubuntu 10.04, ec2-174-129-127-206.compute-1.amazonaws.com, 184.129.143.111, role<span class="o">[</span>lb<span class="o">]</span>.
+</pre></div>
+</div>
+<p><strong>View status using a query</strong></p>
+<p>To show the status of a subset of nodes that are returned by a specific query, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife status <span class="s2">&quot;role:web&quot;</span> --run-list
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>3 hours ago, i-225f954f, ubuntu 10.04, ec2-67-202-63-102.compute-1.amazonaws.com, 67.202.63.102, role<span class="o">[</span>web<span class="o">]</span>.
+3 hours ago, i-a45298c9, ubuntu 10.04, ec2-174-129-127-206.compute-1.amazonaws.com, 174.129.127.206, role<span class="o">[</span>web<span class="o">]</span>.
+3 hours ago, i-5272a43f, ubuntu 10.04, ec2-184-73-9-250.compute-1.amazonaws.com, 184.73.9.250, role<span class="o">[</span>web<span class="o">]</span>.
+3 hours ago, i-226ca64f, ubuntu 10.04, ec2-75-101-240-230.compute-1.amazonaws.com, 75.101.240.230, role<span class="o">[</span>web<span class="o">]</span>.
+3 hours ago, i-f65c969b, ubuntu 10.04, ec2-184-73-60-141.compute-1.amazonaws.com, 184.73.60.141, role<span class="o">[</span>web<span class="o">]</span>.
+</pre></div>
+</div>
+<p><strong>View status for all nodes</strong></p>
+<p>To view the status of all nodes in the organization, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife status
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>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
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_tag.html b/distro/common/html/knife_tag.html
new file mode 100644
index 0000000000..0aab5089b9
--- /dev/null
+++ b/distro/common/html/knife_tag.html
@@ -0,0 +1,140 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife tag &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-tag">
+<h1>knife tag<a class="headerlink" href="#knife-tag" title="Permalink to this headline">¶</a></h1>
+<p>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.</p>
+<p>The <strong>knife tag</strong> subcommand is used to apply tags to nodes on a server.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="create">
+<h2>create<a class="headerlink" href="#create" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">create</span></tt> argument is used to add one or more tags to a node.</p>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife tag create NODE_NAME <span class="o">[</span>TAG...<span class="o">]</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create tags</strong></p>
+<p>To create tags named &#8220;seattle&#8221;, &#8220;portland&#8221;, and &#8220;vancouver&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife tag create node seattle portland vancouver
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="delete">
+<h2>delete<a class="headerlink" href="#delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">delete</span></tt> argument is used to delete one or more tags from a node.</p>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife tag delete NODE_NAME <span class="o">[</span>TAG...<span class="o">]</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Delete tags</strong></p>
+<p>To delete tags named &#8220;denver&#8221; and &#8220;phoenix&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife tag delete node denver phoenix
+</pre></div>
+</div>
+<p>Type <tt class="docutils literal"><span class="pre">Y</span></tt> to confirm a deletion.</p>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> argument is used to list all of the tags that have been applied to a node.</p>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife tag list <span class="o">[</span>NODE_NAME...<span class="o">]</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>View a list of tags</strong></p>
+<p>To view the tags for a node named &#8220;devops_prod1&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife tag list devops_prod1
+</pre></div>
+</div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_upload.html b/distro/common/html/knife_upload.html
new file mode 100644
index 0000000000..b1a4de29a7
--- /dev/null
+++ b/distro/common/html/knife_upload.html
@@ -0,0 +1,155 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife upload &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-upload">
+<h1>knife upload<a class="headerlink" href="#knife-upload" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife upload</strong> 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 <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">diff</span></tt>, which can be used to see exactly what changes will be uploaded, and then <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">download</span></tt>, which does the opposite of <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">upload</span></tt>.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload <span class="o">[</span>PATTERN...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]diff</span></tt></dt>
+<dd>Indicates that only new and modified files will be uploaded. Set to <tt class="docutils literal"><span class="pre">false</span></tt> to upload all files. Default: <tt class="docutils literal"><span class="pre">true</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]force</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--force</span></tt> to upload roles, cookbooks, etc. even if the file in the directory is identical (by default, no <tt class="docutils literal"><span class="pre">POST</span></tt> or <tt class="docutils literal"><span class="pre">PUT</span></tt> is performed unless an actual change would be made). Default: <tt class="docutils literal"><span class="pre">--no-force</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]freeze</span></tt></dt>
+<dd>Indicates that a cookbook cannot be modified; any changes to this cookbook must be included as a new version. Only the <tt class="docutils literal"><span class="pre">--force</span></tt> option can override this setting. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-n</span></tt>, <tt class="docutils literal"><span class="pre">--dry-run</span></tt></dt>
+<dd>Indicates that no action is taken and that results are only printed out. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]purge</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--purge</span></tt> 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: <tt class="docutils literal"><span class="pre">--no-purge</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]recurse</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">--no-recurse</span></tt> to disable uploading a directory recursively. Default: <tt class="docutils literal"><span class="pre">--recurse</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default: <tt class="docutils literal"><span class="pre">everything</span></tt> / <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Upload the entire chef-repo</strong></p>
+<p>Browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload
+</pre></div>
+</div>
+<p>or from anywhere in the chef-repo, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload /
+</pre></div>
+</div>
+<p><strong>Upload the /cookbooks directory</strong></p>
+<p>Browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload cookbooks
+</pre></div>
+</div>
+<p>or from anywhere in the chef-repo, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload /cookbooks
+</pre></div>
+</div>
+<p><strong>Upload the /environments directory</strong></p>
+<p>Browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload environments
+</pre></div>
+</div>
+<p>or from anywhere in the chef-repo, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload /environments
+</pre></div>
+</div>
+<p><strong>Upload a single environment</strong></p>
+<p>Browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload environments/production.json
+</pre></div>
+</div>
+<p>or from the <tt class="docutils literal"><span class="pre">environments/</span></tt> directory, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload production.json
+</pre></div>
+</div>
+<p><strong>Upload the /roles directory</strong></p>
+<p>Browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload roles
+</pre></div>
+</div>
+<p>or from anywhere in the chef-repo, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload /roles
+</pre></div>
+</div>
+<p><strong>Upload cookbooks and roles</strong></p>
+<p>Browse to the top level of the chef-repo and enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload cookbooks/apache<span class="se">\*</span> roles/webserver.json
+</pre></div>
+</div>
+<p><strong>Use output of knife deps to pass command to knife upload</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife upload <span class="sb">`</span>knife deps nodes/*.json<span class="sb">`</span>
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_user.html b/distro/common/html/knife_user.html
new file mode 100644
index 0000000000..cd07585fc8
--- /dev/null
+++ b/distro/common/html/knife_user.html
@@ -0,0 +1,244 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife user &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-user">
+<h1>knife user<a class="headerlink" href="#knife-user" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife user</strong> subcommand is used to manage the list of users and their associated RSA public key-pairs.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">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.</p>
+</div>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<div class="section" id="create">
+<h2>create<a class="headerlink" href="#create" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">create</span></tt> 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 <tt class="docutils literal"><span class="pre">STDOUT</span></tt> or written to a named file.</p>
+<ul class="simple">
+<li>For the user, the private key should be copied to the system as <tt class="docutils literal"><span class="pre">/etc/chef/client.pem</span></tt>.</li>
+<li>For Knife, the private key is typically copied to <tt class="docutils literal"><span class="pre">~/.chef/client_name.pem</span></tt> and referenced in the knife.rb configuration file.</li>
+</ul>
+<div class="section" id="syntax">
+<h3>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user create USER_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h3>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--admin</span></tt></dt>
+<dd>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 Enterprise Chef.</dd>
+<dt><tt class="docutils literal"><span class="pre">-f</span> <span class="pre">FILE_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--file</span> <span class="pre">FILE_NAME</span></tt></dt>
+<dd>Indicates that the private key will be saved to a specified file name.</dd>
+<dt><tt class="docutils literal"><span class="pre">-p</span> <span class="pre">PASSWORD</span></tt>, <tt class="docutils literal"><span class="pre">--password</span> <span class="pre">PASSWORD</span></tt></dt>
+<dd>The user password.</dd>
+<dt><tt class="docutils literal"><span class="pre">--user-key</span> <span class="pre">FILE_NAME</span></tt></dt>
+<dd>All users are assigned a public key. Use to write the public key to a file.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Create a user</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user create <span class="s2">&quot;Radio Birdman&quot;</span> -f /keys/user_name
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="delete">
+<h2>delete<a class="headerlink" href="#delete" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">delete</span></tt> argument is used to delete a registered user.</p>
+<div class="section" id="id1">
+<h3>Syntax<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user delete USER_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id2">
+<h3>Options<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id3">
+<h3>Examples<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Delete a user</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user delete <span class="s2">&quot;Steve Danno&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="edit">
+<h2>edit<a class="headerlink" href="#edit" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">edit</span></tt> 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.</p>
+<div class="section" id="id4">
+<h3>Syntax<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user edit USER_NAME
+</pre></div>
+</div>
+</div>
+<div class="section" id="id5">
+<h3>Options<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
+<p>This command does not have any specific options.</p>
+</div>
+<div class="section" id="id6">
+<h3>Examples<a class="headerlink" href="#id6" title="Permalink to this headline">¶</a></h3>
+<p>None.</p>
+</div>
+</div>
+<div class="section" id="list">
+<h2>list<a class="headerlink" href="#list" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">list</span></tt> argument is used to view a list of registered users.</p>
+<div class="section" id="id7">
+<h3>Syntax<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user list <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id8">
+<h3>Options<a class="headerlink" href="#id8" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-w</span></tt>, <tt class="docutils literal"><span class="pre">--with-uri</span></tt></dt>
+<dd>Indicates that the corresponding URIs will be shown.</dd>
+</dl>
+</div>
+<div class="section" id="id9">
+<h3>Examples<a class="headerlink" href="#id9" title="Permalink to this headline">¶</a></h3>
+<p>None.</p>
+</div>
+</div>
+<div class="section" id="reregister">
+<h2>reregister<a class="headerlink" href="#reregister" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">reregister</span></tt> 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 <tt class="docutils literal"><span class="pre">STDOUT</span></tt> or written to a named file.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Running this argument will invalidate the previous RSA key pair, making it unusable during authentication to the server.</p>
+</div>
+<div class="section" id="id10">
+<h3>Syntax<a class="headerlink" href="#id10" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user reregister USER_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id11">
+<h3>Options<a class="headerlink" href="#id11" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-f</span> <span class="pre">FILE_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--file</span> <span class="pre">FILE_NAME</span></tt></dt>
+<dd>Indicates that the private key will be saved to a specified file name.</dd>
+</dl>
+</div>
+<div class="section" id="id12">
+<h3>Examples<a class="headerlink" href="#id12" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Regenerate the RSA key-pair</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user reregister <span class="s2">&quot;Robert Younger&quot;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="show">
+<h2>show<a class="headerlink" href="#show" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">show</span></tt> argument is used to show the details of a user.</p>
+<div class="section" id="id13">
+<h3>Syntax<a class="headerlink" href="#id13" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user show USER_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="id14">
+<h3>Options<a class="headerlink" href="#id14" title="Permalink to this headline">¶</a></h3>
+<p>This argument has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">ATTR</span></tt></dt>
+<dd>The attribute (or attributes) to show.</dd>
+</dl>
+</div>
+<div class="section" id="id15">
+<h3>Examples<a class="headerlink" href="#id15" title="Permalink to this headline">¶</a></h3>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Show user data</strong></p>
+<p>To view a user named &#8220;Dennis Teck&#8221;, enter:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user show <span class="s2">&quot;Dennis Teck&quot;</span>
+</pre></div>
+</div>
+<p>to return something like:</p>
+<div class="highlight-bash"><div class="highlight"><pre>chef_type: user
+json_class: Chef::User
+name: Dennis Teck
+public_key:
+</pre></div>
+</div>
+<p><strong>Show user data as JSON</strong></p>
+<p>To view information in JSON format, use the <tt class="docutils literal"><span class="pre">-F</span></tt> common option as part of the command like this:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife user show <span class="s2">&quot;Dennis Teck&quot;</span> -F json
+</pre></div>
+</div>
+<p>(Other formats available include <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, and <tt class="docutils literal"><span class="pre">pp</span></tt>, e.g. <tt class="docutils literal"><span class="pre">-F</span> <span class="pre">yaml</span></tt> for YAML.)</p>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_using.html b/distro/common/html/knife_using.html
new file mode 100644
index 0000000000..d22557e466
--- /dev/null
+++ b/distro/common/html/knife_using.html
@@ -0,0 +1,211 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Working with Knife &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="working-with-knife">
+<h1>Working with Knife<a class="headerlink" href="#working-with-knife" title="Permalink to this headline">¶</a></h1>
+<p>Knife runs from a management workstation and sits in-between a server and an organization&#8217;s infrastructure. Knife interacts with a server by using the same REST API that is used by a chef-client. Role-based authentication controls (RBAC) can be used to authorize changes when Knife is run with Enterprise Chef. Knife is configured during workstation setup, but subsequent modifications can be made using the knife.rb configuration file.</p>
+<div class="section" id="json-data-format">
+<h2>JSON Data Format<a class="headerlink" href="#json-data-format" title="Permalink to this headline">¶</a></h2>
+<p>Most data is entered using a text editor in JSON format, unless the <tt class="docutils literal"><span class="pre">--disable-editing</span></tt> option is entered as part of a command. (Encrypted data bags use YAML, which is a superset of JSON.) JSON is a common, language-independent data format that provides a simple text representation of arbitrary data structures. For more information about JSON, see <a class="reference external" href="http://www.json.org/">http://www.json.org/</a> or <a class="reference external" href="http://en.wikipedia.org/wiki/JSON">http://en.wikipedia.org/wiki/JSON</a>.</p>
+<div class="section" id="set-the-text-editor">
+<h3>Set the Text Editor<a class="headerlink" href="#set-the-text-editor" title="Permalink to this headline">¶</a></h3>
+<p>Some Knife commands, such as <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">data</span> <span class="pre">bag</span> <span class="pre">edit</span></tt>, require that information be edited as JSON data using a text editor. For example, the following command:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife data bag edit admins admin_name
+</pre></div>
+</div>
+<p>will open up the text editor with data similar to:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;id&quot;</span><span class="o">:</span> <span class="s2">&quot;admin_name&quot;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Changes to that file can then be made:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;id&quot;</span><span class="o">:</span> <span class="s2">&quot;Justin C.&quot;</span>
+ <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;I am passing the time by letting time pass over me ...&quot;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>The type of text editor that is used by Knife can be configured by adding an entry to the knife.rb file or by setting an <tt class="docutils literal"><span class="pre">EDITOR</span></tt> environment variable. For example, to configure the text editor to always open with vim, add the following to the knife.rb file:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">knife</span><span class="o">[</span><span class="ss">:editor</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/vim&quot;</span>
+</pre></div>
+</div>
+<p>When a Microsoft Windows file path is enclosed in a double-quoted string (&#8221; &#8221;), the same backslash character (<tt class="docutils literal"><span class="pre">\</span></tt>) that is used to define the file path separator is also used in Ruby to define an escape character. The knife.rb file is a Ruby file; therefore, file path separators must be escaped. In addition, spaces in the file path must be replaced with <tt class="docutils literal"><span class="pre">~1</span></tt> so that the length of each section within the file path is not more than 8 characters. For example, if EditPad Pro is the text editor of choice and is located at the following path:</p>
+<div class="highlight-python"><pre>C:\\Program Files (x86)\EditPad Pro\EditPad.exe</pre>
+</div>
+<p>the setting in the knife.rb file would be similar to:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">knife</span><span class="o">[</span><span class="ss">:editor</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;C:</span><span class="se">\\</span><span class="s2">Progra~1</span><span class="se">\\</span><span class="s2">EditPa~1</span><span class="se">\\</span><span class="s2">EditPad.exe&quot;</span>
+</pre></div>
+</div>
+<p>One approach to working around the double- vs. single-quote issue is to put the single-quotes outside of the double-quotes. For example, for Notepad++:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">knife</span><span class="o">[</span><span class="ss">:editor</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;&quot;C:\Program Files (x86)\Notepad++\notepad++.exe -nosession -multiInst&quot;&#39;</span>
+</pre></div>
+</div>
+<p>for Sublime Text:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">knife</span><span class="o">[</span><span class="ss">:editor</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;&quot;C:\Program Files\Sublime Text 2\sublime_text.exe --wait&quot;&#39;</span>
+</pre></div>
+</div>
+<p>for TextPad:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">knife</span><span class="o">[</span><span class="ss">:editor</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;&quot;C:\Program Files (x86)\TextPad 7\TextPad.exe&quot;&#39;</span>
+</pre></div>
+</div>
+<p>and for vim:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">knife</span><span class="o">[</span><span class="ss">:editor</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;&quot;C:\Program Files (x86)\vim\vim74\gvim.exe&quot;&#39;</span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="using-quotes">
+<h2>Using Quotes<a class="headerlink" href="#using-quotes" title="Permalink to this headline">¶</a></h2>
+<p>Values can be entered with double quotes (&#8221; &#8221;) or single quotes (&#8216; &#8216;), but this should be done consistently.</p>
+</div>
+<div class="section" id="sub-commands">
+<h2>Sub-commands<a class="headerlink" href="#sub-commands" title="Permalink to this headline">¶</a></h2>
+<p>Knife comes with a collection of built in subcommands that work together to provide all of the functionality required to take specific actions against any object in an organization, including cookbooks, nodes, roles, data bags, environments, and users. A Knife plugin extends the functionality beyond built-in subcommands.</p>
+<p>Knife has the following subcommands: <tt class="docutils literal"><span class="pre">bootstrap</span></tt>, <tt class="docutils literal"><span class="pre">client</span></tt>, <tt class="docutils literal"><span class="pre">configure</span></tt>, <tt class="docutils literal"><span class="pre">cookbook</span></tt>, <tt class="docutils literal"><span class="pre">cookbook</span> <span class="pre">site</span></tt>, <tt class="docutils literal"><span class="pre">data</span> <span class="pre">bag</span></tt>, <tt class="docutils literal"><span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">deps</span></tt>, <tt class="docutils literal"><span class="pre">diff</span></tt>, <tt class="docutils literal"><span class="pre">download</span></tt>, <tt class="docutils literal"><span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">environment</span></tt>, <tt class="docutils literal"><span class="pre">exec</span></tt>, <tt class="docutils literal"><span class="pre">index</span> <span class="pre">rebuild</span></tt>, <tt class="docutils literal"><span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">node</span></tt>, <tt class="docutils literal"><span class="pre">recipe</span> <span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">role</span></tt>, <tt class="docutils literal"><span class="pre">search</span></tt>, <tt class="docutils literal"><span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">ssh</span></tt>, <tt class="docutils literal"><span class="pre">status</span></tt>, <tt class="docutils literal"><span class="pre">tag</span></tt>, <tt class="docutils literal"><span class="pre">upload</span></tt>, <tt class="docutils literal"><span class="pre">user</span></tt>, and <tt class="docutils literal"><span class="pre">xargs</span></tt>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">The following subcommands run only against the open source server: <tt class="docutils literal"><span class="pre">index</span> <span class="pre">rebuild</span></tt> and <tt class="docutils literal"><span class="pre">user</span></tt>.</p>
+</div>
+</div>
+<div class="section" id="verb-sub-commands">
+<h2>Verb Sub-commands<a class="headerlink" href="#verb-sub-commands" title="Permalink to this headline">¶</a></h2>
+<p>Knife includes a set of subcommands that are built around common verbs: <tt class="docutils literal"><span class="pre">delete</span></tt>, <tt class="docutils literal"><span class="pre">deps</span></tt>, <tt class="docutils literal"><span class="pre">diff</span></tt>, <tt class="docutils literal"><span class="pre">download</span></tt>, <tt class="docutils literal"><span class="pre">edit</span></tt>, <tt class="docutils literal"><span class="pre">list</span></tt>, <tt class="docutils literal"><span class="pre">show</span></tt>, <tt class="docutils literal"><span class="pre">upload</span></tt>, <tt class="docutils literal"><span class="pre">xargs</span></tt>. These subcommands allow Knife to issue commands that interact with any object stored in the chef-repo or stored on the server. Some important principles behind this group of subcommands includes:</p>
+<ul class="simple">
+<li>A command that works with each object in the chef-repo. The subcommands specify the desired action (the &#8220;verb&#8221;), and then directory in which that object resides (<tt class="docutils literal"><span class="pre">clients</span></tt>, <tt class="docutils literal"><span class="pre">cookbooks/</span></tt>, <tt class="docutils literal"><span class="pre">data_bags/</span></tt>, <tt class="docutils literal"><span class="pre">environments/</span></tt>, <tt class="docutils literal"><span class="pre">nodes</span></tt>, <tt class="docutils literal"><span class="pre">roles/</span></tt>, and <tt class="docutils literal"><span class="pre">users</span></tt>). For example: <tt class="docutils literal"><span class="pre">download</span> <span class="pre">cookbooks/</span></tt></li>
+<li>A command that works with certain objects in Enterprise Chef, including <tt class="docutils literal"><span class="pre">acls</span></tt>, <tt class="docutils literal"><span class="pre">groups</span></tt>, and <tt class="docutils literal"><span class="pre">containers</span></tt></li>
+<li>Uses the server as if it were a file system, allowing the chef-repo on the server to behave like a mirror of the chef-repo on the workstation. The server will have the same objects as the local chef-repo. To make changes to the files on the server, just download files from the server or upload files from the chef-repo</li>
+<li>The context from which a command is run matters. For example, when working in the <tt class="docutils literal"><span class="pre">roles/</span></tt> directory, Knife will know what is being worked with. Enter <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">show</span> <span class="pre">base.json</span></tt> and Knife will return the base role from the server. From the chef-repo root, enter <tt class="docutils literal"><span class="pre">knife</span> <span class="pre">show</span> <span class="pre">roles/base.json</span></tt> to get the same result</li>
+<li>Parallel requests can be made to the server and are configurable on a per-command basis</li>
+</ul>
+<div class="section" id="wildcard-search">
+<h3>Wildcard Search<a class="headerlink" href="#wildcard-search" title="Permalink to this headline">¶</a></h3>
+<p>A wildcard matching pattern can be used for substring matches that replace zero (or more) characters. There are two types of wildcard patterns:</p>
+<ul class="simple">
+<li>A question mark (”?”) can be used to replace exactly one character (as long as that character is not the first character)</li>
+<li>An asterisk (“*”) can be used to replace any number of characters (including zero)</li>
+</ul>
+<p>Wildcard patterns must be escaped (using a backslash) so that the wildcard itself can reach the server. If they are not escaped, the wildcard is expanded into the actual filenames and Knife will not know the wildcard was intended to be used. For example, if the server has data bags named <tt class="docutils literal"><span class="pre">aardvarks</span></tt>, <tt class="docutils literal"><span class="pre">anagrams</span></tt>, and <tt class="docutils literal"><span class="pre">arp_tables</span></tt>, but the local file system only has <tt class="docutils literal"><span class="pre">aardvarks</span></tt> and <tt class="docutils literal"><span class="pre">anagrams</span></tt>, escaping vs. not escaping the wildcard pattern will yield different results:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife list data_bags/a<span class="se">\*</span>
+</pre></div>
+</div>
+<p>asks the server for everything starting with the letter &#8220;a&#8221; and will return:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>aardvarks/ anagrams/ arp_tables/
+</pre></div>
+</div>
+<p>But, the following:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife list data_bags/a*
+</pre></div>
+</div>
+<p>will return:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>aardvarks/ anagrams/
+</pre></div>
+</div>
+<p>Which is the same as entering:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife list data_bags/aardvarks data_bags/anagrams
+</pre></div>
+</div>
+<p>to return:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>aardvarks/ anagrams/
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="plug-ins">
+<h2>Plug-ins<a class="headerlink" href="#plug-ins" title="Permalink to this headline">¶</a></h2>
+<p>Chef provides the following plugins, which work the same as built-in subcommands (including common options), but must be installed separately (using RubyGems): <strong>knife azure</strong>, <strong>knife bluebox</strong>, <strong>knife ec2</strong>, <strong>knife eucalyptus</strong>, <strong>knife google</strong>, <strong>knife hp</strong>, <strong>knife linode</strong>, <strong>knife openstack</strong>, <strong>knife rackspace</strong>, <strong>knife terremark</strong>, <strong>knife vcloud</strong>, and <strong>knife windows</strong>.</p>
+<p>The community provides many other plugins for Knife: <a class="reference external" href="http://community.opscode.com/">http://community.opscode.com/</a>.</p>
+</div>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>All Knife subcommands have the following syntax:</p>
+<blockquote>
+<div>knife subcommand [ARGUMENT] (options)</div></blockquote>
+<p>Each subcommand has its own set of arguments and options.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">All syntax examples in this document show variables in ALL_CAPS. For example <tt class="docutils literal"><span class="pre">-u</span> <span class="pre">PORT_LIST</span></tt> (where PORT_LIST is a comma-separated list of local and public UDP ports) or <tt class="docutils literal"><span class="pre">-F</span> <span class="pre">FORMAT</span></tt> (where FORMAT determines the output format, either <tt class="docutils literal"><span class="pre">summary</span></tt>, <tt class="docutils literal"><span class="pre">text</span></tt>, <tt class="docutils literal"><span class="pre">json</span></tt>, <tt class="docutils literal"><span class="pre">yaml</span></tt>, or <tt class="docutils literal"><span class="pre">pp</span></tt>). These variables often require specific values that are unique to each organization.</p>
+</div>
+</div>
+<div class="section" id="many-users-same-repo">
+<h2>Many Users, Same Repo<a class="headerlink" href="#many-users-same-repo" title="Permalink to this headline">¶</a></h2>
+<p>It is possible for multiple users to access the server using the same knife.rb file. (A user can even access multiple organizations if, for example, each instance of the chef-repo contained the same copy of the knife.rb file.) This can be done by adding the knife.rb file to the chef-repo, and then using environment variables to handle the user-specific credential details and/or sensitive values. For example:</p>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">current_dir</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">)</span>
+ <span class="n">user</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;OPSCODE_USER&#39;</span><span class="o">]</span> <span class="o">||</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;USER&#39;</span><span class="o">]</span>
+ <span class="n">node_name</span> <span class="n">user</span>
+ <span class="n">client_key</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;HOME&#39;</span><span class="o">]</span><span class="si">}</span><span class="s2">/.chef/</span><span class="si">#{</span><span class="n">user</span><span class="si">}</span><span class="s2">.pem&quot;</span>
+ <span class="n">validation_client_name</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;ORGNAME&#39;</span><span class="o">]</span><span class="si">}</span><span class="s2">-validator&quot;</span>
+ <span class="n">validation_key</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;HOME&#39;</span><span class="o">]</span><span class="si">}</span><span class="s2">/.chef/</span><span class="si">#{</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;ORGNAME&#39;</span><span class="o">]</span><span class="si">}</span><span class="s2">-validator.pem&quot;</span>
+ <span class="n">chef_server_url</span> <span class="s2">&quot;https://api.opscode.com/organizations/</span><span class="si">#{</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;ORGNAME&#39;</span><span class="o">]</span><span class="si">}</span><span class="s2">&quot;</span>
+ <span class="n">syntax_check_cache_path</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;HOME&#39;</span><span class="o">]</span><span class="si">}</span><span class="s2">/.chef/syntax_check_cache&quot;</span>
+ <span class="n">cookbook_path</span> <span class="o">[</span><span class="s2">&quot;</span><span class="si">#{</span><span class="n">current_dir</span><span class="si">}</span><span class="s2">/../cookbooks&quot;</span><span class="o">]</span>
+ <span class="n">cookbook_copyright</span> <span class="s2">&quot;Your Company, Inc.&quot;</span>
+ <span class="n">cookbook_license</span> <span class="s2">&quot;apachev2&quot;</span>
+ <span class="n">cookbook_email</span> <span class="s2">&quot;cookbooks@yourcompany.com&quot;</span>
+
+ <span class="c1"># Amazon AWS</span>
+ <span class="n">knife</span><span class="o">[</span><span class="ss">:aws_access_key_id</span><span class="o">]</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;AWS_ACCESS_KEY_ID&#39;</span><span class="o">]</span>
+ <span class="n">knife</span><span class="o">[</span><span class="ss">:aws_secret_access_key</span><span class="o">]</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;AWS_SECRET_ACCESS_KEY&#39;</span><span class="o">]</span>
+
+ <span class="c1"># Rackspace Cloud</span>
+ <span class="n">knife</span><span class="o">[</span><span class="ss">:rackspace_api_username</span><span class="o">]</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;RACKSPACE_USERNAME&#39;</span><span class="o">]</span>
+ <span class="n">knife</span><span class="o">[</span><span class="ss">:rackspace_api_key</span><span class="o">]</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;RACKSPACE_API_KEY&#39;</span><span class="o">]</span>
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/knife_xargs.html b/distro/common/html/knife_xargs.html
new file mode 100644
index 0000000000..d6071137f5
--- /dev/null
+++ b/distro/common/html/knife_xargs.html
@@ -0,0 +1,115 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>knife xargs &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+ <div class="section" id="knife-xargs">
+<h1>knife xargs<a class="headerlink" href="#knife-xargs" title="Permalink to this headline">¶</a></h1>
+<p>The <strong>knife xargs</strong> subcommand is used to build and execute command lines against objects on a server using standard input.</p>
+<div class="section" id="syntax">
+<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
+<p>This argument has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife xargs <span class="o">[</span>PATTERN...<span class="o">]</span> <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="options">
+<h2>Options<a class="headerlink" href="#options" title="Permalink to this headline">¶</a></h2>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Review the list of <a class="reference internal" href="knife_common_options.html"><em>common options</em></a> available to this (and all) Knife subcommands and plugins.</p>
+</div>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">-0</span></tt></dt>
+<dd>Indicates that a <tt class="docutils literal"><span class="pre">NULL</span></tt> character (<tt class="docutils literal"><span class="pre">\0</span></tt>) will be used as a separator, instead of white space. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--chef-repo-path</span> <span class="pre">PATH</span></tt></dt>
+<dd>The path to the chef-repo. This setting will override the default path to the chef-repo. Default: same as specified by <tt class="docutils literal"><span class="pre">chef_repo_path</span></tt> in config.rb.</dd>
+<dt><tt class="docutils literal"><span class="pre">--concurrency</span></tt></dt>
+<dd>The number of allowed concurrent connections. Default: <tt class="docutils literal"><span class="pre">10</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]diff</span></tt></dt>
+<dd>Use to show a diff when a file changes. Default: <tt class="docutils literal"><span class="pre">--diff</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--dry-run</span></tt></dt>
+<dd>Use to prevent changes from being uploaded to the server. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]force</span></tt></dt>
+<dd>Use to force the upload of files even if they haven&#8217;t been changed. Default: <tt class="docutils literal"><span class="pre">--no-force</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--local</span></tt></dt>
+<dd>Indicates that a command line will be built or executed against a local file. Set to <tt class="docutils literal"><span class="pre">false</span></tt> to build or execute against a remote file. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-n</span> <span class="pre">MAX_ARGS</span></tt>, <tt class="docutils literal"><span class="pre">--max-args</span> <span class="pre">MAX_ARGS</span></tt></dt>
+<dd>The maximum number of arguments per command line. Default: <tt class="docutils literal"><span class="pre">nil</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-s</span> <span class="pre">LENGTH</span></tt>, <tt class="docutils literal"><span class="pre">--max-chars</span> <span class="pre">LENGTH</span></tt></dt>
+<dd>The maximum size (in characters) for a command line. Default: <tt class="docutils literal"><span class="pre">nil</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-p</span> <span class="pre">[PATTERN...]</span></tt>, <tt class="docutils literal"><span class="pre">--pattern</span> <span class="pre">[PATTERN...]</span></tt></dt>
+<dd>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: <tt class="docutils literal"><span class="pre">nil</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-I</span> <span class="pre">REPLACE_STRING</span></tt>, <tt class="docutils literal"><span class="pre">--replace</span> <span class="pre">REPLACE_STRING</span></tt></dt>
+<dd>Use to define a string that will be used to replace all occurrences of a file name. Default: <tt class="docutils literal"><span class="pre">nil</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-J</span> <span class="pre">REPLACE_STRING</span></tt>, <tt class="docutils literal"><span class="pre">--replace-first</span> <span class="pre">REPLACE_STRING</span></tt></dt>
+<dd>Use to define a string that will be used to replace the first occurrence of a file name. Default: <tt class="docutils literal"><span class="pre">nil</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--repo-mode</span> <span class="pre">MODE</span></tt></dt>
+<dd>The layout of the local chef-repo. Possible values: <tt class="docutils literal"><span class="pre">static</span></tt>, <tt class="docutils literal"><span class="pre">everything</span></tt>, or <tt class="docutils literal"><span class="pre">hosted_everything</span></tt>. Use <tt class="docutils literal"><span class="pre">static</span></tt> for just roles, environments, cookbooks, and data bags. By default, <tt class="docutils literal"><span class="pre">everything</span></tt> and <tt class="docutils literal"><span class="pre">hosted_everything</span></tt> are dynamically selected depending on the server type. Default value: <tt class="docutils literal"><span class="pre">default</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-t</span></tt></dt>
+<dd>Indicates that the print command will be run on the command line. Default: <tt class="docutils literal"><span class="pre">nil</span></tt>.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
+<p>The following examples show how to use this Knife subcommand:</p>
+<p><strong>Use output of knife deps to pass command to knife xargs</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>knife deps nodes/*.json | xargs knife upload
+</pre></div>
+</div>
+</div>
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/objects.inv b/distro/common/html/objects.inv
new file mode 100644
index 0000000000..2dbcd31810
--- /dev/null
+++ b/distro/common/html/objects.inv
Binary files differ
diff --git a/distro/common/html/search.html b/distro/common/html/search.html
new file mode 100644
index 0000000000..fdb4be6edc
--- /dev/null
+++ b/distro/common/html/search.html
@@ -0,0 +1,84 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Search &mdash; chef-client Man Pages</title>
+
+ <link rel="stylesheet" href="_static/guide.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '',
+ VERSION: '',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/searchtools.js"></script>
+ <link rel="shortcut icon" href="_static/chef.ico"/>
+
+
+ </head>
+ <body>
+<div style="background-color: #212c35; text-align: left; padding: 0px 0px 0px 0px">
+<a href="http://docs.opscode.com/"><img src="_static/chef_html_logo.png" border="0" alt="Chef"/></a>
+</div>
+
+
+
+
+ <div class="document">
+ <div class="documentwrapper">
+
+ <div class="body">
+
+
+<h1 id="search-documentation">Search the Documentation for Chef</h1>
+
+<div class="container">
+
+<p>
+From here you can use a scoped Google search query to search all of the documentation about Chef that is located at docs.opscode.com. (This page requires JavaScript be enabled to view the search box.)
+</p>
+
+<!-- Place this tag where you want both of the search box and the search results to render -->
+<gcse:search defaultToRefinement="Chef Documentation" webSearchResultSetSize="20"></gcse:search>
+
+&nbsp;<br>
+&nbsp;<br>
+&nbsp;<br>
+&nbsp;<br>
+&nbsp;<br>
+
+&nbsp;<br>
+&nbsp;<br>
+&nbsp;<br>
+&nbsp;<br>
+&nbsp;<br>
+
+</div>
+
+
+ </div>
+
+ </div>
+
+
+ <div class="clearer"></div>
+ </div>
+
+
+
+
+ </body>
+</html> \ No newline at end of file
diff --git a/distro/common/html/searchindex.js b/distro/common/html/searchindex.js
new file mode 100644
index 0000000000..f846b10631
--- /dev/null
+++ b/distro/common/html/searchindex.js
@@ -0,0 +1 @@
+Search.setIndex({objects:{},terms:{kickstart:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],perl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chisamor:12,poorli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],prefix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dirnam:24,rsyslog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],oldest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],whose:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],accur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],service_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],umask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chef_typ:[0,14,28,29,4,7,18],under:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],slowest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],everi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_maintain:5,upstream:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],affect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ibm305ramac:1,csshx:30,cmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],upload:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rabbitmq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rabbitmqctl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],verif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],x86_64:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],proxy_url:27,hord:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_java:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hint_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],direct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],consequ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],second:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],street:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aggreg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ips_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],start_chef:27,blue:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hide:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],eventlet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],asid:25,dism:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"new":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],net:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],topolog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],metadata:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],supervisor_servic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],default_attribut:[4,0],manipul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],run_list_item:[29,9,31],never:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],macports_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],here:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],num_vers:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],recipe_nam:[29,0],path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],print_aft:[],interpret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hosted_everyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dry:[6,32,26],erl_cal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],runlist:[9,31],brought:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],substr:24,unix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],printf:1,hipchat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],txt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],describ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],would:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bundler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],call:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],asset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],recommend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],indiana:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],envdir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],until:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fastcgi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],relat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],server_url:25,notic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],warn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],exce:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],relai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],killal:31,hold:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],must:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gecod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],join:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],orgnam:[24,18,27],setup:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],work:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bluebox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],raid1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],erb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fnmatch:28,root:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ss6p92l_sca:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],minfd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],overrid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],give:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],smtp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],elrepo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],indic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],want:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],end:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],quot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vagrant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],how:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],env:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],place:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],config:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],checkin:1,updat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],after:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hide_healthi:[],lab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],befor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windows_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],arch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],parallel:[13,30,19,24],demonstr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],request_path:14,attempt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],client_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],opaqu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bootstrap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],credenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],python_virtualenv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],exclud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alias:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],maintain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],environ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],danno:7,enter:[12,20,31,0,14,1,29,30,15,28,4,5,6,32,7,34,17,24,33,18],order:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],oper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],over:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],php_pear:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],becaus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],privileg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vari:[33,27],cli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],generic_execut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],denver:34,better:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],persist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hidden:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],erlang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windowsreboothandl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],them:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],woken:31,thei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fragment:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rackspaceknif:5,"40g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],choic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],etag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],changelog:28,use_sudo:[],languages_ruby_vers:15,timeout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],each:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],debug:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],search_queri:[30,15,5],eacc:31,side:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mean:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],voxel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssh_user:[],log_loc:27,extract:[6,9,19,13],linod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unshar:5,network:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reg_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],god:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],newli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],content:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rewrit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],devops_prod1:34,billing_admin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],erubi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],http_request:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],putti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gunicorn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ntp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],multilib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],free:1,standard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],qword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],node1:29,kit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"1_0_0":5,"1_0_1":5,"1_0_2":5,"1_0_3":5,reconfigur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sigkil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reg_dword_big_endian:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],whateverthedefaultmightb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],openssh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],openssl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],filter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iso:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],isn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nosess:24,pristin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rang:[12,15],render:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mkdir:27,cron_d:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],system:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],restrict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hook:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hkey_classes_root:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alreadi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],messag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],apt_repositori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],agre:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],primari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],role1:0,tinydn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],top:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sometim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mercuri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],master:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],too:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],amqp_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],listen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cloudform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iptabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],consol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"8wjyvhy9fhcegaareg":33,namespac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],erchef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"0a58cf8":15,yield:24,"10g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bookshelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],task:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],max_arg:26,auxw:31,target:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],provid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tree:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],zero:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],project:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],matter:24,gnupg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],british_sea_pow:27,minut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],provis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],abov:27,ram:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mine:27,unicast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],raw:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],seed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_rubi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],environment_nam:[9,4,23],client:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chefservicefeatur:27,even:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],template_fil:[],though:29,usernam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],glob:28,object:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],regular:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],s001:31,specifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],letter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],breakpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],don:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],doc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],doe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_licens:24,wildcard:[20,15,23,24],teck:7,enclos:24,unchang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],runit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],opposit:[6,13,19,32],whitelist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],random:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ruby_block:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],syntax:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],radio:7,identifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dhcpserver:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],make:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],celeri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],absolut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bind:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],layout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"0a58e134":15,holder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fstab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],apach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lwrp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ldap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],folder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],oct:30,firewall_rul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],likewis:5,stop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],amazon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],servermanagercmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],report:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],youtub:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"public":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],runa:31,reload:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],respond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_python_django:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],groupinstal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],homedr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],num:30,mandatori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],result:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],respons:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],noinput:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],key_fil:31,mdadm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],best:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rsa_kei:18,awar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],said:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],databas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],multiinst:24,wikipedia:24,discoveri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],irb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],irc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],approach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],databag:14,attribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],extend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],extens:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],host_key_verifi:[],toler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],advertis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],protect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],metadta:28,easi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],met:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],howev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],against:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fedora13:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],logic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],countri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],login:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stopsign:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],com:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],publishset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],excess:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_descript:5,usr2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],your_email:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],usr1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],diff:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trust:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],assum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],duplic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chrome:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fri:30,patch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],three:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],webpi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trigger:31,basic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],homepath:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hesit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],quickli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],life:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],file_edit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],suppress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],worker:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],telnet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ani:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],verify_api_cert:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_java_tomcat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],child:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"catch":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],no_dep:[],ident:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],data_bag_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gnu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],servic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],properti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],calcul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dashboard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nexenta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cont:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],remount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],player:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],attribute_nam:29,conf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sever:15,cookbook_vers:[4,5,28],growl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],perform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],suggest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],use_last_modifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],couchdb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],preserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],descend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],djbdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],complet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],raid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],orgmapp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rais:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],portal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unicorn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tune:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mirror_expir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],kept:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],scenario:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"30t21":5,inherit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],contact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],thi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gzip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],everyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],left:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],protocol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],just:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sigusr1:31,bandwidth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],qr_knife_web:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],human:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],name_of_servic:17,yet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],languag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],previous:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mod_php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],had:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],macport:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],save:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ubuntu12:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ubuntu10:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],opt:1,applic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],supervisord:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],metabas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fusion:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"256f884f":12,shadow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],daemon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],specif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],deprec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nrpe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],arbitrari:[13,33,19,24],manual:[30,31],graylog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],deploy_revis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],public_kei:[7,18],sublime_text:24,grizzli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],underli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],multi_str:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],right:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_python_celeri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],interv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],percentag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],intern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],user_kei:[],successfulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],transmiss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],knife_config:27,total:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],setloc:27,fidel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tornado:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],select:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],condit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],script_fil:1,localhost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],core:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],plu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],uncompress:5,repositori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],peer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],post:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"super":31,subkei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],plug:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],postgresql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],surround:[13,0,28,29,3,19,18],birdman:7,svn_argument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],horizon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],commit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssh_port:[],"float":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],profession:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],www:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],value_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],run_list:[12,29,27,0,1],storag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],git:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],wai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],support:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nova:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],why:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],avail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reli:27,gid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],wordpress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],editor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],war:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fork:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],head:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],noevict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],form:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],forc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],macterm:30,transmission_torrent_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],useradd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"25t23":5,"true":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],wmi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],attr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],type:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unpin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],maximum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mtu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],inaccur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],solaris_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],opensus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],featur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],openbsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_php_php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],decrypt:33,exist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],glanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ship:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],check:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sticki:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],assembl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vista:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],groupmod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],encrypt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],when:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],actor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],win_wget_p:27,role:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],test:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],roll:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],node:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],notif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],intend:24,phoenix:34,null_separ:[],kvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],notepad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],devop:[0,28,29,4,5,18],stompserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],intent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],consid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],younger:7,search_attribut:1,longer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],anywher:[6,32],ignor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],time:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],push:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],backward:25,skip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],consum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],redis2:5,mysql_databas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],netbsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],childn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],row:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],millisecond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],varnish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],depend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],zone:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],decim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],installonlypkg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],decis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],jvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aspx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],undon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],string:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbooks_path:9,cloudstack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lru:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],template_filenam:27,brows:[6,32],public_hostnam:30,supervisor_group:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windows_batch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hour:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],administr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],level:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],did:12,item:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cooki:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reregist:[7,18],dir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],validation_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windows_featur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bffcreat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sign:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unprotect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],learnchef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],port:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"5272a43f":12,raid5:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],appear:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],icinga:5,current:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],id3lib:5,reg_binari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],executionpolici:27,gener:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unauthor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],satisfi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],modif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],address:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],along:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],redmin:5,wait:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],box:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chef_environ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],invit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],netdev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],checksum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],membership:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],behav:24,healthi:12,regardless:27,rightscal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],extra:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],modul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],test_system:1,prefer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],anagram:24,seattl:34,visibl:1,instal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],regex:[29,3,28,0,18],memori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],subvers:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],msn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],live:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],handler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],msi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],criteria:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],checkout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],peopl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rabbitmq_chef:5,visual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],templat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trywgfa6r70no28pnhmpghevkbzuxouemnbnauqsuyo:33,effort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],role_nam:[29,0,23],tokyo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],uniqu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cat:1,descriptor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],profitbrick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],graphit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],can:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cloudkick_monitor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],purpos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nearest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],backslash:24,agent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],topic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],critic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],recycl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],occur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alwai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sundai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],multipl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gem_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],uptim:30,write:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mixlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windows_reboot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],purg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],webplcmdlin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stomp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],map:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],product:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],omnitruck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],max:26,clone:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sp4:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],identity_fil:[30,27],appnam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hklm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],log_level:[9,31,27],roundrobin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],data:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],man:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nullsoft:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],purge_before_symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],logwatch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],inform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],preced:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],combin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],talk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],port_list:24,config_fil:10,ssh_wrapper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],partial_search:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ttl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gitignor:20,still:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dynam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],entiti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_ruby_rail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],conjunct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],group:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],monitor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rvm:27,duplex:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],name_statu:[],platform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],window:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],main:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],non:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],main_monitor:3,rake:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],initi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bound:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],run_stat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],safari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],half:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nov:31,superset:24,discuss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],term:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],name:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],drop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],separ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],junip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],compil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],domain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],replac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],individu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],continu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unlock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gnu_parallel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],year:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],happen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],subnet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],shown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"3rd":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],space:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"100g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],profil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vrrp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],internet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],formula:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],correct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hkey_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],orgtest:15,migrat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],argv:1,mime:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pacman_aur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],org:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"byte":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],care:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reusabl:28,suffici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],question:24,frequenc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],synchron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],homebrew_tap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],turn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],yum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fa0fc4abf3f6787aeb5c3c5c35de667c:28,router:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],principl:24,think:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],frequent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],first:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],origin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],directli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],carri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],onc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],arrai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windows_auto_run:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],use_current_branch:[],fast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],oppos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ring:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],open:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],predefin:1,size:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],given:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reprepro:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],silent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],install_chef:27,ssh_command:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iaa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],baremetalcloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cumul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],averag:30,white:26,apt_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],json_attrib:[9,27],repo_mod:[],provinc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],copi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],full_control:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],artifact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],broadcast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],github:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hup:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mostli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nested_attribut:15,pecl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],than:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],png:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],serv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],wide:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],user_hom:[],sbuild:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cloudkick_check:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],posix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],balanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],were:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],posit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],zsh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pre:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lowest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],config_cont:27,pro:24,delim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],argument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],client_kei:[24,31],ant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],medium:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],smartos_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],extralarg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],engin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],displayvers:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],destroi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],note:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sendfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ideal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],copyright_hold:28,take:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],noth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],channel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],begin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sure:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trace:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],normal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],buffer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],compress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],statu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],instiki:5,timestamped_deploi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],beta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pair:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_ruby_passenger_apache2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],collectstat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],later:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],drive:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reg_expand_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],runtim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],superblock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],expand_str:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],steadi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],review:[0,1,2,3,4,5,6,7,8,11,12,14,15,16,32,27,20,21,22,23,26,18,28,29,30,33,34],"4d44b5b":5,show:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],encrypted_data_bag_secret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],concurr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],permiss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sysctl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rotat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],xml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],onli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],moneta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],transact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],activ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],written:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_java_webapp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hello_world:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],overwritten:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nearli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],variou:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],get:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stdout_logfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],secondari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],repo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cannot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],requir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chef_shel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],debian5:27,aptitud:30,netscalar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],where:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],summari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],wiki:[24,5],kernel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],installshield:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],proce:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],endloc:27,data_bag:[24,33,14],python_pip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],xenserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],detect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],netdev_interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],label:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],enough:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],volatil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],between:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"import":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],across:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sname:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],parent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],node_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],screen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fundament:28,syntax_check_cache_path:24,uncondition:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],come:24,tue:31,gpasswd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],uuid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windows_path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],region:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],quiet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pychef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],library_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],datamapp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mani:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],runcontext:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rabbitmq_vhost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reindex:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],prereleas:27,color:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],period:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],symfoni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],colon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],generic_writ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cancel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bluepil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ultim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],west:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rebuild:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],replace_str:26,altern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],spiceweasel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rebuilt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],my_cookbook:28,rubi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],editpad:24,bare_directori:[],those:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"case":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],eip:20,pedant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],invok:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],librato:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],suse:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_nginx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stdout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],metric:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],airbrak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cluster:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ascii:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aa384235:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],develop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dry_run:[],author:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],media:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],same:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],binari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],html:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],document:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],week:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],finish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],webserv:[20,29,30,23,6,32,27],see:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nagios_nrpecheck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],confidenti:33,openldap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cinder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],extern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],repoforg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],appropri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],without:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],disassoci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],model:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],etm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],a29d6f254577b830091f140c3a78b1f:28,execut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],loaderror:30,key_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],kill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aspect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],org_cleanu:3,touch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],passphras:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],http_proxi:27,speed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aws_access_key_id:24,samba:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],display_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],except:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],apache2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],identif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],instrument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],blob:27,query_to_run:15,ruby1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iis_app:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],real:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],around:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ohai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],read:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],traffic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],platform_vers:28,world:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],yyyymmddhhmmss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],meaning:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iftop:5,integ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],server:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],either:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],output:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rubyv:1,manag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cisco:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],glesi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pushi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],user_nam:[30,7],freez:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rsync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],keytab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],easili:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],definit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],appscript:30,exit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],highcpu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],portage_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],knife:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],refer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],power:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],asterisk:24,inspect:[6,13,19],a45298c9:12,starttim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bazaar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],comparison:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],central:9,ack:5,gplv2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gplv3:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],appcmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],acl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chef_server_url:[24,31,25,27],act:25,backup:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],processor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],effici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_ruby_memcach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],your:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],charli:33,hkey_current_config:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],log:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_nginx_load_balanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],daemontool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],overwrit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],start:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ipv4:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ipv6:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iis_pool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bundl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],untar:5,cabinet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],opensolari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],activemq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],faster:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chefclientfeatur:27,pull:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],possibl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"default":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pacman:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],powershell_script:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vhd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],embed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],expect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cbc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],displaynam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],uid:33,creat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],certain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],remote_directori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],yourcompani:24,chef_handl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fail2ban:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],file:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],incorrect:31,file_maxbyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],googl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],prepend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],field:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],valid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],you:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssh_gatewai:[],architectur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],openid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],codecademi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],registri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sublim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sequenc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],symbol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pear:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fsck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],track:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],snitch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dropbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],djbdns_rr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],netdev_lag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],directori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_copyright:24,mask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],use_etag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],escap:24,cpu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],scm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],represent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],all:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],selinux:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],forbidden:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],month:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lacp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],netdev_l2_interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],follow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],disk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],children:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sympa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dsl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],init:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],program:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],app_conf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],introduc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cloudkick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],global:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fals:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],secret_fil:[],subcommand:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],util:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],verb:[13,21,22,8,24,11,19],failur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],veri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ossec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],excluded_memb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],list:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],recipe_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stderr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],plain:33,small:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pid_fil:31,enterpris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],drbd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],past:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],syslog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rate:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],keyston:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],design:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pass:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssh_attr:30,val2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],val1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],current_dir:24,devops_data:33,what:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],yum_repositori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sub:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],section:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],abl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],brief:[12,13,19],rackspac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],delet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],abbrevi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],version:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],noprofil:27,method:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],zookeep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],full:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],berkelei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],situat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],solari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gandi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fred:33,modifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],valu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],thrift:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],search:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],memcach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],prior:[13,19,20],amount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],action:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],elsewher:9,transit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bluepill_servic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tmux:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],filenam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iis_sit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],establish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],redisio:4,proceed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],regist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],two:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],validation_client_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],taken:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],more:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],flat:8,aws_elastic_lb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],desir:24,rpc_password:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],slicehost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],flag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],particular:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],known:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],compani:24,destin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],installroot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],psql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],none:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],endpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pkgbuild:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dev:[12,29,15,4],histori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],oktawav:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],remain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hkey_local_machin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],learn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],deb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nagio:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],external_url:5,prompt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sensu:4,share:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bootstrap_directori:27,accept:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],verify_non:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],minimum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],poni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],explor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],csh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],freshli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],secur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rather:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],anoth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pxe_dust:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reject:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],simpl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],distro:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],regener:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],resourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],referenc:[7,18],vlan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fstype:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rbac:24,bootstrap_vers:[],associ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_php_mod_php_apache2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"short":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],postfix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],created_at:5,django:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],caus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],allkei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],azur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],logrot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],opscod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],help:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],templatefortextstr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],i386:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],through:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],htop:5,paramet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],create_dirs_before_symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],systemd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],exact:[29,15],pend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_nam:[0,23,5,28],bypass:[6,13,19],verbose_command:[],application_python_gunicorn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],independ:24,"return":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],graylog2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],timestamp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],framework:31,detach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],admin_nam:24,instruct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],authent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"1password":5,userprofil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],token:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],average_r:5,compris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],found:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unicod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],only_if:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],truncat:[29,5],denni:7,"300mb":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],crontab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],connect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],new_client:1,portland:34,beyond:24,event:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ftp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vancouv:34,robert:7,publish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mirrorlist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],print:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],occurr:26,file_nam:[28,7,18],pgdg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],qualifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],asp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],proxi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],advanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],campfir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],quick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reason:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],base:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],workstat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],basi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],launch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],omit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],perman:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],heartbeat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],assign:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],notifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],prevent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],number:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],placehold:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],env_vari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],done:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stdlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],file_atomic_upd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gpl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssl_ca_path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],script:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ipaddress:1,interact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unrestrict:27,least:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],checkpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],swarm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],win2k8:15,storm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],zeromq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],scheme:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],journli:4,jetti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],store:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dpkg_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],statement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],behind:24,bag_nam:33,part:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pars:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],consult:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dpkg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reinstal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],grep:[31,5,27],remot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],remov:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reg_qword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],randomli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],comput:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gvim:24,packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],expir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dedic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"null":26,option:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],berkshelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],built:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],equival:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],also:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],centos5:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rakefil:20,build:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stackforg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],splai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pipelin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],distribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],exec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],previou:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],erlang_solut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],most:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],private_kei:1,alpha:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],clear:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cover:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],destruct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],clojur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],clean:30,microsoft:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],readme_format:[],carefulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],xcode:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alphanumer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ignore_failur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],session:25,value_data:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fine:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],affin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cssh:30,firewal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pretti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],solut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],jtimberman:[5,27],darwin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],yml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],everysec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unus:[7,18],chef_gem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"__file__":24,express:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],verify_p:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nativ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fastest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],restart:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"225f954f":12,data_bag_name_or_path:33,crt:20,boost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],your_company_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],common:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,32,18,19,20,21,22,23,24,26,27,28,29,30,33,34],gelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],syntax_check_cach:24,certif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],set:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dump:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],creator:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],startup:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ifconfig:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],emac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],arg:26,reserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],flavor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ps1:27,git_ssh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],example_nod:1,jenkin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],someth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],subscript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],max_arguments_per_command:[],solo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gemfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssh_password:[],numer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],javascript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],succeed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],distinguish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],solr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],popul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],both:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reg_multi_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],delimit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hint_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],context:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lash:1,application_ruby_unicorn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],load:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],markdown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],point:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],schedul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],header:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],shutdown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],linux:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ucspi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],desktop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],authz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rackspace_api_kei:24,unsuccess:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],java:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],devic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],omnibu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],empti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],secret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],strategi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],atomic_upd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],imag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],understand:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"0_8_0":5,bifrost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],look:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],registry_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],frozen:28,hkcc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],batch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],durat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],formatt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"while":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],corpsit:20,behavior:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],error:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hkcr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],maradn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],loop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hkcu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ami:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],motd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],key2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],key1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],readm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],client_desc:1,dynect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],itself:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cento:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],skype:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vcloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unmount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fedora:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],grant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],belong:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hadoop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],shorter:1,octal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],conflict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],higher:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],x86:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"0_7_0":5,wherea:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],inflat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alert:5,jpackag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],temporari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],user:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],recent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lower:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sha1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lib:27,older:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],entri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],person:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reflect:4,elev:31,rbenv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],propos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],override_attribut:[4,0],mysql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],openstack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"07z":5,shortcut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],freebsd_port_opt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],web03:15,appli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],input:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tell:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],subsequ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],approxim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],powershel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vendor:5,obsolet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fqdn_or_ip_address:27,format:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ipmi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],main_attribut:15,local_download_path:27,nginx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],exceptionclass:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],characterist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dynect_rr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fsync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],signal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],svlogd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],resolv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],elaps:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],princip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"boolean":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alrm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],encount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vsphere:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],often:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],simplifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],add_formatt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],acknowledg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],creation:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],some:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],back:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unspecifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sampl:[29,33,0],staticfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],force_overrid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mirror:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],virtualenv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lamin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],per:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],retri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],larg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_python:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],slash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],max_command_lin:[],proc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],snort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],machin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],run:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],agreement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],step:31,wget:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],crond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ufw:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],generic_read:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],constraint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],drbdadm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],idl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],block:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],instance_typ:15,nsi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],doubl:24,ohai_tim:1,smart_o_s_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],opscodesupport:5,within:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ensur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rundeck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],errno:31,megabyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"long":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],custom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],includ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],suit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],forward:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],repo_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],properli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ifcfg:15,myinstal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],textpad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],remote_source_msi_url:27,pwd:27,link:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],translat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],newer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],atom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],noninteract:27,line:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],php_pear_channel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],info:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],utc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],consist:[24,0],munin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rabbitmq_plugin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nscd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],similar:[13,18,14,20,21,30,15,28,4,22,29,34,24,8,9,11,19,27],nsca:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],supervisor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],doesn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],repres:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"char":26,server01:30,incomplet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],curl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],titl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sequenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],invalid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"_imag":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],librari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nice:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gigabyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mongodb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],drag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],percona:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],eval:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],splunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ladvd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],desert:23,svn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"1024mb":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],infrequ:[13,19,1],algorithm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],confirm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],svc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],depth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],minproc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chef_overview_attribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hello:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],endtim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],code:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],partial:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],queri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],groupadd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],steve:7,privat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ulimit:4,base64:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],send:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fatal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],user_password:[],sent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],passiv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unzip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vlc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],volum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],recip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],magic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],netdev_vlan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],id_rsa:27,geograph:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hive:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"try":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pleas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],impli:15,jdk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],slackwar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],download:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],click:31,append:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],compat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],index:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],compar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],a47823c9:12,gunicorn_instal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],winrm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],find:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],access:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windows_registri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],f65c969b:12,logloc:[9,31],isapi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hku:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],let:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ubuntu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],becom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sinc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],convert:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],copyright:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],apt_prefer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aardvark:24,larger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],converg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rpm_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ctl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],typic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],honor:25,configur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],firefox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ago:12,danger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],win:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],app:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gatewai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],apt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],api:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],smartmon:28,redi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],wix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],from:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],zip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],commun:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hudson:5,upgrad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],nexu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],next:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],websit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],few:31,use_conditional_get:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],usr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],src:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mismatch:4,sbin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"transient":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iis_modul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],starter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],justin:24,account:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chdir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],retriev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tunnel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alia:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],crazi:33,fetch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],control:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sqlite:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],weaker:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],process:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sudo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],high:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],proprietari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tarbal:5,serial:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],someurlher:28,symlink_before_migr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],delai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sit:24,zenpack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reg_dword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],instead:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],opscode_us:24,zendmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],msdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],somelongurlher:28,overridden:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],watch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],apicli:18,chef_repo_path:[20,21,32,23,22,6,8,11,26],physic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],alloc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],delete_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],essenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssh_known_host:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],zenoss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],correspond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],issu:[24,31],client_foo:18,allow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],yum_globalconfig:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aws_secret_access_kei:24,jira:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],restorecon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],comma:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],webpi_product:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],suppli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],admin_client_nam:[],infrastructur:[9,24],openvpn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],asa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bittorr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],therefor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],keepaliv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],iis_config:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],greater:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],python:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],auto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rabbitmq_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],auth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],devel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rubygem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],data_bag_item:33,fingerprint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],front:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],file_cache_path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],trac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],anyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],edit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],radiant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pacman_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"0a7cffd5":15,mode:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],all_cap:24,subset:[12,13,30,19,17],chunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],riak_clust:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],meta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"static":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ec2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],citrix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],differ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],special:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],out:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],variabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gentoo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],armor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reboot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],users_manag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rails_enterpris:5,categori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],suitabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rem:27,hardwar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dhcp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"_default":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],merg:[0,5],local_destination_msi_path:27,red:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sql_server:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],insid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],workflow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],kilobyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],standalon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],releas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tenant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],qpid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stackscript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],could:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],put:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fqdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],keep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],length:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],outsid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],retain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],no_proxy_url_or_ip:27,polici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],echo:27,date:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ssh_attribut:[],puppet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pgp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],kerbero:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],owner:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],facil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],underscor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],prioriti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unknown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],licens:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chefignor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],capac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],wrapper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],attach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],privaci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],termin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"final":27,udp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],shell:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fuzzi:15,shallow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rdoc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rsa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],exactli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],haven:26,passenger_apache2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],prune:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],split:1,stderr_logfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],structur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],charact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sens:5,sensit:[24,33],torrent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],start_tim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dmg_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],disable_edit:[],plaintext:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],remote_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],inno:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],download_directori:28,have:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bootstrap_proxi:27,cfengin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],freebsd_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],min:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],atim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],accuraci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],which:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],json_class:[0,14,28,29,4,7,18],datacent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],zlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],force_default:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],reposerv:27,unless:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],freebsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],deploy:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],who:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],oracl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],discov:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cipher:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],deploi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],xarg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],kuwata:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],segment:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"class":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],p180:27,url:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],request:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],uri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],recipe_url:9,deni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],snapshot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],determin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],editpa:24,aws_elastic_ip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],text:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],verbos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bring:31,nagl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vim74:24,redirect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],highest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],locat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],launchpad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rackspace_usernam:24,terremark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"26am":31,jar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sendmail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],should:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],local:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],contribut:5,"226ca64f":12,notat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],familiar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],passeng:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],autom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],beam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],increas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],replace_al:[],enabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],organ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],twice:29,upper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sudoer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],num_to_keep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sha:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],integr:[9,17],contain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],script_path:[],view:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],debconf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],conform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],legaci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],libshadow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],signatur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rc1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],elast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],temporarili:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],imagemagick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],xxxxx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],closer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],datadog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],impos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],open_sourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],correctli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pattern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],windows_shortcut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],favor:30,state:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],progress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],application_php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],email:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],verifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],retry_delai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],job:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],entir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],homebrew:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],swift:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],addit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],plugin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],admin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],equal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],etc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],instanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],uncaught:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],testclient:18,strftime:1,resource_collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],comment:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],epel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pacman_group:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],replace_first:[],hyphen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],chmod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],name_onli:[],b4c32f2:5,rpm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ceilomet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mailto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],quit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_email:24,yaml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bluelock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dword_big_endian:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],compos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],insuffici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],compon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],json:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ruleset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],scriptabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ia2itmjrsw8:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],immedi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],capistrano:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vmware:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bulk:[29,28,0,18],togeth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],last:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],thesecret123:33,present:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],authorized_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],need:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mvc3:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],samba_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],defin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hkey_current_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],flowdock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],helper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],squid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],site:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],archiv:[9,5],lightweight:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],incom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],revis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],parti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],member:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],handl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],amazonec2tag:5,infer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],backtrac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],http:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],hostnam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],again:33,keepal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],upon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],effect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],identify_fil:30,logfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],yum_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tftp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],expand:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cosmet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],center:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],not_if:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],well:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],exampl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],command:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],digitalocean:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],fail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],setx:27,latest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],newest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],paus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],less:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tcp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],end_tim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],webui:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sdanna:5,simultan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sku:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],web:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],foo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],add:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],myhelpermodul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],apparmor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],foobar:29,logger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],warrant:[13,19,1],match:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],cookbook_path:24,cpan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],know:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mynod:[23,27],password:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],recurs:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],insert:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],resid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],like:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],success:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],latest_vers:5,amazonaw:[12,30],necessari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],page:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],apachev2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],shef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],eucalyptu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],revers:12,captur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],twitter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],installer_typ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],kdc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],msiexec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gevent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"export":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],flush:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],proper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],home:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],supervisor_fcgi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],transport:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tmp:31,cookbookvers:28,leaf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],leak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],leav:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"0a7ca19f":15,easy_install_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],throttl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],usag:[13,19,1],symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],maven:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],vhost:5,host:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],offset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stage:4,homesick:5,about:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ntlm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],actual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],socket:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],column:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],gunicorn_config:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],haproxi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],loftninja:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],disabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sort_revers:[],own:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],automat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],guard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],been:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],smarto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],merb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],virtualbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"56g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],omnio:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],transfer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],netfx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],singl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],appl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],downgrad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],progra:24,"var":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],exampleorg:18,"function":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],unexpect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],subscrib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],baseurl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],addloc:27,bff_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],uninstal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],oauth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],inlin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],bug:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],count:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],made:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],wise:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],arp_tabl:24,dmg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],whether:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aws_ebs_volum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],displai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],brightbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],asynchron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],record:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],below:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],limit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],lvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],otherwis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],problem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],extrasmal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"int":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],descript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],dure:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],updated_at:5,ephemer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],implement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],ini:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],mtime:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],pip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],daemontools_servic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],inc:24,windows_zipfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],aws_resource_tag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],boot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],detail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],virtual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],other:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],branch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],riak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],upstart:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],juno:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rackspace_api_usernam:24,"100m":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],sbdm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],debian:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],stai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"25z":5,sphinx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],tomcat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],scientif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],rule:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],blog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],emerg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"0_8_1":5,cookbook:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34]},objtypes:{},titles:["knife role","knife exec","knife configure","knife recipe list","knife environment","knife cookbook site","knife download","knife user","knife list","chef-solo","Common Options","knife delete","knife status","chef-client Man Pages","knife raw","knife search","knife index rebuild","chef-server-ctl","knife client","knife","knife diff","knife edit","knife show","knife deps","Working with Knife","chef-shell","knife xargs","knife bootstrap","knife cookbook","knife node","knife ssh","chef-client","knife upload","knife data bag","knife tag"],objnames:{},filenames:["knife_role","knife_exec","knife_configure","knife_recipe_list","knife_environment","knife_cookbook_site","knife_download","knife_user","knife_list","ctl_chef_solo","knife_common_options","knife_delete","knife_status","index","knife_raw","knife_search","knife_index_rebuild","ctl_chef_server","knife_client","knife","knife_diff","knife_edit","knife_show","knife_deps","knife_using","ctl_chef_shell","knife_xargs","knife_bootstrap","knife_cookbook","knife_node","knife_ssh","ctl_chef_client","knife_upload","knife_data_bag","knife_tag"]}) \ No newline at end of file
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 095e8623c0..9b00184610 100644
--- a/distro/common/man/man1/chef-shell.1
+++ b/distro/common/man/man1/chef-shell.1
@@ -1,220 +1,115 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "CHEF-SHELL" "1" "Chef 11.10.0" "" "chef-shell"
+.SH NAME
+chef-shell \- The man page for the chef-shell command line tool.
+.
+.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
+chef\-shell is a recipe debugging tool that allows the use of breakpoints within recipes. chef\-shell runs as an Interactive Ruby (IRb) session. chef\-shell supports both recipe and attribute file syntax, as well as interactive debugging features.
+.IP Note
+chef\-shell is the new name for Shef as of Chef 11.x. chef\-shell is backwards compatible and aside from the name change, has the same set of functionality as with previous releases.
+.RE
+.sp
+The chef\-shell executable can be run as a command\-line tool.
+.SH MODES
+.sp
+chef\-shell is tool that allows Knife to be run using an Interactive Ruby (IRb) session. chef\-shell currently supports recipe and attribute file syntax, as well as interactive debugging features. chef\-shell has three run modes:
+.TS
+center;
+|l|l|.
+_
+T{
+Mode
+T} T{
+Description
+T}
+_
+T{
+Standalone
+T} T{
+No cookbooks are loaded, and the run list is empty. This mode is the default.
+T}
+_
+T{
+Solo
+T} T{
+chef\-shell acts as a chef\-solo client. It attempts to load the chef\-solo configuration file and JSON attributes. If the JSON attributes set a run list, it will be honored. Cookbooks will be loaded in the same way that chef\-solo loads them. chef\-solo mode is activated with the \fB\-s\fP or \fB\-\-solo\fP command line option, and JSON attributes are specified in the same way as for chef\-solo, with \fB\-j /path/to/chef\-solo.json\fP.
+T}
+_
+T{
+Client
+T} T{
+chef\-shell acts as a chef\-client. During startup, it reads the chef\-client configuration file and contacts the server to get attributes and cookbooks. The run list will be set in the same way as normal chef\-client runs. chef\-client mode is activated with the \fB\-z\fP or \fB\-\-client\fP options. You can also specify the configuration file with \fB\-c CONFIG\fP and the server URL with \fB\-S SERVER_URL\fP.
+T}
+_
+.TE
+.SH OPTIONS
+.sp
+This command has the following syntax:
+.sp
+.nf
+.ft C
+chef\-shell OPTION VALUE OPTION VALUE ...
+.ft P
+.fi
+.sp
+This command has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-a\fP, \fB\-\-standalone\fP
+Indicates that chef\-shell will be run in standalone mode.
+.TP
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.TP
+.B \fB\-j PATH\fP, \fB\-\-json\-attributes PATH\fP
+The path to a file that contains JSON data.
+.TP
+.B \fB\-l LEVEL\fP, \fB\-\-log\-level LEVEL\fP
+The level of logging that will be stored in a log file.
+.TP
+.B \fB\-s\fP, \fB\-\-solo\fP
+Indicates that chef\-shell will be run in chef\-solo mode.
+.TP
+.B \fB\-S CHEF_SERVER_URL\fP, \fB\-\-server CHEF_SERVER_URL\fP
+The URL for the server.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-z\fP, \fB\-\-client\fP
+Indicates that chef\-shell will be run in chef\-client mode.
+.UNINDENT
+.SH AUTHOR
+Chef
+.\" Generated by docutils manpage writer.
.
-.TH "CHEF\-SHELL" "1" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
-.
-.SH "NAME"
-\fBchef\-shell\fR \- Interactive Chef Console
-.
-.SH "SYNOPSIS"
-\fBchef\-shell\fR [\fInamed configuration\fR] \fI(options)\fR
-.
-.TP
-\fB\-S\fR, \fB\-\-server CHEF_SERVER_URL\fR
-The chef server URL
-.
-.TP
-\fB\-z\fR, \fB\-\-client\fR
-chef\-client mode
-.
-.TP
-\fB\-c\fR, \fB\-\-config CONFIG\fR
-The configuration file to use
-.
-.TP
-\fB\-j\fR, \fB\-\-json\-attributes JSON_ATTRIBS\fR
-Load attributes from a JSON file or URL
-.
-.TP
-\fB\-l\fR, \fB\-\-log\-level LOG_LEVEL\fR
-Set the logging level
-.
-.TP
-\fB\-s\fR, \fB\-\-solo\fR
-chef\-solo session
-.
-.TP
-\fB\-a\fR, \fB\-\-standalone\fR
-standalone session
-.
-.TP
-\fB\-v\fR, \fB\-\-version\fR
-Show chef version
-.
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-Show command options
-.
-.P
-When no \-\-config option is specified, chef\-shell attempts to load a default configuration file:
-.
-.IP "\(bu" 4
-If a \fInamed configuration\fR is given, chef\-shell will load ~/\.chef/\fInamed configuration\fR/chef_shell\.rb
-.
-.IP "\(bu" 4
-If no \fInamed configuration\fR is given chef\-shell will load ~/\.chef/chef_shell\.rb if it exists
-.
-.IP "\(bu" 4
-chef\-shell falls back to loading /etc/chef/client\.rb or /etc/chef/solo\.rb if \-z or \-s options are given and no chef_shell\.rb can be found\.
-.
-.IP "\(bu" 4
-The \-\-config option takes precedence over implicit configuration paths\.
-.
-.IP "" 0
-.
-.SH "DESCRIPTION"
-\fBchef\-shell\fR is an irb(1) (interactive ruby) session customized for Chef\. \fBchef\-shell\fR serves two primary functions: it provides a means to interact with a Chef Server interactively using a convenient DSL; it allows you to define and run Chef recipes interactively\.
-.
-.SH "SYNTAX"
-chef\-shell uses irb\'s subsession feature to provide multiple modes of interaction\. In addition to the primary mode which is entered on start, \fBrecipe\fR and \fBattributes\fR modes are available\.
-.
-.SH "PRIMARY MODE"
-The following commands are available in the primary session:
-.
-.TP
-\fBhelp\fR
-Prints a list of available commands
-.
-.TP
-\fBversion\fR
-Prints the Chef version
-.
-.TP
-\fBrecipe\fR
-Switches to \fBrecipe\fR mode
-.
-.TP
-\fBattributes\fR
-Switches to \fBattributes\fR mode
-.
-.TP
-\fBrun_chef\fR
-Initiates a chef run
-.
-.TP
-\fBreset\fR
-reinitializes chef\-shell session
-.
-.TP
-\fBecho :on|:off\fR
-Turns irb\'s echo function on or off\. Echo is \fIon\fR by default\.
-.
-.TP
-\fBtracing :on|:off\fR
-Turns irb\'s function tracing feature on or off\. Tracing is extremely verbose and expected to be of interest primarily to developers\.
-.
-.TP
-\fBnode\fR
-Returns the \fInode\fR object for the current host\. See knife\-node(1) for more information about nodes\.
-.
-.TP
-\fBohai\fR
-Prints the attributes of \fInode\fR
-.
-.P
-In addition to these commands, chef\-shell provides a DSL for accessing data on the Chef Server\. When working with remote data in chef\-shell, you chain method calls in the form \fIobject type\fR\.\fIoperation\fR, where \fIobject type\fR is in plural form\. The following object types are available:
-.
-.IP "\(bu" 4
-\fBnodes\fR
-.
-.IP "\(bu" 4
-\fBroles\fR
-.
-.IP "\(bu" 4
-\fBdata_bags\fR
-.
-.IP "\(bu" 4
-\fBclients\fR
-.
-.IP "\(bu" 4
-\fBcookbooks\fR
-.
-.IP "" 0
-.
-.P
-For each \fIobject type\fR the following operations are available:
-.
-.TP
-\fIobject type\fR\.all(\fI&block\fR)
-Loads all items from the server\. If the optional code \fIblock\fR is given, each item will be passed to the block and the results returned, similar to ruby\'s \fBEnumerable#map\fR method\.
-.
-.TP
-\fIobject type\fR\.show(\fIobject name\fR)
-Aliased as \fIobject type\fR\.load
-.
-.IP
-Loads the singular item identified by \fIobject name\fR\.
-.
-.TP
-\fIobject type\fR\.search(\fIquery\fR, \fI&block\fR)
-Aliased as \fIobject type\fR\.find
-.
-.IP
-Runs a search against the server and returns the matching items\. If the optional code \fIblock\fR is given each item will be passed to the block and the results returned\.
-.
-.IP
-The \fIquery\fR may be a Solr/Lucene format query given as a String, or a Hash of conditions\. If a Hash is given, the options will be ANDed together\. To join conditions with OR, use negative queries, or any advanced search syntax, you must provide give the query in String form\.
-.
-.TP
-\fIobject type\fR\.transform(:all|\fIquery\fR, \fI&block\fR)
-Aliased as \fIobject type\fR\.bulk_edit
-.
-.IP
-Bulk edit objects by processing them with the (required) code \fIblock\fR\. You can edit all objects of the given type by passing the Symbol \fB:all\fR as the argument, or only a subset by passing a \fIquery\fR as the argument\. The \fIquery\fR is evaluated in the same way as with \fBsearch\fR\.
-.
-.IP
-The return value of the code \fIblock\fR is used to alter the behavior of \fBtransform\fR\. If the value returned from the block is \fBnil\fR or \fBfalse\fR, the object will not be saved\. Otherwise, the object is saved after being passed to the block\. This behavior can be exploited to create a dry run to test a data transformation\.
-.
-.SH "RECIPE MODE"
-Recipe mode implements Chef\'s recipe DSL\. Exhaustively documenting this DSL is outside the scope of this document\. See the following pages in the Chef documentation for more information:
-.
-.IP "\(bu" 4
-\fIhttp://wiki\.opscode\.com/display/chef/Resources\fR
-.
-.IP "\(bu" 4
-\fIhttp://wiki\.opscode\.com/display/chef/Recipes\fR
-.
-.IP "" 0
-.
-.P
-Once you have defined resources in the recipe, you can trigger a convergence run via \fBrun_chef\fR
-.
-.SH "EXAMPLES"
-.
-.IP "\(bu" 4
-A "Hello World" interactive recipe
-.
-.IP
-chef > recipe chef:recipe > echo :off chef:recipe > file "/tmp/hello_world" chef:recipe > run_chef [Sat, 09 Apr 2011 08:56:56 \-0700] INFO: Processing file[/tmp/hello_world] action create ((irb#1) line 2) [Sat, 09 Apr 2011 08:56:56 \-0700] INFO: file[/tmp/hello_world] created file /tmp/hello_world chef:recipe > pp ls \'/tmp\' ["\.", "\.\.", "hello_world"]
-.
-.IP "\(bu" 4
-Search for \fInodes\fR by role, and print their IP addresses
-.
-.IP
-chef > nodes\.find(:roles => \'monitoring\-server\') {|n| n[:ipaddress] } => ["10\.254\.199\.5"]
-.
-.IP "\(bu" 4
-Remove the role \fIobsolete\fR from every node in the system
-.
-.IP
-chef > nodes\.transform(:all) {|n| n\.run_list\.delete(\'role[obsolete]\') } => [node[chef098b2\.opschef\.com], node[ree\-woot], node[graphite\-dev], node[fluke\.localdomain], node[ghost\.local], node[kallistec]]
-.
-.IP "" 0
-.
-.SH "BUGS"
-\fBchef\-shell\fR often does not perfectly replicate the context in which chef\-client(8) configures a host, which may lead to discrepancies in observed behavior\.
-.
-.P
-\fBchef\-shell\fR has to duplicate much code from chef\-client\'s internal libraries and may become out of sync with the behavior of those libraries\.
-.
-.SH "SEE ALSO"
-chef\-client(8) knife(1) \fIhttp://wiki\.opscode\.com/display/chef/Chef+Shell\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR with many contributions from the community\. chef\-shell was written by Daniel DeLeo\.
-.
-.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"
-chef\-shell is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-bootstrap.1 b/distro/common/man/man1/knife-bootstrap.1
index 893a4452cf..8b934f8ed7 100644
--- a/distro/common/man/man1/knife-bootstrap.1
+++ b/distro/common/man/man1/knife-bootstrap.1
@@ -1,201 +1,188 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-BOOTSTRAP" "1" "July 2013" "Chef 11.8.0.alpha.0" "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.10.0" "" "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.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife bootstrap FQDN_or_IP_ADDRESS (options)
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
.TP
-\fB\-i\fR, \fB\-\-identity\-file IDENTITY_FILE\fR
-The SSH identity file used for authentication
-.
+.B \fB\-A\fP, \fB\-\-forward\-agent\fP
+Indicates that SSH agent forwarding is enabled.
.TP
-\fB\-N\fR, \fB\-\-node\-name NAME\fR
-The Chef node name for your new node
-.
+.B \fB\-\-bootstrap\-no\-proxy NO_PROXY_URL_or_IP\fP
+A URL or IP address that specifies a location that should not be proxied. Note: This option is used internally by Chef to help verify bootstrap operations during testing and should never be used during an actual bootstrap operation.
.TP
-\fB\-P\fR, \fB\-\-ssh\-password PASSWORD\fR
-The ssh password
-.
+.B \fB\-\-bootstrap\-proxy PROXY_URL\fP
+The proxy server for the node that is the target of a bootstrap operation.
.TP
-\fB\-x\fR, \fB\-\-ssh\-user USERNAME\fR
-The ssh username
-.
+.B \fB\-\-bootstrap\-version VERSION\fP
+The version of the chef\-client to install.
.TP
-\fB\-p\fR, \fB\-\-ssh\-port PORT\fR
-The ssh port
-.
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
.TP
-\fB\-\-bootstrap\-version VERSION\fR
-The version of Chef to install
-.
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.TP
-\fB\-\-bootstrap\-proxy PROXY_URL\fR
-\fBThe proxy server for the node being bootstrapped\fR
-.
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
.TP
-\fB\-\-prerelease\fR
-Install pre\-release Chef gems
-.
+.B \fB\-d DISTRO\fP, \fB\-\-distro DISTRO\fP
+.IP Warning
+The default bootstrap operation uses the omnibus installer, which means the default template file (\fBchef\-full\fP) should work on all supported platforms. It is recommended to use custom bootstrap templates only when the omnibus installer cannot be used.
+.RE
+.sp
+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
-\fB\-r\fR, \fB\-\-run\-list RUN_LIST\fR
-Comma separated list of roles/recipes to apply
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-\-template\-file TEMPLATE\fR
-Full path to location of template to use
-.
+.B \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-\-sudo\fR
-Execute the bootstrap via sudo
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fB\-d\fR, \fB\-\-distro DISTRO\fR
-Bootstrap a distro using a template
-.
+.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\-\-[no\-]host\-key\-verify\fR
-Enable host key verification, which is the default behavior\.
-.
+.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\-\-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
-.
-.nf
-
-mkdir ~/\.chef/bootstrap
-vi ~/\.chef/bootstrap/debian5\.0\-apt\.erb
-.
-.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
-.
+.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\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.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\-\-[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\-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\-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\-N NAME\fP, \fB\-\-node\-name NAME\fP
+The name of the node.
+.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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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 URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-\-secret SECRET\fP
+The encryption key that is used for values contained within a data bag item.
+.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\-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\-\-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\-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\-x USERNAME\fP, \fB\-\-ssh\-user USERNAME\fP
+The SSH user name.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.sp
+\fBExamples\fP
+.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
.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
+Chef
+.\" 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 290ef5071e..6303359f84 100644
--- a/distro/common/man/man1/knife-client.1
+++ b/distro/common/man/man1/knife-client.1
@@ -1,99 +1,357 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-CLIENT" "1" "Chef 11.10.0" "" "knife client"
+.SH NAME
+knife-client \- The man page for the knife client subcommand.
.
-.TH "KNIFE\-CLIENT" "1" "July 2013" "Chef 11.8.0.alpha.0" "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 \fB/etc/chef/validation.pem\fP.
+.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.
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife client\fP subcommand:
+.INDENT 0.0
.TP
-\fB\-a\fR, \fB\-\-admin\fR
-Create the client as an admin
-.
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
.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 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 whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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 \fB/etc/chef/client.pem\fP.
+.IP \(bu 2
+For Knife, the private key is typically copied to \fB~/.chef/client_name.pem\fP 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 Enterprise 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 Enterprise 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
+Chef
+.\" 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 cfbacf6cd3..49b7f9dac5 100644
--- a/distro/common/man/man1/knife-configure.1
+++ b/distro/common/man/man1/knife-configure.1
@@ -1,88 +1,145 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-CONFIGURE" "1" "July 2013" "Chef 11.8.0.alpha.0" "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.10.0" "" "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
+\fBSyntax\fP
+.sp
+This argument has the following syntax when creating a knife.rb file:
+.sp
+.nf
+.ft C
+$ knife configure (options)
+.ft P
+.fi
+.sp
+and the following syntax when creating a client.rb file:
+.sp
+.nf
+.ft C
+$ knife configure client DIRECTORY
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This subcommand has the following options:
+.INDENT 0.0
.TP
-\fB\-i\fR, \fB\-\-initial\fR
-Create an initial API Client
-.
+.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
-\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\-\-admin\-client\-name NAME\fP
+The name of the client, typically the name of the admin client.
+.TP
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.TP
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether 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 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\-i\fP, \fB\-\-initial\fP
+Use to create a API client, typically an administrator client on a freshly\-installed server.
+.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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-r REPO\fP, \fB\-\-repository REPO\fP
+The path to the chef\-repo.
+.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\-\-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.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+.nf
+.ft C
+$ knife configure
+.ft P
+.fi
+.sp
+.nf
+.ft C
+$ knife configure client \(aq/directory\(aq
+.ft P
+.fi
+.SH AUTHOR
+Chef
+.\" 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 122c76c6ed..d1a8a0a9da 100644
--- a/distro/common/man/man1/knife-cookbook-site.1
+++ b/distro/common/man/man1/knife-cookbook-site.1
@@ -1,145 +1,466 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-COOKBOOK\-SITE" "1" "July 2013" "Chef 11.8.0.alpha.0" "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.10.0" "" "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.
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife cookbook site\fP subcommand:
+.INDENT 0.0
.TP
-\fB\-D\fR, \fB\-\-skip\-dependencies\fR
-Skip automatic installation of dependencies\.
-.
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.TP
-\fB\-o\fR, \fB\-\-cookbook\-path PATH\fR
-Install cookbooks to PATH
-.
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
.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 FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-\fB\-u\fR, \fB\-\-user USER\fR
-API Client Username
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.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\-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 whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Chef
+.\" 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 9e6b71b08d..31648f0cd8 100644
--- a/distro/common/man/man1/knife-cookbook.1
+++ b/distro/common/man/man1/knife-cookbook.1
@@ -1,332 +1,629 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-COOKBOOK" "1" "July 2013" "Chef 11.8.0.alpha.0" "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
-.
-.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
-.
-.TP
-\fB\-a\fR, \fB\-\-all\fR
-upload 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
-.
-.TP
-\fB\-d\fR, \fB\-\-upload\-dependencies\fR
-Uploads additional cookbooks that this cookbook lists in as dependencies in its metadata\.
-.
-.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\.
-.
-.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\.
-.
-.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
-.
-.TP
-\fB\-d\fR, \fB\-\-dir download_directory\fR
-the directory to download the cookbook into
-.
-.TP
-\fB\-f\fR, \fB\-\-force\fR
-overwrite an existing directory with the download
-.
-.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
-.
-.TP
-\fB\-a\fR, \fB\-\-all\fR
-delete all versions
-.
-.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
-.
-.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
-.
-.TP
-\fB\-o\fR, \fB\-\-cookbook\-path path\fR
-the directory where the cookbook will be created
-.
-.TP
-\fB\-r\fR, \fB\-\-readme\-format format\fR
-format of the readme file md, mkd, txt, rdoc
-.
-.TP
-\fB\-c\fR, \fB\-\-copyright copyright\fR
-name of copyright holder
-.
-.TP
-\fB\-i\fR, \fB\-\-license license\fR
-license for cookbook, apachev2 or none
-.
-.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
+.TH "KNIFE-COOKBOOK" "1" "Chef 11.10.0" "" "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.
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife cookbook\fP subcommand:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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 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 whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Use a regular expression to define the pattern used to bulk delete cookbooks:
+.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: \fBApache v2.0\fP (for \fBapachev2\fP), \fBGPL v2\fP (for \fBgplv2\fP), \fBGPL v3\fP (for \fBgplv3\fP), \fBMIT\fP (for \fBmit\fP), or \fBlicense \(aqProprietary \- All Rights Reserved\fP (for \fBnone\fP). 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
+.nf
+.ft C
+$ knife cookbook delete cookbook_name version
+.ft P
+.fi
+.sp
+For example:
+.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
+.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
+.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 Embedded Ruby (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
+.nf
+.ft C
+$ knife cookbook test cookbook_name
+.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
+.nf
+.ft C
+$ knife cookbook upload cookbook_name
+.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
+Chef
+.\" 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 5aca0bf317..20f48dd2fa 100644
--- a/distro/common/man/man1/knife-data-bag.1
+++ b/distro/common/man/man1/knife-data-bag.1
@@ -1,123 +1,469 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-DATA\-BAG" "1" "July 2013" "Chef 11.8.0.alpha.0" "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.10.0" "" "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
+A data bag item may be encrypted using \fI\%shared secret encryption\fP. This allows each data bag item 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). Each data bag item may be encrypted individually; if a data bag contains multiple encrypted data bag items, these data bag items are not required to share the same encryption keys.
+.sp
+The \fBknife data bag\fP subcommand is used to manage arbitrary stores of globally available JSON data.
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife data bag\fP subcommand:
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
.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 FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.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\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.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\-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 whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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 item.
+.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
+.nf
+.ft C
+$ knife data bag delete data_bag_name
+.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 item.
+.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 item.
+.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
+.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 item.
+.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
+.nf
+.ft C
+$ knife data bag show admins
+.ft P
+.fi
+.sp
+to return something like:
+.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
+Chef
+.\" 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..f5207b8dfc
--- /dev/null
+++ b/distro/common/man/man1/knife-delete.1
@@ -0,0 +1,123 @@
+.TH "KNIFE-DELETE" "1" "Chef 11.10.0" "" "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
+\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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.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 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\-\-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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.SH AUTHOR
+Chef
+.\" 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..9199556f9b
--- /dev/null
+++ b/distro/common/man/man1/knife-deps.1
@@ -0,0 +1,202 @@
+.TH "KNIFE-DEPS" "1" "Chef 11.10.0" "" "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
+\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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.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 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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-\-tree\fP
+Indicates that dependencies are shown in a visual tree structure (including duplicates, if they exist). Default: \fBfalse\fP.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+.nf
+.ft C
+$ knife deps nodes/node_name.json
+.ft P
+.fi
+.sp
+.nf
+.ft C
+$ knife deps roles/role_name.json
+.ft P
+.fi
+.sp
+.nf
+.ft C
+$ knife deps cookbooks/cookbook_name.json
+.ft P
+.fi
+.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
+A wildcard can be used to return all of the child nodes. For example, all of the environments:
+.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
+The output of \fBknife deps\fP can be passed to \fBknife upload\fP:
+.sp
+.nf
+.ft C
+$ knife upload \(gaknife deps nodes/*.json
+.ft P
+.fi
+.sp
+The output of \fBknife deps\fP can be passed to \fBknife xargs\fP:
+.sp
+.nf
+.ft C
+$ knife deps nodes/*.json | xargs knife upload
+.ft P
+.fi
+.SH AUTHOR
+Chef
+.\" 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..0ffd499991
--- /dev/null
+++ b/distro/common/man/man1/knife-diff.1
@@ -0,0 +1,206 @@
+.TH "KNIFE-DIFF" "1" "Chef 11.10.0" "" "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
+\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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.TP
+.B \fB\-\-cookbook\-version VERSION\fP
+The version of a cookbook to be downloaded.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.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\-\-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\-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 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\-\-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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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\-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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Chef
+.\" 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..f76fe9530c
--- /dev/null
+++ b/distro/common/man/man1/knife-download.1
@@ -0,0 +1,214 @@
+.TH "KNIFE-DOWNLOAD" "1" "Chef 11.10.0" "" "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
+\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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.TP
+.B \fB\-\-cookbook\-version VERSION\fP
+The version of a cookbook to be downloaded.
+.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\-\-[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\-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 FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
+.TP
+.B \fB\-\-[no\-]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\-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\-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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.TP
+.B \fB\-\-[no\-]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\-\-[no\-]recurse\fP
+Use \fB\-\-no\-recurse\fP to disable downloading 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.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Chef
+.\" 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..aa9919b1a7
--- /dev/null
+++ b/distro/common/man/man1/knife-edit.1
@@ -0,0 +1,117 @@
+.TH "KNIFE-EDIT" "1" "Chef 11.10.0" "" "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
+\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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.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 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\-\-local\fP
+Use to show files in the local chef\-repo instead of a remote location. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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\-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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.SH AUTHOR
+Chef
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-environment.1 b/distro/common/man/man1/knife-environment.1
index c52eb3b11a..7d91ab7f22 100644
--- a/distro/common/man/man1/knife-environment.1
+++ b/distro/common/man/man1/knife-environment.1
@@ -1,168 +1,420 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-ENVIRONMENT" "1" "July 2013" "Chef 11.8.0.alpha.0" "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
-.
+.TH "KNIFE-ENVIRONMENT" "1" "Chef 11.10.0" "" "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.
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife environment\fP subcommand:
+.INDENT 0.0
.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
-.
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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 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 whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.SH COMPARE
+.sp
+The \fBcompare\fP argument is used to compare the cookbook version constraints that are set on one (or more) environments.
+.sp
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
.nf
-
-{"apache2" => ">= 1\.5\.0"}
-.
+.ft C
+$ knife environment compare [ENVIRONMENT_NAME...] (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:
-.
-.TP
-\fB= VERSION\fR
-Equality\. Only the exact version specified may be used\.
-.
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
.TP
-\fB> VERSION\fR
-Greater than\. Only versions greater than \fBVERSION\fR may be used\.
-.
+.B \fB\-a\fP, \fB\-\-all\fP
+Indicates that all environments found at the specified path will be uploaded.
.TP
-\fB>= VERSION\fR
-Greater than or equal to\. Only versions equal to VERSION or greater may be used\.
-.
+.B \fB\-m\fP, \fB\-\-mismatch\fP
+Use to show only matching versions.
+.UNINDENT
+.sp
+\fBExample\fP
+.sp
+To compare cookbook versions for a single environment:
+.sp
+.nf
+.ft C
+$ knife environment compare development
+.ft P
+.fi
+.sp
+to return something similar to:
+.sp
+.nf
+.ft C
+ development
+apache 2.3.1
+windows 4.1.2
+.ft P
+.fi
+.sp
+To compare cookbook versions for multiple environments:
+.sp
+.nf
+.ft C
+$ knife environment compare development staging
+.ft P
+.fi
+.sp
+to return something similar to:
+.sp
+.nf
+.ft C
+ development staging
+apache 2.3.1 1.2.2
+windows 4.1.2 1.0.0
+postgresql 1.0.0 1.0.0
+.ft P
+.fi
+.sp
+To compare all cookbook versions for all environments:
+.sp
+.nf
+.ft C
+$ knife environment compare \-\-all
+.ft P
+.fi
+.sp
+to return something similar to:
+.sp
+.nf
+.ft C
+ staging development
+ulimit latest latest
+redisio latest latest
+journly latest latest
+aws latest latest
+test latest latest
+unicorn latest latest
+sensu latest latest
+runit latest latest
+templater latest latest
+powershell latest latest
+openssl latest latest
+rbenv latest latest
+rabbitmq latest latest
+postgresql latest latest
+mysql latest latest
+ohai latest latest
+git latest latest
+erlang latest latest
+ssh_known_hosts latest latest
+nginx latest latest
+database latest latest
+yum latest latest
+xfs latest latest
+apt latest latest
+dmg latest latest
+chef_handler latest latest
+windows 1.0.0 4.1.2
+.ft P
+.fi
+.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
+.ft C
+$ knife environment create ENVIRONMENT_NAME \-d DESCRIPTION
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This argument has the following options:
+.INDENT 0.0
.TP
-\fB< VERSION\fR
-Less than\. Only versions less than VERSION may be used\.
-.
+.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
-\fB<= VERSION\fR
-Less than or equal to\. Only versions lesser or equal to VERSION may be used\.
-.
+.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
-\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\-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
-
-{
- "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 list \-w
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-The Ruby format of an environment is as follows:
-.
-.IP "" 4
-.
+.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
+Chef
+.\" 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 69539d7161..f9a2c3b570 100644
--- a/distro/common/man/man1/knife-exec.1
+++ b/distro/common/man/man1/knife-exec.1
@@ -1,43 +1,302 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-EXEC" "1" "Chef 11.10.0" "" "knife exec"
+.SH NAME
+knife-exec \- The man page for the knife exec subcommand.
.
-.TH "KNIFE\-EXEC" "1" "July 2013" "Chef 11.8.0.alpha.0" "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
+\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
-\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_FILE\fP, \fB\-\-config CONFIG_FILE\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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.TP
-Remove the role \fIobsolete\fR from all nodes
-knife exec \-E \'nodes\.transform(:all){|n| n\.run_list\.delete("role[obsolete]")}\'
-.
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
.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\-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 CODE\fP, \fB\-\-exec CODE\fP
+A string of code that will be executed.
+.TP
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
+.TP
+.B \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 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\-p PATH:PATH\fP, \fB\-\-script\-path PATH:PATH\fP
+A colon\-separated path at which Ruby scripts are located.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Chef
+.\" 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..03c8332a31
--- /dev/null
+++ b/distro/common/man/man1/knife-index-rebuild.1
@@ -0,0 +1,55 @@
+.TH "KNIFE-INDEX-REBUILD" "1" "Chef 11.10.0" "" "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
+\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
+Chef
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-index.1 b/distro/common/man/man1/knife-index.1
deleted file mode 100644
index ac7c5b2655..0000000000
--- a/distro/common/man/man1/knife-index.1
+++ /dev/null
@@ -1,29 +0,0 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.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
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fBindex rebuild\fR \fI(options)\fR
-.
-.TP
-\fB\-y\fR, \fB\-\-yes\fR
-don\'t bother to ask if I\'m sure
-.
-.SH "DESCRIPTION"
-Rebuilds all the search indexes on the server\. This is accomplished by deleting all objects from the search index, and then forwarding each item in the database to \fBchef\-expander\fR(8) via \fBrabbitmq\-server\fR(1)\. Depending on the number of objects in the database, it may take some time for all objects to be indexed and available for search\.
-.
-.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\.
-.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man1/knife-list.1 b/distro/common/man/man1/knife-list.1
new file mode 100644
index 0000000000..acc3fe47c7
--- /dev/null
+++ b/distro/common/man/man1/knife-list.1
@@ -0,0 +1,158 @@
+.TH "KNIFE-LIST" "1" "Chef 11.10.0" "" "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
+\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\-1\fP
+Indicates that only one column of results will be shown. Default: \fBfalse\fP.
+.TP
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.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\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
+.TP
+.B \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
+.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\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\-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\-\-local\fP
+Indicates that only contents of the local directory will be returned. Default: \fBfalse\fP.
+.TP
+.B \fB\-p\fP
+Indicates that trailing slashes (/) will be shown for directories. Default: \fBfalse\fP.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Chef
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-node.1 b/distro/common/man/man1/knife-node.1
index 2d23088d69..1eae3344f2 100644
--- a/distro/common/man/man1/knife-node.1
+++ b/distro/common/man/man1/knife-node.1
@@ -1,134 +1,565 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-NODE" "1" "July 2013" "Chef 11.8.0.alpha.0" "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.10.0" "" "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.
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife node\fP subcommand:
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
.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 FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP.
.TP
-Fully Qualified Format
-"recipe[COOKBOOK::RECIPE_NAME]", for example, "recipe[chef::client]"
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.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\-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
-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\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Use a regular expression to define the pattern used to bulk delete nodes:
+.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
+.nf
+.ft C
+$ knife node delete node_name
+.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.
+.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
+Chef
+.\" 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..4965ea315b
--- /dev/null
+++ b/distro/common/man/man1/knife-raw.1
@@ -0,0 +1,152 @@
+.TH "KNIFE-RAW" "1" "Chef 11.10.0" "" "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
+\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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.TP
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether 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 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\-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\-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\-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\-\-[no\-]pretty\fP
+Use \fB\-\-no\-pretty\fP to disable pretty\-print output for JSON. Default: \fB\-\-pretty\fP.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Chef
+.\" 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..06f8936f70
--- /dev/null
+++ b/distro/common/man/man1/knife-recipe-list.1
@@ -0,0 +1,73 @@
+.TH "KNIFE-RECIPE-LIST" "1" "Chef 11.10.0" "" "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
+\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
+Chef
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-role.1 b/distro/common/man/man1/knife-role.1
index 95290921e6..347eac4c82 100644
--- a/distro/common/man/man1/knife-role.1
+++ b/distro/common/man/man1/knife-role.1
@@ -1,88 +1,358 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-ROLE" "1" "Chef 11.10.0" "" "knife role"
+.SH NAME
+knife-role \- The man page for the knife role subcommand.
.
-.TH "KNIFE\-ROLE" "1" "July 2013" "Chef 11.8.0.alpha.0" "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.
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife role\fP subcommand:
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
.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 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 whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Use a regular expression to define the pattern used to bulk delete roles:
+.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. 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": [\(aqrecipe[cookbook_name::recipe_name],
+ role[role_name]\(aq
+ ],
+ "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
+.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": [\(aqrecipe[cookbook_name::recipe_name],
+ role[role_name]\(aq
+ ],
+ "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
+Chef
+.\" 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 c15dd3a856..6cd09b57f4 100644
--- a/distro/common/man/man1/knife-search.1
+++ b/distro/common/man/man1/knife-search.1
@@ -1,280 +1,295 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-SEARCH" "1" "July 2013" "Chef 11.8.0.alpha.0" "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.10.0" "" "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 Chef Manage, 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
+\fBSyntax\fP
+.sp
+This argument has the following syntax:
+.sp
+.nf
+.ft C
+$ knife search INDEX SEARCH_QUERY
+.ft P
+.fi
+.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
+.ft C
+$ knife search \(aq*:*\(aq \-i
+.ft P
+.fi
+.sp
+will return something similar to:
+.sp
+.nf
+.ft C
+8 items found
+
+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
+.sp
+and is the same search as:
+.sp
+.nf
+.ft C
+$ knife search node \(aq*:*" \-i
+.ft P
+.fi
+.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
+.ft C
+$ knife search ubuntu
+.ft P
+.fi
+.sp
+or:
+.sp
+.nf
+.ft C
+$ knife search node "tags:*ubuntu* OR roles:*ubuntu* OR fqdn:*ubuntu* (etc.)"
+.ft P
+.fi
+.sp
+\fBOptions\fP
+.sp
+This sub\-command has the following options:
+.INDENT 0.0
.TP
-\fB\-a\fR, \fB\-\-attribute ATTR\fR
-Show only one attribute
-.
+.B \fB\-a ATTR\fP, \fB\-\-attribute ATTR\fP
+The attribute (or attributes) to show.
.TP
-\fB\-i\fR, \fB\-\-id\-only\fR
-Show only the ID of matching objects
-.
+.B \fB\-b ROW\fP, \fB\-\-start ROW\fP
+The row at which return results will begin.
.TP
-\fB\-q\fR, \fB\-\-query QUERY\fR
-The search query; useful to protect queries starting with \-
-.
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
.TP
-\fB\-R\fR, \fB\-\-rows INT\fR
-The number of rows to return
-.
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.TP
-\fB\-r\fR, \fB\-\-run\-list\fR
-Show only the run list
-.
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
.TP
-\fB\-o\fR, \fB\-\-sort SORT\fR
-The order to sort the results in
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.TP
-\fB\-b\fR, \fB\-\-start ROW\fR
-The row to start returning results at
-.
+.B \fB\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fB\-m\fR, \fB\-\-medium\fR
-Display medium sized output when searching nodes using the default summary format
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.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\-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 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\-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\-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\-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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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 \fB\-s URL\fP, \fB\-\-server\-url URL\fP
+The URL for the server.
+.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.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+To search for the IDs of all nodes running on the Amazon EC2 platform, enter:
+.sp
.nf
-
-knife search admins "field:search_pattern"
-.
+.ft C
+$ knife search node \(aqec2:*\(aq \-i
+.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
+to return something like:
+.sp
.nf
+.ft C
+4 items found
-knife search INDEX \'field:[X TO Y]
-.
-.fi
-.
-.IP "" 0
-.
-.P
-To match values between X and Y, exclusively, use curly brackets:
-.
-.IP "" 4
-.
-.nf
+ip\-0A7CA19F.ec2.internal
-knife search INDEX \'field:{X TO Y}\'
-.
-.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
-.
-.nf
+ip\-0A58CF8E.ec2.internal
-knife search INDEX \'field:term~\'
-.
+ip\-0A58E134.ec2.internal
+
+ip\-0A7CFFD5.ec2.internal
+.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
+To search for the instance type (flavor) of all nodes running on the Amazon EC2 platform, enter:
+.sp
.nf
-
-knife search INDEX \'field:(NOT X)\'
-.
+.ft C
+$ knife search node \(aqec2:*\(aq \-a ec2.instance_type
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-To find records where \fBfield1\fR is X and \fBfield2\fR is Y:
-.
-.IP "" 4
-.
+.sp
+to return something like:
+.sp
.nf
+.ft C
+4 items found
-knife search INDEX \'field1:X AND field2:Y\'
-.
+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
-To find records where \fBfield\fR is X or Y:
-.
-.IP "" 4
-.
+.sp
+To search for all nodes running Ubuntu, enter:
+.sp
.nf
-
-knife search INDEX \'field:X OR field:Y\'
-.
+.ft C
+$ knife search node \(aqplatform:ubuntu\(aq
+.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 search for all nodes running CentOS in the production environment, enter:
+.sp
.nf
-
-knife search INDEX \'field:"term with spaces"\'
-.
+.ft C
+$ knife search node \(aqchef_environment:production AND platform:centos\(aq
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-The following characters must be escaped:
-.
-.IP "" 4
-.
+.sp
+To find a nested attribute, use a pattern similar to the following:
+.sp
.nf
-
-+ \- && || ! ( ) { } [ ] ^ " ~ * ? : \e
-.
+.ft C
+$ knife search node <query_to_run> \-a <main_attribute>.<nested_attribute>
+.ft P
.fi
-.
-.IP "" 0
-.
-.SH "EXAMPLES"
-Find the nodes with the fully\-qualified domain name (FQDN) www\.example\.com:
-.
-.IP "" 4
-.
+.sp
+To build a search query to use more than one attribute, use an underscore (\fB_\fP) to separate each attribute. For example, the following query will search for all nodes running a specific version of Ruby:
+.sp
.nf
-
-knife search node \'fqdn:www\.example\.com\'
-.
+.ft C
+$ knife search node "languages_ruby_version:1.9.3"
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-Find the nodes running a version of Ubuntu:
-.
-.IP "" 4
-.
+.sp
+To build a search query that can find a nested attribute:
+.sp
.nf
-
-knife search node \'platform:ubuntu*\'
-.
+.ft C
+$ knife search node name:<node_name> \-a kernel.machine
+.ft P
.fi
-.
-.IP "" 0
-.
-.P
-Find all nodes running CentOS in the production environment:
-.
-.IP "" 4
-.
+.sp
+To test a search query that will be used in a \fBknife ssh\fP command:
+.sp
.nf
-
-knife search node \'chef_environment:production AND platform:centos\'
-.
+.ft C
+$ knife search node "role:web 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
+Chef
+.\" 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..6ec1d14f0d
--- /dev/null
+++ b/distro/common/man/man1/knife-show.1
@@ -0,0 +1,144 @@
+.TH "KNIFE-SHOW" "1" "Chef 11.10.0" "" "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
+\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 subcommand 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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.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 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\-\-local\fP
+Indicates that instead of remote files, local files will be shown.
+.TP
+.B \fB\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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\-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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.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
+.nf
+.ft C
+$ knife show roles/ environments/
+.ft P
+.fi
+.SH AUTHOR
+Chef
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife-ssh.1 b/distro/common/man/man1/knife-ssh.1
index 3d1a648a47..e50e7ebdb8 100644
--- a/distro/common/man/man1/knife-ssh.1
+++ b/distro/common/man/man1/knife-ssh.1
@@ -1,79 +1,244 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "KNIFE\-SSH" "1" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
-.
-.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
-.
+.TH "KNIFE-SSH" "1" "Chef 11.10.0" "" "knife ssh"
+.SH NAME
+knife-ssh \- The man page for the knife ssh 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 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
+\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
-\fB\-a\fR, \fB\-\-attribute ATTR\fR
-The attribute to use for opening the connection \- default is fqdn
-.
+.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
-\fB\-C\fR, \fB\-\-concurrency NUM\fR
-The number of concurrent connections
-.
+.B \fB\-A\fP, \fB\-\-forward\-agent\fP
+Indicates that SSH agent forwarding is enabled.
.TP
-\fB\-m\fR, \fB\-\-manual\-list\fR
-QUERY is a space separated list of servers
-.
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
.TP
-\fB\-P\fR, \fB\-\-ssh\-password PASSWORD\fR
-The ssh password
-.
+.B \fB\-C NUM\fP, \fB\-\-concurrency NUM\fP
+The number of allowed concurrent connections.
.TP
-\fB\-x\fR, \fB\-\-ssh\-user USERNAME\fR
-The ssh username
-.
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.TP
-\fB\-i\fR, \fB\-\-identity\-file IDENTITY_FILE\fR
-The SSH identity file used for authentication
-.
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
.TP
-\fB\-p\fR, \fB\-\-ssh\-port PORT\fR
-The ssh port
-.
+.B \fB\-d\fP, \fB\-\-disable\-editing\fP
+Indicates that $EDITOR will not be opened; data will be accepted as\-is.
.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\-\-defaults\fP
+Indicates that Knife will use the default value, instead of asking a user to provide one.
.TP
-\fBinteractive\fR
-A built\-in multiplexer\. \fBinteractive\fR supports running commands on a subset of the connected hosts in parallel
-.
+.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
+The $EDITOR that is used for all interactive commands.
.TP
-\fBscreen\fR(1)
-Runs ssh interactively inside \fBscreen\fR\. ~/\.screenrc will be sourced if it exists\.
-.
+.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
-\fBtmux\fR(1)
-Runs ssh interactively inside tmux\.
-.
+.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
-\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\-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\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.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\-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\-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 \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 \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\-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\-x USER_NAME\fP, \fB\-\-ssh\-user USER_NAME\fP
+The SSH user name.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+.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
+.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
+Chef
+.\" 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 1f99d067ba..544129e2f8 100644
--- a/distro/common/man/man1/knife-status.1
+++ b/distro/common/man/man1/knife-status.1
@@ -1,29 +1,198 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-STATUS" "1" "Chef 11.10.0" "" "knife status"
+.SH NAME
+knife-status \- The man page for the knife status subcommand.
.
-.TH "KNIFE\-STATUS" "1" "July 2013" "Chef 11.8.0.alpha.0" "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
+\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
-\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_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.TP
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether 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 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\-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\-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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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.
+.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.
+.TP
+.B \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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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 the status for nodes on which the chef\-client did not run successfully 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
+Chef
+.\" 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 5ccbeda299..b9e9343b73 100644
--- a/distro/common/man/man1/knife-tag.1
+++ b/distro/common/man/man1/knife-tag.1
@@ -1,43 +1,169 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE-TAG" "1" "Chef 11.10.0" "" "knife tag"
+.SH NAME
+knife-tag \- The man page for the knife tag subcommand.
.
-.TH "KNIFE\-TAG" "1" "July 2013" "Chef 11.8.0.alpha.0" "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.
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife tag\fP subcommand:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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 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 whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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
+Chef
+.\" 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..e51c9ebcbe
--- /dev/null
+++ b/distro/common/man/man1/knife-upload.1
@@ -0,0 +1,228 @@
+.TH "KNIFE-UPLOAD" "1" "Chef 11.10.0" "" "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
+\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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.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\-\-[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\-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 FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\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\-\-[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\-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\-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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+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
+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
+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
+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
+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
+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
+.nf
+.ft C
+$ knife upload \(gaknife deps nodes/*.json\(ga
+.ft P
+.fi
+.SH AUTHOR
+Chef
+.\" 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..978a0e7d43
--- /dev/null
+++ b/distro/common/man/man1/knife-user.1
@@ -0,0 +1,300 @@
+.TH "KNIFE-USER" "1" "Chef 11.10.0" "" "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 version 10.x. This subcommand will NOT run against open source server 11, Enterprise Chef (including hosted Enterprise Chef), or Private Chef.
+.RE
+.SH COMMON OPTIONS
+.sp
+The following options may be used with any of the arguments available to the \fBknife user\fP subcommand:
+.INDENT 0.0
+.TP
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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 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 whether colored output will be used.
+.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\-\-verbose\fP
+Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.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 \fB/etc/chef/client.pem\fP.
+.IP \(bu 2
+For Knife, the private key is typically copied to \fB~/.chef/client_name.pem\fP 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 Enterprise 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
+.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
+.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
+.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, e.g. \fB\-F yaml\fP for YAML.)
+.SH AUTHOR
+Chef
+.\" 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..b0e8f0b22d
--- /dev/null
+++ b/distro/common/man/man1/knife-xargs.1
@@ -0,0 +1,155 @@
+.TH "KNIFE-XARGS" "1" "Chef 11.10.0" "" "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
+\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\-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\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
+The configuration file to use.
+.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\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used.
+.TP
+.B \fB\-\-concurrency\fP
+The number of allowed concurrent connections. Default: \fB10\fP.
+.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\-\-[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\-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 FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\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\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.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\-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\-\-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\-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\-\-print\-after\fP
+Indicates that data will be shown after a destructive operation.
+.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\-s LENGTH\fP, \fB\-\-max\-chars LENGTH\fP
+The maximum size (in characters) for a command line. Default: \fBnil\fP.
+.TP
+.B \fB\-\-server\-url URL\fP
+The URL for the server.
+.TP
+.B \fB\-t\fP
+Indicates that the print command will be run on the command line. Default: \fBnil\fP.
+.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).
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo.
+.UNINDENT
+.sp
+\fBExamples\fP
+.sp
+.nf
+.ft C
+$ knife deps nodes/*.json | xargs knife upload
+.ft P
+.fi
+.SH AUTHOR
+Chef
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man1/knife.1 b/distro/common/man/man1/knife.1
index a8ce1c10fd..7e20d8a4c9 100644
--- a/distro/common/man/man1/knife.1
+++ b/distro/common/man/man1/knife.1
@@ -1,285 +1,228 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "KNIFE" "1" "Chef 11.8.0" "" "knife"
+.SH NAME
+knife \- The man page for the knife command line tool.
+.
+.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
+Knife is a command\-line tool that provides an interface between a local chef\-repo and the server. Knife helps users to manage:
+.INDENT 0.0
+.IP \(bu 2
+Nodes
+.IP \(bu 2
+Cookbooks and recipes
+.IP \(bu 2
+Roles
+.IP \(bu 2
+Stores of JSON data (data bags), including encrypted data
+.IP \(bu 2
+Environments
+.IP \(bu 2
+Cloud resources, including provisioning
+.IP \(bu 2
+The installation of the chef\-client on management workstations
+.IP \(bu 2
+Searching of indexed data on the server
+.UNINDENT
+.sp
+Knife subcommands:
+.INDENT 0.0
+.IP \(bu 2
+knife bootstrap
+.IP \(bu 2
+knife client
+.IP \(bu 2
+knife configure
+.IP \(bu 2
+knife cookbook
+.IP \(bu 2
+knife cookbook site
+.IP \(bu 2
+knife data bag
+.IP \(bu 2
+knife delete
+.IP \(bu 2
+knife deps
+.IP \(bu 2
+knife diff
+.IP \(bu 2
+knife download
+.IP \(bu 2
+knife edit
+.IP \(bu 2
+knife environment
+.IP \(bu 2
+knife exec
+.IP \(bu 2
+knife list
+.IP \(bu 2
+knife node
+.IP \(bu 2
+knife raw
+.IP \(bu 2
+knife recipe list
+.IP \(bu 2
+knife role
+.IP \(bu 2
+knife search
+.IP \(bu 2
+knife show
+.IP \(bu 2
+knife ssh
+.IP \(bu 2
+knife status
+.IP \(bu 2
+knife tag
+.IP \(bu 2
+knife upload
+.IP \(bu 2
+knife user
+.IP \(bu 2
+knife xargs
+.UNINDENT
+.SH WORKING WITH KNIFE
+.sp
+Knife runs from a management workstation and sits in\-between a server and an organization\(aqs infrastructure. Knife interacts with a server by using the same REST API that is used by a chef\-client. Role\-based authentication controls (RBAC) can be used to authorize changes when Knife is run with Hosted Chef or Private Chef. Knife is configured during workstation setup, but subsequent modifications can be made using the knife.rb configuration file.
+.SS JSON Data Format
+.sp
+Most data is entered using a text editor in JSON format, unless the \fB\-\-disable\-editing\fP option is entered as part of a command. (Encrypted data bags use YAML, which is a superset of JSON.) JSON is a common, language\-independent data format that provides a simple text representation of arbitrary data structures. For more information about JSON, see \fI\%http://www.json.org/\fP or \fI\%http://en.wikipedia.org/wiki/JSON\fP.
+.SS Set the Text Editor
+.sp
+Some Knife commands, such as \fBknife data bag edit\fP, require that information be edited as JSON data using a text editor. For example, the following command:
+.sp
+.nf
+.ft C
+$ knife data bag edit admins admin_name
+.ft P
+.fi
+.sp
+will open up the text editor with data similar to:
+.sp
+.nf
+.ft C
+{
+ "id": "admin_name"
+}
+.ft P
+.fi
+.sp
+Changes to that file can then be made:
+.sp
+.nf
+.ft C
+{
+ "id": "Justin C."
+ "description": "I am passing the time by letting time pass over me ..."
+}
+.ft P
+.fi
+.sp
+The type of text editor that is used by Knife can be configured by adding an entry to the knife.rb file or by setting an \fBEDITOR\fP environment variable. For example, to configure the text editor to always open with vim, add the following to the knife.rb file:
+.sp
+.nf
+.ft C
+knife[:editor] = "/usr/bin/vim"
+.ft P
+.fi
+.sp
+When a Microsoft Windows file path is enclosed in a double\-quoted string (" "), the same backslash character (\fB\e\fP) that is used to define the file path separator is also used in Ruby to define an escape character. The knife.rb file is a Ruby file; therefore, file path separators must be escaped. In addition, spaces in the file path must be replaced with \fB~1\fP so that the length of each section within the file path is not more than 8 characters. For example, if EditPad Pro is the text editor of choice and is located at the following path:
+.sp
+.nf
+.ft C
+C:\e\eProgram Files (x86)\eEditPad Pro\eEditPad.exe
+.ft P
+.fi
+.sp
+the setting in the knife.rb file would be similar to:
+.sp
+.nf
+.ft C
+knife[:editor] = "C:\e\eProgra~1\e\eEditPa~1\e\eEditPad.exe"
+.ft P
+.fi
+.sp
+One approach to working around the double\- vs. single\-quote issue is to put the single\-quotes outside of the double\-quotes. For example, for Notepad++:
+.sp
+.nf
+.ft C
+knife[:editor] = \(aq"C:\eProgram Files (x86)\eNotepad++\enotepad++.exe \-nosession \-multiInst"\(aq
+.ft P
+.fi
+.sp
+for Sublime Text:
+.sp
+.nf
+.ft C
+knife[:editor] = \(aq"C:\eProgram Files\eSublime Text 2\esublime_text.exe \-\-wait"\(aq
+.ft P
+.fi
+.sp
+for TextPad:
+.sp
+.nf
+.ft C
+knife[:editor] = \(aq"C:\eProgram Files (x86)\eTextPad 7\eTextPad.exe"\(aq
+.ft P
+.fi
+.sp
+and for vim:
+.sp
+.nf
+.ft C
+knife[:editor] = \(aq"C:\eProgram Files (x86)\evim\evim74\egvim.exe"\(aq
+.ft P
+.fi
+.SS Using Quotes
+.sp
+Values can be entered with double quotes (" ") or single quotes (\(aq \(aq), but this should be done consistently.
+.SS Sub\-commands
+.sp
+Knife comes with a collection of built in subcommands that work together to provide all of the functionality required to take specific actions against any object in an organization, including cookbooks, nodes, roles, data bags, environments, and users. A Knife plugin extends the functionality beyond built\-in subcommands.
+.sp
+Knife has the following subcommands: \fBbootstrap\fP, \fBclient\fP, \fBconfigure\fP, \fBcookbook\fP, \fBcookbook site\fP, \fBdata bag\fP, \fBdelete\fP, \fBdeps\fP, \fBdiff\fP, \fBdownload\fP, \fBedit\fP, \fBenvironment\fP, \fBexec\fP, \fBindex rebuild\fP, \fBlist\fP, \fBnode\fP, \fBrecipe list\fP, \fBrole\fP, \fBsearch\fP, \fBshow\fP, \fBssh\fP, \fBstatus\fP, \fBtag\fP, \fBupload\fP, \fBuser\fP, and \fBxargs\fP.
+.IP Note
+The following subcommands run only against the open source server: \fBindex rebuild\fP and \fBuser\fP.
+.RE
+.SS Syntax
+.sp
+All Knife subcommands have the following syntax:
+.INDENT 0.0
+.INDENT 3.5
+knife subcommand [ARGUMENT] (options)
+.UNINDENT
+.UNINDENT
+.sp
+Each subcommand has its own set of arguments and options.
+.IP Note
+All syntax examples in this document show variables in ALL_CAPS. For example \fB\-u PORT_LIST\fP (where PORT_LIST is a comma\-separated list of local and public UDP ports) or \fB\-F FORMAT\fP (where FORMAT determines the output format, either \fBsummary\fP, \fBtext\fP, \fBjson\fP, \fByaml\fP, or \fBpp\fP). These variables often require specific values that are unique to each organization.
+.RE
+.SH AUTHOR
+Opscode
+.\" Generated by docutils manpage writer.
.
-.TH "KNIFE" "1" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
-.
-.SH "NAME"
-\fBknife\fR \- Chef Server API client utility
-.
-.SH "SYNOPSIS"
-\fBknife\fR \fIsub\-command\fR [\fIargument\fR\.\.\.] \fI(options)\fR
-.
-.SH "DESCRIPTION"
-Knife is a command\-line utility used to manage data on a Chef server through the HTTP(S) API\. Knife is organized into groups of subcommands centered around the various object types in Chef\. Each category of subcommand is documented in its own manual page\. Available topics are:
-.
-.IP "\(bu" 4
-bootstrap
-.
-.IP "\(bu" 4
-client
-.
-.IP "\(bu" 4
-configure
-.
-.IP "\(bu" 4
-cookbook\-site
-.
-.IP "\(bu" 4
-cookbook
-.
-.IP "\(bu" 4
-data\-bag
-.
-.IP "\(bu" 4
-environment
-.
-.IP "\(bu" 4
-exec
-.
-.IP "\(bu" 4
-index
-.
-.IP "\(bu" 4
-node
-.
-.IP "\(bu" 4
-recipe
-.
-.IP "\(bu" 4
-role
-.
-.IP "\(bu" 4
-search
-.
-.IP "\(bu" 4
-ssh
-.
-.IP "\(bu" 4
-status
-.
-.IP "\(bu" 4
-tag
-.
-.IP "" 0
-.
-.P
-If the knife manuals are in your \fBMANPATH\fR, you can access help for the above topics using \fBman knife\-TOPIC\fR; otherwise, you can view the documentation using \fBknife help TOPIC\fR\.
-.
-.SH "OPTIONS"
-.
-.TP
-\fB\-s\fR, \fB\-\-server\-url\fR URL
-Chef Server URL, corresponds to \fBChef::Config\fR \fBchef_server_url\fR\.
-.
-.TP
-\fB\-k\fR, \fB\-\-key\fR KEY
-API Client Key, corresponds to \fBChef::Config\fR \fBclient_key\fR\.
-.
-.TP
-\fB\-c\fR, \fB\-\-config\fR CONFIG
-The configuration file to use
-.
-.TP
-\fB\-E\fR, \fB\-\-environment ENVIRONMENT\fR
-Set the Chef environment
-.
-.TP
-\fB\-e\fR, \fB\-\-editor\fR EDITOR
-Set the editor to use for interactive commands
-.
-.TP
-\fB\-F\fR, \fB\-\-format\fR FORMAT
-Which format to use for output\. See FORMATS for details\.
-.
-.TP
-\fB\-d\fR, \fB\-\-disable\-editing\fR
-Do not open EDITOR, just accept the data as is
-.
-.TP
-\fB\-u\fR, \fB\-\-user\fR USER
-API Client Username, corresponds to \fBChef::Config\fR \fBnode_name\fR\.
-.
-.TP
-\fB\-p\fR, \fB\-\-print\-after\fR
-Show the data after a destructive operation
-.
-.TP
-\fB\-v\fR, \fB\-\-version\fR
-Show chef version
-.
-.TP
-\fB\-V\fR, \fB\-\-verbose\fR
-More verbose output\. Use twice for max verbosity\.
-.
-.TP
-\fB\-y\fR, \fB\-\-yes\fR
-Say yes to all prompts for confirmation
-.
-.TP
-\fB\-\-defaults\fR
-Accept default values for all questions
-.
-.TP
-\fB\-\-[no\-]color\fR
-Use colored output\. Color enabled by default\.
-.
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-Show the available options for a command\.
-.
-.SH "SUB\-COMMANDS"
-Sub\-commands that operate on the basic Chef data types are structured as \fINOUN verb NOUN (options)\fR\. For all data types, the following commands are available:
-.
-.IP "\(bu" 4
-create (create)
-.
-.IP "\(bu" 4
-list and show (read)
-.
-.IP "\(bu" 4
-edit (update)
-.
-.IP "\(bu" 4
-delete (destroy)
-.
-.IP "" 0
-.
-.P
-Knife also includes commands that take actions other than displaying or modifying data on the Chef Server, such as \fBknife\-ssh(1)\fR\.
-.
-.SH "CONFIGURATION"
-The knife configuration file is a Ruby DSL to set configuration parameters for Knife\'s \fBGENERAL OPTIONS\fR\. The default location for the config file is \fB~/\.chef/knife\.rb\fR\. If managing multiple Chef repositories, per\-repository config files can be created\. The file must be \fB\.chef/knife\.rb\fR in the current directory of the repository\.
-.
-.P
-If the config file exists, knife uses these settings for \fBGENERAL OPTIONS\fR defaults\.
-.
-.IP "\(bu" 4
-\fBnode_name\fR: User or client identity (i\.e\., \fIname\fR) to use for authenticating requests to the Chef Server\.
-.
-.IP "\(bu" 4
-\fBclient_key\fR: Private key file to authenticate to the Chef server\. Corresponds to the \fB\-k\fR or \fB\-\-key\fR option\.
-.
-.IP "\(bu" 4
-\fBchef_server_url\fR: URL of the Chef server\. Corresponds to the \fB\-s\fR or \fB\-\-server\-url\fR option\. This is requested from the user when running this sub\-command\.
-.
-.IP "\(bu" 4
-\fBsyntax_check_cache_path\fR: Specifies the path to a directory where knife caches information about files that it has syntax checked\.
-.
-.IP "\(bu" 4
-\fBvalidation_client_name\fR: Specifies the name of the client used to validate new clients\.
-.
-.IP "\(bu" 4
-\fBvalidation_key\fR: Specifies the private key file to use when bootstrapping new hosts\. See knife\-client(1) for more information about the validation client\.
-.
-.IP "\(bu" 4
-\fBcookbook_copyright\fR, \fBcookbook_email\fR, \fBcookbook_license\fR, \fBreadme_format\fR Used by \fBknife cookbook create\fR sub\-command to specify the copyright holder, maintainer email, license and readme format (respectively) for new cookbooks\. The copyright holder is listed as the maintainer in the cookbook\'s metadata and as the Copyright in the comments of the default recipe\. The maintainer email is used in the cookbook metadata\. The license determines what preamble to put in the comment of the default recipe, and is listed as the license in the cookbook metadata\. Currently supported licenses are "apachev2" and "none"\. Any other values will result in an empty license in the metadata (needs to be filled in by the author), and no comment preamble in the default recipe\. Currently supported readme formats are "md", "mkd", "txt", and "rdoc"\. Any other value will result in an unformatted README\.
-.
-.IP "" 0
-.
-.SH "FILES"
-\fI~/\.chef/knife\.rb\fR
-.
-.P
-Ruby DSL configuration file for knife\. See \fBCONFIGURATION\fR\.
-.
-.SH "FORMATS"
-The amount of content displayed and the output format are modified by the \fB\-\-format\fR option\. If no alternate format is selected, the default is summary\.
-.
-.P
-Valid formats are:
-.
-.TP
-\fBsummary\fR
-displays the node in a custom, summarized format (default)
-.
-.TP
-\fBtext\fR
-displays the node data in its entirety using the colorized tree display
-.
-.TP
-\fBjson\fR
-displays the node in JSON format
-.
-.TP
-\fByaml\fR
-displays the node in YAML format
-.
-.TP
-\fBpp\fR
-displays the node using Ruby\'s pretty printer\.
-.
-.P
-For brevity, only the first character of the format is required, for example, \-Fj will produce JSON format output\.
-.
-.SH "CHEF WORKFLOW"
-When working with Chef and Knife in the local repository, the recommended workflow outline looks like:
-.
-.IP "\(bu" 4
-Create repository\. A skeleton sample is provided at \fIhttp://github\.com/opscode/chef\-repo/\fR\.
-.
-.IP "\(bu" 4
-Configure knife, see \fBCONFIGURATION\fR\.
-.
-.IP "\(bu" 4
-Download cookbooks from the Opscode cookbooks site, see \fBCOOKBOOK SITE SUB\-COMMANDS\fR\.
-.
-.IP "\(bu" 4
-Or, create new cookbooks, see \fBcookbook create\fR sub\-command\.
-.
-.IP "\(bu" 4
-Commit changes to the version control system\. See your tool\'s documentation\.
-.
-.IP "\(bu" 4
-Upload cookbooks to the Chef Server, see \fBCOOKBOOK SUB\-COMMANDS\fR\.
-.
-.IP "\(bu" 4
-Launch instances in the Cloud, OR provision new hosts; see \fBCLOUD COMPUTING SUB\-COMMANDS\fR and \fBBOOTSTRAP SUB\-COMMANDS\fR\.
-.
-.IP "\(bu" 4
-Watch Chef configure systems!
-.
-.IP "" 0
-.
-.P
-A note about git: Opscode and many folks in the Chef community use git, but it is not required, except in the case of the \fBcookbook site vendor\fR sub\-command, as it uses git directly\. Version control is strongly recommended though, and git fits with a lot of the workflow paradigms\.
-.
-.SH "EXAMPLES"
-.
-.SH "ENVIRONMENT"
-.
-.TP
-\fBEDITOR\fR
-The text editor to use for editing data\. The \-\-editor option takes precedence over this value, and the \-\-disable\-editing option supresses data editing entirely\.
-.
-.SH "SEE ALSO"
-\fBchef\-client(8)\fR \fBchef\-server(8)\fR \fBchef\-shell(1)\fR
-.
-.P
-\fBknife\-bootstrap(1)\fR \fBknife\-client(1)\fR \fBknife\-configure(1)\fR \fBknife\-cookbook\-site(1)\fR \fBknife\-cookbook(1)\fR \fBknife\-data\-bag(1)\fR \fBknife\-environment(1)\fR \fBknife\-exec(1)\fR \fBknife\-index(1)\fR \fBknife\-node(1)\fR \fBknife\-recipe(1)\fR \fBknife\-role(1)\fR \fBknife\-search(1)\fR \fBknife\-ssh(1)\fR \fBknife\-tag(1)\fR
-.
-.P
-Complete Chef documentation is available online: \fIhttp://wiki\.opscode\.com/display/chef/Home/\fR
-.
-.P
-JSON is JavaScript Object Notation \fIhttp://json\.org/\fR
-.
-.P
-SOLR is an open source search engine\. \fIhttp://lucene\.apache\.org/solr/\fR
-.
-.P
-\fBgit(1)\fR is a version control system \fIhttp://git\-scm\.com/\fR
-.
-.P
-This manual page was generated from Markdown with \fBronn(1)\fR \fIhttp://rtomayko\.github\.com/ronn/ronn\.1\.html\fR
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@opscode\.com\fR of Opscode (\fIhttp://www\.opscode\.com\fR), with contributions from the community\.
-.
-.SH "DOCUMENTATION"
-This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR\.
-.
-.SH "LICENSE"
-Both Chef and this documentation are released under the terms of the Apache 2\.0 License\. You may view the license online: \fIhttp://www\.apache\.org/licenses/LICENSE\-2\.0\.html\fR On some systems, the complete text of the Apache 2\.0 License may be found in \fB/usr/share/common\-licenses/Apache\-2\.0\fR\.
-.
-.SH "CHEF"
-Knife is distributed with Chef\. \fIhttp://wiki\.opscode\.com/display/chef/Home\fR
diff --git a/distro/common/man/man8/chef-client.8 b/distro/common/man/man8/chef-client.8
index b0e8eac533..ff10522772 100644
--- a/distro/common/man/man8/chef-client.8
+++ b/distro/common/man/man8/chef-client.8
@@ -1,104 +1,273 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.TH "CHEF-CLIENT" "8" "Chef 11.10.0" "" "chef-client"
+.SH NAME
+chef-client \- The man page for the chef-client command line tool.
.
-.TH "CHEF\-CLIENT" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
+.nr rst2man-indent-level 0
.
-.SH "NAME"
-\fBchef\-client\fR \- Runs a client node connecting to a chef\-server\.
-.
-.SH "SYNOPSIS"
-\fBchef\-client\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 chef\-client is an agent that runs locally on every node that is registered with the server. When a chef\-client is run, it will perform all of the steps that are required to bring the node into the expected state, including:
+.INDENT 0.0
+.IP \(bu 2
+Registering and authenticating the node with the server
+.IP \(bu 2
+Building the node object
+.IP \(bu 2
+Synchronizing cookbooks
+.IP \(bu 2
+Compiling the resource collection by loading each of the required cookbooks, including recipes, attributes, and all other dependencies
+.IP \(bu 2
+Taking the appropriate and required actions to configure the node
+.IP \(bu 2
+Looking for exceptions and notifications, handling each as required
+.UNINDENT
+.sp
+The chef\-client executable can be run as a command\-line tool.
+.IP Note
+A client.rb file is used to specify the configuration details for the chef\-client. This file is the default configuration file and is loaded every time the chef\-client executable is run. The chef\-client executable can be run as a daemon. On UNIX\- and Linux\-based machines, the configuration file is located at: \fB/etc/chef/client.rb\fP. On Microsoft Windows machines, the configuration file is located at \fBC:\echef\eclient.rb\fP.
+.RE
+.SH OPTIONS
+.sp
+This command has the following syntax:
+.sp
+.nf
+.ft C
+chef\-client OPTION VALUE OPTION VALUE ...
+.ft P
+.fi
+.sp
+This command has the following options:
+.INDENT 0.0
.TP
-\fB\-S\fR, \fB\-\-server CHEFSERVERURL\fR
-The chef server URL
-.
+.B \fB\-A\fP, \fB\-\-fatal\-windows\-admin\-check\fP
+Indicates that a chef\-client run should fail if the chef\-client does not have administrator privileges in Microsoft Windows.
.TP
-\fB\-c\fR, \fB\-\-config CONFIG\fR
-The configuration file to use
-.
+.B \fB\-\-chef\-zero\-port PORT\fP
+The port on which chef\-zero will listen.
.TP
-\fB\-d\fR, \fB\-\-daemonize\fR
-Daemonize the process
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBdoc\fP (default) or \fBmin\fP.
+.sp
+Use \fBdoc\fP to print the progress of the chef\-client run using full strings that display a summary of updates as they occur.
+.sp
+Use \fBmin\fP to print the progress of the chef\-client run using single characters. A summary of updates is printed at the end of the chef\-client run. A dot (\fB.\fP) is printed for events that do not have meaningful status information, such as loading a file or synchronizing a cookbook. For resources, a dot (\fB.\fP) is printed when the resource is up to date, an \fBS\fP is printed when the resource is skipped by \fBnot_if\fP or \fBonly_if\fP, and a \fBU\fP is printed when the resource is updated.
+.sp
+Other formatting options are available when those formatters are configured in the client.rb file using the \fBadd_formatter\fP option.
.TP
-\fB\-g\fR, \fB\-\-group GROUP\fR
-Group to set privilege to
-.
+.B \fB\-\-force\-formatter\fP
+Indicates that formatter output will be used instead of logger output.
.TP
-\fB\-i\fR, \fB\-\-interval SECONDS\fR
-Run chef\-client periodically, in seconds
-.
+.B \fB\-\-force\-logger\fP
+Indicates that logger output will be used instead of formatter output.
.TP
-\fB\-j\fR, \fB\-\-json\-attributes JSON_ATTRIBS\fR
-Load attributes from a JSON file or URL
-.
+.B \fB\-g GROUP\fP, \fB\-\-group GROUP\fP
+The name of the group that owns a process. This is required when starting any executable as a daemon.
.TP
-\fB\-E\fR, \fB\-\-environment ENVIRONMENT\fR
-Set the Chef Environment on the node
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.TP
-\fB\-l\fR, \fB\-\-log_level LEVEL\fR
-Set the log level (debug, info, warn, error, fatal)
-.
+.B \fB\-i SECONDS\fP, \fB\-\-interval SECONDS\fP
+The frequency (in seconds) at which the chef\-client runs. Default value: \fB1800\fP.
.TP
-\fB\-L\fR, \fB\-\-logfile LOGLOCATION\fR
-Set the log file location, defaults to STDOUT \- recommended for daemonizing
-.
+.B \fB\-j PATH\fP, \fB\-\-json\-attributes PATH\fP
+The path to a file that contains JSON data.
.TP
-\fB\-N\fR, \fB\-\-node\-name NODE_NAME\fR
-The node name for this client
-.
+.B \fB\-k KEY_FILE\fP, \fB\-\-client_key KEY_FILE\fP
+The location of the file which contains the client key. Default value: \fB/etc/chef/client.pem\fP.
.TP
-\fB\-o\fR, \fB\-\-override\-runlist\fR
-Replace current run list with specified items
-.
+.B \fB\-K KEY_FILE\fP, \fB\-\-validation_key KEY_FILE\fP
+The location of the file which contains the key used when a chef\-client is registered with a server. A validation key is signed using the \fBvalidation_client_name\fP for authentication. Default value: \fB/etc/chef/validation.pem\fP.
.TP
-\fB\-K\fR, \fB\-\-validation_key KEY_FILE\fR
-Set the validation key file location, used for registering new clients
-.
+.B \fB\-l LEVEL\fP, \fB\-\-log_level LEVEL\fP
+The level of logging that will be stored in a log file.
.TP
-\fB\-k\fR, \fB\-\-client_key KEY_FILE\fR
-Set the client key file location
-.
+.B \fB\-L LOGLOCATION\fP, \fB\-\-logfile c\fP
+The location in which log file output files will be saved. If this location is set to something other than \fBSTDOUT\fP, standard output logging will still be performed (otherwise there would be no output other than to a file). This is recommended when starting any executable as a daemon. Default value: \fBSTDOUT\fP.
.TP
-\fB\-s\fR, \fB\-\-splay SECONDS\fR
-The splay time for running at intervals, in seconds
-.
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used. Default setting: \fB\-\-color\fP.
.TP
-\fB\-u\fR, \fB\-\-user USER\fR
-User to set privilege to
-.
+.B \fB\-N NODE_NAME\fP, \fB\-\-node\-name NODE_NAME\fP
+The name of the node.
.TP
-\fB\-P\fR, \fB\-\-pid PIDFILE\fR
-Set the PID file location, defaults to /tmp/chef\-client\.pid
-.
+.B \fB\-o RUN_LIST_ITEM\fP, \fB\-\-override\-runlist RUN_LIST_ITEM\fP
+Replace the current run list with the specified items.
.TP
-\fB\-\-once\fR
-Cancel any interval or splay options, run chef once and exit
-.
+.B \fB\-\-once\fP
+Indicates that the chef\-client is run once and that interval and splay options are cancelled.
.TP
-\fB\-v\fR, \fB\-\-version\fR
-Show chef version
-.
+.B \fB\-P PID_FILE\fP, \fB\-\-pid PID_FILE\fP
+The location in which a process identification number (pid) is saved. An executable, when started as a daemon, will write the pid to the specified file. Default value: \fB/tmp/name\-of\-executable.pid\fP.
.TP
-\fB\-h\fR, \fB\-\-help\fR
-Show this message
-.
-.SH "DESCRIPTION"
-The Chef Client is where almost all of the work in Chef is done\. It communicates with the Chef Server via REST, authenticates via Signed Header Authentication, and compiles and executes Cookbooks\.
-.
-.P
-A Chef Client does work on behalf of a Node\. A single Chef Client can run recipes for multiple Nodes\.
-.
-.P
-Clients are where all the action happens \- the Chef Server and Chef Expander are largely services that exist only to provide the Client with information\.
-.
-.SH "SEE ALSO"
-Full documentation for Chef and chef\-client is located on the Chef wiki, http://wiki\.opscode\.com/display/chef/Home\.
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@ospcode\.com\fR of Opscode (http://www\.opscode\.com), with contributions from the community\. This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR with help2man\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
+.B \fB\-R\fP, \fB\-\-enable\-reporting\fP
+Indicates that data collection reporting is enabled during a chef\-client run.
+.TP
+.B \fBRECIPE_FILE\fP
+The path to a recipe. For example, if a recipe file is in the current directory, use \fBrecipe_file.rb\fP. This is typically used with the \fB\-\-local\-mode\fP option.
+.TP
+.B \fB\-s SECONDS\fP, \fB\-\-splay SECONDS\fP
+A number (in seconds) to add to the \fBinterval\fP that is used to determine the frequency of chef\-client runs. This number can help prevent server load when there are many clients running at the same time.
+.TP
+.B \fB\-S CHEF_SERVER_URL\fP, \fB\-\-server CHEF_SERVER_URL\fP
+The URL for the server.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user that owns a process. This is required when starting any executable as a daemon.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-W\fP, \fB\-\-why\-run\fP
+Indicates that the executable will be run in why\-run mode, which is a type of chef\-client run that does everything except modify the system. Use why\-run mode to understand why the chef\-client makes the decisions that it makes and to learn more about the current and proposed state of the system.
+.TP
+.B \fB\-z\fP, \fB\-\-local\-mode\fP
+Indicates that the chef\-client will be run in local mode, which allows all commands that work against the server to also work against the local chef\-repo..
+.UNINDENT
+.SH RUN WITH ELEVATED PRIVILEGES
+.sp
+The chef\-client may need to be run with elevated privileges in order to get a recipe to converge correctly. On UNIX and UNIX\-like operating systems this can be done by running the command as root. On Microsoft Windows this can be done by running the command prompt as an administrator.
+.SS Linux
+.sp
+On Linux, the following error sometimes occurs when the permissions used to run the chef\-client are incorrect:
+.sp
+.nf
+.ft C
+$ chef\-client
+[Tue, 29 Nov 2011 19:46:17 \-0800] INFO: *** Chef 10.X.X ***
+[Tue, 29 Nov 2011 19:46:18 \-0800] WARN: Failed to read the private key /etc/chef/client.pem: #<Errno::EACCES: Permission denied \- /etc/chef/client.pem>
+.ft P
+.fi
+.sp
+This can be resolved by running the command as root. There are a few ways this can be done:
+.INDENT 0.0
+.IP \(bu 2
+Log in as root and then run the chef\-client
+.IP \(bu 2
+Use \fBsu\fP to become the root user, and then run the chef\-client. For example:
+.INDENT 2.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ su
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.sp
+and then:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ chef\-client
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.IP \(bu 2
+Use the sudo utility
+.INDENT 2.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ sudo chef\-client
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.IP \(bu 2
+Give a user access to read \fB/etc/chef\fP and also the files accessed by the chef\-client. This requires super user privileges and, as such, is not a recommended approach
+.UNINDENT
+.SS Windows
+.sp
+On Microsoft Windows, running without elevated privileges (when they are necessary) is an issue that fails silently. It will appear that the chef\-client completed its run successfully, but the changes will not have been made. When this occurs, do one of the following to run the chef\-client as the administrator:
+.INDENT 0.0
+.IP \(bu 2
+Log in to the administrator account. (This is not the same as an account in the administrator\(aqs security group.)
+.IP \(bu 2
+Run the chef\-client process from the administrator account while being logged into another account. Run the following command:
+.INDENT 2.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ runas /user:Administrator "cmd /C chef\-client"
+.ft P
+.fi
+.sp
+This will prompt for the administrator account password.
+.UNINDENT
+.UNINDENT
+.IP \(bu 2
+Open a command prompt by right\-clicking on the command prompt application, and then selecting \fBRun as administrator\fP. After the command window opens, the chef\-client can be run as the administrator
+.UNINDENT
+.SH EXAMPLES
+.sp
+\fBStart a Chef run when the chef\-client is running as a daemon\fP
+.sp
+A chef\-client that is running as a daemon can be woken up and started by sending the process a \fBSIGUSR1\fP. For example, to trigger a chef\-client run on a machine running Linux:
+.sp
+.nf
+.ft C
+$ sudo killall \-USR1 chef\-client
+.ft P
+.fi
+.sp
+\fBStart a Chef run manually\fP
+.sp
+.nf
+.ft C
+$ ps auxw|grep chef\-client
+.ft P
+.fi
+.sp
+to return something like:
+.sp
+.nf
+.ft C
+root 66066 0.9 0.0 2488880 264 s001 S+ 10:26AM 0:03.05
+/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby /usr/bin/chef\-client \-i 3600 \-s 20
+.ft P
+.fi
+.sp
+and then enter:
+.sp
+.nf
+.ft C
+$ sudo kill \-USR1 66066
+.ft P
+.fi
+.SH AUTHOR
+Chef
+.\" Generated by docutils manpage writer.
.
-.P
-On Debian systems, the complete text of the Apache 2\.0 License can be found in /usr/share/common\-licenses/Apache\-2\.0\.
diff --git a/distro/common/man/man8/chef-expander.8 b/distro/common/man/man8/chef-expander.8
deleted file mode 100644
index 6ab31d46c4..0000000000
--- a/distro/common/man/man8/chef-expander.8
+++ /dev/null
@@ -1,97 +0,0 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.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
-.
-.SH "SYNOPSIS"
-\fBchef\-expander\fR \fI(options)\fR
-.
-.TP
-\fB\-c\fR, \fB\-\-config CONFIG_FILE\fR
-a configuration file to use
-.
-.TP
-\fB\-i\fR, \fB\-\-index INDEX\fR
-the slot this node will occupy in the ring
-.
-.TP
-\fB\-n\fR, \fB\-\-node\-count NUMBER\fR
-the number of nodes in the ring
-.
-.TP
-\fB\-l\fR, \fB\-\-log\-level LOG_LEVEL\fR
-set the log level
-.
-.TP
-\fB\-L\fR, \fB\-\-logfile LOG_LOCATION\fR
-Logfile to use
-.
-.TP
-\fB\-d\fR, \fB\-\-daemonize\fR
-fork into the background
-.
-.TP
-\fB\-P\fR, \fB\-\-pid PIDFILE\fR
-PID file
-.
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show help message
-.
-.TP
-\fB\-v\fR, \fB\-\-version\fR
-show the version and exit
-.
-.SH "DESCRIPTION"
-Chef Expander fetches messages from RabbitMQ, processes them into the correct format to be loaded into Solr and loads them into Solr\.
-.
-.P
-\fBRunning Chef Expander\fR
-.
-.P
-Chef Expander is designed for clustered operation, though small installations will only need one worker process\. To run Chef Expander with one worker process, run chef\-expander \-n 1\. You will then have a master and worker process, which looks like this in ps:
-.
-.IP "" 4
-.
-.nf
-
-your\-shell> ps aux|grep expander
-you 52110 0\.1 0\.7 2515476 62748 s003 S+ 3:49PM 0:00\.80 chef\-expander worker #1 (vnodes 0\-1023)
-you 52108 0\.1 0\.5 2492880 41696 s003 S+ 3:49PM 0:00\.91 ruby bin/chef\-expander \-n 1
-.
-.fi
-.
-.IP "" 0
-.
-.P
-Workers are single threaded and therefore cannot use more than 100% of a single CPU\. If you find that your queues are getting backlogged, increase the number of workers
-.
-.P
-\fBDesign\fR
-.
-.P
-Chef Expander uses 1024 queues (called vnodes in some places) to allow you to scale the number of Chef Expander workers to meet the needs of your infrastructure\. When objects are saved in the API server, they are added to queues based on their database IDs\. These queues can be assigned to different Chef Expander workers to distribute the load of processing the index updates\.
-.
-.P
-\fBChef Expander Operation and Troubleshooting\fR
-.
-.P
-Chef Expander includes chef\-expanderctl, a management program that allows you to get status information or change the logging verbosity (without restarting)\.
-.
-.P
-See \fBchef\-expanderctl\fR(8) for details\.
-.
-.SH "SEE ALSO"
-\fBchef\-expanderctl\fR(8) \fBchef\-solr\fR(8)
-.
-.P
-Full documentation for Chef and chef\-server is located on the Chef wiki, http://wiki\.opscode\.com/display/chef/Home\.
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@ospcode\.com\fR of Opscode (http://www\.opscode\.com), with contributions from the community\. This manual page was created by Nuo Yan \fInuo@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.P
-On Debian systems, the complete text of the Apache 2\.0 License can be found in /usr/share/common\-licenses/Apache\-2\.0\.
diff --git a/distro/common/man/man8/chef-expanderctl.8 b/distro/common/man/man8/chef-expanderctl.8
deleted file mode 100644
index f2e88a426f..0000000000
--- a/distro/common/man/man8/chef-expanderctl.8
+++ /dev/null
@@ -1,62 +0,0 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.TH "CHEF\-EXPANDERCTL" "8" "July 2013" "Chef 11.8.0.alpha.0" "Chef Manual"
-.
-.SH "NAME"
-\fBchef\-expanderctl\fR \- management program for chef\-expander
-.
-.SH "SYNOPSIS"
-\fBchef\-expanderctl\fR \fICOMMAND\fR
-.
-.P
-\fBCommands:\fR
-.
-.TP
-\fBhelp\fR
-Show help message
-.
-.TP
-\fBqueue\-depth\fR
-display the aggregate queue backlog
-.
-.TP
-\fBqueue\-status\fR
-show the backlog and consumer count for each vnode queue
-.
-.TP
-\fBnode\-status\fR
-show the status of the nodes in the cluster
-.
-.TP
-\fBlog\-level\fR
-sets the log level of all nodes in the cluster
-.
-.SH "DESCRIPTION"
-Chef\-expanderctl is a management program that allows you to get status information or change the logging verbosity (without restarting)\. chef\-expanderctl has the following commands:
-.
-.IP "\(bu" 4
-\fBchef\-expanderctl help\fR prints usage\.
-.
-.IP "\(bu" 4
-\fBchef\-expanderctl queue\-depth\fR Shows the total number of messages in the queues\.
-.
-.IP "\(bu" 4
-\fBchef\-expanderctl queue\-status\fR Show the number of messages in each queue\. This is mainly of use when debugging a Chef Expander cluster\.
-.
-.IP "\(bu" 4
-\fBchef\-expanderctl log\-level LEVEL\fR Sets the log level on a running Chef Expander or cluster\. If you suspect that a worker process is stuck, as long as you are using clustered operation, you can simply kill the worker process and it will be restarted by the master process\.
-.
-.IP "" 0
-.
-.SH "SEE ALSO"
-\fBchef\-expander\-cluster\fR(8) \fBchef\-solr\fR(8)
-.
-.P
-Full documentation for Chef and chef\-server is located on the Chef wiki, http://wiki\.opscode\.com/display/chef/Home\.
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@ospcode\.com\fR of Opscode (http://www\.opscode\.com), with contributions from the community\. This manual page was created by Nuo Yan \fInuo@opscode\.com\fR\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.P
-On Debian systems, the complete text of the Apache 2\.0 License can be found in /usr/share/common\-licenses/Apache\-2\.0\.
diff --git a/distro/common/man/man8/chef-server-webui.8 b/distro/common/man/man8/chef-server-webui.8
deleted file mode 100644
index 3f2157216c..0000000000
--- a/distro/common/man/man8/chef-server-webui.8
+++ /dev/null
@@ -1,155 +0,0 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.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)\.
-.
-.SH "SYNOPSIS"
-\fBchef\-server\-webui\fR \fI(options)\fR
-.
-.TP
-\fB\-u\fR, \fB\-\-user USER\fR
-This flag is for having chef\-server\-webui run as a user other than the one currently logged in\. Note: if you set this you must also provide a \-\-group option for it to take effect\.
-.
-.TP
-\fB\-G\fR, \fB\-\-group GROUP\fR
-This flag is for having chef\-server\-webui run as a group other than the one currently logged in\. Note: if you set this you must also provide a \-\-user option for it to take effect\.
-.
-.TP
-\fB\-d\fR, \fB\-\-daemonize\fR
-This will run a single chef\-server\-webui in the background\.
-.
-.TP
-\fB\-N\fR, \fB\-\-no\-daemonize\fR
-This will allow you to run a cluster in console mode\.
-.
-.TP
-\fB\-c\fR, \fB\-\-cluster\-nodes NUM_MERBS\fR
-Number of merb daemons to run for chef\-server\-webui\.
-.
-.TP
-\fB\-I\fR, \fB\-\-init\-file FILE\fR
-File to use for initialization on load, defaults to config/init\.rb\.
-.
-.TP
-\fB\-p\fR, \fB\-\-port PORTNUM\fR
-Port to run chef\-server\-webui on, defaults to 4040\. Additional nodes (\-c) listen on incrementing port numbers\.
-.
-.TP
-\fB\-o\fR, \fB\-\-socket\-file FILE\fR
-Socket file to run chef\-server\-webui on, defaults to [Merb\.root]/log/merb\.sock\. This is for web servers, like thin, that use sockets\. Specify this \fIonly\fR if you \fImust\fR\.
-.
-.TP
-\fB\-s\fR, \fB\-\-socket SOCKNUM\fR
-Socket number to run chef\-server\-webui on, defaults to 0\.
-.
-.TP
-\fB\-n\fR, \fB\-\-name NAME\fR
-Set the name of the application\. This is used in the process title and log file names\.
-.
-.TP
-\fB\-P\fR, \fB\-\-pid PIDFILE\fR
-PID file, defaults to [Merb\.root]/log/merb\.main\.pid for the master process and[Merb\.root]/log/merb\.[port number]\.pid for worker processes\. For clusters, use %s to specify where in the file chef\-server\-webui should place the port number\. For instance: \-P myapp\.%s\.pid\.
-.
-.TP
-\fB\-h\fR, \fB\-\-host HOSTNAME\fR
-Host to bind to (default is 0\.0\.0\.0)\.
-.
-.TP
-\fB\-m\fR, \fB\-\-merb\-root PATH_TO_APP_ROOT\fR
-The path to the Merb\.root for the app you want to run (default is current working directory)\.
-.
-.TP
-\fB\-a\fR, \fB\-\-adapter ADAPTER\fR
-The rack adapter to use to run chef\-server\-webui (default is mongrel) [mongrel, emongrel, thin, ebb, fastcgi, webrick]\.
-.
-.TP
-\fB\-R\fR, \fB\-\-rackup FILE\fR
-Load an alternate Rack config file (default is config/rack\.rb)\.
-.
-.TP
-\fB\-i\fR, \fB\-\-irb\-console\fR
-This flag will start chef\-server\-webui in irb console mode\. All your models and other classes will be available for you in an irb session\.
-.
-.TP
-\fB\-S\fR, \fB\-\-sandbox\fR
-This flag will enable a sandboxed irb console\. If your ORM supports transactions, all edits will be rolled back on exit\.
-.
-.TP
-\fB\-l\fR, \fB\-\-log\-level LEVEL\fR
-Log levels can be set to any of these options: debug < info < warn < error < fatal (default is info)\.
-.
-.TP
-\fB\-L\fR, \fB\-\-log LOGFILE\fR
-A string representing the logfile to use\. Defaults to [Merb\.root]/log/merb\.[main]\.log for the master process and [Merb\.root]/log/merb[port number]\.logfor worker processes\.
-.
-.TP
-\fB\-e\fR, \fB\-\-environment STRING\fR
-Environment to run Merb under [development, production, testing] (default is development)\.
-.
-.TP
-\fB\-r\fR, \fB\-\-script\-runner [\'RUBY CODE\'| FULL_SCRIPT_PATH]\fR
-Command\-line option to run scripts and/or code in the chef\-server\-webui app\.
-.
-.TP
-\fB\-K\fR, \fB\-graceful PORT or all\fR
-Gracefully kill chef\-server\-webui proceses by port number\. Use chef\-server \-K all to gracefully kill all merbs\.
-.
-.TP
-\fB\-k\fR, \fB\-\-kill PORT\fR
-Force kill one merb worker by port number\. This will cause the worker to be respawned\.
-.
-.TP
-\fB\-\-fast\-deploy\fR
-Reload the code, but not yourinit\.rb or gems\.
-.
-.TP
-\fB\-X\fR, \fB\-\-mutex on/off\fR
-This flag is for turning the mutex lock on and off\.
-.
-.TP
-\fB\-D\fR, \fB\-\-debugger\fR
-Run chef\-server\-webui using rDebug\.
-.
-.TP
-\fB\-V\fR, \fB\-\-verbose\fR
-Print extra information\.
-.
-.TP
-\fB\-C\fR, \fB\-\-console\-trap\fR
-Enter an irb console on ^C\.
-.
-.TP
-\fB\-?\fR, \fB\-H\fR, \fB\-\-help\fR
-Show this help message\.
-.
-.SH "DESCRIPTION"
-The Chef Server WebUI (Management Console) is a Merb application slice\. The default listen port is 4040\.
-.
-.P
-The Management Console is Chef Server\'s web interface\. Nodes, roles, cookbooks, data bags, and API clients can be managed through the Management Console\. Search can also be done on the console\.
-.
-.P
-In order to start using the Management Console, you need to first create a user or change the default password on the "admin" user\.
-.
-.P
-The default credentials are:
-.
-.IP "\(bu" 4
-\fBUsername\fR: admin
-.
-.IP "\(bu" 4
-\fBPassword\fR: p@ssw0rd1
-.
-.IP "" 0
-.
-.SH "SEE ALSO"
-Full documentation for Chef and chef\-server\-webui (Management Console) is located on the Chef wiki, http://wiki\.opscode\.com/display/chef/Home\.
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@ospcode\.com\fR of Opscode (http://www\.opscode\.com), with contributions from the community\. This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR 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
-On Debian systems, the complete text of the Apache 2\.0 License can be found in /usr/share/common\-licenses/Apache\-2\.0\.
diff --git a/distro/common/man/man8/chef-server.8 b/distro/common/man/man8/chef-server.8
deleted file mode 100644
index ce928d6f63..0000000000
--- a/distro/common/man/man8/chef-server.8
+++ /dev/null
@@ -1,147 +0,0 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.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\.
-.
-.SH "SYNOPSIS"
-\fBchef\-server\fR \fI(options)\fR
-.
-.TP
-\fB\-u\fR, \fB\-\-user USER\fR
-This flag is for having chef\-server\-webui run as a user other than the one currently logged in\. Note: if you set this you must also provide a \-\-group option for it to take effect\.
-.
-.TP
-\fB\-G\fR, \fB\-\-group GROUP\fR
-This flag is for having chef\-server\-webui run as a group other than the one currently logged in\. Note: if you set this you must also provide a \-\-user option for it to take effect\.
-.
-.TP
-\fB\-d\fR, \fB\-\-daemonize\fR
-This will run a single chef\-server\-webui in the background\.
-.
-.TP
-\fB\-N\fR, \fB\-\-no\-daemonize\fR
-This will allow you to run a cluster in console mode\.
-.
-.TP
-\fB\-c\fR, \fB\-\-cluster\-nodes NUM_MERBS\fR
-Number of merb daemons to run for chef\-server\-webui\.
-.
-.TP
-\fB\-I\fR, \fB\-\-init\-file FILE\fR
-File to use for initialization on load, defaults to config/init\.rb\.
-.
-.TP
-\fB\-p\fR, \fB\-\-port PORTNUM\fR
-Port to run chef\-server\-webui on, defaults to 4040\. Additional nodes (\-c) listen on incrementing port numbers\.
-.
-.TP
-\fB\-o\fR, \fB\-\-socket\-file FILE\fR
-Socket file to run chef\-server\-webui on, defaults to [Merb\.root]/log/merb\.sock\. This is for web servers, like thin, that use sockets\. Specify this \fIonly\fR if you \fImust\fR\.
-.
-.TP
-\fB\-s\fR, \fB\-\-socket SOCKNUM\fR
-Socket number to run chef\-server\-webui on, defaults to 0\.
-.
-.TP
-\fB\-n\fR, \fB\-\-name NAME\fR
-Set the name of the application\. This is used in the process title and log file names\.
-.
-.TP
-\fB\-P\fR, \fB\-\-pid PIDFILE\fR
-PID file, defaults to [Merb\.root]/log/merb\.main\.pid for the master process and[Merb\.root]/log/merb\.[port number]\.pid for worker processes\. For clusters, use %s to specify where in the file chef\-server\-webui should place the port number\. For instance: \-P myapp\.%s\.pid\.
-.
-.TP
-\fB\-h\fR, \fB\-\-host HOSTNAME\fR
-Host to bind to (default is 0\.0\.0\.0)\.
-.
-.TP
-\fB\-m\fR, \fB\-\-merb\-root PATH_TO_APP_ROOT\fR
-The path to the Merb\.root for the app you want to run (default is current working directory)\.
-.
-.TP
-\fB\-a\fR, \fB\-\-adapter ADAPTER\fR
-The rack adapter to use to run chef\-server\-webui (default is mongrel) [mongrel, emongrel, thin, ebb, fastcgi, webrick]\.
-.
-.TP
-\fB\-R\fR, \fB\-\-rackup FILE\fR
-Load an alternate Rack config file (default is config/rack\.rb)\.
-.
-.TP
-\fB\-i\fR, \fB\-\-irb\-console\fR
-This flag will start chef\-server\-webui in irb console mode\. All your models and other classes will be available for you in an irb session\.
-.
-.TP
-\fB\-S\fR, \fB\-\-sandbox\fR
-This flag will enable a sandboxed irb console\. If your ORM supports transactions, all edits will be rolled back on exit\.
-.
-.TP
-\fB\-l\fR, \fB\-\-log\-level LEVEL\fR
-Log levels can be set to any of these options: debug < info < warn < error < fatal (default is info)\.
-.
-.TP
-\fB\-L\fR, \fB\-\-log LOGFILE\fR
-A string representing the logfile to use\. Defaults to [Merb\.root]/log/merb\.[main]\.log for the master process and [Merb\.root]/log/merb[port number]\.logfor worker processes\.
-.
-.TP
-\fB\-e\fR, \fB\-\-environment STRING\fR
-Environment to run Merb under [development, production, testing] (default is development)\.
-.
-.TP
-\fB\-r\fR, \fB\-\-script\-runner [\'RUBY CODE\'| FULL_SCRIPT_PATH]\fR
-Command\-line option to run scripts and/or code in the chef\-server\-webui app\.
-.
-.TP
-\fB\-K\fR, \fB\-graceful PORT or all\fR
-Gracefully kill chef\-server\-webui proceses by port number\. Use chef\-server \-K all to gracefully kill all merbs\.
-.
-.TP
-\fB\-k\fR, \fB\-\-kill PORT\fR
-Force kill one merb worker by port number\. This will cause the worker to be respawned\.
-.
-.TP
-\fB\-\-fast\-deploy\fR
-Reload the code, but not yourinit\.rb or gems\.
-.
-.TP
-\fB\-X\fR, \fB\-\-mutex on/off\fR
-This flag is for turning the mutex lock on and off\.
-.
-.TP
-\fB\-D\fR, \fB\-\-debugger\fR
-Run chef\-server\-webui using rDebug\.
-.
-.TP
-\fB\-V\fR, \fB\-\-verbose\fR
-Print extra information\.
-.
-.TP
-\fB\-C\fR, \fB\-\-console\-trap\fR
-Enter an irb console on ^C\.
-.
-.TP
-\fB\-?\fR, \fB\-H\fR, \fB\-\-help\fR
-Show this help message\.
-.
-.SH "DESCRIPTION"
-The Chef Server provides a central point for the distribution of Cookbooks, management and authentication of Nodes, and the use of Search\. It provides a REST API\.
-.
-.P
-The API service is what clients use to interact with the server to manage node configuration in Chef\. By default, the service is started on port 4000 as a Merb application slice running with the thin server adapter\.
-.
-.P
-The two methods of interaction with the API for humans are the command\-line tool Knife and the Management Console\. The Chef Client library is used for interacting with the API for client nodes\.
-.
-.SH "SEE ALSO"
-\fBchef\-client\fR(8) \fBchef\-server\-webui\fR(8) \fBknife\fR(1)
-.
-.P
-Full documentation for Chef and chef\-server is located on the Chef wiki, http://wiki\.opscode\.com/display/chef/Home\.
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@ospcode\.com\fR of Opscode (http://www\.opscode\.com), with contributions from the community\. This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR with help2man\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.P
-On Debian systems, the complete text of the Apache 2\.0 License can be found in /usr/share/common\-licenses/Apache\-2\.0\.
diff --git a/distro/common/man/man8/chef-solo.8 b/distro/common/man/man8/chef-solo.8
index 30c5956825..5c56608fba 100644
--- a/distro/common/man/man8/chef-solo.8
+++ b/distro/common/man/man8/chef-solo.8
@@ -1,126 +1,167 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.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\.
-.
-.SH "SYNOPSIS"
-\fBchef\-solo\fR \fI(options)\fR
-.
+.TH "CHEF-SOLO" "8" "Chef 11.10.0" "" "chef-solo"
+.SH NAME
+chef-solo \- The man page for the chef-solo command line tool.
+.
+.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
+chef\-solo is an open source version of the chef\-client that allows using cookbooks with nodes without requiring access to a server. chef\-solo runs locally and requires that a cookbook (and any of its dependencies) be on the same physical disk as the node. chef\-solo is a limited\-functionality version of the chef\-client and \fBdoes not support\fP the following:
+.INDENT 0.0
+.IP \(bu 2
+Node data storage
+.IP \(bu 2
+Search indexes
+.IP \(bu 2
+Centralized distribution of cookbooks
+.IP \(bu 2
+A centralized API that interacts with and integrates infrastructure components
+.IP \(bu 2
+Authentication or authorization
+.IP \(bu 2
+Persistent attributes
+.UNINDENT
+.sp
+The chef\-solo executable can be run as a command\-line tool.
+.SH OPTIONS
+.sp
+This command has the following syntax:
+.sp
+.nf
+.ft C
+chef\-solo OPTION VALUE OPTION VALUE ...
+.ft P
+.fi
+.sp
+This command has the following options:
+.INDENT 0.0
.TP
-\fB\-c\fR, \fB\-\-config CONFIG\fR
-The configuration file to use
-.
+.B \fB\-c CONFIG\fP, \fB\-\-config CONFIG\fP
+The configuration file to use.
.TP
-\fB\-d\fR, \fB\-\-daemonize\fR
-Daemonize the process
-.
+.B \fB\-d\fP, \fB\-\-daemonize\fP
+Indicates that the executable will be run as a daemon. This option is only available on machines that run in UNIX or Linux environments. For machines that are running Microsoft Windows that require similar functionality, use the \fBchef\-client::service\fP recipe in the \fBchef\-client\fP cookbook: \fI\%http://community.opscode.com/cookbooks/chef-client\fP. This will install a chef\-client service under Microsoft Windows using the Windows Service Wrapper.
.TP
-\fB\-g\fR, \fB\-\-group GROUP\fR
-Group to set privilege to
-.
+.B \fB\-E ENVIRONMENT_NAME\fP, \fB\-\-environment ENVIRONMENT_NAME\fP
+The name of the environment.
.TP
-\fB\-i\fR, \fB\-\-interval SECONDS\fR
-Run chef\-client periodically, in seconds
-.
+.B \fB\-f\fP, \fB\-\-[no\-]fork\fP
+Indicates that a chef\-client run will be contained in a secondary process with dedicated RAM. When the chef\-client run is complete the RAM will be returned to the master process. This option helps ensure that a chef\-client will use a steady amount of RAM over time because the master process will not run recipes. This option will also help prevent memory leaks (such as those that can be introduced by the code contained within a poorly designed cookbook). Use \fB\-\-no\-fork\fP to disable running the chef\-client in fork node. Default value: \fB\-\-fork\fP.
.TP
-\fB\-j\fR, \fB\-\-json\-attributes JSON_ATTRIBS\fR
-Load attributes from a JSON file or URL
-.
+.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
+The output format: \fBdoc\fP (default) or \fBmin\fP.
+.sp
+Use \fBdoc\fP to print the progress of the chef\-client run using full strings that display a summary of updates as they occur.
+.sp
+Use \fBmin\fP to print the progress of the chef\-client run using single characters. A summary of updates is printed at the end of the chef\-client run. A dot (\fB.\fP) is printed for events that do not have meaningful status information, such as loading a file or synchronizing a cookbook. For resources, a dot (\fB.\fP) is printed when the resource is up to date, an \fBS\fP is printed when the resource is skipped by \fBnot_if\fP or \fBonly_if\fP, and a \fBU\fP is printed when the resource is updated.
+.sp
+Other formatting options are available when those formatters are configured in the client.rb file using the \fBadd_formatter\fP option.
.TP
-\fB\-l\fR, \fB\-\-log_level LEVEL\fR
-Set the log level (debug, info, warn, error, fatal)
-.
+.B \fB\-\-force\-formatter\fP
+Indicates that formatter output will be used instead of logger output.
.TP
-\fB\-L\fR, \fB\-\-logfile LOGLOCATION\fR
-Set the log file location, defaults to STDOUT \- recommended for daemonizing
-.
+.B \fB\-\-force\-logger\fP
+Indicates that logger output will be used instead of formatter output.
.TP
-\fB\-N\fR, \fB\-\-node\-name NODE_NAME\fR
-The node name for this client
-.
+.B \fB\-g GROUP\fP, \fB\-\-group GROUP\fP
+The name of the group that owns a process. This is required when starting any executable as a daemon.
.TP
-\fB\-r\fR, \fB\-\-recipe\-url RECIPE_URL\fR
-Pull down a remote gzipped tarball of recipes and untar it to the cookbook cache\.
-.
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
.TP
-\fB\-s\fR, \fB\-\-splay SECONDS\fR
-The splay time for running at intervals, in seconds
-.
+.B \fB\-i SECONDS\fP, \fB\-\-interval SECONDS\fP
+The frequency (in seconds) at which the chef\-client runs.
.TP
-\fB\-u\fR, \fB\-\-user USER\fR
-User to set privilege to
-.
+.B \fB\-j PATH\fP, \fB\-\-json\-attributes PATH\fP
+The path to a file that contains JSON data. Use this option to override \fBnormal\fP attributes set elsewhere.
.TP
-\fB\-v\fR, \fB\-\-version\fR
-Show chef version
-.
+.B \fB\-l LEVEL\fP, \fB\-\-log_level LEVEL\fP
+The level of logging that will be stored in a log file.
.TP
-\fB\-h\fR, \fB\-\-help\fR
-Show this message
-.
-.SH "DESCRIPTION"
-Chef Solo allows you to run Chef Cookbooks in the absence of a Chef Server\. To do this, the complete cookbook needs to be present on disk\.
-.
-.P
-By default Chef Solo will look in /etc/chef/solo\.rb for its configuration\. This configuration file has two required variables: file_cache_path and cookbook_path\.
-.
-.P
-For example: file_cache_path "/var/chef\-solo" cookbook_path "/var/chef\-solo/cookbooks"
-.
-.P
-For your own systems, you can change this to reflect any directory you like, but you\'ll need to specify absolute paths and the cookbook_path directory should be a subdirectory of the file_cache_path\.
-.
-.P
-You can also specify cookbook_path as an array, passing multiple locations to search for cookbooks\.
-.
-.P
-For example: file_cache_path "/var/chef\-solo" cookbook_path ["/var/chef\-solo/cookbooks", "/var/chef\-solo/site\-cookbooks"]
-.
-.P
-Note that earlier entries are now overridden by later ones\.
-.
-.P
-Since chef\-solo doesn\'t have any interaction with a Chef Server, you\'ll need to specify node\-specifc attributes in a JSON file\. This can be located on the target system itself, or it can be stored on a remote server such as S3, or a web server on your network\.
-.
-.P
-Within the JSON file, you\'ll also specify the recipes that Chef should run in the "run_list"\. An example JSON file, which sets a resolv\.conf:
-.
-.IP "" 4
-.
+.B \fB\-L LOGLOCATION\fP, \fB\-\-logfile c\fP
+The location in which log file output files will be saved. If this location is set to something other than \fBSTDOUT\fP, standard output logging will still be performed (otherwise there would be no output other than to a file). This is recommended when starting any executable as a daemon.
+.TP
+.B \fB\-\-[no\-]color\fP
+Indicates whether colored output will be used. Default setting: \fB\-\-color\fP.
+.TP
+.B \fB\-N NODE_NAME\fP, \fB\-\-node\-name NODE_NAME\fP
+The name of the node.
+.TP
+.B \fB\-o RUN_LIST_ITEM\fP, \fB\-\-override\-runlist RUN_LIST_ITEM\fP
+Replace the current run list with the specified items.
+.TP
+.B \fB\-r RECIPE_URL\fP, \fB\-\-recipe\-url RECIPE_URL\fP
+The URL location from which a remote cookbook tar.gz will be downloaded.
+.TP
+.B \fB\-s SECONDS\fP, \fB\-\-splay SECONDS\fP
+A number (in seconds) to add to the \fBinterval\fP that is used to determine the frequency of chef\-client runs. This number can help prevent server load when there are many clients running at the same time.
+.TP
+.B \fB\-u USER\fP, \fB\-\-user USER\fP
+The user that owns a process. This is required when starting any executable as a daemon.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client.
+.TP
+.B \fB\-W\fP, \fB\-\-why\-run\fP
+Indicates that the executable will be run in why\-run mode, which is a type of chef\-client run that does everything except modify the system. Use why\-run mode to understand why the chef\-client makes the decisions that it makes and to learn more about the current and proposed state of the system.
+.UNINDENT
+.SH EXAMPLES
+.sp
+\fBUse a URL\fP
+.sp
.nf
-
-{
- "resolver": {
- "nameservers": [ "10\.0\.0\.1" ],
- "search":"int\.example\.com"
- },
- "run_list": [ "recipe[resolver]" ]
-}
-.
+.ft C
+$ chef\-solo \-c ~/solo.rb \-j ~/node.json \-r http://www.example.com/chef\-solo.tar.gz
+.ft P
.fi
+.sp
+where \fB\-r\fP uses the \fBremote_file\fP resource to retrieve the tar.gz archive into the \fBfile_cache_path\fP, and then extract it to \fBcookbooks_path\fP.
+.sp
+\fBUse a directory\fP
+.sp
+.nf
+.ft C
+$ chef\-solo \-c ~/solo.rb \-j ~/node.json
+.ft P
+.fi
+.sp
+where the \fB\-r URL\fP option is not used. chef\-solo will look in the solo.rb file to determine the directory in which cookbooks are located.
+.sp
+\fBUse a URL for cookbook and JSON data\fP
+.sp
+.nf
+.ft C
+$ chef\-solo \-c ~/solo.rb \-j http://www.example.com/node.json \-r http://www.example.com/chef\-solo.tar.gz
+.ft P
+.fi
+.sp
+where \fB\-r\fP corresponds to \fBrecipe_url\fP and \fB\-j\fP corresponds to \fBjson_attribs\fP, both of which are configuration options in solo.rb.
+.SH AUTHOR
+Chef
+.\" Generated by docutils manpage writer.
.
-.IP "" 0
-.
-.P
-Then you can run chef\-solo with \-j to specify the JSON file\. It will look for cookbooks in the cookbook_path configured in the configuration file, and apply attributes and use the run_list from the JSON file specified\.
-.
-.P
-You can use \-c to specify the path to the configuration file (if you don\'t want chef\-solo to use the default)\. You can also specify \-r for a cookbook tarball\.
-.
-.P
-For example: chef\-solo \-c ~/solo\.rb \-j ~/node\.json \-r http://www\.example\.com/chef\-solo\.tar\.gz
-.
-.P
-In the above case, chef\-solo would extract the tarball to your specified cookbook_path, use ~/solo\.rb as the configuration file, and apply attributes and use the run_list from ~/node\.json\.
-.
-.SH "SEE ALSO"
-Full documentation for Chef and chef\-solo is located on the Chef wiki, http://wiki\.opscode\.com/display/chef/Home\.
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@ospcode\.com\fR of Opscode (http://www\.opscode\.com), with contributions from the community\. This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR with help2man\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.P
-On Debian systems, the complete text of the Apache 2\.0 License can be found in /usr/share/common\-licenses/Apache\-2\.0\.
diff --git a/distro/common/man/man8/chef-solr.8 b/distro/common/man/man8/chef-solr.8
deleted file mode 100644
index 28c8e92cf3..0000000000
--- a/distro/common/man/man8/chef-solr.8
+++ /dev/null
@@ -1,122 +0,0 @@
-.\" generated with Ronn/v0.7.3
-.\" http://github.com/rtomayko/ronn/tree/0.7.3
-.
-.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
-.
-.SH "SYNOPSIS"
-\fBchef\-solr\fR \fI(options)\fR
-.
-.TP
-\fB\-c\fR, \fB\-\-config CONFIG\fR
-The configuration file to use
-.
-.TP
-\fB\-d\fR, \fB\-\-daemonize\fR
-Daemonize the process
-.
-.TP
-\fB\-g\fR, \fB\-\-group GROUP\fR
-Group to set privilege to
-.
-.TP
-\fB\-l\fR, \fB\-\-log_level LEVEL\fR
-Set the log level (debug, info, warn, error, fatal)
-.
-.TP
-\fB\-L\fR, \fB\-\-logfile LOGLOCATION\fR
-Set the log file location, defaults to STDOUT \- recommended for daemonizing
-.
-.TP
-\fB\-P\fR, \fB\-\-pid PIDFILE\fR
-Set the PID file location, defaults to /tmp/chef\-solr\.pid
-.
-.TP
-\fB\-D\fR, \fB\-\-solr\-data\-dir PATH\fR
-Where the Solr data lives
-.
-.TP
-\fB\-x\fR, \fB\-\-solor\-heap\-size SIZE\fR
-Set the size of the Java Heap
-.
-.TP
-\fB\-H\fR, \fB\-\-solr\-home\-dir PATH\fR
-Solr home directory
-.
-.TP
-\fB\-j\fR, \fB\-\-java\-opts OPTS\fR
-Raw options passed to Java
-.
-.TP
-\fB\-x\fR, \fB\-\-solor\-heap\-size\fR
-Set the size of the Java Heap
-.
-.TP
-\fB\-W\fR, \fB\-\-solr\-jetty\-dir PATH\fR
-Where to place the Solr Jetty instance
-.
-.TP
-\fB\-u\fR, \fB\-\-user USER\fR
-User to set privilege to
-.
-.TP
-\fB\-v\fR, \fB\-\-version\fR
-Show chef\-solr version
-.
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-Show this message
-.
-.SH "DESCRIPTION"
-Chef\-solr provides search service for Chef\. You need to have both chef\-solr and chef\-expander\-cluster running in order for search to work\.
-.
-.P
-\fBInstallation\fR
-.
-.P
-Make sure you backed up your data if you are upgrading from a previous version\. Run chef\-solr\-installer to upgrade your Chef Solr installation\. Answer "yes" when prompted for confirmation\. The process should look like this:
-.
-.IP "" 4
-.
-.nf
-
-yourshell> chef\-solr\-installer
-Configuration setting solr_heap_size is unknown and will be ignored
-
-Chef Solr is already installed in /var/chef/solr
-Do you want to overwrite the current install? All existing Solr data will be lost\. [y/n] y
-Removing the existing Chef Solr installation
- rm \-rf /var/chef/solr
- rm \-rf /var/chef/solr\-jetty
- rm \-rf /var/chef/solr/data
-Creating Solr Home Directory
- mkdir \-p /var/chef/solr
- entering /var/chef/solr
- tar zxvf /Users/ddeleo/opscode/chef/chef\-solr/solr/solr\-home\.tar\.gz
-Creating Solr Data Directory
- mkdir \-p /var/chef/solr/data
-Unpacking Solr Jetty
- mkdir \-p /var/chef/solr\-jetty
- entering /var/chef/solr\-jetty
- tar zxvf /Users/ddeleo/opscode/chef/chef\-solr/solr/solr\-jetty\.tar\.gz
-
-Successfully installed Chef Solr\.
-You can restore your search index using `knife index rebuild`
-.
-.fi
-.
-.IP "" 0
-.
-.SH "SEE ALSO"
-\fBchef\-expander\-cluster\fR(8)
-.
-.P
-Full documentation for Chef and chef\-server is located on the Chef wiki, http://wiki\.opscode\.com/display/chef/Home\.
-.
-.SH "AUTHOR"
-Chef was written by Adam Jacob \fIadam@ospcode\.com\fR of Opscode (http://www\.opscode\.com), with contributions from the community\. This manual page was written by Joshua Timberman \fIjoshua@opscode\.com\fR with help2man\. Permission is granted to copy, distribute and / or modify this document under the terms of the Apache 2\.0 License\.
-.
-.P
-On Debian systems, the complete text of the Apache 2\.0 License can be found in /usr/share/common\-licenses/Apache\-2\.0\.
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.rb b/lib/chef.rb
index 3e5394b141..0d5fb3de2c 100644
--- a/lib/chef.rb
+++ b/lib/chef.rb
@@ -37,3 +37,5 @@ require 'chef/monkey_patches/string'
require 'chef/monkey_patches/numeric'
require 'chef/monkey_patches/object'
require 'chef/monkey_patches/file'
+require 'chef/monkey_patches/uri'
+
diff --git a/lib/chef/api_client.rb b/lib/chef/api_client.rb
index 32e1eee017..7b7fd99ff7 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
@@ -146,9 +162,7 @@ class Chef
if response.kind_of?(Chef::ApiClient)
response
else
- client = Chef::ApiClient.new
- client.name(response['clientname'])
- client
+ json_create(response)
end
end
@@ -160,11 +174,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 +186,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 +206,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 +216,3 @@ class Chef
end
end
-
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index 6522ba6e64..601bbd91f1 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.
@@ -123,11 +118,13 @@ class Chef::Application
configure_stdout_logger
end
Chef::Log.level = resolve_log_level
+ rescue StandardError => error
+ Chef::Log.fatal("Failed to open or create log file at #{Chef::Config[:log_location]}: #{error.class} (#{error.message})")
+ Chef::Application.fatal!("Aborting due to invalid 'log_location' configuration", 2)
end
def configure_stdout_logger
stdout_logger = MonoLogger.new(STDOUT)
- STDOUT.sync = true
stdout_logger.formatter = Chef::Log.logger.formatter
Chef::Log.loggers << stdout_logger
end
@@ -172,23 +169,65 @@ 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
+ def run_chef_client(specific_recipes = [])
+ Chef::Application.setup_server_connectivity
+
+ override_runlist = config[:override_runlist]
+ if specific_recipes.size > 0
+ override_runlist ||= []
+ end
@chef_client = Chef::Client.new(
- @chef_client_json,
- :override_runlist => config[:override_runlist]
+ @chef_client_json,
+ :override_runlist => config[:override_runlist],
+ :specific_recipes => specific_recipes,
+ :runlist => config[: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/apply.rb b/lib/chef/application/apply.rb
index 9bffa4824e..dfec31c51e 100644
--- a/lib/chef/application/apply.rb
+++ b/lib/chef/application/apply.rb
@@ -74,6 +74,12 @@ class Chef::Application::Apply < Chef::Application
:description => 'Enable whyrun mode',
:boolean => true
+ option :color,
+ :long => '--[no-]color',
+ :boolean => true,
+ :default => !Chef::Platform.windows?,
+ :description => "Use colored output, defaults to enabled"
+
def initialize
super
end
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index b08a795697..e14266d82a 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,
@@ -171,7 +170,7 @@ class Chef::Application::Client < Chef::Application
option :override_runlist,
:short => "-o RunlistItem,RunlistItem...",
:long => "--override-runlist RunlistItem,RunlistItem...",
- :description => "Replace current run list with specified items",
+ :description => "Replace current run list with specified items for a single run",
:proc => lambda{|items|
items = items.split(',')
items.compact.map{|item|
@@ -179,6 +178,16 @@ class Chef::Application::Client < Chef::Application
}
}
+ option :runlist,
+ :short => "-r RunlistItem,RunlistItem...",
+ :long => "--runlist RunlistItem,RunlistItem...",
+ :description => "Permanently replace current run list with specified items",
+ :proc => lambda{|items|
+ items = items.split(',')
+ items.compact.map{|item|
+ Chef::RunList::RunListItem.new(item)
+ }
+ }
option :why_run,
:short => '-W',
:long => '--why-run',
@@ -197,6 +206,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",
@@ -217,8 +240,16 @@ class Chef::Application::Client < Chef::Application
def reconfigure
super
+ Chef::Config[:specific_recipes] = cli_arguments.map { |file| File.expand_path(file) }
+
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 +260,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
@@ -299,7 +321,7 @@ class Chef::Application::Client < Chef::Application
Chef::Log.debug("Splay sleep #{splay} seconds")
sleep splay
end
- run_chef_client
+ run_chef_client(Chef::Config[:specific_recipes])
if Chef::Config[:interval]
Chef::Log.debug("Sleeping for #{Chef::Config[:interval]} seconds")
unless SELF_PIPE.empty?
diff --git a/lib/chef/application/knife.rb b/lib/chef/application/knife.rb
index 13612a4bf3..5f2456311c 100644
--- a/lib/chef/application/knife.rb
+++ b/lib/chef/application/knife.rb
@@ -19,6 +19,8 @@ require 'chef/knife'
require 'chef/application'
require 'mixlib/log'
require 'ohai/config'
+require 'chef/monkey_patches/net_http.rb'
+require 'chef/monkey_patches/uri.rb'
class Chef::Application::Knife < Chef::Application
@@ -106,6 +108,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 ada8cb0ae7..dc8a3588ad 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,
@@ -55,7 +55,7 @@ class Chef::Application::Solo < Chef::Application
option :color,
:long => '--[no-]color',
:boolean => true,
- :default => true,
+ :default => !Chef::Platform.windows?,
:description => "Use colored output, defaults to enabled"
option :log_level,
@@ -165,7 +165,7 @@ class Chef::Application::Solo < Chef::Application
:long => '--environment ENVIRONMENT',
:description => 'Set the Chef Environment on the node'
- attr_reader :chef_solo_json
+ attr_reader :chef_client_json
def initialize
super
@@ -181,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_client_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 e8e2760c1c..bea5e9fcdc 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",
@@ -103,6 +105,10 @@ class Chef
end
end
+ # Daemon class needs to have all the signal callbacks return
+ # before service_main returns.
+ Chef::Log.debug("Giving signal callbacks some time to exit...")
+ sleep 1
Chef::Log.debug("Exiting service...")
end
@@ -111,15 +117,27 @@ class Chef
################################################################################
def service_stop
+ run_warning_displayed = false
Chef::Log.info("STOP request from operating system.")
- if @service_action_mutex.try_lock
- @service_signal.signal
- @service_action_mutex.unlock
- Chef::Log.info("Service is stopping....")
- else
- Chef::Log.info("Currently a chef-client run is happening.")
- Chef::Log.info("Service will stop once it's completed.")
+ loop do
+ # See if a run is in flight
+ if @service_action_mutex.try_lock
+ # Run is not in flight. Wake up service_main to exit.
+ @service_signal.signal
+ @service_action_mutex.unlock
+ break
+ else
+ unless run_warning_displayed
+ Chef::Log.info("Currently a chef run is happening on this system.")
+ Chef::Log.info("Service will stop when run is completed.")
+ run_warning_displayed = true
+ end
+
+ Chef::Log.debug("Waiting for chef-client run...")
+ sleep 1
+ end
end
+ Chef::Log.info("Service is stopping....")
end
def service_pause
@@ -160,17 +178,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)
@@ -203,7 +233,6 @@ class Chef
def configure_stdout_logger
stdout_logger = MonoLogger.new(STDOUT)
- STDOUT.sync = true
stdout_logger.formatter = Chef::Log.logger.formatter
Chef::Log.loggers << stdout_logger
end
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 e5a6e93d1e..aa03f043c2 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -43,6 +43,8 @@ require 'chef/formatters/minimal'
require 'chef/version'
require 'chef/resource_reporter'
require 'chef/run_lock'
+require 'chef/policy_builder'
+require 'chef/request_id'
require 'ohai'
require 'rbconfig'
@@ -53,6 +55,16 @@ class Chef
class Client
include Chef::Mixin::PathSanity
+ # IO stream that will be used as 'STDOUT' for formatters. Formatters are
+ # configured during `initialize`, so this provides a convenience for
+ # setting alternative IO stream during tests.
+ STDOUT_FD = STDOUT
+
+ # IO stream that will be used as 'STDERR' for formatters. Formatters are
+ # configured during `initialize`, so this provides a convenience for
+ # setting alternative IO stream during tests.
+ STDERR_FD = STDERR
+
# Clears all notifications for client run status events.
# Primarily for testing purposes.
def self.clear_notifications
@@ -127,15 +139,13 @@ class Chef
attr_accessor :rest
attr_accessor :runner
- #--
- # TODO: timh/cw: 5-19-2010: json_attribs should be moved to RunContext?
attr_reader :json_attribs
attr_reader :run_status
attr_reader :events
# Creates a new Chef::Client.
def initialize(json_attribs=nil, args={})
- @json_attribs = json_attribs
+ @json_attribs = json_attribs || {}
@node = nil
@run_status = nil
@runner = nil
@@ -146,13 +156,17 @@ class Chef
@events = EventDispatch::Dispatcher.new(*event_handlers)
@override_runlist = args.delete(:override_runlist)
- runlist_override_sanity_check!
+ @specific_recipes = args.delete(:specific_recipes)
+
+ if new_runlist = args.delete(:runlist)
+ @json_attribs["run_list"] = new_runlist
+ end
end
def configure_formatters
formatters_for_run.map do |formatter_name, output_path|
if output_path.nil?
- Chef::Formatters.new(formatter_name, STDOUT, STDERR)
+ Chef::Formatters.new(formatter_name, STDOUT_FD, STDERR_FD)
else
io = File.open(output_path, "a+")
io.sync = true
@@ -197,7 +211,8 @@ class Chef
begin
Chef::Log.debug "Forked instance now converging"
do_run
- rescue Exception
+ rescue Exception => e
+ Chef::Log.error(e.to_s)
exit 1
else
exit 0
@@ -206,7 +221,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
@@ -224,40 +239,51 @@ class Chef
raise Exceptions::ChildConvergeError, message
end
+ # Instantiates a Chef::Node object, possibly loading the node's prior state
+ # when using chef-client. Delegates to policy_builder
+ #
+ #
+ # === Returns
+ # Chef::Node:: The node object for this chef run
+ def load_node
+ policy_builder.load_node
+ @node = policy_builder.node
+ end
+ # Mutates the `node` object to prepare it for the chef run. Delegates to
+ # policy_builder
+ #
+ # === Returns
+ # Chef::Node:: The updated node object
+ def build_node
+ policy_builder.build_node
+ @run_status = Chef::RunStatus.new(node, events)
+ node
+ end
- # Configures the Chef::Cookbook::FileVendor class to fetch file from the
- # server or disk as appropriate, creates the run context for this run, and
- # sanity checks the cookbook collection.
- #===Returns
- # Chef::RunContext:: the run context for this run.
def setup_run_context
- if Chef::Config[:solo]
- Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, Chef::Config[:cookbook_path]) }
- 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)
- else
- Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, rest) }
- cookbook_hash = sync_cookbooks
- cookbook_collection = Chef::CookbookCollection.new(cookbook_hash)
- run_context = Chef::RunContext.new(node, cookbook_collection, @events)
- end
- run_status.run_context = run_context
-
- run_context.load(@run_list_expansion)
+ run_context = policy_builder.setup_run_context(@specific_recipes)
assert_cookbook_path_not_empty(run_context)
+ run_status.run_context = run_context
run_context
end
+ def sync_cookbooks
+ policy_builder.sync_cookbooks
+ end
+
+ def policy_builder
+ @policy_builder ||= Chef::PolicyBuilder.strategy.new(node_name, ohai.data, json_attribs, @override_runlist, events)
+ end
+
+
def save_updated_node
- unless Chef::Config[:solo]
+ if Chef::Config[:solo]
+ # nothing to do
+ elsif policy_builder.temporary_policy?
+ Chef::Log.warn("Skipping final node save because override_runlist was given")
+ else
Chef::Log.debug("Saving the current state of node #{node_name}")
- if(@node.override_runlist)
- @node.automatic_attrs[:runlist_override_history] = {Time.now.to_i => @node.override_runlist.inspect}
- @node.override_runlist.reset!
- end
@node.save
end
end
@@ -284,89 +310,14 @@ class Chef
name
end
- # Applies environment, external JSON attributes, and override run list to
- # the node, Then expands the run_list.
- #
- # === Returns
- # node<Chef::Node>:: The modified @node object. @node is modified in place.
- def build_node
- # Allow user to override the environment of a node by specifying
- # a config parameter.
- if Chef::Config[:environment] && !Chef::Config[:environment].chop.empty?
- @node.chef_environment(Chef::Config[:environment])
- end
-
- # consume_external_attrs may add items to the run_list. Save the
- # expanded run_list, which we will pass to the server later to
- # determine which versions of cookbooks to use.
- @node.reset_defaults_and_overrides
- @node.consume_external_attrs(ohai.data, @json_attribs)
-
- unless(@override_runlist.empty?)
- runlist_override_sanity_check!
- @node.override_runlist(*@override_runlist)
- Chef::Log.warn "Run List override has been provided."
- Chef::Log.warn "Original Run List: [#{@node.primary_runlist}]"
- Chef::Log.warn "Overridden Run List: [#{@node.run_list}]"
- end
-
- @run_list_expansion = expand_run_list
-
- # @run_list_expansion is a RunListExpansion.
- #
- # Convert @expanded_run_list, which is an
- # Array of Hashes of the form
- # {:name => NAME, :version_constraint => Chef::VersionConstraint },
- # into @expanded_run_list_with_versions, an
- # Array of Strings of the form
- # "#{NAME}@#{VERSION}"
- @expanded_run_list_with_versions = @run_list_expansion.recipes.with_version_constraints_strings
-
- Chef::Log.info("Run List is [#{@node.run_list}]")
- Chef::Log.info("Run List expands to [#{@expanded_run_list_with_versions.join(', ')}]")
-
- @run_status = Chef::RunStatus.new(@node, @events)
-
- @events.node_load_completed(node, @expanded_run_list_with_versions, Chef::Config)
-
- @node
- end
-
- # In client-server operation, loads the node state from the server. In
- # chef-solo operation, builds a new node object.
- def load_node
- @events.node_load_start(node_name, Chef::Config)
- Chef::Log.debug("Building node object for #{node_name}")
-
- if Chef::Config[:solo]
- @node = Chef::Node.build(node_name)
- else
- @node = Chef::Node.find_or_create(node_name)
- end
- rescue Exception => e
- # TODO: wrap this exception so useful error info can be given to the
- # user.
- @events.node_load_failed(node_name, e, Chef::Config)
- raise
- end
-
- def expand_run_list
- if Chef::Config[:solo]
- @node.expand!('disk')
- else
- @node.expand!('server')
- end
- rescue Exception => e
- # TODO: wrap/munge exception with useful error output.
- @events.run_list_expand_failed(node, e)
- raise
- end
-
#
# === 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
@@ -386,37 +337,6 @@ class Chef
raise
end
- # Sync_cookbooks eagerly loads all files except files and
- # templates. It returns the cookbook_hash -- the return result
- # from /environments/#{node.chef_environment}/cookbook_versions,
- # which we will use for our run_context.
- #
- # === Returns
- # Hash:: The hash of cookbooks with download URLs as given by the server
- def sync_cookbooks
- Chef::Log.debug("Synchronizing cookbooks")
-
- begin
- @events.cookbook_resolution_start(@expanded_run_list_with_versions)
- cookbook_hash = rest.post_rest("environments/#{@node.chef_environment}/cookbook_versions",
- {:run_list => @expanded_run_list_with_versions})
- rescue Exception => e
- # TODO: wrap/munge exception to provide helpful error output
- @events.cookbook_resolution_failed(@expanded_run_list_with_versions, e)
- raise
- else
- @events.cookbook_resolution_complete(cookbook_hash)
- end
-
- synchronizer = Chef::CookbookSynchronizer.new(cookbook_hash, @events)
- synchronizer.sync_cookbooks
-
- # register the file cache path in the cookbook path so that CookbookLoader actually picks up the synced cookbooks
- Chef::Config[:cookbook_path] = File.join(Chef::Config[:file_cache_path], "cookbooks")
-
- cookbook_hash
- end
-
# Converges the node.
#
# === Returns
@@ -434,6 +354,19 @@ class Chef
raise
end
+ # Expands the run list. Delegates to the policy_builder.
+ #
+ # Normally this does not need to be called from here, it will be called by
+ # build_node. This is provided so external users (like the chefspec
+ # project) can inject custom behavior into the run process.
+ #
+ # === Returns
+ # RunListExpansion: A RunListExpansion or API compatible object.
+ def expanded_run_list
+ policy_builder.expand_run_list
+ end
+
+
def do_windows_admin_check
if Chef::Platform.windows?
Chef::Log.debug("Checking for administrator privileges....")
@@ -466,13 +399,17 @@ 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
+ request_id = Chef::RequestID.instance.request_id
run_context = nil
@events.run_start(Chef::VERSION)
Chef::Log.info("*** Chef #{Chef::VERSION} ***")
+ Chef::Log.info "Chef-client pid: #{Process.pid}"
+ Chef::Log.debug("Chef-client request_id: #{request_id}")
enforce_path_sanity
run_ohai
@events.ohai_completed(node)
@@ -482,6 +419,7 @@ class Chef
build_node
+ run_status.run_id = request_id
run_status.start_clock
Chef::Log.info("Starting Chef Run for #{node.name}")
run_started
@@ -512,6 +450,8 @@ class Chef
@events.run_failed(e)
raise
ensure
+ Chef::RequestID.instance.reset_request_id
+ request_id = nil
@run_status = nil
run_context = nil
runlock.release
@@ -520,24 +460,8 @@ class Chef
true
end
- # Ensures runlist override contains RunListItem instances
- def runlist_override_sanity_check!
- # Convert to array and remove whitespace
- if @override_runlist.is_a?(String)
- @override_runlist = @override_runlist.split(',').map { |e| e.strip }
- end
- @override_runlist = [@override_runlist].flatten.compact
- @override_runlist.map! do |item|
- if(item.is_a?(Chef::RunList::RunListItem))
- item
- else
- Chef::RunList::RunListItem.new(item)
- end
- end
- end
-
- def directory_not_empty?(path)
- File.exists?(path) && (Dir.entries(path).size > 2)
+ def empty_directory?(path)
+ !File.exists?(path) || (Dir.entries(path).size <= 2)
end
def is_last_element?(index, object)
@@ -549,15 +473,12 @@ class Chef
# Check for cookbooks in the path given
# Chef::Config[:cookbook_path] can be a string or an array
# if it's an array, go through it and check each one, raise error at the last one if no files are found
- Chef::Log.debug "Loading from cookbook_path: #{Array(Chef::Config[:cookbook_path]).map { |path| File.expand_path(path) }.join(', ')}"
- Array(Chef::Config[:cookbook_path]).each_with_index do |cookbook_path, index|
- if directory_not_empty?(cookbook_path)
- break
- else
- msg = "No cookbook found in #{Chef::Config[:cookbook_path].inspect}, make sure cookbook_path is set correctly."
- Chef::Log.fatal(msg)
- raise Chef::Exceptions::CookbookNotFound, msg if is_last_element?(index, Chef::Config[:cookbook_path])
- end
+ cookbook_paths = Array(Chef::Config[:cookbook_path])
+ Chef::Log.debug "Loading from cookbook_path: #{cookbook_paths.map { |path| File.expand_path(path) }.join(', ')}"
+ if cookbook_paths.all? {|path| empty_directory?(path) }
+ msg = "None of the cookbook paths set in Chef::Config[:cookbook_path], #{cookbook_paths.inspect}, contain any cookbooks"
+ Chef::Log.fatal(msg)
+ raise Chef::Exceptions::CookbookNotFound, msg
end
else
Chef::Log.warn("Node #{node_name} has an empty run list.") if run_context.node.run_list.empty?
diff --git a/lib/chef/config.rb b/lib/chef/config.rb
index e3211d232e..da3f3790f6 100644
--- a/lib/chef/config.rb
+++ b/lib/chef/config.rb
@@ -23,12 +23,20 @@ require 'chef/log'
require 'chef/exceptions'
require 'mixlib/config'
require 'chef/util/selinux'
+require 'pathname'
class Chef
class Config
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 +58,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,93 +97,174 @@ 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
+ configurable(:daemonize).writes_value { |v| v }
+
+ # 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
- # Override the config dispatch to set the value of log_location configuration option
- #
- # === Parameters
- # location<IO||String>:: Logging location as either an IO stream or string representing log file path
- #
- config_attr_writer :log_location do |location|
- if location.respond_to? :sync=
- location.sync = true
- location
- elsif location.respond_to? :to_str
- begin
- f = File.new(location.to_str, "a")
- f.sync = true
- rescue Errno::ENOENT
- raise Chef::Exceptions::ConfigurationError, "Failed to open or create log file at #{location.to_str}"
+ 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
- f
+ 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 +277,95 @@ 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
+
+ # Logging location as either an IO stream or string representing log file path
+ default :log_location, STDOUT
# 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
+ default :force_logger, false
- http_retry_count 5
- http_retry_delay 5
- interval nil
- json_attribs nil
- log_location STDOUT
+ default :http_retry_count, 5
+ default :http_retry_delay, 5
+ default :interval, nil
+ default :once, nil
+ default :json_attribs, nil
# 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
+
+ # Policyfile is an experimental feature where a node gets its run list and
+ # cookbook version set from a single document on the server instead of
+ # expanding the run list and having the server compute the cookbook version
+ # set based on environment constraints.
+ #
+ # Because this feature is experimental, it is not recommended for
+ # production use. Developent/release of this feature may not adhere to
+ # semver guidelines.
+ default :use_policyfile, 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")
-
- data_bag_path platform_specific_path("/var/chef/data_bags")
+ # 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
+
+ # 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
+
+ # Path to the default CA bundle files.
+ default :ssl_ca_path, nil
+ default(:ssl_ca_file) do
+ if on_windows? and embedded_path = embedded_dir
+ cacert_path = File.join(embedded_path, "ssl/certs/cacert.pem")
+ cacert_path if File.exist?(cacert_path)
+ else
+ nil
+ end
+ end
- environment_path platform_specific_path("/var/chef/environments")
+ # 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,56 @@ 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, []
+
+ # Event Handlers
+ default :event_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 +484,53 @@ 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+$/ ]
+ # user/group cannot start with '-', '+' or '~'
+ # user/group cannot contain ':', ',' or non-space-whitespace or null byte
+ # everything else is allowed (UTF-8, spaces, etc) and we delegate to your O/S useradd program to barf or not
+ # copies: http://anonscm.debian.org/viewvc/pkg-shadow/debian/trunk/debian/patches/506_relaxed_usernames?view=markup
+ default :user_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
+ default :group_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
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
+
+ # If installed via an omnibus installer, this gives the path to the
+ # "embedded" directory which contains all of the software packaged with
+ # omnibus. This is used to locate the cacert.pem file on windows.
+ def self.embedded_dir
+ Pathname.new(_this_file).ascend do |path|
+ if path.basename.to_s == "embedded"
+ return path.to_s
+ end
+ end
+
+ nil
+ end
+
+ # Path to this file in the current install.
+ def self._this_file
+ File.expand_path(__FILE__)
+ end
end
end
diff --git a/lib/chef/config_fetcher.rb b/lib/chef/config_fetcher.rb
new file mode 100644
index 0000000000..26440c9c01
--- /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=nil)
+ @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..4f8dcff6dc 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.
@@ -17,6 +17,8 @@
#
require 'pathname'
+require 'stringio'
+require 'erubis'
require 'chef/mixin/shell_out'
require 'chef/mixin/checksum'
@@ -39,19 +41,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 +129,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
@@ -171,28 +163,127 @@ class Chef
def validate_template(erb_file)
Chef::Log.debug("Testing template #{erb_file} for syntax errors...")
- result = shell_out("erubis -x #{erb_file} | ruby -c")
+ if validate_inline?
+ validate_erb_file_inline(erb_file)
+ else
+ validate_erb_via_subcommand(erb_file)
+ end
+ end
+
+ def validate_ruby_file(ruby_file)
+ Chef::Log.debug("Testing #{ruby_file} for syntax errors...")
+ if validate_inline?
+ validate_ruby_file_inline(ruby_file)
+ else
+ validate_ruby_by_subcommand(ruby_file)
+ end
+ end
+
+ # Whether or not we're running on a version of ruby that can support
+ # inline validation. Inline validation relies on the `RubyVM` features
+ # introduced with ruby 1.9, so 1.8 cannot be supported.
+ def validate_inline?
+ defined?(RubyVM::InstructionSequence)
+ end
+
+ # Validate the ruby code in an erb template. Uses RubyVM to do syntax
+ # checking, so callers should check #validate_inline? before calling.
+ def validate_erb_file_inline(erb_file)
+ old_stderr = $stderr
+
+ engine = Erubis::Eruby.new
+ engine.convert!(IO.read(erb_file))
+
+ ruby_code = engine.src
+
+ # Even when we're compiling the code w/ RubyVM, syntax errors just
+ # print to $stderr. We want to capture this and handle the printing
+ # ourselves, so we must temporarily swap $stderr to capture the output.
+ tmp_stderr = $stderr = StringIO.new
+
+ abs_path = File.expand_path(erb_file)
+ RubyVM::InstructionSequence.new(ruby_code, erb_file, abs_path, 0)
+
+ true
+ rescue SyntaxError
+ $stderr = old_stderr
+ invalid_erb_file(erb_file, tmp_stderr.string)
+ false
+ ensure
+ # be paranoid about setting stderr back to the old value.
+ $stderr = old_stderr if defined?(old_stderr) && old_stderr
+ end
+
+ # Validate the ruby code in an erb template. Pipes the output of `erubis
+ # -x` to `ruby -c`, so it works with any ruby version, but is much slower
+ # than the inline version.
+ # --
+ # TODO: This can be removed when ruby 1.8 support is dropped.
+ def validate_erb_via_subcommand(erb_file)
+ result = shell_out("erubis -x #{erb_file} | #{ruby} -c")
result.error!
true
rescue Mixlib::ShellOut::ShellCommandFailed
+ invalid_erb_file(erb_file, result.stderr)
+ false
+ end
+
+ # Debug a syntax error in a template.
+ def invalid_erb_file(erb_file, error_message)
file_relative_path = erb_file[/^#{Regexp.escape(cookbook_path+File::Separator)}(.*)/, 1]
Chef::Log.fatal("Erb template #{file_relative_path} has a syntax error:")
- result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) }
+ error_message.each_line { |l| Chef::Log.fatal(l.chomp) }
+ nil
+ end
+
+ # Validate the syntax of a ruby file. Uses (Ruby 1.9+ only) RubyVM to
+ # compile the code without evaluating it or spawning a new process.
+ # Callers should check #validate_inline? before calling.
+ def validate_ruby_file_inline(ruby_file)
+ # Even when we're compiling the code w/ RubyVM, syntax errors just
+ # print to $stderr. We want to capture this and handle the printing
+ # ourselves, so we must temporarily swap $stderr to capture the output.
+ old_stderr = $stderr
+ tmp_stderr = $stderr = StringIO.new
+ abs_path = File.expand_path(ruby_file)
+ file_content = IO.read(abs_path)
+ RubyVM::InstructionSequence.new(file_content, ruby_file, abs_path, 0)
+ true
+ rescue SyntaxError
+ $stderr = old_stderr
+ invalid_ruby_file(ruby_file, tmp_stderr.string)
false
+ ensure
+ # be paranoid about setting stderr back to the old value.
+ $stderr = old_stderr if defined?(old_stderr) && old_stderr
end
- def validate_ruby_file(ruby_file)
- Chef::Log.debug("Testing #{ruby_file} for syntax errors...")
- result = shell_out("ruby -c #{ruby_file}")
+ # Validate the syntax of a ruby file by shelling out to `ruby -c`. Should
+ # work for all ruby versions, but is slower and uses more resources than
+ # the inline strategy.
+ def validate_ruby_by_subcommand(ruby_file)
+ result = shell_out("#{ruby} -c #{ruby_file}")
result.error!
true
rescue Mixlib::ShellOut::ShellCommandFailed
+ invalid_ruby_file(ruby_file, result.stderr)
+ false
+ end
+
+ # Debugs ruby syntax errors by printing the path to the file and any
+ # diagnostic info given in +error_message+
+ def invalid_ruby_file(ruby_file, error_message)
file_relative_path = ruby_file[/^#{Regexp.escape(cookbook_path+File::Separator)}(.*)/, 1]
Chef::Log.fatal("Cookbook file #{file_relative_path} has a ruby syntax error:")
- result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) }
+ error_message.each_line { |l| Chef::Log.fatal(l.chomp) }
false
end
+ # Returns the full path to the running ruby.
+ def ruby
+ Gem.ruby
+ end
+
end
end
end
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..6524eed3e5 100644
--- a/lib/chef/cookbook_uploader.rb
+++ b/lib/chef/cookbook_uploader.rb
@@ -8,6 +8,7 @@ require 'chef/cookbook_version'
require 'chef/cookbook/syntax_check'
require 'chef/cookbook/file_system_file_vendor'
require 'chef/sandbox'
+require 'thread'
class Chef
class CookbookUploader
@@ -16,10 +17,10 @@ class Chef
@work_queue ||= Queue.new
end
- def self.setup_worker_threads
+ def self.setup_worker_threads(concurrency=10)
@worker_threads ||= begin
work_queue
- (1...10).map do
+ (1..concurrency).map do
Thread.new do
loop do
work_queue.pop.call
@@ -33,6 +34,7 @@ class Chef
attr_reader :path
attr_reader :opts
attr_reader :rest
+ attr_reader :concurrency
# Creates a new CookbookUploader.
# ===Arguments:
@@ -49,10 +51,13 @@ class Chef
# * :rest A Chef::REST object that you have configured the way you like it.
# If you don't provide this, one will be created using the values
# in Chef::Config.
+ # * :concurrency An integer that decided how many threads will be used to
+ # perform concurrent uploads
def initialize(cookbooks, path, opts={})
@path, @opts = path, opts
@cookbooks = Array(cookbooks)
@rest = opts[:rest] || Chef::REST.new(Chef::Config[:chef_server_url])
+ @concurrency = opts[:concurrency] || 10
end
def upload_cookbooks
@@ -72,7 +77,7 @@ class Chef
Chef::Log.info("Uploading files")
- self.class.setup_worker_threads
+ self.class.setup_worker_threads(concurrency)
checksums_to_upload = Set.new
@@ -137,21 +142,25 @@ 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)))
+ headers = { 'content-type' => 'application/x-binary', 'content-md5' => checksum64, "accept" => 'application/json' }
+ 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)
+ Chef::HTTP::Simple.new(url, :headers=>headers).put(url, file_contents)
checksums_to_upload.delete(checksum)
- rescue RestClient::Exception => e
- Chef::Knife.ui.error("Failed to upload #@cookbook : #{e.message}\n#{e.response.body}")
+ rescue Net::HTTPServerException, Net::HTTPFatalError, Errno::ECONNREFUSED, Timeout::Error, Errno::ETIMEDOUT, SocketError => e
+ error_message = "Failed to upload #{file} (#{checksum}) to #{url} : #{e.message}"
+ error_message << "\n#{e.response.body}" if e.respond_to?(:response)
+ Chef::Knife.ui.error(error_message)
raise
end
end
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..639d71a74d 100644
--- a/lib/chef/data_bag.rb
+++ b/lib/chef/data_bag.rb
@@ -31,7 +31,7 @@ class Chef
include Chef::Mixin::FromFile
include Chef::Mixin::ParamsValidate
- VALID_NAME = /^[\-[:alnum:]_]+$/
+ VALID_NAME = /^[\.\-[:alnum:]_]+$/
def self.validate_name!(name)
unless name =~ VALID_NAME
@@ -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/data_bag_item.rb b/lib/chef/data_bag_item.rb
index 3528ba724a..07dd15a1dc 100644
--- a/lib/chef/data_bag_item.rb
+++ b/lib/chef/data_bag_item.rb
@@ -35,7 +35,7 @@ class Chef
include Chef::Mixin::FromFile
include Chef::Mixin::ParamsValidate
- VALID_ID = /^[\-[:alnum:]_]+$/
+ VALID_ID = /^[\.\-[:alnum:]_]+$/
def self.validate_id!(id_str)
if id_str.nil? || ( id_str !~ VALID_ID )
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/dsl/reboot_pending.rb b/lib/chef/dsl/reboot_pending.rb
new file mode 100644
index 0000000000..9f80d38c61
--- /dev/null
+++ b/lib/chef/dsl/reboot_pending.rb
@@ -0,0 +1,61 @@
+# Author:: Bryan McLellan <btm@loftninjas.org>
+# Author:: Seth Chisamore <schisamo@opscode.com>
+# Copyright:: Copyright (c) 2011,2014, Chef Software, 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/dsl/platform_introspection'
+require 'chef/dsl/registry_helper'
+
+class Chef
+ module DSL
+ module RebootPending
+
+ include Chef::DSL::RegistryHelper
+ include Chef::DSL::PlatformIntrospection
+
+ # Returns true if the system needs a reboot or is expected to reboot
+ # Raises UnsupportedPlatform if this functionality isn't provided yet
+ def reboot_pending?
+
+ if platform?("windows")
+ # PendingFileRenameOperations contains pairs (REG_MULTI_SZ) of filenames that cannot be updated
+ # due to a file being in use (usually a temporary file and a system file)
+ # \??\c:\temp\test.sys!\??\c:\winnt\system32\test.sys
+ # http://technet.microsoft.com/en-us/library/cc960241.aspx
+ registry_value_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { :name => 'PendingFileRenameOperations' }) ||
+
+ # RebootRequired key contains Update IDs with a value of 1 if they require a reboot.
+ # The existence of RebootRequired alone is sufficient on my Windows 8.1 workstation in Windows Update
+ registry_key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') ||
+
+ # Vista + Server 2008 and newer may have reboots pending from CBS
+ registry_key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired') ||
+
+ # The mere existance of the UpdateExeVolatile key should indicate a pending restart for certain updates
+ # http://support.microsoft.com/kb/832475
+ (registry_key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile') &&
+ !registry_get_values('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').select { |v| v[:name] == "Flags" }[0].nil? &&
+ [1,2,3].include?(registry_get_values('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').select { |v| v[:name] == "Flags" }[0][:data]))
+ elsif platform?("ubuntu")
+ # This should work for Debian as well if update-notifier-common happens to be installed. We need an API for that.
+ File.exists?('/var/run/reboot-required')
+ else
+ raise Chef::Exceptions::UnsupportedPlatform.new(node[:platform])
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb
index f3507a8031..ebf19c7f23 100644
--- a/lib/chef/dsl/recipe.rb
+++ b/lib/chef/dsl/recipe.rb
@@ -35,46 +35,116 @@ class Chef
# If we have a definition that matches, we want to use that instead. This should
# let you do some really crazy over-riding of "native" types, if you really want
# to.
- if run_context.definitions.has_key?(method_symbol)
- # This dupes the high level object, but we still need to dup the params
- new_def = run_context.definitions[method_symbol].dup
- new_def.params = new_def.params.dup
- new_def.node = run_context.node
- # This sets up the parameter overrides
- new_def.instance_eval(&block) if block
- new_recipe = Chef::Recipe.new(cookbook_name, @recipe_name, run_context)
- new_recipe.params = new_def.params
- new_recipe.params[:name] = args[0]
- new_recipe.instance_eval(&new_def.recipe)
- else
+ if has_resource_definition?(method_symbol)
+ evaluate_resource_definition(method_symbol, *args, &block)
+ elsif have_resource_class_for?(method_symbol)
# Otherwise, we're rocking the regular resource call route.
+ declare_resource(method_symbol, args[0], caller[0], &block)
+ else
+ begin
+ super
+ rescue NoMethodError
+ raise NoMethodError, "No resource or method named `#{method_symbol}' for #{describe_self_for_error}"
+ rescue NameError
+ raise NameError, "No resource, method, or local variable named `#{method_symbol}' for #{describe_self_for_error}"
+ end
+ end
+ end
+
+ def has_resource_definition?(name)
+ yes_or_no = run_context.definitions.has_key?(name)
+
+ yes_or_no
+ end
+
+ # Processes the arguments and block as a resource definition.
+ def evaluate_resource_definition(definition_name, *args, &block)
- # Checks the new platform => short_name => resource mapping initially
- # then fall back to the older approach (Chef::Resource.const_get) for
- # backward compatibility
- resource_class = Chef::Resource.resource_for_node(method_symbol, run_context.node)
-
- super unless resource_class
- raise ArgumentError, "You must supply a name when declaring a #{method_symbol} resource" unless args.size > 0
-
- # If we have a resource like this one, we want to steal its state
- args << run_context
- resource = resource_class.new(*args)
- resource.source_line = caller[0]
- resource.load_prior_resource
- resource.cookbook_name = cookbook_name
- resource.recipe_name = @recipe_name
- resource.params = @params
- # Determine whether this resource is being created in the context of an enclosing Provider
- resource.enclosing_provider = self.is_a?(Chef::Provider) ? self : nil
- # Evaluate resource attribute DSL
- resource.instance_eval(&block) if block
-
- # Run optional resource hook
- resource.after_created
-
- run_context.resource_collection.insert(resource)
- resource
+ # This dupes the high level object, but we still need to dup the params
+ new_def = run_context.definitions[definition_name].dup
+
+ new_def.params = new_def.params.dup
+ new_def.node = run_context.node
+ # This sets up the parameter overrides
+ new_def.instance_eval(&block) if block
+
+
+ new_recipe = Chef::Recipe.new(cookbook_name, recipe_name, run_context)
+ new_recipe.params = new_def.params
+ new_recipe.params[:name] = args[0]
+ new_recipe.instance_eval(&new_def.recipe)
+ new_recipe
+ end
+
+ # Instantiates a resource (via #build_resource), then adds it to the
+ # resource collection. Note that resource classes are looked up directly,
+ # so this will create the resource you intended even if the method name
+ # corresponding to that resource has been overridden.
+ def declare_resource(type, name, created_at=nil, &resource_attrs_block)
+ created_at ||= caller[0]
+
+ resource = build_resource(type, name, created_at, &resource_attrs_block)
+
+ run_context.resource_collection.insert(resource)
+ resource
+ end
+
+ # Instantiate a resource of the given +type+ with the given +name+ and
+ # attributes as given in the +resource_attrs_block+.
+ #
+ # The resource is NOT added to the resource collection.
+ def build_resource(type, name, created_at=nil, &resource_attrs_block)
+ created_at ||= caller[0]
+
+ # Checks the new platform => short_name => resource mapping initially
+ # then fall back to the older approach (Chef::Resource.const_get) for
+ # backward compatibility
+ resource_class = resource_class_for(type)
+
+ raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil?
+
+ resource = resource_class.new(name, run_context)
+ resource.source_line = created_at
+ # If we have a resource like this one, we want to steal its state
+ # This behavior is very counter-intuitive and should be removed.
+ # See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694
+ # Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052
+ resource.load_prior_resource
+ resource.cookbook_name = cookbook_name
+ resource.recipe_name = recipe_name
+ # Determine whether this resource is being created in the context of an enclosing Provider
+ resource.enclosing_provider = self.is_a?(Chef::Provider) ? self : nil
+
+ # XXX: This is very crufty, but it's required for resource definitions
+ # to work properly :(
+ resource.params = @params
+
+ # Evaluate resource attribute DSL
+ resource.instance_eval(&resource_attrs_block) if block_given?
+
+ # Run optional resource hook
+ resource.after_created
+
+ resource
+ end
+
+ def resource_class_for(snake_case_name)
+ Chef::Resource.resource_for_node(snake_case_name, run_context.node)
+ end
+
+ def have_resource_class_for?(snake_case_name)
+ not resource_class_for(snake_case_name).nil?
+ rescue NameError
+ false
+ end
+
+ def describe_self_for_error
+ if respond_to?(:name)
+ %Q[`#{self.class.name} "#{name}"']
+ elsif respond_to?(:recipe_name)
+ %Q[`#{self.class.name} "#{recipe_name}"']
+ else
+ to_s
end
end
diff --git a/lib/chef/encrypted_data_bag_item.rb b/lib/chef/encrypted_data_bag_item.rb
index 452a8224df..b38a6f3512 100644
--- a/lib/chef/encrypted_data_bag_item.rb
+++ b/lib/chef/encrypted_data_bag_item.rb
@@ -16,11 +16,10 @@
# limitations under the License.
#
-require 'base64'
-require 'openssl'
+require 'chef/config'
require 'chef/data_bag_item'
-require 'yaml'
-require 'yajl'
+require 'chef/encrypted_data_bag_item/decryptor'
+require 'chef/encrypted_data_bag_item/encryptor'
require 'open-uri'
# An EncryptedDataBagItem represents a read-only data bag item where
@@ -50,305 +49,6 @@ require 'open-uri'
class Chef::EncryptedDataBagItem
ALGORITHM = 'aes-256-cbc'
- class UnacceptableEncryptedDataBagItemFormat < StandardError
- end
-
- class UnsupportedEncryptedDataBagItemFormat < StandardError
- end
-
- class DecryptionFailure < StandardError
- end
-
- class UnsupportedCipher < StandardError
- end
-
- # Implementation class for converting plaintext data bag item values to an
- # encrypted value, including any necessary wrappers and metadata.
- module Encryptor
-
- # "factory" method that creates an encryptor object with the proper class
- # for the desired encrypted data bag format version.
- #
- # +Chef::Config[:data_bag_encrypt_version]+ determines which version is used.
- def self.new(value, secret, iv=nil)
- format_version = Chef::Config[:data_bag_encrypt_version]
- case format_version
- when 1
- Version1Encryptor.new(value, secret, iv)
- when 2
- Version2Encryptor.new(value, secret, iv)
- else
- raise UnsupportedEncryptedDataBagItemFormat,
- "Invalid encrypted data bag format version `#{format_version}'. Supported versions are '1', '2'"
- end
- end
-
- class Version1Encryptor
- attr_reader :key
- attr_reader :plaintext_data
-
- # Create a new Encryptor for +data+, which will be encrypted with the given
- # +key+.
- #
- # === Arguments:
- # * data: An object of any type that can be serialized to json
- # * key: A String representing the desired passphrase
- # * iv: The optional +iv+ parameter is intended for testing use only. When
- # *not* supplied, Encryptor will use OpenSSL to generate a secure random
- # IV, which is what you want.
- def initialize(plaintext_data, key, iv=nil)
- @plaintext_data = plaintext_data
- @key = key
- @iv = iv && Base64.decode64(iv)
- end
-
- # Returns a wrapped and encrypted version of +plaintext_data+ suitable for
- # using as the value in an encrypted data bag item.
- def for_encrypted_item
- {
- "encrypted_data" => encrypted_data,
- "iv" => Base64.encode64(iv),
- "version" => 1,
- "cipher" => ALGORITHM
- }
- end
-
- # Generates or returns the IV.
- def iv
- # Generated IV comes from OpenSSL::Cipher::Cipher#random_iv
- # This gets generated when +openssl_encryptor+ gets created.
- openssl_encryptor if @iv.nil?
- @iv
- end
-
- # Generates (and memoizes) an OpenSSL::Cipher::Cipher object and configures
- # it for the specified iv and encryption key.
- def openssl_encryptor
- @openssl_encryptor ||= begin
- encryptor = OpenSSL::Cipher::Cipher.new(ALGORITHM)
- encryptor.encrypt
- @iv ||= encryptor.random_iv
- encryptor.iv = @iv
- encryptor.key = Digest::SHA256.digest(key)
- encryptor
- end
- end
-
- # Encrypts and Base64 encodes +serialized_data+
- def encrypted_data
- @encrypted_data ||= begin
- enc_data = openssl_encryptor.update(serialized_data)
- enc_data << openssl_encryptor.final
- Base64.encode64(enc_data)
- end
- end
-
- # Wraps the data in a single key Hash (JSON Object) and converts to JSON.
- # The wrapper is required because we accept values (such as Integers or
- # Strings) that do not produce valid JSON when serialized without the
- # wrapper.
- def serialized_data
- Yajl::Encoder.encode(:json_wrapper => plaintext_data)
- end
- end
-
- class Version2Encryptor < Version1Encryptor
-
- # Returns a wrapped and encrypted version of +plaintext_data+ suitable for
- # using as the value in an encrypted data bag item.
- def for_encrypted_item
- {
- "encrypted_data" => encrypted_data,
- "hmac" => hmac,
- "iv" => Base64.encode64(iv),
- "version" => 2,
- "cipher" => ALGORITHM
- }
- end
-
- # Generates an HMAC-SHA2-256 of the encrypted data (encrypt-then-mac)
- def hmac
- @hmac ||= begin
- digest = OpenSSL::Digest::Digest.new("sha256")
- raw_hmac = OpenSSL::HMAC.digest(digest, key, encrypted_data)
- Base64.encode64(raw_hmac)
- end
- end
-
- end
- end
-
- #=== Decryptor
- # For backwards compatibility, Chef implements decryption/deserialization for
- # older encrypted data bag item formats in addition to the current version.
- # Each decryption/deserialization strategy is implemented as a class in this
- # namespace. For convenience the factory method +Decryptor.for()+ can be used
- # to create an instance of the appropriate strategy for the given encrypted
- # data bag value.
- module Decryptor
-
- # Detects the encrypted data bag item format version and instantiates a
- # decryptor object for that version. Call #for_decrypted_item on the
- # resulting object to decrypt and deserialize it.
- def self.for(encrypted_value, key)
- format_version = format_version_of(encrypted_value)
- assert_format_version_acceptable!(format_version)
- case format_version
- when 2
- Version2Decryptor.new(encrypted_value, key)
- when 1
- Version1Decryptor.new(encrypted_value, key)
- when 0
- Version0Decryptor.new(encrypted_value, key)
- else
- raise UnsupportedEncryptedDataBagItemFormat,
- "This version of chef does not support encrypted data bag item format version '#{format_version}'"
- end
- end
-
- def self.format_version_of(encrypted_value)
- if encrypted_value.respond_to?(:key?)
- encrypted_value["version"]
- else
- 0
- end
- end
-
- def self.assert_format_version_acceptable!(format_version)
- unless format_version.kind_of?(Integer) and format_version >= Chef::Config[:data_bag_decrypt_minimum_version]
- raise UnacceptableEncryptedDataBagItemFormat,
- "The encrypted data bag item has format version `#{format_version}', " +
- "but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'"
- end
- end
-
- class Version1Decryptor
-
- attr_reader :encrypted_data
- attr_reader :key
-
- def initialize(encrypted_data, key)
- @encrypted_data = encrypted_data
- @key = key
- end
-
- def for_decrypted_item
- Yajl::Parser.parse(decrypted_data)["json_wrapper"]
- rescue Yajl::ParseError
- # convert to a DecryptionFailure error because the most likely scenario
- # here is that the decryption step was unsuccessful but returned bad
- # data rather than raising an error.
- raise DecryptionFailure, "Error decrypting data bag value. Most likely the provided key is incorrect"
- end
-
- def encrypted_bytes
- Base64.decode64(@encrypted_data["encrypted_data"])
- end
-
- def iv
- Base64.decode64(@encrypted_data["iv"])
- end
-
- def decrypted_data
- @decrypted_data ||= begin
- plaintext = openssl_decryptor.update(encrypted_bytes)
- plaintext << openssl_decryptor.final
- rescue OpenSSL::Cipher::CipherError => e
- raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect"
- end
- end
-
- def openssl_decryptor
- @openssl_decryptor ||= begin
- assert_valid_cipher!
- d = OpenSSL::Cipher::Cipher.new(ALGORITHM)
- d.decrypt
- d.key = Digest::SHA256.digest(key)
- d.iv = iv
- d
- end
- end
-
- def assert_valid_cipher!
- # In the future, chef may support configurable ciphers. For now, only
- # aes-256-cbc is supported.
- requested_cipher = @encrypted_data["cipher"]
- unless requested_cipher == ALGORITHM
- raise UnsupportedCipher,
- "Cipher '#{requested_cipher}' is not supported by this version of Chef. Available ciphers: ['#{ALGORITHM}']"
- end
- end
-
- end
-
- class Version2Decryptor < Version1Decryptor
-
- def decrypted_data
- validate_hmac! unless @decrypted_data
- super
- end
-
- def validate_hmac!
- digest = OpenSSL::Digest::Digest.new("sha256")
- raw_hmac = OpenSSL::HMAC.digest(digest, key, @encrypted_data["encrypted_data"])
-
- if candidate_hmac_matches?(raw_hmac)
- true
- else
- raise DecryptionFailure, "Error decrypting data bag value: invalid hmac. Most likely the provided key is incorrect"
- end
- end
-
- private
-
- def candidate_hmac_matches?(expected_hmac)
- return false unless @encrypted_data["hmac"]
- expected_bytes = expected_hmac.bytes.to_a
- candidate_hmac_bytes = Base64.decode64(@encrypted_data["hmac"]).bytes.to_a
- valid = expected_bytes.size ^ candidate_hmac_bytes.size
- expected_bytes.zip(candidate_hmac_bytes) { |x, y| valid |= x ^ y.to_i }
- valid == 0
- end
- end
-
- class Version0Decryptor
-
- attr_reader :encrypted_data
- attr_reader :key
-
- def initialize(encrypted_data, key)
- @encrypted_data = encrypted_data
- @key = key
- end
-
- def for_decrypted_item
- YAML.load(decrypted_data)
- end
-
- def decrypted_data
- @decrypted_data ||= begin
- plaintext = openssl_decryptor.update(encrypted_bytes)
- plaintext << openssl_decryptor.final
- rescue OpenSSL::Cipher::CipherError => e
- raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect"
- end
- end
-
- def encrypted_bytes
- Base64.decode64(@encrypted_data)
- end
-
- def openssl_decryptor
- @openssl_decryptor ||= begin
- d = OpenSSL::Cipher::Cipher.new(ALGORITHM)
- d.decrypt
- d.pkcs5_keyivgen(key)
- d
- end
- end
- end
- end
-
def initialize(enc_hash, secret)
@enc_hash = enc_hash
@secret = secret
@@ -390,6 +90,9 @@ class Chef::EncryptedDataBagItem
def self.load_secret(path=nil)
path ||= Chef::Config[:encrypted_data_bag_secret]
+ if !path
+ raise ArgumentError, "No secret specified to load_secret and no secret found at #{Chef::Config.platform_specific_path('/etc/chef/encrypted_data_bag_secret')}"
+ end
secret = case path
when /^\w+:\/\//
# We have a remote key
diff --git a/lib/chef/encrypted_data_bag_item/decryption_failure.rb b/lib/chef/encrypted_data_bag_item/decryption_failure.rb
new file mode 100644
index 0000000000..47d263f197
--- /dev/null
+++ b/lib/chef/encrypted_data_bag_item/decryption_failure.rb
@@ -0,0 +1,22 @@
+#
+# Author:: Seth Falcon (<seth@opscode.com>)
+# Copyright:: Copyright 2010-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.
+#
+
+class Chef::EncryptedDataBagItem
+ class DecryptionFailure < StandardError
+ end
+end
diff --git a/lib/chef/encrypted_data_bag_item/decryptor.rb b/lib/chef/encrypted_data_bag_item/decryptor.rb
new file mode 100644
index 0000000000..9ee38a12c4
--- /dev/null
+++ b/lib/chef/encrypted_data_bag_item/decryptor.rb
@@ -0,0 +1,201 @@
+#
+# Author:: Seth Falcon (<seth@opscode.com>)
+# Copyright:: Copyright 2010-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 'yaml'
+require 'yajl'
+require 'openssl'
+require 'base64'
+require 'digest/sha2'
+require 'chef/encrypted_data_bag_item'
+require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format'
+require 'chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format'
+require 'chef/encrypted_data_bag_item/decryption_failure'
+require 'chef/encrypted_data_bag_item/unsupported_cipher'
+
+class Chef::EncryptedDataBagItem
+
+ #=== Decryptor
+ # For backwards compatibility, Chef implements decryption/deserialization for
+ # older encrypted data bag item formats in addition to the current version.
+ # Each decryption/deserialization strategy is implemented as a class in this
+ # namespace. For convenience the factory method +Decryptor.for()+ can be used
+ # to create an instance of the appropriate strategy for the given encrypted
+ # data bag value.
+ module Decryptor
+
+ # Detects the encrypted data bag item format version and instantiates a
+ # decryptor object for that version. Call #for_decrypted_item on the
+ # resulting object to decrypt and deserialize it.
+ def self.for(encrypted_value, key)
+ format_version = format_version_of(encrypted_value)
+ assert_format_version_acceptable!(format_version)
+ case format_version
+ when 2
+ Version2Decryptor.new(encrypted_value, key)
+ when 1
+ Version1Decryptor.new(encrypted_value, key)
+ when 0
+ Version0Decryptor.new(encrypted_value, key)
+ else
+ raise UnsupportedEncryptedDataBagItemFormat,
+ "This version of chef does not support encrypted data bag item format version '#{format_version}'"
+ end
+ end
+
+ def self.format_version_of(encrypted_value)
+ if encrypted_value.respond_to?(:key?)
+ encrypted_value["version"]
+ else
+ 0
+ end
+ end
+
+ def self.assert_format_version_acceptable!(format_version)
+ unless format_version.kind_of?(Integer) and format_version >= Chef::Config[:data_bag_decrypt_minimum_version]
+ raise UnacceptableEncryptedDataBagItemFormat,
+ "The encrypted data bag item has format version `#{format_version}', " +
+ "but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'"
+ end
+ end
+
+ class Version0Decryptor
+
+ attr_reader :encrypted_data
+ attr_reader :key
+
+ def initialize(encrypted_data, key)
+ @encrypted_data = encrypted_data
+ @key = key
+ end
+
+ def for_decrypted_item
+ YAML.load(decrypted_data)
+ end
+
+ def decrypted_data
+ @decrypted_data ||= begin
+ plaintext = openssl_decryptor.update(encrypted_bytes)
+ plaintext << openssl_decryptor.final
+ rescue OpenSSL::Cipher::CipherError => e
+ raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect"
+ end
+ end
+
+ def encrypted_bytes
+ Base64.decode64(@encrypted_data)
+ end
+
+ def openssl_decryptor
+ @openssl_decryptor ||= begin
+ d = OpenSSL::Cipher::Cipher.new(ALGORITHM)
+ d.decrypt
+ d.pkcs5_keyivgen(key)
+ d
+ end
+ end
+ end
+
+ class Version1Decryptor
+
+ attr_reader :encrypted_data
+ attr_reader :key
+
+ def initialize(encrypted_data, key)
+ @encrypted_data = encrypted_data
+ @key = key
+ end
+
+ def for_decrypted_item
+ Yajl::Parser.parse(decrypted_data)["json_wrapper"]
+ rescue Yajl::ParseError
+ # convert to a DecryptionFailure error because the most likely scenario
+ # here is that the decryption step was unsuccessful but returned bad
+ # data rather than raising an error.
+ raise DecryptionFailure, "Error decrypting data bag value. Most likely the provided key is incorrect"
+ end
+
+ def encrypted_bytes
+ Base64.decode64(@encrypted_data["encrypted_data"])
+ end
+
+ def iv
+ Base64.decode64(@encrypted_data["iv"])
+ end
+
+ def decrypted_data
+ @decrypted_data ||= begin
+ plaintext = openssl_decryptor.update(encrypted_bytes)
+ plaintext << openssl_decryptor.final
+ rescue OpenSSL::Cipher::CipherError => e
+ raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect"
+ end
+ end
+
+ def openssl_decryptor
+ @openssl_decryptor ||= begin
+ assert_valid_cipher!
+ d = OpenSSL::Cipher::Cipher.new(ALGORITHM)
+ d.decrypt
+ d.key = Digest::SHA256.digest(key)
+ d.iv = iv
+ d
+ end
+ end
+
+ def assert_valid_cipher!
+ # In the future, chef may support configurable ciphers. For now, only
+ # aes-256-cbc is supported.
+ requested_cipher = @encrypted_data["cipher"]
+ unless requested_cipher == ALGORITHM
+ raise UnsupportedCipher,
+ "Cipher '#{requested_cipher}' is not supported by this version of Chef. Available ciphers: ['#{ALGORITHM}']"
+ end
+ end
+ end
+
+ class Version2Decryptor < Version1Decryptor
+
+ def decrypted_data
+ validate_hmac! unless @decrypted_data
+ super
+ end
+
+ def validate_hmac!
+ digest = OpenSSL::Digest::Digest.new("sha256")
+ raw_hmac = OpenSSL::HMAC.digest(digest, key, @encrypted_data["encrypted_data"])
+
+ if candidate_hmac_matches?(raw_hmac)
+ true
+ else
+ raise DecryptionFailure, "Error decrypting data bag value: invalid hmac. Most likely the provided key is incorrect"
+ end
+ end
+
+ private
+
+ def candidate_hmac_matches?(expected_hmac)
+ return false unless @encrypted_data["hmac"]
+ expected_bytes = expected_hmac.bytes.to_a
+ candidate_hmac_bytes = Base64.decode64(@encrypted_data["hmac"]).bytes.to_a
+ valid = expected_bytes.size ^ candidate_hmac_bytes.size
+ expected_bytes.zip(candidate_hmac_bytes) { |x, y| valid |= x ^ y.to_i }
+ valid == 0
+ end
+ end
+ end
+end
diff --git a/lib/chef/encrypted_data_bag_item/encryptor.rb b/lib/chef/encrypted_data_bag_item/encryptor.rb
new file mode 100644
index 0000000000..f99c913c62
--- /dev/null
+++ b/lib/chef/encrypted_data_bag_item/encryptor.rb
@@ -0,0 +1,142 @@
+#
+# Author:: Seth Falcon (<seth@opscode.com>)
+# Copyright:: Copyright 2010-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 'base64'
+require 'digest/sha2'
+require 'openssl'
+require 'yajl'
+require 'chef/encrypted_data_bag_item'
+require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format'
+
+class Chef::EncryptedDataBagItem
+
+ # Implementation class for converting plaintext data bag item values to an
+ # encrypted value, including any necessary wrappers and metadata.
+ module Encryptor
+
+ # "factory" method that creates an encryptor object with the proper class
+ # for the desired encrypted data bag format version.
+ #
+ # +Chef::Config[:data_bag_encrypt_version]+ determines which version is used.
+ def self.new(value, secret, iv=nil)
+ format_version = Chef::Config[:data_bag_encrypt_version]
+ case format_version
+ when 1
+ Version1Encryptor.new(value, secret, iv)
+ when 2
+ Version2Encryptor.new(value, secret, iv)
+ else
+ raise UnsupportedEncryptedDataBagItemFormat,
+ "Invalid encrypted data bag format version `#{format_version}'. Supported versions are '1', '2'"
+ end
+ end
+
+ class Version1Encryptor
+ attr_reader :key
+ attr_reader :plaintext_data
+
+ # Create a new Encryptor for +data+, which will be encrypted with the given
+ # +key+.
+ #
+ # === Arguments:
+ # * data: An object of any type that can be serialized to json
+ # * key: A String representing the desired passphrase
+ # * iv: The optional +iv+ parameter is intended for testing use only. When
+ # *not* supplied, Encryptor will use OpenSSL to generate a secure random
+ # IV, which is what you want.
+ def initialize(plaintext_data, key, iv=nil)
+ @plaintext_data = plaintext_data
+ @key = key
+ @iv = iv && Base64.decode64(iv)
+ end
+
+ # Returns a wrapped and encrypted version of +plaintext_data+ suitable for
+ # using as the value in an encrypted data bag item.
+ def for_encrypted_item
+ {
+ "encrypted_data" => encrypted_data,
+ "iv" => Base64.encode64(iv),
+ "version" => 1,
+ "cipher" => ALGORITHM
+ }
+ end
+
+ # Generates or returns the IV.
+ def iv
+ # Generated IV comes from OpenSSL::Cipher::Cipher#random_iv
+ # This gets generated when +openssl_encryptor+ gets created.
+ openssl_encryptor if @iv.nil?
+ @iv
+ end
+
+ # Generates (and memoizes) an OpenSSL::Cipher::Cipher object and configures
+ # it for the specified iv and encryption key.
+ def openssl_encryptor
+ @openssl_encryptor ||= begin
+ encryptor = OpenSSL::Cipher::Cipher.new(ALGORITHM)
+ encryptor.encrypt
+ @iv ||= encryptor.random_iv
+ encryptor.iv = @iv
+ encryptor.key = Digest::SHA256.digest(key)
+ encryptor
+ end
+ end
+
+ # Encrypts and Base64 encodes +serialized_data+
+ def encrypted_data
+ @encrypted_data ||= begin
+ enc_data = openssl_encryptor.update(serialized_data)
+ enc_data << openssl_encryptor.final
+ Base64.encode64(enc_data)
+ end
+ end
+
+ # Wraps the data in a single key Hash (JSON Object) and converts to JSON.
+ # The wrapper is required because we accept values (such as Integers or
+ # Strings) that do not produce valid JSON when serialized without the
+ # wrapper.
+ def serialized_data
+ Yajl::Encoder.encode(:json_wrapper => plaintext_data)
+ end
+ end
+
+ class Version2Encryptor < Version1Encryptor
+
+ # Returns a wrapped and encrypted version of +plaintext_data+ suitable for
+ # using as the value in an encrypted data bag item.
+ def for_encrypted_item
+ {
+ "encrypted_data" => encrypted_data,
+ "hmac" => hmac,
+ "iv" => Base64.encode64(iv),
+ "version" => 2,
+ "cipher" => ALGORITHM
+ }
+ end
+
+ # Generates an HMAC-SHA2-256 of the encrypted data (encrypt-then-mac)
+ def hmac
+ @hmac ||= begin
+ digest = OpenSSL::Digest::Digest.new("sha256")
+ raw_hmac = OpenSSL::HMAC.digest(digest, key, encrypted_data)
+ Base64.encode64(raw_hmac)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format.rb b/lib/chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format.rb
new file mode 100644
index 0000000000..2f3b07c7f3
--- /dev/null
+++ b/lib/chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format.rb
@@ -0,0 +1,22 @@
+#
+# Author:: Seth Falcon (<seth@opscode.com>)
+# Copyright:: Copyright 2010-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.
+#
+
+class Chef::EncryptedDataBagItem
+ class UnacceptableEncryptedDataBagItemFormat < StandardError
+ end
+end
diff --git a/lib/chef/encrypted_data_bag_item/unsupported_cipher.rb b/lib/chef/encrypted_data_bag_item/unsupported_cipher.rb
new file mode 100644
index 0000000000..1df5cd5efd
--- /dev/null
+++ b/lib/chef/encrypted_data_bag_item/unsupported_cipher.rb
@@ -0,0 +1,22 @@
+#
+# Author:: Seth Falcon (<seth@opscode.com>)
+# Copyright:: Copyright 2010-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.
+#
+
+class Chef::EncryptedDataBagItem
+ class UnsupportedCipher < StandardError
+ end
+end
diff --git a/lib/chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format.rb b/lib/chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format.rb
new file mode 100644
index 0000000000..e7cf087307
--- /dev/null
+++ b/lib/chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format.rb
@@ -0,0 +1,22 @@
+#
+# Author:: Seth Falcon (<seth@opscode.com>)
+# Copyright:: Copyright 2010-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.
+#
+
+class Chef::EncryptedDataBagItem
+ class UnsupportedEncryptedDataBagItemFormat < StandardError
+ end
+end
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/exceptions.rb b/lib/chef/exceptions.rb
index 99054eb254..3877e3d17a 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -77,8 +77,13 @@ class Chef
class DsclCommandFailed < RuntimeError; end
class UserIDNotFound < ArgumentError; end
class GroupIDNotFound < ArgumentError; end
+ class ConflictingMembersInGroup < ArgumentError; end
class InvalidResourceReference < RuntimeError; end
class ResourceNotFound < RuntimeError; end
+
+ # Can't find a Resource of this type that is valid on this platform.
+ class NoSuchResourceType < NameError; end
+
class InvalidResourceSpecification < ArgumentError; end
class SolrConnectionError < RuntimeError; end
class IllegalChecksumRevert < RuntimeError; end
@@ -296,5 +301,18 @@ class Chef
# non-GET and non-HEAD request will thus raise an InvalidRedirect.
class InvalidRedirect < StandardError; end
+ # Raised when the content length of a download does not match the content
+ # length declared in the http response.
+ class ContentLengthMismatch < RuntimeError
+ def initialize(response_length, content_length)
+ super "Response body length #{response_length} does not match HTTP Content-Length header #{content_length}."
+ end
+ end
+
+ class UnsupportedPlatform < RuntimeError
+ def initialize(platform)
+ super "This functionality is not supported on platform #{platform}."
+ end
+ end
end
end
diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb
index 300311819f..a0b49f4ab5 100644
--- a/lib/chef/formatters/doc.rb
+++ b/lib/chef/formatters/doc.rb
@@ -8,31 +8,46 @@ class Chef
# "specdoc"
class Doc < Formatters::Base
+ attr_reader :start_time, :end_time
cli_name(:doc)
+
def initialize(out, err)
super
@updated_resources = 0
+ @up_to_date_resources = 0
+ @start_time = Time.now
+ @end_time = @start_time
+ end
+
+ def elapsed_time
+ end_time - start_time
end
def run_start(version)
puts "Starting Chef Client, version #{version}"
end
+ def total_resources
+ @up_to_date_resources + @updated_resources
+ end
+
def run_completed(node)
+ @end_time = Time.now
if Chef::Config[:why_run]
- puts "Chef Client finished, #{@updated_resources} resources would have been updated"
+ puts "Chef Client finished, #{@updated_resources}/#{total_resources} resources would have been updated"
else
- puts "Chef Client finished, #{@updated_resources} resources updated"
+ puts "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated in #{elapsed_time} seconds"
end
end
def run_failed(exception)
+ @end_time = Time.now
if Chef::Config[:why_run]
puts "Chef Client failed. #{@updated_resources} resources would have been updated"
else
- puts "Chef Client failed. #{@updated_resources} resources updated"
+ puts "Chef Client failed. #{@updated_resources} resources updated in #{elapsed_time} seconds"
end
end
@@ -171,6 +186,7 @@ class Chef
# Called when a resource has no converge actions, e.g., it was already correct.
def resource_up_to_date(resource, action)
+ @up_to_date_resources+= 1
puts " (up to date)"
end
@@ -188,13 +204,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
@@ -214,9 +230,24 @@ class Chef
@output.color("\n * Whyrun not supported for #{resource}, bypassing load.", :yellow)
end
+ # Called before handlers run
+ def handlers_start(handler_count)
+ puts "\nRunning handlers:"
+ end
+
+ # Called after an individual handler has run
+ def handler_executed(handler)
+ puts " - #{handler.class.name}"
+ end
+
+ # Called after all handlers have executed
+ def handlers_completed
+ puts "Running handlers complete\n"
+ end
+
# 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..1e4e258906 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.
@@ -52,7 +52,8 @@ chef_server_url "#{server_url}"
node_name "#{username}"
client_key "#{api_key}"
-If these settings are correct, your client_key may be invalid.
+If these settings are correct, your client_key may be invalid, or
+you may have a chef user with the same client name as this node.
E
end
end
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..78c47735d2
--- /dev/null
+++ b/lib/chef/http.rb
@@ -0,0 +1,396 @@
+#--
+# 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)
+ end
+ apply_stream_complete_middleware(http_response, rest_request, return_value)
+ end
+
+ return nil if response.kind_of?(Net::HTTPRedirection)
+ unless response.kind_of?(Net::HTTPSuccess)
+ response.error!
+ end
+
+ if block_given?
+ begin
+ yield tempfile
+ ensure
+ tempfile && tempfile.close!
+ end
+ 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 apply_stream_complete_middleware(response, rest_request, return_value)
+ middlewares.reverse.inject([response, rest_request, return_value]) do |res_data, middleware|
+ middleware.handle_stream_complete(*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..4255f18cbd
--- /dev/null
+++ b/lib/chef/http/authenticator.rb
@@ -0,0 +1,93 @@
+#--
+# 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 handle_stream_complete(http_response, rest_request, return_value)
+ [http_response, rest_request, return_value]
+ 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..05ac662b7c
--- /dev/null
+++ b/lib/chef/http/basic_client.rb
@@ -0,0 +1,118 @@
+#--
+# 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.hostname
+ 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}")
+ Chef::Log.debug("---- HTTP Request Header Data: ----")
+ base_headers.each do |name, value|
+ Chef::Log.debug("#{name}: #{value}")
+ end
+ 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..e9cb7aa4f7
--- /dev/null
+++ b/lib/chef/http/cookie_manager.rb
@@ -0,0 +1,59 @@
+#--
+# 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
+
+ def handle_stream_complete(http_response, rest_request, return_value)
+ [http_response, rest_request, return_value]
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/http/decompressor.rb b/lib/chef/http/decompressor.rb
new file mode 100644
index 0000000000..78af47798c
--- /dev/null
+++ b/lib/chef/http/decompressor.rb
@@ -0,0 +1,141 @@
+#--
+# 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 handle_stream_complete(http_response, rest_request, return_value)
+ [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..90b805e73f 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"
@@ -59,6 +58,8 @@ class Chef
SLASH = "/".freeze
+ HOST_LOWER = "host".freeze
+
def self.user_agent=(ua)
@user_agent = ua
end
@@ -72,13 +73,15 @@ 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
def host
+ @url.hostname
+ end
+
+ def uri_safe_host
@url.host
end
@@ -94,10 +97,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 +111,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 +133,13 @@ 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['Host'] = "#{uri_safe_host}:#{port}" unless @headers.keys.any? {|k| k.downcase.to_s == HOST_LOWER }
+ @headers
end
@@ -225,6 +169,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..1e4e736030
--- /dev/null
+++ b/lib/chef/http/json_input.rb
@@ -0,0 +1,57 @@
+#--
+# 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
+
+ def handle_stream_complete(http_response, rest_request, return_value)
+ [http_response, rest_request, return_value]
+ 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..ae164c6aed
--- /dev/null
+++ b/lib/chef/http/json_output.rb
@@ -0,0 +1,73 @@
+#--
+# 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.debug("Expected JSON response, but got content-type '#{http_response['content-type']}'")
+ return [http_response, rest_request, http_response.body.to_s]
+ end
+ end
+
+ def handle_stream_complete(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_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/remote_request_id.rb b/lib/chef/http/remote_request_id.rb
new file mode 100644
index 0000000000..6bec5dba4f
--- /dev/null
+++ b/lib/chef/http/remote_request_id.rb
@@ -0,0 +1,46 @@
+# Author:: Prajakta Purohit (<prajakta@opscode.com>)
+# Copyright:: Copyright (c) 2009, 2010, 2013, 2014 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/request_id'
+
+class Chef
+ class HTTP
+ class RemoteRequestID
+
+ def initialize(opts={})
+ end
+
+ def handle_request(method, url, headers={}, data=false)
+ headers.merge!({'X-REMOTE-REQUEST-ID' => Chef::RequestID.instance.request_id})
+ [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 handle_stream_complete(http_response, rest_request, return_value)
+ [http_response, rest_request, return_value]
+ 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..f2a9c5b845
--- /dev/null
+++ b/lib/chef/http/ssl_policies.rb
@@ -0,0 +1,129 @@
+#--
+# 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))
+ add_trusted_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
+
+ private
+
+ def add_trusted_cert(cert)
+ http_client.cert_store.add_cert(cert)
+ rescue OpenSSL::X509::StoreError => e
+ raise e unless e.message == 'cert already in hash table'
+ 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/http/validate_content_length.rb b/lib/chef/http/validate_content_length.rb
new file mode 100644
index 0000000000..49f1738d42
--- /dev/null
+++ b/lib/chef/http/validate_content_length.rb
@@ -0,0 +1,94 @@
+#--
+# Author:: Lamont Granquist (<lamont@getchef.com>)
+# Copyright:: Copyright (c) 2013 Chef Software, 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 'pp'
+require 'chef/log'
+
+class Chef
+ class HTTP
+
+ # Middleware that validates the Content-Length header against the downloaded number of bytes.
+ #
+ # This must run before the decompressor middleware, since otherwise we will count the uncompressed
+ # streamed bytes, rather than the on-the-wire compressed bytes.
+ class ValidateContentLength
+
+ class ContentLengthCounter
+ attr_accessor :content_length
+
+ def initialize
+ @content_length = 0
+ end
+
+ def handle_chunk(chunk)
+ @content_length += chunk.bytesize
+ chunk
+ end
+ end
+
+ def initialize(opts={})
+ end
+
+ def handle_request(method, url, headers={}, data=false)
+ [method, url, headers, data]
+ end
+
+ def handle_response(http_response, rest_request, return_value)
+ unless http_response['content-length']
+ Chef::Log.debug("HTTP server did not include a Content-Length header in response, cannot identify truncated downloads.")
+ return [http_response, rest_request, return_value]
+ end
+ validate(response_content_length(http_response), http_response.body.bytesize)
+ return [http_response, rest_request, return_value]
+ end
+
+ def handle_stream_complete(http_response, rest_request, return_value)
+ if http_response['content-length'].nil?
+ Chef::Log.debug("HTTP server did not include a Content-Length header in response, cannot idenfity streamed download.")
+ elsif @content_length_counter.nil?
+ Chef::Log.debug("No content-length information collected for the streamed download, cannot identify streamed download.")
+ else
+ validate(response_content_length(http_response), @content_length_counter.content_length)
+ end
+ return [http_response, rest_request, return_value]
+ end
+
+ def stream_response_handler(response)
+ @content_length_counter = ContentLengthCounter.new
+ end
+
+ private
+ def response_content_length(response)
+ if response['content-length'].is_a?(Array)
+ response['content-length'].first.to_i
+ else
+ response['content-length'].to_i
+ end
+ end
+
+ def validate(content_length, response_length)
+ Chef::Log.debug "Content-Length header = #{content_length}"
+ Chef::Log.debug "Response body length = #{response_length}"
+ if response_length != content_length
+ raise Chef::Exceptions::ContentLengthMismatch.new(response_length, content_length)
+ end
+ true
+ end
+ end
+ end
+end
diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb
index 9c48925216..eb2c321cab 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'
@@ -238,7 +239,13 @@ class Chef
end
def self.working_directory
- ENV['PWD'] || Dir.pwd
+ a = if Chef::Platform.windows?
+ ENV['CD']
+ else
+ ENV['PWD']
+ end || Dir.pwd
+
+ a
end
def self.reset_config_path!
@@ -314,7 +321,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 +337,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 +346,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 +390,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 +414,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 +438,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 +481,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..14dccb3892 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; this option is used internally by Opscode",
+ :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/README.md b/lib/chef/knife/bootstrap/README.md
new file mode 100644
index 0000000000..13a0fe7ada
--- /dev/null
+++ b/lib/chef/knife/bootstrap/README.md
@@ -0,0 +1,12 @@
+This directory contains bootstrap templates which can be used with the -d flag
+to 'knife bootstrap' to install Chef in different ways. To simplify installation,
+and reduce the matrix of common installation patterns to support, we have
+standardized on the [Omnibus](https://github.com/opscode/omnibus-ruby) built installation
+packages.
+
+The 'chef-full' template downloads a script which is used to determine the correct
+Omnibus package for this system from the [Omnitruck](https://github.com/opscode/opscode-omnitruck) API. All other templates in this directory are deprecated and will be removed
+in the future.
+
+You can still utilize custom bootstrap templates on your system if your installation
+needs are unique. Additional information can be found on the [docs site](http://docs.opscode.com/knife_bootstrap.html#custom-templates). \ No newline at end of file
diff --git a/lib/chef/knife/bootstrap/chef-full.erb b/lib/chef/knife/bootstrap/chef-full.erb
index 974b522653..24ffca2c69 100644
--- a/lib/chef/knife/bootstrap/chef-full.erb
+++ b/lib/chef/knife/bootstrap/chef-full.erb
@@ -1,5 +1,14 @@
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 test "x$distro" = "xSunOS"; then
+ if test -d "/usr/sfw/bin"; then
+ PATH=/usr/sfw/bin:$PATH
+ export 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..b2bac36081 100644
--- a/lib/chef/knife/client_create.rb
+++ b/lib/chef/knife/client_create.rb
@@ -38,6 +38,11 @@ class Chef
:description => "Create the client as an admin",
:boolean => true
+ option :validator,
+ :long => "--validator",
+ :description => "Create the client as a validator",
+ :boolean => true
+
banner "knife client create CLIENT (options)"
def run
@@ -52,6 +57,7 @@ class Chef
client = Chef::ApiClient.new
client.name(@client_name)
client.admin(config[:admin])
+ client.validator(config[:validator])
output = edit_data(client)
@@ -61,7 +67,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/client_delete.rb b/lib/chef/knife/client_delete.rb
index 6a6fae7ea0..56814de1b2 100644
--- a/lib/chef/knife/client_delete.rb
+++ b/lib/chef/knife/client_delete.rb
@@ -27,6 +27,11 @@ class Chef
require 'chef/json_compat'
end
+ option :force,
+ :short => "-f",
+ :long => "--force",
+ :description => "Force deletion of client if it's a validator"
+
banner "knife client delete CLIENT (options)"
def run
@@ -38,7 +43,16 @@ class Chef
exit 1
end
- delete_object(Chef::ApiClient, @client_name)
+ delete_object(Chef::ApiClient, @client_name, 'client') {
+ object = Chef::ApiClient.load(@client_name)
+ if object.validator
+ unless config[:force]
+ ui.fatal("You must specify --force to delete the validator client #{@client_name}")
+ exit 2
+ end
+ end
+ object.destroy
+ }
end
end
diff --git a/lib/chef/knife/configure.rb b/lib/chef/knife/configure.rb
index 8e725952b4..6af3d4ea1d 100644
--- a/lib/chef/knife/configure.rb
+++ b/lib/chef/knife/configure.rb
@@ -35,29 +35,29 @@ class Chef
option :repository,
:short => "-r REPO",
:long => "--repository REPO",
- :description => "The path to your chef-repo"
+ :description => "The path to the chef-repo"
option :initial,
:short => "-i",
:long => "--initial",
:boolean => true,
- :description => "Create an initial API User"
+ :description => "Use to create a API client, typically an administrator client on a freshly-installed server"
option :admin_client_name,
:long => "--admin-client-name NAME",
- :description => "The existing admin clientname (usually admin)"
+ :description => "The name of the client, typically the name of the admin client"
option :admin_client_key,
:long => "--admin-client-key PATH",
- :description => "The path to the admin client's private key (usually a file named admin.pem)"
+ :description => "The path to the private key used by the client, typically a file named admin.pem"
option :validation_client_name,
:long => "--validation-client-name NAME",
- :description => "The validation clientname (usually chef-validator)"
+ :description => "The name of the validation client, typically a client named chef-validator"
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 path to the validation key used by the client, typically 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..f4183a7245 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
------------
@@ -290,7 +290,7 @@ e.g.
Attributes
----------
-TODO: List you cookbook attributes here.
+TODO: List your cookbook attributes here.
e.g.
#### #{cookbook_name}::default
@@ -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.
@@ -358,7 +358,7 @@ Requirements
toaster #{cookbook_name} needs toaster to brown your bagel.
Attributes
- TODO: List you cookbook attributes here.
+ TODO: List your cookbook attributes here.
#{cookbook_name}
Key Type Description Default
@@ -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_share.rb b/lib/chef/knife/cookbook_site_share.rb
index 21645d4a08..d3143a533a 100644
--- a/lib/chef/knife/cookbook_site_share.rb
+++ b/lib/chef/knife/cookbook_site_share.rb
@@ -58,7 +58,7 @@ class Chef
ui.info("Making tarball #{cookbook_name}.tgz")
Chef::Mixin::Command.run_command(:command => "tar -czf #{cookbook_name}.tgz #{cookbook_name}", :cwd => tmp_cookbook_dir)
rescue => e
- ui.error("Error making tarball #{cookbook_name}.tgz: #{e.message}. Set log level to debug (-l debug) for more information.")
+ ui.error("Error making tarball #{cookbook_name}.tgz: #{e.message}. Increase log verbosity (-VV) for more information.")
Chef::Log.debug("\n#{e.backtrace.join("\n")}")
exit(1)
end
@@ -69,7 +69,7 @@ class Chef
Chef::Log.debug("Removing local staging directory at #{tmp_cookbook_dir}")
FileUtils.rm_rf tmp_cookbook_dir
rescue => e
- ui.error("Error uploading cookbook #{cookbook_name} to the Opscode Cookbook Site: #{e.message}. Set log level to debug (-l debug) for more information.")
+ ui.error("Error uploading cookbook #{cookbook_name} to the Opscode Cookbook Site: #{e.message}. Increase log verbosity (-VV) for more information.")
Chef::Log.debug("\n#{e.backtrace.join("\n")}")
exit(1)
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/cookbook_upload.rb b/lib/chef/knife/cookbook_upload.rb
index d4a66e6925..a882cd7109 100644
--- a/lib/chef/knife/cookbook_upload.rb
+++ b/lib/chef/knife/cookbook_upload.rb
@@ -57,6 +57,12 @@ class Chef
:boolean => true,
:description => "Update cookbook versions even if they have been frozen"
+ option :concurrency,
+ :long => '--concurrency NUMBER_OF_THREADS',
+ :description => "How many concurrent threads will be used",
+ :default => 10,
+ :proc => lambda { |o| o.to_i }
+
option :environment,
:short => '-E',
:long => '--environment ENVIRONMENT',
@@ -228,7 +234,7 @@ WARNING
check_for_broken_links!(cb)
check_for_dependencies!(cb)
end
- Chef::CookbookUploader.new(cookbooks, config[:cookbook_path], :force => config[:force]).upload_cookbooks
+ Chef::CookbookUploader.new(cookbooks, config[:cookbook_path], :force => config[:force], :concurrency => config[:concurrency]).upload_cookbooks
rescue Chef::Exceptions::CookbookFrozen => e
ui.error e
raise
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_editor.rb b/lib/chef/knife/core/node_editor.rb
index 7707743ce5..073492197c 100644
--- a/lib/chef/knife/core/node_editor.rb
+++ b/lib/chef/knife/core/node_editor.rb
@@ -18,6 +18,7 @@
require 'chef/json_compat'
require 'chef/node'
+require 'tempfile'
class Chef
class Knife
@@ -35,11 +36,24 @@ class Chef
abort "You specified the --disable_editing option, nothing to edit" if config[:disable_editing]
assert_editor_set!
- updated_node_data = edit_data(view)
+ updated_node_data = @ui.edit_data(view)
apply_updates(updated_node_data)
@updated_node
end
+ def updated?
+ pristine_copy = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(node), :create_additions => false)
+ updated_copy = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@updated_node), :create_additions => false)
+ unless pristine_copy == updated_copy
+ updated_properties = %w{name normal chef_environment run_list default override automatic}.reject do |key|
+ pristine_copy[key] == updated_copy[key]
+ end
+ end
+ ( pristine_copy != updated_copy ) && updated_properties
+ end
+
+ private
+
def view
result = {}
result["name"] = node.name
@@ -52,12 +66,7 @@ class Chef
result["override"] = node.override_attrs
result["automatic"] = node.automatic_attrs
end
- Chef::JSONCompat.to_json_pretty(result)
- end
-
- def edit_data(text)
- edited_data = tempfile_for(text) {|filename| system("#{config[:editor]} #{filename}")}
- Chef::JSONCompat.from_json(edited_data)
+ result
end
def apply_updates(updated_data)
@@ -84,19 +93,6 @@ class Chef
end
end
- def updated?
- pristine_copy = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(node), :create_additions => false)
- updated_copy = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@updated_node), :create_additions => false)
- unless pristine_copy == updated_copy
- updated_properties = %w{name normal chef_environment run_list default override automatic}.reject do |key|
- pristine_copy[key] == updated_copy[key]
- end
- end
- ( pristine_copy != updated_copy ) && updated_properties
- end
-
- private
-
def abort(message)
ui.error(message)
exit 1
@@ -108,22 +104,6 @@ class Chef
end
end
- def tempfile_for(data)
- # TODO: include useful info like the node name in the temp file
- # name
- basename = "knife-edit-" << rand(1_000_000_000_000_000).to_s.rjust(15, '0') << '.json'
- filename = File.join(Dir.tmpdir, basename)
- File.open(filename, "w+") do |f|
- f.sync = true
- f.puts data
- end
-
- yield filename
-
- IO.read(filename)
- ensure
- File.unlink(filename)
- end
end
end
end
diff --git a/lib/chef/knife/core/subcommand_loader.rb b/lib/chef/knife/core/subcommand_loader.rb
index 2475717441..0489c726b3 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.
@@ -60,9 +60,13 @@ class Chef
# subcommand loader has been modified to load the plugins by using Kernel.load
# with the absolute path.
def gem_and_builtin_subcommands
- # search all gems for chef/knife/*.rb
- require 'rubygems'
- find_subcommands_via_rubygems
+ if have_plugin_manifest?
+ find_subcommands_via_manifest
+ else
+ # search all gems for chef/knife/*.rb
+ require 'rubygems'
+ find_subcommands_via_rubygems
+ end
rescue LoadError
find_subcommands_via_dirglob
end
@@ -71,6 +75,36 @@ class Chef
@subcommand_files ||= (gem_and_builtin_subcommands.values + site_subcommands).flatten.uniq
end
+ # If the user has created a ~/.chef/plugin_manifest.json file, we'll use
+ # that instead of inspecting the on-system gems to find the plugins. The
+ # file format is expected to look like:
+ #
+ # { "plugins": {
+ # "knife-ec2": {
+ # "paths": [
+ # "/home/alice/.rubymanagerthing/gems/knife-ec2-x.y.z/lib/chef/knife/ec2_server_create.rb",
+ # "/home/alice/.rubymanagerthing/gems/knife-ec2-x.y.z/lib/chef/knife/ec2_server_delete.rb"
+ # ]
+ # }
+ # }
+ # }
+ #
+ # Extraneous content in this file is ignored. This intentional so that we
+ # can adapt the file format for potential behavior changes to knife in
+ # the future.
+ def find_subcommands_via_manifest
+ # Format of subcommand_files is "relative_path" (something you can
+ # Kernel.require()) => full_path. The relative path isn't used
+ # currently, so we just map full_path => full_path.
+ subcommand_files = {}
+ plugin_manifest["plugins"].each do |plugin_name, plugin_manifest|
+ plugin_manifest["paths"].each do |cmd_path|
+ subcommand_files[cmd_path] = cmd_path
+ end
+ end
+ subcommand_files.merge(find_subcommands_via_dirglob)
+ end
+
def find_subcommands_via_dirglob
# The "require paths" of the core knife subcommands bundled with chef
files = Dir[File.expand_path('../../../knife/*.rb', __FILE__)]
@@ -93,6 +127,18 @@ class Chef
subcommand_files.merge(find_subcommands_via_dirglob)
end
+ def have_plugin_manifest?
+ ENV["HOME"] && File.exist?(plugin_manifest_path)
+ end
+
+ def plugin_manifest
+ Chef::JSONCompat.from_json(File.read(plugin_manifest_path))
+ end
+
+ def plugin_manifest_path
+ File.join(ENV['HOME'], '.chef', 'plugin_manifest.json')
+ end
+
private
def find_files_latest_gems(glob, check_load_path=true)
@@ -112,7 +158,7 @@ class Chef
check_spec_for_glob(spec, glob)
end
end.flatten
-
+
files.concat gem_files
files.uniq! if check_load_path
@@ -121,9 +167,9 @@ class Chef
def latest_gem_specs
@latest_gem_specs ||= if Gem::Specification.respond_to? :latest_specs
- Gem::Specification.latest_specs
+ Gem::Specification.latest_specs(true) # find prerelease gems
else
- Gem.source_index.latest_specs
+ Gem.source_index.latest_specs(true)
end
end
@@ -133,9 +179,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..dfa8c11644 100644
--- a/lib/chef/knife/core/ui.rb
+++ b/lib/chef/knife/core/ui.rb
@@ -21,6 +21,7 @@
require 'forwardable'
require 'chef/platform/query_helpers'
require 'chef/knife/core/generic_presenter'
+require 'tempfile'
class Chef
class Knife
@@ -165,19 +166,14 @@ class Chef
output = Chef::JSONCompat.to_json_pretty(data)
if (!config[:disable_editing])
- filename = "knife-edit-"
- 0.upto(20) { filename += rand(9).to_s }
- filename << ".js"
- filename = File.join(Dir.tmpdir, filename)
- tf = File.open(filename, "w")
- tf.sync = true
- tf.puts output
- tf.close
- raise "Please set EDITOR environment variable" unless system("#{config[:editor]} #{tf.path}")
- tf = File.open(filename, "r")
- output = tf.gets(nil)
- tf.close
- File.unlink(filename)
+ Tempfile.open([ 'knife-edit-', '.json' ]) do |tf|
+ tf.sync = true
+ tf.puts output
+ tf.close
+ raise "Please set EDITOR environment variable" unless system("#{config[:editor]} #{tf.path}")
+
+ output = IO.read(tf.path)
+ end
end
parse_output ? Chef::JSONCompat.from_json(output) : output
diff --git a/lib/chef/knife/data_bag_create.rb b/lib/chef/knife/data_bag_create.rb
index e644ab78d3..bc49c68448 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]
@@ -65,6 +67,13 @@ class Chef
exit 1
end
+ begin
+ Chef::DataBag.validate_name!(@data_bag_name)
+ rescue Chef::Exceptions::InvalidDataBagName => e
+ ui.fatal(e.message)
+ exit(1)
+ end
+
# create the data bag
begin
rest.post_rest("data", { "name" => @data_bag_name })
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..7408179ed0 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'
@@ -49,10 +51,8 @@ class Chef
def edit_text(text, extension)
if (!config[:disable_editing])
- file = Tempfile.new([ 'knife-edit-', extension ])
- begin
+ Tempfile.open([ 'knife-edit-', extension ]) do |file|
# Write the text to a temporary file
- file.open
file.write(text)
file.close
@@ -61,12 +61,9 @@ class Chef
raise "Please set EDITOR environment variable"
end
- file.open
- result_text = file.read
- return result_text if result_text != text
+ result_text = IO.read(file.path)
- ensure
- file.close!
+ return result_text if result_text != text
end
end
end
diff --git a/lib/chef/knife/environment_compare.rb b/lib/chef/knife/environment_compare.rb
new file mode 100644
index 0000000000..792ec444ea
--- /dev/null
+++ b/lib/chef/knife/environment_compare.rb
@@ -0,0 +1,127 @@
+#
+# Author:: Sander Botman (<sbotman@schubergphilis.com>)
+# Copyright:: Copyright (c) 2013 Sander Botman.
+# 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'
+
+class Chef
+ class Knife
+ class EnvironmentCompare < Knife
+
+ deps do
+ require 'chef/environment'
+ end
+
+ banner "knife environment compare [ENVIRONMENT..] (options)"
+
+ option :all,
+ :short => "-a",
+ :long => "--all",
+ :description => "Show all cookbooks",
+ :boolean => true
+
+ option :mismatch,
+ :short => "-m",
+ :long => "--mismatch",
+ :description => "Only show mismatching versions",
+ :boolean => true
+
+ def run
+ # Get the commandline environments or all if none are provided.
+ environments = environment_list
+
+ # Get a list of all cookbooks that have constraints and their environment.
+ constraints = constraint_list(environments)
+
+ # Get the total list of cookbooks that have constraints
+ cookbooks = cookbook_list(constraints)
+
+ # If we cannot find any cookbooks, we can stop here.
+ if cookbooks.nil? || cookbooks.empty?
+ ui.error "Cannot find any environment cookbook constraints"
+ exit 1
+ end
+
+ # Get all cookbooks so we can compare them all
+ cookbooks = rest.get_rest("/cookbooks?num_versions=1") if config[:all]
+
+ # display matrix view of in the requested format.
+ if config[:format] == 'summary'
+ matrix = matrix_output(cookbooks, constraints)
+ ui.output(matrix)
+ else
+ ui.output(constraints)
+ end
+ end
+
+ private
+
+ def environment_list
+ environments = []
+ unless @name_args.nil? || @name_args.empty?
+ @name_args.each { |name| environments << name }
+ else
+ environments = Chef::Environment.list
+ end
+ end
+
+ def constraint_list(environments)
+ constraints = {}
+ environments.each do |env,url|
+ # Because you cannot modify the default environment I filter it out here.
+ unless env == "_default"
+ envdata = Chef::Environment.load(env)
+ ver = envdata.cookbook_versions
+ constraints[env] = ver
+ end
+ end
+ constraints
+ end
+
+ def cookbook_list(constraints)
+ result = {}
+ constraints.each { |env, cb| result.merge!(cb) }
+ result
+ end
+
+ def matrix_output(cookbooks, constraints)
+ rows = [ '' ]
+ environments = []
+ constraints.each { |e,v| environments << e.to_s }
+ columns = environments.count + 1
+ environments.each { |env| rows << ui.color(env, :bold) }
+ cookbooks.each do |c,v|
+ total = []
+ environments.each { |n| total << constraints[n][c]}
+ if total.uniq.count == 1
+ next if config[:mismatch]
+ color = :white
+ else
+ color = :yellow
+ end
+ rows << ui.color(c, :bold)
+ environments.each do |e|
+ tag = constraints[e][c] || "latest"
+ rows << ui.color(tag, color)
+ end
+ end
+ ui.list(rows, :uneven_columns_across, columns)
+ end
+
+ end
+ end
+end
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/help_topics.rb b/lib/chef/knife/help_topics.rb
index 8427204fd6..a2aad65f55 100644
--- a/lib/chef/knife/help_topics.rb
+++ b/lib/chef/knife/help_topics.rb
@@ -1,4 +1,4 @@
# Do not edit this file by hand
# This file is autogenerated by the docs:list rake task from the available manpages
-HELP_TOPICS = ["chef-shell", "knife-bootstrap", "knife-client", "knife-configure", "knife-cookbook-site", "knife-cookbook", "knife-data-bag", "knife-environment", "knife-exec", "knife-index", "knife-node", "knife-role", "knife-search", "knife-ssh", "knife-status", "knife-tag", "knife", "shef"]
+HELP_TOPICS = ["chef-shell", "knife-bootstrap", "knife-client", "knife-configure", "knife-cookbook-site", "knife-cookbook", "knife-data-bag", "knife-delete", "knife-deps", "knife-diff", "knife-download", "knife-edit", "knife-environment", "knife-exec", "knife-index-rebuild", "knife-list", "knife-node", "knife-raw", "knife-recipe-list", "knife-role", "knife-search", "knife-show", "knife-ssh", "knife-status", "knife-tag", "knife-upload", "knife-user", "knife-xargs", "knife"]
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..954d46beee 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,19 @@ 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
+ use Chef::HTTP::RemoteRequestID
+ end
+
def run
if name_args.length == 0
show_usage
@@ -45,9 +61,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 ba6b9ae0e1..83c1735b4a 100644
--- a/lib/chef/knife/ssh.rb
+++ b/lib/chef/knife/ssh.rb
@@ -64,10 +64,14 @@ class Chef
:long => "--ssh-user USERNAME",
:description => "The ssh username"
- option :ssh_password,
- :short => "-P PASSWORD",
- :long => "--ssh-password PASSWORD",
- :description => "The ssh password"
+ option :ssh_password_ng,
+ :short => "-P [PASSWORD]",
+ :long => "--ssh-password [PASSWORD]",
+ :description => "The ssh password - will prompt if flag is specified but no password is given",
+ # default to a value that can not be a password (boolean)
+ # so we can effectively test if this parameter was specified
+ # without a vlaue
+ :default => false
option :ssh_port,
:short => "-p PORT",
@@ -147,7 +151,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]
@@ -397,7 +401,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
@@ -432,6 +436,31 @@ class Chef
Chef::Config[:knife][:ssh_user])
end
+ # This is a bit overly complicated because of the way we want knife ssh to work with -P causing a password prompt for
+ # the user, but we have to be conscious that this code gets included in knife bootstrap and knife * server create as
+ # well. We want to change the semantics so that the default is false and 'nil' means -P without an argument on the
+ # command line. But the other utilities expect nil to be the default and we can't prompt in that case. So we effectively
+ # use ssh_password_ng to determine if we're coming from knife ssh or from the other utilities. The other utilties can
+ # also be patched to use ssh_password_ng easily as long they follow the convention that the default is false.
+ def configure_password
+ if config.has_key?(:ssh_password_ng) && config[:ssh_password_ng].nil?
+ # If the parameter is called on the command line with no value
+ # it will set :ssh_password_ng = nil
+ # This is where we want to trigger a prompt for password
+ config[:ssh_password] = get_password
+ else
+ # if ssh_password_ng is false then it has not been set at all, and we may be in knife ec2 and still
+ # using an old config[:ssh_password]. this is backwards compatibility. all knife cloud plugins should
+ # be updated to use ssh_password_ng with a default of false and ssh_password should be retired, (but
+ # we'll still need to use the ssh_password out of knife.rb if we find that).
+ ssh_password = config.has_key?(:ssh_password_ng) ? config[:ssh_password_ng] : config[:ssh_password]
+ # Otherwise, the password has either been specified on the command line,
+ # in knife.rb, or key based auth will be attempted
+ config[:ssh_password] = get_stripped_unfrozen_value(ssh_password ||
+ Chef::Config[:knife][:ssh_password])
+ end
+ end
+
def configure_identity_file
config[:identity_file] = get_stripped_unfrozen_value(config[:identity_file] ||
Chef::Config[:knife][:ssh_identity_file])
@@ -448,6 +477,7 @@ class Chef
configure_attribute
configure_user
+ configure_password
configure_identity_file
configure_gateway
configure_session
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 719151a6b6..c92315e718 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.
@@ -24,6 +24,26 @@ require 'etc'
class Chef
module Mixin
+
+ #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # NOTE:
+ # The popen4 method upon which all the code here is based has a race
+ # condition where it may fail to read all of the data written to stdout and
+ # stderr after the child process exits. The tests for the code here
+ # occasionally fail because of this race condition, so they have been
+ # tagged "volatile".
+ #
+ # This code is considered deprecated, so it should not need to be modified
+ # frequently, if at all. HOWEVER, if you do modify the code here, you must
+ # explicitly enable volatile tests:
+ #
+ # bundle exec rspec spec/unit/mixin/command_spec.rb -t volatile
+ #
+ # In addition, you should make a note that tests need to be run with
+ # volatile tests enabled on any pull request or bug report you submit with
+ # your patch.
+ #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
module Command
extend self
@@ -41,23 +61,23 @@ 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
@@ -77,7 +97,7 @@ class Chef
return false
end
end
-
+
status, stdout, stderr = output_of_command(args[:command], args)
command_output << "STDOUT: #{stdout}"
command_output << "STDERR: #{stderr}"
@@ -89,16 +109,16 @@ class Chef
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
@@ -112,33 +132,32 @@ 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
- unless Array(opts[:returns]).include?(status.exitstatus)
- # if the log level is not debug, through output of command when we fail
- output = ""
- if Chef::Log.level == :debug || opts[:output_on_failure]
- output << "\n---- Begin output of #{opts[:command]} ----\n"
- output << command_output.to_s
- output << "\n---- End output of #{opts[:command]} ----\n"
- end
- raise Chef::Exceptions::Exec, "#{opts[:command]} returned #{status.exitstatus}, expected #{opts[:returns]}#{output}"
- end
+ return if opts[:ignore_failure]
+ opts[:returns] ||= 0
+ return if Array(opts[:returns]).include?(status.exitstatus)
+
+ # if the log level is not debug, through output of command when we fail
+ output = ""
+ if Chef::Log.level == :debug || opts[:output_on_failure]
+ output << "\n---- Begin output of #{opts[:command]} ----\n"
+ output << command_output.to_s
+ output << "\n---- End output of #{opts[:command]} ----\n"
end
+ raise Chef::Exceptions::Exec, "#{opts[:command]} returned #{status.exitstatus}, expected #{opts[:returns]}#{output}"
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..ad3e5803fd 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.
@@ -84,17 +84,17 @@ class Chef
when nil
dest
when Hash
- source.each do |src_key, src_value|
- if dest.kind_of?(Hash)
+ if dest.kind_of?(Hash)
+ source.each do |src_key, src_value|
if dest[src_key]
dest[src_key] = deep_merge!(src_value, dest[src_key])
else # dest[src_key] doesn't exist so we take whatever source has
raise_if_knockout_used!(src_value)
dest[src_key] = src_value
end
- else # dest isn't a hash, so we overwrite it completely
- dest = source
end
+ else # dest isn't a hash, so we overwrite it completely
+ dest = source
end
when Array
if dest.kind_of?(Array)
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/path_sanity.rb b/lib/chef/mixin/path_sanity.rb
index 1d324f54e9..ed857ffd36 100644
--- a/lib/chef/mixin/path_sanity.rb
+++ b/lib/chef/mixin/path_sanity.rb
@@ -22,6 +22,7 @@ class Chef
def enforce_path_sanity(env=ENV)
if Chef::Config[:enforce_path_sanity]
+ env["PATH"] = "" if env["PATH"].nil?
path_separator = Chef::Platform.windows? ? ';' : ':'
existing_paths = env["PATH"].split(path_separator)
# ensure the Ruby and Gem bindirs are included
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/net_http.rb b/lib/chef/monkey_patches/net_http.rb
index ad4ba957f6..083db2216b 100644
--- a/lib/chef/monkey_patches/net_http.rb
+++ b/lib/chef/monkey_patches/net_http.rb
@@ -20,3 +20,37 @@ module Net
include ChefNetHTTPExceptionExtensions
end
end
+
+if Net::HTTP.instance_methods.map {|m| m.to_s}.include?("proxy_uri")
+ begin
+ # Ruby 2.0 changes the way proxy support is implemented in Net::HTTP.
+ # The implementation does not work correctly with IPv6 literals because it
+ # concatenates the address into a URI without adding square brackets for
+ # IPv6 addresses.
+ #
+ # If the bug is present, a call to Net::HTTP#proxy_uri when the host is an
+ # IPv6 address will fail by creating an invalid URI, like so:
+ #
+ # ruby -r'net/http' -e 'Net::HTTP.new("::1", 80).proxy_uri'
+ # /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:214:in `initialize': the scheme http does not accept registry part: ::1:80 (or bad hostname?) (URI::InvalidURIError)
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:84:in `initialize'
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:214:in `new'
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:214:in `parse'
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:747:in `parse'
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:994:in `URI'
+ # from /Users/ddeleo/.rbenv/versions/2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1027:in `proxy_uri'
+ # from -e:1:in `<main>'
+ #
+ # https://bugs.ruby-lang.org/issues/9129
+ Net::HTTP.new("::1", 80).proxy_uri
+ rescue URI::InvalidURIError
+ class Net::HTTP
+
+ def proxy_uri # :nodoc:
+ ipv6_safe_addr = address.to_s.include?(":") ? "[#{address}]" : address
+ @proxy_uri ||= URI("http://#{ipv6_safe_addr}:#{port}").find_proxy
+ end
+
+ end
+ end
+end
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/monkey_patches/uri.rb b/lib/chef/monkey_patches/uri.rb
new file mode 100644
index 0000000000..158285e395
--- /dev/null
+++ b/lib/chef/monkey_patches/uri.rb
@@ -0,0 +1,70 @@
+# Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
+# You can redistribute it and/or modify it under either the terms of the
+# 2-clause BSDL (see the file BSDL), or the conditions below:
+#
+# 1. You may make and give away verbatim copies of the source form of the
+# software without restriction, provided that you duplicate all of the
+# original copyright notices and associated disclaimers.
+#
+# 2. You may modify your copy of the software in any way, provided that
+# you do at least ONE of the following:
+#
+# a) place your modifications in the Public Domain or otherwise
+# make them Freely Available, such as by posting said
+# modifications to Usenet or an equivalent medium, or by allowing
+# the author to include your modifications in the software.
+#
+# b) use the modified software only within your corporation or
+# organization.
+#
+# c) give non-standard binaries non-standard names, with
+# instructions on where to get the original software distribution.
+#
+# d) make other distribution arrangements with the author.
+#
+# 3. You may distribute the software in object code or binary form,
+# provided that you do at least ONE of the following:
+#
+# a) distribute the binaries and library files of the software,
+# together with instructions (in the manual page or equivalent)
+# on where to get the original distribution.
+#
+# b) accompany the distribution with the machine-readable source of
+# the software.
+#
+# c) give non-standard binaries non-standard names, with
+# instructions on where to get the original software distribution.
+#
+# d) make other distribution arrangements with the author.
+#
+# 4. You may modify and include the part of the software into any other
+# software (possibly commercial). But some files in the distribution
+# are not written by the author, so that they are not under these terms.
+#
+# For the list of those files and their copying conditions, see the
+# file LEGAL.
+#
+# 5. The scripts and library files supplied as input to or produced as
+# output from the software do not automatically fall under the
+# copyright of the software, but belong to whomever generated them,
+# and may be sold commercially, and may be aggregated with this
+# software.
+#
+# 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE.
+
+require 'uri'
+
+unless URI::Generic.instance_methods.map {|m| m.to_s}.include?("hostname")
+
+ class URI::Generic
+ # Copied from the MRI source for Ruby 1.9.3
+ # File lib/uri/generic.rb, line 659
+ def hostname
+ v = self.host
+ /\A\[(.*)\]\z/ =~ v ? $1 : v
+ end
+ end
+end
diff --git a/lib/chef/monologger.rb b/lib/chef/monologger.rb
index fed60514d7..464b21bdd3 100644
--- a/lib/chef/monologger.rb
+++ b/lib/chef/monologger.rb
@@ -48,9 +48,9 @@ class MonoLogger < Logger
@dev = log
else
@dev = open_logfile(log)
- @dev.sync = true
@filename = log
end
+ @dev.sync = true
end
def write(message)
@@ -75,7 +75,6 @@ class MonoLogger < Logger
def create_logfile(filename)
logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT))
- logdev.sync = true
add_log_header(logdev)
logdev
end
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 623ca33842..4992ec2430 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -248,6 +248,13 @@ class Chef
run_list.include?(recipe_name) || Array(self[:recipes]).include?(recipe_name)
end
+ # used by include_recipe to add recipes to the expanded run_list to be
+ # saved back to the node and be searchable
+ def loaded_recipe(cookbook, recipe)
+ fully_qualified_recipe = "#{cookbook}::#{recipe}"
+ automatic_attrs[:recipes] << fully_qualified_recipe unless Array(self[:recipes]).include?(fully_qualified_recipe)
+ end
+
# Returns true if this Node expects a given role, false if not.
def role?(role_name)
run_list.include?("role[#{role_name}]")
@@ -309,6 +316,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 : {}
@@ -316,7 +331,7 @@ class Chef
if attrs.key?("recipes") || attrs.key?("run_list")
raise Chef::Exceptions::AmbiguousRunlistSpecification, "please set the node's run list using the 'run_list' attribute only."
end
- Chef::Log.info("Setting the run_list to #{new_run_list.inspect} from JSON")
+ Chef::Log.info("Setting the run_list to #{new_run_list.inspect} from CLI options")
run_list(new_run_list)
end
attrs
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 2911e32284..92a7278d2f 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
}
@@ -323,7 +344,8 @@ class Chef
:group => Chef::Provider::Group::Aix,
:mount => Chef::Provider::Mount::Aix,
:ifconfig => Chef::Provider::Ifconfig::Aix,
- :cron => Chef::Provider::Cron::Aix
+ :cron => Chef::Provider::Cron::Aix,
+ :package => Chef::Provider::Package::Aix
}
},
:default => {
@@ -347,6 +369,7 @@ class Chef
:route => Chef::Provider::Route,
:ifconfig => Chef::Provider::Ifconfig,
:ruby_block => Chef::Provider::RubyBlock,
+ :whyrun_safe_ruby_block => Chef::Provider::WhyrunSafeRubyBlock,
:erl_call => Chef::Provider::ErlCall,
:log => Chef::Provider::Log::ChefLog
}
diff --git a/lib/chef/policy_builder.rb b/lib/chef/policy_builder.rb
new file mode 100644
index 0000000000..136b2853b0
--- /dev/null
+++ b/lib/chef/policy_builder.rb
@@ -0,0 +1,49 @@
+#
+# Author:: Daniel DeLeo (<dan@getchef.com>)
+# Copyright:: Copyright 2008-2014 Chef Software, 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/policy_builder/expand_node_object'
+require 'chef/policy_builder/policyfile'
+
+class Chef
+
+ # PolicyBuilder contains classes that handles fetching policy from server or
+ # disk and resolving any indirection (e.g. expanding run_list).
+ #
+ # INPUTS
+ # * event stream object
+ # * node object/run_list
+ # * json_attribs
+ # * override_runlist
+ #
+ # OUTPUTS
+ # * mutated node object (implicit)
+ # * a new RunStatus (probably doesn't need to be here)
+ # * cookbooks sync'd to disk
+ # * cookbook_hash is stored in run_context
+ module PolicyBuilder
+
+ def self.strategy
+ if Chef::Config[:use_policyfile]
+ Policyfile
+ else
+ ExpandNodeObject
+ end
+ end
+
+ end
+end
diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb
new file mode 100644
index 0000000000..38b8b7551b
--- /dev/null
+++ b/lib/chef/policy_builder/expand_node_object.rb
@@ -0,0 +1,237 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Tim Hinderliter (<tim@opscode.com>)
+# Author:: Christopher Walters (<cw@opscode.com>)
+# Author:: Daniel DeLeo (<dan@getchef.com>)
+# Copyright:: Copyright 2008-2014 Chef Software, 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/log'
+require 'chef/rest'
+require 'chef/run_context'
+require 'chef/config'
+require 'chef/node'
+
+class Chef
+ module PolicyBuilder
+
+ # ExpandNodeObject is the "classic" policy builder implementation. It
+ # expands the run_list on a node object and then queries the chef-server
+ # to find the correct set of cookbooks, given version constraints of the
+ # node's environment.
+ class ExpandNodeObject
+
+ attr_reader :events
+ attr_reader :node
+ attr_reader :node_name
+ attr_reader :ohai_data
+ attr_reader :json_attribs
+ attr_reader :override_runlist
+ attr_reader :original_runlist
+ attr_reader :run_context
+ attr_reader :run_list_expansion
+
+ def initialize(node_name, ohai_data, json_attribs, override_runlist, events)
+ @node_name = node_name
+ @ohai_data = ohai_data
+ @json_attribs = json_attribs
+ @override_runlist = override_runlist
+ @events = events
+
+ @node = nil
+ @original_runlist = nil
+ @run_list_expansion = nil
+ end
+
+ def setup_run_context(specific_recipes=nil)
+ if Chef::Config[:solo]
+ Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, Chef::Config[:cookbook_path]) }
+ 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)
+ else
+ Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, api_service) }
+ cookbook_hash = sync_cookbooks
+ cookbook_collection = Chef::CookbookCollection.new(cookbook_hash)
+ run_context = Chef::RunContext.new(node, cookbook_collection, @events)
+ end
+
+ # TODO: this is not the place for this. It should be in Runner or
+ # CookbookCompiler or something.
+ run_context.load(@run_list_expansion)
+ if specific_recipes
+ specific_recipes.each do |recipe_file|
+ run_context.load_recipe_file(recipe_file)
+ end
+ end
+ run_context
+ end
+
+
+ # In client-server operation, loads the node state from the server. In
+ # chef-solo operation, builds a new node object.
+ def load_node
+ events.node_load_start(node_name, Chef::Config)
+ Chef::Log.debug("Building node object for #{node_name}")
+
+ if Chef::Config[:solo]
+ @node = Chef::Node.build(node_name)
+ else
+ @node = Chef::Node.find_or_create(node_name)
+ end
+ rescue Exception => e
+ # TODO: wrap this exception so useful error info can be given to the
+ # user.
+ events.node_load_failed(node_name, e, Chef::Config)
+ raise
+ end
+
+
+ # Applies environment, external JSON attributes, and override run list to
+ # the node, Then expands the run_list.
+ #
+ # === Returns
+ # node<Chef::Node>:: The modified node object. node is modified in place.
+ def build_node
+ # Allow user to override the environment of a node by specifying
+ # a config parameter.
+ if Chef::Config[:environment] && !Chef::Config[:environment].chop.empty?
+ node.chef_environment(Chef::Config[:environment])
+ end
+
+ # consume_external_attrs may add items to the run_list. Save the
+ # expanded run_list, which we will pass to the server later to
+ # determine which versions of cookbooks to use.
+ node.reset_defaults_and_overrides
+ node.consume_external_attrs(ohai_data, @json_attribs)
+
+ setup_run_list_override
+
+ expand_run_list
+
+ Chef::Log.info("Run List is [#{node.run_list}]")
+ Chef::Log.info("Run List expands to [#{@expanded_run_list_with_versions.join(', ')}]")
+
+ events.node_load_completed(node, @expanded_run_list_with_versions, Chef::Config)
+
+ node
+ end
+
+ # Expands the node's run list. Stores the run_list_expansion object for later use.
+ def expand_run_list
+ @run_list_expansion = if Chef::Config[:solo]
+ node.expand!('disk')
+ else
+ node.expand!('server')
+ end
+
+ # @run_list_expansion is a RunListExpansion.
+ #
+ # Convert @expanded_run_list, which is an
+ # Array of Hashes of the form
+ # {:name => NAME, :version_constraint => Chef::VersionConstraint },
+ # into @expanded_run_list_with_versions, an
+ # Array of Strings of the form
+ # "#{NAME}@#{VERSION}"
+ @expanded_run_list_with_versions = @run_list_expansion.recipes.with_version_constraints_strings
+ @run_list_expansion
+ rescue Exception => e
+ # TODO: wrap/munge exception with useful error output.
+ events.run_list_expand_failed(node, e)
+ raise
+ end
+
+ # Sync_cookbooks eagerly loads all files except files and
+ # templates. It returns the cookbook_hash -- the return result
+ # from /environments/#{node.chef_environment}/cookbook_versions,
+ # which we will use for our run_context.
+ #
+ # === Returns
+ # Hash:: The hash of cookbooks with download URLs as given by the server
+ def sync_cookbooks
+ Chef::Log.debug("Synchronizing cookbooks")
+
+ begin
+ events.cookbook_resolution_start(@expanded_run_list_with_versions)
+ cookbook_hash = api_service.post("environments/#{node.chef_environment}/cookbook_versions",
+ {:run_list => @expanded_run_list_with_versions})
+ rescue Exception => e
+ # TODO: wrap/munge exception to provide helpful error output
+ events.cookbook_resolution_failed(@expanded_run_list_with_versions, e)
+ raise
+ else
+ events.cookbook_resolution_complete(cookbook_hash)
+ end
+
+ synchronizer = Chef::CookbookSynchronizer.new(cookbook_hash, events)
+ synchronizer.sync_cookbooks
+
+ # register the file cache path in the cookbook path so that CookbookLoader actually picks up the synced cookbooks
+ Chef::Config[:cookbook_path] = File.join(Chef::Config[:file_cache_path], "cookbooks")
+
+ cookbook_hash
+ end
+
+ # Indicates whether the policy is temporary, which means an
+ # override_runlist was provided. Chef::Client uses this to decide whether
+ # to do the final node save at the end of the run or not.
+ def temporary_policy?
+ !!@original_runlist
+ end
+
+ ########################################
+ # Internal public API
+ ########################################
+
+ def setup_run_list_override
+ runlist_override_sanity_check!
+ unless(override_runlist.empty?)
+ @original_runlist = node.run_list.run_list_items.dup
+ node.run_list(*override_runlist)
+ Chef::Log.warn "Run List override has been provided."
+ Chef::Log.warn "Original Run List: [#{original_runlist.join(', ')}]"
+ Chef::Log.warn "Overridden Run List: [#{node.run_list}]"
+ end
+ end
+
+ # Ensures runlist override contains RunListItem instances
+ def runlist_override_sanity_check!
+ # Convert to array and remove whitespace
+ if override_runlist.is_a?(String)
+ @override_runlist = override_runlist.split(',').map { |e| e.strip }
+ end
+ @override_runlist = [override_runlist].flatten.compact
+ override_runlist.map! do |item|
+ if(item.is_a?(Chef::RunList::RunListItem))
+ item
+ else
+ Chef::RunList::RunListItem.new(item)
+ end
+ end
+ end
+
+ def api_service
+ @api_service ||= Chef::REST.new(config[:chef_server_url])
+ end
+
+ def config
+ Chef::Config
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb
new file mode 100644
index 0000000000..19b9aaf542
--- /dev/null
+++ b/lib/chef/policy_builder/policyfile.rb
@@ -0,0 +1,344 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Tim Hinderliter (<tim@opscode.com>)
+# Author:: Christopher Walters (<cw@opscode.com>)
+# Author:: Daniel DeLeo (<dan@getchef.com>)
+# Copyright:: Copyright 2008-2014 Chef Software, 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/log'
+require 'chef/rest'
+require 'chef/run_context'
+require 'chef/config'
+require 'chef/node'
+
+class Chef
+ module PolicyBuilder
+
+ # Policyfile is an experimental policy builder implementation that gets run
+ # list and cookbook version information from a single document.
+ #
+ # == WARNING
+ # This implementation is experimental. It may be changed in incompatible
+ # ways in minor or even patch releases, or even abandoned altogether. If
+ # using this with other tools, you may be forced to upgrade those tools in
+ # lockstep with chef-client because of incompatible behavior changes.
+ #
+ # == Unsupported Options:
+ # * override_runlist:: This could potentially be integrated into the
+ # policyfile, or replaced with a similar feature that has different
+ # semantics.
+ # * specific_recipes:: put more design thought into this use case.
+ # * run_list in json_attribs:: would be ignored anyway, so it raises an error.
+ # * chef-solo:: not currently supported. Need more design thought around
+ # how this should work.
+ class Policyfile
+
+ class UnsupportedFeature < StandardError; end
+
+ class PolicyfileError < StandardError; end
+
+ RunListExpansionIsh = Struct.new(:recipes, :roles)
+
+ attr_reader :events
+ attr_reader :node
+ attr_reader :node_name
+ attr_reader :ohai_data
+ attr_reader :json_attribs
+ attr_reader :run_context
+
+ def initialize(node_name, ohai_data, json_attribs, override_runlist, events)
+ @node_name = node_name
+ @ohai_data = ohai_data
+ @json_attribs = json_attribs
+ @events = events
+
+ @node = nil
+
+ Chef::Log.warn("Using experimental Policyfile feature")
+
+ if Chef::Config[:solo]
+ raise UnsupportedFeature, "Policyfile does not support chef-solo at this time."
+ end
+
+ if override_runlist
+ raise UnsupportedFeature, "Policyfile does not support override run lists at this time"
+ end
+
+ if json_attribs && json_attribs.key?("run_list")
+ raise UnsupportedFeature, "Policyfile does not support setting the run_list in json data at this time"
+ end
+
+ if Chef::Config[:environment] && !Chef::Config[:environment].chop.empty?
+ raise UnsupportedFeature, "Policyfile does not work with Chef Environments"
+ end
+ end
+
+ ## API Compat ##
+ # Methods related to unsupported features
+
+ # Override run_list is not supported.
+ def original_runlist
+ nil
+ end
+
+ # Override run_list is not supported.
+ def override_runlist
+ nil
+ end
+
+ # Policyfile gives you the run_list already expanded, but users of this
+ # class may expect to get a run_list expansion compatible object by
+ # calling this method.
+ #
+ # === Returns
+ # RunListExpansionIsh:: A RunListExpansion duck type
+ def run_list_expansion
+ run_list_expansion_ish
+ end
+
+ ## PolicyBuilder API ##
+
+ # Loads the node state from the server.
+ def load_node
+ events.node_load_start(node_name, Chef::Config)
+ Chef::Log.debug("Building node object for #{node_name}")
+
+ @node = Chef::Node.find_or_create(node_name)
+ validate_policyfile
+ node
+ rescue Exception => e
+ events.node_load_failed(node_name, e, Chef::Config)
+ raise
+ end
+
+ # Applies environment, external JSON attributes, and override run list to
+ # the node, Then expands the run_list.
+ #
+ # === Returns
+ # node<Chef::Node>:: The modified node object. node is modified in place.
+ def build_node
+ # consume_external_attrs may add items to the run_list. Save the
+ # expanded run_list, which we will pass to the server later to
+ # determine which versions of cookbooks to use.
+ node.reset_defaults_and_overrides
+
+ node.consume_external_attrs(ohai_data, json_attribs)
+
+ expand_run_list
+ apply_policyfile_attributes
+
+ Chef::Log.info("Run List is [#{run_list}]")
+ Chef::Log.info("Run List expands to [#{run_list_with_versions_for_display.join(', ')}]")
+
+
+ events.node_load_completed(node, run_list_with_versions_for_display, Chef::Config)
+
+ node
+ rescue Exception => e
+ events.node_load_failed(node_name, e, Chef::Config)
+ raise
+ end
+
+ def setup_run_context(specific_recipes=nil)
+ # TODO: This file vendor stuff is duplicated and initializing it with a
+ # block traps a reference to this object in a global context which will
+ # prevent it from getting GC'd. Simplify it.
+ Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, api_service) }
+ sync_cookbooks
+ cookbook_collection = Chef::CookbookCollection.new(cookbooks_to_sync)
+ run_context = Chef::RunContext.new(node, cookbook_collection, events)
+
+ run_context.load(run_list_expansion_ish)
+
+ run_context
+ end
+
+ def expand_run_list
+ node.run_list(run_list)
+ node.automatic_attrs[:roles] = []
+ node.automatic_attrs[:recipes] = run_list_expansion_ish.recipes
+ run_list_expansion_ish
+ end
+
+
+ def sync_cookbooks
+ Chef::Log.debug("Synchronizing cookbooks")
+ synchronizer = Chef::CookbookSynchronizer.new(cookbooks_to_sync, events)
+ synchronizer.sync_cookbooks
+
+ # register the file cache path in the cookbook path so that CookbookLoader actually picks up the synced cookbooks
+ Chef::Config[:cookbook_path] = File.join(Chef::Config[:file_cache_path], "cookbooks")
+
+ cookbooks_to_sync
+ end
+
+ # Whether or not this is a temporary policy. Since PolicyBuilder doesn't
+ # support override_runlist, this is always false.
+ def temporary_policy?
+ false
+ end
+
+ ## Internal Public API ##
+
+ def run_list_with_versions_for_display
+ run_list.map do |recipe_spec|
+ cookbook, recipe = parse_recipe_spec(recipe_spec)
+ lock_data = cookbook_lock_for(cookbook)
+ display = "#{cookbook}::#{recipe}@#{lock_data["version"]} (#{lock_data["identifier"][0...7]})"
+ display
+ end
+ end
+
+ def run_list_expansion_ish
+ recipes = run_list.map do |recipe_spec|
+ cookbook, recipe = parse_recipe_spec(recipe_spec)
+ "#{cookbook}::#{recipe}"
+ end
+ RunListExpansionIsh.new(recipes, [])
+ end
+
+ def apply_policyfile_attributes
+ node.attributes.role_default = policy["default_attributes"]
+ node.attributes.role_override = policy["override_attributes"]
+ end
+
+ def parse_recipe_spec(recipe_spec)
+ rmatch = recipe_spec.match(/recipe\[([^:]+)::([^:]+)\]/)
+ if rmatch.nil?
+ raise PolicyfileError, "invalid recipe specification #{recipe_spec} in Policyfile from #{policyfile_location}"
+ else
+ [rmatch[1], rmatch[2]]
+ end
+ end
+
+ def cookbook_lock_for(cookbook_name)
+ cookbook_locks[cookbook_name]
+ end
+
+ def run_list
+ policy["run_list"]
+ end
+
+ def policy
+ @policy ||= http_api.get(policyfile_location)
+ rescue Net::HTTPServerException => e
+ raise ConfigurationError, "Error loading policyfile from `#{policyfile_location}': #{e.class} - #{e.message}"
+ end
+
+ def policyfile_location
+ "data/policyfiles/#{deployment_group}"
+ end
+
+ # Do some mimimal validation of the policyfile we fetched from the
+ # server. Compatibility mode relies on using data bags to store policy
+ # files; therefore no real validation will be performed server-side and
+ # we need to make additional checks to ensure the data will be formatted
+ # correctly.
+ def validate_policyfile
+ errors = []
+ unless run_list
+ errors << "Policyfile is missing run_list element"
+ end
+ unless policy.key?("cookbook_locks")
+ errors << "Policyfile is missing cookbook_locks element"
+ end
+ if run_list.kind_of?(Array)
+ run_list_errors = run_list.select do |maybe_recipe_spec|
+ validate_recipe_spec(maybe_recipe_spec)
+ end
+ errors += run_list_errors
+ else
+ errors << "Policyfile run_list is malformed, must be an array of `recipe[cb_name::recipe_name]` items: #{policy["run_list"]}"
+ end
+
+ unless errors.empty?
+ raise PolicyfileError, "Policyfile fetched from #{policyfile_location} was invalid:\n#{errors.join("\n")}"
+ end
+ end
+
+ def validate_recipe_spec(recipe_spec)
+ parse_recipe_spec(recipe_spec)
+ nil
+ rescue PolicyfileError => e
+ e.message
+ end
+
+ class ConfigurationError < StandardError; end
+
+ def deployment_group
+ Chef::Config[:deployment_group] or
+ raise ConfigurationError, "Setting `deployment_group` is not configured."
+ end
+
+ # Builds a 'cookbook_hash' map of the form
+ # "COOKBOOK_NAME" => "IDENTIFIER"
+ #
+ # This can be passed to a Chef::CookbookSynchronizer object to
+ # synchronize the cookbooks.
+ #
+ # TODO: Currently this makes N API calls to the server to get the
+ # cookbook objects. With server support (bulk API or the like), this
+ # should be reduced to a single call.
+ def cookbooks_to_sync
+ @cookbook_to_sync ||= begin
+ events.cookbook_resolution_start(run_list_with_versions_for_display)
+
+ cookbook_versions_by_name = cookbook_locks.inject({}) do |cb_map, (name, lock_data)|
+ cb_map[name] = manifest_for(name, lock_data)
+ cb_map
+ end
+ events.cookbook_resolution_complete(cookbook_versions_by_name)
+
+ cookbook_versions_by_name
+ end
+ rescue Exception => e
+ # TODO: wrap/munge exception to provide helpful error output
+ events.cookbook_resolution_failed(run_list_with_versions_for_display, e)
+ raise
+ end
+
+ # Fetches the CookbookVersion object for the given name and identifer
+ # specified in the lock_data.
+ # TODO: This only implements Chef 11 compatibility mode, which means that
+ # cookbooks are fetched by the "dotted_decimal_identifier": a
+ # representation of a SHA1 in the traditional x.y.z version format.
+ def manifest_for(cookbook_name, lock_data)
+ xyz_version = lock_data["dotted_decimal_identifier"]
+ http_api.get("cookbooks/#{cookbook_name}/#{xyz_version}")
+ rescue Exception => e
+ message = "Error loading cookbook #{cookbook_name} at version #{xyz_version}: #{e.class} - #{e.message}"
+ err = Chef::Exceptions::CookbookNotFound.new(message)
+ err.set_backtrace(e.backtrace)
+ raise err
+ end
+
+ def cookbook_locks
+ policy["cookbook_locks"]
+ end
+
+ def http_api
+ @api_service ||= Chef::REST.new(config[:chef_server_url])
+ end
+
+ def config
+ Chef::Config
+ end
+
+ end
+ end
+end
+
diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb
index 3fb86d72c0..152a067f03 100644
--- a/lib/chef/provider.rb
+++ b/lib/chef/provider.rb
@@ -31,6 +31,9 @@ class Chef
attr_accessor :current_resource
attr_accessor :run_context
+ attr_reader :recipe_name
+ attr_reader :cookbook_name
+
#--
# TODO: this should be a reader, and the action should be passed in the
# constructor; however, many/most subclasses override the constructor so
@@ -44,6 +47,9 @@ class Chef
@current_resource = nil
@run_context = run_context
@converge_actions = nil
+
+ @recipe_name = nil
+ @cookbook_name = nil
end
def whyrun_mode?
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/cookbook_file.rb b/lib/chef/provider/cookbook_file.rb
index d59950780f..18af70d415 100644
--- a/lib/chef/provider/cookbook_file.rb
+++ b/lib/chef/provider/cookbook_file.rb
@@ -38,6 +38,14 @@ class Chef
super
end
+ private
+
+ def managing_content?
+ return true if @new_resource.checksum
+ return true if !@new_resource.source.nil? && @action != :create_if_missing
+ false
+ end
+
end
end
end
diff --git a/lib/chef/provider/cron.rb b/lib/chef/provider/cron.rb
index 4430e3e18f..87452b4872 100644
--- a/lib/chef/provider/cron.rb
+++ b/lib/chef/provider/cron.rb
@@ -40,7 +40,7 @@ class Chef
def whyrun_supported?
true
end
-
+
def load_current_resource
crontab_lines = []
@current_resource = Chef::Resource::Cron.new(@new_resource.name)
@@ -82,10 +82,10 @@ 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)
+ @new_resource.send(cron_var) != @current_resource.send(cron_var)
end
end
@@ -165,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
diff --git a/lib/chef/provider/cron/solaris.rb b/lib/chef/provider/cron/solaris.rb
index 6861820676..20fa7abcce 100644
--- a/lib/chef/provider/cron/solaris.rb
+++ b/lib/chef/provider/cron/solaris.rb
@@ -19,4 +19,4 @@
require "chef/provider/cron/unix"
# 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 \ No newline at end of file
+Chef::Provider::Cron::Solaris = Chef::Provider::Cron::Unix
diff --git a/lib/chef/provider/cron/unix.rb b/lib/chef/provider/cron/unix.rb
index 1149f43f76..5cb1bcda41 100644
--- a/lib/chef/provider/cron/unix.rb
+++ b/lib/chef/provider/cron/unix.rb
@@ -63,7 +63,7 @@ class Chef
Chef::Log.debug(e.message)
exit_status = 1
error_message = e.message
- end
+ end
tempcron.close!
if exit_status > 0
raise Chef::Exceptions::Cron, "Error updating state of #{@new_resource.name}, exit: #{exit_status}, message: #{error_message}"
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/directory.rb b/lib/chef/provider/directory.rb
index e3d2b89f2e..067737b9d4 100644
--- a/lib/chef/provider/directory.rb
+++ b/lib/chef/provider/directory.rb
@@ -123,6 +123,13 @@ class Chef
end
end
end
+
+ private
+
+ def managing_content?
+ false
+ end
+
end
end
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/file.rb b/lib/chef/provider/file.rb
index e727aa9ec1..b6a20fe9b7 100644
--- a/lib/chef/provider/file.rb
+++ b/lib/chef/provider/file.rb
@@ -75,7 +75,8 @@ class Chef
@current_resource ||= Chef::Resource::File.new(@new_resource.name)
@current_resource.path(@new_resource.path)
if ::File.exists?(@current_resource.path) && ::File.file?(::File.realpath(@current_resource.path))
- if @action != :create_if_missing && @current_resource.respond_to?(:checksum)
+ if managing_content?
+ Chef::Log.debug("#{@new_resource} checksumming file at #{@new_resource.path}.")
@current_resource.checksum(checksum(@current_resource.path))
end
load_resource_attributes_from_file(@current_resource)
@@ -159,6 +160,15 @@ class Chef
private
+ # What to check in this resource to see if we're going to be actively managing
+ # content (for things like doing checksums in load_current_resource). Expected to
+ # be overridden in subclasses.
+ def managing_content?
+ return true if @new_resource.checksum
+ return true if !@new_resource.content.nil? && @action != :create_if_missing
+ false
+ end
+
# Handles resource requirements for action :create when some fs entry
# already exists at the destination path. For actions other than create,
# we don't care what kind of thing is at the destination path because:
@@ -240,8 +250,8 @@ class Chef
def content
@content ||= begin
- load_current_resource if @current_resource.nil?
- @content_class.new(@new_resource, @current_resource, @run_context)
+ load_current_resource if @current_resource.nil?
+ @content_class.new(@new_resource, @current_resource, @run_context)
end
end
@@ -330,7 +340,9 @@ class Chef
do_backup unless file_created?
deployment_strategy.deploy(tempfile.path, ::File.realpath(@new_resource.path))
Chef::Log.info("#{@new_resource} updated file contents #{@new_resource.path}")
- @new_resource.checksum(checksum(@new_resource.path)) # for reporting
+ if managing_content?
+ @new_resource.checksum(checksum(@new_resource.path)) # for reporting
+ end
end
def do_contents_changes
@@ -340,17 +352,29 @@ class Chef
if tempfile.path.nil? || !::File.exists?(tempfile.path)
raise "chef-client is confused, trying to deploy a file that has no path or does not exist..."
end
+
# the file? on the next line suppresses the case in why-run when we have a not-file here that would have otherwise been removed
if ::File.file?(@new_resource.path) && contents_changed?
- diff.diff(@current_resource.path, tempfile.path)
- @new_resource.diff( diff.for_reporting ) unless file_created?
- description = [ "update content in file #{@new_resource.path} from #{short_cksum(@current_resource.checksum)} to #{short_cksum(checksum(tempfile.path))}" ]
- description << diff.for_output
+ description = [ "update content in file #{@new_resource.path} from \
+#{short_cksum(@current_resource.checksum)} to #{short_cksum(checksum(tempfile.path))}" ]
+
+ # Hide the diff output if the resource is marked as a sensitive resource
+ if @new_resource.sensitive
+ @new_resource.diff("suppressed sensitive resource")
+ description << "suppressed sensitive resource"
+ else
+ diff.diff(@current_resource.path, tempfile.path)
+ @new_resource.diff( diff.for_reporting ) unless file_created?
+ description << diff.for_output
+ end
+
converge_by(description) do
update_file_contents
end
end
+
# unlink necessary to clean up in why-run mode
+ tempfile.close
tempfile.unlink
end
@@ -379,6 +403,7 @@ class Chef
end
def contents_changed?
+ Chef::Log.debug "calculating checksum of #{tempfile.path} to compare with #{@current_resource.checksum}"
checksum(tempfile.path) != @current_resource.checksum
end
@@ -407,4 +432,3 @@ class Chef
end
end
end
-
diff --git a/lib/chef/provider/git.rb b/lib/chef/provider/git.rb
index 7cda1a873a..e77948d367 100644
--- a/lib/chef/provider/git.rb
+++ b/lib/chef/provider/git.rb
@@ -17,6 +17,7 @@
#
+require 'chef/exceptions'
require 'chef/log'
require 'chef/provider'
require 'chef/mixin/shell_out'
@@ -75,7 +76,9 @@ class Chef
def action_checkout
if target_dir_non_existent_or_empty?
clone
- checkout
+ if @new_resource.enable_checkout
+ checkout
+ end
enable_submodules
add_remotes
else
@@ -151,10 +154,11 @@ class Chef
def checkout
sha_ref = target_revision
+
converge_by("checkout ref #{sha_ref} branch #{@new_resource.revision}") do
# checkout into a local branch rather than a detached HEAD
- shell_out!("git checkout -b deploy #{sha_ref}", run_options(:cwd => @new_resource.destination))
- Chef::Log.info "#{@new_resource} checked out branch: #{@new_resource.revision} reference: #{sha_ref}"
+ shell_out!("git checkout -b #{@new_resource.checkout_branch} #{sha_ref}", run_options(:cwd => @new_resource.destination))
+ Chef::Log.info "#{@new_resource} checked out branch: #{@new_resource.revision} onto: #{@new_resource.checkout_branch} reference: #{sha_ref}"
end
end
@@ -269,11 +273,26 @@ class Chef
private
def run_options(run_opts={})
- run_opts[:user] = @new_resource.user if @new_resource.user
+ env = {}
+ if @new_resource.user
+ run_opts[:user] = @new_resource.user
+ # Certain versions of `git` misbehave if git configuration is
+ # inaccessible in $HOME. We need to ensure $HOME matches the
+ # user who is executing `git` not the user running Chef.
+ env['HOME'] = begin
+ require 'etc'
+ Etc.getpwnam(@new_resource.user).dir
+ rescue ArgumentError # user not found
+ raise Chef::Exceptions::User, "Could not determine HOME for specified user '#{@new_resource.user}' for resource '#{@new_resource.name}'"
+ end
+ end
run_opts[:group] = @new_resource.group if @new_resource.group
- run_opts[:environment] = {"GIT_SSH" => @new_resource.ssh_wrapper} if @new_resource.ssh_wrapper
+ env['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[:environment] = env unless env.empty?
run_opts
+
end
def cwd
diff --git a/lib/chef/provider/group.rb b/lib/chef/provider/group.rb
index c941ed72bd..f01677b3ac 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,73 +47,96 @@ 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
+
+ requirements.assert(:all_actions) do |a|
+ # Make sure that the resource doesn't contain any common
+ # user names in the members and exclude_members properties.
+ if !@new_resource.members.nil? && !@new_resource.excluded_members.nil?
+ common_members = @new_resource.members & @new_resource.excluded_members
+ a.assertion { common_members.empty? }
+ a.failure_message(Chef::Exceptions::ConflictingMembersInGroup, "Attempting to both add and remove users from a group: '#{common_members.join(', ')}'")
+ # No why-run alternative
+ end
+ 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
# <false>:: If a change is not required
def compare_group
- @change_desc = nil
+ @change_desc = [ ]
if @new_resource.gid != @current_resource.gid
- @change_desc = "change gid #{@current_resource.gid} to #{@new_resource.gid}"
- return true
+ @change_desc << "change gid #{@current_resource.gid} to #{@new_resource.gid}"
end
-
+
if(@new_resource.append)
missing_members = []
@new_resource.members.each do |member|
- next if @current_resource.members.include?(member)
+ next if has_current_group_member?(member)
missing_members << member
end
if missing_members.length > 0
- @change_desc = "add missing member(s): #{missing_members.join(", ")}"
- return true
+ @change_desc << "add missing member(s): #{missing_members.join(", ")}"
+ end
+
+ members_to_be_removed = []
+ @new_resource.excluded_members.each do |member|
+ if has_current_group_member?(member)
+ members_to_be_removed << member
+ end
+ end
+ if members_to_be_removed.length > 0
+ @change_desc << "remove existing member(s): #{members_to_be_removed.join(", ")}"
end
else
if @new_resource.members != @current_resource.members
- @change_desc = "replace group members with new list of members"
- return true
+ @change_desc << "replace group members with new list of members"
end
end
- return false
+
+ !@change_desc.empty?
end
-
+
+ def has_current_group_member?(member)
+ @current_resource.members.include?(member)
+ 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,25 +145,25 @@ class Chef
end
end
end
-
+
def action_manage
if @group_exists && compare_group
- converge_by(["manage group #{@new_resource}", @change_desc]) do
- manage_group
+ converge_by(["manage group #{@new_resource}"] + change_desc) do
+ 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
+ converge_by(["modify group #{@new_resource}"] + change_desc) do
manage_group
Chef::Log.info("#{@new_resource} modified")
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..c204c09321 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")
@@ -73,21 +73,43 @@ class Chef
end
def set_members
+ # First reset the memberships if the append is not set
unless @new_resource.append
Chef::Log.debug("#{@new_resource} removing group members #{@current_resource.members.join(' ')}") unless @current_resource.members.empty?
safe_dscl("create /Groups/#{@new_resource.group_name} GroupMembers ''") # clear guid list
safe_dscl("create /Groups/#{@new_resource.group_name} GroupMembership ''") # clear user list
+ @current_resource.members([ ])
+ end
+
+ # Add any members that need to be added
+ if @new_resource.members && !@new_resource.members.empty?
+ members_to_be_added = [ ]
+ @new_resource.members.each do |member|
+ members_to_be_added << member if !@current_resource.members.include?(member)
+ end
+ unless members_to_be_added.empty?
+ Chef::Log.debug("#{@new_resource} setting group members #{members_to_be_added.join(', ')}")
+ safe_dscl("append /Groups/#{@new_resource.group_name} GroupMembership #{members_to_be_added.join(' ')}")
+ end
end
- unless @new_resource.members.empty?
- Chef::Log.debug("#{@new_resource} setting group members #{@new_resource.members.join(', ')}")
- safe_dscl("append /Groups/#{@new_resource.group_name} GroupMembership #{@new_resource.members.join(' ')}")
+
+ # Remove any members that need to be removed
+ if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
+ members_to_be_removed = [ ]
+ @new_resource.excluded_members.each do |member|
+ members_to_be_removed << member if @current_resource.members.include?(member)
+ end
+ unless members_to_be_removed.empty?
+ Chef::Log.debug("#{@new_resource} removing group members #{members_to_be_removed.join(', ')}")
+ safe_dscl("delete /Groups/#{@new_resource.group_name} GroupMembership #{members_to_be_removed.join(' ')}")
+ end
end
end
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 +118,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
@@ -110,16 +132,16 @@ class Chef
if @new_resource.gid && (@current_resource.gid != @new_resource.gid)
set_gid
end
- if @new_resource.members && (@current_resource.members != @new_resource.members)
+ if @new_resource.members || @new_resource.excluded_members
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..a65a7ffd53 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,32 +32,27 @@ 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
- def modify_group_members
- if(@new_resource.append)
- unless @new_resource.members.empty?
- @new_resource.members.each do |member|
- Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
- shell_out!("gpasswd -a #{member} #{@new_resource.group_name}")
- end
- else
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add")
- end
- else
- unless @new_resource.members.empty?
- Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
- shell_out!("gpasswd -M #{@new_resource.members.join(',')} #{@new_resource.group_name}")
- else
- Chef::Log.debug("#{@new_resource} setting group members to: none")
- shell_out!("gpasswd -M \"\" #{@new_resource.group_name}")
- end
- end
+ def set_members(members)
+ unless members.empty?
+ shell_out!("gpasswd -M #{members.join(',')} #{@new_resource.group_name}")
+ else
+ shell_out!("gpasswd -M \"\" #{@new_resource.group_name}")
+ end
+ end
+
+ def add_member(member)
+ shell_out!("gpasswd -a #{member} #{@new_resource.group_name}")
+ end
+
+ def remove_member(member)
+ shell_out!("gpasswd -d #{member} #{@new_resource.group_name}")
end
end
end
diff --git a/lib/chef/provider/group/groupadd.rb b/lib/chef/provider/group/groupadd.rb
index 544fee4304..cb480aab54 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,15 +58,55 @@ 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}"
+ if @new_resource.append
+ if @new_resource.members && !@new_resource.members.empty?
+ members_to_be_added = [ ]
+ @new_resource.members.each do |member|
+ members_to_be_added << member if !@current_resource.members.include?(member)
+ end
+ members_to_be_added.each do |member|
+ Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
+ add_member(member)
+ end
+ end
+
+ if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
+ members_to_be_removed = [ ]
+ @new_resource.excluded_members.each do |member|
+ members_to_be_removed << member if @current_resource.members.include?(member)
+ end
+
+ members_to_be_removed.each do |member|
+ Chef::Log.debug("#{@new_resource} removing member #{member} from group #{@new_resource.group_name}")
+ remove_member(member)
+ end
+ end
+ else
+ members_description = @new_resource.members.empty? ? "none" : @new_resource.members.join(", ")
+ Chef::Log.debug("#{@new_resource} setting group members to: #{members_description}")
+ set_members(@new_resource.members)
+ end
+ end
+
+ def add_member(member)
+ raise Chef::Exceptions::Group, "you must override add_member in #{self.to_s}"
end
+
+ def remove_member(member)
+ raise Chef::Exceptions::Group, "you must override remove_member in #{self.to_s}"
+ end
+
+ def set_members(members)
+ raise Chef::Exceptions::Group, "you must override set_members in #{self.to_s}"
+ end
+
# Little bit of magic as per Adam's useradd provider to pull the assign the command line flags
#
# ==== Returns
@@ -87,6 +127,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/groupmod.rb b/lib/chef/provider/group/groupmod.rb
index 10fc680d78..c8b6458db0 100644
--- a/lib/chef/provider/group/groupmod.rb
+++ b/lib/chef/provider/group/groupmod.rb
@@ -44,45 +44,40 @@ class Chef
# Manage the group when it already exists
def manage_group
if @new_resource.append
- to_add = @new_resource.members.dup
- to_add.reject! { |user| @current_resource.members.include?(user) }
-
- to_delete = Array.new
-
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add") if to_add.empty?
+ members_to_be_added = [ ]
+ if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
+ # First find out if any member needs to be removed
+ members_to_be_removed = [ ]
+ @new_resource.excluded_members.each do |member|
+ members_to_be_removed << member if @current_resource.members.include?(member)
+ end
+
+ unless members_to_be_removed.empty?
+ # We are using a magic trick to remove the groups.
+ reset_group_membership
+
+ # Capture the members we need to add in
+ # members_to_be_added to be added later on.
+ @current_resource.members.each do |member|
+ members_to_be_added << member unless members_to_be_removed.include?(member)
+ end
+ end
+ end
+
+ if @new_resource.members && !@new_resource.members.empty?
+ @new_resource.members.each do |member|
+ members_to_be_added << member if !@current_resource.members.include?(member)
+ end
+ end
+
+ Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add") if members_to_be_added.empty?
+
+ add_group_members(members_to_be_added)
else
- to_add = @new_resource.members.dup
- to_add.reject! { |user| @current_resource.members.include?(user) }
-
- to_delete = @current_resource.members.dup
- to_delete.reject! { |user| @new_resource.members.include?(user) }
-
+ # We are resetting the members of a group so use the same trick
+ reset_group_membership
Chef::Log.debug("#{@new_resource} setting group members to: none") if @new_resource.members.empty?
- end
-
- if to_delete.empty?
- # If we are only adding new members to this group, then
- # call add_group_members with only those users
- add_group_members(to_add)
- else
- Chef::Log.debug("#{@new_resource} removing members #{to_delete.join(', ')}")
-
- # This is tricky, but works: rename the existing group to
- # "<name>_bak", create a new group with the same GID and
- # "<name>", then set correct members on that group
- rename = "group mod -n #{@new_resource.group_name}_bak #{@new_resource.group_name}"
- shell_out!(rename)
-
- create = "group add"
- create << set_options(:overwrite_gid => true)
- shell_out!(create)
-
- # Ignore to_add here, since we're replacing the group we
- # have to add all members who should be in the group.
add_group_members(@new_resource.members)
-
- remove = "group del #{@new_resource.group_name}_bak"
- shell_out!(remove)
end
end
@@ -99,6 +94,21 @@ class Chef
end
end
+ # This is tricky, but works: rename the existing group to
+ # "<name>_bak", create a new group with the same GID and
+ # "<name>", then set correct members on that group
+ def reset_group_membership
+ rename = "group mod -n #{@new_resource.group_name}_bak #{@new_resource.group_name}"
+ shell_out!(rename)
+
+ create = "group add"
+ create << set_options(:overwrite_gid => true)
+ shell_out!(create)
+
+ remove = "group del #{@new_resource.group_name}_bak"
+ shell_out!(remove)
+ end
+
# Little bit of magic as per Adam's useradd provider to pull and assign the command line flags
#
# ==== Returns
diff --git a/lib/chef/provider/group/pw.rb b/lib/chef/provider/group/pw.rb
index 3bf67a515a..3ec6f6f668 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,42 +20,54 @@ 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"
command << set_options
- command << set_members_option
- run_command(:command => command)
+ member_options = set_members_options
+ if member_options.empty?
+ run_command(:command => command)
+ else
+ member_options.each do |option|
+ run_command(:command => command + option)
+ end
+ end
end
-
+
# Manage the group when it already exists
def manage_group
command = "pw groupmod"
command << set_options
- command << set_members_option
- run_command(:command => command)
+ member_options = set_members_options
+ if member_options.empty?
+ run_command(:command => command)
+ else
+ member_options.each do |option|
+ run_command(:command => command + option)
+ end
+ end
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
@@ -70,23 +82,54 @@ class Chef
end
# Set the membership option depending on the current resource states
- def set_members_option
- opt = ""
- unless @new_resource.members.empty?
- opt << " -M #{@new_resource.members.join(',')}"
- Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
+ def set_members_options
+ opts = [ ]
+ members_to_be_added = [ ]
+ members_to_be_removed = [ ]
+
+ if @new_resource.append
+ # Append is set so we will only add members given in the
+ # members list and remove members given in the
+ # excluded_members list.
+ if @new_resource.members && !@new_resource.members.empty?
+ @new_resource.members.each do |member|
+ members_to_be_added << member if !@current_resource.members.include?(member)
+ end
+ end
+
+ if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
+ @new_resource.excluded_members.each do |member|
+ members_to_be_removed << member if @current_resource.members.include?(member)
+ end
+ end
else
- # New member list is empty so we should delete any old group members
- unless @current_resource.members.empty?
- opt << " -d #{@current_resource.members.join(',')}"
- Chef::Log.debug("#{@new_resource} removing group members #{@current_resource.members.join(', ')}")
- else
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
+ # Append is not set so we're resetting the membership of
+ # the group to the given members.
+ members_to_be_added = @new_resource.members
+ @current_resource.members.each do |member|
+ # No need to re-add a member if it's present in the new
+ # list of members
+ if members_to_be_added.include? member
+ members_to_be_added.delete member
+ else
+ members_to_be_removed << member
+ end
end
end
- opt
+
+ unless members_to_be_added.empty?
+ Chef::Log.debug("#{@new_resource} adding group members: #{members_to_be_added.join(',')}")
+ opts << " -m #{members_to_be_added.join(',')}"
+ end
+
+ unless members_to_be_removed.empty?
+ Chef::Log.debug("#{@new_resource} removing group members: #{members_to_be_removed.join(',')}")
+ opts << " -d #{members_to_be_removed.join(',')}"
+ end
+
+ opts
end
-
+
end
end
end
diff --git a/lib/chef/provider/group/suse.rb b/lib/chef/provider/group/suse.rb
index 0b66c1f912..14380f1705 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,28 +32,31 @@ 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
end
- def modify_group_members
- unless @new_resource.members.empty?
- if(@new_resource.append)
- @new_resource.members.each do |member|
- Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
- shell_out!("groupmod -A #{member} #{@new_resource.group_name}")
- end
- else
- Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
- shell_out!("groupmod -A #{@new_resource.members.join(',')} #{@new_resource.group_name}")
- end
- else
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
+ def set_members(members)
+ unless @current_resource.members.empty?
+ shell_out!("groupmod -R #{@current_resource.members.join(',')} #{@new_resource.group_name}")
+ end
+
+ unless members.empty?
+ shell_out!("groupmod -A #{members.join(',')} #{@new_resource.group_name}")
end
end
+
+ def add_member(member)
+ shell_out!("groupmod -A #{member} #{@new_resource.group_name}")
+ end
+
+ def remove_member(member)
+ shell_out!("groupmod -R #{member} #{@new_resource.group_name}")
+ end
+
end
end
end
diff --git a/lib/chef/provider/group/usermod.rb b/lib/chef/provider/group/usermod.rb
index 0d44d3940f..8323c3e9ba 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.
@@ -17,12 +17,15 @@
#
require 'chef/provider/group/groupadd'
+require 'chef/mixin/shell_out'
class Chef
class Provider
class Group
class Usermod < Chef::Provider::Group::Groupadd
-
+
+ include Chef::Mixin::ShellOut
+
def load_current_resource
super
end
@@ -30,38 +33,58 @@ 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 }
+ requirements.assert(:modify, :manage) do |a|
+ 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"
- append_flags = "-a -G"
+
+ requirements.assert(:all_actions) do |a|
+ a.assertion { @new_resource.excluded_members.empty? }
+ a.failure_message Chef::Exceptions::Group, "excluded_members is not supported by #{self.to_s}"
+ # No whyrun alternative - this action is simply not supported.
end
+ end
- unless @new_resource.members.empty?
- if(@new_resource.append)
- @new_resource.members.each do |member|
- Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
- run_command(:command => "usermod #{append_flags} #{@new_resource.group_name} #{member}" )
- end
+ def set_members(members)
+ return if members.empty?
+ # This provider only supports adding members with
+ # append. Only if the action is create we will go
+ # ahead and add members.
+ if @new_resource.action == :create
+ members.each do |member|
+ add_member(member)
end
else
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
+ raise Chef::Exceptions::UnsupportedAction, "Setting members directly is not supported by #{self.to_s}"
end
end
+
+ def add_member(member)
+ shell_out!("usermod #{append_flags} #{@new_resource.group_name} #{member}")
+ end
+
+ def remove_member(member)
+ # This provider only supports adding members with
+ # append. This function should never be called.
+ raise Chef::Exceptions::UnsupportedAction, "Removing members members is not supported by #{self.to_s}"
+ end
+
+ def append_flags
+ case node[:platform]
+ when "openbsd", "netbsd", "aix", "solaris2", "smartos"
+ "-G"
+ when "solaris", "suse", "opensuse"
+ "-a -G"
+ end
+ end
+
end
end
end
diff --git a/lib/chef/provider/group/windows.rb b/lib/chef/provider/group/windows.rb
index 88280408cd..c9c3da29e0 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,30 +49,47 @@ class Chef
@current_resource
end
-
+
def create_group
@net_group.local_add
manage_group
end
-
+
def manage_group
if @new_resource.append
- begin
- #ERROR_MEMBER_IN_ALIAS if a member already exists in the group
- @net_group.local_add_members(@new_resource.members)
- rescue
- members = @new_resource.members + @current_resource.members
- @net_group.local_set_members(members.uniq)
+ members_to_be_added = [ ]
+ @new_resource.members.each do |member|
+ members_to_be_added << member if ! has_current_group_member?(member)
+ end
+
+ # local_add_members will raise ERROR_MEMBER_IN_ALIAS if a
+ # member already exists in the group.
+ @net_group.local_add_members(members_to_be_added) unless members_to_be_added.empty?
+
+ members_to_be_removed = [ ]
+ @new_resource.excluded_members.each do |member|
+ member_sid = local_group_name_to_sid(member)
+ members_to_be_removed << member if has_current_group_member?(member)
end
+ @net_group.local_delete_members(members_to_be_removed) unless members_to_be_removed.empty?
else
@net_group.local_set_members(@new_resource.members)
end
end
-
+
+ def has_current_group_member?(member)
+ member_sid = local_group_name_to_sid(member)
+ @current_resource.members.include?(member_sid)
+ end
+
def remove_group
@net_group.local_delete
end
-
+
+ def local_group_name_to_sid(group_name)
+ locally_qualified_name = group_name.include?("\\") ? group_name : "#{ENV['COMPUTERNAME']}\\#{group_name}"
+ Chef::ReservedNames::Win32::Security.lookup_account_name(locally_qualified_name)[1].to_s
+ end
end
end
end
diff --git a/lib/chef/provider/http_request.rb b/lib/chef/provider/http_request.rb
index a5bc3b5e04..2bbd20aa2c 100644
--- a/lib/chef/provider/http_request.rb
+++ b/lib/chef/provider/http_request.rb
@@ -17,33 +17,35 @@
#
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(
+ # CHEF-4762: we expect a nil return value from Chef::HTTP for a "200 Success" response
+ # and false for a "304 Not Modified" response
+ modified = @http.head(
"#{@new_resource.url}?message=#{message}",
@new_resource.headers
)
Chef::Log.info("#{@new_resource} HEAD to #{@new_resource.url} successful")
Chef::Log.debug("#{@new_resource} HEAD request response: #{modified}")
# :head is usually used to trigger notifications, which converge_by now does
- if modified
+ if modified != false
converge_by("#{@new_resource} HEAD to #{@new_resource.url} returned modified, trigger notifications") {}
end
end
@@ -53,9 +55,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 +68,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 +82,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 +95,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 3a354bb5c6..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
@@ -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
@@ -215,7 +215,7 @@ class Chef
def delete_command
"ifconfig #{@new_resource.device} down"
end
-
+
def loopback_device
'lo'
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
index 128bb4c6c3..0d7e11a1b8 100644
--- a/lib/chef/provider/mount/aix.rb
+++ b/lib/chef/provider/mount/aix.rb
@@ -1,5 +1,5 @@
#
-# Author::
+# Author::
# Copyright:: Copyright (c) 2009 Opscode, Inc
# License:: Apache License, Version 2.0
#
@@ -38,7 +38,7 @@ class Chef
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 |
@@ -74,8 +74,8 @@ class Chef
device_details = device_fstab.split(":")
search_device = device_details[1]
else
- search_device = device_fstab_regex
- end
+ search_device = device_fstab_regex
+ end
case line
when /#{search_device}\s+#{Regexp.escape(@new_resource.mount_point)}/
mounted = true
@@ -140,7 +140,7 @@ class Chef
fstab.puts("\tnodename\t\t= #{device_details[0]}")
else
fstab.puts("\tdev\t\t= #{device_fstab}")
- end
+ 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?
@@ -164,7 +164,7 @@ class Chef
if !found_device
contents << line
end
- end
+ end
::File.open("/etc/filesystems", "w") do |fstab|
contents.each { |line| fstab.puts line}
end
diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb
index f7118d6c3c..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)
@@ -141,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.
@@ -156,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)}/
@@ -167,7 +177,7 @@ class Chef
contents << line
end
end
-
+
::File.open("/etc/fstab", "w") do |fstab|
contents.reverse_each { |line| fstab.puts line}
end
@@ -181,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
@@ -200,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
@@ -247,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 572cc84877..adae880b7f 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" : ""
@@ -202,6 +202,7 @@ class Chef
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.variables(@new_resource.response_file_variables)
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)
diff --git a/lib/chef/provider/package/aix.rb b/lib/chef/provider/package/aix.rb
new file mode 100644
index 0000000000..9fb87d6ea0
--- /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 4e9a0cff01..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
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.rb b/lib/chef/provider/remote_file.rb
index d62f4aa13c..ed99c0bb84 100644
--- a/lib/chef/provider/remote_file.rb
+++ b/lib/chef/provider/remote_file.rb
@@ -39,6 +39,14 @@ class Chef
super
end
+ private
+
+ def managing_content?
+ return true if @new_resource.checksum
+ return true if !@new_resource.source.nil? && @action != :create_if_missing
+ false
+ end
+
end
end
end
diff --git a/lib/chef/provider/remote_file/cache_control_data.rb b/lib/chef/provider/remote_file/cache_control_data.rb
index d21ad2da12..27c724620b 100644
--- a/lib/chef/provider/remote_file/cache_control_data.rb
+++ b/lib/chef/provider/remote_file/cache_control_data.rb
@@ -149,7 +149,10 @@ class Chef
end
def sanitized_cache_file_basename
- scrubbed_uri = uri.gsub(/\W/, '_')
+ # Scrub and truncate in accordance with the goals of keeping the name
+ # human-readable but within the bounds of local file system
+ # path length limits
+ scrubbed_uri = uri.gsub(/\W/, '_')[0..63]
uri_md5 = Chef::Digester.instance.generate_md5_checksum(StringIO.new(uri))
"#{scrubbed_uri}-#{uri_md5}.json"
end
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..f17ab5a56d 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'
@@ -56,19 +56,12 @@ class Chef
end
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)
- rescue Net::HTTPRetriableError => e
- if e.response.is_a? Net::HTTPNotModified
- tempfile = nil
- else
- raise e
- end
+ http = Chef::HTTP::Simple.new(uri, http_client_opts)
+ tempfile = http.streaming_request(uri, headers)
+ if tempfile
+ update_cache_control_data(tempfile, http.last_response)
+ tempfile.close
end
-
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..2c3dda55c4 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
@@ -97,7 +103,7 @@ class Chef
priority.each { |runlevel, arguments|
Chef::Log.debug("#{@new_resource} runlevel #{runlevel}, action #{arguments[0]}, priority #{arguments[1]}")
# if we are in a update-rc.d default startup runlevel && we start in this runlevel
- if (2..5).include?(runlevel.to_i) && arguments[0] == :start
+ if %w[ 1 2 3 4 5 S ].include?(runlevel) && arguments[0] == :start
enabled = true
end
}
@@ -105,14 +111,33 @@ class Chef
enabled
end
- def enable_service()
+ # Override method from parent to ensure priority is up-to-date
+ def action_enable
+ if @new_resource.priority.nil?
+ priority_ok = true
+ else
+ priority_ok = @current_resource.priority == @new_resource.priority
+ end
+ if @current_resource.enabled and priority_ok
+ 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 +145,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/template.rb b/lib/chef/provider/template.rb
index 217f9e56ec..555f4f14f0 100644
--- a/lib/chef/provider/template.rb
+++ b/lib/chef/provider/template.rb
@@ -52,6 +52,14 @@ class Chef
end
end
+ private
+
+ def managing_content?
+ return true if @new_resource.checksum
+ return true if !@new_resource.source.nil? && @action != :create_if_missing
+ false
+ end
+
end
end
end
diff --git a/lib/chef/provider/user.rb b/lib/chef/provider/user.rb
index e815ba9c9e..2ab7b0fb98 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.
@@ -63,11 +63,15 @@ class Chef
if user_info
@current_resource.uid(user_info.uid)
@current_resource.gid(user_info.gid)
- @current_resource.comment(user_info.gecos)
@current_resource.home(user_info.dir)
@current_resource.shell(user_info.shell)
@current_resource.password(user_info.passwd)
+ if @new_resource.comment && user_info.gecos.respond_to?(:force_encoding)
+ user_info.gecos.force_encoding(@new_resource.comment.encoding)
+ end
+ @current_resource.comment(user_info.gecos)
+
if @new_resource.password && @current_resource.password == 'x'
begin
require 'shadow'
@@ -79,9 +83,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 +91,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 +114,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..409da10e53 100644
--- a/lib/chef/provider/user/useradd.rb
+++ b/lib/chef/provider/user/useradd.rb
@@ -57,6 +57,13 @@ class Chef
# we can get an exit code of 1 even when it's successful on
# rhel/centos (redhat bug 578534). See additional error checks below.
passwd_s = shell_out!("passwd", "-S", new_resource.username, :returns => [0,1])
+ if whyrun_mode? && passwd_s.stdout.empty? && passwd_s.stderr.match(/does not exist/)
+ # if we're in whyrun mode and the user is not yet created we assume it would be
+ return false
+ end
+
+ raise Chef::Exceptions::User, "Cannot determine if #{@new_resource} is locked!" if passwd_s.stdout.empty?
+
status_line = passwd_s.stdout.split(' ')
case status_line[1]
when /^P/
@@ -124,7 +131,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/whyrun_safe_ruby_block.rb b/lib/chef/provider/whyrun_safe_ruby_block.rb
new file mode 100644
index 0000000000..4b491a4f60
--- /dev/null
+++ b/lib/chef/provider/whyrun_safe_ruby_block.rb
@@ -0,0 +1,30 @@
+#
+# Author:: Phil Dibowitz (<phild@fb.com>)
+# Copyright:: Copyright (c) 2013 Facebook
+# 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.
+#
+
+class Chef
+ class Provider
+ class WhyrunSafeRubyBlock < Chef::Provider::RubyBlock
+ def action_create
+ @new_resource.block.call
+ @new_resource.updated_by_last_action(true)
+ @run_context.events.resource_update_applied(@new_resource, :create, "execute the whyrun_safe_ruby_block #{@new_resource.name}")
+ Chef::Log.info("#{@new_resource} called")
+ end
+ end
+ end
+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 a87aa9d141..6cfd12827a 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -48,6 +48,7 @@ require 'chef/provider/service'
require 'chef/provider/subversion'
require 'chef/provider/template'
require 'chef/provider/user'
+require 'chef/provider/whyrun_safe_ruby_block'
require 'chef/provider/env/windows'
@@ -65,6 +66,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'
diff --git a/lib/chef/recipe.rb b/lib/chef/recipe.rb
index 6ea69360b8..5b95d80590 100644
--- a/lib/chef/recipe.rb
+++ b/lib/chef/recipe.rb
@@ -23,6 +23,7 @@ require 'chef/dsl/data_query'
require 'chef/dsl/platform_introspection'
require 'chef/dsl/include_recipe'
require 'chef/dsl/registry_helper'
+require 'chef/dsl/reboot_pending'
require 'chef/mixin/from_file'
@@ -38,6 +39,7 @@ class Chef
include Chef::DSL::IncludeRecipe
include Chef::DSL::Recipe
include Chef::DSL::RegistryHelper
+ include Chef::DSL::RebootPending
include Chef::Mixin::FromFile
include Chef::Mixin::Deprecation
@@ -81,26 +83,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/request_id.rb b/lib/chef/request_id.rb
new file mode 100644
index 0000000000..7fc177c633
--- /dev/null
+++ b/lib/chef/request_id.rb
@@ -0,0 +1,37 @@
+# Author:: Prajakta Purohit (<prajakta@opscode.com>)
+# Copyright:: Copyright (c) 2009, 2010, 2013, 2014 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/monkey_patches/securerandom'
+require 'singleton'
+
+class Chef
+ class RequestID
+ include Singleton
+
+ def reset_request_id
+ @request_id = nil
+ end
+
+ def request_id
+ @request_id ||= generate_request_id
+ end
+
+ def generate_request_id
+ SecureRandom.uuid
+ end
+ end
+end
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 997c614171..e015a9eaf5 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -21,6 +21,7 @@ require 'chef/mixin/params_validate'
require 'chef/dsl/platform_introspection'
require 'chef/dsl/data_query'
require 'chef/dsl/registry_helper'
+require 'chef/dsl/reboot_pending'
require 'chef/mixin/convert_to_class_name'
require 'chef/resource/conditional'
require 'chef/resource/conditional_action_not_nothing'
@@ -125,6 +126,7 @@ F
include Chef::Mixin::ParamsValidate
include Chef::DSL::PlatformIntrospection
include Chef::DSL::RegistryHelper
+ include Chef::DSL::RebootPending
include Chef::Mixin::ConvertToClassName
include Chef::Mixin::Deprecation
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..a08e8aeeea 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
@@ -81,6 +81,8 @@ class Chef
@allowed_actions.push(:force_deploy, :deploy, :rollback)
@additional_remotes = Hash[]
@keep_releases = 5
+ @enable_checkout = true
+ @checkout_branch = "deploy"
end
# where the checked out/cloned code goes
@@ -389,7 +391,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 +400,35 @@ class Chef
)
end
+ def enable_checkout(arg=nil)
+ set_or_return(
+ :enable_checkout,
+ arg,
+ :kind_of => [TrueClass, FalseClass]
+ )
+ end
+
+ def checkout_branch(arg=nil)
+ set_or_return(
+ :checkout_branch,
+ arg,
+ :kind_of => String
+ )
+ 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/file.rb b/lib/chef/resource/file.rb
index 676cbf200a..3db88dcda0 100644
--- a/lib/chef/resource/file.rb
+++ b/lib/chef/resource/file.rb
@@ -52,9 +52,9 @@ class Chef
@force_unlink = false
@manage_symlink_source = nil
@diff = nil
+ @sensitive = false
end
-
def content(arg=nil)
set_or_return(
:content,
@@ -119,6 +119,13 @@ class Chef
)
end
+ def sensitive(arg=nil)
+ set_or_return(
+ :sensitive,
+ arg,
+ :kind_of => [ TrueClass, FalseClass ]
+ )
+ end
end
end
end
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..daf851fac6 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
@@ -31,11 +31,13 @@ class Chef
@group_name = name
@gid = nil
@members = []
+ @excluded_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 +45,7 @@ class Chef
:kind_of => [ String ]
)
end
-
+
def gid(arg=nil)
set_or_return(
:gid,
@@ -62,7 +64,17 @@ class Chef
end
alias_method :users, :members
-
+
+ def excluded_members(arg=nil)
+ converted_members = arg.is_a?(String) ? [].push(arg) : arg
+ set_or_return(
+ :excluded_members,
+ converted_members,
+ :kind_of => [ Array ]
+ )
+ end
+
+
def append(arg=nil)
set_or_return(
:append,
@@ -78,6 +90,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/package.rb b/lib/chef/resource/package.rb
index eaad3e2e58..f9fdd1ab59 100644
--- a/lib/chef/resource/package.rb
+++ b/lib/chef/resource/package.rb
@@ -36,6 +36,7 @@ class Chef
@package_name = name
@resource_name = :package
@response_file = nil
+ @response_file_variables = Hash.new
@source = nil
@version = nil
end
@@ -64,6 +65,14 @@ class Chef
)
end
+ def response_file_variables(arg=nil)
+ set_or_return(
+ :response_file_variables,
+ arg,
+ :kind_of => [ Hash ]
+ )
+ end
+
def source(arg=nil)
set_or_return(
:source,
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..91782e4114 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)
@@ -32,12 +32,14 @@ class Chef
@destination = name
@resource_name = :scm
@enable_submodules = false
+ @enable_checkout = true
@revision = "HEAD"
@remote = "origin"
@ssh_wrapper = nil
@depth = nil
@allowed_actions.push(:checkout, :export, :sync, :diff, :log)
@action = [:sync]
+ @checkout_branch = "deploy"
end
def destination(arg=nil)
@@ -130,6 +132,14 @@ class Chef
)
end
+ def enable_checkout(arg=nil)
+ set_or_return(
+ :enable_checkout,
+ arg,
+ :kind_of => [TrueClass, FalseClass]
+ )
+ end
+
def remote(arg=nil)
set_or_return(
:remote,
@@ -146,6 +156,22 @@ class Chef
)
end
+ def timeout(arg=nil)
+ set_or_return(
+ :timeout,
+ arg,
+ :kind_of => Integer
+ )
+ end
+
+ def checkout_branch(arg=nil)
+ set_or_return(
+ :checkout_branch,
+ arg,
+ :kind_of => String
+ )
+ 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..c3d009bc55 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
@@ -43,11 +43,10 @@ class Chef
@init_command = nil
@priority = nil
@action = "nothing"
- @startup_type = :automatic
@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 +54,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/whyrun_safe_ruby_block.rb b/lib/chef/resource/whyrun_safe_ruby_block.rb
new file mode 100644
index 0000000000..ddb9d91dc3
--- /dev/null
+++ b/lib/chef/resource/whyrun_safe_ruby_block.rb
@@ -0,0 +1,31 @@
+#
+# Author:: Phil Dibowitz (<phild@fb.com>)
+# Copyright:: Copyright (c) 2013 Facebook
+# 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.
+#
+
+class Chef
+ class Resource
+ class WhyrunSafeRubyBlock < Chef::Resource::RubyBlock
+
+ def initialize(name, run_context=nil)
+ super
+ @resource_name = :whyrun_safe_ruby_block
+ @provider = Chef::Provider::WhyrunSafeRubyBlock
+ 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_platform_map.rb b/lib/chef/resource_platform_map.rb
index ad27aa91c1..a678f5be4b 100644
--- a/lib/chef/resource_platform_map.rb
+++ b/lib/chef/resource_platform_map.rb
@@ -123,7 +123,7 @@ class Chef
resource_klass = platform_resource(short_name, platform, version) ||
resource_matching_short_name(short_name)
- raise NameError, "Cannot find a resource for #{short_name} on #{platform} version #{version}" if resource_klass.nil?
+ raise Exceptions::NoSuchResourceType, "Cannot find a resource for #{short_name} on #{platform} version #{version}" if resource_klass.nil?
resource_klass
end
diff --git a/lib/chef/resource_reporter.rb b/lib/chef/resource_reporter.rb
index 434150e83d..d191710cb4 100644
--- a/lib/chef/resource_reporter.rb
+++ b/lib/chef/resource_reporter.rb
@@ -50,10 +50,10 @@ class Chef
def for_json
as_hash = {}
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["name"] = new_resource.name.to_s
+ as_hash["id"] = new_resource.identity.to_s
+ 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
@@ -101,7 +107,6 @@ class Chef
@pending_update = nil
@status = "success"
@exception = nil
- @run_id = SecureRandom.uuid
@rest_client = rest_client
@error_descriptions = {}
end
@@ -112,7 +117,7 @@ class Chef
if reporting_enabled?
begin
resource_history_url = "reports/nodes/#{node_name}/runs"
- server_response = @rest_client.post_rest(resource_history_url, {:action => :start, :run_id => @run_id,
+ server_response = @rest_client.post_rest(resource_history_url, {:action => :start, :run_id => run_id,
:start_time => start_time.to_s}, headers)
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
handle_error_starting_run(e, resource_history_url)
@@ -152,6 +157,10 @@ class Chef
@reporting_enabled = false
end
+ def run_id
+ @run_status.run_id
+ end
+
def resource_current_state_loaded(new_resource, action, current_resource)
unless nested_resource?(new_resource)
@pending_update = ResourceReport.new_with_current_state(new_resource, action, current_resource)
@@ -208,8 +217,8 @@ class Chef
def post_reporting_data
if reporting_enabled?
run_data = prepare_run_data
- resource_history_url = "reports/nodes/#{node_name}/runs/#{@run_id}"
- Chef::Log.info("Sending resource update report (run-id: #{@run_id})")
+ resource_history_url = "reports/nodes/#{node_name}/runs/#{run_id}"
+ Chef::Log.info("Sending resource update report (run-id: #{run_id})")
Chef::Log.debug run_data.inspect
compressed_data = encode_gzip(run_data.to_json)
begin
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 55c6a0dbf3..76adb6f1e1 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'
@@ -67,5 +68,7 @@ require 'chef/resource/smartos_package'
require 'chef/resource/template'
require 'chef/resource/timestamped_deploy'
require 'chef/resource/user'
+require 'chef/resource/whyrun_safe_ruby_block'
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..73ca4b3293 100644
--- a/lib/chef/rest.rb
+++ b/lib/chef/rest.rb
@@ -20,71 +20,79 @@
# 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/http/validate_content_length'
require 'chef/config'
require 'chef/exceptions'
require 'chef/platform/query_helpers'
+require 'chef/http/remote_request_id'
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)
+ @request_id = RemoteRequestID.new(options)
+
+ @middlewares << ValidateContentLength.new(options)
+ @middlewares << JSONInput.new(options)
+ @middlewares << JSONToModelOutput.new(options)
+ @middlewares << CookieManager.new(options)
+ @middlewares << @decompressor
+ @middlewares << @authenticator
+ @middlewares << @request_id
+
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 +105,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 +128,76 @@ 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
+ alias :api_request :request
- 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
+ # Do a HTTP request where no middleware is loaded (e.g. JSON input/output
+ # conversion) but the standard Chef Authentication headers are added to the
+ # request.
+ def raw_http_request(method, path, headers, data)
+ url = create_url(path)
+ method, url, headers, data = @authenticator.handle_request(method, url, headers, data)
+ method, url, headers, data = @request_id.handle_request(method, url, headers, data)
+ response, rest_request, return_value = send_http_request(method, url, headers, data)
+ response.error! unless success_response?(response)
+ return_value
+ rescue Exception => exception
+ log_failed_request(response, return_value) unless response.nil?
- # 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
+ if exception.respond_to?(:chef_rest_request=)
+ exception.chef_rest_request = rest_request
end
+ raise
end
- 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
+ ############################################################################
+ # DEPRECATED
+ ############################################################################
- 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
-
- 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 4d431116f9..05a954ad15 100644
--- a/lib/chef/run_context.rb
+++ b/lib/chef/run_context.rb
@@ -146,12 +146,23 @@ class Chef
false
else
loaded_recipe(cookbook_name, recipe_short_name)
-
+ node.loaded_recipe(cookbook_name, recipe_short_name)
cookbook = cookbook_collection[cookbook_name]
cookbook.load_recipe(recipe_short_name, self)
end
end
+ def load_recipe_file(recipe_file)
+ if !File.exist?(recipe_file)
+ raise Chef::Exceptions::RecipeNotFound, "could not find recipe file #{recipe_file}"
+ end
+
+ Chef::Log.debug("Loading Recipe File #{recipe_file}")
+ recipe = Chef::Recipe.new('@recipe_files', recipe_file, self)
+ recipe.from_file(recipe_file)
+ recipe
+ end
+
# Looks up an attribute file given the +cookbook_name+ and
# +attr_file_name+. Used by DSL::IncludeAttribute
def resolve_attribute(cookbook_name, attr_file_name)
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/run_status.rb b/lib/chef/run_status.rb
index 9354f7872a..0f181426b0 100644
--- a/lib/chef/run_status.rb
+++ b/lib/chef/run_status.rb
@@ -37,6 +37,8 @@ class Chef::RunStatus
attr_writer :exception
+ attr_accessor :run_id
+
def initialize(node, events)
@node = node
@events = events
@@ -112,7 +114,8 @@ class Chef::RunStatus
:all_resources => all_resources,
:updated_resources => updated_resources,
:exception => formatted_exception,
- :backtrace => backtrace}
+ :backtrace => backtrace,
+ :run_id => run_id}
end
# Returns a string of the format "ExceptionClass: message" or +nil+ if no
diff --git a/lib/chef/server_api.rb b/lib/chef/server_api.rb
new file mode 100644
index 0000000000..8cdcd7a09d
--- /dev/null
+++ b/lib/chef/server_api.rb
@@ -0,0 +1,43 @@
+#
+# 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'
+require 'chef/http/remote_request_id'
+
+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
+ use Chef::HTTP::RemoteRequestID
+ end
+end
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/ext.rb b/lib/chef/shell/ext.rb
index 30d841e4cd..bc4e955169 100644
--- a/lib/chef/shell/ext.rb
+++ b/lib/chef/shell/ext.rb
@@ -212,7 +212,7 @@ E
puts "This is the chef-shell.\n" +
" Chef Version: #{::Chef::VERSION}\n" +
" http://www.opscode.com/chef\n" +
- " http://wiki.opscode.com/display/chef/Home"
+ " http://docs.opscode.com/"
:ucanhaz_automation
end
alias :shell :version
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 44d167f776..7bce52d874 100644
--- a/lib/chef/util/diff.rb
+++ b/lib/chef/util/diff.rb
@@ -82,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
@@ -104,7 +141,7 @@ class Chef
begin
Chef::Log.debug("running: diff -u #{old_file} #{new_file}")
diff_str = udiff(old_file, new_file)
-
+
rescue Exception => e
# Should *not* receive this, but in some circumstances it seems that
# an exception can be thrown even using shell_out instead of shell_out!
@@ -138,42 +175,6 @@ class Chef
end
end
- # produces a unified-output-format diff with 3 lines of context
- 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
-
def encode_diff_for_json(diff_str)
if Object.const_defined? :Encoding
diff_str.encode!('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
diff --git a/lib/chef/util/file_edit.rb b/lib/chef/util/file_edit.rb
index ea0a523baa..bb19435a12 100644
--- a/lib/chef/util/file_edit.rb
+++ b/lib/chef/util/file_edit.rb
@@ -33,7 +33,7 @@ class Chef
@file_edited = false
raise ArgumentError, "File doesn't exist" unless File.exist? @original_pathname
- @contents = File.new(@original_pathname).readlines
+ @contents = File.open(@original_pathname) { |f| f.readlines }
end
#search the file line by line and match each line with the given regex
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..924bd392f9 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.
@@ -55,19 +55,20 @@ class Chef::Util::Windows::NetGroup < Chef::Util::Windows
nread = 0.chr * PTR_SIZE
total = 0.chr * PTR_SIZE
- rc = NetLocalGroupGetMembers.call(nil, @name, 1, ptr, -1,
+ rc = NetLocalGroupGetMembers.call(nil, @name, 0, ptr, -1,
nread, total, handle)
if (rc == NERR_Success) || (rc == ERROR_MORE_DATA)
ptr = ptr.unpack('L')[0]
nread = nread.unpack('i')[0]
- members = 0.chr * (nread * (PTR_SIZE * 3)) #nread * sizeof(LOCALGROUP_MEMBERS_INFO_1)
+ members = 0.chr * (nread * PTR_SIZE ) #nread * sizeof(LOCALGROUP_MEMBERS_INFO_0)
memcpy(members, ptr, members.size)
- #3 pointer fields in LOCALGROUP_MEMBERS_INFO_1, offset 2*PTR_SIZE is lgrmi1_name
+ # 1 pointer field in LOCALGROUP_MEMBERS_INFO_0, offset 0 is lgrmi0_sid
nread.times do |i|
- offset = (i * 3) + 2
- member = lpwstr_to_s(members, offset)
- group_members << member
+ sid_address = members[i * PTR_SIZE, PTR_SIZE].unpack('L')[0]
+ sid_ptr = FFI::Pointer.new(sid_address)
+ member_sid = Chef::ReservedNames::Win32::Security::SID.new(sid_ptr)
+ group_members << member_sid.to_s
end
NetApiBufferFree(ptr)
else
@@ -92,6 +93,10 @@ class Chef::Util::Windows::NetGroup < Chef::Util::Windows
modify_members(members, NetLocalGroupAddMembers)
end
+ def local_delete_members(members)
+ modify_members(members, NetLocalGroupDelMembers)
+ end
+
def local_delete
rc = NetLocalGroupDel.call(nil, @name)
if rc != NERR_Success
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 c46f6c1fa3..4aff92d00b 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.8.0.alpha.0'
+ VERSION = '11.10.0.rc.1'
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 49088c67ae..7a8dafd8b5 100644
--- a/lib/chef/win32/api/file.rb
+++ b/lib/chef/win32/api/file.rb
@@ -471,6 +471,13 @@ BOOL WINAPI DeviceIoControl(
# ensures the handle is closed on exit of the block
def file_search_handle(path, &block)
begin
+ # Workaround for CHEF-4419:
+ # Make sure paths starting with "/" has a drive letter
+ # assigned from the current working diretory.
+ # 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? "/"
path = encode_path(path)
find_data = WIN32_FIND_DATA.new
handle = FindFirstFileW(path, find_data)
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..0b7d99f111
--- /dev/null
+++ b/lib/chef/win32/mutex.rb
@@ -0,0 +1,117 @@
+#
+# 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
+
+ def initialize(name)
+ @name = name
+ create_system_mutex
+ 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
+ loop do
+ wait_result = WaitForSingleObject(handle, 1000)
+ case wait_result
+ when WAIT_TIMEOUT
+ # We are periodically waking up in order to give ruby a
+ # chance to process any signal it got while we were
+ # sleeping. This condition shouldn't contain any logic
+ # other than sleeping.
+ sleep 0.1
+ 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."
+ break
+ when WAIT_OBJECT_0
+ # Mutex is successfully acquired.
+ break
+ else
+ Chef::Log.error("Failed to acquire system mutex '#{name}'. Return code: #{wait_result}")
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ 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
+
+ private
+
+ def create_system_mutex
+ # First check if there exists a mutex in the system with the
+ # given name. We need only synchronize rights if a mutex is
+ # already created.
+ # InheritHandle is set to true so that subprocesses can
+ # inherit the ownership of the mutex.
+ @handle = OpenMutexW(SYNCHRONIZE, true, name.to_wstring)
+
+ if @handle == 0
+ # Mutext doesn't exist so create one.
+ # 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)
+
+ # Looks like we can't create the mutex for some reason.
+ # Fail early.
+ if @handle == 0
+ Chef::Log.error("Failed to create system mutex with name'#{name}'")
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ 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..e008ff15e8 100644
--- a/lib/chef/win32/version.rb
+++ b/lib/chef/win32/version.rb
@@ -30,23 +30,30 @@ 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
+ def self.method_name_from_marketing_name(marketing_name)
+ "#{marketing_name.gsub(/\s/, '_').gsub(/\./, '_').downcase}?"
+ # "#{marketing_name.gsub(/\s/, '_').gsub(//, '_').downcase}?"
+ end
+
public
-
+
WIN_VERSIONS = {
- "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 }},
- "Windows Server 2008 R2" => {:major => 6, :minor => 1, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
- "Windows Server 2008" => {:major => 6, :minor => 0, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
- "Windows Vista" => {:major => 6, :minor => 0, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
- "Windows Server 2003 R2" => {:major => 5, :minor => 2, :callable => lambda{ get_system_metrics(SM_SERVERR2) != 0 }},
- "Windows Home Server" => {:major => 5, :minor => 2, :callable => lambda{ (@suite_mask & VER_SUITE_WH_SERVER) == VER_SUITE_WH_SERVER }},
- "Windows Server 2003" => {:major => 5, :minor => 2, :callable => lambda{ get_system_metrics(SM_SERVERR2) == 0 }},
+ "Windows 8.1" => {:major => 6, :minor => 3, :callable => lambda{ |product_type, suite_mask| product_type == VER_NT_WORKSTATION }},
+ "Windows Server 2012 R2" => {:major => 6, :minor => 3, :callable => lambda {|product_type, suite_mask| product_type != VER_NT_WORKSTATION }},
+ "Windows 8" => {:major => 6, :minor => 2, :callable => lambda{ |product_type, suite_mask| product_type == VER_NT_WORKSTATION }},
+ "Windows Server 2012" => {:major => 6, :minor => 2, :callable => lambda{ |product_type, suite_mask| product_type != VER_NT_WORKSTATION }},
+ "Windows 7" => {:major => 6, :minor => 1, :callable => lambda{ |product_type, suite_mask| product_type == VER_NT_WORKSTATION }},
+ "Windows Server 2008 R2" => {:major => 6, :minor => 1, :callable => lambda{ |product_type, suite_mask| product_type != VER_NT_WORKSTATION }},
+ "Windows Server 2008" => {:major => 6, :minor => 0, :callable => lambda{ |product_type, suite_mask| product_type != VER_NT_WORKSTATION }},
+ "Windows Vista" => {:major => 6, :minor => 0, :callable => lambda{ |product_type, suite_mask| product_type == VER_NT_WORKSTATION }},
+ "Windows Server 2003 R2" => {:major => 5, :minor => 2, :callable => lambda{ |product_type, suite_mask| get_system_metrics(SM_SERVERR2) != 0 }},
+ "Windows Home Server" => {:major => 5, :minor => 2, :callable => lambda{ |product_type, suite_mask| (suite_mask & VER_SUITE_WH_SERVER) == VER_SUITE_WH_SERVER }},
+ "Windows Server 2003" => {:major => 5, :minor => 2, :callable => lambda{ |product_type, suite_mask| get_system_metrics(SM_SERVERR2) == 0 }},
"Windows XP" => {:major => 5, :minor => 1},
"Windows 2000" => {:major => 5, :minor => 0}
}
@@ -68,18 +75,18 @@ 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
# General Windows checks
WIN_VERSIONS.each do |k,v|
- method_name = "#{k.gsub(/\s/, '_').downcase}?"
+ method_name = method_name_from_marketing_name(k)
define_method(method_name) do
(@major_version == v[:major]) &&
(@minor_version == v[:minor]) &&
- (v[:callable] ? v[:callable].call : true)
+ (v[:callable] ? v[:callable].call(@product_type, @suite_mask) : true)
end
marketing_names << [k, method_name]
end
@@ -103,11 +110,19 @@ class Chef
private
def get_version
- version = GetVersion()
- major = LOBYTE(LOWORD(version))
- minor = HIBYTE(LOWORD(version))
- build = version < 0x80000000 ? HIWORD(version) : 0
- [major, minor, build]
+ # Use WMI here because API's like GetVersion return faked
+ # version numbers on Windows Server 2012 R2 and Windows 8.1 --
+ # WMI always returns the truth. See article at
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
+ require 'ruby-wmi'
+
+ os_info = WMI::Win32_OperatingSystem.find(:first)
+ os_version = os_info.send('Version')
+
+ # The operating system version is a string in the following form
+ # that can be split into components based on the '.' delimiter:
+ # MajorVersionNumber.MinorVersionNumber.BuildNumber
+ os_version.split('.').collect { | version_string | version_string.to_i }
end
def get_version_ex
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/templates/default/preseed-template-variables.seed b/spec/data/cookbooks/preseed/templates/default/preseed-template-variables.seed
new file mode 100644
index 0000000000..0df0015f05
--- /dev/null
+++ b/spec/data/cookbooks/preseed/templates/default/preseed-template-variables.seed
@@ -0,0 +1 @@
+chef-integration-test chef-integration-test/sample-var string "<%= @template_variable -%>"
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/dsl/reboot_pending_spec.rb b/spec/functional/dsl/reboot_pending_spec.rb
new file mode 100644
index 0000000000..10d667f7bd
--- /dev/null
+++ b/spec/functional/dsl/reboot_pending_spec.rb
@@ -0,0 +1,118 @@
+#
+# Author:: Bryan McLellan <btm@loftninjas.org>
+# Copyright:: Copyright (c) 2014 Chef Software, 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/dsl/reboot_pending"
+require "chef/win32/registry"
+require "spec_helper"
+
+describe Chef::DSL::RebootPending, :windows_only do
+ def run_ohai
+ ohai = Ohai::System.new
+ # Would be nice to limit this to platform/kernel/arch etc for Ohai 7
+ ohai.all_plugins
+ node.consume_external_attrs(ohai.data,{})
+
+ ohai
+ end
+
+ def registry_safe?
+ !registry.value_exists?('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { :name => 'PendingFileRenameOperations' }) ||
+ !registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') ||
+ !registry.key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired') ||
+ !registry.key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile')
+ end
+
+ let(:node) { Chef::Node.new }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let!(:ohai) { run_ohai } # Ensure we have necessary node data
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
+ let(:recipe) { Chef::Recipe.new("a windows cookbook", "the windows recipe", run_context) }
+ let(:registry) { Chef::Win32::Registry.new(run_context) }
+
+ describe "reboot_pending?" do
+
+ context "when there is nothing to indicate a reboot is pending" do
+ it { expect(recipe.reboot_pending?).to be_false }
+ end
+
+ describe 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations' do
+ it "returns true if the registry value exists" do
+ pending "Found existing registry keys" unless registry_safe?
+ registry.set_value('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager',
+ { :name => 'PendingFileRenameOperations', :type => :multi_string, :data => ['\??\C:\foo.txt|\??\C:\bar.txt'] })
+
+ expect(recipe.reboot_pending?).to be_true
+ end
+
+ after do
+ if registry_safe?
+ registry.delete_value('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { :name => 'PendingFileRenameOperations' })
+ end
+ end
+ end
+
+ describe 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' do
+ it "returns true if the registry key exists" do
+ pending "Found existing registry keys" unless registry_safe?
+ registry.create_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired', false)
+
+ expect(recipe.reboot_pending?).to be_true
+ end
+
+ after do
+ if registry_safe?
+ registry.delete_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired', false)
+ end
+ end
+ end
+
+ describe 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired' do
+ it "returns true if the registry key exists" do
+ pending "Permissions are limited to 'TrustedInstaller' by default"
+ pending "Found existing registry keys" unless registry_safe?
+ registry.create_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired', false)
+
+ expect(recipe.reboot_pending?).to be_true
+ end
+
+ after do
+ if registry_safe?
+ registry.delete_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired', false)
+ end
+ end
+ end
+
+ describe 'HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile\Flags' do
+ it "returns true if the registry key exists" do
+ pending "Found existing registry keys" unless registry_safe?
+ registry.create_key('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', true)
+ registry.set_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile',
+ { :name => 'Flags', :type => :dword, :data => 3 })
+
+ expect(recipe.reboot_pending?).to be_true
+ end
+
+ after do
+ if registry_safe?
+ registry.delete_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', { :name => 'Flags' })
+ registry.delete_key('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', false)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/functional/knife/cookbook_delete_spec.rb b/spec/functional/knife/cookbook_delete_spec.rb
index a6dba9bc28..ee620bf165 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,7 +36,6 @@ describe Chef::Knife::CookbookDelete do
end
after(:all) do
- Chef::Config.configuration = @original_config
@server.stop
end
@@ -54,7 +51,7 @@ describe Chef::Knife::CookbookDelete do
end
it "logs an error and exits" do
- @knife.ui.stub!(:stderr).and_return(@log_output)
+ @knife.ui.stub(:stderr).and_return(@log_output)
lambda {@knife.run}.should raise_error(SystemExit)
@log_output.string.should match(/Cannot find a cookbook named no-such-cookbook to delete/)
end
@@ -70,8 +67,8 @@ describe Chef::Knife::CookbookDelete do
it "asks for confirmation, then deletes the cookbook" do
stdin, stdout = StringIO.new("y\n"), StringIO.new
- @knife.ui.stub!(:stdin).and_return(stdin)
- @knife.ui.stub!(:stdout).and_return(stdout)
+ @knife.ui.stub(:stdin).and_return(stdin)
+ @knife.ui.stub(:stdout).and_return(stdout)
cb100_deleted = false
@api.delete("/cookbooks/obsolete-cookbook/1.0.0", 200) { cb100_deleted = true; "[\"true\"]" }
@@ -86,8 +83,8 @@ describe Chef::Knife::CookbookDelete do
@knife.config[:purge] = true
stdin, stdout = StringIO.new("y\ny\n"), StringIO.new
- @knife.ui.stub!(:stdin).and_return(stdin)
- @knife.ui.stub!(:stdout).and_return(stdout)
+ @knife.ui.stub(:stdin).and_return(stdin)
+ @knife.ui.stub(:stdout).and_return(stdout)
cb100_deleted = false
@api.delete("/cookbooks/obsolete-cookbook/1.0.0?purge=true", 200) { cb100_deleted = true; "[\"true\"]" }
@@ -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
@@ -129,8 +126,8 @@ describe Chef::Knife::CookbookDelete do
cb100_deleted = cb110_deleted = cb120_deleted = nil
@api.delete("/cookbooks/obsolete-cookbook/1.0.0", 200) { cb100_deleted = true; "[\"true\"]" }
stdin, stdout = StringIO.new, StringIO.new
- @knife.ui.stub!(:stdin).and_return(stdin)
- @knife.ui.stub!(:stdout).and_return(stdout)
+ @knife.ui.stub(:stdin).and_return(stdin)
+ @knife.ui.stub(:stdout).and_return(stdout)
stdin << "1\n"
stdin.rewind
@knife.run
@@ -145,8 +142,8 @@ describe Chef::Knife::CookbookDelete do
@api.delete("/cookbooks/obsolete-cookbook/1.2.0", 200) { cb120_deleted = true; "[\"true\"]" }
stdin, stdout = StringIO.new("4\n"), StringIO.new
- @knife.ui.stub!(:stdin).and_return(stdin)
- @knife.ui.stub!(:stdout).and_return(stdout)
+ @knife.ui.stub(:stdin).and_return(stdin)
+ @knife.ui.stub(:stdout).and_return(stdout)
@knife.run
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..40d71859c7 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
@@ -256,7 +252,7 @@ describe Chef::Knife::Ssh do
# if available, but #merge_configs (which is called by #configure_chef) is
# necessary to have default options merged in.
@knife.merge_configs
- @knife.stub!(:ssh_command).and_return { 0 }
+ @knife.stub(:ssh_command).and_return { 0 }
@api = TinyServer::API.instance
@api.clear
diff --git a/spec/functional/provider/remote_file/cache_control_data_spec.rb b/spec/functional/provider/remote_file/cache_control_data_spec.rb
new file mode 100755
index 0000000000..63a4578c69
--- /dev/null
+++ b/spec/functional/provider/remote_file/cache_control_data_spec.rb
@@ -0,0 +1,101 @@
+#
+# Author:: Adam Edwards (<adamed@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 'spec_helper'
+require 'uri'
+
+describe Chef::Provider::RemoteFile::CacheControlData do
+
+ before do
+ @original_config = Chef::Config.hash_dup
+ end
+
+ after do
+ Chef::Config.configuration = @original_config if @original_config
+ end
+
+ before(:each) do
+ Chef::Config[:file_cache_path] = Dir.mktmpdir
+ end
+
+ after(:each) do
+ FileUtils.rm_rf(Chef::Config[:file_cache_path])
+ end
+
+ let(:uri) { URI.parse("http://www.bing.com/robots.txt") }
+
+ describe "when the cache control data save method is invoked" do
+
+ subject(:cache_control_data) do
+ Chef::Provider::RemoteFile::CacheControlData.load_and_validate(uri, file_checksum)
+ end
+
+ # the checksum of the file last we fetched it.
+ let(:file_checksum) { "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }
+
+ let(:etag) { "\"a-strong-identifier\"" }
+ let(:mtime) { "Thu, 01 Aug 2013 08:16:32 GMT" }
+
+ before do
+ cache_control_data.etag = etag
+ cache_control_data.mtime = mtime
+ cache_control_data.checksum = file_checksum
+ end
+
+ it "writes data to the cache" do
+ cache_control_data.save
+ end
+
+ it "writes the data to the cache and the same data can be read back" do
+ cache_control_data.save
+ saved_cache_control_data = Chef::Provider::RemoteFile::CacheControlData.load_and_validate(uri, file_checksum)
+ saved_cache_control_data.etag.should == cache_control_data.etag
+ saved_cache_control_data.mtime.should == cache_control_data.mtime
+ saved_cache_control_data.checksum.should == cache_control_data.checksum
+ end
+
+ # Cover the very long remote file path case -- see CHEF-4422 where
+ # local cache file names generated from the long uri exceeded
+ # local file system path limits resulting in exceptions from
+ # file system API's on both Windows and Unix systems.
+ context "when the length of the uri exceeds the path length limits for the local file system" do
+ let(:uri_exceeds_file_system_limit) do
+ URI.parse("http://www.bing.com/" + ('0' * 1024))
+ end
+
+ let(:uri) { uri_exceeds_file_system_limit }
+
+ it "writes data to the cache" do
+ lambda do
+ cache_control_data.save
+ end.should_not raise_error
+ end
+
+ it "writes the data to the cache and the same data can be read back" do
+ cache_control_data.save
+ saved_cache_control_data = Chef::Provider::RemoteFile::CacheControlData.load_and_validate(uri, file_checksum)
+ saved_cache_control_data.etag.should == cache_control_data.etag
+ saved_cache_control_data.mtime.should == cache_control_data.mtime
+ saved_cache_control_data.checksum.should == cache_control_data.checksum
+ end
+
+ end
+ end
+
+end
+
diff --git a/spec/functional/resource/base.rb b/spec/functional/resource/base.rb
index 456b396a9c..13438c1759 100644
--- a/spec/functional/resource/base.rb
+++ b/spec/functional/resource/base.rb
@@ -7,7 +7,7 @@
# you may not use this 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,
@@ -38,3 +38,4 @@ def run_context
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
index 35be2bbaa6..4c20023d78 100644
--- a/spec/functional/resource/cron_spec.rb
+++ b/spec/functional/resource/cron_spec.rb
@@ -78,7 +78,7 @@ describe Chef::Resource::Cron, :requires_root, :unix_only do
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
@@ -144,4 +144,4 @@ describe Chef::Resource::Cron, :requires_root, :unix_only do
end
end
-end \ No newline at end of file
+end
diff --git a/spec/functional/resource/file_spec.rb b/spec/functional/resource/file_spec.rb
index f688bae434..d6f56db3e9 100644
--- a/spec/functional/resource/file_spec.rb
+++ b/spec/functional/resource/file_spec.rb
@@ -115,5 +115,4 @@ describe Chef::Resource::File do
end
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..3c2c1a86ba
--- /dev/null
+++ b/spec/functional/resource/group_spec.rb
@@ -0,0 +1,423 @@
+#
+# 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'
+
+# Chef::Resource::Group are turned off on Mac OS X 10.6 due to caching
+# issues around Etc.getgrnam() not picking up the group membership
+# changes that are done on the system. Etc.endgrent is not functioning
+# correctly on certain 10.6 boxes.
+describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supported_on_mac_osx_106 do
+ def group_should_exist(group)
+ case ohai[:platform_family]
+ when "debian", "fedora", "rhel", "suse", "gentoo", "slackware", "arch"
+ expect { Etc::getgrnam(group) }.to_not raise_error(ArgumentError, "can't find group for #{group}")
+ expect(group).to eq(Etc::getgrnam(group).name)
+ when "windows"
+ expect { Chef::Util::Windows::NetGroup.new(group).local_get_members }.to_not raise_error(ArgumentError, "The group name could not be found.")
+ end
+ end
+
+ def user_exist_in_group?(user)
+ case ohai[:platform_family]
+ when "windows"
+ user_sid = sid_string_from_user(user)
+ user_sid.nil? ? false : Chef::Util::Windows::NetGroup.new(group_name).local_get_members.include?(user_sid)
+ else
+ Etc::getgrnam(group_name).mem.include?(user)
+ end
+ end
+
+ def group_should_not_exist(group)
+ case ohai[:platform_family]
+ when "debian", "fedora", "rhel", "suse", "gentoo", "slackware", "arch"
+ expect { Etc::getgrnam(group) }.to raise_error(ArgumentError, "can't find group for #{group}")
+ when "windows"
+ expect { Chef::Util::Windows::NetGroup.new(group).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 sid_string_from_user(user)
+ begin
+ sid = Chef::ReservedNames::Win32::Security.lookup_account_name(user)
+ rescue Chef::Exceptions::Win32APIError
+ sid = nil
+ end
+
+ sid.nil? ? nil : sid[1].to_s
+ end
+
+ def windows_domain_user?(user_name)
+ domain, user = user_name.split('\\')
+
+ if user && domain != '.'
+ computer_name = ENV['computername']
+ domain.downcase != computer_name.downcase
+ end
+ end
+
+ def user(username)
+ usr = Chef::Resource::User.new("#{username}", run_context)
+ if ohai[:platform_family] == "windows"
+ usr.password("ComplexPass11!")
+ end
+ usr
+ end
+
+ def create_user(username)
+ user(username).run_action(:create) if ! windows_domain_user?(username)
+ # TODO: User shouldn't exist
+ end
+
+ def remove_user(username)
+ user(username).run_action(:remove) if ! windows_domain_user?(username)
+ # TODO: User shouldn't exist
+ end
+
+ shared_examples_for "correct group management" do
+ def add_members_to_group(members)
+ temp_resource = group_resource.dup
+ temp_resource.members(members)
+ temp_resource.excluded_members([ ])
+ temp_resource.append(true)
+ temp_resource.run_action(:modify)
+ members.each do |member|
+ user_exist_in_group?(member).should == true
+ end
+ end
+
+ def create_group
+ temp_resource = group_resource.dup
+ temp_resource.members([ ])
+ temp_resource.excluded_members([ ])
+ temp_resource.run_action(:create)
+ group_should_exist(group_name)
+ included_members.each do |member|
+ user_exist_in_group?(member).should == false
+ end
+ end
+
+ before(:each) do
+ create_group
+ end
+
+ after(:each) do
+ group_resource.run_action(:remove)
+ group_should_not_exist(group_name)
+ end
+
+ describe "when append is not set" do
+ let(:included_members) { [spec_members[1]] }
+
+ before do
+ create_user(spec_members[1])
+ create_user(spec_members[0])
+ add_members_to_group([spec_members[0]])
+ end
+
+ after do
+ remove_user(spec_members[1])
+ remove_user(spec_members[0])
+ end
+
+ it "should remove the existing users and add the new users to the group" do
+ group_resource.run_action(tested_action)
+
+ user_exist_in_group?(spec_members[1]).should == true
+ user_exist_in_group?(spec_members[0]).should == false
+ end
+ end
+
+ describe "when append is set" do
+ before(:each) do
+ group_resource.append(true)
+ end
+
+ describe "when the users exist" do
+ before do
+ (included_members + excluded_members).each do |member|
+ create_user(member)
+ end
+ end
+
+ after do
+ (included_members + excluded_members).each do |member|
+ remove_user(member)
+ end
+ end
+
+ it "should add included members to the group" do
+ group_resource.run_action(tested_action)
+
+ included_members.each do |member|
+ user_exist_in_group?(member).should == true
+ end
+ excluded_members.each do |member|
+ user_exist_in_group?(member).should == false
+ end
+ end
+
+ describe "when group contains some users" do
+ before(:each) do
+ add_members_to_group([ spec_members[0], spec_members[2] ])
+ end
+
+ it "should add the included users and remove excluded users" do
+ group_resource.run_action(tested_action)
+
+ included_members.each do |member|
+ user_exist_in_group?(member).should == true
+ end
+ excluded_members.each do |member|
+ user_exist_in_group?(member).should == false
+ end
+ end
+ end
+ end
+
+ describe "when the users doesn't exist" do
+ describe "when append is not set" do
+ it "should raise an error" do
+ lambda { @grp_resource.run_action(tested_action) }.should raise_error
+ end
+ end
+
+ describe "when append is set" do
+ it "should raise an error" do
+ lambda { @grp_resource.run_action(tested_action) }.should raise_error
+ end
+ end
+ end
+ end
+ end
+
+ shared_examples_for "an expected invalid domain error case" do
+ let(:invalid_domain_user_name) { "no space\\administrator" }
+ let(:nonexistent_domain_user_name) { "xxfakedom\\administrator" }
+ before(:each) do
+ group_resource.members []
+ group_resource.excluded_members []
+ group_resource.append(true)
+ group_resource.run_action(:create)
+ group_should_exist(group_name)
+ end
+
+ describe "when updating membership" do
+ it "raises an error for a non well-formed domain name" do
+ group_resource.members [invalid_domain_user_name]
+ lambda { group_resource.run_action(tested_action) }.should raise_error Chef::Exceptions::Win32APIError
+ end
+
+ it "raises an error for a nonexistent domain" do
+ group_resource.members [nonexistent_domain_user_name]
+ lambda { group_resource.run_action(tested_action) }.should raise_error Chef::Exceptions::Win32APIError
+ end
+ end
+
+ describe "when removing members" do
+ it "raises an error for a non well-formed domain name" do
+ group_resource.excluded_members [invalid_domain_user_name]
+ lambda { group_resource.run_action(tested_action) }.should raise_error Chef::Exceptions::Win32APIError
+ end
+
+ it "raises an error for a nonexistent domain" do
+ group_resource.excluded_members [nonexistent_domain_user_name]
+ lambda { group_resource.run_action(tested_action) }.should raise_error Chef::Exceptions::Win32APIError
+ end
+ end
+ end
+
+ let(:group_name) { "cheftest-#{SecureRandom.random_number(9999)}" }
+ let(:included_members) { nil }
+ let(:excluded_members) { nil }
+ let(:group_resource) {
+ group = Chef::Resource::Group.new(group_name, run_context)
+ group.members(included_members)
+ group.excluded_members(excluded_members)
+ group
+ }
+
+ it "append should be false by default" do
+ group_resource.append.should == false
+ end
+
+ describe "group create action" do
+ after(:each) do
+ group_resource.run_action(:remove)
+ group_should_not_exist(group_name)
+ end
+
+ it "should create a group" do
+ group_resource.run_action(:create)
+ group_should_exist(group_name)
+ end
+
+ describe "when group name is length 256", :windows_only do
+ let!(:group_name) { "theoldmanwalkingdownthestreetalwayshadagood\
+smileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisface\
+theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalking\
+downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestree" }
+
+ it "should create a group" do
+ group_resource.run_action(:create)
+ group_should_exist(group_name)
+ end
+ end
+
+ describe "when group name length is more than 256", :windows_only do
+ let!(:group_name) { "theoldmanwalkingdownthestreetalwayshadagood\
+smileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisface\
+theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalking\
+downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
+
+ it "should not create a group" do
+ lambda { group_resource.run_action(:create) }.should raise_error
+ group_should_not_exist(group_name)
+ end
+ end
+
+ # not_supported_on_solaris because of the use of excluded_members
+ describe "should raise an error when same member is included in the members and excluded_members", :not_supported_on_solaris do
+ it "should raise an error" do
+ invalid_resource = group_resource.dup
+ invalid_resource.members(["Jack"])
+ invalid_resource.excluded_members(["Jack"])
+ lambda { invalid_resource.run_action(:create)}.should raise_error(Chef::Exceptions::ConflictingMembersInGroup)
+ end
+ end
+ end
+
+ describe "group remove action" do
+ describe "when there is a group" do
+ before do
+ group_resource.run_action(:create)
+ group_should_exist(group_name)
+ end
+
+ it "should remove a group" do
+ group_resource.run_action(:remove)
+ group_should_not_exist(group_name)
+ end
+ end
+
+ describe "when there is no group" do
+ it "should be no-op" do
+ group_resource.run_action(:remove)
+ group_should_not_exist(group_name)
+ end
+ end
+ end
+
+ describe "group modify action", :not_supported_on_solaris do
+ let(:spec_members){ ["spec-Gordon", "spec-Eric", "spec-Anthony"] }
+ let(:included_members) { [spec_members[0], spec_members[1]] }
+ let(:excluded_members) { [spec_members[2]] }
+ let(:tested_action) { :modify }
+
+ describe "when there is no group" do
+ it "should raise an error" do
+ lambda { group_resource.run_action(:modify) }.should raise_error
+ end
+ end
+
+ describe "when there is a group" do
+ it_behaves_like "correct group management"
+ end
+
+ describe "when running on Windows", :windows_only do
+ describe "when members are Active Directory domain identities", :windows_domain_joined_only do
+ let(:computer_domain) { ohai[:kernel]['cs_info']['domain'].split('.')[0] }
+ let(:spec_members){ ["#{computer_domain}\\Domain Admins", "#{computer_domain}\\Domain Users", "#{computer_domain}\\Domain Computers"] }
+
+ include_examples "correct group management"
+ end
+
+ it_behaves_like "an expected invalid domain error case"
+ end
+ end
+
+ describe "group manage action", :not_supported_on_solaris do
+ let(:spec_members){ ["spec-Gordon", "spec-Eric", "spec-Anthony"] }
+ let(:included_members) { [spec_members[0], spec_members[1]] }
+ let(:excluded_members) { [spec_members[2]] }
+ let(:tested_action) { :manage }
+
+ describe "when there is no group" do
+ it "should raise an error" do
+ lambda { group_resource.run_action(:manage) }.should_not raise_error
+ group_should_not_exist(group_name)
+ end
+ end
+
+ describe "when there is a group" do
+ it_behaves_like "correct group management"
+ end
+
+ describe "running on windows", :windows_only do
+ describe "when members are Windows domain identities", :windows_domain_joined_only do
+ let(:computer_domain) { ohai[:kernel]['cs_info']['domain'].split('.')[0] }
+ let(:spec_members){ ["#{computer_domain}\\Domain Admins", "#{computer_domain}\\Domain Users", "#{computer_domain}\\Domain Computers"] }
+
+ include_examples "correct group management"
+ end
+
+ it_behaves_like "an expected invalid domain error case"
+ end
+ end
+
+ describe "group resource with Usermod provider", :solaris_only do
+ describe "when excluded_members is set" do
+ let(:excluded_members) { ["spec-Anthony"] }
+
+ it ":manage should raise an error" do
+ lambda {group_resource.run_action(:manage) }.should raise_error
+ end
+
+ it ":modify should raise an error" do
+ lambda {group_resource.run_action(:modify) }.should raise_error
+ end
+
+ it ":create should raise an error" do
+ lambda {group_resource.run_action(:create) }.should raise_error
+ end
+ end
+
+ describe "when append is not set" do
+ let(:included_members) { ["spec-Gordon", "spec-Eric"] }
+
+ before(:each) do
+ group_resource.append(false)
+ end
+
+ it ":manage should raise an error" do
+ lambda {group_resource.run_action(:manage) }.should raise_error
+ end
+
+ it ":modify should raise an error" do
+ lambda {group_resource.run_action(:modify) }.should raise_error
+ end
+ end
+ end
+end
+
diff --git a/spec/functional/resource/link_spec.rb b/spec/functional/resource/link_spec.rb
index fd13353bad..9dc0afca06 100644
--- a/spec/functional/resource/link_spec.rb
+++ b/spec/functional/resource/link_spec.rb
@@ -132,7 +132,7 @@ describe Chef::Resource::Link do
describe 'the :delete action' do
before(:each) do
@info = []
- Chef::Log.stub!(:info) { |msg| @info << msg }
+ Chef::Log.stub(:info) { |msg| @info << msg }
resource.run_action(:delete)
end
@@ -153,7 +153,7 @@ describe Chef::Resource::Link do
describe 'the :delete action' do
before(:each) do
@info = []
- Chef::Log.stub!(:info) { |msg| @info << msg }
+ Chef::Log.stub(:info) { |msg| @info << msg }
resource.run_action(:delete)
end
@@ -174,7 +174,7 @@ describe Chef::Resource::Link do
describe 'the :create action' do
before(:each) do
@info = []
- Chef::Log.stub!(:info) { |msg| @info << msg }
+ Chef::Log.stub(:info) { |msg| @info << msg }
resource.run_action(:create)
end
@@ -195,7 +195,7 @@ describe Chef::Resource::Link do
describe 'the :create action' do
before(:each) do
@info = []
- Chef::Log.stub!(:info) { |msg| @info << msg }
+ Chef::Log.stub(:info) { |msg| @info << msg }
resource.run_action(:create)
end
@@ -216,7 +216,7 @@ describe Chef::Resource::Link do
describe 'the :create action' do
before(:each) do
@info = []
- Chef::Log.stub!(:info) { |msg| @info << msg }
+ Chef::Log.stub(:info) { |msg| @info << msg }
resource.run_action(:create)
end
it 'preserves the hard link' do
@@ -241,7 +241,7 @@ describe Chef::Resource::Link do
describe 'the :create action' do
before(:each) do
@info = []
- Chef::Log.stub!(:info) { |msg| @info << msg }
+ Chef::Log.stub(:info) { |msg| @info << msg }
resource.run_action(:create)
end
it 'links to the target file' do
@@ -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
index 4070cacfda..199ccbd37e 100644
--- a/spec/functional/resource/mount_spec.rb
+++ b/spec/functional/resource/mount_spec.rb
@@ -67,30 +67,20 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag do
end
def cleanup_mount(mount_point)
- if windows?
- else
- shell_out("umount #{mount_point}")
- end
+ shell_out("umount #{mount_point}")
end
# platform specific validations.
def mount_should_exists(mount_point, device, fstype = nil, options = nil)
- if windows?
- else
- # unix only validations
- 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
+ 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)
- if windows?
- else
- expect(shell_out("mount | grep #{mount_point}").exitstatus).to eq(1)
- end
+ shell_out("mount").stdout.should_not include(mount_point)
end
def unix_mount_config_file
@@ -100,25 +90,19 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag do
else
mount_config = "/etc/fstab"
end
- end
+ end
def mount_should_be_enabled(mount_point, device)
- if windows?
+ case ohai[:platform]
+ when 'aix'
+ expect(shell_out("cat #{unix_mount_config_file} | grep \"#{mount_point}:\" ").exitstatus).to eq(0)
else
- 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
+ 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)
- if windows?
- else
- expect(shell_out("cat #{unix_mount_config_file} | grep \"#{mount_point}:\"").exitstatus).to eq(1)
- end
+ shell_out("cat #{unix_mount_config_file}").stdout.should_not include("#{mount_point}:")
end
let(:new_resource) do
@@ -145,6 +129,16 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag 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
@@ -152,13 +146,11 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag do
cleanup_device(@device)
end
-
+ after(:each) do
+ cleanup_mount(new_resource.mount_point)
+ end
describe "when the target state is a mounted filesystem" do
- after do
- cleanup_mount(new_resource.mount_point)
- end
-
it "should mount the filesystem if it isn't mounted" do
current_resource.enabled.should be_false
current_resource.mounted.should be_false
@@ -170,10 +162,6 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag do
end
describe "when the filesystem should be remounted and the resource supports remounting" do
- after do
- cleanup_mount(new_resource.mount_point)
- end
-
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)
@@ -192,40 +180,28 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag do
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
- before do
- new_resource.run_action(:mount)
- end
-
after do
new_resource.run_action(:disable)
- cleanup_mount(new_resource.mount_point)
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
- before do
+ it "should disable the mount if it is enabled" do
new_resource.run_action(:mount)
new_resource.run_action(:enable)
- end
-
- after do
- cleanup_mount(new_resource.mount_point)
- end
-
- it "should disable the mount if it is enabled" do
new_resource.run_action(:disable)
mount_should_be_disabled(new_resource.mount_point)
end
end
-end \ No newline at end of file
+end
diff --git a/spec/functional/resource/package_spec.rb b/spec/functional/resource/package_spec.rb
index 24ad96d135..797f308cf9 100644
--- a/spec/functional/resource/package_spec.rb
+++ b/spec/functional/resource/package_spec.rb
@@ -202,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")
@@ -210,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
@@ -275,6 +273,23 @@ describe Chef::Resource::Package, metadata do
package_resource.should be_updated_by_last_action
end
+ context "with variables" do
+ let(:package_resource) do
+ r = base_resource
+ r.cookbook_name = "preseed"
+ r.response_file("preseed-template-variables.seed")
+ r.response_file_variables({ :template_variable => 'SUPPORTS VARIABLES' })
+ r
+ end
+
+ it "preseeds the package, then installs it" do
+ package_resource.run_action(:install)
+ cmd = shell_out!("debconf-show chef-integration-test")
+ cmd.stdout.should include('chef-integration-test/sample-var: "SUPPORTS VARIABLES"')
+ package_resource.should be_updated_by_last_action
+ end
+ end
+
end
end # installing w/ preseed
end # when package not installed
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 7662ec7331..2d24eee6a3 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
@@ -113,21 +111,21 @@ describe Chef::Resource::RegistryKey, :windows_only do
before do
@node.name("windowsbox")
- @rest_client = mock("Chef::REST (mock)")
- @rest_client.stub!(:create_url).and_return("reports/nodes/windowsbox/runs/#{@run_id}");
- @rest_client.stub!(:raw_http_request).and_return({"result"=>"ok"});
- @rest_client.stub!(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/windowsbox/runs/#{@run_id}"});
+ @rest_client = double("Chef::REST (mock)")
+ @rest_client.stub(:create_url).and_return("reports/nodes/windowsbox/runs/#{@run_id}");
+ @rest_client.stub(:raw_http_request).and_return({"result"=>"ok"});
+ @rest_client.stub(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/windowsbox/runs/#{@run_id}"});
@resource_reporter = Chef::ResourceReporter.new(@rest_client)
@events.register(@resource_reporter)
- @run_id = @resource_reporter.run_id
@run_status = Chef::RunStatus.new(@node, @events)
-
@resource_reporter.run_started(@run_status)
+ @run_id = @resource_reporter.run_id
+
@new_resource.cookbook_name = "monkey"
- @cookbook_version = mock("Cookbook::Version", :version => "1.2.3")
- @new_resource.stub!(:cookbook_version).and_return(@cookbook_version)
+ @cookbook_version = double("Cookbook::Version", :version => "1.2.3")
+ @new_resource.stub(:cookbook_version).and_return(@cookbook_version)
end
after (:all) do
@@ -259,18 +257,15 @@ 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')
@new_resource.values([{:name=>"BriskWalk",:type=>:string,:data=>"is good for health"}])
@new_resource.recursive(false)
- lambda{@new_resource.run_action(:create)}.should_not raise_error
+ @new_resource.run_action(:create) # should not raise_error
@registry.key_exists?(reg_child + '\Slitheen').should == false
@registry.key_exists?(reg_child + '\Slitheen\Raxicoricofallapatorius').should == false
end
@@ -373,18 +368,15 @@ 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')
@new_resource.values([{:name=>"BriskWalk",:type=>:string,:data=>"is good for health"}])
@new_resource.recursive(false)
- lambda{@new_resource.run_action(:create_if_missing)}.should_not raise_error
+ @new_resource.run_action(:create_if_missing) # should not raise_error
@registry.key_exists?(reg_child + '\Zygons').should == false
@registry.key_exists?(reg_child + '\Zygons\Zygor').should == false
end
@@ -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"}])
@@ -549,19 +538,15 @@ 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')
@new_resource.values([{:name=>"BriskWalk",:type=>:string,:data=>"is good for health"}])
@new_resource.recursive(false)
@new_resource.run_action(:delete_key)
- @new_resource.should_not raise_error(ArgumentError)
end
it "does nothing if the action is delete_key" do
@new_resource.key(reg_parent + '\OpscodeWhyRun')
diff --git a/spec/functional/resource/remote_file_spec.rb b/spec/functional/resource/remote_file_spec.rb
index 9d68389a77..bfc09dccd9 100644
--- a/spec/functional/resource/remote_file_spec.rb
+++ b/spec/functional/resource/remote_file_spec.rb
@@ -83,6 +83,19 @@ describe Chef::Resource::RemoteFile do
stop_tiny_server
end
+ describe "when redownload isn't necessary" do
+ let(:source) { 'http://localhost:9000/seattle_capo.png' }
+
+ before do
+ @api.get("/seattle_capo.png", 304, "", { 'Etag' => 'abcdef' } )
+ end
+
+ it "does not fetch the file" do
+ resource.run_action(:create)
+ end
+
+ end
+
context "when using normal encoding" do
let(:source) { 'http://localhost:9000/nyan_cat.png' }
let(:expected_content) do
@@ -112,6 +125,7 @@ describe Chef::Resource::RemoteFile do
it_behaves_like "a securable resource with reporting"
end
+
end
context "when fetching files over HTTPS" do
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..434faec408 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
@@ -195,7 +196,7 @@ describe Chef::Resource::User, metadata do
pw_entry.home.should == "/home/#{username}"
end
- if OHAI_SYSTEM["platform_family"] == "rhel"
+ if %w{rhel fedora}.include?(OHAI_SYSTEM["platform_family"])
# Inconsistent behavior. See: CHEF-2205
it "creates the home dir when not explicitly asked to on RHEL (XXX)" do
File.should exist("/home/#{username}")
@@ -339,7 +340,7 @@ describe Chef::Resource::User, metadata do
let(:existing_manage_home) { false }
let(:manage_home) { true }
- if OHAI_SYSTEM["platform_family"] == "rhel"
+ if %w{rhel fedora}.include?(OHAI_SYSTEM["platform_family"])
# Inconsistent behavior. See: CHEF-2205
it "created the home dir b/c of CHEF-2205 so it still exists" do
# This behavior seems contrary to expectation and non-convergent.
@@ -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..3fe77ff7ff 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,10 +160,10 @@ 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)
+ lambda { run_lock.acquire }.should_not raise_error
File.should exist(lockfile)
end
@@ -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/version_spec.rb b/spec/functional/version_spec.rb
new file mode 100644
index 0000000000..a342206161
--- /dev/null
+++ b/spec/functional/version_spec.rb
@@ -0,0 +1,35 @@
+#
+# Author:: Serdar Sutay (<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 File.expand_path('../../spec_helper', __FILE__)
+require 'chef/mixin/shell_out'
+require 'chef/version'
+require 'ohai/version'
+
+describe "Chef Versions" do
+ include Chef::Mixin::ShellOut
+ let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..") }
+
+ binaries = [ "chef-client", "chef-shell", "chef-apply", "knife", "chef-solo" ]
+
+ binaries.each do |binary|
+ it "#{binary} version should be sane" do
+ shell_out!("ruby #{File.join("bin", binary)} -v", :cwd => chef_dir).stdout.chomp.should == "Chef: #{Chef::VERSION}"
+ end
+ end
+
+end
diff --git a/spec/functional/win32/versions_spec.rb b/spec/functional/win32/versions_spec.rb
index 5cf3a13fd8..0b8a65114c 100644
--- a/spec/functional/win32/versions_spec.rb
+++ b/spec/functional/win32/versions_spec.rb
@@ -44,21 +44,60 @@ 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
end
+ def for_each_windows_version(&block)
+ @version.methods.each do |method_name|
+ if Chef::ReservedNames::Win32::Version::WIN_VERSIONS.keys.find { | key | method_name.to_s == Chef::ReservedNames::Win32::Version.send(:method_name_from_marketing_name,key) }
+ yield method_name
+ end
+ end
+ end
+
+ context "Win32 version object" do
+ it "should have have one method for each marketing version" do
+ versions = 0
+ for_each_windows_version { versions += 1 }
+ versions.should > 0
+ versions.should == Chef::ReservedNames::Win32::Version::WIN_VERSIONS.length
+ end
+
+ it "should only contain version methods with legal method names" do
+ method_name_pattern = /[a-z]+([a-z]|[0-9]|_)*\?{0,1}/
+
+ for_each_windows_version do |method_name|
+ method_match = method_name_pattern.match(method_name.to_s)
+ method_match.should_not be_nil
+ method_name.to_s.should == method_match[0]
+ end
+ end
+
+ it "should have exactly one method that returns true" do
+ true_versions = 0
+ for_each_windows_version do |method_name|
+ true_versions += 1 if @version.send(method_name)
+ end
+ true_versions.should == 1
+ end
+
+ it "should successfully execute all version methods" do
+ for_each_windows_version { |method_name| @version.send(method_name.to_sym) }
+ end
+ end
+
context "Windows Operating System version" do
it "should match the version from WMI" 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..6357f1e2c0
--- /dev/null
+++ b/spec/integration/client/client_spec.rb
@@ -0,0 +1,233 @@
+require 'support/shared/integration/integration_helper'
+require 'chef/mixin/shell_out'
+
+describe "chef-client" do
+ extend IntegrationSupport
+ include Chef::Mixin::ShellOut
+
+ let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..", "bin") }
+
+ # Invoke `chef-client` as `ruby PATH/TO/chef-client`. This ensures the
+ # following constraints are satisfied:
+ # * Windows: windows can only run batch scripts as bare executables. Rubygems
+ # creates batch wrappers for installed gems, but we don't have batch wrappers
+ # in the source tree.
+ # * Other `chef-client` in PATH: A common case is running the tests on a
+ # machine that has omnibus chef installed. In that case we need to ensure
+ # we're running `chef-client` from the source tree and not the external one.
+ # cf. CHEF-4914
+ let(:chef_client) { "ruby #{chef_dir}/chef-client" }
+
+ 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
+
+ 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
+ result = shell_out("#{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
+ result = shell_out("#{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
+ result = shell_out("#{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
+ result = shell_out("#{chef_client} -z -o 'x::default' --config-file-jail \"#{path_to('')}\"", :cwd => path_to(''))
+ # FATAL: Configuration error NoMethodError: undefined method `xxx' for nil:NilClass
+ result.stdout.should include("xxx")
+ end
+
+ it 'fails to load .chef/knife.rb when -z is specified and --config-file-jail does not include the .chef/knife.rb' do
+ result = shell_out("#{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
+
+ 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').inspect}
+cookbook_path #{path_to('cookbooks').inspect}
+EOM
+
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'x::default'", :cwd => chef_dir)
+ result.error!
+ end
+
+ it "should run recipes specified directly on the command line" do
+ file 'config/client.rb', <<EOM
+local_mode true
+client_key #{path_to('mykey.pem').inspect}
+cookbook_path #{path_to('cookbooks').inspect}
+EOM
+
+ file 'arbitrary.rb', <<EOM
+file #{path_to('tempfile.txt').inspect} do
+ content '1'
+end
+EOM
+
+ file 'arbitrary2.rb', <<EOM
+file #{path_to('tempfile2.txt').inspect} do
+ content '2'
+end
+EOM
+
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" #{path_to('arbitrary.rb')} #{path_to('arbitrary2.rb')}", :cwd => chef_dir)
+ result.error!
+
+ IO.read(path_to('tempfile.txt')).should == '1'
+ IO.read(path_to('tempfile2.txt')).should == '2'
+ end
+
+ it "should run recipes specified as relative paths directly on the command line" do
+ file 'config/client.rb', <<EOM
+local_mode true
+client_key #{path_to('mykey.pem').inspect}
+cookbook_path #{path_to('cookbooks').inspect}
+EOM
+
+ file 'arbitrary.rb', <<EOM
+file #{path_to('tempfile.txt').inspect} do
+ content '1'
+end
+EOM
+
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" arbitrary.rb", :cwd => path_to(''))
+ result.error!
+
+ IO.read(path_to('tempfile.txt')).should == '1'
+ end
+
+ it "should run recipes specified directly on the command line AFTER recipes in the run list" do
+ file 'config/client.rb', <<EOM
+local_mode true
+client_key #{path_to('mykey.pem').inspect}
+cookbook_path #{path_to('cookbooks').inspect}
+EOM
+
+ file 'cookbooks/x/recipes/constant_definition.rb', <<EOM
+class ::Blah
+ THECONSTANT = '1'
+end
+EOM
+ file 'arbitrary.rb', <<EOM
+file #{path_to('tempfile.txt').inspect} do
+ content ::Blah::THECONSTANT
+end
+EOM
+
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o x::constant_definition arbitrary.rb", :cwd => path_to(''))
+ result.error!
+
+ IO.read(path_to('tempfile.txt')).should == '1'
+ 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
+
+ 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
+
+ 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
+
+ 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 setting the run list with -r" do
+ file 'config/client.rb', <<EOM
+chef_server_url 'http://omg.com/blah'
+cookbook_path "#{path_to('cookbooks')}"
+EOM
+
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -r 'x::default' -z", :cwd => chef_dir)
+ result.stdout.should_not include("Overridden Run List")
+ result.stdout.should include("Run List is [recipe[x::default]]")
+ #puts result.stdout
+ result.error!
+ end
+
+ end
+end
diff --git a/spec/integration/client/ipv6_spec.rb b/spec/integration/client/ipv6_spec.rb
new file mode 100644
index 0000000000..141715318b
--- /dev/null
+++ b/spec/integration/client/ipv6_spec.rb
@@ -0,0 +1,133 @@
+#
+# 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 'support/shared/integration/integration_helper'
+require 'chef/mixin/shell_out'
+
+describe "chef-client" do
+ extend IntegrationSupport
+ include Chef::Mixin::ShellOut
+
+ let(:chef_zero_opts) { {:host => "::1"} }
+
+ let(:validation_pem) do
+ <<-END_VALIDATION_PEM
+-----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-----
+END_VALIDATION_PEM
+ end
+
+ let(:cache_path) do
+ Dir.mktmpdir
+ end
+
+ let(:basic_config_file) do
+ <<-END_CLIENT_RB
+chef_server_url "http://[::1]:8889"
+validation_key '#{path_to('config/validator.pem')}'
+cache_path '#{cache_path}'
+client_key '#{cache_path}/client.pem'
+END_CLIENT_RB
+ end
+
+ let(:client_rb_content) do
+ basic_config_file
+ end
+
+
+ let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..", "bin") }
+
+ let(:chef_client_cmd) { %Q[chef-client -c "#{path_to('config/client.rb')}" -lwarn] }
+
+ after do
+ FileUtils.rm_rf(cache_path)
+ end
+
+ # Some Solaris test platforms are too old for IPv6. These tests should not
+ # otherwise be platform dependent, so exclude solaris
+ when_the_chef_server "is running on IPv6", :not_supported_on_solaris do
+
+ when_the_repository "has a cookbook with a no-op recipe" do
+ cookbook 'noop', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }, "recipes" => {"default.rb" => "#raise 'foo'"}
+ before do
+ file 'config/client.rb', client_rb_content
+ file 'config/validator.pem', validation_pem
+ end
+
+ it "should complete with success" do
+ result = shell_out("#{chef_client_cmd} -o 'noop::default'", :cwd => chef_dir)
+ result.error!
+ end
+
+ end
+
+ when_the_repository "has a cookbook that hits server APIs" do
+
+ recipe=<<-END_RECIPE
+ actual_item = data_bag_item("expect_bag", "expect_item")
+ if actual_item.key?("expect_key") and actual_item["expect_key"] == "expect_value"
+ Chef::Log.info "lookin good"
+ else
+ Chef::Log.error("!" * 80)
+ raise "unexpected data bag item content \#{actual_item.inspect}"
+ Chef::Log.error("!" * 80)
+ end
+
+ END_RECIPE
+
+ data_bag('expect_bag', { 'expect_item' => {"expect_key" => "expect_value"} })
+
+ cookbook 'api-smoke-test', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }, "recipes" => {"default.rb" => recipe}
+
+ before do
+ file 'config/client.rb', client_rb_content
+ file 'config/validator.pem', validation_pem
+ end
+
+ it "should complete with success" do
+ result = shell_out("#{chef_client_cmd} -o 'api-smoke-test::default'", :cwd => chef_dir)
+ result.error!
+ end
+
+ 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/cookbook_api_ipv6_spec.rb b/spec/integration/knife/cookbook_api_ipv6_spec.rb
new file mode 100644
index 0000000000..bde449ee71
--- /dev/null
+++ b/spec/integration/knife/cookbook_api_ipv6_spec.rb
@@ -0,0 +1,111 @@
+#
+# 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 'support/shared/integration/integration_helper'
+require 'chef/mixin/shell_out'
+
+describe "Knife cookbook API integration with IPv6" do
+ extend IntegrationSupport
+ include Chef::Mixin::ShellOut
+
+ when_the_chef_server "is bound to IPv6" do
+ let(:chef_zero_opts) { {:host => "::1"} }
+
+ let(:client_key) do
+ <<-END_VALIDATION_PEM
+-----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-----
+END_VALIDATION_PEM
+ end
+
+ let(:cache_path) do
+ Dir.mktmpdir
+ end
+
+ let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..", "bin") }
+
+ let(:knife_config_flag) { "-c '#{path_to("config/knife.rb")}'" }
+
+ # Some Solaris test platforms are too old for IPv6. These tests should not
+ # otherwise be platform dependent, so exclude solaris
+ context "and the chef_server_url contains an IPv6 literal", :not_supported_on_solaris do
+
+ # This provides helper functions we need such as #path_to()
+ when_the_repository "has the cookbook to be uploaded" do
+
+ let(:knife_rb_content) do
+ <<-END_CLIENT_RB
+chef_server_url "http://[::1]:8889"
+syntax_check_cache_path '#{cache_path}'
+client_key '#{path_to('config/knifeuser.pem')}'
+node_name 'whoisthisis'
+cookbook_path '#{CHEF_SPEC_DATA}/cookbooks'
+END_CLIENT_RB
+ end
+
+ before do
+ file 'config/knife.rb', knife_rb_content
+ file 'config/knifeuser.pem', client_key
+ end
+
+ it "successfully uploads a cookbook" do
+ shell_out!("knife cookbook upload apache2 #{knife_config_flag}", :cwd => chef_dir)
+ versions_list_json = Chef::HTTP::Simple.new("http://[::1]:8889").get("/cookbooks/apache2", "accept" => "application/json")
+ versions_list = Chef::JSONCompat.from_json(versions_list_json)
+ versions_list["apache2"]["versions"].should_not be_empty
+ end
+
+ context "and the cookbook has been uploaded to the server" do
+ before do
+ shell_out!("knife cookbook upload apache2 #{knife_config_flag}", :cwd => chef_dir)
+ end
+
+ it "downloads the cookbook" do
+ s = shell_out!("knife cookbook download apache2 #{knife_config_flag} -d #{cache_path}", :cwd => chef_dir)
+ Dir["#{cache_path}/*"].map {|entry| File.basename(entry)}.should include("apache2-0.0.0")
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/spec/integration/knife/download_spec.rb b/spec/integration/knife/download_spec.rb
index a3b3b875a8..f266b47b1b 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', :ruby_gte_19_only 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..69630061ac 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)
+{ "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)
+{ "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..cd4678f94d 100644
--- a/spec/integration/solo/solo_spec.rb
+++ b/spec/integration/solo/solo_spec.rb
@@ -1,41 +1,112 @@
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
+ let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..") }
- 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', ''
+ when_the_repository "has a cookbook with a basic recipe" do
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
+ file 'cookbooks/x/recipes/default.rb', 'puts "ITWORKS"'
- before do
- @chef_file_cache = Dir.mktmpdir('file_cache')
- end
+ it "should complete with success" do
+ file 'config/solo.rb', <<EOM
+cookbook_path "#{path_to('cookbooks')}"
+file_cache_path "#{path_to('config/cache')}"
+EOM
+ result = shell_out("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir)
+ result.error!
+ result.stdout.should include("ITWORKS")
+ end
- after do
- FileUtils.rm_rf(@chef_file_cache) if @chef_file_cache
- end
+ it "should evaluate its node.json file" do
+ file 'config/solo.rb', <<EOM
+cookbook_path "#{path_to('cookbooks')}"
+file_cache_path "#{path_to('config/cache')}"
+EOM
+
+ file 'config/node.json',<<-E
+{"run_list":["x::default"]}
+E
- 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}"
+ result = shell_out("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -j '#{path_to('config/node.json')}' -l debug", :cwd => chef_dir)
+ result.error!
+ result.stdout.should include("ITWORKS")
+ end
+
+ 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 5
+ 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
- config_file = canonicalize_path(File.join(@repository_dir, 'config', 'solo.rb'))
+ # 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__), "..", "..", "..")
- 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 first chef-solo run
+ s1 = Process.spawn("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \
+-l debug -L #{path_to('logs/runs.log')}", :chdir => chef_dir)
+
+ # Give it some time to progress
+ sleep 1
+
+ # Instantiate the second chef-solo run
+ s2 = Process.spawn("ruby bin/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
+ # 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/scripts/ssl-serve.rb b/spec/scripts/ssl-serve.rb
new file mode 100644
index 0000000000..24ed70addc
--- /dev/null
+++ b/spec/scripts/ssl-serve.rb
@@ -0,0 +1,52 @@
+# ssl-serve.rb
+# USAGE: ruby ssl-serve.rb
+#
+# ssl-serve is a script that serves a local directory over SSL.
+# You can use it to test various HTTP behaviors in chef, like chef-client's
+# `-j` and `-c` options and remote_file with https connections.
+#
+require 'pp'
+require 'openssl'
+require 'webrick'
+require 'webrick/https'
+
+
+$ssl = true
+
+CHEF_SPEC_DATA = File.expand_path("../../data", __FILE__)
+cert_text = File.read(File.expand_path("ssl/chef-rspec.cert", CHEF_SPEC_DATA))
+cert = OpenSSL::X509::Certificate.new(cert_text)
+key_text = File.read(File.expand_path("ssl/chef-rspec.key", CHEF_SPEC_DATA))
+key = OpenSSL::PKey::RSA.new(key_text)
+
+server_opts = {}
+if $ssl
+server_opts.merge!( { :SSLEnable => true,
+ :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
+ :SSLCertificate => cert,
+ :SSLPrivateKey => key })
+end
+
+
+
+# 5 == debug, 3 == warning
+LOGGER = WEBrick::Log.new(STDOUT, 5)
+DEFAULT_OPTIONS = {
+ :server => 'webrick',
+ :Port => 9000,
+ :Host => 'localhost',
+ :environment => :none,
+ :Logger => LOGGER,
+ :DocumentRoot => File.expand_path("/tmp/chef-118-sampledata")
+ #:AccessLog => [] # Remove this option to enable the access log when debugging.
+}
+
+webrick_opts = DEFAULT_OPTIONS.merge(server_opts)
+pp :webrick_opts => webrick_opts
+
+server = WEBrick::HTTPServer.new(webrick_opts)
+trap 'INT' do server.shutdown end
+
+server.start
+
+
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 56d8088324..5098a1fb85 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -33,6 +33,7 @@ end
# Ruby 1.9 Compat
$:.unshift File.expand_path("../..", __FILE__)
+
require 'rubygems'
require 'rspec/mocks'
@@ -67,6 +68,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'))
@@ -83,7 +86,6 @@ Dir["spec/support/**/*.rb"].
map { |f| f.gsub(%r[spec/], '')}.
each { |f| require f }
-
OHAI_SYSTEM = Ohai::System.new
OHAI_SYSTEM.require_plugin("os")
OHAI_SYSTEM.require_plugin("platform")
@@ -100,11 +102,14 @@ RSpec.configure do |config|
# Add jruby filters here
config.filter_run_excluding :windows_only => true unless windows?
+ config.filter_run_excluding :not_supported_on_mac_osx_106 => true if mac_osx_106?
config.filter_run_excluding :not_supported_on_win2k3 => true if windows_win2k3?
config.filter_run_excluding :not_supported_on_solaris => true if solaris?
config.filter_run_excluding :win2k3_only => true unless windows_win2k3?
config.filter_run_excluding :windows64_only => true unless windows64?
config.filter_run_excluding :windows32_only => true unless windows32?
+ config.filter_run_excluding :windows_domain_joined_only => true unless windows_domain_joined?
+ config.filter_run_excluding :solaris_only => true unless solaris?
config.filter_run_excluding :system_windows_service_gem_only => true unless system_windows_service_gem?
config.filter_run_excluding :unix_only => true unless unix?
config.filter_run_excluding :supports_cloexec => true unless supports_cloexec?
@@ -114,8 +119,9 @@ 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' || ENV['LOGIN'] == 'root'
- config.filter_run_excluding :requires_unprivileged_user => true if ENV['USER'] == 'root'
+ config.filter_run_excluding :requires_root => true unless root?
+ config.filter_run_excluding :requires_root_or_running_windows => true unless (root? || windows?)
+ config.filter_run_excluding :requires_unprivileged_user => true if root?
config.filter_run_excluding :uses_diff => true unless has_diff?
running_platform_arch = `uname -m`.strip
@@ -142,4 +148,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/stress/win32/file_spec.rb b/spec/stress/win32/file_spec.rb
index ef01aa632c..22de7ecd03 100644
--- a/spec/stress/win32/file_spec.rb
+++ b/spec/stress/win32/file_spec.rb
@@ -25,10 +25,16 @@ describe 'Chef::ReservedNames::Win32::File', :windows_only do
end
it "should not leak memory" do
+ pending "Fix required for CHEF-5004"
test = lambda { Chef::ReservedNames::Win32::File.symlink?(@path) }
test.should_not leak_memory(:warmup => 50, :iterations => 100)
end
+ it "should not leak significant memory" do
+ test = lambda { Chef::ReservedNames::Win32::File.symlink?(@path) }
+ test.should_not leak_memory(:warmup => 50000, :iterations => 100)
+ end
+
it "should not leak handles" do
test = lambda { Chef::ReservedNames::Win32::File.symlink?(@path) }
test.should_not leak_handles(:warmup => 50, :iterations => 100)
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/chef/resource/zen_master.rb b/spec/support/lib/chef/resource/zen_master.rb
index 7a7076ca4b..d47d174e28 100644
--- a/spec/support/lib/chef/resource/zen_master.rb
+++ b/spec/support/lib/chef/resource/zen_master.rb
@@ -27,6 +27,7 @@ class Chef
def initialize(name, run_context=nil)
@resource_name = :zen_master
super
+ allowed_actions << :win << :score
end
def peace(tf)
@@ -34,7 +35,7 @@ class Chef
end
def something(arg=nil)
- if arg == true or arg == false
+ if !arg.nil?
@something = arg
end
@something
diff --git a/spec/support/mock/platform.rb b/spec/support/mock/platform.rb
index 78b704ea9b..df90d1eda2 100644
--- a/spec/support/mock/platform.rb
+++ b/spec/support/mock/platform.rb
@@ -6,7 +6,7 @@
# testing code that mixes in platform specific modules like +Chef::Mixin::Securable+
# or +Chef::FileAccessControl+
def platform_mock(platform = :unix, &block)
- Chef::Platform.stub!(:windows?).and_return(platform == :windows ? true : false)
+ Chef::Platform.stub(:windows?).and_return(platform == :windows ? true : false)
ENV['SYSTEMDRIVE'] = (platform == :windows ? 'C:' : nil)
if block_given?
mock_constants({"RUBY_PLATFORM" => (platform == :windows ? 'i386-mingw32' : 'x86_64-darwin11.2.0'),
diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb
index 1aea6dfad3..884893865f 100644
--- a/spec/support/platform_helpers.rb
+++ b/spec/support/platform_helpers.rb
@@ -1,4 +1,7 @@
require 'fcntl'
+require 'chef/mixin/shell_out'
+
+include Chef::Mixin::ShellOut
def ruby_gte_20?
RUBY_VERSION.to_f >= 2.0
@@ -24,14 +27,33 @@ def windows?
!!(RUBY_PLATFORM =~ /mswin|mingw|windows/)
end
+require 'ruby-wmi' if windows?
+
+def windows_domain_joined?
+ return false unless windows?
+ WMI::Win32_ComputerSystem.find(:first).PartOfDomain
+end
+
def windows_win2k3?
return false unless windows?
- require 'ruby-wmi'
host = WMI::Win32_OperatingSystem.find(:first)
(host.version && host.version.start_with?("5.2"))
end
+def mac_osx_106?
+ if File.exists? "/usr/bin/sw_vers"
+ result = shell_out("/usr/bin/sw_vers")
+ result.stdout.each_line do |line|
+ if line =~ /^ProductVersion:\s10.6.*$/
+ return true
+ end
+ end
+ end
+
+ false
+end
+
# detects if the hardware is 64-bit (evaluates to true in "WOW64" mode in a 32-bit app on a 64-bit system)
def windows64?
windows? && ( ENV['PROCESSOR_ARCHITECTURE'] == 'AMD64' || ENV['PROCESSOR_ARCHITEW6432'] == 'AMD64' )
@@ -60,6 +82,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 +113,12 @@ def selinux_enabled?
return false
end
end
+
+def suse?
+ File.exists?("/etc/SuSE-release")
+end
+
+def root?
+ return false if windows?
+ Process.euid == 0
+end
diff --git a/spec/support/shared/functional/file_resource.rb b/spec/support/shared/functional/file_resource.rb
index 30f012bb0d..ccb224ab71 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
@@ -70,26 +54,62 @@ shared_examples_for "a file with the wrong content" do
sha256_checksum(path).should == @expected_checksum
end
- include_context "diff disabled"
+ describe "when diff is disabled" 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)
+ include_context "diff disabled"
+
+ context "when running action :create" do
+ context "with backups enabled" do
+ before do
+ resource.run_action(:create)
+ end
+
+ it "overwrites the file with the updated content when the :create action is run" do
+ File.stat(path).mtime.should > @expected_mtime
+ sha256_checksum(path).should_not == @expected_checksum
+ end
+
+ it "backs up the existing file" do
+ Dir.glob(backup_glob).size.should equal(1)
+ end
+
+ it "is marked as updated by last action" do
+ resource.should be_updated_by_last_action
+ end
+
+ it "should restore the security contexts on selinux", :selinux_only do
+ selinux_security_context_restored?(path).should be_true
+ end
end
- it "overwrites the file with the updated content when the :create action is run" do
- File.stat(path).mtime.should > @expected_mtime
- sha256_checksum(path).should_not == @expected_checksum
+ context "with backups disabled" do
+ before do
+ resource.backup(0)
+ resource.run_action(:create)
+ end
+
+ it "should not attempt to backup the existing file if :backup == 0" do
+ Dir.glob(backup_glob).size.should equal(0)
+ end
+
+ it "should restore the security contexts on selinux", :selinux_only do
+ selinux_security_context_restored?(path).should be_true
+ end
end
+ end
- it "backs up the existing file" do
- Dir.glob(backup_glob).size.should equal(1)
+ describe "when running action :create_if_missing" do
+ before do
+ resource.run_action(:create_if_missing)
end
- it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ it "doesn't overwrite the file when the :create_if_missing action is run" do
+ File.stat(path).mtime.should == @expected_mtime
+ sha256_checksum(path).should == @expected_checksum
+ end
+
+ it "is not marked as updated" do
+ resource.should_not be_updated_by_last_action
end
it "should restore the security contexts on selinux", :selinux_only do
@@ -97,53 +117,53 @@ shared_examples_for "a file with the wrong content" do
end
end
- context "with backups disabled" do
+ describe "when running action :delete" do
before do
- Chef::Config[:file_backup_path] = CHEF_SPEC_BACKUP_PATH
- resource.backup(0)
- resource.run_action(:create)
+ resource.run_action(:delete)
end
- it "should not attempt to backup the existing file if :backup == 0" do
- Dir.glob(backup_glob).size.should equal(0)
+ it "deletes the file" do
+ File.should_not exist(path)
end
- it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
+ it "is marked as updated by last action" do
+ resource.should be_updated_by_last_action
end
end
+
end
- describe "when running action :create_if_missing" do
- before do
- resource.run_action(:create_if_missing)
- end
+ context "when diff is enabled" do
+ describe 'sensitive attribute' do
+ context "should be insensitive by default" do
+ it { expect(resource.sensitive).to(be_false) }
+ end
- it "doesn't overwrite the file when the :create_if_missing action is run" do
- File.stat(path).mtime.should == @expected_mtime
- sha256_checksum(path).should == @expected_checksum
- end
+ context "when set" do
+ before { resource.sensitive(true) }
- it "is not marked as updated" do
- resource.should_not be_updated_by_last_action
- end
+ it "should be set on the resource" do
+ expect(resource.sensitive).to(be_true)
+ end
- it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
- end
- end
+ context "when running :create action" do
+ let(:provider) { resource.provider_for_action(:create) }
+ let(:reporter_messages) { provider.instance_variable_get("@converge_actions").actions[0][0] }
- describe "when running action :delete" do
- before do
- resource.run_action(:delete)
- end
+ before do
+ provider.run_action
+ end
- it "deletes the file" do
- File.should_not exist(path)
- end
+ it "should suppress the diff" do
+ expect(resource.diff).to(include('suppressed sensitive resource'))
+ expect(reporter_messages[1]).to eq("suppressed sensitive resource")
+ end
- it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ it "should still include the updated checksums" do
+ expect(reporter_messages[0]).to include("update content in file")
+ end
+ end
+ end
end
end
end
@@ -895,6 +915,43 @@ shared_examples_for "a configured file resource" do
end
end
+ # Regression test for http://tickets.opscode.com/browse/CHEF-4419
+ context "when the path starts with '/' and target file exists", :windows_only do
+ let(:path) do
+ File.join(test_file_dir[2..test_file_dir.length], make_tmpname(file_base))
+ end
+
+ before do
+ File.open(path, "wb") { |f| f.print expected_content }
+ now = Time.now.to_i
+ File.utime(now - 9000, now - 9000, path)
+
+ @expected_mtime = File.stat(path).mtime
+ @expected_checksum = sha256_checksum(path)
+ end
+
+ describe ":create action should run without any updates" do
+ before do
+ # Assert starting state is as expected
+ File.should exist(path)
+ sha256_checksum(path).should == @expected_checksum
+ resource.run_action(:create)
+ end
+
+ it "does not overwrite the original when the :create action is run" do
+ sha256_checksum(path).should == @expected_checksum
+ end
+
+ it "does not update the mtime of the file when the :create action is run" do
+ File.stat(path).mtime.should == @expected_mtime
+ end
+
+ it "is not marked as updated by last action" do
+ resource.should_not be_updated_by_last_action
+ end
+ end
+ end
+
end
shared_context Chef::Resource::File do
diff --git a/spec/support/shared/functional/securable_resource.rb b/spec/support/shared/functional/securable_resource.rb
index 3952b783dc..48daf78ae3 100644
--- a/spec/support/shared/functional/securable_resource.rb
+++ b/spec/support/shared/functional/securable_resource.rb
@@ -482,7 +482,7 @@ shared_examples_for "a securable resource without existing target" do
it 'warns when mode tries to set owner bits but owner is not specified' do
@warn = []
- Chef::Log.stub!(:warn) { |msg| @warn << msg }
+ Chef::Log.stub(:warn) { |msg| @warn << msg }
resource.mode 0400
resource.run_action(:create)
@@ -492,7 +492,7 @@ shared_examples_for "a securable resource without existing target" do
it 'warns when mode tries to set group bits but group is not specified' do
@warn = []
- Chef::Log.stub!(:warn) { |msg| @warn << msg }
+ Chef::Log.stub(:warn) { |msg| @warn << msg }
resource.mode 0040
resource.run_action(:create)
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/api_error_inspector.rb b/spec/support/shared/unit/api_error_inspector.rb
index 8231ceb195..b59fbce2c7 100644
--- a/spec/support/shared/unit/api_error_inspector.rb
+++ b/spec/support/shared/unit/api_error_inspector.rb
@@ -72,7 +72,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "synchronize the clock on your host"
@response = Net::HTTPUnauthorized.new("1.1", "401", "(response) unauthorized")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -88,7 +88,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "check your key and node name"
@response = Net::HTTPUnauthorized.new("1.1", "401", "(response) unauthorized")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -104,7 +104,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "forbidden"
@response = Net::HTTPForbidden.new("1.1", "403", "(response) forbidden")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) forbidden", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -120,7 +120,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "didn't like your data"
@response = Net::HTTPBadRequest.new("1.1", "400", "(response) bad request")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) bad request", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -136,7 +136,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "probably caused by a redirect to a get"
@response = Net::HTTPNotFound.new("1.1", "404", "(response) not found")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) not found", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -151,7 +151,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "sad trombone"
@response = Net::HTTPInternalServerError.new("1.1", "500", "(response) internal server error")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPFatalError.new("(exception) internal server error", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -166,7 +166,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "sad trombone orchestra"
@response = Net::HTTPBadGateway.new("1.1", "502", "(response) bad gateway")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPFatalError.new("(exception) bad gateway", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
diff --git a/spec/support/shared/unit/provider/file.rb b/spec/support/shared/unit/provider/file.rb
index 11e991d830..02f68e0acc 100644
--- a/spec/support/shared/unit/provider/file.rb
+++ b/spec/support/shared/unit/provider/file.rb
@@ -35,50 +35,117 @@ def normalized_path
File.expand_path(resource_path)
end
+# forwards-vs-reverse slashes on windows sucks
+def windows_path
+ windows? ? normalized_path.gsub(/\\/, '/') : normalized_path
+end
+
+# this is all getting a bit stupid, CHEF-4802 cut to remove all this
def setup_normal_file
- File.stub!(:exists?).with(resource_path).and_return(true)
- File.stub!(:directory?).with(resource_path).and_return(false)
- File.stub!(:directory?).with(enclosing_directory).and_return(true)
- File.stub!(:writable?).with(resource_path).and_return(true)
- file_symlink_class.stub!(:symlink?).with(resource_path).and_return(false)
- file_symlink_class.stub!(:symlink?).with(normalized_path).and_return(false)
+ [ resource_path, normalized_path, windows_path].each do |path|
+ File.stub(:file?).with(path).and_return(true)
+ File.stub(:exists?).with(path).and_return(true)
+ File.stub(:exist?).with(path).and_return(true)
+ File.stub(:directory?).with(path).and_return(false)
+ File.stub(:writable?).with(path).and_return(true)
+ file_symlink_class.stub(:symlink?).with(path).and_return(false)
+ File.stub(:realpath?).with(path).and_return(normalized_path)
+ end
+ File.stub(:directory?).with(enclosing_directory).and_return(true)
end
def setup_missing_file
- File.stub!(:exists?).with(resource_path).and_return(false)
- File.stub!(:directory?).with(resource_path).and_return(false)
- File.stub!(:directory?).with(enclosing_directory).and_return(true)
- File.stub!(:writable?).with(resource_path).and_return(false)
- file_symlink_class.stub!(:symlink?).with(resource_path).and_return(false)
+ [ resource_path, normalized_path, windows_path].each do |path|
+ File.stub(:file?).with(path).and_return(false)
+ File.stub(:realpath?).with(path).and_return(resource_path)
+ File.stub(:exists?).with(path).and_return(false)
+ File.stub(:exist?).with(path).and_return(false)
+ File.stub(:directory?).with(path).and_return(false)
+ File.stub(:writable?).with(path).and_return(false)
+ file_symlink_class.stub(:symlink?).with(path).and_return(false)
+ end
+ File.stub(:directory?).with(enclosing_directory).and_return(true)
end
def setup_symlink
- File.stub!(:exists?).with(resource_path).and_return(true)
- File.stub!(:directory?).with(normalized_path).and_return(false)
- File.stub!(:directory?).with(enclosing_directory).and_return(true)
- File.stub!(:writable?).with(resource_path).and_return(true)
- file_symlink_class.stub!(:symlink?).with(resource_path).and_return(true)
- file_symlink_class.stub!(:symlink?).with(normalized_path).and_return(true)
+ [ resource_path, normalized_path, windows_path].each do |path|
+ File.stub(:file?).with(path).and_return(true)
+ File.stub(:realpath?).with(path).and_return(normalized_path)
+ File.stub(:exists?).with(path).and_return(true)
+ File.stub(:exist?).with(path).and_return(true)
+ File.stub(:directory?).with(path).and_return(false)
+ File.stub(:writable?).with(path).and_return(true)
+ file_symlink_class.stub(:symlink?).with(path).and_return(true)
+ end
+ File.stub(:directory?).with(enclosing_directory).and_return(true)
end
def setup_unwritable_file
- File.stub!(:exists?).with(resource_path).and_return(true)
- File.stub!(:directory?).with(resource_path).and_return(false)
- File.stub!(:directory?).with(enclosing_directory).and_return(true)
- File.stub!(:writable?).with(resource_path).and_return(false)
- file_symlink_class.stub!(:symlink?).with(resource_path).and_return(false)
+ [ resource_path, normalized_path, windows_path].each do |path|
+ File.stub(:file?).with(path).and_return(false)
+ File.stub(:realpath?).with(path).and_raise(Errno::ENOENT)
+ File.stub(:exists?).with(path).and_return(true)
+ File.stub(:exist?).with(path).and_return(true)
+ File.stub(:directory?).with(path).and_return(false)
+ File.stub(:writable?).with(path).and_return(false)
+ file_symlink_class.stub(:symlink?).with(path).and_return(false)
+ end
+ File.stub(:directory?).with(enclosing_directory).and_return(true)
end
def setup_missing_enclosing_directory
- File.stub!(:exists?).with(resource_path).and_return(false)
- File.stub!(:directory?).with(resource_path).and_return(false)
- File.stub!(:directory?).with(enclosing_directory).and_return(false)
- File.stub!(:writable?).with(resource_path).and_return(false)
- file_symlink_class.stub!(:symlink?).with(resource_path).and_return(false)
+ [ resource_path, normalized_path, windows_path].each do |path|
+ File.stub(:file?).with(path).and_return(false)
+ File.stub(:realpath?).with(path).and_raise(Errno::ENOENT)
+ File.stub(:exists?).with(path).and_return(false)
+ File.stub(:exist?).with(path).and_return(false)
+ File.stub(:directory?).with(path).and_return(false)
+ File.stub(:writable?).with(path).and_return(false)
+ file_symlink_class.stub(:symlink?).with(path).and_return(false)
+ end
+ File.stub(:directory?).with(enclosing_directory).and_return(false)
+end
+
+# A File subclass that we use as a replacement for Tempfile. Some versions of
+# Tempfile call `File.exist?()` internally which will cause test failures if
+# `File.exist?()` has been stubbed.
+class BasicTempfile < ::File
+
+ def self.make_tmp_path(basename)
+ slug = "#{basename}-#{rand(1 << 128)}"
+ File.join(Dir.tmpdir, slug)
+ end
+
+ def self.new(basename)
+ super(make_tmp_path(basename), File::RDWR|File::CREAT|File::EXCL, 0600)
+ end
+
+ def unlink
+ self.class.unlink(path)
+ end
+
end
shared_examples_for Chef::Provider::File do
+ let(:tempfile_path) do
+ end
+
+ let!(:tempfile) do
+ BasicTempfile.new("rspec-shared-file-provider")
+ end
+
+ before(:each) do
+ content.stub(:tempfile).and_return(tempfile)
+ File.stub(:exist?).with(tempfile.path).and_call_original
+ File.stub(:exists?).with(tempfile.path).and_call_original
+ end
+
+ after do
+ tempfile.close if (tempfile && !tempfile.closed?)
+ File.unlink(tempfile.path) rescue nil
+ end
+
it "should return a #{described_class}" do
provider.should be_a_kind_of(described_class)
end
@@ -93,63 +160,109 @@ shared_examples_for Chef::Provider::File do
context "when loading the current resource" do
+ context "when running load_current_resource" do
+ #
+ # the content objects need the current_resource to be loaded (esp remote_file), so calling
+ # for content inside of load_current_resource is totally crossing the streams...
+ #
+ it "should not try to load the content when the file is present" do
+ setup_normal_file
+ provider.should_not_receive(:tempfile)
+ provider.should_not_receive(:content)
+ provider.load_current_resource
+ end
+
+ it "should not try to load the content when the file is missing" do
+ setup_missing_file
+ provider.should_not_receive(:tempfile)
+ provider.should_not_receive(:content)
+ provider.load_current_resource
+ end
+ end
+
context "when running load_current_resource and the file exists" do
before do
setup_normal_file
- provider.load_current_resource
end
+ let(:tempfile_sha256) { "42971f0ddce0cb20cf7660a123ffa1a1543beb2f1e7cd9d65858764a27f3201d" }
+
it "should load a current resource based on the one specified at construction" do
+ provider.load_current_resource
provider.current_resource.should be_a_kind_of(Chef::Resource::File)
end
it "the loaded current_resource name should be the same as the resource name" do
+ provider.load_current_resource
provider.current_resource.name.should eql(resource.name)
end
it "the loaded current_resource path should be the same as the resoure path" do
+ provider.load_current_resource
provider.current_resource.path.should eql(resource.path)
end
it "the loaded current_resource content should be nil" do
+ provider.load_current_resource
provider.current_resource.content.should eql(nil)
end
+
+ it "it should call checksum if we are managing content" do
+ provider.should_receive(:managing_content?).at_least(:once).and_return(true)
+ provider.should_receive(:checksum).with(resource.path).and_return(tempfile_sha256)
+ provider.load_current_resource
+ end
+
+ it "it should not call checksum if we are not managing content" do
+ provider.should_receive(:managing_content?).at_least(:once).and_return(false)
+ provider.should_not_receive(:checksum)
+ provider.load_current_resource
+ end
end
context "when running load_current_resource and the file does not exist" do
before do
setup_missing_file
- provider.load_current_resource
end
it "the current_resource should be a Chef::Resource::File" do
+ provider.load_current_resource
provider.current_resource.should be_a_kind_of(Chef::Resource::File)
end
it "the current_resource name should be the same as the resource name" do
+ provider.load_current_resource
provider.current_resource.name.should eql(resource.name)
end
it "the current_resource path should be the same as the resource path" do
+ provider.load_current_resource
provider.current_resource.path.should eql(resource.path)
end
it "the loaded current_resource content should be nil" do
+ provider.load_current_resource
provider.current_resource.content.should eql(nil)
end
+
+ it "it should not call checksum if we are not managing content" do
+ provider.should_not_receive(:managing_content?)
+ provider.should_not_receive(:checksum)
+ provider.load_current_resource
+ end
end
context "examining file security metadata on Unix with a file that exists" do
before do
# fake that we're on unix even if we're on windows
- Chef::Platform.stub!(:windows?).and_return(false)
+ Chef::Platform.stub(:windows?).and_return(false)
# mock up the filesystem to behave like unix
setup_normal_file
- stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
+ stat_struct = double("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
resource_real_path = File.realpath(resource.path)
File.should_receive(:stat).with(resource_real_path).at_least(:once).and_return(stat_struct)
- Etc.stub!(:getgrgid).with(0).and_return(mock("Group Ent", :name => "wheel"))
- Etc.stub!(:getpwuid).with(0).and_return(mock("User Ent", :name => "root"))
+ Etc.stub(:getgrgid).with(0).and_return(double("Group Ent", :name => "wheel"))
+ Etc.stub(:getpwuid).with(0).and_return(double("User Ent", :name => "root"))
end
context "when the new_resource does not specify any state" do
@@ -218,7 +331,7 @@ shared_examples_for Chef::Provider::File do
context "examining file security metadata on Unix with a file that does not exist" do
before do
# fake that we're on unix even if we're on windows
- Chef::Platform.stub!(:windows?).and_return(false)
+ Chef::Platform.stub(:windows?).and_return(false)
setup_missing_file
end
@@ -267,14 +380,14 @@ shared_examples_for Chef::Provider::File do
before do
# fake that we're on unix even if we're on windows
- Chef::Platform.stub!(:windows?).and_return(false)
+ Chef::Platform.stub(:windows?).and_return(false)
# mock up the filesystem to behave like unix
setup_normal_file
- stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
+ stat_struct = double("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
resource_real_path = File.realpath(resource.path)
- File.stub!(:stat).with(resource_real_path).and_return(stat_struct)
- Etc.stub!(:getgrgid).with(0).and_return(mock("Group Ent", :name => "wheel"))
- Etc.stub!(:getpwuid).with(0).and_return(mock("User Ent", :name => "root"))
+ File.stub(:stat).with(resource_real_path).and_return(stat_struct)
+ Etc.stub(:getgrgid).with(0).and_return(double("Group Ent", :name => "wheel"))
+ Etc.stub(:getpwuid).with(0).and_return(double("User Ent", :name => "root"))
provider.send(:load_resource_attributes_from_file, resource)
end
@@ -311,7 +424,7 @@ shared_examples_for Chef::Provider::File do
it "does not raise an exception in why-run mode" do
Chef::Config[:why_run] = true
- lambda {provider.run_action(action)}.should_not raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist)
+ lambda {provider.run_action(action)}.should_not raise_error
Chef::Config[:why_run] = false
end
end
@@ -368,8 +481,9 @@ shared_examples_for Chef::Provider::File do
setup_normal_file
provider.load_current_resource
tempfile = double('Tempfile', :path => "/tmp/foo-bar-baz")
- content.stub!(:tempfile).and_return(tempfile)
+ content.stub(:tempfile).and_return(tempfile)
File.should_receive(:exists?).with("/tmp/foo-bar-baz").and_return(true)
+ tempfile.should_receive(:close).once
tempfile.should_receive(:unlink).once
end
@@ -378,11 +492,12 @@ shared_examples_for Chef::Provider::File do
let(:tempfile_sha256) { "42971f0ddce0cb20cf7660a123ffa1a1543beb2f1e7cd9d65858764a27f3201d" }
let(:diff_for_reporting) { "+++\n---\n+foo\n-bar\n" }
before do
- provider.stub!(:contents_changed?).and_return(true)
+ provider.stub(:contents_changed?).and_return(true)
diff = double('Diff', :for_output => ['+++','---','+foo','-bar'],
:for_reporting => diff_for_reporting )
- diff.stub!(:diff).with(resource_path, tempfile_path).and_return(true)
+ diff.stub(:diff).with(resource_path, tempfile_path).and_return(true)
provider.should_receive(:diff).at_least(:once).and_return(diff)
+ provider.should_receive(:managing_content?).at_least(:once).and_return(true)
provider.should_receive(:checksum).with(tempfile_path).and_return(tempfile_sha256)
provider.should_receive(:checksum).with(resource_path).and_return(tempfile_sha256)
provider.deployment_strategy.should_receive(:deploy).with(tempfile_path, normalized_path)
@@ -406,7 +521,7 @@ shared_examples_for Chef::Provider::File do
end
it "does nothing when the contents have not changed" do
- provider.stub!(:contents_changed?).and_return(false)
+ provider.stub(:contents_changed?).and_return(false)
provider.should_not_receive(:diff)
provider.send(:do_contents_changes)
end
@@ -443,7 +558,7 @@ shared_examples_for Chef::Provider::File do
before do
setup_normal_file
provider.load_current_resource
- provider.stub!(:resource_updated?).and_return(true)
+ provider.stub(:resource_updated?).and_return(true)
end
it "should check for selinux_enabled? by default" do
@@ -508,7 +623,7 @@ shared_examples_for Chef::Provider::File do
context "when resource is not updated" do
before do
- provider.stub!(:resource_updated?).and_return(false)
+ provider.stub(:resource_updated?).and_return(false)
end
it "should not check for selinux_enabled?" do
@@ -559,7 +674,7 @@ shared_examples_for Chef::Provider::File do
it "should not try to backup or delete the file, and should not be updated by last action" do
provider.should_not_receive(:do_backup)
File.should_not_receive(:delete)
- lambda { provider.run_action(:delete) }.should_not raise_error()
+ lambda { provider.run_action(:delete) }.should_not raise_error
resource.should_not be_updated_by_last_action
end
end
@@ -607,3 +722,65 @@ shared_examples_for Chef::Provider::File do
end
+shared_examples_for "a file provider with content field" do
+ context "when testing managing_content?" do
+ it "should be false when creating a file without content" do
+ provider.action = :create
+ resource.stub(:content).and_return(nil)
+ resource.stub(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_false
+ end
+ it "should be true when creating a file with content" do
+ provider.action = :create
+ resource.stub(:content).and_return("flurbleblobbleblooble")
+ resource.stub(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_true
+ end
+ it "should be true when checksum is set on the content (no matter how crazy)" do
+ provider.action = :create_if_missing
+ resource.stub(:checksum).and_return("1234123234234234")
+ resource.stub(:content).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_true
+ end
+ it "should be false when action is create_if_missing" do
+ provider.action = :create_if_missing
+ resource.stub(:content).and_return("flurbleblobbleblooble")
+ resource.stub(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_false
+ end
+ end
+end
+
+shared_examples_for "a file provider with source field" do
+ context "when testing managing_content?" do
+ it "should be false when creating a file without content" do
+ provider.action = :create
+ resource.stub(:content).and_return(nil)
+ resource.stub(:source).and_return(nil)
+ resource.stub(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_false
+ end
+ it "should be true when creating a file with content" do
+ provider.action = :create
+ resource.stub(:content).and_return(nil)
+ resource.stub(:source).and_return("http://somewhere.com/something.php")
+ resource.stub(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_true
+ end
+ it "should be true when checksum is set on the content (no matter how crazy)" do
+ provider.action = :create_if_missing
+ resource.stub(:content).and_return(nil)
+ resource.stub(:source).and_return(nil)
+ resource.stub(:checksum).and_return("1234123234234234")
+ expect(provider.send(:managing_content?)).to be_true
+ end
+ it "should be false when action is create_if_missing" do
+ provider.action = :create_if_missing
+ resource.stub(:content).and_return(nil)
+ resource.stub(:source).and_return("http://somewhere.com/something.php")
+ resource.stub(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_false
+ end
+ end
+end
+
diff --git a/spec/support/shared/unit/provider/useradd_based_user_provider.rb b/spec/support/shared/unit/provider/useradd_based_user_provider.rb
index 3b8f8678bf..a95d19d33c 100644
--- a/spec/support/shared/unit/provider/useradd_based_user_provider.rb
+++ b/spec/support/shared/unit/provider/useradd_based_user_provider.rb
@@ -57,21 +57,21 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
end
it "should set the option for #{attribute} if the new resources #{attribute} is not nil" do
- @new_resource.stub!(attribute).and_return("hola")
+ @new_resource.stub(attribute).and_return("hola")
provider.universal_options.should eql([option, 'hola'])
end
it "should set the option for #{attribute} if the new resources #{attribute} is not nil, without homedir management" do
- @new_resource.stub!(:supports).and_return({:manage_home => false,
+ @new_resource.stub(:supports).and_return({:manage_home => false,
:non_unique => false})
- @new_resource.stub!(attribute).and_return("hola")
+ @new_resource.stub(attribute).and_return("hola")
provider.universal_options.should eql([option, 'hola'])
end
it "should set the option for #{attribute} if the new resources #{attribute} is not nil, without homedir management (using real attributes)" do
- @new_resource.stub!(:manage_home).and_return(false)
- @new_resource.stub!(:non_unique).and_return(false)
- @new_resource.stub!(attribute).and_return("hola")
+ @new_resource.stub(:manage_home).and_return(false)
+ @new_resource.stub(:non_unique).and_return(false)
+ @new_resource.stub(attribute).and_return("hola")
provider.universal_options.should eql([option, 'hola'])
end
end
@@ -79,7 +79,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
it "should combine all the possible options" do
combined_opts = []
supported_useradd_options.sort{ |a,b| a[0] <=> b[0] }.each do |attribute, option|
- @new_resource.stub!(attribute).and_return("hola")
+ @new_resource.stub(attribute).and_return("hola")
combined_opts << option << 'hola'
end
provider.universal_options.should eql(combined_opts)
@@ -99,8 +99,8 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
describe "when the resource has a different home directory and supports home directory management" do
before do
- @new_resource.stub!(:home).and_return("/wowaweea")
- @new_resource.stub!(:supports).and_return({:manage_home => true,
+ @new_resource.stub(:home).and_return("/wowaweea")
+ @new_resource.stub(:supports).and_return({:manage_home => true,
:non_unique => false})
end
@@ -112,9 +112,9 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
describe "when the resource has a different home directory and supports home directory management (using real attributes)" do
before do
- @new_resource.stub!(:home).and_return("/wowaweea")
- @new_resource.stub!(:manage_home).and_return(true)
- @new_resource.stub!(:non_unique).and_return(false)
+ @new_resource.stub(:home).and_return("/wowaweea")
+ @new_resource.stub(:manage_home).and_return(true)
+ @new_resource.stub(:non_unique).and_return(false)
end
it "should set -m -d /homedir" do
@@ -125,7 +125,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
describe "when the resource supports non_unique ids" do
before do
- @new_resource.stub!(:supports).and_return({:manage_home => false,
+ @new_resource.stub(:supports).and_return({:manage_home => false,
:non_unique => true})
end
@@ -136,8 +136,8 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
describe "when the resource supports non_unique ids (using real attributes)" do
before do
- @new_resource.stub!(:manage_home).and_return(false)
- @new_resource.stub!(:non_unique).and_return(true)
+ @new_resource.stub(:manage_home).and_return(false)
+ @new_resource.stub(:non_unique).and_return(true)
end
it "should set -m -o" do
@@ -260,12 +260,12 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
describe "when checking the lock" do
# lazy initialize so we can modify stdout and stderr strings
let(:passwd_s_status) do
- mock("Mixlib::ShellOut command", :exitstatus => 0, :stdout => @stdout, :stderr => @stderr)
+ double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => @stdout, :stderr => @stderr)
end
before(:each) do
# @node = Chef::Node.new
- # @new_resource = mock("Chef::Resource::User",
+ # @new_resource = double("Chef::Resource::User",
# :nil_object => true,
# :username => "adam"
# )
@@ -313,9 +313,9 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
provider.should_receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_s_status)
- rpm_status = mock("Mixlib::ShellOut command", :exitstatus => 0, :stdout => "passwd-0.73-1\n", :stderr => "")
+ rpm_status = double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => "passwd-0.73-1\n", :stderr => "")
provider.should_receive(:shell_out!).with("rpm -q passwd").and_return(rpm_status)
- lambda { provider.check_lock }.should_not raise_error(Chef::Exceptions::User)
+ lambda { provider.check_lock }.should_not raise_error
end
it "should raise a Chef::Exceptions::User if passwd -S exits with 1 on #{os} and the passwd package is not version 0.73-1" do
@@ -324,7 +324,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
provider.should_receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_s_status)
- rpm_status = mock("Mixlib::ShellOut command", :exitstatus => 0, :stdout => "passwd-0.73-2\n", :stderr => "")
+ rpm_status = double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => "passwd-0.73-2\n", :stderr => "")
provider.should_receive(:shell_out!).with("rpm -q passwd").and_return(rpm_status)
lambda { provider.check_lock }.should raise_error(Chef::Exceptions::User)
end
@@ -335,6 +335,24 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
lambda { provider.check_lock }.should raise_error(Mixlib::ShellOut::ShellCommandFailed)
end
end
+
+ context "when in why run mode" do
+ before do
+ passwd_status = double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => "", :stderr => "passwd: user 'chef-test' does not exist\n")
+ provider.should_receive(:shell_out!).
+ with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
+ and_return(passwd_status)
+ Chef::Config[:why_run] = true
+ end
+
+ it "should return false if the user does not exist" do
+ provider.check_lock.should eql(false)
+ end
+
+ it "should not raise an error if the user does not exist" do
+ lambda { provider.check_lock }.should_not raise_error
+ end
+ end
end
describe "when locking the user" do
@@ -380,9 +398,9 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
].each do |home_check|
it home_check["action"] do
provider.current_resource.home home_check["current_resource_home"].first
- @current_home_mock = mock("Pathname")
+ @current_home_mock = double("Pathname")
provider.new_resource.home home_check["new_resource_home"].first
- @new_home_mock = mock("Pathname")
+ @new_home_mock = double("Pathname")
Pathname.should_receive(:new).with(@current_resource.home).and_return(@current_home_mock)
@current_home_mock.should_receive(:cleanpath).and_return(home_check["current_resource_home"].last)
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..845c217f72 100644
--- a/spec/unit/api_client/registration_spec.rb
+++ b/spec/unit/api_client/registration_spec.rb
@@ -50,14 +50,14 @@ describe Chef::ApiClient::Registration do
end
describe "when creating/updating the client on the server" do
- let(:http_mock) { mock("Chef::REST mock") }
+ let(:http_mock) { double("Chef::REST mock") }
before do
- registration.stub!(:http_api).and_return(http_mock)
+ registration.stub(:http_api).and_return(http_mock)
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).
@@ -103,7 +103,7 @@ describe Chef::ApiClient::Registration do
describe "when writing the private key to disk" do
before do
- registration.stub!(:private_key).and_return('--begin rsa key etc--')
+ registration.stub(:private_key).and_return('--begin rsa key etc--')
end
# Permission read via File.stat is busted on windows, though creating the
@@ -125,10 +125,10 @@ describe Chef::ApiClient::Registration do
describe "when registering a client" do
- let(:http_mock) { mock("Chef::REST mock") }
+ let(:http_mock) { double("Chef::REST mock") }
before do
- registration.stub!(:http_api).and_return(http_mock)
+ registration.stub(:http_api).and_return(http_mock)
end
it "creates the client on the server and writes the key" do
diff --git a/spec/unit/api_client_spec.rb b/spec/unit/api_client_spec.rb
index 50f22c7066..8657fa59a8 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,56 @@ 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
+
+ end
+
+ describe "when loading from JSON" do
+ before do
+ end
+
+ before(:each) do
+ client = {
+ "name" => "black",
+ "clientname" => "black",
+ "public_key" => "crowes",
+ "private_key" => "monkeypants",
+ "admin" => true,
+ "validator" => true,
+ "json_class" => "Chef::ApiClient"
+ }
+ @http_client = double("Chef::REST mock")
+ Chef::REST.stub(:new).and_return(@http_client)
+ @http_client.should_receive(:get).with("clients/black").and_return(client)
+ @client = Chef::ApiClient.load(client['name'])
+ end
+
+ it "should deserialize to a Chef::ApiClient object" do
+ @client.should be_a_kind_of(Chef::ApiClient)
+ end
+
+ it "preserves the name" do
+ @client.name.should == "black"
+ end
+
+ it "preserves the public key" do
+ @client.public_key.should == "crowes"
+ end
+
+ it "preserves the admin status" do
+ @client.admin.should be_a_kind_of(Chef::TrueClass)
+ end
+
+ it "preserves the 'validator' status" do
+ @client.validator.should be_a_kind_of(Chef::TrueClass)
+ end
+
it "includes the private key if present" do
@client.private_key.should == "monkeypants"
end
@@ -167,8 +235,8 @@ describe Chef::ApiClient do
describe "when requesting a new key" do
before do
- @http_client = mock("Chef::REST mock")
- Chef::REST.stub!(:new).and_return(@http_client)
+ @http_client = double("Chef::REST mock")
+ Chef::REST.stub(:new).and_return(@http_client)
end
context "and the client does not exist on the server" do
@@ -198,7 +266,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 +284,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 +295,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..32c98c6ed6 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)
+ @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
@@ -44,10 +36,10 @@ describe Chef::Application::Apply do
before do
@recipe_file_name = "foo.rb"
@recipe_path = File.expand_path("foo.rb")
- @recipe_file = mock("Tempfile (mock)", :read => @recipe_text)
- @app.stub!(:open).with(@recipe_path).and_return(@recipe_file)
- File.stub!(:exist?).with("foo.rb").and_return(true)
- Chef::Application.stub!(:fatal!).and_return(true)
+ @recipe_file = double("Tempfile (mock)", :read => @recipe_text)
+ @app.stub(:open).with(@recipe_path).and_return(@recipe_file)
+ File.stub(:exist?).with("foo.rb").and_return(true)
+ Chef::Application.stub(:fatal!).and_return(true)
end
it "should read text properly" do
@app.read_recipe_file(@recipe_file_name)[0].should == @recipe_text
@@ -57,7 +49,7 @@ describe Chef::Application::Apply do
end
describe "when recipe doesn't exist" do
before do
- File.stub!(:exist?).with(@recipe_file_name).and_return(false)
+ File.stub(:exist?).with(@recipe_file_name).and_return(false)
end
it "should raise a fatal" do
Chef::Application.should_receive(:fatal!)
@@ -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 45893119e2..f84932073f 100644
--- a/spec/unit/application/client_spec.rb
+++ b/spec/unit/application/client_spec.rb
@@ -21,21 +21,18 @@ describe Chef::Application::Client, "reconfigure" do
before do
@original_argv = ARGV.dup
ARGV.clear
- @original_config = Chef::Config.configuration.dup
@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
+ @app.stub(:configure_opt_parser).and_return(true)
+ @app.stub(:configure_chef).and_return(true)
+ @app.stub(:configure_logging).and_return(true)
+ @app.cli_arguments = []
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
@@ -73,49 +70,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
@@ -124,9 +91,9 @@ describe Chef::Application::Client, "setup_application" do
before do
@app = Chef::Application::Client.new
# this is all stuff the reconfigure method needs
- @app.stub!(:configure_opt_parser).and_return(true)
- @app.stub!(:configure_chef).and_return(true)
- @app.stub!(:configure_logging).and_return(true)
+ @app.stub(:configure_opt_parser).and_return(true)
+ @app.stub(:configure_chef).and_return(true)
+ @app.stub(:configure_logging).and_return(true)
end
it "should change privileges" do
diff --git a/spec/unit/application/knife_spec.rb b/spec/unit/application/knife_spec.rb
index 16f94c7786..1baaad110d 100644
--- a/spec/unit/application/knife_spec.rb
+++ b/spec/unit/application/knife_spec.rb
@@ -35,8 +35,8 @@ describe Chef::Application::Knife do
before(:each) do
@knife = Chef::Application::Knife.new
- @knife.stub!(:puts)
- Chef::Knife.stub!(:list_commands)
+ @knife.stub(:puts)
+ Chef::Knife.stub(:list_commands)
end
it "should exit 1 and print the options if no arguments are given at all" do
@@ -54,7 +54,7 @@ describe Chef::Application::Knife do
it "should run a sub command with the applications command line option prototype" do
with_argv(*%w{noop knife command with some args}) do
- knife = mock(Chef::Knife)
+ knife = double(Chef::Knife)
Chef::Knife.should_receive(:run).with(ARGV, @knife.options).and_return(knife)
@knife.should_receive(:exit).with(0)
@knife.run
@@ -76,7 +76,7 @@ describe Chef::Application::Knife do
describe "when given a path to the client key" do
it "expands a relative path relative to the CWD" do
relative_path = '.chef/client.pem'
- Dir.stub!(:pwd).and_return(CHEF_SPEC_DATA)
+ Dir.stub(:pwd).and_return(CHEF_SPEC_DATA)
with_argv(*%W{noop knife command -k #{relative_path}}) do
@knife.should_receive(:exit).with(0)
@knife.run
@@ -158,7 +158,7 @@ describe Chef::Application::Knife do
it "should run a sub command with the applications command line option prototype" do
with_argv(*%w{noop knife command with some args}) do
- knife = mock(Chef::Knife)
+ knife = double(Chef::Knife)
Chef::Knife.should_receive(:run).with(ARGV, @knife.options).and_return(knife)
@knife.should_receive(:exit).with(0)
@knife.run
diff --git a/spec/unit/application/solo_spec.rb b/spec/unit/application/solo_spec.rb
index 07598dd01c..d2f8b93169 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)
+ @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_client_json.should == json_attribs
end
end
@@ -110,14 +70,14 @@ describe Chef::Application::Solo do
before do
Chef::Config[:cookbook_path] = "#{Dir.tmpdir}/chef-solo/cookbooks"
Chef::Config[:recipe_url] = "http://junglist.gen.nz/recipes.tgz"
- FileUtils.stub!(:mkdir_p).and_return(true)
+ FileUtils.stub(:mkdir_p).and_return(true)
@tarfile = StringIO.new("remote_tarball_content")
- @app.stub!(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(@tarfile)
+ @app.stub(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(@tarfile)
@target_file = StringIO.new
- File.stub!(:open).with("#{Dir.tmpdir}/chef-solo/recipes.tgz", "wb").and_yield(@target_file)
+ File.stub(:open).with("#{Dir.tmpdir}/chef-solo/recipes.tgz", "wb").and_yield(@target_file)
- Chef::Mixin::Command.stub!(:run_command).and_return(true)
+ Chef::Mixin::Command.stub(:run_command).and_return(true)
end
it "should create the recipes path based on the parent of the cookbook path" do
@@ -147,14 +107,14 @@ describe Chef::Application::Solo do
before do
Chef::Config[:solo] = true
- Chef::Daemon.stub!(:change_privilege)
- @chef_client = mock("Chef::Client")
- Chef::Client.stub!(:new).and_return(@chef_client)
+ Chef::Daemon.stub(:change_privilege)
+ @chef_client = double("Chef::Client")
+ Chef::Client.stub(:new).and_return(@chef_client)
@app = Chef::Application::Solo.new
# this is all stuff the reconfigure method needs
- @app.stub!(:configure_opt_parser).and_return(true)
- @app.stub!(:configure_chef).and_return(true)
- @app.stub!(:configure_logging).and_return(true)
+ @app.stub(:configure_opt_parser).and_return(true)
+ @app.stub(:configure_chef).and_return(true)
+ @app.stub(:configure_logging).and_return(true)
end
it "should change privileges" do
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index e0701614a3..6110a8a3c5 100644
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -22,23 +22,22 @@ describe Chef::Application do
before do
@original_argv = ARGV.dup
ARGV.clear
- @original_conf = Chef::Config.configuration
Chef::Log.logger = Logger.new(StringIO.new)
@app = Chef::Application.new
- Dir.stub!(:chdir).and_return(0)
- @app.stub!(:reconfigure)
+ 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
before do
@app = Chef::Application.new
- @app.stub!(:configure_chef).and_return(true)
- @app.stub!(:configure_logging).and_return(true)
+ @app.stub(:configure_chef).and_return(true)
+ @app.stub(:configure_logging).and_return(true)
end
it "should configure chef" do
@@ -60,10 +59,10 @@ describe Chef::Application do
describe "run" do
before do
- @app.stub!(:setup_application).and_return(true)
- @app.stub!(:run_application).and_return(true)
- @app.stub!(:configure_chef).and_return(true)
- @app.stub!(:configure_logging).and_return(true)
+ @app.stub(:setup_application).and_return(true)
+ @app.stub(:run_application).and_return(true)
+ @app.stub(:configure_chef).and_return(true)
+ @app.stub(:configure_logging).and_return(true)
end
it "should reconfigure the application before running" do
@@ -86,8 +85,8 @@ describe Chef::Application do
describe "configure_chef" do
before do
@app = Chef::Application.new
- #Chef::Config.stub!(:merge!).and_return(true)
- @app.stub!(:parse_options).and_return(true)
+ #Chef::Config.stub(:merge!).and_return(true)
+ @app.stub(:parse_options).and_return(true)
end
it "should parse the commandline options" do
@@ -97,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
@@ -130,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
@@ -146,65 +147,33 @@ 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
before do
@app = Chef::Application.new
- Chef::Log.stub!(:init)
+ Chef::Log.stub(:init)
end
it "should initialise the chef logger" do
- Chef::Log.stub!(:level=)
- @monologger = mock("Monologger")
+ Chef::Log.stub(:level=)
+ @monologger = double("Monologger")
MonoLogger.should_receive(:new).with(Chef::Config[:log_location]).and_return(@monologger)
Chef::Log.should_receive(:init).with(@monologger)
@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)
+ it "should raise fatals if log location is invalid" do
+ Chef::Config[:log_location] = "/tmp/non-existing-dir/logfile"
+ Chef::Log.should_receive(:fatal).at_least(:once)
+ Process.should_receive(:exit)
@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)
+ STDOUT.stub(:tty?).and_return(true)
end
it "configures the log level to :warn" do
@@ -212,7 +181,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
@@ -224,9 +193,9 @@ 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)
+ STDOUT.stub(:tty?).and_return(false)
end
it "configures the log level to :info" do
@@ -234,7 +203,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
@@ -244,15 +213,26 @@ 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
describe "class method: fatal!" do
before do
- STDERR.stub!(:puts).with("FATAL: blah").and_return(true)
- Chef::Log.stub!(:fatal).with("blah").and_return(true)
- Process.stub!(:exit).and_return(true)
+ STDERR.stub(:puts).with("FATAL: blah").and_return(true)
+ Chef::Log.stub(:fatal).and_return(true)
+ Process.stub(:exit).and_return(true)
end
it "should log an error message to the logger" do
@@ -296,34 +276,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)
+ Chef::Log.stub(:warn).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
@@ -338,11 +313,6 @@ describe Chef::Application do
@config_file.unlink
end
- it "should raise informative fatals for missing log file dir" do
- create_config_file('log_location "/tmp/non-existing-dir/logfile"')
- raises_informative_fatals_on_configure_chef
- end
-
it "should raise informative fatals for badly written config" do
create_config_file("text that should break the config parsing")
raises_informative_fatals_on_configure_chef
diff --git a/spec/unit/checksum/storage/filesystem_spec.rb b/spec/unit/checksum/storage/filesystem_spec.rb
index 5be345ce4c..755a64fe07 100644
--- a/spec/unit/checksum/storage/filesystem_spec.rb
+++ b/spec/unit/checksum/storage/filesystem_spec.rb
@@ -26,10 +26,11 @@ describe Chef::Checksum::Storage::Filesystem do
@now = Time.now
- Time.stub!(:now).and_return(@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
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..e4143d7653 100644
--- a/spec/unit/client_spec.rb
+++ b/spec/unit/client_spec.rb
@@ -24,29 +24,52 @@ require 'chef/run_context'
require 'chef/rest'
require 'rbconfig'
-shared_examples_for Chef::Client do
+describe Chef::Client do
+
+ let(:hostname) { "hostname" }
+ let(:fqdn) { "hostname.example.org" }
+
+ let(:ohai_data) do
+ { :fqdn => fqdn,
+ :hostname => hostname,
+ :platform => 'example-platform',
+ :platform_version => 'example-platform-1.0',
+ :data => {}
+ }
+ end
+
+ let(:ohai_system) do
+ ohai_system = double( "Ohai::System",
+ :all_plugins => true,
+ :data => ohai_data)
+ ohai_system.stub(:[]) do |key|
+ ohai_data[key]
+ end
+ ohai_system
+ end
+
+ let(:node) do
+ Chef::Node.new.tap do |n|
+ n.name(fqdn)
+ n.chef_environment("_default")
+ end
+ end
+
+ let(:json_attribs) { nil }
+ let(:client_opts) { {} }
+
+ let(:client) do
+ Chef::Client.new(json_attribs, client_opts).tap do |c|
+ c.node = node
+ end
+ end
+
before do
Chef::Log.logger = Logger.new(StringIO.new)
# Node/Ohai data
- @hostname = "hostname"
- @fqdn = "hostname.example.org"
- Chef::Config[:node_name] = @fqdn
- ohai_data = { :fqdn => @fqdn,
- :hostname => @hostname,
- :platform => 'example-platform',
- :platform_version => 'example-platform-1.0',
- :data => {} }
- ohai_data.stub!(:all_plugins).and_return(true)
- ohai_data.stub!(:data).and_return(ohai_data)
- Ohai::System.stub!(:new).and_return(ohai_data)
-
- @node = Chef::Node.new
- @node.name(@fqdn)
- @node.chef_environment("_default")
-
- @client = Chef::Client.new
- @client.node = @node
+ #Chef::Config[:node_name] = fqdn
+ Ohai::System.stub(:new).and_return(ohai_system)
end
describe "authentication protocol selection" do
@@ -58,7 +81,7 @@ shared_examples_for Chef::Client do
it "does not force the authentication protocol to 1.1" do
Chef::Config[:node_name] = ("f" * 90)
# ugly that this happens as a side effect of a getter :(
- @client.node_name
+ client.node_name
Chef::Config[:authentication_protocol_version].should == "1.0"
end
end
@@ -67,35 +90,22 @@ shared_examples_for Chef::Client do
it "sets the authentication protocol to version 1.1" do
Chef::Config[:node_name] = ("f" * 91)
# ugly that this happens as a side effect of a getter :(
- @client.node_name
+ client.node_name
Chef::Config[:authentication_protocol_version].should == "1.1"
end
end
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)
+ STDOUT.stub(:tty?).and_return(true)
end
it "configures the :doc formatter" do
- @client.formatters_for_run.should == [[:doc]]
+ client.formatters_for_run.should == [[:doc]]
end
context "and force_logger is set" do
@@ -105,7 +115,7 @@ shared_examples_for Chef::Client do
it "configures the :null formatter" do
Chef::Config[:force_logger].should be_true
- @client.formatters_for_run.should == [[:null]]
+ client.formatters_for_run.should == [[:null]]
end
end
@@ -114,12 +124,11 @@ 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)
+ STDOUT.stub(:tty?).and_return(false)
end
it "configures the :null formatter" do
- @client.formatters_for_run.should == [[:null]]
+ client.formatters_for_run.should == [[:null]]
end
context "and force_formatter is set" do
@@ -127,7 +136,7 @@ shared_examples_for Chef::Client do
Chef::Config[:force_formatter] = true
end
it "it configures the :doc formatter" do
- @client.formatters_for_run.should == [[:doc]]
+ client.formatters_for_run.should == [[:doc]]
end
end
end
@@ -137,17 +146,15 @@ 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
it "does not configure a default formatter" do
- @client.formatters_for_run.should == [[:min, nil]]
+ client.formatters_for_run.should == [[:min, nil]]
end
it "configures the formatter for STDOUT/STDERR" do
- configured_formatters = @client.configure_formatters
+ configured_formatters = client.configure_formatters
min_formatter = configured_formatters[0]
min_formatter.output.out.should == STDOUT
min_formatter.output.err.should == STDERR
@@ -156,8 +163,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)
end
@@ -168,7 +173,7 @@ shared_examples_for Chef::Client do
end
it "configures the formatter for the file path" do
- configured_formatters = @client.configure_formatters
+ configured_formatters = client.configure_formatters
min_formatter = configured_formatters[0]
min_formatter.output.out.path.should == @tmpout.path
min_formatter.output.err.path.should == @tmpout.path
@@ -178,195 +183,320 @@ shared_examples_for Chef::Client do
end
end
- describe "run" do
-
- it "should identify the node and run ohai, then register the client" do
- mock_chef_rest_for_node = mock("Chef::REST (node)")
- mock_chef_rest_for_client = mock("Chef::REST (client)")
- mock_chef_rest_for_node_save = mock("Chef::REST (node save)")
- mock_chef_runner = mock("Chef::Runner")
-
- # --Client.register
- # Make sure Client#register thinks the client key doesn't
- # exist, so it tries to register and create one.
- File.should_receive(:exists?).with(Chef::Config[:client_key]).exactly(1).times.and_return(false)
-
- # Client.register will register with the validation client name.
- Chef::ApiClient::Registration.any_instance.should_receive(:run)
- # Client.register will then turn around create another
- # Chef::REST object, this time with the client key it got from the
- # previous step.
- Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url], @fqdn, Chef::Config[:client_key]).exactly(1).and_return(mock_chef_rest_for_node)
-
- # --Client#build_node
- # looks up the node, which we will return, then later saves it.
- Chef::Node.should_receive(:find_or_create).with(@fqdn).and_return(@node)
-
- # --ResourceReporter#node_load_completed
- # gets a run id from the server for storing resource history
- # (has its own tests, so stubbing it here.)
- Chef::ResourceReporter.any_instance.should_receive(:node_load_completed)
-
- # --ResourceReporter#run_completed
- # updates the server with the resource history
- # (has its own tests, so stubbing it here.)
- Chef::ResourceReporter.any_instance.should_receive(:run_completed)
- # --Client#setup_run_context
- # ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
- #
- Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
- mock_chef_rest_for_node.should_receive(:post_rest).with("environments/_default/cookbook_versions", {:run_list => []}).and_return({})
-
- # --Client#converge
- Chef::Runner.should_receive(:new).and_return(mock_chef_runner)
- mock_chef_runner.should_receive(:converge).and_return(true)
-
- # --Client#save_updated_node
- Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(mock_chef_rest_for_node_save)
- 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(:release)
-
- # Post conditions: check that node has been filled in correctly
- @client.should_receive(:run_started)
- @client.should_receive(:run_completed_successfully)
+ describe "a full client run" do
+ shared_examples_for "a successful client run" do
+ let(:http_node_load) { double("Chef::REST (node)") }
+ let(:http_cookbook_sync) { double("Chef::REST (cookbook sync)") }
+ let(:http_node_save) { double("Chef::REST (node save)") }
+ let(:runner) { double("Chef::Runner") }
- if(Chef::Config[:client_fork] && !windows?)
- require 'stringio'
- if(Chef::Config[:pipe_node])
- pipe_sim = StringIO.new
- pipe_sim.should_receive(:close).exactly(4).and_return(nil)
- res = ''
- pipe_sim.should_receive(:puts) do |string|
- res.replace(string)
- end
- pipe_sim.should_receive(:gets).and_return(res)
- IO.should_receive(:pipe).and_return([pipe_sim, pipe_sim])
- IO.should_receive(:select).and_return(true)
+ let(:api_client_exists?) { false }
+
+ let(:stdout) { StringIO.new }
+ let(:stderr) { StringIO.new }
+
+ let(:enable_fork) { false }
+
+ def stub_for_register
+ # --Client.register
+ # Make sure Client#register thinks the client key doesn't
+ # exist, so it tries to register and create one.
+ File.should_receive(:exists?).with(Chef::Config[:client_key]).exactly(1).times.and_return(api_client_exists?)
+
+ unless api_client_exists?
+ # Client.register will register with the validation client name.
+ Chef::ApiClient::Registration.any_instance.should_receive(:run)
end
- proc_ret = Class.new.new
- proc_ret.should_receive(:success?).and_return(true)
- Process.should_receive(:waitpid2).and_return([1, proc_ret])
- @client.should_receive(:exit).and_return(nil)
- @client.should_receive(:fork) do |&block|
- block.call
+ end
+
+ def stub_for_node_load
+ # Client.register will then turn around create another
+ # Chef::REST object, this time with the client key it got from the
+ # previous step.
+ Chef::REST.should_receive(:new).
+ with(Chef::Config[:chef_server_url], fqdn, Chef::Config[:client_key]).
+ exactly(1).
+ and_return(http_node_load)
+
+ # --Client#build_node
+ # looks up the node, which we will return, then later saves it.
+ Chef::Node.should_receive(:find_or_create).with(fqdn).and_return(node)
+
+ # --ResourceReporter#node_load_completed
+ # gets a run id from the server for storing resource history
+ # (has its own tests, so stubbing it here.)
+ Chef::ResourceReporter.any_instance.should_receive(:node_load_completed)
+ end
+
+ def stub_for_sync_cookbooks
+ # --Client#setup_run_context
+ # ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
+ #
+ Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
+ Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
+ http_cookbook_sync.should_receive(:post).
+ with("environments/_default/cookbook_versions", {:run_list => []}).
+ and_return({})
+ end
+
+ def stub_for_converge
+ # --Client#converge
+ Chef::Runner.should_receive(:new).and_return(runner)
+ runner.should_receive(:converge).and_return(true)
+
+ # --ResourceReporter#run_completed
+ # updates the server with the resource history
+ # (has its own tests, so stubbing it here.)
+ Chef::ResourceReporter.any_instance.should_receive(:run_completed)
+ end
+
+ def stub_for_node_save
+ # --Client#save_updated_node
+ Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_node_save)
+ http_node_save.should_receive(:put_rest).with("nodes/#{fqdn}", node).and_return(true)
+ end
+
+ def stub_for_run
+ 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
+ client.should_receive(:run_started)
+ client.should_receive(:run_completed_successfully)
+ end
+
+ before do
+ Chef::Config[:client_fork] = enable_fork
+
+ stub_const("Chef::Client::STDOUT_FD", stdout)
+ stub_const("Chef::Client::STDERR_FD", stderr)
+
+ stub_for_register
+ stub_for_node_load
+ stub_for_sync_cookbooks
+ stub_for_converge
+ stub_for_node_save
+ stub_for_run
+ end
+
+ it "runs ohai, sets up authentication, loads node state, synchronizes policy, and converges" do
+ # This is what we're testing.
+ client.run
+
+ # fork is stubbed, so we can see the outcome of the run
+ node.automatic_attrs[:platform].should == "example-platform"
+ node.automatic_attrs[:platform_version].should == "example-platform-1.0"
+ end
+ end
+
+
+ describe "when running chef-client without fork" do
+
+ include_examples "a successful client run"
+ end
+
+ describe "when running chef-client with forking enabled", :unix_only do
+ include_examples "a successful client run" do
+ let(:process_status) do
+ double("Process::Status")
+ end
+
+ let(:enable_fork) { true }
+
+ before do
+ Process.should_receive(:waitpid2).and_return([1, process_status])
+
+ process_status.should_receive(:success?).and_return(true)
+ client.should_receive(:exit).and_return(nil)
+ client.should_receive(:fork).and_yield
end
end
- # This is what we're testing.
- @client.run
+ end
+
+ describe "when the client key already exists" do
+
+ let(:api_client_exists?) { true }
+
+ include_examples "a successful client run"
+ end
+
+ describe "when an override run list is given" do
+ let(:client_opts) { {:override_runlist => "recipe[override_recipe]"} }
+
+ it "should permit spaces in overriding run list" do
+ Chef::Client.new(nil, :override_runlist => 'role[a], role[b]')
+ end
+
+ describe "when running the client" do
+ include_examples "a successful client run" do
+
+ before do
+ # Client will try to compile and run override_recipe
+ Chef::RunContext::CookbookCompiler.any_instance.should_receive(:compile)
+ end
+
+ def stub_for_sync_cookbooks
+ # --Client#setup_run_context
+ # ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
+ #
+ Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
+ Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
+ http_cookbook_sync.should_receive(:post).
+ with("environments/_default/cookbook_versions", {:run_list => ["override_recipe"]}).
+ and_return({})
+ end
+
+ def stub_for_node_save
+ # Expect NO node save
+ node.should_not_receive(:save)
+ end
+ end
+ end
+ end
+
+ describe "when a permanent run list is passed as an option" do
+
+ include_examples "a successful client run" do
+
+ let(:new_runlist) { "recipe[new_run_list_recipe]" }
+ let(:client_opts) { {:runlist => new_runlist} }
+
+ def stub_for_sync_cookbooks
+ # --Client#setup_run_context
+ # ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
+ #
+ Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
+ Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
+ http_cookbook_sync.should_receive(:post).
+ with("environments/_default/cookbook_versions", {:run_list => ["new_run_list_recipe"]}).
+ and_return({})
+ end
+
+ before do
+ # Client will try to compile and run the new_run_list_recipe, but we
+ # do not create a fixture for this.
+ Chef::RunContext::CookbookCompiler.any_instance.should_receive(:compile)
+ end
+
+ it "sets the new run list on the node" do
+ client.run
+ node.run_list.should == Chef::RunList.new(new_runlist)
+ end
- if(!Chef::Config[:client_fork] || Chef::Config[:pipe_node])
- @node.automatic_attrs[:platform].should == "example-platform"
- @node.automatic_attrs[:platform_version].should == "example-platform-1.0"
end
end
+ end
+
+
+ describe "when handling run failures" do
+
it "should remove the run_lock on failure of #load_node" do
- @run_lock = mock("Chef::RunLock", :acquire => true)
- Chef::RunLock.stub!(:new).and_return(@run_lock)
+ @run_lock = double("Chef::RunLock", :acquire => true)
+ Chef::RunLock.stub(:new).and_return(@run_lock)
- @events = mock("Chef::EventDispatch::Dispatcher").as_null_object
- Chef::EventDispatch::Dispatcher.stub!(:new).and_return(@events)
+ @events = double("Chef::EventDispatch::Dispatcher").as_null_object
+ Chef::EventDispatch::Dispatcher.stub(:new).and_return(@events)
# @events is created on Chef::Client.new, so we need to recreate it after mocking
- @client = Chef::Client.new
- @client.stub!(:load_node).and_raise(Exception)
+ client = Chef::Client.new
+ client.stub(:load_node).and_raise(Exception)
@run_lock.should_receive(:release)
if(Chef::Config[:client_fork] && !windows?)
- @client.should_receive(:fork) do |&block|
+ client.should_receive(:fork) do |&block|
block.call
end
end
- lambda { @client.run }.should raise_error(Exception)
+ lambda { client.run }.should raise_error(Exception)
end
+ end
- describe "when notifying other objects of the status of the chef run" do
- before do
- Chef::Client.clear_notifications
- Chef::Node.stub!(:find_or_create).and_return(@node)
- @node.stub!(:save)
- @client.build_node
- end
-
- it "notifies observers that the run has started" do
- notified = false
- Chef::Client.when_run_starts do |run_status|
- run_status.node.should == @node
- notified = true
- end
+ describe "when notifying other objects of the status of the chef run" do
+ before do
+ Chef::Client.clear_notifications
+ Chef::Node.stub(:find_or_create).and_return(node)
+ node.stub(:save)
+ client.load_node
+ client.build_node
+ end
- @client.run_started
- notified.should be_true
+ it "notifies observers that the run has started" do
+ notified = false
+ Chef::Client.when_run_starts do |run_status|
+ run_status.node.should == node
+ notified = true
end
- it "notifies observers that the run has completed successfully" do
- notified = false
- Chef::Client.when_run_completes_successfully do |run_status|
- run_status.node.should == @node
- notified = true
- end
+ client.run_started
+ notified.should be_true
+ end
- @client.run_completed_successfully
- notified.should be_true
+ it "notifies observers that the run has completed successfully" do
+ notified = false
+ Chef::Client.when_run_completes_successfully do |run_status|
+ run_status.node.should == node
+ notified = true
end
- it "notifies observers that the run failed" do
- notified = false
- Chef::Client.when_run_fails do |run_status|
- run_status.node.should == @node
- notified = true
- end
+ client.run_completed_successfully
+ notified.should be_true
+ end
- @client.run_failed
- notified.should be_true
+ it "notifies observers that the run failed" do
+ notified = false
+ Chef::Client.when_run_fails do |run_status|
+ run_status.node.should == node
+ notified = true
end
+
+ client.run_failed
+ notified.should be_true
end
end
describe "build_node" do
it "should expand the roles and recipes for the node" do
- @node.run_list << "role[role_containing_cookbook1]"
+ node.run_list << "role[role_containing_cookbook1]"
role_containing_cookbook1 = Chef::Role.new
role_containing_cookbook1.name("role_containing_cookbook1")
role_containing_cookbook1.run_list << "cookbook1"
# build_node will call Node#expand! with server, which will
# eventually hit the server to expand the included role.
- mock_chef_rest = mock("Chef::REST")
+ mock_chef_rest = double("Chef::REST")
mock_chef_rest.should_receive(:get_rest).with("roles/role_containing_cookbook1").and_return(role_containing_cookbook1)
Chef::REST.should_receive(:new).and_return(mock_chef_rest)
# check pre-conditions.
- @node[:roles].should be_nil
- @node[:recipes].should be_nil
+ node[:roles].should be_nil
+ node[:recipes].should be_nil
+
+ client.policy_builder.stub(:node).and_return(node)
- @client.build_node
+ # chefspec and possibly others use the return value of this method
+ client.build_node.should == node
# check post-conditions.
- @node[:roles].should_not be_nil
- @node[:roles].length.should == 1
- @node[:roles].should include("role_containing_cookbook1")
- @node[:recipes].should_not be_nil
- @node[:recipes].length.should == 1
- @node[:recipes].should include("cookbook1")
+ node[:roles].should_not be_nil
+ node[:roles].length.should == 1
+ node[:roles].should include("role_containing_cookbook1")
+ node[:recipes].should_not be_nil
+ node[:recipes].length.should == 1
+ node[:recipes].should include("cookbook1")
end
end
describe "windows_admin_check" do
- before do
- @client = Chef::Client.new
- end
-
context "platform is not windows" do
before do
Chef::Platform.stub(:windows?).and_return(false)
end
it "shouldn't be called" do
- @client.should_not_receive(:has_admin_privileges?)
- @client.do_windows_admin_check
+ client.should_not_receive(:has_admin_privileges?)
+ client.do_windows_admin_check
end
end
@@ -376,106 +506,59 @@ shared_examples_for Chef::Client do
end
it "should be called" do
- @client.should_receive(:has_admin_privileges?)
- @client.do_windows_admin_check
+ client.should_receive(:has_admin_privileges?)
+ client.do_windows_admin_check
end
context "admin privileges exist" do
before do
- @client.should_receive(:has_admin_privileges?).and_return(true)
+ client.should_receive(:has_admin_privileges?).and_return(true)
end
it "should not log a warning message" do
Chef::Log.should_not_receive(:warn)
- @client.do_windows_admin_check
+ client.do_windows_admin_check
end
context "fatal admin check is configured" do
it "should not raise an exception" do
- @client.do_windows_admin_check.should_not raise_error(Chef::Exceptions::WindowsNotAdmin)
+ client.do_windows_admin_check #should not raise
end
end
end
context "admin privileges doesn't exist" do
before do
- @client.should_receive(:has_admin_privileges?).and_return(false)
+ client.should_receive(:has_admin_privileges?).and_return(false)
end
it "should log a warning message" do
Chef::Log.should_receive(:warn)
- @client.do_windows_admin_check
+ client.do_windows_admin_check
end
context "fatal admin check is configured" do
it "should raise an exception" do
- @client.do_windows_admin_check.should_not raise_error(Chef::Exceptions::WindowsNotAdmin)
+ client.do_windows_admin_check # should not raise
end
end
end
end
end
- describe "when a run list override is provided" do
+ describe "assert_cookbook_path_not_empty" do
before do
- @node = Chef::Node.new
- @node.name(@fqdn)
- @node.chef_environment("_default")
- @node.automatic_attrs[:platform] = "example-platform"
- @node.automatic_attrs[:platform_version] = "example-platform-1.0"
+ Chef::Config[:solo] = true
+ Chef::Config[:cookbook_path] = ["/path/to/invalid/cookbook_path"]
end
-
- it "should permit spaces in overriding run list" do
- @client = Chef::Client.new(nil, :override_runlist => 'role[a], role[b]')
- end
-
- it "should override the run list and save original runlist" do
- @client = Chef::Client.new(nil, :override_runlist => 'role[test_role]')
- @client.node = @node
-
- @node.run_list << "role[role_containing_cookbook1]"
-
- override_role = Chef::Role.new
- override_role.name 'test_role'
- override_role.run_list << 'cookbook1'
-
- original_runlist = @node.run_list.dup
-
- mock_chef_rest = mock("Chef::REST")
- mock_chef_rest.should_receive(:get_rest).with("roles/test_role").and_return(override_role)
- Chef::REST.should_receive(:new).and_return(mock_chef_rest)
-
- @node.should_receive(:save).and_return(nil)
-
- @client.build_node
-
- @node[:roles].should_not be_nil
- @node[:roles].should eql(['test_role'])
- @node[:recipes].should eql(['cookbook1'])
-
- @client.save_updated_node
-
- @node.run_list.should == original_runlist
-
+ context "when any directory of cookbook_path contains no cookbook" do
+ it "raises CookbookNotFound error" do
+ expect do
+ client.send(:assert_cookbook_path_not_empty, nil)
+ end.to raise_error(Chef::Exceptions::CookbookNotFound, 'None of the cookbook paths set in Chef::Config[:cookbook_path], ["/path/to/invalid/cookbook_path"], contain any cookbooks')
+ end
end
end
end
-describe Chef::Client do
- 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..0f9bfce4aa 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,30 +81,26 @@ 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
describe "class method: manage_secret_key" do
before do
- Chef::FileCache.stub!(:load).and_return(true)
- Chef::FileCache.stub!(:has_key?).with("chef_server_cookie_id").and_return(false)
+ Chef::FileCache.stub(:load).and_return(true)
+ Chef::FileCache.stub(:has_key?).with("chef_server_cookie_id").and_return(false)
end
it "should generate and store a chef server cookie id" do
@@ -115,7 +110,7 @@ describe Chef::Config do
describe "when the filecache has a chef server cookie id key" do
before do
- Chef::FileCache.stub!(:has_key?).with("chef_server_cookie_id").and_return(true)
+ Chef::FileCache.stub(:has_key?).with("chef_server_cookie_id").and_return(true)
end
it "should not generate and store a chef server cookie id" do
@@ -126,33 +121,6 @@ describe Chef::Config do
end
- describe "config attribute writer: log_method=" do
- describe "when given an object that responds to sync= e.g. IO" do
- it "should configure itself to use the IO as log_location" do
- Chef::Config.log_location = STDOUT
- Chef::Config.log_location.should == STDOUT
- end
- end
-
- describe "when given an object that is stringable (to_str)" do
- before do
- @mockfile = mock("File", :path => "/var/log/chef/client.log", :sync= => true)
- File.should_receive(:new).
- with("/var/log/chef/client.log", "a").
- 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"
- end
- end
- end
-
describe "class method: plaform_specific_path" do
it "should return given path on non-windows systems" do
platform_mock :unix do
@@ -164,7 +132,7 @@ describe Chef::Config do
it "should return a windows path on windows systems" do
platform_mock :windows do
path = "/etc/chef/cookbooks"
- ENV.stub!(:[]).with('SYSTEMDRIVE').and_return('C:')
+ ENV.stub(:[]).with('SYSTEMDRIVE').and_return('C:')
# match on a regex that looks for the base path with an optional
# system drive at the beginning (c:)
# system drive is not hardcoded b/c it can change and b/c it is not present on linux systems
@@ -174,15 +142,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?
@@ -201,8 +160,14 @@ describe Chef::Config do
Chef::Config[:ssl_ca_path].should be_nil
end
- it "Chef::Config[:ssl_ca_file] defaults to nil" do
- Chef::Config[:ssl_ca_file].should be_nil
+ describe "when on UNIX" do
+ before do
+ Chef::Config.stub(:on_windows?).and_return(false)
+ end
+
+ it "Chef::Config[:ssl_ca_file] defaults to nil" do
+ Chef::Config[:ssl_ca_file].should be_nil
+ end
end
it "Chef::Config[:data_bag_path] defaults to /var/chef/data_bags" do
@@ -220,6 +185,100 @@ 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
+
+ describe "finding the windows embedded dir" do
+ let(:default_config_location) { "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
+ let(:alternate_install_location) { "c:/my/alternate/install/place/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
+ let(:non_omnibus_location) { "c:/my/dev/stuff/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
+
+ let(:default_ca_file) { "c:/opscode/chef/embedded/ssl/certs/cacert.pem" }
+
+ it "finds the embedded dir in the default location" do
+ Chef::Config.stub(:_this_file).and_return(default_config_location)
+ Chef::Config.embedded_dir.should == "c:/opscode/chef/embedded"
+ end
+
+ it "finds the embedded dir in a custom install location" do
+ Chef::Config.stub(:_this_file).and_return(alternate_install_location)
+ Chef::Config.embedded_dir.should == "c:/my/alternate/install/place/chef/embedded"
+ end
+
+ it "doesn't error when not in an omnibus install" do
+ Chef::Config.stub(:_this_file).and_return(non_omnibus_location)
+ Chef::Config.embedded_dir.should be_nil
+ end
+
+ it "sets the ssl_ca_cert path if the cert file is available" do
+ Chef::Config.stub(:_this_file).and_return(default_config_location)
+ Chef::Config.stub(:on_windows?).and_return(true)
+ File.stub(:exist?).with(default_ca_file).and_return(true)
+ Chef::Config.ssl_ca_file.should == default_ca_file
+ end
+ end
end
describe "Chef::Config[:user_home]" do
@@ -272,14 +331,23 @@ describe Chef::Config do
end
end
- describe "Chef::Config[:log_location]" do
- it "raises ConfigurationError when log_location directory is missing" do
- missing_path = "/tmp/non-existing-dir/file"
- expect{Chef::Config.log_location = missing_path}.to raise_error Chef::Exceptions::ConfigurationError
+ describe "Chef::Config[:event_handlers]" do
+ it "sets a event_handlers to an empty array by default" do
+ Chef::Config[:event_handlers].should eq([])
+ end
+ it "should be able to add custom handlers" do
+ o = Object.new
+ Chef::Config[:event_handlers] << o
+ Chef::Config[:event_handlers].should be_include(o)
end
end
- after(:each) do
- Chef::Config.configuration = @original_config
+ describe "Chef::Config[:user_valid_regex]" do
+ context "on a platform that is not Windows" do
+ it "allows one letter usernames" do
+ any_match = Chef::Config[:user_valid_regex].any? { |regex| regex.match('a') }
+ expect(any_match).to be_true
+ end
+ end
end
end
diff --git a/spec/unit/cookbook/metadata_spec.rb b/spec/unit/cookbook/metadata_spec.rb
index 2757f92506..cba2aff5da 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 = {
@@ -247,7 +247,7 @@ describe Chef::Cookbook::Metadata do
it "should not accept anything but a string for display_name" do
lambda {
@meta.grouping("db/mysql/databases", :title => "foo")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.grouping("db/mysql/databases", :title => Hash.new)
}.should raise_error(ArgumentError)
@@ -256,7 +256,7 @@ describe Chef::Cookbook::Metadata do
it "should not accept anything but a string for the description" do
lambda {
@meta.grouping("db/mysql/databases", :description => "foo")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.grouping("db/mysql/databases", :description => Hash.new)
}.should raise_error(ArgumentError)
@@ -281,7 +281,7 @@ describe Chef::Cookbook::Metadata do
it "should not accept anything but a string for display_name" do
lambda {
@meta.attribute("db/mysql/databases", :display_name => "foo")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :display_name => Hash.new)
}.should raise_error(ArgumentError)
@@ -290,7 +290,7 @@ describe Chef::Cookbook::Metadata do
it "should not accept anything but a string for the description" do
lambda {
@meta.attribute("db/mysql/databases", :description => "foo")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :description => Hash.new)
}.should raise_error(ArgumentError)
@@ -299,7 +299,7 @@ describe Chef::Cookbook::Metadata do
it "should not accept anything but an array of strings for choice" do
lambda {
@meta.attribute("db/mysql/databases", :choice => ['dedicated', 'shared'])
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :choice => [10, 'shared'])
}.should raise_error(ArgumentError)
@@ -312,19 +312,19 @@ 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)
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :calculated => false)
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@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
@@ -333,13 +333,13 @@ describe Chef::Cookbook::Metadata do
it "accepts String for the attribute type" do
lambda {
@meta.attribute("db/mysql/databases", :type => "string")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
end
it "accepts Array for the attribute type" do
lambda {
@meta.attribute("db/mysql/databases", :type => "array")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :type => Array.new)
}.should raise_error(ArgumentError)
@@ -348,38 +348,38 @@ describe Chef::Cookbook::Metadata do
it "accepts symbol for the attribute type" do
lambda {
@meta.attribute("db/mysql/databases", :type => "symbol")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
end
-
+
it "should let type be hash (backwards compatability only)" do
lambda {
@meta.attribute("db/mysql/databases", :type => "hash")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
end
it "should let required be required, recommended or optional" do
lambda {
@meta.attribute("db/mysql/databases", :required => 'required')
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :required => 'recommended')
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :required => 'optional')
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
end
it "should convert required true to required" do
lambda {
@meta.attribute("db/mysql/databases", :required => true)
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
#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)
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
#attrib = @meta.attributes["db/mysql/databases"][:required].should == "optional"
end
@@ -387,11 +387,11 @@ 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 => [])
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :required => Hash.new)
}.should raise_error(ArgumentError)
@@ -399,19 +399,19 @@ 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
lambda {
@meta.attribute("db/mysql/databases", :default => [])
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :default => {})
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :default => "alice in chains")
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
lambda {
@meta.attribute("db/mysql/databases", :required => :not_gonna_do_it)
}.should raise_error(ArgumentError)
@@ -438,24 +438,24 @@ 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)
+ }.should_not raise_error
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)
+ }.should_not raise_error
end
it "should error if default is not a choice" 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..c52593287a 100644
--- a/spec/unit/cookbook/synchronizer_spec.rb
+++ b/spec/unit/cookbook/synchronizer_spec.rb
@@ -14,7 +14,7 @@ describe Chef::CookbookCacheCleaner do
end
it "removes all files not validated during the chef run" do
- file_cache = mock("Chef::FileCache with files from unused cookbooks")
+ file_cache = double("Chef::FileCache with files from unused cookbooks")
unused_template_files = %w{cookbooks/unused/templates/default/foo.conf.erb cookbooks/unused/tempaltes/default/bar.conf.erb}
valid_cached_cb_files = %w{cookbooks/valid1/recipes/default.rb cookbooks/valid2/recipes/default.rb}
@cleaner.mark_file_as_valid('cookbooks/valid1/recipes/default.rb')
@@ -23,7 +23,7 @@ describe Chef::CookbookCacheCleaner do
file_cache.should_receive(:delete).with('cookbooks/unused/templates/default/foo.conf.erb')
file_cache.should_receive(:delete).with('cookbooks/unused/tempaltes/default/bar.conf.erb')
cookbook_hash = {"valid1"=> {}, "valid2" => {}}
- @cleaner.stub!(:cache).and_return(file_cache)
+ @cleaner.stub(:cache).and_return(file_cache)
@cleaner.cleanup_file_cache
end
@@ -37,7 +37,7 @@ describe Chef::CookbookCacheCleaner do
end
it "does not remove anything" do
- @cleaner.cache.stub!(:find).and_return(%w{cookbooks/valid1/recipes/default.rb cookbooks/valid2/recipes/default.rb})
+ @cleaner.cache.stub(:find).and_return(%w{cookbooks/valid1/recipes/default.rb cookbooks/valid2/recipes/default.rb})
@cleaner.cache.should_not_receive(:delete)
@cleaner.cleanup_file_cache
end
@@ -81,7 +81,7 @@ describe Chef::CookbookSynchronizer do
context "when the cache contains unneeded cookbooks" do
before do
- @file_cache = mock("Chef::FileCache with files from unused cookbooks")
+ @file_cache = double("Chef::FileCache with files from unused cookbooks")
@valid_cached_cb_files = %w{cookbooks/valid1/recipes/default.rb cookbooks/valid2/recipes/default.rb}
@obsolete_cb_files = %w{cookbooks/old1/recipes/default.rb cookbooks/old2/recipes/default.rb}
@@ -94,7 +94,7 @@ describe Chef::CookbookSynchronizer do
@file_cache.should_receive(:find).with(File.join(%w{cookbooks ** *})).and_return(@valid_cached_cb_files + @obsolete_cb_files)
@file_cache.should_receive(:delete).with('cookbooks/old1/recipes/default.rb')
@file_cache.should_receive(:delete).with('cookbooks/old2/recipes/default.rb')
- @synchronizer.stub!(:cache).and_return(@file_cache)
+ @synchronizer.stub(:cache).and_return(@file_cache)
@synchronizer.clear_obsoleted_cookbooks
end
end
@@ -103,18 +103,18 @@ describe Chef::CookbookSynchronizer do
before do
# Would rather not stub out methods on the test subject, but setting up
# the state is a PITA and tests for this behavior are above.
- @synchronizer.stub!(:clear_obsoleted_cookbooks)
+ @synchronizer.stub(:clear_obsoleted_cookbooks)
- @server_api = mock("Chef::REST (mock)")
- @file_cache = mock("Chef::FileCache (mock)")
- @synchronizer.stub!(:server_api).and_return(@server_api)
- @synchronizer.stub!(:cache).and_return(@file_cache)
+ @server_api = double("Chef::REST (mock)")
+ @file_cache = double("Chef::FileCache (mock)")
+ @synchronizer.stub(:server_api).and_return(@server_api)
+ @synchronizer.stub(:cache).and_return(@file_cache)
- @cookbook_a_default_recipe_tempfile = mock("Tempfile for cookbook_a default.rb recipe",
+ @cookbook_a_default_recipe_tempfile = double("Tempfile for cookbook_a default.rb recipe",
:path => "/tmp/cookbook_a_recipes_default_rb")
- @cookbook_a_default_attribute_tempfile = mock("Tempfile for cookbook_a default.rb attr file",
+ @cookbook_a_default_attribute_tempfile = double("Tempfile for cookbook_a default.rb attr file",
:path => "/tmp/cookbook_a_attributes_default_rb")
end
@@ -167,20 +167,20 @@ describe Chef::CookbookSynchronizer do
before do
Chef::Config[:no_lazy_load] = true
@synchronizer = Chef::CookbookSynchronizer.new(@cookbook_manifest, @events)
- @synchronizer.stub!(:server_api).and_return(@server_api)
- @synchronizer.stub!(:cache).and_return(@file_cache)
- @synchronizer.stub!(:clear_obsoleted_cookbooks)
+ @synchronizer.stub(:server_api).and_return(@server_api)
+ @synchronizer.stub(:cache).and_return(@file_cache)
+ @synchronizer.stub(:clear_obsoleted_cookbooks)
- @cookbook_a_file_default_tempfile = mock("Tempfile for cookbook_a megaman.conf file",
+ @cookbook_a_file_default_tempfile = double("Tempfile for cookbook_a megaman.conf file",
:path => "/tmp/cookbook_a_file_default_tempfile")
- @cookbook_a_template_default_tempfile = mock("Tempfile for cookbook_a apache.conf.erb template",
+ @cookbook_a_template_default_tempfile = double("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..40a89c99a4 100644
--- a/spec/unit/cookbook/syntax_check_spec.rb
+++ b/spec/unit/cookbook/syntax_check_spec.rb
@@ -28,11 +28,10 @@ describe Chef::Cookbook::SyntaxCheck do
Chef::Log.logger = Logger.new(StringIO.new)
Chef::Log.level = :warn # suppress "Syntax OK" messages
-
@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 +73,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_spec.rb b/spec/unit/cookbook_spec.rb
index c28a5c7a2a..ca4f4adc08 100644
--- a/spec/unit/cookbook_spec.rb
+++ b/spec/unit/cookbook_spec.rb
@@ -70,6 +70,7 @@ describe Chef::CookbookVersion do
it "should allow you to include a fully-qualified recipe using the DSL" do
# DSL method include_recipe allows multiple arguments, so extract the first
+ @node.should_receive(:loaded_recipe).with(:openldap, "gigantor")
recipe = @run_context.include_recipe("openldap::gigantor").first
recipe.recipe_name.should == "gigantor"
diff --git a/spec/unit/daemon_spec.rb b/spec/unit/daemon_spec.rb
index 5c0d828354..9132dae389 100644
--- a/spec/unit/daemon_spec.rb
+++ b/spec/unit/daemon_spec.rb
@@ -20,52 +20,15 @@ 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)
- Etc.stub!(:getpwnam).and_return mock_struct
- Etc.stub!(:getgrnam).and_return mock_struct
+ Etc.stub(:getpwnam).and_return mock_struct
+ Etc.stub(:getgrnam).and_return mock_struct
# mock unimplemented methods
- Process.stub!(:initgroups).and_return nil
- Process::GID.stub!(:change_privilege).and_return 11
- Process::UID.stub!(:change_privilege).and_return 11
- 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
-
+ Process.stub(:initgroups).and_return nil
+ Process::GID.stub(:change_privilege).and_return 11
+ Process::UID.stub(:change_privilege).and_return 11
end
end
@@ -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,102 +70,15 @@ 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
- Chef::Application.stub!(:fatal!).and_return(true)
+ Chef::Application.stub(:fatal!).and_return(true)
Chef::Config[:user] = 'aj'
- Dir.stub!(:chdir)
+ Dir.stub(:chdir)
end
it "changes the working directory to root" do
- Dir.rspec_reset
Dir.should_receive(:chdir).with("/").and_return(0)
Chef::Daemon.change_privilege
end
@@ -230,10 +101,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
@@ -249,25 +116,25 @@ describe Chef::Daemon do
describe "._change_privilege" do
before do
- Process.stub!(:euid).and_return(0)
- Process.stub!(:egid).and_return(0)
+ Process.stub(:euid).and_return(0)
+ Process.stub(:egid).and_return(0)
- Process::UID.stub!(:change_privilege).and_return(nil)
- Process::GID.stub!(:change_privilege).and_return(nil)
+ Process::UID.stub(:change_privilege).and_return(nil)
+ Process::GID.stub(:change_privilege).and_return(nil)
- @pw_user = mock("Struct::Passwd", :uid => 501)
- @pw_group = mock("Struct::Group", :gid => 20)
+ @pw_user = double("Struct::Passwd", :uid => 501)
+ @pw_group = double("Struct::Group", :gid => 20)
- Process.stub!(:initgroups).and_return(true)
+ Process.stub(:initgroups).and_return(true)
- Etc.stub!(:getpwnam).and_return(@pw_user)
- Etc.stub!(:getgrnam).and_return(@pw_group)
+ Etc.stub(:getpwnam).and_return(@pw_user)
+ Etc.stub(:getgrnam).and_return(@pw_group)
end
describe "with sufficient privileges" do
before do
- Process.stub!(:euid).and_return(0)
- Process.stub!(:egid).and_return(0)
+ Process.stub(:euid).and_return(0)
+ Process.stub(:egid).and_return(0)
end
it "should initialize the supplemental group list" do
@@ -288,12 +155,12 @@ describe Chef::Daemon do
describe "with insufficient privileges" do
before do
- Process.stub!(:euid).and_return(999)
- Process.stub!(:egid).and_return(999)
+ Process.stub(:euid).and_return(999)
+ Process.stub(:egid).and_return(999)
end
it "should log an appropriate error message and fail miserably" do
- Process.stub!(:initgroups).and_raise(Errno::EPERM)
+ Process.stub(:initgroups).and_raise(Errno::EPERM)
error = "Operation not permitted"
if RUBY_PLATFORM.match("solaris2") || RUBY_PLATFORM.match("aix")
error = "Not owner"
diff --git a/spec/unit/data_bag_item_spec.rb b/spec/unit/data_bag_item_spec.rb
index 6f46c81054..ead0dadfa2 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.
@@ -67,7 +67,15 @@ describe Chef::DataBagItem do
end
it "should accept alphanum/-/_ for the id" do
- lambda { @data_bag_item.raw_data = { "id" => "h1-_" } }.should_not raise_error(ArgumentError)
+ lambda { @data_bag_item.raw_data = { "id" => "h1-_" } }.should_not raise_error
+ end
+
+ it "should accept alphanum.alphanum for the id" do
+ lambda { @data_bag_item.raw_data = { "id" => "foo.bar" } }.should_not raise_error
+ end
+
+ it "should accept .alphanum for the id" do
+ lambda { @data_bag_item.raw_data = { "id" => ".bozo" } }.should_not raise_error
end
it "should raise an exception if the id contains anything but alphanum/-/_" do
@@ -130,7 +138,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
@@ -195,9 +203,9 @@ describe Chef::DataBagItem do
describe "save" do
before do
- @rest = mock("Chef::REST")
- Chef::REST.stub!(:new).and_return(@rest)
- @data_bag_item['id'] = "heart of darkness"
+ @rest = double("Chef::REST")
+ Chef::REST.stub(:new).and_return(@rest)
+ @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,8 +215,8 @@ describe Chef::DataBagItem do
@data_bag_item.save
end
- it "should create if the item is not found" do
- exception = mock("404 error", :code => "404")
+ it "should create if the item is not found" do
+ exception = double("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)
@data_bag_item.save
@@ -228,7 +236,7 @@ describe Chef::DataBagItem do
end
end
-
+
end
describe "when loading" do
@@ -239,8 +247,8 @@ describe Chef::DataBagItem do
describe "from an API call" do
before do
- @http_client = mock("Chef::REST")
- Chef::REST.stub!(:new).and_return(@http_client)
+ @http_client = double("Chef::REST")
+ Chef::REST.stub(:new).and_return(@http_client)
end
it "converts raw data to a data bag item" do
diff --git a/spec/unit/data_bag_spec.rb b/spec/unit/data_bag_spec.rb
index 273ef38d9f..4ac843c869 100644
--- a/spec/unit/data_bag_spec.rb
+++ b/spec/unit/data_bag_spec.rb
@@ -47,6 +47,12 @@ describe Chef::DataBag do
it "should throw an ArgumentError if you feed it anything but a string" do
lambda { @data_bag.name Hash.new }.should raise_error(ArgumentError)
end
+
+ [ ".", "-", "_", "1"].each do |char|
+ it "should allow a '#{char}' character in the data bag name" do
+ @data_bag.name("clown#{char}clown").should == "clown#{char}clown"
+ end
+ end
end
describe "deserialize" do
@@ -69,24 +75,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)
+ @rest = double("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 = double("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 +101,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
@@ -107,7 +111,7 @@ describe Chef::DataBag do
describe "from an API call" do
before do
Chef::Config[:chef_server_url] = 'https://myserver.example.com'
- @http_client = mock('Chef::REST')
+ @http_client = double('Chef::REST')
end
it "should get the data bag from the server" do
@@ -117,7 +121,7 @@ describe Chef::DataBag do
end
it "should return the data bag" do
- Chef::REST.stub!(:new).and_return(@http_client)
+ Chef::REST.stub(:new).and_return(@http_client)
@http_client.should_receive(:get_rest).with('data/foo').and_return({'bar' => 'https://myserver.example.com/data/foo/bar'})
data_bag = Chef::DataBag.load('foo')
data_bag.should == {'bar' => 'https://myserver.example.com/data/foo/bar'}
@@ -148,7 +152,7 @@ describe Chef::DataBag do
it "should return the data bag" do
File.should_receive(:directory?).with('/var/chef/data_bags').and_return(true)
- Dir.stub!(:glob).and_return(["/var/chef/data_bags/foo/bar.json", "/var/chef/data_bags/foo/baz.json"])
+ Dir.stub(:glob).and_return(["/var/chef/data_bags/foo/bar.json", "/var/chef/data_bags/foo/baz.json"])
IO.should_receive(:read).with('/var/chef/data_bags/foo/bar.json').and_return('{"id": "bar", "name": "Bob Bar" }')
IO.should_receive(:read).with('/var/chef/data_bags/foo/baz.json').and_return('{"id": "baz", "name": "John Baz" }')
data_bag = Chef::DataBag.load('foo')
diff --git a/spec/unit/deprecation_spec.rb b/spec/unit/deprecation_spec.rb
index 58db295067..8617cb3cb3 100644
--- a/spec/unit/deprecation_spec.rb
+++ b/spec/unit/deprecation_spec.rb
@@ -62,7 +62,7 @@ describe Chef::Deprecation do
context 'deprecation warning messages' do
before(:each) do
@warning_output = [ ]
- Chef::Log.stub!(:warn) { |msg| @warning_output << msg }
+ Chef::Log.stub(:warn) { |msg| @warning_output << msg }
end
it 'should be enabled for deprecated methods' do
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/dsl/data_query_spec.rb b/spec/unit/dsl/data_query_spec.rb
index 8960ad9957..e31c0725d6 100644
--- a/spec/unit/dsl/data_query_spec.rb
+++ b/spec/unit/dsl/data_query_spec.rb
@@ -27,7 +27,7 @@ describe Chef::DSL::DataQuery do
before(:each) do
@language = DataQueryDSLTester.new
@node = Hash.new
- @language.stub!(:node).and_return(@node)
+ @language.stub(:node).and_return(@node)
end
describe "when loading data bags and items" do
diff --git a/spec/unit/dsl/reboot_pending_spec.rb b/spec/unit/dsl/reboot_pending_spec.rb
new file mode 100644
index 0000000000..8576ae168a
--- /dev/null
+++ b/spec/unit/dsl/reboot_pending_spec.rb
@@ -0,0 +1,100 @@
+#
+# Author:: Bryan McLellan <btm@loftninjas.org>
+# Copyright:: Copyright (c) 2014 Chef Software, 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/dsl/reboot_pending"
+require "spec_helper"
+
+describe Chef::DSL::RebootPending do
+ describe "reboot_pending?" do
+ describe "in isoloation" do
+ let(:recipe) { Object.new.extend(Chef::DSL::RebootPending) }
+
+ before do
+ recipe.stub(:platform?).and_return(false)
+ end
+
+ context "platform is windows" do
+ before do
+ recipe.stub(:platform?).with('windows').and_return(true)
+ recipe.stub(:registry_key_exists?).and_return(false)
+ recipe.stub(:registry_value_exists?).and_return(false)
+ end
+
+ it 'should return true if "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations" exists' do
+ recipe.stub(:registry_value_exists?).with('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { :name => 'PendingFileRenameOperations' }).and_return(true)
+ expect(recipe.reboot_pending?).to be_true
+ end
+
+ it 'should return true if "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" exists' do
+ recipe.stub(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired').and_return(true)
+ expect(recipe.reboot_pending?).to be_true
+ end
+
+ it 'should return true if key "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired" exists' do
+ recipe.stub(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired').and_return(true)
+ expect(recipe.reboot_pending?).to be_true
+ end
+
+ it 'should return true if value "HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile" contains specific data' do
+ recipe.stub(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').and_return(true)
+ recipe.stub(:registry_get_values).with('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').and_return(
+ [{:name => "Flags", :type => :dword, :data => 3}])
+ expect(recipe.reboot_pending?).to be_true
+ end
+ end
+
+ context "platform is ubuntu" do
+ before do
+ recipe.stub(:platform?).with('ubuntu').and_return(true)
+ end
+
+ it 'should return true if /var/run/reboot-required exists' do
+ File.stub(:exists?).with('/var/run/reboot-required').and_return(true)
+ expect(recipe.reboot_pending?).to be_true
+ end
+
+ it 'should return false if /var/run/reboot-required does not exist' do
+ File.stub(:exists?).with('/var/run/reboot-required').and_return(false)
+ expect(recipe.reboot_pending?).to be_false
+ end
+ end
+
+ context "platform is not supported" do
+ it 'should raise an exception' do
+ recipe.stub_chain(:node, :[]).with(:platform).and_return('msdos')
+ expect { recipe.reboot_pending? }.to raise_error(Chef::Exceptions::UnsupportedPlatform)
+ end
+ end
+ end # describe in isolation
+
+ describe "in a recipe" do
+ it "responds to reboot_pending?" do
+ # Chef::Recipe.new(cookbook_name, recipe_name, run_context(node, cookbook_collection, events))
+ recipe = Chef::Recipe.new(nil,nil,Chef::RunContext.new(Chef::Node.new, {}, nil))
+ expect(recipe).to respond_to(:reboot_pending?)
+ end
+ end # describe in a recipe
+
+ describe "in a resource" do
+ it "responds to reboot_pending?" do
+ resource = Chef::Resource::new("Crackerjack::Timing", nil)
+ expect(resource).to respond_to(:reboot_pending?)
+ end
+ end # describe in a resource
+ end
+end
diff --git a/spec/unit/dsl/recipe_spec.rb b/spec/unit/dsl/recipe_spec.rb
new file mode 100644
index 0000000000..14ee30be44
--- /dev/null
+++ b/spec/unit/dsl/recipe_spec.rb
@@ -0,0 +1,70 @@
+#
+# Author:: Daniel DeLeo (<dan@getchef.com>)
+# Copyright:: Copyright (c) 2014 Chef Software, 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/dsl/recipe'
+
+
+RecipeDSLExampleClass = Struct.new(:cookbook_name, :recipe_name)
+class RecipeDSLExampleClass
+ include Chef::DSL::Recipe
+end
+
+RecipeDSLBaseAPI = Struct.new(:cookbook_name, :recipe_name)
+class RecipeDSLExampleSubclass < RecipeDSLBaseAPI
+ include Chef::DSL::Recipe
+end
+
+# TODO: most of DSL::Recipe's implementation is tested in Chef::Recipe's tests,
+# move those to here.
+describe Chef::DSL::Recipe do
+
+ let(:cookbook_name) { "example_cb" }
+ let(:recipe_name) { "example_recipe" }
+
+ shared_examples_for "A Recipe DSL Implementation" do
+
+ it "responds to cookbook_name" do
+ expect(recipe.cookbook_name).to eq(cookbook_name)
+ end
+
+ it "responds to recipe_name" do
+ expect(recipe.recipe_name).to eq(recipe_name)
+ end
+ end
+
+ context "when included in a class that defines the required interface directly" do
+
+ let(:recipe) { RecipeDSLExampleClass.new(cookbook_name, recipe_name) }
+
+ include_examples "A Recipe DSL Implementation"
+
+ end
+
+ # This is the situation that occurs when the Recipe DSL gets mixed in to a
+ # resource, for example.
+ context "when included in a class that defines the required interface in a superclass" do
+
+ let(:recipe) { RecipeDSLExampleSubclass.new(cookbook_name, recipe_name) }
+
+ include_examples "A Recipe DSL Implementation"
+
+ end
+
+end
+
diff --git a/spec/unit/encrypted_data_bag_item_spec.rb b/spec/unit/encrypted_data_bag_item_spec.rb
index 9eda1633ab..1e662a0b7c 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
@@ -298,35 +283,49 @@ describe Chef::EncryptedDataBagItem do
end
describe ".load_secret" do
- subject(:loaded_secret) { Chef::EncryptedDataBagItem.load_secret(path) }
- let(:path) { "/var/mysecret" }
let(:secret) { "opensesame" }
- let(:stubbed_path) { path }
- before do
- ::File.stub(:exist?).with(stubbed_path).and_return(true)
- IO.stub(:read).with(stubbed_path).and_return(secret)
- Kernel.stub(:open).with(path).and_return(StringIO.new(secret))
+
+ context "when /var/mysecret exists" do
+ before do
+ ::File.stub(:exist?).with("/var/mysecret").and_return(true)
+ IO.stub(:read).with("/var/mysecret").and_return(secret)
+ end
+
+ it "load_secret('/var/mysecret') reads the secret" do
+ Chef::EncryptedDataBagItem.load_secret("/var/mysecret").should eq secret
+ end
end
- it "reads from a specified path" do
- loaded_secret.should eq secret
+ context "when /etc/chef/encrypted_data_bag_secret exists" do
+ before do
+ path = Chef::Config.platform_specific_path("/etc/chef/encrypted_data_bag_secret")
+ ::File.stub(:exist?).with(path).and_return(true)
+ IO.stub(:read).with(path).and_return(secret)
+ end
+
+ it "load_secret(nil) reads the secret" do
+ Chef::EncryptedDataBagItem.load_secret(nil).should eq secret
+ end
end
- context "path argument is nil" do
- let(:path) { nil }
- let(:stubbed_path) { "/etc/chef/encrypted_data_bag_secret" }
+ context "when /etc/chef/encrypted_data_bag_secret does not exist" do
+ before do
+ path = Chef::Config.platform_specific_path("/etc/chef/encrypted_data_bag_secret")
+ ::File.stub(:exist?).with(path).and_return(false)
+ end
- it "reads from Chef::Config[:encrypted_data_bag_secret]" do
- Chef::Config[:encrypted_data_bag_secret] = stubbed_path
- loaded_secret.should eq secret
+ it "load_secret(nil) emits a reasonable error message" do
+ lambda { Chef::EncryptedDataBagItem.load_secret(nil) }.should raise_error(ArgumentError, "No secret specified to load_secret and no secret found at #{Chef::Config.platform_specific_path('/etc/chef/encrypted_data_bag_secret')}")
end
end
context "path argument is a URL" do
- let(:path) { "http://www.opscode.com/" }
+ before do
+ Kernel.stub(:open).with("http://www.opscode.com/").and_return(StringIO.new(secret))
+ end
- it "reads the URL" do
- loaded_secret.should eq secret
+ it "reads from the URL" do
+ Chef::EncryptedDataBagItem.load_secret("http://www.opscode.com/").should eq secret
end
end
end
diff --git a/spec/unit/environment_spec.rb b/spec/unit/environment_spec.rb
index 5f9675a307..ebbcdd9861 100644
--- a/spec/unit/environment_spec.rb
+++ b/spec/unit/environment_spec.rb
@@ -355,16 +355,16 @@ describe Chef::Environment do
describe "api model" do
before(:each) do
- @rest = mock("Chef::REST")
- Chef::REST.stub!(:new).and_return(@rest)
- @query = mock("Chef::Search::Query")
- Chef::Search::Query.stub!(:new).and_return(@query)
+ @rest = double("Chef::REST")
+ Chef::REST.stub(:new).and_return(@rest)
+ @query = double("Chef::Search::Query")
+ Chef::Search::Query.stub(:new).and_return(@query)
end
describe "list" do
describe "inflated" do
it "should return a hash of environment names and objects" do
- e1 = mock("Chef::Environment", :name => "one")
+ e1 = double("Chef::Environment", :name => "one")
@query.should_receive(:search).with(:environment).and_yield(e1)
r = Chef::Environment.list(true)
r["one"].should == e1
diff --git a/spec/unit/file_access_control_spec.rb b/spec/unit/file_access_control_spec.rb
index 609bd826b6..4e257c2a22 100644
--- a/spec/unit/file_access_control_spec.rb
+++ b/spec/unit/file_access_control_spec.rb
@@ -36,7 +36,7 @@ describe Chef::FileAccessControl do
@run_context = Chef::RunContext.new(@node, {}, @events)
@current_resource = Chef::Resource::File.new('/tmp/different_file.txt')
@provider_requirements = Chef::Provider::ResourceRequirements.new(@resource, @run_context)
- @provider = mock("File provider", :requirements => @provider_requirements, :manage_symlink_access? => false)
+ @provider = double("File provider", :requirements => @provider_requirements, :manage_symlink_access? => false)
@fac = Chef::FileAccessControl.new(@current_resource, @resource, @provider)
end
@@ -217,7 +217,7 @@ describe Chef::FileAccessControl do
@resource.group(2342)
@current_resource.group(2342)
- # @fac.stub!(:stat).and_return(OpenStruct.new(:gid => 2342))
+ # @fac.stub(:stat).and_return(OpenStruct.new(:gid => 2342))
File.should_not_receive(:chown)
@fac.set_group
@fac.should_not be_modified
@@ -267,7 +267,7 @@ describe Chef::FileAccessControl do
it "sets the file's mode as specified in the resource when the current modes are incorrect" do
# stat returns modes like 0100644 (octal) => 33188 (decimal)
- #@fac.stub!(:stat).and_return(OpenStruct.new(:mode => 33188))
+ #@fac.stub(:stat).and_return(OpenStruct.new(:mode => 33188))
@current_resource.mode("0644")
File.should_receive(:chmod).with(256, '/tmp/different_file.txt')
@fac.set_mode
@@ -280,7 +280,7 @@ describe Chef::FileAccessControl do
end
it "does not set the file's mode when the current modes are correct" do
- #@fac.stub!(:stat).and_return(OpenStruct.new(:mode => 0100400))
+ #@fac.stub(:stat).and_return(OpenStruct.new(:mode => 0100400))
@current_resource.mode("0400")
File.should_not_receive(:chmod)
@fac.set_mode
@@ -288,7 +288,7 @@ describe Chef::FileAccessControl do
end
it "sets all access controls on a file" do
- @fac.stub!(:stat).and_return(OpenStruct.new(:owner => 99, :group => 99, :mode => 0100444))
+ @fac.stub(:stat).and_return(OpenStruct.new(:owner => 99, :group => 99, :mode => 0100444))
@resource.mode(0400)
@resource.owner(0)
@resource.group(0)
diff --git a/spec/unit/file_cache_spec.rb b/spec/unit/file_cache_spec.rb
index 6596326565..f57f11dcc2 100644
--- a/spec/unit/file_cache_spec.rb
+++ b/spec/unit/file_cache_spec.rb
@@ -41,10 +41,10 @@ describe Chef::FileCache do
end
end
-
+
describe "when storing a file" do
before do
- File.stub!(:open).and_yield(@io)
+ File.stub(:open).and_yield(@io)
end
it "should print the contents to the file" do
diff --git a/spec/unit/file_content_management/deploy/mv_unix_spec.rb b/spec/unit/file_content_management/deploy/mv_unix_spec.rb
index 2be0abe7bb..0e8662b8ec 100644
--- a/spec/unit/file_content_management/deploy/mv_unix_spec.rb
+++ b/spec/unit/file_content_management/deploy/mv_unix_spec.rb
@@ -37,7 +37,7 @@ describe Chef::FileContentManagement::Deploy::MvUnix do
let(:target_file_mode) { 0644 }
let(:target_file_stat) do
- mock "File::Stat struct for target file",
+ double "File::Stat struct for target file",
:mode => target_file_mode,
:uid => target_file_uid,
:gid => target_file_gid
diff --git a/spec/unit/file_content_management/deploy/mv_windows_spec.rb b/spec/unit/file_content_management/deploy/mv_windows_spec.rb
index 0a0b1f899a..7c2a2d7e71 100644
--- a/spec/unit/file_content_management/deploy/mv_windows_spec.rb
+++ b/spec/unit/file_content_management/deploy/mv_windows_spec.rb
@@ -51,11 +51,11 @@ describe Chef::FileContentManagement::Deploy::MvWindows do
let(:staging_file_path) { "/tmp/random-dir/staging-file.tmp" }
let(:target_file_security_object) do
- mock "Securable Object for target file"
+ double "Securable Object for target file"
end
let(:updated_target_security_object) do
- mock "Securable Object for target file after staging file deploy"
+ double "Securable Object for target file after staging file deploy"
end
before do
@@ -79,17 +79,17 @@ describe Chef::FileContentManagement::Deploy::MvWindows do
context "when run with administrator privileges" do
- let(:original_target_file_owner) { mock("original target file owner") }
- let(:original_target_file_group) { mock("original target file group") }
+ let(:original_target_file_owner) { double("original target file owner") }
+ let(:original_target_file_group) { double("original target file group") }
let(:target_file_security_descriptor) do
- mock "security descriptor for target file",
+ double "security descriptor for target file",
:group => original_target_file_group,
:owner => original_target_file_owner
end
let(:updated_target_security_descriptor) do
- mock "security descriptor for target file"
+ double "security descriptor for target file"
end
@@ -116,17 +116,17 @@ describe Chef::FileContentManagement::Deploy::MvWindows do
end
context "and the target has a dacl and sacl" do
- let(:inherited_dacl_ace) { mock("Windows dacl ace (inherited)", :inherited? => true) }
- let(:not_inherited_dacl_ace) { mock("Windows dacl ace (not inherited)", :inherited? => false) }
+ let(:inherited_dacl_ace) { double("Windows dacl ace (inherited)", :inherited? => true) }
+ let(:not_inherited_dacl_ace) { double("Windows dacl ace (not inherited)", :inherited? => false) }
let(:original_target_file_dacl) { [inherited_dacl_ace, not_inherited_dacl_ace] }
- let(:inherited_sacl_ace) { mock("Windows sacl ace (inherited)", :inherited? => true) }
- let(:not_inherited_sacl_ace) { mock("Windows sacl ace (not inherited)", :inherited? => false) }
+ let(:inherited_sacl_ace) { double("Windows sacl ace (inherited)", :inherited? => true) }
+ let(:not_inherited_sacl_ace) { double("Windows sacl ace (not inherited)", :inherited? => false) }
let(:original_target_file_sacl) { [inherited_sacl_ace, not_inherited_sacl_ace] }
- let(:custom_dacl) { mock("Windows ACL for non-inherited dacl aces") }
- let(:custom_sacl) { mock("Windows ACL for non-inherited sacl aces") }
+ let(:custom_dacl) { double("Windows ACL for non-inherited dacl aces") }
+ let(:custom_sacl) { double("Windows ACL for non-inherited sacl aces") }
before do
target_file_security_descriptor.stub(:dacl_present?).and_return(true)
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..bea7eeed21 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.
@@ -51,7 +51,7 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
# Error inspector originally used file_cache_path which is incorrect on
# chef-solo. Using cookbook_path should do the right thing for client and
# solo.
- Chef::Config.stub!(:cookbook_path).and_return([ "/home/someuser/dev-laptop/cookbooks" ])
+ Chef::Config.stub(:cookbook_path).and_return([ "/home/someuser/dev-laptop/cookbooks" ])
@trace = [
"/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'",
"/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'",
@@ -71,7 +71,7 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
describe "when explaining an error in the compile phase" do
before do
- Chef::Config.stub!(:cookbook_path).and_return([ "/var/chef/cache/cookbooks" ])
+ Chef::Config.stub(:cookbook_path).and_return([ "/var/chef/cache/cookbooks" ])
recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" }
IO.should_receive(:readlines).with("/var/chef/cache/cookbooks/syntax-err/recipes/default.rb").and_return(recipe_lines)
@trace = [
@@ -96,9 +96,9 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
describe "when explaining an error on windows" do
before do
- Chef::Config.stub!(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ])
+ 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
@@ -154,7 +154,7 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
describe "when explaining an error on windows, and the backtrace lowercases the drive letter" do
before do
- Chef::Config.stub!(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ])
+ 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).with("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb").and_return(recipe_lines)
@trace = [
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..c573dc016b 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.
@@ -34,7 +34,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@response_body = %Q({"error": [{"message": "gtfo"}])
@response = Net::HTTPForbidden.new("1.1", "403", "(response) forbidden")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) forbidden", @response)
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
@@ -55,7 +55,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@response_body = "{\"error\":[\"{\\\"non_existent_cookbooks\\\":[\\\"apache2\\\"],\\\"cookbooks_with_no_versions\\\":[\\\"users\\\"],\\\"message\\\":\\\"Run list contains invalid items: no such cookbook nope.\\\"}\"]}"
@response = Net::HTTPPreconditionFailed.new("1.1", "412", "(response) unauthorized")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) precondition failed", @response)
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
@@ -83,7 +83,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@response_body = "{\"error\":[{\"non_existent_cookbooks\":[],\"cookbooks_with_no_versions\":[],\"message\":\"unable to solve dependencies in alotted time.\"}]}"
@response = Net::HTTPPreconditionFailed.new("1.1", "412", "(response) unauthorized")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) precondition failed", @response)
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
@@ -106,7 +106,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@response_body = "{\"error\":[{\"non_existent_cookbooks\":[\"apache2\"],\"cookbooks_with_no_versions\":[\"users\"],\"message\":\"Run list contains invalid items: no such cookbook nope.\"}]}"
@response = Net::HTTPPreconditionFailed.new("1.1", "412", "(response) unauthorized")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) precondition failed", @response)
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
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..e586f5e3b3 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.
@@ -29,7 +29,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookSyncErrorInspector do
before do
@response_body = "sad trombone orchestra"
@response = Net::HTTPBadGateway.new("1.1", "502", "(response) bad gateway")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPFatalError.new("(exception) bad gateway", @response)
@inspector = described_class.new({}, @exception)
@inspector.add_explanation(@description)
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..8cafbcc9d6 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.
@@ -32,18 +32,21 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
"rspec-example"
end
+ def recipe_name
+ "rspec-example-recipe"
+ end
+
before do
@description = Chef::Formatters::ErrorDescription.new("Error Converging Resource:")
@stdout = StringIO.new
@outputter = Chef::Formatters::Outputter.new(@stdout, STDERR)
#@outputter = Chef::Formatters::Outputter.new(STDOUT, STDERR)
- Chef::Config.stub!(:cookbook_path).and_return([ "/var/chef/cache" ])
+ Chef::Config.stub(:cookbook_path).and_return([ "/var/chef/cache" ])
end
describe "when explaining an error converging a resource" do
before do
- source_line = caller(0)[0]
@resource = package("non-existing-package") do
only_if do
@@ -112,8 +115,8 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
before do
# fake code to run through #recipe_snippet
source_file = [ "if true", "var = non_existant", "end" ]
- IO.stub!(:readlines).and_return(source_file)
- File.stub!(:exists?).and_return(true)
+ IO.stub(:readlines).and_return(source_file)
+ File.stub(:exists?).and_return(true)
end
it "parses a Windows path" do
@@ -129,11 +132,11 @@ 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)
- IO.stub!(:readlines).and_raise(Errno::ENOENT)
+ File.stub(:exists?).and_return(false)
+ IO.stub(:readlines).and_raise(Errno::ENOENT)
end
it "does not try to parse a recipe in chef-shell/irb (CHEF-3411)" do
@@ -141,7 +144,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)
@@ -172,7 +175,7 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
end
it "does not generate an error" do
- lambda { @inspector.add_explanation(@description) }.should_not raise_error(TypeError)
+ lambda { @inspector.add_explanation(@description) }.should_not raise_error
@description.display(@outputter)
end
end
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..56a6eceec3 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.
@@ -55,10 +55,10 @@ describe Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector do
@response_body = "forbidden"
@response = Net::HTTPForbidden.new("1.1", "403", "(response) forbidden")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) forbidden", @response)
@inspector = Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector.new(@node, @exception)
- @inspector.stub!(:config).and_return(:node_name => "unit-test.example.com")
+ @inspector.stub(:config).and_return(:node_name => "unit-test.example.com")
@inspector.add_explanation(@description)
end
@@ -73,11 +73,11 @@ describe Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector do
before do
@response_body = "check your key and node name"
@response = Net::HTTPUnauthorized.new("1.1", "401", "(response) unauthorized")
- @response.stub!(:body).and_return(@response_body)
+ @response.stub(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
@inspector = Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector.new(@node, @exception)
- @inspector.stub!(:config).and_return(:node_name => "unit-test.example.com",
+ @inspector.stub(:config).and_return(:node_name => "unit-test.example.com",
:client_key => "/etc/chef/client.pem",
:chef_server_url => "http://chef.example.com")
diff --git a/spec/unit/handler/json_file_spec.rb b/spec/unit/handler/json_file_spec.rb
index 1f47c40937..05270e4731 100644
--- a/spec/unit/handler/json_file_spec.rb
+++ b/spec/unit/handler/json_file_spec.rb
@@ -46,7 +46,7 @@ describe Chef::Handler::JsonFile do
@run_status.run_context = @run_context
@run_status.exception = Exception.new("Boy howdy!")
@file_mock = StringIO.new
- File.stub!(:open).and_yield(@file_mock)
+ File.stub(:open).and_yield(@file_mock)
end
diff --git a/spec/unit/handler_spec.rb b/spec/unit/handler_spec.rb
index 9eeba478ac..80d9df5e82 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.
@@ -42,7 +42,7 @@ describe Chef::Handler do
@run_status.run_context = @run_context
@start_time = Time.now
@end_time = @start_time + 4.2
- Time.stub!(:now).and_return(@start_time, @end_time)
+ Time.stub(:now).and_return(@start_time, @end_time)
@run_status.start_clock
@run_status.stop_clock
end
@@ -124,11 +124,11 @@ describe Chef::Handler do
@run_status.run_context = @run_context
@start_time = Time.now
@end_time = @start_time + 4.2
- Time.stub!(:now).and_return(@start_time, @end_time)
+ 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
@@ -171,7 +171,7 @@ describe Chef::Handler do
describe "when running a start handler" do
before do
@start_time = Time.now
- Time.stub!(:now).and_return(@start_time)
+ Time.stub(:now).and_return(@start_time)
@run_status.start_clock
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..b95e13a370
--- /dev/null
+++ b/spec/unit/http/ssl_policies_spec.rb
@@ -0,0 +1,170 @@
+#--
+# 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
+
+ context "and some certs are duplicates" do
+ it "skips duplicate certs" do
+ # For whatever reason, OpenSSL errors out when adding a
+ # cert you already have to the certificate store.
+ ssl_policy.set_custom_certs
+ ssl_policy.set_custom_certs #should not raise an error
+ end
+ 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/http_spec.rb b/spec/unit/http_spec.rb
new file mode 100644
index 0000000000..d747482260
--- /dev/null
+++ b/spec/unit/http_spec.rb
@@ -0,0 +1,48 @@
+#
+# Author:: Xabier de Zuazo (xabier@onddo.com)
+# Copyright:: Copyright (c) 2014 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/http'
+require 'chef/http/basic_client'
+
+describe Chef::HTTP do
+
+ describe "head" do
+
+ it 'should return nil for a "200 Success" response (CHEF-4762)' do
+ resp = Net::HTTPOK.new("1.1", 200, "OK")
+ resp.should_receive(:read_body).and_return(nil)
+ http = Chef::HTTP.new("")
+ Chef::HTTP::BasicClient.any_instance.should_receive(:request).and_return(["request", resp])
+
+ http.head("http://www.getchef.com/").should eql(nil)
+ end
+
+ it 'should return false for a "304 Not Modified" response (CHEF-4762)' do
+ resp = Net::HTTPNotModified.new("1.1", 304, "Not Modified")
+ resp.should_receive(:read_body).and_return(nil)
+ http = Chef::HTTP.new("")
+ Chef::HTTP::BasicClient.any_instance.should_receive(:request).and_return(["request", resp])
+
+ http.head("http://www.getchef.com/").should eql(false)
+ end
+
+ end # head
+
+end
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index c716896302..b055cadcee 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
@@ -39,9 +29,9 @@ describe Chef::Knife::Bootstrap do
@knife.merge_configs
@knife.config[:template_file] = File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb"))
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
@stderr = StringIO.new
- @knife.ui.stub!(:stderr).and_return(@stderr)
+ @knife.ui.stub(:stderr).and_return(@stderr)
end
it "should return a name of default bootstrap template" do
@@ -57,8 +47,8 @@ describe Chef::Knife::Bootstrap do
it "should look for templates early in the run" do
File.stub(:exists?).and_return(true)
@knife.name_args = ['shatner']
- @knife.stub!(:read_template).and_return("")
- @knife.stub!(:knife_ssh).and_return(true)
+ @knife.stub(:read_template).and_return("")
+ @knife.stub(:knife_ssh).and_return(true)
@knife_ssh = @knife.knife_ssh
@knife.should_receive(:find_template).ordered
@knife.should_receive(:knife_ssh).ordered
@@ -120,10 +110,10 @@ describe Chef::Knife::Bootstrap do
it "should populate a hint file with JSON when given a file to read" do
@knife.stub(:find_template).and_return(true)
@knife.config[:template_file] = File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test-hints.erb"))
- ::File.stub!(:read).and_return('{ "foo" : "bar" }')
+ ::File.stub(:read).and_return('{ "foo" : "bar" }')
@knife.instance_variable_set("@template_file", @knife.config[:template_file])
template_string = @knife.read_template
- @knife.stub!(:read_template).and_return('{ "foo" : "bar" }')
+ @knife.stub(:read_template).and_return('{ "foo" : "bar" }')
@knife.parse_options(["--hint", "openstack=hints/openstack.json"])
@knife.render_template(template_string).should match /\{\"foo\":\"bar\"\}/
end
@@ -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
@@ -197,7 +214,7 @@ describe Chef::Knife::Bootstrap do
Chef::Config[:knife][:ssh_port] = nil
@knife.config[:forward_agent] = true
@knife.config[:identity_file] = "~/.ssh/me.rsa"
- @knife.stub!(:read_template).and_return("")
+ @knife.stub(:read_template).and_return("")
@knife_ssh = @knife.knife_ssh
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
@@ -265,7 +282,7 @@ describe Chef::Knife::Bootstrap do
Chef::Config[:knife][:identity_file] = "~/.ssh/you.rsa"
Chef::Config[:knife][:ssh_gateway] = "towel.blinkenlights.nl"
Chef::Config[:knife][:host_key_verify] = true
- @knife.stub!(:read_template).and_return("")
+ @knife.stub(:read_template).and_return("")
@knife_ssh = @knife.knife_ssh
end
@@ -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
@@ -299,20 +316,20 @@ describe Chef::Knife::Bootstrap do
@knife.name_args = ["foo.example.com"]
@knife.config[:ssh_user] = "rooty"
@knife.config[:identity_file] = "~/.ssh/me.rsa"
- @knife.stub!(:read_template).and_return("")
+ @knife.stub(:read_template).and_return("")
@knife_ssh = @knife.knife_ssh
end
it "prompts the user for a password " do
- @knife.stub!(:knife_ssh).and_return(@knife_ssh)
- @knife_ssh.stub!(:get_password).and_return('typed_in_password')
+ @knife.stub(:knife_ssh).and_return(@knife_ssh)
+ @knife_ssh.stub(:get_password).and_return('typed_in_password')
alternate_knife_ssh = @knife.knife_ssh_with_password_auth
alternate_knife_ssh.config[:ssh_password].should == 'typed_in_password'
end
it "configures knife not to use the identity file that didn't work previously" do
- @knife.stub!(:knife_ssh).and_return(@knife_ssh)
- @knife_ssh.stub!(:get_password).and_return('typed_in_password')
+ @knife.stub(:knife_ssh).and_return(@knife_ssh)
+ @knife_ssh.stub(:get_password).and_return('typed_in_password')
alternate_knife_ssh = @knife.knife_ssh_with_password_auth
alternate_knife_ssh.config[:identity_file].should be_nil
end
@@ -324,9 +341,9 @@ describe Chef::Knife::Bootstrap do
@knife.name_args = ["foo.example.com"]
@knife.config[:ssh_user] = "rooty"
@knife.config[:identity_file] = "~/.ssh/me.rsa"
- @knife.stub!(:read_template).and_return("")
+ @knife.stub(:read_template).and_return("")
@knife_ssh = @knife.knife_ssh
- @knife.stub!(:knife_ssh).and_return(@knife_ssh)
+ @knife.stub(:knife_ssh).and_return(@knife_ssh)
end
it "verifies that a server to bootstrap was given as a command line arg" do
@@ -341,11 +358,11 @@ describe Chef::Knife::Bootstrap do
end
it "falls back to password based auth when auth fails the first time" do
- @knife.stub!(:puts)
+ @knife.stub(:puts)
@fallback_knife_ssh = @knife_ssh.dup
@knife_ssh.should_receive(:run).and_raise(Net::SSH::AuthenticationFailed.new("no ssh for you"))
- @knife.stub!(:knife_ssh_with_password_auth).and_return(@fallback_knife_ssh)
+ @knife.stub(:knife_ssh_with_password_auth).and_return(@fallback_knife_ssh)
@fallback_knife_ssh.should_receive(:run)
@knife.run
end
diff --git a/spec/unit/knife/client_bulk_delete_spec.rb b/spec/unit/knife/client_bulk_delete_spec.rb
index 55351554d1..bedd4911c5 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.
@@ -26,42 +26,42 @@ describe Chef::Knife::ClientBulkDelete do
@knife = Chef::Knife::ClientBulkDelete.new
@knife.name_args = ["."]
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
- @knife.ui.stub!(:confirm).and_return(true)
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ @knife.ui.stub(:confirm).and_return(true)
@clients = Hash.new
%w{tim dan stephen}.each do |client_name|
client = Chef::ApiClient.new()
client.name(client_name)
- client.stub!(:destroy).and_return(true)
+ client.stub(:destroy).and_return(true)
@clients[client_name] = client
end
- Chef::ApiClient.stub!(:list).and_return(@clients)
+ 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..897cee8974 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.
@@ -25,16 +25,18 @@ describe Chef::Knife::ClientCreate do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::ClientCreate.new
@knife.config = {
- :file => nil
+ :file => nil,
+ :admin => false,
+ :validator => false
}
@knife.name_args = [ "adam" ]
@client = Chef::ApiClient.new
- @client.stub!(:save).and_return({ 'private_key' => '' })
- @knife.stub!(:edit_data).and_return(@client)
- @knife.stub!(:puts)
- Chef::ApiClient.stub!(:new).and_return(@client)
+ @client.stub(:save).and_return({ 'private_key' => '' })
+ @knife.stub(:edit_data).and_return(@client)
+ @knife.stub(:puts)
+ Chef::ApiClient.stub(:new).and_return(@client)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
@@ -49,6 +51,16 @@ describe Chef::Knife::ClientCreate do
@knife.run
end
+ it "by default it is not an admin" do
+ @client.should_receive(:admin).with(false)
+ @knife.run
+ end
+
+ it "by default it is not a validator" do
+ @client.should_receive(:validator).with(false)
+ @knife.run
+ end
+
it "should allow you to edit the data" do
@knife.should_receive(:edit_data).with(@client)
@knife.run
@@ -62,13 +74,29 @@ describe Chef::Knife::ClientCreate do
describe "with -f or --file" do
it "should write the private key to a file" do
@knife.config[:file] = "/tmp/monkeypants"
- @client.stub!(:save).and_return({ 'private_key' => "woot" })
- filehandle = mock("Filehandle")
+ @client.stub(:save).and_return({ 'private_key' => "woot" })
+ filehandle = double("Filehandle")
filehandle.should_receive(:print).with('woot')
File.should_receive(:open).with("/tmp/monkeypants", "w").and_yield(filehandle)
@knife.run
end
end
+ describe "with -a or --admin" do
+ it "should create an admin client" do
+ @knife.config[:admin] = true
+ @client.should_receive(:admin).with(true)
+ @knife.run
+ end
+ end
+
+ describe "with --validator" do
+ it "should create an validator client" do
+ @knife.config[:validator] = true
+ @client.should_receive(:validator).with(true)
+ @knife.run
+ end
+ end
+
end
end
diff --git a/spec/unit/knife/client_delete_spec.rb b/spec/unit/knife/client_delete_spec.rb
index 865f19f713..a7ec14ce83 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.
@@ -21,12 +21,16 @@ require 'spec_helper'
describe Chef::Knife::ClientDelete do
before(:each) do
@knife = Chef::Knife::ClientDelete.new
+ # defaults
+ @knife.config = {
+ :force => false
+ }
@knife.name_args = [ 'adam' ]
end
describe 'run' do
it 'should delete the client' do
- @knife.should_receive(:delete_object).with(Chef::ApiClient, 'adam')
+ @knife.should_receive(:delete_object).with(Chef::ApiClient, 'adam', 'client')
@knife.run
end
@@ -37,4 +41,43 @@ describe Chef::Knife::ClientDelete do
lambda { @knife.run }.should raise_error(SystemExit)
end
end
+
+ describe 'with a validator' do
+ before(:each) do
+ Chef::Knife::UI.stub(:confirm).and_return(true)
+ @knife.stub(:confirm).and_return(true)
+ @client = Chef::ApiClient.new
+ Chef::ApiClient.should_receive(:load).and_return(@client)
+ end
+
+ it 'should delete non-validator client if --force is not set' do
+ @knife.config[:force] = false
+ @client.should_receive(:destroy).and_return(@client)
+ @knife.should_receive(:msg)
+
+ @knife.run
+ end
+
+ it 'should delete non-validator client if --force is set' do
+ @knife.config[:force] = true
+ @client.should_receive(:destroy).and_return(@client)
+ @knife.should_receive(:msg)
+
+ @knife.run
+ end
+
+ it 'should not delete validator client if --force is not set' do
+ @client.validator(true)
+ @knife.ui.should_receive(:fatal)
+ lambda { @knife.run}.should raise_error(SystemExit)
+ end
+
+ it 'should delete validator client if --force is set' do
+ @knife.config[:force] = true
+ @client.should_receive(:destroy).and_return(@client)
+ @knife.should_receive(:msg)
+
+ @knife.run
+ end
+ end
end
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..daf18d5d25 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.
@@ -22,9 +22,9 @@ describe Chef::Knife::ClientReregister do
before(:each) do
@knife = Chef::Knife::ClientReregister.new
@knife.name_args = [ 'adam' ]
- @client_mock = mock('client_mock', :private_key => "foo_key")
+ @client_mock = double('client_mock', :private_key => "foo_key")
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
context "when no client name is given on the command line" do
diff --git a/spec/unit/knife/client_show_spec.rb b/spec/unit/knife/client_show_spec.rb
index 5bac3b4af6..b5c95db097 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.
@@ -22,7 +22,7 @@ describe Chef::Knife::ClientShow do
before(:each) do
@knife = Chef::Knife::ClientShow.new
@knife.name_args = [ 'adam' ]
- @client_mock = mock('client_mock')
+ @client_mock = double('client_mock')
end
describe 'run' do
diff --git a/spec/unit/knife/config_file_selection_spec.rb b/spec/unit/knife/config_file_selection_spec.rb
index 33aaddbf48..0a623714d7 100644
--- a/spec/unit/knife/config_file_selection_spec.rb
+++ b/spec/unit/knife/config_file_selection_spec.rb
@@ -20,6 +20,20 @@ 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"]
@@ -31,13 +45,13 @@ describe Chef::Knife do
end
before :each do
- Chef::Config.stub!(:from_file).and_return(true)
+ 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
@@ -47,9 +61,7 @@ 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
@@ -59,10 +71,8 @@ describe Chef::Knife do
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
- Chef::Knife.stub!(:chef_config_dir).and_return(upward_dir)
+ have_config_file(upward_config)
+ Chef::Knife.stub(:chef_config_dir).and_return(upward_dir)
@knife = Chef::Knife.new
@knife.configure_chef
@@ -71,9 +81,7 @@ describe Chef::Knife do
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
@@ -81,7 +89,7 @@ describe Chef::Knife do
end
it "configure knife from nothing" do
- ::File.stub!(:exist?).and_return(false)
+ ::File.stub(:exist?).and_return(false)
@knife = Chef::Knife.new
@knife.ui.should_receive(:warn).with("No knife configuration file found")
@knife.configure_chef
@@ -95,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)
+
+ 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
+ @knife.config[:config_file].should be_nil
- configs.delete env_config
- @knife.config.delete :config_file
+ 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_client_spec.rb b/spec/unit/knife/configure_client_spec.rb
index ba832103bc..d101780317 100644
--- a/spec/unit/knife/configure_client_spec.rb
+++ b/spec/unit/knife/configure_client_spec.rb
@@ -26,7 +26,7 @@ describe Chef::Knife::ConfigureClient do
Chef::Config[:validation_key] = '/etc/chef/validation.pem'
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe 'run' do
@@ -56,7 +56,7 @@ describe Chef::Knife::ConfigureClient do
end
it 'should write out the config file' do
- FileUtils.stub!(:mkdir_p)
+ FileUtils.stub(:mkdir_p)
@knife.run
@client_file.string.should match /log_level\s+\:info/
@client_file.string.should match /log_location\s+STDOUT/
@@ -65,13 +65,13 @@ describe Chef::Knife::ConfigureClient do
end
it 'should write out the validation.pem file' do
- FileUtils.stub!(:mkdir_p)
+ FileUtils.stub(:mkdir_p)
@knife.run
@validation_file.string.should match /foo_bar_baz/
end
it 'should print information on what is being configured' do
- FileUtils.stub!(:mkdir_p)
+ FileUtils.stub(:mkdir_p)
@knife.run
@stdout.string.should match /creating client configuration/i
@stdout.string.should match /writing client\.rb/i
diff --git a/spec/unit/knife/configure_spec.rb b/spec/unit/knife/configure_spec.rb
index 3fe4f86eb9..eab42fadd5 100644
--- a/spec/unit/knife/configure_spec.rb
+++ b/spec/unit/knife/configure_spec.rb
@@ -4,28 +4,22 @@ 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 })
- @knife.stub!(:rest).and_return(@rest_client)
+ @rest_client = double("null rest client", :post_rest => { :result => :true })
+ @knife.stub(:rest).and_return(@rest_client)
@out = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@out)
+ @knife.ui.stub(:stdout).and_return(@out)
@knife.config[:config_file] = '/home/you/.chef/knife.rb'
@in = StringIO.new("\n" * 7)
- @knife.ui.stub!(:stdin).and_return(@in)
+ @knife.ui.stub(:stdin).and_return(@in)
@err = StringIO.new
- @knife.ui.stub!(:stderr).and_return(@err)
-
- Ohai::System.stub!(:new).and_return(ohai)
- end
+ @knife.ui.stub(:stderr).and_return(@err)
- after do
- Chef::Config.configuration.replace(@original_config)
+ Ohai::System.stub(:new).and_return(ohai)
end
@@ -55,7 +49,7 @@ describe Chef::Knife::Configure do
it "asks the user for the clientname they want for the new client if -i is specified" do
@knife.config[:initial] = true
- Etc.stub!(:getlogin).and_return("a-new-user")
+ Etc.stub(:getlogin).and_return("a-new-user")
@knife.ask_user_for_config
@out.string.should match(Regexp.escape("Please enter a name for the new user: [a-new-user]"))
@knife.new_client_name.should == Etc.getlogin
@@ -64,14 +58,14 @@ describe Chef::Knife::Configure do
it "should not ask the user for the clientname they want for the new client if -i and --node_name are specified" do
@knife.config[:initial] = true
@knife.config[:node_name] = 'testnode'
- Etc.stub!(:getlogin).and_return("a-new-user")
+ Etc.stub(:getlogin).and_return("a-new-user")
@knife.ask_user_for_config
@out.string.should_not match(Regexp.escape("Please enter a name for the new user"))
@knife.new_client_name.should == 'testnode'
end
it "asks the user for the existing API username or clientname if -i is not specified" do
- Etc.stub!(:getlogin).and_return("a-new-user")
+ Etc.stub(:getlogin).and_return("a-new-user")
@knife.ask_user_for_config
@out.string.should match(Regexp.escape("Please enter an existing username or clientname for the API: [a-new-user]"))
@knife.new_client_name.should == Etc.getlogin
@@ -181,7 +175,7 @@ describe Chef::Knife::Configure do
@knife.config[:validation_key] = '/home/you/.chef/my-validation.pem'
@knife.config[:repository] = ''
@knife.config[:client_key] = '/home/you/a-new-user.pem'
- Etc.stub!(:getlogin).and_return('a-new-user')
+ Etc.stub(:getlogin).and_return('a-new-user')
@knife.ask_user_for_config
@out.string.should match(/\s*/)
@@ -203,10 +197,10 @@ describe Chef::Knife::Configure do
end
it "writes the new data to a config file" do
- File.stub!(:expand_path).with("/home/you/.chef/knife.rb").and_return("/home/you/.chef/knife.rb")
- File.stub!(:expand_path).with("/home/you/.chef/#{Etc.getlogin}.pem").and_return("/home/you/.chef/#{Etc.getlogin}.pem")
- File.stub!(:expand_path).with(default_validator_key).and_return(default_validator_key)
- File.stub!(:expand_path).with(default_admin_key).and_return(default_admin_key)
+ File.stub(:expand_path).with("/home/you/.chef/knife.rb").and_return("/home/you/.chef/knife.rb")
+ File.stub(:expand_path).with("/home/you/.chef/#{Etc.getlogin}.pem").and_return("/home/you/.chef/#{Etc.getlogin}.pem")
+ File.stub(:expand_path).with(default_validator_key).and_return(default_validator_key)
+ File.stub(:expand_path).with(default_admin_key).and_return(default_admin_key)
FileUtils.should_receive(:mkdir_p).with("/home/you/.chef")
config_file = StringIO.new
::File.should_receive(:open).with("/home/you/.chef/knife.rb", "w").and_yield config_file
@@ -230,9 +224,9 @@ describe Chef::Knife::Configure do
user_command = Chef::Knife::UserCreate.new
user_command.should_receive(:run)
- Etc.stub!(:getlogin).and_return("a-new-user")
+ Etc.stub(:getlogin).and_return("a-new-user")
- Chef::Knife::UserCreate.stub!(:new).and_return(user_command)
+ Chef::Knife::UserCreate.stub(:new).and_return(user_command)
FileUtils.should_receive(:mkdir_p).with("/home/you/.chef")
::File.should_receive(:open).with("/home/you/.chef/knife.rb", "w")
@knife.config[:initial] = true
diff --git a/spec/unit/knife/cookbook_bulk_delete_spec.rb b/spec/unit/knife/cookbook_bulk_delete_spec.rb
index ced2a9a4e4..0cff690bc2 100644
--- a/spec/unit/knife/cookbook_bulk_delete_spec.rb
+++ b/spec/unit/knife/cookbook_bulk_delete_spec.rb
@@ -27,18 +27,18 @@ describe Chef::Knife::CookbookBulkDelete do
@knife.config = {:print_after => nil}
@knife.name_args = ["."]
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
- @knife.ui.stub!(:confirm).and_return(true)
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ @knife.ui.stub(:confirm).and_return(true)
@cookbooks = Hash.new
%w{cheezburger pizza lasagna}.each do |cookbook_name|
cookbook = Chef::CookbookVersion.new(cookbook_name)
@cookbooks[cookbook_name] = cookbook
end
- @rest = mock("Chef::REST")
- @rest.stub!(:get_rest).and_return(@cookbooks)
- @rest.stub!(:delete_rest).and_return(true)
- @knife.stub!(:rest).and_return(@rest)
- Chef::CookbookVersion.stub!(:list).and_return(@cookbooks)
+ @rest = double("Chef::REST")
+ @rest.stub(:get_rest).and_return(@cookbooks)
+ @rest.stub(:delete_rest).and_return(true)
+ @knife.stub(:rest).and_return(@rest)
+ Chef::CookbookVersion.stub(:list).and_return(@cookbooks)
end
@@ -47,11 +47,11 @@ describe Chef::Knife::CookbookBulkDelete do
describe "when there are several cookbooks on the server" do
before do
@cheezburger = {'cheezburger' => {"url" => "file:///dev/null", "versions" => [{"url" => "file:///dev/null-cheez", "version" => "1.0.0"}]}}
- @rest.stub!(:get_rest).with('cookbooks/cheezburger').and_return(@cheezburger)
+ @rest.stub(:get_rest).with('cookbooks/cheezburger').and_return(@cheezburger)
@pizza = {'pizza' => {"url" => "file:///dev/null", "versions" => [{"url" => "file:///dev/null-pizza", "version" => "2.0.0"}]}}
- @rest.stub!(:get_rest).with('cookbooks/pizza').and_return(@pizza)
+ @rest.stub(:get_rest).with('cookbooks/pizza').and_return(@pizza)
@lasagna = {'lasagna' => {"url" => "file:///dev/null", "versions" => [{"url" => "file:///dev/null-lasagna", "version" => "3.0.0"}]}}
- @rest.stub!(:get_rest).with('cookbooks/lasagna').and_return(@lasagna)
+ @rest.stub(:get_rest).with('cookbooks/lasagna').and_return(@lasagna)
end
it "should print the cookbooks you are about to delete" do
diff --git a/spec/unit/knife/cookbook_create_spec.rb b/spec/unit/knife/cookbook_create_spec.rb
index dc1d7d7f79..06475d3ac9 100644
--- a/spec/unit/knife/cookbook_create_spec.rb
+++ b/spec/unit/knife/cookbook_create_spec.rb
@@ -26,7 +26,7 @@ describe Chef::Knife::CookbookCreate do
@knife.config = {}
@knife.name_args = ["foobar"]
@stdout = StringIO.new
- @knife.stub!(:stdout).and_return(@stdout)
+ @knife.stub(:stdout).and_return(@stdout)
end
describe "run" do
@@ -35,10 +35,10 @@ describe Chef::Knife::CookbookCreate do
it "should expand the path of the cookbook directory" do
File.should_receive(:expand_path).with("~/tmp/monkeypants")
@knife.config = {:cookbook_path => "~/tmp/monkeypants"}
- @knife.stub!(:create_cookbook)
- @knife.stub!(:create_readme)
- @knife.stub!(:create_changelog)
- @knife.stub!(:create_metadata)
+ @knife.stub(:create_cookbook)
+ @knife.stub(:create_readme)
+ @knife.stub(:create_changelog)
+ @knife.stub(:create_metadata)
@knife.run
end
@@ -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_delete_spec.rb b/spec/unit/knife/cookbook_delete_spec.rb
index afaa3b69a5..f4ba46f513 100644
--- a/spec/unit/knife/cookbook_delete_spec.rb
+++ b/spec/unit/knife/cookbook_delete_spec.rb
@@ -24,9 +24,9 @@ describe Chef::Knife::CookbookDelete do
@knife.name_args = ['foobar']
@knife.cookbook_name = 'foobar'
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
@stderr = StringIO.new
- @knife.ui.stub!(:stderr).and_return(@stderr)
+ @knife.ui.stub(:stderr).and_return(@stderr)
end
describe 'run' do
@@ -125,7 +125,7 @@ describe Chef::Knife::CookbookDelete do
describe 'available_versions' do
before(:each) do
- @rest_mock = mock('rest')
+ @rest_mock = double('rest')
@knife.should_receive(:rest).and_return(@rest_mock)
@cookbook_data = { 'foobar' => { 'versions' => [{'version' => '1.0.0'},
{'version' => '1.1.0'},
@@ -163,7 +163,7 @@ describe Chef::Knife::CookbookDelete do
describe 'ask_which_version_to_delete' do
before(:each) do
- @knife.stub!(:available_versions).and_return(['1.0.0', '1.1.0', '2.0.0'])
+ @knife.stub(:available_versions).and_return(['1.0.0', '1.1.0', '2.0.0'])
end
it 'should prompt the user to select a version' do
@@ -202,7 +202,7 @@ describe Chef::Knife::CookbookDelete do
end
it 'should output that the cookbook was deleted' do
- @knife.stub!(:delete_request)
+ @knife.stub(:delete_request)
@knife.delete_version_without_confirmation('1.0.0')
@stdout.string.should match /deleted cookbook\[foobar\]\[1.0.0\]/im
end
@@ -211,7 +211,7 @@ describe Chef::Knife::CookbookDelete do
it 'should display the cookbook data' do
object = ''
@knife.config[:print_after] = true
- @knife.stub!(:delete_request).and_return(object)
+ @knife.stub(:delete_request).and_return(object)
@knife.should_receive(:format_for_display).with(object)
@knife.delete_version_without_confirmation('1.0.0')
end
diff --git a/spec/unit/knife/cookbook_download_spec.rb b/spec/unit/knife/cookbook_download_spec.rb
index cc3c300fdf..efab98f646 100644
--- a/spec/unit/knife/cookbook_download_spec.rb
+++ b/spec/unit/knife/cookbook_download_spec.rb
@@ -22,7 +22,7 @@ describe Chef::Knife::CookbookDownload do
before(:each) do
@knife = Chef::Knife::CookbookDownload.new
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe 'run' do
@@ -44,7 +44,7 @@ describe Chef::Knife::CookbookDownload do
before(:each) do
@knife.name_args = ['foobar']
@knife.config[:download_directory] = '/var/tmp/chef'
- @rest_mock = mock('rest')
+ @rest_mock = double('rest')
@knife.stub(:rest).and_return(@rest_mock)
@manifest_data = {
@@ -66,18 +66,18 @@ describe Chef::Knife::CookbookDownload do
]
}
- @cookbook_mock = mock('cookbook')
- @cookbook_mock.stub!(:version).and_return('1.0.0')
- @cookbook_mock.stub!(:manifest).and_return(@manifest_data)
+ @cookbook_mock = double('cookbook')
+ @cookbook_mock.stub(:version).and_return('1.0.0')
+ @cookbook_mock.stub(:manifest).and_return(@manifest_data)
@rest_mock.should_receive(:get_rest).with('cookbooks/foobar/1.0.0').
and_return(@cookbook_mock)
end
it 'should determine which version if one was not explicitly specified'do
- @cookbook_mock.stub!(:manifest).and_return({})
+ @cookbook_mock.stub(:manifest).and_return({})
@knife.should_receive(:determine_version).and_return('1.0.0')
File.should_receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(false)
- Chef::CookbookVersion.stub!(:COOKBOOK_SEGEMENTS).and_return([])
+ Chef::CookbookVersion.stub(:COOKBOOK_SEGEMENTS).and_return([])
@knife.run
end
@@ -87,8 +87,8 @@ describe Chef::Knife::CookbookDownload do
@files = @manifest_data.values.map { |v| v.map { |i| i['path'] } }.flatten.uniq
@files_mocks = {}
@files.map { |f| File.basename(f) }.flatten.uniq.each do |f|
- @files_mocks[f] = mock("#{f}_mock")
- @files_mocks[f].stub!(:path).and_return("/var/tmp/#{f}")
+ @files_mocks[f] = double("#{f}_mock")
+ @files_mocks[f].stub(:path).and_return("/var/tmp/#{f}")
end
end
@@ -207,7 +207,7 @@ describe Chef::Knife::CookbookDownload do
describe 'ask_which_version' do
before(:each) do
@knife.cookbook_name = 'foobar'
- @knife.stub!(:available_versions).and_return(['1.0.0', '1.1.0', '2.0.0'])
+ @knife.stub(:available_versions).and_return(['1.0.0', '1.1.0', '2.0.0'])
end
it 'should prompt the user to select a version' do
diff --git a/spec/unit/knife/cookbook_list_spec.rb b/spec/unit/knife/cookbook_list_spec.rb
index db6f061bd1..9ff16edb37 100644
--- a/spec/unit/knife/cookbook_list_spec.rb
+++ b/spec/unit/knife/cookbook_list_spec.rb
@@ -21,8 +21,8 @@ require 'spec_helper'
describe Chef::Knife::CookbookList do
before do
@knife = Chef::Knife::CookbookList.new
- @rest_mock = mock('rest')
- @knife.stub!(:rest).and_return(@rest_mock)
+ @rest_mock = double('rest')
+ @knife.stub(:rest).and_return(@rest_mock)
@cookbook_names = ['apache2', 'mysql']
@base_url = 'https://server.example.com/cookbooks'
@cookbook_data = {}
@@ -32,7 +32,7 @@ describe Chef::Knife::CookbookList do
'url' => "#{@base_url}/#{item}/1.0.1"}]}
end
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe 'run' do
diff --git a/spec/unit/knife/cookbook_metadata_from_file_spec.rb b/spec/unit/knife/cookbook_metadata_from_file_spec.rb
index 60555d89dc..68ab6740ab 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.
@@ -27,10 +27,10 @@ describe Chef::Knife::CookbookMetadataFromFile do
@tgt = File.expand_path(File.join(CHEF_SPEC_DATA, "metadata", "quick_start", "metadata.json"))
@knife = Chef::Knife::CookbookMetadataFromFile.new
@knife.name_args = [ @src ]
- @knife.stub!(:to_json_pretty).and_return(true)
+ @knife.stub(:to_json_pretty).and_return(true)
@md = Chef::Cookbook::Metadata.new
Chef::Cookbook::Metadata.stub(:new).and_return(@md)
- $stdout.stub!(:write)
+ $stdout.stub(:write)
end
after do
diff --git a/spec/unit/knife/cookbook_metadata_spec.rb b/spec/unit/knife/cookbook_metadata_spec.rb
index c664326a3d..92db650435 100644
--- a/spec/unit/knife/cookbook_metadata_spec.rb
+++ b/spec/unit/knife/cookbook_metadata_spec.rb
@@ -26,8 +26,8 @@ describe Chef::Knife::CookbookMetadata do
@json_data = '{ "version": "1.0.0" }'
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
- @knife.ui.stub!(:stderr).and_return(@stderr)
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stderr).and_return(@stderr)
end
describe 'run' do
@@ -84,7 +84,7 @@ describe Chef::Knife::CookbookMetadata do
describe 'generate_metadata' do
before(:each) do
@knife.config[:cookbook_path] = @cookbook_dir
- File.stub!(:expand_path).with("#{@cookbook_dir}/foobar/metadata.rb").
+ File.stub(:expand_path).with("#{@cookbook_dir}/foobar/metadata.rb").
and_return("#{@cookbook_dir}/foobar/metadata.rb")
end
@@ -105,12 +105,12 @@ describe Chef::Knife::CookbookMetadata do
describe 'generate_metadata_from_file' do
before(:each) do
- @metadata_mock = mock('metadata')
- @json_file_mock = mock('json_file')
+ @metadata_mock = double('metadata')
+ @json_file_mock = double('json_file')
end
it 'should generate the metatdata json from metatdata.rb' do
- Chef::Cookbook::Metadata.stub!(:new).and_return(@metadata_mock)
+ Chef::Cookbook::Metadata.stub(:new).and_return(@metadata_mock)
@metadata_mock.should_receive(:name).with('foobar')
@metadata_mock.should_receive(:from_file).with("#{@cookbook_dir}/foobar/metadata.rb")
File.should_receive(:open).with("#{@cookbook_dir}/foobar/metadata.json", 'w').
@@ -127,7 +127,7 @@ describe Chef::Knife::CookbookMetadata do
}.each_pair do |klass, description|
it "should print an error and exit when an #{description} syntax exception is encountered" do
exception = klass.new("#{description} blah")
- Chef::Cookbook::Metadata.stub!(:new).and_raise(exception)
+ Chef::Cookbook::Metadata.stub(:new).and_raise(exception)
lambda {
@knife.generate_metadata_from_file('foobar', "#{@cookbook_dir}/foobar/metadata.rb")
}.should raise_error(SystemExit)
@@ -165,7 +165,7 @@ describe Chef::Knife::CookbookMetadata do
IO.should_receive(:read).with("#{@cookbook_dir}/foobar/metadata.json").
and_return(@json_data)
exception = klass.new("#{description} blah")
- Chef::Cookbook::Metadata.stub!(:validate_json).and_raise(exception)
+ Chef::Cookbook::Metadata.stub(:validate_json).and_raise(exception)
lambda {
@knife.validate_metadata_json(@cookbook_dir, 'foobar')
}.should raise_error(SystemExit)
diff --git a/spec/unit/knife/cookbook_show_spec.rb b/spec/unit/knife/cookbook_show_spec.rb
index 2f2d841fea..b862c3154c 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.
@@ -25,10 +25,10 @@ describe Chef::Knife::CookbookShow do
@knife = Chef::Knife::CookbookShow.new
@knife.config = { }
@knife.name_args = [ "cookbook_name" ]
- @rest = mock(Chef::REST)
- @knife.stub!(:rest).and_return(@rest)
- @knife.stub!(:pretty_print).and_return(true)
- @knife.stub!(:output).and_return(true)
+ @rest = double(Chef::REST)
+ @knife.stub(:rest).and_return(@rest)
+ @knife.stub(:pretty_print).and_return(true)
+ @knife.stub(:output).and_return(true)
end
describe "run" do
@@ -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_download_spec.rb b/spec/unit/knife/cookbook_site_download_spec.rb
index a3d43c5b4a..faf58f7bc7 100644
--- a/spec/unit/knife/cookbook_site_download_spec.rb
+++ b/spec/unit/knife/cookbook_site_download_spec.rb
@@ -24,7 +24,7 @@ describe Chef::Knife::CookbookSiteDownload do
before do
@knife = Chef::Knife::CookbookSiteDownload.new
@knife.name_args = ['apache2']
- @noauth_rest = mock 'no auth rest'
+ @noauth_rest = double('no auth rest')
@stdout = StringIO.new
@cookbook_api_url = 'http://cookbooks.opscode.com/api/v1/cookbooks'
@version = '1.0.2'
@@ -58,7 +58,7 @@ describe Chef::Knife::CookbookSiteDownload do
before do
@cookbook_data = { 'version' => @version,
'file' => "http://example.com/apache2_#{@version_us}.tgz" }
- @temp_file = stub :path => "/tmp/apache2_#{@version_us}.tgz"
+ @temp_file = double( :path => "/tmp/apache2_#{@version_us}.tgz" )
@file = File.join(Dir.pwd, "apache2-#{@version}.tar.gz")
@noauth_rest.should_receive(:sign_on_redirect=).with(false)
@@ -125,7 +125,7 @@ describe Chef::Knife::CookbookSiteDownload do
@version_us = @version.gsub '.', '_'
@cookbook_data = { 'version' => @version,
'file' => "http://example.com/apache2_#{@version_us}.tgz" }
- @temp_file = stub :path => "/tmp/apache2_#{@version_us}.tgz"
+ @temp_file = double(:path => "/tmp/apache2_#{@version_us}.tgz")
@file = File.join(Dir.pwd, "apache2-#{@version}.tar.gz")
@knife.name_args << @version
end
diff --git a/spec/unit/knife/cookbook_site_install_spec.rb b/spec/unit/knife/cookbook_site_install_spec.rb
index 43afe09f5e..3086c817d9 100644
--- a/spec/unit/knife/cookbook_site_install_spec.rb
+++ b/spec/unit/knife/cookbook_site_install_spec.rb
@@ -25,25 +25,25 @@ 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 ]
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.stub!(:stderr).and_return(@stdout)
- @knife.stub!(:stdout).and_return(@stdout)
+ @knife.stub(:stderr).and_return(@stdout)
+ @knife.stub(:stdout).and_return(@stdout)
#Assume all external commands would have succeed. :(
- File.stub!(:unlink)
- File.stub!(:rmtree)
- @knife.stub!(:shell_out!).and_return(true)
+ File.stub(:unlink)
+ File.stub(:rmtree)
+ @knife.stub(:shell_out!).and_return(true)
#CookbookSiteDownload Stup
@downloader = {}
- @knife.stub!(:download_cookbook_to).and_return(@downloader)
- @downloader.stub!(:version).and_return do
+ @knife.stub(:download_cookbook_to).and_return(@downloader)
+ @downloader.stub(:version).and_return do
if @knife.name_args.size == 2
@knife.name_args[1]
else
@@ -55,7 +55,7 @@ describe Chef::Knife::CookbookSiteInstall do
@repo = stub(:sanity_check => true, :reset_to_default_state => true,
:prepare_to_import => true, :finalize_updates_to => true,
:merge_updates_from => true)
- Chef::Knife::CookbookSCMRepo.stub!(:new).and_return(@repo)
+ Chef::Knife::CookbookSCMRepo.stub(:new).and_return(@repo)
end
diff --git a/spec/unit/knife/cookbook_site_share_spec.rb b/spec/unit/knife/cookbook_site_share_spec.rb
index 3b912af0c5..14c4262cb3 100644
--- a/spec/unit/knife/cookbook_site_share_spec.rb
+++ b/spec/unit/knife/cookbook_site_share_spec.rb
@@ -29,25 +29,25 @@ describe Chef::Knife::CookbookSiteShare do
@cookbook = Chef::CookbookVersion.new('cookbook_name')
- @cookbook_loader = mock('Chef::CookbookLoader')
- @cookbook_loader.stub!(:cookbook_exists?).and_return(true)
- @cookbook_loader.stub!(:[]).and_return(@cookbook)
- Chef::CookbookLoader.stub!(:new).and_return(@cookbook_loader)
+ @cookbook_loader = double('Chef::CookbookLoader')
+ @cookbook_loader.stub(:cookbook_exists?).and_return(true)
+ @cookbook_loader.stub(:[]).and_return(@cookbook)
+ Chef::CookbookLoader.stub(:new).and_return(@cookbook_loader)
@cookbook_uploader = Chef::CookbookUploader.new('herpderp', File.join(CHEF_SPEC_DATA, 'cookbooks'), :rest => "norest")
- Chef::CookbookUploader.stub!(:new).and_return(@cookbook_uploader)
- @cookbook_uploader.stub!(:validate_cookbooks).and_return(true)
- Chef::CookbookSiteStreamingUploader.stub!(:create_build_dir).and_return(Dir.mktmpdir)
+ Chef::CookbookUploader.stub(:new).and_return(@cookbook_uploader)
+ @cookbook_uploader.stub(:validate_cookbooks).and_return(true)
+ Chef::CookbookSiteStreamingUploader.stub(:create_build_dir).and_return(Dir.mktmpdir)
Chef::Mixin::Command.stub(:run_command).and_return(true)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe 'run' do
before(:each) do
- @knife.stub!(:do_upload).and_return(true)
+ @knife.stub(:do_upload).and_return(true)
end
it 'should should print usage and exit when given no arguments' do
@@ -83,7 +83,7 @@ describe Chef::Knife::CookbookSiteShare do
end
it 'should exit and log to error when the tarball creation fails' do
- Chef::Mixin::Command.stub!(:run_command).and_raise(Chef::Exceptions::Exec)
+ Chef::Mixin::Command.stub(:run_command).and_raise(Chef::Exceptions::Exec)
@knife.ui.should_receive(:error)
lambda { @knife.run }.should raise_error(SystemExit)
end
@@ -98,44 +98,44 @@ describe Chef::Knife::CookbookSiteShare do
describe 'do_upload' do
before(:each) do
- @upload_response = mock('Net::HTTPResponse')
- Chef::CookbookSiteStreamingUploader.stub!(:post).and_return(@upload_response)
+ @upload_response = double('Net::HTTPResponse')
+ Chef::CookbookSiteStreamingUploader.stub(:post).and_return(@upload_response)
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
- @knife.ui.stub!(:stderr).and_return(@stderr)
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stderr).and_return(@stderr)
File.stub(:open).and_return(true)
end
it 'should post the cookbook to "http://cookbooks.opscode.com"' do
response_text = {:uri => 'http://cookbooks.opscode.com/cookbooks/cookbook_name'}.to_json
- @upload_response.stub!(:body).and_return(response_text)
- @upload_response.stub!(:code).and_return(201)
+ @upload_response.stub(:body).and_return(response_text)
+ @upload_response.stub(:code).and_return(201)
Chef::CookbookSiteStreamingUploader.should_receive(:post).with(/cookbooks\.opscode\.com/, anything(), anything(), anything())
@knife.run
end
it 'should alert the user when a version already exists' do
response_text = {:error_messages => ['Version already exists']}.to_json
- @upload_response.stub!(:body).and_return(response_text)
- @upload_response.stub!(:code).and_return(409)
+ @upload_response.stub(:body).and_return(response_text)
+ @upload_response.stub(:code).and_return(409)
lambda { @knife.run }.should raise_error(SystemExit)
@stderr.string.should match(/ERROR(.+)cookbook already exists/)
end
it 'should pass any errors on to the user' do
response_text = {:error_messages => ["You're holding it wrong"]}.to_json
- @upload_response.stub!(:body).and_return(response_text)
- @upload_response.stub!(:code).and_return(403)
+ @upload_response.stub(:body).and_return(response_text)
+ @upload_response.stub(:code).and_return(403)
lambda { @knife.run }.should raise_error(SystemExit)
@stderr.string.should match("ERROR(.*)You're holding it wrong")
end
it 'should print the body if no errors are exposed on failure' do
response_text = {:system_error => "Your call was dropped", :reason => "There's a map for that"}.to_json
- @upload_response.stub!(:body).and_return(response_text)
- @upload_response.stub!(:code).and_return(500)
+ @upload_response.stub(:body).and_return(response_text)
+ @upload_response.stub(:code).and_return(500)
@knife.ui.should_receive(:error).with(/#{Regexp.escape(response_text)}/)#.ordered
@knife.ui.should_receive(:error).with(/Unknown error/)#.ordered
lambda { @knife.run }.should raise_error(SystemExit)
diff --git a/spec/unit/knife/cookbook_site_unshare_spec.rb b/spec/unit/knife/cookbook_site_unshare_spec.rb
index ffba2ec664..14cda65b43 100644
--- a/spec/unit/knife/cookbook_site_unshare_spec.rb
+++ b/spec/unit/knife/cookbook_site_unshare_spec.rb
@@ -24,13 +24,13 @@ describe Chef::Knife::CookbookSiteUnshare do
before(:each) do
@knife = Chef::Knife::CookbookSiteUnshare.new
@knife.name_args = ['cookbook_name']
- @knife.stub!(:confirm).and_return(true)
+ @knife.stub(:confirm).and_return(true)
- @rest = mock('Chef::REST')
- @rest.stub!(:delete_rest).and_return(true)
- @knife.stub!(:rest).and_return(@rest)
+ @rest = double('Chef::REST')
+ @rest.stub(:delete_rest).and_return(true)
+ @knife.stub(:rest).and_return(@rest)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe 'run' do
@@ -55,14 +55,14 @@ describe Chef::Knife::CookbookSiteUnshare do
end
it 'should log an error and exit when forbidden' do
- exception = mock('403 "Forbidden"', :code => '403')
- @rest.stub!(:delete_rest).and_raise(Net::HTTPServerException.new('403 "Forbidden"', exception))
+ exception = double('403 "Forbidden"', :code => '403')
+ @rest.stub(:delete_rest).and_raise(Net::HTTPServerException.new('403 "Forbidden"', exception))
@knife.ui.should_receive(:error)
lambda { @knife.run }.should raise_error(SystemExit)
end
it 'should re-raise any non-forbidden errors on delete_rest' do
- exception = mock('500 "Application Error"', :code => '500')
+ exception = double('500 "Application Error"', :code => '500')
@rest.stub(:delete_rest).and_raise(Net::HTTPServerException.new('500 "Application Error"', exception))
lambda { @knife.run }.should raise_error(Net::HTTPServerException)
end
diff --git a/spec/unit/knife/cookbook_test_spec.rb b/spec/unit/knife/cookbook_test_spec.rb
index 24c658dc6c..0e261c02a4 100644
--- a/spec/unit/knife/cookbook_test_spec.rb
+++ b/spec/unit/knife/cookbook_test_spec.rb
@@ -26,25 +26,25 @@ describe Chef::Knife::CookbookTest do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::CookbookTest.new
@knife.config[:cookbook_path] = File.join(CHEF_SPEC_DATA,'cookbooks')
- @knife.cookbook_loader.stub!(:cookbook_exists?).and_return(true)
+ @knife.cookbook_loader.stub(:cookbook_exists?).and_return(true)
@cookbooks = []
%w{tats central_market jimmy_johns pho}.each do |cookbook_name|
@cookbooks << Chef::CookbookVersion.new(cookbook_name)
end
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
it "should test the cookbook" do
- @knife.stub!(:test_cookbook).and_return(true)
+ @knife.stub(:test_cookbook).and_return(true)
@knife.name_args = ["italian"]
@knife.should_receive(:test_cookbook).with("italian")
@knife.run
end
it "should test multiple cookbooks when provided" do
- @knife.stub!(:test_cookbook).and_return(true)
+ @knife.stub(:test_cookbook).and_return(true)
@knife.name_args = ["tats", "jimmy_johns"]
@knife.should_receive(:test_cookbook).with("tats")
@knife.should_receive(:test_cookbook).with("jimmy_johns")
@@ -65,14 +65,14 @@ describe Chef::Knife::CookbookTest do
describe "with -a or --all" do
it "should test all of the cookbooks" do
- @knife.stub!(:test_cookbook).and_return(true)
+ @knife.stub(:test_cookbook).and_return(true)
@knife.config[:all] = true
@loader = {}
- @loader.stub!(:load_cookbooks).and_return(@loader)
+ @loader.stub(:load_cookbooks).and_return(@loader)
@cookbooks.each do |cookbook|
@loader[cookbook.name] = cookbook
end
- @knife.stub!(:cookbook_loader).and_return(@loader)
+ @knife.stub(:cookbook_loader).and_return(@loader)
@loader.each do |key, cookbook|
@knife.should_receive(:test_cookbook).with(cookbook.name)
end
diff --git a/spec/unit/knife/cookbook_upload_spec.rb b/spec/unit/knife/cookbook_upload_spec.rb
index d9f1b8f1ce..65331b3952 100644
--- a/spec/unit/knife/cookbook_upload_spec.rb
+++ b/spec/unit/knife/cookbook_upload_spec.rb
@@ -30,19 +30,33 @@ describe Chef::Knife::CookbookUpload do
@cookbook = Chef::CookbookVersion.new('test_cookbook')
@cookbook_loader = {}
- @cookbook_loader.stub!(:[]).and_return(@cookbook)
- @cookbook_loader.stub!(:merged_cookbooks).and_return([])
- @cookbook_loader.stub!(:load_cookbooks).and_return(@cookbook_loader)
- Chef::CookbookLoader.stub!(:new).and_return(@cookbook_loader)
+ @cookbook_loader.stub(:[]).and_return(@cookbook)
+ @cookbook_loader.stub(:merged_cookbooks).and_return([])
+ @cookbook_loader.stub(:load_cookbooks).and_return(@cookbook_loader)
+ Chef::CookbookLoader.stub(:new).and_return(@cookbook_loader)
@output = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@output)
- @knife.ui.stub!(:stderr).and_return(@output)
+ @knife.ui.stub(:stdout).and_return(@output)
+ @knife.ui.stub(:stderr).and_return(@output)
+ end
+
+ describe 'with --concurrency' do
+ it 'should upload cookbooks with predefined concurrency' do
+ @cookbook_uploader = double(:upload_cookbooks => nil)
+ Chef::CookbookVersion.stub(:list_all_versions).and_return({})
+ @knife.config[:concurrency] = 3
+ @test_cookbook = Chef::CookbookVersion.new('test_cookbook')
+ @cookbook_loader.stub(:each).and_yield("test_cookbook", @test_cookbook)
+ @cookbook_loader.stub(:cookbook_names).and_return(["test_cookbook"])
+ Chef::CookbookUploader.should_receive(:new).with( kind_of(Array), kind_of(Array),
+ {:force=>nil, :concurrency => 3}).and_return(double("Chef::CookbookUploader", :upload_cookbooks=> true))
+ @knife.run
+ end
end
describe 'run' do
before(:each) do
- @cookbook_uploader = stub(:upload_cookbooks => nil)
+ @cookbook_uploader = double(:upload_cookbooks => nil)
Chef::CookbookUploader.stub(:new => @cookbook_uploader)
Chef::CookbookVersion.stub(:list_all_versions).and_return({})
end
@@ -84,9 +98,9 @@ describe Chef::Knife::CookbookUpload do
'test_cookbook3' => Chef::CookbookVersion.new('test_cookbook3')
}
@cookbook_loader = {}
- @cookbook_loader.stub!(:merged_cookbooks).and_return([])
+ @cookbook_loader.stub(:merged_cookbooks).and_return([])
@cookbook_loader.stub(:[]) { |ckbk| @cookbooks[ckbk] }
- Chef::CookbookLoader.stub!(:new).and_return(@cookbook_loader)
+ Chef::CookbookLoader.stub(:new).and_return(@cookbook_loader)
end
it "should read only one cookbook" do
@@ -116,16 +130,16 @@ describe Chef::Knife::CookbookUpload do
@test_cookbook2.metadata.depends("test_cookbook3")
@test_cookbook3.metadata.depends("test_cookbook1")
@test_cookbook3.metadata.depends("test_cookbook2")
- @cookbook_loader.stub!(:[]) do |ckbk|
+ @cookbook_loader.stub(:[]) do |ckbk|
{ "test_cookbook1" => @test_cookbook1,
"test_cookbook2" => @test_cookbook2,
"test_cookbook3" => @test_cookbook3 }[ckbk]
end
- @knife.stub!(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2", "test_cookbook3"])
+ @knife.stub(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2", "test_cookbook3"])
@knife.should_receive(:upload).exactly(3).times
Timeout::timeout(5) do
@knife.run
- end.should_not raise_error(Timeout::Error)
+ end.should_not raise_error
end
end
@@ -140,8 +154,8 @@ describe Chef::Knife::CookbookUpload do
@knife.config[:all] = true
@test_cookbook1 = Chef::CookbookVersion.new('test_cookbook1')
@test_cookbook2 = Chef::CookbookVersion.new('test_cookbook2')
- @cookbook_loader.stub!(:each).and_yield("test_cookbook1", @test_cookbook1).and_yield("test_cookbook2", @test_cookbook2)
- @cookbook_loader.stub!(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2"])
+ @cookbook_loader.stub(:each).and_yield("test_cookbook1", @test_cookbook1).and_yield("test_cookbook2", @test_cookbook2)
+ @cookbook_loader.stub(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2"])
end
it 'should upload all cookbooks' do
@@ -156,7 +170,7 @@ describe Chef::Knife::CookbookUpload do
end
it 'should update the version constraints for an environment' do
- @knife.stub!(:assert_environment_valid!).and_return(true)
+ @knife.stub(:assert_environment_valid!).and_return(true)
@knife.config[:environment] = "production"
@knife.should_receive(:update_version_constraints).once
@knife.run
@@ -174,9 +188,9 @@ describe Chef::Knife::CookbookUpload do
end
it 'should not update the version constraints for an environment' do
- @knife.stub!(:assert_environment_valid!).and_return(true)
+ @knife.stub(:assert_environment_valid!).and_return(true)
@knife.config[:environment] = "production"
- @knife.stub!(:upload).and_raise(Chef::Exceptions::CookbookFrozen)
+ @knife.stub(:upload).and_raise(Chef::Exceptions::CookbookFrozen)
@knife.ui.should_receive(:error).with(/Failed to upload 1 cookbook/)
@knife.ui.should_receive(:warn).with(/Not updating version constraints/)
@knife.should_not_receive(:update_version_constraints)
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/core/cookbook_scm_repo_spec.rb b/spec/unit/knife/core/cookbook_scm_repo_spec.rb
index 629164ad0a..69da5400b0 100644
--- a/spec/unit/knife/core/cookbook_scm_repo_spec.rb
+++ b/spec/unit/knife/core/cookbook_scm_repo_spec.rb
@@ -54,17 +54,17 @@ BRANCHES
describe "and the repo dir exists" do
before do
- ::File.stub!(:directory?).with(@repo_path).and_return(true)
+ ::File.stub(:directory?).with(@repo_path).and_return(true)
end
it "exits when there is no git repo" do
- ::File.stub!(:directory?).with(/.*\.git/).and_return(false)
+ ::File.stub(:directory?).with(/.*\.git/).and_return(false)
lambda {@cookbook_repo.sanity_check}.should raise_error(SystemExit)
end
describe "and the repo is a git repo" do
before do
- ::File.stub!(:directory?).with(File.join(@repo_path, '.git')).and_return(true)
+ ::File.stub(:directory?).with(File.join(@repo_path, '.git')).and_return(true)
end
it "exits when the default branch doesn't exist" do
@@ -92,7 +92,7 @@ DIRTY
describe "and the repo is clean" do
before do
@clean_status = Mixlib::ShellOut.new.tap {|s| s.stdout.replace("\n")}
- @cookbook_repo.stub!(:shell_out!).with('git status --porcelain', :cwd => @repo_path).and_return(@clean_status)
+ @cookbook_repo.stub(:shell_out!).with('git status --porcelain', :cwd => @repo_path).and_return(@clean_status)
end
it "passes the sanity check" do
@@ -143,7 +143,7 @@ DIRTY
before do
@updates = Mixlib::ShellOut.new
@updates.stdout.replace("\n")
- @cookbook_repo.stub!(:shell_out!).with('git status --porcelain -- apache2', :cwd => @repo_path).and_return(@updates)
+ @cookbook_repo.stub(:shell_out!).with('git status --porcelain -- apache2', :cwd => @repo_path).and_return(@updates)
end
it "shows no changes in the pristine copy" do
@@ -159,7 +159,7 @@ DIRTY
before do
@updates = Mixlib::ShellOut.new
@updates.stdout.replace(" M cookbooks/apache2/recipes/default.rb\n")
- @cookbook_repo.stub!(:shell_out!).with('git status --porcelain -- apache2', :cwd => @repo_path).and_return(@updates)
+ @cookbook_repo.stub(:shell_out!).with('git status --porcelain -- apache2', :cwd => @repo_path).and_return(@updates)
end
it "shows changes in the pristine copy" do
diff --git a/spec/unit/knife/core/object_loader_spec.rb b/spec/unit/knife/core/object_loader_spec.rb
index b3456e2b15..53a538da91 100644
--- a/spec/unit/knife/core/object_loader_spec.rb
+++ b/spec/unit/knife/core/object_loader_spec.rb
@@ -24,7 +24,7 @@ describe Chef::Knife::Core::ObjectLoader do
before(:each) do
@knife = Chef::Knife.new
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
Dir.chdir(File.join(CHEF_SPEC_DATA, 'object_loader'))
end
diff --git a/spec/unit/knife/core/subcommand_loader_spec.rb b/spec/unit/knife/core/subcommand_loader_spec.rb
index 3af1a8cf06..033649bbc2 100644
--- a/spec/unit/knife/core/subcommand_loader_spec.rb
+++ b/spec/unit/knife/core/subcommand_loader_spec.rb
@@ -20,6 +20,7 @@ require 'spec_helper'
describe Chef::Knife::SubcommandLoader do
before do
+
@home = File.join(CHEF_SPEC_DATA, 'knife-home')
@env = {'HOME' => @home}
@loader = Chef::Knife::SubcommandLoader.new(File.join(CHEF_SPEC_DATA, 'knife-site-subcommands'), @env)
@@ -45,10 +46,10 @@ describe Chef::Knife::SubcommandLoader do
]
$LOAD_PATH.should_receive(:map).and_return([])
if Gem::Specification.respond_to? :latest_specs
- Gem::Specification.should_receive(:latest_specs).and_return(gems)
- gems[0].should_receive(:matches_for_glob).with(/chef\/knife\/\*\.rb{(.*),\.rb,(.*)}/).and_return(gem_files)
+ Gem::Specification.should_receive(:latest_specs).with(true).and_return(gems)
+ gems[0].should_receive(:matches_for_glob).with(/chef\/knife\/\*\.rb\{(.*),\.rb,(.*)\}/).and_return(gem_files)
else
- Gem.source_index.should_receive(:latest_specs).and_return(gems)
+ Gem.source_index.should_receive(:latest_specs).with(true).and_return(gems)
gems[0].should_receive(:require_paths).twice.and_return(['lib'])
gems[0].should_receive(:full_gem_path).and_return('/usr/lib/ruby/gems/knife-ec2-0.5.12')
Dir.should_receive(:[]).with('/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/*.rb').and_return(gem_files)
@@ -71,4 +72,79 @@ describe Chef::Knife::SubcommandLoader do
expected_command = File.join(CHEF_SPEC_DATA, 'knife-site-subcommands', 'plugins', 'knife', 'example_subcommand.rb')
@loader.site_subcommands.should include(expected_command)
end
+
+ describe "finding 3rd party plugins" do
+ let(:env_home) { "/home/alice" }
+ let(:manifest_path) { env_home + "/.chef/plugin_manifest.json" }
+
+ before do
+ env_dup = ENV.to_hash
+ ENV.stub(:[]).and_return { |key| env_dup[key] }
+ ENV.stub(:[]).with("HOME").and_return(env_home)
+ end
+
+ context "when there is not a ~/.chef/plugin_manifest.json file" do
+ before do
+ File.stub(:exist?).with(manifest_path).and_return(false)
+ end
+
+ it "searches rubygems for plugins" do
+ if Gem::Specification.respond_to?(:latest_specs)
+ Gem::Specification.should_receive(:latest_specs).and_call_original
+ else
+ Gem.source_index.should_receive(:latest_specs).and_call_original
+ end
+ @loader.subcommand_files.each do |require_path|
+ require_path.should match(/chef\/knife\/.*|plugins\/knife\/.*/)
+ end
+ end
+
+ context "and HOME environment variable is not set" do
+ before do
+ ENV.stub(:[]).with("HOME").and_return(nil)
+ end
+
+ it "searches rubygems for plugins" do
+ if Gem::Specification.respond_to?(:latest_specs)
+ Gem::Specification.should_receive(:latest_specs).and_call_original
+ else
+ Gem.source_index.should_receive(:latest_specs).and_call_original
+ end
+ @loader.subcommand_files.each do |require_path|
+ require_path.should match(/chef\/knife\/.*|plugins\/knife\/.*/)
+ end
+ end
+ end
+
+ end
+
+ context "when there is a ~/.chef/plugin_manifest.json file" do
+ let(:ec2_server_create_plugin) { "/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_server_create.rb" }
+
+ let(:manifest_content) do
+ { "plugins" => {
+ "knife-ec2" => {
+ "paths" => [
+ ec2_server_create_plugin
+ ]
+ }
+ }
+ }
+ end
+
+ let(:manifest_json) { Chef::JSONCompat.to_json(manifest_content) }
+
+ before do
+ File.stub(:exist?).with(manifest_path).and_return(true)
+ File.stub(:read).with(manifest_path).and_return(manifest_json)
+ end
+
+ it "uses paths from the manifest instead of searching gems" do
+ Gem::Specification.should_not_receive(:latest_specs).and_call_original
+ @loader.subcommand_files.should include(ec2_server_create_plugin)
+ end
+
+ end
+ end
+
end
diff --git a/spec/unit/knife/core/ui_spec.rb b/spec/unit/knife/core/ui_spec.rb
index 0b6978596a..c626747918 100644
--- a/spec/unit/knife/core/ui_spec.rb
+++ b/spec/unit/knife/core/ui_spec.rb
@@ -24,10 +24,132 @@ require 'spec_helper'
describe Chef::Knife::UI do
before do
@out, @err, @in = StringIO.new, StringIO.new, StringIO.new
- @config = {}
+ @config = {
+ :verbosity => 0,
+ :yes => nil,
+ :format => "summary",
+ }
@ui = Chef::Knife::UI.new(@out, @err, @in, @config)
end
+ describe "edit" do
+ ruby_for_json = { 'foo' => 'bar' }
+ json_from_ruby = "{\n \"foo\": \"bar\"\n}"
+ json_from_editor = "{\n \"bar\": \"foo\"\n}"
+ ruby_from_editor = { 'bar' => 'foo' }
+ my_editor = "veeeye"
+ temp_path = "/tmp/bar/baz"
+
+ let(:subject) { @ui.edit_data(ruby_for_json, parse_output) }
+ let(:parse_output) { false }
+
+ context "when editing is disabled" do
+ before do
+ @ui.config[:disable_editing] = true
+ stub_const("Tempfile", double) # Tempfiles should never be invoked
+ end
+ context "when parse_output is false" do
+ it "returns pretty json string" do
+ expect(subject).to eql(json_from_ruby)
+ end
+ end
+ context "when parse_output is true" do
+ let(:parse_output) { true }
+ it "returns a ruby object" do
+ expect(subject).to eql(ruby_for_json)
+ end
+ end
+
+ end
+
+ context "when editing is enabled" do
+ before do
+ @ui.config[:disable_editing] = false
+ @ui.config[:editor] = my_editor
+ @mock = double('Tempfile')
+ @mock.should_receive(:sync=).with(true)
+ @mock.should_receive(:puts).with(json_from_ruby)
+ @mock.should_receive(:close)
+ @mock.should_receive(:path).at_least(:once).and_return(temp_path)
+ Tempfile.should_receive(:open).with([ 'knife-edit-', '.json' ]).and_yield(@mock)
+ end
+ context "and the editor works" do
+ before do
+ @ui.should_receive(:system).with("#{my_editor} #{temp_path}").and_return(true)
+ IO.should_receive(:read).with(temp_path).and_return(json_from_editor)
+ end
+
+ context "when parse_output is false" do
+ it "returns an edited pretty json string" do
+ expect(subject).to eql(json_from_editor)
+ end
+ end
+ context "when parse_output is true" do
+ let(:parse_output) { true }
+ it "returns an edited ruby object" do
+ expect(subject).to eql(ruby_from_editor)
+ end
+ end
+ end
+ context "when running the editor fails with nil" do
+ before do
+ @ui.should_receive(:system).with("#{my_editor} #{temp_path}").and_return(nil)
+ IO.should_not_receive(:read)
+ end
+ it "throws an exception" do
+ expect{ subject }.to raise_error(RuntimeError)
+ end
+ end
+ context "when running the editor fails with false" do
+ before do
+ @ui.should_receive(:system).with("#{my_editor} #{temp_path}").and_return(false)
+ IO.should_not_receive(:read)
+ end
+ it "throws an exception" do
+ expect{ subject }.to raise_error(RuntimeError)
+ end
+ end
+ end
+ context "when editing and not stubbing Tempfile (semi-functional test)" do
+ before do
+ @ui.config[:disable_editing] = false
+ @ui.config[:editor] = my_editor
+ @tempfile = Tempfile.new([ 'knife-edit-', '.json' ])
+ Tempfile.should_receive(:open).with([ 'knife-edit-', '.json' ]).and_yield(@tempfile)
+ end
+
+ context "and the editor works" do
+ before do
+ @ui.should_receive(:system).with("#{my_editor} #{@tempfile.path}").and_return(true)
+ IO.should_receive(:read).with(@tempfile.path).and_return(json_from_editor)
+ end
+
+ context "when parse_output is false" do
+ it "returns an edited pretty json string" do
+ expect(subject).to eql(json_from_editor)
+ end
+ it "the tempfile should have mode 0600", :unix_only do
+ # XXX: this looks odd because we're really testing Tempfile.new here
+ expect(File.stat(@tempfile.path).mode & 0777).to eql(0600)
+ expect(subject).to eql(json_from_editor)
+ end
+ end
+
+ context "when parse_output is true" do
+ let(:parse_output) { true }
+ it "returns an edited ruby object" do
+ expect(subject).to eql(ruby_from_editor)
+ end
+ it "the tempfile should have mode 0600", :unix_only do
+ # XXX: this looks odd because we're really testing Tempfile.new here
+ expect(File.stat(@tempfile.path).mode & 0777).to eql(0600)
+ expect(subject).to eql(ruby_from_editor)
+ end
+ end
+ end
+ end
+ end
+
describe "format_list_for_display" do
it "should print the full hash if --with-uri is true" do
@ui.config[:with_uri] = true
@@ -50,7 +172,7 @@ describe Chef::Knife::UI do
it "should ignore Errno::EPIPE exceptions (CHEF-3516)" do
@out.stub(:puts).and_raise(Errno::EPIPE)
@err.stub(:puts).and_raise(Errno::EPIPE)
- lambda {@ui.send(method, "hi")}.should_not raise_error(Errno::EPIPE)
+ lambda {@ui.send(method, "hi")}.should raise_error(SystemExit)
end
it "should throw Errno::EPIPE exceptions with -VV (CHEF-3516)" do
@@ -180,15 +302,9 @@ EOM
it "formats hashes with nested array values appropriately" do
@ui.output({ 'a' => [ [ 'foo', 'bar' ], [ 'baz', 'bjork' ] ], 'b' => 'c' })
- @out.string.should == <<EOM
-a:
- foo
- bar
-
- baz
- bjork
-b: c
-EOM
+ # XXX: using a HEREDOC at this point results in a line with required spaces which auto-whitespace removal settings
+ # on editors will remove and will break this test.
+ @out.string.should == "a:\n foo\n bar\n \n baz\n bjork\nb: c\n"
end
it "formats hashes with hash values appropriately" do
@@ -294,28 +410,28 @@ EOM
@question = "monkeys rule"
@stdout = StringIO.new
@ui.stub(:stdout).and_return(@stdout)
- @ui.stdin.stub!(:readline).and_return("y")
+ @ui.stdin.stub(:readline).and_return("y")
end
it "should return true if you answer Y" do
- @ui.stdin.stub!(:readline).and_return("Y")
+ @ui.stdin.stub(:readline).and_return("Y")
@ui.confirm(@question).should == true
end
it "should return true if you answer y" do
- @ui.stdin.stub!(:readline).and_return("y")
+ @ui.stdin.stub(:readline).and_return("y")
@ui.confirm(@question).should == true
end
it "should exit 3 if you answer N" do
- @ui.stdin.stub!(:readline).and_return("N")
+ @ui.stdin.stub(:readline).and_return("N")
lambda {
@ui.confirm(@question)
}.should raise_error(SystemExit) { |e| e.status.should == 3 }
end
it "should exit 3 if you answer n" do
- @ui.stdin.stub!(:readline).and_return("n")
+ @ui.stdin.stub(:readline).and_return("n")
lambda {
@ui.confirm(@question)
}.should raise_error(SystemExit) { |e| e.status.should == 3 }
@@ -331,16 +447,16 @@ EOM
describe "when asking for free-form user input" do
it "asks a question and returns the answer provided by the user" do
out = StringIO.new
- @ui.stub!(:stdout).and_return(out)
- @ui.stub!(:stdin).and_return(StringIO.new("http://mychefserver.example.com\n"))
+ @ui.stub(:stdout).and_return(out)
+ @ui.stub(:stdin).and_return(StringIO.new("http://mychefserver.example.com\n"))
@ui.ask_question("your chef server URL?").should == "http://mychefserver.example.com"
out.string.should == "your chef server URL?"
end
it "suggests a default setting and returns the default when the user's response only contains whitespace" do
out = StringIO.new
- @ui.stub!(:stdout).and_return(out)
- @ui.stub!(:stdin).and_return(StringIO.new(" \n"))
+ @ui.stub(:stdout).and_return(out)
+ @ui.stub(:stdin).and_return(StringIO.new(" \n"))
@ui.ask_question("your chef server URL? ", :default => 'http://localhost:4000').should == "http://localhost:4000"
out.string.should == "your chef server URL? [http://localhost:4000] "
end
diff --git a/spec/unit/knife/data_bag_create_spec.rb b/spec/unit/knife/data_bag_create_spec.rb
index 0ac9b6f033..984be8e58a 100644
--- a/spec/unit/knife/data_bag_create_spec.rb
+++ b/spec/unit/knife/data_bag_create_spec.rb
@@ -39,9 +39,9 @@ describe Chef::Knife::DataBagCreate do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::DataBagCreate.new
@rest = ChefSpecs::ChefRest.new
- @knife.stub!(:rest).and_return(@rest)
+ @knife.stub(:rest).and_return(@rest)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
@@ -53,6 +53,13 @@ describe Chef::Knife::DataBagCreate do
@knife.run
end
+ it "tries to create a data bag with an invalid name when given one argument" do
+ @knife.name_args = ['invalid&char']
+ @knife.should_receive(:exit).with(1)
+
+ @knife.run
+ end
+
it "creates a data bag item when given two arguments" do
@knife.name_args = ['sudoing_admins', 'ME']
user_supplied_hash = {"login_name" => "alphaomega", "id" => "ME"}
@@ -94,7 +101,7 @@ describe Chef::Knife::DataBagCreate do
end
it "creates an encrypted data bag item via --secret" do
- @knife.stub!(:config).and_return({:secret => @secret})
+ @knife.stub(:config).and_return({:secret => @secret})
@knife.run
end
@@ -102,7 +109,7 @@ describe Chef::Knife::DataBagCreate do
secret_file = Tempfile.new("encrypted_data_bag_secret_file_test")
secret_file.puts(@secret)
secret_file.flush
- @knife.stub!(:config).and_return({:secret_file => secret_file.path})
+ @knife.stub(:config).and_return({:secret_file => secret_file.path})
@knife.run
end
end
diff --git a/spec/unit/knife/data_bag_edit_spec.rb b/spec/unit/knife/data_bag_edit_spec.rb
index 412a237321..866ca99174 100644
--- a/spec/unit/knife/data_bag_edit_spec.rb
+++ b/spec/unit/knife/data_bag_edit_spec.rb
@@ -29,11 +29,11 @@ describe Chef::Knife::DataBagEdit do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::DataBagEdit.new
- @rest = mock('chef-rest-mock')
- @knife.stub!(:rest).and_return(@rest)
+ @rest = double('chef-rest-mock')
+ @knife.stub(:rest).and_return(@rest)
@stdout = StringIO.new
- @knife.stub!(:stdout).and_return(@stdout)
+ @knife.stub(:stdout).and_return(@stdout)
@log = Chef::Log
@knife.name_args = ['bag_name', 'item_name']
end
@@ -45,7 +45,7 @@ describe Chef::Knife::DataBagEdit do
end
it "saves edits on a data bag item" do
- Chef::DataBagItem.stub!(:load).with('bag_name', 'item_name').and_return(@plain_data)
+ Chef::DataBagItem.stub(:load).with('bag_name', 'item_name').and_return(@plain_data)
@knife.should_receive(:edit_data).with(@plain_data).and_return(@edited_data)
@rest.should_receive(:put_rest).with("data/bag_name/item_name", @edited_data).ordered
@knife.run
@@ -58,7 +58,7 @@ describe Chef::Knife::DataBagEdit do
@secret)
@enc_edited_data = Chef::EncryptedDataBagItem.encrypt_data_bag_item(@edited_data,
@secret)
- Chef::DataBagItem.stub!(:load).with('bag_name', 'item_name').and_return(@enc_data)
+ Chef::DataBagItem.stub(:load).with('bag_name', 'item_name').and_return(@enc_data)
# Random IV is used each time the data bag item is encrypted, so values
# will not be equal if we encrypt same value twice.
@@ -75,7 +75,7 @@ describe Chef::Knife::DataBagEdit do
end
it "decrypts and encrypts via --secret" do
- @knife.stub!(:config).and_return({:secret => @secret})
+ @knife.stub(:config).and_return({:secret => @secret})
@knife.should_receive(:edit_data).with(@plain_data).and_return(@edited_data)
@rest.should_receive(:put_rest).with("data/bag_name/item_name", @enc_edited_data).ordered
@@ -83,7 +83,7 @@ describe Chef::Knife::DataBagEdit do
end
it "decrypts and encrypts via --secret_file" do
- @knife.stub!(:config).and_return({:secret_file => @secret_file.path})
+ @knife.stub(:config).and_return({:secret_file => @secret_file.path})
@knife.should_receive(:edit_data).with(@plain_data).and_return(@edited_data)
@rest.should_receive(:put_rest).with("data/bag_name/item_name", @enc_edited_data).ordered
diff --git a/spec/unit/knife/data_bag_from_file_spec.rb b/spec/unit/knife/data_bag_from_file_spec.rb
index cef1babd0b..8537045164 100644
--- a/spec/unit/knife/data_bag_from_file_spec.rb
+++ b/spec/unit/knife/data_bag_from_file_spec.rb
@@ -29,10 +29,10 @@ describe Chef::Knife::DataBagFromFile do
before :each do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::DataBagFromFile.new
- @rest = mock("Chef::REST")
- @knife.stub!(:rest).and_return(@rest)
+ @rest = double("Chef::REST")
+ @knife.stub(:rest).and_return(@rest)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
@tmp_dir = Dir.mktmpdir
@db_folder = File.join(@tmp_dir, 'data_bags', 'bag_name')
FileUtils.mkdir_p(@db_folder)
@@ -64,7 +64,7 @@ describe Chef::Knife::DataBagFromFile do
it "loads from a file and saves" do
@knife.loader.should_receive(:load_from).with("data_bags", 'bag_name', @db_file.path).and_return(@plain_data)
dbag = Chef::DataBagItem.new
- Chef::DataBagItem.stub!(:new).and_return(dbag)
+ Chef::DataBagItem.stub(:new).and_return(dbag)
dbag.should_receive(:save)
@knife.run
@@ -77,7 +77,7 @@ describe Chef::Knife::DataBagFromFile do
@knife.loader.should_receive(:load_from).with("data_bags", 'bag_name', @db_file.path).and_return(@plain_data)
@knife.loader.should_receive(:load_from).with("data_bags", 'bag_name', @db_file2.path).and_return(@plain_data)
dbag = Chef::DataBagItem.new
- Chef::DataBagItem.stub!(:new).and_return(dbag)
+ Chef::DataBagItem.stub(:new).and_return(dbag)
dbag.should_receive(:save).twice
@knife.run
@@ -91,7 +91,7 @@ describe Chef::Knife::DataBagFromFile do
@knife.loader.should_receive(:load_from).with("data_bags", 'bag_name', @db_file.path).and_return(@plain_data)
@knife.loader.should_receive(:load_from).with("data_bags", 'bag_name', @db_file2.path).and_return(@plain_data)
dbag = Chef::DataBagItem.new
- Chef::DataBagItem.stub!(:new).and_return(dbag)
+ Chef::DataBagItem.stub(:new).and_return(dbag)
dbag.should_receive(:save).twice
@knife.run
end
@@ -109,7 +109,7 @@ describe Chef::Knife::DataBagFromFile do
it "loads all data bags when -a or --all options is provided" do
@knife.name_args = []
- @knife.stub!(:config).and_return({:all => true})
+ @knife.stub(:config).and_return({:all => true})
@knife.loader.should_receive(:load_from).with("data_bags", "bag_name", File.basename(@db_file.path)).
and_return(@plain_data)
@knife.loader.should_receive(:load_from).with("data_bags", "bag_name", File.basename(@db_file2.path)).
@@ -117,18 +117,18 @@ describe Chef::Knife::DataBagFromFile do
@knife.loader.should_receive(:load_from).with("data_bags", "bag_name2", File.basename(@db_file3.path)).
and_return(@plain_data)
dbag = Chef::DataBagItem.new
- Chef::DataBagItem.stub!(:new).and_return(dbag)
+ Chef::DataBagItem.stub(:new).and_return(dbag)
dbag.should_receive(:save).exactly(3).times
@knife.run
end
it "loads all data bags items when -a or --all options is provided" do
@knife.name_args = ["bag_name2"]
- @knife.stub!(:config).and_return({:all => true})
+ @knife.stub(:config).and_return({:all => true})
@knife.loader.should_receive(:load_from).with("data_bags", "bag_name2", File.basename(@db_file3.path)).
and_return(@plain_data)
dbag = Chef::DataBagItem.new
- Chef::DataBagItem.stub!(:new).and_return(dbag)
+ Chef::DataBagItem.stub(:new).and_return(dbag)
dbag.should_receive(:save)
@knife.run
dbag.data_bag.should == 'bag_name2'
@@ -158,11 +158,11 @@ describe Chef::Knife::DataBagFromFile do
end
it "encrypts values when given --secret" do
- @knife.stub!(:config).and_return({:secret => @secret})
+ @knife.stub(:config).and_return({:secret => @secret})
@knife.loader.should_receive(:load_from).with("data_bags", "bag_name", @db_file.path).and_return(@plain_data)
dbag = Chef::DataBagItem.new
- Chef::DataBagItem.stub!(:new).and_return(dbag)
+ Chef::DataBagItem.stub(:new).and_return(dbag)
dbag.should_receive(:save)
@knife.run
dbag.data_bag.should == 'bag_name'
@@ -170,11 +170,11 @@ describe Chef::Knife::DataBagFromFile do
end
it "encrypts values when given --secret_file" do
- @knife.stub!(:config).and_return({:secret_file => @secret_file.path})
+ @knife.stub(:config).and_return({:secret_file => @secret_file.path})
- @knife.loader.stub!(:load_from).with("data_bags", 'bag_name', @db_file.path).and_return(@plain_data)
+ @knife.loader.stub(:load_from).with("data_bags", 'bag_name', @db_file.path).and_return(@plain_data)
dbag = Chef::DataBagItem.new
- Chef::DataBagItem.stub!(:new).and_return(dbag)
+ Chef::DataBagItem.stub(:new).and_return(dbag)
dbag.should_receive(:save)
@knife.run
dbag.data_bag.should == 'bag_name'
diff --git a/spec/unit/knife/data_bag_show_spec.rb b/spec/unit/knife/data_bag_show_spec.rb
index 08ecfaa0a7..d8d1077d0d 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.
@@ -29,10 +29,10 @@ describe Chef::Knife::DataBagShow do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::DataBagShow.new
@knife.config[:format] = 'json'
- @rest = mock("Chef::REST")
- @knife.stub!(:rest).and_return(@rest)
+ @rest = double("Chef::REST")
+ @knife.stub(:rest).and_return(@rest)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
@@ -83,7 +83,7 @@ describe Chef::Knife::DataBagShow do
end
it "prints the decrypted contents of an item when given --secret" do
- @knife.stub!(:config).and_return({:secret => @secret})
+ @knife.stub(:config).and_return({:secret => @secret})
Chef::EncryptedDataBagItem.should_receive(:load).
with('bag_name', 'item_name', @secret).
and_return(Chef::EncryptedDataBagItem.new(@enc_data, @secret))
@@ -92,7 +92,7 @@ describe Chef::Knife::DataBagShow do
end
it "prints the decrypted contents of an item when given --secret_file" do
- @knife.stub!(:config).and_return({:secret_file => @secret_file.path})
+ @knife.stub(:config).and_return({:secret_file => @secret_file.path})
Chef::EncryptedDataBagItem.should_receive(:load).
with('bag_name', 'item_name', @secret).
and_return(Chef::EncryptedDataBagItem.new(@enc_data, @secret))
diff --git a/spec/unit/knife/environment_compare_spec.rb b/spec/unit/knife/environment_compare_spec.rb
new file mode 100644
index 0000000000..3606b617a9
--- /dev/null
+++ b/spec/unit/knife/environment_compare_spec.rb
@@ -0,0 +1,112 @@
+#
+# Author:: Sander Botman (<sbotman@schubergphilis.com>)
+# Copyright:: Copyright (c) 2013 Sander Botman.
+# 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::Knife::EnvironmentCompare do
+ before(:each) do
+ @knife = Chef::Knife::EnvironmentCompare.new
+
+ @environments = {
+ "cita" => "http://localhost:4000/environments/cita",
+ "citm" => "http://localhost:4000/environments/citm"
+ }
+
+ @knife.stub(:environment_list).and_return(@environments)
+
+ @constraints = {
+ "cita" => { "foo" => "= 1.0.1", "bar" => "= 0.0.4" },
+ "citm" => { "foo" => "= 1.0.1", "bar" => "= 0.0.2" }
+ }
+
+ @knife.stub(:constraint_list).and_return(@constraints)
+
+ @cookbooks = { "foo"=>"= 1.0.1", "bar"=>"= 0.0.1" }
+
+ @knife.stub(:cookbook_list).and_return(@cookbooks)
+
+ @rest_double = double('rest')
+ @knife.stub(:rest).and_return(@rest_double)
+ @cookbook_names = ['apache2', 'mysql', 'foo', 'bar', 'dummy', 'chef_handler']
+ @base_url = 'https://server.example.com/cookbooks'
+ @cookbook_data = {}
+ @cookbook_names.each do |item|
+ @cookbook_data[item] = {'url' => "#{@base_url}/#{item}",
+ 'versions' => [{'version' => '1.0.1',
+ 'url' => "#{@base_url}/#{item}/1.0.1"}]}
+ end
+
+ @rest_double.stub(:get_rest).with("/cookbooks?num_versions=1").and_return(@cookbook_data)
+
+ @stdout = StringIO.new
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ end
+
+ describe 'run' do
+ it 'should display only cookbooks with version constraints' do
+ @knife.config[:format] = 'summary'
+ @knife.run
+ @environments.each do |item, url|
+ @stdout.string.should match /#{item}/ and @stdout.string.lines.count.should be 4
+ end
+ end
+
+ it 'should display 4 number of lines' do
+ @knife.config[:format] = 'summary'
+ @knife.run
+ @stdout.string.lines.count.should be 4
+ end
+ end
+
+ describe 'with -m or --mismatch' do
+ it 'should display only cookbooks that have mismatching version constraints' do
+ @knife.config[:format] = 'summary'
+ @knife.config[:mismatch] = true
+ @knife.run
+ @constraints.each do |item, ver|
+ @stdout.string.should match /#{ver[1]}/
+ end
+ end
+
+ it 'should display 3 number of lines' do
+ @knife.config[:format] = 'summary'
+ @knife.config[:mismatch] = true
+ @knife.run
+ @stdout.string.lines.count.should be 3
+ end
+ end
+
+ describe 'with -a or --all' do
+ it 'should display all cookbooks' do
+ @knife.config[:format] = 'summary'
+ @knife.config[:all] = true
+ @knife.run
+ @constraints.each do |item, ver|
+ @stdout.string.should match /#{ver[1]}/
+ end
+ end
+
+ it 'should display 8 number of lines' do
+ @knife.config[:format] = 'summary'
+ @knife.config[:all] = true
+ @knife.run
+ @stdout.string.lines.count.should be 8
+ end
+ end
+
+end
diff --git a/spec/unit/knife/environment_create_spec.rb b/spec/unit/knife/environment_create_spec.rb
index 36f6556682..81bf6731b7 100644
--- a/spec/unit/knife/environment_create_spec.rb
+++ b/spec/unit/knife/environment_create_spec.rb
@@ -21,16 +21,16 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentCreate do
before(:each) do
@knife = Chef::Knife::EnvironmentCreate.new
- @knife.stub!(:msg).and_return true
- @knife.stub!(:output).and_return true
- @knife.stub!(:show_usage).and_return true
+ @knife.stub(:msg).and_return true
+ @knife.stub(:output).and_return true
+ @knife.stub(:show_usage).and_return true
@knife.name_args = [ "production" ]
@environment = Chef::Environment.new
- @environment.stub!(:save)
+ @environment.stub(:save)
- Chef::Environment.stub!(:new).and_return @environment
- @knife.stub!(:edit_data).and_return @environment
+ Chef::Environment.stub(:new).and_return @environment
+ @knife.stub(:edit_data).and_return @environment
end
describe "run" do
diff --git a/spec/unit/knife/environment_delete_spec.rb b/spec/unit/knife/environment_delete_spec.rb
index 219ae4a923..0f6b5f3272 100644
--- a/spec/unit/knife/environment_delete_spec.rb
+++ b/spec/unit/knife/environment_delete_spec.rb
@@ -21,17 +21,17 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentDelete do
before(:each) do
@knife = Chef::Knife::EnvironmentDelete.new
- @knife.stub!(:msg).and_return true
- @knife.stub!(:output).and_return true
- @knife.stub!(:show_usage).and_return true
- @knife.stub!(:confirm).and_return true
+ @knife.stub(:msg).and_return true
+ @knife.stub(:output).and_return true
+ @knife.stub(:show_usage).and_return true
+ @knife.stub(:confirm).and_return true
@knife.name_args = [ "production" ]
@environment = Chef::Environment.new
@environment.name("production")
@environment.description("Please delete me")
- @environment.stub!(:destroy).and_return true
- Chef::Environment.stub!(:load).and_return @environment
+ @environment.stub(:destroy).and_return true
+ Chef::Environment.stub(:load).and_return @environment
end
it "should confirm that you want to delete" do
diff --git a/spec/unit/knife/environment_edit_spec.rb b/spec/unit/knife/environment_edit_spec.rb
index 91f9f5d0f0..a82ead0b6b 100644
--- a/spec/unit/knife/environment_edit_spec.rb
+++ b/spec/unit/knife/environment_edit_spec.rb
@@ -21,16 +21,16 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentEdit do
before(:each) do
@knife = Chef::Knife::EnvironmentEdit.new
- @knife.ui.stub!(:msg).and_return true
- @knife.ui.stub!(:output).and_return true
- @knife.ui.stub!(:show_usage).and_return true
+ @knife.ui.stub(:msg).and_return true
+ @knife.ui.stub(:output).and_return true
+ @knife.ui.stub(:show_usage).and_return true
@knife.name_args = [ "production" ]
@environment = Chef::Environment.new
@environment.name("production")
@environment.description("Please edit me")
- @environment.stub!(:save).and_return true
- Chef::Environment.stub!(:load).and_return @environment
+ @environment.stub(:save).and_return true
+ Chef::Environment.stub(:load).and_return @environment
@knife.ui.stub(:edit_data).and_return @environment
end
diff --git a/spec/unit/knife/environment_from_file_spec.rb b/spec/unit/knife/environment_from_file_spec.rb
index d2234d9be1..f208320c5d 100644
--- a/spec/unit/knife/environment_from_file_spec.rb
+++ b/spec/unit/knife/environment_from_file_spec.rb
@@ -25,15 +25,15 @@ describe Chef::Knife::EnvironmentFromFile do
before(:each) do
@knife = Chef::Knife::EnvironmentFromFile.new
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
@knife.name_args = [ "spec.rb" ]
@environment = Chef::Environment.new
@environment.name("spec")
@environment.description("runs the unit tests")
@environment.cookbook_versions({"apt" => "= 1.2.3"})
- @environment.stub!(:save).and_return true
- @knife.loader.stub!(:load_from).and_return @environment
+ @environment.stub(:save).and_return true
+ @knife.loader.stub(:load_from).and_return @environment
end
describe "run" do
@@ -47,20 +47,20 @@ describe Chef::Knife::EnvironmentFromFile do
before(:each) do
@env_apple = @environment.dup
@env_apple.name("apple")
- @knife.loader.stub!(:load_from).with("apple.rb").and_return @env_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"])
+ File.stub(:expand_path).with("./environments/*.{json,rb}").and_return("/tmp/environments")
+ Dir.stub(:glob).with("/tmp/environments").and_return(["spec.rb", "apple.rb"])
@knife.name_args = []
- @knife.stub!(:config).and_return({:all => true})
+ @knife.stub(:config).and_return({:all => true})
@environment.should_receive(:save).twice
@knife.run
end
diff --git a/spec/unit/knife/environment_list_spec.rb b/spec/unit/knife/environment_list_spec.rb
index 05a3ae748a..25d2714d23 100644
--- a/spec/unit/knife/environment_list_spec.rb
+++ b/spec/unit/knife/environment_list_spec.rb
@@ -21,16 +21,16 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentList do
before(:each) do
@knife = Chef::Knife::EnvironmentList.new
- @knife.stub!(:msg).and_return true
- @knife.stub!(:output).and_return true
- @knife.stub!(:show_usage).and_return true
+ @knife.stub(:msg).and_return true
+ @knife.stub(:output).and_return true
+ @knife.stub(:show_usage).and_return true
@environments = {
"production" => "http://localhost:4000/environments/production",
"development" => "http://localhost:4000/environments/development",
"testing" => "http://localhost:4000/environments/testing"
}
- Chef::Environment.stub!(:list).and_return @environments
+ Chef::Environment.stub(:list).and_return @environments
end
it "should make an api call to list the environments" do
diff --git a/spec/unit/knife/environment_show_spec.rb b/spec/unit/knife/environment_show_spec.rb
index 1e1556f4c3..c7b0c21657 100644
--- a/spec/unit/knife/environment_show_spec.rb
+++ b/spec/unit/knife/environment_show_spec.rb
@@ -21,15 +21,15 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentShow do
before(:each) do
@knife = Chef::Knife::EnvironmentShow.new
- @knife.stub!(:msg).and_return true
- @knife.stub!(:output).and_return true
- @knife.stub!(:show_usage).and_return true
+ @knife.stub(:msg).and_return true
+ @knife.stub(:output).and_return true
+ @knife.stub(:show_usage).and_return true
@knife.name_args = [ "production" ]
@environment = Chef::Environment.new
@environment.name("production")
@environment.description("Look at me!")
- Chef::Environment.stub!(:load).and_return @environment
+ Chef::Environment.stub(:load).and_return @environment
end
it "should load the environment" do
diff --git a/spec/unit/knife/index_rebuild_spec.rb b/spec/unit/knife/index_rebuild_spec.rb
index 414ec95fad..3a8ec00651 100644
--- a/spec/unit/knife/index_rebuild_spec.rb
+++ b/spec/unit/knife/index_rebuild_spec.rb
@@ -21,7 +21,7 @@ require 'spec_helper'
describe Chef::Knife::IndexRebuild do
let(:knife){Chef::Knife::IndexRebuild.new}
- let(:rest_client){mock(Chef::REST)}
+ let(:rest_client){double(Chef::REST)}
let(:stub_rest!) do
knife.should_receive(:rest).and_return(rest_client)
@@ -29,7 +29,7 @@ describe Chef::Knife::IndexRebuild do
before :each do
# This keeps the test output clean
- knife.ui.stub!(:stdout).and_return(StringIO.new)
+ knife.ui.stub(:stdout).and_return(StringIO.new)
end
context "#grab_api_info" do
@@ -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/knife_help.rb b/spec/unit/knife/knife_help.rb
index f5753e3d62..e66a44801b 100644
--- a/spec/unit/knife/knife_help.rb
+++ b/spec/unit/knife/knife_help.rb
@@ -37,10 +37,10 @@ describe Chef::Knife::Help do
it "should suggest topics" do
@knife.name_args = [ "list" ]
- @knife.ui.stub!(:msg)
+ @knife.ui.stub(:msg)
@knife.ui.should_receive(:info).with("Available help topics are: ")
@knife.ui.should_receive(:msg).with(/knife/)
- @knife.stub!(:exec)
+ @knife.stub(:exec)
@knife.should_receive(:exit).with(1)
@knife.run
end
@@ -57,9 +57,9 @@ describe Chef::Knife::Help do
describe "find_manpages_for_query" do
it "should error if it does not find a match" do
- @knife.ui.stub!(:error)
- @knife.ui.stub!(:info)
- @knife.ui.stub!(:msg)
+ @knife.ui.stub(:error)
+ @knife.ui.stub(:info)
+ @knife.ui.stub(:msg)
@knife.should_receive(:exit).with(1)
@knife.ui.should_receive(:error).with("No help found for 'chickens'")
@knife.ui.should_receive(:msg).with(/knife/)
@@ -69,22 +69,22 @@ describe Chef::Knife::Help do
describe "print_help_topics" do
it "should print the known help topics" do
- @knife.ui.stub!(:msg)
- @knife.ui.stub!(:info)
+ @knife.ui.stub(:msg)
+ @knife.ui.stub(:info)
@knife.ui.should_receive(:msg).with(/knife/)
@knife.print_help_topics
end
it "should shorten topics prefixed by knife-" do
- @knife.ui.stub!(:msg)
- @knife.ui.stub!(:info)
+ @knife.ui.stub(:msg)
+ @knife.ui.stub(:info)
@knife.ui.should_receive(:msg).with(/node/)
@knife.print_help_topics
end
it "should not leave topics prefixed by knife-" do
- @knife.ui.stub!(:msg)
- @knife.ui.stub!(:info)
+ @knife.ui.stub(:msg)
+ @knife.ui.stub(:info)
@knife.ui.should_not_receive(:msg).with(/knife-node/)
@knife.print_help_topics
end
diff --git a/spec/unit/knife/node_bulk_delete_spec.rb b/spec/unit/knife/node_bulk_delete_spec.rb
index 51f707dfcf..3faece5469 100644
--- a/spec/unit/knife/node_bulk_delete_spec.rb
+++ b/spec/unit/knife/node_bulk_delete_spec.rb
@@ -26,8 +26,8 @@ describe Chef::Knife::NodeBulkDelete do
@knife = Chef::Knife::NodeBulkDelete.new
@knife.name_args = ["."]
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
- @knife.ui.stub!(:confirm).and_return(true)
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ @knife.ui.stub(:confirm).and_return(true)
@nodes = Hash.new
%w{adam brent jacob}.each do |node_name|
@nodes[node_name] = "http://localhost:4000/nodes/#{node_name}"
@@ -53,11 +53,11 @@ describe Chef::Knife::NodeBulkDelete do
@inflatedish_list = @nodes.keys.inject({}) do |nodes_by_name, name|
node = Chef::Node.new()
node.name(name)
- node.stub!(:destroy).and_return(true)
+ node.stub(:destroy).and_return(true)
nodes_by_name[name] = node
nodes_by_name
end
- @knife.stub!(:all_nodes).and_return(@inflatedish_list)
+ @knife.stub(:all_nodes).and_return(@inflatedish_list)
end
it "should print the nodes you are about to delete" do
diff --git a/spec/unit/knife/node_delete_spec.rb b/spec/unit/knife/node_delete_spec.rb
index b1b3db1aa4..04eca389c6 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.
@@ -26,13 +26,13 @@ describe Chef::Knife::NodeDelete do
:print_after => nil
}
@knife.name_args = [ "adam" ]
- @knife.stub!(:output).and_return(true)
- @knife.stub!(:confirm).and_return(true)
- @node = Chef::Node.new()
- @node.stub!(:destroy).and_return(true)
- Chef::Node.stub!(:load).and_return(@node)
+ @knife.stub(:output).and_return(true)
+ @knife.stub(:confirm).and_return(true)
+ @node = Chef::Node.new()
+ @node.stub(:destroy).and_return(true)
+ Chef::Node.stub(:load).and_return(@node)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
diff --git a/spec/unit/knife/node_edit_spec.rb b/spec/unit/knife/node_edit_spec.rb
index 0ba2e90cfe..27db3416f4 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.
@@ -20,6 +20,12 @@ require 'spec_helper'
Chef::Knife::NodeEdit.load_deps
describe Chef::Knife::NodeEdit do
+
+ # helper to convert the view from Chef objects into Ruby objects representing JSON
+ def deserialized_json_view
+ actual = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json_pretty(@knife.node_editor.send(:view)))
+ end
+
before(:each) do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::NodeEdit.new
@@ -39,7 +45,7 @@ describe Chef::Knife::NodeEdit do
describe "after loading the node" do
before do
- @knife.stub!(:node).and_return(@node)
+ @knife.stub(:node).and_return(@node)
@node.automatic_attrs = {:go => :away}
@node.default_attrs = {:hide => :me}
@node.override_attrs = {:dont => :show}
@@ -49,7 +55,7 @@ describe Chef::Knife::NodeEdit do
end
it "creates a view of the node without attributes from roles or ohai" do
- actual = Chef::JSONCompat.from_json(@knife.node_editor.view)
+ actual = deserialized_json_view
actual.should_not have_key("automatic")
actual.should_not have_key("override")
actual.should_not have_key("default")
@@ -61,7 +67,7 @@ describe Chef::Knife::NodeEdit do
it "shows the extra attributes when given the --all option" do
@knife.config[:all_attributes] = true
- actual = Chef::JSONCompat.from_json(@knife.node_editor.view)
+ actual = deserialized_json_view
actual["automatic"].should == {"go" => "away"}
actual["override"].should == {"dont" => "show"}
actual["default"].should == {"hide" => "me"}
@@ -71,18 +77,39 @@ describe Chef::Knife::NodeEdit do
end
it "does not consider unedited data updated" do
- view = Chef::JSONCompat.from_json( @knife.node_editor.view )
- @knife.node_editor.apply_updates(view)
+ view = deserialized_json_view
+ @knife.node_editor.send(:apply_updates, view)
@knife.node_editor.should_not be_updated
end
it "considers edited data updated" do
- view = Chef::JSONCompat.from_json( @knife.node_editor.view )
+ view = deserialized_json_view
view["run_list"] << "role[fuuu]"
- @knife.node_editor.apply_updates(view)
+ @knife.node_editor.send(:apply_updates, view)
@knife.node_editor.should be_updated
end
end
+
+ describe "edit_node" do
+
+ before do
+ @knife.stub(:node).and_return(@node)
+ end
+
+ let(:subject) { @knife.node_editor.edit_node }
+
+ it "raises an exception when editing is disabled" do
+ @knife.config[:disable_editing] = true
+ expect{ subject }.to raise_error(SystemExit)
+ end
+
+ it "raises an exception when the editor is not set" do
+ @knife.config[:editor] = nil
+ expect{ subject }.to raise_error(SystemExit)
+ end
+
+ end
+
end
diff --git a/spec/unit/knife/node_from_file_spec.rb b/spec/unit/knife/node_from_file_spec.rb
index c6b9610d9e..56a2a08b68 100644
--- a/spec/unit/knife/node_from_file_spec.rb
+++ b/spec/unit/knife/node_from_file_spec.rb
@@ -28,13 +28,13 @@ describe Chef::Knife::NodeFromFile do
:print_after => nil
}
@knife.name_args = [ "adam.rb" ]
- @knife.stub!(:output).and_return(true)
- @knife.stub!(:confirm).and_return(true)
+ @knife.stub(:output).and_return(true)
+ @knife.stub(:confirm).and_return(true)
@node = Chef::Node.new()
- @node.stub!(:save)
- @knife.loader.stub!(:load_from).and_return(@node)
+ @node.stub(:save)
+ @knife.loader.stub(:load_from).and_return(@node)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
diff --git a/spec/unit/knife/node_list_spec.rb b/spec/unit/knife/node_list_spec.rb
index 5637d679c8..cad2d6482d 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.
@@ -23,13 +23,13 @@ describe Chef::Knife::NodeList do
Chef::Config[:node_name] = "webmonkey.example.com"
Chef::Config[:environment] = nil # reset this value each time, as it is not reloaded
@knife = Chef::Knife::NodeList.new
- @knife.stub!(:output).and_return(true)
+ @knife.stub(:output).and_return(true)
@list = {
"foo" => "http://example.com/foo",
"bar" => "http://example.com/foo"
}
- Chef::Node.stub!(:list).and_return(@list)
- Chef::Node.stub!(:list_by_environment).and_return(@list)
+ Chef::Node.stub(:list).and_return(@list)
+ Chef::Node.stub(:list_by_environment).and_return(@list)
end
describe "run" do
@@ -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..61f2e6af4c 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.
@@ -26,10 +26,10 @@ describe Chef::Knife::NodeRunListAdd do
:after => nil
}
@knife.name_args = [ "adam", "role[monkey]" ]
- @knife.stub!(:output).and_return(true)
- @node = Chef::Node.new()
- @node.stub!(:save).and_return(true)
- Chef::Node.stub!(:load).and_return(@node)
+ @knife.stub(:output).and_return(true)
+ @node = Chef::Node.new()
+ @node.stub(:save).and_return(true)
+ Chef::Node.stub(:load).and_return(@node)
end
describe "run" do
diff --git a/spec/unit/knife/node_run_list_remove_spec.rb b/spec/unit/knife/node_run_list_remove_spec.rb
index 90869e8baa..5a008a3e07 100644
--- a/spec/unit/knife/node_run_list_remove_spec.rb
+++ b/spec/unit/knife/node_run_list_remove_spec.rb
@@ -27,12 +27,12 @@ describe Chef::Knife::NodeRunListRemove do
@node = Chef::Node.new()
@node.name("knifetest-node")
@node.run_list << "role[monkey]"
- @node.stub!(:save).and_return(true)
+ @node.stub(:save).and_return(true)
- @knife.ui.stub!(:output).and_return(true)
- @knife.ui.stub!(:confirm).and_return(true)
+ @knife.ui.stub(:output).and_return(true)
+ @knife.ui.stub(:confirm).and_return(true)
- Chef::Node.stub!(:load).and_return(@node)
+ Chef::Node.stub(:load).and_return(@node)
end
describe "run" do
diff --git a/spec/unit/knife/node_run_list_set_spec.rb b/spec/unit/knife/node_run_list_set_spec.rb
index bc102695ee..02281f8385 100644
--- a/spec/unit/knife/node_run_list_set_spec.rb
+++ b/spec/unit/knife/node_run_list_set_spec.rb
@@ -24,10 +24,10 @@ describe Chef::Knife::NodeRunListSet do
@knife = Chef::Knife::NodeRunListSet.new
@knife.config = {}
@knife.name_args = [ "adam", "role[monkey]" ]
- @knife.stub!(:output).and_return(true)
+ @knife.stub(:output).and_return(true)
@node = Chef::Node.new()
- @node.stub!(:save).and_return(true)
- Chef::Node.stub!(:load).and_return(@node)
+ @node.stub(:save).and_return(true)
+ Chef::Node.stub(:load).and_return(@node)
end
describe "run" do
@@ -117,8 +117,8 @@ describe Chef::Knife::NodeRunListSet do
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
- @knife.ui.stub!(:stderr).and_return(@stderr)
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stderr).and_return(@stderr)
end
it "should exit" do
diff --git a/spec/unit/knife/node_show_spec.rb b/spec/unit/knife/node_show_spec.rb
index 6600b2aa96..72a269278e 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.
@@ -28,9 +28,9 @@ describe Chef::Knife::NodeShow do
:environment => nil
}
@knife.name_args = [ "adam" ]
- @knife.stub!(:output).and_return(true)
- @node = Chef::Node.new()
- Chef::Node.stub!(:load).and_return(@node)
+ @knife.stub(:output).and_return(true)
+ @node = Chef::Node.new()
+ Chef::Node.stub(:load).and_return(@node)
end
describe "run" do
diff --git a/spec/unit/knife/role_bulk_delete_spec.rb b/spec/unit/knife/role_bulk_delete_spec.rb
index 0ee84f6455..eb1d3b4cff 100644
--- a/spec/unit/knife/role_bulk_delete_spec.rb
+++ b/spec/unit/knife/role_bulk_delete_spec.rb
@@ -27,16 +27,16 @@ describe Chef::Knife::RoleBulkDelete do
}
@knife.name_args = ["."]
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
- @knife.ui.stub!(:confirm).and_return(true)
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ @knife.ui.stub(:confirm).and_return(true)
@roles = Hash.new
%w{dev staging production}.each do |role_name|
role = Chef::Role.new()
role.name(role_name)
- role.stub!(:destroy).and_return(true)
+ role.stub(:destroy).and_return(true)
@roles[role_name] = role
end
- Chef::Role.stub!(:list).and_return(@roles)
+ Chef::Role.stub(:list).and_return(@roles)
end
describe "run" do
diff --git a/spec/unit/knife/role_create_spec.rb b/spec/unit/knife/role_create_spec.rb
index af3a6bf539..a4d7392b68 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.
@@ -26,13 +26,13 @@ describe Chef::Knife::RoleCreate do
:description => nil
}
@knife.name_args = [ "adam" ]
- @knife.stub!(:output).and_return(true)
- @role = Chef::Role.new()
- @role.stub!(:save)
- Chef::Role.stub!(:new).and_return(@role)
- @knife.stub!(:edit_data).and_return(@role)
+ @knife.stub(:output).and_return(true)
+ @role = Chef::Role.new()
+ @role.stub(:save)
+ Chef::Role.stub(:new).and_return(@role)
+ @knife.stub(:edit_data).and_return(@role)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
diff --git a/spec/unit/knife/role_delete_spec.rb b/spec/unit/knife/role_delete_spec.rb
index d2d8b889b3..0771446d49 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.
@@ -26,13 +26,13 @@ describe Chef::Knife::RoleDelete do
:print_after => nil
}
@knife.name_args = [ "adam" ]
- @knife.stub!(:output).and_return(true)
- @knife.stub!(:confirm).and_return(true)
- @role = Chef::Role.new()
- @role.stub!(:destroy).and_return(true)
- Chef::Role.stub!(:load).and_return(@role)
+ @knife.stub(:output).and_return(true)
+ @knife.stub(:confirm).and_return(true)
+ @role = Chef::Role.new()
+ @role.stub(:destroy).and_return(true)
+ Chef::Role.stub(:load).and_return(@role)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
diff --git a/spec/unit/knife/role_edit_spec.rb b/spec/unit/knife/role_edit_spec.rb
index 3a002f348c..f6d3b41d98 100644
--- a/spec/unit/knife/role_edit_spec.rb
+++ b/spec/unit/knife/role_edit_spec.rb
@@ -24,12 +24,12 @@ describe Chef::Knife::RoleEdit do
@knife = Chef::Knife::RoleEdit.new
@knife.config[:print_after] = nil
@knife.name_args = [ "adam" ]
- @knife.ui.stub!(:output).and_return(true)
+ @knife.ui.stub(:output).and_return(true)
@role = Chef::Role.new()
- @role.stub!(:save)
- Chef::Role.stub!(:load).and_return(@role)
- @knife.ui.stub!(:edit_data).and_return(@role)
- @knife.ui.stub!(:msg)
+ @role.stub(:save)
+ Chef::Role.stub(:load).and_return(@role)
+ @knife.ui.stub(:edit_data).and_return(@role)
+ @knife.ui.stub(:msg)
end
describe "run" do
diff --git a/spec/unit/knife/role_from_file_spec.rb b/spec/unit/knife/role_from_file_spec.rb
index 9b81bb14af..986414647c 100644
--- a/spec/unit/knife/role_from_file_spec.rb
+++ b/spec/unit/knife/role_from_file_spec.rb
@@ -28,13 +28,13 @@ describe Chef::Knife::RoleFromFile do
:print_after => nil
}
@knife.name_args = [ "adam.rb" ]
- @knife.stub!(:output).and_return(true)
- @knife.stub!(:confirm).and_return(true)
+ @knife.stub(:output).and_return(true)
+ @knife.stub(:confirm).and_return(true)
@role = Chef::Role.new()
- @role.stub!(:save)
- @knife.loader.stub!(:load_from).and_return(@role)
+ @role.stub(:save)
+ @knife.loader.stub(:load_from).and_return(@role)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
diff --git a/spec/unit/knife/role_list_spec.rb b/spec/unit/knife/role_list_spec.rb
index 1a5e8e2a72..ef9642c04c 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.
@@ -22,12 +22,12 @@ describe Chef::Knife::RoleList do
before(:each) do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::RoleList.new
- @knife.stub!(:output).and_return(true)
+ @knife.stub(:output).and_return(true)
@list = {
"foo" => "http://example.com/foo",
"bar" => "http://example.com/foo"
}
- Chef::Role.stub!(:list).and_return(@list)
+ Chef::Role.stub(:list).and_return(@list)
end
describe "run" do
diff --git a/spec/unit/knife/ssh_spec.rb b/spec/unit/knife/ssh_spec.rb
index 7f1ed0e321..eff7c9ba5b 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
@@ -52,8 +45,8 @@ describe Chef::Knife::Ssh do
end
def configure_query(node_array)
- @query.stub!(:search).and_return([node_array])
- Chef::Search::Query.stub!(:new).and_return(@query)
+ @query.stub(:search).and_return([node_array])
+ Chef::Search::Query.stub(:new).and_return(@query)
end
def self.should_return_specified_attributes
@@ -106,10 +99,10 @@ describe Chef::Knife::Ssh do
context "when there are some hosts found but they do not have an attribute to connect with" do
before do
- @query.stub!(:search).and_return([[@node_foo, @node_bar]])
+ @query.stub(:search).and_return([[@node_foo, @node_bar]])
@node_foo.automatic_attrs[:fqdn] = nil
@node_bar.automatic_attrs[:fqdn] = nil
- Chef::Search::Query.stub!(:new).and_return(@query)
+ Chef::Search::Query.stub(:new).and_return(@query)
end
it "should raise a specific error (CHEF-3402)" do
@@ -182,7 +175,7 @@ describe Chef::Knife::Ssh do
before :each do
@knife.instance_variable_set(:@longest, 0)
ssh_config = {:timeout => 50, :user => "locutus", :port => 23 }
- Net::SSH.stub!(:configuration_for).with('the.b.org').and_return(ssh_config)
+ Net::SSH.stub(:configuration_for).with('the.b.org').and_return(ssh_config)
end
it "uses the port from an ssh config file" do
@@ -264,7 +257,7 @@ describe Chef::Knife::Ssh do
before do
@query = Chef::Search::Query.new
@query.should_receive(:search).and_return([[@node_foo]])
- Chef::Search::Query.stub!(:new).and_return(@query)
+ Chef::Search::Query.stub(:new).and_return(@query)
@knife.stub(:ssh_command).and_return(exit_code)
@knife.name_args = ['*:*', 'false']
end
@@ -287,4 +280,111 @@ describe Chef::Knife::Ssh do
end
end
end
+
+ describe "#configure_password" do
+ before do
+ @knife.config.delete(:ssh_password_ng)
+ @knife.config.delete(:ssh_password)
+ end
+
+ context "when setting ssh_password_ng from knife ssh" do
+ # in this case ssh_password_ng exists, but ssh_password does not
+ it "should prompt for a password when ssh_passsword_ng is nil" do
+ @knife.config[:ssh_password_ng] = nil
+ @knife.should_receive(:get_password).and_return("mysekretpassw0rd")
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ end
+
+ it "should set ssh_password to false if ssh_password_ng is false" do
+ @knife.config[:ssh_password_ng] = false
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should be_false
+ end
+
+ it "should set ssh_password to ssh_password_ng if we set a password" do
+ @knife.config[:ssh_password_ng] = "mysekretpassw0rd"
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ end
+ end
+
+ context "when setting ssh_password from knife bootstrap / knife * server create" do
+ # in this case ssh_password exists, but ssh_password_ng does not
+ it "should set ssh_password to nil when ssh_password is nil" do
+ @knife.config[:ssh_password] = nil
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should be_nil
+ end
+
+ it "should set ssh_password to false when ssh_password is false" do
+ @knife.config[:ssh_password] = false
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should be_false
+ end
+
+ it "should set ssh_password to ssh_password if we set a password" do
+ @knife.config[:ssh_password] = "mysekretpassw0rd"
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ end
+ end
+ context "when setting ssh_password in the config variable" do
+ before(:each) do
+ Chef::Config[:knife][:ssh_password] = "my_knife_passw0rd"
+ end
+ context "when setting ssh_password_ng from knife ssh" do
+ # in this case ssh_password_ng exists, but ssh_password does not
+ it "should prompt for a password when ssh_passsword_ng is nil" do
+ @knife.config[:ssh_password_ng] = nil
+ @knife.should_receive(:get_password).and_return("mysekretpassw0rd")
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ end
+
+ it "should set ssh_password to the configured knife.rb value if ssh_password_ng is false" do
+ @knife.config[:ssh_password_ng] = false
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "my_knife_passw0rd"
+ end
+
+ it "should set ssh_password to ssh_password_ng if we set a password" do
+ @knife.config[:ssh_password_ng] = "mysekretpassw0rd"
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ end
+ end
+
+ context "when setting ssh_password from knife bootstrap / knife * server create" do
+ # in this case ssh_password exists, but ssh_password_ng does not
+ it "should set ssh_password to the configured knife.rb value when ssh_password is nil" do
+ @knife.config[:ssh_password] = nil
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "my_knife_passw0rd"
+ end
+
+ it "should set ssh_password to the configured knife.rb value when ssh_password is false" do
+ @knife.config[:ssh_password] = false
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "my_knife_passw0rd"
+ end
+
+ it "should set ssh_password to ssh_password if we set a password" do
+ @knife.config[:ssh_password] = "mysekretpassw0rd"
+ @knife.should_not_receive(:get_password)
+ @knife.configure_password
+ @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ end
+ end
+ end
+ end
end
diff --git a/spec/unit/knife/status_spec.rb b/spec/unit/knife/status_spec.rb
index b009997ab1..6d8d9d5b25 100644
--- a/spec/unit/knife/status_spec.rb
+++ b/spec/unit/knife/status_spec.rb
@@ -25,12 +25,12 @@ describe Chef::Knife::Status do
n.automatic_attrs["fqdn"] = "foobar"
n.automatic_attrs["ohai_time"] = 1343845969
end
- query = mock("Chef::Search::Query")
- query.stub!(:search).and_yield(node)
- Chef::Search::Query.stub!(:new).and_return(query)
+ query = double("Chef::Search::Query")
+ query.stub(:search).and_yield(node)
+ Chef::Search::Query.stub(:new).and_return(query)
@knife = Chef::Knife::Status.new
@stdout = StringIO.new
- @knife.stub!(:highline).and_return(HighLine.new(StringIO.new, @stdout))
+ @knife.stub(:highline).and_return(HighLine.new(StringIO.new, @stdout))
end
describe "run" do
diff --git a/spec/unit/knife/tag_create_spec.rb b/spec/unit/knife/tag_create_spec.rb
index 925d060879..82e3ad68cd 100644
--- a/spec/unit/knife/tag_create_spec.rb
+++ b/spec/unit/knife/tag_create_spec.rb
@@ -7,10 +7,10 @@ describe Chef::Knife::TagCreate do
@knife.name_args = [ Chef::Config[:node_name], "happytag" ]
@node = Chef::Node.new
- @node.stub! :save
- Chef::Node.stub!(:load).and_return @node
+ @node.stub :save
+ Chef::Node.stub(:load).and_return @node
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
diff --git a/spec/unit/knife/tag_delete_spec.rb b/spec/unit/knife/tag_delete_spec.rb
index ca279033a4..67e3dd3ff0 100644
--- a/spec/unit/knife/tag_delete_spec.rb
+++ b/spec/unit/knife/tag_delete_spec.rb
@@ -7,11 +7,11 @@ describe Chef::Knife::TagDelete do
@knife.name_args = [ Chef::Config[:node_name], "sadtag" ]
@node = Chef::Node.new
- @node.stub! :save
+ @node.stub :save
@node.tags << "sadtag" << "happytag"
- Chef::Node.stub!(:load).and_return @node
+ Chef::Node.stub(:load).and_return @node
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
describe "run" do
diff --git a/spec/unit/knife/tag_list_spec.rb b/spec/unit/knife/tag_list_spec.rb
index 0de5d5ebd8..3724a5c0b7 100644
--- a/spec/unit/knife/tag_list_spec.rb
+++ b/spec/unit/knife/tag_list_spec.rb
@@ -7,9 +7,9 @@ describe Chef::Knife::TagList do
@knife.name_args = [ Chef::Config[:node_name], "sadtag" ]
@node = Chef::Node.new
- @node.stub! :save
+ @node.stub :save
@node.tags << "sadtag" << "happytag"
- Chef::Node.stub!(:load).and_return @node
+ Chef::Node.stub(:load).and_return @node
end
describe "run" do
diff --git a/spec/unit/knife/user_create_spec.rb b/spec/unit/knife/user_create_spec.rb
index 0e36e148ac..cc803e99ce 100644
--- a/spec/unit/knife/user_create_spec.rb
+++ b/spec/unit/knife/user_create_spec.rb
@@ -30,14 +30,14 @@ describe Chef::Knife::UserCreate do
@user_with_private_key = Chef::User.new
@user_with_private_key.name "a_user"
@user_with_private_key.private_key 'private_key'
- @user.stub!(:create).and_return(@user_with_private_key)
- Chef::User.stub!(:new).and_return(@user)
- Chef::User.stub!(:from_hash).and_return(@user)
- @knife.stub!(:edit_data).and_return(@user.to_hash)
+ @user.stub(:create).and_return(@user_with_private_key)
+ Chef::User.stub(:new).and_return(@user)
+ Chef::User.stub(:from_hash).and_return(@user)
+ @knife.stub(:edit_data).and_return(@user.to_hash)
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
- @knife.ui.stub!(:stderr).and_return(@stderr)
+ @knife.ui.stub(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stderr).and_return(@stderr)
end
it "creates a new user" do
@@ -78,7 +78,7 @@ describe Chef::Knife::UserCreate do
it "writes the private key to a file when --file is specified" do
@knife.config[:file] = "/tmp/a_file"
- filehandle = mock("filehandle")
+ filehandle = double("filehandle")
filehandle.should_receive(:print).with('private_key')
File.should_receive(:open).with("/tmp/a_file", "w").and_yield(filehandle)
@knife.run
diff --git a/spec/unit/knife/user_reregister_spec.rb b/spec/unit/knife/user_reregister_spec.rb
index fddab57467..1cbbdb47d2 100644
--- a/spec/unit/knife/user_reregister_spec.rb
+++ b/spec/unit/knife/user_reregister_spec.rb
@@ -23,10 +23,10 @@ describe Chef::Knife::UserReregister do
Chef::Knife::UserReregister.load_deps
@knife = Chef::Knife::UserReregister.new
@knife.name_args = [ 'a_user' ]
- @user_mock = mock('user_mock', :private_key => "private_key")
- Chef::User.stub!(:load).and_return(@user_mock)
+ @user_mock = double('user_mock', :private_key => "private_key")
+ Chef::User.stub(:load).and_return(@user_mock)
@stdout = StringIO.new
- @knife.ui.stub!(:stdout).and_return(@stdout)
+ @knife.ui.stub(:stdout).and_return(@stdout)
end
it 'prints usage and exits when a user name is not provided' do
diff --git a/spec/unit/knife/user_show_spec.rb b/spec/unit/knife/user_show_spec.rb
index f2bd959d15..af8485ad7d 100644
--- a/spec/unit/knife/user_show_spec.rb
+++ b/spec/unit/knife/user_show_spec.rb
@@ -23,7 +23,7 @@ describe Chef::Knife::UserShow do
Chef::Knife::UserShow.load_deps
@knife = Chef::Knife::UserShow.new
@knife.name_args = [ 'my_user' ]
- @user_mock = mock('user_mock')
+ @user_mock = double('user_mock')
end
it 'loads and displays the user' do
diff --git a/spec/unit/knife_spec.rb b/spec/unit/knife_spec.rb
index 4c5bb3e207..8bf85bf604 100644
--- a/spec/unit/knife_spec.rb
+++ b/spec/unit/knife_spec.rb
@@ -22,6 +22,7 @@ module KnifeSpecs
end
require 'spec_helper'
+require 'uri'
describe Chef::Knife do
before(:each) do
@@ -29,14 +30,14 @@ describe Chef::Knife do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife.new
- @knife.ui.stub!(:puts)
- @knife.ui.stub!(:print)
- Chef::Log.stub!(:init)
- Chef::Log.stub!(:level)
+ @knife.ui.stub(:puts)
+ @knife.ui.stub(:print)
+ Chef::Log.stub(:init)
+ Chef::Log.stub(:level)
[:debug, :info, :warn, :error, :crit].each do |level_sym|
- Chef::Log.stub!(level_sym)
+ Chef::Log.stub(level_sym)
end
- Chef::Knife.stub!(:puts)
+ Chef::Knife.stub(:puts)
@stdout = StringIO.new
end
@@ -46,8 +47,13 @@ describe Chef::Knife do
Chef::Knife.reset_config_path!
# pwd according to your shell is /home/someuser/prod/chef-repo, but
# chef-repo is a symlink to /home/someuser/codes/chef-repo
- ENV.stub!(:[]).with("PWD").and_return("/home/someuser/prod/chef-repo")
- Dir.stub!(:pwd).and_return("/home/someuser/codes/chef-repo")
+ if Chef::Platform.windows?
+ ENV.should_receive(:[]).with("CD").and_return("/home/someuser/prod/chef-repo")
+ else
+ ENV.should_receive(:[]).with("PWD").and_return("/home/someuser/prod/chef-repo")
+ end
+
+ Dir.stub(:pwd).and_return("/home/someuser/codes/chef-repo")
end
after do
@@ -136,6 +142,60 @@ describe Chef::Knife do
end
+ describe "the headers include X-Remote-Request-Id" do
+
+ let(:headers) {{"Accept"=>"application/json",
+ "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
+ 'X-Chef-Version' => Chef::VERSION,
+ "Host"=>"api.opscode.piab:443",
+ "X-REMOTE-REQUEST-ID"=>request_id}}
+
+ let(:request_id) {"1234"}
+
+ let(:request_mock) { {} }
+
+ let(:rest) do
+ Net::HTTP.stub(:new).and_return(http_client)
+ Chef::RequestID.instance.stub(:request_id).and_return(request_id)
+ Chef::Config.stub(:chef_server_url).and_return("https://api.opscode.piab")
+ command = Chef::Knife.run(%w{test yourself})
+ rest = command.noauth_rest
+ rest
+ end
+
+ let!(:http_client) do
+ http_client = Net::HTTP.new(url.host, url.port)
+ http_client.stub(:request).and_yield(http_response).and_return(http_response)
+ http_client
+ end
+
+ let(:url) { URI.parse("https://api.opscode.piab") }
+
+ let(:http_response) do
+ http_response = Net::HTTPSuccess.new("1.1", "200", "successful rest req")
+ http_response.stub(:read_body)
+ http_response.stub(:body).and_return(body)
+ http_response["Content-Length"] = body.bytesize.to_s
+ http_response
+ end
+
+ let(:body) { "ninja" }
+
+ before(:each) do
+ Chef::Config[:chef_server_url] = "https://api.opscode.piab"
+ if KnifeSpecs.const_defined?(:TestYourself)
+ KnifeSpecs.send :remove_const, :TestYourself
+ end
+ Kernel.load(File.join(CHEF_SPEC_DATA, 'knife_subcommand', 'test_yourself.rb'))
+ Chef::Knife.subcommands.each { |name, klass| Chef::Knife.subcommands.delete(name) unless klass.kind_of?(Class) }
+ end
+
+ it "confirms that the headers include X-Remote-Request-Id" do
+ Net::HTTP::Get.should_receive(:new).with("/monkey", headers).and_return(request_mock)
+ rest.get_rest("monkey")
+ end
+ end
+
describe "when running a command" do
before(:each) do
if KnifeSpecs.const_defined?(:TestYourself)
@@ -178,7 +238,7 @@ describe Chef::Knife do
end
it "exits if no subcommand matches the CLI args" do
- Chef::Knife.ui.stub!(:stdout).and_return(@stdout)
+ Chef::Knife.ui.stub(:stdout).and_return(@stdout)
Chef::Knife.ui.should_receive(:fatal)
lambda {Chef::Knife.run(%w{fuuu uuuu fuuuu})}.should raise_error(SystemExit) { |e| e.status.should_not == 0 }
end
@@ -203,7 +263,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 +286,6 @@ describe Chef::Knife do
end
end
-
end
describe "when first created" do
@@ -261,8 +319,8 @@ describe Chef::Knife do
it "formats 401s nicely" do
response = Net::HTTPUnauthorized.new("1.1", "401", "Unauthorized")
response.instance_variable_set(:@read, true) # I hate you, net/http.
- response.stub!(:body).and_return(Chef::JSONCompat.to_json(:error => "y u no syncronize your clock?"))
- @knife.stub!(:run).and_raise(Net::HTTPServerException.new("401 Unauthorized", response))
+ response.stub(:body).and_return(Chef::JSONCompat.to_json(:error => "y u no syncronize your clock?"))
+ @knife.stub(:run).and_raise(Net::HTTPServerException.new("401 Unauthorized", response))
@knife.run_with_pretty_exceptions
@stderr.string.should match(/ERROR: Failed to authenticate to/)
@stdout.string.should match(/Response: y u no syncronize your clock\?/)
@@ -271,9 +329,9 @@ describe Chef::Knife do
it "formats 403s nicely" do
response = Net::HTTPForbidden.new("1.1", "403", "Forbidden")
response.instance_variable_set(:@read, true) # I hate you, net/http.
- response.stub!(:body).and_return(Chef::JSONCompat.to_json(:error => "y u no administrator"))
- @knife.stub!(:run).and_raise(Net::HTTPServerException.new("403 Forbidden", response))
- @knife.stub!(:username).and_return("sadpanda")
+ response.stub(:body).and_return(Chef::JSONCompat.to_json(:error => "y u no administrator"))
+ @knife.stub(:run).and_raise(Net::HTTPServerException.new("403 Forbidden", response))
+ @knife.stub(:username).and_return("sadpanda")
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: You authenticated successfully to http.+ as sadpanda but you are not authorized for this action])
@stdout.string.should match(%r[Response: y u no administrator])
@@ -282,8 +340,8 @@ describe Chef::Knife do
it "formats 400s nicely" do
response = Net::HTTPBadRequest.new("1.1", "400", "Bad Request")
response.instance_variable_set(:@read, true) # I hate you, net/http.
- response.stub!(:body).and_return(Chef::JSONCompat.to_json(:error => "y u search wrong"))
- @knife.stub!(:run).and_raise(Net::HTTPServerException.new("400 Bad Request", response))
+ response.stub(:body).and_return(Chef::JSONCompat.to_json(:error => "y u search wrong"))
+ @knife.stub(:run).and_raise(Net::HTTPServerException.new("400 Bad Request", response))
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: The data in your request was invalid])
@stdout.string.should match(%r[Response: y u search wrong])
@@ -292,8 +350,8 @@ describe Chef::Knife do
it "formats 404s nicely" do
response = Net::HTTPNotFound.new("1.1", "404", "Not Found")
response.instance_variable_set(:@read, true) # I hate you, net/http.
- response.stub!(:body).and_return(Chef::JSONCompat.to_json(:error => "nothing to see here"))
- @knife.stub!(:run).and_raise(Net::HTTPServerException.new("404 Not Found", response))
+ response.stub(:body).and_return(Chef::JSONCompat.to_json(:error => "nothing to see here"))
+ @knife.stub(:run).and_raise(Net::HTTPServerException.new("404 Not Found", response))
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: The object you are looking for could not be found])
@stdout.string.should match(%r[Response: nothing to see here])
@@ -302,8 +360,8 @@ describe Chef::Knife do
it "formats 500s nicely" do
response = Net::HTTPInternalServerError.new("1.1", "500", "Internal Server Error")
response.instance_variable_set(:@read, true) # I hate you, net/http.
- response.stub!(:body).and_return(Chef::JSONCompat.to_json(:error => "sad trombone"))
- @knife.stub!(:run).and_raise(Net::HTTPFatalError.new("500 Internal Server Error", response))
+ response.stub(:body).and_return(Chef::JSONCompat.to_json(:error => "sad trombone"))
+ @knife.stub(:run).and_raise(Net::HTTPFatalError.new("500 Internal Server Error", response))
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: internal server error])
@stdout.string.should match(%r[Response: sad trombone])
@@ -312,8 +370,8 @@ describe Chef::Knife do
it "formats 502s nicely" do
response = Net::HTTPBadGateway.new("1.1", "502", "Bad Gateway")
response.instance_variable_set(:@read, true) # I hate you, net/http.
- response.stub!(:body).and_return(Chef::JSONCompat.to_json(:error => "sadder trombone"))
- @knife.stub!(:run).and_raise(Net::HTTPFatalError.new("502 Bad Gateway", response))
+ response.stub(:body).and_return(Chef::JSONCompat.to_json(:error => "sadder trombone"))
+ @knife.stub(:run).and_raise(Net::HTTPFatalError.new("502 Bad Gateway", response))
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: bad gateway])
@stdout.string.should match(%r[Response: sadder trombone])
@@ -322,8 +380,8 @@ describe Chef::Knife do
it "formats 503s nicely" do
response = Net::HTTPServiceUnavailable.new("1.1", "503", "Service Unavailable")
response.instance_variable_set(:@read, true) # I hate you, net/http.
- response.stub!(:body).and_return(Chef::JSONCompat.to_json(:error => "saddest trombone"))
- @knife.stub!(:run).and_raise(Net::HTTPFatalError.new("503 Service Unavailable", response))
+ response.stub(:body).and_return(Chef::JSONCompat.to_json(:error => "saddest trombone"))
+ @knife.stub(:run).and_raise(Net::HTTPFatalError.new("503 Service Unavailable", response))
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: Service temporarily unavailable])
@stdout.string.should match(%r[Response: saddest trombone])
@@ -332,15 +390,15 @@ describe Chef::Knife do
it "formats other HTTP errors nicely" do
response = Net::HTTPPaymentRequired.new("1.1", "402", "Payment Required")
response.instance_variable_set(:@read, true) # I hate you, net/http.
- response.stub!(:body).and_return(Chef::JSONCompat.to_json(:error => "nobugfixtillyoubuy"))
- @knife.stub!(:run).and_raise(Net::HTTPServerException.new("402 Payment Required", response))
+ response.stub(:body).and_return(Chef::JSONCompat.to_json(:error => "nobugfixtillyoubuy"))
+ @knife.stub(:run).and_raise(Net::HTTPServerException.new("402 Payment Required", response))
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: Payment Required])
@stdout.string.should match(%r[Response: nobugfixtillyoubuy])
end
it "formats NameError and NoMethodError nicely" do
- @knife.stub!(:run).and_raise(NameError.new("Undefined constant FUUU"))
+ @knife.stub(:run).and_raise(NameError.new("Undefined constant FUUU"))
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: knife encountered an unexpected error])
@stdout.string.should match(%r[This may be a bug in the 'knife' knife command or plugin])
@@ -348,15 +406,15 @@ describe Chef::Knife do
end
it "formats missing private key errors nicely" do
- @knife.stub!(:run).and_raise(Chef::Exceptions::PrivateKeyMissing.new('key not there'))
- @knife.stub!(:api_key).and_return("/home/root/.chef/no-key-here.pem")
+ @knife.stub(:run).and_raise(Chef::Exceptions::PrivateKeyMissing.new('key not there'))
+ @knife.stub(:api_key).and_return("/home/root/.chef/no-key-here.pem")
@knife.run_with_pretty_exceptions
@stderr.string.should match(%r[ERROR: Your private key could not be loaded from /home/root/.chef/no-key-here.pem])
@stdout.string.should match(%r[Check your configuration file and ensure that your private key is readable])
end
it "formats connection refused errors nicely" do
- @knife.stub!(:run).and_raise(Errno::ECONNREFUSED.new('y u no shut up'))
+ @knife.stub(:run).and_raise(Errno::ECONNREFUSED.new('y u no shut up'))
@knife.run_with_pretty_exceptions
# Errno::ECONNREFUSED message differs by platform
# *nix = Errno::ECONNREFUSED: Connection refused
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/lwrp_spec.rb b/spec/unit/lwrp_spec.rb
index 19d3504f3c..0e0ea5dbb7 100644
--- a/spec/unit/lwrp_spec.rb
+++ b/spec/unit/lwrp_spec.rb
@@ -33,7 +33,7 @@ describe "LWRP" do
describe "when overriding an existing class" do
before :each do
- $stderr.stub!(:write)
+ $stderr.stub(:write)
end
it "should log if attempting to load resource of same name" do
@@ -179,7 +179,7 @@ describe "LWRP" do
end
it "should create a method for each attribute" do
- new_resource = mock("new resource", :null_object=>true)
+ new_resource = double("new resource").as_null_object
Chef::Provider::LwrpBuckPasser.new(nil, new_resource).methods.map{|m|m.to_sym}.should include(:action_pass_buck)
Chef::Provider::LwrpThumbTwiddler.new(nil, new_resource).methods.map{|m|m.to_sym}.should include(:action_twiddle_thumbs)
end
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..54689c9992 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
@@ -29,8 +29,8 @@ describe Chef::Mixin::Checksum do
@checksum_user = Chef::CMCCheck.new
@cache = Chef::Digester.instance
@file = CHEF_SPEC_DATA + "/checksum/random.txt"
- @stat = mock("File::Stat", { :mtime => Time.at(0) })
- File.stub!(:stat).and_return(@stat)
+ @stat = double("File::Stat", { :mtime => Time.at(0) })
+ File.stub(:stat).and_return(@stat)
end
it "gets the checksum of a file" do
diff --git a/spec/unit/mixin/command_spec.rb b/spec/unit/mixin/command_spec.rb
index e143b8728b..96660be436 100644
--- a/spec/unit/mixin/command_spec.rb
+++ b/spec/unit/mixin/command_spec.rb
@@ -18,7 +18,7 @@
require 'spec_helper'
-describe Chef::Mixin::Command do
+describe Chef::Mixin::Command, :volatile do
if windows?
@@ -76,7 +76,7 @@ describe Chef::Mixin::Command do
include Chef::Mixin::Command
it "logs the command's stderr and stdout output if the command failed" do
- Chef::Log.stub!(:level).and_return(:debug)
+ Chef::Log.stub(:level).and_return(:debug)
begin
run_command(:command => "sh -c 'echo hello; echo world >&2; false'")
violated "Exception expected, but nothing raised."
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/enforce_ownership_and_permissions_spec.rb b/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb
index cffb1b941d..fe72d53de5 100644
--- a/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb
+++ b/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb
@@ -56,8 +56,8 @@ describe Chef::Mixin::EnforceOwnershipAndPermissions do
Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash")
end
group_struct = OpenStruct.new(:name => "root", :passwd => "x", :gid => 0)
- Etc.stub!(:getpwuid).and_return(passwd_struct)
- Etc.stub!(:getgrgid).and_return(group_struct)
+ Etc.stub(:getpwuid).and_return(passwd_struct)
+ Etc.stub(:getgrgid).and_return(group_struct)
end
it "does not set updated_by_last_action on the new resource" do
@@ -80,8 +80,8 @@ describe Chef::Mixin::EnforceOwnershipAndPermissions do
Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash")
end
group_struct = OpenStruct.new(:name => "root", :passwd => "x", :gid => 0)
- Etc.stub!(:getpwuid).and_return(passwd_struct)
- Etc.stub!(:getgrgid).and_return(group_struct)
+ Etc.stub(:getpwuid).and_return(passwd_struct)
+ Etc.stub(:getgrgid).and_return(group_struct)
end
it "sets updated_by_last_action on the new resource" do
diff --git a/spec/unit/mixin/params_validate_spec.rb b/spec/unit/mixin/params_validate_spec.rb
index aa37362dc3..cc2fe198ca 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)
+ lambda { @vo.validate({:one => "two"}, {}) }.should_not raise_error
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"}, { :one => true }) }.should_not raise_error
+ lambda { @vo.validate({:one => "two"}, { "one" => true }) }.should_not raise_error
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)
+ lambda { @vo.validate({:one => "two"}, { :one => true }) }.should_not raise_error
end
-
+
it "should allow options to be optional with false" do
- lambda { @vo.validate({}, {:one => false})}.should_not raise_error(ArgumentError)
- end
-
+ lambda { @vo.validate({}, {:one => false})}.should_not raise_error
+ 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 {
+ )
+ }.should_not raise_error
+
+ 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 {
+ )
+ }.should_not raise_error
+
+ 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)
+ )
+ }.should_not raise_error
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 {
+ )
+ }.should_not raise_error
+
+ 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 {
+ )
+ }.should_not raise_error
+
+ 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" },
{
@@ -180,9 +180,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error(ArgumentError)
-
- lambda {
+ }.should_not raise_error
+
+ 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
+
+ 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,
{
@@ -250,7 +250,7 @@ describe Chef::Mixin::ParamsValidate do
:three => { :default => "neato mosquito" }
}
)
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
args[:three].should == "neato mosquito"
lambda {
@vo.validate(
@@ -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$/ }})
- }.should_not raise_error(ArgumentError)
+ @vo.validate({ "one" => "two" }, { :one => { :regex => /^two$/ }})
+ }.should_not raise_error
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 {
+ )
+ }.should_not raise_error
+ lambda {
@vo.validate(
- {:one => ["string"]},
+ {:one => ["string"]},
{
:one => {
:kind_of => [ String, Array ]
}
}
- )
- }.should_not raise_error(ArgumentError)
- lambda {
+ )
+ }.should_not raise_error
+ lambda {
@vo.validate(
- {:one => Hash.new},
+ {:one => Hash.new},
{
:one => {
:kind_of => [ String, Array ]
}
}
- )
+ )
}.should raise_error(ArgumentError)
end
@@ -360,7 +360,7 @@ describe Chef::Mixin::ParamsValidate do
it "should not raise an error when argument is nil and required is false" do
lambda {
@vo.set_or_return(:test, nil, { :required => false })
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
end
it "should set and return @name, then return @name for foo when argument is nil" do
@@ -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/path_sanity_spec.rb b/spec/unit/mixin/path_sanity_spec.rb
index e38ee7dc8a..64c667b483 100644
--- a/spec/unit/mixin/path_sanity_spec.rb
+++ b/spec/unit/mixin/path_sanity_spec.rb
@@ -33,9 +33,15 @@ describe Chef::Mixin::PathSanity do
Chef::Config[:enforce_path_sanity] = true
@ruby_bindir = '/some/ruby/bin'
@gem_bindir = '/some/gem/bin'
- Gem.stub!(:bindir).and_return(@gem_bindir)
- RbConfig::CONFIG.stub!(:[]).with('bindir').and_return(@ruby_bindir)
- Chef::Platform.stub!(:windows?).and_return(false)
+ Gem.stub(:bindir).and_return(@gem_bindir)
+ RbConfig::CONFIG.stub(:[]).with('bindir').and_return(@ruby_bindir)
+ Chef::Platform.stub(:windows?).and_return(false)
+ end
+
+ it "adds all useful PATHs even if environment is an empty hash" do
+ env={}
+ @sanity.enforce_path_sanity(env)
+ env["PATH"].should == "#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
end
it "adds all useful PATHs that are not yet in PATH to PATH" do
@@ -59,8 +65,8 @@ describe Chef::Mixin::PathSanity do
it "does not create entries for Ruby/Gem bindirs if they exist in SANE_PATH or PATH" do
ruby_bindir = '/usr/bin'
gem_bindir = '/yo/gabba/gabba'
- Gem.stub!(:bindir).and_return(gem_bindir)
- RbConfig::CONFIG.stub!(:[]).with('bindir').and_return(ruby_bindir)
+ Gem.stub(:bindir).and_return(gem_bindir)
+ RbConfig::CONFIG.stub(:[]).with('bindir').and_return(ruby_bindir)
env = {"PATH" => gem_bindir}
@sanity.enforce_path_sanity(env)
env["PATH"].should == "/yo/gabba/gabba:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
@@ -69,9 +75,9 @@ describe Chef::Mixin::PathSanity do
it "builds a valid windows path" do
ruby_bindir = 'C:\ruby\bin'
gem_bindir = 'C:\gems\bin'
- Gem.stub!(:bindir).and_return(gem_bindir)
- RbConfig::CONFIG.stub!(:[]).with('bindir').and_return(ruby_bindir)
- Chef::Platform.stub!(:windows?).and_return(true)
+ Gem.stub(:bindir).and_return(gem_bindir)
+ RbConfig::CONFIG.stub(:[]).with('bindir').and_return(ruby_bindir)
+ Chef::Platform.stub(:windows?).and_return(true)
env = {"PATH" => 'C:\Windows\system32;C:\mr\softie'}
@sanity.enforce_path_sanity(env)
env["PATH"].should == "C:\\Windows\\system32;C:\\mr\\softie;#{ruby_bindir};#{gem_bindir}"
diff --git a/spec/unit/mixin/securable_spec.rb b/spec/unit/mixin/securable_spec.rb
index 764da9b1d1..89916e0039 100644
--- a/spec/unit/mixin/securable_spec.rb
+++ b/spec/unit/mixin/securable_spec.rb
@@ -1,3 +1,4 @@
+# encoding: UTF-8
#
# Author:: Mark Mzyk (<mmzyk@opscode.com>)
# Copyright:: Copyright (c) 2011 Opscode, Inc.
@@ -27,15 +28,15 @@ describe Chef::Mixin::Securable do
end
it "should accept a group name or id for group" do
- lambda { @securable.group "root" }.should_not raise_error(ArgumentError)
- lambda { @securable.group 123 }.should_not raise_error(ArgumentError)
- lambda { @securable.group "root*goo" }.should raise_error(ArgumentError)
+ lambda { @securable.group "root" }.should_not raise_error
+ lambda { @securable.group 123 }.should_not raise_error
+ lambda { @securable.group "+bad:group" }.should raise_error(ArgumentError)
end
it "should accept a user name or id for owner" do
- lambda { @securable.owner "root" }.should_not raise_error(ArgumentError)
- lambda { @securable.owner 123 }.should_not raise_error(ArgumentError)
- lambda { @securable.owner "root*goo" }.should raise_error(ArgumentError)
+ lambda { @securable.owner "root" }.should_not raise_error
+ lambda { @securable.owner 123 }.should_not raise_error
+ lambda { @securable.owner "+bad:owner" }.should raise_error(ArgumentError)
end
it "allows the owner to be specified as #user" do
@@ -45,7 +46,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,24 +54,93 @@ describe Chef::Mixin::Securable do
end
end
- after(:each) do
- Chef::Config.configuration = @original_config
+ it "should accept group/owner names with spaces and backslashes" do
+ lambda { @securable.group 'test\ group' }.should_not raise_error
+ lambda { @securable.owner 'test\ group' }.should_not raise_error
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)
+ it "should accept group/owner names that are a single character or digit" do
+ lambda { @securable.group 'v' }.should_not raise_error
+ lambda { @securable.group '1' }.should_not raise_error
+ lambda { @securable.owner 'v' }.should_not raise_error
+ lambda { @securable.owner '1' }.should_not raise_error
+ end
+
+ it "should not accept group/owner names starting with '-', '+', or '~'" do
+ lambda { @securable.group '-test' }.should raise_error(ArgumentError)
+ lambda { @securable.group '+test' }.should raise_error(ArgumentError)
+ lambda { @securable.group '~test' }.should raise_error(ArgumentError)
+ lambda { @securable.group 'te-st' }.should_not raise_error
+ lambda { @securable.group 'te+st' }.should_not raise_error
+ lambda { @securable.group 'te~st' }.should_not raise_error
+ lambda { @securable.owner '-test' }.should raise_error(ArgumentError)
+ lambda { @securable.owner '+test' }.should raise_error(ArgumentError)
+ lambda { @securable.owner '~test' }.should raise_error(ArgumentError)
+ lambda { @securable.owner 'te-st' }.should_not raise_error
+ lambda { @securable.owner 'te+st' }.should_not raise_error
+ lambda { @securable.owner 'te~st' }.should_not raise_error
+ end
+
+ it "should not accept group/owner names containing ':', ',' or non-space whitespace" do
+ lambda { @securable.group ':test' }.should raise_error(ArgumentError)
+ lambda { @securable.group 'te:st' }.should raise_error(ArgumentError)
+ lambda { @securable.group ',test' }.should raise_error(ArgumentError)
+ lambda { @securable.group 'te,st' }.should raise_error(ArgumentError)
+ lambda { @securable.group "\ttest" }.should raise_error(ArgumentError)
+ lambda { @securable.group "te\tst" }.should raise_error(ArgumentError)
+ lambda { @securable.group "\rtest" }.should raise_error(ArgumentError)
+ lambda { @securable.group "te\rst" }.should raise_error(ArgumentError)
+ lambda { @securable.group "\ftest" }.should raise_error(ArgumentError)
+ lambda { @securable.group "te\fst" }.should raise_error(ArgumentError)
+ lambda { @securable.group "\0test" }.should raise_error(ArgumentError)
+ lambda { @securable.group "te\0st" }.should raise_error(ArgumentError)
+ lambda { @securable.owner ':test' }.should raise_error(ArgumentError)
+ lambda { @securable.owner 'te:st' }.should raise_error(ArgumentError)
+ lambda { @securable.owner ',test' }.should raise_error(ArgumentError)
+ lambda { @securable.owner 'te,st' }.should raise_error(ArgumentError)
+ lambda { @securable.owner "\ttest" }.should raise_error(ArgumentError)
+ lambda { @securable.owner "te\tst" }.should raise_error(ArgumentError)
+ lambda { @securable.owner "\rtest" }.should raise_error(ArgumentError)
+ lambda { @securable.owner "te\rst" }.should raise_error(ArgumentError)
+ lambda { @securable.owner "\ftest" }.should raise_error(ArgumentError)
+ lambda { @securable.owner "te\fst" }.should raise_error(ArgumentError)
+ lambda { @securable.owner "\0test" }.should raise_error(ArgumentError)
+ lambda { @securable.owner "te\0st" }.should raise_error(ArgumentError)
+ end
+
+ it "should accept Active Directory-style domain names pulled in via LDAP (on unix hosts)" do
+ lambda { @securable.owner "domain\@user" }.should_not raise_error
+ lambda { @securable.owner "domain\\user" }.should_not raise_error
+ lambda { @securable.group "domain\@group" }.should_not raise_error
+ lambda { @securable.group "domain\\group" }.should_not raise_error
+ lambda { @securable.group "domain\\group^name" }.should_not raise_error
+ end
+
+ it "should not accept group/owner names containing embedded carriage returns" do
+ pending "XXX: params_validate needs to be extended to support multi-line regex"
+ #lambda { @securable.group "\ntest" }.should raise_error(ArgumentError)
+ #lambda { @securable.group "te\nst" }.should raise_error(ArgumentError)
+ #lambda { @securable.owner "\ntest" }.should raise_error(ArgumentError)
+ #lambda { @securable.owner "te\nst" }.should raise_error(ArgumentError)
+ end
+
+ it "should accept group/owner names in UTF-8" do
+ lambda { @securable.group 'tëst' }.should_not raise_error
+ lambda { @securable.group 'ë' }.should_not raise_error
+ lambda { @securable.owner 'tëst' }.should_not raise_error
+ lambda { @securable.owner 'ë' }.should_not raise_error
end
it "should accept a unix file mode in string form as an octal number" do
- lambda { @securable.mode "0" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "0000" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "0111" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "0444" }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode "0" }.should_not raise_error
+ lambda { @securable.mode "0000" }.should_not raise_error
+ lambda { @securable.mode "0111" }.should_not raise_error
+ lambda { @securable.mode "0444" }.should_not raise_error
- lambda { @securable.mode "111" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "444" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "7777" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "07777" }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode "111" }.should_not raise_error
+ lambda { @securable.mode "444" }.should_not raise_error
+ lambda { @securable.mode "7777" }.should_not raise_error
+ lambda { @securable.mode "07777" }.should_not raise_error
lambda { @securable.mode "-01" }.should raise_error(ArgumentError)
lambda { @securable.mode "010000" }.should raise_error(ArgumentError)
@@ -87,17 +156,17 @@ describe Chef::Mixin::Securable do
end
it "should accept a unix file mode in numeric form as a ruby-interpreted integer" do
- lambda { @securable.mode 0 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 0000 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 444 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 0444 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 07777 }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode 0 }.should_not raise_error
+ lambda { @securable.mode 0000 }.should_not raise_error
+ lambda { @securable.mode 444 }.should_not raise_error
+ lambda { @securable.mode 0444 }.should_not raise_error
+ lambda { @securable.mode 07777 }.should_not raise_error
- lambda { @securable.mode 292 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 4095 }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode 292 }.should_not raise_error
+ lambda { @securable.mode 4095 }.should_not raise_error
- lambda { @securable.mode 0111 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 73 }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode 0111 }.should_not raise_error
+ lambda { @securable.mode 73 }.should_not raise_error
lambda { @securable.mode -01 }.should raise_error(ArgumentError)
lambda { @securable.mode 010000 }.should raise_error(ArgumentError)
@@ -109,7 +178,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,26 +188,18 @@ 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
it "should accept a unix file mode in string form as an octal number" do
- lambda { @securable.mode "0" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "0000" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "0111" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "0444" }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode "0" }.should_not raise_error
+ lambda { @securable.mode "0000" }.should_not raise_error
+ lambda { @securable.mode "0111" }.should_not raise_error
+ lambda { @securable.mode "0444" }.should_not raise_error
- lambda { @securable.mode "111" }.should_not raise_error(ArgumentError)
- lambda { @securable.mode "444" }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode "111" }.should_not raise_error
+ lambda { @securable.mode "444" }.should_not raise_error
lambda { @securable.mode "7777" }.should raise_error(ArgumentError)
lambda { @securable.mode "07777" }.should raise_error(ArgumentError)
@@ -157,17 +217,17 @@ describe Chef::Mixin::Securable do
end
it "should accept a unix file mode in numeric form as a ruby-interpreted integer" do
- lambda { @securable.mode 0 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 0000 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 444 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 0444 }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode 0 }.should_not raise_error
+ lambda { @securable.mode 0000 }.should_not raise_error
+ lambda { @securable.mode 444 }.should_not raise_error
+ lambda { @securable.mode 0444 }.should_not raise_error
lambda { @securable.mode 07777 }.should raise_error(ArgumentError)
- lambda { @securable.mode 292 }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode 292 }.should_not raise_error
lambda { @securable.mode 4095 }.should raise_error(ArgumentError)
- lambda { @securable.mode 0111 }.should_not raise_error(ArgumentError)
- lambda { @securable.mode 73 }.should_not raise_error(ArgumentError)
+ lambda { @securable.mode 0111 }.should_not raise_error
+ lambda { @securable.mode 73 }.should_not raise_error
lambda { @securable.mode -01 }.should raise_error(ArgumentError)
lambda { @securable.mode 010000 }.should raise_error(ArgumentError)
@@ -176,46 +236,46 @@ describe Chef::Mixin::Securable do
end
it "should allow you to specify :full_control, :modify, :read_execute, :read, and :write rights" do
- lambda { @securable.rights :full_control, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :modify, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read_execute, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :write, "The Dude" }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :full_control, "The Dude" }.should_not raise_error
+ lambda { @securable.rights :modify, "The Dude" }.should_not raise_error
+ lambda { @securable.rights :read_execute, "The Dude" }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude" }.should_not raise_error
+ lambda { @securable.rights :write, "The Dude" }.should_not raise_error
lambda { @securable.rights :to_party, "The Dude" }.should raise_error(ArgumentError)
end
it "should allow you to specify :full_control, :modify, :read_execute, :read, and :write deny_rights" do
- lambda { @securable.deny_rights :full_control, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.deny_rights :modify, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.deny_rights :read_execute, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.deny_rights :read, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.deny_rights :write, "The Dude" }.should_not raise_error(ArgumentError)
+ lambda { @securable.deny_rights :full_control, "The Dude" }.should_not raise_error
+ lambda { @securable.deny_rights :modify, "The Dude" }.should_not raise_error
+ lambda { @securable.deny_rights :read_execute, "The Dude" }.should_not raise_error
+ lambda { @securable.deny_rights :read, "The Dude" }.should_not raise_error
+ lambda { @securable.deny_rights :write, "The Dude" }.should_not raise_error
lambda { @securable.deny_rights :to_party, "The Dude" }.should raise_error(ArgumentError)
end
it "should accept a principal as a string or an array" do
- lambda { @securable.rights :read, "The Dude" }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, ["The Dude","Donny"] }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :read, "The Dude" }.should_not raise_error
+ lambda { @securable.rights :read, ["The Dude","Donny"] }.should_not raise_error
lambda { @securable.rights :read, 3 }.should raise_error(ArgumentError)
end
it "should allow you to specify whether the permissions applies_to_children with true/false/:containers_only/:objects_only" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => false }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => :containers_only }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => :objects_only }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => false }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => true }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => :containers_only }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => :objects_only }.should_not raise_error
lambda { @securable.rights :read, "The Dude", :applies_to_children => 'poop' }.should raise_error(ArgumentError)
end
it "should allow you to specify whether the permissions applies_to_self with true/false" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => false }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_self => true }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => false }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_self => true }.should_not raise_error
lambda { @securable.rights :read, "The Dude", :applies_to_self => 'poop' }.should raise_error(ArgumentError)
end
it "should allow you to specify whether the permissions applies one_level_deep with true/false" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => false }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => true }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => false }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => true }.should_not raise_error
lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => 'poop' }.should raise_error(ArgumentError)
end
@@ -230,26 +290,26 @@ describe Chef::Mixin::Securable do
end
it "should allow you to specify whether the permission applies_to_self only if you specified applies_to_children" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => true }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => false }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :applies_to_self => true }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => true }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => false }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :applies_to_self => true }.should_not raise_error
lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :applies_to_self => false }.should raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_self => true }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_self => false }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :read, "The Dude", :applies_to_self => true }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_self => false }.should_not raise_error
end
it "should allow you to specify whether the permission applies one_level_deep only if you specified applies_to_children" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => true }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => false }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => true }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => false }.should_not raise_error
lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :one_level_deep => true }.should raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :one_level_deep => false }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :one_level_deep => true }.should_not raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :one_level_deep => false }.should_not raise_error(ArgumentError)
+ lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :one_level_deep => false }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :one_level_deep => true }.should_not raise_error
+ lambda { @securable.rights :read, "The Dude", :one_level_deep => false }.should_not raise_error
end
it "should allow you to specify whether the permissions inherit with true/false" do
- lambda { @securable.inherits true }.should_not raise_error(ArgumentError)
- lambda { @securable.inherits false }.should_not raise_error(ArgumentError)
+ lambda { @securable.inherits true }.should_not raise_error
+ lambda { @securable.inherits false }.should_not raise_error
lambda { @securable.inherits "monkey" }.should raise_error(ArgumentError)
end
end
diff --git a/spec/unit/mixin/shell_out_spec.rb b/spec/unit/mixin/shell_out_spec.rb
index c7ca56fe84..f325f687d9 100644
--- a/spec/unit/mixin/shell_out_spec.rb
+++ b/spec/unit/mixin/shell_out_spec.rb
@@ -32,7 +32,7 @@ describe Chef::Mixin::ShellOut do
let(:output) { StringIO.new }
let!(:capture_log_output) { Chef::Log.logger = Logger.new(output) }
- let(:assume_deprecation_log_level) { Chef::Log.stub!(:level).and_return(:warn) }
+ let(:assume_deprecation_log_level) { Chef::Log.stub(:level).and_return(:warn) }
context 'without options' do
let(:command_args) { [ cmd ] }
diff --git a/spec/unit/mixin/template_spec.rb b/spec/unit/mixin/template_spec.rb
index 039bc1984f..3aa0b9ba22 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/monkey_patches/uri_spec.rb b/spec/unit/monkey_patches/uri_spec.rb
new file mode 100644
index 0000000000..cff252ac3b
--- /dev/null
+++ b/spec/unit/monkey_patches/uri_spec.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 'spec_helper'
+describe URI do
+
+ describe "when a URI contains an IPv6 literal" do
+
+ let(:ipv6_uri) do
+ URI.parse("https://[2a00:1450:4009:809::1008]:8443")
+ end
+
+ it "returns the hostname without brackets" do
+ ipv6_uri.hostname.should == "2a00:1450:4009:809::1008"
+ end
+
+ end
+
+end
diff --git a/spec/unit/monologger_spec.rb b/spec/unit/monologger_spec.rb
new file mode 100644
index 0000000000..3babc29218
--- /dev/null
+++ b/spec/unit/monologger_spec.rb
@@ -0,0 +1,45 @@
+#
+# Copyright:: Copyright (c) 2014 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/monologger'
+require 'tempfile'
+require 'spec_helper'
+
+describe MonoLogger do
+ it "should disable buffering when passed an IO stream" do
+ STDOUT.sync = false
+ MonoLogger.new(STDOUT)
+ STDOUT.sync.should == true
+ end
+
+ describe "when given an object that responds to write and close e.g. IO" do
+ it "should use the object directly" do
+ stream = StringIO.new
+ MonoLogger.new(stream).fatal("Houston, we've had a problem.")
+ stream.string.should =~ /Houston, we've had a problem./
+ end
+ end
+
+ describe "when given an object that is stringable (to_str)" do
+ it "should open a File object with the given path" do
+ temp_file = Tempfile.new("rspec-monologger-log")
+ temp_file.close
+ MonoLogger.new(temp_file.path).fatal("Do, or do not. There is no try.")
+ File.read(temp_file.path).should =~ /Do, or do not. There is no try./
+ end
+ end
+end
diff --git a/spec/unit/node/attribute_spec.rb b/spec/unit/node/attribute_spec.rb
index 5aa563aedf..ef3fc60cc6 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
@@ -437,7 +437,7 @@ describe Chef::Node::Attribute do
it "should let you set an attribute value when another hash has an intermediate value" do
@attributes.normal["the_ghost"] = { "exterminate" => "the future" }
- lambda { @attributes.normal["the_ghost"]["exterminate"]["tomorrow"] = false }.should_not raise_error(NoMethodError)
+ lambda { @attributes.normal["the_ghost"]["eviscerate"]["tomorrow"] = false }.should_not raise_error
end
it "should set the attribute value" do
@@ -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,11 +593,11 @@ 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
- lambda { @attributes.place.keys { |k| } }.should_not raise_error(NoMethodError)
+ lambda { @attributes.place.keys { |k| } }.should_not raise_error
end
end
@@ -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(
@@ -981,7 +981,7 @@ describe Chef::Node::Attribute do
if RUBY_VERSION >= "1.8.7"
it "should not raise a LocalJumpError if no block is given" do
- lambda { @attributes.select }.should_not raise_error(LocalJumpError)
+ lambda { @attributes.select }.should_not raise_error
end
else
it "should raise a LocalJumpError if no block is given" do
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 20f750279f..832e10f645 100644
--- a/spec/unit/node_spec.rb
+++ b/spec/unit/node_spec.rb
@@ -46,12 +46,12 @@ describe Chef::Node do
before do
response = OpenStruct.new(:code => '404')
exception = Net::HTTPServerException.new("404 not found", response)
- Chef::Node.stub!(:load).and_raise(exception)
+ Chef::Node.stub(:load).and_raise(exception)
node.name("created-node")
end
it "creates a new node for find_or_create" do
- Chef::Node.stub!(:new).and_return(node)
+ Chef::Node.stub(:new).and_return(node)
node.should_receive(:create).and_return(node)
node = Chef::Node.find_or_create("created-node")
node.name.should == 'created-node'
@@ -62,7 +62,7 @@ describe Chef::Node do
describe "when the node exists on the server" do
before do
node.name('existing-node')
- Chef::Node.stub!(:load).and_return(node)
+ Chef::Node.stub(:load).and_return(node)
end
it "loads the node via the REST API for find_or_create" do
@@ -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
@@ -400,7 +405,7 @@ describe Chef::Node do
it "saves non-runlist json attrs for later" do
expansion = Chef::RunList::RunListExpansion.new('_default', [])
- node.run_list.stub!(:expand).and_return(expansion)
+ node.run_list.stub(:expand).and_return(expansion)
node.consume_external_attrs(@ohai_data, {"foo" => "bar"})
node.expand!
node.normal_attrs.should == {"foo" => "bar", "tags" => []}
@@ -418,7 +423,7 @@ describe Chef::Node do
Chef::Environment.should_receive(:load).with("rspec_env").and_return(@environment)
@expansion = Chef::RunList::RunListExpansion.new("rspec_env", [])
node.chef_environment("rspec_env")
- node.run_list.stub!(:expand).and_return(@expansion)
+ node.run_list.stub(:expand).and_return(@expansion)
end
it "sets the 'recipes' automatic attribute to the recipes in the expanded run_list" do
@@ -456,6 +461,22 @@ describe Chef::Node do
end
end
+ describe "loaded_recipe" do
+ it "should not add a recipe that is already in the recipes list" do
+ node.automatic_attrs[:recipes] = [ "nginx::module" ]
+ node.loaded_recipe(:nginx, "module")
+ expect(node.automatic_attrs[:recipes].length).to eq(1)
+ end
+
+ it "should add a recipe that is not already in the recipes list" do
+ node.automatic_attrs[:recipes] = [ "nginx::other_module" ]
+ node.loaded_recipe(:nginx, "module")
+ expect(node.automatic_attrs[:recipes].length).to eq(2)
+ expect(node.recipe?("nginx::module")).to be_true
+ expect(node.recipe?("nginx::other_module")).to be_true
+ end
+ end
+
describe "when querying for recipes in the run list" do
context "when a recipe is in the top level run list" do
before do
@@ -519,7 +540,7 @@ describe Chef::Node do
@environment = Chef::Environment.new
@environment.default_attributes = {:default => "from env", :d_env => "env only" }
@environment.override_attributes = {:override => "from env", :o_env => "env only"}
- Chef::Environment.stub!(:load).and_return(@environment)
+ Chef::Environment.stub(:load).and_return(@environment)
node.apply_expansion_attributes(@expansion)
end
@@ -752,16 +773,16 @@ describe Chef::Node do
describe "api model" do
before(:each) do
- @rest = mock("Chef::REST")
- Chef::REST.stub!(:new).and_return(@rest)
- @query = mock("Chef::Search::Query")
- Chef::Search::Query.stub!(:new).and_return(@query)
+ @rest = double("Chef::REST")
+ Chef::REST.stub(:new).and_return(@rest)
+ @query = double("Chef::Search::Query")
+ Chef::Search::Query.stub(:new).and_return(@query)
end
describe "list" do
describe "inflated" do
it "should return a hash of node names and objects" do
- n1 = mock("Chef::Node", :name => "one")
+ n1 = double("Chef::Node", :name => "one")
@query.should_receive(:search).with(:node).and_yield(n1)
r = Chef::Node.list(true)
r["one"].should == n1
@@ -806,7 +827,7 @@ describe Chef::Node do
it "should create if it cannot update" do
node.name("monkey")
- exception = mock("404 error", :code => "404")
+ exception = double("404 error", :code => "404")
@rest.should_receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
@rest.should_receive(:post_rest).with("nodes", node)
node.save
diff --git a/spec/unit/platform_spec.rb b/spec/unit/platform_spec.rb
index 21bc4298b0..e0386a1a61 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,8 +150,8 @@ describe Chef::Platform do
end
it "should prefer an explicit provider" do
- kitty = Chef::Resource::Cat.new("loulou")
- kitty.stub!(:provider).and_return(Chef::Provider::File)
+ kitty = Chef::Resource::Cat.new("loulou")
+ kitty.stub(:provider).and_return(Chef::Provider::File)
node = Chef::Node.new
node.name("Intel")
node.automatic_attrs[:platform] = "mac_os_x"
@@ -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/policy_builder/expand_node_object_spec.rb b/spec/unit/policy_builder/expand_node_object_spec.rb
new file mode 100644
index 0000000000..5c6f39d28c
--- /dev/null
+++ b/spec/unit/policy_builder/expand_node_object_spec.rb
@@ -0,0 +1,336 @@
+#
+# Author:: Daniel DeLeo (<dan@getchef.com>)
+# Copyright:: Copyright 2014 Chef Software, 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/policy_builder'
+
+describe Chef::PolicyBuilder::ExpandNodeObject do
+
+ let(:node_name) { "joe_node" }
+ let(:ohai_data) { {"platform" => "ubuntu", "platform_version" => "13.04", "fqdn" => "joenode.example.com"} }
+ let(:json_attribs) { {"run_list" => []} }
+ let(:override_runlist) { "recipe[foo::default]" }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let(:policy_builder) { Chef::PolicyBuilder::ExpandNodeObject.new(node_name, ohai_data, json_attribs, override_runlist, events) }
+
+ # All methods that Chef::Client calls on this class.
+ describe "Public API" do
+ it "implements a node method" do
+ expect(policy_builder).to respond_to(:node)
+ end
+
+ it "implements a load_node method" do
+ expect(policy_builder).to respond_to(:load_node)
+ end
+
+ it "implements a build_node method" do
+ expect(policy_builder).to respond_to(:build_node)
+ end
+
+ it "implements a setup_run_context method that accepts a list of recipe files to run" do
+ expect(policy_builder).to respond_to(:setup_run_context)
+ expect(policy_builder.method(:setup_run_context).arity).to eq(-1) #optional argument
+ end
+
+ it "implements a run_context method" do
+ expect(policy_builder).to respond_to(:run_context)
+ end
+
+ it "implements an expand_run_list method" do
+ expect(policy_builder).to respond_to(:expand_run_list)
+ end
+
+ it "implements a sync_cookbooks method" do
+ expect(policy_builder).to respond_to(:sync_cookbooks)
+ end
+
+ it "implements a temporary_policy? method" do
+ expect(policy_builder).to respond_to(:temporary_policy?)
+ end
+
+ describe "loading the node" do
+
+ context "on chef-solo" do
+
+ before do
+ Chef::Config[:solo] = true
+ end
+
+ it "creates a new in-memory node object with the given name" do
+ policy_builder.load_node
+ policy_builder.node.name.should == node_name
+ end
+
+ end
+
+ context "on chef-client" do
+
+ let(:node) { Chef::Node.new.tap { |n| n.name(node_name) } }
+
+ it "loads or creates a node on the server" do
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ policy_builder.load_node
+ policy_builder.node.should == node
+ end
+
+ end
+ end
+
+ describe "building the node" do
+
+ # XXX: Chef::Client just needs to be able to call this, it doesn't depend on the return value.
+ it "builds the node and returns the updated node object" do
+ pending
+ end
+
+ end
+
+ end
+
+ # Implementation specific tests
+
+ describe "when first created" do
+
+ it "has a node_name" do
+ expect(policy_builder.node_name).to eq(node_name)
+ end
+
+ it "has ohai data" do
+ expect(policy_builder.ohai_data).to eq(ohai_data)
+ end
+
+ it "has a set of attributes from command line option" do
+ expect(policy_builder.json_attribs).to eq(json_attribs)
+ end
+
+ it "has an override_runlist" do
+ expect(policy_builder.override_runlist).to eq(override_runlist)
+ end
+
+ end
+
+ context "once the node has been loaded" do
+ let(:node) do
+ node = Chef::Node.new
+ node.name(node_name)
+ node.run_list(["recipe[a::default]", "recipe[b::server]"])
+ node
+ end
+
+ before do
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ policy_builder.load_node
+ end
+
+ it "expands the run_list" do
+ expect(policy_builder.expand_run_list).to be_a(Chef::RunList::RunListExpansion)
+ expect(policy_builder.run_list_expansion).to be_a(Chef::RunList::RunListExpansion)
+ expect(policy_builder.run_list_expansion.recipes).to eq(["a::default", "b::server"])
+ end
+
+ end
+
+ describe "building the node" do
+
+ let(:configured_environment) { nil }
+ let(:json_attribs) { nil }
+
+ let(:override_runlist) { nil }
+ let(:primary_runlist) { ["recipe[primary::default]"] }
+
+ let(:original_default_attrs) { {"default_key" => "default_value"} }
+ let(:original_override_attrs) { {"override_key" => "override_value"} }
+
+ let(:node) do
+ node = Chef::Node.new
+ node.name(node_name)
+ node.default_attrs = original_default_attrs
+ node.override_attrs = original_override_attrs
+ node.run_list(primary_runlist)
+ node
+ end
+
+ before do
+ Chef::Config[:environment] = configured_environment
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ policy_builder.load_node
+ policy_builder.build_node
+ end
+
+ it "sanity checks test setup" do
+ expect(node.run_list).to eq(primary_runlist)
+ end
+
+ it "clears existing default and override attributes from the node" do
+ expect(node["default_key"]).to be_nil
+ expect(node["override_key"]).to be_nil
+ end
+
+ it "applies ohai data to the node" do
+ expect(node["fqdn"]).to eq(ohai_data["fqdn"])
+ end
+
+ it "reports that a temporary_policy is not being used" do
+ expect(policy_builder.temporary_policy?).to be_false
+ end
+
+ describe "when the given run list is not in expanded form" do
+
+ # NOTE: for chef-client, the behavior is always to expand the run list,
+ # but this operation is a no-op when none of the run list items are
+ # roles. Because of the amount of mocking required to make this work in
+ # tests, this test is isolated from the others.
+
+ let(:primary_runlist) { ["role[some_role]"] }
+ let(:expansion) do
+ recipe_list = Chef::RunList::VersionedRecipeList.new
+ recipe_list.add_recipe("recipe[from_role::default", "1.0.2")
+ double("RunListExpansion", :recipes => recipe_list)
+ end
+
+ let(:node) do
+ node = Chef::Node.new
+ node.name(node_name)
+ node.default_attrs = original_default_attrs
+ node.override_attrs = original_override_attrs
+ node.run_list(primary_runlist)
+
+ node.should_receive(:expand!).with("server") do
+ node.run_list("recipe[from_role::default]")
+ expansion
+ end
+
+ node
+ end
+
+ it "expands run list items via the server API" do
+ expect(node.run_list).to eq(["recipe[from_role::default]"])
+ end
+
+ end
+
+ context "when JSON attributes are given on the command line" do
+
+ let(:json_attribs) { {"run_list" => ["recipe[json_attribs::default]"], "json_attribs_key" => "json_attribs_value" } }
+
+ it "sets the run list according to the given JSON" do
+ expect(node.run_list).to eq(["recipe[json_attribs::default]"])
+ end
+
+ it "sets node attributes according to the given JSON" do
+ expect(node["json_attribs_key"]).to eq("json_attribs_value")
+ end
+
+ end
+
+ context "when an override_runlist is given" do
+
+ let(:override_runlist) { "recipe[foo::default]" }
+
+ it "sets the override run_list on the node" do
+ expect(node.run_list).to eq([override_runlist])
+ expect(policy_builder.original_runlist).to eq(primary_runlist)
+ end
+
+ it "reports that a temporary policy is being used" do
+ expect(policy_builder.temporary_policy?).to be_true
+ end
+
+ end
+
+ context "when no environment is specified" do
+
+ it "does not set the environment" do
+ expect(node.chef_environment).to eq("_default")
+ end
+
+ end
+
+ context "when a custom environment is configured" do
+
+ let(:configured_environment) { environment.name }
+
+ let(:environment) do
+ environment = Chef::Environment.new.tap {|e| e.name("prod") }
+ Chef::Environment.should_receive(:load).with("prod").and_return(environment)
+ environment
+ end
+
+ it "sets the environment as configured" do
+ expect(node.chef_environment).to eq(environment.name)
+ end
+ end
+
+ end
+
+ describe "configuring the run_context" do
+ let(:json_attribs) { nil }
+ let(:override_runlist) { nil }
+
+ let(:node) do
+ node = Chef::Node.new
+ node.name(node_name)
+ node.run_list("recipe[first::default]", "recipe[second::default]")
+ node
+ end
+
+ let(:chef_http) { double("Chef::REST") }
+
+ let(:cookbook_resolve_url) { "environments/#{node.chef_environment}/cookbook_versions" }
+ let(:cookbook_resolve_post_data) { {:run_list=>["first::default", "second::default"]} }
+
+ # cookbook_hash is just a hash, but since we're passing it between mock
+ # objects, we get a little better test strictness by using a double (which
+ # will have object equality rather than semantic equality #== semantics).
+ let(:cookbook_hash) { double("cookbook hash", :each => nil) }
+
+ let(:cookbook_synchronizer) { double("CookbookSynchronizer") }
+
+ before do
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+
+ policy_builder.stub(:api_service).and_return(chef_http)
+
+ policy_builder.load_node
+ policy_builder.build_node
+
+ run_list_expansion = policy_builder.run_list_expansion
+
+ chef_http.should_receive(:post).with(cookbook_resolve_url, cookbook_resolve_post_data).and_return(cookbook_hash)
+ Chef::CookbookSynchronizer.should_receive(:new).with(cookbook_hash, events).and_return(cookbook_synchronizer)
+ cookbook_synchronizer.should_receive(:sync_cookbooks)
+
+ Chef::RunContext.any_instance.should_receive(:load).with(run_list_expansion)
+
+ policy_builder.setup_run_context
+ end
+
+ it "configures FileVendor to fetch files remotely" do
+ manifest = double("cookbook manifest")
+ Chef::Cookbook::RemoteFileVendor.should_receive(:new).with(manifest, chef_http)
+ Chef::Cookbook::FileVendor.create_from_manifest(manifest)
+ end
+
+ it "triggers cookbook compilation in the run_context" do
+ # Test condition already covered by `Chef::RunContext.any_instance.should_receive(:load).with(run_list_expansion)`
+ end
+
+ end
+
+end
+
diff --git a/spec/unit/policy_builder/policyfile_spec.rb b/spec/unit/policy_builder/policyfile_spec.rb
new file mode 100644
index 0000000000..f02c79ef12
--- /dev/null
+++ b/spec/unit/policy_builder/policyfile_spec.rb
@@ -0,0 +1,403 @@
+#
+# Author:: Daniel DeLeo (<dan@getchef.com>)
+# Copyright:: Copyright 2014 Chef Software, 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/policy_builder'
+
+describe Chef::PolicyBuilder::Policyfile do
+
+ let(:node_name) { "joe_node" }
+ let(:ohai_data) { {"platform" => "ubuntu", "platform_version" => "13.04", "fqdn" => "joenode.example.com"} }
+ let(:json_attribs) { {"custom_attr" => "custom_attr_value"} }
+ let(:override_runlist) { nil }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let(:policy_builder) { Chef::PolicyBuilder::Policyfile.new(node_name, ohai_data, json_attribs, override_runlist, events) }
+
+ # Convert a SHA1 (160 bit) hex string into an x.y.z version number where the
+ # maximum value is smaller than a postgres BIGINT (signed 64bit, so 63 usable
+ # bits). This requires enterprise Chef or open source server 11.1.0+ (currently not released)
+ #
+ # The SHA1 is devided as follows:
+ # * "major": first 14 chars (56 bits)
+ # * "minor": next 14 chars (56 bits)
+ # * "patch": last 12 chars (48 bits)
+ def id_to_dotted(sha1_id)
+ major = sha1_id[0...14]
+ minor = sha1_id[14...28]
+ patch = sha1_id[28..40]
+ decimal_integers =[major, minor, patch].map {|hex| hex.to_i(16) }
+ decimal_integers.join(".")
+ end
+
+
+ let(:example1_lock_data) do
+ # based on https://github.com/danielsdeleo/chef-workflow2-prototype/blob/master/skeletons/basic_policy/Policyfile.lock.json
+ {
+ "identifier" => "168d2102fb11c9617cd8a981166c8adc30a6e915",
+ "version" => "2.3.5",
+ # NOTE: for compatibility mode we include the dotted id in the policyfile to enhance discoverability.
+ "dotted_decimal_identifier" => id_to_dotted("168d2102fb11c9617cd8a981166c8adc30a6e915"),
+ "source" => { "path" => "./cookbooks/demo" },
+ "scm_identifier"=> {
+ "vcs"=> "git",
+ "rev_id"=> "9d5b09026470c322c3cb5ca8a4157c4d2f16cef3",
+ "remote"=> nil
+ }
+ }
+ end
+
+ let(:example2_lock_data) do
+ {
+ "identifier" => "feab40e1fca77c7360ccca1481bb8ba5f919ce3a",
+ "version" => "4.2.0",
+ # NOTE: for compatibility mode we include the dotted id in the policyfile to enhance discoverability.
+ "dotted_decimal_identifier" => id_to_dotted("feab40e1fca77c7360ccca1481bb8ba5f919ce3a"),
+ "source" => { "api" => "https://community.getchef.com/api/v1/cookbooks/example2" }
+ }
+ end
+
+ let(:policyfile_default_attributes) { {"policyfile_default_attr" => "policyfile_default_value"} }
+ let(:policyfile_override_attributes) { {"policyfile_override_attr" => "policyfile_override_value"} }
+
+ let(:policyfile_run_list) { ["recipe[example1::default]", "recipe[example2::server]"] }
+
+ let(:parsed_policyfile_json) do
+ {
+ "run_list" => policyfile_run_list,
+
+ "cookbook_locks" => {
+ "example1" => example1_lock_data,
+ "example2" => example2_lock_data
+ },
+
+ "default_attributes" => policyfile_default_attributes,
+ "override_attributes" => policyfile_override_attributes
+ }
+ end
+
+ let(:err_namespace) { Chef::PolicyBuilder::Policyfile }
+
+ it "configures a Chef HTTP API client" do
+ http = double("Chef::REST")
+ server_url = "https://api.opscode.com/organizations/example"
+ Chef::Config[:chef_server_url] = server_url
+ Chef::REST.should_receive(:new).with(server_url).and_return(http)
+ expect(policy_builder.http_api).to eq(http)
+ end
+
+ describe "reporting unsupported features" do
+
+ def initialize_pb
+ Chef::PolicyBuilder::Policyfile.new(node_name, ohai_data, json_attribs, override_runlist, events)
+ end
+
+ it "always gives `false` for #temporary_policy?" do
+ expect(initialize_pb.temporary_policy?).to be_false
+ end
+
+ context "chef-solo" do
+ before { Chef::Config[:solo] = true }
+
+ it "errors on create" do
+ expect { initialize_pb }.to raise_error(err_namespace::UnsupportedFeature)
+ end
+ end
+
+ context "when given an override run_list" do
+ let(:override_runlist) { "recipe[foo],recipe[bar]" }
+
+ it "errors on create" do
+ expect { initialize_pb }.to raise_error(err_namespace::UnsupportedFeature)
+ end
+ end
+
+ context "when json_attribs contains a run_list" do
+ let(:json_attribs) { {"run_list" => []} }
+
+ it "errors on create" do
+ expect { initialize_pb }.to raise_error(err_namespace::UnsupportedFeature)
+ end
+ end
+
+ context "when an environment is configured" do
+ before { Chef::Config[:environment] = "blurch" }
+
+ it "errors when an environment is configured" do
+ expect { initialize_pb }.to raise_error(err_namespace::UnsupportedFeature)
+ end
+ end
+
+ end
+
+ describe "when using compatibility mode" do
+
+ let(:http_api) { double("Chef::REST") }
+
+ let(:configured_environment) { nil }
+
+ let(:override_runlist) { nil }
+ let(:primary_runlist) { nil }
+
+ let(:original_default_attrs) { {"default_key" => "default_value"} }
+ let(:original_override_attrs) { {"override_key" => "override_value"} }
+
+ let(:node) do
+ node = Chef::Node.new
+ node.name(node_name)
+ node.default_attrs = original_default_attrs
+ node.override_attrs = original_override_attrs
+ node.run_list(primary_runlist) if primary_runlist
+ node
+ end
+
+ before do
+ # TODO: agree on this name and logic.
+ Chef::Config[:deployment_group] = "example-policy-stage"
+ policy_builder.stub(:http_api).and_return(http_api)
+ end
+
+ context "when the deployment group cannot be loaded" do
+ let(:error404) { Net::HTTPServerException.new("404 message", :body) }
+
+ before do
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ http_api.should_receive(:get).
+ with("data/policyfiles/example-policy-stage").
+ and_raise(error404)
+ end
+
+ it "raises an error" do
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+ it "sends error message to the event system" do
+ events.should_receive(:node_load_failed).with(node_name, an_instance_of(err_namespace::ConfigurationError), Chef::Config)
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+ end
+
+ describe "when the deployment_group is not configured" do
+ before do
+ Chef::Config[:deployment_group] = nil
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ end
+
+ it "errors while loading the node" do
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+
+ it "passes error information to the event system" do
+ # TODO: also make sure something acceptable happens with the error formatters
+ err_class = err_namespace::ConfigurationError
+ events.should_receive(:node_load_failed).with(node_name, an_instance_of(err_class), Chef::Config)
+ expect { policy_builder.load_node }.to raise_error(err_class)
+ end
+ end
+
+ context "and a deployment_group is configured" do
+ before do
+ http_api.should_receive(:get).with("data/policyfiles/example-policy-stage").and_return(parsed_policyfile_json)
+ end
+
+ it "fetches the policy file from a data bag item" do
+ expect(policy_builder.policy).to eq(parsed_policyfile_json)
+ end
+
+ it "extracts the run_list from the policyfile" do
+ expect(policy_builder.run_list).to eq(policyfile_run_list)
+ end
+
+ it "extracts the cookbooks and versions for display from the policyfile" do
+ expected = [
+ "example1::default@2.3.5 (168d210)",
+ "example2::server@4.2.0 (feab40e)"
+ ]
+
+ expect(policy_builder.run_list_with_versions_for_display).to eq(expected)
+ end
+
+ it "generates a RunListExpansion-alike object for feeding to the CookbookCompiler" do
+ expect(policy_builder.run_list_expansion_ish).to respond_to(:recipes)
+ expect(policy_builder.run_list_expansion_ish.recipes).to eq(["example1::default", "example2::server"])
+ end
+
+ it "implements #expand_run_list in a manner compatible with ExpandNodeObject" do
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ policy_builder.load_node
+ expect(policy_builder.expand_run_list).to respond_to(:recipes)
+ expect(policy_builder.expand_run_list.recipes).to eq(["example1::default", "example2::server"])
+ expect(policy_builder.expand_run_list.roles).to eq([])
+ end
+
+
+ describe "validating the Policyfile.lock" do
+
+ it "errors if the policyfile json contains any non-recipe items" do
+ parsed_policyfile_json["run_list"] = ["role[foo]"]
+ expect { policy_builder.validate_policyfile }.to raise_error(err_namespace::PolicyfileError)
+ end
+
+ it "errors if the policyfile json contains non-fully qualified recipe items" do
+ parsed_policyfile_json["run_list"] = ["recipe[foo]"]
+ expect { policy_builder.validate_policyfile }.to raise_error(err_namespace::PolicyfileError)
+ end
+
+ it "errors if the policyfile doesn't have a run_list key" do
+ parsed_policyfile_json.delete("run_list")
+ expect { policy_builder.validate_policyfile }.to raise_error(err_namespace::PolicyfileError)
+ end
+
+ it "error if the policyfile doesn't have a cookbook_locks key" do
+ parsed_policyfile_json.delete("cookbook_locks")
+ expect { policy_builder.validate_policyfile }.to raise_error(err_namespace::PolicyfileError)
+ end
+
+ it "accepts a valid policyfile" do
+ policy_builder.validate_policyfile
+ end
+
+ end
+
+ describe "building the node object" do
+
+ before do
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+
+ policy_builder.load_node
+ policy_builder.build_node
+ end
+
+ it "resets default and override data" do
+ expect(node["default_key"]).to be_nil
+ expect(node["override_key"]).to be_nil
+ end
+
+ it "applies ohai data" do
+ expect(ohai_data).to_not be_empty # ensure test is testing something
+ ohai_data.each do |key, value|
+ expect(node.automatic_attrs[key]).to eq(value)
+ end
+ end
+
+ it "applies attributes from json file" do
+ expect(node["custom_attr"]).to eq("custom_attr_value")
+ end
+
+ it "applies attributes from the policyfile" do
+ expect(node["policyfile_default_attr"]).to eq("policyfile_default_value")
+ expect(node["policyfile_override_attr"]).to eq("policyfile_override_value")
+ end
+
+ it "sets the policyfile's run_list on the node object" do
+ expect(node.run_list).to eq(policyfile_run_list)
+ end
+
+ it "creates node.automatic_attrs[:roles]" do
+ expect(node.automatic_attrs[:roles]).to eq([])
+ end
+
+ it "create node.automatic_attrs[:recipes]" do
+ expect(node.automatic_attrs[:recipes]).to eq(["example1::default", "example2::server"])
+ end
+
+ end
+
+
+ describe "fetching the desired cookbook set" do
+
+ let(:example1_cookbook_object) { double("Chef::CookbookVersion for example1 cookbook") }
+ let(:example2_cookbook_object) { double("Chef::CookbookVersion for example2 cookbook") }
+
+ let(:expected_cookbook_hash) do
+ { "example1" => example1_cookbook_object, "example2" => example2_cookbook_object }
+ end
+
+ let(:example1_xyz_version) { example1_lock_data["dotted_decimal_identifier"] }
+ let(:example2_xyz_version) { example2_lock_data["dotted_decimal_identifier"] }
+
+ let(:cookbook_synchronizer) { double("Chef::CookbookSynchronizer") }
+
+ context "and a cookbook is missing" do
+
+ let(:error404) { Net::HTTPServerException.new("404 message", :body) }
+
+ before do
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+
+ # Remove references to example2 cookbook because we're iterating
+ # over a Hash data structure and on ruby 1.8.7 iteration order will
+ # not be stable.
+ parsed_policyfile_json["cookbook_locks"].delete("example2")
+ parsed_policyfile_json["run_list"].delete("recipe[example2::server]")
+
+ policy_builder.load_node
+ policy_builder.build_node
+
+ http_api.should_receive(:get).with("cookbooks/example1/#{example1_xyz_version}").
+ and_raise(error404)
+ end
+
+ it "raises an error indicating which cookbook is missing" do
+ expect { policy_builder.cookbooks_to_sync }.to raise_error(Chef::Exceptions::CookbookNotFound)
+ end
+
+ end
+
+ context "and the cookbooks can be fetched" do
+ before do
+ Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+
+ policy_builder.load_node
+ policy_builder.build_node
+
+ http_api.should_receive(:get).with("cookbooks/example1/#{example1_xyz_version}").
+ and_return(example1_cookbook_object)
+ http_api.should_receive(:get).with("cookbooks/example2/#{example2_xyz_version}").
+ and_return(example2_cookbook_object)
+
+ Chef::CookbookSynchronizer.stub(:new).
+ with(expected_cookbook_hash, events).
+ and_return(cookbook_synchronizer)
+ end
+
+ it "builds a Hash of the form 'cookbook_name' => Chef::CookbookVersion" do
+ expect(policy_builder.cookbooks_to_sync).to eq(expected_cookbook_hash)
+ end
+
+ it "syncs the desired cookbooks via CookbookSynchronizer" do
+ cookbook_synchronizer.should_receive(:sync_cookbooks)
+ policy_builder.sync_cookbooks
+ end
+
+ it "builds a run context" do
+ cookbook_synchronizer.should_receive(:sync_cookbooks)
+ Chef::RunContext.any_instance.should_receive(:load).with(policy_builder.run_list_expansion_ish)
+ run_context = policy_builder.setup_run_context
+ expect(run_context.node).to eq(node)
+ expect(run_context.cookbook_collection.keys).to match_array(["example1", "example2"])
+ end
+
+ end
+ end
+ end
+
+ end
+
+end
diff --git a/spec/unit/policy_builder_spec.rb b/spec/unit/policy_builder_spec.rb
new file mode 100644
index 0000000000..506911452c
--- /dev/null
+++ b/spec/unit/policy_builder_spec.rb
@@ -0,0 +1,26 @@
+#
+# Author:: Daniel DeLeo (<dan@getchef.com>)
+# Copyright:: Copyright 2014 Chef Software, 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/policy_builder'
+
+describe Chef::PolicyBuilder do
+
+ # TODO: test the strategy method
+
+end
diff --git a/spec/unit/provider/breakpoint_spec.rb b/spec/unit/provider/breakpoint_spec.rb
index 977624597a..05f3e8e0ed 100644
--- a/spec/unit/provider/breakpoint_spec.rb
+++ b/spec/unit/provider/breakpoint_spec.rb
@@ -25,8 +25,8 @@ describe Chef::Provider::Breakpoint do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
- @collection = mock("resource collection")
- @run_context.stub!(:resource_collection).and_return(@collection)
+ @collection = double("resource collection")
+ @run_context.stub(:resource_collection).and_return(@collection)
@provider = Chef::Provider::Breakpoint.new(@resource, @run_context)
end
@@ -35,18 +35,18 @@ describe Chef::Provider::Breakpoint do
end
it "gets the iterator from @collection and pauses it" do
- Shell.stub!(:running?).and_return(true)
- @iterator = mock("stepable_iterator")
- @collection.stub!(:iterator).and_return(@iterator)
+ Shell.stub(:running?).and_return(true)
+ @iterator = double("stepable_iterator")
+ @collection.stub(:iterator).and_return(@iterator)
@iterator.should_receive(:pause)
@provider.action_break
@resource.should be_updated
end
it "doesn't pause the iterator if chef-shell isn't running" do
- Shell.stub!(:running?).and_return(false)
- @iterator = mock("stepable_iterator")
- @collection.stub!(:iterator).and_return(@iterator)
+ Shell.stub(:running?).and_return(false)
+ @iterator = double("stepable_iterator")
+ @collection.stub(:iterator).and_return(@iterator)
@iterator.should_not_receive(:pause)
@provider.action_break
end
diff --git a/spec/unit/provider/cookbook_file/content_spec.rb b/spec/unit/provider/cookbook_file/content_spec.rb
index b771b76aae..ed8942aaf2 100644
--- a/spec/unit/provider/cookbook_file/content_spec.rb
+++ b/spec/unit/provider/cookbook_file/content_spec.rb
@@ -20,15 +20,15 @@ require 'spec_helper'
describe Chef::Provider::CookbookFile::Content do
- let(:new_resource) { mock('Chef::Resource::CookbookFile (new)', :cookbook_name => 'apache2', :cookbook => 'apache2') }
+ let(:new_resource) { double('Chef::Resource::CookbookFile (new)', :cookbook_name => 'apache2', :cookbook => 'apache2') }
let(:content) do
- @run_context = mock('Chef::RunContext')
- @current_resource = mock('Chef::Resource::CookbookFile (current)')
+ @run_context = double('Chef::RunContext')
+ @current_resource = double('Chef::Resource::CookbookFile (current)')
Chef::Provider::CookbookFile::Content.new(new_resource, @current_resource, @run_context)
end
it "prefers the explicit cookbook name on the resource to the implicit one" do
- new_resource.stub!(:cookbook).and_return('nginx')
+ new_resource.stub(:cookbook).and_return('nginx')
content.send(:resource_cookbook).should == 'nginx'
end
diff --git a/spec/unit/provider/cookbook_file_spec.rb b/spec/unit/provider/cookbook_file_spec.rb
index 44569075de..131fca2ba6 100644
--- a/spec/unit/provider/cookbook_file_spec.rb
+++ b/spec/unit/provider/cookbook_file_spec.rb
@@ -37,7 +37,7 @@ describe Chef::Provider::CookbookFile do
let(:provider) do
provider = described_class.new(resource, run_context)
- provider.stub!(:content).and_return(content)
+ provider.stub(:content).and_return(content)
provider
end
@@ -49,9 +49,10 @@ describe Chef::Provider::CookbookFile do
end
let(:content) do
- content = mock('Chef::Provider::CookbookFile::Content')
+ content = double('Chef::Provider::CookbookFile::Content')
end
it_behaves_like Chef::Provider::File
+ it_behaves_like "a file provider with source field"
end
diff --git a/spec/unit/provider/cron/unix_spec.rb b/spec/unit/provider/cron/unix_spec.rb
index ffdfa198b6..60e09baceb 100644
--- a/spec/unit/provider/cron/unix_spec.rb
+++ b/spec/unit/provider/cron/unix_spec.rb
@@ -39,7 +39,7 @@ describe Chef::Provider::Cron::Unix do
describe "read_crontab" do
before :each do
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@stdout = StringIO.new(<<-CRONTAB)
0 2 * * * /some/other/command
@@ -48,7 +48,7 @@ describe Chef::Provider::Cron::Unix do
# Another comment
CRONTAB
- @provider.stub!(:popen4).and_yield(1234, StringIO.new, @stdout, StringIO.new).and_return(@status)
+ @provider.stub(:popen4).and_yield(1234, StringIO.new, @stdout, StringIO.new).and_return(@status)
end
it "should call crontab -l with the user" do
@@ -69,14 +69,14 @@ CRONTAB
end
it "should return nil if the user has no crontab" do
- status = mock("Status", :exitstatus => 1)
- @provider.stub!(:popen4).and_return(status)
+ status = double("Status", :exitstatus => 1)
+ @provider.stub(:popen4).and_return(status)
@provider.send(:read_crontab).should == nil
end
it "should raise an exception if another error occurs" do
- status = mock("Status", :exitstatus => 2)
- @provider.stub!(:popen4).and_return(status)
+ status = double("Status", :exitstatus => 2)
+ @provider.stub(:popen4).and_return(status)
lambda do
@provider.send(:read_crontab)
end.should raise_error(Chef::Exceptions::Cron, "Error determining state of #{@new_resource.name}, exit: 2")
@@ -85,10 +85,10 @@ CRONTAB
describe "write_crontab" do
before :each do
- @status = mock("Status", :exitstatus => 0)
- @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)
+ @status = double("Status", :exitstatus => 0)
+ @provider.stub(:run_command_and_return_stdout_stderr).and_return(@status, String.new, String.new)
+ @tempfile = double("foo", :path => "/tmp/foo", :close => true)
+ Tempfile.stub(:new).and_return(@tempfile)
@tempfile.should_receive(:flush)
@tempfile.should_receive(:chmod).with(420)
@tempfile.should_receive(:close!)
@@ -112,7 +112,7 @@ CRONTAB
it "should raise an exception if the command returns non-zero" do
@tempfile.should_receive(:<<).with("Foo")
- @status.stub!(:exitstatus).and_return(1)
+ @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/)
diff --git a/spec/unit/provider/cron_spec.rb b/spec/unit/provider/cron_spec.rb
index f0d800741d..3a7a96c549 100644
--- a/spec/unit/provider/cron_spec.rb
+++ b/spec/unit/provider/cron_spec.rb
@@ -34,7 +34,7 @@ describe Chef::Provider::Cron do
describe "when examining the current system state" do
context "with no crontab for the user" do
before :each do
- @provider.stub!(:read_crontab).and_return(nil)
+ @provider.stub(:read_crontab).and_return(nil)
end
it "should set cron_empty" do
@@ -51,7 +51,7 @@ describe Chef::Provider::Cron do
context "with no matching entry in the user's crontab" do
before :each do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: something else
@@ -73,7 +73,7 @@ CRONTAB
end
it "should not fail if there's an existing cron with a numerical argument" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
# Chef Name: foo[bar] (baz)
21 */4 * * * some_prog 1234567
CRONTAB
@@ -85,7 +85,7 @@ CRONTAB
context "with a matching entry in the user's crontab" do
before :each do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -114,7 +114,7 @@ CRONTAB
end
it "should pull env vars out" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -142,7 +142,7 @@ CRONTAB
end
it "should parse and load generic and standard environment variables from cron entry" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
# Chef Name: cronhole some stuff
MAILTO=warn@example.com
TEST=lol
@@ -156,7 +156,7 @@ CRONTAB
end
it "should not break with variabels that match the cron resource internals" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
# Chef Name: cronhole some stuff
MINUTE=40
HOUR=midnight
@@ -179,9 +179,9 @@ CRONTAB
context "with a matching entry in the user's crontab using month names and weekday names (#CHEF-3178)" do
before :each do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @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 == '*'
@@ -215,7 +215,7 @@ CRONTAB
context "with a matching entry without a crontab line" do
it "should set cron_exists and leave current_resource values at defaults" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -231,7 +231,7 @@ CRONTAB
end
it "should not pick up a commented out crontab line" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -248,7 +248,7 @@ CRONTAB
end
it "should not pick up a later crontab entry" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -291,6 +291,12 @@ CRONTAB
@provider.cron_different?.should eql(true)
end
+ it "should return true if mailto doesn't match" do
+ @current_resource.mailto "foo@bar.com"
+ @new_resource.mailto(nil)
+ @provider.cron_different?.should eql(true)
+ end
+
it "should return false if the objects are identical" do
@provider.cron_different?.should == false
end
@@ -298,8 +304,8 @@ CRONTAB
describe "action_create" do
before :each do
- @provider.stub!(:write_crontab)
- @provider.stub!(:read_crontab).and_return(nil)
+ @provider.stub(:write_crontab)
+ @provider.stub(:read_crontab).and_return(nil)
end
context "when there is no existing crontab" do
@@ -348,7 +354,7 @@ TEST=LOL
context "when there is a crontab with no matching section" do
before :each do
@provider.cron_exists = false
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: something else
@@ -410,8 +416,8 @@ TEST=LOL
context "when there is a crontab with a matching but different section" do
before :each do
@provider.cron_exists = true
- @provider.stub!(:cron_different?).and_return(true)
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:cron_different?).and_return(true)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -475,11 +481,11 @@ TEST=LOL
context "when there is a crontab with a matching section with no crontab line in it" do
before :each do
@provider.cron_exists = true
- @provider.stub!(:cron_different?).and_return(true)
+ @provider.stub(:cron_different?).and_return(true)
end
it "should add the crontab to the entry" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -494,7 +500,7 @@ TEST=LOL
end
it "should not blat any following entries" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -519,7 +525,7 @@ TEST=LOL
end
it "should handle env vars with no crontab" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -559,8 +565,8 @@ HOME=/home/foo
context "when there is a crontab with a matching and identical section" do
before :each do
@provider.cron_exists = true
- @provider.stub!(:cron_different?).and_return(false)
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:cron_different?).and_return(false)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -581,7 +587,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("Found cron '#{@new_resource.name}'")
Chef::Log.should_receive(:debug).with("Skipping existing cron entry '#{@new_resource.name}'")
@provider.run_action(:create)
end
@@ -590,8 +596,8 @@ CRONTAB
describe "action_delete" do
before :each do
- @provider.stub!(:write_crontab)
- @provider.stub!(:read_crontab).and_return(nil)
+ @provider.stub(:write_crontab)
+ @provider.stub(:read_crontab).and_return(nil)
end
context "when the user's crontab has no matching section" do
@@ -614,7 +620,7 @@ CRONTAB
context "when the user has a crontab with a matching section" do
before :each do
@provider.cron_exists = true
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -639,7 +645,7 @@ CRONTAB
end
it "should remove any env vars with the entry" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -679,7 +685,7 @@ FOO=test
end
it "should remove the section" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -692,7 +698,7 @@ FOO=test
end
it "should not blat following sections" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -715,7 +721,7 @@ FOO=test
end
it "should remove any envvars with the section" do
- @provider.stub!(:read_crontab).and_return(<<-CRONTAB)
+ @provider.stub(:read_crontab).and_return(<<-CRONTAB)
0 2 * * * /some/other/command
# Chef Name: cronhole some stuff
@@ -742,7 +748,7 @@ MAILTO=foo@example.com
describe "read_crontab" do
before :each do
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@stdout = StringIO.new(<<-CRONTAB)
0 2 * * * /some/other/command
@@ -751,7 +757,7 @@ MAILTO=foo@example.com
# Another comment
CRONTAB
- @provider.stub!(:popen4).and_yield(1234, StringIO.new, @stdout, StringIO.new).and_return(@status)
+ @provider.stub(:popen4).and_yield(1234, StringIO.new, @stdout, StringIO.new).and_return(@status)
end
it "should call crontab -l with the user" do
@@ -772,14 +778,14 @@ MAILTO=foo@example.com
end
it "should return nil if the user has no crontab" do
- status = mock("Status", :exitstatus => 1)
- @provider.stub!(:popen4).and_return(status)
+ status = double("Status", :exitstatus => 1)
+ @provider.stub(:popen4).and_return(status)
@provider.send(:read_crontab).should == nil
end
it "should raise an exception if another error occurs" do
- status = mock("Status", :exitstatus => 2)
- @provider.stub!(:popen4).and_return(status)
+ status = double("Status", :exitstatus => 2)
+ @provider.stub(:popen4).and_return(status)
lambda do
@provider.send(:read_crontab)
end.should raise_error(Chef::Exceptions::Cron, "Error determining state of #{@new_resource.name}, exit: 2")
@@ -788,9 +794,9 @@ MAILTO=foo@example.com
describe "write_crontab" do
before :each do
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@stdin = StringIO.new
- @provider.stub!(:popen4).and_yield(1234, @stdin, StringIO.new, StringIO.new).and_return(@status)
+ @provider.stub(:popen4).and_yield(1234, @stdin, StringIO.new, StringIO.new).and_return(@status)
end
it "should call crontab for the user" do
@@ -804,7 +810,7 @@ MAILTO=foo@example.com
end
it "should raise an exception if the command returns non-zero" do
- @status.stub!(:exitstatus).and_return(1)
+ @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")
@@ -816,8 +822,8 @@ MAILTO=foo@example.com
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)
+ @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")
diff --git a/spec/unit/provider/deploy/revision_spec.rb b/spec/unit/provider/deploy/revision_spec.rb
index 13eaee6867..8d4590378e 100644
--- a/spec/unit/provider/deploy/revision_spec.rb
+++ b/spec/unit/provider/deploy/revision_spec.rb
@@ -30,20 +30,19 @@ describe Chef::Provider::Deploy::Revision do
@run_context = Chef::RunContext.new(@node, {}, @events)
@provider = Chef::Provider::Deploy::Revision.new(@resource, @run_context)
@provider.load_current_resource
- @runner = mock("runnah")
- Chef::Runner.stub!(:new).and_return(@runner)
+ @runner = double("runnah")
+ Chef::Runner.stub(:new).and_return(@runner)
@expected_release_dir = "/my/deploy/dir/releases/8a3195bf3efa246f743c5dfa83683201880f935c"
end
after do
# Make sure we don't keep any state in our tests
- FileUtils.rspec_reset
FileUtils.rm_rf @temp_dir if File.directory?( @temp_dir )
end
it "uses the resolved revision from the SCM as the release slug" do
- @provider.scm_provider.stub!(:revision_slug).and_return("uglySlugly")
+ @provider.scm_provider.stub(:revision_slug).and_return("uglySlugly")
@provider.send(:release_slug).should == "uglySlugly"
end
@@ -52,10 +51,10 @@ describe Chef::Provider::Deploy::Revision do
end
it "stores the release dir in the file cache in the cleanup step" do
- FileUtils.stub!(:mkdir_p)
- FileUtils.stub!(:cp_r)
+ FileUtils.stub(:mkdir_p)
+ FileUtils.stub(:cp_r)
@provider.cleanup!
- @provider.stub!(:release_slug).and_return("73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2")
+ @provider.stub(:release_slug).and_return("73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2")
@provider.load_current_resource
@provider.cleanup!
second_release = "/my/deploy/dir/releases/73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2"
@@ -64,17 +63,17 @@ describe Chef::Provider::Deploy::Revision do
end
it "removes a release from the file cache when it's used again in another release and append it to the end" do
- FileUtils.stub!(:mkdir_p)
- FileUtils.stub!(:cp_r)
+ FileUtils.stub(:mkdir_p)
+ FileUtils.stub(:cp_r)
@provider.cleanup!
- @provider.stub!(:release_slug).and_return("73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2")
+ @provider.stub(:release_slug).and_return("73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2")
@provider.load_current_resource
@provider.cleanup!
second_release = "/my/deploy/dir/releases/73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2"
@provider.all_releases.should == [@expected_release_dir,second_release]
@provider.cleanup!
- @provider.stub!(:release_slug).and_return("8a3195bf3efa246f743c5dfa83683201880f935c")
+ @provider.stub(:release_slug).and_return("8a3195bf3efa246f743c5dfa83683201880f935c")
@provider.load_current_resource
@provider.cleanup!
@provider.all_releases.should == [second_release, @expected_release_dir]
@@ -89,7 +88,7 @@ describe Chef::Provider::Deploy::Revision do
end
@provider.all_releases.should == release_paths
- FileUtils.stub!(:rm_rf)
+ FileUtils.stub(:rm_rf)
@provider.cleanup!
expected_release_paths = (%w{second third fourth fifth} << @resource.revision).map do |release_name|
diff --git a/spec/unit/provider/deploy/timestamped_spec.rb b/spec/unit/provider/deploy/timestamped_spec.rb
index b891a03ce2..1d42abfc05 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,22 +19,22 @@
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)
+ Time.stub(:now).and_return(@release_time)
@expected_release_dir = "/my/deploy/dir/releases/20040815162342"
@resource = Chef::Resource::Deploy.new("/my/deploy/dir")
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
@timestamped_deploy = Chef::Provider::Deploy::Timestamped.new(@resource, @run_context)
- @runner = mock("runnah")
- Chef::Runner.stub!(:new).and_return(@runner)
+ @runner = double("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..e6e4566011 100644
--- a/spec/unit/provider/deploy_spec.rb
+++ b/spec/unit/provider/deploy_spec.rb
@@ -22,15 +22,15 @@ describe Chef::Provider::Deploy do
before do
@release_time = Time.utc( 2004, 8, 15, 16, 23, 42)
- Time.stub!(:now).and_return(@release_time)
+ Time.stub(:now).and_return(@release_time)
@expected_release_dir = "/my/deploy/dir/releases/20040815162342"
@resource = Chef::Resource::Deploy.new("/my/deploy/dir")
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
@provider = Chef::Provider::Deploy.new(@resource, @run_context)
- @provider.stub!(:release_slug)
- @provider.stub!(:release_path).and_return(@expected_release_dir)
+ @provider.stub(:release_slug)
+ @provider.stub(:release_path).and_return(@expected_release_dir)
end
it "loads scm resource" do
@@ -43,11 +43,25 @@ 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
FileUtils.should_receive(:mkdir_p).with(@resource.shared_path).ordered
- ::File.stub!(:directory?).and_return(false)
+ ::File.stub(:directory?).and_return(false)
@provider.stub(:symlink)
@provider.stub(:migrate)
@provider.stub(:copy_cached_repo)
@@ -55,6 +69,7 @@ describe Chef::Provider::Deploy do
it "creates deploy_to dir" do
::Dir.should_receive(:chdir).with(@expected_release_dir).exactly(4).times
+ @provider.should_receive(:enforce_ownership).twice
@provider.stub(:update_cached_repo)
@provider.deploy
end
@@ -62,10 +77,11 @@ describe Chef::Provider::Deploy do
end
it "does not create deploy_to dir if it exists" do
- ::File.stub!(:directory?).and_return(true)
+ ::File.stub(:directory?).and_return(true)
::Dir.should_receive(:chdir).with(@expected_release_dir).exactly(4).times
FileUtils.should_not_receive(:mkdir_p).with(@resource.deploy_to)
FileUtils.should_not_receive(:mkdir_p).with(@resource.shared_path)
+ @provider.should_receive(:enforce_ownership).twice
@provider.stub(:copy_cached_repo)
@provider.stub(:update_cached_repo)
@provider.stub(:symlink)
@@ -80,6 +96,7 @@ describe Chef::Provider::Deploy do
@provider.stub(:copy_cached_repo)
@provider.stub(:update_cached_repo)
@provider.stub(:install_gems)
+ @provider.should_receive(:enforce_ownership).ordered
@provider.stub(:enforce_ownership)
@provider.stub(:symlink)
@provider.stub(:migrate)
@@ -105,22 +122,22 @@ describe Chef::Provider::Deploy do
end
it "should not deploy if there is already a deploy at release_path, and it is the current release" do
- @provider.stub!(:all_releases).and_return([@expected_release_dir])
- @provider.stub!(:current_release?).with(@expected_release_dir).and_return(true)
+ @provider.stub(:all_releases).and_return([@expected_release_dir])
+ @provider.stub(:current_release?).with(@expected_release_dir).and_return(true)
@provider.should_not_receive(:deploy)
@provider.run_action(:deploy)
end
it "should call action_rollback if there is already a deploy of this revision at release_path, and it is not the current release" do
- @provider.stub!(:all_releases).and_return([@expected_release_dir, "102021"])
- @provider.stub!(:current_release?).with(@expected_release_dir).and_return(false)
+ @provider.stub(:all_releases).and_return([@expected_release_dir, "102021"])
+ @provider.stub(:current_release?).with(@expected_release_dir).and_return(false)
@provider.should_receive(:rollback_to).with(@expected_release_dir)
@provider.should_receive(:current_release?)
@provider.run_action(:deploy)
end
it "calls deploy when deploying a new release" do
- @provider.stub!(:all_releases).and_return([])
+ @provider.stub(:all_releases).and_return([])
@provider.should_receive(:deploy)
@provider.run_action(:deploy)
end
@@ -132,44 +149,44 @@ describe Chef::Provider::Deploy do
end
it "Removes the old release before deploying when force deploying over it" do
- @provider.stub!(:all_releases).and_return([@expected_release_dir])
+ @provider.stub(:all_releases).and_return([@expected_release_dir])
FileUtils.should_receive(:rm_rf).with(@expected_release_dir)
@provider.should_receive(:deploy)
@provider.run_action(:force_deploy)
end
it "deploys as normal when force deploying and there's no prior release at the same path" do
- @provider.stub!(:all_releases).and_return([])
+ @provider.stub(:all_releases).and_return([])
@provider.should_receive(:deploy)
@provider.run_action(:force_deploy)
end
it "dont care by default if error happens on deploy" do
- @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.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_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.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
describe "on systems without broken Dir.glob results" do
it "sets the release path to the penultimate release when one is not specified, symlinks, and rm's the last release on rollback" do
- @provider.stub!(:release_path).and_return("/my/deploy/dir/releases/3")
+ @provider.stub(:release_path).and_return("/my/deploy/dir/releases/3")
all_releases = ["/my/deploy/dir/releases/1", "/my/deploy/dir/releases/2", "/my/deploy/dir/releases/3", "/my/deploy/dir/releases/4", "/my/deploy/dir/releases/5"]
- Dir.stub!(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
+ Dir.stub(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
@provider.should_receive(:symlink)
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/releases/4")
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/releases/5")
@@ -178,10 +195,10 @@ describe Chef::Provider::Deploy do
end
it "sets the release path to the specified release, symlinks, and rm's any newer releases on rollback" do
- @provider.unstub!(:release_path)
+ @provider.unstub(:release_path)
all_releases = ["/my/deploy/dir/releases/20040815162342", "/my/deploy/dir/releases/20040700000000",
"/my/deploy/dir/releases/20040600000000", "/my/deploy/dir/releases/20040500000000"].sort!
- Dir.stub!(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
+ Dir.stub(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
@provider.should_receive(:symlink)
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342")
@provider.run_action(:rollback)
@@ -189,12 +206,12 @@ describe Chef::Provider::Deploy do
end
it "sets the release path to the penultimate release, symlinks, and rm's the last release on rollback" do
- @provider.unstub!(:release_path)
+ @provider.unstub(:release_path)
all_releases = [ "/my/deploy/dir/releases/20040815162342",
"/my/deploy/dir/releases/20040700000000",
"/my/deploy/dir/releases/20040600000000",
"/my/deploy/dir/releases/20040500000000"]
- Dir.stub!(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
+ Dir.stub(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
@provider.should_receive(:symlink)
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342")
@provider.run_action(:rollback)
@@ -204,22 +221,22 @@ describe Chef::Provider::Deploy do
describe "if there are no releases to fallback to" do
it "an exception is raised when there is only 1 release" do
- #@provider.unstub!(:release_path) -- unstub the release path on top to feed our own release path
+ #@provider.unstub(:release_path) -- unstub the release path on top to feed our own release path
all_releases = [ "/my/deploy/dir/releases/20040815162342"]
- Dir.stub!(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
+ Dir.stub(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
#@provider.should_receive(:symlink)
#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 {
+ Dir.stub(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
+ lambda {
@provider.run_action(:rollback)
}.should raise_exception(RuntimeError, "There is no release to rollback to!")
end
@@ -228,12 +245,12 @@ describe Chef::Provider::Deploy do
describe "CHEF-628: on systems with broken Dir.glob results" do
it "sets the release path to the penultimate release, symlinks, and rm's the last release on rollback" do
- @provider.unstub!(:release_path)
+ @provider.unstub(:release_path)
all_releases = [ "/my/deploy/dir/releases/20040500000000",
"/my/deploy/dir/releases/20040600000000",
"/my/deploy/dir/releases/20040700000000",
"/my/deploy/dir/releases/20040815162342" ]
- Dir.stub!(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
+ Dir.stub(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
@provider.should_receive(:symlink)
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342")
@provider.run_action(:rollback)
@@ -243,13 +260,13 @@ describe Chef::Provider::Deploy do
it "raises a runtime error when there's no release to rollback to" do
all_releases = []
- Dir.stub!(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
+ Dir.stub(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases)
lambda {@provider.run_action(:rollback)}.should raise_error(RuntimeError)
end
it "runs the new resource collection in the runner during a callback" do
- @runner = mock("Runner")
- Chef::Runner.stub!(:new).and_return(@runner)
+ @runner = double("Runner")
+ Chef::Runner.stub(:new).and_return(@runner)
@runner.should_receive(:converge)
callback_code = Proc.new { :noop }
@provider.callback(:whatevs, callback_code)
@@ -325,8 +342,8 @@ describe Chef::Provider::Deploy do
end
it "calls the internal callback :release_created when cleaning up the releases" do
- FileUtils.stub!(:mkdir_p)
- FileUtils.stub!(:cp_r)
+ FileUtils.stub(:mkdir_p)
+ FileUtils.stub(:cp_r)
@provider.should_receive(:release_created)
@provider.cleanup!
end
@@ -354,8 +371,8 @@ describe Chef::Provider::Deploy do
FileUtils.should_receive(:ln_sf).with("/my/deploy/dir/shared/config/database.yml", @expected_release_dir + "/config/database.yml")
@provider.should_receive(:enforce_ownership)
- STDOUT.stub!(:tty?).and_return(true)
- Chef::Log.stub!(:info?).and_return(true)
+ STDOUT.stub(:tty?).and_return(true)
+ Chef::Log.stub(:info?).and_return(true)
@provider.should_receive(:run_command).with(:command => "migration_foo", :cwd => @expected_release_dir,
:user => "deployNinja", :group => "deployNinjas",
:log_level => :info, :live_stream => STDOUT,
@@ -419,7 +436,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
@@ -445,7 +462,7 @@ describe Chef::Provider::Deploy do
"/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000",
"/my/deploy/dir/20040400000000", "/my/deploy/dir/20040300000000",
"/my/deploy/dir/20040200000000", "/my/deploy/dir/20040100000000"].sort!
- @provider.stub!(:all_releases).and_return(all_releases)
+ @provider.stub(:all_releases).and_return(all_releases)
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/20040100000000")
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/20040200000000")
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/20040300000000")
@@ -458,7 +475,7 @@ describe Chef::Provider::Deploy do
"/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000",
"/my/deploy/dir/20040400000000", "/my/deploy/dir/20040300000000",
"/my/deploy/dir/20040200000000", "/my/deploy/dir/20040100000000"].sort!
- @provider.stub!(:all_releases).and_return(all_releases)
+ @provider.stub(:all_releases).and_return(all_releases)
FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/20040100000000")
@provider.cleanup!
end
@@ -467,8 +484,8 @@ describe Chef::Provider::Deploy do
all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000",
"/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000",
"/my/deploy/dir/20040400000000", "/my/deploy/dir/20040300000000"].sort!
- @provider.stub!(:all_releases).and_return(all_releases)
- FileUtils.stub!(:rm_rf)
+ @provider.stub(:all_releases).and_return(all_releases)
+ FileUtils.stub(:rm_rf)
@provider.should_receive(:release_deleted).with("/my/deploy/dir/20040300000000")
@provider.cleanup!
end
@@ -485,9 +502,9 @@ describe Chef::Provider::Deploy do
end
it "shouldn't give a no method error on migrate if the environment is nil" do
- @provider.stub!(:enforce_ownership)
- @provider.stub!(:run_symlinks_before_migrate)
- @provider.stub!(:run_command)
+ @provider.stub(:enforce_ownership)
+ @provider.stub(:run_symlinks_before_migrate)
+ @provider.stub(:run_command)
@provider.migrate
end
@@ -526,7 +543,7 @@ describe Chef::Provider::Deploy do
end
it "defines run as a forwarder to execute, setting the user, group, cwd and environment to new_resource.user" do
- mock_execution = mock("Resource::Execute")
+ mock_execution = double("Resource::Execute")
@provider.should_receive(:execute).with("iGoToHell4this").and_return(mock_execution)
@resource.user("notCoolMan")
@resource.group("Ggroup")
@@ -555,7 +572,7 @@ describe Chef::Provider::Deploy do
end
it "defines run as a forwarder to execute, setting cwd and environment but not override" do
- mock_execution = mock("Resource::Execute")
+ mock_execution = double("Resource::Execute")
@provider.should_receive(:execute).with("iGoToHell4this").and_return(mock_execution)
@resource.user("notCoolMan")
mock_execution.should_receive(:user).with("notCoolMan")
@@ -566,8 +583,8 @@ describe Chef::Provider::Deploy do
it "converts sudo and run to exec resources in hooks" do
- runner = mock("tehRunner")
- Chef::Runner.stub!(:new).and_return(runner)
+ runner = double("tehRunner")
+ Chef::Runner.stub(:new).and_return(runner)
snitch = nil
@resource.user("tehCat")
@@ -590,7 +607,7 @@ describe Chef::Provider::Deploy do
describe "installing gems from a gems.yml" do
before do
- ::File.stub!(:exist?).with("#{@expected_release_dir}/gems.yml").and_return(true)
+ ::File.stub(:exist?).with("#{@expected_release_dir}/gems.yml").and_return(true)
@gem_list = [{:name=>"eventmachine", :version=>"0.12.9"}]
end
@@ -606,8 +623,8 @@ describe Chef::Provider::Deploy do
end
it "takes a list of gem providers converges them" do
- IO.stub!(:read)
- YAML.stub!(:load).and_return(@gem_list)
+ IO.stub(:read)
+ YAML.stub(:load).and_return(@gem_list)
expected_gem_resources = @provider.send(:gem_packages).map { |r| [r.name, r.version] }
gem_runner = @provider.send(:gem_resource_collection_runner)
# no one has heard of defining == to be meaningful so I have use this monstrosity
diff --git a/spec/unit/provider/directory_spec.rb b/spec/unit/provider/directory_spec.rb
index 61946d2664..25ca9e0175 100644
--- a/spec/unit/provider/directory_spec.rb
+++ b/spec/unit/provider/directory_spec.rb
@@ -48,18 +48,18 @@ describe Chef::Provider::Directory do
describe "scanning file security metadata on unix" do
before do
- Chef::Platform.stub!(:windows?).and_return(false)
+ Chef::Platform.stub(:windows?).and_return(false)
end
let(:mock_stat) do
- cstats = mock("stats")
- cstats.stub!(:uid).and_return(500)
- cstats.stub!(:gid).and_return(500)
- cstats.stub!(:mode).and_return(0755)
+ cstats = double("stats")
+ cstats.stub(:uid).and_return(500)
+ cstats.stub(:gid).and_return(500)
+ cstats.stub(:mode).and_return(0755)
cstats
end
it "describes the access mode as a String of octal integers" do
- File.stub!(:exists?).and_return(true)
+ File.stub(:exists?).and_return(true)
File.should_receive(:stat).and_return(mock_stat)
@directory.load_current_resource
@directory.current_resource.mode.should == "0755"
@@ -67,7 +67,7 @@ describe Chef::Provider::Directory do
context "when user and group are specified with UID/GID" do
it "describes the current owner and group as UID and GID" do
- File.stub!(:exists?).and_return(true)
+ File.stub(:exists?).and_return(true)
File.should_receive(:stat).and_return(mock_stat)
@directory.load_current_resource
@directory.current_resource.path.should eql(@new_resource.path)
@@ -91,7 +91,7 @@ describe Chef::Provider::Directory do
Dir.should_receive(:mkdir).with(@new_resource.path).once.and_return(true)
@directory.should_receive(:do_acl_changes)
- @directory.stub!(:do_selinux)
+ @directory.stub(:do_selinux)
@directory.run_action(:create)
@directory.new_resource.should be_updated
end
@@ -117,7 +117,7 @@ describe Chef::Provider::Directory do
FileUtils.should_receive(:mkdir_p).with(@new_resource.path).and_return(true)
@directory.should_receive(:do_acl_changes)
- @directory.stub!(:do_selinux)
+ @directory.stub(:do_selinux)
@directory.run_action(:create)
@new_resource.should be_updated
end
@@ -152,14 +152,14 @@ describe Chef::Provider::Directory do
end
it "should raise an exception if it cannot delete the directory due to bad permissions" do
- File.stub!(:exists?).and_return(true)
- File.stub!(:writable?).and_return(false)
+ File.stub(:exists?).and_return(true)
+ File.stub(:writable?).and_return(false)
lambda { @directory.run_action(:delete) }.should raise_error(RuntimeError)
end
it "should take no action when deleting a target directory that does not exist" do
@new_resource.path "/an/invalid/path"
- File.stub!(:exists?).and_return(false)
+ File.stub(:exists?).and_return(false)
Dir.should_not_receive(:delete).with(@new_resource.path)
@directory.run_action(:delete)
@directory.new_resource.should_not be_updated
@@ -168,7 +168,7 @@ describe Chef::Provider::Directory do
it "should raise an exception when deleting a directory when target directory is a file" do
stub_file_cstats
@new_resource.path "/an/invalid/path"
- File.stub!(:exists?).and_return(true)
+ File.stub(:exists?).and_return(true)
File.should_receive(:directory?).and_return(false)
Dir.should_not_receive(:delete).with(@new_resource.path)
lambda { @directory.run_action(:delete) }.should raise_error(RuntimeError)
@@ -176,13 +176,13 @@ describe Chef::Provider::Directory do
end
def stub_file_cstats
- cstats = mock("stats")
- cstats.stub!(:uid).and_return(500)
- cstats.stub!(:gid).and_return(500)
- cstats.stub!(:mode).and_return(0755)
+ cstats = double("stats")
+ cstats.stub(:uid).and_return(500)
+ cstats.stub(:gid).and_return(500)
+ cstats.stub(:mode).and_return(0755)
# File.stat is called in:
# - Chef::Provider::File.load_current_resource_attrs
# - Chef::ScanAccessControl via Chef::Provider::File.setup_acl
- File.stub!(:stat).and_return(cstats)
+ File.stub(:stat).and_return(cstats)
end
end
diff --git a/spec/unit/provider/env_spec.rb b/spec/unit/provider/env_spec.rb
index 673ba9798a..0bc5117e48 100644
--- a/spec/unit/provider/env_spec.rb
+++ b/spec/unit/provider/env_spec.rb
@@ -36,10 +36,10 @@ describe Chef::Provider::Env do
describe "when loading the current status" do
before do
#@current_resource = @new_resource.clone
- #Chef::Resource::Env.stub!(:new).and_return(@current_resource)
+ #Chef::Resource::Env.stub(:new).and_return(@current_resource)
@provider.current_resource = @current_resource
- @provider.stub!(:env_value).with("FOO").and_return("bar")
- @provider.stub!(:env_key_exists).and_return(true)
+ @provider.stub(:env_value).with("FOO").and_return("bar")
+ @provider.stub(:env_key_exists).and_return(true)
end
it "should create a current resource with the same name as the new resource" do
@@ -72,8 +72,8 @@ describe Chef::Provider::Env do
describe "action_create" do
before do
@provider.key_exists = false
- @provider.stub!(:create_env).and_return(true)
- @provider.stub!(:modify_env).and_return(true)
+ @provider.stub(:create_env).and_return(true)
+ @provider.stub(:modify_env).and_return(true)
end
it "should call create_env if the key does not exist" do
@@ -94,15 +94,15 @@ describe Chef::Provider::Env do
it "should call modify_env if the key exists and values are not equal" do
@provider.key_exists = true
- @provider.stub!(:compare_value).and_return(true)
+ @provider.stub(:compare_value).and_return(true)
@provider.should_receive(:modify_env).and_return(true)
@provider.action_create
end
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)
+ @provider.stub(:compare_value).and_return(true)
+ @provider.stub(:modify_env).and_return(true)
@provider.action_create
@new_resource.should be_updated
end
@@ -112,8 +112,8 @@ describe Chef::Provider::Env do
before(:each) do
@provider.current_resource = @current_resource
@provider.key_exists = false
- @provider.stub!(:delete_element).and_return(false)
- @provider.stub!(:delete_env).and_return(true)
+ @provider.stub(:delete_element).and_return(false)
+ @provider.stub(:delete_env).and_return(true)
end
it "should not call delete_env if the key does not exist" do
@@ -143,7 +143,7 @@ describe Chef::Provider::Env do
before(:each) do
@provider.current_resource = @current_resource
@provider.key_exists = true
- @provider.stub!(:modify_env).and_return(true)
+ @provider.stub(:modify_env).and_return(true)
end
it "should call modify_group if the key exists and values are not equal" do
@@ -153,8 +153,8 @@ describe Chef::Provider::Env do
end
it "should set the new resources updated flag to true if modify_env is called" do
- @provider.stub!(:compare_value).and_return(true)
- @provider.stub!(:modify_env).and_return(true)
+ @provider.stub(:compare_value).and_return(true)
+ @provider.stub(:modify_env).and_return(true)
@provider.action_modify
@new_resource.should be_updated
end
@@ -183,12 +183,12 @@ describe Chef::Provider::Env do
end
it "should return true if the element is not found" do
- @new_resource.stub!(:value).and_return("C:/baz/bin")
+ @new_resource.stub(:value).and_return("C:/baz/bin")
@provider.delete_element.should eql(true)
end
it "should return false if the delim not defined" do
- @new_resource.stub!(:delim).and_return(nil)
+ @new_resource.stub(:delim).and_return(nil)
@provider.delete_element.should eql(false)
end
diff --git a/spec/unit/provider/erl_call_spec.rb b/spec/unit/provider/erl_call_spec.rb
index fa85b6cda7..19e16f282f 100644
--- a/spec/unit/provider/erl_call_spec.rb
+++ b/spec/unit/provider/erl_call_spec.rb
@@ -31,7 +31,7 @@ describe Chef::Provider::ErlCall do
@provider = Chef::Provider::ErlCall.new(@new_resource, @run_context)
- @provider.stub!(:popen4).and_return(@status)
+ @provider.stub(:popen4).and_return(@status)
@stdin = StringIO.new
@stdout = StringIO.new('{ok, woohoo}')
@stderr = StringIO.new
diff --git a/spec/unit/provider/execute_spec.rb b/spec/unit/provider/execute_spec.rb
index bf913cca12..78216a89fa 100644
--- a/spec/unit/provider/execute_spec.rb
+++ b/spec/unit/provider/execute_spec.rb
@@ -31,14 +31,14 @@ 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)
+ STDOUT.stub(:tty?).and_return(true)
end
it "should execute foo_resource" do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
opts = {}
opts[:timeout] = @new_resource.timeout
opts[:returns] = @new_resource.returns
@@ -53,7 +53,7 @@ describe Chef::Provider::Execute do
end
it "should do nothing if the sentinel file exists" do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
File.should_receive(:exists?).with(@new_resource.creates).and_return(true)
@provider.should_not_receive(:shell_out!)
Chef::Log.should_not_receive(:warn)
@@ -65,7 +65,7 @@ describe Chef::Provider::Execute do
it "should respect cwd options for 'creates'" do
@new_resource.cwd "/tmp"
@new_resource.creates "foo_resource"
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
File.should_receive(:exists?).with(@new_resource.creates).and_return(false)
File.should_receive(:exists?).with(File.join("/tmp", @new_resource.creates)).and_return(true)
Chef::Log.should_not_receive(:warn)
@@ -73,11 +73,11 @@ 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"
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
Chef::Log.should_receive(:warn).with(/relative path/)
File.should_receive(:exists?).with(@new_resource.creates).and_return(true)
@provider.should_not_receive(:shell_out!)
diff --git a/spec/unit/provider/file/content_spec.rb b/spec/unit/provider/file/content_spec.rb
index 693877760e..34d98b6619 100644
--- a/spec/unit/provider/file/content_spec.rb
+++ b/spec/unit/provider/file/content_spec.rb
@@ -20,20 +20,12 @@ 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
#
let(:current_resource) do
- mock("Chef::Provider::File::Resource (current)")
+ double("Chef::Provider::File::Resource (current)")
end
let(:enclosing_directory) {
@@ -44,11 +36,11 @@ describe Chef::Provider::File::Content do
}
let(:new_resource) do
- mock("Chef::Provider::File::Resource (new)", :name => "seattle.txt", :path => resource_path)
+ double("Chef::Provider::File::Resource (new)", :name => "seattle.txt", :path => resource_path)
end
let(:run_context) do
- mock("Chef::RunContext")
+ double("Chef::RunContext")
end
#
@@ -61,7 +53,7 @@ describe Chef::Provider::File::Content do
describe "when the resource has a content attribute set" do
before do
- new_resource.stub!(:content).and_return("Do do do do, do do do do, do do do do, do do do do")
+ new_resource.stub(:content).and_return("Do do do do, do do do do, do do do do, do do do do")
end
it "returns a tempfile" do
@@ -89,7 +81,7 @@ describe Chef::Provider::File::Content do
describe "when the resource does not have a content attribute set" do
before do
- new_resource.stub!(:content).and_return(nil)
+ new_resource.stub(:content).and_return(nil)
end
it "should return nil instead of a tempfile" do
diff --git a/spec/unit/provider/file_spec.rb b/spec/unit/provider/file_spec.rb
index 291f510067..059f1722fb 100644
--- a/spec/unit/provider/file_spec.rb
+++ b/spec/unit/provider/file_spec.rb
@@ -29,7 +29,7 @@ describe Chef::Provider::File do
end
let(:content) do
- content = mock('Chef::Provider::File::Content')
+ content = double('Chef::Provider::File::Content')
end
let(:node) { double('Chef::Node') }
@@ -46,10 +46,12 @@ describe Chef::Provider::File do
let(:provider) do
provider = described_class.new(resource, run_context)
- provider.stub!(:content).and_return(content)
+ provider.stub(:content).and_return(content)
provider
end
it_behaves_like Chef::Provider::File
+
+ it_behaves_like "a file provider with content field"
end
diff --git a/spec/unit/provider/git_spec.rb b/spec/unit/provider/git_spec.rb
index 763de240cc..b18a2a8996 100644
--- a/spec/unit/provider/git_spec.rb
+++ b/spec/unit/provider/git_spec.rb
@@ -21,7 +21,7 @@ require 'spec_helper'
describe Chef::Provider::Git do
before(:each) do
- STDOUT.stub!(:tty?).and_return(true)
+ STDOUT.stub(:tty?).and_return(true)
Chef::Log.level = :info
@current_resource = Chef::Resource::Git.new("web2.0 app")
@@ -41,9 +41,9 @@ describe Chef::Provider::Git do
context "determining the revision of the currently deployed checkout" do
before do
- @stdout = mock("standard out")
- @stderr = mock("standard error")
- @exitstatus = mock("exitstatus")
+ @stdout = double("standard out")
+ @stderr = double("standard error")
+ @exitstatus = double("exitstatus")
end
it "sets the current revision to nil if the deploy dir does not exist" do
@@ -54,7 +54,7 @@ describe Chef::Provider::Git do
it "determines the current revision when there is one" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(true)
@stdout = "9b4d8dc38dd471246e7cfb1c3c1ad14b0f2bee13\n"
- @provider.should_receive(:shell_out!).with('git rev-parse HEAD', {:cwd => '/my/deploy/dir', :returns => [0,128]}).and_return(mock("ShellOut result", :stdout => @stdout))
+ @provider.should_receive(:shell_out!).with('git rev-parse HEAD', {:cwd => '/my/deploy/dir', :returns => [0,128]}).and_return(double("ShellOut result", :stdout => @stdout))
@provider.find_current_revision.should eql("9b4d8dc38dd471246e7cfb1c3c1ad14b0f2bee13")
end
@@ -62,13 +62,13 @@ describe Chef::Provider::Git do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(true)
@stderr = "fatal: Not a git repository (or any of the parent directories): .git"
@stdout = ""
- @provider.should_receive(:shell_out!).with('git rev-parse HEAD', :cwd => '/my/deploy/dir', :returns => [0,128]).and_return(mock("ShellOut result", :stdout => "", :stderr => @stderr))
+ @provider.should_receive(:shell_out!).with('git rev-parse HEAD', :cwd => '/my/deploy/dir', :returns => [0,128]).and_return(double("ShellOut result", :stdout => "", :stderr => @stderr))
@provider.find_current_revision.should be_nil
end
end
it "creates a current_resource with the currently deployed revision when a clone exists in the destination dir" do
- @provider.stub!(:find_current_revision).and_return("681c9802d1c62a45b490786c18f0b8216b309440")
+ @provider.stub(:find_current_revision).and_return("681c9802d1c62a45b490786c18f0b8216b309440")
@provider.load_current_resource
@provider.current_resource.name.should eql(@resource.name)
@provider.current_resource.revision.should eql("681c9802d1c62a45b490786c18f0b8216b309440")
@@ -93,7 +93,7 @@ describe Chef::Provider::Git do
@resource.revision "v1.0"
@stdout = ("d03c22a5e41f5ae3193460cca044ed1435029f53\trefs/heads/0.8-alpha\n" +
"503c22a5e41f5ae3193460cca044ed1435029f53\trefs/heads/v1.0\n")
- @provider.should_receive(:shell_out!).with(@git_ls_remote + "v1.0*", {:log_tag=>"git[web2.0 app]"}).and_return(mock("ShellOut result", :stdout => @stdout))
+ @provider.should_receive(:shell_out!).with(@git_ls_remote + "v1.0*", {:log_tag=>"git[web2.0 app]"}).and_return(double("ShellOut result", :stdout => @stdout))
@provider.target_revision.should eql("503c22a5e41f5ae3193460cca044ed1435029f53")
end
@@ -102,7 +102,7 @@ describe Chef::Provider::Git do
@stdout = ("d03c22a5e41f5ae3193460cca044ed1435029f53\trefs/heads/0.8-alpha\n" +
"503c22a5e41f5ae3193460cca044ed1435029f53\trefs/heads/v1.0\n" +
"663c22a5e41f5ae3193460cca044ed1435029f53\trefs/heads/v1.0^{}\n")
- @provider.should_receive(:shell_out!).with(@git_ls_remote + "v1.0*", {:log_tag=>"git[web2.0 app]"}).and_return(mock("ShellOut result", :stdout => @stdout))
+ @provider.should_receive(:shell_out!).with(@git_ls_remote + "v1.0*", {:log_tag=>"git[web2.0 app]"}).and_return(double("ShellOut result", :stdout => @stdout))
@provider.target_revision.should eql("663c22a5e41f5ae3193460cca044ed1435029f53")
end
@@ -110,32 +110,32 @@ describe Chef::Provider::Git do
@resource.revision "origin/"
@provider.action = :checkout
@provider.define_resource_requirements
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
lambda {@provider.process_resource_requirements}.should raise_error(Chef::Exceptions::InvalidRemoteGitReference)
end
it "raises an unresolvable git reference error if the revision can't be resolved to any revision and assertions are run" do
@resource.revision "FAIL, that's the revision I want"
@provider.action = :checkout
- @provider.should_receive(:shell_out!).and_return(mock("ShellOut result", :stdout => "\n"))
+ @provider.should_receive(:shell_out!).and_return(double("ShellOut result", :stdout => "\n"))
@provider.define_resource_requirements
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::UnresolvableGitReference)
end
it "does not raise an error if the revision can't be resolved when assertions are not run" do
@resource.revision "FAIL, that's the revision I want"
- @provider.should_receive(:shell_out!).and_return(mock("ShellOut result", :stdout => "\n"))
+ @provider.should_receive(:shell_out!).and_return(double("ShellOut result", :stdout => "\n"))
@provider.target_revision.should == nil
end
it "does not raise an error when the revision is valid and assertions are run." do
@resource.revision "0.8-alpha"
@stdout = "503c22a5e41f5ae3193460cca044ed1435029f53\trefs/heads/0.8-alpha\n"
- @provider.should_receive(:shell_out!).with(@git_ls_remote + "0.8-alpha*", {:log_tag=>"git[web2.0 app]"}).and_return(mock("ShellOut result", :stdout => @stdout))
+ @provider.should_receive(:shell_out!).with(@git_ls_remote + "0.8-alpha*", {:log_tag=>"git[web2.0 app]"}).and_return(double("ShellOut result", :stdout => @stdout))
@provider.action = :checkout
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
@provider.define_resource_requirements
- lambda { @provider.process_resource_requirements }.should_not raise_error(RuntimeError)
+ lambda { @provider.process_resource_requirements }.should_not raise_error
end
it "gives the latest HEAD revision SHA if nothing is specified" do
@@ -156,7 +156,7 @@ b7d19519a1c15f1c1a324e2683bd728b6198ce5a\trefs/tags/0.7.8^{}
ebc1b392fe7e8f0fbabc305c299b4d365d2b4d9b\trefs/tags/chef-server-package
SHAS
@resource.revision ''
- @provider.should_receive(:shell_out!).with(@git_ls_remote + "HEAD", {:log_tag=>"git[web2.0 app]"}).and_return(mock("ShellOut result", :stdout => @stdout))
+ @provider.should_receive(:shell_out!).with(@git_ls_remote + "HEAD", {:log_tag=>"git[web2.0 app]"}).and_return(double("ShellOut result", :stdout => @stdout))
@provider.target_revision.should eql("28af684d8460ba4793eda3e7ac238c864a5d029a")
end
end
@@ -165,24 +165,47 @@ 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, "HOME" => "/home/deployNinja" },
+ :log_tag => "git[web2.0 app]"
+ }
+ end
+ before do
+ @resource.user deploy_user
+ @resource.ssh_wrapper wrapper
+ Etc.stub(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/deployNinja"))
+ 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
@resource.user "deployNinja"
+ Etc.stub(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/deployNinja"))
@resource.destination "/Application Support/with/space"
@resource.ssh_wrapper "do_it_this_way.sh"
expected_cmd = "git clone \"git://github.com/opscode/chef.git\" \"/Application Support/with/space\""
@provider.should_receive(:shell_out!).with(expected_cmd, :user => "deployNinja",
- :environment =>{"GIT_SSH"=>"do_it_this_way.sh"},
+ :environment =>{"GIT_SSH"=>"do_it_this_way.sh",
+ "HOME" => "/home/deployNinja"},
:log_tag => "git[web2.0 app]")
@provider.clone
end
@@ -232,11 +255,14 @@ SHAS
it "runs a sync command with the user and group specified in the resource" do
@resource.user("whois")
+ Etc.stub(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/whois"))
@resource.group("thisis")
@provider.should_receive(:setup_remote_tracking_branches).with(@resource.remote, @resource.repository)
expected_cmd = "git fetch origin && git fetch origin --tags && git reset --hard d35af14d41ae22b19da05d7d03a0bafc321b244c"
@provider.should_receive(:shell_out!).with(expected_cmd, :cwd => "/my/deploy/dir",
- :user => "whois", :group => "thisis", :log_tag => "git[web2.0 app]")
+ :user => "whois", :group => "thisis",
+ :log_tag => "git[web2.0 app]",
+ :environment=>{"HOME"=>"/home/whois"})
@provider.fetch_updates
end
@@ -276,6 +302,7 @@ SHAS
it "runs the config with the user and group specified in the resource" do
@resource.user("whois")
@resource.group("thisis")
+ Etc.stub(:getpwnam).and_return(double("Struct::Passwd", :name => @resource.user, :dir => "/home/whois"))
command_response = double('shell_out')
command_response.stub(:exitstatus) { 1 }
expected_command = "git config --get remote.#{@resource.remote}.url"
@@ -284,13 +311,15 @@ SHAS
:log_tag => "git[web2.0 app]",
:user => "whois",
:group => "thisis",
+ :environment=>{"HOME"=>"/home/whois"},
:returns => [0,1,2]).and_return(command_response)
add_remote_command = "git remote add #{@resource.remote} #{@resource.repository}"
@provider.should_receive(:shell_out!).with(add_remote_command,
:cwd => "/my/deploy/dir",
:log_tag => "git[web2.0 app]",
:user => "whois",
- :group => "thisis")
+ :group => "thisis",
+ :environment=>{"HOME"=>"/home/whois"})
@provider.setup_remote_tracking_branches(@resource.remote, @resource.repository)
end
@@ -362,17 +391,17 @@ SHAS
end
it "raises an error if the git clone command would fail because the enclosing directory doesn't exist" do
- @provider.stub!(:shell_out!)
+ @provider.stub(:shell_out!)
lambda {@provider.run_action(:sync)}.should raise_error(Chef::Exceptions::MissingParentDirectory)
end
it "does a checkout by cloning the repo and then enabling submodules" do
# will be invoked in load_current_resource
- ::File.stub!(:exist?).with("/my/deploy/dir/.git").and_return(false)
+ ::File.stub(:exist?).with("/my/deploy/dir/.git").and_return(false)
- ::File.stub!(:exist?).with("/my/deploy/dir").and_return(true)
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
- ::Dir.stub!(:entries).with("/my/deploy/dir").and_return(['.','..'])
+ ::File.stub(:exist?).with("/my/deploy/dir").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
+ ::Dir.stub(:entries).with("/my/deploy/dir").and_return(['.','..'])
@provider.should_receive(:clone)
@provider.should_receive(:checkout)
@provider.should_receive(:enable_submodules)
@@ -382,13 +411,28 @@ SHAS
# @resource.should be_updated
end
+ it "does not call checkout if enable_checkout is false" do
+ # will be invoked in load_current_resource
+ ::File.stub(:exist?).with("/my/deploy/dir/.git").and_return(false)
+
+ ::File.stub(:exist?).with("/my/deploy/dir").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
+ ::Dir.stub(:entries).with("/my/deploy/dir").and_return(['.','..'])
+
+ @resource.enable_checkout false
+ @provider.should_receive(:clone)
+ @provider.should_not_receive(:checkout)
+ @provider.should_receive(:enable_submodules)
+ @provider.run_action(:checkout)
+ end
+
# REGRESSION TEST: on some OSes, the entries from an empty directory will be listed as
# ['..', '.'] but this shouldn't change the behavior
it "does a checkout by cloning the repo and then enabling submodules when the directory entries are listed as %w{.. .}" do
- ::File.stub!(:exist?).with("/my/deploy/dir/.git").and_return(false)
- ::File.stub!(:exist?).with("/my/deploy/dir").and_return(false)
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
- ::Dir.stub!(:entries).with("/my/deploy/dir").and_return(['..','.'])
+ ::File.stub(:exist?).with("/my/deploy/dir/.git").and_return(false)
+ ::File.stub(:exist?).with("/my/deploy/dir").and_return(false)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
+ ::Dir.stub(:entries).with("/my/deploy/dir").and_return(['..','.'])
@provider.should_receive(:clone)
@provider.should_receive(:checkout)
@provider.should_receive(:enable_submodules)
@@ -399,11 +443,11 @@ SHAS
it "should not checkout if the destination exists or is a non empty directory" do
# will be invoked in load_current_resource
- ::File.stub!(:exist?).with("/my/deploy/dir/.git").and_return(false)
+ ::File.stub(:exist?).with("/my/deploy/dir/.git").and_return(false)
- ::File.stub!(:exist?).with("/my/deploy/dir").and_return(true)
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
- ::Dir.stub!(:entries).with("/my/deploy/dir").and_return(['.','..','foo','bar'])
+ ::File.stub(:exist?).with("/my/deploy/dir").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
+ ::Dir.stub(:entries).with("/my/deploy/dir").and_return(['.','..','foo','bar'])
@provider.should_not_receive(:clone)
@provider.should_not_receive(:checkout)
@provider.should_not_receive(:enable_submodules)
@@ -414,7 +458,7 @@ SHAS
it "syncs the code by updating the source when the repo has already been checked out" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(true)
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
@provider.should_receive(:find_current_revision).exactly(2).and_return('d35af14d41ae22b19da05d7d03a0bafc321b244c')
@provider.should_not_receive(:fetch_updates)
@provider.should_receive(:add_remotes)
@@ -424,10 +468,10 @@ SHAS
it "marks the resource as updated when the repo is updated and gets a new version" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(true)
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
# invoked twice - first time from load_current_resource
@provider.should_receive(:find_current_revision).exactly(2).and_return('d35af14d41ae22b19da05d7d03a0bafc321b244c')
- @provider.stub!(:target_revision).and_return('28af684d8460ba4793eda3e7ac238c864a5d029a')
+ @provider.stub(:target_revision).and_return('28af684d8460ba4793eda3e7ac238c864a5d029a')
@provider.should_receive(:fetch_updates)
@provider.should_receive(:enable_submodules)
@provider.should_receive(:add_remotes)
@@ -437,9 +481,9 @@ SHAS
it "does not fetch any updates if the remote revision matches the current revision" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").and_return(true)
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
- @provider.stub!(:find_current_revision).and_return('d35af14d41ae22b19da05d7d03a0bafc321b244c')
- @provider.stub!(:target_revision).and_return('d35af14d41ae22b19da05d7d03a0bafc321b244c')
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
+ @provider.stub(:find_current_revision).and_return('d35af14d41ae22b19da05d7d03a0bafc321b244c')
+ @provider.stub(:target_revision).and_return('d35af14d41ae22b19da05d7d03a0bafc321b244c')
@provider.should_not_receive(:fetch_updates)
@provider.should_receive(:add_remotes)
@provider.run_action(:sync)
@@ -447,7 +491,7 @@ SHAS
end
it "clones the repo instead of fetching it if the deploy directory doesn't exist" do
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
::File.should_receive(:exist?).with("/my/deploy/dir/.git").exactly(2).and_return(false)
@provider.should_receive(:action_checkout)
@provider.should_not_receive(:shell_out!)
@@ -457,9 +501,9 @@ SHAS
it "clones the repo instead of fetching updates if the deploy directory is empty" do
::File.should_receive(:exist?).with("/my/deploy/dir/.git").exactly(2).and_return(false)
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
- ::File.stub!(:directory?).with("/my/deploy/dir").and_return(true)
- @provider.stub!(:sync_command).and_return("huzzah!")
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy/dir").and_return(true)
+ @provider.stub(:sync_command).and_return("huzzah!")
@provider.should_receive(:action_checkout)
@provider.should_not_receive(:shell_out!).with("huzzah!", :cwd => "/my/deploy/dir")
@provider.run_action(:sync)
diff --git a/spec/unit/provider/group/dscl_spec.rb b/spec/unit/provider/group/dscl_spec.rb
index b526848dfd..5a02ee8dfb 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 = double("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)
+ @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")
@@ -50,9 +50,9 @@ describe Chef::Provider::Group::Dscl do
before do
@node = Chef::Node.new
@provider = Chef::Provider::Group::Dscl.new(@node, @new_resource)
- @provider.stub!(:dscl).and_return(["cmd", @status, "stdout", "stderr"])
+ @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")
@@ -60,8 +60,8 @@ describe Chef::Provider::Group::Dscl do
describe "with the dscl command returning a non zero exit status for a delete" do
before do
- @status = mock("Process::Status", :exitstatus => 1)
- @provider.stub!(:dscl).and_return(["cmd", @status, "stdout", "stderr"])
+ @status = double("Process::Status", :exitstatus => 1)
+ @provider.stub(:dscl).and_return(["cmd", @status, "stdout", "stderr"])
end
it "should return an empty string of standard output for a delete" do
@@ -77,14 +77,14 @@ describe Chef::Provider::Group::Dscl do
describe "with the dscl command returning no such key" do
before do
- @provider.stub!(:dscl).and_return(["cmd", @status, "No such key: ", "stderr"])
+ @provider.stub(:dscl).and_return(["cmd", @status, "No such key: ", "stderr"])
end
it "should raise an exception" 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")
@@ -98,9 +98,9 @@ describe Chef::Provider::Group::Dscl do
before do
@node = Chef::Node.new
@provider = Chef::Provider::Group::Dscl.new(@node, @new_resource)
- @provider.stub!(:safe_dscl).and_return("\naj 200\njt 201\n")
+ @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)
@@ -120,14 +120,14 @@ describe Chef::Provider::Group::Dscl do
before do
@node = Chef::Node.new
@provider = Chef::Provider::Group::Dscl.new(@node, @new_resource)
- @provider.stub!(:safe_dscl).and_return("\naj 500\n")
+ @provider.stub(:safe_dscl).and_return("\naj 500\n")
end
it "should run safe_dscl with list /Groups gid" 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
@@ -144,14 +144,14 @@ describe Chef::Provider::Group::Dscl do
describe "set_gid" do
describe "with the new resource and a gid number which is already in use" do
before do
- @provider.stub!(:gid_used?).and_return(true)
+ @provider.stub(:gid_used?).and_return(true)
end
it "should raise an exception if the new resources gid is already in use" 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)
@@ -162,7 +162,7 @@ describe Chef::Provider::Group::Dscl do
describe "with blank gid number for the new resources" do
before do
@new_resource.instance_variable_set(:@gid, nil)
- @new_resource.stub!(:safe_dscl)
+ @new_resource.stub(:safe_dscl)
end
it "should run get_free_gid and return a valid, unused gid number" do
@@ -185,9 +185,9 @@ describe Chef::Provider::Group::Dscl do
describe "with existing members in the current resource and append set to false in the new resource" do
before do
- @new_resource.stub!(:members).and_return([])
- @new_resource.stub!(:append).and_return(false)
- @current_resource.stub!(:members).and_return(["all", "your", "base"])
+ @new_resource.stub(:members).and_return([])
+ @new_resource.stub(:append).and_return(false)
+ @current_resource.stub(:members).and_return(["all", "your", "base"])
end
it "should log an appropriate message" do
@@ -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)
@@ -236,6 +236,7 @@ describe Chef::Provider::Group::Dscl do
describe "when loading the current system state" do
before (:each) do
+ @provider.action = :create
@provider.load_current_resource
@provider.define_resource_requirements
end
@@ -246,8 +247,8 @@ describe Chef::Provider::Group::Dscl do
end
it "doesn't raise an error if /usr/bin/dscl exists" do
- File.stub!(:exists?).and_return(true)
- lambda { @provider.process_resource_requirements }.should_not raise_error(Chef::Exceptions::Group)
+ File.stub(:exists?).and_return(true)
+ lambda { @provider.process_resource_requirements }.should_not raise_error
end
end
@@ -265,6 +266,7 @@ describe Chef::Provider::Group::Dscl do
it "should manage the group_name if it changed and the new resources group_name is not null" do
@current_resource.group_name("oldval")
@new_resource.group_name("newname")
+ @provider.should_receive(:set_members).and_return(true)
@provider.should_receive(:safe_dscl).with("create /Groups/newname")
@provider.should_receive(:safe_dscl).with("create /Groups/newname Password '*'")
@provider.manage_group
@@ -276,7 +278,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..5bd7fdc569 100644
--- a/spec/unit/provider/group/gpasswd_spec.rb
+++ b/spec/unit/provider/group/gpasswd_spec.rb
@@ -27,27 +27,28 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do
@new_resource.members %w{lobster rage fist}
@new_resource.append false
@provider = Chef::Provider::Group::Gpasswd.new(@new_resource, @run_context)
- #@provider.stub!(:run_command).and_return(true)
+ #@provider.stub(:run_command).and_return(true)
end
describe "when determining the current group state" do
before (:each) do
+ @provider.action = :create
@provider.load_current_resource
@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)
+ File.stub(:exists?).and_return(true)
File.should_receive(:exists?).with("/usr/bin/gpasswd").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)
+ File.stub(:exists?).and_return(true)
+ lambda { @provider.process_resource_requirements }.should_not raise_error
end
end
@@ -76,8 +77,7 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do
@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")
+ it "does not modify group membership" do
@provider.should_not_receive(:shell_out!)
@provider.modify_group_members
end
@@ -85,8 +85,8 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do
describe "when the resource specifies group members" do
it "should log an appropriate debug message" do
- Chef::Log.should_receive(:debug).with("group[wheel] setting group members to lobster, rage, fist")
- @provider.stub!(:shell_out!)
+ Chef::Log.should_receive(:debug).with("group[wheel] setting group members to: lobster, rage, fist")
+ @provider.stub(:shell_out!)
@provider.modify_group_members
end
@@ -95,12 +95,20 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do
@provider.modify_group_members
end
- it "should run gpasswd individually for each user when the append option is set" do
- @new_resource.append(true)
- @provider.should_receive(:shell_out!).with("gpasswd -a lobster wheel")
- @provider.should_receive(:shell_out!).with("gpasswd -a rage wheel")
- @provider.should_receive(:shell_out!).with("gpasswd -a fist wheel")
- @provider.modify_group_members
+ describe "when no user exists in the system" do
+ before do
+ current_resource = @new_resource.dup
+ current_resource.members([ ])
+ @provider.current_resource = current_resource
+ end
+
+ it "should run gpasswd individually for each user when the append option is set" do
+ @new_resource.append(true)
+ @provider.should_receive(:shell_out!).with("gpasswd -a lobster wheel")
+ @provider.should_receive(:shell_out!).with("gpasswd -a rage wheel")
+ @provider.should_receive(:shell_out!).with("gpasswd -a fist wheel")
+ @provider.modify_group_members
+ end
end
end
diff --git a/spec/unit/provider/group/groupadd_spec.rb b/spec/unit/provider/group/groupadd_spec.rb
index 5e07da59b4..793615d04c 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
@@ -46,7 +48,7 @@ describe Chef::Provider::Group::Groupadd, "set_options" do
@provider.set_options
end
it "should set the option for #{attribute} if the new resources #{attribute} is not null" do
- @new_resource.stub!(attribute).and_return("wowaweea")
+ @new_resource.stub(attribute).and_return("wowaweea")
@provider.set_options.should eql(" #{option} '#{@new_resource.send(attribute)}' #{@new_resource.group_name}")
end
end
@@ -54,7 +56,7 @@ describe Chef::Provider::Group::Groupadd, "set_options" do
it "should combine all the possible options" do
match_string = ""
field_list.sort{ |a,b| a[0] <=> b[0] }.each do |attribute, option|
- @new_resource.stub!(attribute).and_return("hola")
+ @new_resource.stub(attribute).and_return("hola")
match_string << " #{option} 'hola'"
end
match_string << " aj"
@@ -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
@@ -79,10 +93,10 @@ describe Chef::Provider::Group::Groupadd, "create_group" do
@node = Chef::Node.new
@new_resource = Chef::Resource::Group.new("aj")
@provider = Chef::Provider::Group::Groupadd.new(@node, @new_resource)
- @provider.stub!(:run_command).and_return(true)
- @provider.stub!(:set_options).and_return(" monkey")
- @provider.stub!(:groupadd_options).and_return("")
- @provider.stub!(:modify_group_members).and_return(true)
+ @provider.stub(:run_command).and_return(true)
+ @provider.stub(:set_options).and_return(" monkey")
+ @provider.stub(:groupadd_options).and_return("")
+ @provider.stub(:modify_group_members).and_return(true)
end
it "should run groupadd with the return of set_options" do
@@ -103,14 +117,14 @@ describe Chef::Provider::Group::Groupadd do
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Group.new("aj")
@provider = Chef::Provider::Group::Groupadd.new(@new_resource, @run_context)
- @provider.stub!(:run_command).and_return(true)
- @provider.stub!(:set_options).and_return(" monkey")
+ @provider.stub(:run_command).and_return(true)
+ @provider.stub(:set_options).and_return(" monkey")
end
describe "manage group" do
it "should run groupmod with the return of set_options" do
- @provider.stub!(:modify_group_members).and_return(true)
+ @provider.stub(:modify_group_members).and_return(true)
@provider.should_receive(:run_command).with({ :command => "groupmod monkey" }).and_return(true)
@provider.manage_group
end
@@ -129,16 +143,15 @@ describe Chef::Provider::Group::Groupadd do
end
end
- describe "modify_group_members" do
-
- it "should raise an error when calling modify_group_members" do
- lambda { @provider.modify_group_members }.should raise_error(Chef::Exceptions::Group, "you must override modify_group_members in #{@provider.to_s}")
+ [:add_member, :remove_member, :set_members].each do |m|
+ it "should raise an error when calling #{m}" do
+ lambda { @provider.send(m, [ ]) }.should raise_error(Chef::Exceptions::Group, "you must override #{m} in #{@provider.to_s}")
end
end
describe "load_current_resource" do
before do
- File.stub!(:exists?).and_return(false)
+ File.stub(:exists?).and_return(false)
@provider.define_resource_requirements
end
it "should raise an error if the required binary /usr/sbin/groupadd doesn't exist" do
diff --git a/spec/unit/provider/group/groupmod_spec.rb b/spec/unit/provider/group/groupmod_spec.rb
index c9c56313b5..001f9c66e8 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,56 +41,55 @@ 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)
+ File.stub(:exists?).and_return(true)
+ lambda { @provider.load_current_resource }.should_not raise_error
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")
@provider.should_receive(:shell_out!).with("group mod -n wheel_bak wheel")
@provider.should_receive(:shell_out!).with("group add -g '123' -o wheel")
@provider.should_receive(:shell_out!).with("group del wheel_bak")
@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)
+ Chef::Log.stub(:debug)
@provider.should_receive(:shell_out!).with("group mod -n wheel_bak wheel")
@provider.should_receive(:shell_out!).with("user mod -G wheel lobster")
@provider.should_receive(:shell_out!).with("group add -g '123' -o wheel")
@@ -100,14 +99,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 +116,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..af64a21fde 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'")
@@ -49,16 +49,18 @@ describe Chef::Provider::Group::Pw do
describe "when creating a group" do
it "should run pw groupadd with the return of set_options and set_members_option" do
@new_resource.gid(23)
- @provider.should_receive(:run_command).with({ :command => "pw groupadd wheel -g '23' -M root,aj" }).and_return(true)
+ @provider.should_receive(:run_command).with({ :command => "pw groupadd wheel -g '23'" }).and_return(true)
@provider.create_group
end
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)
+ @new_resource.members(["someone"])
+ @provider.should_receive(:run_command).with({ :command => "pw groupmod wheel -g '42' -m someone" }).and_return(true)
+ @provider.should_receive(:run_command).with({ :command => "pw groupmod wheel -g '42' -d root,aj" }).and_return(true)
@provider.manage_group
end
@@ -72,58 +74,54 @@ 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
+ @new_resource.stub(:members).and_return([])
+ @current_resource.stub(:members).and_return([])
end
-
+
it "should set no options" do
- @provider.set_members_option.should eql("")
+ @provider.set_members_options.should eql([ ])
end
end
describe "with an empty members array in the new resource and existing members in the current resource" do
before do
- @new_resource.stub!(:members).and_return([])
- @current_resource.stub!(:members).and_return(["all", "your", "base"])
+ @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
+ Chef::Log.should_receive(:debug).with("group[wheel] removing group members: all,your,base")
+ @provider.set_members_options
end
-
+
it "should set the -d option with the members joined by ','" do
- @provider.set_members_option.should eql(" -d all,your,base")
+ @provider.set_members_options.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([])
+ @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
+ Chef::Log.should_receive(:debug).with("group[wheel] adding group members: all,your,base")
+ @provider.set_members_options
end
-
+
it "should set the -M option with the members joined by ','" do
- @provider.set_members_option.should eql(" -M all,your,base")
+ @provider.set_members_options.should eql([ " -m all,your,base" ])
end
end
end
describe"load_current_resource" do
- before (:each) do
+ before (:each) do
+ @provider.action = :create
@provider.load_current_resource
@provider.define_resource_requirements
end
@@ -131,10 +129,10 @@ 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)
+ File.stub(:exists?).and_return(true)
+ lambda { @provider.process_resource_requirements }.should_not raise_error
end
end
end
diff --git a/spec/unit/provider/group/usermod_spec.rb b/spec/unit/provider/group/usermod_spec.rb
index 1807aaf57d..c0178e5e57 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.
@@ -25,52 +25,68 @@ describe Chef::Provider::Group::Usermod do
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Group.new("wheel")
@new_resource.members [ "all", "your", "base" ]
+ @new_resource.excluded_members [ ]
@provider = Chef::Provider::Group::Usermod.new(@new_resource, @run_context)
- @provider.stub!(:run_command)
+ @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([])
+ @new_resource.stub(:append).and_return(true)
+ @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.should_not_receive(:shell_out!)
@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"
}
before do
- @new_resource.stub!(:members).and_return(["all", "your", "base"])
- File.stub!(:exists?).and_return(true)
+ @new_resource.stub(:members).and_return(["all", "your", "base"])
+ File.stub(:exists?).and_return(true)
end
it "should raise an error when setting the entire group directly" 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
-
+
+ it "should raise an error when excluded_members are set" do
+ @provider.define_resource_requirements
+ @provider.load_current_resource
+ @provider.instance_variable_set("@group_exists", true)
+ @provider.action = :modify
+ @new_resource.stub(:append).and_return(true)
+ @new_resource.stub(:excluded_members).and_return(["someone"])
+ lambda { @provider.run_action(@provider.process_resource_requirements) }.should raise_error(Chef::Exceptions::Group, "excluded_members is not supported by #{@provider.to_s}")
+ end
+
platforms.each do |platform, flags|
it "should usermod each user when the append option is set on #{platform}" do
+ current_resource = @new_resource.dup
+ current_resource.members([ ])
+ @provider.current_resource = current_resource
@node.automatic_attrs[:platform] = platform
- @new_resource.stub!(:append).and_return(true)
- @provider.should_receive(:run_command).with({:command => "usermod #{flags} wheel all"})
- @provider.should_receive(:run_command).with({:command => "usermod #{flags} wheel your"})
- @provider.should_receive(:run_command).with({:command => "usermod #{flags} wheel base"})
+ @new_resource.stub(:append).and_return(true)
+ @provider.should_receive(:shell_out!).with("usermod #{flags} wheel all")
+ @provider.should_receive(:shell_out!).with("usermod #{flags} wheel your")
+ @provider.should_receive(:shell_out!).with("usermod #{flags} wheel base")
@provider.modify_group_members
end
end
@@ -79,19 +95,20 @@ describe Chef::Provider::Group::Usermod do
describe "when loading the current resource" do
before(:each) do
- File.stub!(:exists?).and_return(false)
+ File.stub(:exists?).and_return(false)
+ @provider.action = :create
@provider.define_resource_requirements
end
it "should raise an error if the required binary /usr/sbin/usermod doesn't exist" do
- File.stub!(:exists?).and_return(true)
+ File.stub(:exists?).and_return(true)
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)
+ File.stub(:exists?).and_return(true)
+ lambda { @provider.process_resource_requirements }.should_not raise_error
end
end
end
diff --git a/spec/unit/provider/group/windows_spec.rb b/spec/unit/provider/group/windows_spec.rb
index 084d1d0acf..6888c750f5 100644
--- a/spec/unit/provider/group/windows_spec.rb
+++ b/spec/unit/provider/group/windows_spec.rb
@@ -33,8 +33,8 @@ describe Chef::Provider::Group::Windows do
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Group.new("staff")
- @net_group = mock("Chef::Util::Windows::NetGroup")
- Chef::Util::Windows::NetGroup.stub!(:new).and_return(@net_group)
+ @net_group = double("Chef::Util::Windows::NetGroup")
+ Chef::Util::Windows::NetGroup.stub(:new).and_return(@net_group)
@provider = Chef::Provider::Group::Windows.new(@new_resource, @run_context)
end
@@ -52,38 +52,31 @@ describe Chef::Provider::Group::Windows do
@current_resource = Chef::Resource::Group.new("staff")
@current_resource.members [ "all", "your", "base" ]
- Chef::Util::Windows::NetGroup.stub!(:new).and_return(@net_group)
- @net_group.stub!(:local_add_members)
- @net_group.stub!(:local_set_members)
+ Chef::Util::Windows::NetGroup.stub(:new).and_return(@net_group)
+ @net_group.stub(:local_add_members)
+ @net_group.stub(:local_set_members)
+ @provider.stub(:local_group_name_to_sid)
@provider.current_resource = @current_resource
end
it "should call @net_group.local_set_members" do
- @new_resource.stub!(:append).and_return(false)
+ @new_resource.stub(:append).and_return(false)
@net_group.should_receive(:local_set_members).with(@new_resource.members)
@provider.manage_group
end
it "should call @net_group.local_add_members" do
- @new_resource.stub!(:append).and_return(true)
+ @new_resource.stub(:append).and_return(true)
@net_group.should_receive(:local_add_members).with(@new_resource.members)
@provider.manage_group
end
- it "should call @net_group.local_set_members if append fails" do
- @new_resource.stub!(:append).and_return(true)
- @net_group.stub!(:local_add_members).and_raise(ArgumentError)
- @net_group.should_receive(:local_add_members).with(@new_resource.members)
- @net_group.should_receive(:local_set_members).with(@new_resource.members + @current_resource.members)
- @provider.manage_group
- end
-
end
describe "remove_group" do
before do
- Chef::Util::Windows::NetGroup.stub!(:new).and_return(@net_group)
- @provider.stub!(:run_command).and_return(true)
+ Chef::Util::Windows::NetGroup.stub(:new).and_return(@net_group)
+ @provider.stub(:run_command).and_return(true)
end
it "should call @net_group.local_delete" do
@@ -92,3 +85,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 8fceb7428e..9ff9f85c7c 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,23 +33,23 @@ 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",
+ @pw_group = double("Struct::Group",
:name => "wheel",
:gid => 20,
:mem => [ "root", "aj" ]
)
- Etc.stub!(:getgrnam).with('wheel').and_return(@pw_group)
+ 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,46 +65,59 @@ 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)
+ 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
describe "when determining if the system is already in the target state" do
[ :gid, :members ].each do |attribute|
it "should return true if #{attribute} doesn't match" do
- @current_resource.stub!(attribute).and_return("looooooooooooooooooool")
+ @current_resource.stub(attribute).and_return("looooooooooooooooooool")
@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
it "should return false if append is true and the group member(s) already exists" do
@current_resource.members << "extra_user"
- @new_resource.stub!(:append).and_return(true)
+ @new_resource.stub(:append).and_return(true)
@provider.compare_group.should be_false
end
it "should return true if append is true and the group member(s) do not already exist" do
@new_resource.members << "extra_user"
- @new_resource.stub!(:append).and_return(true)
+ @new_resource.stub(:append).and_return(true)
+ @provider.compare_group.should be_true
+ end
+
+ it "should return false if append is true and excluded_members include a non existing member" do
+ @new_resource.excluded_members << "extra_user"
+ @new_resource.stub(:append).and_return(true)
+ @provider.compare_group.should be_false
+ end
+
+ it "should return true if the append is true and excluded_members include an existing user" do
+ @new_resource.members.each {|m| @new_resource.excluded_members << m }
+ @new_resource.members.clear
+ @new_resource.stub(:append).and_return(true)
@provider.compare_group.should be_true
end
@@ -116,46 +129,49 @@ describe Chef::Provider::User do
@provider.should_receive(:create_group).and_return(true)
@provider.run_action(:create)
end
-
+
it "should set the new_resources updated flag when it creates the group" do
@provider.group_exists = false
- @provider.stub!(:create_group)
+ @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.stub(:compare_group).and_return(false)
+ @provider.stub(:change_desc).and_return([ ])
@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.stub(:compare_group).and_return(true)
+ @provider.stub(:change_desc).and_return([ ])
@provider.should_receive(:manage_group).and_return(true)
@provider.run_action(:create)
end
-
+
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)
+ @provider.stub(:compare_group).and_return(true)
+ @provider.stub(:change_desc).and_return(["Some changes are going to be done."])
+ @provider.stub(:manage_group).and_return(true)
@provider.run_action(:create)
@new_resource.should be_updated
end
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)
@@ -167,30 +183,33 @@ describe Chef::Provider::User do
describe "when updating a group" do
before(:each) do
@provider.group_exists = true
- @provider.stub!(:manage_group).and_return(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.stub(:change_desc).and_return(["Some changes are going to be done."])
@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.stub(:compare_group).and_return(true)
+ @provider.stub(:change_desc).and_return(["Some changes are going to be done."])
+ @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.stub(:change_desc).and_return(["Some changes are going to be done."])
@provider.should_not_receive(:manage_group)
@provider.run_action(:manage)
end
@@ -199,28 +218,31 @@ describe Chef::Provider::User do
describe "when modifying the group" do
before(:each) do
@provider.group_exists = true
- @provider.stub!(:manage_group).and_return(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.stub(:change_desc).and_return(["Some changes are going to be done."])
@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.stub(:compare_group).and_return(true)
+ @provider.stub(:change_desc).and_return(["Some changes are going to be done."])
+ @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.stub(:change_desc).and_return(["Some changes are going to be done."])
@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,29 +252,29 @@ 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.stub!(:append).and_return true
+ @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"
+ @provider.change_desc.should == [ "add missing member(s): user1, user2" ]
end
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"
+ @provider.change_desc.should == [ "replace group members with new list of members" ]
end
it "should report the gid will be changed when it does not match" do
- @current_resource.stub!(:gid).and_return("BADF00D")
+ @current_resource.stub(:gid).and_return("BADF00D")
@provider.compare_group.should be_true
- @provider.change_desc.should == "change gid #{@current_resource.gid} to #{@new_resource.gid}"
+ @provider.change_desc.should == [ "change gid #{@current_resource.gid} to #{@new_resource.gid}" ]
end
it "should report no change reason when no change is required" do
@provider.compare_group.should be_false
- @provider.change_desc.should == nil
+ @provider.change_desc.should == [ ]
end
end
diff --git a/spec/unit/provider/http_request_spec.rb b/spec/unit/provider/http_request_spec.rb
index 436eaec558..605287fcc3 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
@@ -44,22 +44,22 @@ describe Chef::Provider::HttpRequest do
before(:each) 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
+ @provider.stub(:load_current_resource).and_return(true)
+ @http = double("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", {})
+ @new_resource.stub(:message).and_return(lambda { "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,38 +97,60 @@ 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
end
+ # CHEF-4762: we expect a nil return value for a "200 Success" response
+ # and false for a "304 Not Modified" response
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(nil)
@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(nil)
@provider.run_action(:head)
@new_resource.should be_updated
end
+ it "should update a HEAD request with empty string response body (CHEF-4762)" do
+ @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 update a HEAD request with nil response body (CHEF-4762)" do
+ @http.should_receive(:head).with("http://www.opscode.com/?message=is cool", {}).and_return(nil)
+ @provider.run_action(:head)
+ @new_resource.should be_updated
+ end
+
+ it "should not update a HEAD request if a not modified response (CHEF-4762)" do
+ if_modified_since = File.mtime(__FILE__).httpdate
+ @new_resource.headers "If-Modified-Since" => if_modified_since
+ @http.should_receive(:head).with("http://www.opscode.com/?message=is cool", {"If-Modified-Since" => if_modified_since}).and_return(false)
+ @provider.run_action(:head)
+ @new_resource.should_not 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
index a97853b22c..24f5fb18f3 100644
--- a/spec/unit/provider/ifconfig/aix_spec.rb
+++ b/spec/unit/provider/ifconfig/aix_spec.rb
@@ -20,7 +20,7 @@ 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>
@@ -47,8 +47,8 @@ IFCONFIG
@provider = Chef::Provider::Ifconfig::Aix.new(@new_resource, @run_context)
end
- describe "#load_current_resource" do
- before do
+ 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"
@@ -67,7 +67,7 @@ IFCONFIG
it "should add an interface if it does not exist" do
@new_resource.device "en10"
- @provider.stub!(:load_current_resource) do
+ @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
@@ -81,7 +81,7 @@ IFCONFIG
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.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
@@ -93,7 +93,7 @@ IFCONFIG
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.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
@@ -109,7 +109,7 @@ IFCONFIG
it "should not disable an interface if it does not exist" do
@new_resource.device "en10"
- @provider.stub!(:load_current_resource) do
+ @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
@@ -123,7 +123,7 @@ IFCONFIG
context "interface exists" do
before do
@new_resource.device "en10"
- @provider.stub!(:load_current_resource) do
+ @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
@@ -146,7 +146,7 @@ IFCONFIG
it "should not delete an interface if it does not exist" do
@new_resource.device "en10"
- @provider.stub!(:load_current_resource) do
+ @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
@@ -160,7 +160,7 @@ IFCONFIG
context "interface exists" do
before do
@new_resource.device "en10"
- @provider.stub!(:load_current_resource) do
+ @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
@@ -177,4 +177,4 @@ IFCONFIG
end
end
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/provider/ifconfig/debian_spec.rb b/spec/unit/provider/ifconfig/debian_spec.rb
index 617e840e1f..c2e2d1bfd1 100644
--- a/spec/unit/provider/ifconfig/debian_spec.rb
+++ b/spec/unit/provider/ifconfig/debian_spec.rb
@@ -20,70 +20,82 @@ require 'spec_helper'
require 'chef/exceptions'
describe Chef::Provider::Ifconfig::Debian do
- before do
- @node = Chef::Node.new
- @cookbook_collection = Chef::CookbookCollection.new([])
- @events = Chef::EventDispatch::Dispatcher.new
- @run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
- #This new_resource can be called anything --> it is not the same as in ifconfig.rb
- @new_resource = Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)
- @new_resource.mask "255.255.254.0"
- @new_resource.metric "1"
- @new_resource.mtu "1500"
- @new_resource.device "eth0"
- @provider = Chef::Provider::Ifconfig::Debian.new(@new_resource, @run_context)
- @current_resource = Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)
-
- status = mock("Status", :exitstatus => 0)
- @provider.instance_variable_set("@status", status)
- @provider.current_resource = @current_resource
- @provider.stub!(:load_current_resource)
- @provider.stub!(:run_command)
-
- @config_filename_ifaces = "/etc/network/interfaces"
- @config_filename_ifcfg = "/etc/network/interfaces.d/ifcfg-#{@new_resource.device}"
+
+ let(:run_context) do
+ node = Chef::Node.new
+ cookbook_collection = Chef::CookbookCollection.new([])
+ events = Chef::EventDispatch::Dispatcher.new
+ Chef::RunContext.new(node, cookbook_collection, events)
+ end
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::Ifconfig.new("10.0.0.1", run_context)
+ new_resource.mask "255.255.254.0"
+ new_resource.metric "1"
+ new_resource.mtu "1500"
+ new_resource.device "eth0"
+ new_resource
end
+ let(:current_resource) { Chef::Resource::Ifconfig.new("10.0.0.1", run_context) }
+
+ let(:provider) do
+ status = double("Status", :exitstatus => 0)
+ provider = Chef::Provider::Ifconfig::Debian.new(new_resource, run_context)
+ provider.instance_variable_set("@status", status)
+ provider.current_resource = current_resource
+ allow(provider).to receive(:load_current_resource)
+ allow(provider).to receive(:run_command)
+ provider
+ end
+
+ let(:config_filename_ifaces) { "/etc/network/interfaces" }
+
+ let(:config_filename_ifcfg) { "/etc/network/interfaces.d/ifcfg-#{new_resource.device}" }
+
describe "generate_config for action_add" do
- before do
- @config_file_ifaces = StringIO.new
- @config_file_ifcfg = StringIO.new
- FileUtils.should_receive(:cp)
- File.should_receive(:new).with(@config_filename_ifaces).and_return(StringIO.new)
- File.should_receive(:open).with(@config_filename_ifaces, "w").and_yield(@config_file_ifaces)
- File.should_receive(:new).with(@config_filename_ifcfg, "w").and_return(@config_file_ifcfg)
- File.should_receive(:exist?).with(@config_filename_ifaces).and_return(true)
- end
-
- it "should create network-scripts directory" do
- File.should_receive(:directory?).with(File.dirname(@config_filename_ifcfg)).and_return(false)
- Dir.should_receive(:mkdir).with(File.dirname(@config_filename_ifcfg))
- @provider.run_action(:add)
- end
-
- it "should write configure network-scripts directory" do
- File.should_receive(:directory?).with(File.dirname(@config_filename_ifcfg)).and_return(true)
- @provider.run_action(:add)
- @config_file_ifaces.string.should match(/^\s*source\s+\/etc\/network\/interfaces[.]d\/[*]\s*$/)
- end
-
- it "should write a network-script" do
- File.should_receive(:directory?).with(File.dirname(@config_filename_ifcfg)).and_return(true)
- @provider.run_action(:add)
- @config_file_ifcfg.string.should match(/^iface eth0 inet static\s*$/)
- @config_file_ifcfg.string.should match(/^\s+address 10\.0\.0\.1\s*$/)
- @config_file_ifcfg.string.should match(/^\s+netmask 255\.255\.254\.0\s*$/)
- end
+
+ let(:config_file_ifaces) { StringIO.new }
+
+ let(:config_file_ifcfg) { StringIO.new }
+
+ before do
+ expect(FileUtils).to receive(:cp)
+ expect(File).to receive(:open).with(config_filename_ifaces).and_return(StringIO.new)
+ expect(File).to receive(:open).with(config_filename_ifaces, "w").and_yield(config_file_ifaces)
+ expect(File).to receive(:new).with(config_filename_ifcfg, "w").and_return(config_file_ifcfg)
+ expect(File).to receive(:exist?).with(config_filename_ifaces).and_return(true)
+ end
+
+ it "should create network-scripts directory" do
+ expect(File).to receive(:directory?).with(File.dirname(config_filename_ifcfg)).and_return(false)
+ expect(Dir).to receive(:mkdir).with(File.dirname(config_filename_ifcfg))
+ provider.run_action(:add)
+ end
+
+ it "should write configure network-scripts directory" do
+ expect(File).to receive(:directory?).with(File.dirname(config_filename_ifcfg)).and_return(true)
+ provider.run_action(:add)
+ expect(config_file_ifaces.string).to match(/^\s*source\s+\/etc\/network\/interfaces[.]d\/[*]\s*$/)
+ end
+
+ it "should write a network-script" do
+ expect(File).to receive(:directory?).with(File.dirname(config_filename_ifcfg)).and_return(true)
+ provider.run_action(:add)
+ expect(config_file_ifcfg.string).to match(/^iface eth0 inet static\s*$/)
+ expect(config_file_ifcfg.string).to match(/^\s+address 10\.0\.0\.1\s*$/)
+ expect(config_file_ifcfg.string).to match(/^\s+netmask 255\.255\.254\.0\s*$/)
+ end
end
describe "delete_config for action_delete" do
it "should delete network-script if it exists" do
- @current_resource.device @new_resource.device
- File.should_receive(:exist?).with(@config_filename_ifcfg).and_return(true)
- FileUtils.should_receive(:rm_f).with(@config_filename_ifcfg, :verbose => false)
+ current_resource.device new_resource.device
+ expect(File).to receive(:exist?).with(config_filename_ifcfg).and_return(true)
+ expect(FileUtils).to receive(:rm_f).with(config_filename_ifcfg, :verbose => false)
- @provider.run_action(:delete)
+ provider.run_action(:delete)
end
end
end
diff --git a/spec/unit/provider/ifconfig/redhat_spec.rb b/spec/unit/provider/ifconfig/redhat_spec.rb
index b6f83ffea9..f4b98dfc32 100644
--- a/spec/unit/provider/ifconfig/redhat_spec.rb
+++ b/spec/unit/provider/ifconfig/redhat_spec.rb
@@ -34,7 +34,7 @@ describe Chef::Provider::Ifconfig::Redhat do
@provider = Chef::Provider::Ifconfig::Redhat.new(@new_resource, @run_context)
@current_resource = Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)
- status = mock("Status", :exitstatus => 0)
+ status = double("Status", :exitstatus => 0)
@provider.instance_variable_set("@status", status)
@provider.current_resource = @current_resource
end
@@ -42,8 +42,8 @@ describe Chef::Provider::Ifconfig::Redhat do
describe "generate_config for action_add" do
it "should write network-script for centos" do
- @provider.stub!(:load_current_resource)
- @provider.stub!(:run_command)
+ @provider.stub(:load_current_resource)
+ @provider.stub(:run_command)
config_filename = "/etc/sysconfig/network-scripts/ifcfg-#{@new_resource.device}"
config_file = StringIO.new
File.should_receive(:new).with(config_filename, "w").and_return(config_file)
@@ -59,8 +59,8 @@ describe Chef::Provider::Ifconfig::Redhat do
it "should delete network-script if it exists for centos" do
@current_resource.device @new_resource.device
- @provider.stub!(:load_current_resource)
- @provider.stub!(:run_command)
+ @provider.stub(:load_current_resource)
+ @provider.stub(:run_command)
config_filename = "/etc/sysconfig/network-scripts/ifcfg-#{@new_resource.device}"
File.should_receive(:exist?).with(config_filename).and_return(true)
FileUtils.should_receive(:rm_f).with(config_filename, :verbose => false)
diff --git a/spec/unit/provider/ifconfig_spec.rb b/spec/unit/provider/ifconfig_spec.rb
index d1d20f7f22..fb8d0956d7 100644
--- a/spec/unit/provider/ifconfig_spec.rb
+++ b/spec/unit/provider/ifconfig_spec.rb
@@ -35,30 +35,30 @@ describe Chef::Provider::Ifconfig do
@provider = Chef::Provider::Ifconfig.new(@new_resource, @run_context)
@current_resource = Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)
- status = mock("Status", :exitstatus => 0)
+ status = double("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
- status = mock("Status", :exitstatus => 1)
- @provider.should_receive(:popen4).and_return status
+ describe Chef::Provider::Ifconfig, "load_current_resource" do
+ before do
+ status = double("Status", :exitstatus => 1)
+ @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
it "should add an interface if it does not exist" do
- #@provider.stub!(:run_command).and_return(true)
- @provider.stub!(:load_current_resource)
+ #@provider.stub(:run_command).and_return(true)
+ @provider.stub(:load_current_resource)
@current_resource.inet_addr nil
command = "ifconfig eth0 10.0.0.1 netmask 255.255.254.0 metric 1 mtu 1500"
@provider.should_receive(:run_command).with(:command => command)
@@ -69,7 +69,7 @@ describe Chef::Provider::Ifconfig do
end
it "should not add an interface if it already exists" do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
@provider.should_not_receive(:run_command)
@current_resource.inet_addr "10.0.0.1"
@provider.should_not_receive(:generate_config)
@@ -84,9 +84,9 @@ 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)
+ @provider.stub(:load_current_resource)
@current_resource.inet_addr nil
command = "ifconfig eth0 10.0.0.1 netmask 255.255.254.0 metric 1 mtu 1500"
@provider.should_receive(:run_command).with(:command => command)
@@ -97,7 +97,7 @@ describe Chef::Provider::Ifconfig do
end
it "should not enable interface if it already exists" do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
@provider.should_not_receive(:run_command)
@current_resource.inet_addr "10.0.0.1"
@provider.should_not_receive(:generate_config)
@@ -110,7 +110,7 @@ describe Chef::Provider::Ifconfig do
describe Chef::Provider::Ifconfig, "action_delete" do
it "should delete interface if it exists" do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
@current_resource.device "eth0"
command = "ifconfig #{@new_resource.device} down"
@provider.should_receive(:run_command).with(:command => command)
@@ -121,7 +121,7 @@ describe Chef::Provider::Ifconfig do
end
it "should not delete interface if it does not exist" do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
@provider.should_not_receive(:run_command)
@provider.should_not_receive(:delete_config)
@@ -129,11 +129,11 @@ 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
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
@current_resource.device "eth0"
command = "ifconfig #{@new_resource.device} down"
@provider.should_receive(:run_command).with(:command => command)
@@ -144,7 +144,7 @@ describe Chef::Provider::Ifconfig do
end
it "should not delete interface if it does not exist" do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
@provider.should_not_receive(:run_command)
@provider.should_not_receive(:delete_config)
@@ -156,7 +156,7 @@ describe Chef::Provider::Ifconfig do
describe Chef::Provider::Ifconfig, "action_delete" do
it "should delete interface of it exists" do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
@current_resource.device "eth0"
command = "ifconfig #{@new_resource.device} down"
@provider.should_receive(:run_command).with(:command => command)
@@ -168,7 +168,7 @@ describe Chef::Provider::Ifconfig do
it "should not delete interface if it does not exist" do
# This is so that our fake values do not get overwritten
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
# This is so that nothing actually runs
@provider.should_not_receive(:run_command)
@provider.should_not_receive(:delete_config)
diff --git a/spec/unit/provider/link_spec.rb b/spec/unit/provider/link_spec.rb
index 171e21171c..6052f5dd3b 100644
--- a/spec/unit/provider/link_spec.rb
+++ b/spec/unit/provider/link_spec.rb
@@ -44,13 +44,13 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
describe "when the target is a symlink" do
before(:each) do
- lstat = mock("stats", :ino => 5)
- lstat.stub!(:uid).and_return(501)
- lstat.stub!(:gid).and_return(501)
- lstat.stub!(:mode).and_return(0777)
- File.stub!(:lstat).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(lstat)
- provider.file_class.stub!(:symlink?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(true)
- provider.file_class.stub!(:readlink).with("#{CHEF_SPEC_DATA}/fofile-link").and_return("#{CHEF_SPEC_DATA}/fofile")
+ lstat = double("stats", :ino => 5)
+ lstat.stub(:uid).and_return(501)
+ lstat.stub(:gid).and_return(501)
+ lstat.stub(:mode).and_return(0777)
+ File.stub(:lstat).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(lstat)
+ provider.file_class.stub(:symlink?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(true)
+ provider.file_class.stub(:readlink).with("#{CHEF_SPEC_DATA}/fofile-link").and_return("#{CHEF_SPEC_DATA}/fofile")
end
describe "to a file that exists" do
@@ -95,9 +95,9 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
describe "to a file that doesn't exist" do
before do
- File.stub!(:exist?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(false)
- provider.file_class.stub!(:symlink?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(true)
- provider.file_class.stub!(:readlink).with("#{CHEF_SPEC_DATA}/fofile-link").and_return("#{CHEF_SPEC_DATA}/fofile")
+ File.stub(:exist?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(false)
+ provider.file_class.stub(:symlink?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(true)
+ provider.file_class.stub(:readlink).with("#{CHEF_SPEC_DATA}/fofile-link").and_return("#{CHEF_SPEC_DATA}/fofile")
new_resource.owner "501" # only loaded in current_resource if present in new
new_resource.group "501"
provider.load_current_resource
@@ -123,8 +123,8 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
describe "when the target doesn't exist" do
before do
- File.stub!(:exists?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(false)
- provider.file_class.stub!(:symlink?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(false)
+ File.stub(:exists?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(false)
+ provider.file_class.stub(:symlink?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(false)
provider.load_current_resource
end
@@ -144,19 +144,19 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
describe "when the target is a regular old file" do
before do
- stat = mock("stats", :ino => 5)
- stat.stub!(:uid).and_return(501)
- stat.stub!(:gid).and_return(501)
- stat.stub!(:mode).and_return(0755)
- provider.file_class.stub!(:stat).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(stat)
-
- File.stub!(:exists?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(true)
- provider.file_class.stub!(:symlink?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(false)
+ stat = double("stats", :ino => 5)
+ stat.stub(:uid).and_return(501)
+ stat.stub(:gid).and_return(501)
+ stat.stub(:mode).and_return(0755)
+ provider.file_class.stub(:stat).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(stat)
+
+ File.stub(:exists?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(true)
+ provider.file_class.stub(:symlink?).with("#{CHEF_SPEC_DATA}/fofile-link").and_return(false)
end
describe "and the source does not exist" do
before do
- File.stub!(:exists?).with("#{CHEF_SPEC_DATA}/fofile").and_return(false)
+ File.stub(:exists?).with("#{CHEF_SPEC_DATA}/fofile").and_return(false)
provider.load_current_resource
end
@@ -176,14 +176,14 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
describe "and the source exists" do
before do
- stat = mock("stats", :ino => 6)
- stat.stub!(:uid).and_return(502)
- stat.stub!(:gid).and_return(502)
- stat.stub!(:mode).and_return(0644)
+ stat = double("stats", :ino => 6)
+ stat.stub(:uid).and_return(502)
+ stat.stub(:gid).and_return(502)
+ stat.stub(:mode).and_return(0644)
- provider.file_class.stub!(:stat).with("#{CHEF_SPEC_DATA}/fofile").and_return(stat)
+ provider.file_class.stub(:stat).with("#{CHEF_SPEC_DATA}/fofile").and_return(stat)
- File.stub!(:exists?).with("#{CHEF_SPEC_DATA}/fofile").and_return(true)
+ File.stub(:exists?).with("#{CHEF_SPEC_DATA}/fofile").and_return(true)
provider.load_current_resource
end
@@ -203,14 +203,14 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
describe "and is hardlinked to the source" do
before do
- stat = mock("stats", :ino => 5)
- stat.stub!(:uid).and_return(502)
- stat.stub!(:gid).and_return(502)
- stat.stub!(:mode).and_return(0644)
+ stat = double("stats", :ino => 5)
+ stat.stub(:uid).and_return(502)
+ stat.stub(:gid).and_return(502)
+ stat.stub(:mode).and_return(0644)
- provider.file_class.stub!(:stat).with("#{CHEF_SPEC_DATA}/fofile").and_return(stat)
+ provider.file_class.stub(:stat).with("#{CHEF_SPEC_DATA}/fofile").and_return(stat)
- File.stub!(:exists?).with("#{CHEF_SPEC_DATA}/fofile").and_return(true)
+ File.stub(:exists?).with("#{CHEF_SPEC_DATA}/fofile").and_return(true)
provider.load_current_resource
end
@@ -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..6595728741 100644
--- a/spec/unit/provider/mdadm_spec.rb
+++ b/spec/unit/provider/mdadm_spec.rb
@@ -25,31 +25,27 @@ 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
describe "when determining the current metadevice status" do
it "should set the current resources mount point to the new resources mount point" do
- @provider.stub!(:shell_out!).and_return(OpenStruct.new(:status => 0))
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:status => 0))
@provider.load_current_resource
@provider.current_resource.name.should == '/dev/md1'
@provider.current_resource.raid_device.should == '/dev/md1'
end
it "determines that the metadevice exists when mdadm exit code is zero" do
- @provider.stub!(:shell_out!).with("mdadm --detail --test /dev/md1", :returns => [0,4]).and_return(OpenStruct.new(:status => 0))
+ @provider.stub(:shell_out!).with("mdadm --detail --test /dev/md1", :returns => [0,4]).and_return(OpenStruct.new(:status => 0))
@provider.load_current_resource
@provider.current_resource.exists.should be_true
end
it "determines that the metadevice does not exist when mdadm exit code is 4" do
- @provider.stub!(:shell_out!).with("mdadm --detail --test /dev/md1", :returns => [0,4]).and_return(OpenStruct.new(:status => 4))
+ @provider.stub(:shell_out!).with("mdadm --detail --test /dev/md1", :returns => [0,4]).and_return(OpenStruct.new(:status => 4))
@provider.load_current_resource
@provider.current_resource.exists.should be_false
end
@@ -58,17 +54,15 @@ 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
- @provider.stub!(:load_current_resource).and_return(true)
+ @new_resource.level 5
+ @provider.stub(:load_current_resource).and_return(true)
@provider.current_resource = @current_resource
end
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
index 92aa8177f2..dcd9170e1f 100644
--- a/spec/unit/provider/mount/aix_spec.rb
+++ b/spec/unit/provider/mount/aix_spec.rb
@@ -60,8 +60,8 @@ ENABLED
@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
+ ::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)
@@ -179,7 +179,7 @@ ENABLED
@new_resource.options("nodev,rw")
stub_mounted_enabled(@provider, @mounted_output, "")
filesystems = StringIO.new
- ::File.stub!(:open).with("/etc/filesystems", "a").and_yield(filesystems)
+ ::File.stub(:open).with("/etc/filesystems", "a").and_yield(filesystems)
@provider.run_action(:enable)
@@ -200,7 +200,7 @@ ENABLED
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)
+ ::File.stub(:open).with("/etc/filesystems", "r").and_return(<<-ETCFILESYSTEMS)
/tmp/foo:
dev = /dev/sdz1
vfs = jfs2
@@ -217,9 +217,9 @@ ENABLED
mount = true
options = rw
ETCFILESYSTEMS
-
+
filesystems = StringIO.new
- ::File.stub!(:open).with("/etc/filesystems", "w").and_yield(filesystems)
+ ::File.stub(:open).with("/etc/filesystems", "w").and_yield(filesystems)
@provider.run_action(:disable)
@@ -234,4 +234,4 @@ ETCFILESYSTEMS
@provider.run_action(:disable)
end
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/provider/mount/mount_spec.rb b/spec/unit/provider/mount/mount_spec.rb
index 00cc9a10e2..99e78590f1 100644
--- a/spec/unit/provider/mount/mount_spec.rb
+++ b/spec/unit/provider/mount/mount_spec.rb
@@ -34,14 +34,16 @@ describe Chef::Provider::Mount::Mount do
@provider = Chef::Provider::Mount::Mount.new(@new_resource, @run_context)
- ::File.stub!(:exists?).with("/dev/sdz1").and_return true
- ::File.stub!(:exists?).with("/tmp/foo").and_return true
+ ::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
before do
- @provider.stub!(:shell_out!).and_return(OpenStruct.new(:stdout => ''))
- ::File.stub!(:foreach).with("/etc/fstab")
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => ''))
+ ::File.stub(:foreach).with("/etc/fstab")
end
it "should create a current resource with the same mount point and device" do
@@ -54,7 +56,7 @@ describe Chef::Provider::Mount::Mount do
it "should accecpt device_type :uuid" do
@new_resource.device_type :uuid
@new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
- @stdout_findfs = mock("STDOUT", :first => "/dev/sdz1")
+ @stdout_findfs = double("STDOUT", :first => "/dev/sdz1")
@provider.should_receive(:popen4).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_yield(@pid,@stdin,@stdout_findfs,@stderr).and_return(@status)
@provider.load_current_resource()
@provider.mountable?
@@ -70,7 +72,7 @@ describe Chef::Provider::Mount::Mount do
it "should ignore trailing slash and set mounted to true for network mount (#{type})" do
@new_resource.device fs_spec
- @provider.stub!(:shell_out!).and_return(OpenStruct.new(:stdout => "#{fs_spec}/ on /tmp/foo type #{type} (rw)\n"))
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => "#{fs_spec}/ on /tmp/foo type #{type} (rw)\n"))
@provider.load_current_resource
@provider.current_resource.mounted.should be_true
end
@@ -78,12 +80,12 @@ describe Chef::Provider::Mount::Mount do
end
it "should raise an error if the mount device does not exist" do
- ::File.stub!(:exists?).with("/dev/sdz1").and_return false
+ ::File.stub(:exists?).with("/dev/sdz1").and_return false
lambda { @provider.load_current_resource();@provider.mountable? }.should raise_error(Chef::Exceptions::Mount)
end
it "should not call mountable? with load_current_resource - CHEF-1565" do
- ::File.stub!(:exists?).with("/dev/sdz1").and_return false
+ ::File.stub(:exists?).with("/dev/sdz1").and_return false
@provider.should_receive(:mounted?).and_return(true)
@provider.should_receive(:enabled?).and_return(true)
@provider.should_not_receive(:mountable?)
@@ -93,15 +95,15 @@ describe Chef::Provider::Mount::Mount do
it "should raise an error if the mount device (uuid) does not exist" do
@new_resource.device_type :uuid
@new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
- status_findfs = mock("Status", :exitstatus => 1)
- stdout_findfs = mock("STDOUT", :first => nil)
+ status_findfs = double("Status", :exitstatus => 1)
+ stdout_findfs = double("STDOUT", :first => nil)
@provider.should_receive(:popen4).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_yield(@pid,@stdin,stdout_findfs,@stderr).and_return(status_findfs)
::File.should_receive(:exists?).with("").and_return(false)
lambda { @provider.load_current_resource();@provider.mountable? }.should raise_error(Chef::Exceptions::Mount)
end
it "should raise an error if the mount point does not exist" do
- ::File.stub!(:exists?).with("/tmp/foo").and_return false
+ ::File.stub(:exists?).with("/tmp/foo").and_return false
lambda { @provider.load_current_resource();@provider.mountable? }.should raise_error(Chef::Exceptions::Mount)
end
@@ -123,7 +125,7 @@ describe Chef::Provider::Mount::Mount do
end
it "should set mounted true if the mount point is found in the mounts list" do
- @provider.stub!(:shell_out!).and_return(OpenStruct.new(:stdout => '/dev/sdz1 on /tmp/foo'))
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => '/dev/sdz1 on /tmp/foo'))
@provider.load_current_resource()
@provider.current_resource.mounted.should be_true
end
@@ -131,10 +133,10 @@ describe Chef::Provider::Mount::Mount do
it "should set mounted true if the symlink target of the device is found in the mounts list" do
target = "/dev/mapper/target"
- ::File.stub!(:symlink?).with("#{@new_resource.device}").and_return(true)
- ::File.stub!(:readlink).with("#{@new_resource.device}").and_return(target)
+ ::File.stub(:symlink?).with("#{@new_resource.device}").and_return(true)
+ ::File.stub(:readlink).with("#{@new_resource.device}").and_return(target)
- @provider.stub!(:shell_out!).and_return(OpenStruct.new(:stdout => "/dev/mapper/target on /tmp/foo type ext3 (rw)\n"))
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => "/dev/mapper/target on /tmp/foo type ext3 (rw)\n"))
@provider.load_current_resource()
@provider.current_resource.mounted.should be_true
end
@@ -143,7 +145,7 @@ describe Chef::Provider::Mount::Mount do
mount = "/dev/sdy1 on #{@new_resource.mount_point} type ext3 (rw)\n"
mount << "#{@new_resource.device} on #{@new_resource.mount_point} type ext3 (rw)\n"
- @provider.stub!(:shell_out!).and_return(OpenStruct.new(:stdout => mount))
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => mount))
@provider.load_current_resource()
@provider.current_resource.mounted.should be_true
end
@@ -152,13 +154,13 @@ describe Chef::Provider::Mount::Mount do
mount = "#{@new_resource.device} on #{@new_resource.mount_point} type ext3 (rw)\n"
mount << "/dev/sdy1 on #{@new_resource.mount_point} type ext3 (rw)\n"
- @provider.stub!(:shell_out!).and_return(OpenStruct.new(:stdout => mount))
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => mount))
@provider.load_current_resource()
@provider.current_resource.mounted.should be_false
end
it "mounted should be false if the mount point is not found in the mounts list" do
- @provider.stub!(:shell_out!).and_return(OpenStruct.new(:stdout => "/dev/sdy1 on /tmp/foo type ext3 (rw)\n"))
+ @provider.stub(:shell_out!).and_return(OpenStruct.new(:stdout => "/dev/sdy1 on /tmp/foo type ext3 (rw)\n"))
@provider.load_current_resource()
@provider.current_resource.mounted.should be_false
end
@@ -167,7 +169,7 @@ describe Chef::Provider::Mount::Mount do
fstab1 = "/dev/sdy1 /tmp/foo ext3 defaults 1 2\n"
fstab2 = "#{@new_resource.device} #{@new_resource.mount_point} ext3 defaults 1 2\n"
- ::File.stub!(:foreach).with("/etc/fstab").and_yield(fstab1).and_yield(fstab2)
+ ::File.stub(:foreach).with("/etc/fstab").and_yield(fstab1).and_yield(fstab2)
@provider.load_current_resource
@provider.current_resource.enabled.should be_true
@@ -177,7 +179,7 @@ describe Chef::Provider::Mount::Mount do
fstab1 = "#{@new_resource.device} #{@new_resource.mount_point} ext3 defaults 1 2\n"
fstab2 = "/dev/sdy1 /tmp/foo/bar ext3 defaults 1 2\n"
- ::File.stub!(:foreach).with("/etc/fstab").and_yield(fstab1).and_yield(fstab2)
+ ::File.stub(:foreach).with("/etc/fstab").and_yield(fstab1).and_yield(fstab2)
@provider.load_current_resource
@provider.current_resource.enabled.should be_true
@@ -186,12 +188,12 @@ describe Chef::Provider::Mount::Mount do
it "should set enabled to true if the symlink target is in fstab" do
target = "/dev/mapper/target"
- ::File.stub!(:symlink?).with("#{@new_resource.device}").and_return(true)
- ::File.stub!(:readlink).with("#{@new_resource.device}").and_return(target)
+ ::File.stub(:symlink?).with("#{@new_resource.device}").and_return(true)
+ ::File.stub(:readlink).with("#{@new_resource.device}").and_return(target)
fstab = "/dev/sdz1 /tmp/foo ext3 defaults 1 2\n"
- ::File.stub!(:foreach).with("/etc/fstab").and_yield fstab
+ ::File.stub(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
@provider.current_resource.enabled.should be_true
@@ -199,7 +201,7 @@ describe Chef::Provider::Mount::Mount do
it "should set enabled to false if the mount point is not in fstab" do
fstab = "/dev/sdy1 #{@new_resource.mount_point} ext3 defaults 1 2\n"
- ::File.stub!(:foreach).with("/etc/fstab").and_yield fstab
+ ::File.stub(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
@provider.current_resource.enabled.should be_false
@@ -207,7 +209,7 @@ describe Chef::Provider::Mount::Mount do
it "should ignore commented lines in fstab " do
fstab = "\# #{@new_resource.device} #{@new_resource.mount_point} ext3 defaults 1 2\n"
- ::File.stub!(:foreach).with("/etc/fstab").and_yield fstab
+ ::File.stub(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
@provider.current_resource.enabled.should be_false
@@ -216,7 +218,7 @@ describe Chef::Provider::Mount::Mount do
it "should set enabled to false if the mount point is not last in fstab" do
line_1 = "#{@new_resource.device} #{@new_resource.mount_point} ext3 defaults 1 2\n"
line_2 = "/dev/sdy1 #{@new_resource.mount_point} ext3 defaults 1 2\n"
- ::File.stub!(:foreach).with("/etc/fstab").and_yield(line_1).and_yield(line_2)
+ ::File.stub(:foreach).with("/etc/fstab").and_yield(line_1).and_yield(line_2)
@provider.load_current_resource
@provider.current_resource.enabled.should be_false
@@ -226,11 +228,11 @@ describe Chef::Provider::Mount::Mount do
target = "/dev/mapper/target"
options = "rw,noexec,noauto"
- ::File.stub!(:symlink?).with(@new_resource.device).and_return(true)
- ::File.stub!(:readlink).with(@new_resource.device).and_return(target)
+ ::File.stub(:symlink?).with(@new_resource.device).and_return(true)
+ ::File.stub(:readlink).with(@new_resource.device).and_return(target)
fstab = "#{@new_resource.device} #{@new_resource.mount_point} #{@new_resource.fstype} #{options} 1 2\n"
- ::File.stub!(:foreach).with("/etc/fstab").and_yield fstab
+ ::File.stub(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
@provider.current_resource.options.should eq(options.split(','))
end
@@ -239,11 +241,11 @@ describe Chef::Provider::Mount::Mount do
target = "/dev/mapper/target"
options = "rw,noexec,noauto"
- ::File.stub!(:symlink?).with(@new_resource.device).and_return(true)
- ::File.stub!(:readlink).with(@new_resource.device).and_return(target)
+ ::File.stub(:symlink?).with(@new_resource.device).and_return(true)
+ ::File.stub(:readlink).with(@new_resource.device).and_return(target)
fstab = "#{target} #{@new_resource.mount_point} #{@new_resource.fstype} #{options} 1 2\n"
- ::File.stub!(:foreach).with("/etc/fstab").and_yield fstab
+ ::File.stub(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
@provider.current_resource.options.should eq(options.split(','))
end
@@ -261,7 +263,6 @@ describe Chef::Provider::Mount::Mount do
describe "mount_fs" do
it "should mount the filesystem if it is not mounted" do
- @provider.rspec_reset
@provider.should_receive(:shell_out!).with("mount -t ext3 -o defaults /dev/sdz1 /tmp/foo")
@provider.mount_fs()
end
@@ -276,16 +277,16 @@ describe Chef::Provider::Mount::Mount do
it "should mount the filesystem specified by uuid" do
@new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
@new_resource.device_type :uuid
- @stdout_findfs = mock("STDOUT", :first => "/dev/sdz1")
- @provider.stub!(:popen4).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_yield(@pid,@stdin,@stdout_findfs,@stderr).and_return(@status)
- @stdout_mock = mock('stdout mock')
- @stdout_mock.stub!(:each).and_yield("#{@new_resource.device} on #{@new_resource.mount_point}")
+ @stdout_findfs = double("STDOUT", :first => "/dev/sdz1")
+ @provider.stub(:popen4).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_yield(@pid,@stdin,@stdout_findfs,@stderr).and_return(@status)
+ @stdout_mock = double('stdout mock')
+ @stdout_mock.stub(:each).and_yield("#{@new_resource.device} on #{@new_resource.mount_point}")
@provider.should_receive(:shell_out!).with("mount -t #{@new_resource.fstype} -o defaults -U #{@new_resource.device} #{@new_resource.mount_point}").and_return(@stdout_mock)
@provider.mount_fs()
end
it "should not mount the filesystem if it is mounted" do
- @current_resource.stub!(:mounted).and_return(true)
+ @current_resource.stub(:mounted).and_return(true)
@provider.should_not_receive(:shell_out!)
@provider.mount_fs()
end
@@ -337,7 +338,7 @@ describe Chef::Provider::Mount::Mount do
@current_resource.enabled(false)
@fstab = StringIO.new
- ::File.stub!(:open).with("/etc/fstab", "a").and_yield(@fstab)
+ ::File.stub(:open).with("/etc/fstab", "a").and_yield(@fstab)
@provider.enable_fs
@fstab.string.should match(%r{^/dev/sdz1\s+/tmp/foo\s+ext3\s+defaults\s+0\s+2\s*$})
end
@@ -376,9 +377,9 @@ describe Chef::Provider::Mount::Mount do
this_mount = "/dev/sdz1 /tmp/foo ext3 defaults 1 2\n"
@fstab_read = [this_mount, other_mount]
- ::File.stub!(:readlines).with("/etc/fstab").and_return(@fstab_read)
+ ::File.stub(:readlines).with("/etc/fstab").and_return(@fstab_read)
@fstab_write = StringIO.new
- ::File.stub!(:open).with("/etc/fstab", "w").and_yield(@fstab_write)
+ ::File.stub(:open).with("/etc/fstab", "w").and_yield(@fstab_write)
@provider.disable_fs
@fstab_write.string.should match(Regexp.escape(other_mount))
@@ -393,8 +394,8 @@ describe Chef::Provider::Mount::Mount do
%q{#/dev/sdz1 /tmp/foo ext3 defaults 1 2}]
fstab_write = StringIO.new
- ::File.stub!(:readlines).with("/etc/fstab").and_return(fstab_read)
- ::File.stub!(:open).with("/etc/fstab", "w").and_yield(fstab_write)
+ ::File.stub(:readlines).with("/etc/fstab").and_return(fstab_read)
+ ::File.stub(:open).with("/etc/fstab", "w").and_yield(fstab_write)
@provider.disable_fs
fstab_write.string.should match(%r{^/dev/sdy1 /tmp/foo ext3 defaults 1 2$})
@@ -403,23 +404,23 @@ describe Chef::Provider::Mount::Mount do
end
it "should disable only the last entry if enabled is true" do
- @current_resource.stub!(:enabled).and_return(true)
+ @current_resource.stub(:enabled).and_return(true)
fstab_read = ["/dev/sdz1 /tmp/foo ext3 defaults 1 2\n",
"/dev/sdy1 /tmp/foo ext3 defaults 1 2\n",
"/dev/sdz1 /tmp/foo ext3 defaults 1 2\n"]
fstab_write = StringIO.new
- ::File.stub!(:readlines).with("/etc/fstab").and_return(fstab_read)
- ::File.stub!(:open).with("/etc/fstab", "w").and_yield(fstab_write)
+ ::File.stub(:readlines).with("/etc/fstab").and_return(fstab_read)
+ ::File.stub(:open).with("/etc/fstab", "w").and_yield(fstab_write)
@provider.disable_fs
fstab_write.string.should == "/dev/sdz1 /tmp/foo ext3 defaults 1 2\n/dev/sdy1 /tmp/foo ext3 defaults 1 2\n"
end
it "should not disable if enabled is false" do
- @current_resource.stub!(:enabled).and_return(false)
+ @current_resource.stub(:enabled).and_return(false)
- ::File.stub!(:readlines).with("/etc/fstab").and_return([])
+ ::File.stub(:readlines).with("/etc/fstab").and_return([])
::File.should_not_receive(:open).and_yield(@fstab)
@provider.disable_fs
diff --git a/spec/unit/provider/mount/windows_spec.rb b/spec/unit/provider/mount/windows_spec.rb
index 74579b14fe..80e7f1e695 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.
@@ -40,12 +40,12 @@ describe Chef::Provider::Mount::Windows do
@new_resource = Chef::Resource::Mount.new("X:")
@new_resource.device GUID
@current_resource = Chef::Resource::Mount.new("X:")
- Chef::Resource::Mount.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Mount.stub(:new).and_return(@current_resource)
- @net_use = mock("Chef::Util::Windows::NetUse")
- Chef::Util::Windows::NetUse.stub!(:new).and_return(@net_use)
- @vol = mock("Chef::Util::Windows::Volume")
- Chef::Util::Windows::Volume.stub!(:new).and_return(@vol)
+ @net_use = double("Chef::Util::Windows::NetUse")
+ Chef::Util::Windows::NetUse.stub(:new).and_return(@net_use)
+ @vol = double("Chef::Util::Windows::Volume")
+ Chef::Util::Windows::Volume.stub(:new).and_return(@vol)
@provider = Chef::Provider::Mount::Windows.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
@@ -53,13 +53,13 @@ describe Chef::Provider::Mount::Windows do
describe "when loading the current resource" do
it "should set mounted true if the mount point is found" do
- @vol.stub!(:device).and_return(@new_resource.device)
+ @vol.stub(:device).and_return(@new_resource.device)
@current_resource.should_receive(:mounted).with(true)
@provider.load_current_resource
end
it "should set mounted false if the mount point is not found" do
- @vol.stub!(:device).and_raise(ArgumentError)
+ @vol.stub(:device).and_raise(ArgumentError)
@current_resource.should_receive(:mounted).with(false)
@provider.load_current_resource
end
@@ -67,8 +67,8 @@ describe Chef::Provider::Mount::Windows do
describe "with a local device" do
before do
@new_resource.device GUID
- @vol.stub!(:device).and_return(@new_resource.device)
- @net_use.stub!(:device).and_raise(ArgumentError)
+ @vol.stub(:device).and_return(@new_resource.device)
+ @net_use.stub(:device).and_raise(ArgumentError)
end
it "should determine the device is a volume GUID" do
@@ -80,8 +80,8 @@ describe Chef::Provider::Mount::Windows do
describe "with a remote device" do
before do
@new_resource.device REMOTE
- @net_use.stub!(:device).and_return(@new_resource.device)
- @vol.stub!(:device).and_raise(ArgumentError)
+ @net_use.stub(:device).and_return(@new_resource.device)
+ @vol.stub(:device).and_raise(ArgumentError)
end
it "should determine the device is remote" do
@@ -93,8 +93,8 @@ describe Chef::Provider::Mount::Windows do
describe "when mounting a file system" do
before do
@new_resource.device GUID
- @vol.stub!(:add)
- @vol.stub!(:device).and_raise(ArgumentError)
+ @vol.stub(:add)
+ @vol.stub(:device).and_raise(ArgumentError)
@provider.load_current_resource
end
@@ -108,7 +108,7 @@ describe Chef::Provider::Mount::Windows do
it "should not mount the filesystem if it is mounted" do
@vol.should_not_receive(:add)
- @current_resource.stub!(:mounted).and_return(true)
+ @current_resource.stub(:mounted).and_return(true)
@provider.mount_fs
end
end
@@ -116,19 +116,19 @@ describe Chef::Provider::Mount::Windows do
describe "when unmounting a file system" do
before do
@new_resource.device GUID
- @vol.stub!(:delete)
- @vol.stub!(:device).and_raise(ArgumentError)
+ @vol.stub(:delete)
+ @vol.stub(:device).and_raise(ArgumentError)
@provider.load_current_resource
end
it "should umount the filesystem if it is mounted" do
- @current_resource.stub!(:mounted).and_return(true)
+ @current_resource.stub(:mounted).and_return(true)
@vol.should_receive(:delete)
@provider.umount_fs
end
it "should not umount the filesystem if it is not mounted" do
- @current_resource.stub!(:mounted).and_return(false)
+ @current_resource.stub(:mounted).and_return(false)
@vol.should_not_receive(:delete)
@provider.umount_fs
end
diff --git a/spec/unit/provider/mount_spec.rb b/spec/unit/provider/mount_spec.rb
index 1a98f10cb0..d9bfeb3e0f 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,18 +39,18 @@ 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
- @current_resource.stub!(:mounted).and_return(false)
+ @current_resource.stub(:mounted).and_return(false)
@provider.should_receive(:mount_fs).with.and_return(true)
@provider.run_action(:mount)
@new_resource.should be_updated_by_last_action
end
it "should not mount the filesystem if it is mounted" do
- @current_resource.stub!(:mounted).and_return(true)
+ @current_resource.stub(:mounted).and_return(true)
@provider.should_not_receive(:mount_fs)
@provider.run_action(:mount)
@new_resource.should_not be_updated_by_last_action
@@ -60,14 +60,14 @@ describe Chef::Provider::Mount do
describe "when the target state is an unmounted filesystem" do
it "should umount the filesystem if it is mounted" do
- @current_resource.stub!(:mounted).and_return(true)
+ @current_resource.stub(:mounted).and_return(true)
@provider.should_receive(:umount_fs).with.and_return(true)
@provider.run_action(:umount)
@new_resource.should be_updated_by_last_action
end
it "should not umount the filesystem if it is not mounted" do
- @current_resource.stub!(:mounted).and_return(false)
+ @current_resource.stub(:mounted).and_return(false)
@provider.should_not_receive(:umount_fs)
@provider.run_action(:umount)
@new_resource.should_not be_updated_by_last_action
@@ -78,23 +78,23 @@ 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)
+ @current_resource.stub(:mounted).and_return(true)
@provider.should_receive(:remount_fs).and_return(true)
@provider.run_action(:remount)
@new_resource.should be_updated_by_last_action
end
it "should not remount the filesystem if it is not mounted" do
- @current_resource.stub!(:mounted).and_return(false)
+ @current_resource.stub(:mounted).and_return(false)
@provider.should_not_receive(:remount_fs)
@provider.run_action(:remount)
@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
@@ -107,7 +107,7 @@ describe Chef::Provider::Mount do
end
describe "when enabling the filesystem to be mounted" do
it "should enable the mount if it isn't enable" do
- @current_resource.stub!(:enabled).and_return(false)
+ @current_resource.stub(:enabled).and_return(false)
@provider.should_not_receive(:mount_options_unchanged?)
@provider.should_receive(:enable_fs).and_return(true)
@provider.run_action(:enable)
@@ -115,7 +115,7 @@ describe Chef::Provider::Mount do
end
it "should enable the mount if it is enabled and mount options have changed" do
- @current_resource.stub!(:enabled).and_return(true)
+ @current_resource.stub(:enabled).and_return(true)
@provider.should_receive(:mount_options_unchanged?).and_return(false)
@provider.should_receive(:enable_fs).and_return(true)
@provider.run_action(:enable)
@@ -123,9 +123,9 @@ describe Chef::Provider::Mount do
end
it "should not enable the mount if it is enabled and mount options have not changed" do
- @current_resource.stub!(:enabled).and_return(true)
+ @current_resource.stub(:enabled).and_return(true)
@provider.should_receive(:mount_options_unchanged?).and_return(true)
- @provider.should_not_receive(:enable_fs).and_return(true)
+ @provider.should_not_receive(:enable_fs)
@provider.run_action(:enable)
@new_resource.should_not be_updated_by_last_action
end
@@ -133,14 +133,14 @@ describe Chef::Provider::Mount do
describe "when the target state is to disable the mount" do
it "should disable the mount if it is enabled" do
- @current_resource.stub!(:enabled).and_return(true)
+ @current_resource.stub(:enabled).and_return(true)
@provider.should_receive(:disable_fs).with.and_return(true)
@provider.run_action(:disable)
@new_resource.should be_updated_by_last_action
end
it "should not disable the mount if it isn't enabled" do
- @current_resource.stub!(:enabled).and_return(false)
+ @current_resource.stub(:enabled).and_return(false)
@provider.should_not_receive(:disable_fs)
@provider.run_action(:disable)
@new_resource.should_not be_updated_by_last_action
diff --git a/spec/unit/provider/ohai_spec.rb b/spec/unit/provider/ohai_spec.rb
index 8402c92e97..8b8a6b5939 100644
--- a/spec/unit/provider/ohai_spec.rb
+++ b/spec/unit/provider/ohai_spec.rb
@@ -41,17 +41,17 @@ describe Chef::Provider::Ohai do
:newdata => "somevalue"
}
}
- mock_ohai.stub!(:all_plugins).and_return(true)
- mock_ohai.stub!(:require_plugin).and_return(true)
- mock_ohai.stub!(:data).and_return(mock_ohai[:data],
+ mock_ohai.stub(:all_plugins).and_return(true)
+ mock_ohai.stub(:require_plugin).and_return(true)
+ mock_ohai.stub(:data).and_return(mock_ohai[:data],
mock_ohai[:data2])
- Ohai::System.stub!(:new).and_return(mock_ohai)
- Chef::Platform.stub!(:find_platform_and_version).and_return({ "platform" => @platform,
+ Ohai::System.stub(:new).and_return(mock_ohai)
+ Chef::Platform.stub(:find_platform_and_version).and_return({ "platform" => @platform,
"platform_version" => @platform_version})
# Fake node with a dummy save
@node = Chef::Node.new
@node.name(@fqdn)
- @node.stub!(:save).and_return(@node)
+ @node.stub(:save).and_return(@node)
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Ohai.new("ohai_reload")
diff --git a/spec/unit/provider/package/aix_spec.rb b/spec/unit/provider/package/aix_spec.rb
new file mode 100644
index 0000000000..35f85b628f
--- /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 = double("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 = double("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 = double("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 = double("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 eb11c1e417..b8e23d8756 100644
--- a/spec/unit/provider/package/apt_spec.rb
+++ b/spec/unit/provider/package/apt_spec.rb
@@ -26,7 +26,7 @@ describe Chef::Provider::Package::Apt do
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Package.new("irssi", @run_context)
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::Apt.new(@new_resource, @run_context)
@stdin = StringIO.new
@stdout =<<-PKG_STATUS
@@ -83,27 +83,27 @@ libmysqlclient15-dev:
Candidate: (none)
Version table:
VPKG_STDOUT
- virtual_package = mock(:stdout => virtual_package_out,:exitstatus => 0)
+ virtual_package = double(:stdout => virtual_package_out,:exitstatus => 0)
@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
SHOWPKG_STDOUT
- showpkg = mock(:stdout => showpkg_out,:exitstatus => 0)
+ showpkg = double(:stdout => showpkg_out,:exitstatus => 0)
@provider.should_receive(:shell_out!).with("apt-cache showpkg libmysqlclient15-dev").and_return(showpkg)
real_package_out=<<-RPKG_STDOUT
libmysqlclient-dev:
@@ -118,7 +118,7 @@ libmysqlclient-dev:
5.1.41-3ubuntu12 0
500 http://us.archive.ubuntu.com/ubuntu/ lucid/main Packages
RPKG_STDOUT
- real_package = mock(:stdout => real_package_out,:exitstatus => 0)
+ real_package = double(:stdout => real_package_out,:exitstatus => 0)
@provider.should_receive(:shell_out!).with("apt-cache policy libmysqlclient-dev").and_return(real_package)
@provider.load_current_resource
end
@@ -131,21 +131,21 @@ mp3-decoder:
Candidate: (none)
Version table:
VPKG_STDOUT
- virtual_package = mock(:stdout => virtual_package_out,:exitstatus => 0)
+ virtual_package = double(:stdout => virtual_package_out,:exitstatus => 0)
@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
@@ -154,7 +154,7 @@ opencubicplayer 1:0.1.17-2
mpg321 0.2.10.6
mpg123 1.12.1-0ubuntu1
SHOWPKG_STDOUT
- showpkg = mock(:stdout => showpkg_out,:exitstatus => 0)
+ showpkg = double(:stdout => showpkg_out,:exitstatus => 0)
@provider.should_receive(:shell_out!).with("apt-cache showpkg mp3-decoder").and_return(showpkg)
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package)
end
@@ -163,8 +163,8 @@ SHOWPKG_STDOUT
@new_resource = Chef::Resource::AptPackage.new("irssi", @run_context)
@provider = Chef::Provider::Package::Apt.new(@new_resource, @run_context)
- @new_resource.stub!(:default_release).and_return("lenny-backports")
- @new_resource.stub!(:provider).and_return("Chef::Provider::Package::Apt")
+ @new_resource.stub(:default_release).and_return("lenny-backports")
+ @new_resource.stub(:provider).and_return("Chef::Provider::Package::Apt")
@provider.should_receive(:shell_out!).with("apt-cache -o APT::Default-Release=lenny-backports policy irssi").and_return(@shell_out)
@provider.load_current_resource
end
@@ -256,7 +256,7 @@ SHOWPKG_STDOUT
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(: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
@@ -282,7 +282,7 @@ SHOWPKG_STDOUT
@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.stub(:get_preseed_file).and_return(false)
@provider.should_not_receive(:shell_out!)
@provider.run_action(:reconfig)
end
diff --git a/spec/unit/provider/package/dpkg_spec.rb b/spec/unit/provider/package/dpkg_spec.rb
index aa22e0a2a3..6ba7695a1e 100644
--- a/spec/unit/provider/package/dpkg_spec.rb
+++ b/spec/unit/provider/package/dpkg_spec.rb
@@ -30,12 +30,12 @@ describe Chef::Provider::Package::Dpkg do
@stdin = StringIO.new
@stdout = StringIO.new
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@stderr = StringIO.new
- @pid = mock("PID")
- @provider.stub!(:popen4).and_return(@status)
+ @pid = double("PID")
+ @provider.stub(:popen4).and_return(@status)
- ::File.stub!(:exists?).and_return(true)
+ ::File.stub(:exists?).and_return(true)
end
describe "when loading the current resource state" do
@@ -48,27 +48,27 @@ describe Chef::Provider::Package::Dpkg do
it "should raise an exception if a source is supplied but not found" do
@provider.load_current_resource
@provider.define_resource_requirements
- ::File.stub!(:exists?).and_return(false)
+ ::File.stub(:exists?).and_return(false)
lambda { @provider.run_action(:install) }.should raise_error(Chef::Exceptions::Package)
end
describe 'gets the source package version from dpkg-deb' do
def check_version(version)
@stdout = StringIO.new("wget\t#{version}")
- @provider.stub!(:popen4).with("dpkg-deb -W #{@new_resource.source}").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).with("dpkg-deb -W #{@new_resource.source}").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@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
@@ -76,7 +76,7 @@ describe Chef::Provider::Package::Dpkg do
it "gets the source package name from dpkg-deb correctly when the package name has `-', `+' or `.' characters" do
@stdout = StringIO.new("f.o.o-pkg++2\t1.11.4-1ubuntu1")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@provider.current_resource.package_name.should == "f.o.o-pkg++2"
end
@@ -103,15 +103,15 @@ Config-Version: 1.11.4-1ubuntu1
Depends: libc6 (>= 2.8~20080505), libssl0.9.8 (>= 0.9.8f-5)
Conflicts: wget-ssl
DPKG_S
- @provider.stub!(:popen4).with("dpkg -s wget").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).with("dpkg -s wget").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@provider.current_resource.version.should == "1.11.4-1ubuntu1"
end
it "should raise an exception if dpkg fails to run" do
- @status = mock("Status", :exitstatus => -1)
- @provider.stub!(:popen4).and_return(@status)
+ @status = double("Status", :exitstatus => -1)
+ @provider.stub(:popen4).and_return(@status)
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package)
end
end
@@ -158,7 +158,7 @@ DPKG_S
"DEBIAN_FRONTEND" => "noninteractive"
}
})
- @new_resource.stub!(:options).and_return("--force-yes")
+ @new_resource.stub(:options).and_return("--force-yes")
@provider.install_package("wget", "1.11.4-1ubuntu1")
end
@@ -186,7 +186,7 @@ DPKG_S
"DEBIAN_FRONTEND" => "noninteractive"
}
})
- @new_resource.stub!(:options).and_return("--force-yes")
+ @new_resource.stub(:options).and_return("--force-yes")
@provider.remove_package("wget", "1.11.4-1ubuntu1")
end
@@ -208,7 +208,7 @@ DPKG_S
"DEBIAN_FRONTEND" => "noninteractive"
}
})
- @new_resource.stub!(:options).and_return("--force-yes")
+ @new_resource.stub(:options).and_return("--force-yes")
@provider.purge_package("wget", "1.11.4-1ubuntu1")
end
diff --git a/spec/unit/provider/package/easy_install_spec.rb b/spec/unit/provider/package/easy_install_spec.rb
index 02f8399af8..87cbabcc19 100644
--- a/spec/unit/provider/package/easy_install_spec.rb
+++ b/spec/unit/provider/package/easy_install_spec.rb
@@ -30,14 +30,14 @@ describe Chef::Provider::Package::EasyInstall do
@current_resource.version('1.8d')
@provider = Chef::Provider::Package::EasyInstall.new(@new_resource, @run_context)
- Chef::Resource::Package.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Package.stub(:new).and_return(@current_resource)
@stdin = StringIO.new
@stdout = StringIO.new
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@stderr = StringIO.new
@pid = 2342
- @provider.stub!(:popen4).and_return(@status)
+ @provider.stub(:popen4).and_return(@status)
end
describe "easy_install_binary_path" do
@@ -47,7 +47,7 @@ describe Chef::Provider::Package::EasyInstall do
end
it "should set the current resources package name to the new resources package name" do
- $stdout.stub!(:write)
+ $stdout.stub(:write)
@current_resource.should_receive(:package_name).with(@new_resource.package_name)
@provider.load_current_resource
end
@@ -75,7 +75,7 @@ describe Chef::Provider::Package::EasyInstall do
@provider.should_receive(:run_command).with({
:command => "easy_install --always-unzip \"boto==1.8d\""
})
- @new_resource.stub!(:options).and_return("--always-unzip")
+ @new_resource.stub(:options).and_return("--always-unzip")
@provider.install_package("boto", "1.8d")
end
@@ -97,7 +97,7 @@ describe Chef::Provider::Package::EasyInstall do
@provider.should_receive(:run_command).with({
:command => "easy_install -x -m boto"
})
- @new_resource.stub!(:options).and_return("-x")
+ @new_resource.stub(:options).and_return("-x")
@provider.remove_package("boto", "1.8d")
end
diff --git a/spec/unit/provider/package/freebsd_spec.rb b/spec/unit/provider/package/freebsd_spec.rb
index 270c85d934..962f9c23d1 100644
--- a/spec/unit/provider/package/freebsd_spec.rb
+++ b/spec/unit/provider/package/freebsd_spec.rb
@@ -30,12 +30,12 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
- ::File.stub!(:exist?).with('/usr/ports/Makefile').and_return(false)
+ ::File.stub(:exist?).with('/usr/ports/Makefile').and_return(false)
end
describe "when determining the current package state" do
before do
- @provider.stub!(:ports_candidate_version).and_return("4.3.6")
+ @provider.stub(:ports_candidate_version).and_return("4.3.6")
end
it "should create a current resource with the name of the new_resource" do
@@ -68,25 +68,25 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
#@provider = Chef::Provider::Package::Freebsd.new(@node, @new_resource)
- #@status = mock("Status", :exitstatus => 0)
- #@stdin = mock("STDIN", :null_object => true)
- #@stdout = mock("STDOUT", :null_object => true)
- #@stderr = mock("STDERR", :null_object => true)
- #@pid = mock("PID", :null_object => true)
+ #@status = double("Status", :exitstatus => 0)
+ #@stdin = double("STDIN", :null_object => true)
+ #@stdout = double("STDOUT", :null_object => true)
+ #@stderr = double("STDERR", :null_object => true)
+ #@pid = double("PID", :null_object => true)
end
it "should return the version number when it is installed" do
pkg_info = OpenStruct.new(:stdout => "zsh-4.3.6_7")
@provider.should_receive(:shell_out!).with('pkg_info -E "zsh*"', :env => nil, :returns => [0,1]).and_return(pkg_info)
#@provider.should_receive(:popen4).with('pkg_info -E "zsh*"').and_yield(@pid, @stdin, ["zsh-4.3.6_7"], @stderr).and_return(@status)
- @provider.stub!(:package_name).and_return("zsh")
+ @provider.stub(:package_name).and_return("zsh")
@provider.current_installed_version.should == "4.3.6_7"
end
it "does not set the current version number when the package is not installed" do
pkg_info = OpenStruct.new(:stdout => "")
@provider.should_receive(:shell_out!).with('pkg_info -E "zsh*"', :env => nil, :returns => [0,1]).and_return(pkg_info)
- @provider.stub!(:package_name).and_return("zsh")
+ @provider.stub(:package_name).and_return("zsh")
@provider.current_installed_version.should be_nil
end
@@ -94,21 +94,21 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
whereis = OpenStruct.new(:stdout => "zsh: /usr/ports/shells/zsh")
@provider.should_receive(:shell_out!).with("whereis -s zsh", :env => nil).and_return(whereis)
#@provider.should_receive(:popen4).with("whereis -s zsh").and_yield(@pid, @stdin, ["zsh: /usr/ports/shells/zsh"], @stderr).and_return(@status)
- @provider.stub!(:port_name).and_return("zsh")
+ @provider.stub(:port_name).and_return("zsh")
@provider.port_path.should == "/usr/ports/shells/zsh"
end
# Not happy with the form of these tests as they are far too closely tied to the implementation and so very fragile.
it "should return the ports candidate version when given a valid port path" do
- @provider.stub!(:port_path).and_return("/usr/ports/shells/zsh")
+ @provider.stub(:port_path).and_return("/usr/ports/shells/zsh")
make_v = OpenStruct.new(:stdout => "4.3.6\n")
@provider.should_receive(:shell_out!).with("make -V PORTVERSION", {:cwd=>"/usr/ports/shells/zsh", :returns=>[0, 1], :env=>nil}).and_return(make_v)
@provider.ports_candidate_version.should == "4.3.6"
end
it "should figure out the package name when we have ports" do
- ::File.stub!(:exist?).with('/usr/ports/Makefile').and_return(true)
- @provider.stub!(:port_path).and_return("/usr/ports/shells/zsh")
+ ::File.stub(:exist?).with('/usr/ports/Makefile').and_return(true)
+ @provider.stub(:port_path).and_return("/usr/ports/shells/zsh")
make_v = OpenStruct.new(:stdout => "zsh-4.3.6_7\n")
@provider.should_receive(:shell_out!).with("make -V PKGNAME", {:cwd=>"/usr/ports/shells/zsh", :env=>nil, :returns=>[0, 1]}).and_return(make_v)
#@provider.should_receive(:ports_makefile_variable_value).with("PKGNAME").and_return("zsh-4.3.6_7")
@@ -121,9 +121,9 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@cmd_result = OpenStruct.new(:status => true)
@provider.current_resource = @current_resource
- @provider.stub!(:package_name).and_return("zsh")
- @provider.stub!(:latest_link_name).and_return("zsh")
- @provider.stub!(:port_path).and_return("/usr/ports/shells/zsh")
+ @provider.stub(:package_name).and_return("zsh")
+ @provider.stub(:latest_link_name).and_return("zsh")
+ @provider.stub(:port_path).and_return("/usr/ports/shells/zsh")
end
it "should run pkg_add -r with the package name" do
@@ -132,7 +132,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
end
it "should run make install when installing from ports" do
- @new_resource.stub!(:source).and_return("ports")
+ @new_resource.stub(:source).and_return("ports")
@provider.should_not_receive(:shell_out!).with("make -DBATCH -f /usr/ports/shells/zsh/Makefile install", :timeout => 1200, :env=>nil)
@provider.should_receive(:shell_out!).with("make -DBATCH install", :timeout => 1200, :env=>nil, :cwd => @provider.port_path).and_return(@cmd_result)
@provider.install_package("zsh", "4.3.6_7")
@@ -161,7 +161,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
end
it "should use the package_name as a relative path from /usr/ports when it contains / but doesn't start with it" do
- # @new_resource = mock( "Chef::Resource::Package",
+ # @new_resource = double( "Chef::Resource::Package",
# :package_name => "www/wordpress",
# :cookbook_name => "xenoparadox")
new_resource = Chef::Resource::Package.new("www/wordpress")
@@ -177,9 +177,9 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@current_resource = Chef::Resource::Package.new("ruby-iconv")
@provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
- @provider.stub!(:port_path).and_return("/usr/ports/converters/ruby-iconv")
- @provider.stub!(:package_name).and_return("ruby18-iconv")
- @provider.stub!(:latest_link_name).and_return("ruby18-iconv")
+ @provider.stub(:port_path).and_return("/usr/ports/converters/ruby-iconv")
+ @provider.stub(:package_name).and_return("ruby18-iconv")
+ @provider.stub(:latest_link_name).and_return("ruby18-iconv")
@install_result = OpenStruct.new(:status => true)
end
@@ -190,7 +190,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
end
it "should run make install when installing from ports" do
- @new_resource.stub!(:source).and_return("ports")
+ @new_resource.stub(:source).and_return("ports")
@provider.should_receive(:shell_out!).with("make -DBATCH install", :timeout => 1200, :env=>nil, :cwd => @provider.port_path).and_return(@install_result)
@provider.install_package("ruby-iconv", "1.0")
end
@@ -202,7 +202,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@new_resource.version "4.3.6_7"
@current_resource.version "4.3.6_7"
@provider.current_resource = @current_resource
- @provider.stub!(:package_name).and_return("zsh")
+ @provider.stub(:package_name).and_return("zsh")
end
it "should run pkg_delete with the package name and version" do
@@ -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
@@ -234,8 +262,8 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@current_resource = Chef::Resource::Package.new("perl5.8")
@provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
- @provider.stub!(:package_name).and_return("perl")
- @provider.stub!(:latest_link_name).and_return("perl")
+ @provider.stub(:package_name).and_return("perl")
+ @provider.stub(:latest_link_name).and_return("perl")
cmd = OpenStruct.new(:status => true)
@provider.should_receive(:shell_out!).with("pkg_add -r perl", :env => nil).and_return(cmd)
@@ -248,8 +276,8 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@current_resource = Chef::Resource::Package.new("mysql50-server")
@provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
- @provider.stub!(:package_name).and_return("mysql-server")
- @provider.stub!(:latest_link_name).and_return("mysql50-server")
+ @provider.stub(:package_name).and_return("mysql-server")
+ @provider.stub(:latest_link_name).and_return("mysql50-server")
cmd = OpenStruct.new(:status => true)
@provider.should_receive(:shell_out!).with("pkg_add -r mysql50-server", :env=>nil).and_return(cmd)
diff --git a/spec/unit/provider/package/ips_spec.rb b/spec/unit/provider/package/ips_spec.rb
index 641a527012..53f8169623 100644
--- a/spec/unit/provider/package/ips_spec.rb
+++ b/spec/unit/provider/package/ips_spec.rb
@@ -28,7 +28,7 @@ describe Chef::Provider::Package::Ips do
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Package.new("crypto/gnupg", @run_context)
@current_resource = Chef::Resource::Package.new("crypto/gnupg", @run_context)
- Chef::Resource::Package.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Package.stub(:new).and_return(@current_resource)
@provider = Chef::Provider::Package::Ips.new(@new_resource, @run_context)
@stdin = StringIO.new
@@ -117,7 +117,7 @@ INSTALLED
@provider.should_receive(:run_command_with_systems_locale).with({
:command => "pkg --no-refresh install -q crypto/gnupg@2.0.17"
})
- @new_resource.stub!(:options).and_return("--no-refresh")
+ @new_resource.stub(:options).and_return("--no-refresh")
@provider.install_package("crypto/gnupg", "2.0.17")
end
@@ -168,9 +168,9 @@ PKG_STATUS
context "when accept_license is true" do
before do
- @new_resource.stub!(:accept_license).and_return(true)
+ @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"
@@ -202,7 +202,7 @@ PKG_STATUS
@provider.should_receive(:run_command_with_systems_locale).with({
:command => "pkg --no-refresh uninstall -q crypto/gnupg@2.0.17"
})
- @new_resource.stub!(:options).and_return("--no-refresh")
+ @new_resource.stub(:options).and_return("--no-refresh")
@provider.remove_package("crypto/gnupg", "2.0.17")
end
end
diff --git a/spec/unit/provider/package/macports_spec.rb b/spec/unit/provider/package/macports_spec.rb
index 2f0db3f7a8..9ebf23860d 100644
--- a/spec/unit/provider/package/macports_spec.rb
+++ b/spec/unit/provider/package/macports_spec.rb
@@ -27,9 +27,9 @@ describe Chef::Provider::Package::Macports do
@current_resource = Chef::Resource::Package.new("zsh")
@provider = Chef::Provider::Package::Macports.new(@new_resource, @run_context)
- Chef::Resource::Package.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Package.stub(:new).and_return(@current_resource)
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@stdin = StringIO.new
@stdout = StringIO.new
@stderr = StringIO.new
@@ -121,7 +121,7 @@ EOF
it "should add options to the port command when specified" do
@current_resource.should_receive(:version).and_return("4.1.6")
@provider.current_resource = @current_resource
- @new_resource.stub!(:options).and_return("-f")
+ @new_resource.stub(:options).and_return("-f")
@provider.should_receive(:run_command_with_systems_locale).with(:command => "port -f install zsh @4.2.7")
@provider.install_package("zsh", "4.2.7")
@@ -140,7 +140,7 @@ EOF
end
it "should add options to the port command when specified" do
- @new_resource.stub!(:options).and_return("-f")
+ @new_resource.stub(:options).and_return("-f")
@provider.should_receive(:run_command_with_systems_locale).with(:command => "port -f uninstall zsh @4.2.7")
@provider.purge_package("zsh", "4.2.7")
end
@@ -158,7 +158,7 @@ EOF
end
it "should add options to the port command when specified" do
- @new_resource.stub!(:options).and_return("-f")
+ @new_resource.stub(:options).and_return("-f")
@provider.should_receive(:run_command_with_systems_locale).with(:command => "port -f deactivate zsh @4.2.7")
@provider.remove_package("zsh", "4.2.7")
end
@@ -191,7 +191,7 @@ EOF
end
it "should add options to the port command when specified" do
- @new_resource.stub!(:options).and_return("-f")
+ @new_resource.stub(:options).and_return("-f")
@current_resource.should_receive(:version).at_least(:once).and_return("4.1.6")
@provider.current_resource = @current_resource
diff --git a/spec/unit/provider/package/pacman_spec.rb b/spec/unit/provider/package/pacman_spec.rb
index 7e4abcb6d5..528f7097e8 100644
--- a/spec/unit/provider/package/pacman_spec.rb
+++ b/spec/unit/provider/package/pacman_spec.rb
@@ -26,10 +26,10 @@ describe Chef::Provider::Package::Pacman do
@new_resource = Chef::Resource::Package.new("nano")
@current_resource = Chef::Resource::Package.new("nano")
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::Pacman.new(@new_resource, @run_context)
- Chef::Resource::Package.stub!(:new).and_return(@current_resource)
- @provider.stub!(:popen4).and_return(@status)
+ Chef::Resource::Package.stub(:new).and_return(@current_resource)
+ @provider.stub(:popen4).and_return(@status)
@stdin = StringIO.new
@stdout = StringIO.new(<<-ERR)
error: package "nano" not found
@@ -55,13 +55,13 @@ ERR
end
it "should read stdout on pacman" do
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@stdout.should_receive(:each).and_return(true)
@provider.load_current_resource
end
it "should set the installed version to nil on the current resource if pacman installed version not exists" do
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@current_resource.should_receive(:version).with(nil).and_return(true)
@provider.load_current_resource
end
@@ -88,17 +88,17 @@ Install Reason : Explicitly installed
Install Script : Yes
Description : Pico editor clone with enhancements
PACMAN
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@current_resource.version.should == "2.2.2-1"
end
it "should set the candidate version if pacman has one" do
- @stdout.stub!(:each).and_yield("core/nano 2.2.3-1 (base)").
+ @stdout.stub(:each).and_yield("core/nano 2.2.3-1 (base)").
and_yield(" Pico editor clone with enhancements").
and_yield("community/nanoblogger 3.4.1-1").
and_yield(" NanoBlogger is a small weblog engine written in Bash for the command line")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@provider.candidate_version.should eql("2.2.3-1")
end
@@ -122,11 +122,11 @@ Include = /etc/pacman.d/mirrorlist
Include = /etc/pacman.d/mirrorlist
PACMAN_CONF
- ::File.stub!(:exists?).with("/etc/pacman.conf").and_return(true)
- ::File.stub!(:read).with("/etc/pacman.conf").and_return(@pacman_conf)
- @stdout.stub!(:each).and_yield("customrepo/nano 1.2.3-4").
+ ::File.stub(:exists?).with("/etc/pacman.conf").and_return(true)
+ ::File.stub(:read).with("/etc/pacman.conf").and_return(@pacman_conf)
+ @stdout.stub(:each).and_yield("customrepo/nano 1.2.3-4").
and_yield(" My custom package")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@provider.candidate_version.should eql("1.2.3-4")
@@ -139,12 +139,12 @@ PACMAN_CONF
it "should not raise an exception if pacman succeeds" do
@status.should_receive(:exitstatus).and_return(0)
- lambda { @provider.load_current_resource }.should_not raise_error(Chef::Exceptions::Package)
+ lambda { @provider.load_current_resource }.should_not raise_error
end
it "should raise an exception if pacman does not return a candidate version" do
- @stdout.stub!(:each).and_yield("")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @stdout.stub(:each).and_yield("")
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
lambda { @provider.candidate_version }.should raise_error(Chef::Exceptions::Package)
end
@@ -165,7 +165,7 @@ PACMAN_CONF
@provider.should_receive(:run_command_with_systems_locale).with({
:command => "pacman --sync --noconfirm --noprogressbar --debug nano"
})
- @new_resource.stub!(:options).and_return("--debug")
+ @new_resource.stub(:options).and_return("--debug")
@provider.install_package("nano", "1.0")
end
@@ -190,7 +190,7 @@ PACMAN_CONF
@provider.should_receive(:run_command_with_systems_locale).with({
:command => "pacman --remove --noconfirm --noprogressbar --debug nano"
})
- @new_resource.stub!(:options).and_return("--debug")
+ @new_resource.stub(:options).and_return("--debug")
@provider.remove_package("nano", "1.0")
end
diff --git a/spec/unit/provider/package/portage_spec.rb b/spec/unit/provider/package/portage_spec.rb
index f44731b73a..6f22952da2 100644
--- a/spec/unit/provider/package/portage_spec.rb
+++ b/spec/unit/provider/package/portage_spec.rb
@@ -27,70 +27,70 @@ describe Chef::Provider::Package::Portage, "load_current_resource" do
@current_resource = Chef::Resource::Package.new("dev-util/git")
@provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context)
- Chef::Resource::Package.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Package.stub(:new).and_return(@current_resource)
end
describe "when determining the current state of the package" do
it "should create a current resource with the name of new_resource" do
- ::Dir.stub!(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"])
+ ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"])
Chef::Resource::Package.should_receive(:new).and_return(@current_resource)
@provider.load_current_resource
end
it "should set the current resource package name to the new resource package name" do
- ::Dir.stub!(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"])
+ ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"])
@current_resource.should_receive(:package_name).with(@new_resource.package_name)
@provider.load_current_resource
end
it "should return a current resource with the correct version if the package is found" do
- ::Dir.stub!(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-foobar-0.9", "/var/db/pkg/dev-util/git-1.0.0"])
+ ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-foobar-0.9", "/var/db/pkg/dev-util/git-1.0.0"])
@provider.load_current_resource
@provider.current_resource.version.should == "1.0.0"
end
it "should return a current resource with the correct version if the package is found with revision" do
- ::Dir.stub!(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0-r1"])
+ ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0-r1"])
@provider.load_current_resource
@provider.current_resource.version.should == "1.0.0-r1"
end
it "should return a current resource with a nil version if the package is not found" do
- ::Dir.stub!(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"])
+ ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"])
@provider.load_current_resource
@provider.current_resource.version.should be_nil
end
it "should return a package name match from /var/db/pkg/* if a category isn't specified and a match is found" do
- ::Dir.stub!(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-foobar-0.9", "/var/db/pkg/dev-util/git-1.0.0"])
+ ::Dir.stub(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-foobar-0.9", "/var/db/pkg/dev-util/git-1.0.0"])
@provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context)
@provider.load_current_resource
@provider.current_resource.version.should == "1.0.0"
end
it "should return a current resource with a nil version if a category isn't specified and a name match from /var/db/pkg/* is not found" do
- ::Dir.stub!(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"])
+ ::Dir.stub(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"])
@provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context)
@provider.load_current_resource
@provider.current_resource.version.should be_nil
end
it "should throw an exception if a category isn't specified and multiple packages are found" do
- ::Dir.stub!(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/funny-words/git-1.0.0"])
+ ::Dir.stub(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/funny-words/git-1.0.0"])
@provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context)
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package)
end
it "should return a current resource with a nil version if a category is specified and multiple packages are found" do
- ::Dir.stub!(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/funny-words/git-1.0.0"])
+ ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/funny-words/git-1.0.0"])
@provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context)
@provider.load_current_resource
@provider.current_resource.version.should be_nil
end
it "should return a current resource with a nil version if a category is not specified and multiple packages from the same category are found" do
- ::Dir.stub!(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/dev-util/git-1.0.1"])
+ ::Dir.stub(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/dev-util/git-1.0.1"])
@provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context)
@provider.load_current_resource
@provider.current_resource.version.should be_nil
@@ -107,8 +107,8 @@ describe Chef::Provider::Package::Portage, "load_current_resource" do
end
it "should throw an exception if the exitstatus is not 0" do
- @status = mock("Status", :exitstatus => 1)
- @provider.stub!(:popen4).and_return(@status)
+ @status = double("Status", :exitstatus => 1)
+ @provider.stub(:popen4).and_return(@status)
lambda { @provider.candidate_version }.should raise_error(Chef::Exceptions::Package)
end
@@ -143,7 +143,7 @@ Searching...
License: GPL-2
EOF
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@provider.should_receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status)
@provider.candidate_version.should == "1.6.0.6"
end
@@ -179,7 +179,7 @@ Searching...
License: GPL-2
EOF
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context)
@provider.should_receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status)
@provider.candidate_version.should == "1.6.0.6"
@@ -224,7 +224,7 @@ Searching...
License: GPL-2
EOF
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context)
@provider.should_receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status)
lambda { @provider.candidate_version }.should raise_error(Chef::Exceptions::Package)
@@ -269,7 +269,7 @@ Searching...
License: GPL-2
EOF
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context)
@provider.should_receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status)
@provider.candidate_version.should == "1.6.0.6"
@@ -295,7 +295,7 @@ EOF
@provider.should_receive(:run_command_with_systems_locale).with({
:command => "emerge -g --color n --nospinner --quiet --oneshot =dev-util/git-1.0.0"
})
- @new_resource.stub!(:options).and_return("--oneshot")
+ @new_resource.stub(:options).and_return("--oneshot")
@provider.install_package("dev-util/git", "1.0.0")
end
diff --git a/spec/unit/provider/package/rpm_spec.rb b/spec/unit/provider/package/rpm_spec.rb
index 9dd94a7441..7126b06d66 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)
+
+ @status = double("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.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.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)
+ ::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)
+ status = double("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/rubygems_spec.rb b/spec/unit/provider/package/rubygems_spec.rb
index 7d0567314a..d3cb9cf7fa 100644
--- a/spec/unit/provider/package/rubygems_spec.rb
+++ b/spec/unit/provider/package/rubygems_spec.rb
@@ -89,7 +89,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
it "finds a matching gem candidate version" do
dep = Gem::Dependency.new('rspec', '>= 0')
dep_installer = Gem::DependencyInstaller.new
- @gem_env.stub!(:dependency_installer).and_return(dep_installer)
+ @gem_env.stub(:dependency_installer).and_return(dep_installer)
latest = [[gemspec("rspec", Gem::Version.new("1.3.0")), "http://rubygems.org/"]]
dep_installer.should_receive(:find_gems_with_sources).with(dep).and_return(latest)
@gem_env.candidate_version_from_remote(Gem::Dependency.new('rspec', '>= 0')).should == Gem::Version.new('1.3.0')
@@ -98,9 +98,9 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
it "finds a matching gem candidate version on rubygems 2.0.0+" do
dep = Gem::Dependency.new('rspec', '>= 0')
dep_installer = Gem::DependencyInstaller.new
- @gem_env.stub!(:dependency_installer).and_return(dep_installer)
- best_gem = mock("best gem match", :spec => gemspec("rspec", Gem::Version.new("1.3.0")), :source => "https://rubygems.org")
- available_set = mock("Gem::AvailableSet test double")
+ @gem_env.stub(:dependency_installer).and_return(dep_installer)
+ best_gem = double("best gem match", :spec => gemspec("rspec", Gem::Version.new("1.3.0")), :source => "https://rubygems.org")
+ available_set = double("Gem::AvailableSet test double")
available_set.should_receive(:pick_best!)
available_set.should_receive(:set).and_return([best_gem])
dep_installer.should_receive(:find_gems_with_sources).with(dep).and_return(available_set)
@@ -121,7 +121,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
Gem.const_set(:Format, Object.new)
@remove_gem_format = true
end
- Gem::Package.stub!(:respond_to?).with(:open).and_return(false)
+ Gem::Package.stub(:respond_to?).with(:open).and_return(false)
end
after do
@@ -131,7 +131,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
end
it "finds a matching gem candidate version on rubygems 2.0+ with some rubygems 1.8 code loaded" do
- package = mock("Gem::Package", :spec => "a gemspec from package")
+ package = double("Gem::Package", :spec => "a gemspec from package")
Gem::Package.should_receive(:new).with("/path/to/package.gem").and_return(package)
@gem_env.spec_from_file("/path/to/package.gem").should == "a gemspec from package"
end
@@ -142,7 +142,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
dep = Gem::Dependency.new('rspec', '>= 0')
latest = []
dep_installer = Gem::DependencyInstaller.new
- @gem_env.stub!(:dependency_installer).and_return(dep_installer)
+ @gem_env.stub(:dependency_installer).and_return(dep_installer)
dep_installer.should_receive(:find_gems_with_sources).with(dep).and_return(latest)
@gem_env.candidate_version_from_remote(Gem::Dependency.new('rspec', '>= 0')).should be_nil
end
@@ -159,7 +159,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
@gem_env.should_receive(:with_gem_sources).with('http://gems.example.com').and_yield
dep_installer = Gem::DependencyInstaller.new
- @gem_env.stub!(:dependency_installer).and_return(dep_installer)
+ @gem_env.stub(:dependency_installer).and_return(dep_installer)
dep_installer.should_receive(:find_gems_with_sources).with(dep).and_return(latest)
@gem_env.candidate_version_from_remote(Gem::Dependency.new('rspec', '>=0'), 'http://gems.example.com').should == Gem::Version.new('1.3.0')
end
@@ -180,14 +180,14 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
end
it "uninstalls all versions of a gem" do
- uninstaller = mock('gem uninstaller')
+ uninstaller = double('gem uninstaller')
uninstaller.should_receive(:uninstall)
@gem_env.should_receive(:uninstaller).with('rspec', :all => true).and_return(uninstaller)
@gem_env.uninstall('rspec')
end
it "uninstalls a specific version of a gem" do
- uninstaller = mock('gem uninstaller')
+ uninstaller = double('gem uninstaller')
uninstaller.should_receive(:uninstall)
@gem_env.should_receive(:uninstaller).with('rspec', :version => '1.2.3').and_return(uninstaller)
@gem_env.uninstall('rspec', '1.2.3')
@@ -230,7 +230,7 @@ describe Chef::Provider::Package::Rubygems::AlternateGemEnvironment do
end
it "builds the gems source index from the gem paths" do
- @gem_env.stub!(:gem_paths).and_return(['/path/to/gems', '/another/path/to/gems'])
+ @gem_env.stub(:gem_paths).and_return(['/path/to/gems', '/another/path/to/gems'])
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.0')
@gem_env.gem_specification
Gem::Specification.dirs.should == [ '/path/to/gems/specifications', '/another/path/to/gems/specifications' ]
@@ -244,17 +244,17 @@ describe Chef::Provider::Package::Rubygems::AlternateGemEnvironment do
gems = [gemspec('rspec', Gem::Version.new('1.2.9')), gemspec('rspec', Gem::Version.new('1.3.0'))]
rspec_dep = Gem::Dependency.new('rspec', nil)
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.0')
- @gem_env.stub!(:gem_specification).and_return(Gem::Specification)
+ @gem_env.stub(:gem_specification).and_return(Gem::Specification)
@gem_env.gem_specification.should_receive(:find_all_by_name).with(rspec_dep.name, rspec_dep.requirement).and_return(gems)
else
- @gem_env.stub!(:gem_source_index).and_return(Gem.source_index)
+ @gem_env.stub(:gem_source_index).and_return(Gem.source_index)
@gem_env.gem_source_index.should_receive(:search).with(rspec_dep).and_return(gems)
end
@gem_env.installed_versions(Gem::Dependency.new('rspec', nil)).should == gems
end
it "determines the installed versions of gems from the source index (part2: the unmockening)" do
- $stdout.stub!(:write)
+ $stdout.stub(:write)
path_to_gem = if windows?
`where gem`.split[1]
else
@@ -295,7 +295,7 @@ RubyGems Environment:
- http://rubygems.org/
- http://gems.github.com/
JRUBY_GEM_ENV
- @gem_env.should_receive(:shell_out!).with('/usr/weird/bin/gem env').and_return(mock('jruby_gem_env', :stdout => gem_env_out))
+ @gem_env.should_receive(:shell_out!).with('/usr/weird/bin/gem env').and_return(double('jruby_gem_env', :stdout => gem_env_out))
expected = ['ruby', Gem::Platform.new('universal-java-1.6')]
@gem_env.gem_platforms.should == expected
# it should also cache the result
@@ -337,7 +337,7 @@ RubyGems Environment:
- http://rubygems.org/
- http://gems.github.com/
RBX_GEM_ENV
- @gem_env.should_receive(:shell_out!).with('/usr/weird/bin/gem env').and_return(mock('rbx_gem_env', :stdout => gem_env_out))
+ @gem_env.should_receive(:shell_out!).with('/usr/weird/bin/gem env').and_return(double('rbx_gem_env', :stdout => gem_env_out))
@gem_env.gem_platforms.should == Gem.platforms
Chef::Provider::Package::Rubygems::AlternateGemEnvironment.platform_cache['/usr/weird/bin/gem'].should == Gem.platforms
end
@@ -367,7 +367,7 @@ describe Chef::Provider::Package::Rubygems do
@run_context = Chef::RunContext.new(@node, {}, @events)
# We choose detect omnibus via RbConfig::CONFIG['bindir'] in Chef::Provider::Package::Rubygems.new
- RbConfig::CONFIG.stub!(:[]).with('bindir').and_return("/usr/bin/ruby")
+ RbConfig::CONFIG.stub(:[]).with('bindir').and_return("/usr/bin/ruby")
@provider = Chef::Provider::Package::Rubygems.new(@new_resource, @run_context)
end
@@ -388,11 +388,11 @@ describe Chef::Provider::Package::Rubygems do
it "searches for a gem binary when running on Omnibus on Unix" do
platform_mock :unix do
- RbConfig::CONFIG.stub!(:[]).with('bindir').and_return("/opt/chef/embedded/bin")
- ENV.stub!(:[]).with('PATH').and_return("/usr/bin:/usr/sbin:/opt/chef/embedded/bin")
- File.stub!(:exists?).with('/usr/bin/gem').and_return(false)
- File.stub!(:exists?).with('/usr/sbin/gem').and_return(true)
- File.stub!(:exists?).with('/opt/chef/embedded/bin/gem').and_return(true) # should not get here
+ RbConfig::CONFIG.stub(:[]).with('bindir').and_return("/opt/chef/embedded/bin")
+ ENV.stub(:[]).with('PATH').and_return("/usr/bin:/usr/sbin:/opt/chef/embedded/bin")
+ File.stub(:exists?).with('/usr/bin/gem').and_return(false)
+ File.stub(:exists?).with('/usr/sbin/gem').and_return(true)
+ File.stub(:exists?).with('/opt/chef/embedded/bin/gem').and_return(true) # should not get here
provider = Chef::Provider::Package::Rubygems.new(@new_resource, @run_context)
provider.gem_env.gem_binary_location.should == '/usr/sbin/gem'
end
@@ -400,13 +400,13 @@ describe Chef::Provider::Package::Rubygems do
it "searches for a gem binary when running on Omnibus on Windows" do
platform_mock :windows do
- RbConfig::CONFIG.stub!(:[]).with('bindir').and_return("d:/opscode/chef/embedded/bin")
- ENV.stub!(:[]).with('PATH').and_return('C:\windows\system32;C:\windows;C:\Ruby186\bin;d:\opscode\chef\embedded\bin')
- File.stub!(:exists?).with('C:\\windows\\system32\\gem').and_return(false)
- File.stub!(:exists?).with('C:\\windows\\gem').and_return(false)
- File.stub!(:exists?).with('C:\\Ruby186\\bin\\gem').and_return(true)
- File.stub!(:exists?).with('d:\\opscode\\chef\\bin\\gem').and_return(false) # should not get here
- File.stub!(:exists?).with('d:\\opscode\\chef\\embedded\\bin\\gem').and_return(false) # should not get here
+ RbConfig::CONFIG.stub(:[]).with('bindir').and_return("d:/opscode/chef/embedded/bin")
+ ENV.stub(:[]).with('PATH').and_return('C:\windows\system32;C:\windows;C:\Ruby186\bin;d:\opscode\chef\embedded\bin')
+ File.stub(:exists?).with('C:\\windows\\system32\\gem').and_return(false)
+ File.stub(:exists?).with('C:\\windows\\gem').and_return(false)
+ File.stub(:exists?).with('C:\\Ruby186\\bin\\gem').and_return(true)
+ File.stub(:exists?).with('d:\\opscode\\chef\\bin\\gem').and_return(false) # should not get here
+ File.stub(:exists?).with('d:\\opscode\\chef\\embedded\\bin\\gem').and_return(false) # should not get here
provider = Chef::Provider::Package::Rubygems.new(@new_resource, @run_context)
provider.gem_env.gem_binary_location.should == 'C:\Ruby186\bin\gem'
end
@@ -475,7 +475,7 @@ describe Chef::Provider::Package::Rubygems do
@current_resource = Chef::Resource::GemPackage.new('rspec-core')
@provider.current_resource = @current_resource
@gem_dep = Gem::Dependency.new('rspec-core', @spec_version)
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
end
describe "in the current gem environment" do
@@ -508,7 +508,7 @@ describe Chef::Provider::Package::Rubygems do
# this catches 'gem_package "foo"' when "./foo" is a file in the cwd, and instead of installing './foo' it fetches the remote gem
it "installs the gem via the gems api, when the package has no file separator characters in it, but a matching file exists in cwd" do
- ::File.stub!(:exists?).and_return(true)
+ ::File.stub(:exists?).and_return(true)
@new_resource.package_name('rspec-core')
@provider.gem_env.should_receive(:install).with(@gem_dep, :sources => nil)
@provider.action_install.should be_true
diff --git a/spec/unit/provider/package/smartos_spec.rb b/spec/unit/provider/package/smartos_spec.rb
index 47db00988c..1c690acbf5 100644
--- a/spec/unit/provider/package/smartos_spec.rb
+++ b/spec/unit/provider/package/smartos_spec.rb
@@ -27,11 +27,11 @@ 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)
+
+
+ @status = double("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::SmartOS.new(@new_resource, @run_context)
- Chef::Resource::Package.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Package.stub(:new).and_return(@current_resource)
@stdin = StringIO.new
@stdout = "varnish-2.1.5nb2\n"
@stderr = StringIO.new
@@ -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 = double()
+ 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 = double('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/solaris_spec.rb b/spec/unit/provider/package/solaris_spec.rb
index dd7cea2aaa..086e327cce 100644
--- a/spec/unit/provider/package/solaris_spec.rb
+++ b/spec/unit/provider/package/solaris_spec.rb
@@ -27,7 +27,7 @@ describe Chef::Provider::Package::Solaris do
@new_resource.source("/tmp/bash.pkg")
@provider = Chef::Provider::Package::Solaris.new(@new_resource, @run_context)
- ::File.stub!(:exists?).and_return(true)
+ ::File.stub(:exists?).and_return(true)
end
describe "assessing the current package status" do
@@ -46,24 +46,24 @@ INSTDATE: Nov 04 2009 01:02
HOTLINE: Please contact your local service provider
PKGINFO
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
end
it "should create a current resource with the name of new_resource" do
- @provider.stub!(:popen4).and_return(@status)
+ @provider.stub(:popen4).and_return(@status)
@provider.load_current_resource
@provider.current_resource.name.should == "SUNWbash"
end
it "should set the current reource package name to the new resource package name" do
- @provider.stub!(:popen4).and_return(@status)
+ @provider.stub(:popen4).and_return(@status)
@provider.load_current_resource
@provider.current_resource.package_name.should == "SUNWbash"
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.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)
@@ -93,13 +93,13 @@ PKGINFO
it "should raise an exception if the source is not set but we are installing" do
@new_resource = Chef::Resource::Package.new("SUNWbash")
@provider = Chef::Provider::Package::Solaris.new(@new_resource, @run_context)
- @provider.stub!(:popen4).and_return(@status)
+ @provider.stub(:popen4).and_return(@status)
lambda { @provider.run_action(:install) }.should raise_error(Chef::Exceptions::Package)
end
it "should raise an exception if pkginfo fails to run" do
- @status = mock("Status", :exitstatus => -1)
- @provider.stub!(:popen4).and_return(@status)
+ @status = double("Status", :exitstatus => -1)
+ @provider.stub(:popen4).and_return(@status)
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package)
end
@@ -120,15 +120,15 @@ PKGINFO
end
it "should lookup the candidate_version if the variable is not already set" do
- @status = mock("Status", :exitstatus => 0)
- @provider.stub!(:popen4).and_return(@status)
+ @status = double("Status", :exitstatus => 0)
+ @provider.stub(:popen4).and_return(@status)
@provider.should_receive(:popen4)
@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)
+ @status = double("Status", :exitstatus => 1)
+ @provider.stub(:popen4).and_return(@status)
lambda { @provider.candidate_version }.should raise_error(Chef::Exceptions::Package)
end
@@ -153,7 +153,7 @@ PKGINFO
end
it "should run pkgadd -n -a /tmp/myadmin -d with the package options -a /tmp/myadmin" do
- @new_resource.stub!(:options).and_return("-a /tmp/myadmin")
+ @new_resource.stub(:options).and_return("-a /tmp/myadmin")
@provider.should_receive(:run_command_with_systems_locale).with({
:command => "pkgadd -n -a /tmp/myadmin -d /tmp/bash.pkg all"
})
@@ -170,7 +170,7 @@ PKGINFO
end
it "should run pkgrm -n -a /tmp/myadmin with options -a /tmp/myadmin" do
- @new_resource.stub!(:options).and_return("-a /tmp/myadmin")
+ @new_resource.stub(:options).and_return("-a /tmp/myadmin")
@provider.should_receive(:run_command_with_systems_locale).with({
:command => "pkgrm -n -a /tmp/myadmin SUNWbash"
})
diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb
index d2674f523d..adbcd86722 100644
--- a/spec/unit/provider/package/yum_spec.rb
+++ b/spec/unit/provider/package/yum_spec.rb
@@ -24,8 +24,8 @@ describe Chef::Provider::Package::Yum do
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
@new_resource = Chef::Resource::Package.new('cups')
- @status = mock("Status", :exitstatus => 0)
- @yum_cache = mock(
+ @status = double("Status", :exitstatus => 0)
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -37,9 +37,9 @@ describe Chef::Provider::Package::Yum do
:package_repository => "base",
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
- @pid = mock("PID")
+ @pid = double("PID")
end
describe "when loading the current system state" do
@@ -54,7 +54,7 @@ describe Chef::Provider::Package::Yum do
end
it "should set the installed version to nil on the current resource if no installed package" do
- @yum_cache.stub!(:installed_version).and_return(nil)
+ @yum_cache.stub(:installed_version).and_return(nil)
@provider.load_current_resource
@provider.current_resource.version.should be_nil
end
@@ -76,14 +76,14 @@ describe Chef::Provider::Package::Yum do
describe "when arch in package_name" do
it "should set the arch if no existing package_name is found and new_package_name+new_arch is available" do
@new_resource = Chef::Resource::YumPackage.new('testing.noarch')
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache'
)
- @yum_cache.stub!(:installed_version) do |package_name, arch|
+ @yum_cache.stub(:installed_version) do |package_name, arch|
# nothing installed for package_name/new_package_name
nil
end
- @yum_cache.stub!(:candidate_version) do |package_name, arch|
+ @yum_cache.stub(:candidate_version) do |package_name, arch|
if package_name == "testing.noarch" || package_name == "testing.more.noarch"
nil
# candidate for new_package_name
@@ -91,9 +91,9 @@ describe Chef::Provider::Package::Yum do
"1.1"
end
end
- @yum_cache.stub!(:package_available?).and_return(true)
- @yum_cache.stub!(:disable_extra_repo_control).and_return(true)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @yum_cache.stub(:package_available?).and_return(true)
+ @yum_cache.stub(:disable_extra_repo_control).and_return(true)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
@provider.new_resource.package_name.should == "testing"
@@ -110,10 +110,10 @@ describe Chef::Provider::Package::Yum do
it "should not set the arch when an existing package_name is found" do
@new_resource = Chef::Resource::YumPackage.new('testing.beta3')
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache'
)
- @yum_cache.stub!(:installed_version) do |package_name, arch|
+ @yum_cache.stub(:installed_version) do |package_name, arch|
# installed for package_name
if package_name == "testing.beta3" || package_name == "testing.beta3.more"
"1.1"
@@ -121,13 +121,13 @@ describe Chef::Provider::Package::Yum do
nil
end
end
- @yum_cache.stub!(:candidate_version) do |package_name, arch|
+ @yum_cache.stub(:candidate_version) do |package_name, arch|
# no candidate for package_name/new_package_name
nil
end
- @yum_cache.stub!(:package_available?).and_return(true)
- @yum_cache.stub!(:disable_extra_repo_control).and_return(true)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @yum_cache.stub(:package_available?).and_return(true)
+ @yum_cache.stub(:disable_extra_repo_control).and_return(true)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
# annoying side effect of the fun stub'ing above
@provider.load_current_resource
@@ -145,20 +145,20 @@ describe Chef::Provider::Package::Yum do
it "should not set the arch when no existing package_name or new_package_name+new_arch is found" do
@new_resource = Chef::Resource::YumPackage.new('testing.beta3')
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache'
)
- @yum_cache.stub!(:installed_version) do |package_name, arch|
+ @yum_cache.stub(:installed_version) do |package_name, arch|
# nothing installed for package_name/new_package_name
nil
end
- @yum_cache.stub!(:candidate_version) do |package_name, arch|
+ @yum_cache.stub(:candidate_version) do |package_name, arch|
# no candidate for package_name/new_package_name
nil
end
- @yum_cache.stub!(:package_available?).and_return(true)
- @yum_cache.stub!(:disable_extra_repo_control).and_return(true)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @yum_cache.stub(:package_available?).and_return(true)
+ @yum_cache.stub(:disable_extra_repo_control).and_return(true)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
@provider.new_resource.package_name.should == "testing.beta3"
@@ -176,14 +176,14 @@ describe Chef::Provider::Package::Yum do
it "should ensure it doesn't clobber an existing arch if passed" do
@new_resource = Chef::Resource::YumPackage.new('testing.i386')
@new_resource.arch("x86_64")
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache'
)
- @yum_cache.stub!(:installed_version) do |package_name, arch|
+ @yum_cache.stub(:installed_version) do |package_name, arch|
# nothing installed for package_name/new_package_name
nil
end
- @yum_cache.stub!(:candidate_version) do |package_name, arch|
+ @yum_cache.stub(:candidate_version) do |package_name, arch|
if package_name == "testing.noarch"
nil
# candidate for new_package_name
@@ -191,9 +191,9 @@ describe Chef::Provider::Package::Yum do
"1.1"
end
end.and_return("something")
- @yum_cache.stub!(:package_available?).and_return(true)
- @yum_cache.stub!(:disable_extra_repo_control).and_return(true)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @yum_cache.stub(:package_available?).and_return(true)
+ @yum_cache.stub(:disable_extra_repo_control).and_return(true)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
@provider.new_resource.package_name.should == "testing.i386"
@@ -202,37 +202,37 @@ describe Chef::Provider::Package::Yum do
end
it "should flush the cache if :before is true" do
- @new_resource.stub!(:flush_cache).and_return({:after => false, :before => true})
+ @new_resource.stub(:flush_cache).and_return({:after => false, :before => true})
@yum_cache.should_receive(:reload).once
@provider.load_current_resource
end
it "should flush the cache if :before is false" do
- @new_resource.stub!(:flush_cache).and_return({:after => false, :before => false})
+ @new_resource.stub(:flush_cache).and_return({:after => false, :before => false})
@yum_cache.should_not_receive(:reload)
@provider.load_current_resource
end
it "should detect --enablerepo or --disablerepo when passed among options, collect them preserving order and notify the yum cache" do
- @new_resource.stub!(:options).and_return("--stuff --enablerepo=foo --otherthings --disablerepo=a,b,c --enablerepo=bar")
+ @new_resource.stub(:options).and_return("--stuff --enablerepo=foo --otherthings --disablerepo=a,b,c --enablerepo=bar")
@yum_cache.should_receive(:enable_extra_repo_control).with("--enablerepo=foo --disablerepo=a,b,c --enablerepo=bar")
@provider.load_current_resource
end
it "should let the yum cache know extra repos are disabled if --enablerepo or --disablerepo aren't among options" do
- @new_resource.stub!(:options).and_return("--stuff --otherthings")
+ @new_resource.stub(:options).and_return("--stuff --otherthings")
@yum_cache.should_receive(:disable_extra_repo_control)
@provider.load_current_resource
end
it "should let the yum cache know extra repos are disabled if options aren't set" do
- @new_resource.stub!(:options).and_return(nil)
+ @new_resource.stub(:options).and_return(nil)
@yum_cache.should_receive(:disable_extra_repo_control)
@provider.load_current_resource
end
it "should search provides if package name can't be found then set package_name to match" do
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -242,7 +242,7 @@ describe Chef::Provider::Package::Yum do
:version_available? => true,
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
pkg = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "1.2.4-11.18.el5", "x86_64", [])
@yum_cache.should_receive(:packages_from_require).and_return([pkg])
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@@ -251,7 +251,7 @@ describe Chef::Provider::Package::Yum do
end
it "should search provides if package name can't be found, warn about multiple matches, but use the first one" do
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -261,7 +261,7 @@ describe Chef::Provider::Package::Yum do
:version_available? => true,
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
pkg_x = Chef::Provider::Package::Yum::RPMPackage.new("test-package-x", "1.2.4-11.18.el5", "x86_64", [])
pkg_y = Chef::Provider::Package::Yum::RPMPackage.new("test-package-y", "1.2.6-11.3.el5", "i386", [])
@yum_cache.should_receive(:packages_from_require).and_return([pkg_x, pkg_y])
@@ -272,7 +272,7 @@ describe Chef::Provider::Package::Yum do
end
it "should search provides if no package is available - if no match in installed provides then load the complete set" do
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -282,7 +282,7 @@ describe Chef::Provider::Package::Yum do
:version_available? => true,
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@yum_cache.should_receive(:packages_from_require).twice.and_return([])
@yum_cache.should_receive(:reload_provides)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@@ -290,7 +290,7 @@ describe Chef::Provider::Package::Yum do
end
it "should search provides if no package is available and not load the complete set if action is :remove or :purge" do
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -300,7 +300,7 @@ describe Chef::Provider::Package::Yum do
:version_available? => true,
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@yum_cache.should_receive(:packages_from_require).once.and_return([])
@yum_cache.should_not_receive(:reload_provides)
@@ -313,7 +313,7 @@ describe Chef::Provider::Package::Yum do
end
it "should search provides if no package is available - if no match in provides leave the name intact" do
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_provides => true,
:reload_installed => true,
@@ -324,7 +324,7 @@ describe Chef::Provider::Package::Yum do
:version_available? => true,
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@yum_cache.should_receive(:packages_from_require).twice.and_return([])
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
@@ -335,7 +335,7 @@ describe Chef::Provider::Package::Yum do
describe "when installing a package" do
it "should run yum install with the package name and version" do
@provider.load_current_resource
- Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ Chef::Provider::Package::Yum::RPMUtils.stub(:rpmvercmp).and_return(-1)
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y install emacs-1.0"
)
@@ -343,7 +343,7 @@ describe Chef::Provider::Package::Yum do
end
it "should run yum localinstall if given a path to an rpm" do
- @new_resource.stub!(:source).and_return("/tmp/emacs-21.4-20.el5.i386.rpm")
+ @new_resource.stub(:source).and_return("/tmp/emacs-21.4-20.el5.i386.rpm")
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y localinstall /tmp/emacs-21.4-20.el5.i386.rpm"
)
@@ -352,7 +352,7 @@ describe Chef::Provider::Package::Yum do
it "should run yum localinstall if given a path to an rpm as the package" do
@new_resource = Chef::Resource::Package.new("/tmp/emacs-21.4-20.el5.i386.rpm")
- ::File.stub!(:exists?).and_return(true)
+ ::File.stub(:exists?).and_return(true)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@new_resource.source.should == "/tmp/emacs-21.4-20.el5.i386.rpm"
@provider.should_receive(:yum_command).with(
@@ -363,8 +363,8 @@ describe Chef::Provider::Package::Yum do
it "should run yum install with the package name, version and arch" do
@provider.load_current_resource
- @new_resource.stub!(:arch).and_return("i386")
- Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @new_resource.stub(:arch).and_return("i386")
+ Chef::Provider::Package::Yum::RPMUtils.stub(:rpmvercmp).and_return(-1)
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y install emacs-21.4-20.el5.i386"
)
@@ -374,8 +374,8 @@ describe Chef::Provider::Package::Yum do
it "installs the package with the options given in the resource" do
@provider.load_current_resource
@provider.candidate_version = '11'
- @new_resource.stub!(:options).and_return("--disablerepo epmd")
- Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @new_resource.stub(:options).and_return("--disablerepo epmd")
+ Chef::Provider::Package::Yum::RPMUtils.stub(:rpmvercmp).and_return(-1)
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y --disablerepo epmd install cups-11"
)
@@ -383,7 +383,7 @@ describe Chef::Provider::Package::Yum do
end
it "should raise an exception if the package is not available" do
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_from_cache => true,
:reset => true,
@@ -393,14 +393,14 @@ describe Chef::Provider::Package::Yum do
:version_available? => nil,
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
lambda { @provider.install_package("lolcats", "0.99") }.should raise_error(Chef::Exceptions::Package, %r{Version .* not found})
end
it "should raise an exception if candidate version is older than the installed version and allow_downgrade is false" do
- @new_resource.stub!(:allow_downgrade).and_return(false)
- @yum_cache = mock(
+ @new_resource.stub(:allow_downgrade).and_return(false)
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -411,14 +411,14 @@ describe Chef::Provider::Package::Yum do
:allow_multi_install => [ "kernel" ],
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
lambda { @provider.install_package("cups", "1.2.4-11.15.el5") }.should raise_error(Chef::Exceptions::Package, %r{is newer than candidate package})
end
it "should not raise an exception if candidate version is older than the installed version and the package is list in yum's installonlypkg option" do
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -430,7 +430,7 @@ describe Chef::Provider::Package::Yum do
:package_repository => "base",
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
@provider.should_receive(:yum_command).with(
@@ -440,8 +440,8 @@ describe Chef::Provider::Package::Yum do
end
it "should run yum downgrade if candidate version is older than the installed version and allow_downgrade is true" do
- @new_resource.stub!(:allow_downgrade).and_return(true)
- @yum_cache = mock(
+ @new_resource.stub(:allow_downgrade).and_return(true)
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -453,7 +453,7 @@ describe Chef::Provider::Package::Yum do
:package_repository => "base",
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
@provider.should_receive(:yum_command).with(
@@ -463,9 +463,9 @@ describe Chef::Provider::Package::Yum do
end
it "should run yum install then flush the cache if :after is true" do
- @new_resource.stub!(:flush_cache).and_return({:after => true, :before => false})
+ @new_resource.stub(:flush_cache).and_return({:after => true, :before => false})
@provider.load_current_resource
- Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ Chef::Provider::Package::Yum::RPMUtils.stub(:rpmvercmp).and_return(-1)
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y install emacs-1.0"
)
@@ -474,9 +474,9 @@ describe Chef::Provider::Package::Yum do
end
it "should run yum install then not flush the cache if :after is false" do
- @new_resource.stub!(:flush_cache).and_return({:after => false, :before => false})
+ @new_resource.stub(:flush_cache).and_return({:after => false, :before => false})
@provider.load_current_resource
- Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ Chef::Provider::Package::Yum::RPMUtils.stub(:rpmvercmp).and_return(-1)
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y install emacs-1.0"
)
@@ -489,7 +489,7 @@ describe Chef::Provider::Package::Yum do
it "should run yum install if the package is installed and a version is given" do
@provider.load_current_resource
@provider.candidate_version = '11'
- Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ Chef::Provider::Package::Yum::RPMUtils.stub(:rpmvercmp).and_return(-1)
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y install cups-11"
)
@@ -500,7 +500,7 @@ describe Chef::Provider::Package::Yum do
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
@provider.candidate_version = '11'
- Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ Chef::Provider::Package::Yum::RPMUtils.stub(:rpmvercmp).and_return(-1)
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y install cups-11"
)
@@ -508,7 +508,7 @@ describe Chef::Provider::Package::Yum do
end
it "should raise an exception if candidate version is older than the installed version" do
- @yum_cache = mock(
+ @yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
:reset => true,
@@ -519,7 +519,7 @@ describe Chef::Provider::Package::Yum do
:allow_multi_install => [ "kernel" ],
:disable_extra_repo_control => true
)
- Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ Chef::Provider::Package::Yum::YumCache.stub(:instance).and_return(@yum_cache)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
lambda { @provider.upgrade_package("cups", "1.2.4-11.15.el5") }.should raise_error(Chef::Exceptions::Package, %r{is newer than candidate package})
@@ -527,7 +527,7 @@ describe Chef::Provider::Package::Yum do
# Test our little workaround, some crossover into Chef::Provider::Package territory
it "should call action_upgrade in the parent if the current resource version is nil" do
- @yum_cache.stub!(:installed_version).and_return(nil)
+ @yum_cache.stub(:installed_version).and_return(nil)
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
@provider.candidate_version = '11'
@@ -558,7 +558,7 @@ describe Chef::Provider::Package::Yum do
end
it "should not call action_upgrade in the parent if the candidate is older" do
- @yum_cache.stub!(:installed_version).and_return("12")
+ @yum_cache.stub(:installed_version).and_return("12")
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
@provider.candidate_version = '11'
@@ -576,7 +576,7 @@ describe Chef::Provider::Package::Yum do
end
it "should run yum remove with the package name and arch" do
- @new_resource.stub!(:arch).and_return("x86_64")
+ @new_resource.stub(:arch).and_return("x86_64")
@provider.should_receive(:yum_command).with(
"yum -d0 -e0 -y remove emacs-1.0.x86_64"
)
@@ -595,8 +595,8 @@ describe Chef::Provider::Package::Yum do
describe "when running yum" do
it "should run yum once if it exits with a return code of 0" do
- @status = mock("Status", :exitstatus => 0)
- @provider.stub!(:output_of_command).and_return([@status, "", ""])
+ @status = double("Status", :exitstatus => 0)
+ @provider.stub(:output_of_command).and_return([@status, "", ""])
@provider.should_receive(:output_of_command).once.with(
"yum -d0 -e0 -y install emacs-1.0",
{:timeout => Chef::Config[:yum_timeout]}
@@ -605,8 +605,8 @@ describe Chef::Provider::Package::Yum do
end
it "should run yum once if it exits with a return code > 0 and no scriptlet failures" do
- @status = mock("Status", :exitstatus => 2)
- @provider.stub!(:output_of_command).and_return([@status, "failure failure", "problem problem"])
+ @status = double("Status", :exitstatus => 2)
+ @provider.stub(:output_of_command).and_return([@status, "failure failure", "problem problem"])
@provider.should_receive(:output_of_command).once.with(
"yum -d0 -e0 -y install emacs-1.0",
{:timeout => Chef::Config[:yum_timeout]}
@@ -615,8 +615,8 @@ describe Chef::Provider::Package::Yum do
end
it "should run yum once if it exits with a return code of 1 and %pre scriptlet failures" do
- @status = mock("Status", :exitstatus => 1)
- @provider.stub!(:output_of_command).and_return([@status, "error: %pre(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", ""])
+ @status = double("Status", :exitstatus => 1)
+ @provider.stub(:output_of_command).and_return([@status, "error: %pre(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", ""])
@provider.should_receive(:output_of_command).once.with(
"yum -d0 -e0 -y install emacs-1.0",
{:timeout => Chef::Config[:yum_timeout]}
@@ -626,8 +626,8 @@ describe Chef::Provider::Package::Yum do
end
it "should run yum twice if it exits with a return code of 1 and %post scriptlet failures" do
- @status = mock("Status", :exitstatus => 1)
- @provider.stub!(:output_of_command).and_return([@status, "error: %post(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", ""])
+ @status = double("Status", :exitstatus => 1)
+ @provider.stub(:output_of_command).and_return([@status, "error: %post(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", ""])
@provider.should_receive(:output_of_command).twice.with(
"yum -d0 -e0 -y install emacs-1.0",
{:timeout => Chef::Config[:yum_timeout]}
@@ -1543,8 +1543,8 @@ describe Chef::Provider::Package::Yum::YumCache do
end
before(:each) do
- @stdin = mock("STDIN", :nil_object => true)
- @stdout = mock("STDOUT", :nil_object => true)
+ @stdin = double("STDIN", :nil_object => true)
+ @stdout = double("STDOUT", :nil_object => true)
@stdout_good = <<EOF
[option installonlypkgs] kernel kernel-bigmem kernel-enterprise
@@ -1586,13 +1586,13 @@ yum-dump Config Error: File contains no section headers.
file: file://///etc/yum.repos.d/CentOS-Base.repo, line: 12
'qeqwewe\n'
EOF
- @status = mock("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_good, :stderr => @stderr)
+ @status = double("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_good, :stderr => @stderr)
# new singleton each time
Chef::Provider::Package::Yum::YumCache.reset_instance
@yc = Chef::Provider::Package::Yum::YumCache.instance
# load valid data
- @yc.stub!(:shell_out!).and_return(@status)
+ @yc.stub(:shell_out!).and_return(@status)
end
describe "initialize" do
@@ -1642,29 +1642,29 @@ EOF
end
it "should warn about invalid data with too many separators" do
- @status = mock("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_bad_separators, :stderr => @stderr)
- @yc.stub!(:shell_out!).and_return(@status)
+ @status = double("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_bad_separators, :stderr => @stderr)
+ @yc.stub(:shell_out!).and_return(@status)
Chef::Log.should_receive(:warn).exactly(3).times.with(%r{Problem parsing})
@yc.refresh
end
it "should warn about invalid data with an incorrect type" do
- @status = mock("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_bad_type, :stderr => @stderr)
- @yc.stub!(:shell_out!).and_return(@status)
+ @status = double("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_bad_type, :stderr => @stderr)
+ @yc.stub(:shell_out!).and_return(@status)
Chef::Log.should_receive(:warn).exactly(2).times.with(%r{Problem parsing})
@yc.refresh
end
it "should warn about no output from yum-dump.py" do
- @status = mock("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_no_output, :stderr => @stderr)
- @yc.stub!(:shell_out!).and_return(@status)
+ @status = double("Status", :exitstatus => 0, :stdin => @stdin, :stdout => @stdout_no_output, :stderr => @stderr)
+ @yc.stub(:shell_out!).and_return(@status)
Chef::Log.should_receive(:warn).exactly(1).times.with(%r{no output from yum-dump.py})
@yc.refresh
end
it "should raise exception yum-dump.py exits with a non zero status" do
- @status = mock("Status", :exitstatus => 1, :stdin => @stdin, :stdout => @stdout_no_output, :stderr => @stderr)
- @yc.stub!(:shell_out!).and_return(@status)
+ @status = double("Status", :exitstatus => 1, :stdin => @stdin, :stdout => @stdout_no_output, :stderr => @stderr)
+ @yc.stub(:shell_out!).and_return(@status)
lambda { @yc.refresh}.should raise_error(Chef::Exceptions::Package, %r{CentOS-Base.repo, line: 12})
end
@@ -1690,8 +1690,8 @@ EOF
describe "installed_version" do
it "should take one or two arguments" do
- lambda { @yc.installed_version("zip") }.should_not raise_error(ArgumentError)
- lambda { @yc.installed_version("zip", "i386") }.should_not raise_error(ArgumentError)
+ lambda { @yc.installed_version("zip") }.should_not raise_error
+ lambda { @yc.installed_version("zip", "i386") }.should_not raise_error
lambda { @yc.installed_version("zip", "i386", "extra") }.should raise_error(ArgumentError)
end
@@ -1714,8 +1714,8 @@ EOF
describe "available_version" do
it "should take one or two arguments" do
- lambda { @yc.available_version("zisofs-tools") }.should_not raise_error(ArgumentError)
- lambda { @yc.available_version("zisofs-tools", "i386") }.should_not raise_error(ArgumentError)
+ lambda { @yc.available_version("zisofs-tools") }.should_not raise_error
+ lambda { @yc.available_version("zisofs-tools", "i386") }.should_not raise_error
lambda { @yc.available_version("zisofs-tools", "i386", "extra") }.should raise_error(ArgumentError)
end
@@ -1739,8 +1739,8 @@ EOF
describe "version_available?" do
it "should take two or three arguments" do
lambda { @yc.version_available?("zisofs-tools") }.should raise_error(ArgumentError)
- lambda { @yc.version_available?("zisofs-tools", "1.0.6-3.2.2") }.should_not raise_error(ArgumentError)
- lambda { @yc.version_available?("zisofs-tools", "1.0.6-3.2.2", "x86_64") }.should_not raise_error(ArgumentError)
+ lambda { @yc.version_available?("zisofs-tools", "1.0.6-3.2.2") }.should_not raise_error
+ lambda { @yc.version_available?("zisofs-tools", "1.0.6-3.2.2", "x86_64") }.should_not raise_error
end
it "should return true if our package-version-arch is available" do
@@ -1768,8 +1768,8 @@ EOF
describe "package_repository" do
it "should take two or three arguments" do
lambda { @yc.package_repository("zisofs-tools") }.should raise_error(ArgumentError)
- lambda { @yc.package_repository("zisofs-tools", "1.0.6-3.2.2") }.should_not raise_error(ArgumentError)
- lambda { @yc.package_repository("zisofs-tools", "1.0.6-3.2.2", "x86_64") }.should_not raise_error(ArgumentError)
+ lambda { @yc.package_repository("zisofs-tools", "1.0.6-3.2.2") }.should_not raise_error
+ lambda { @yc.package_repository("zisofs-tools", "1.0.6-3.2.2", "x86_64") }.should_not raise_error
end
it "should return repoid for package-version-arch" do
diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb
index cf0193993d..c437631309 100644
--- a/spec/unit/provider/package/zypper_spec.rb
+++ b/spec/unit/provider/package/zypper_spec.rb
@@ -27,15 +27,15 @@ describe Chef::Provider::Package::Zypper do
@current_resource = Chef::Resource::Package.new("cups")
- @status = mock("Status", :exitstatus => 0)
+ @status = double("Status", :exitstatus => 0)
@provider = Chef::Provider::Package::Zypper.new(@new_resource, @run_context)
- Chef::Resource::Package.stub!(:new).and_return(@current_resource)
- @provider.stub!(:popen4).and_return(@status)
+ Chef::Resource::Package.stub(:new).and_return(@current_resource)
+ @provider.stub(:popen4).and_return(@status)
@stderr = StringIO.new
@stdout = StringIO.new
- @pid = mock("PID")
- @provider.stub!(:`).and_return("2.0")
+ @pid = double("PID")
+ @provider.stub(:`).and_return("2.0")
end
describe "when loading the current package state" do
@@ -55,14 +55,14 @@ describe Chef::Provider::Package::Zypper do
end
it "should set the installed version to nil on the current resource if zypper info installed version is (none)" do
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@current_resource.should_receive(:version).with(nil).and_return(true)
@provider.load_current_resource
end
it "should set the installed version if zypper info has one" do
@stdout = StringIO.new("Version: 1.0\nInstalled: Yes\n")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@current_resource.should_receive(:version).with("1.0").and_return(true)
@provider.load_current_resource
end
@@ -70,7 +70,7 @@ describe Chef::Provider::Package::Zypper do
it "should set the candidate version if zypper info has one" do
@stdout = StringIO.new("Version: 1.0\nInstalled: No\nStatus: out-of-date (version 0.9 installed)")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@provider.candidate_version.should eql("1.0")
end
@@ -82,7 +82,7 @@ describe Chef::Provider::Package::Zypper do
it "should not raise an exception if zypper info succeeds" do
@status.should_receive(:exitstatus).and_return(0)
- lambda { @provider.load_current_resource }.should_not raise_error(Chef::Exceptions::Package)
+ lambda { @provider.load_current_resource }.should_not raise_error
end
it "should return the current resouce" do
@@ -191,7 +191,7 @@ describe Chef::Provider::Package::Zypper do
describe "on an older zypper" do
before(:each) do
- @provider.stub!(:`).and_return("0.11.6")
+ @provider.stub(:`).and_return("0.11.6")
end
describe "install_package" do
diff --git a/spec/unit/provider/package_spec.rb b/spec/unit/provider/package_spec.rb
index 85aab981e8..33b4f8186a 100644
--- a/spec/unit/provider/package_spec.rb
+++ b/spec/unit/provider/package_spec.rb
@@ -34,7 +34,7 @@ describe Chef::Provider::Package do
describe "when installing a package" do
before(:each) do
@provider.current_resource = @current_resource
- @provider.stub!(:install_package).and_return(true)
+ @provider.stub(:install_package).and_return(true)
end
it "should raise a Chef::Exceptions::Package if no version is specified, and no candidate is available" do
@@ -81,7 +81,7 @@ describe Chef::Provider::Package do
it "should install the package at the version specified if a different version is installed" do
@new_resource.version("1.0")
- @current_resource.stub!(:version).and_return("0.99")
+ @current_resource.stub(:version).and_return("0.99")
@provider.should_receive(:install_package).with(
@new_resource.name,
@new_resource.version
@@ -107,7 +107,7 @@ describe Chef::Provider::Package do
it "should call the candidate_version accessor only once if the package is already installed and no version is specified" do
@current_resource.version("1.0")
- @provider.stub!(:candidate_version).and_return("1.0")
+ @provider.stub(:candidate_version).and_return("1.0")
@provider.run_action(:install)
end
@@ -126,7 +126,7 @@ describe Chef::Provider::Package do
describe "when upgrading the package" do
before(:each) do
- @provider.stub!(:upgrade_package).and_return(true)
+ @provider.stub(:upgrade_package).and_return(true)
end
it "should upgrade the package if the current version is not the candidate version" do
@@ -151,14 +151,14 @@ describe Chef::Provider::Package do
end
it "should print the word 'uninstalled' if there was no original version" do
- @current_resource.stub!(:version).and_return(nil)
+ @current_resource.stub(:version).and_return(nil)
Chef::Log.should_receive(:info).with("package[emacs] upgraded from uninstalled to 1.0")
@provider.run_action(:upgrade)
@new_resource.should be_updated_by_last_action
end
it "should raise a Chef::Exceptions::Package if current version and candidate are nil" do
- @current_resource.stub!(:version).and_return(nil)
+ @current_resource.stub(:version).and_return(nil)
@provider.candidate_version = nil
lambda { @provider.run_action(:upgrade) }.should raise_error(Chef::Exceptions::Package)
end
@@ -174,7 +174,7 @@ describe Chef::Provider::Package do
describe "When removing the package" do
before(:each) do
- @provider.stub!(:remove_package).and_return(true)
+ @provider.stub(:remove_package).and_return(true)
@current_resource.version '1.4.2'
end
@@ -204,7 +204,7 @@ describe Chef::Provider::Package do
it "should not remove the package if it is not installed" do
@provider.should_not_receive(:remove_package)
- @current_resource.stub!(:version).and_return(nil)
+ @current_resource.stub(:version).and_return(nil)
@provider.run_action(:remove)
@new_resource.should_not be_updated_by_last_action
end
@@ -218,7 +218,7 @@ describe Chef::Provider::Package do
describe "When purging the package" do
before(:each) do
- @provider.stub!(:purge_package).and_return(true)
+ @provider.stub(:purge_package).and_return(true)
@current_resource.version '1.4.2'
end
@@ -264,15 +264,15 @@ describe Chef::Provider::Package do
describe "when reconfiguring the package" do
before(:each) do
- @provider.stub!(:reconfig_package).and_return(true)
+ @provider.stub(:reconfig_package).and_return(true)
end
it "should info log, reconfigure the package and update the resource" do
- @current_resource.stub!(:version).and_return('1.0')
- @new_resource.stub!(:response_file).and_return(true)
+ @current_resource.stub(:version).and_return('1.0')
+ @new_resource.stub(:response_file).and_return(true)
@provider.should_receive(:get_preseed_file).and_return('/var/cache/preseed-test')
- @provider.stub!(:preseed_package).and_return(true)
- @provider.stub!(:reconfig_package).and_return(true)
+ @provider.stub(:preseed_package).and_return(true)
+ @provider.stub(:reconfig_package).and_return(true)
Chef::Log.should_receive(:info).with("package[emacs] reconfigured")
@provider.should_receive(:reconfig_package)
@provider.run_action(:reconfig)
@@ -281,16 +281,16 @@ describe Chef::Provider::Package do
end
it "should debug log and not reconfigure the package if the package is not installed" do
- @current_resource.stub!(:version).and_return(nil)
+ @current_resource.stub(:version).and_return(nil)
Chef::Log.should_receive(:debug).with("package[emacs] is NOT installed - nothing to 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')
- @new_resource.stub!(:response_file).and_return(nil)
+ @current_resource.stub(:version).and_return('1.0')
+ @new_resource.stub(:response_file).and_return(nil)
Chef::Log.should_receive(:debug).with("package[emacs] no response_file provided - nothing to do")
@provider.should_not_receive(:reconfig_package)
@provider.run_action(:reconfig)
@@ -298,10 +298,10 @@ describe Chef::Provider::Package do
end
it "should debug log and not reconfigure the package if the response_file has not changed" do
- @current_resource.stub!(:version).and_return('1.0')
- @new_resource.stub!(:response_file).and_return(true)
+ @current_resource.stub(:version).and_return('1.0')
+ @new_resource.stub(:response_file).and_return(true)
@provider.should_receive(:get_preseed_file).and_return(false)
- @provider.stub!(:preseed_package).and_return(false)
+ @provider.stub(:preseed_package).and_return(false)
Chef::Log.should_receive(:debug).with("package[emacs] preseeding has not changed - nothing to do")
@provider.should_not_receive(:reconfig_package)
@provider.run_action(:reconfig)
@@ -362,7 +362,7 @@ describe Chef::Provider::Package do
end
it "sets the preseed resource's runcontext to its own run context" do
- Chef::FileCache.stub!(:create_cache_path).and_return("/tmp/preseed/java")
+ 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)
end
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/registry_key_spec.rb b/spec/unit/provider/registry_key_spec.rb
index 2f6f8179e6..f88d4c0a87 100644
--- a/spec/unit/provider/registry_key_spec.rb
+++ b/spec/unit/provider/registry_key_spec.rb
@@ -38,9 +38,9 @@ describe Chef::Provider::RegistryKey do
@provider = Chef::Provider::RegistryKey.new(@new_resource, @run_context)
- @provider.stub!(:running_on_windows!).and_return(true)
+ @provider.stub(:running_on_windows!).and_return(true)
@double_registry = double(Chef::Win32::Registry)
- @provider.stub!(:registry).and_return(@double_registry)
+ @provider.stub(:registry).and_return(@double_registry)
end
describe "when first created" do
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/cache_control_data_spec.rb b/spec/unit/provider/remote_file/cache_control_data_spec.rb
index ee29e21890..2ae3c41214 100644
--- a/spec/unit/provider/remote_file/cache_control_data_spec.rb
+++ b/spec/unit/provider/remote_file/cache_control_data_spec.rb
@@ -19,6 +19,15 @@
require 'spec_helper'
require 'uri'
+CACHE_FILE_TRUNCATED_FRIENDLY_FILE_NAME_LENGTH = 64
+CACHE_FILE_MD5_HEX_LENGTH = 32
+CACHE_FILE_JSON_FILE_EXTENSION_LENGTH = 5
+CACHE_FILE_PATH_LIMIT =
+ CACHE_FILE_TRUNCATED_FRIENDLY_FILE_NAME_LENGTH +
+ 1 +
+ CACHE_FILE_MD5_HEX_LENGTH +
+ CACHE_FILE_JSON_FILE_EXTENSION_LENGTH # {friendly}-{md5hex}.json == 102
+
describe Chef::Provider::RemoteFile::CacheControlData do
let(:uri) { URI.parse("http://www.google.com/robots.txt") }
@@ -164,6 +173,38 @@ describe Chef::Provider::RemoteFile::CacheControlData do
cache_control_data.save
end
end
+
+ # Cover the very long remote file path case -- see CHEF-4422 where
+ # local cache file names generated from the long uri exceeded
+ # local file system path limits resulting in exceptions from
+ # file system API's on both Windows and Unix systems.
+ context "and the URI results in a file cache path that exceeds #{CACHE_FILE_PATH_LIMIT} characters in length" do
+ let(:long_remote_path) { "http://www.bing.com/" + ('0' * (CACHE_FILE_TRUNCATED_FRIENDLY_FILE_NAME_LENGTH * 2 )) }
+ let(:uri) { URI.parse(long_remote_path) }
+ let(:truncated_remote_uri) { URI.parse(long_remote_path[0...CACHE_FILE_TRUNCATED_FRIENDLY_FILE_NAME_LENGTH]) }
+ let(:truncated_file_cache_path) do
+ cache_control_data_truncated = Chef::Provider::RemoteFile::CacheControlData.load_and_validate(truncated_remote_uri, current_file_checksum)
+ cache_control_data_truncated.send('sanitized_cache_file_basename')[0...CACHE_FILE_TRUNCATED_FRIENDLY_FILE_NAME_LENGTH]
+ end
+
+ it "truncates the file cache path to 102 characters" do
+ normalized_cache_path = cache_control_data.send('sanitized_cache_file_basename')
+
+ Chef::FileCache.should_receive(:store).with("remote_file/" + normalized_cache_path, cache_control_data.json_data)
+
+ cache_control_data.save
+
+ normalized_cache_path.length.should == CACHE_FILE_PATH_LIMIT
+ end
+
+ it "uses a file cache path that starts with the first #{CACHE_FILE_TRUNCATED_FRIENDLY_FILE_NAME_LENGTH} characters of the URI" do
+ normalized_cache_path = cache_control_data.send('sanitized_cache_file_basename')
+
+ truncated_file_cache_path.length.should == CACHE_FILE_TRUNCATED_FRIENDLY_FILE_NAME_LENGTH
+ normalized_cache_path.start_with?(truncated_file_cache_path).should == true
+ end
+ end
+
end
end
diff --git a/spec/unit/provider/remote_file/content_spec.rb b/spec/unit/provider/remote_file/content_spec.rb
index 36ecfe1c8d..0f311dc0ec 100644
--- a/spec/unit/provider/remote_file/content_spec.rb
+++ b/spec/unit/provider/remote_file/content_spec.rb
@@ -36,7 +36,7 @@ describe Chef::Provider::RemoteFile::Content do
r
end
- let(:run_context) { mock("Chef::RunContext") }
+ let(:run_context) { double("Chef::RunContext") }
#
# subject
@@ -47,8 +47,8 @@ describe Chef::Provider::RemoteFile::Content do
describe "when the checksum of the current_resource matches the checksum set on the resource" do
before do
- new_resource.stub!(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
- current_resource.stub!(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
+ new_resource.stub(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
+ current_resource.stub(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
end
it "should return nil for the tempfile" do
@@ -62,8 +62,8 @@ describe Chef::Provider::RemoteFile::Content do
describe "when the checksum of the current_resource is a partial match for the checksum set on the resource" do
before do
- new_resource.stub!(:checksum).and_return("0fd012fd")
- current_resource.stub!(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
+ new_resource.stub(:checksum).and_return("0fd012fd")
+ current_resource.stub(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
end
it "should return nil for the tempfile" do
@@ -78,13 +78,13 @@ describe Chef::Provider::RemoteFile::Content do
shared_examples_for "the resource needs fetching" do
before do
# FIXME: test one or the other nil, test both not nil and not equal, abuse the regexp a little
- @uri = mock("URI")
+ @uri = double("URI")
URI.should_receive(:parse).with(new_resource.source[0]).and_return(@uri)
end
describe "when the fetcher returns nil for the tempfile" do
before do
- http_fetcher = mock("Chef::Provider::RemoteFile::HTTP", :fetch => nil)
+ http_fetcher = double("Chef::Provider::RemoteFile::HTTP", :fetch => nil)
Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri, new_resource, current_resource).and_return(http_fetcher)
end
@@ -96,8 +96,8 @@ describe Chef::Provider::RemoteFile::Content do
describe "when the fetcher returns a valid tempfile" do
let(:mtime) { Time.now }
- let(:tempfile) { mock("Tempfile") }
- let(:http_fetcher) { mock("Chef::Provider::RemoteFile::HTTP", :fetch => tempfile) }
+ let(:tempfile) { double("Tempfile") }
+ let(:http_fetcher) { double("Chef::Provider::RemoteFile::HTTP", :fetch => tempfile) }
before do
Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri, new_resource, current_resource).and_return(http_fetcher)
@@ -119,24 +119,24 @@ describe Chef::Provider::RemoteFile::Content do
describe "when the current_resource checksum is nil" do
before do
- new_resource.stub!(:checksum).and_return("fd012fd")
- current_resource.stub!(:checksum).and_return(nil)
+ new_resource.stub(:checksum).and_return("fd012fd")
+ current_resource.stub(:checksum).and_return(nil)
end
it_behaves_like "the resource needs fetching"
end
describe "when the new_resource checksum is nil" do
before do
- new_resource.stub!(:checksum).and_return(nil)
- current_resource.stub!(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
+ new_resource.stub(:checksum).and_return(nil)
+ current_resource.stub(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
end
it_behaves_like "the resource needs fetching"
end
describe "when the checksums are a partial match, but not to the leading portion" do
before do
- new_resource.stub!(:checksum).and_return("fd012fd")
- current_resource.stub!(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
+ new_resource.stub(:checksum).and_return("fd012fd")
+ current_resource.stub(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
end
it_behaves_like "the resource needs fetching"
end
@@ -144,11 +144,11 @@ describe Chef::Provider::RemoteFile::Content do
describe "when the fetcher throws an exception" do
before do
- new_resource.stub!(:checksum).and_return(nil)
- current_resource.stub!(:checksum).and_return(nil)
- @uri = mock("URI")
+ new_resource.stub(:checksum).and_return(nil)
+ current_resource.stub(:checksum).and_return(nil)
+ @uri = double("URI")
URI.should_receive(:parse).with(new_resource.source[0]).and_return(@uri)
- http_fetcher = mock("Chef::Provider::RemoteFile::HTTP")
+ http_fetcher = double("Chef::Provider::RemoteFile::HTTP")
http_fetcher.should_receive(:fetch).and_raise(Errno::ECONNREFUSED)
Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri, new_resource, current_resource).and_return(http_fetcher)
end
@@ -162,22 +162,22 @@ describe Chef::Provider::RemoteFile::Content do
let(:source) { [ "http://opscode.com/seattle.txt", "http://opscode.com/nyc.txt" ] }
before do
- new_resource.stub!(:checksum).and_return(nil)
- current_resource.stub!(:checksum).and_return(nil)
- @uri0 = mock("URI0")
- @uri1 = mock("URI1")
+ new_resource.stub(:checksum).and_return(nil)
+ current_resource.stub(:checksum).and_return(nil)
+ @uri0 = double("URI0")
+ @uri1 = double("URI1")
URI.should_receive(:parse).with(new_resource.source[0]).and_return(@uri0)
URI.should_receive(:parse).with(new_resource.source[1]).and_return(@uri1)
- @http_fetcher_throws_exception = mock("Chef::Provider::RemoteFile::HTTP")
+ @http_fetcher_throws_exception = double("Chef::Provider::RemoteFile::HTTP")
@http_fetcher_throws_exception.should_receive(:fetch).at_least(:once).and_raise(Errno::ECONNREFUSED)
Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri0, new_resource, current_resource).and_return(@http_fetcher_throws_exception)
end
describe "when the second url succeeds" do
before do
- @tempfile = mock("Tempfile")
+ @tempfile = double("Tempfile")
mtime = Time.now
- http_fetcher_works = mock("Chef::Provider::RemoteFile::HTTP", :fetch => @tempfile)
+ http_fetcher_works = double("Chef::Provider::RemoteFile::HTTP", :fetch => @tempfile)
Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri1, new_resource, current_resource).and_return(http_fetcher_works)
end
@@ -205,14 +205,14 @@ describe Chef::Provider::RemoteFile::Content do
describe "when there is an array of sources and the first succeeds" do
let(:source) { [ "http://opscode.com/seattle.txt", "http://opscode.com/nyc.txt" ] }
before do
- new_resource.stub!(:checksum).and_return(nil)
- current_resource.stub!(:checksum).and_return(nil)
- @uri0 = mock("URI0")
+ new_resource.stub(:checksum).and_return(nil)
+ current_resource.stub(:checksum).and_return(nil)
+ @uri0 = double("URI0")
URI.should_receive(:parse).with(new_resource.source[0]).and_return(@uri0)
URI.should_not_receive(:parse).with(new_resource.source[1])
- @tempfile = mock("Tempfile")
+ @tempfile = double("Tempfile")
mtime = Time.now
- http_fetcher_works = mock("Chef::Provider::RemoteFile::HTTP", :fetch => @tempfile)
+ http_fetcher_works = double("Chef::Provider::RemoteFile::HTTP", :fetch => @tempfile)
Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri0, new_resource, current_resource).and_return(http_fetcher_works)
end
diff --git a/spec/unit/provider/remote_file/fetcher_spec.rb b/spec/unit/provider/remote_file/fetcher_spec.rb
index 68802fb83c..b5594b50e6 100644
--- a/spec/unit/provider/remote_file/fetcher_spec.rb
+++ b/spec/unit/provider/remote_file/fetcher_spec.rb
@@ -20,12 +20,12 @@ require 'spec_helper'
describe Chef::Provider::RemoteFile::Fetcher do
- let(:current_resource) { mock("current resource") }
- let(:new_resource) { mock("new resource") }
- let(:fetcher_instance) { mock("fetcher") }
+ let(:current_resource) { double("current resource") }
+ let(:new_resource) { double("new resource") }
+ let(:fetcher_instance) { double("fetcher") }
describe "when passed an http url" do
- let(:uri) { mock("uri", :scheme => "http" ) }
+ let(:uri) { double("uri", :scheme => "http" ) }
before do
Chef::Provider::RemoteFile::HTTP.should_receive(:new).and_return(fetcher_instance)
end
@@ -35,7 +35,7 @@ describe Chef::Provider::RemoteFile::Fetcher do
end
describe "when passed an https url" do
- let(:uri) { mock("uri", :scheme => "https" ) }
+ let(:uri) { double("uri", :scheme => "https" ) }
before do
Chef::Provider::RemoteFile::HTTP.should_receive(:new).and_return(fetcher_instance)
end
@@ -45,7 +45,7 @@ describe Chef::Provider::RemoteFile::Fetcher do
end
describe "when passed an ftp url" do
- let(:uri) { mock("uri", :scheme => "ftp" ) }
+ let(:uri) { double("uri", :scheme => "ftp" ) }
before do
Chef::Provider::RemoteFile::FTP.should_receive(:new).and_return(fetcher_instance)
end
@@ -55,7 +55,7 @@ describe Chef::Provider::RemoteFile::Fetcher do
end
describe "when passed a file url" do
- let(:uri) { mock("uri", :scheme => "file" ) }
+ let(:uri) { double("uri", :scheme => "file" ) }
before do
Chef::Provider::RemoteFile::LocalFile.should_receive(:new).and_return(fetcher_instance)
end
@@ -65,7 +65,7 @@ describe Chef::Provider::RemoteFile::Fetcher do
end
describe "when passed a url we do not recognize" do
- let(:uri) { mock("uri", :scheme => "xyzzy" ) }
+ let(:uri) { double("uri", :scheme => "xyzzy" ) }
it "throws an ArgumentError exception" do
lambda { described_class.for_resource(uri, new_resource, current_resource) }.should raise_error(ArgumentError)
end
diff --git a/spec/unit/provider/remote_file/ftp_spec.rb b/spec/unit/provider/remote_file/ftp_spec.rb
index 4022fb25d3..b393912ef9 100644
--- a/spec/unit/provider/remote_file/ftp_spec.rb
+++ b/spec/unit/provider/remote_file/ftp_spec.rb
@@ -38,14 +38,14 @@ describe Chef::Provider::RemoteFile::FTP do
end
let(:ftp) do
- ftp = mock(Net::FTP, { })
- ftp.stub!(:connect)
- ftp.stub!(:login)
- ftp.stub!(:voidcmd)
- ftp.stub!(:mtime).and_return(Time.now)
- ftp.stub!(:getbinaryfile)
- ftp.stub!(:close)
- ftp.stub!(:passive=)
+ ftp = double(Net::FTP, { })
+ ftp.stub(:connect)
+ ftp.stub(:login)
+ ftp.stub(:voidcmd)
+ ftp.stub(:mtime).and_return(Time.now)
+ ftp.stub(:getbinaryfile)
+ ftp.stub(:close)
+ ftp.stub(:passive=)
ftp
end
@@ -60,8 +60,8 @@ describe Chef::Provider::RemoteFile::FTP do
let(:uri) { URI.parse("ftp://opscode.com/seattle.txt") }
before(:each) do
- Net::FTP.stub!(:new).with().and_return(ftp)
- Tempfile.stub!(:new).and_return(tempfile)
+ Net::FTP.stub(:new).with().and_return(ftp)
+ Tempfile.stub(:new).and_return(tempfile)
end
describe "when first created" do
@@ -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..951d9f0a05 100644
--- a/spec/unit/provider/remote_file/http_spec.rb
+++ b/spec/unit/provider/remote_file/http_spec.rb
@@ -155,18 +155,18 @@ 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) { double(Tempfile, :path => tempfile_path, :close => nil) }
let(:last_response) { {} }
let(:rest) do
- rest = mock(Chef::REST)
- rest.stub!(:streaming_request).and_return(tempfile)
- rest.stub!(:last_response).and_return(last_response)
+ rest = double(Chef::HTTP::Simple)
+ rest.stub(:streaming_request).and_return(tempfile)
+ rest.stub(:last_response).and_return(last_response)
rest
end
@@ -175,32 +175,16 @@ 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
describe "and the request does not return new content" do
- it "should propagate non-304 exceptions to the caller" do
- r = Net::HTTPBadRequest.new("one", "two", "three")
- e = Net::HTTPServerException.new("fake exception", r)
- rest.stub!(:streaming_request).and_raise(e)
- lambda { fetcher.fetch }.should raise_error(Net::HTTPServerException)
- end
-
- it "should return HTTPRetriableError when Chef::REST returns a 301" do
- r = Net::HTTPMovedPermanently.new("one", "two", "three")
- e = Net::HTTPRetriableError.new("301", r)
- rest.stub!(:streaming_request).and_raise(e)
- lambda { fetcher.fetch }.should raise_error(Net::HTTPRetriableError)
- end
-
it "should return a nil tempfile for a 304 HTTPNotModifed" do
- r = Net::HTTPNotModified.new("one", "two", "three")
- e = Net::HTTPRetriableError.new("304", r)
- rest.stub!(:streaming_request).and_raise(e)
- result = fetcher.fetch
- result.should be_nil
+ # Streaming request returns nil for 304 errors
+ rest.stub(:streaming_request).and_return(nil)
+ fetcher.fetch.should be_nil
end
end
@@ -290,21 +274,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..0020a03210 100644
--- a/spec/unit/provider/remote_file/local_file_spec.rb
+++ b/spec/unit/provider/remote_file/local_file_spec.rb
@@ -40,8 +40,8 @@ describe Chef::Provider::RemoteFile::LocalFile do
describe "when fetching the object" do
- let(:tempfile) { mock("Tempfile", :path => "/tmp/foo/bar/nyan.png") }
- let(:chef_tempfile) { mock("Chef::FileContentManagement::Tempfile", :tempfile => tempfile) }
+ let(:tempfile) { double("Tempfile", :path => "/tmp/foo/bar/nyan.png", :close => nil) }
+ let(:chef_tempfile) { double("Chef::FileContentManagement::Tempfile", :tempfile => tempfile) }
before do
current_resource.source("file:///nyan_cat.png")
@@ -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/remote_file_spec.rb b/spec/unit/provider/remote_file_spec.rb
index 3b01b45983..3fa3866743 100644
--- a/spec/unit/provider/remote_file_spec.rb
+++ b/spec/unit/provider/remote_file_spec.rb
@@ -32,7 +32,7 @@ describe Chef::Provider::RemoteFile do
end
let(:content) do
- content = mock('Chef::Provider::File::Content::RemoteFile')
+ content = double('Chef::Provider::File::Content::RemoteFile')
end
let(:node) { double('Chef::Node') }
@@ -47,16 +47,17 @@ describe Chef::Provider::RemoteFile do
subject(:provider) do
provider = described_class.new(resource, run_context)
- provider.stub!(:content).and_return(content)
- provider.stub!(:update_new_resource_checksum).and_return(nil) # Otherwise it doesn't behave like a File provider
+ provider.stub(:content).and_return(content)
+ provider.stub(:update_new_resource_checksum).and_return(nil) # Otherwise it doesn't behave like a File provider
provider
end
before do
- Chef::FileCache.stub!(:load).with("remote_file/#{resource.name}").and_raise(Chef::Exceptions::FileNotFound)
+ Chef::FileCache.stub(:load).with("remote_file/#{resource.name}").and_raise(Chef::Exceptions::FileNotFound)
end
it_behaves_like Chef::Provider::File
+ it_behaves_like "a file provider with source field"
end
diff --git a/spec/unit/provider/route_spec.rb b/spec/unit/provider/route_spec.rb
index 072cb2a698..2a6d48c79e 100644
--- a/spec/unit/provider/route_spec.rb
+++ b/spec/unit/provider/route_spec.rb
@@ -55,13 +55,13 @@ describe Chef::Provider::Route do
routing_table = "Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT\n" +
"eth0 0064A8C0 0984A8C0 0003 0 0 0 00FFFFFF 0 0 0\n"
route_file = StringIO.new(routing_table)
- File.stub!(:open).with("/proc/net/route", "r").and_return(route_file)
+ File.stub(:open).with("/proc/net/route", "r").and_return(route_file)
end
it "should set is_running to false when a route is not detected" do
resource = Chef::Resource::Route.new('10.10.10.0/24')
- resource.stub!(:gateway).and_return("10.0.0.1")
- resource.stub!(:device).and_return("eth0")
+ resource.stub(:gateway).and_return("10.0.0.1")
+ resource.stub(:device).and_return("eth0")
provider = Chef::Provider::Route.new(resource, @run_context)
provider.load_current_resource
@@ -70,8 +70,8 @@ describe Chef::Provider::Route do
it "should detect existing routes and set is_running attribute correctly" do
resource = Chef::Resource::Route.new('192.168.100.0/24')
- resource.stub!(:gateway).and_return("192.168.132.9")
- resource.stub!(:device).and_return("eth0")
+ resource.stub(:gateway).and_return("192.168.132.9")
+ resource.stub(:device).and_return("eth0")
provider = Chef::Provider::Route.new(resource, @run_context)
provider.load_current_resource
@@ -80,8 +80,8 @@ describe Chef::Provider::Route do
it "should use gateway value when matching routes" do
resource = Chef::Resource::Route.new('192.168.100.0/24')
- resource.stub!(:gateway).and_return("10.10.10.10")
- resource.stub!(:device).and_return("eth0")
+ resource.stub(:gateway).and_return("10.10.10.10")
+ resource.stub(:device).and_return("eth0")
provider = Chef::Provider::Route.new(resource, @run_context)
provider.load_current_resource
@@ -92,8 +92,8 @@ describe Chef::Provider::Route do
describe Chef::Provider::Route, "action_add" do
it "should add the route if it does not exist" do
- @provider.stub!(:run_command).and_return(true)
- @current_resource.stub!(:gateway).and_return(nil)
+ @provider.stub(:run_command).and_return(true)
+ @current_resource.stub(:gateway).and_return(nil)
@provider.should_receive(:generate_command).once.with(:add)
@provider.should_receive(:generate_config)
@provider.run_action(:add)
@@ -101,8 +101,8 @@ describe Chef::Provider::Route do
end
it "should not add the route if it exists" do
- @provider.stub!(:run_command).and_return(true)
- @provider.stub!(:is_running).and_return(true)
+ @provider.stub(:run_command).and_return(true)
+ @provider.stub(:is_running).and_return(true)
@provider.should_not_receive(:generate_command).with(:add)
@provider.should_receive(:generate_config)
@provider.run_action(:add)
@@ -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)
-
+ @provider.stub(:run_command).and_return(true)
+
@resource_add.action(:add)
@provider.run_action(:add)
route_file.string.split("\n").should have(1).items
@@ -127,16 +127,16 @@ describe Chef::Provider::Route do
describe Chef::Provider::Route, "action_delete" do
it "should delete the route if it exists" do
- @provider.stub!(:run_command).and_return(true)
+ @provider.stub(:run_command).and_return(true)
@provider.should_receive(:generate_command).once.with(:delete)
- @provider.stub!(:is_running).and_return(true)
+ @provider.stub(:is_running).and_return(true)
@provider.run_action(:delete)
@new_resource.should be_updated
end
it "should not delete the route if it does not exist" do
- @current_resource.stub!(:gateway).and_return(nil)
- @provider.stub!(:run_command).and_return(true)
+ @current_resource.stub(:gateway).and_return(nil)
+ @provider.stub(:run_command).and_return(true)
@provider.should_not_receive(:generate_command).with(:add)
@provider.run_action(:delete)
@new_resource.should_not be_updated
@@ -145,12 +145,12 @@ describe Chef::Provider::Route do
describe Chef::Provider::Route, "generate_command for action_add" do
it "should include a netmask when a one is specified" do
- @new_resource.stub!(:netmask).and_return('255.255.0.0')
+ @new_resource.stub(:netmask).and_return('255.255.0.0')
@provider.generate_command(:add).should match(/\/\d{1,2}\s/)
end
it "should not include a netmask when a one is specified" do
- @new_resource.stub!(:netmask).and_return(nil)
+ @new_resource.stub(:netmask).and_return(nil)
@provider.generate_command(:add).should_not match(/\/\d{1,2}\s/)
end
@@ -159,19 +159,19 @@ describe Chef::Provider::Route do
end
it "should not include ' via $gateway ' when a gateway is not specified" do
- @new_resource.stub!(:gateway).and_return(nil)
+ @new_resource.stub(:gateway).and_return(nil)
@provider.generate_command(:add).should_not match(/\svia\s#{Regexp.escape(@new_resource.gateway.to_s)}\s/)
end
end
describe Chef::Provider::Route, "generate_command for action_delete" do
it "should include a netmask when a one is specified" do
- @new_resource.stub!(:netmask).and_return('255.255.0.0')
+ @new_resource.stub(:netmask).and_return('255.255.0.0')
@provider.generate_command(:delete).should match(/\/\d{1,2}\s/)
end
it "should not include a netmask when a one is specified" do
- @new_resource.stub!(:netmask).and_return(nil)
+ @new_resource.stub(:netmask).and_return(nil)
@provider.generate_command(:delete).should_not match(/\/\d{1,2}\s/)
end
@@ -180,14 +180,14 @@ describe Chef::Provider::Route do
end
it "should not include ' via $gateway ' when a gateway is not specified" do
- @new_resource.stub!(:gateway).and_return(nil)
+ @new_resource.stub(:gateway).and_return(nil)
@provider.generate_command(:delete).should_not match(/\svia\s#{Regexp.escape(@new_resource.gateway.to_s)}\s/)
end
end
describe Chef::Provider::Route, "config_file_contents for action_add" do
it "should include a netmask when a one is specified" do
- @new_resource.stub!(:netmask).and_return('255.255.0.0')
+ @new_resource.stub(:netmask).and_return('255.255.0.0')
@provider.config_file_contents(:add, { :target => @new_resource.target, :netmask => @new_resource.netmask}).should match(/\/\d{1,2}.*\n$/)
end
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/script_spec.rb b/spec/unit/provider/script_spec.rb
index 5111a94578..d072eddd04 100644
--- a/spec/unit/provider/script_spec.rb
+++ b/spec/unit/provider/script_spec.rb
@@ -30,9 +30,9 @@ describe Chef::Provider::Script, "action_run" do
@provider = Chef::Provider::Script.new(@new_resource, @run_context)
@script_file = StringIO.new
- @script_file.stub!(:path).and_return('/tmp/the_script_file')
+ @script_file.stub(:path).and_return('/tmp/the_script_file')
- @provider.stub!(:shell_out!).and_return(true)
+ @provider.stub(:shell_out!).and_return(true)
end
it "creates a temporary file to store the script" do
@@ -48,15 +48,15 @@ describe Chef::Provider::Script, "action_run" do
it "sets the owner and group for the script file" do
@new_resource.user 'toor'
@new_resource.group 'wheel'
- @provider.stub!(:script_file).and_return(@script_file)
+ @provider.stub(:script_file).and_return(@script_file)
FileUtils.should_receive(:chown).with('toor', 'wheel', "/tmp/the_script_file")
@provider.set_owner_and_group
end
context "with the script file set to the correct owner and group" do
before do
- @provider.stub!(:set_owner_and_group)
- @provider.stub!(:script_file).and_return(@script_file)
+ @provider.stub(:set_owner_and_group)
+ @provider.stub(:script_file).and_return(@script_file)
end
describe "when writing the script to the file" do
it "should put the contents of the script in the temp file" do
diff --git a/spec/unit/provider/service/arch_service_spec.rb b/spec/unit/provider/service/arch_service_spec.rb
index 42e7868600..b267915e44 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.
@@ -39,8 +39,8 @@ describe Chef::Provider::Service::Arch, "load_current_resource" do
@provider = Chef::Provider::Service::Arch.new(@new_resource, @run_context)
- ::File.stub!(:exists?).with("/etc/rc.conf").and_return(true)
- ::File.stub!(:read).with("/etc/rc.conf").and_return("DAEMONS=(network apache sshd)")
+ ::File.stub(:exists?).with("/etc/rc.conf").and_return(true)
+ ::File.stub(:read).with("/etc/rc.conf").and_return("DAEMONS=(network apache sshd)")
end
describe "when first created" do
@@ -61,21 +61,21 @@ 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 status command returns 0" do
- @provider.stub!(:shell_out).with("/etc/rc.d/chef status").and_return(OpenStruct.new(:exitstatus => 0))
+ @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
end
it "should set running to false if the status command returns anything except 0" do
- @provider.stub!(:shell_out).with("/etc/rc.d/chef status").and_return(OpenStruct.new(:exitstatus => 1))
+ @provider.stub(:shell_out).with("/etc/rc.d/chef status").and_return(OpenStruct.new(:exitstatus => 1))
@provider.load_current_resource
@provider.current_resource.running.should be_false
end
it "should set running to false if the status command raises" do
- @provider.stub!(:shell_out).with("/etc/rc.d/chef status").and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ @provider.stub(:shell_out).with("/etc/rc.d/chef status").and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
@provider.current_resource.running.should be_false
end
@@ -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
@@ -111,12 +111,12 @@ describe Chef::Provider::Service::Arch, "load_current_resource" do
it "should fail if file /etc/rc.conf does not exist" do
- ::File.stub!(:exists?).with("/etc/rc.conf").and_return(false)
+ ::File.stub(:exists?).with("/etc/rc.conf").and_return(false)
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Service)
end
it "should fail if file /etc/rc.conf does not contain DAEMONS array" do
- ::File.stub!(:read).with("/etc/rc.conf").and_return("")
+ ::File.stub(:read).with("/etc/rc.conf").and_return("")
lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Service)
end
@@ -127,9 +127,9 @@ aj 7842 5057 0 21:26 pts/2 00:00:06 vi init.rb
aj 7903 5016 0 21:26 pts/5 00:00:00 /bin/bash
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)
-
+ @status = double("Status", :exitstatus => 0, :stdout => @stdout)
+ @provider.stub(:shell_out!).and_return(@status)
+
@node.automatic_attrs[:command] = {:ps => "ps -ef"}
end
@@ -138,19 +138,19 @@ DEFAULT_PS
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
+ @status.stub(:stdout).and_return(@stdout)
+ @provider.load_current_resource
@provider.current_resource.running.should be_true
end
it "determines the service is not running when it does not appear in ps" do
- @provider.stub!(:shell_out!).and_return(@status)
+ @provider.stub(:shell_out!).and_return(@status)
@provider.load_current_resource
@provider.current_resource.running.should be_false
end
it "should raise an exception if ps fails" do
- @provider.stub!(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ @provider.stub(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
@provider.action = :start
@provider.define_resource_requirements
@@ -159,32 +159,32 @@ RUNNING_PS
end
it "should return existing entries in DAEMONS array" do
- ::File.stub!(:read).with("/etc/rc.conf").and_return("DAEMONS=(network !apache ssh)")
+ ::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",
+ # @new_resource = double("Chef::Resource::Service",
# :null_object => true,
# :name => "chef",
# :service_name => "chef",
# :running => false
# )
- # @new_resource.stub!(:start_command).and_return(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)
+ # Chef::Resource::Service.stub(:new).and_return(@current_resource)
# end
it "should add chef to DAEMONS array" do
- ::File.stub!(:read).with("/etc/rc.conf").and_return("DAEMONS=(network)")
+ ::File.stub(:read).with("/etc/rc.conf").and_return("DAEMONS=(network)")
@provider.should_receive(:update_daemons).with(['network', 'chef'])
@provider.enable_service()
end
@@ -192,20 +192,20 @@ RUNNING_PS
describe Chef::Provider::Service::Arch, "disable_service" do
# before(:each) do
- # @new_resource = mock("Chef::Resource::Service",
+ # @new_resource = double("Chef::Resource::Service",
# :null_object => true,
# :name => "chef",
# :service_name => "chef",
# :running => false
# )
- # @new_resource.stub!(:start_command).and_return(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)
+ # Chef::Resource::Service.stub(:new).and_return(@current_resource)
# end
it "should remove chef from DAEMONS array" do
- ::File.stub!(:read).with("/etc/rc.conf").and_return("DAEMONS=(network chef)")
+ ::File.stub(:read).with("/etc/rc.conf").and_return("DAEMONS=(network chef)")
@provider.should_receive(:update_daemons).with(['network', '!chef'])
@provider.disable_service()
end
@@ -214,20 +214,20 @@ RUNNING_PS
describe Chef::Provider::Service::Arch, "start_service" do
# before(:each) do
- # @new_resource = mock("Chef::Resource::Service",
+ # @new_resource = double("Chef::Resource::Service",
# :null_object => true,
# :name => "chef",
# :service_name => "chef",
# :running => false
# )
- # @new_resource.stub!(:start_command).and_return(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)
+ # 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")
+ @new_resource.stub(:start_command).and_return("/etc/rc.d/chef startyousillysally")
@provider.should_receive(:shell_out!).with("/etc/rc.d/chef startyousillysally")
@provider.start_service()
end
@@ -235,25 +235,25 @@ 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
# before(:each) do
- # @new_resource = mock("Chef::Resource::Service",
+ # @new_resource = double("Chef::Resource::Service",
# :null_object => true,
# :name => "chef",
# :service_name => "chef",
# :running => false
# )
- # @new_resource.stub!(:stop_command).and_return(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)
+ # Chef::Resource::Service.stub(:new).and_return(@current_resource)
# end
it "should call the stop command if one is specified" do
- @new_resource.stub!(:stop_command).and_return("/etc/rc.d/chef itoldyoutostop")
+ @new_resource.stub(:stop_command).and_return("/etc/rc.d/chef itoldyoutostop")
@provider.should_receive(:shell_out!).with("/etc/rc.d/chef itoldyoutostop")
@provider.stop_service()
end
@@ -266,27 +266,27 @@ RUNNING_PS
describe Chef::Provider::Service::Arch, "restart_service" do
# before(:each) do
- # @new_resource = mock("Chef::Resource::Service",
+ # @new_resource = double("Chef::Resource::Service",
# :null_object => true,
# :name => "chef",
# :service_name => "chef",
# :running => false
# )
- # @new_resource.stub!(:restart_command).and_return(false)
- # @new_resource.stub!(:supports).and_return({:restart => false})
- #
+ # @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)
+ # Chef::Resource::Service.stub(:new).and_return(@current_resource)
# end
it "should call 'restart' on the service_name if the resource supports it" do
- @new_resource.stub!(:supports).and_return({:restart => true})
+ @new_resource.stub(:supports).and_return({:restart => true})
@provider.should_receive(:shell_out!).with("/etc/rc.d/#{@new_resource.service_name} restart")
@provider.restart_service()
end
it "should call the restart_command if one has been specified" do
- @new_resource.stub!(:restart_command).and_return("/etc/rc.d/chef restartinafire")
+ @new_resource.stub(:restart_command).and_return("/etc/rc.d/chef restartinafire")
@provider.should_receive(:shell_out!).with("/etc/rc.d/#{@new_resource.service_name} restartinafire")
@provider.restart_service()
end
@@ -301,27 +301,27 @@ RUNNING_PS
describe Chef::Provider::Service::Arch, "reload_service" do
# before(:each) do
- # @new_resource = mock("Chef::Resource::Service",
+ # @new_resource = double("Chef::Resource::Service",
# :null_object => true,
# :name => "chef",
# :service_name => "chef",
# :running => false
# )
- # @new_resource.stub!(:reload_command).and_return(false)
- # @new_resource.stub!(:supports).and_return({:reload => false})
- #
+ # @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)
+ # Chef::Resource::Service.stub(:new).and_return(@current_resource)
# end
it "should call 'reload' on the service if it supports it" do
- @new_resource.stub!(:supports).and_return({:reload => true})
+ @new_resource.stub(:supports).and_return({:reload => true})
@provider.should_receive(:shell_out!).with("/etc/rc.d/#{@new_resource.service_name} reload")
@provider.reload_service()
end
it "should should run the user specified reload command if one is specified and the service doesn't support reload" do
- @new_resource.stub!(:reload_command).and_return("/etc/rc.d/chef lollerpants")
+ @new_resource.stub(:reload_command).and_return("/etc/rc.d/chef lollerpants")
@provider.should_receive(:shell_out!).with("/etc/rc.d/#{@new_resource.service_name} lollerpants")
@provider.reload_service()
end
diff --git a/spec/unit/provider/service/debian_service_spec.rb b/spec/unit/provider/service/debian_service_spec.rb
index bea9360561..567eb6744a 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,98 +26,44 @@ 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 "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
- 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)
- 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
+ @provider.define_resource_requirements
+ lambda {
+ @provider.process_resource_requirements
+ }.should raise_error(Chef::Exceptions::Service)
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"])
- @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)
+ @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 = double("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
@@ -125,32 +71,22 @@ insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop"
end
it "stores the 'enabled' state" do
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ 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
- 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 => @stdout)
- @provider.stub!(:shell_out!).and_return(@status)
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:assert_update_rcd_available)
+ @status = double("Status", :exitstatus => 0)
+ @stdout = StringIO.new(
+ " Removing any system startup links for /etc/init.d/chef ...")
+ @stderr = StringIO.new
+ @status = double("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
@@ -158,97 +94,282 @@ insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop"
end
it "stores the 'disabled' state" do
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ 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
- 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 = double("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" => "",
+ "priorities" => {
+ "0"=>[:stop, "20"],
+ "1"=>[:stop, "20"],
+ "2"=>[:start, "20"],
+ "3"=>[:start, "20"],
+ "4"=>[:start, "20"],
+ "5"=>[:start, "20"],
+ "6"=>[:stop, "20"]
+ }
+ },
+ "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
+ "priorities" => {
+ "0"=>[:stop, "20"],
+ "1"=>[:stop, "20"],
+ "2"=>[:start, "20"],
+ "3"=>[:start, "20"],
+ "4"=>[:start, "20"],
+ "5"=>[:start, "20"],
+ "6"=>[:stop, "20"]
+ }
+ },
+ "not linked" => {
+ "stdout" => "update-rc.d: using dependency based boot sequencing",
+ "stderr" => ""
+ }
+ },
+ "Debian/Wheezy and earlier, a service only starting at run level S" => {
+ "linked" => {
+ "stdout" => "",
+ "stderr" => <<-STDERR,
+insserv: remove service /etc/init.d/../rc0.d/K06rpcbind
+insserv: remove service /etc/init.d/../rc1.d/K06rpcbind
+insserv: remove service /etc/init.d/../rc6.d/K06rpcbind
+insserv: remove service /etc/init.d/../rcS.d/S13rpcbind
+insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop
+ STDERR
+ "priorities" => {
+ "0"=>[:stop, "06"],
+ "1"=>[:stop, "06"],
+ "6"=>[:stop, "06"],
+ "S"=>[:start, "13"]
+ }
+ },
+ "not linked" => {
+ "stdout" => "",
+ "stderr" => "insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop"
+ }
+ }
+ }.each do |model, expected_results|
+ 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(expected_results["linked"]["stdout"])
+ @stderr = StringIO.new(expected_results["linked"]["stderr"])
+ @status = double("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
+ @provider.current_resource.priority.should == expected_results["linked"]["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(expected_results["not linked"]["stdout"])
+ @stderr = StringIO.new(expected_results["not linked"]["stderr"])
+ @status = double("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)
+ @current_resource.priority(80)
+ 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
+ @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
+ @new_resource.priority(20)
+ 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 72e896a16b..820dfb8dc7 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.
@@ -34,7 +34,7 @@ describe Chef::Provider::Service::Freebsd do
@provider = Chef::Provider::Service::Freebsd.new(@new_resource,@run_context)
@provider.action = :start
@init_command = "/usr/local/etc/rc.d/apache22"
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
end
describe "load_current_resource" do
@@ -44,21 +44,21 @@ describe Chef::Provider::Service::Freebsd do
539 ?? Is 0:00.14 /usr/sbin/sshd
545 ?? Ss 0:17.53 sendmail: accepting connections (sendmail)
PS_SAMPLE
- @status = mock(:stdout => @stdout, :exitstatus => 0)
- @provider.stub!(:shell_out!).with(@node[:command][:ps]).and_return(@status)
+ @status = double(:stdout => @stdout, :exitstatus => 0)
+ @provider.stub(:shell_out!).with(@node[:command][:ps]).and_return(@status)
- ::File.stub!(:exists?).and_return(false)
- ::File.stub!(:exists?).with("/usr/local/etc/rc.d/#{@new_resource.service_name}").and_return(true)
- @lines = mock("lines")
- @lines.stub!(:each).and_yield("sshd_enable=\"YES\"").
+ ::File.stub(:exists?).and_return(false)
+ ::File.stub(:exists?).with("/usr/local/etc/rc.d/#{@new_resource.service_name}").and_return(true)
+ @lines = double("lines")
+ @lines.stub(:each).and_yield("sshd_enable=\"YES\"").
and_yield("#{@new_resource.name}_enable=\"YES\"")
- ::File.stub!(:open).and_return(@lines)
+ ::File.stub(:open).and_return(@lines)
@rc_with_name = StringIO.new(<<-RC_SAMPLE)
name="apache22"
rcvar=`set_rcvar`
RC_SAMPLE
- ::File.stub!(:open).with("/usr/local/etc/rc.d/#{@new_resource.service_name}").and_return(@rc_with_name)
+ ::File.stub(:open).with("/usr/local/etc/rc.d/#{@new_resource.service_name}").and_return(@rc_with_name)
@provider.stub(:service_enable_variable_name).and_return nil
end
@@ -75,7 +75,7 @@ RC_SAMPLE
it "should not raise an exception if the rcscript have a name variable" do
@provider.load_current_resource
- lambda { @provider.service_enable_variable_name }.should_not raise_error(Chef::Exceptions::Service)
+ lambda { @provider.service_enable_variable_name }.should_not raise_error
end
describe "when the service supports status" do
@@ -125,20 +125,20 @@ 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")
- @provider.stub!(:service_enable_variable_name).and_return("#{@current_resource.service_name}_enable")
+ @provider.stub(:service_enable_variable_name).and_return("#{@current_resource.service_name}_enable")
@provider.load_current_resource
end
context "and the init script is not found" do
[ "start", "reload", "restart", "enable" ].each do |action|
it "should raise an exception when the action is #{action}" do
- ::File.stub!(:exists?).and_return(false)
+ ::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,18 +157,18 @@ 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)
+ ::File.stub(:exist?).with("/usr/local/etc/rc.d/#{@new_resource.service_name}").and_return(true)
::File.should_receive(:exists?).with("/etc/rc.conf").and_return true
@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
@@ -189,26 +189,26 @@ RC_SAMPLE
end
it "should read stdout of the ps command" do
- @provider.stub!(:shell_out!).and_return(@status)
+ @provider.stub(:shell_out!).and_return(@status)
@stdout.should_receive(:each_line).and_return(true)
@provider.load_current_resource
end
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").
+ @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
it "should set running to false if the regex doesn't match" do
- @provider.stub!(:shell_out!).and_return(@status)
+ @provider.stub(:shell_out!).and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_false
end
it "should raise an exception if ps fails" do
- @provider.stub!(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ @provider.stub(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
@provider.define_resource_requirements
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
@@ -270,7 +270,7 @@ RC_SAMPLE
@rc_without_name = StringIO.new(<<-RC_SAMPLE)
rcvar=`set_rcvar`
RC_SAMPLE
- ::File.stub!(:open).with("/usr/local/etc/rc.d/#{@current_resource.service_name}").and_return(@rc_with_noname)
+ ::File.stub(:open).with("/usr/local/etc/rc.d/#{@current_resource.service_name}").and_return(@rc_with_noname)
@provider.current_resource = @current_resource
end
@@ -282,19 +282,19 @@ RC_SAMPLE
# #{@current_resource.service_name}_enable="YES"
# (default: "")
RCVAR_SAMPLE
- @status = mock(:stdout => @rcvar_stdout, :exitstatus => 0)
- @provider.stub!(:shell_out!).with("/usr/local/etc/rc.d/#{@current_resource.service_name} rcvar").and_return(@status)
+ @status = double(:stdout => @rcvar_stdout, :exitstatus => 0)
+ @provider.stub(:shell_out!).with("/usr/local/etc/rc.d/#{@current_resource.service_name} rcvar").and_return(@status)
end
it "should get the service name from rcvar if the rcscript does not have a name variable" do
@provider.load_current_resource
- @provider.unstub!(:service_enable_variable_name)
+ @provider.unstub(:service_enable_variable_name)
@provider.service_enable_variable_name.should == "#{@current_resource.service_name}_enable"
end
it "should not raise an exception if the rcscript does not have a name variable" do
@provider.load_current_resource
- lambda { @provider.service_enable_variable_name }.should_not raise_error(Chef::Exceptions::Service)
+ lambda { @provider.service_enable_variable_name }.should_not raise_error
end
end
@@ -304,8 +304,8 @@ RCVAR_SAMPLE
# service_with_noname
#
RCVAR_SAMPLE
- @status = mock(:stdout => @rcvar_stdout, :exitstatus => 0)
- @provider.stub!(:shell_out!).with("/usr/local/etc/rc.d/#{@current_resource.service_name} rcvar").and_return(@status)
+ @status = double(:stdout => @rcvar_stdout, :exitstatus => 0)
+ @provider.stub(:shell_out!).with("/usr/local/etc/rc.d/#{@current_resource.service_name} rcvar").and_return(@status)
end
[ "start", "reload", "restart", "enable" ].each do |action|
@@ -319,11 +319,11 @@ RCVAR_SAMPLE
[ "stop", "disable" ].each do |action|
it "should not raise an error when the action is #{action}" do
- ::File.stub!(:exist?).with("/usr/local/etc/rc.d/#{@new_resource.service_name}").and_return(true)
+ ::File.stub(:exist?).with("/usr/local/etc/rc.d/#{@new_resource.service_name}").and_return(true)
@provider.action = action
@provider.load_current_resource
@provider.define_resource_requirements
- lambda { @provider.process_resource_requirements }.should_not raise_error(Chef::Exceptions::Service)
+ lambda { @provider.process_resource_requirements }.should_not raise_error
end
end
end
@@ -333,25 +333,25 @@ RCVAR_SAMPLE
describe Chef::Provider::Service::Freebsd, "enable_service" do
before do
@provider.current_resource = @current_resource
- @provider.stub!(:service_enable_variable_name).and_return("#{@current_resource.service_name}_enable")
+ @provider.stub(:service_enable_variable_name).and_return("#{@current_resource.service_name}_enable")
end
it "should enable the service if it is not enabled" do
- @current_resource.stub!(:enabled).and_return(false)
+ @current_resource.stub(:enabled).and_return(false)
@provider.should_receive(:read_rc_conf).and_return([ "foo", "#{@current_resource.service_name}_enable=\"NO\"", "bar" ])
@provider.should_receive(:write_rc_conf).with(["foo", "bar", "#{@current_resource.service_name}_enable=\"YES\""])
@provider.enable_service()
end
it "should enable the service if it is not enabled and not already specified in the rc.conf file" do
- @current_resource.stub!(:enabled).and_return(false)
+ @current_resource.stub(:enabled).and_return(false)
@provider.should_receive(:read_rc_conf).and_return([ "foo", "bar" ])
@provider.should_receive(:write_rc_conf).with(["foo", "bar", "#{@current_resource.service_name}_enable=\"YES\""])
@provider.enable_service()
end
it "should not enable the service if it is already enabled" do
- @current_resource.stub!(:enabled).and_return(true)
+ @current_resource.stub(:enabled).and_return(true)
@provider.should_not_receive(:write_rc_conf)
@provider.enable_service
end
@@ -360,18 +360,18 @@ RCVAR_SAMPLE
describe Chef::Provider::Service::Freebsd, "disable_service" do
before do
@provider.current_resource = @current_resource
- @provider.stub!(:service_enable_variable_name).and_return("#{@current_resource.service_name}_enable")
+ @provider.stub(:service_enable_variable_name).and_return("#{@current_resource.service_name}_enable")
end
it "should should disable the service if it is not disabled" do
- @current_resource.stub!(:enabled).and_return(true)
+ @current_resource.stub(:enabled).and_return(true)
@provider.should_receive(:read_rc_conf).and_return([ "foo", "#{@current_resource.service_name}_enable=\"YES\"", "bar" ])
@provider.should_receive(:write_rc_conf).with(["foo", "bar", "#{@current_resource.service_name}_enable=\"NO\""])
@provider.disable_service()
end
it "should not disable the service if it is already disabled" do
- @current_resource.stub!(:enabled).and_return(false)
+ @current_resource.stub(:enabled).and_return(false)
@provider.should_not_receive(:write_rc_conf)
@provider.disable_service()
end
diff --git a/spec/unit/provider/service/gentoo_service_spec.rb b/spec/unit/provider/service/gentoo_service_spec.rb
index 8d4ada043b..95dc04108d 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,22 +24,22 @@ 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)
- @provider.stub!(:shell_out).and_return(@status)
- File.stub!(:exists?).with("/etc/init.d/chef").and_return(true)
- File.stub!(:exists?).with("/sbin/rc-update").and_return(true)
- File.stub!(:exists?).with("/etc/runlevels/default/chef").and_return(false)
- File.stub!(:readable?).with("/etc/runlevels/default/chef").and_return(false)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
+ @status = double("Status", :exitstatus => 0, :stdout => @stdout)
+ @provider.stub(:shell_out).and_return(@status)
+ File.stub(:exists?).with("/etc/init.d/chef").and_return(true)
+ File.stub(:exists?).with("/sbin/rc-update").and_return(true)
+ File.stub(:exists?).with("/etc/runlevels/default/chef").and_return(false)
+ File.stub(:readable?).with("/etc/runlevels/default/chef").and_return(false)
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
@@ -52,7 +52,7 @@ describe Chef::Provider::Service::Gentoo do
end
it "should track when service file is found in /etc/runlevels/**/" do
- Dir.stub!(:glob).with("/etc/runlevels/**/chef").and_return(["/etc/runlevels/default/chef"])
+ Dir.stub(:glob).with("/etc/runlevels/**/chef").and_return(["/etc/runlevels/default/chef"])
@provider.load_current_resource
@provider.instance_variable_get("@found_script").should be_true
end
@@ -60,13 +60,13 @@ describe Chef::Provider::Service::Gentoo do
describe "when detecting the service enable state" do
describe "and the glob returns a default service script file" do
before do
- Dir.stub!(:glob).with("/etc/runlevels/**/chef").and_return(["/etc/runlevels/default/chef"])
+ Dir.stub(:glob).with("/etc/runlevels/**/chef").and_return(["/etc/runlevels/default/chef"])
end
describe "and the file exists and is readable" do
before do
- File.stub!(:exists?).with("/etc/runlevels/default/chef").and_return(true)
- File.stub!(:readable?).with("/etc/runlevels/default/chef").and_return(true)
+ File.stub(:exists?).with("/etc/runlevels/default/chef").and_return(true)
+ File.stub(:readable?).with("/etc/runlevels/default/chef").and_return(true)
end
it "should set enabled to true" do
@provider.load_current_resource
@@ -76,10 +76,10 @@ describe Chef::Provider::Service::Gentoo do
describe "and the file exists but is not readable" do
before do
- File.stub!(:exists?).with("/etc/runlevels/default/chef").and_return(true)
- File.stub!(:readable?).with("/etc/runlevels/default/chef").and_return(false)
+ 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
@@ -88,8 +88,8 @@ describe Chef::Provider::Service::Gentoo do
describe "and the file does not exist" do
before do
- File.stub!(:exists?).with("/etc/runlevels/default/chef").and_return(false)
- File.stub!(:readable?).with("/etc/runlevels/default/chef").and_return("foobarbaz")
+ File.stub(:exists?).with("/etc/runlevels/default/chef").and_return(false)
+ File.stub(:readable?).with("/etc/runlevels/default/chef").and_return("foobarbaz")
end
it "should set enabled to false" do
@@ -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,9 +122,9 @@ describe Chef::Provider::Service::Gentoo do
end
end
-
+
describe "action_methods" do
- before(:each) { @provider.stub!(:load_current_resource).and_return(@current_resource) }
+ before(:each) { @provider.stub(:load_current_resource).and_return(@current_resource) }
describe Chef::Provider::Service::Gentoo, "enable_service" do
it "should call rc-update add *service* default" do
diff --git a/spec/unit/provider/service/init_service_spec.rb b/spec/unit/provider/service/init_service_spec.rb
index 4131ee61a8..ad887c84a5 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.
@@ -30,17 +30,17 @@ describe Chef::Provider::Service::Init, "load_current_resource" do
@current_resource = Chef::Resource::Service.new("chef")
@provider = Chef::Provider::Service::Init.new(@new_resource, @run_context)
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
@stdout = StringIO.new(<<-PS)
aj 7842 5057 0 21:26 pts/2 00:00:06 vi init.rb
aj 7903 5016 0 21:26 pts/5 00:00:00 /bin/bash
aj 8119 6041 0 21:34 pts/3 00:00:03 vi init_service_spec.rb
PS
- @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
- @provider.stub!(:shell_out!).and_return(@status)
+ @status = double("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,22 +60,22 @@ 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 status command returns 0" do
- @provider.stub!(:shell_out).with("/etc/init.d/#{@current_resource.service_name} status").and_return(@status)
+ @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
end
it "should set running to false if the status command returns anything except 0" do
- @status.stub!(:exitstatus).and_return(1)
- @provider.stub!(:shell_out).with("/etc/init.d/#{@current_resource.service_name} status").and_return(@status)
+ @status.stub(:exitstatus).and_return(1)
+ @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_false
end
it "should set running to false if the status command raises" do
- @provider.stub!(:shell_out).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ @provider.stub(:shell_out).and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
@current_resource.running.should be_false
end
@@ -83,19 +83,19 @@ PS
describe "when a status command has been specified" do
before do
- @new_resource.stub!(:status_command).and_return("/etc/init.d/chefhasmonkeypants status")
+ @new_resource.stub(:status_command).and_return("/etc/init.d/chefhasmonkeypants status")
end
it "should run the services status command if one has been specified" do
@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")
+ @new_resource.stub(:init_command).and_return("/opt/chef-server/service/erchef")
@provider = Chef::Provider::Service::Init.new(@new_resource, @run_context)
end
@@ -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
@@ -138,19 +138,19 @@ PS
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
+ @status.stub(:stdout).and_return(@stdout)
+ @provider.load_current_resource
@current_resource.running.should be_true
end
it "should set running to false if the regex doesn't match" do
- @provider.stub!(:shell_out!).and_return(@status)
+ @provider.stub(:shell_out!).and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_false
end
it "should raise an exception if ps fails" do
- @provider.stub!(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ @provider.stub(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
@provider.action = :start
@provider.define_resource_requirements
@@ -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
@@ -229,7 +229,7 @@ RUNNING_PS
end
it "should still pass all why run assertions" do
- lambda { @provider.run_action(:start) }.should_not raise_error(Chef::Exceptions::Service)
+ lambda { @provider.run_action(:start) }.should_not raise_error
end
end
end
diff --git a/spec/unit/provider/service/insserv_service_spec.rb b/spec/unit/provider/service/insserv_service_spec.rb
index c823d511b5..04e63458a0 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.
@@ -29,14 +29,14 @@ describe Chef::Provider::Service::Insserv do
@current_resource = Chef::Resource::Service.new("initgrediant")
@provider = Chef::Provider::Service::Insserv.new(@new_resource, @run_context)
- @status = mock("Process::Status mock", :exitstatus => 0, :stdout => "")
- @provider.stub!(:shell_out!).and_return(@status)
+ @status = double("Process::Status mock", :exitstatus => 0, :stdout => "")
+ @provider.stub(:shell_out!).and_return(@status)
end
describe "load_current_resource" do
describe "when startup links exist" 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"])
+ 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
it "sets the current enabled status to true" do
@@ -46,8 +46,8 @@ describe Chef::Provider::Service::Insserv do
end
describe "when startup links do not exist" do
- before do
- Dir.stub!(:glob).with("/etc/rc**/S*initgrediant").and_return([])
+ before do
+ Dir.stub(:glob).with("/etc/rc**/S*initgrediant").and_return([])
end
it "sets the current enabled status to false" do
@@ -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 798b987dd5..b638b08b72 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.
@@ -30,17 +30,17 @@ describe Chef::Provider::Service::Invokercd, "load_current_resource" do
@current_resource = Chef::Resource::Service.new("chef")
@provider = Chef::Provider::Service::Invokercd.new(@new_resource, @run_context)
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
@stdout = StringIO.new(<<-PS)
aj 7842 5057 0 21:26 pts/2 00:00:06 vi init.rb
aj 7903 5016 0 21:26 pts/5 00:00:00 /bin/bash
aj 8119 6041 0 21:34 pts/3 00:00:03 vi init_service_spec.rb
PS
- @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
- @provider.stub!(:shell_out!).and_return(@status)
+ @status = double("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,22 +60,22 @@ 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 status command returns 0" do
- @provider.stub!(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_return(@status)
+ @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
end
it "should set running to false if the status command returns anything except 0" do
- @status.stub!(:exitstatus).and_return(1)
- @provider.stub!(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_return(@status)
+ @status.stub(:exitstatus).and_return(1)
+ @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_false
end
it "should set running to false if the status command raises" do
- @provider.stub!(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ @provider.stub(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
@current_resource.running.should be_false
end
@@ -83,16 +83,16 @@ PS
describe "when a status command has been specified" do
before do
- @new_resource.stub!(:status_command).and_return("/usr/sbin/invoke-rc.d chefhasmonkeypants status")
+ @new_resource.stub(:status_command).and_return("/usr/sbin/invoke-rc.d chefhasmonkeypants status")
end
it "should run the services status command if one has been specified" do
@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,13 +107,13 @@ PS
@provider.define_resource_requirements
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
end
-
+
end
describe "when we have a 'ps' attribute" do
it "should shell_out! the node's ps command" do
- @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
+ @status = double("Status", :exitstatus => 0, :stdout => @stdout)
@provider.should_receive(:shell_out!).with(@node[:command][:ps]).and_return(@status)
@provider.load_current_resource
end
@@ -123,21 +123,21 @@ PS
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 = mock("Status", :exitstatus => 0, :stdout => @stdout)
+ @status = double("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
it "should set running to false if the regex doesn't match" do
- @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
+ @status = double("Status", :exitstatus => 0, :stdout => @stdout)
@provider.should_receive(:shell_out!).and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_false
end
it "should raise an exception if ps fails" do
- @provider.stub!(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ @provider.stub(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.action = :start
@provider.load_current_resource
@provider.define_resource_requirements
@@ -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/macosx_spec.rb b/spec/unit/provider/service/macosx_spec.rb
index 61bd5583e1..65639f2084 100644
--- a/spec/unit/provider/service/macosx_spec.rb
+++ b/spec/unit/provider/service/macosx_spec.rb
@@ -50,12 +50,12 @@ describe Chef::Provider::Service::Macosx do
["redis-server", "io.redis.redis-server"].each do |service_name|
before do
- Dir.stub!(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist"], [])
- provider.stub!(:shell_out!).
+ Dir.stub(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist"], [])
+ provider.stub(:shell_out!).
with("launchctl list", {:group => 1001, :user => 101}).
- and_return(mock("ouput", :stdout => stdout))
+ and_return(double("ouput", :stdout => stdout))
- File.stub!(:stat).and_return(mock("stat", :gid => 1001, :uid => 101))
+ File.stub(:stat).and_return(double("stat", :gid => 1001, :uid => 101))
end
context "#{service_name}" do
@@ -85,7 +85,7 @@ describe Chef::Provider::Service::Macosx do
describe "running unsupported actions" do
before do
- Dir.stub!(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist"], [])
+ Dir.stub(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist"], [])
end
it "should throw an exception when enable action is attempted" do
lambda {provider.run_action(:enable)}.should raise_error(Chef::Exceptions::UnsupportedAction)
@@ -130,7 +130,7 @@ describe Chef::Provider::Service::Macosx do
context "and plist for service is not available" do
before do
- Dir.stub!(:glob).and_return([])
+ Dir.stub(:glob).and_return([])
provider.load_current_resource
end
@@ -141,7 +141,7 @@ describe Chef::Provider::Service::Macosx do
context "and plist for service is available" do
before do
- Dir.stub!(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist"], [])
+ Dir.stub(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist"], [])
provider.load_current_resource
end
@@ -152,7 +152,7 @@ describe Chef::Provider::Service::Macosx do
describe "and several plists match service name" do
it "throws exception" do
- Dir.stub!(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist",
+ Dir.stub(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist",
"/Users/wtf/something.plist"])
provider.load_current_resource
provider.define_resource_requirements
@@ -163,20 +163,20 @@ describe Chef::Provider::Service::Macosx do
end
describe "#start_service" do
before do
- Chef::Resource::Service.stub!(:new).and_return(current_resource)
+ Chef::Resource::Service.stub(:new).and_return(current_resource)
provider.load_current_resource
- current_resource.stub!(:running).and_return(false)
+ current_resource.stub(:running).and_return(false)
end
it "calls the start command if one is specified and service is not running" do
- new_resource.stub!(:start_command).and_return("cowsay dirty")
+ new_resource.stub(:start_command).and_return("cowsay dirty")
provider.should_receive(:shell_out!).with("cowsay dirty")
provider.start_service
end
it "shows warning message if service is already running" do
- current_resource.stub!(:running).and_return(true)
+ current_resource.stub(:running).and_return(true)
Chef::Log.should_receive(:debug).with("service[#{service_name}] already running, not starting")
provider.start_service
@@ -194,21 +194,21 @@ describe Chef::Provider::Service::Macosx do
describe "#stop_service" do
before do
- Chef::Resource::Service.stub!(:new).and_return(current_resource)
+ Chef::Resource::Service.stub(:new).and_return(current_resource)
provider.load_current_resource
- current_resource.stub!(:running).and_return(true)
+ current_resource.stub(:running).and_return(true)
end
it "calls the stop command if one is specified and service is running" do
- new_resource.stub!(:stop_command).and_return("kill -9 123")
+ new_resource.stub(:stop_command).and_return("kill -9 123")
provider.should_receive(:shell_out!).with("kill -9 123")
provider.stop_service
end
it "shows warning message if service is not running" do
- current_resource.stub!(:running).and_return(false)
+ current_resource.stub(:running).and_return(false)
Chef::Log.should_receive(:debug).with("service[#{service_name}] not running, not stopping")
provider.stop_service
@@ -226,15 +226,15 @@ describe Chef::Provider::Service::Macosx do
describe "#restart_service" do
before do
- Chef::Resource::Service.stub!(:new).and_return(current_resource)
+ Chef::Resource::Service.stub(:new).and_return(current_resource)
provider.load_current_resource
- current_resource.stub!(:running).and_return(true)
- provider.stub!(:sleep)
+ current_resource.stub(:running).and_return(true)
+ provider.stub(:sleep)
end
it "issues a command if given" do
- new_resource.stub!(:restart_command).and_return("reload that thing")
+ new_resource.stub(:restart_command).and_return("reload that thing")
provider.should_receive(:shell_out!).with("reload that thing")
provider.restart_service
diff --git a/spec/unit/provider/service/redhat_spec.rb b/spec/unit/provider/service/redhat_spec.rb
index dd874a4f05..8cc6fb6549 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.
@@ -21,18 +21,18 @@ require 'ostruct'
shared_examples_for "define_resource_requirements_common" do
it "should raise an error if /sbin/chkconfig does not exist" do
- File.stub!(:exists?).with("/sbin/chkconfig").and_return(false)
- @provider.stub!(:shell_out).with("/sbin/service chef status").and_raise(Errno::ENOENT)
- @provider.stub!(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_raise(Errno::ENOENT)
+ File.stub(:exists?).with("/sbin/chkconfig").and_return(false)
+ @provider.stub(:shell_out).with("/sbin/service chef status").and_raise(Errno::ENOENT)
+ @provider.stub(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_raise(Errno::ENOENT)
@provider.load_current_resource
@provider.define_resource_requirements
lambda { @provider.process_resource_requirements }.should raise_error(Chef::Exceptions::Service)
end
it "should not raise an error if the service exists but is not added to any runlevels" do
- status = mock("Status", :exitstatus => 0, :stdout => "" , :stderr => "")
+ status = double("Status", :exitstatus => 0, :stdout => "" , :stderr => "")
@provider.should_receive(:shell_out).with("/sbin/service chef status").and_return(status)
- chkconfig = mock("Chkconfig", :exitstatus => 0, :stdout => "", :stderr => "service chef supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add chef')")
+ chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "", :stderr => "service chef supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add chef')")
@provider.should_receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig)
@provider.load_current_resource
@provider.define_resource_requirements
@@ -47,15 +47,15 @@ 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")
@provider = Chef::Provider::Service::Redhat.new(@new_resource, @run_context)
@provider.action = :start
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
- File.stub!(:exists?).with("/sbin/chkconfig").and_return(true)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
+ File.stub(:exists?).with("/sbin/chkconfig").and_return(true)
end
describe "while not in why run mode" do
@@ -65,34 +65,34 @@ describe "Chef::Provider::Service::Redhat" do
describe "load current resource" do
it "sets the current enabled status to true if the service is enabled for any run level" do
- status = mock("Status", :exitstatus => 0, :stdout => "" , :stderr => "")
+ status = double("Status", :exitstatus => 0, :stdout => "" , :stderr => "")
@provider.should_receive(:shell_out).with("/sbin/service chef status").and_return(status)
- chkconfig = mock("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:off 2:off 3:off 4:off 5:on 6:off", :stderr => "")
+ chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:off 2:off 3:off 4:off 5:on 6:off", :stderr => "")
@provider.should_receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig)
@provider.instance_variable_get("@service_missing").should be_false
@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 => "")
+ status = double("Status", :exitstatus => 0, :stdout => "" , :stderr => "")
@provider.should_receive(:shell_out).with("/sbin/service chef status").and_return(status)
- chkconfig = mock("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:off 2:off 3:off 4:off 5:off 6:off", :stderr => "")
+ chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:off 2:off 3:off 4:off 5:off 6:off", :stderr => "")
@provider.should_receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig)
@provider.instance_variable_get("@service_missing").should be_false
@provider.load_current_resource.should eql(@current_resource)
@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")
+ status = double("Status", :exitstatus => 1, :stdout => "", :stderr => "chef: unrecognized service")
@provider.should_receive(:shell_out).with("/sbin/service chef status").and_return(status)
- chkconfig = mock("Chkconfig", :existatus=> 1, :stdout => "", :stderr => "error reading information on service chef: No such file or directory")
+ chkconfig = double("Chkconfig", :existatus=> 1, :stdout => "", :stderr => "error reading information on service chef: No such file or directory")
@provider.should_receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig)
@provider.load_current_resource
@provider.define_resource_requirements
@@ -128,9 +128,9 @@ describe "Chef::Provider::Service::Redhat" do
it_should_behave_like "define_resource_requirements_common"
it "should not raise an error if the service does not exist" do
- status = mock("Status", :exitstatus => 1, :stdout => "", :stderr => "chef: unrecognized service")
+ status = double("Status", :exitstatus => 1, :stdout => "", :stderr => "chef: unrecognized service")
@provider.should_receive(:shell_out).with("/sbin/service chef status").and_return(status)
- chkconfig = mock("Chkconfig", :existatus=> 1, :stdout => "", :stderr => "error reading information on service chef: No such file or directory")
+ chkconfig = double("Chkconfig", :existatus=> 1, :stdout => "", :stderr => "error reading information on service chef: No such file or directory")
@provider.should_receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig)
@provider.load_current_resource
@provider.define_resource_requirements
diff --git a/spec/unit/provider/service/simple_service_spec.rb b/spec/unit/provider/service/simple_service_spec.rb
index cc0173e246..1d94534320 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.
@@ -29,17 +29,17 @@ describe Chef::Provider::Service::Simple, "load_current_resource" do
@current_resource = Chef::Resource::Service.new("chef")
@provider = Chef::Provider::Service::Simple.new(@new_resource, @run_context)
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
@stdout = StringIO.new(<<-NOMOCKINGSTRINGSPLZ)
aj 7842 5057 0 21:26 pts/2 00:00:06 vi init.rb
aj 7903 5016 0 21:26 pts/5 00:00:00 /bin/bash
aj 8119 6041 0 21:34 pts/3 00:00:03 vi simple_service_spec.rb
NOMOCKINGSTRINGSPLZ
- @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
- @provider.stub!(:shell_out!).and_return(@status)
+ @status = double("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
@@ -69,7 +69,7 @@ NOMOCKINGSTRINGSPLZ
end
it "should read stdout of the ps command" do
- @provider.stub!(:shell_out!).and_return(@status)
+ @provider.stub(:shell_out!).and_return(@status)
@stdout.should_receive(:each_line).and_return(true)
@provider.load_current_resource
end
@@ -79,20 +79,20 @@ NOMOCKINGSTRINGSPLZ
aj 7842 5057 0 21:26 pts/2 00:00:06 chef
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
+ @status = double("Status", :exitstatus => 0, :stdout => @stdout)
+ @provider.stub(:shell_out!).and_return(@status)
+ @provider.load_current_resource
@current_resource.running.should be_true
end
it "should set running to false if the regex doesn't match" do
- @provider.stub!(:shell_out!).and_return(@status)
+ @provider.stub(:shell_out!).and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_false
end
it "should raise an exception if ps fails" do
- @provider.stub!(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ @provider.stub(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.action = :start
@provider.load_current_resource
@provider.define_resource_requirements
@@ -108,7 +108,7 @@ NOMOCKINGSTRINGSPLZ
describe "when starting the service" do
it "should call the start command if one is specified" do
- @new_resource.stub!(:start_command).and_return("#{@new_resource.start_command}")
+ @new_resource.stub(:start_command).and_return("#{@new_resource.start_command}")
@provider.should_receive(:shell_out!).with("#{@new_resource.start_command}")
@provider.start_service()
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..887c1f6b5f 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.
@@ -29,41 +29,41 @@ describe Chef::Provider::Service::Solaris do
@current_resource = Chef::Resource::Service.new('chef')
@provider = Chef::Provider::Service::Solaris.new(@new_resource, @run_context)
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
@stdin = StringIO.new
@stdout = StringIO.new
@stderr = StringIO.new
@pid = 2342
@stdout_string = "state disabled"
- @stdout.stub!(:gets).and_return(@stdout_string)
- @status = mock("Status", :exitstatus => 0, :stdout => @stdout)
- @provider.stub!(:shell_out!).and_return(@status)
+ @stdout.stub(:gets).and_return(@stdout_string)
+ @status = double("Status", :exitstatus => 0, :stdout => @stdout)
+ @provider.stub(:shell_out!).and_return(@status)
end
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
before do
- File.stub!(:exists?).with('/bin/svcs').and_return(true)
+ File.stub(:exists?).with('/bin/svcs').and_return(true)
end
describe "when discovering the current service state" do
it "should create a current resource with the name of the new resource" do
- @provider.stub!(:popen4).with("/bin/svcs -l chef").and_return(@status)
+ @provider.stub(:popen4).with("/bin/svcs -l chef").and_return(@status)
Chef::Resource::Service.should_receive(:new).and_return(@current_resource)
@provider.load_current_resource
end
it "should return the current resource" do
- @provider.stub!(:popen4).with("/bin/svcs -l chef").and_return(@status)
+ @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)
@@ -71,14 +71,14 @@ describe Chef::Provider::Service::Solaris do
end
it "should mark service as not running" do
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@current_resource.should_receive(:running).with(false)
@provider.load_current_resource
end
it "should mark service as running" do
- @stdout.stub!(:each).and_yield("state online")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @stdout.stub(:each).and_yield("state online")
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@current_resource.should_receive(:running).with(true)
@provider.load_current_resource
end
@@ -91,14 +91,14 @@ describe Chef::Provider::Service::Solaris do
end
it "should call svcadm enable -s chef" do
- @new_resource.stub!(:enable_command).and_return("#{@new_resource.enable_command}")
+ @new_resource.stub(:enable_command).and_return("#{@new_resource.enable_command}")
@provider.should_receive(:shell_out!).with("/usr/sbin/svcadm enable -s #{@current_resource.service_name}").and_return(@status)
@provider.enable_service.should be_true
@current_resource.enabled.should be_true
end
it "should call svcadm enable -s chef for start_service" do
- @new_resource.stub!(:start_command).and_return("#{@new_resource.start_command}")
+ @new_resource.stub(:start_command).and_return("#{@new_resource.start_command}")
@provider.should_receive(:shell_out!).with("/usr/sbin/svcadm enable -s #{@current_resource.service_name}").and_return(@status)
@provider.start_service.should be_true
@current_resource.enabled.should be_true
@@ -129,7 +129,7 @@ describe Chef::Provider::Service::Solaris do
describe "when reloading the service" do
before(:each) do
- @status = mock("Process::Status", :exitstatus => 0)
+ @status = double("Process::Status", :exitstatus => 0)
@provider.current_resource = @current_resource
end
diff --git a/spec/unit/provider/service/systemd_service_spec.rb b/spec/unit/provider/service/systemd_service_spec.rb
index bca28a2d92..f631bfc31d 100644
--- a/spec/unit/provider/service/systemd_service_spec.rb
+++ b/spec/unit/provider/service/systemd_service_spec.rb
@@ -30,10 +30,10 @@ describe Chef::Provider::Service::Systemd do
describe "load_current_resource" do
before(:each) do
@current_resource = Chef::Resource::Service.new('rsyslog.service')
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
- @provider.stub!(:is_active?).and_return(false)
- @provider.stub!(:is_enabled?).and_return(false)
+ @provider.stub(:is_active?).and_return(false)
+ @provider.stub(:is_enabled?).and_return(false)
end
it "should create a current resource with the name of the new resource" do
@@ -52,46 +52,46 @@ describe Chef::Provider::Service::Systemd do
end
it "should set running to true if the service is running" do
- @provider.stub!(:is_active?).and_return(true)
+ @provider.stub(:is_active?).and_return(true)
@current_resource.should_receive(:running).with(true)
@provider.load_current_resource
end
it "should set running to false if the service is not running" do
- @provider.stub!(:is_active?).and_return(false)
+ @provider.stub(:is_active?).and_return(false)
@current_resource.should_receive(:running).with(false)
@provider.load_current_resource
end
describe "when a status command has been specified" do
before do
- @new_resource.stub!(:status_command).and_return("/bin/chefhasmonkeypants status")
+ @new_resource.stub(:status_command).and_return("/bin/chefhasmonkeypants status")
end
it "should run the services status command if one has been specified" do
- @provider.stub!(:run_command_with_systems_locale).with({:command => "/bin/chefhasmonkeypants status"}).and_return(0)
+ @provider.stub(:run_command_with_systems_locale).with({:command => "/bin/chefhasmonkeypants status"}).and_return(0)
@current_resource.should_receive(:running).with(true)
@provider.load_current_resource
end
it "should run the services status command if one has been specified and properly set status check state" do
- @provider.stub!(:run_command_with_systems_locale).with({:command => "/bin/chefhasmonkeypants status"}).and_return(0)
+ @provider.stub(:run_command_with_systems_locale).with({:command => "/bin/chefhasmonkeypants status"}).and_return(0)
@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)
+ @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.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?)
@@ -99,13 +99,13 @@ describe Chef::Provider::Service::Systemd do
end
it "should set enabled to true if the service is enabled" do
- @provider.stub!(:is_enabled?).and_return(true)
+ @provider.stub(:is_enabled?).and_return(true)
@current_resource.should_receive(:enabled).with(true)
@provider.load_current_resource
end
it "should set enabled to false if the service is not enabled" do
- @provider.stub!(:is_enabled?).and_return(false)
+ @provider.stub(:is_enabled?).and_return(false)
@current_resource.should_receive(:enabled).with(false)
@provider.load_current_resource
end
@@ -118,12 +118,12 @@ describe Chef::Provider::Service::Systemd do
describe "start and stop service" do
before(:each) do
@current_resource = Chef::Resource::Service.new('rsyslog.service')
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
@provider.current_resource = @current_resource
end
it "should call the start command if one is specified" do
- @new_resource.stub!(:start_command).and_return("/sbin/rsyslog startyousillysally")
+ @new_resource.stub(:start_command).and_return("/sbin/rsyslog startyousillysally")
@provider.should_receive(:shell_out!).with("/sbin/rsyslog startyousillysally")
@provider.start_service
end
@@ -134,52 +134,52 @@ describe Chef::Provider::Service::Systemd do
end
it "should not call '/bin/systemctl start service_name' if it is already running" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_not_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl start #{@new_resource.service_name}"})
@provider.start_service
end
it "should call the restart command if one is specified" do
- @current_resource.stub!(:running).and_return(true)
- @new_resource.stub!(:restart_command).and_return("/sbin/rsyslog restartyousillysally")
+ @current_resource.stub(:running).and_return(true)
+ @new_resource.stub(:restart_command).and_return("/sbin/rsyslog restartyousillysally")
@provider.should_receive(:shell_out!).with("/sbin/rsyslog restartyousillysally")
@provider.restart_service
end
it "should call '/bin/systemctl restart service_name' if no restart command is specified" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl restart #{@new_resource.service_name}"}).and_return(0)
@provider.restart_service
end
it "should call the reload command if one is specified" do
- @current_resource.stub!(:running).and_return(true)
- @new_resource.stub!(:reload_command).and_return("/sbin/rsyslog reloadyousillysally")
+ @current_resource.stub(:running).and_return(true)
+ @new_resource.stub(:reload_command).and_return("/sbin/rsyslog reloadyousillysally")
@provider.should_receive(:shell_out!).with("/sbin/rsyslog reloadyousillysally")
@provider.reload_service
end
it "should call '/bin/systemctl reload service_name' if no reload command is specified" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl reload #{@new_resource.service_name}"}).and_return(0)
@provider.reload_service
end
it "should call the stop command if one is specified" do
- @current_resource.stub!(:running).and_return(true)
- @new_resource.stub!(:stop_command).and_return("/sbin/rsyslog stopyousillysally")
+ @current_resource.stub(:running).and_return(true)
+ @new_resource.stub(:stop_command).and_return("/sbin/rsyslog stopyousillysally")
@provider.should_receive(:shell_out!).with("/sbin/rsyslog stopyousillysally")
@provider.stop_service
end
it "should call '/bin/systemctl stop service_name' if no stop command is specified" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl stop #{@new_resource.service_name}"}).and_return(0)
@provider.stop_service
end
it "should not call '/bin/systemctl stop service_name' if it is already stopped" do
- @current_resource.stub!(:running).and_return(false)
+ @current_resource.stub(:running).and_return(false)
@provider.should_not_receive(:run_command_with_systems_locale).with({:command => "/bin/systemctl stop #{@new_resource.service_name}"})
@provider.stop_service
end
@@ -188,7 +188,7 @@ describe Chef::Provider::Service::Systemd do
describe "enable and disable service" do
before(:each) do
@current_resource = Chef::Resource::Service.new('rsyslog.service')
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
@provider.current_resource = @current_resource
end
@@ -206,7 +206,7 @@ describe Chef::Provider::Service::Systemd do
describe "is_active?" do
before(:each) do
@current_resource = Chef::Resource::Service.new('rsyslog.service')
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
end
it "should return true if '/bin/systemctl is-active service_name' returns 0" do
@@ -223,7 +223,7 @@ describe Chef::Provider::Service::Systemd do
describe "is_enabled?" do
before(:each) do
@current_resource = Chef::Resource::Service.new('rsyslog.service')
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
end
it "should return true if '/bin/systemctl is-enabled service_name' returns 0" do
diff --git a/spec/unit/provider/service/upstart_service_spec.rb b/spec/unit/provider/service/upstart_service_spec.rb
index 4224b229e5..154527a7da 100644
--- a/spec/unit/provider/service/upstart_service_spec.rb
+++ b/spec/unit/provider/service/upstart_service_spec.rb
@@ -39,7 +39,7 @@ describe Chef::Provider::Service::Upstart do
it "should return /etc/event.d as the upstart job directory when running on Ubuntu 9.04" do
@node.automatic_attrs[:platform_version] = '9.04'
- #Chef::Platform.stub!(:find_platform_and_version).and_return([ "ubuntu", "9.04" ])
+ #Chef::Platform.stub(:find_platform_and_version).and_return([ "ubuntu", "9.04" ])
@provider = Chef::Provider::Service::Upstart.new(@new_resource, @run_context)
@provider.instance_variable_get(:@upstart_job_dir).should == "/etc/event.d"
@provider.instance_variable_get(:@upstart_conf_suffix).should == ""
@@ -65,17 +65,17 @@ describe Chef::Provider::Service::Upstart do
@node.automatic_attrs[:command] = {:ps => "ps -ax"}
@current_resource = Chef::Resource::Service.new("rsyslog")
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
- @status = mock("Status", :exitstatus => 0)
- @provider.stub!(:popen4).and_return(@status)
+ @status = double("Status", :exitstatus => 0)
+ @provider.stub(:popen4).and_return(@status)
@stdin = StringIO.new
@stdout = StringIO.new
@stderr = StringIO.new
- @pid = mock("PID")
-
- ::File.stub!(:exists?).and_return(true)
- ::File.stub!(:open).and_return(true)
+ @pid = double("PID")
+
+ ::File.stub(:exists?).and_return(true)
+ ::File.stub(:open).and_return(true)
end
it "should create a current resource with the name of the new resource" do
@@ -99,14 +99,14 @@ describe Chef::Provider::Service::Upstart 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.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_true
end
it "should set running to false if the status command returns anything except 0" do
@stdout = StringIO.new("rsyslog stop/waiting")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_false
end
@@ -115,41 +115,41 @@ describe Chef::Provider::Service::Upstart do
describe "when the status command uses the old format" 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.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_true
end
it "should set running to false if the status command returns anything except 0" do
@stdout = StringIO.new("rsyslog (stop) waiting")
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
@current_resource.running.should be_false
end
end
it "should set running to false if it catches a Chef::Exceptions::Exec" do
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_raise(Chef::Exceptions::Exec)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_raise(Chef::Exceptions::Exec)
@current_resource.should_receive(:running).with(false)
@provider.load_current_resource
end
it "should set enabled to true when it finds 'starts on'" do
- @lines = mock("start on filesystem", :gets => "start on filesystem")
- ::File.stub!(:open).and_yield(@lines)
+ @lines = double("start on filesystem", :gets => "start on filesystem")
+ ::File.stub(:open).and_yield(@lines)
@current_resource.should_receive(:running).with(false)
@provider.load_current_resource
end
it "should set enabled to false when it finds '#starts on'" do
- @lines = mock("start on filesystem", :gets => "#start on filesystem")
- ::File.stub!(:open).and_yield(@lines)
+ @lines = double("start on filesystem", :gets => "#start on filesystem")
+ ::File.stub(:open).and_yield(@lines)
@current_resource.should_receive(:running).with(false)
@provider.load_current_resource
end
it "should assume disable when no job configuration file is found" do
- ::File.stub!(:exists?).and_return(false)
+ ::File.stub(:exists?).and_return(false)
@current_resource.should_receive(:running).with(false)
@provider.load_current_resource
end
@@ -163,23 +163,23 @@ describe Chef::Provider::Service::Upstart do
describe "when a status command has been specified" do
before do
- @new_resource.stub!(:status_command).and_return("/bin/chefhasmonkeypants status")
+ @new_resource.stub(:status_command).and_return("/bin/chefhasmonkeypants status")
end
it "should run the services status command if one has been specified" do
- @provider.stub!(:run_command_with_systems_locale).with({:command => "/bin/chefhasmonkeypants status"}).and_return(0)
+ @provider.stub(:run_command_with_systems_locale).with({:command => "/bin/chefhasmonkeypants status"}).and_return(0)
@current_resource.should_receive(:running).with(true)
@provider.load_current_resource
end
- 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)
+ 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
end
it "should set running to false if it catches a Chef::Exceptions::Exec when using a status command" do
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_raise(Chef::Exceptions::Exec)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_raise(Chef::Exceptions::Exec)
@current_resource.should_receive(:running).with(false)
@provider.load_current_resource
end
@@ -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
@@ -201,15 +201,15 @@ describe Chef::Provider::Service::Upstart do
describe "enable and disable service" do
before(:each) do
@current_resource = Chef::Resource::Service.new('rsyslog')
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
@provider.current_resource = @current_resource
- Chef::Util::FileEdit.stub!(:new)
+ Chef::Util::FileEdit.stub(:new)
end
it "should enable the service if it is not enabled" do
@file = Object.new
- Chef::Util::FileEdit.stub!(:new).and_return(@file)
- @current_resource.stub!(:enabled).and_return(false)
+ Chef::Util::FileEdit.stub(:new).and_return(@file)
+ @current_resource.stub(:enabled).and_return(false)
@file.should_receive(:search_file_replace)
@file.should_receive(:write_file)
@provider.enable_service()
@@ -217,8 +217,8 @@ describe Chef::Provider::Service::Upstart do
it "should disable the service if it is enabled" do
@file = Object.new
- Chef::Util::FileEdit.stub!(:new).and_return(@file)
- @current_resource.stub!(:enabled).and_return(true)
+ Chef::Util::FileEdit.stub(:new).and_return(@file)
+ @current_resource.stub(:enabled).and_return(true)
@file.should_receive(:search_file_replace)
@file.should_receive(:write_file)
@provider.disable_service()
@@ -230,12 +230,12 @@ describe Chef::Provider::Service::Upstart do
before(:each) do
@current_resource = Chef::Resource::Service.new('rsyslog')
- Chef::Resource::Service.stub!(:new).and_return(@current_resource)
+ Chef::Resource::Service.stub(:new).and_return(@current_resource)
@provider.current_resource = @current_resource
end
it "should call the start command if one is specified" do
- @new_resource.stub!(:start_command).and_return("/sbin/rsyslog startyousillysally")
+ @new_resource.stub(:start_command).and_return("/sbin/rsyslog startyousillysally")
@provider.should_receive(:shell_out!).with("/sbin/rsyslog startyousillysally")
@provider.start_service()
end
@@ -246,7 +246,7 @@ describe Chef::Provider::Service::Upstart do
end
it "should not call '/sbin/start service_name' if it is already running" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_not_receive(:run_command_with_systems_locale).with({:command => "/sbin/start #{@new_resource.service_name}"})
@provider.start_service()
end
@@ -261,52 +261,52 @@ describe Chef::Provider::Service::Upstart do
end
it "should call the restart command if one is specified" do
- @current_resource.stub!(:running).and_return(true)
- @new_resource.stub!(:restart_command).and_return("/sbin/rsyslog restartyousillysally")
+ @current_resource.stub(:running).and_return(true)
+ @new_resource.stub(:restart_command).and_return("/sbin/rsyslog restartyousillysally")
@provider.should_receive(:shell_out!).with("/sbin/rsyslog restartyousillysally")
@provider.restart_service()
end
it "should call '/sbin/restart service_name' if no restart command is specified" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_receive(:run_command_with_systems_locale).with({:command => "/sbin/restart #{@new_resource.service_name}"}).and_return(0)
@provider.restart_service()
end
it "should call '/sbin/start service_name' if restart_service is called for a stopped service" do
- @current_resource.stub!(:running).and_return(false)
+ @current_resource.stub(:running).and_return(false)
@provider.should_receive(:run_command_with_systems_locale).with({:command => "/sbin/start #{@new_resource.service_name}"}).and_return(0)
@provider.restart_service()
end
it "should call the reload command if one is specified" do
- @current_resource.stub!(:running).and_return(true)
- @new_resource.stub!(:reload_command).and_return("/sbin/rsyslog reloadyousillysally")
+ @current_resource.stub(:running).and_return(true)
+ @new_resource.stub(:reload_command).and_return("/sbin/rsyslog reloadyousillysally")
@provider.should_receive(:shell_out!).with("/sbin/rsyslog reloadyousillysally")
@provider.reload_service()
end
it "should call '/sbin/reload service_name' if no reload command is specified" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_receive(:run_command_with_systems_locale).with({:command => "/sbin/reload #{@new_resource.service_name}"}).and_return(0)
@provider.reload_service()
end
it "should call the stop command if one is specified" do
- @current_resource.stub!(:running).and_return(true)
- @new_resource.stub!(:stop_command).and_return("/sbin/rsyslog stopyousillysally")
+ @current_resource.stub(:running).and_return(true)
+ @new_resource.stub(:stop_command).and_return("/sbin/rsyslog stopyousillysally")
@provider.should_receive(:shell_out!).with("/sbin/rsyslog stopyousillysally")
@provider.stop_service()
end
it "should call '/sbin/stop service_name' if no stop command is specified" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_receive(:run_command_with_systems_locale).with({:command => "/sbin/stop #{@new_resource.service_name}"}).and_return(0)
@provider.stop_service()
end
it "should not call '/sbin/stop service_name' if it is already stopped" do
- @current_resource.stub!(:running).and_return(false)
+ @current_resource.stub(:running).and_return(false)
@provider.should_not_receive(:run_command_with_systems_locale).with({:command => "/sbin/stop #{@new_resource.service_name}"})
@provider.stop_service()
end
diff --git a/spec/unit/provider/service/windows_spec.rb b/spec/unit/provider/service/windows_spec.rb
index a68e798d36..08f5a81a9d 100644
--- a/spec/unit/provider/service/windows_spec.rb
+++ b/spec/unit/provider/service/windows_spec.rb
@@ -31,11 +31,11 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
Win32::Service = Class.new
Win32::Service::AUTO_START = 0x00000002
Win32::Service::DISABLED = 0x00000004
- Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
- mock("StatusStruct", :current_state => "running"))
- Win32::Service.stub!(:config_info).with(@new_resource.service_name).and_return(
- mock("ConfigStruct", :start_type => "auto start"))
- Win32::Service.stub!(:exists?).and_return(true)
+ Win32::Service.stub(:status).with(@new_resource.service_name).and_return(
+ double("StatusStruct", :current_state => "running"))
+ Win32::Service.stub(:config_info).with(@new_resource.service_name).and_return(
+ double("ConfigStruct", :start_type => "auto start"))
+ Win32::Service.stub(:exists?).and_return(true)
end
it "should set the current resources service name to the new resources service name" do
@@ -59,9 +59,9 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
describe Chef::Provider::Service::Windows, "start_service" do
before(:each) do
- Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
- mock("StatusStruct", :current_state => "stopped"),
- mock("StatusStruct", :current_state => "running"))
+ Win32::Service.stub(:status).with(@new_resource.service_name).and_return(
+ double("StatusStruct", :current_state => "stopped"),
+ double("StatusStruct", :current_state => "running"))
end
it "should call the start command if one is specified" do
@@ -78,15 +78,15 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
end
it "should do nothing if the service does not exist" do
- Win32::Service.stub!(:exists?).with(@new_resource.service_name).and_return(false)
+ Win32::Service.stub(:exists?).with(@new_resource.service_name).and_return(false)
Win32::Service.should_not_receive(:start).with(@new_resource.service_name)
@provider.start_service
@new_resource.updated_by_last_action?.should be_false
end
it "should do nothing if the service is running" do
- Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
- mock("StatusStruct", :current_state => "running"))
+ Win32::Service.stub(:status).with(@new_resource.service_name).and_return(
+ double("StatusStruct", :current_state => "running"))
@provider.load_current_resource
Win32::Service.should_not_receive(:start).with(@new_resource.service_name)
@provider.start_service
@@ -95,11 +95,11 @@ 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"),
- mock("StatusStruct", :current_state => "stopped"))
+ Win32::Service.stub(:status).with(@new_resource.service_name).and_return(
+ double("StatusStruct", :current_state => "running"),
+ double("StatusStruct", :current_state => "stopped"))
end
it "should call the stop command if one is specified" do
@@ -116,15 +116,15 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
end
it "should do nothing if the service does not exist" do
- Win32::Service.stub!(:exists?).with(@new_resource.service_name).and_return(false)
+ Win32::Service.stub(:exists?).with(@new_resource.service_name).and_return(false)
Win32::Service.should_not_receive(:stop).with(@new_resource.service_name)
@provider.stop_service
@new_resource.updated_by_last_action?.should be_false
end
it "should do nothing if the service is stopped" do
- Win32::Service.stub!(:status).with(@new_resource.service_name).and_return(
- mock("StatusStruct", :current_state => "stopped"))
+ Win32::Service.stub(:status).with(@new_resource.service_name).and_return(
+ double("StatusStruct", :current_state => "stopped"))
@provider.load_current_resource
Win32::Service.should_not_receive(:stop).with(@new_resource.service_name)
@provider.stop_service
@@ -142,11 +142,11 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
end
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"))
+ Win32::Service.stub(:status).with(@new_resource.service_name).and_return(
+ double("StatusStruct", :current_state => "running"),
+ double("StatusStruct", :current_state => "stopped"),
+ double("StatusStruct", :current_state => "stopped"),
+ double("StatusStruct", :current_state => "running"))
Win32::Service.should_receive(:stop).with(@new_resource.service_name)
Win32::Service.should_receive(:start).with(@new_resource.service_name)
@provider.restart_service
@@ -154,17 +154,17 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
end
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 => "running"))
+ Win32::Service.stub(:status).with(@new_resource.service_name).and_return(
+ double("StatusStruct", :current_state => "stopped"),
+ double("StatusStruct", :current_state => "stopped"),
+ double("StatusStruct", :current_state => "running"))
Win32::Service.should_receive(:start).with(@new_resource.service_name)
@provider.restart_service
@new_resource.updated_by_last_action?.should be_true
end
it "should do nothing if the service does not exist" do
- Win32::Service.stub!(:exists?).with(@new_resource.service_name).and_return(false)
+ Win32::Service.stub(:exists?).with(@new_resource.service_name).and_return(false)
Win32::Service.should_not_receive(:stop).with(@new_resource.service_name)
Win32::Service.should_not_receive(:start).with(@new_resource.service_name)
@provider.restart_service
@@ -176,8 +176,8 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
describe Chef::Provider::Service::Windows, "enable_service" do
before(:each) do
- Win32::Service.stub!(:config_info).with(@new_resource.service_name).and_return(
- mock("ConfigStruct", :start_type => "disabled"))
+ Win32::Service.stub(:config_info).with(@new_resource.service_name).and_return(
+ double("ConfigStruct", :start_type => "disabled"))
end
it "should enable service" do
@@ -187,26 +187,26 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
end
it "should do nothing if the service does not exist" do
- Win32::Service.stub!(:exists?).with(@new_resource.service_name).and_return(false)
+ Win32::Service.stub(:exists?).with(@new_resource.service_name).and_return(false)
Win32::Service.should_not_receive(:configure)
@provider.enable_service
@new_resource.updated_by_last_action?.should be_false
end
it "should do nothing if the service is enabled" do
- Win32::Service.stub!(:config_info).with(@new_resource.service_name).and_return(
- mock("ConfigStruct", :start_type => "auto start"))
+ Win32::Service.stub(:config_info).with(@new_resource.service_name).and_return(
+ double("ConfigStruct", :start_type => "auto start"))
Win32::Service.should_not_receive(:configure)
@provider.enable_service
@new_resource.updated_by_last_action?.should be_false
end
end
-
+
describe Chef::Provider::Service::Windows, "disable_service" do
before(:each) do
- Win32::Service.stub!(:config_info).with(@new_resource.service_name).and_return(
- mock("ConfigStruct", :start_type => "auto start"))
+ Win32::Service.stub(:config_info).with(@new_resource.service_name).and_return(
+ double("ConfigStruct", :start_type => "auto start"))
end
it "should disable service" do
@@ -216,15 +216,15 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
end
it "should do nothing if the service does not exist" do
- Win32::Service.stub!(:exists?).with(@new_resource.service_name).and_return(false)
+ Win32::Service.stub(:exists?).with(@new_resource.service_name).and_return(false)
Win32::Service.should_not_receive(:configure)
@provider.disable_service
@new_resource.updated_by_last_action?.should be_false
end
it "should do nothing if the service is disabled" do
- Win32::Service.stub!(:config_info).with(@new_resource.service_name).and_return(
- mock("ConfigStruct", :start_type => "disabled"))
+ Win32::Service.stub(:config_info).with(@new_resource.service_name).and_return(
+ double("ConfigStruct", :start_type => "disabled"))
@provider.load_current_resource
Win32::Service.should_not_receive(:configure)
@provider.disable_service
diff --git a/spec/unit/provider/service_spec.rb b/spec/unit/provider/service_spec.rb
index 3719af56f2..7ddc01ff0b 100644
--- a/spec/unit/provider/service_spec.rb
+++ b/spec/unit/provider/service_spec.rb
@@ -28,7 +28,7 @@ describe Chef::Provider::Service do
@provider = Chef::Provider::Service.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
end
describe "when enabling the service" do
@@ -52,14 +52,14 @@ describe Chef::Provider::Service do
describe "when disabling the service" do
it "should disable the service if enabled and set the resource as updated" do
- @current_resource.stub!(:enabled).and_return(true)
+ @current_resource.stub(:enabled).and_return(true)
@provider.should_receive(:disable_service).and_return(true)
@provider.run_action(:disable)
@provider.new_resource.should be_updated
end
it "should not disable the service if already disabled" do
- @current_resource.stub!(:enabled).and_return(false)
+ @current_resource.stub(:enabled).and_return(false)
@provider.should_not_receive(:disable_service)
@provider.run_action(:disable)
@provider.new_resource.should_not be_updated
@@ -84,14 +84,14 @@ describe Chef::Provider::Service do
describe "action_stop" do
it "should stop the service if it is running and set the resource as updated" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_receive(:stop_service).and_return(true)
@provider.run_action(:stop)
@provider.new_resource.should be_updated
end
it "should not stop the service if it's already stopped" do
- @current_resource.stub!(:running).and_return(false)
+ @current_resource.stub(:running).and_return(false)
@provider.should_not_receive(:stop_service)
@provider.run_action(:stop)
@provider.new_resource.should_not be_updated
@@ -110,7 +110,7 @@ describe Chef::Provider::Service do
end
it "should restart the service even if it isn't running and set the resource as updated" do
- @current_resource.stub!(:running).and_return(false)
+ @current_resource.stub(:running).and_return(false)
@provider.should_receive(:restart_service).and_return(true)
@provider.run_action(:restart)
@provider.new_resource.should be_updated
@@ -124,19 +124,19 @@ describe Chef::Provider::Service do
it "should raise an exception if reload isn't supported" do
@new_resource.supports(:reload => false)
- @new_resource.stub!(:reload_command).and_return(false)
+ @new_resource.stub(:reload_command).and_return(false)
lambda { @provider.run_action(:reload) }.should raise_error(Chef::Exceptions::UnsupportedAction)
end
it "should reload the service if it is running and set the resource as updated" do
- @current_resource.stub!(:running).and_return(true)
+ @current_resource.stub(:running).and_return(true)
@provider.should_receive(:reload_service).and_return(true)
@provider.run_action(:reload)
@provider.new_resource.should be_updated
end
it "should not reload the service if it's stopped" do
- @current_resource.stub!(:running).and_return(false)
+ @current_resource.stub(:running).and_return(false)
@provider.should_not_receive(:reload_service)
@provider.run_action(:stop)
@provider.new_resource.should_not be_updated
diff --git a/spec/unit/provider/subversion_spec.rb b/spec/unit/provider/subversion_spec.rb
index 81e5860225..f37a42d235 100644
--- a/spec/unit/provider/subversion_spec.rb
+++ b/spec/unit/provider/subversion_spec.rb
@@ -43,9 +43,9 @@ describe Chef::Provider::Subversion do
context "determining the revision of the currently deployed code" do
before do
- @stdout = mock("stdout")
- @stderr = mock("stderr")
- @exitstatus = mock("exitstatus")
+ @stdout = double("stdout")
+ @stderr = double("stderr")
+ @exitstatus = double("exitstatus")
end
it "sets the revision to nil if there isn't any deployed code yet" do
@@ -66,9 +66,9 @@ describe Chef::Provider::Subversion do
::File.should_receive(:exist?).at_least(1).times.with("/my/deploy/dir/.svn").and_return(true)
::File.should_receive(:directory?).with("/my/deploy/dir").and_return(true)
::Dir.should_receive(:chdir).with("/my/deploy/dir").and_yield
- @stdout.stub!(:string).and_return(example_svn_info)
- @stderr.stub!(:string).and_return("")
- @exitstatus.stub!(:exitstatus).and_return(0)
+ @stdout.stub(:string).and_return(example_svn_info)
+ @stderr.stub(:string).and_return("")
+ @exitstatus.stub(:exitstatus).and_return(0)
expected_command = ["svn info", {:cwd=>"/my/deploy/dir"}]
@provider.should_receive(:popen4).with(*expected_command).
and_yield("no-pid", "no-stdin", @stdout,@stderr).
@@ -81,9 +81,9 @@ describe Chef::Provider::Subversion do
::File.should_receive(:exist?).with("/my/deploy/dir/.svn").and_return(true)
::File.should_receive(:directory?).with("/my/deploy/dir").and_return(true)
::Dir.should_receive(:chdir).with("/my/deploy/dir").and_yield
- @stdout.stub!(:string).and_return(example_svn_info)
- @stderr.stub!(:string).and_return("")
- @exitstatus.stub!(:exitstatus).and_return(1)
+ @stdout.stub(:string).and_return(example_svn_info)
+ @stderr.stub(:string).and_return("")
+ @exitstatus.stub(:exitstatus).and_return(1)
@provider.should_receive(:popen4).and_yield("no-pid", "no-stdin", @stdout,@stderr).
and_return(@exitstatus)
@provider.find_current_revision.should be_nil
@@ -99,7 +99,7 @@ describe Chef::Provider::Subversion do
end
it "creates the current_resource object and sets its revision to the current deployment's revision as long as we're not exporting" do
- @provider.stub!(:find_current_revision).and_return("11410")
+ @provider.stub(:find_current_revision).and_return("11410")
@provider.new_resource.instance_variable_set :@action, [:checkout]
@provider.load_current_resource
@provider.current_resource.name.should eql(@resource.name)
@@ -109,8 +109,8 @@ describe Chef::Provider::Subversion do
context "resolving revisions to an integer" do
before do
- @stdout = mock("stdout")
- @stderr = mock("stderr")
+ @stdout = double("stdout")
+ @stderr = double("stderr")
@resource.svn_info_args "--no-auth-cache"
end
@@ -128,11 +128,11 @@ describe Chef::Provider::Subversion do
"Last Changed Author: codeninja\n" +
"Last Changed Rev: 11410\n" + # Last Changed Rev is preferred to Revision
"Last Changed Date: 2009-03-25 06:09:56 -0600 (Wed, 25 Mar 2009)\n\n"
- exitstatus = mock("exitstatus")
- exitstatus.stub!(:exitstatus).and_return(0)
+ exitstatus = double("exitstatus")
+ exitstatus.stub(:exitstatus).and_return(0)
@resource.revision "HEAD"
- @stdout.stub!(:string).and_return(example_svn_info)
- @stderr.stub!(:string).and_return("")
+ @stdout.stub(:string).and_return(example_svn_info)
+ @stderr.stub(:string).and_return("")
expected_command = ["svn info http://svn.example.org/trunk/ --no-auth-cache -rHEAD", {:cwd=>Dir.tmpdir}]
@provider.should_receive(:popen4).with(*expected_command).
and_yield("no-pid","no-stdin",@stdout,@stderr).
@@ -142,11 +142,11 @@ describe Chef::Provider::Subversion do
it "returns a helpful message if data from `svn info` can't be parsed" do
example_svn_info = "some random text from an error message\n"
- exitstatus = mock("exitstatus")
- exitstatus.stub!(:exitstatus).and_return(0)
+ exitstatus = double("exitstatus")
+ exitstatus.stub(:exitstatus).and_return(0)
@resource.revision "HEAD"
- @stdout.stub!(:string).and_return(example_svn_info)
- @stderr.stub!(:string).and_return("")
+ @stdout.stub(:string).and_return(example_svn_info)
+ @stderr.stub(:string).and_return("")
@provider.should_receive(:popen4).and_yield("no-pid","no-stdin",@stdout,@stderr).
and_return(exitstatus)
lambda {@provider.revision_int}.should raise_error(RuntimeError, "Could not parse `svn info` data: some random text from an error message")
@@ -197,7 +197,7 @@ describe Chef::Provider::Subversion do
end
it "runs an export with the --force option" do
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
expected_cmd = "svn export --force -q -r12345 http://svn.example.org/trunk/ /my/deploy/dir"
@provider.should_receive(:run_command).with(:command => expected_cmd)
@provider.run_action(:force_export)
@@ -205,7 +205,7 @@ describe Chef::Provider::Subversion do
end
it "runs the checkout command for action_checkout" do
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
expected_cmd = "svn checkout -q -r12345 http://svn.example.org/trunk/ /my/deploy/dir"
@provider.should_receive(:run_command).with(:command => expected_cmd)
@provider.run_action(:checkout)
@@ -217,17 +217,17 @@ describe Chef::Provider::Subversion do
end
it "should not checkout if the destination exists or is a non empty directory" do
- ::File.stub!(:exist?).with("/my/deploy/dir/.svn").and_return(false)
- ::File.stub!(:exist?).with("/my/deploy/dir").and_return(true)
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
- ::Dir.stub!(:entries).with("/my/deploy/dir").and_return(['.','..','foo','bar'])
+ ::File.stub(:exist?).with("/my/deploy/dir/.svn").and_return(false)
+ ::File.stub(:exist?).with("/my/deploy/dir").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
+ ::Dir.stub(:entries).with("/my/deploy/dir").and_return(['.','..','foo','bar'])
@provider.should_not_receive(:checkout_command)
@provider.run_action(:checkout)
@resource.should_not be_updated
end
it "runs commands with the user and group specified in the resource" do
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
@resource.user "whois"
@resource.group "thisis"
expected_cmd = "svn checkout -q -r12345 http://svn.example.org/trunk/ /my/deploy/dir"
@@ -237,24 +237,24 @@ describe Chef::Provider::Subversion do
end
it "does a checkout for action_sync if there's no deploy dir" do
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::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)
end
it "does a checkout for action_sync if the deploy dir exists but is empty" do
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::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
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
::File.should_receive(:exist?).with("/my/deploy/dir/.svn").and_return(true)
- @provider.stub!(:find_current_revision).and_return("11410")
- @provider.stub!(:current_revision_matches_target_revision?).and_return(false)
+ @provider.stub(:find_current_revision).and_return("11410")
+ @provider.stub(:current_revision_matches_target_revision?).and_return(false)
expected_cmd = "svn update -q -r12345 /my/deploy/dir"
@provider.should_receive(:run_command).with(:command => expected_cmd)
@provider.run_action(:sync)
@@ -262,16 +262,16 @@ describe Chef::Provider::Subversion do
end
it "does not fetch any updates if the remote revision matches the current revision" do
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
::File.should_receive(:exist?).with("/my/deploy/dir/.svn").and_return(true)
- @provider.stub!(:find_current_revision).and_return('12345')
- @provider.stub!(:current_revision_matches_target_revision?).and_return(true)
+ @provider.stub(:find_current_revision).and_return('12345')
+ @provider.stub(:current_revision_matches_target_revision?).and_return(true)
@provider.run_action(:sync)
@resource.should_not be_updated
end
it "runs the export_command on action_export" do
- ::File.stub!(:directory?).with("/my/deploy").and_return(true)
+ ::File.stub(:directory?).with("/my/deploy").and_return(true)
expected_cmd = "svn export --force -q -r12345 http://svn.example.org/trunk/ /my/deploy/dir"
@provider.should_receive(:run_command).with(:command => expected_cmd)
@provider.run_action(:export)
diff --git a/spec/unit/provider/template/content_spec.rb b/spec/unit/provider/template/content_spec.rb
index 4061d99d7b..dfc5d21c2a 100644
--- a/spec/unit/provider/template/content_spec.rb
+++ b/spec/unit/provider/template/content_spec.rb
@@ -21,7 +21,7 @@ require 'spec_helper'
describe Chef::Provider::Template::Content do
let(:new_resource) do
- mock("Chef::Resource::Template (new)",
+ double("Chef::Resource::Template (new)",
:cookbook_name => 'openldap',
:source => 'openldap_stuff.conf.erb',
:local => false,
@@ -41,11 +41,11 @@ describe Chef::Provider::Template::Content do
cl.load_cookbooks
cookbook_collection = Chef::CookbookCollection.new(cl)
node = Chef::Node.new
- mock("Chef::Resource::RunContext", :node => node, :cookbook_collection => cookbook_collection)
+ double("Chef::Resource::RunContext", :node => node, :cookbook_collection => cookbook_collection)
end
let(:content) do
- current_resource = mock("Chef::Resource::Template (current)")
+ current_resource = double("Chef::Resource::Template (current)")
Chef::Provider::Template::Content.new(new_resource, current_resource, run_context)
end
@@ -58,15 +58,15 @@ describe Chef::Provider::Template::Content do
end
it "finds the template file locally if it is local" do
- new_resource.stub!(:local).and_return(true)
- new_resource.stub!(:source).and_return('/tmp/its_on_disk.erb')
+ new_resource.stub(:local).and_return(true)
+ new_resource.stub(:source).and_return('/tmp/its_on_disk.erb')
content.template_location.should == '/tmp/its_on_disk.erb'
end
it "should use the cookbook name if defined in the template resource" do
- new_resource.stub!(:cookbook_name).and_return('apache2')
- new_resource.stub!(:cookbook).and_return('openldap')
- new_resource.stub!(:source).and_return("test.erb")
+ new_resource.stub(:cookbook_name).and_return('apache2')
+ new_resource.stub(:cookbook).and_return('openldap')
+ new_resource.stub(:source).and_return("test.erb")
content.template_location.should == CHEF_SPEC_DATA + '/cookbooks/openldap/templates/default/test.erb'
end
diff --git a/spec/unit/provider/template_spec.rb b/spec/unit/provider/template_spec.rb
index ca8f1db5e2..514bdc12ff 100644
--- a/spec/unit/provider/template_spec.rb
+++ b/spec/unit/provider/template_spec.rb
@@ -39,7 +39,7 @@ describe Chef::Provider::Template do
let(:provider) do
provider = described_class.new(resource, run_context)
- provider.stub!(:content).and_return(content)
+ provider.stub(:content).and_return(content)
provider
end
@@ -50,7 +50,7 @@ describe Chef::Provider::Template do
end
let(:content) do
- content = mock('Chef::Provider::File::Content::Template', :template_location => "/foo/bar/baz")
+ content = double('Chef::Provider::File::Content::Template', :template_location => "/foo/bar/baz")
File.stub(:exists?).with("/foo/bar/baz").and_return(true)
content
end
@@ -73,16 +73,18 @@ describe Chef::Provider::Template do
let(:provider) do
provider = described_class.new(resource, run_context)
- provider.stub!(:content).and_return(content)
+ provider.stub(:content).and_return(content)
provider
end
it "stops executing when the local template source can't be found" do
setup_normal_file
- content.stub!(:template_location).and_return("/baz/bar/foo")
+ content.stub(:template_location).and_return("/baz/bar/foo")
File.stub(:exists?).with("/baz/bar/foo").and_return(false)
lambda { provider.run_action(:create) }.should raise_error Chef::Mixin::WhyRun::ResourceRequirements::Assertion::AssertionFailure
end
end
+
+ it_behaves_like "a file provider with source field"
end
diff --git a/spec/unit/provider/user/dscl_spec.rb b/spec/unit/provider/user/dscl_spec.rb
index 3894cd61b4..c7657aa6e5 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)
@@ -64,9 +64,9 @@ describe Chef::Provider::User::Dscl do
describe "get_free_uid" do
before do
- @provider.stub!(:safe_dscl).and_return("\nwheel 200\nstaff 201\n")
+ @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)
@@ -84,14 +84,14 @@ describe Chef::Provider::User::Dscl do
describe "uid_used?" do
before do
- @provider.stub!(:safe_dscl).and_return("\naj 500\n")
+ @provider.stub(:safe_dscl).and_return("\naj 500\n")
end
it "should run safe_dscl with list /Users uid" 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
@@ -107,11 +107,11 @@ describe Chef::Provider::User::Dscl do
describe "when determining the uid to set" do
it "raises RequestedUIDUnavailable if the requested uid is already in use" do
- @provider.stub!(:uid_used?).and_return(true)
+ @provider.stub(:uid_used?).and_return(true)
@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,26 +151,26 @@ 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)
-
+ ::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
it "should raise an exception when the systems user template dir (skel) cannot be found" do
- ::File.stub!(:exists?).and_return(false,false,false)
+ ::File.stub(:exists?).and_return(false,false,false)
lambda { @provider.modify_home }.should raise_error(Chef::Exceptions::User)
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
@@ -284,7 +284,7 @@ describe Chef::Provider::User::Dscl 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)
@new_resource.password("password")
- OpenSSL::Random.stub!(:random_bytes).and_return("\377\377\377\377\377\377\377\377")
+ OpenSSL::Random.stub(:random_bytes).and_return("\377\377\377\377\377\377\377\377")
expected_salted_sha1 = "F"*8+"SHA1-"*8
expected_shadow_hash = "00000000"*155
expected_shadow_hash[168] = expected_salted_sha1
@@ -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
@@ -324,8 +324,8 @@ describe Chef::Provider::User::Dscl do
end
it "shouldn't raise an error if /usr/bin/dscl exists" do
- ::File.stub!(:exists?).and_return(true)
- lambda { @provider.load_current_resource }.should_not raise_error(Chef::Exceptions::User)
+ ::File.stub(:exists?).and_return(true)
+ lambda { @provider.load_current_resource }.should_not raise_error
end
end
@@ -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..1d5ad38c9c 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")
@@ -62,13 +62,13 @@ describe Chef::Provider::User::Pw do
end
it "should set the option for #{attribute} if the new resources #{attribute} is not null" do
- @new_resource.stub!(attribute).and_return("hola")
+ @new_resource.stub(attribute).and_return("hola")
@provider.set_options.should eql(" #{@new_resource.username} #{option} '#{@new_resource.send(attribute)}' -m")
end
it "should set the option for #{attribute} if the new resources #{attribute} is not null, without homedir management" do
- @new_resource.stub!(:supports).and_return({:manage_home => false})
- @new_resource.stub!(attribute).and_return("hola")
+ @new_resource.stub(:supports).and_return({:manage_home => false})
+ @new_resource.stub(attribute).and_return("hola")
@provider.set_options.should eql(" #{@new_resource.username} #{option} '#{@new_resource.send(attribute)}'")
end
end
@@ -76,7 +76,7 @@ describe Chef::Provider::User::Pw do
it "should combine all the possible options" do
match_string = " adam"
field_list.sort{ |a,b| a[0] <=> b[0] }.each do |attribute, option|
- @new_resource.stub!(attribute).and_return("hola")
+ @new_resource.stub(attribute).and_return("hola")
match_string << " #{option} 'hola'"
end
match_string << " -m"
@@ -86,8 +86,8 @@ describe Chef::Provider::User::Pw do
describe "create_user" do
before(:each) do
- @provider.stub!(:run_command).and_return(true)
- @provider.stub!(:modify_password).and_return(true)
+ @provider.stub(:run_command).and_return(true)
+ @provider.stub(:modify_password).and_return(true)
end
it "should run pw useradd with the return of set_options" do
@@ -103,8 +103,8 @@ describe Chef::Provider::User::Pw do
describe "manage_user" do
before(:each) do
- @provider.stub!(:run_command).and_return(true)
- @provider.stub!(:modify_password).and_return(true)
+ @provider.stub(:run_command).and_return(true)
+ @provider.stub(:modify_password).and_return(true)
end
it "should run pw usermod with the return of set_options" do
@@ -133,12 +133,12 @@ describe Chef::Provider::User::Pw do
describe "determining if the user is locked" do
it "should return true if user is locked" do
- @current_resource.stub!(:password).and_return("*LOCKED*abracadabra")
+ @current_resource.stub(:password).and_return("*LOCKED*abracadabra")
@provider.check_lock.should eql(true)
end
it "should return false if user is not locked" do
- @current_resource.stub!(:password).and_return("abracadabra")
+ @current_resource.stub(:password).and_return("abracadabra")
@provider.check_lock.should eql(false)
end
end
@@ -159,8 +159,8 @@ describe Chef::Provider::User::Pw do
describe "when modifying the password" do
before(:each) do
- @status = mock("Status", :exitstatus => 0)
- @provider.stub!(:popen4).and_return(@status)
+ @status = double("Status", :exitstatus => 0)
+ @provider.stub(:popen4).and_return(@status)
@pid, @stdin, @stdout, @stderr = nil, nil, nil, nil
end
@@ -172,8 +172,8 @@ describe Chef::Provider::User::Pw do
describe "and the passwords are identical" do
before(:each) do
- @new_resource.stub!(:password).and_return("abracadabra")
- @current_resource.stub!(:password).and_return("abracadabra")
+ @new_resource.stub(:password).and_return("abracadabra")
+ @current_resource.stub(:password).and_return("abracadabra")
end
it "logs an appropriate message" do
@@ -184,8 +184,8 @@ describe Chef::Provider::User::Pw do
describe "and the passwords are different" do
before(:each) do
- @new_resource.stub!(:password).and_return("abracadabra")
- @current_resource.stub!(:password).and_return("sesame")
+ @new_resource.stub(:password).and_return("abracadabra")
+ @current_resource.stub(:password).and_return("sesame")
end
it "should log an appropriate message" do
@@ -200,7 +200,7 @@ describe Chef::Provider::User::Pw do
it "should send the new password to the stdin of pw usermod" do
@stdin = StringIO.new
- @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @provider.stub(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.modify_password
@stdin.string.should == "abracadabra\n"
end
@@ -212,7 +212,7 @@ describe Chef::Provider::User::Pw do
it "should not raise an exception if pw usermod succeeds" do
@status.should_receive(:exitstatus).and_return(0)
- lambda { @provider.modify_password }.should_not raise_error(Chef::Exceptions::User)
+ lambda { @provider.modify_password }.should_not raise_error
end
end
end
@@ -228,8 +228,8 @@ describe Chef::Provider::User::Pw do
end
it "shouldn't raise an error if /usr/sbin/pw exists" do
- File.stub!(:exists?).and_return(true)
- lambda { @provider.load_current_resource }.should_not raise_error(Chef::Exceptions::User)
+ File.stub(:exists?).and_return(true)
+ lambda { @provider.load_current_resource }.should_not raise_error
end
end
end
diff --git a/spec/unit/provider/user/solaris_spec.rb b/spec/unit/provider/user/solaris_spec.rb
index 5500eac812..d8bd0f9e75 100644
--- a/spec/unit/provider/user/solaris_spec.rb
+++ b/spec/unit/provider/user/solaris_spec.rb
@@ -27,7 +27,7 @@ describe Chef::Provider::User::Solaris do
p.current_resource = @current_resource
# Prevent the useradd-based provider tests from trying to write /etc/shadow
- p.stub!(:write_shadow_file)
+ p.stub(:write_shadow_file)
p
end
@@ -52,12 +52,12 @@ describe Chef::Provider::User::Solaris do
@new_resource.password "hocus-pocus"
# Let these tests run #write_shadow_file
- provider.unstub!(:write_shadow_file)
+ provider.unstub(:write_shadow_file)
end
it "should use its own shadow file writer to set the password" do
provider.should_receive(:write_shadow_file)
- provider.stub!(:shell_out!).and_return(true)
+ provider.stub(:shell_out!).and_return(true)
provider.manage_user
end
@@ -66,10 +66,10 @@ describe Chef::Provider::User::Solaris do
password_file.puts "adam:existingpassword:15441::::::"
password_file.close
provider.password_file = password_file.path
- provider.stub!(:shell_out!).and_return(true)
+ provider.stub(:shell_out!).and_return(true)
# may not be able to write to /etc for tests...
temp_file = Tempfile.new("shadow")
- Tempfile.stub!(:new).with("shadow", "/etc").and_return(temp_file)
+ Tempfile.stub(:new).with("shadow", "/etc").and_return(temp_file)
@new_resource.password "verysecurepassword"
provider.manage_user
::File.open(password_file.path, "r").read.should =~ /adam:verysecurepassword:/
diff --git a/spec/unit/provider/user/windows_spec.rb b/spec/unit/provider/user/windows_spec.rb
index 6ede11b28c..70adb8025a 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.
@@ -35,13 +35,13 @@ describe Chef::Provider::User::Windows do
@run_context = Chef::RunContext.new(@node, {}, @events)
@current_resource = Chef::Resource::User.new("monkey")
- @net_user = mock("Chef::Util::Windows::NetUser")
- Chef::Util::Windows::NetUser.stub!(:new).and_return(@net_user)
+ @net_user = double("Chef::Util::Windows::NetUser")
+ Chef::Util::Windows::NetUser.stub(:new).and_return(@net_user)
@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")
@@ -120,7 +120,7 @@ describe Chef::Provider::User::Windows do
describe "when creating the user" do
it "should call @net_user.add with the return of set_options" do
- @provider.stub!(:set_options).and_return(:name=> "monkey")
+ @provider.stub(:set_options).and_return(:name=> "monkey")
@net_user.should_receive(:add).with(:name=> "monkey")
@provider.create_user
end
@@ -128,9 +128,9 @@ describe Chef::Provider::User::Windows do
describe "manage_user" do
before(:each) do
- @provider.stub!(:set_options).and_return(:name=> "monkey")
+ @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
@@ -150,19 +150,19 @@ describe Chef::Provider::User::Windows do
end
it "should return true if user is locked" do
- @net_user.stub!(:check_enabled).and_return(true)
+ @net_user.stub(:check_enabled).and_return(true)
@provider.check_lock.should eql(true)
end
it "should return false if user is not locked" do
- @net_user.stub!(:check_enabled).and_return(false)
+ @net_user.stub(:check_enabled).and_return(false)
@provider.check_lock.should eql(false)
end
end
describe "locking the user" do
it "should call @net_user.disable_account" do
- @net_user.stub!(:check_enabled).and_return(true)
+ @net_user.stub(:check_enabled).and_return(true)
@net_user.should_receive(:disable_account)
@provider.lock_user
end
@@ -170,7 +170,7 @@ describe Chef::Provider::User::Windows do
describe "unlocking the user" do
it "should call @net_user.enable_account" do
- @net_user.stub!(:check_enabled).and_return(false)
+ @net_user.stub(:check_enabled).and_return(false)
@net_user.should_receive(:enable_account)
@provider.unlock_user
end
diff --git a/spec/unit/provider/user_spec.rb b/spec/unit/provider/user_spec.rb
index 0b3d000b4b..153db6f283 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 = double("Chef::Resource::User",
# :null_object => true,
# :username => "adam",
# :comment => "Adam Jacob",
@@ -69,7 +69,7 @@ describe Chef::Provider::User do
# :password => nil,
# :updated => nil
#)
- Chef::Resource::User.stub!(:new).and_return(@current_resource)
+ Chef::Resource::User.stub(:new).and_return(@current_resource)
@pw_user = EtcPwnamIsh.new
@pw_user.name = "adam"
@pw_user.gid = 1000
@@ -78,7 +78,7 @@ describe Chef::Provider::User do
@pw_user.dir = "/home/adam"
@pw_user.shell = "/usr/bin/zsh"
@pw_user.passwd = "*"
- Etc.stub!(:getpwnam).and_return(@pw_user)
+ Etc.stub(:getpwnam).and_return(@pw_user)
end
it "should create a current resource with the same name as the new resource" do
@@ -91,6 +91,12 @@ describe Chef::Provider::User do
@current_resource.username.should == @new_resource.username
end
+ it "should change the encoding of gecos to the encoding of the new resource", :ruby_gte_19_only do
+ @pw_user.gecos.force_encoding('ASCII-8BIT')
+ @provider.load_current_resource
+ @provider.current_resource.comment.encoding.should == @new_resource.comment.encoding
+ end
+
it "should look up the user in /etc/passwd with getpwnam" do
Etc.should_receive(:getpwnam).with(@new_resource.username).and_return(@pw_user)
@provider.load_current_resource
@@ -123,7 +129,7 @@ describe Chef::Provider::User do
end
it "shouldn't try and convert the group gid if none has been supplied" do
- @new_resource.stub!(:gid).and_return(nil)
+ @new_resource.stub(:gid).and_return(nil)
@provider.should_not_receive(:convert_group_name)
@provider.load_current_resource
end
@@ -150,19 +156,19 @@ describe Chef::Provider::User do
user.name = "root"
user.passwd = "x"
@new_resource.password "some new password"
- Etc.stub!(:getpwnam).and_return(user)
+ 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 +183,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",
+ @provider.stub(:load_current_resource)
+ # @current_resource = double("Chef::Resource::User",
# :null_object => true,
# :username => "adam",
# :comment => "Adam Jacob",
@@ -242,8 +240,8 @@ describe Chef::Provider::User do
# @provider = Chef::Provider::User.new(@node, @new_resource)
# @provider.current_resource = @current_resource
# @provider.user_exists = false
- # @provider.stub!(:create_user).and_return(true)
- # @provider.stub!(:manage_user).and_return(true)
+ # @provider.stub(:create_user).and_return(true)
+ # @provider.stub(:manage_user).and_return(true)
end
it "should call create_user if the user does not exist" do
@@ -256,15 +254,15 @@ describe Chef::Provider::User do
it "should call manage_user if the user exists and has mismatched attributes" do
@provider.user_exists = true
- @provider.stub!(:compare_user).and_return(true)
+ @provider.stub(:compare_user).and_return(true)
@provider.should_receive(:manage_user).and_return(true)
@provider.action_create
end
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)
+ @provider.stub(:compare_user).and_return(true)
+ @provider.stub(:manage_user).and_return(true)
@provider.action_create
@provider.set_updated_status
@new_resource.should be_updated
@@ -273,12 +271,12 @@ describe Chef::Provider::User do
describe "action_remove" do
before(:each) do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
end
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
@@ -299,18 +297,18 @@ describe Chef::Provider::User do
describe "action_manage" do
before(:each) do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
# @node = Chef::Node.new
- # @new_resource = mock("Chef::Resource::User",
+ # @new_resource = double("Chef::Resource::User",
# :null_object => true
# )
- # @current_resource = mock("Chef::Resource::User",
+ # @current_resource = double("Chef::Resource::User",
# :null_object => true
# )
# @provider = Chef::Provider::User.new(@node, @new_resource)
# @provider.current_resource = @current_resource
# @provider.user_exists = true
- # @provider.stub!(:manage_user).and_return(true)
+ # @provider.stub(:manage_user).and_return(true)
end
it "should run manage_user if the user exists and has mismatched attributes" do
@@ -320,8 +318,8 @@ describe Chef::Provider::User do
end
it "should set the new resources updated flag to true if manage_user is called" do
- @provider.stub!(:compare_user).and_return(true)
- @provider.stub!(:manage_user).and_return(true)
+ @provider.stub(:compare_user).and_return(true)
+ @provider.stub(:manage_user).and_return(true)
@provider.action_manage
@provider.set_updated_status
@new_resource.should be_updated
@@ -342,18 +340,18 @@ describe Chef::Provider::User do
describe "action_modify" do
before(:each) do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
# @node = Chef::Node.new
- # @new_resource = mock("Chef::Resource::User",
+ # @new_resource = double("Chef::Resource::User",
# :null_object => true
# )
- # @current_resource = mock("Chef::Resource::User",
+ # @current_resource = double("Chef::Resource::User",
# :null_object => true
# )
# @provider = Chef::Provider::User.new(@node, @new_resource)
# @provider.current_resource = @current_resource
# @provider.user_exists = true
- # @provider.stub!(:manage_user).and_return(true)
+ # @provider.stub(:manage_user).and_return(true)
end
it "should run manage_user if the user exists and has mismatched attributes" do
@@ -363,8 +361,8 @@ describe Chef::Provider::User do
end
it "should set the new resources updated flag to true if manage_user is called" do
- @provider.stub!(:compare_user).and_return(true)
- @provider.stub!(:manage_user).and_return(true)
+ @provider.stub(:compare_user).and_return(true)
+ @provider.stub(:manage_user).and_return(true)
@provider.action_modify
@provider.set_updated_status
@new_resource.should be_updated
@@ -385,16 +383,16 @@ describe Chef::Provider::User do
describe "action_lock" do
before(:each) do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
end
it "should lock the user if it exists and is unlocked" do
- @provider.stub!(:check_lock).and_return(false)
+ @provider.stub(:check_lock).and_return(false)
@provider.should_receive(:lock_user).and_return(true)
@provider.action_lock
end
it "should set the new resources updated flag to true if lock_user is called" do
- @provider.stub!(:check_lock).and_return(false)
+ @provider.stub(:check_lock).and_return(false)
@provider.should_receive(:lock_user)
@provider.action_lock
@provider.set_updated_status
@@ -411,23 +409,23 @@ describe Chef::Provider::User do
describe "action_unlock" do
before(:each) do
- @provider.stub!(:load_current_resource)
+ @provider.stub(:load_current_resource)
# @node = Chef::Node.new
- # @new_resource = mock("Chef::Resource::User",
+ # @new_resource = double("Chef::Resource::User",
# :null_object => true
# )
- # @current_resource = mock("Chef::Resource::User",
+ # @current_resource = double("Chef::Resource::User",
# :null_object => true
# )
# @provider = Chef::Provider::User.new(@node, @new_resource)
# @provider.current_resource = @current_resource
# @provider.user_exists = true
- # @provider.stub!(:check_lock).and_return(true)
- # @provider.stub!(:unlock_user).and_return(true)
+ # @provider.stub(:check_lock).and_return(true)
+ # @provider.stub(:unlock_user).and_return(true)
end
it "should unlock the user if it exists and is locked" do
- @provider.stub!(:check_lock).and_return(true)
+ @provider.stub(:check_lock).and_return(true)
@provider.should_receive(:unlock_user).and_return(true)
@provider.action_unlock
@provider.set_updated_status
diff --git a/spec/unit/provider/whyrun_safe_ruby_block_spec.rb b/spec/unit/provider/whyrun_safe_ruby_block_spec.rb
new file mode 100644
index 0000000000..5a17aacbd9
--- /dev/null
+++ b/spec/unit/provider/whyrun_safe_ruby_block_spec.rb
@@ -0,0 +1,47 @@
+#
+# Author:: Phil Dibowitz (<phild@fb.com>)
+# Copyright:: Copyright (c) 2013 Facebook
+# 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::WhyrunSafeRubyBlock, "initialize" do
+ before(:each) do
+ $evil_global_evil_laugh = :wahwah
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ @new_resource = Chef::Resource::WhyrunSafeRubyBlock.new("bloc party")
+ @new_resource.block { $evil_global_evil_laugh = :mwahahaha}
+ @provider = Chef::Provider::WhyrunSafeRubyBlock.new(@new_resource, @run_context)
+ end
+
+ it "should call the block and flag the resource as updated" do
+ @provider.run_action(:create)
+ $evil_global_evil_laugh.should == :mwahahaha
+ @new_resource.should be_updated
+ end
+
+ it "should call the block and flat the resource as updated - even in whyrun" do
+ Chef::Config[:why_run] = true
+ @provider.run_action(:create)
+ $evil_global_evil_laugh.should == :mwahahaha
+ @new_resource.should be_updated
+ Chef::Config[:why_run] = false
+ end
+
+end
+
diff --git a/spec/unit/provider_spec.rb b/spec/unit/provider_spec.rb
index 7873be0f28..363649ec46 100644
--- a/spec/unit/provider_spec.rb
+++ b/spec/unit/provider_spec.rb
@@ -93,15 +93,15 @@ describe Chef::Provider do
it "does not re-load recipes when creating the temporary run context" do
# we actually want to test that RunContext#load is never called, but we
# can't stub all instances of an object with rspec's mocks. :/
- Chef::RunContext.stub!(:new).and_raise("not supposed to happen")
+ Chef::RunContext.stub(:new).and_raise("not supposed to happen")
snitch = Proc.new {temporary_collection = @run_context.resource_collection}
@provider.send(:recipe_eval, &snitch)
end
context "when no converge actions are queued" do
before do
- @provider.stub!(:whyrun_supported?).and_return(true)
- @provider.stub!(:load_current_resource)
+ @provider.stub(:whyrun_supported?).and_return(true)
+ @provider.stub(:load_current_resource)
end
it "does not mark the new resource as updated" do
diff --git a/spec/unit/recipe_spec.rb b/spec/unit/recipe_spec.rb
index 4615bcb4d4..b0cd04b245 100644
--- a/spec/unit/recipe_spec.rb
+++ b/spec/unit/recipe_spec.rb
@@ -22,84 +22,94 @@
require 'spec_helper'
describe Chef::Recipe do
- before(:each) do
- @cookbook_repo = File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "cookbooks"))
- cl = Chef::CookbookLoader.new(@cookbook_repo)
- cl.load_cookbooks
- @cookbook_collection = Chef::CookbookCollection.new(cl)
- @node = Chef::Node.new
- @node.normal[:tags] = Array.new
- @events = Chef::EventDispatch::Dispatcher.new
- @run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
- @recipe = Chef::Recipe.new("hjk", "test", @run_context)
-
- # Shell/ext.rb is on the run path, and it defines
- # Chef::Recipe#resources to call pp, which we don't want when
- # we're running tests.
- @recipe.stub!(:pp)
+
+ let(:cookbook_repo) { File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "cookbooks")) }
+
+ let(:cookbook_loader) do
+ loader = Chef::CookbookLoader.new(cookbook_repo)
+ loader.load_cookbooks
+ loader
+ end
+
+ let(:cookbook_collection) { Chef::CookbookCollection.new(cookbook_loader) }
+
+ let(:node) do
+ Chef::Node.new.tap {|n| n.normal[:tags] = [] }
+ end
+
+ let(:events) do
+ Chef::EventDispatch::Dispatcher.new
+ end
+
+ let(:run_context) do
+ Chef::RunContext.new(node, cookbook_collection, events)
+ end
+
+ let(:recipe) do
+ Chef::Recipe.new("hjk", "test", run_context)
end
describe "method_missing" do
describe "resources" do
it "should load a two word (zen_master) resource" do
lambda do
- @recipe.zen_master "monkey" do
+ recipe.zen_master "monkey" do
peace true
end
- end.should_not raise_error(ArgumentError)
+ end.should_not raise_error
end
it "should load a one word (cat) resource" do
lambda do
- @recipe.cat "loulou" do
+ recipe.cat "loulou" do
pretty_kitty true
end
- end.should_not raise_error(ArgumentError)
+ end.should_not raise_error
end
it "should load a four word (one_two_three_four) resource" do
lambda do
- @recipe.one_two_three_four "numbers" do
+ recipe.one_two_three_four "numbers" do
i_can_count true
end
- end.should_not raise_error(ArgumentError)
+ end.should_not raise_error
end
it "should throw an error if you access a resource that we can't find" do
- lambda { @recipe.not_home("not_home_resource") }.should raise_error(NameError)
+ lambda { recipe.not_home("not_home_resource") }.should raise_error(NameError)
end
it "should require a name argument" do
lambda {
- @recipe.cat
+ recipe.cat
}.should raise_error(ArgumentError, "You must supply a name when declaring a cat resource")
end
it "should allow regular errors (not NameErrors) to pass unchanged" do
lambda {
- @recipe.cat("felix") { raise ArgumentError, "You Suck" }
+ recipe.cat("felix") { raise ArgumentError, "You Suck" }
}.should raise_error(ArgumentError)
end
it "should add our zen_master to the collection" do
- @recipe.zen_master "monkey" do
+ recipe.zen_master "monkey" do
peace true
end
- @run_context.resource_collection.lookup("zen_master[monkey]").name.should eql("monkey")
+ run_context.resource_collection.lookup("zen_master[monkey]").name.should eql("monkey")
end
it "should add our zen masters to the collection in the order they appear" do
%w{monkey dog cat}.each do |name|
- @recipe.zen_master name do
+ recipe.zen_master name do
peace true
end
end
- @run_context.resource_collection.map{|r| r.name}.should eql(["monkey", "dog", "cat"])
+ run_context.resource_collection.map{|r| r.name}.should eql(["monkey", "dog", "cat"])
end
it "should return the new resource after creating it" do
- res = @recipe.zen_master "makoto" do
+ res = recipe.zen_master "makoto" do
peace true
end
res.resource_name.should eql(:zen_master)
@@ -110,16 +120,16 @@ describe Chef::Recipe do
it "locate resource for particular platform" do
Object.const_set('ShaunTheSheep', Class.new(Chef::Resource){ provides :laughter, :on_platforms => ["television"] })
- @node.automatic[:platform] = "television"
- @node.automatic[:platform_version] = "123"
- res = @recipe.laughter "timmy"
+ node.automatic[:platform] = "television"
+ node.automatic[:platform_version] = "123"
+ res = recipe.laughter "timmy"
res.name.should eql("timmy")
res.kind_of?(ShaunTheSheep)
end
it "locate a resource for all platforms" do
Object.const_set("YourMom", Class.new(Chef::Resource){ provides :love_and_caring })
- res = @recipe.love_and_caring "mommy"
+ res = recipe.love_and_caring "mommy"
res.name.should eql("mommy")
res.kind_of?(YourMom)
end
@@ -127,6 +137,141 @@ describe Chef::Recipe do
end
end
+ describe "creating resources via build_resource" do
+ let(:zm_resource) do
+ recipe.build_resource(:zen_master, "klopp") do
+ something "bvb"
+ end
+ end
+
+ it "applies attributes from the block to the resource" do
+ zm_resource.something.should == "bvb"
+ end
+
+ it "sets contextual attributes on the resource" do
+ zm_resource.recipe_name.should == "test"
+ zm_resource.cookbook_name.should == "hjk"
+ zm_resource.source_line.should include(__FILE__)
+ end
+
+ it "does not add the resource to the resource collection" do
+ zm_resource # force let binding evaluation
+ expect { run_context.resource_collection.resources(:zen_master => "klopp") }.to raise_error(Chef::Exceptions::ResourceNotFound)
+ end
+
+ end
+
+ describe "creating resources via declare_resource" do
+ let(:zm_resource) do
+ recipe.declare_resource(:zen_master, "klopp") do
+ something "bvb"
+ end
+ end
+
+ it "applies attributes from the block to the resource" do
+ zm_resource.something.should == "bvb"
+ end
+
+ it "sets contextual attributes on the resource" do
+ zm_resource.recipe_name.should == "test"
+ zm_resource.cookbook_name.should == "hjk"
+ zm_resource.source_line.should include(__FILE__)
+ end
+
+ it "adds the resource to the resource collection" do
+ zm_resource # force let binding evaluation
+ run_context.resource_collection.resources(:zen_master => "klopp").should == zm_resource
+ end
+
+ end
+
+ describe "when attempting to create a resource of an invalid type" do
+
+ it "gives a sane error message when using method_missing" do
+ lambda do
+ recipe.no_such_resource("foo")
+ end.should raise_error(NoMethodError, %q[No resource or method named `no_such_resource' for `Chef::Recipe "test"'])
+ end
+
+ it "gives a sane error message when using method_missing 'bare'" do
+ lambda do
+ recipe.instance_eval do
+ # Giving an argument will change this from NameError to NoMethodError
+ no_such_resource
+ end
+ end.should raise_error(NameError, %q[No resource, method, or local variable named `no_such_resource' for `Chef::Recipe "test"'])
+ end
+
+ it "gives a sane error message when using build_resource" do
+ expect { recipe.build_resource(:no_such_resource, "foo") }.to raise_error(Chef::Exceptions::NoSuchResourceType)
+ end
+
+ it "gives a sane error message when using declare_resource" do
+ expect { recipe.declare_resource(:no_such_resource, "bar") }.to raise_error(Chef::Exceptions::NoSuchResourceType)
+ end
+
+ end
+
+ describe "when creating a resource that contains an error in the attributes block" do
+
+ it "does not obfuscate the error source" do
+ lambda do
+ recipe.zen_master("klopp") do
+ this_method_doesnt_exist
+ end
+ end.should raise_error(NoMethodError, "undefined method `this_method_doesnt_exist' for Chef::Resource::ZenMaster")
+
+ end
+
+ end
+
+ describe "resource cloning" do
+
+ let(:second_recipe) do
+ Chef::Recipe.new("second_cb", "second_recipe", run_context)
+ end
+
+ let(:original_resource) do
+ recipe.zen_master("klopp") do
+ something "bvb09"
+ action :score
+ end
+ end
+
+ let(:duplicated_resource) do
+ original_resource
+ second_recipe.zen_master("klopp") do
+ # attrs should be cloned
+ end
+ end
+
+ it "copies attributes from the first resource" do
+ duplicated_resource.something.should == "bvb09"
+ end
+
+ it "does not copy the action from the first resource" do
+ original_resource.action.should == [:score]
+ duplicated_resource.action.should == :nothing
+ end
+
+ it "does not copy the source location of the first resource" do
+ # sanity check source location:
+ original_resource.source_line.should include(__FILE__)
+ duplicated_resource.source_line.should include(__FILE__)
+ # actual test:
+ original_resource.source_line.should_not == duplicated_resource.source_line
+ end
+
+ it "sets the cookbook name on the cloned resource to that resource's cookbook" do
+ duplicated_resource.cookbook_name.should == "second_cb"
+ end
+
+ it "sets the recipe name on the cloned resource to that resoure's recipe" do
+ duplicated_resource.recipe_name.should == "second_recipe"
+ end
+
+ end
+
describe "resource definitions" do
it "should execute defined resources" do
crow_define = Chef::ResourceDefinition.new
@@ -136,12 +281,12 @@ describe Chef::Recipe do
something params[:something]
end
end
- @run_context.definitions[:crow] = crow_define
- @recipe.crow "mine" do
+ run_context.definitions[:crow] = crow_define
+ recipe.crow "mine" do
peace true
end
- @run_context.resource_collection.resources(:zen_master => "lao tzu").name.should eql("lao tzu")
- @run_context.resource_collection.resources(:zen_master => "lao tzu").something.should eql(true)
+ run_context.resource_collection.resources(:zen_master => "lao tzu").name.should eql("lao tzu")
+ run_context.resource_collection.resources(:zen_master => "lao tzu").something.should eql(true)
end
it "should set the node on defined resources" do
@@ -152,12 +297,12 @@ describe Chef::Recipe do
something params[:something]
end
end
- @run_context.definitions[:crow] = crow_define
- @node.normal[:foo] = false
- @recipe.crow "mine" do
+ run_context.definitions[:crow] = crow_define
+ node.normal[:foo] = false
+ recipe.crow "mine" do
something node[:foo]
end
- @recipe.resources(:zen_master => "lao tzu").something.should eql(false)
+ recipe.resources(:zen_master => "lao tzu").something.should eql(false)
end
end
@@ -170,15 +315,15 @@ describe Chef::Recipe do
peace = true
end
CODE
- lambda { @recipe.instance_eval(code) }.should_not raise_error
- @recipe.resources(:zen_master => "gnome").name.should eql("gnome")
+ lambda { recipe.instance_eval(code) }.should_not raise_error
+ recipe.resources(:zen_master => "gnome").name.should eql("gnome")
end
end
describe "from_file" do
it "should load a resource from a ruby file" do
- @recipe.from_file(File.join(CHEF_SPEC_DATA, "recipes", "test.rb"))
- res = @recipe.resources(:file => "/etc/nsswitch.conf")
+ recipe.from_file(File.join(CHEF_SPEC_DATA, "recipes", "test.rb"))
+ res = recipe.resources(:file => "/etc/nsswitch.conf")
res.name.should eql("/etc/nsswitch.conf")
res.action.should eql([:create])
res.owner.should eql("root")
@@ -187,84 +332,88 @@ describe Chef::Recipe do
end
it "should raise an exception if the file cannot be found or read" do
- lambda { @recipe.from_file("/tmp/monkeydiving") }.should raise_error(IOError)
+ lambda { recipe.from_file("/tmp/monkeydiving") }.should raise_error(IOError)
end
end
describe "include_recipe" do
it "should evaluate another recipe with include_recipe" do
- @run_context.include_recipe "openldap::gigantor"
- res = @run_context.resource_collection.resources(:cat => "blanket")
+ node.should_receive(:loaded_recipe).with(:openldap, "gigantor")
+ run_context.include_recipe "openldap::gigantor"
+ res = run_context.resource_collection.resources(:cat => "blanket")
res.name.should eql("blanket")
res.pretty_kitty.should eql(false)
end
it "should load the default recipe for a cookbook if include_recipe is called without a ::" do
- @run_context.include_recipe "openldap"
- res = @run_context.resource_collection.resources(:cat => "blanket")
+ node.should_receive(:loaded_recipe).with(:openldap, "default")
+ run_context.include_recipe "openldap"
+ res = run_context.resource_collection.resources(:cat => "blanket")
res.name.should eql("blanket")
res.pretty_kitty.should eql(true)
end
it "should store that it has seen a recipe in the run_context" do
- @run_context.include_recipe "openldap"
- @run_context.loaded_recipe?("openldap").should be_true
+ node.should_receive(:loaded_recipe).with(:openldap, "default")
+ run_context.include_recipe "openldap"
+ run_context.loaded_recipe?("openldap").should be_true
end
it "should not include the same recipe twice" do
- @cookbook_collection[:openldap].should_receive(:load_recipe).with("default", @run_context)
- @recipe.include_recipe "openldap"
- @cookbook_collection[:openldap].should_not_receive(:load_recipe).with("default", @run_context)
- @recipe.include_recipe "openldap"
+ node.should_receive(:loaded_recipe).with(:openldap, "default").exactly(:once)
+ cookbook_collection[:openldap].should_receive(:load_recipe).with("default", run_context)
+ recipe.include_recipe "openldap"
+ cookbook_collection[:openldap].should_not_receive(:load_recipe).with("default", run_context)
+ recipe.include_recipe "openldap"
end
end
describe "tags" do
it "should set tags via tag" do
- @recipe.tag "foo"
- @node[:tags].should include("foo")
+ recipe.tag "foo"
+ node[:tags].should include("foo")
end
it "should set multiple tags via tag" do
- @recipe.tag "foo", "bar"
- @node[:tags].should include("foo")
- @node[:tags].should include("bar")
+ recipe.tag "foo", "bar"
+ node[:tags].should include("foo")
+ node[:tags].should include("bar")
end
it "should not set the same tag twice via tag" do
- @recipe.tag "foo"
- @recipe.tag "foo"
- @node[:tags].should eql([ "foo" ])
+ recipe.tag "foo"
+ recipe.tag "foo"
+ node[:tags].should eql([ "foo" ])
end
it "should return the current list of tags from tag with no arguments" do
- @recipe.tag "foo"
- @recipe.tag.should eql([ "foo" ])
+ recipe.tag "foo"
+ recipe.tag.should eql([ "foo" ])
end
it "should return true from tagged? if node is tagged" do
- @recipe.tag "foo"
- @recipe.tagged?("foo").should be(true)
+ recipe.tag "foo"
+ recipe.tagged?("foo").should be(true)
end
it "should return false from tagged? if node is not tagged" do
- @recipe.tagged?("foo").should be(false)
+ recipe.tagged?("foo").should be(false)
end
it "should return false from tagged? if node is not tagged" do
- @recipe.tagged?("foo").should be(false)
+ recipe.tagged?("foo").should be(false)
end
it "should remove a tag from the tag list via untag" do
- @recipe.tag "foo"
- @recipe.untag "foo"
- @node[:tags].should eql([])
+ recipe.tag "foo"
+ recipe.untag "foo"
+ node[:tags].should eql([])
end
it "should remove multiple tags from the tag list via untag" do
- @recipe.tag "foo", "bar"
- @recipe.untag "bar", "foo"
- @node[:tags].should eql([])
+ recipe.tag "foo", "bar"
+ recipe.untag "bar", "foo"
+ node[:tags].should eql([])
end
end
end
diff --git a/spec/unit/registry_helper_spec.rb b/spec/unit/registry_helper_spec.rb
index 49469b27e6..444a82dc7c 100644
--- a/spec/unit/registry_helper_spec.rb
+++ b/spec/unit/registry_helper_spec.rb
@@ -43,8 +43,8 @@ describe Chef::Provider::RegistryKey do
Win32::Registry::Error = Class.new(RuntimeError)
- @hive_mock = mock("::Win32::Registry::HKEY_CURRENT_USER")
- @reg_mock = mock("reg")
+ @hive_mock = double("::Win32::Registry::HKEY_CURRENT_USER")
+ @reg_mock = double("reg")
end
describe "get_values" do
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..355a7f09ba 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,24 +23,24 @@ 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)
+ lambda { @resource.action :create }.should_not raise_error
+ lambda { @resource.action :delete }.should_not raise_error
lambda { @resource.action :lolcat }.should raise_error(ArgumentError)
end
@@ -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..a42383c49e 100644
--- a/spec/unit/resource/directory_spec.rb
+++ b/spec/unit/resource/directory_spec.rb
@@ -39,8 +39,8 @@ describe Chef::Resource::Directory do
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)
+ lambda { @resource.action :create }.should_not raise_error
+ lambda { @resource.action :delete }.should_not raise_error
lambda { @resource.action :blues }.should raise_error(ArgumentError)
end
@@ -49,19 +49,19 @@ describe Chef::Resource::Directory do
end
it "should accept a string as the path" do
- lambda { @resource.path "/tmp" }.should_not raise_error(ArgumentError)
+ lambda { @resource.path "/tmp" }.should_not raise_error
@resource.path.should eql("/tmp")
lambda { @resource.path Hash.new }.should raise_error(ArgumentError)
end
it "should allow you to have specify whether the action is recursive with true/false" do
- lambda { @resource.recursive true }.should_not raise_error(ArgumentError)
- lambda { @resource.recursive false }.should_not raise_error(ArgumentError)
+ lambda { @resource.recursive true }.should_not raise_error
+ lambda { @resource.recursive false }.should_not raise_error
lambda { @resource.recursive "monkey" }.should raise_error(ArgumentError)
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..a1f599400b 100644
--- a/spec/unit/resource/env_spec.rb
+++ b/spec/unit/resource/env_spec.rb
@@ -43,7 +43,7 @@ describe Chef::Resource::Env do
if bad_value
lambda { @resource.action action }.should raise_error(ArgumentError)
else
- lambda { @resource.action action }.should_not raise_error(ArgumentError)
+ lambda { @resource.action action }.should_not raise_error
end
end
end
@@ -53,7 +53,7 @@ describe Chef::Resource::Env do
end
it "should accept a string as the env value via 'value'" do
- lambda { @resource.value "bar" }.should_not raise_error(ArgumentError)
+ lambda { @resource.value "bar" }.should_not raise_error
end
it "should not accept a Hash for the env value via 'to'" do
@@ -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..3efbdca9a0 100644
--- a/spec/unit/resource/erl_call_spec.rb
+++ b/spec/unit/resource/erl_call_spec.rb
@@ -39,7 +39,7 @@ describe Chef::Resource::ErlCall do
end
it "should accept run as an action" do
- lambda { @resource.action :run }.should_not raise_error(ArgumentError)
+ lambda { @resource.action :run }.should_not raise_error
end
it "should allow you to set the code attribute" do
@@ -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/file_spec.rb b/spec/unit/resource/file_spec.rb
index f937d0035b..9c6365f6d3 100644
--- a/spec/unit/resource/file_spec.rb
+++ b/spec/unit/resource/file_spec.rb
@@ -44,25 +44,25 @@ describe Chef::Resource::File do
lambda { @resource.content 5 }.should raise_error(ArgumentError)
lambda { @resource.content :foo }.should raise_error(ArgumentError)
lambda { @resource.content "hello" => "there" }.should raise_error(ArgumentError)
- lambda { @resource.content "hi" }.should_not raise_error(ArgumentError)
+ lambda { @resource.content "hi" }.should_not raise_error
end
it "should only accept false or a number for backup" do
lambda { @resource.backup true }.should raise_error(ArgumentError)
- lambda { @resource.backup false }.should_not raise_error(ArgumentError)
- lambda { @resource.backup 10 }.should_not raise_error(ArgumentError)
+ lambda { @resource.backup false }.should_not raise_error
+ lambda { @resource.backup 10 }.should_not raise_error
lambda { @resource.backup "blues" }.should raise_error(ArgumentError)
end
it "should accept a sha256 for checksum" do
- lambda { @resource.checksum "0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa" }.should_not raise_error(ArgumentError)
+ lambda { @resource.checksum "0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa" }.should_not raise_error
lambda { @resource.checksum "monkey!" }.should raise_error(ArgumentError)
end
it "should accept create, delete or touch for action" do
- lambda { @resource.action :create }.should_not raise_error(ArgumentError)
- lambda { @resource.action :delete }.should_not raise_error(ArgumentError)
- lambda { @resource.action :touch }.should_not raise_error(ArgumentError)
+ lambda { @resource.action :create }.should_not raise_error
+ lambda { @resource.action :delete }.should_not raise_error
+ lambda { @resource.action :touch }.should_not raise_error
lambda { @resource.action :blues }.should raise_error(ArgumentError)
end
@@ -71,7 +71,7 @@ describe Chef::Resource::File do
end
it "should accept a string as the path" do
- lambda { @resource.path "/tmp" }.should_not raise_error(ArgumentError)
+ lambda { @resource.path "/tmp" }.should_not raise_error
@resource.path.should eql("/tmp")
lambda { @resource.path Hash.new }.should raise_error(ArgumentError)
end
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..0c3cf4f67f 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)
@@ -60,11 +60,11 @@ describe Chef::Resource::Group, "initialize" do
end
it "should accept domain groups (@ or \ separator) on non-windows" do
- lambda { @resource.group_name "domain\@group" }.should_not raise_error(ArgumentError)
+ lambda { @resource.group_name "domain\@group" }.should_not raise_error
@resource.group_name.should == "domain\@group"
- lambda { @resource.group_name "domain\\group" }.should_not raise_error(ArgumentError)
+ lambda { @resource.group_name "domain\\group" }.should_not raise_error
@resource.group_name.should == "domain\\group"
- lambda { @resource.group_name "domain\\group^name" }.should_not raise_error(ArgumentError)
+ lambda { @resource.group_name "domain\\group^name" }.should_not raise_error
@resource.group_name.should == "domain\\group^name"
end
end
@@ -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..221617f9b3 100644
--- a/spec/unit/resource/link_spec.rb
+++ b/spec/unit/resource/link_spec.rb
@@ -44,7 +44,7 @@ describe Chef::Resource::Link do
if bad_value
lambda { @resource.action action }.should raise_error(ArgumentError)
else
- lambda { @resource.action action }.should_not raise_error(ArgumentError)
+ lambda { @resource.action action }.should_not raise_error
end
end
end
@@ -54,7 +54,7 @@ describe Chef::Resource::Link do
end
it "should accept a string as the link source via 'to'" do
- lambda { @resource.to "/tmp" }.should_not raise_error(ArgumentError)
+ lambda { @resource.to "/tmp" }.should_not raise_error
end
it "should not accept a Hash for the link source via 'to'" do
@@ -85,19 +85,19 @@ describe Chef::Resource::Link do
end
it "should accept a group name or id for group" do
- lambda { @resource.group "root" }.should_not raise_error(ArgumentError)
- lambda { @resource.group 123 }.should_not raise_error(ArgumentError)
- lambda { @resource.group "root*goo" }.should raise_error(ArgumentError)
+ lambda { @resource.group "root" }.should_not raise_error
+ lambda { @resource.group 123 }.should_not raise_error
+ lambda { @resource.group "root:goo" }.should raise_error(ArgumentError)
end
it "should accept a user name or id for owner" do
- lambda { @resource.owner "root" }.should_not raise_error(ArgumentError)
- lambda { @resource.owner 123 }.should_not raise_error(ArgumentError)
- lambda { @resource.owner "root*goo" }.should raise_error(ArgumentError)
+ lambda { @resource.owner "root" }.should_not raise_error
+ lambda { @resource.owner 123 }.should_not raise_error
+ lambda { @resource.owner "root:goo" }.should raise_error(ArgumentError)
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..daf10bcfea 100644
--- a/spec/unit/resource/mdadm_spec.rb
+++ b/spec/unit/resource/mdadm_spec.rb
@@ -39,9 +39,9 @@ describe Chef::Resource::Mdadm do
end
it "should accept create, assemble, stop as actions" do
- lambda { @resource.action :create }.should_not raise_error(ArgumentError)
- lambda { @resource.action :assemble }.should_not raise_error(ArgumentError)
- lambda { @resource.action :stop }.should_not raise_error(ArgumentError)
+ lambda { @resource.action :create }.should_not raise_error
+ lambda { @resource.action :assemble }.should_not raise_error
+ lambda { @resource.action :stop }.should_not raise_error
end
it "should allow you to set the raid_device attribute" do
@@ -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..c80f6971f1 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 :mount }.should_not raise_error
+ lambda { @resource.action :umount }.should_not raise_error
+ lambda { @resource.action :remount }.should_not raise_error
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..2884c94393 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,17 +38,22 @@ 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")
end
+ it "should accept a hash for response file template variables" do
+ @resource.response_file_variables({:variables => true})
+ @resource.response_file_variables.should eql({:variables => true})
+ end
+
it "should accept a string for the source" do
@resource.source "something"
@resource.source.should eql("something")
@@ -71,7 +76,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..4522438402 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 :add }.should_not raise_error
+ lambda { @resource.action :delete }.should_not raise_error
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..2141ae3c88 100644
--- a/spec/unit/resource/scm_spec.rb
+++ b/spec/unit/resource/scm_spec.rb
@@ -118,6 +118,16 @@ describe Chef::Resource::Scm do
@resource.enable_submodules.should be_false
end
+ it "takes a boolean for #enable_checkout" do
+ @resource.enable_checkout true
+ @resource.enable_checkout.should be_true
+ lambda {@resource.enable_checkout "lolz"}.should raise_error(ArgumentError)
+ end
+
+ it "defaults to enabling checkout" do
+ @resource.enable_checkout.should be_true
+ end
+
it "takes a string for the remote" do
@resource.remote "opscode"
@resource.remote.should eql("opscode")
@@ -137,8 +147,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..9972ddbba1 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)
@@ -61,9 +61,9 @@ describe Chef::Resource::User, "initialize" do
end
it "should accept domain users (@ or \ separator) on non-windows" do
- lambda { @resource.username "domain\@user" }.should_not raise_error(ArgumentError)
+ lambda { @resource.username "domain\@user" }.should_not raise_error
@resource.username.should == "domain\@user"
- lambda { @resource.username "domain\\user" }.should_not raise_error(ArgumentError)
+ lambda { @resource.username "domain\\user" }.should_not raise_error
@resource.username.should == "domain\\user"
end
end
@@ -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..57ab4dfcd9 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 ]
@@ -78,8 +78,8 @@ describe Chef::Resource::YumPackage, "allow_downgrade" do
end
it "should allow you to specify whether allow_downgrade is true or false" do
- lambda { @resource.allow_downgrade true }.should_not raise_error(ArgumentError)
- lambda { @resource.allow_downgrade false }.should_not raise_error(ArgumentError)
+ lambda { @resource.allow_downgrade true }.should_not raise_error
+ lambda { @resource.allow_downgrade false }.should_not raise_error
lambda { @resource.allow_downgrade "monkey" }.should raise_error(ArgumentError)
end
end
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_collection_spec.rb b/spec/unit/resource_collection_spec.rb
index d8fc0db8e0..cf62f5ff40 100644
--- a/spec/unit/resource_collection_spec.rb
+++ b/spec/unit/resource_collection_spec.rb
@@ -118,7 +118,7 @@ describe Chef::ResourceCollection do
@rc.each_index do |i|
results << @rc[i].name
end
- }.should_not raise_error()
+ }.should_not raise_error
results.each_index do |i|
case i
when 0
diff --git a/spec/unit/resource_definition_spec.rb b/spec/unit/resource_definition_spec.rb
index a29c15a1e3..f24254cfce 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 {
+ }.should_not raise_error
+ 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)
+ }.should_not raise_error
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..d412234596 100644
--- a/spec/unit/resource_reporter_spec.rb
+++ b/spec/unit/resource_reporter_spec.rb
@@ -35,21 +35,21 @@ describe Chef::ResourceReporter do
before do
@node = Chef::Node.new
@node.name("spitfire")
- @rest_client = mock("Chef::REST (mock)")
- @rest_client.stub!(:post_rest).and_return(true)
+ @rest_client = double("Chef::REST (mock)")
+ @rest_client.stub(:post_rest).and_return(true)
@resource_reporter = Chef::ResourceReporter.new(@rest_client)
- @run_id = @resource_reporter.run_id
@new_resource = Chef::Resource::File.new("/tmp/a-file.txt")
@new_resource.cookbook_name = "monkey"
- @cookbook_version = mock("Cookbook::Version", :version => "1.2.3")
- @new_resource.stub!(:cookbook_version).and_return(@cookbook_version)
+ @cookbook_version = double("Cookbook::Version", :version => "1.2.3")
+ @new_resource.stub(:cookbook_version).and_return(@cookbook_version)
@current_resource = Chef::Resource::File.new("/tmp/a-file.txt")
@start_time = Time.new
@end_time = Time.new + 20
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, {}, @events)
@run_status = Chef::RunStatus.new(@node, @events)
- Time.stub!(:now).and_return(@start_time, @end_time)
+ @run_id = @run_status.run_id
+ Time.stub(:now).and_return(@start_time, @end_time)
end
context "when first created" do
@@ -87,9 +87,9 @@ describe Chef::ResourceReporter do
context "when chef fails" do
before do
- @rest_client.stub!(:create_url).and_return("reports/nodes/spitfire/runs/#{@run_id}");
- @rest_client.stub!(:raw_http_request).and_return({"result"=>"ok"});
- @rest_client.stub!(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/spitfire/runs/#{@run_id}"});
+ @rest_client.stub(:create_url).and_return("reports/nodes/spitfire/runs/#{@run_id}");
+ @rest_client.stub(:raw_http_request).and_return({"result"=>"ok"});
+ @rest_client.stub(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/spitfire/runs/#{@run_id}"});
end
@@ -255,13 +255,68 @@ describe Chef::ResourceReporter do
describe "when generating a report for the server" do
before do
- @rest_client.stub!(:create_url).and_return("reports/nodes/spitfire/runs/#{@run_id}");
- @rest_client.stub!(:raw_http_request).and_return({"result"=>"ok"});
- @rest_client.stub!(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/spitfire/runs/#{@run_id}"});
+ @rest_client.stub(:create_url).and_return("reports/nodes/spitfire/runs/#{@run_id}");
+ @rest_client.stub(:raw_http_request).and_return({"result"=>"ok"});
+ @rest_client.stub(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/spitfire/runs/#{@run_id}"});
@resource_reporter.run_started(@run_status)
end
+ context "when the new_resource does not have a string for name and identity" do
+ context "the new_resource name and id are nil" do
+ before do
+ @bad_resource = Chef::Resource::File.new("/tmp/nameless_file.txt")
+ @bad_resource.stub(:name).and_return(nil)
+ @bad_resource.stub(:identity).and_return(nil)
+ @resource_reporter.resource_action_start(@bad_resource, :create)
+ @resource_reporter.resource_current_state_loaded(@bad_resource, :create, @current_resource)
+ @resource_reporter.resource_updated(@bad_resource, :create)
+ @resource_reporter.resource_completed(@bad_resource)
+ @run_status.stop_clock
+ @report = @resource_reporter.prepare_run_data
+ @first_update_report = @report["resources"].first
+ end
+
+ it "resource_name in prepared_run_data is a string" do
+ @first_update_report["name"].class.should == String
+ end
+
+ it "resource_id in prepared_run_data is a string" do
+ @first_update_report["id"].class.should == String
+ end
+ end
+
+ context "the new_resource name and id are hashes" do
+ before do
+ @bad_resource = Chef::Resource::File.new("/tmp/filename_as_hash.txt")
+ @bad_resource.stub(:name).and_return({:foo=>:bar})
+ @bad_resource.stub(:identity).and_return({:foo=>:bar})
+ @resource_reporter.resource_action_start(@bad_resource, :create)
+ @resource_reporter.resource_current_state_loaded(@bad_resource, :create, @current_resource)
+ @resource_reporter.resource_updated(@bad_resource, :create)
+ @resource_reporter.resource_completed(@bad_resource)
+ @run_status.stop_clock
+ @report = @resource_reporter.prepare_run_data
+ @first_update_report = @report["resources"].first
+ end
+ # Ruby 1.8.7 flattens out hash to string using join instead of inspect, resulting in
+ # irb(main):001:0> {:foo => :bar}.to_s
+ # => "foobar"
+ # instead of the expected
+ # irb(main):001:0> {:foo => :bar}.to_s
+ # => "{:foo=>:bar}"
+ # Hence checking for the class instead of the actual value.
+ it "resource_name in prepared_run_data is a string" do
+ @first_update_report["name"].class.should == String
+ end
+
+ it "resource_id in prepared_run_data is a string" do
+ @first_update_report["id"].class.should == String
+ end
+ end
+ end
+
+
context "for a successful client run" do
before do
# TODO: add inputs to generate expected output.
@@ -381,10 +436,10 @@ describe Chef::ResourceReporter do
@backtrace = ["foo.rb:1 in `foo!'","bar.rb:2 in `bar!","'baz.rb:3 in `baz!'"]
@node = Chef::Node.new
@node.name("spitfire")
- @exception = mock("ArgumentError")
- @exception.stub!(:inspect).and_return("Net::HTTPServerException")
- @exception.stub!(:message).and_return("Object not found")
- @exception.stub!(:backtrace).and_return(@backtrace)
+ @exception = double("ArgumentError")
+ @exception.stub(:inspect).and_return("Net::HTTPServerException")
+ @exception.stub(:message).and_return("Object not found")
+ @exception.stub(:backtrace).and_return(@backtrace)
@resource_reporter.run_list_expand_failed(@node, @exception)
@resource_reporter.run_failed(@exception)
@report = @resource_reporter.prepare_run_data
@@ -464,6 +519,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
@@ -575,7 +657,7 @@ describe Chef::ResourceReporter do
@resource_reporter.resource_current_state_loaded(@new_resource, :create, @current_resource)
@resource_reporter.resource_updated(@new_resource, :create)
- @resource_reporter.stub!(:end_time).and_return(@end_time)
+ @resource_reporter.stub(:end_time).and_return(@end_time)
@expected_data = @resource_reporter.prepare_run_data
post_url = "https://chef_server/example_url"
diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb
index dd1a0259e4..e9a60c9861 100644
--- a/spec/unit/resource_spec.rb
+++ b/spec/unit/resource_spec.rb
@@ -205,8 +205,8 @@ describe Chef::Resource do
describe "noop" do
it "should accept true or false for noop" do
- lambda { @resource.noop true }.should_not raise_error(ArgumentError)
- lambda { @resource.noop false }.should_not raise_error(ArgumentError)
+ lambda { @resource.noop true }.should_not raise_error
+ lambda { @resource.noop false }.should_not raise_error
lambda { @resource.noop "eat it" }.should raise_error(ArgumentError)
end
end
@@ -589,7 +589,7 @@ describe Chef::Resource do
it "should print \"skipped due to action :nothing\" message for doc formatter when action is :nothing" do
fdoc = Chef::Formatters.new(:doc, STDOUT, STDERR)
- @run_context.stub!(:events).and_return(fdoc)
+ @run_context.stub(:events).and_return(fdoc)
fdoc.should_receive(:puts).with(" (skipped due to action :nothing)")
@resource.should_skip?(:nothing)
end
diff --git a/spec/unit/rest/auth_credentials_spec.rb b/spec/unit/rest/auth_credentials_spec.rb
index de06b2cc55..477da0faec 100644
--- a/spec/unit/rest/auth_credentials_spec.rb
+++ b/spec/unit/rest/auth_credentials_spec.rb
@@ -84,7 +84,7 @@ describe Chef::REST::AuthCredentials do
end
it "generates signature headers for the request" do
- Time.stub!(:now).and_return(@request_time)
+ Time.stub(:now).and_return(@request_time)
actual = @auth_credentials.signature_headers(@request_params)
actual["HOST"].should == "localhost"
actual["X-OPS-AUTHORIZATION-1"].should == "kBssX1ENEwKtNYFrHElN9vYGWS7OeowepN9EsYc9csWfh8oUovryPKDxytQ/"
@@ -110,7 +110,7 @@ describe Chef::REST::AuthCredentials do
end
it "generates the correct signature for version 1.1" do
- Time.stub!(:now).and_return(@request_time)
+ Time.stub(:now).and_return(@request_time)
actual = @auth_credentials.signature_headers(@request_params)
actual["HOST"].should == "localhost"
actual["X-OPS-CONTENT-HASH"].should == "1tuzs5XKztM1ANrkGNPah6rW9GY="
@@ -135,7 +135,10 @@ describe Chef::REST::RESTRequest do
@auth_credentials = Chef::REST::AuthCredentials.new("client-name", CHEF_SPEC_DATA + '/ssl/private_key.pem')
@url = URI.parse("http://chef.example.com:4000/?q=chef_is_awesome")
@req_body = '{"json_data":"as_a_string"}'
- @headers = {"Content-type" =>"application/json", "Accept"=>"application/json", "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
+ @headers = { "Content-type" =>"application/json",
+ "Accept"=>"application/json",
+ "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ "Host" => "chef.example.com:4000" }
@request = Chef::REST::RESTRequest.new(:POST, @url, @req_body, @headers)
end
@@ -199,100 +202,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..3d6144ab35 100644
--- a/spec/unit/rest_spec.rb
+++ b/spec/unit/rest_spec.rb
@@ -53,228 +53,288 @@ Y6S6MeZ69Rp89ma4ttMZ+kwi1+XyHqC/dlcVRW42Zl5Dc7BALRlJjQ==
-----END RSA PRIVATE KEY-----"
describe Chef::REST do
- before(:each) do
- @log_stringio = StringIO.new
- Chef::Log.init(@log_stringio)
+ let(:base_url) { "http://chef.example.com:4000" }
+
+ let(:monkey_uri) { URI.parse("http://chef.example.com:4000/monkey") }
- 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)
+ let(:log_stringio) { StringIO.new }
+ let(:request_id) {"1234"}
+
+ let(:rest) do
+ Chef::REST::CookieJar.stub(:instance).and_return({})
+ Chef::RequestID.instance.stub(:request_id).and_return(request_id)
+ rest = Chef::REST.new(base_url, nil, nil)
Chef::REST::CookieJar.instance.clear
+ rest
+ end
+
+ let(:standard_read_headers) {{"Accept"=>"application/json", "Accept"=>"application/json", "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3", "X-REMOTE-REQUEST-ID"=>request_id}}
+ let(: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", "X-REMOTE-REQUEST-ID"=>request_id}}
+
+ before(:each) do
+ Chef::Log.init(log_stringio)
end
describe "calling an HTTP verb on a path or absolute URL" do
it "adds a relative URL to the base url it was initialized with" do
- @rest.create_url("foo/bar/baz").should == URI.parse(@base_url + "/foo/bar/baz")
+ expect(rest.create_url("foo/bar/baz")).to eq(URI.parse(base_url + "/foo/bar/baz"))
end
it "replaces the base URL when given an absolute URL" do
- @rest.create_url("http://chef-rulez.example.com:9000").should == URI.parse("http://chef-rulez.example.com:9000")
+ expect(rest.create_url("http://chef-rulez.example.com:9000")).to eq(URI.parse("http://chef-rulez.example.com:9000"))
end
it "makes a :GET request with the composed url object" do
- @rest.should_receive(:api_request).with(:GET, @monkey_uri, {})
- @rest.get_rest("monkey")
+ 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.get_rest("monkey", true)
+ 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, {})
- @rest.delete_rest("monkey")
+ 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.post_rest("monkey", "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.put_rest("monkey", "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
+
+ describe "legacy API" do
+ let(:rest) do
+ Chef::REST.new(base_url)
+ end
+
+ before(:each) do
+ Chef::Config[:node_name] = "webmonkey.example.com"
+ Chef::Config[:client_key] = CHEF_SPEC_DATA + "/ssl/private_key.pem"
+ end
+
+ it 'responds to raw_http_request as a public method' do
+ expect(rest.public_methods.map(&:to_s)).to include("raw_http_request")
+ end
+
+ it 'calls the authn middleware' do
+ data = "\"secure data\""
+
+ auth_headers = standard_write_headers.merge({"auth_done"=>"yep"})
+
+ rest.authenticator.should_receive(:handle_request).
+ with(:POST, monkey_uri, standard_write_headers, data).
+ and_return([:POST, monkey_uri, auth_headers, data])
+ rest.should_receive(:send_http_request).
+ with(:POST, monkey_uri, auth_headers, data).
+ and_return([1,2,3])
+ rest.should_receive('success_response?'.to_sym).with(1).and_return(true)
+ rest.raw_http_request(:POST, monkey_uri, standard_write_headers, data)
+ end
+
+ it 'sets correct authn headers' do
+ data = "\"secure data\""
+ method, uri, auth_headers, d = rest.authenticator.handle_request(:POST, monkey_uri, standard_write_headers, data)
+
+ rest.should_receive(:send_http_request).
+ with(:POST, monkey_uri, auth_headers, data).
+ and_return([1,2,3])
+ rest.should_receive('success_response?'.to_sym).with(1).and_return(true)
+ rest.raw_http_request(:POST, monkey_uri, standard_write_headers, data)
end
end
describe "when configured to authenticate to the Chef server" do
+ let(:base_url) { URI.parse("http://chef.example.com:4000") }
+
+ let(:rest) do
+ Chef::REST.new(base_url)
+ end
+
before do
- @url = URI.parse("http://chef.example.com:4000")
Chef::Config[:node_name] = "webmonkey.example.com"
Chef::Config[:client_key] = CHEF_SPEC_DATA + "/ssl/private_key.pem"
- @rest = Chef::REST.new(@url)
end
it "configures itself to use the node_name and client_key in the config by default" do
- @rest.client_name.should == "webmonkey.example.com"
- @rest.signing_key_filename.should == CHEF_SPEC_DATA + "/ssl/private_key.pem"
+ expect(rest.client_name).to eq("webmonkey.example.com")
+ expect(rest.signing_key_filename).to eq(CHEF_SPEC_DATA + "/ssl/private_key.pem")
end
it "provides access to the raw key data" do
- @rest.signing_key.should == SIGNING_KEY_DOT_PEM
+ expect(rest.signing_key).to eq(SIGNING_KEY_DOT_PEM)
end
it "does not error out when initialized without credentials" do
- @rest = Chef::REST.new(@url, nil, nil) #should_not raise_error hides the bt from you, so screw it.
- @rest.client_name.should be_nil
- @rest.signing_key.should be_nil
+ rest = Chef::REST.new(base_url, nil, nil) #should_not raise_error hides the bt from you, so screw it.
+ expect(rest.client_name).to be_nil
+ expect(rest.signing_key).to be_nil
end
it "indicates that requests should not be signed when it has no credentials" do
- @rest = Chef::REST.new(@url, nil, nil)
- @rest.sign_requests?.should be_false
+ rest = Chef::REST.new(base_url, nil, nil)
+ expect(rest.sign_requests?).to be_false
end
it "raises PrivateKeyMissing when the key file doesn't exist" do
- lambda {Chef::REST.new(@url, "client-name", "/dev/null/nothing_here")}.should raise_error(Chef::Exceptions::PrivateKeyMissing)
+ expect {Chef::REST.new(base_url, "client-name", "/dev/null/nothing_here")}.to raise_error(Chef::Exceptions::PrivateKeyMissing)
end
it "raises InvalidPrivateKey when the key file doesnt' look like a key" do
invalid_key_file = CHEF_SPEC_DATA + "/bad-config.rb"
- lambda {Chef::REST.new(@url, "client-name", invalid_key_file)}.should raise_error(Chef::Exceptions::InvalidPrivateKey)
+ expect {Chef::REST.new(base_url, "client-name", invalid_key_file)}.to raise_error(Chef::Exceptions::InvalidPrivateKey)
end
it "can take private key as a sting :raw_key in options during initializaton" do
- Chef::REST.new(@url, "client-name", nil, :raw_key => SIGNING_KEY_DOT_PEM).signing_key.should == SIGNING_KEY_DOT_PEM
+ expect(Chef::REST.new(base_url, "client-name", nil, :raw_key => SIGNING_KEY_DOT_PEM).signing_key).to eq(SIGNING_KEY_DOT_PEM)
end
it "raises InvalidPrivateKey when the key passed as string :raw_key in options doesnt' look like a key" do
- lambda {Chef::REST.new(@url, "client-name", nil, :raw_key => "bad key string")}.should raise_error(Chef::Exceptions::InvalidPrivateKey)
+ expect {Chef::REST.new(base_url, "client-name", nil, :raw_key => "bad key string")}.to raise_error(Chef::Exceptions::InvalidPrivateKey)
end
end
context "when making REST requests" do
- before(:each) do
- Chef::Config[:ssl_client_cert] = nil
- Chef::Config[:ssl_client_key] = nil
- @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.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)
-
- @base_headers = { 'Accept' => 'application/json',
- 'X-Chef-Version' => Chef::VERSION,
- 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
- @req_with_body_headers = @base_headers.merge("Content-Type" => "application/json", "Content-Length" => '13')
+ let(:body) { "ninja" }
+
+ let(:http_response) do
+ http_response = Net::HTTPSuccess.new("1.1", "200", "successful rest req")
+ http_response.stub(:read_body)
+ http_response.stub(:body).and_return(body)
+ http_response["Content-Length"] = body.bytesize.to_s
+ http_response
end
- 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)
-
- @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!
- 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}
- Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
- @rest.streaming_request(@url, {})
- end
+ let(:host_header) { "one:80" }
- it "should create a tempfile for the output of a raw request" do
- @rest.streaming_request(@url, {}).should equal(@tempfile)
- end
+ let(:url) { URI.parse("https://one:80/?foo=bar") }
- it "should read the body of the response in chunks on a raw request" do
- @http_response.should_receive(:read_body).and_return(true)
- @rest.streaming_request(@url, {})
- end
+ let(:base_url) { "http://chef.example.com:4000" }
- 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)
- @rest.streaming_request(@url, {})
- end
+ let!(:http_client) do
+ http_client = Net::HTTP.new(url.host, url.port)
+ http_client.stub(:request).and_yield(http_response).and_return(http_response)
+ http_client
+ end
- it "should close the tempfile if we're doing a raw request" do
- @tempfile.should_receive(:close).once.and_return(true)
- @rest.streaming_request(@url, {})
- end
+ let(:rest) do
+ Net::HTTP.stub(:new).and_return(http_client)
+ Chef::REST::CookieJar.stub(:instance).and_return({})
+ Chef::RequestID.instance.stub(:request_id).and_return(request_id)
+ rest = Chef::REST.new(base_url, nil, nil)
+ Chef::REST::CookieJar.instance.clear
+ rest
+ 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)
- end
+ let(:base_headers) do
+ {
+ 'Accept' => 'application/json',
+ 'X-Chef-Version' => Chef::VERSION,
+ 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ 'X-REMOTE-REQUEST-ID' => request_id
+ }
+ 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)
- end
+ let (:req_with_body_headers) do
+ base_headers.merge("Content-Type" => "application/json", "Content-Length" => '13')
+ end
+ before(:each) do
+ Chef::Config[:ssl_client_cert] = nil
+ Chef::Config[:ssl_client_key] = nil
end
describe "as JSON API requests" do
- before do
- @request_mock = {}
- Net::HTTP::Get.stub!(:new).and_return(@request_mock)
-
- @base_headers = {"Accept" => "application/json",
- "X-Chef-Version" => Chef::VERSION,
- "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE
+ let(:request_mock) { {} }
+
+ let(:base_headers) do #FIXME: huh?
+ {
+ 'Accept' => 'application/json',
+ 'X-Chef-Version' => Chef::VERSION,
+ 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ 'Host' => host_header,
+ 'X-REMOTE-REQUEST-ID' => request_id
}
end
+ before do
+ Net::HTTP::Get.stub(:new).and_return(request_mock)
+ end
+
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, {})
+ Net::HTTP::Get.should_receive(:new).with("/?foo=bar", base_headers).and_return(request_mock)
+ rest.request(:GET, url, {})
+ end
+
+ it "should always include the X-Remote-Request-Id header" do
+ Net::HTTP::Get.should_receive(:new).with("/?foo=bar", base_headers).and_return(request_mock)
+ rest.request(:GET, url, {})
end
it "sets the user agent to chef-client" do
- # must reset to default b/c knife changes the UA
+ # XXX: 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, {})
+ expect(request_mock['User-Agent']).to match(/^Chef Client\/#{Chef::VERSION}/)
end
# CHEF-3140
context "when configured to disable compression" do
- before do
- @rest = Chef::REST.new(@base_url, nil, nil, :disable_gzip => true)
+ let(:rest) do
+ Net::HTTP.stub(:new).and_return(http_client)
+ Chef::REST.new(base_url, nil, nil, :disable_gzip => true)
end
it "does not accept encoding gzip" do
- @rest.send(:build_headers, :GET, @url, {}).should_not have_key("Accept-Encoding")
+ expect(rest.send(:build_headers, :GET, url, {})).not_to have_key("Accept-Encoding")
end
it "does not decompress a response encoded as gzip" do
- @http_response.add_field("content-encoding", "gzip")
- request = Net::HTTP::Get.new(@url.path)
+ http_response.add_field("content-encoding", "gzip")
+ 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"
+ expect(rest.request(:GET, url, {})).to eq("ninja")
end
end
+
context "when configured with custom http headers" do
- before(:each) do
- @custom_headers = {
+ let(:custom_headers) do
+ {
'X-Custom-ChefSecret' => 'sharpknives',
'X-Custom-RequestPriority' => 'extremely low'
}
- Chef::Config[:custom_http_headers] = @custom_headers
+ end
+
+ before(:each) do
+ Chef::Config[:custom_http_headers] = custom_headers
end
after(:each) do
@@ -283,84 +343,112 @@ describe Chef::REST do
it "should set them on the http request" do
url_string = an_instance_of(String)
- header_hash = hash_including(@custom_headers)
+ 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, {})
+ context "when setting cookies" do
+ let(:rest) do
+ Net::HTTP.stub(:new).and_return(http_client)
+ Chef::REST::CookieJar.instance["#{url.host}:#{url.port}"] = "cookie monster"
+ Chef::RequestID.instance.stub(:request_id).and_return(request_id)
+ rest = Chef::REST.new(base_url, nil, nil)
+ rest
+ end
+
+ it "should set the cookie for this request if one exists for the given host:port" do
+ Net::HTTP::Get.should_receive(:new).with("/?foo=bar", base_headers.merge('Cookie' => "cookie monster")).and_return(request_mock)
+ rest.request(:GET, url, {})
+ end
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, {})
+ Net::HTTP::Get.should_receive(:new).with("/?foo=bar", base_headers).and_return(request_mock)
+ rest.request(:GET, url, {})
end
it "should build a new HTTP POST request" do
- request = Net::HTTP::Post.new(@url.path)
- expected_headers = @base_headers.merge("Content-Type" => 'application/json', 'Content-Length' => '13')
+ request = Net::HTTP::Post.new(url.path)
+ 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})
- request.body.should == '{"one":"two"}'
+ rest.request(:POST, url, {}, {:one=>:two})
+ expect(request.body).to eq('{"one":"two"}')
end
it "should build a new HTTP PUT request" do
- request = Net::HTTP::Put.new(@url.path)
- expected_headers = @base_headers.merge("Content-Type" => 'application/json', 'Content-Length' => '13')
+ 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})
- request.body.should == '{"one":"two"}'
+ rest.request(:PUT, url, {}, {:one=>:two})
+ expect(request.body).to eq('{"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)
+ Net::HTTP::Delete.should_receive(:new).with("/?foo=bar", base_headers).and_return(request_mock)
+ 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)
+ expect { rest.request(:MONKEY, url) }.to 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"
+ expect(rest.request(:GET, url)).to eq("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"}
+ it "should fail if the response is truncated" do
+ http_response["Content-Length"] = (body.bytesize + 99).to_s
+ expect { rest.request(:GET, url) }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
end
- %w[ HTTPFound HTTPMovedPermanently HTTPSeeOther HTTPUseProxy HTTPTemporaryRedirect HTTPMultipleChoice ].each do |resp_name|
- it "should call api_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)
+ context "when JSON is returned" do
+ let(:body) { '{"ohai2u":"json_api"}' }
+ it "should inflate the body as to an object" do
+ http_response.add_field('content-type', "application/json")
+ expect(rest.request(:GET, url, {})).to eq({"ohai2u"=>"json_api"})
+ end
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
+ it "should fail if the response is truncated" do
+ http_response.add_field('content-type', "application/json")
+ http_response["Content-Length"] = (body.bytesize + 99).to_s
+ expect { rest.request(:GET, url, {}) }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
+ end
+ end
+
+ %w[ HTTPFound HTTPMovedPermanently HTTPSeeOther HTTPUseProxy HTTPTemporaryRedirect HTTPMultipleChoice ].each do |resp_name|
+ describe "when encountering a #{resp_name} redirect" do
+ let(:http_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
+ end
+ it "should call request again" do
- lambda { @rest.api_request(:GET, @url) }.should raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ expect { rest.request(:GET, url) }.to raise_error(Chef::Exceptions::RedirectLimitExceeded)
- [:PUT, :POST, :DELETE].each do |method|
- lambda { @rest.api_request(method, @url) }.should raise_error(Chef::Exceptions::InvalidRedirect)
+ [:PUT, :POST, :DELETE].each do |method|
+ expect { rest.request(method, url) }.to raise_error(Chef::Exceptions::InvalidRedirect)
+ end
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_client.stub!(:request).and_yield(http_response).and_return(http_response)
+ context "when the response is 304 NotModified" do
+ let (:http_response) 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
+ end
- @rest.api_request(:GET, @url).should be_false
+ it "should return `false`" do
+ expect(rest.request(:GET, url)).to be_false
+ end
end
describe "when the request fails" do
@@ -373,210 +461,265 @@ describe Chef::REST do
Chef::Log.level = @original_log_level
end
- 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)
+ context "on an unsuccessful response with a JSON error" do
+ let(:http_response) 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)
+ http_response
+ end
+
+ it "should show the JSON error message" do
+ rest.stub(:sleep)
- lambda {@rest.api_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'))
+ expect {rest.request(:GET, url)}.to raise_error(Net::HTTPFatalError)
+ expect(log_stringio.string).to match(Regexp.escape('INFO: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
+ end
end
- it "decompresses 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.add_field("content-encoding", "deflate")
- unzipped_body = '{ "error":[ "Ears get sore!", "Not even four" ] }'
- 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)
-
- lambda {@rest.api_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'))
+ context "on an unsuccessful response with a JSON error that is compressed" do
+ let(:http_response) do
+ http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
+ http_response.add_field("content-type", "application/json")
+ http_response.add_field("content-encoding", "deflate")
+ unzipped_body = '{ "error":[ "Ears get sore!", "Not even four" ] }'
+ 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)
+ http_response
+ end
+ it "decompresses the JSON error message" do
+ rest.stub(:sleep)
+ rest.stub(:http_retry_count).and_return(0)
+
+ expect {rest.request(:GET, url)}.to raise_error(Net::HTTPFatalError)
+ expect(log_stringio.string).to match(Regexp.escape('INFO: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
+ end
+ it "fails when the compressed body is truncated" do
+ http_response["Content-Length"] = (body.bytesize + 99).to_s
+ expect {rest.request(:GET, url)}.to raise_error(Chef::Exceptions::ContentLengthMismatch)
+ end
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)
+ context "on a generic unsuccessful request" do
+ let(:http_response) do
+ http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
+ http_response.stub(:body)
+ http_response.stub(:read_body)
+ http_response
+ end
+ it "throws an exception" do
+ rest.stub(:sleep)
+ expect {rest.request(:GET, url)}.to raise_error(Net::HTTPFatalError)
+ end
end
end
-
-
end
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)
- @request_mock = {}
- Net::HTTP::Get.stub!(:new).and_return(@request_mock)
+ let!(:tempfile) { Tempfile.open("chef-rspec-rest_spec-line-@{__LINE__}--") }
- @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)
+ let(:request_mock) { {} }
+
+ let(:http_response) do
+ http_response = Net::HTTPSuccess.new("1.1",200, "it-works")
+
+ http_response.stub(:read_body)
+ http_response.should_not_receive(:body)
+ http_response["Content-Length"] = "0" # call set_content_length (in test), if otherwise
+ http_response
+ end
+
+ def set_content_length
+ content_length = 0
+ http_response.read_body do |chunk|
+ content_length += chunk.bytesize
+ end
+ http_response["Content-Length"] = content_length.to_s
+ end
+
+ before do
+ Tempfile.stub(:new).with("chef-rest").and_return(tempfile)
+ Net::HTTP::Get.stub(:new).and_return(request_mock)
end
after do
- @tempfile.rspec_reset
- @tempfile.close!
+ 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}
- Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
- @rest.streaming_request(@url, {})
+ expected_headers = {'Accept' => "*/*",
+ 'X-Chef-Version' => Chef::VERSION,
+ 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ 'Host' => host_header,
+ 'X-REMOTE-REQUEST-ID'=> request_id
+ }
+ Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(request_mock)
+ rest.streaming_request(url, {})
+ end
+
+ it "build a new HTTP GET request with the X-Remote-Request-Id header" do
+ expected_headers = {'Accept' => "*/*",
+ 'X-Chef-Version' => Chef::VERSION,
+ 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
+ 'Host' => host_header,
+ 'X-REMOTE-REQUEST-ID'=> request_id
+ }
+ Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(request_mock)
+ rest.streaming_request(url, {})
end
it "returns a tempfile containing the streamed response body" do
- @rest.streaming_request(@url, {}).should equal(@tempfile)
+ expect(rest.streaming_request(url, {})).to equal(tempfile)
end
it "writes the response body to a tempfile" do
- @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"
+ http_response.stub(:read_body).and_yield("real").and_yield("ultimate").and_yield("power")
+ set_content_length
+ rest.streaming_request(url, {})
+ expect(IO.read(tempfile.path).chomp).to eq("realultimatepower")
end
it "closes the tempfile" do
- @rest.streaming_request(@url, {})
- @tempfile.should be_closed
+ rest.streaming_request(url, {})
+ expect(tempfile).to be_closed
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")
+ set_content_length
tempfile_path = nil
- @rest.streaming_request(@url, {}) do |tempfile|
+ rest.streaming_request(url, {}) do |tempfile|
tempfile_path = tempfile.path
- File.exist?(tempfile.path).should be_true
- IO.read(@tempfile.path).chomp.should == "realultimatepower"
+ expect(File.exist?(tempfile.path)).to be_true
+ expect(IO.read(tempfile.path).chomp).to eq("realultimatepower")
end
- File.exist?(tempfile_path).should be_false
+ expect(File.exist?(tempfile_path)).to be_false
end
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['Content-Length'] = "5"
+ http_response.stub(:read_body).and_yield('')
+ expect { rest.streaming_request(url, {}) }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
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['Content-Length'] = "0"
+ http_response.stub(:read_body).and_yield("ninja")
+ expect { rest.streaming_request(url, {}) }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
+ end
+
+ it "it raises an exception when the download is truncated" do
+ http_response["Content-Length"] = (body.bytesize + 99).to_s
+ http_response.stub(:read_body).and_yield("ninja")
+ expect { rest.streaming_request(url, {}) }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
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")
+ set_content_length
tempfile_path = nil
- @rest.fetch("cookbooks/a_cookbook") do |tempfile|
+ rest.fetch("cookbooks/a_cookbook") do |tempfile|
tempfile_path = tempfile.path
- IO.read(@tempfile.path).chomp.should == "realultimatepower"
+ expect(IO.read(tempfile.path).chomp).to eq("realultimatepower")
end
- File.exist?(tempfile_path).should be_false
+ expect(File.exist?(tempfile_path)).to be_false
end
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)
- @rest.fetch("cookbooks/a_cookbook") {|tmpfile| "shouldn't get here"}
- File.exists?(path).should be_false
+ path = tempfile.path
+ expect(path).not_to be_nil
+ tempfile.stub(:write).and_raise(IOError)
+ rest.fetch("cookbooks/a_cookbook") {|tmpfile| "shouldn't get here"}
+ expect(File.exists?(path)).to 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)
- @rest.fetch("cookbooks/a_cookbook") {|tmpfile| "shouldn't get here"}
+ 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_redirect = Net::HTTPFound.new("1.1", "302", "bob is taking care of that one for me today")
+ http_redirect.add_field("location","/that-thing-is-here-now")
+ http_redirect.stub(:read_body)
block_called = false
- @http_client.stub!(:request).and_yield(@http_response).and_return(http_response, @http_response)
- @rest.fetch("cookbooks/a_cookbook") do |tmpfile|
+ http_client.stub(:request).and_yield(http_response).and_return(http_redirect, http_response)
+ rest.fetch("cookbooks/a_cookbook") do |tmpfile|
block_called = true
end
- block_called.should be_true
+ expect(block_called).to be_true
end
end
end
context "when following redirects" do
+ let(:rest) do
+ Chef::REST.new(base_url)
+ end
+
before do
Chef::Config[:node_name] = "webmonkey.example.com"
Chef::Config[:client_key] = CHEF_SPEC_DATA + "/ssl/private_key.pem"
- @rest = Chef::REST.new(@url)
end
it "raises a RedirectLimitExceeded when redirected more than 10 times" do
- redirected = lambda {@rest.follow_redirect { redirected.call }}
- lambda {redirected.call}.should raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ redirected = lambda {rest.follow_redirect { redirected.call }}
+ expect {redirected.call}.to raise_error(Chef::Exceptions::RedirectLimitExceeded)
end
it "does not count redirects from previous calls against the redirect limit" do
total_redirects = 0
redirected = lambda do
- @rest.follow_redirect do
+ rest.follow_redirect do
total_redirects += 1
redirected.call unless total_redirects >= 9
end
end
- lambda {redirected.call}.should_not raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ expect {redirected.call}.not_to raise_error
total_redirects = 0
- lambda {redirected.call}.should_not raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ expect {redirected.call}.not_to raise_error
end
it "does not sign the redirected request when sign_on_redirect is false" do
- @rest.sign_on_redirect = false
- @rest.follow_redirect { @rest.sign_requests?.should be_false }
+ rest.sign_on_redirect = false
+ rest.follow_redirect { expect(rest.sign_requests?).to be_false }
end
it "resets sign_requests to the original value after following an unsigned redirect" do
- @rest.sign_on_redirect = false
- @rest.sign_requests?.should be_true
+ rest.sign_on_redirect = false
+ expect(rest.sign_requests?).to be_true
- @rest.follow_redirect { @rest.sign_requests?.should be_false }
- @rest.sign_requests?.should be_true
+ rest.follow_redirect { expect(rest.sign_requests?).to be_false }
+ expect(rest.sign_requests?).to be_true
end
it "configures the redirect limit" do
total_redirects = 0
redirected = lambda do
- @rest.follow_redirect do
+ rest.follow_redirect do
total_redirects += 1
redirected.call unless total_redirects >= 9
end
end
- lambda {redirected.call}.should_not raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ expect {redirected.call}.not_to raise_error
total_redirects = 0
- @rest.redirect_limit = 3
- lambda {redirected.call}.should raise_error(Chef::Exceptions::RedirectLimitExceeded)
+ rest.redirect_limit = 3
+ expect {redirected.call}.to raise_error(Chef::Exceptions::RedirectLimitExceeded)
end
end
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 fe6bef5618..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.
@@ -162,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 d75d6628bb..39b8a8a50d 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.
@@ -45,6 +45,10 @@ describe Chef::RunContext do
describe "loading cookbooks for a run list" do
before do
+ @node.run_list << "test" << "test::one" << "test::two"
+ @node.should_receive(:loaded_recipe).with(:test, "default")
+ @node.should_receive(:loaded_recipe).with(:test, "one")
+ @node.should_receive(:loaded_recipe).with(:test, "two")
@run_context.load(@node.run_list.expand('_default'))
end
diff --git a/spec/unit/run_list/run_list_expansion_spec.rb b/spec/unit/run_list/run_list_expansion_spec.rb
index 012ee9ea31..907e3d3985 100644
--- a/spec/unit/run_list/run_list_expansion_spec.rb
+++ b/spec/unit/run_list/run_list_expansion_spec.rb
@@ -66,7 +66,7 @@ describe Chef::RunList::RunListExpansion do
describe "after applying a role" do
before do
- @expansion.stub!(:fetch_role).and_return(Chef::Role.new)
+ @expansion.stub(:fetch_role).and_return(Chef::Role.new)
@expansion.inflate_role('rage', "role[base]")
end
@@ -89,7 +89,7 @@ describe Chef::RunList::RunListExpansion do
@second_role.run_list('recipe[crabrevenge]')
@second_role.default_attributes({'foo' => 'boo'})
@second_role.override_attributes({'baz' => 'bux'})
- @expansion.stub!(:fetch_role).and_return(@first_role, @second_role)
+ @expansion.stub(:fetch_role).and_return(@first_role, @second_role)
@expansion.expand
end
@@ -111,7 +111,7 @@ describe Chef::RunList::RunListExpansion do
describe "after expanding a run list with a non existant role" do
before do
- @expansion.stub!(:fetch_role) { @expansion.role_not_found('crabrevenge', "role[base]") }
+ @expansion.stub(:fetch_role) { @expansion.role_not_found('crabrevenge', "role[base]") }
@expansion.expand
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_list_spec.rb b/spec/unit/run_list_spec.rb
index f18f21a82b..220e4ea4a6 100644
--- a/spec/unit/run_list_spec.rb
+++ b/spec/unit/run_list_spec.rb
@@ -173,9 +173,9 @@ describe Chef::RunList do
@role.default_attributes :one => :two
@role.override_attributes :three => :four
- Chef::Role.stub!(:load).and_return(@role)
- @rest = mock("Chef::REST", { :get_rest => @role, :url => "/" })
- Chef::REST.stub!(:new).and_return(@rest)
+ Chef::Role.stub(:load).and_return(@role)
+ @rest = double("Chef::REST", { :get_rest => @role, :url => "/" })
+ Chef::REST.stub(:new).and_return(@rest)
@run_list << "role[stubby]"
@run_list << "kitty"
@@ -188,7 +188,7 @@ describe Chef::RunList do
end
it "should log a helpful error if the role is not available" do
- Chef::Role.stub!(:from_disk).and_raise(Chef::Exceptions::RoleNotFound)
+ Chef::Role.stub(:from_disk).and_raise(Chef::Exceptions::RoleNotFound)
Chef::Log.should_receive(:error).with("Role stubby (included by 'top level') is in the runlist but does not exist. Skipping expand.")
@run_list.expand("_default", "disk")
end
@@ -218,7 +218,7 @@ describe Chef::RunList do
describe "and multiply nested roles" do
before do
- @multiple_rest_requests = mock("Chef::REST")
+ @multiple_rest_requests = double("Chef::REST")
@role.env_run_list["production"] << "role[prod-base]"
@@ -233,7 +233,7 @@ describe Chef::RunList do
end
it "expands the run list using the specified environment for all nested roles" do
- Chef::REST.stub!(:new).and_return(@multiple_rest_requests)
+ Chef::REST.stub(:new).and_return(@multiple_rest_requests)
@multiple_rest_requests.should_receive(:get_rest).with("roles/stubby").and_return(@role)
@multiple_rest_requests.should_receive(:get_rest).with("roles/prod-base").and_return(@role_prod_base)
@multiple_rest_requests.should_receive(:get_rest).with("roles/nested-deeper").and_return(@role_nested_deeper)
@@ -270,8 +270,8 @@ describe Chef::RunList do
dog.default_attributes :seven => :nine
dog.run_list "three"
@role.run_list << "role[dog]"
- Chef::Role.stub!(:from_disk).with("stubby").and_return(@role)
- Chef::Role.stub!(:from_disk).with("dog").and_return(dog)
+ Chef::Role.stub(:from_disk).with("stubby").and_return(@role)
+ Chef::Role.stub(:from_disk).with("dog").and_return(dog)
expansion = @run_list.expand("_default", 'disk')
expansion.recipes[2].should == "three"
@@ -284,7 +284,7 @@ describe Chef::RunList do
dog.default_attributes :seven => :nine
dog.run_list "role[dog]", "three"
@role.run_list << "role[dog]"
- Chef::Role.stub!(:from_disk).with("stubby").and_return(@role)
+ Chef::Role.stub(:from_disk).with("stubby").and_return(@role)
Chef::Role.should_receive(:from_disk).with("dog").once.and_return(dog)
expansion = @run_list.expand("_default", 'disk')
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/run_status_spec.rb b/spec/unit/run_status_spec.rb
index 049b86cf54..6c85364871 100644
--- a/spec/unit/run_status_spec.rb
+++ b/spec/unit/run_status_spec.rb
@@ -55,7 +55,7 @@ describe Chef::RunStatus do
before do
@start_time = Time.new
@end_time = @start_time + 23
- Time.stub!(:now).and_return(@start_time, @end_time)
+ Time.stub(:now).and_return(@start_time, @end_time)
@run_status.start_clock
@run_status.stop_clock
end
diff --git a/spec/unit/runner_spec.rb b/spec/unit/runner_spec.rb
index 28082078c2..68d8b0e011 100644
--- a/spec/unit/runner_spec.rb
+++ b/spec/unit/runner_spec.rb
@@ -125,24 +125,24 @@ describe Chef::Runner do
it "should raise exceptions as thrown by a provider" do
provider = Chef::Provider::SnakeOil.new(@run_context.resource_collection[0], @run_context)
- Chef::Provider::SnakeOil.stub!(:new).once.and_return(provider)
- provider.stub!(:action_sell).once.and_raise(ArgumentError)
+ Chef::Provider::SnakeOil.stub(:new).once.and_return(provider)
+ provider.stub(:action_sell).once.and_raise(ArgumentError)
lambda { @runner.converge }.should raise_error(ArgumentError)
end
it "should not raise exceptions thrown by providers if the resource has ignore_failure set to true" do
- @run_context.resource_collection[0].stub!(:ignore_failure).and_return(true)
+ @run_context.resource_collection[0].stub(:ignore_failure).and_return(true)
provider = Chef::Provider::SnakeOil.new(@run_context.resource_collection[0], @run_context)
- Chef::Provider::SnakeOil.stub!(:new).once.and_return(provider)
- provider.stub!(:action_sell).once.and_raise(ArgumentError)
- lambda { @runner.converge }.should_not raise_error(ArgumentError)
+ Chef::Provider::SnakeOil.stub(:new).once.and_return(provider)
+ provider.stub(:action_sell).once.and_raise(ArgumentError)
+ lambda { @runner.converge }.should_not raise_error
end
it "should retry with the specified delay if retries are specified" do
@first_resource.retries 3
provider = Chef::Provider::SnakeOil.new(@run_context.resource_collection[0], @run_context)
- Chef::Provider::SnakeOil.stub!(:new).once.and_return(provider)
- provider.stub!(:action_sell).and_raise(ArgumentError)
+ Chef::Provider::SnakeOil.stub(:new).once.and_return(provider)
+ provider.stub(:action_sell).and_raise(ArgumentError)
@first_resource.should_receive(:sleep).with(2).exactly(3).times
lambda { @runner.converge }.should raise_error(ArgumentError)
end
diff --git a/spec/unit/scan_access_control_spec.rb b/spec/unit/scan_access_control_spec.rb
index c83a552626..48f820ff85 100644
--- a/spec/unit/scan_access_control_spec.rb
+++ b/spec/unit/scan_access_control_spec.rb
@@ -49,7 +49,7 @@ describe Chef::ScanAccessControl do
describe "when the fs entity exists" do
before do
- @stat = mock("File::Stat for #{@new_resource.path}", :uid => 0, :gid => 0, :mode => 00100644)
+ @stat = double("File::Stat for #{@new_resource.path}", :uid => 0, :gid => 0, :mode => 00100644)
File.should_receive(:realpath).with(@new_resource.path).and_return(@real_file)
File.should_receive(:stat).with(@real_file).and_return(@stat)
File.should_receive(:exist?).with(@new_resource.path).and_return(true)
@@ -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
@@ -128,7 +128,7 @@ describe Chef::ScanAccessControl do
end
it "sets the owner of current_resource to the username of the current owner" do
- @root_passwd = mock("Struct::Passwd for uid 0", :name => "root")
+ @root_passwd = double("Struct::Passwd for uid 0", :name => "root")
Etc.should_receive(:getpwuid).with(0).and_return(@root_passwd)
@scanner.set_all!
@@ -163,7 +163,7 @@ describe Chef::ScanAccessControl do
end
it "sets the group of the current resource to the group name" do
- @group_entry = mock("Struct::Group for wheel", :name => "wheel")
+ @group_entry = double("Struct::Group for wheel", :name => "wheel")
Etc.should_receive(:getgrgid).with(0).and_return(@group_entry)
@scanner.set_all!
diff --git a/spec/unit/search/query_spec.rb b/spec/unit/search/query_spec.rb
index e32bed697c..7463e3bb3c 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,10 +19,10 @@
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)
+ @rest = double("Chef::REST")
+ Chef::REST.stub(:new).and_return(@rest)
@query = Chef::Search::Query.new
end
@@ -38,12 +38,12 @@ describe Chef::Search::Query do
"start" => 0,
"total" => 4
}
- @rest.stub!(:get_rest).and_return(@response)
+ @rest.stub(:get_rest).and_return(@response)
end
it "should accept a type as the first argument" do
- lambda { @query.search("foo") }.should_not raise_error(ArgumentError)
- lambda { @query.search(:foo) }.should_not raise_error(ArgumentError)
+ lambda { @query.search("foo") }.should_not raise_error
+ lambda { @query.search(:foo) }.should_not raise_error
lambda { @query.search(Hash.new) }.should raise_error(ArgumentError)
end
@@ -85,13 +85,13 @@ describe Chef::Search::Query do
end
it "should call a block for each object in the response" do
- @call_me = mock("blocky")
+ @call_me = double("blocky")
@response["rows"].each { |r| @call_me.should_receive(:do).with(r) }
@query.search(:foo) { |r| @call_me.do(r) }
end
it "should page through the responses" do
- @call_me = mock("blocky")
+ @call_me = double("blocky")
@response["rows"].each { |r| @call_me.should_receive(:do).with(r) }
@query.search(:foo, "*:*", nil, 0, 1) { |r| @call_me.do(r) }
end
diff --git a/spec/unit/shell/model_wrapper_spec.rb b/spec/unit/shell/model_wrapper_spec.rb
index 35dc591edc..eae3b2b581 100644
--- a/spec/unit/shell/model_wrapper_spec.rb
+++ b/spec/unit/shell/model_wrapper_spec.rb
@@ -71,8 +71,8 @@ describe Shell::ModelWrapper do
@wrapper = Shell::ModelWrapper.new(Chef::Node)
# Creating a Chef::Search::Query object tries to read the private key...
- @searcher = mock("Chef::Search::Query #{__FILE__}:#{__LINE__}")
- Chef::Search::Query.stub!(:new).and_return(@searcher)
+ @searcher = double("Chef::Search::Query #{__FILE__}:#{__LINE__}")
+ Chef::Search::Query.stub(:new).and_return(@searcher)
end
it "falls back to listing the objects when the 'query' is :all" do
diff --git a/spec/unit/shell/shell_ext_spec.rb b/spec/unit/shell/shell_ext_spec.rb
index 22e9ae674b..c24acbca3e 100644
--- a/spec/unit/shell/shell_ext_spec.rb
+++ b/spec/unit/shell/shell_ext_spec.rb
@@ -23,21 +23,21 @@ describe Shell::Extensions do
before do
@shell_client = TestableShellSession.instance
- Shell.stub!(:session).and_return(@shell_client)
+ Shell.stub(:session).and_return(@shell_client)
@job_manager = TestJobManager.new
@root_context = Object.new
@root_context.instance_eval(&ObjectTestHarness)
Shell::Extensions.extend_context_object(@root_context)
- @root_context.conf = mock("irbconf")
+ @root_context.conf = double("irbconf")
end
it "finds a subsession in irb for an object" do
target_context_obj = Chef::Node.new
- irb_context = mock("context", :main => target_context_obj)
- irb_session = mock("irb session", :context => irb_context)
+ irb_context = double("context", :main => target_context_obj)
+ irb_session = double("irb session", :context => irb_context)
@job_manager.jobs = [[:thread, irb_session]]
- @root_context.stub!(:jobs).and_return(@job_manager)
+ @root_context.stub(:jobs).and_return(@job_manager)
@root_context.ensure_session_select_defined
@root_context.jobs.select_shell_session(target_context_obj).should == irb_session
@root_context.jobs.select_shell_session(:idontexist).should be_nil
@@ -45,8 +45,8 @@ describe Shell::Extensions do
it "finds, then switches to a session" do
@job_manager.jobs = []
- @root_context.stub!(:ensure_session_select_defined)
- @root_context.stub!(:jobs).and_return(@job_manager)
+ @root_context.stub(:ensure_session_select_defined)
+ @root_context.stub(:jobs).and_return(@job_manager)
@job_manager.should_receive(:select_shell_session).and_return(:the_shell_session)
@job_manager.should_receive(:switch).with(:the_shell_session)
@root_context.find_or_create_session_for(:foo)
@@ -54,8 +54,8 @@ describe Shell::Extensions do
it "creates a new session if an existing one isn't found" do
@job_manager.jobs = []
- @root_context.stub!(:jobs).and_return(@job_manager)
- @job_manager.stub!(:select_shell_session).and_return(nil)
+ @root_context.stub(:jobs).and_return(@job_manager)
+ @job_manager.stub(:select_shell_session).and_return(nil)
@root_context.should_receive(:irb).with(:foo)
@root_context.find_or_create_session_for(:foo)
end
@@ -81,18 +81,18 @@ describe Shell::Extensions do
it "turns irb tracing on and off" do
@root_context.should respond_to(:trace)
@root_context.conf.should_receive(:use_tracer=).with(true)
- @root_context.stub!(:tracing?)
+ @root_context.stub(:tracing?)
@root_context.tracing :on
end
it "says if tracing is on or off" do
- @root_context.conf.stub!(:use_tracer).and_return(true)
+ @root_context.conf.stub(:use_tracer).and_return(true)
@root_context.should_receive(:puts).with("tracing is on")
@root_context.tracing?
end
it "prints node attributes" do
- node = mock("node", :attribute => {:foo => :bar})
+ node = double("node", :attribute => {:foo => :bar})
@shell_client.node = node
@root_context.should_receive(:pp).with({:foo => :bar})
@root_context.ohai
@@ -111,14 +111,14 @@ describe Shell::Extensions do
end
it "says if echo is on or off" do
- @root_context.conf.stub!(:echo).and_return(true)
+ @root_context.conf.stub(:echo).and_return(true)
@root_context.should_receive(:puts).with("echo is on")
@root_context.echo?
end
it "gives access to the stepable iterator" do
- Shell::StandAloneSession.instance.stub!(:reset!)
- Shell.session.stub!(:rebuild_context)
+ Shell::StandAloneSession.instance.stub(:reset!)
+ Shell.session.stub(:rebuild_context)
events = Chef::EventDispatch::Dispatcher.new
run_context = Chef::RunContext.new(Chef::Node.new, {}, events)
run_context.resource_collection.instance_variable_set(:@iterator, :the_iterator)
diff --git a/spec/unit/shell/shell_session_spec.rb b/spec/unit/shell/shell_session_spec.rb
index a0fc3028f6..e5fc46e945 100644
--- a/spec/unit/shell/shell_session_spec.rb
+++ b/spec/unit/shell/shell_session_spec.rb
@@ -52,7 +52,7 @@ describe Shell::ClientSession do
@session = Shell::ClientSession.instance
@node = Chef::Node.build("foo")
@session.node = @node
- @session.instance_variable_set(:@client, stub(:sync_cookbooks => {}))
+ @session.instance_variable_set(:@client, double(:sync_cookbooks => {}))
@expansion = Chef::RunList::RunListExpansion.new(@node.chef_environment, [])
@node.run_list.should_receive(:expand).with(@node.chef_environment).and_return(@expansion)
@@ -87,9 +87,9 @@ describe Shell::StandAloneSession do
end
it "runs chef with the standalone recipe" do
- @session.stub!(:node_built?).and_return(true)
- Chef::Log.stub!(:level)
- chef_runner = mock("Chef::Runner.new", :converge => :converged)
+ @session.stub(:node_built?).and_return(true)
+ Chef::Log.stub(:level)
+ chef_runner = double("Chef::Runner.new", :converge => :converged)
# pre-heat resource collection cache
@session.resource_collection
@@ -116,7 +116,7 @@ describe Shell::SoloSession do
end
it "returns a collection based on it's compilation object and the extra recipe provided by chef-shell" do
- @session.stub!(:node_built?).and_return(true)
+ @session.stub(:node_built?).and_return(true)
kitteh = Chef::Resource::Cat.new("keyboard")
@recipe.run_context.resource_collection << kitteh
@session.resource_collection.should include(kitteh)
@@ -133,7 +133,7 @@ describe Shell::SoloSession do
end
it "generates its resource collection from the compiled cookbooks and the ad hoc recipe" do
- @session.stub!(:node_built?).and_return(true)
+ @session.stub(:node_built?).and_return(true)
kitteh_cat = Chef::Resource::Cat.new("kitteh")
@run_context.resource_collection << kitteh_cat
keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@@ -143,9 +143,9 @@ describe Shell::SoloSession do
end
it "runs chef with a resource collection from the compiled cookbooks" do
- @session.stub!(:node_built?).and_return(true)
- Chef::Log.stub!(:level)
- chef_runner = mock("Chef::Runner.new", :converge => :converged)
+ @session.stub(:node_built?).and_return(true)
+ Chef::Log.stub(:level)
+ chef_runner = double("Chef::Runner.new", :converge => :converged)
Chef::Runner.should_receive(:new).with(an_instance_of(Chef::RunContext)).and_return(chef_runner)
@recipe.run_chef.should == :converged
diff --git a/spec/unit/shell_spec.rb b/spec/unit/shell_spec.rb
index fd4241732f..cce743873f 100644
--- a/spec/unit/shell_spec.rb
+++ b/spec/unit/shell_spec.rb
@@ -42,8 +42,7 @@ describe Shell do
before do
Shell.irb_conf = {}
- Shell::ShellSession.instance.rspec_reset
- Shell::ShellSession.instance.stub!(:reset!)
+ Shell::ShellSession.instance.stub(:reset!)
end
describe "reporting its status" do
diff --git a/spec/unit/user_spec.rb b/spec/unit/user_spec.rb
index 9121babeed..c535e4172b 100644
--- a/spec/unit/user_spec.rb
+++ b/spec/unit/user_spec.rb
@@ -196,8 +196,8 @@ describe Chef::User do
before (:each) do
@user = Chef::User.new
@user.name "foobar"
- @http_client = mock("Chef::REST mock")
- Chef::REST.stub!(:new).and_return(@http_client)
+ @http_client = double("Chef::REST mock")
+ Chef::REST.stub(:new).and_return(@http_client)
end
describe "list" do
@@ -208,12 +208,12 @@ describe Chef::User do
end
it "lists all clients on an OSC server" do
- @http_client.stub!(:get_rest).with("users").and_return(@osc_response)
+ @http_client.stub(:get_rest).with("users").and_return(@osc_response)
Chef::User.list.should == @osc_response
end
it "lists all clients on an OHC/OPC server" do
- @http_client.stub!(:get_rest).with("users").and_return(@ohc_response)
+ @http_client.stub(:get_rest).with("users").and_return(@ohc_response)
# We expect that Chef::User.list will give a consistent response
# so OHC API responses should be transformed to OSC-style output.
Chef::User.list.should == @osc_response
diff --git a/spec/unit/util/backup_spec.rb b/spec/unit/util/backup_spec.rb
index f0e182e181..617886cede 100644
--- a/spec/unit/util/backup_spec.rb
+++ b/spec/unit/util/backup_spec.rb
@@ -21,20 +21,13 @@ 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")
end
before(:each) do
- @new_resource = mock("new_resource")
+ @new_resource = double("new_resource")
@new_resource.should_receive(:path).at_least(:once).and_return(tempfile.path)
@backup = Chef::Util::Backup.new(@new_resource)
end
@@ -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 ad1166f9fc..947ce1d5aa 100644
--- a/spec/unit/util/diff_spec.rb
+++ b/spec/unit/util/diff_spec.rb
@@ -20,32 +20,17 @@
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
+shared_context "using file paths with spaces" do
+ let!(:old_tempfile) { Tempfile.new("chef-util diff-spec") }
+ let!(:new_tempfile) { Tempfile.new("chef-util diff-spec") }
+end
+shared_context "using file paths without spaces" do
let!(:old_tempfile) { Tempfile.new("chef-util-diff-spec") }
let!(:new_tempfile) { Tempfile.new("chef-util-diff-spec") }
- let!(:old_file) { old_tempfile.path }
- let!(:new_file) { new_tempfile.path }
-
- let(:plain_ascii) { "This is a text file.\nWith more than one line.\nAnd a \tTab.\nAnd lets make sure that other printable chars work too: ~!@\#$%^&*()`:\"<>?{}|_+,./;'[]\\-=\n" }
- # these are all byte sequences that are illegal in the other encodings... (but they may legally transcode)
- let(:utf_8) { "testing utf-8 unicode...\n\n\non a new line: \xE2\x80\x93\n" } # unicode em-dash
- let(:latin_1) { "It is more metal.\nif you have an \xFDmlaut.\n" } # NB: changed to y-with-diaresis, but i'm American so I don't know the difference
- let(:shift_jis) { "I have no idea what this character is:\n \x83\x80.\n" } # seriously, no clue, but \x80 is nice and illegal in other encodings
-
- let(:differ) do # subject
- differ = Chef::Util::Diff.new
- differ.diff(old_file, new_file)
- differ
- end
+end
+shared_examples_for "a diff util" do
it "should return a Chef::Util::Diff" do
expect(differ).to be_a_kind_of(Chef::Util::Diff)
end
@@ -562,4 +547,33 @@ describe Chef::Util::Diff, :uses_diff => true do
end
+describe Chef::Util::Diff, :uses_diff => true do
+ let!(:old_file) { old_tempfile.path }
+ let!(:new_file) { new_tempfile.path }
+
+ let(:plain_ascii) { "This is a text file.\nWith more than one line.\nAnd a \tTab.\nAnd lets make sure that other printable chars work too: ~!@\#$%^&*()`:\"<>?{}|_+,./;'[]\\-=\n" }
+ # these are all byte sequences that are illegal in the other encodings... (but they may legally transcode)
+ let(:utf_8) { "testing utf-8 unicode...\n\n\non a new line: \xE2\x80\x93\n" } # unicode em-dash
+ let(:latin_1) { "It is more metal.\nif you have an \xFDmlaut.\n" } # NB: changed to y-with-diaresis, but i'm American so I don't know the difference
+ let(:shift_jis) { "I have no idea what this character is:\n \x83\x80.\n" } # seriously, no clue, but \x80 is nice and illegal in other encodings
+
+ let(:differ) do # subject
+ differ = Chef::Util::Diff.new
+ differ.diff(old_file, new_file)
+ differ
+ end
+
+ describe "when file path has spaces" do
+ include_context "using file paths with spaces"
+
+ it_behaves_like "a diff util"
+ end
+
+
+ describe "when file path doesn't have spaces" do
+ include_context "using file paths without spaces"
+
+ it_behaves_like "a diff util"
+ end
+end
diff --git a/spec/unit/util/file_edit_spec.rb b/spec/unit/util/file_edit_spec.rb
index 3cf60172d9..d1d87a6bda 100644
--- a/spec/unit/util/file_edit_spec.rb
+++ b/spec/unit/util/file_edit_spec.rb
@@ -20,116 +20,169 @@ require 'spec_helper'
describe Chef::Util::FileEdit do
- before(:each) do
+ let(:starting_content) do
+ <<-EOF
+127.0.0.1 localhost
+255.255.255.255 broadcasthost
+::1 localhost
+fe80::1%lo0 localhost
+ EOF
+ end
+
+ let(:localhost_replaced) do
+ <<-EOF
+127.0.0.1 replacement
+255.255.255.255 broadcasthost
+::1 replacement
+fe80::1%lo0 replacement
+ EOF
+ end
+
+ let(:localhost_line_replaced) do
+ <<-EOF
+replacement line
+255.255.255.255 broadcasthost
+replacement line
+replacement line
+ EOF
+ end
+
+ let(:localhost_deleted) do
+ # sensitive to deliberate trailing whitespace
+ "127.0.0.1 \n255.255.255.255 broadcasthost\n::1 \nfe80::1%lo0 \n"
+ end
+
+ let(:localhost_line_deleted) do
+ <<-EOF
+255.255.255.255 broadcasthost
+ EOF
+ end
+
+ let(:append_after_all_localhost) do
+ <<-EOF
+127.0.0.1 localhost
+new line inserted
+255.255.255.255 broadcasthost
+::1 localhost
+new line inserted
+fe80::1%lo0 localhost
+new line inserted
+ EOF
+ end
- @hosts_content=<<-HOSTS
+ let(:append_after_content) do
+ <<-EOF
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
fe80::1%lo0 localhost
-HOSTS
+new line inserted
+ EOF
+ end
- @tempfile = Tempfile.open('file_edit_spec')
- @tempfile.write(@hosts_content)
- @tempfile.close
- @fedit = Chef::Util::FileEdit.new(@tempfile.path)
+ let(:target_file) do
+ f = Tempfile.open('file_edit_spec')
+ f.write(starting_content)
+ f.close
+ f
end
+ let(:fedit) { Chef::Util::FileEdit.new(target_file.path) }
+
after(:each) do
- @tempfile && @tempfile.close!
+ target_file.close!
end
describe "initialiize" do
it "should create a new Chef::Util::FileEdit object" do
- Chef::Util::FileEdit.new(@tempfile.path).should be_kind_of(Chef::Util::FileEdit)
+ expect(fedit).to be_instance_of(Chef::Util::FileEdit)
end
it "should throw an exception if the input file does not exist" do
- lambda{Chef::Util::FileEdit.new("nonexistfile")}.should raise_error
+ expect{Chef::Util::FileEdit.new("nonexistfile")}.to raise_error(ArgumentError)
end
- it "should throw an exception if the input file is blank" do
- lambda do
- Chef::Util::FileEdit.new(File.join(CHEF_SPEC_DATA, "filedit", "blank"))
- end.should raise_error
+ # CHEF-5018: people have monkey patched this and it has accidentally been broken
+ it "should read the contents into memory as an array" do
+ expect(fedit.send(:contents)).to be_instance_of(Array)
end
end
+ describe "when the file is blank" do
+ let(:hosts_content) { "" }
+
+ it "should not throw an exception" do
+ expect{ fedit }.not_to raise_error
+ end
+ end
+
+ def edited_file_contents
+ IO.read(target_file.path)
+ end
+
describe "search_file_replace" do
it "should accept regex passed in as a string (not Regexp object) and replace the match if there is one" do
- @fedit.search_file_replace("localhost", "replacement")
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile[0].should match(/replacement/)
+ fedit.search_file_replace("localhost", "replacement")
+ fedit.write_file
+ expect(edited_file_contents).to eq(localhost_replaced)
end
it "should accept regex passed in as a Regexp object and replace the match if there is one" do
- @fedit.search_file_replace(/localhost/, "replacement")
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile[0].should match(/replacement/)
+ fedit.search_file_replace(/localhost/, "replacement")
+ fedit.write_file
+ expect(edited_file_contents).to eq(localhost_replaced)
end
it "should do nothing if there isn't a match" do
- @fedit.search_file_replace(/pattern/, "replacement")
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile[0].should_not match(/replacement/)
+ fedit.search_file_replace(/pattern/, "replacement")
+ fedit.write_file
+ expect(edited_file_contents).to eq(starting_content)
end
end
describe "search_file_replace_line" do
it "should search for match and replace the whole line" do
- @fedit.search_file_replace_line(/localhost/, "replacement line")
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile[0].should match(/replacement/)
- newfile[0].should_not match(/127/)
+ fedit.search_file_replace_line(/localhost/, "replacement line")
+ fedit.write_file
+ expect(edited_file_contents).to eq(localhost_line_replaced)
end
end
describe "search_file_delete" do
it "should search for match and delete the match" do
- @fedit.search_file_delete(/localhost/)
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile[0].should_not match(/localhost/)
- newfile[0].should match(/127/)
+ fedit.search_file_delete(/localhost/)
+ fedit.write_file
+ expect(edited_file_contents).to eq(localhost_deleted)
end
end
describe "search_file_delete_line" do
it "should search for match and delete the matching line" do
- @fedit.search_file_delete_line(/localhost/)
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile[0].should_not match(/localhost/)
- newfile[0].should match(/broadcasthost/)
+ fedit.search_file_delete_line(/localhost/)
+ fedit.write_file
+ expect(edited_file_contents).to eq(localhost_line_deleted)
end
end
describe "insert_line_after_match" do
it "should search for match and insert the given line after the matching line" do
- @fedit.insert_line_after_match(/localhost/, "new line inserted")
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile[1].should match(/new/)
+ fedit.insert_line_after_match(/localhost/, "new line inserted")
+ fedit.write_file
+ expect(edited_file_contents).to eq(append_after_all_localhost)
end
end
describe "insert_line_if_no_match" do
it "should search for match and insert the given line if no line match" do
- @fedit.insert_line_if_no_match(/pattern/, "new line inserted")
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile.last.should match(/new/)
+ fedit.insert_line_if_no_match(/pattern/, "new line inserted")
+ fedit.write_file
+ expect(edited_file_contents).to eq(append_after_content)
end
it "should do nothing if there is a match" do
- @fedit.insert_line_if_no_match(/localhost/, "replacement")
- @fedit.write_file
- newfile = File.new(@tempfile.path).readlines
- newfile[1].should_not match(/replacement/)
+ fedit.insert_line_if_no_match(/localhost/, "replacement")
+ fedit.write_file
+ expect(edited_file_contents).to eq(starting_content)
end
end
end
diff --git a/spec/unit/util/selinux_spec.rb b/spec/unit/util/selinux_spec.rb
index 710380e6fc..d87cebf95c 100644
--- a/spec/unit/util/selinux_spec.rb
+++ b/spec/unit/util/selinux_spec.rb
@@ -53,7 +53,7 @@ describe Chef::Util::Selinux do
describe "when selinuxenabled binary exists" do
before do
@selinux_enabled_path = File.join("/sbin", "selinuxenabled")
- File.stub!(:executable?) do |file_path|
+ File.stub(:executable?) do |file_path|
file_path.end_with?("selinuxenabled").should be_true
file_path == @selinux_enabled_path
end
@@ -61,7 +61,7 @@ describe Chef::Util::Selinux do
describe "when selinux is enabled" do
before do
- cmd_result = mock("Cmd Result", :exitstatus => 0)
+ cmd_result = double("Cmd Result", :exitstatus => 0)
@test_instance.should_receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
end
@@ -74,7 +74,7 @@ describe Chef::Util::Selinux do
describe "when selinux is disabled" do
before do
- cmd_result = mock("Cmd Result", :exitstatus => 1)
+ cmd_result = double("Cmd Result", :exitstatus => 1)
@test_instance.should_receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
end
@@ -87,7 +87,7 @@ describe Chef::Util::Selinux do
describe "when selinux gives an unexpected status" do
before do
- cmd_result = mock("Cmd Result", :exitstatus => 101)
+ cmd_result = double("Cmd Result", :exitstatus => 101)
@test_instance.should_receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
end
@@ -99,7 +99,7 @@ describe Chef::Util::Selinux do
describe "when selinuxenabled binary doesn't exist" do
before do
- File.stub!(:executable?) do |file_path|
+ File.stub(:executable?) do |file_path|
file_path.end_with?("selinuxenabled").should be_true
false
end
@@ -118,7 +118,7 @@ describe Chef::Util::Selinux do
before do
@restorecon_enabled_path = File.join("/sbin", "restorecon")
- File.stub!(:executable?) do |file_path|
+ File.stub(:executable?) do |file_path|
file_path.end_with?("restorecon").should be_true
file_path == @restorecon_enabled_path
end
@@ -150,7 +150,7 @@ describe Chef::Util::Selinux do
describe "when restorecon doesn't exist on the system" do
before do
- File.stub!(:executable?) do |file_path|
+ File.stub(:executable?) do |file_path|
file_path.end_with?("restorecon").should be_true
false
end
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