TrueCar-chef 0.10.0.beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +201 -0
- data/README.rdoc +171 -0
- data/bin/chef-client +26 -0
- data/bin/chef-solo +25 -0
- data/bin/knife +26 -0
- data/bin/shef +34 -0
- data/distro/README +2 -0
- data/distro/arch/etc/conf.d/chef-client.conf +5 -0
- data/distro/arch/etc/conf.d/chef-server-webui.conf +10 -0
- data/distro/arch/etc/conf.d/chef-server.conf +10 -0
- data/distro/arch/etc/conf.d/chef-solr-indexer.conf +8 -0
- data/distro/arch/etc/conf.d/chef-solr.conf +8 -0
- data/distro/arch/etc/rc.d/chef-client +76 -0
- data/distro/arch/etc/rc.d/chef-server +78 -0
- data/distro/arch/etc/rc.d/chef-server-webui +78 -0
- data/distro/arch/etc/rc.d/chef-solr +78 -0
- data/distro/arch/etc/rc.d/chef-solr-indexer +78 -0
- data/distro/common/man/man1/chef-indexer.1 +42 -0
- data/distro/common/man/man1/chef-server-webui.1 +106 -0
- data/distro/common/man/man1/chef-server.1 +107 -0
- data/distro/common/man/man1/chef-solr-indexer.1 +55 -0
- data/distro/common/man/man1/chef-solr.1 +55 -0
- data/distro/common/man/man8/chef-client.8 +63 -0
- data/distro/common/man/man8/chef-solo.8 +57 -0
- data/distro/common/man/man8/chef-solr-rebuild.8 +37 -0
- data/distro/common/man/man8/knife.8 +1349 -0
- data/distro/common/man/man8/shef.8 +45 -0
- data/distro/common/markdown/README +3 -0
- data/distro/common/markdown/knife.mkd +865 -0
- data/distro/debian/etc/default/chef-client +4 -0
- data/distro/debian/etc/default/chef-server +9 -0
- data/distro/debian/etc/default/chef-server-webui +9 -0
- data/distro/debian/etc/default/chef-solr +8 -0
- data/distro/debian/etc/default/chef-solr-indexer +7 -0
- data/distro/debian/etc/init.d/chef-client +175 -0
- data/distro/debian/etc/init.d/chef-server +122 -0
- data/distro/debian/etc/init.d/chef-server-webui +123 -0
- data/distro/debian/etc/init.d/chef-solr +176 -0
- data/distro/debian/etc/init.d/chef-solr-indexer +176 -0
- data/distro/debian/etc/init/chef-client.conf +17 -0
- data/distro/debian/etc/init/chef-server-webui.conf +17 -0
- data/distro/debian/etc/init/chef-server.conf +17 -0
- data/distro/debian/etc/init/chef-solr-indexer.conf +17 -0
- data/distro/debian/etc/init/chef-solr.conf +17 -0
- data/distro/redhat/etc/init.d/chef-client +106 -0
- data/distro/redhat/etc/init.d/chef-server +112 -0
- data/distro/redhat/etc/init.d/chef-server-webui +112 -0
- data/distro/redhat/etc/init.d/chef-solr +104 -0
- data/distro/redhat/etc/init.d/chef-solr-indexer +104 -0
- data/distro/redhat/etc/logrotate.d/chef-client +8 -0
- data/distro/redhat/etc/logrotate.d/chef-server +8 -0
- data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
- data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
- data/distro/redhat/etc/logrotate.d/chef-solr-indexer +8 -0
- data/distro/redhat/etc/sysconfig/chef-client +15 -0
- data/distro/redhat/etc/sysconfig/chef-server +14 -0
- data/distro/redhat/etc/sysconfig/chef-server-webui +14 -0
- data/distro/redhat/etc/sysconfig/chef-solr +8 -0
- data/distro/redhat/etc/sysconfig/chef-solr-indexer +7 -0
- data/lib/chef.rb +40 -0
- data/lib/chef/api_client.rb +264 -0
- data/lib/chef/application.rb +137 -0
- data/lib/chef/application/agent.rb +18 -0
- data/lib/chef/application/client.rb +242 -0
- data/lib/chef/application/knife.rb +169 -0
- data/lib/chef/application/solo.rb +217 -0
- data/lib/chef/applications.rb +4 -0
- data/lib/chef/certificate.rb +194 -0
- data/lib/chef/checksum.rb +182 -0
- data/lib/chef/checksum_cache.rb +189 -0
- data/lib/chef/client.rb +362 -0
- data/lib/chef/config.rb +244 -0
- data/lib/chef/cookbook/chefignore.rb +66 -0
- data/lib/chef/cookbook/cookbook_collection.rb +45 -0
- data/lib/chef/cookbook/cookbook_version_loader.rb +151 -0
- data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
- data/lib/chef/cookbook/file_vendor.rb +48 -0
- data/lib/chef/cookbook/metadata.rb +592 -0
- data/lib/chef/cookbook/remote_file_vendor.rb +87 -0
- data/lib/chef/cookbook/syntax_check.rb +136 -0
- data/lib/chef/cookbook_loader.rb +103 -0
- data/lib/chef/cookbook_site_streaming_uploader.rb +244 -0
- data/lib/chef/cookbook_uploader.rb +125 -0
- data/lib/chef/cookbook_version.rb +979 -0
- data/lib/chef/cookbook_version_selector.rb +163 -0
- data/lib/chef/couchdb.rb +247 -0
- data/lib/chef/daemon.rb +172 -0
- data/lib/chef/data_bag.rb +223 -0
- data/lib/chef/data_bag_item.rb +267 -0
- data/lib/chef/encrypted_data_bag_item.rb +126 -0
- data/lib/chef/environment.rb +386 -0
- data/lib/chef/exceptions.rb +153 -0
- data/lib/chef/file_access_control.rb +140 -0
- data/lib/chef/file_cache.rb +218 -0
- data/lib/chef/handler.rb +206 -0
- data/lib/chef/handler/json_file.rb +58 -0
- data/lib/chef/index_queue.rb +29 -0
- data/lib/chef/index_queue/amqp_client.rb +116 -0
- data/lib/chef/index_queue/consumer.rb +76 -0
- data/lib/chef/index_queue/indexable.rb +109 -0
- data/lib/chef/json_compat.rb +52 -0
- data/lib/chef/knife.rb +424 -0
- data/lib/chef/knife/bootstrap.rb +185 -0
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +47 -0
- data/lib/chef/knife/bootstrap/centos5-gems.erb +41 -0
- data/lib/chef/knife/bootstrap/client-install.vbs +80 -0
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +38 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +32 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +46 -0
- data/lib/chef/knife/bootstrap/windows-gems.erb +34 -0
- data/lib/chef/knife/client_bulk_delete.rb +43 -0
- data/lib/chef/knife/client_create.rb +73 -0
- data/lib/chef/knife/client_delete.rb +48 -0
- data/lib/chef/knife/client_edit.rb +48 -0
- data/lib/chef/knife/client_list.rb +43 -0
- data/lib/chef/knife/client_reregister.rb +59 -0
- data/lib/chef/knife/client_show.rb +53 -0
- data/lib/chef/knife/configure.rb +136 -0
- data/lib/chef/knife/configure_client.rb +52 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +61 -0
- data/lib/chef/knife/cookbook_create.rb +274 -0
- data/lib/chef/knife/cookbook_delete.rb +149 -0
- data/lib/chef/knife/cookbook_download.rb +134 -0
- data/lib/chef/knife/cookbook_list.rb +50 -0
- data/lib/chef/knife/cookbook_metadata.rb +102 -0
- data/lib/chef/knife/cookbook_metadata_from_file.rb +44 -0
- data/lib/chef/knife/cookbook_show.rb +101 -0
- data/lib/chef/knife/cookbook_site_download.rb +58 -0
- data/lib/chef/knife/cookbook_site_list.rb +56 -0
- data/lib/chef/knife/cookbook_site_search.rb +51 -0
- data/lib/chef/knife/cookbook_site_share.rb +114 -0
- data/lib/chef/knife/cookbook_site_show.rb +57 -0
- data/lib/chef/knife/cookbook_site_unshare.rb +56 -0
- data/lib/chef/knife/cookbook_site_vendor.rb +145 -0
- data/lib/chef/knife/cookbook_test.rb +82 -0
- data/lib/chef/knife/cookbook_upload.rb +146 -0
- data/lib/chef/knife/data_bag_create.rb +94 -0
- data/lib/chef/knife/data_bag_delete.rb +51 -0
- data/lib/chef/knife/data_bag_edit.rb +94 -0
- data/lib/chef/knife/data_bag_from_file.rb +85 -0
- data/lib/chef/knife/data_bag_list.rb +46 -0
- data/lib/chef/knife/data_bag_show.rb +81 -0
- data/lib/chef/knife/environment_create.rb +53 -0
- data/lib/chef/knife/environment_delete.rb +45 -0
- data/lib/chef/knife/environment_edit.rb +45 -0
- data/lib/chef/knife/environment_from_file.rb +39 -0
- data/lib/chef/knife/environment_list.rb +42 -0
- data/lib/chef/knife/environment_show.rb +46 -0
- data/lib/chef/knife/exec.rb +51 -0
- data/lib/chef/knife/index_rebuild.rb +50 -0
- data/lib/chef/knife/node_bulk_delete.rb +46 -0
- data/lib/chef/knife/node_create.rb +50 -0
- data/lib/chef/knife/node_delete.rb +47 -0
- data/lib/chef/knife/node_edit.rb +163 -0
- data/lib/chef/knife/node_from_file.rb +45 -0
- data/lib/chef/knife/node_list.rb +46 -0
- data/lib/chef/knife/node_run_list_add.rb +67 -0
- data/lib/chef/knife/node_run_list_remove.rb +48 -0
- data/lib/chef/knife/node_show.rb +62 -0
- data/lib/chef/knife/recipe_list.rb +33 -0
- data/lib/chef/knife/role_bulk_delete.rb +47 -0
- data/lib/chef/knife/role_create.rb +55 -0
- data/lib/chef/knife/role_delete.rb +47 -0
- data/lib/chef/knife/role_edit.rb +48 -0
- data/lib/chef/knife/role_from_file.rb +49 -0
- data/lib/chef/knife/role_list.rb +43 -0
- data/lib/chef/knife/role_show.rb +54 -0
- data/lib/chef/knife/search.rb +123 -0
- data/lib/chef/knife/ssh.rb +318 -0
- data/lib/chef/knife/status.rb +90 -0
- data/lib/chef/knife/subcommand_loader.rb +101 -0
- data/lib/chef/knife/tag_create.rb +31 -0
- data/lib/chef/knife/tag_delete.rb +31 -0
- data/lib/chef/knife/tag_list.rb +29 -0
- data/lib/chef/knife/ui.rb +227 -0
- data/lib/chef/knife/windows_bootstrap.rb +157 -0
- data/lib/chef/log.rb +39 -0
- data/lib/chef/mash.rb +211 -0
- data/lib/chef/mixin/check_helper.rb +31 -0
- data/lib/chef/mixin/checksum.rb +32 -0
- data/lib/chef/mixin/command.rb +221 -0
- data/lib/chef/mixin/command/unix.rb +215 -0
- data/lib/chef/mixin/command/windows.rb +76 -0
- data/lib/chef/mixin/convert_to_class_name.rb +63 -0
- data/lib/chef/mixin/create_path.rb +56 -0
- data/lib/chef/mixin/deep_merge.rb +225 -0
- data/lib/chef/mixin/deprecation.rb +65 -0
- data/lib/chef/mixin/from_file.rb +50 -0
- data/lib/chef/mixin/language.rb +165 -0
- data/lib/chef/mixin/language_include_attribute.rb +61 -0
- data/lib/chef/mixin/language_include_recipe.rb +52 -0
- data/lib/chef/mixin/params_validate.rb +225 -0
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +81 -0
- data/lib/chef/mixin/shell_out.rb +40 -0
- data/lib/chef/mixin/template.rb +95 -0
- data/lib/chef/mixin/xml_escape.rb +140 -0
- data/lib/chef/mixins.rb +15 -0
- data/lib/chef/monkey_patches/dir.rb +36 -0
- data/lib/chef/monkey_patches/numeric.rb +7 -0
- data/lib/chef/monkey_patches/regexp.rb +34 -0
- data/lib/chef/monkey_patches/string.rb +28 -0
- data/lib/chef/monkey_patches/tempfile.rb +64 -0
- data/lib/chef/nil_argument.rb +3 -0
- data/lib/chef/node.rb +661 -0
- data/lib/chef/node/attribute.rb +487 -0
- data/lib/chef/openid_registration.rb +187 -0
- data/lib/chef/platform.rb +409 -0
- data/lib/chef/provider.rb +124 -0
- data/lib/chef/provider/breakpoint.rb +36 -0
- data/lib/chef/provider/cookbook_file.rb +101 -0
- data/lib/chef/provider/cron.rb +186 -0
- data/lib/chef/provider/cron/solaris.rb +195 -0
- data/lib/chef/provider/deploy.rb +320 -0
- data/lib/chef/provider/deploy/revision.rb +80 -0
- data/lib/chef/provider/deploy/timestamped.rb +33 -0
- data/lib/chef/provider/directory.rb +72 -0
- data/lib/chef/provider/env.rb +152 -0
- data/lib/chef/provider/env/windows.rb +75 -0
- data/lib/chef/provider/erl_call.rb +100 -0
- data/lib/chef/provider/execute.rb +60 -0
- data/lib/chef/provider/file.rb +222 -0
- data/lib/chef/provider/git.rb +221 -0
- data/lib/chef/provider/group.rb +133 -0
- data/lib/chef/provider/group/aix.rb +70 -0
- data/lib/chef/provider/group/dscl.rb +121 -0
- data/lib/chef/provider/group/gpasswd.rb +53 -0
- data/lib/chef/provider/group/groupadd.rb +81 -0
- data/lib/chef/provider/group/pw.rb +84 -0
- data/lib/chef/provider/group/usermod.rb +57 -0
- data/lib/chef/provider/group/windows.rb +79 -0
- data/lib/chef/provider/http_request.rb +122 -0
- data/lib/chef/provider/ifconfig.rb +132 -0
- data/lib/chef/provider/link.rb +161 -0
- data/lib/chef/provider/log.rb +54 -0
- data/lib/chef/provider/mdadm.rb +91 -0
- data/lib/chef/provider/mount.rb +117 -0
- data/lib/chef/provider/mount/mount.rb +232 -0
- data/lib/chef/provider/mount/windows.rb +80 -0
- data/lib/chef/provider/ohai.rb +41 -0
- data/lib/chef/provider/package.rb +160 -0
- data/lib/chef/provider/package/apt.rb +110 -0
- data/lib/chef/provider/package/dpkg.rb +112 -0
- data/lib/chef/provider/package/easy_install.rb +136 -0
- data/lib/chef/provider/package/freebsd.rb +123 -0
- data/lib/chef/provider/package/macports.rb +105 -0
- data/lib/chef/provider/package/pacman.rb +101 -0
- data/lib/chef/provider/package/portage.rb +135 -0
- data/lib/chef/provider/package/rpm.rb +101 -0
- data/lib/chef/provider/package/rubygems.rb +462 -0
- data/lib/chef/provider/package/solaris.rb +127 -0
- data/lib/chef/provider/package/yum-dump.py +128 -0
- data/lib/chef/provider/package/yum.rb +261 -0
- data/lib/chef/provider/package/zypper.rb +133 -0
- data/lib/chef/provider/remote_directory.rb +138 -0
- data/lib/chef/provider/remote_file.rb +119 -0
- data/lib/chef/provider/route.rb +195 -0
- data/lib/chef/provider/ruby_block.rb +33 -0
- data/lib/chef/provider/script.rb +55 -0
- data/lib/chef/provider/service.rb +128 -0
- data/lib/chef/provider/service/arch.rb +109 -0
- data/lib/chef/provider/service/debian.rb +130 -0
- data/lib/chef/provider/service/freebsd.rb +156 -0
- data/lib/chef/provider/service/gentoo.rb +54 -0
- data/lib/chef/provider/service/init.rb +71 -0
- data/lib/chef/provider/service/insserv.rb +52 -0
- data/lib/chef/provider/service/redhat.rb +60 -0
- data/lib/chef/provider/service/simple.rb +118 -0
- data/lib/chef/provider/service/solaris.rb +85 -0
- data/lib/chef/provider/service/upstart.rb +192 -0
- data/lib/chef/provider/service/windows.rb +146 -0
- data/lib/chef/provider/subversion.rb +194 -0
- data/lib/chef/provider/template.rb +105 -0
- data/lib/chef/provider/user.rb +187 -0
- data/lib/chef/provider/user/dscl.rb +280 -0
- data/lib/chef/provider/user/pw.rb +113 -0
- data/lib/chef/provider/user/useradd.rb +137 -0
- data/lib/chef/provider/user/windows.rb +124 -0
- data/lib/chef/providers.rb +93 -0
- data/lib/chef/recipe.rb +128 -0
- data/lib/chef/resource.rb +530 -0
- data/lib/chef/resource/apt_package.rb +34 -0
- data/lib/chef/resource/bash.rb +33 -0
- data/lib/chef/resource/breakpoint.rb +35 -0
- data/lib/chef/resource/cookbook_file.rb +45 -0
- data/lib/chef/resource/cron.rb +188 -0
- data/lib/chef/resource/csh.rb +33 -0
- data/lib/chef/resource/deploy.rb +371 -0
- data/lib/chef/resource/deploy_revision.rb +35 -0
- data/lib/chef/resource/directory.rb +76 -0
- data/lib/chef/resource/dpkg_package.rb +34 -0
- data/lib/chef/resource/easy_install_package.rb +57 -0
- data/lib/chef/resource/env.rb +58 -0
- data/lib/chef/resource/erl_call.rb +83 -0
- data/lib/chef/resource/execute.rb +127 -0
- data/lib/chef/resource/file.rb +99 -0
- data/lib/chef/resource/freebsd_package.rb +35 -0
- data/lib/chef/resource/gem_package.rb +53 -0
- data/lib/chef/resource/git.rb +37 -0
- data/lib/chef/resource/group.rb +70 -0
- data/lib/chef/resource/http_request.rb +61 -0
- data/lib/chef/resource/ifconfig.rb +134 -0
- data/lib/chef/resource/link.rb +78 -0
- data/lib/chef/resource/log.rb +62 -0
- data/lib/chef/resource/macports_package.rb +29 -0
- data/lib/chef/resource/mdadm.rb +82 -0
- data/lib/chef/resource/mount.rb +135 -0
- data/lib/chef/resource/ohai.rb +40 -0
- data/lib/chef/resource/package.rb +80 -0
- data/lib/chef/resource/pacman_package.rb +33 -0
- data/lib/chef/resource/perl.rb +33 -0
- data/lib/chef/resource/portage_package.rb +33 -0
- data/lib/chef/resource/python.rb +33 -0
- data/lib/chef/resource/remote_directory.rb +109 -0
- data/lib/chef/resource/remote_file.rb +83 -0
- data/lib/chef/resource/route.rb +135 -0
- data/lib/chef/resource/rpm_package.rb +34 -0
- data/lib/chef/resource/ruby.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +40 -0
- data/lib/chef/resource/scm.rb +147 -0
- data/lib/chef/resource/script.rb +60 -0
- data/lib/chef/resource/service.rb +160 -0
- data/lib/chef/resource/solaris_package.rb +36 -0
- data/lib/chef/resource/subversion.rb +36 -0
- data/lib/chef/resource/template.rb +69 -0
- data/lib/chef/resource/timestamped_deploy.rb +31 -0
- data/lib/chef/resource/user.rb +130 -0
- data/lib/chef/resource/yum_package.rb +43 -0
- data/lib/chef/resource_collection.rb +217 -0
- data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
- data/lib/chef/resource_definition.rb +67 -0
- data/lib/chef/resource_definition_list.rb +38 -0
- data/lib/chef/resources.rb +64 -0
- data/lib/chef/rest.rb +386 -0
- data/lib/chef/rest/auth_credentials.rb +71 -0
- data/lib/chef/rest/cookie_jar.rb +31 -0
- data/lib/chef/rest/rest_request.rb +188 -0
- data/lib/chef/role.rb +341 -0
- data/lib/chef/run_context.rb +126 -0
- data/lib/chef/run_list.rb +165 -0
- data/lib/chef/run_list/run_list_expansion.rb +193 -0
- data/lib/chef/run_list/run_list_item.rb +92 -0
- data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
- data/lib/chef/run_status.rb +121 -0
- data/lib/chef/runner.rb +99 -0
- data/lib/chef/sandbox.rb +153 -0
- data/lib/chef/search/query.rb +65 -0
- data/lib/chef/shef.rb +326 -0
- data/lib/chef/shef/ext.rb +569 -0
- data/lib/chef/shef/model_wrapper.rb +120 -0
- data/lib/chef/shef/shef_rest.rb +28 -0
- data/lib/chef/shef/shef_session.rb +284 -0
- data/lib/chef/shell_out.rb +238 -0
- data/lib/chef/shell_out/unix.rb +223 -0
- data/lib/chef/shell_out/windows.rb +98 -0
- data/lib/chef/solr_query.rb +187 -0
- data/lib/chef/solr_query/lucene.treetop +150 -0
- data/lib/chef/solr_query/lucene_nodes.rb +285 -0
- data/lib/chef/solr_query/query_transform.rb +65 -0
- data/lib/chef/solr_query/solr_http_request.rb +118 -0
- data/lib/chef/streaming_cookbook_uploader.rb +201 -0
- data/lib/chef/tasks/chef_repo.rake +256 -0
- data/lib/chef/util/file_edit.rb +122 -0
- data/lib/chef/util/windows.rb +56 -0
- data/lib/chef/util/windows/net_group.rb +101 -0
- data/lib/chef/util/windows/net_use.rb +121 -0
- data/lib/chef/util/windows/net_user.rb +198 -0
- data/lib/chef/util/windows/volume.rb +59 -0
- data/lib/chef/version.rb +23 -0
- data/lib/chef/version_class.rb +70 -0
- data/lib/chef/version_constraint.rb +116 -0
- data/lib/chef/webui_user.rb +231 -0
- metadata +600 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
|
4
|
+
# License:: Apache License, Version 2.0
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require 'chef/config'
|
|
20
|
+
require 'uri'
|
|
21
|
+
require 'chef/rest'
|
|
22
|
+
require 'chef/node'
|
|
23
|
+
require 'chef/role'
|
|
24
|
+
require 'chef/data_bag'
|
|
25
|
+
require 'chef/data_bag_item'
|
|
26
|
+
|
|
27
|
+
class Chef
|
|
28
|
+
class Search
|
|
29
|
+
class Query
|
|
30
|
+
|
|
31
|
+
attr_accessor :rest
|
|
32
|
+
|
|
33
|
+
def initialize(url=nil)
|
|
34
|
+
@rest = Chef::REST.new(url ||Chef::Config[:search_url])
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Search Solr for objects of a given type, for a given query. If you give
|
|
38
|
+
# it a block, it will handle the paging for you dynamically.
|
|
39
|
+
def search(type, query="*:*", sort='X_CHEF_id_CHEF_X asc', start=0, rows=1000, &block)
|
|
40
|
+
raise ArgumentError, "Type must be a string or a symbol!" unless (type.kind_of?(String) || type.kind_of?(Symbol))
|
|
41
|
+
|
|
42
|
+
response = @rest.get_rest("search/#{type}?q=#{escape(query)}&sort=#{escape(sort)}&start=#{escape(start)}&rows=#{escape(rows)}")
|
|
43
|
+
if block
|
|
44
|
+
response["rows"].each { |o| block.call(o) unless o.nil?}
|
|
45
|
+
unless (response["start"] + response["rows"].length) >= response["total"]
|
|
46
|
+
nstart = response["start"] + rows
|
|
47
|
+
search(type, query, sort, nstart, rows, &block)
|
|
48
|
+
end
|
|
49
|
+
true
|
|
50
|
+
else
|
|
51
|
+
[ response["rows"], response["start"], response["total"] ]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def list_indexes
|
|
56
|
+
response = @rest.get_rest("search")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
def escape(s)
|
|
61
|
+
s && URI.escape(s.to_s)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/chef/shef.rb
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# Author:: Daniel DeLeo (<dan@kallistec.com>)
|
|
2
|
+
# Copyright:: Copyright (c) 2009 Daniel DeLeo
|
|
3
|
+
# License:: Apache License, Version 2.0
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
require 'singleton'
|
|
19
|
+
require 'pp'
|
|
20
|
+
require 'etc'
|
|
21
|
+
require 'mixlib/cli'
|
|
22
|
+
|
|
23
|
+
require 'chef/version'
|
|
24
|
+
require 'chef/client'
|
|
25
|
+
require 'chef/config'
|
|
26
|
+
|
|
27
|
+
require 'chef/shef/shef_session'
|
|
28
|
+
require 'chef/shef/ext'
|
|
29
|
+
require 'chef/json_compat'
|
|
30
|
+
|
|
31
|
+
# = Shef
|
|
32
|
+
# Shef is Chef in an IRB session. Shef can interact with a Chef server via the
|
|
33
|
+
# REST API, and run and debug recipes interactively.
|
|
34
|
+
module Shef
|
|
35
|
+
LEADERS = Hash.new("")
|
|
36
|
+
LEADERS[Chef::Recipe] = ":recipe"
|
|
37
|
+
LEADERS[Chef::Node] = ":attributes"
|
|
38
|
+
|
|
39
|
+
class << self
|
|
40
|
+
attr_accessor :client_type
|
|
41
|
+
attr_accessor :options
|
|
42
|
+
attr_accessor :env
|
|
43
|
+
attr_writer :editor
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Start the irb REPL with shef's customizations
|
|
47
|
+
def self.start
|
|
48
|
+
setup_logger
|
|
49
|
+
# FUGLY HACK: irb gives us no other choice.
|
|
50
|
+
irb_help = [:help, :irb_help, IRB::ExtendCommandBundle::NO_OVERRIDE]
|
|
51
|
+
IRB::ExtendCommandBundle.instance_variable_get(:@ALIASES).delete(irb_help)
|
|
52
|
+
|
|
53
|
+
parse_opts
|
|
54
|
+
|
|
55
|
+
# HACK: this duplicates the functions of IRB.start, but we have to do it
|
|
56
|
+
# to get access to the main object before irb starts.
|
|
57
|
+
::IRB.setup(nil)
|
|
58
|
+
|
|
59
|
+
irb = IRB::Irb.new
|
|
60
|
+
|
|
61
|
+
init(irb.context.main)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
irb_conf[:IRB_RC].call(irb.context) if irb_conf[:IRB_RC]
|
|
65
|
+
irb_conf[:MAIN_CONTEXT] = irb.context
|
|
66
|
+
|
|
67
|
+
trap("SIGINT") do
|
|
68
|
+
irb.signal_handle
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
catch(:IRB_EXIT) do
|
|
72
|
+
irb.eval_input
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.setup_logger
|
|
77
|
+
Chef::Config[:log_level] ||= :warn
|
|
78
|
+
Chef::Log.init(STDERR)
|
|
79
|
+
Mixlib::Authentication::Log.logger = Ohai::Log.logger = Chef::Log.logger
|
|
80
|
+
Chef::Log.level = Chef::Config[:log_level] || :warn
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Shef assumes it's running whenever it is defined
|
|
84
|
+
def self.running?
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Set the irb_conf object to something other than IRB.conf
|
|
89
|
+
# usful for testing.
|
|
90
|
+
def self.irb_conf=(conf_hash)
|
|
91
|
+
@irb_conf = conf_hash
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def self.irb_conf
|
|
95
|
+
@irb_conf || IRB.conf
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def self.configure_irb
|
|
99
|
+
irb_conf[:HISTORY_FILE] = "~/.shef_history"
|
|
100
|
+
irb_conf[:SAVE_HISTORY] = 1000
|
|
101
|
+
|
|
102
|
+
irb_conf[:IRB_RC] = lambda do |conf|
|
|
103
|
+
m = conf.main
|
|
104
|
+
|
|
105
|
+
conf.prompt_c = "chef#{leader(m)} > "
|
|
106
|
+
conf.return_format = " => %s \n"
|
|
107
|
+
conf.prompt_i = "chef#{leader(m)} > "
|
|
108
|
+
conf.prompt_n = "chef#{leader(m)} ?> "
|
|
109
|
+
conf.prompt_s = "chef#{leader(m)}%l> "
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def self.leader(main_object)
|
|
114
|
+
env_string = Shef.env ? " (#{Shef.env})" : ""
|
|
115
|
+
LEADERS[main_object.class] + env_string
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def self.session
|
|
119
|
+
unless client_type.instance.node_built?
|
|
120
|
+
puts "Session type: #{client_type.session_type}"
|
|
121
|
+
client_type.instance.reset!
|
|
122
|
+
end
|
|
123
|
+
client_type.instance
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.init(main)
|
|
127
|
+
parse_json
|
|
128
|
+
configure_irb
|
|
129
|
+
|
|
130
|
+
session # trigger ohai run + session load
|
|
131
|
+
|
|
132
|
+
session.node.consume_attributes(@json_attribs)
|
|
133
|
+
|
|
134
|
+
Extensions.extend_context_object(main)
|
|
135
|
+
|
|
136
|
+
main.version
|
|
137
|
+
puts
|
|
138
|
+
|
|
139
|
+
puts "run `help' for help, `exit' or ^D to quit."
|
|
140
|
+
puts
|
|
141
|
+
puts "Ohai2u#{greeting}!"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def self.greeting
|
|
145
|
+
" #{Etc.getlogin}@#{Shef.session.node.fqdn}"
|
|
146
|
+
rescue NameError
|
|
147
|
+
""
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def self.parse_json
|
|
151
|
+
# HACK: copied verbatim from chef/application/client, because it's not
|
|
152
|
+
# reusable as written there :(
|
|
153
|
+
if Chef::Config[:json_attribs]
|
|
154
|
+
begin
|
|
155
|
+
json_io = open(Chef::Config[:json_attribs])
|
|
156
|
+
rescue SocketError => error
|
|
157
|
+
fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2)
|
|
158
|
+
rescue Errno::ENOENT => error
|
|
159
|
+
fatal!("I cannot find #{Chef::Config[:json_attribs]}", 2)
|
|
160
|
+
rescue Errno::EACCES => error
|
|
161
|
+
fatal!("Permissions are incorrect on #{Chef::Config[:json_attribs]}. Please chmod a+r #{Chef::Config[:json_attribs]}", 2)
|
|
162
|
+
rescue Exception => error
|
|
163
|
+
fatal!("Got an unexpected error reading #{Chef::Config[:json_attribs]}: #{error.message}", 2)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
begin
|
|
167
|
+
@json_attribs = Chef::JSONCompat.from_json(json_io.read)
|
|
168
|
+
rescue JSON::ParserError => error
|
|
169
|
+
fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def self.fatal!(message, exit_status)
|
|
175
|
+
Chef::Log.fatal(message)
|
|
176
|
+
exit exit_status
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def self.client_type
|
|
180
|
+
type = Shef::StandAloneSession
|
|
181
|
+
type = Shef::SoloSession if Chef::Config[:shef_solo]
|
|
182
|
+
type = Shef::ClientSession if Chef::Config[:client]
|
|
183
|
+
type = Shef::DoppelGangerSession if Chef::Config[:doppelganger]
|
|
184
|
+
type
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def self.parse_opts
|
|
188
|
+
@options = Options.new
|
|
189
|
+
@options.parse_opts
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def self.editor
|
|
193
|
+
@editor || Chef::Config[:editor] || ENV['EDITOR']
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
class Options
|
|
197
|
+
include Mixlib::CLI
|
|
198
|
+
|
|
199
|
+
def self.footer(text=nil)
|
|
200
|
+
@footer = text if text
|
|
201
|
+
@footer
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
banner("shef #{Chef::VERSION}\n\nUsage: shef [NAMED_CONF] (OPTIONS)")
|
|
205
|
+
|
|
206
|
+
footer(<<-FOOTER)
|
|
207
|
+
When no CONFIG is specified, shef attempts to load a default configuration file:
|
|
208
|
+
* If a NAMED_CONF is given, shef will load ~/.chef/NAMED_CONF/shef.rb
|
|
209
|
+
* If no NAMED_CONF is given shef will load ~/.chef/shef.rb if it exists
|
|
210
|
+
* Shef falls back to loading /etc/chef/client.rb or /etc/chef/solo.rb if -z or
|
|
211
|
+
-s options are given and no shef.rb can be found.
|
|
212
|
+
FOOTER
|
|
213
|
+
|
|
214
|
+
option :config_file,
|
|
215
|
+
:short => "-c CONFIG",
|
|
216
|
+
:long => "--config CONFIG",
|
|
217
|
+
:description => "The configuration file to use"
|
|
218
|
+
|
|
219
|
+
option :help,
|
|
220
|
+
:short => "-h",
|
|
221
|
+
:long => "--help",
|
|
222
|
+
:description => "Show this message",
|
|
223
|
+
:on => :tail,
|
|
224
|
+
:boolean => true,
|
|
225
|
+
:proc => proc { print_help }
|
|
226
|
+
|
|
227
|
+
option :log_level,
|
|
228
|
+
:short => "-l LOG_LEVEL",
|
|
229
|
+
:long => '--log-level LOG_LEVEL',
|
|
230
|
+
:description => "Set the logging level",
|
|
231
|
+
:proc => proc { |level| Chef::Log.level = level.to_sym }
|
|
232
|
+
|
|
233
|
+
option :standalone,
|
|
234
|
+
:short => "-a",
|
|
235
|
+
:long => "--standalone",
|
|
236
|
+
:description => "standalone shef session",
|
|
237
|
+
:default => true,
|
|
238
|
+
:boolean => true
|
|
239
|
+
|
|
240
|
+
option :shef_solo,
|
|
241
|
+
:short => "-s",
|
|
242
|
+
:long => "--solo",
|
|
243
|
+
:description => "chef-solo shef session",
|
|
244
|
+
:boolean => true,
|
|
245
|
+
:proc => proc {Chef::Config[:solo] = true}
|
|
246
|
+
|
|
247
|
+
option :client,
|
|
248
|
+
:short => "-z",
|
|
249
|
+
:long => "--client",
|
|
250
|
+
:description => "chef-client shef session",
|
|
251
|
+
:boolean => true
|
|
252
|
+
|
|
253
|
+
option :json_attribs,
|
|
254
|
+
:short => "-j JSON_ATTRIBS",
|
|
255
|
+
:long => "--json-attributes JSON_ATTRIBS",
|
|
256
|
+
:description => "Load attributes from a JSON file or URL",
|
|
257
|
+
:proc => nil
|
|
258
|
+
|
|
259
|
+
option :chef_server_url,
|
|
260
|
+
:short => "-S CHEFSERVERURL",
|
|
261
|
+
:long => "--server CHEFSERVERURL",
|
|
262
|
+
:description => "The chef server URL",
|
|
263
|
+
:proc => nil
|
|
264
|
+
|
|
265
|
+
option :version,
|
|
266
|
+
:short => "-v",
|
|
267
|
+
:long => "--version",
|
|
268
|
+
:description => "Show chef version",
|
|
269
|
+
:boolean => true,
|
|
270
|
+
:proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"},
|
|
271
|
+
:exit => 0
|
|
272
|
+
|
|
273
|
+
def self.print_help
|
|
274
|
+
instance = new
|
|
275
|
+
instance.parse_options([])
|
|
276
|
+
puts instance.opt_parser
|
|
277
|
+
puts
|
|
278
|
+
puts footer
|
|
279
|
+
puts
|
|
280
|
+
exit 1
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def self.setup!
|
|
284
|
+
self.new.parse_opts
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def parse_opts
|
|
288
|
+
remainder = parse_options
|
|
289
|
+
environment = remainder.first
|
|
290
|
+
# We have to nuke ARGV to make sure irb's option parser never sees it.
|
|
291
|
+
# otherwise, IRB complains about command line switches it doesn't recognize.
|
|
292
|
+
ARGV.clear
|
|
293
|
+
config[:config_file] = config_file_for_shef_mode(environment)
|
|
294
|
+
config_msg = config[:config_file] || "none (standalone shef session)"
|
|
295
|
+
puts "loading configuration: #{config_msg}"
|
|
296
|
+
Chef::Config.from_file(config[:config_file]) if !config[:config_file].nil? && File.exists?(config[:config_file]) && File.readable?(config[:config_file])
|
|
297
|
+
Chef::Config.merge!(config)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
private
|
|
301
|
+
|
|
302
|
+
def config_file_for_shef_mode(environment)
|
|
303
|
+
if config[:config_file]
|
|
304
|
+
config[:config_file]
|
|
305
|
+
elsif environment
|
|
306
|
+
Shef.env = environment
|
|
307
|
+
config_file_to_try = ::File.join(ENV['HOME'], '.chef', environment, 'shef.rb')
|
|
308
|
+
unless ::File.exist?(config_file_to_try)
|
|
309
|
+
puts "could not find shef config for environment #{environment} at #{config_file_to_try}"
|
|
310
|
+
exit 1
|
|
311
|
+
end
|
|
312
|
+
config_file_to_try
|
|
313
|
+
elsif ENV['HOME'] && ::File.exist?(File.join(ENV['HOME'], '.chef', 'shef.rb'))
|
|
314
|
+
File.join(ENV['HOME'], '.chef', 'shef.rb')
|
|
315
|
+
elsif config[:solo]
|
|
316
|
+
"/etc/chef/solo.rb"
|
|
317
|
+
elsif config[:client]
|
|
318
|
+
"/etc/chef/client.rb"
|
|
319
|
+
else
|
|
320
|
+
nil
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
end
|
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Daniel DeLeo (<dan@kallistec.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2009 Daniel DeLeo
|
|
4
|
+
# License:: Apache License, Version 2.0
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require 'tempfile'
|
|
20
|
+
require 'chef/recipe'
|
|
21
|
+
require 'fileutils'
|
|
22
|
+
require 'chef/version'
|
|
23
|
+
require 'chef/shef/shef_session'
|
|
24
|
+
require 'chef/shef/model_wrapper'
|
|
25
|
+
require 'chef/shef/shef_rest'
|
|
26
|
+
require 'chef/json_compat'
|
|
27
|
+
|
|
28
|
+
module Shef
|
|
29
|
+
module Extensions
|
|
30
|
+
|
|
31
|
+
Help = Struct.new(:cmd, :desc, :explanation)
|
|
32
|
+
|
|
33
|
+
# Extensions to be included in every 'main' object in shef. These objects
|
|
34
|
+
# are extended with this module.
|
|
35
|
+
module ObjectCoreExtensions
|
|
36
|
+
|
|
37
|
+
def ensure_session_select_defined
|
|
38
|
+
# irb breaks if you prematurely define IRB::JobMangager
|
|
39
|
+
# so these methods need to be defined at the latest possible time.
|
|
40
|
+
unless jobs.respond_to?(:select_session_by_context)
|
|
41
|
+
def jobs.select_session_by_context(&block)
|
|
42
|
+
@jobs.select { |job| block.call(job[1].context.main)}
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
unless jobs.respond_to?(:session_select)
|
|
47
|
+
def jobs.select_shef_session(target_context)
|
|
48
|
+
session = if target_context.kind_of?(Class)
|
|
49
|
+
select_session_by_context { |main| main.kind_of?(target_context) }
|
|
50
|
+
else
|
|
51
|
+
select_session_by_context { |main| main.equal?(target_context) }
|
|
52
|
+
end
|
|
53
|
+
Array(session.first)[1]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def find_or_create_session_for(context_obj)
|
|
59
|
+
ensure_session_select_defined
|
|
60
|
+
if subsession = jobs.select_shef_session(context_obj)
|
|
61
|
+
jobs.switch(subsession)
|
|
62
|
+
else
|
|
63
|
+
irb(context_obj)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def help_banner
|
|
68
|
+
banner = []
|
|
69
|
+
banner << ""
|
|
70
|
+
banner << "Shef Help"
|
|
71
|
+
banner << "".ljust(80, "=")
|
|
72
|
+
banner << "| " + "Command".ljust(25) + "| " + "Description"
|
|
73
|
+
banner << "".ljust(80, "=")
|
|
74
|
+
|
|
75
|
+
self.all_help_descriptions.each do |help_text|
|
|
76
|
+
banner << "| " + help_text.cmd.ljust(25) + "| " + help_text.desc
|
|
77
|
+
end
|
|
78
|
+
banner << "".ljust(80, "=")
|
|
79
|
+
banner << "\n"
|
|
80
|
+
banner << "Use help(:command) to get detailed help with individual commands"
|
|
81
|
+
banner << "\n"
|
|
82
|
+
banner.join("\n")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def explain_command(method_name)
|
|
86
|
+
help = self.all_help_descriptions.find { |h| h.cmd.to_s == method_name.to_s }
|
|
87
|
+
if help
|
|
88
|
+
puts ""
|
|
89
|
+
puts "Command: #{method_name}"
|
|
90
|
+
puts "".ljust(80, "=")
|
|
91
|
+
puts help.explanation || help.desc
|
|
92
|
+
puts "".ljust(80, "=")
|
|
93
|
+
puts ""
|
|
94
|
+
else
|
|
95
|
+
puts ""
|
|
96
|
+
puts "command #{method_name} not found or no help available"
|
|
97
|
+
puts ""
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# helpfully returns +:on+ so we can have sugary syntax like `tracing on'
|
|
102
|
+
def on
|
|
103
|
+
:on
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# returns +:off+ so you can just do `tracing off'
|
|
107
|
+
def off
|
|
108
|
+
:off
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def help_descriptions
|
|
112
|
+
@help_descriptions ||= []
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def all_help_descriptions
|
|
116
|
+
help_descriptions
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def desc(help_text)
|
|
120
|
+
@desc = help_text
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def explain(explain_text)
|
|
124
|
+
@explain = explain_text
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def subcommands(subcommand_help={})
|
|
128
|
+
@subcommand_help = subcommand_help
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def singleton_method_added(mname)
|
|
132
|
+
if @desc
|
|
133
|
+
help_descriptions << Help.new(mname.to_s, @desc.to_s, @explain)
|
|
134
|
+
@desc, @explain = nil, nil
|
|
135
|
+
end
|
|
136
|
+
if @subcommand_help
|
|
137
|
+
@subcommand_help.each do |subcommand, text|
|
|
138
|
+
help_descriptions << Help.new("#{mname}.#{subcommand}", text.to_s, nil)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
@subcommand_help = {}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
module String
|
|
147
|
+
def on_off_to_bool
|
|
148
|
+
case self
|
|
149
|
+
when "on"
|
|
150
|
+
true
|
|
151
|
+
when "off"
|
|
152
|
+
false
|
|
153
|
+
else
|
|
154
|
+
self
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
module Symbol
|
|
160
|
+
def on_off_to_bool
|
|
161
|
+
self.to_s.on_off_to_bool
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
module TrueClass
|
|
166
|
+
def to_on_off_str
|
|
167
|
+
"on"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def on_off_to_bool
|
|
171
|
+
self
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
module FalseClass
|
|
176
|
+
def to_on_off_str
|
|
177
|
+
"off"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def on_off_to_bool
|
|
181
|
+
self
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Methods that have associated help text need to be dynamically added
|
|
186
|
+
# to the main irb objects, so we define them in a proc and later
|
|
187
|
+
# instance_eval the proc in the object.
|
|
188
|
+
ObjectUIExtensions = Proc.new do
|
|
189
|
+
extend Shef::Extensions::ObjectCoreExtensions
|
|
190
|
+
|
|
191
|
+
desc "prints this help message"
|
|
192
|
+
explain(<<-E)
|
|
193
|
+
## SUMMARY ##
|
|
194
|
+
When called with no argument, +help+ prints a table of all shef commands. When
|
|
195
|
+
called with an argument COMMAND, +help+ prints a detailed explanation of the
|
|
196
|
+
command if available, or the description if no explanation is available.
|
|
197
|
+
E
|
|
198
|
+
def help(commmand=nil)
|
|
199
|
+
if commmand
|
|
200
|
+
explain_command(commmand)
|
|
201
|
+
else
|
|
202
|
+
puts help_banner
|
|
203
|
+
end
|
|
204
|
+
:ucanhaz_halp
|
|
205
|
+
end
|
|
206
|
+
alias :halp :help
|
|
207
|
+
|
|
208
|
+
desc "prints information about chef"
|
|
209
|
+
def version
|
|
210
|
+
puts "This is shef, the Chef shell.\n" +
|
|
211
|
+
" Chef Version: #{::Chef::VERSION}\n" +
|
|
212
|
+
" http://www.opscode.com/chef\n" +
|
|
213
|
+
" http://wiki.opscode.com/display/chef/Home"
|
|
214
|
+
:ucanhaz_automation
|
|
215
|
+
end
|
|
216
|
+
alias :shef :version
|
|
217
|
+
|
|
218
|
+
desc "switch to recipe mode"
|
|
219
|
+
def recipe
|
|
220
|
+
find_or_create_session_for Shef.session.recipe
|
|
221
|
+
:recipe
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
desc "switch to attributes mode"
|
|
225
|
+
def attributes
|
|
226
|
+
find_or_create_session_for Shef.session.node
|
|
227
|
+
:attributes
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
desc "run chef using the current recipe"
|
|
231
|
+
def run_chef
|
|
232
|
+
Chef::Log.level = :debug
|
|
233
|
+
session = Shef.session
|
|
234
|
+
runrun = Chef::Runner.new(session.run_context).converge
|
|
235
|
+
Chef::Log.level = :info
|
|
236
|
+
runrun
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
desc "returns an object to control a paused chef run"
|
|
240
|
+
subcommands :resume => "resume the chef run",
|
|
241
|
+
:step => "run only the next resource",
|
|
242
|
+
:skip_back => "move back in the run list",
|
|
243
|
+
:skip_forward => "move forward in the run list"
|
|
244
|
+
def chef_run
|
|
245
|
+
Shef.session.resource_collection.iterator
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
desc "resets the current recipe"
|
|
249
|
+
def reset
|
|
250
|
+
Shef.session.reset!
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
desc "assume the identity of another node."
|
|
254
|
+
def become_node(node_name)
|
|
255
|
+
Shef::DoppelGangerSession.instance.assume_identity(node_name)
|
|
256
|
+
:doppelganger
|
|
257
|
+
end
|
|
258
|
+
alias :doppelganger :become_node
|
|
259
|
+
|
|
260
|
+
desc "turns printout of return values on or off"
|
|
261
|
+
def echo(on_or_off)
|
|
262
|
+
conf.echo = on_or_off.on_off_to_bool
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
desc "says if echo is on or off"
|
|
266
|
+
def echo?
|
|
267
|
+
puts "echo is #{conf.echo.to_on_off_str}"
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
desc "turns on or off tracing of execution. *verbose*"
|
|
271
|
+
def tracing(on_or_off)
|
|
272
|
+
conf.use_tracer = on_or_off.on_off_to_bool
|
|
273
|
+
tracing?
|
|
274
|
+
end
|
|
275
|
+
alias :trace :tracing
|
|
276
|
+
|
|
277
|
+
desc "says if tracing is on or off"
|
|
278
|
+
def tracing?
|
|
279
|
+
puts "tracing is #{conf.use_tracer.to_on_off_str}"
|
|
280
|
+
end
|
|
281
|
+
alias :trace? :tracing?
|
|
282
|
+
|
|
283
|
+
desc "simple ls style command"
|
|
284
|
+
def ls(directory)
|
|
285
|
+
Dir.entries(directory)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
MainContextExtensions = Proc.new do
|
|
290
|
+
desc "returns the current node (i.e., this host)"
|
|
291
|
+
def node
|
|
292
|
+
Shef.session.node
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
desc "pretty print the node's attributes"
|
|
296
|
+
def ohai(key=nil)
|
|
297
|
+
pp(key ? node.attribute[key] : node.attribute)
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
RESTApiExtensions = Proc.new do
|
|
302
|
+
desc "edit an object in your EDITOR"
|
|
303
|
+
explain(<<-E)
|
|
304
|
+
## SUMMARY ##
|
|
305
|
+
+edit(object)+ allows you to edit any object that can be converted to JSON.
|
|
306
|
+
When finished editing, this method will return the edited object:
|
|
307
|
+
|
|
308
|
+
new_node = edit(existing_node)
|
|
309
|
+
|
|
310
|
+
## EDITOR SELECTION ##
|
|
311
|
+
Shef looks for an editor using the following logic
|
|
312
|
+
1. Looks for an EDITOR set by Shef.editor = "EDITOR"
|
|
313
|
+
2. Looks for an EDITOR configured in your shef config file
|
|
314
|
+
3. Uses the value of the EDITOR environment variable
|
|
315
|
+
E
|
|
316
|
+
def edit(object)
|
|
317
|
+
unless Shef.editor
|
|
318
|
+
puts "Please set your editor with Shef.editor = \"vim|emacs|mate|ed\""
|
|
319
|
+
return :failburger
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
filename = "shef-edit-#{object.class.name}-"
|
|
323
|
+
if object.respond_to?(:name)
|
|
324
|
+
filename += object.name
|
|
325
|
+
elsif object.respond_to?(:id)
|
|
326
|
+
filename += object.id
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
edited_data = Tempfile.open([filename, ".js"]) do |tempfile|
|
|
330
|
+
tempfile.sync = true
|
|
331
|
+
tempfile.puts Chef::JSONCompat.to_json(object)
|
|
332
|
+
system("#{Shef.editor.to_s} #{tempfile.path}")
|
|
333
|
+
tempfile.rewind
|
|
334
|
+
tempfile.read
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
Chef::JSONCompat.from_json(edited_data)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
desc "Find and edit API clients"
|
|
341
|
+
explain(<<-E)
|
|
342
|
+
## SUMMARY ##
|
|
343
|
+
+clients+ allows you to query you chef server for information about your api
|
|
344
|
+
clients.
|
|
345
|
+
|
|
346
|
+
## LIST ALL CLIENTS ##
|
|
347
|
+
To see all clients on the system, use
|
|
348
|
+
|
|
349
|
+
clients.all #=> [<Chef::ApiClient...>, ...]
|
|
350
|
+
|
|
351
|
+
If the output from all is too verbose, or you're only interested in a specific
|
|
352
|
+
value from each of the objects, you can give a code block to +all+:
|
|
353
|
+
|
|
354
|
+
clients.all { |client| client.name } #=> [CLIENT1_NAME, CLIENT2_NAME, ...]
|
|
355
|
+
|
|
356
|
+
## SHOW ONE CLIENT ##
|
|
357
|
+
To see a specific client, use
|
|
358
|
+
|
|
359
|
+
clients.show(CLIENT_NAME)
|
|
360
|
+
|
|
361
|
+
## SEARCH FOR CLIENTS ##
|
|
362
|
+
You can also search for clients using +find+ or +search+. You can use the
|
|
363
|
+
familiar string search syntax:
|
|
364
|
+
|
|
365
|
+
clients.search("KEY:VALUE")
|
|
366
|
+
|
|
367
|
+
Just as the +all+ subcommand, the +search+ subcommand can use a code block to
|
|
368
|
+
filter or transform the information returned from the search:
|
|
369
|
+
|
|
370
|
+
clients.search("KEY:VALUE") { |c| c.name }
|
|
371
|
+
|
|
372
|
+
You can also use a Hash based syntax, multiple search conditions will be
|
|
373
|
+
joined with AND.
|
|
374
|
+
|
|
375
|
+
clients.find :KEY => :VALUE, :KEY2 => :VALUE2, ...
|
|
376
|
+
|
|
377
|
+
## BULK-EDIT CLIENTS ##
|
|
378
|
+
**BE CAREFUL, THIS IS DESTRUCTIVE**
|
|
379
|
+
You can bulk edit API Clients using the +transform+ subcommand, which requires
|
|
380
|
+
a code block. Each client will be saved after the code block is run. If the
|
|
381
|
+
code block returns +nil+ or +false+, that client will be skipped:
|
|
382
|
+
|
|
383
|
+
clients.transform("*:*") do |client|
|
|
384
|
+
if client.name =~ /borat/i
|
|
385
|
+
client.admin(false)
|
|
386
|
+
true
|
|
387
|
+
else
|
|
388
|
+
nil
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
This will strip the admin privileges from any client named after borat.
|
|
393
|
+
E
|
|
394
|
+
subcommands :all => "list all api clients",
|
|
395
|
+
:show => "load an api client by name",
|
|
396
|
+
:search => "search for API clients",
|
|
397
|
+
:transform => "edit all api clients via a code block and save them"
|
|
398
|
+
def clients
|
|
399
|
+
@clients ||= Shef::ModelWrapper.new(Chef::ApiClient, :client)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
desc "Find and edit cookbooks"
|
|
403
|
+
subcommands :all => "list all cookbooks",
|
|
404
|
+
:show => "load a cookbook by name",
|
|
405
|
+
:transform => "edit all cookbooks via a code block and save them"
|
|
406
|
+
def cookbooks
|
|
407
|
+
@cookbooks ||= Shef::ModelWrapper.new(Chef::CookbookVersion)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
desc "Find and edit nodes via the API"
|
|
411
|
+
explain(<<-E)
|
|
412
|
+
## SUMMARY ##
|
|
413
|
+
+nodes+ Allows you to query your chef server for information about your nodes.
|
|
414
|
+
|
|
415
|
+
## LIST ALL NODES ##
|
|
416
|
+
You can list all nodes using +all+ or +list+
|
|
417
|
+
|
|
418
|
+
nodes.all #=> [<Chef::Node...>, <Chef::Node...>, ...]
|
|
419
|
+
|
|
420
|
+
To limit the information returned for each node, pass a code block to the +all+
|
|
421
|
+
subcommand:
|
|
422
|
+
|
|
423
|
+
nodes.all { |node| node.name } #=> [NODE1_NAME, NODE2_NAME, ...]
|
|
424
|
+
|
|
425
|
+
## SHOW ONE NODE ##
|
|
426
|
+
You can show the data for a single node using the +show+ subcommand:
|
|
427
|
+
|
|
428
|
+
nodes.show("NODE_NAME") => <Chef::Node @name="NODE_NAME" ...>
|
|
429
|
+
|
|
430
|
+
## SEARCH FOR NODES ##
|
|
431
|
+
You can search for nodes using the +search+ or +find+ subcommands:
|
|
432
|
+
|
|
433
|
+
nodes.find(:name => "app*") #=> [<Chef::Node @name="app1.example.com" ...>, ...]
|
|
434
|
+
|
|
435
|
+
Similarly to +all+, you can pass a code block to limit or transform the
|
|
436
|
+
information returned:
|
|
437
|
+
|
|
438
|
+
nodes.find(:name => "app#") { |node| node.ec2 }
|
|
439
|
+
|
|
440
|
+
## BULK EDIT NODES ##
|
|
441
|
+
**BE CAREFUL, THIS OPERATION IS DESTRUCTIVE**
|
|
442
|
+
|
|
443
|
+
Bulk edit nodes by passing a code block to the +transform+ or +bulk_edit+
|
|
444
|
+
subcommand. The block will be applied to each matching node, and then the node
|
|
445
|
+
will be saved. If the block returns +nil+ or +false+, that node will be
|
|
446
|
+
skipped.
|
|
447
|
+
|
|
448
|
+
nodes.transform do |node|
|
|
449
|
+
if node.fqdn =~ /.*\\.preprod\\.example\\.com/
|
|
450
|
+
node.set[:environment] = "preprod"
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
This will assign the attribute to every node with a FQDN matching the regex.
|
|
455
|
+
E
|
|
456
|
+
subcommands :all => "list all nodes",
|
|
457
|
+
:show => "load a node by name",
|
|
458
|
+
:search => "search for nodes",
|
|
459
|
+
:transform => "edit all nodes via a code block and save them"
|
|
460
|
+
def nodes
|
|
461
|
+
@nodes ||= Shef::ModelWrapper.new(Chef::Node)
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
desc "Find and edit roles via the API"
|
|
465
|
+
explain(<<-E)
|
|
466
|
+
## SUMMARY ##
|
|
467
|
+
+roles+ allows you to query and edit roles on your Chef server.
|
|
468
|
+
|
|
469
|
+
## SUBCOMMANDS ##
|
|
470
|
+
* all (list)
|
|
471
|
+
* show (load)
|
|
472
|
+
* search (find)
|
|
473
|
+
* transform (bulk_edit)
|
|
474
|
+
|
|
475
|
+
## SEE ALSO ##
|
|
476
|
+
See the help for +nodes+ for more information about the subcommands.
|
|
477
|
+
E
|
|
478
|
+
subcommands :all => "list all roles",
|
|
479
|
+
:show => "load a role by name",
|
|
480
|
+
:search => "search for roles",
|
|
481
|
+
:transform => "edit all roles via a code block and save them"
|
|
482
|
+
def roles
|
|
483
|
+
@roles ||= Shef::ModelWrapper.new(Chef::Role)
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
desc "Find and edit +databag_name+ via the api"
|
|
487
|
+
explain(<<-E)
|
|
488
|
+
## SUMMARY ##
|
|
489
|
+
+databags(DATABAG_NAME)+ allows you to query and edit data bag items on your
|
|
490
|
+
Chef server. Unlike other commands for working with data on the server,
|
|
491
|
+
+databags+ requires the databag name as an argument, for example:
|
|
492
|
+
databags(:users).all
|
|
493
|
+
|
|
494
|
+
## SUBCOMMANDS ##
|
|
495
|
+
* all (list)
|
|
496
|
+
* show (load)
|
|
497
|
+
* search (find)
|
|
498
|
+
* transform (bulk_edit)
|
|
499
|
+
|
|
500
|
+
## SEE ALSO ##
|
|
501
|
+
See the help for +nodes+ for more information about the subcommands.
|
|
502
|
+
|
|
503
|
+
E
|
|
504
|
+
subcommands :all => "list all items in the data bag",
|
|
505
|
+
:show => "load a data bag item by id",
|
|
506
|
+
:search => "search for items in the data bag",
|
|
507
|
+
:transform => "edit all items via a code block and save them"
|
|
508
|
+
def databags(databag_name)
|
|
509
|
+
@named_databags_wrappers ||= {}
|
|
510
|
+
@named_databags_wrappers[databag_name] ||= Shef::NamedDataBagWrapper.new(databag_name)
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
desc "A REST Client configured to authenticate with the API"
|
|
514
|
+
def api
|
|
515
|
+
@rest = Shef::ShefREST.new(Chef::Config[:chef_server_url])
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
RecipeUIExtensions = Proc.new do
|
|
521
|
+
alias :original_resources :resources
|
|
522
|
+
|
|
523
|
+
desc "list all the resources on the current recipe"
|
|
524
|
+
def resources(*args)
|
|
525
|
+
if args.empty?
|
|
526
|
+
pp run_context.resource_collection.instance_variable_get(:@resources_by_name).keys
|
|
527
|
+
else
|
|
528
|
+
pp resources = original_resources(*args)
|
|
529
|
+
resources
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
def self.extend_context_object(obj)
|
|
535
|
+
obj.instance_eval(&ObjectUIExtensions)
|
|
536
|
+
obj.instance_eval(&MainContextExtensions)
|
|
537
|
+
obj.instance_eval(&RESTApiExtensions)
|
|
538
|
+
obj.extend(FileUtils)
|
|
539
|
+
obj.extend(Chef::Mixin::Language)
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
def self.extend_context_node(node_obj)
|
|
543
|
+
node_obj.instance_eval(&ObjectUIExtensions)
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
def self.extend_context_recipe(recipe_obj)
|
|
547
|
+
recipe_obj.instance_eval(&ObjectUIExtensions)
|
|
548
|
+
recipe_obj.instance_eval(&RecipeUIExtensions)
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
class String
|
|
555
|
+
include Shef::Extensions::String
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
class Symbol
|
|
559
|
+
include Shef::Extensions::Symbol
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
class TrueClass
|
|
563
|
+
include Shef::Extensions::TrueClass
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
class FalseClass
|
|
567
|
+
include Shef::Extensions::FalseClass
|
|
568
|
+
end
|
|
569
|
+
|