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,87 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Tim Hinderliter (<tim@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2010 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/cookbook/file_vendor'
|
|
20
|
+
|
|
21
|
+
class Chef
|
|
22
|
+
class Cookbook
|
|
23
|
+
# == Chef::Cookbook::RemoteFileVendor
|
|
24
|
+
# This FileVendor loads files by either fetching them from the local cache, or
|
|
25
|
+
# if not available, loading them from the remote server.
|
|
26
|
+
class RemoteFileVendor < FileVendor
|
|
27
|
+
|
|
28
|
+
def initialize(manifest, rest)
|
|
29
|
+
@manifest = manifest
|
|
30
|
+
@cookbook_name = @manifest[:cookbook_name]
|
|
31
|
+
@rest = rest
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Implements abstract base's requirement. It looks in the
|
|
35
|
+
# Chef::Config.cookbook_path file hierarchy for the requested
|
|
36
|
+
# file.
|
|
37
|
+
def get_filename(filename)
|
|
38
|
+
if filename =~ /([^\/]+)\/(.+)$/
|
|
39
|
+
segment = $1
|
|
40
|
+
else
|
|
41
|
+
raise "get_filename: Cannot determine segment/filename for incoming filename #{filename}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
raise "No such segment #{segment} in cookbook #{@cookbook_name}" unless @manifest[segment]
|
|
45
|
+
found_manifest_record = @manifest[segment].find {|manifest_record| manifest_record[:path] == filename }
|
|
46
|
+
raise "No such file #{filename} in #{@cookbook_name}" unless found_manifest_record
|
|
47
|
+
|
|
48
|
+
cache_filename = File.join("cookbooks", @cookbook_name, found_manifest_record['path'])
|
|
49
|
+
|
|
50
|
+
# update valid_cache_entries so the upstream cache cleaner knows what
|
|
51
|
+
# we've used.
|
|
52
|
+
validate_cached_copy(cache_filename)
|
|
53
|
+
|
|
54
|
+
current_checksum = nil
|
|
55
|
+
if Chef::FileCache.has_key?(cache_filename)
|
|
56
|
+
current_checksum = Chef::CookbookVersion.checksum_cookbook_file(Chef::FileCache.load(cache_filename, false))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# If the checksums are different between on-disk (current) and on-server
|
|
60
|
+
# (remote, per manifest), do the update. This will also execute if there
|
|
61
|
+
# is no current checksum.
|
|
62
|
+
if current_checksum != found_manifest_record['checksum']
|
|
63
|
+
raw_file = @rest.get_rest(found_manifest_record[:url], true)
|
|
64
|
+
|
|
65
|
+
Chef::Log.info("Storing updated #{cache_filename} in the cache.")
|
|
66
|
+
Chef::FileCache.move_to(raw_file.path, cache_filename)
|
|
67
|
+
else
|
|
68
|
+
Chef::Log.debug("Not storing #{cache_filename}, as the cache is up to date.")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
full_path_cache_filename = Chef::FileCache.load(cache_filename, false)
|
|
72
|
+
|
|
73
|
+
# return the filename, not the contents (second argument= false)
|
|
74
|
+
full_path_cache_filename
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def validate_cached_copy(cache_filename)
|
|
78
|
+
valid_cache_entries[cache_filename] = true
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def valid_cache_entries
|
|
82
|
+
Chef::CookbookVersion.valid_cache_entries
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Daniel DeLeo (<dan@opscode.com>)
|
|
3
|
+
# Copyright:: Copyright (c) 2010 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/checksum_cache'
|
|
20
|
+
require 'chef/mixin/shell_out'
|
|
21
|
+
|
|
22
|
+
class Chef
|
|
23
|
+
class Cookbook
|
|
24
|
+
# == Chef::Cookbook::SyntaxCheck
|
|
25
|
+
# Encapsulates the process of validating the ruby syntax of files in Chef
|
|
26
|
+
# cookbooks.
|
|
27
|
+
class SyntaxCheck
|
|
28
|
+
include Chef::Mixin::ShellOut
|
|
29
|
+
|
|
30
|
+
attr_reader :cookbook_path
|
|
31
|
+
|
|
32
|
+
# Creates a new SyntaxCheck given the +cookbook_name+ and a +cookbook_path+.
|
|
33
|
+
# If no +cookbook_path+ is given, +Chef::Config.cookbook_path+ is used.
|
|
34
|
+
def self.for_cookbook(cookbook_name, cookbook_path=nil)
|
|
35
|
+
cookbook_path ||= Chef::Config.cookbook_path
|
|
36
|
+
unless cookbook_path
|
|
37
|
+
raise ArgumentError, "Cannot find cookbook #{cookbook_name} unless Chef::Config.cookbook_path is set or an explicit cookbook path is given"
|
|
38
|
+
end
|
|
39
|
+
new(File.join(cookbook_path, cookbook_name.to_s))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Create a new SyntaxCheck object
|
|
43
|
+
# === Arguments
|
|
44
|
+
# cookbook_path::: the (on disk) path to the cookbook
|
|
45
|
+
def initialize(cookbook_path)
|
|
46
|
+
@cookbook_path = cookbook_path
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def cache
|
|
50
|
+
Chef::ChecksumCache.instance
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def ruby_files
|
|
54
|
+
Dir[File.join(cookbook_path, '**', '*.rb')]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def untested_ruby_files
|
|
58
|
+
ruby_files.reject do |file|
|
|
59
|
+
if validated?(file)
|
|
60
|
+
Chef::Log.debug("ruby file #{file} is unchanged, skipping syntax check")
|
|
61
|
+
true
|
|
62
|
+
else
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def template_files
|
|
69
|
+
Dir[File.join(cookbook_path, '**', '*.erb')]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def untested_template_files
|
|
73
|
+
template_files.reject do |file|
|
|
74
|
+
if validated?(file)
|
|
75
|
+
Chef::Log.debug("template #{file} is unchanged, skipping syntax check")
|
|
76
|
+
true
|
|
77
|
+
else
|
|
78
|
+
false
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def validated?(file)
|
|
84
|
+
!!cache.lookup_checksum(cache_key(file), File.stat(file))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def validated(file)
|
|
88
|
+
cache.generate_checksum(cache_key(file), file, File.stat(file))
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def cache_key(file)
|
|
92
|
+
@cache_keys ||= {}
|
|
93
|
+
@cache_keys[file] ||= cache.generate_key(file, "chef-test")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def validate_ruby_files
|
|
97
|
+
untested_ruby_files.each do |ruby_file|
|
|
98
|
+
return false unless validate_ruby_file(ruby_file)
|
|
99
|
+
validated(ruby_file)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def validate_templates
|
|
104
|
+
untested_template_files.each do |template|
|
|
105
|
+
return false unless validate_template(template)
|
|
106
|
+
validated(template)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def validate_template(erb_file)
|
|
111
|
+
Chef::Log.debug("Testing template #{erb_file} for syntax errors...")
|
|
112
|
+
result = shell_out("sh -c 'erubis -x #{erb_file} | ruby -c'")
|
|
113
|
+
result.error!
|
|
114
|
+
true
|
|
115
|
+
rescue Chef::Exceptions::ShellCommandFailed
|
|
116
|
+
file_relative_path = erb_file[/^#{Regexp.escape(cookbook_path+File::Separator)}(.*)/, 1]
|
|
117
|
+
Chef::Log.fatal("Erb template #{file_relative_path} has a syntax error:")
|
|
118
|
+
result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) }
|
|
119
|
+
false
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def validate_ruby_file(ruby_file)
|
|
123
|
+
Chef::Log.debug("Testing #{ruby_file} for syntax errors...")
|
|
124
|
+
result = shell_out("ruby -c #{ruby_file}")
|
|
125
|
+
result.error!
|
|
126
|
+
true
|
|
127
|
+
rescue Chef::Exceptions::ShellCommandFailed
|
|
128
|
+
file_relative_path = ruby_file[/^#{Regexp.escape(cookbook_path+File::Separator)}(.*)/, 1]
|
|
129
|
+
Chef::Log.fatal("Cookbook file #{file_relative_path} has a ruby syntax error:")
|
|
130
|
+
result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) }
|
|
131
|
+
false
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
|
4
|
+
# Author:: Daniel DeLeo (<dan@kallistec.com>)
|
|
5
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
|
6
|
+
# Copyright:: Copyright (c) 2009 Daniel DeLeo
|
|
7
|
+
# License:: Apache License, Version 2.0
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
|
|
21
|
+
require 'chef/config'
|
|
22
|
+
require 'chef/exceptions'
|
|
23
|
+
require 'chef/cookbook/cookbook_version_loader'
|
|
24
|
+
require 'chef/cookbook_version'
|
|
25
|
+
require 'chef/cookbook/chefignore'
|
|
26
|
+
require 'chef/cookbook/metadata'
|
|
27
|
+
|
|
28
|
+
class Chef
|
|
29
|
+
class CookbookLoader
|
|
30
|
+
|
|
31
|
+
attr_accessor :metadata
|
|
32
|
+
attr_reader :cookbooks_by_name
|
|
33
|
+
|
|
34
|
+
include Enumerable
|
|
35
|
+
|
|
36
|
+
def initialize(*repo_paths)
|
|
37
|
+
@repo_paths = repo_paths.flatten
|
|
38
|
+
raise ArgumentError, "You must specify at least one cookbook repo path" if @repo_paths.empty?
|
|
39
|
+
@cookbooks_by_name = Mash.new
|
|
40
|
+
@loaded_cookbooks = {}
|
|
41
|
+
@metadata = Mash.new
|
|
42
|
+
load_cookbooks
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def load_cookbooks
|
|
46
|
+
cookbook_settings = Hash.new
|
|
47
|
+
@repo_paths.each do |repo_path|
|
|
48
|
+
repo_path = File.expand_path(repo_path)
|
|
49
|
+
chefignore = Cookbook::Chefignore.new(repo_path)
|
|
50
|
+
Dir[File.join(repo_path, "*")].each do |cookbook_path|
|
|
51
|
+
next unless File.directory?(cookbook_path)
|
|
52
|
+
loader = Cookbook::CookbookVersionLoader.new(cookbook_path, chefignore)
|
|
53
|
+
loader.load_cookbooks
|
|
54
|
+
next if loader.empty?
|
|
55
|
+
if @loaded_cookbooks.key?(loader.cookbook_name)
|
|
56
|
+
@loaded_cookbooks[loader.cookbook_name].merge!(loader)
|
|
57
|
+
else
|
|
58
|
+
@loaded_cookbooks[loader.cookbook_name] = loader
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
@loaded_cookbooks.each do |cookbook, loader|
|
|
64
|
+
cookbook_version = loader.cookbook_version
|
|
65
|
+
@cookbooks_by_name[cookbook] = cookbook_version
|
|
66
|
+
@metadata[cookbook] = cookbook_version.metadata
|
|
67
|
+
end
|
|
68
|
+
@cookbooks_by_name
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def [](cookbook)
|
|
72
|
+
if @cookbooks_by_name.has_key?(cookbook.to_sym)
|
|
73
|
+
@cookbooks_by_name[cookbook.to_sym]
|
|
74
|
+
else
|
|
75
|
+
raise Exceptions::CookbookNotFoundInRepo, "Cannot find a cookbook named #{cookbook.to_s}; did you forget to add metadata to a cookbook? (http://wiki.opscode.com/display/chef/Metadata)"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
alias :fetch :[]
|
|
80
|
+
|
|
81
|
+
def has_key?(cookbook_name)
|
|
82
|
+
@cookbooks_by_name.has_key?(cookbook_name)
|
|
83
|
+
end
|
|
84
|
+
alias :cookbook_exists? :has_key?
|
|
85
|
+
alias :key? :has_key?
|
|
86
|
+
|
|
87
|
+
def each
|
|
88
|
+
@cookbooks_by_name.keys.sort { |a,b| a.to_s <=> b.to_s }.each do |cname|
|
|
89
|
+
yield(cname, @cookbooks_by_name[cname])
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def cookbook_names
|
|
94
|
+
@cookbooks_by_name.keys.sort
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def values
|
|
98
|
+
@cookbooks_by_name.values
|
|
99
|
+
end
|
|
100
|
+
alias :cookbooks :values
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Stanislav Vitvitskiy
|
|
3
|
+
# Author:: Nuo Yan (nuo@opscode.com)
|
|
4
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
|
5
|
+
# Copyright:: Copyright (c) 2009, 2010 Opscode, Inc.
|
|
6
|
+
# License:: Apache License, Version 2.0
|
|
7
|
+
#
|
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
# See the License for the specific language governing permissions and
|
|
18
|
+
# limitations under the License.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'net/http'
|
|
22
|
+
require 'mixlib/authentication/signedheaderauth'
|
|
23
|
+
require 'openssl'
|
|
24
|
+
|
|
25
|
+
class Chef
|
|
26
|
+
# == Chef::CookbookSiteStreamingUploader
|
|
27
|
+
# A streaming multipart HTTP upload implementation. Used to upload cookbooks
|
|
28
|
+
# (in tarball form) to http://cookbooks.opscode.com
|
|
29
|
+
#
|
|
30
|
+
# inspired by http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html
|
|
31
|
+
class CookbookSiteStreamingUploader
|
|
32
|
+
|
|
33
|
+
DefaultHeaders = { 'accept' => 'application/json', 'x-chef-version' => ::Chef::VERSION }
|
|
34
|
+
|
|
35
|
+
class << self
|
|
36
|
+
|
|
37
|
+
def create_build_dir(cookbook)
|
|
38
|
+
tmp_cookbook_path = Tempfile.new("chef-#{cookbook.name}-build")
|
|
39
|
+
tmp_cookbook_path.close
|
|
40
|
+
tmp_cookbook_dir = tmp_cookbook_path.path
|
|
41
|
+
File.unlink(tmp_cookbook_dir)
|
|
42
|
+
FileUtils.mkdir_p(tmp_cookbook_dir)
|
|
43
|
+
Chef::Log.debug("Staging at #{tmp_cookbook_dir}")
|
|
44
|
+
checksums_to_on_disk_paths = cookbook.checksums
|
|
45
|
+
Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
|
|
46
|
+
cookbook.manifest[segment].each do |manifest_record|
|
|
47
|
+
path_in_cookbook = manifest_record[:path]
|
|
48
|
+
on_disk_path = checksums_to_on_disk_paths[manifest_record[:checksum]]
|
|
49
|
+
dest = File.join(tmp_cookbook_dir, cookbook.name.to_s, path_in_cookbook)
|
|
50
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
51
|
+
Chef::Log.debug("Staging #{on_disk_path} to #{dest}")
|
|
52
|
+
FileUtils.cp(on_disk_path, dest)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# First, generate metadata
|
|
57
|
+
Chef::Log.debug("Generating metadata")
|
|
58
|
+
kcm = Chef::Knife::CookbookMetadata.new
|
|
59
|
+
kcm.config[:cookbook_path] = [ tmp_cookbook_dir ]
|
|
60
|
+
kcm.name_args = [ cookbook.name.to_s ]
|
|
61
|
+
kcm.run
|
|
62
|
+
|
|
63
|
+
tmp_cookbook_dir
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def post(to_url, user_id, secret_key_filename, params = {}, headers = {})
|
|
67
|
+
make_request(:post, to_url, user_id, secret_key_filename, params, headers)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def put(to_url, user_id, secret_key_filename, params = {}, headers = {})
|
|
71
|
+
make_request(:put, to_url, user_id, secret_key_filename, params, headers)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def make_request(http_verb, to_url, user_id, secret_key_filename, params = {}, headers = {})
|
|
75
|
+
boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
|
|
76
|
+
parts = []
|
|
77
|
+
content_file = nil
|
|
78
|
+
|
|
79
|
+
timestamp = Time.now.utc.iso8601
|
|
80
|
+
secret_key = OpenSSL::PKey::RSA.new(File.read(secret_key_filename))
|
|
81
|
+
|
|
82
|
+
unless params.nil? || params.empty?
|
|
83
|
+
params.each do |key, value|
|
|
84
|
+
if value.kind_of?(File)
|
|
85
|
+
content_file = value
|
|
86
|
+
filepath = value.path
|
|
87
|
+
filename = File.basename(filepath)
|
|
88
|
+
parts << StringPart.new( "--" + boundary + "\r\n" +
|
|
89
|
+
"Content-Disposition: form-data; name=\"" + key.to_s + "\"; filename=\"" + filename + "\"\r\n" +
|
|
90
|
+
"Content-Type: application/octet-stream\r\n\r\n")
|
|
91
|
+
parts << StreamPart.new(value, File.size(filepath))
|
|
92
|
+
parts << StringPart.new("\r\n")
|
|
93
|
+
else
|
|
94
|
+
parts << StringPart.new( "--" + boundary + "\r\n" +
|
|
95
|
+
"Content-Disposition: form-data; name=\"" + key.to_s + "\"\r\n\r\n")
|
|
96
|
+
parts << StringPart.new(value.to_s + "\r\n")
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
parts << StringPart.new("--" + boundary + "--\r\n")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
body_stream = MultipartStream.new(parts)
|
|
103
|
+
|
|
104
|
+
timestamp = Time.now.utc.iso8601
|
|
105
|
+
|
|
106
|
+
url = URI.parse(to_url)
|
|
107
|
+
|
|
108
|
+
Chef::Log.logger.debug("Signing: method: #{http_verb}, path: #{url.path}, file: #{content_file}, User-id: #{user_id}, Timestamp: #{timestamp}")
|
|
109
|
+
|
|
110
|
+
# We use the body for signing the request if the file parameter
|
|
111
|
+
# wasn't a valid file or wasn't included. Extract the body (with
|
|
112
|
+
# multi-part delimiters intact) to sign the request.
|
|
113
|
+
# TODO: tim: 2009-12-28: It'd be nice to remove this special case, and
|
|
114
|
+
# always hash the entire request body. In the file case it would just be
|
|
115
|
+
# expanded multipart text - the entire body of the POST.
|
|
116
|
+
content_body = parts.inject("") { |result,part| result + part.read(0, part.size) }
|
|
117
|
+
content_file.rewind if content_file # we consumed the file for the above operation, so rewind it.
|
|
118
|
+
|
|
119
|
+
signing_options = {
|
|
120
|
+
:http_method=>http_verb,
|
|
121
|
+
:path=>url.path,
|
|
122
|
+
:user_id=>user_id,
|
|
123
|
+
:timestamp=>timestamp}
|
|
124
|
+
(content_file && signing_options[:file] = content_file) || (signing_options[:body] = (content_body || ""))
|
|
125
|
+
|
|
126
|
+
headers.merge!(Mixlib::Authentication::SignedHeaderAuth.signing_object(signing_options).sign(secret_key))
|
|
127
|
+
|
|
128
|
+
content_file.rewind if content_file
|
|
129
|
+
|
|
130
|
+
# net/http doesn't like symbols for header keys, so we'll to_s each one just in case
|
|
131
|
+
headers = DefaultHeaders.merge(Hash[*headers.map{ |k,v| [k.to_s, v] }.flatten])
|
|
132
|
+
|
|
133
|
+
req = case http_verb
|
|
134
|
+
when :put
|
|
135
|
+
Net::HTTP::Put.new(url.path, headers)
|
|
136
|
+
when :post
|
|
137
|
+
Net::HTTP::Post.new(url.path, headers)
|
|
138
|
+
end
|
|
139
|
+
req.content_length = body_stream.size
|
|
140
|
+
req.content_type = 'multipart/form-data; boundary=' + boundary unless parts.empty?
|
|
141
|
+
req.body_stream = body_stream
|
|
142
|
+
|
|
143
|
+
http = Net::HTTP.new(url.host, url.port)
|
|
144
|
+
if url.scheme == "https"
|
|
145
|
+
http.use_ssl = true
|
|
146
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
147
|
+
end
|
|
148
|
+
res = http.request(req)
|
|
149
|
+
#res = http.start {|http_proc| http_proc.request(req) }
|
|
150
|
+
|
|
151
|
+
# alias status to code and to_s to body for test purposes
|
|
152
|
+
# TODO: stop the following madness!
|
|
153
|
+
class << res
|
|
154
|
+
alias :to_s :body
|
|
155
|
+
|
|
156
|
+
# BUGBUG this makes the response compatible with what respsonse_steps expects to test headers (response.headers[] -> response[])
|
|
157
|
+
def headers
|
|
158
|
+
self
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def status
|
|
162
|
+
code.to_i
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
res
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
class StreamPart
|
|
171
|
+
def initialize(stream, size)
|
|
172
|
+
@stream, @size = stream, size
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def size
|
|
176
|
+
@size
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# read the specified amount from the stream
|
|
180
|
+
def read(offset, how_much)
|
|
181
|
+
@stream.read(how_much)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
class StringPart
|
|
186
|
+
def initialize(str)
|
|
187
|
+
@str = str
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def size
|
|
191
|
+
@str.length
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# read the specified amount from the string startiung at the offset
|
|
195
|
+
def read(offset, how_much)
|
|
196
|
+
@str[offset, how_much]
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
class MultipartStream
|
|
201
|
+
def initialize(parts)
|
|
202
|
+
@parts = parts
|
|
203
|
+
@part_no = 0
|
|
204
|
+
@part_offset = 0
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def size
|
|
208
|
+
@parts.inject(0) {|size, part| size + part.size}
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def read(how_much)
|
|
212
|
+
return nil if @part_no >= @parts.size
|
|
213
|
+
|
|
214
|
+
how_much_current_part = @parts[@part_no].size - @part_offset
|
|
215
|
+
|
|
216
|
+
how_much_current_part = if how_much_current_part > how_much
|
|
217
|
+
how_much
|
|
218
|
+
else
|
|
219
|
+
how_much_current_part
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
how_much_next_part = how_much - how_much_current_part
|
|
223
|
+
|
|
224
|
+
current_part = @parts[@part_no].read(@part_offset, how_much_current_part)
|
|
225
|
+
|
|
226
|
+
# recurse into the next part if the current one was not large enough
|
|
227
|
+
if how_much_next_part > 0
|
|
228
|
+
@part_no += 1
|
|
229
|
+
@part_offset = 0
|
|
230
|
+
next_part = read(how_much_next_part)
|
|
231
|
+
current_part + if next_part
|
|
232
|
+
next_part
|
|
233
|
+
else
|
|
234
|
+
''
|
|
235
|
+
end
|
|
236
|
+
else
|
|
237
|
+
@part_offset += how_much_current_part
|
|
238
|
+
current_part
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
end
|
|
244
|
+
end
|