gcloud 0.0.4 → 0.0.6
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.tar.gz.sig +0 -0
- data/CHANGELOG +4 -0
- data/Makefile +4 -0
- data/Manifest +760 -1
- data/bin/gcloud +7 -0
- data/bin/{gcutil → gcutil.symlink} +0 -0
- data/bin/gsutil-symlink +377 -0
- data/gcloud.gemspec +5 -5
- data/packages/gsutil/CHECKSUM +1 -0
- data/packages/gsutil/COPYING +202 -0
- data/packages/gsutil/LICENSE.third_party +295 -0
- data/packages/gsutil/MANIFEST.in +5 -0
- data/packages/gsutil/README +38 -0
- data/packages/gsutil/README.pkg +49 -0
- data/packages/gsutil/ReleaseNotes.txt +780 -0
- data/packages/gsutil/VERSION +1 -0
- data/packages/gsutil/boto/Changelog.rst +35 -0
- data/packages/gsutil/boto/LICENSE +18 -0
- data/packages/gsutil/boto/MANIFEST.in +12 -0
- data/packages/gsutil/boto/README.rst +163 -0
- data/packages/gsutil/boto/bin/asadmin +290 -0
- data/packages/gsutil/boto/bin/bundle_image +27 -0
- data/packages/gsutil/boto/bin/cfadmin +108 -0
- data/packages/gsutil/boto/bin/cq +89 -0
- data/packages/gsutil/boto/bin/cwutil +140 -0
- data/packages/gsutil/boto/bin/elbadmin +284 -0
- data/packages/gsutil/boto/bin/fetch_file +43 -0
- data/packages/gsutil/boto/bin/glacier +154 -0
- data/packages/gsutil/boto/bin/instance_events +145 -0
- data/packages/gsutil/boto/bin/kill_instance +35 -0
- data/packages/gsutil/boto/bin/launch_instance +252 -0
- data/packages/gsutil/boto/bin/list_instances +90 -0
- data/packages/gsutil/boto/bin/lss3 +77 -0
- data/packages/gsutil/boto/bin/mturk +465 -0
- data/packages/gsutil/boto/bin/pyami_sendmail +52 -0
- data/packages/gsutil/boto/bin/route53 +205 -0
- data/packages/gsutil/boto/bin/s3put +374 -0
- data/packages/gsutil/boto/bin/sdbadmin +194 -0
- data/packages/gsutil/boto/bin/taskadmin +116 -0
- data/packages/gsutil/boto/boto/__init__.py +793 -0
- data/packages/gsutil/boto/boto/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/auth.py +682 -0
- data/packages/gsutil/boto/boto/auth.pyc +0 -0
- data/packages/gsutil/boto/boto/auth_handler.py +58 -0
- data/packages/gsutil/boto/boto/auth_handler.pyc +0 -0
- data/packages/gsutil/boto/boto/beanstalk/__init__.py +65 -0
- data/packages/gsutil/boto/boto/beanstalk/exception.py +64 -0
- data/packages/gsutil/boto/boto/beanstalk/layer1.py +1153 -0
- data/packages/gsutil/boto/boto/beanstalk/response.py +703 -0
- data/packages/gsutil/boto/boto/beanstalk/wrapper.py +29 -0
- data/packages/gsutil/boto/boto/cacerts/__init__.py +22 -0
- data/packages/gsutil/boto/boto/cacerts/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/cacerts/cacerts.txt +633 -0
- data/packages/gsutil/boto/boto/cloudformation/__init__.py +68 -0
- data/packages/gsutil/boto/boto/cloudformation/connection.py +364 -0
- data/packages/gsutil/boto/boto/cloudformation/stack.py +360 -0
- data/packages/gsutil/boto/boto/cloudformation/template.py +43 -0
- data/packages/gsutil/boto/boto/cloudfront/__init__.py +324 -0
- data/packages/gsutil/boto/boto/cloudfront/distribution.py +745 -0
- data/packages/gsutil/boto/boto/cloudfront/exception.py +26 -0
- data/packages/gsutil/boto/boto/cloudfront/identity.py +122 -0
- data/packages/gsutil/boto/boto/cloudfront/invalidation.py +216 -0
- data/packages/gsutil/boto/boto/cloudfront/logging.py +38 -0
- data/packages/gsutil/boto/boto/cloudfront/object.py +48 -0
- data/packages/gsutil/boto/boto/cloudfront/origin.py +150 -0
- data/packages/gsutil/boto/boto/cloudfront/signers.py +60 -0
- data/packages/gsutil/boto/boto/cloudsearch/__init__.py +45 -0
- data/packages/gsutil/boto/boto/cloudsearch/document.py +265 -0
- data/packages/gsutil/boto/boto/cloudsearch/domain.py +394 -0
- data/packages/gsutil/boto/boto/cloudsearch/layer1.py +738 -0
- data/packages/gsutil/boto/boto/cloudsearch/layer2.py +67 -0
- data/packages/gsutil/boto/boto/cloudsearch/optionstatus.py +248 -0
- data/packages/gsutil/boto/boto/cloudsearch/search.py +365 -0
- data/packages/gsutil/boto/boto/cloudsearch/sourceattribute.py +75 -0
- data/packages/gsutil/boto/boto/compat.py +28 -0
- data/packages/gsutil/boto/boto/compat.pyc +0 -0
- data/packages/gsutil/boto/boto/connection.py +1081 -0
- data/packages/gsutil/boto/boto/connection.pyc +0 -0
- data/packages/gsutil/boto/boto/contrib/__init__.py +22 -0
- data/packages/gsutil/boto/boto/contrib/ymlmessage.py +52 -0
- data/packages/gsutil/boto/boto/core/README +58 -0
- data/packages/gsutil/boto/boto/core/__init__.py +23 -0
- data/packages/gsutil/boto/boto/core/auth.py +78 -0
- data/packages/gsutil/boto/boto/core/credentials.py +154 -0
- data/packages/gsutil/boto/boto/core/dictresponse.py +178 -0
- data/packages/gsutil/boto/boto/core/service.py +67 -0
- data/packages/gsutil/boto/boto/datapipeline/__init__.py +0 -0
- data/packages/gsutil/boto/boto/datapipeline/exceptions.py +42 -0
- data/packages/gsutil/boto/boto/datapipeline/layer1.py +546 -0
- data/packages/gsutil/boto/boto/dynamodb/__init__.py +66 -0
- data/packages/gsutil/boto/boto/dynamodb/batch.py +262 -0
- data/packages/gsutil/boto/boto/dynamodb/condition.py +170 -0
- data/packages/gsutil/boto/boto/dynamodb/exceptions.py +64 -0
- data/packages/gsutil/boto/boto/dynamodb/item.py +196 -0
- data/packages/gsutil/boto/boto/dynamodb/layer1.py +575 -0
- data/packages/gsutil/boto/boto/dynamodb/layer2.py +798 -0
- data/packages/gsutil/boto/boto/dynamodb/schema.py +112 -0
- data/packages/gsutil/boto/boto/dynamodb/table.py +540 -0
- data/packages/gsutil/boto/boto/dynamodb/types.py +326 -0
- data/packages/gsutil/boto/boto/ec2/__init__.py +96 -0
- data/packages/gsutil/boto/boto/ec2/address.py +103 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/__init__.py +781 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/activity.py +74 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/group.py +337 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/instance.py +60 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/launchconfig.py +209 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/policy.py +166 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/request.py +38 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/scheduled.py +60 -0
- data/packages/gsutil/boto/boto/ec2/autoscale/tag.py +84 -0
- data/packages/gsutil/boto/boto/ec2/blockdevicemapping.py +141 -0
- data/packages/gsutil/boto/boto/ec2/bundleinstance.py +78 -0
- data/packages/gsutil/boto/boto/ec2/buyreservation.py +84 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/__init__.py +603 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/alarm.py +316 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/datapoint.py +40 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/dimension.py +38 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/listelement.py +31 -0
- data/packages/gsutil/boto/boto/ec2/cloudwatch/metric.py +175 -0
- data/packages/gsutil/boto/boto/ec2/connection.py +3409 -0
- data/packages/gsutil/boto/boto/ec2/ec2object.py +107 -0
- data/packages/gsutil/boto/boto/ec2/elb/__init__.py +553 -0
- data/packages/gsutil/boto/boto/ec2/elb/healthcheck.py +89 -0
- data/packages/gsutil/boto/boto/ec2/elb/instancestate.py +62 -0
- data/packages/gsutil/boto/boto/ec2/elb/listelement.py +36 -0
- data/packages/gsutil/boto/boto/ec2/elb/listener.py +75 -0
- data/packages/gsutil/boto/boto/ec2/elb/loadbalancer.py +324 -0
- data/packages/gsutil/boto/boto/ec2/elb/policies.py +89 -0
- data/packages/gsutil/boto/boto/ec2/elb/securitygroup.py +38 -0
- data/packages/gsutil/boto/boto/ec2/group.py +39 -0
- data/packages/gsutil/boto/boto/ec2/image.py +350 -0
- data/packages/gsutil/boto/boto/ec2/instance.py +661 -0
- data/packages/gsutil/boto/boto/ec2/instanceinfo.py +51 -0
- data/packages/gsutil/boto/boto/ec2/instancestatus.py +207 -0
- data/packages/gsutil/boto/boto/ec2/keypair.py +113 -0
- data/packages/gsutil/boto/boto/ec2/launchspecification.py +105 -0
- data/packages/gsutil/boto/boto/ec2/networkinterface.py +247 -0
- data/packages/gsutil/boto/boto/ec2/placementgroup.py +51 -0
- data/packages/gsutil/boto/boto/ec2/regioninfo.py +34 -0
- data/packages/gsutil/boto/boto/ec2/reservedinstance.py +227 -0
- data/packages/gsutil/boto/boto/ec2/securitygroup.py +357 -0
- data/packages/gsutil/boto/boto/ec2/snapshot.py +170 -0
- data/packages/gsutil/boto/boto/ec2/spotdatafeedsubscription.py +63 -0
- data/packages/gsutil/boto/boto/ec2/spotinstancerequest.py +188 -0
- data/packages/gsutil/boto/boto/ec2/spotpricehistory.py +55 -0
- data/packages/gsutil/boto/boto/ec2/tag.py +87 -0
- data/packages/gsutil/boto/boto/ec2/vmtype.py +58 -0
- data/packages/gsutil/boto/boto/ec2/volume.py +293 -0
- data/packages/gsutil/boto/boto/ec2/volumestatus.py +200 -0
- data/packages/gsutil/boto/boto/ec2/zone.py +80 -0
- data/packages/gsutil/boto/boto/ecs/__init__.py +90 -0
- data/packages/gsutil/boto/boto/ecs/item.py +153 -0
- data/packages/gsutil/boto/boto/elasticache/__init__.py +62 -0
- data/packages/gsutil/boto/boto/elasticache/layer1.py +1252 -0
- data/packages/gsutil/boto/boto/elastictranscoder/__init__.py +62 -0
- data/packages/gsutil/boto/boto/elastictranscoder/exceptions.py +46 -0
- data/packages/gsutil/boto/boto/elastictranscoder/layer1.py +509 -0
- data/packages/gsutil/boto/boto/emr/__init__.py +73 -0
- data/packages/gsutil/boto/boto/emr/bootstrap_action.py +44 -0
- data/packages/gsutil/boto/boto/emr/connection.py +531 -0
- data/packages/gsutil/boto/boto/emr/emrobject.py +176 -0
- data/packages/gsutil/boto/boto/emr/instance_group.py +43 -0
- data/packages/gsutil/boto/boto/emr/step.py +281 -0
- data/packages/gsutil/boto/boto/exception.py +476 -0
- data/packages/gsutil/boto/boto/exception.pyc +0 -0
- data/packages/gsutil/boto/boto/file/README +49 -0
- data/packages/gsutil/boto/boto/file/__init__.py +28 -0
- data/packages/gsutil/boto/boto/file/bucket.py +112 -0
- data/packages/gsutil/boto/boto/file/connection.py +33 -0
- data/packages/gsutil/boto/boto/file/key.py +199 -0
- data/packages/gsutil/boto/boto/file/simpleresultset.py +30 -0
- data/packages/gsutil/boto/boto/fps/__init__.py +21 -0
- data/packages/gsutil/boto/boto/fps/connection.py +369 -0
- data/packages/gsutil/boto/boto/fps/exception.py +344 -0
- data/packages/gsutil/boto/boto/fps/response.py +175 -0
- data/packages/gsutil/boto/boto/glacier/__init__.py +57 -0
- data/packages/gsutil/boto/boto/glacier/concurrent.py +409 -0
- data/packages/gsutil/boto/boto/glacier/exceptions.py +58 -0
- data/packages/gsutil/boto/boto/glacier/job.py +152 -0
- data/packages/gsutil/boto/boto/glacier/layer1.py +637 -0
- data/packages/gsutil/boto/boto/glacier/layer2.py +93 -0
- data/packages/gsutil/boto/boto/glacier/response.py +48 -0
- data/packages/gsutil/boto/boto/glacier/utils.py +163 -0
- data/packages/gsutil/boto/boto/glacier/vault.py +387 -0
- data/packages/gsutil/boto/boto/glacier/writer.py +242 -0
- data/packages/gsutil/boto/boto/gs/__init__.py +22 -0
- data/packages/gsutil/boto/boto/gs/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/acl.py +304 -0
- data/packages/gsutil/boto/boto/gs/acl.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/bucket.py +870 -0
- data/packages/gsutil/boto/boto/gs/bucket.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/bucketlistresultset.py +64 -0
- data/packages/gsutil/boto/boto/gs/bucketlistresultset.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/connection.py +103 -0
- data/packages/gsutil/boto/boto/gs/connection.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/cors.py +169 -0
- data/packages/gsutil/boto/boto/gs/cors.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/key.py +704 -0
- data/packages/gsutil/boto/boto/gs/key.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/resumable_upload_handler.py +659 -0
- data/packages/gsutil/boto/boto/gs/resumable_upload_handler.pyc +0 -0
- data/packages/gsutil/boto/boto/gs/user.py +54 -0
- data/packages/gsutil/boto/boto/gs/user.pyc +0 -0
- data/packages/gsutil/boto/boto/handler.py +44 -0
- data/packages/gsutil/boto/boto/handler.pyc +0 -0
- data/packages/gsutil/boto/boto/https_connection.py +124 -0
- data/packages/gsutil/boto/boto/https_connection.pyc +0 -0
- data/packages/gsutil/boto/boto/iam/__init__.py +74 -0
- data/packages/gsutil/boto/boto/iam/connection.py +1317 -0
- data/packages/gsutil/boto/boto/iam/summarymap.py +42 -0
- data/packages/gsutil/boto/boto/jsonresponse.py +163 -0
- data/packages/gsutil/boto/boto/jsonresponse.pyc +0 -0
- data/packages/gsutil/boto/boto/manage/__init__.py +23 -0
- data/packages/gsutil/boto/boto/manage/cmdshell.py +241 -0
- data/packages/gsutil/boto/boto/manage/propget.py +64 -0
- data/packages/gsutil/boto/boto/manage/server.py +556 -0
- data/packages/gsutil/boto/boto/manage/task.py +175 -0
- data/packages/gsutil/boto/boto/manage/test_manage.py +34 -0
- data/packages/gsutil/boto/boto/manage/volume.py +420 -0
- data/packages/gsutil/boto/boto/mashups/__init__.py +23 -0
- data/packages/gsutil/boto/boto/mashups/interactive.py +97 -0
- data/packages/gsutil/boto/boto/mashups/iobject.py +115 -0
- data/packages/gsutil/boto/boto/mashups/order.py +211 -0
- data/packages/gsutil/boto/boto/mashups/server.py +395 -0
- data/packages/gsutil/boto/boto/mturk/__init__.py +23 -0
- data/packages/gsutil/boto/boto/mturk/connection.py +1027 -0
- data/packages/gsutil/boto/boto/mturk/layoutparam.py +55 -0
- data/packages/gsutil/boto/boto/mturk/notification.py +103 -0
- data/packages/gsutil/boto/boto/mturk/price.py +48 -0
- data/packages/gsutil/boto/boto/mturk/qualification.py +137 -0
- data/packages/gsutil/boto/boto/mturk/question.py +455 -0
- data/packages/gsutil/boto/boto/mws/__init__.py +21 -0
- data/packages/gsutil/boto/boto/mws/connection.py +813 -0
- data/packages/gsutil/boto/boto/mws/exception.py +75 -0
- data/packages/gsutil/boto/boto/mws/response.py +655 -0
- data/packages/gsutil/boto/boto/plugin.py +90 -0
- data/packages/gsutil/boto/boto/plugin.pyc +0 -0
- data/packages/gsutil/boto/boto/provider.py +337 -0
- data/packages/gsutil/boto/boto/provider.pyc +0 -0
- data/packages/gsutil/boto/boto/pyami/__init__.py +22 -0
- data/packages/gsutil/boto/boto/pyami/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/pyami/bootstrap.py +134 -0
- data/packages/gsutil/boto/boto/pyami/config.py +229 -0
- data/packages/gsutil/boto/boto/pyami/config.pyc +0 -0
- data/packages/gsutil/boto/boto/pyami/copybot.cfg +60 -0
- data/packages/gsutil/boto/boto/pyami/copybot.py +97 -0
- data/packages/gsutil/boto/boto/pyami/helloworld.py +28 -0
- data/packages/gsutil/boto/boto/pyami/installers/__init__.py +64 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/__init__.py +22 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/apache.py +43 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/ebs.py +238 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/installer.py +96 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/mysql.py +109 -0
- data/packages/gsutil/boto/boto/pyami/installers/ubuntu/trac.py +139 -0
- data/packages/gsutil/boto/boto/pyami/launch_ami.py +178 -0
- data/packages/gsutil/boto/boto/pyami/scriptbase.py +44 -0
- data/packages/gsutil/boto/boto/pyami/startup.py +60 -0
- data/packages/gsutil/boto/boto/rds/__init__.py +1194 -0
- data/packages/gsutil/boto/boto/rds/dbinstance.py +357 -0
- data/packages/gsutil/boto/boto/rds/dbsecuritygroup.py +177 -0
- data/packages/gsutil/boto/boto/rds/dbsnapshot.py +108 -0
- data/packages/gsutil/boto/boto/rds/event.py +49 -0
- data/packages/gsutil/boto/boto/rds/parametergroup.py +201 -0
- data/packages/gsutil/boto/boto/rds/regioninfo.py +32 -0
- data/packages/gsutil/boto/boto/regioninfo.py +63 -0
- data/packages/gsutil/boto/boto/regioninfo.pyc +0 -0
- data/packages/gsutil/boto/boto/resultset.py +169 -0
- data/packages/gsutil/boto/boto/resultset.pyc +0 -0
- data/packages/gsutil/boto/boto/roboto/__init__.py +1 -0
- data/packages/gsutil/boto/boto/roboto/awsqueryrequest.py +504 -0
- data/packages/gsutil/boto/boto/roboto/awsqueryservice.py +121 -0
- data/packages/gsutil/boto/boto/roboto/param.py +147 -0
- data/packages/gsutil/boto/boto/route53/__init__.py +75 -0
- data/packages/gsutil/boto/boto/route53/connection.py +403 -0
- data/packages/gsutil/boto/boto/route53/exception.py +27 -0
- data/packages/gsutil/boto/boto/route53/hostedzone.py +56 -0
- data/packages/gsutil/boto/boto/route53/record.py +306 -0
- data/packages/gsutil/boto/boto/route53/status.py +42 -0
- data/packages/gsutil/boto/boto/route53/zone.py +412 -0
- data/packages/gsutil/boto/boto/s3/__init__.py +84 -0
- data/packages/gsutil/boto/boto/s3/__init__.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/acl.py +164 -0
- data/packages/gsutil/boto/boto/s3/acl.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/bucket.py +1634 -0
- data/packages/gsutil/boto/boto/s3/bucket.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/bucketlistresultset.py +139 -0
- data/packages/gsutil/boto/boto/s3/bucketlistresultset.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/bucketlogging.py +83 -0
- data/packages/gsutil/boto/boto/s3/bucketlogging.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/connection.py +540 -0
- data/packages/gsutil/boto/boto/s3/connection.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/cors.py +210 -0
- data/packages/gsutil/boto/boto/s3/cors.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/deletemarker.py +55 -0
- data/packages/gsutil/boto/boto/s3/deletemarker.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/key.py +1712 -0
- data/packages/gsutil/boto/boto/s3/key.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/keyfile.py +134 -0
- data/packages/gsutil/boto/boto/s3/keyfile.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/lifecycle.py +231 -0
- data/packages/gsutil/boto/boto/s3/lifecycle.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/multidelete.py +138 -0
- data/packages/gsutil/boto/boto/s3/multidelete.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/multipart.py +315 -0
- data/packages/gsutil/boto/boto/s3/multipart.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/prefix.py +42 -0
- data/packages/gsutil/boto/boto/s3/prefix.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/resumable_download_handler.py +339 -0
- data/packages/gsutil/boto/boto/s3/resumable_download_handler.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/tagging.py +71 -0
- data/packages/gsutil/boto/boto/s3/tagging.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/user.py +49 -0
- data/packages/gsutil/boto/boto/s3/user.pyc +0 -0
- data/packages/gsutil/boto/boto/s3/website.py +237 -0
- data/packages/gsutil/boto/boto/s3/website.pyc +0 -0
- data/packages/gsutil/boto/boto/sdb/__init__.py +67 -0
- data/packages/gsutil/boto/boto/sdb/connection.py +617 -0
- data/packages/gsutil/boto/boto/sdb/db/__init__.py +20 -0
- data/packages/gsutil/boto/boto/sdb/db/blob.py +75 -0
- data/packages/gsutil/boto/boto/sdb/db/key.py +59 -0
- data/packages/gsutil/boto/boto/sdb/db/manager/__init__.py +85 -0
- data/packages/gsutil/boto/boto/sdb/db/manager/sdbmanager.py +732 -0
- data/packages/gsutil/boto/boto/sdb/db/manager/xmlmanager.py +517 -0
- data/packages/gsutil/boto/boto/sdb/db/model.py +294 -0
- data/packages/gsutil/boto/boto/sdb/db/property.py +703 -0
- data/packages/gsutil/boto/boto/sdb/db/query.py +85 -0
- data/packages/gsutil/boto/boto/sdb/db/sequence.py +226 -0
- data/packages/gsutil/boto/boto/sdb/db/test_db.py +231 -0
- data/packages/gsutil/boto/boto/sdb/domain.py +377 -0
- data/packages/gsutil/boto/boto/sdb/item.py +181 -0
- data/packages/gsutil/boto/boto/sdb/queryresultset.py +92 -0
- data/packages/gsutil/boto/boto/sdb/regioninfo.py +32 -0
- data/packages/gsutil/boto/boto/services/__init__.py +23 -0
- data/packages/gsutil/boto/boto/services/bs.py +179 -0
- data/packages/gsutil/boto/boto/services/message.py +58 -0
- data/packages/gsutil/boto/boto/services/result.py +136 -0
- data/packages/gsutil/boto/boto/services/service.py +161 -0
- data/packages/gsutil/boto/boto/services/servicedef.py +91 -0
- data/packages/gsutil/boto/boto/services/sonofmmm.cfg +43 -0
- data/packages/gsutil/boto/boto/services/sonofmmm.py +81 -0
- data/packages/gsutil/boto/boto/services/submit.py +88 -0
- data/packages/gsutil/boto/boto/ses/__init__.py +54 -0
- data/packages/gsutil/boto/boto/ses/connection.py +521 -0
- data/packages/gsutil/boto/boto/ses/exceptions.py +77 -0
- data/packages/gsutil/boto/boto/sns/__init__.py +78 -0
- data/packages/gsutil/boto/boto/sns/connection.py +431 -0
- data/packages/gsutil/boto/boto/sqs/__init__.py +56 -0
- data/packages/gsutil/boto/boto/sqs/attributes.py +46 -0
- data/packages/gsutil/boto/boto/sqs/batchresults.py +95 -0
- data/packages/gsutil/boto/boto/sqs/connection.py +417 -0
- data/packages/gsutil/boto/boto/sqs/jsonmessage.py +43 -0
- data/packages/gsutil/boto/boto/sqs/message.py +253 -0
- data/packages/gsutil/boto/boto/sqs/queue.py +478 -0
- data/packages/gsutil/boto/boto/sqs/regioninfo.py +32 -0
- data/packages/gsutil/boto/boto/storage_uri.py +835 -0
- data/packages/gsutil/boto/boto/storage_uri.pyc +0 -0
- data/packages/gsutil/boto/boto/sts/__init__.py +55 -0
- data/packages/gsutil/boto/boto/sts/connection.py +207 -0
- data/packages/gsutil/boto/boto/sts/credentials.py +215 -0
- data/packages/gsutil/boto/boto/swf/__init__.py +60 -0
- data/packages/gsutil/boto/boto/swf/exceptions.py +44 -0
- data/packages/gsutil/boto/boto/swf/layer1.py +1512 -0
- data/packages/gsutil/boto/boto/swf/layer1_decisions.py +287 -0
- data/packages/gsutil/boto/boto/swf/layer2.py +342 -0
- data/packages/gsutil/boto/boto/utils.py +927 -0
- data/packages/gsutil/boto/boto/utils.pyc +0 -0
- data/packages/gsutil/boto/boto/vpc/__init__.py +910 -0
- data/packages/gsutil/boto/boto/vpc/customergateway.py +54 -0
- data/packages/gsutil/boto/boto/vpc/dhcpoptions.py +72 -0
- data/packages/gsutil/boto/boto/vpc/internetgateway.py +72 -0
- data/packages/gsutil/boto/boto/vpc/routetable.py +109 -0
- data/packages/gsutil/boto/boto/vpc/subnet.py +57 -0
- data/packages/gsutil/boto/boto/vpc/vpc.py +54 -0
- data/packages/gsutil/boto/boto/vpc/vpnconnection.py +60 -0
- data/packages/gsutil/boto/boto/vpc/vpngateway.py +83 -0
- data/packages/gsutil/boto/docs/BotoCheatSheet.pdf +0 -0
- data/packages/gsutil/boto/docs/Makefile +89 -0
- data/packages/gsutil/boto/docs/make.bat +113 -0
- data/packages/gsutil/boto/docs/source/_templates/layout.html +3 -0
- data/packages/gsutil/boto/docs/source/autoscale_tut.rst +220 -0
- data/packages/gsutil/boto/docs/source/boto_config_tut.rst +125 -0
- data/packages/gsutil/boto/docs/source/boto_theme/static/boto.css_t +239 -0
- data/packages/gsutil/boto/docs/source/boto_theme/static/pygments.css +61 -0
- data/packages/gsutil/boto/docs/source/boto_theme/theme.conf +3 -0
- data/packages/gsutil/boto/docs/source/cloudfront_tut.rst +196 -0
- data/packages/gsutil/boto/docs/source/cloudsearch_tut.rst +411 -0
- data/packages/gsutil/boto/docs/source/cloudwatch_tut.rst +116 -0
- data/packages/gsutil/boto/docs/source/conf.py +32 -0
- data/packages/gsutil/boto/docs/source/contributing.rst +204 -0
- data/packages/gsutil/boto/docs/source/documentation.rst +59 -0
- data/packages/gsutil/boto/docs/source/dynamodb_tut.rst +339 -0
- data/packages/gsutil/boto/docs/source/ec2_tut.rst +86 -0
- data/packages/gsutil/boto/docs/source/elb_tut.rst +257 -0
- data/packages/gsutil/boto/docs/source/emr_tut.rst +108 -0
- data/packages/gsutil/boto/docs/source/index.rst +146 -0
- data/packages/gsutil/boto/docs/source/rds_tut.rst +108 -0
- data/packages/gsutil/boto/docs/source/ref/autoscale.rst +62 -0
- data/packages/gsutil/boto/docs/source/ref/beanstalk.rst +26 -0
- data/packages/gsutil/boto/docs/source/ref/boto.rst +47 -0
- data/packages/gsutil/boto/docs/source/ref/cloudformation.rst +34 -0
- data/packages/gsutil/boto/docs/source/ref/cloudfront.rst +68 -0
- data/packages/gsutil/boto/docs/source/ref/cloudsearch.rst +59 -0
- data/packages/gsutil/boto/docs/source/ref/cloudwatch.rst +27 -0
- data/packages/gsutil/boto/docs/source/ref/contrib.rst +32 -0
- data/packages/gsutil/boto/docs/source/ref/datapipeline.rst +26 -0
- data/packages/gsutil/boto/docs/source/ref/dynamodb.rst +61 -0
- data/packages/gsutil/boto/docs/source/ref/ec2.rst +140 -0
- data/packages/gsutil/boto/docs/source/ref/ecs.rst +19 -0
- data/packages/gsutil/boto/docs/source/ref/elasticache.rst +19 -0
- data/packages/gsutil/boto/docs/source/ref/elastictranscoder.rst +26 -0
- data/packages/gsutil/boto/docs/source/ref/elb.rst +47 -0
- data/packages/gsutil/boto/docs/source/ref/emr.rst +34 -0
- data/packages/gsutil/boto/docs/source/ref/file.rst +34 -0
- data/packages/gsutil/boto/docs/source/ref/fps.rst +19 -0
- data/packages/gsutil/boto/docs/source/ref/glacier.rst +63 -0
- data/packages/gsutil/boto/docs/source/ref/gs.rst +72 -0
- data/packages/gsutil/boto/docs/source/ref/iam.rst +27 -0
- data/packages/gsutil/boto/docs/source/ref/index.rst +40 -0
- data/packages/gsutil/boto/docs/source/ref/manage.rst +47 -0
- data/packages/gsutil/boto/docs/source/ref/mturk.rst +54 -0
- data/packages/gsutil/boto/docs/source/ref/mws.rst +33 -0
- data/packages/gsutil/boto/docs/source/ref/pyami.rst +103 -0
- data/packages/gsutil/boto/docs/source/ref/rds.rst +47 -0
- data/packages/gsutil/boto/docs/source/ref/route53.rst +34 -0
- data/packages/gsutil/boto/docs/source/ref/s3.rst +111 -0
- data/packages/gsutil/boto/docs/source/ref/sdb.rst +45 -0
- data/packages/gsutil/boto/docs/source/ref/sdb_db.rst +83 -0
- data/packages/gsutil/boto/docs/source/ref/services.rst +61 -0
- data/packages/gsutil/boto/docs/source/ref/ses.rst +21 -0
- data/packages/gsutil/boto/docs/source/ref/sns.rst +17 -0
- data/packages/gsutil/boto/docs/source/ref/sqs.rst +61 -0
- data/packages/gsutil/boto/docs/source/ref/sts.rst +25 -0
- data/packages/gsutil/boto/docs/source/ref/swf.rst +22 -0
- data/packages/gsutil/boto/docs/source/ref/vpc.rst +54 -0
- data/packages/gsutil/boto/docs/source/s3_tut.rst +450 -0
- data/packages/gsutil/boto/docs/source/security_groups.rst +82 -0
- data/packages/gsutil/boto/docs/source/ses_tut.rst +171 -0
- data/packages/gsutil/boto/docs/source/simpledb_tut.rst +188 -0
- data/packages/gsutil/boto/docs/source/sqs_tut.rst +246 -0
- data/packages/gsutil/boto/docs/source/vpc_tut.rst +100 -0
- data/packages/gsutil/boto/pylintrc +305 -0
- data/packages/gsutil/boto/requirements.txt +10 -0
- data/packages/gsutil/boto/setup.py +89 -0
- data/packages/gsutil/boto/tests/__init__.py +20 -0
- data/packages/gsutil/boto/tests/db/test_lists.py +96 -0
- data/packages/gsutil/boto/tests/db/test_password.py +128 -0
- data/packages/gsutil/boto/tests/db/test_query.py +152 -0
- data/packages/gsutil/boto/tests/db/test_sequence.py +109 -0
- data/packages/gsutil/boto/tests/devpay/__init__.py +0 -0
- data/packages/gsutil/boto/tests/devpay/test_s3.py +181 -0
- data/packages/gsutil/boto/tests/fps/__init__.py +0 -0
- data/packages/gsutil/boto/tests/fps/test.py +100 -0
- data/packages/gsutil/boto/tests/fps/test_verify_signature.py +12 -0
- data/packages/gsutil/boto/tests/integration/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/beanstalk/test_wrapper.py +209 -0
- data/packages/gsutil/boto/tests/integration/cloudformation/__init__.py +21 -0
- data/packages/gsutil/boto/tests/integration/cloudformation/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/cloudformation/test_connection.py +110 -0
- data/packages/gsutil/boto/tests/integration/cloudsearch/__init__.py +21 -0
- data/packages/gsutil/boto/tests/integration/cloudsearch/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/datapipeline/test_layer1.py +122 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/test_layer1.py +266 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/test_layer2.py +484 -0
- data/packages/gsutil/boto/tests/integration/dynamodb/test_table.py +84 -0
- data/packages/gsutil/boto/tests/integration/ec2/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/ec2/autoscale/__init__.py +21 -0
- data/packages/gsutil/boto/tests/integration/ec2/autoscale/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ec2/autoscale/test_connection.py +167 -0
- data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/test_connection.py +277 -0
- data/packages/gsutil/boto/tests/integration/ec2/elb/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/ec2/elb/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ec2/elb/test_connection.py +130 -0
- data/packages/gsutil/boto/tests/integration/ec2/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ec2/test_connection.py +192 -0
- data/packages/gsutil/boto/tests/integration/ec2/vpc/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/ec2/vpc/test_connection.py +95 -0
- data/packages/gsutil/boto/tests/integration/elasticache/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/elasticache/test_layer1.py +67 -0
- data/packages/gsutil/boto/tests/integration/elastictranscoder/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/elastictranscoder/test_cert_verification.py +35 -0
- data/packages/gsutil/boto/tests/integration/elastictranscoder/test_layer1.py +115 -0
- data/packages/gsutil/boto/tests/integration/emr/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/emr/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/glacier/__init__.py +22 -0
- data/packages/gsutil/boto/tests/integration/glacier/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/glacier/test_layer1.py +44 -0
- data/packages/gsutil/boto/tests/integration/glacier/test_layer2.py +45 -0
- data/packages/gsutil/boto/tests/integration/gs/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/gs/cb_test_harness.py +71 -0
- data/packages/gsutil/boto/tests/integration/gs/test_basic.py +379 -0
- data/packages/gsutil/boto/tests/integration/gs/test_generation_conditionals.py +399 -0
- data/packages/gsutil/boto/tests/integration/gs/test_resumable_downloads.py +358 -0
- data/packages/gsutil/boto/tests/integration/gs/test_resumable_uploads.py +525 -0
- data/packages/gsutil/boto/tests/integration/gs/test_storage_uri.py +125 -0
- data/packages/gsutil/boto/tests/integration/gs/test_versioning.py +268 -0
- data/packages/gsutil/boto/tests/integration/gs/testcase.py +116 -0
- data/packages/gsutil/boto/tests/integration/gs/util.py +63 -0
- data/packages/gsutil/boto/tests/integration/iam/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/iam/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/mws/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/mws/test.py +100 -0
- data/packages/gsutil/boto/tests/integration/rds/__init__.py +21 -0
- data/packages/gsutil/boto/tests/integration/rds/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/route53/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/route53/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/route53/test_zone.py +132 -0
- data/packages/gsutil/boto/tests/integration/s3/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/s3/mock_storage_service.py +589 -0
- data/packages/gsutil/boto/tests/integration/s3/other_cacerts.txt +70 -0
- data/packages/gsutil/boto/tests/integration/s3/test_bucket.py +263 -0
- data/packages/gsutil/boto/tests/integration/s3/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/s3/test_connection.py +245 -0
- data/packages/gsutil/boto/tests/integration/s3/test_cors.py +78 -0
- data/packages/gsutil/boto/tests/integration/s3/test_encryption.py +115 -0
- data/packages/gsutil/boto/tests/integration/s3/test_https_cert_validation.py +141 -0
- data/packages/gsutil/boto/tests/integration/s3/test_key.py +375 -0
- data/packages/gsutil/boto/tests/integration/s3/test_mfa.py +95 -0
- data/packages/gsutil/boto/tests/integration/s3/test_multidelete.py +181 -0
- data/packages/gsutil/boto/tests/integration/s3/test_multipart.py +139 -0
- data/packages/gsutil/boto/tests/integration/s3/test_pool.py +246 -0
- data/packages/gsutil/boto/tests/integration/s3/test_versioning.py +158 -0
- data/packages/gsutil/boto/tests/integration/sdb/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/sdb/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/sdb/test_connection.py +119 -0
- data/packages/gsutil/boto/tests/integration/ses/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/ses/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/ses/test_connection.py +38 -0
- data/packages/gsutil/boto/tests/integration/sns/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/sns/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/sqs/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/sqs/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/sqs/test_connection.py +217 -0
- data/packages/gsutil/boto/tests/integration/sts/__init__.py +20 -0
- data/packages/gsutil/boto/tests/integration/sts/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/sts/test_session_token.py +65 -0
- data/packages/gsutil/boto/tests/integration/swf/__init__.py +0 -0
- data/packages/gsutil/boto/tests/integration/swf/test_cert_verification.py +40 -0
- data/packages/gsutil/boto/tests/integration/swf/test_layer1.py +246 -0
- data/packages/gsutil/boto/tests/integration/swf/test_layer1_workflow_execution.py +173 -0
- data/packages/gsutil/boto/tests/mturk/__init__.py +0 -0
- data/packages/gsutil/boto/tests/mturk/_init_environment.py +28 -0
- data/packages/gsutil/boto/tests/mturk/all_tests.py +24 -0
- data/packages/gsutil/boto/tests/mturk/cleanup_tests.py +47 -0
- data/packages/gsutil/boto/tests/mturk/common.py +45 -0
- data/packages/gsutil/boto/tests/mturk/create_free_text_question_regex.doctest +100 -0
- data/packages/gsutil/boto/tests/mturk/create_hit.doctest +92 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_binary.doctest +94 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_external.py +21 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_from_hit_type.doctest +103 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_test.py +21 -0
- data/packages/gsutil/boto/tests/mturk/create_hit_with_qualifications.py +16 -0
- data/packages/gsutil/boto/tests/mturk/hit_persistence.py +27 -0
- data/packages/gsutil/boto/tests/mturk/mocks.py +11 -0
- data/packages/gsutil/boto/tests/mturk/reviewable_hits.doctest +129 -0
- data/packages/gsutil/boto/tests/mturk/run-doctest.py +13 -0
- data/packages/gsutil/boto/tests/mturk/search_hits.doctest +16 -0
- data/packages/gsutil/boto/tests/mturk/selenium_support.py +61 -0
- data/packages/gsutil/boto/tests/mturk/support.py +7 -0
- data/packages/gsutil/boto/tests/mturk/test_disable_hit.py +11 -0
- data/packages/gsutil/boto/tests/test.py +59 -0
- data/packages/gsutil/boto/tests/unit/__init__.py +79 -0
- data/packages/gsutil/boto/tests/unit/auth/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/auth/test_sigv4.py +73 -0
- data/packages/gsutil/boto/tests/unit/beanstalk/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/beanstalk/test_layer1.py +128 -0
- data/packages/gsutil/boto/tests/unit/cloudformation/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/cloudformation/test_connection.py +605 -0
- data/packages/gsutil/boto/tests/unit/cloudformation/test_stack.py +63 -0
- data/packages/gsutil/boto/tests/unit/cloudfront/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/cloudfront/test_invalidation_list.py +113 -0
- data/packages/gsutil/boto/tests/unit/cloudfront/test_signed_urls.py +354 -0
- data/packages/gsutil/boto/tests/unit/cloudsearch/__init__.py +1 -0
- data/packages/gsutil/boto/tests/unit/cloudsearch/test_connection.py +241 -0
- data/packages/gsutil/boto/tests/unit/cloudsearch/test_document.py +324 -0
- data/packages/gsutil/boto/tests/unit/cloudsearch/test_search.py +325 -0
- data/packages/gsutil/boto/tests/unit/dynamodb/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/dynamodb/test_batch.py +103 -0
- data/packages/gsutil/boto/tests/unit/dynamodb/test_layer2.py +119 -0
- data/packages/gsutil/boto/tests/unit/dynamodb/test_types.py +82 -0
- data/packages/gsutil/boto/tests/unit/ec2/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/ec2/autoscale/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/ec2/autoscale/test_group.py +162 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_address.py +39 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_blockdevicemapping.py +79 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_connection.py +480 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_instance.py +243 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_networkinterface.py +140 -0
- data/packages/gsutil/boto/tests/unit/ec2/test_volume.py +248 -0
- data/packages/gsutil/boto/tests/unit/emr/test_emr_responses.py +373 -0
- data/packages/gsutil/boto/tests/unit/glacier/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_concurrent.py +120 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_job.py +60 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_layer1.py +98 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_layer2.py +266 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_utils.py +116 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_vault.py +100 -0
- data/packages/gsutil/boto/tests/unit/glacier/test_writer.py +185 -0
- data/packages/gsutil/boto/tests/unit/provider/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/provider/test_provider.py +176 -0
- data/packages/gsutil/boto/tests/unit/rds/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/rds/test_connection.py +131 -0
- data/packages/gsutil/boto/tests/unit/s3/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/s3/test_cors_configuration.py +77 -0
- data/packages/gsutil/boto/tests/unit/s3/test_key.py +75 -0
- data/packages/gsutil/boto/tests/unit/s3/test_keyfile.py +101 -0
- data/packages/gsutil/boto/tests/unit/s3/test_lifecycle.py +97 -0
- data/packages/gsutil/boto/tests/unit/s3/test_tagging.py +47 -0
- data/packages/gsutil/boto/tests/unit/s3/test_uri.py +257 -0
- data/packages/gsutil/boto/tests/unit/s3/test_website.py +188 -0
- data/packages/gsutil/boto/tests/unit/sns/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/sns/test_connection.py +99 -0
- data/packages/gsutil/boto/tests/unit/sqs/__init__.py +0 -0
- data/packages/gsutil/boto/tests/unit/sqs/test_connection.py +98 -0
- data/packages/gsutil/boto/tests/unit/sqs/test_queue.py +40 -0
- data/packages/gsutil/boto/tests/unit/sts/test_connection.py +74 -0
- data/packages/gsutil/boto/tests/unit/test_connection.py +60 -0
- data/packages/gsutil/boto/tests/unit/utils/test_utils.py +109 -0
- data/packages/gsutil/boto/tox.ini +8 -0
- data/packages/gsutil/gslib/README +5 -0
- data/packages/gsutil/gslib/__init__.py +22 -0
- data/packages/gsutil/gslib/__init__.pyc +0 -0
- data/packages/gsutil/gslib/addlhelp/__init__.py +15 -0
- data/packages/gsutil/gslib/addlhelp/acls.py +234 -0
- data/packages/gsutil/gslib/addlhelp/anon.py +57 -0
- data/packages/gsutil/gslib/addlhelp/command_opts.py +116 -0
- data/packages/gsutil/gslib/addlhelp/dev.py +139 -0
- data/packages/gsutil/gslib/addlhelp/metadata.py +186 -0
- data/packages/gsutil/gslib/addlhelp/naming.py +173 -0
- data/packages/gsutil/gslib/addlhelp/prod.py +160 -0
- data/packages/gsutil/gslib/addlhelp/projects.py +130 -0
- data/packages/gsutil/gslib/addlhelp/subdirs.py +110 -0
- data/packages/gsutil/gslib/addlhelp/support.py +86 -0
- data/packages/gsutil/gslib/addlhelp/versioning.py +242 -0
- data/packages/gsutil/gslib/addlhelp/wildcards.py +170 -0
- data/packages/gsutil/gslib/bucket_listing_ref.py +175 -0
- data/packages/gsutil/gslib/bucket_listing_ref.pyc +0 -0
- data/packages/gsutil/gslib/command.py +722 -0
- data/packages/gsutil/gslib/command.pyc +0 -0
- data/packages/gsutil/gslib/command_runner.py +101 -0
- data/packages/gsutil/gslib/command_runner.pyc +0 -0
- data/packages/gsutil/gslib/commands/__init__.py +15 -0
- data/packages/gsutil/gslib/commands/__init__.pyc +0 -0
- data/packages/gsutil/gslib/commands/cat.py +131 -0
- data/packages/gsutil/gslib/commands/cat.pyc +0 -0
- data/packages/gsutil/gslib/commands/chacl.py +532 -0
- data/packages/gsutil/gslib/commands/chacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/config.py +694 -0
- data/packages/gsutil/gslib/commands/config.pyc +0 -0
- data/packages/gsutil/gslib/commands/cp.py +1818 -0
- data/packages/gsutil/gslib/commands/cp.pyc +0 -0
- data/packages/gsutil/gslib/commands/disablelogging.py +101 -0
- data/packages/gsutil/gslib/commands/disablelogging.pyc +0 -0
- data/packages/gsutil/gslib/commands/enablelogging.py +149 -0
- data/packages/gsutil/gslib/commands/enablelogging.pyc +0 -0
- data/packages/gsutil/gslib/commands/getacl.py +82 -0
- data/packages/gsutil/gslib/commands/getacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/getcors.py +121 -0
- data/packages/gsutil/gslib/commands/getcors.pyc +0 -0
- data/packages/gsutil/gslib/commands/getdefacl.py +86 -0
- data/packages/gsutil/gslib/commands/getdefacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/getlogging.py +137 -0
- data/packages/gsutil/gslib/commands/getlogging.pyc +0 -0
- data/packages/gsutil/gslib/commands/getversioning.py +116 -0
- data/packages/gsutil/gslib/commands/getversioning.pyc +0 -0
- data/packages/gsutil/gslib/commands/getwebcfg.py +122 -0
- data/packages/gsutil/gslib/commands/getwebcfg.pyc +0 -0
- data/packages/gsutil/gslib/commands/help.py +218 -0
- data/packages/gsutil/gslib/commands/help.pyc +0 -0
- data/packages/gsutil/gslib/commands/ls.py +578 -0
- data/packages/gsutil/gslib/commands/ls.pyc +0 -0
- data/packages/gsutil/gslib/commands/mb.py +172 -0
- data/packages/gsutil/gslib/commands/mb.pyc +0 -0
- data/packages/gsutil/gslib/commands/mv.py +159 -0
- data/packages/gsutil/gslib/commands/mv.pyc +0 -0
- data/packages/gsutil/gslib/commands/perfdiag.py +903 -0
- data/packages/gsutil/gslib/commands/perfdiag.pyc +0 -0
- data/packages/gsutil/gslib/commands/rb.py +113 -0
- data/packages/gsutil/gslib/commands/rb.pyc +0 -0
- data/packages/gsutil/gslib/commands/rm.py +239 -0
- data/packages/gsutil/gslib/commands/rm.pyc +0 -0
- data/packages/gsutil/gslib/commands/setacl.py +138 -0
- data/packages/gsutil/gslib/commands/setacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/setcors.py +145 -0
- data/packages/gsutil/gslib/commands/setcors.pyc +0 -0
- data/packages/gsutil/gslib/commands/setdefacl.py +105 -0
- data/packages/gsutil/gslib/commands/setdefacl.pyc +0 -0
- data/packages/gsutil/gslib/commands/setmeta.py +428 -0
- data/packages/gsutil/gslib/commands/setmeta.pyc +0 -0
- data/packages/gsutil/gslib/commands/setversioning.py +114 -0
- data/packages/gsutil/gslib/commands/setversioning.pyc +0 -0
- data/packages/gsutil/gslib/commands/setwebcfg.py +190 -0
- data/packages/gsutil/gslib/commands/setwebcfg.pyc +0 -0
- data/packages/gsutil/gslib/commands/test.py +228 -0
- data/packages/gsutil/gslib/commands/test.pyc +0 -0
- data/packages/gsutil/gslib/commands/update.py +305 -0
- data/packages/gsutil/gslib/commands/update.pyc +0 -0
- data/packages/gsutil/gslib/commands/version.py +150 -0
- data/packages/gsutil/gslib/commands/version.pyc +0 -0
- data/packages/gsutil/gslib/exception.py +76 -0
- data/packages/gsutil/gslib/exception.pyc +0 -0
- data/packages/gsutil/gslib/help_provider.py +81 -0
- data/packages/gsutil/gslib/help_provider.pyc +0 -0
- data/packages/gsutil/gslib/name_expansion.py +550 -0
- data/packages/gsutil/gslib/name_expansion.pyc +0 -0
- data/packages/gsutil/gslib/no_op_auth_plugin.py +30 -0
- data/packages/gsutil/gslib/plurality_checkable_iterator.py +56 -0
- data/packages/gsutil/gslib/plurality_checkable_iterator.pyc +0 -0
- data/packages/gsutil/gslib/project_id.py +67 -0
- data/packages/gsutil/gslib/project_id.pyc +0 -0
- data/packages/gsutil/gslib/storage_uri_builder.py +56 -0
- data/packages/gsutil/gslib/storage_uri_builder.pyc +0 -0
- data/packages/gsutil/gslib/tests/__init__.py +15 -0
- data/packages/gsutil/gslib/tests/__init__.pyc +0 -0
- data/packages/gsutil/gslib/tests/test_chacl.py +236 -0
- data/packages/gsutil/gslib/tests/test_cp.py +267 -0
- data/packages/gsutil/gslib/tests/test_data/test.gif +0 -0
- data/packages/gsutil/gslib/tests/test_data/test.mp3 +0 -0
- data/packages/gsutil/gslib/tests/test_ls.py +66 -0
- data/packages/gsutil/gslib/tests/test_mv.py +69 -0
- data/packages/gsutil/gslib/tests/test_naming.py +989 -0
- data/packages/gsutil/gslib/tests/test_perfdiag.py +41 -0
- data/packages/gsutil/gslib/tests/test_plurality_checkable_iterator.py +67 -0
- data/packages/gsutil/gslib/tests/test_rm.py +143 -0
- data/packages/gsutil/gslib/tests/test_setacl.py +152 -0
- data/packages/gsutil/gslib/tests/test_setcors.py +168 -0
- data/packages/gsutil/gslib/tests/test_setmeta.py +91 -0
- data/packages/gsutil/gslib/tests/test_setversioning.py +44 -0
- data/packages/gsutil/gslib/tests/test_setwebcfg.py +63 -0
- data/packages/gsutil/gslib/tests/test_thread_pool.py +92 -0
- data/packages/gsutil/gslib/tests/test_wildcard_iterator.py +364 -0
- data/packages/gsutil/gslib/tests/testcase/__init__.py +18 -0
- data/packages/gsutil/gslib/tests/testcase/base.py +89 -0
- data/packages/gsutil/gslib/tests/testcase/integration_testcase.py +197 -0
- data/packages/gsutil/gslib/tests/testcase/unit_testcase.py +230 -0
- data/packages/gsutil/gslib/tests/util.py +125 -0
- data/packages/gsutil/gslib/tests/util.pyc +0 -0
- data/packages/gsutil/gslib/thread_pool.py +79 -0
- data/packages/gsutil/gslib/thread_pool.pyc +0 -0
- data/packages/gsutil/gslib/util.py +151 -0
- data/packages/gsutil/gslib/util.pyc +0 -0
- data/packages/gsutil/gslib/wildcard_iterator.py +492 -0
- data/packages/gsutil/gslib/wildcard_iterator.pyc +0 -0
- data/packages/gsutil/gsutil +377 -0
- data/packages/gsutil/gsutil.spec.in +75 -0
- data/packages/gsutil/oauth2_plugin/__init__.py +22 -0
- data/packages/gsutil/oauth2_plugin/__init__.pyc +0 -0
- data/packages/gsutil/oauth2_plugin/oauth2_client.py +642 -0
- data/packages/gsutil/oauth2_plugin/oauth2_client.pyc +0 -0
- data/packages/gsutil/oauth2_plugin/oauth2_client_test.py +374 -0
- data/packages/gsutil/oauth2_plugin/oauth2_helper.py +110 -0
- data/packages/gsutil/oauth2_plugin/oauth2_helper.pyc +0 -0
- data/packages/gsutil/oauth2_plugin/oauth2_plugin.py +24 -0
- data/packages/gsutil/oauth2_plugin/oauth2_plugin.pyc +0 -0
- data/packages/gsutil/pkg_gen.sh +54 -0
- data/packages/gsutil/pkg_util.py +60 -0
- data/packages/gsutil/setup.py +141 -0
- data/packages/gsutil/third_party/__init__.py +0 -0
- data/packages/gsutil/third_party/__init__.pyc +0 -0
- data/packages/gsutil/third_party/fancy_urllib/README +21 -0
- data/packages/gsutil/third_party/fancy_urllib/__init__.py +398 -0
- data/packages/gsutil/third_party/fancy_urllib/__init__.pyc +0 -0
- data/tasks/rubygem.rake +3 -1
- metadata +770 -7
- metadata.gz.sig +0 -0
|
Binary file
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/
|
|
2
|
+
# Copyright (c) 2012 Amazon.com, Inc. or its affiliates.
|
|
3
|
+
# Copyright (c) 2010, Eucalyptus Systems, Inc.
|
|
4
|
+
# All Rights Reserved
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
7
|
+
# copy of this software and associated documentation files (the
|
|
8
|
+
# "Software"), to deal in the Software without restriction, including
|
|
9
|
+
# without limitation the rights to use, copy, modify, merge, publish, dis-
|
|
10
|
+
# tribute, sublicense, and/or sell copies of the Software, and to permit
|
|
11
|
+
# persons to whom the Software is furnished to do so, subject to the fol-
|
|
12
|
+
# lowing conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included
|
|
15
|
+
# in all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
18
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
|
|
19
|
+
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
20
|
+
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
21
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
23
|
+
# IN THE SOFTWARE.
|
|
24
|
+
|
|
25
|
+
import user
|
|
26
|
+
import key
|
|
27
|
+
from boto import handler
|
|
28
|
+
import xml.sax
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class CompleteMultiPartUpload(object):
|
|
32
|
+
"""
|
|
33
|
+
Represents a completed MultiPart Upload. Contains the
|
|
34
|
+
following useful attributes:
|
|
35
|
+
|
|
36
|
+
* location - The URI of the completed upload
|
|
37
|
+
* bucket_name - The name of the bucket in which the upload
|
|
38
|
+
is contained
|
|
39
|
+
* key_name - The name of the new, completed key
|
|
40
|
+
* etag - The MD5 hash of the completed, combined upload
|
|
41
|
+
* version_id - The version_id of the completed upload
|
|
42
|
+
* encrypted - The value of the encryption header
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, bucket=None):
|
|
46
|
+
self.bucket = bucket
|
|
47
|
+
self.location = None
|
|
48
|
+
self.bucket_name = None
|
|
49
|
+
self.key_name = None
|
|
50
|
+
self.etag = None
|
|
51
|
+
self.version_id = None
|
|
52
|
+
self.encrypted = None
|
|
53
|
+
|
|
54
|
+
def __repr__(self):
|
|
55
|
+
return '<CompleteMultiPartUpload: %s.%s>' % (self.bucket_name,
|
|
56
|
+
self.key_name)
|
|
57
|
+
|
|
58
|
+
def startElement(self, name, attrs, connection):
|
|
59
|
+
return None
|
|
60
|
+
|
|
61
|
+
def endElement(self, name, value, connection):
|
|
62
|
+
if name == 'Location':
|
|
63
|
+
self.location = value
|
|
64
|
+
elif name == 'Bucket':
|
|
65
|
+
self.bucket_name = value
|
|
66
|
+
elif name == 'Key':
|
|
67
|
+
self.key_name = value
|
|
68
|
+
elif name == 'ETag':
|
|
69
|
+
self.etag = value
|
|
70
|
+
else:
|
|
71
|
+
setattr(self, name, value)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class Part(object):
|
|
75
|
+
"""
|
|
76
|
+
Represents a single part in a MultiPart upload.
|
|
77
|
+
Attributes include:
|
|
78
|
+
|
|
79
|
+
* part_number - The integer part number
|
|
80
|
+
* last_modified - The last modified date of this part
|
|
81
|
+
* etag - The MD5 hash of this part
|
|
82
|
+
* size - The size, in bytes, of this part
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
def __init__(self, bucket=None):
|
|
86
|
+
self.bucket = bucket
|
|
87
|
+
self.part_number = None
|
|
88
|
+
self.last_modified = None
|
|
89
|
+
self.etag = None
|
|
90
|
+
self.size = None
|
|
91
|
+
|
|
92
|
+
def __repr__(self):
|
|
93
|
+
if isinstance(self.part_number, int):
|
|
94
|
+
return '<Part %d>' % self.part_number
|
|
95
|
+
else:
|
|
96
|
+
return '<Part %s>' % None
|
|
97
|
+
|
|
98
|
+
def startElement(self, name, attrs, connection):
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
def endElement(self, name, value, connection):
|
|
102
|
+
if name == 'PartNumber':
|
|
103
|
+
self.part_number = int(value)
|
|
104
|
+
elif name == 'LastModified':
|
|
105
|
+
self.last_modified = value
|
|
106
|
+
elif name == 'ETag':
|
|
107
|
+
self.etag = value
|
|
108
|
+
elif name == 'Size':
|
|
109
|
+
self.size = int(value)
|
|
110
|
+
else:
|
|
111
|
+
setattr(self, name, value)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def part_lister(mpupload, part_number_marker=None):
|
|
115
|
+
"""
|
|
116
|
+
A generator function for listing parts of a multipart upload.
|
|
117
|
+
"""
|
|
118
|
+
more_results = True
|
|
119
|
+
part = None
|
|
120
|
+
while more_results:
|
|
121
|
+
parts = mpupload.get_all_parts(None, part_number_marker)
|
|
122
|
+
for part in parts:
|
|
123
|
+
yield part
|
|
124
|
+
part_number_marker = mpupload.next_part_number_marker
|
|
125
|
+
more_results = mpupload.is_truncated
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class MultiPartUpload(object):
|
|
129
|
+
"""
|
|
130
|
+
Represents a MultiPart Upload operation.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
def __init__(self, bucket=None):
|
|
134
|
+
self.bucket = bucket
|
|
135
|
+
self.bucket_name = None
|
|
136
|
+
self.key_name = None
|
|
137
|
+
self.id = id
|
|
138
|
+
self.initiator = None
|
|
139
|
+
self.owner = None
|
|
140
|
+
self.storage_class = None
|
|
141
|
+
self.initiated = None
|
|
142
|
+
self.part_number_marker = None
|
|
143
|
+
self.next_part_number_marker = None
|
|
144
|
+
self.max_parts = None
|
|
145
|
+
self.is_truncated = False
|
|
146
|
+
self._parts = None
|
|
147
|
+
|
|
148
|
+
def __repr__(self):
|
|
149
|
+
return '<MultiPartUpload %s>' % self.key_name
|
|
150
|
+
|
|
151
|
+
def __iter__(self):
|
|
152
|
+
return part_lister(self)
|
|
153
|
+
|
|
154
|
+
def to_xml(self):
|
|
155
|
+
s = '<CompleteMultipartUpload>\n'
|
|
156
|
+
for part in self:
|
|
157
|
+
s += ' <Part>\n'
|
|
158
|
+
s += ' <PartNumber>%d</PartNumber>\n' % part.part_number
|
|
159
|
+
s += ' <ETag>%s</ETag>\n' % part.etag
|
|
160
|
+
s += ' </Part>\n'
|
|
161
|
+
s += '</CompleteMultipartUpload>'
|
|
162
|
+
return s
|
|
163
|
+
|
|
164
|
+
def startElement(self, name, attrs, connection):
|
|
165
|
+
if name == 'Initiator':
|
|
166
|
+
self.initiator = user.User(self)
|
|
167
|
+
return self.initiator
|
|
168
|
+
elif name == 'Owner':
|
|
169
|
+
self.owner = user.User(self)
|
|
170
|
+
return self.owner
|
|
171
|
+
elif name == 'Part':
|
|
172
|
+
part = Part(self.bucket)
|
|
173
|
+
self._parts.append(part)
|
|
174
|
+
return part
|
|
175
|
+
return None
|
|
176
|
+
|
|
177
|
+
def endElement(self, name, value, connection):
|
|
178
|
+
if name == 'Bucket':
|
|
179
|
+
self.bucket_name = value
|
|
180
|
+
elif name == 'Key':
|
|
181
|
+
self.key_name = value
|
|
182
|
+
elif name == 'UploadId':
|
|
183
|
+
self.id = value
|
|
184
|
+
elif name == 'StorageClass':
|
|
185
|
+
self.storage_class = value
|
|
186
|
+
elif name == 'PartNumberMarker':
|
|
187
|
+
self.part_number_marker = value
|
|
188
|
+
elif name == 'NextPartNumberMarker':
|
|
189
|
+
self.next_part_number_marker = value
|
|
190
|
+
elif name == 'MaxParts':
|
|
191
|
+
self.max_parts = int(value)
|
|
192
|
+
elif name == 'IsTruncated':
|
|
193
|
+
if value == 'true':
|
|
194
|
+
self.is_truncated = True
|
|
195
|
+
else:
|
|
196
|
+
self.is_truncated = False
|
|
197
|
+
elif name == 'Initiated':
|
|
198
|
+
self.initiated = value
|
|
199
|
+
else:
|
|
200
|
+
setattr(self, name, value)
|
|
201
|
+
|
|
202
|
+
def get_all_parts(self, max_parts=None, part_number_marker=None):
|
|
203
|
+
"""
|
|
204
|
+
Return the uploaded parts of this MultiPart Upload. This is
|
|
205
|
+
a lower-level method that requires you to manually page through
|
|
206
|
+
results. To simplify this process, you can just use the
|
|
207
|
+
object itself as an iterator and it will automatically handle
|
|
208
|
+
all of the paging with S3.
|
|
209
|
+
"""
|
|
210
|
+
self._parts = []
|
|
211
|
+
query_args = 'uploadId=%s' % self.id
|
|
212
|
+
if max_parts:
|
|
213
|
+
query_args += '&max-parts=%d' % max_parts
|
|
214
|
+
if part_number_marker:
|
|
215
|
+
query_args += '&part-number-marker=%s' % part_number_marker
|
|
216
|
+
response = self.bucket.connection.make_request('GET', self.bucket.name,
|
|
217
|
+
self.key_name,
|
|
218
|
+
query_args=query_args)
|
|
219
|
+
body = response.read()
|
|
220
|
+
if response.status == 200:
|
|
221
|
+
h = handler.XmlHandler(self, self)
|
|
222
|
+
xml.sax.parseString(body, h)
|
|
223
|
+
return self._parts
|
|
224
|
+
|
|
225
|
+
def upload_part_from_file(self, fp, part_num, headers=None, replace=True,
|
|
226
|
+
cb=None, num_cb=10, md5=None, size=None):
|
|
227
|
+
"""
|
|
228
|
+
Upload another part of this MultiPart Upload.
|
|
229
|
+
|
|
230
|
+
:type fp: file
|
|
231
|
+
:param fp: The file object you want to upload.
|
|
232
|
+
|
|
233
|
+
:type part_num: int
|
|
234
|
+
:param part_num: The number of this part.
|
|
235
|
+
|
|
236
|
+
The other parameters are exactly as defined for the
|
|
237
|
+
:class:`boto.s3.key.Key` set_contents_from_file method.
|
|
238
|
+
"""
|
|
239
|
+
if part_num < 1:
|
|
240
|
+
raise ValueError('Part numbers must be greater than zero')
|
|
241
|
+
query_args = 'uploadId=%s&partNumber=%d' % (self.id, part_num)
|
|
242
|
+
key = self.bucket.new_key(self.key_name)
|
|
243
|
+
key.set_contents_from_file(fp, headers=headers, replace=replace,
|
|
244
|
+
cb=cb, num_cb=num_cb, md5=md5,
|
|
245
|
+
reduced_redundancy=False,
|
|
246
|
+
query_args=query_args, size=size)
|
|
247
|
+
|
|
248
|
+
def copy_part_from_key(self, src_bucket_name, src_key_name, part_num,
|
|
249
|
+
start=None, end=None, src_version_id=None,
|
|
250
|
+
headers=None):
|
|
251
|
+
"""
|
|
252
|
+
Copy another part of this MultiPart Upload.
|
|
253
|
+
|
|
254
|
+
:type src_bucket_name: string
|
|
255
|
+
:param src_bucket_name: Name of the bucket containing the source key
|
|
256
|
+
|
|
257
|
+
:type src_key_name: string
|
|
258
|
+
:param src_key_name: Name of the source key
|
|
259
|
+
|
|
260
|
+
:type part_num: int
|
|
261
|
+
:param part_num: The number of this part.
|
|
262
|
+
|
|
263
|
+
:type start: int
|
|
264
|
+
:param start: Zero-based byte offset to start copying from
|
|
265
|
+
|
|
266
|
+
:type end: int
|
|
267
|
+
:param end: Zero-based byte offset to copy to
|
|
268
|
+
|
|
269
|
+
:type src_version_id: string
|
|
270
|
+
:param src_version_id: version_id of source object to copy from
|
|
271
|
+
|
|
272
|
+
:type headers: dict
|
|
273
|
+
:param headers: Any headers to pass along in the request
|
|
274
|
+
"""
|
|
275
|
+
if part_num < 1:
|
|
276
|
+
raise ValueError('Part numbers must be greater than zero')
|
|
277
|
+
query_args = 'uploadId=%s&partNumber=%d' % (self.id, part_num)
|
|
278
|
+
if start is not None and end is not None:
|
|
279
|
+
rng = 'bytes=%s-%s' % (start, end)
|
|
280
|
+
provider = self.bucket.connection.provider
|
|
281
|
+
if headers is None:
|
|
282
|
+
headers = {}
|
|
283
|
+
else:
|
|
284
|
+
headers = headers.copy()
|
|
285
|
+
headers[provider.copy_source_range_header] = rng
|
|
286
|
+
return self.bucket.copy_key(self.key_name, src_bucket_name,
|
|
287
|
+
src_key_name,
|
|
288
|
+
src_version_id=src_version_id,
|
|
289
|
+
storage_class=None,
|
|
290
|
+
headers=headers,
|
|
291
|
+
query_args=query_args)
|
|
292
|
+
|
|
293
|
+
def complete_upload(self):
|
|
294
|
+
"""
|
|
295
|
+
Complete the MultiPart Upload operation. This method should
|
|
296
|
+
be called when all parts of the file have been successfully
|
|
297
|
+
uploaded to S3.
|
|
298
|
+
|
|
299
|
+
:rtype: :class:`boto.s3.multipart.CompletedMultiPartUpload`
|
|
300
|
+
:returns: An object representing the completed upload.
|
|
301
|
+
"""
|
|
302
|
+
xml = self.to_xml()
|
|
303
|
+
return self.bucket.complete_multipart_upload(self.key_name,
|
|
304
|
+
self.id, xml)
|
|
305
|
+
|
|
306
|
+
def cancel_upload(self):
|
|
307
|
+
"""
|
|
308
|
+
Cancels a MultiPart Upload operation. The storage consumed by
|
|
309
|
+
any previously uploaded parts will be freed. However, if any
|
|
310
|
+
part uploads are currently in progress, those part uploads
|
|
311
|
+
might or might not succeed. As a result, it might be necessary
|
|
312
|
+
to abort a given multipart upload multiple times in order to
|
|
313
|
+
completely free all storage consumed by all parts.
|
|
314
|
+
"""
|
|
315
|
+
self.bucket.cancel_multipart_upload(self.key_name, self.id)
|
|
Binary file
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
4
|
+
# copy of this software and associated documentation files (the
|
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish, dis-
|
|
7
|
+
# tribute, sublicense, and/or sell copies of the Software, and to permit
|
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the fol-
|
|
9
|
+
# lowing conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included
|
|
12
|
+
# in all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
15
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
|
|
16
|
+
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
17
|
+
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
20
|
+
# IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
class Prefix(object):
|
|
23
|
+
def __init__(self, bucket=None, name=None):
|
|
24
|
+
self.bucket = bucket
|
|
25
|
+
self.name = name
|
|
26
|
+
|
|
27
|
+
def startElement(self, name, attrs, connection):
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
def endElement(self, name, value, connection):
|
|
31
|
+
if name == 'Prefix':
|
|
32
|
+
self.name = value
|
|
33
|
+
else:
|
|
34
|
+
setattr(self, name, value)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def provider(self):
|
|
38
|
+
provider = None
|
|
39
|
+
if self.bucket and self.bucket.connection:
|
|
40
|
+
provider = self.bucket.connection.provider
|
|
41
|
+
return provider
|
|
42
|
+
|
|
Binary file
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# Copyright 2010 Google Inc.
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
4
|
+
# copy of this software and associated documentation files (the
|
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish, dis-
|
|
7
|
+
# tribute, sublicense, and/or sell copies of the Software, and to permit
|
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the fol-
|
|
9
|
+
# lowing conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included
|
|
12
|
+
# in all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
15
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
|
|
16
|
+
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
17
|
+
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
20
|
+
# IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
import errno
|
|
23
|
+
import httplib
|
|
24
|
+
import os
|
|
25
|
+
import re
|
|
26
|
+
import socket
|
|
27
|
+
import time
|
|
28
|
+
import boto
|
|
29
|
+
from boto import config, storage_uri_for_key
|
|
30
|
+
from boto.connection import AWSAuthConnection
|
|
31
|
+
from boto.exception import ResumableDownloadException
|
|
32
|
+
from boto.exception import ResumableTransferDisposition
|
|
33
|
+
from boto.s3.keyfile import KeyFile
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
Resumable download handler.
|
|
37
|
+
|
|
38
|
+
Resumable downloads will retry failed downloads, resuming at the byte count
|
|
39
|
+
completed by the last download attempt. If too many retries happen with no
|
|
40
|
+
progress (per configurable num_retries param), the download will be aborted.
|
|
41
|
+
|
|
42
|
+
The caller can optionally specify a tracker_file_name param in the
|
|
43
|
+
ResumableDownloadHandler constructor. If you do this, that file will
|
|
44
|
+
save the state needed to allow retrying later, in a separate process
|
|
45
|
+
(e.g., in a later run of gsutil).
|
|
46
|
+
|
|
47
|
+
Note that resumable downloads work across providers (they depend only
|
|
48
|
+
on support Range GETs), but this code is in the boto.s3 package
|
|
49
|
+
because it is the wrong abstraction level to go in the top-level boto
|
|
50
|
+
package.
|
|
51
|
+
|
|
52
|
+
TODO: At some point we should refactor the code to have a storage_service
|
|
53
|
+
package where all these provider-independent files go.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ByteTranslatingCallbackHandler(object):
|
|
58
|
+
"""
|
|
59
|
+
Proxy class that translates progress callbacks made by
|
|
60
|
+
boto.s3.Key.get_file(), taking into account that we're resuming
|
|
61
|
+
a download.
|
|
62
|
+
"""
|
|
63
|
+
def __init__(self, proxied_cb, download_start_point):
|
|
64
|
+
self.proxied_cb = proxied_cb
|
|
65
|
+
self.download_start_point = download_start_point
|
|
66
|
+
|
|
67
|
+
def call(self, total_bytes_uploaded, total_size):
|
|
68
|
+
self.proxied_cb(self.download_start_point + total_bytes_uploaded,
|
|
69
|
+
total_size)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_cur_file_size(fp, position_to_eof=False):
|
|
73
|
+
"""
|
|
74
|
+
Returns size of file, optionally leaving fp positioned at EOF.
|
|
75
|
+
"""
|
|
76
|
+
if isinstance(fp, KeyFile) and not position_to_eof:
|
|
77
|
+
# Avoid EOF seek for KeyFile case as it's very inefficient.
|
|
78
|
+
return fp.getkey().size
|
|
79
|
+
if not position_to_eof:
|
|
80
|
+
cur_pos = fp.tell()
|
|
81
|
+
fp.seek(0, os.SEEK_END)
|
|
82
|
+
cur_file_size = fp.tell()
|
|
83
|
+
if not position_to_eof:
|
|
84
|
+
fp.seek(cur_pos, os.SEEK_SET)
|
|
85
|
+
return cur_file_size
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ResumableDownloadHandler(object):
|
|
89
|
+
"""
|
|
90
|
+
Handler for resumable downloads.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
ETAG_REGEX = '([a-z0-9]{32})\n'
|
|
94
|
+
|
|
95
|
+
RETRYABLE_EXCEPTIONS = (httplib.HTTPException, IOError, socket.error,
|
|
96
|
+
socket.gaierror)
|
|
97
|
+
|
|
98
|
+
def __init__(self, tracker_file_name=None, num_retries=None):
|
|
99
|
+
"""
|
|
100
|
+
Constructor. Instantiate once for each downloaded file.
|
|
101
|
+
|
|
102
|
+
:type tracker_file_name: string
|
|
103
|
+
:param tracker_file_name: optional file name to save tracking info
|
|
104
|
+
about this download. If supplied and the current process fails
|
|
105
|
+
the download, it can be retried in a new process. If called
|
|
106
|
+
with an existing file containing an unexpired timestamp,
|
|
107
|
+
we'll resume the transfer for this file; else we'll start a
|
|
108
|
+
new resumable download.
|
|
109
|
+
|
|
110
|
+
:type num_retries: int
|
|
111
|
+
:param num_retries: the number of times we'll re-try a resumable
|
|
112
|
+
download making no progress. (Count resets every time we get
|
|
113
|
+
progress, so download can span many more than this number of
|
|
114
|
+
retries.)
|
|
115
|
+
"""
|
|
116
|
+
self.tracker_file_name = tracker_file_name
|
|
117
|
+
self.num_retries = num_retries
|
|
118
|
+
self.etag_value_for_current_download = None
|
|
119
|
+
if tracker_file_name:
|
|
120
|
+
self._load_tracker_file_etag()
|
|
121
|
+
# Save download_start_point in instance state so caller can
|
|
122
|
+
# find how much was transferred by this ResumableDownloadHandler
|
|
123
|
+
# (across retries).
|
|
124
|
+
self.download_start_point = None
|
|
125
|
+
|
|
126
|
+
def _load_tracker_file_etag(self):
|
|
127
|
+
f = None
|
|
128
|
+
try:
|
|
129
|
+
f = open(self.tracker_file_name, 'r')
|
|
130
|
+
etag_line = f.readline()
|
|
131
|
+
m = re.search(self.ETAG_REGEX, etag_line)
|
|
132
|
+
if m:
|
|
133
|
+
self.etag_value_for_current_download = m.group(1)
|
|
134
|
+
else:
|
|
135
|
+
print('Couldn\'t read etag in tracker file (%s). Restarting '
|
|
136
|
+
'download from scratch.' % self.tracker_file_name)
|
|
137
|
+
except IOError, e:
|
|
138
|
+
# Ignore non-existent file (happens first time a download
|
|
139
|
+
# is attempted on an object), but warn user for other errors.
|
|
140
|
+
if e.errno != errno.ENOENT:
|
|
141
|
+
# Will restart because
|
|
142
|
+
# self.etag_value_for_current_download == None.
|
|
143
|
+
print('Couldn\'t read URI tracker file (%s): %s. Restarting '
|
|
144
|
+
'download from scratch.' %
|
|
145
|
+
(self.tracker_file_name, e.strerror))
|
|
146
|
+
finally:
|
|
147
|
+
if f:
|
|
148
|
+
f.close()
|
|
149
|
+
|
|
150
|
+
def _save_tracker_info(self, key):
|
|
151
|
+
self.etag_value_for_current_download = key.etag.strip('"\'')
|
|
152
|
+
if not self.tracker_file_name:
|
|
153
|
+
return
|
|
154
|
+
f = None
|
|
155
|
+
try:
|
|
156
|
+
f = open(self.tracker_file_name, 'w')
|
|
157
|
+
f.write('%s\n' % self.etag_value_for_current_download)
|
|
158
|
+
except IOError, e:
|
|
159
|
+
raise ResumableDownloadException(
|
|
160
|
+
'Couldn\'t write tracker file (%s): %s.\nThis can happen'
|
|
161
|
+
'if you\'re using an incorrectly configured download tool\n'
|
|
162
|
+
'(e.g., gsutil configured to save tracker files to an '
|
|
163
|
+
'unwritable directory)' %
|
|
164
|
+
(self.tracker_file_name, e.strerror),
|
|
165
|
+
ResumableTransferDisposition.ABORT)
|
|
166
|
+
finally:
|
|
167
|
+
if f:
|
|
168
|
+
f.close()
|
|
169
|
+
|
|
170
|
+
def _remove_tracker_file(self):
|
|
171
|
+
if (self.tracker_file_name and
|
|
172
|
+
os.path.exists(self.tracker_file_name)):
|
|
173
|
+
os.unlink(self.tracker_file_name)
|
|
174
|
+
|
|
175
|
+
def _attempt_resumable_download(self, key, fp, headers, cb, num_cb,
|
|
176
|
+
torrent, version_id):
|
|
177
|
+
"""
|
|
178
|
+
Attempts a resumable download.
|
|
179
|
+
|
|
180
|
+
Raises ResumableDownloadException if any problems occur.
|
|
181
|
+
"""
|
|
182
|
+
cur_file_size = get_cur_file_size(fp, position_to_eof=True)
|
|
183
|
+
|
|
184
|
+
if (cur_file_size and
|
|
185
|
+
self.etag_value_for_current_download and
|
|
186
|
+
self.etag_value_for_current_download == key.etag.strip('"\'')):
|
|
187
|
+
# Try to resume existing transfer.
|
|
188
|
+
if cur_file_size > key.size:
|
|
189
|
+
raise ResumableDownloadException(
|
|
190
|
+
'%s is larger (%d) than %s (%d).\nDeleting tracker file, so '
|
|
191
|
+
'if you re-try this download it will start from scratch' %
|
|
192
|
+
(fp.name, cur_file_size, str(storage_uri_for_key(key)),
|
|
193
|
+
key.size), ResumableTransferDisposition.ABORT)
|
|
194
|
+
elif cur_file_size == key.size:
|
|
195
|
+
if key.bucket.connection.debug >= 1:
|
|
196
|
+
print 'Download complete.'
|
|
197
|
+
return
|
|
198
|
+
if key.bucket.connection.debug >= 1:
|
|
199
|
+
print 'Resuming download.'
|
|
200
|
+
headers = headers.copy()
|
|
201
|
+
headers['Range'] = 'bytes=%d-%d' % (cur_file_size, key.size - 1)
|
|
202
|
+
cb = ByteTranslatingCallbackHandler(cb, cur_file_size).call
|
|
203
|
+
self.download_start_point = cur_file_size
|
|
204
|
+
else:
|
|
205
|
+
if key.bucket.connection.debug >= 1:
|
|
206
|
+
print 'Starting new resumable download.'
|
|
207
|
+
self._save_tracker_info(key)
|
|
208
|
+
self.download_start_point = 0
|
|
209
|
+
# Truncate the file, in case a new resumable download is being
|
|
210
|
+
# started atop an existing file.
|
|
211
|
+
fp.truncate(0)
|
|
212
|
+
|
|
213
|
+
# Disable AWSAuthConnection-level retry behavior, since that would
|
|
214
|
+
# cause downloads to restart from scratch.
|
|
215
|
+
key.get_file(fp, headers, cb, num_cb, torrent, version_id,
|
|
216
|
+
override_num_retries=0)
|
|
217
|
+
fp.flush()
|
|
218
|
+
|
|
219
|
+
def get_file(self, key, fp, headers, cb=None, num_cb=10, torrent=False,
|
|
220
|
+
version_id=None):
|
|
221
|
+
"""
|
|
222
|
+
Retrieves a file from a Key
|
|
223
|
+
:type key: :class:`boto.s3.key.Key` or subclass
|
|
224
|
+
:param key: The Key object from which upload is to be downloaded
|
|
225
|
+
|
|
226
|
+
:type fp: file
|
|
227
|
+
:param fp: File pointer into which data should be downloaded
|
|
228
|
+
|
|
229
|
+
:type headers: string
|
|
230
|
+
:param: headers to send when retrieving the files
|
|
231
|
+
|
|
232
|
+
:type cb: function
|
|
233
|
+
:param cb: (optional) a callback function that will be called to report
|
|
234
|
+
progress on the download. The callback should accept two integer
|
|
235
|
+
parameters, the first representing the number of bytes that have
|
|
236
|
+
been successfully transmitted from the storage service and
|
|
237
|
+
the second representing the total number of bytes that need
|
|
238
|
+
to be transmitted.
|
|
239
|
+
|
|
240
|
+
:type num_cb: int
|
|
241
|
+
:param num_cb: (optional) If a callback is specified with the cb
|
|
242
|
+
parameter this parameter determines the granularity of the callback
|
|
243
|
+
by defining the maximum number of times the callback will be
|
|
244
|
+
called during the file transfer.
|
|
245
|
+
|
|
246
|
+
:type torrent: bool
|
|
247
|
+
:param torrent: Flag for whether to get a torrent for the file
|
|
248
|
+
|
|
249
|
+
:type version_id: string
|
|
250
|
+
:param version_id: The version ID (optional)
|
|
251
|
+
|
|
252
|
+
Raises ResumableDownloadException if a problem occurs during
|
|
253
|
+
the transfer.
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
debug = key.bucket.connection.debug
|
|
257
|
+
if not headers:
|
|
258
|
+
headers = {}
|
|
259
|
+
|
|
260
|
+
# Use num-retries from constructor if one was provided; else check
|
|
261
|
+
# for a value specified in the boto config file; else default to 5.
|
|
262
|
+
if self.num_retries is None:
|
|
263
|
+
self.num_retries = config.getint('Boto', 'num_retries', 5)
|
|
264
|
+
progress_less_iterations = 0
|
|
265
|
+
|
|
266
|
+
while True: # Retry as long as we're making progress.
|
|
267
|
+
had_file_bytes_before_attempt = get_cur_file_size(fp)
|
|
268
|
+
try:
|
|
269
|
+
self._attempt_resumable_download(key, fp, headers, cb, num_cb,
|
|
270
|
+
torrent, version_id)
|
|
271
|
+
# Download succceded, so remove the tracker file (if have one).
|
|
272
|
+
self._remove_tracker_file()
|
|
273
|
+
# Previously, check_final_md5() was called here to validate
|
|
274
|
+
# downloaded file's checksum, however, to be consistent with
|
|
275
|
+
# non-resumable downloads, this call was removed. Checksum
|
|
276
|
+
# validation of file contents should be done by the caller.
|
|
277
|
+
if debug >= 1:
|
|
278
|
+
print 'Resumable download complete.'
|
|
279
|
+
return
|
|
280
|
+
except self.RETRYABLE_EXCEPTIONS, e:
|
|
281
|
+
if debug >= 1:
|
|
282
|
+
print('Caught exception (%s)' % e.__repr__())
|
|
283
|
+
if isinstance(e, IOError) and e.errno == errno.EPIPE:
|
|
284
|
+
# Broken pipe error causes httplib to immediately
|
|
285
|
+
# close the socket (http://bugs.python.org/issue5542),
|
|
286
|
+
# so we need to close and reopen the key before resuming
|
|
287
|
+
# the download.
|
|
288
|
+
key.get_file(fp, headers, cb, num_cb, torrent, version_id,
|
|
289
|
+
override_num_retries=0)
|
|
290
|
+
except ResumableDownloadException, e:
|
|
291
|
+
if (e.disposition ==
|
|
292
|
+
ResumableTransferDisposition.ABORT_CUR_PROCESS):
|
|
293
|
+
if debug >= 1:
|
|
294
|
+
print('Caught non-retryable ResumableDownloadException '
|
|
295
|
+
'(%s)' % e.message)
|
|
296
|
+
raise
|
|
297
|
+
elif (e.disposition ==
|
|
298
|
+
ResumableTransferDisposition.ABORT):
|
|
299
|
+
if debug >= 1:
|
|
300
|
+
print('Caught non-retryable ResumableDownloadException '
|
|
301
|
+
'(%s); aborting and removing tracker file' %
|
|
302
|
+
e.message)
|
|
303
|
+
self._remove_tracker_file()
|
|
304
|
+
raise
|
|
305
|
+
else:
|
|
306
|
+
if debug >= 1:
|
|
307
|
+
print('Caught ResumableDownloadException (%s) - will '
|
|
308
|
+
'retry' % e.message)
|
|
309
|
+
|
|
310
|
+
# At this point we had a re-tryable failure; see if made progress.
|
|
311
|
+
if get_cur_file_size(fp) > had_file_bytes_before_attempt:
|
|
312
|
+
progress_less_iterations = 0
|
|
313
|
+
else:
|
|
314
|
+
progress_less_iterations += 1
|
|
315
|
+
|
|
316
|
+
if progress_less_iterations > self.num_retries:
|
|
317
|
+
# Don't retry any longer in the current process.
|
|
318
|
+
raise ResumableDownloadException(
|
|
319
|
+
'Too many resumable download attempts failed without '
|
|
320
|
+
'progress. You might try this download again later',
|
|
321
|
+
ResumableTransferDisposition.ABORT_CUR_PROCESS)
|
|
322
|
+
|
|
323
|
+
# Close the key, in case a previous download died partway
|
|
324
|
+
# through and left data in the underlying key HTTP buffer.
|
|
325
|
+
# Do this within a try/except block in case the connection is
|
|
326
|
+
# closed (since key.close() attempts to do a final read, in which
|
|
327
|
+
# case this read attempt would get an IncompleteRead exception,
|
|
328
|
+
# which we can safely ignore.
|
|
329
|
+
try:
|
|
330
|
+
key.close()
|
|
331
|
+
except httplib.IncompleteRead:
|
|
332
|
+
pass
|
|
333
|
+
|
|
334
|
+
sleep_time_secs = 2**progress_less_iterations
|
|
335
|
+
if debug >= 1:
|
|
336
|
+
print('Got retryable failure (%d progress-less in a row).\n'
|
|
337
|
+
'Sleeping %d seconds before re-trying' %
|
|
338
|
+
(progress_less_iterations, sleep_time_secs))
|
|
339
|
+
time.sleep(sleep_time_secs)
|