S3(n)
โจ S3 โ Amazon S3 Web Service Interface โจ
okay bestie, sit down, hydrate, because we're about to read the manual page for the S3 package ๐ โ it's the Tcl interface to Amazon's Simple Storage Solution web service, and it is so much. Manual name: S3(n), section n. Let's go ๐ฆ
๐ธ SYNOPSIS ๐ธ
package require Tcl 8.5 9
package require S3 ?1.0.5?
package require sha1 1.1
package require md5 2.1
package require base64 2.4
package require xsxp 1.1
S3::Configure ?-reset boolean? ?-retries integer? ?-accesskeyid idstring? ?-secretaccesskey idstring? ?-service-access-point FQDN? ?-use-tls boolean? ?-default-compare always|never|exists|missing|newer|date|checksum|different? ?-default-separator string? ?-default-acl private|public-read|public-read-write|authenticated-read|keep|calc? ?-default-bucket bucketname?
S3::SuggestBucket ?name?
S3::REST dict
S3::ListAllMyBuckets ?-blocking boolean? ?-parse-xml xmlstring? ?-result-type REST|xml|pxml|dict|names|owner?
S3::PutBucket ?-bucket bucketname? ?-blocking boolean? ?-acl {}|private|public-read|public-read-write|authenticated-read?
S3::DeleteBucket ?-bucket bucketname? ?-blocking boolean?
S3::GetBucket ?-bucket bucketname? ?-blocking boolean? ?-parse-xml xmlstring? ?-max-count integer? ?-prefix prefixstring? ?-delimiter delimiterstring? ?-result-type REST|xml|pxml|names|dict?
S3::Put ?-bucket bucketname? -resource resourcename ?-blocking boolean? ?-file filename? ?-content contentstring? ?-acl private|public-read|public-read-write|authenticated-read|calc|keep? ?-content-type contenttypestring? ?-x-amz-meta-* metadatatext? ?-compare comparemode?
S3::Get ?-bucket bucketname? -resource resourcename ?-blocking boolean? ?-compare comparemode? ?-file filename? ?-content contentvarname? ?-timestamp aws|now? ?-headers headervarname?
S3::Head ?-bucket bucketname? -resource resourcename ?-blocking boolean? ?-dict dictvarname? ?-headers headersvarname? ?-status statusvarname?
S3::GetAcl ?-blocking boolean? ?-bucket bucketname? -resource resourcename ?-result-type REST|xml|pxml?
S3::PutAcl ?-blocking boolean? ?-bucket bucketname? -resource resourcename ?-acl new-acl?
S3::Delete ?-bucket bucketname? -resource resourcename ?-blocking boolean? ?-status statusvar?
S3::Push ?-bucket bucketname? -directory directoryname ?-prefix prefixstring? ?-compare comparemode? ?-x-amz-meta-* metastring? ?-acl aclcode? ?-delete boolean? ?-error throw|break|continue? ?-progress scriptprefix?
S3::Pull ?-bucket bucketname? -directory directoryname ?-prefix prefixstring? ?-blocking boolean? ?-compare comparemode? ?-delete boolean? ?-timestamp aws|now? ?-error throw|break|continue? ?-progress scriptprefix?
S3::Toss ?-bucket bucketname? -prefix prefixstring ?-blocking boolean? ?-error throw|break|continue? ?-progress scriptprefix?
look at all those options, she's serving range ๐
๐ DESCRIPTION ๐
So this package gives you access to Amazon's Simple Storage Solution web service. โจ
Quick summary bestie: Amazon Simple Storage Solution is a for-fee web service that lets you store arbitrary data as "resources" inside "buckets" online. Head to http://www.amazonaws.com/ if you want the deets on that whole system. You reach the service over HTTP, either SOAP or REST. And like โ real talk โ a whole lot of this documentation is gonna be giving nothing if you're not already familiar with the terms and functionality of the Amazon S3 service. ๐ซถ
This package provides the services for reading and writing the data items via the REST interface. It also hooks you up with some higher-level operations. Other packages in the same distribution provide even more functionality. ๐
Copyright 2006 Darren New. All Rights Reserved. NO WARRANTIES OF ANY TYPE ARE PROVIDED. COPYING OR USE INDEMNIFIES THE AUTHOR IN ALL WAYS. This software is licensed under essentially the same terms as Tcl. See LICENSE.txt for the terms.
not me putting the legal bit in pink, but seriously bestie, no warranties of any type, periodt ๐
๐ญ ERROR REPORTING ๐ญ
The error reporting from this package makes use of $errorCode to spill more details on what happened than just throwing an error would. Any error caught by the S3 package (and we try to catch them all) comes back with an $errorCode that's a list having at least three elements. In all cases, the first element will be "S3". The second element takes on one of six values, and that element defines the value of the third and subsequent elements. S3::REST does not throw an error, it just returns a dictionary with the keys "error", "errorInfo", and "errorCode" set. That's what lets it be used reliably in the background. โจ
The possible second elements are these:
usageโ The usage of the package is incorrect. For example, a command has been invoked which requires the library to be configured before the library has been configured, or an invalid combination of options has been specified. The third element of$errorCodesupplies the name of the parameter that was wrong. The fourth usually provides the arguments that were actually supplied to the throwing proc, unless the usage error isn't confined to a single proc.localโ Something happened on the local system which threw an error. For example, a request to upload or download a file was made and the file permissions denied that sort of access. The third element of$errorCodeis the original$errorCode.socketโ Something happened with the socket. It closed prematurely, or some other condition of failure-to-communicate-with-Amazon was detected. The third element of$errorCodeis the original$errorCode, or sometimes the message fromfcopy, or ...? (the "or ...?" is canon, I'm not making that up bestie ๐)remoteโ The Amazon web service returned an error code outside the 2xx range in the HTTP header. In other words, everything went as documented, except this particular case was documented not to work. The third element is the dictionary returned from::S3::REST. Note thatS3::RESTitself never throws this error, but just returns the dictionary. Most of the higher-level commands throw for convenience, unless an argument indicates they should not. If something is documented as "not throwing an S3 remote error", it means a status return is set rather than throwing an error if Amazon returns a non-2XX HTTP result code.notyetโ The user obeyed the documentation, but the author has not yet gotten around to implementing this feature. (Right now, only TLS support and sophisticated permissions fall into this category, as well as theS3::Aclcommand.)xmlโ The service has returned invalid XML, or XML whose schema is unexpected. For the high-level commands that accept service XML as input for parsing, this may also be thrown.
๐ COMMANDS ๐
This package provides several separate levels of complexity. a whole hierarchy, she contains multitudes ๐ฆ
- The lowest level simply takes arguments to be sent to the service, sends them, retrieves the result, and provides it to the caller. Note: This layer allows both synchronous and event-driven processing. It depends on the MD5 and SHA1 and base64 packages from Tcllib (available at
http://core.tcl.tk/tcllib/). Note thatS3::Configureis required forS3::RESTto work due to the authentication portion, so we put that in the "lowest level." - The next layer parses the results of calls, allowing for functionality such as uploading only changed files, synchronizing directories, and so on. This layer depends on the TclXML package as well as the included
xsxppackage. These packages are package required when these more-sophisticated routines are called, so nothing breaks if they are not correctly installed. - Also included is a separate program that uses the library. It provides code to parse
$argv0and$argvfrom the command line, allowing invocation as atclkit, etc. (Not yet implmented.) โ yes that typo is verbatim, I'm preserving the artifacts, it's part of the vibe โจ - Another separate program provides a GUI interface allowing drag-and-drop and other such functionality. (Not yet implemented.)
- Also built on this package is the OddJob program. It is a separate program designed to allow distribution of computational work units over Amazon's Elastic Compute Cloud web service.
The goal is to have at least the bottom-most layers implemented in pure Tcl using only that which comes from widely-available sources, such as Tcllib. ๐
๐ง LOW LEVEL COMMANDS ๐ง
These commands do not require any packages not listed above. They talk directly to the service, or they are utility or configuration routines. Note that the xsxp package was written to support this package, so it should be available wherever you got this package. ๐
S3::Configure ?-reset boolean? ?-retries integer? ?-accesskeyid idstring? ?-secretaccesskey idstring? ?-service-access-point FQDN? ?-use-tls boolean? ?-default-compare always|never|exists|missing|newer|date|checksum|different? ?-default-separator string? ?-default-acl private|public-read|public-read-write|authenticated-read|keep|calc? ?-default-bucket bucketname?
There is one command for configuration, and that is S3::Configure. Here's the tea:
- Called with no arguments, it returns a dictionary of key/value pairs listing all current settings. ๐
- Called with one argument, it returns the value of that single argument.
- Called with two or more arguments, it must be called with pairs of arguments, and it applies the changes in order.
There is only one set of configuration information per interpreter. ๐ฆ
The following options are accepted:
-reset booleanโ By default,false. If true, any previous changes and any changes on the same call before the reset option will be returned to default values. it's giving factory reset but for your config ๐-retries integerโ Default value is3. If Amazon returns a500error, a retry after an exponential backoff delay will be tried this many times before finally throwing the500error. This applies to each call toS3::RESTfrom the higher-level commands, but not toS3::RESTitself. That is,S3::RESTwill always returnhttpstatus 500if that's what it receives. Functions likeS3::Putwill retry thePUTcall, and will also retry theGETandHEADcalls used to do content comparison. Changing this to0will prevent retries and their associated delays. In addition, socket errors (i.e., errors whoseerrorCodestarts with"S3 socket") will be similarly retried after backoffs. ๐ฅ-accesskeyid idstring-secretaccesskey idstringโ both of these default to an empty string, and bestie you have to set them before you make literally any calls. This is your S3 ID ๐ณ. Once you sign up for an account, go tohttp://www.amazonaws.com/, sign in, hit the "Your Web Services Account" button, pick "AWS Access Identifiers", and boom โ your access key ID and secret access key are right there. Every singleS3::RESTcall is authenticated. Blame Amazon for the poor choice of names, not me ๐.-service-access-point FQDNโ defaults to"s3.amazonaws.com". This is the fully-qualified domain name of the server to contact forS3::RESTcalls. You should probably never need to touch this, unless someone else implements a compatible service, or you wanna test something by pointing the library at your own service ๐.-slop-seconds integerโ when comparing dates between Amazon and the local machine, two dates within this many seconds of each other are considered the same. So useful for clock drift correction, processing overhead time, and so on โฐ.-use-tls booleanโ defaults tofalse. This is not yet implemented ๐. Iftrue,S3::RESTwill negotiate a TLS connection to Amazon. Iffalse, unencrypted connections are used.-bucket-prefix stringโ defaults to"TclS3". This string is used byS3::SuggestBucketNameif that command is passed an empty string as an argument. It's how you tell different applications using the Amazon service apart. Your application should always set this, fr fr, to keep from interfering with the buckets of other users of Amazon S3 or with other buckets of the same user ๐ซถ.-default-compare always|never|exists|missing|newer|date|checksum|differentโ defaults to"always."If no-compareis specified onS3::Put,S3::Get, orS3::Delete, this comparison is used. Go see those commands for what the meanings actually are ๐-default-separator stringโ defaults to"/". This is currently unused. It might make sense to use this forS3::PushandS3::Pull, but allowing resources to have slashes in their names that aren't marking directories would be problematic. Hence, this currently does absolutely nothing ๐ .-default-acl private|public-read|public-read-write|authenticated-read|keep|calcโ defaults to an empty string. If no-aclargument is provided toS3::PutorS3::Push, this string is used (given as thex-amz-aclheader if notkeeporcalc). If this is also empty, nox-amz-aclheader is generated. This is not used byS3::REST๐ซ.-default-bucket bucketnameโ if no bucket is given toS3::GetBucket,S3::PutBucket,S3::Get,S3::Put,S3::Head,S3::Acl,S3::Delete,S3::Push,S3::Pull, orS3::Toss, and if this configuration variable is not an empty string (and not simply"/"), then this value will be used for the bucket. Super handy if one program does a large amount of resource manipulation within a single bucket ๐ชฃโจ.
๐ S3::SuggestBucket ?name? ๐
The S3::SuggestBucket command accepts an optional string as a prefix and returns a valid bucket containing the name argument and the Access Key ID. This makes the name unique to the owner and to the application (assuming the application picks a good name argument) ๐ฅ.
If no name is provided, the name from S3::Configure -bucket-prefix is used. If that too is empty (which is not the default), an error is thrown ๐.
โจ S3::REST dict โจ
The S3::REST command takes as an argument a dictionary and returns a dictionary ๐ฆ. The return dictionary has the same keys as the input dictionary, and includes additional keys as the result. The presence or absence of keys in the input dictionary can control the behavior of the routine. It never throws an error directly, but includes keys "error", "errorInfo", and "errorCode" if necessary. Some keys are required, some optional. The routine can run either in blocking or non-blocking mode, based on the presence of resultvar in the input dictionary. This requires the -accesskeyid and -secretaccesskey to be configured via S3::Configure before being called ๐ don't forget that part.
The possible input keys are these:
verb GET|PUT|DELETE|HEADโ this required item indicates the verb to be used ๐โโ๏ธ.resource stringโ this required item indicates the resource to be accessed. A leading/is added if not there already. It will be URL-encoded for you if necessary. Do not supply a resource name that is already URL-encoded. ๐จ?rtype torrent|acl?โ this indicates a torrent or acl resource is being manipulated. Do not include this in theresourcekey, or the"?"separator will get URL-encoded ๐ญ.?parameters dict?โ this optional dictionary provides parameters added to the URL for the transaction. The keys must be in the correct case (which is confusing in the Amazon documentation) and the values must be valid. This can be an empty dictionary or omitted entirely if no parameters are desired. No other error checking on parameters is performed.?headers dict?โ this optional dictionary provides headers to be added to the HTTP request. The keys must be in lower case for the authentication to work. The values must not contain embedded newlines or carriage returns. This is primarily useful for addingx-amz-*headers. Since authentication is calculated byS3::REST, do not add that header here. Sincecontent-typegets its own key, also do not add that header here ๐ โโ๏ธ.?inbody contentstring?โ this optional item, if provided, gives the content that will be sent. It is sent with a transfer encoding of binary, and only the low bytes are used, so use[encoding convertto utf-8]if the string is a utf-8 string. This is written all in one blast, so if you are using non-blocking mode and theinbodyis especially large, you may wind up blocking on the write socket ๐ฌ.?infile filename?โ this optional item, if provided, and ifinbodyis not provided, names the file from which the body of the HTTP message will be constructed. The file is opened for reading and sent progressively by[fcopy], so it should not block in non-blocking mode even if the file is very large ๐ฆ. The file is transferred in binary mode, so the bytes on your disk will match the bytes in your resource. Due to HTTP restrictions, it must be possible to use[file size]on this file to determine the size at the start of the transaction.?S3chan channel?โ this optional item, if provided, indicates the already-open socket over which the transaction should be conducted. If not provided, a connection is made to the service access point specified viaS3::Configure, which is normallys3.amazonaws.com. If this is provided, the channel is not closed at the end of the transaction ๐.?outchan channel?โ this optional item, if provided, indicates the already-open channel to which the body returned from S3 should be written. That is, to retrieve a large resource, open a file, set the translation mode, and pass the channel as the value of the keyoutchan. Output will be written to the channel in pieces so memory does not fill up unnecessarily ๐ง โจ. The channel is not closed at the end of the transaction.?resultvar varname?โ this optional item, if provided, indicates thatS3::RESTshould run in non-blocking mode. Thevarnameshould be fully qualified with respect to namespaces and cannot be local to a proc. If provided, the result of theS3::RESTcall is assigned to this variable once everything has completed; usetraceorvwaitto know when this has happened ๐. If this key is not provided, the result is simply returned from the call toS3::RESTand no calls to the eventloop are invoked from within this call.?throwsocket throw|return?โ this optional item, if provided, indicates thatS3::RESTshould throw an error ifthrowmodeisthrowand a socket error is encountered. It indicates thatS3::RESTshould return the error code in the returned dictionary if a socket error is encountered and this is set toreturn. Ifthrowsocketis set toreturnor if the call is not blocking, then a socket error (i.e., an error whose error code starts with"S3 socket") will be returned in the dictionary aserror,errorInfo, anderrorCode. If a foreground call is made (i.e.,resultvaris not provided), and this option is not provided or is set tothrow, thenerrorwill be invoked instead ๐ฅ.
Once the call to S3::REST completes, a new dict is returned, either in the resultvar or as the result of execution. This dict is a copy of the original dict with the results added as new keys ๐. The possible new keys are these:
error errorstringerrorInfo errorstringerrorCode errorstring
If an error is caught, these three keys will be set in the result ๐. Note that S3::REST does not consider a non-2XX HTTP return code as an error ๐. The errorCode value will be formatted according to the ERROR REPORTING description. If these are present, other keys described here might not be ๐ซ .
httpstatus threedigitsโ the three-digit code that came back from the HTTP transaction, bestie. 2XX means good, 5XX means server error, etc. etc. ๐httpmessage textโ the little text blurb that trails after the status code. Like"OK"or"Forbidden"or whatever the vibe was. โจoutbody contentstringโ ifoutchanwasn't specified, this key holds a reference to the (unencoded) contents of the body that came back. And if Amazon handed you an error (as in,httpstatusis not a 2XX value, we hate that for us), the error message lives inoutbodyor gets written tooutchanas appropriate. ๐outheaders dictโ a whole dictionary of headers that Amazon sent back. The keys are always lower case. It's mostly there so you can hunt down thex-amz-meta-*headers if there are any, though stuff likelast-modifiedandcontent-typeis lowkey useful too. The keys of this dictionary are always lower case (yes, we said it twice, it's that serious). Both keys and values come trimmed of extraneous whitespace. ๐งผ
๐ HIGH LEVEL COMMANDS ๐
Okay so the routines in this section? They all make use of one or more calls to S3::REST to do their thing, and then they parse and manage the data in a way that's actually convenient. All of these commands throw errors as described in ERROR REPORTING unless it says otherwise. No cap. ๐ซถ
In all these commands, all arguments are presented as name/value pairs, in any order. Every single argument name starts with a hyphen.
There are a few options that are common to many of the commands, and those common options get documented right here. ๐
-blocking booleanโ if this is provided and it's false, then any calls toS3:RESTwill be non-blocking, and internally these routines will call[vwait]to get the results. Translation: these routines still return the same value, but they'll have event loops running while they wait for Amazon to get back to them. multitasking queen ๐-parse-xml xmlstringโ if you provide this, the routine skips actually communicating with Amazon and instead behaves as if the XML string you handed over was returned as the body of the call. Since several of these routines let you get data back in various formats, this argument is how you parse existing XML to extract the bits of info you need. Also super helpful for testing. ๐งช-bucket bucketnameโ almost every high-level command needs to know which bucket the resources live in, and this is how you tell it. (The only command that does not require this parameter is the one that lists available buckets.) You do not need to URL-encode this, even if it's got special or non-ASCII characters in it. It may or may not have leading or trailing spaces โ commands normalize the bucket, we got you. If this isn't supplied, the value is taken fromS3::Configure -default-bucketif that string isn't empty. Note that spaces and slashes are always trimmed from both ends and the rest must leave a valid bucket. โ๏ธ-resource resourcenameโ this specifies the resource of interest within the bucket. It may or may not start with a slash, both cases are handled, don't stress. This does not need to be URL-encoded either, even if it's got special or non-ASCII characters. ๐ธ-compare always|never|exists|missing|newer|date|checksum|differentโ when commands copy resources to files or files to resources, the caller can specify that the copy should be skipped if the contents are the same. This argument says under what conditions the files should actually get copied. If you don't pass it, the result ofS3::Configure -default-compareis used, which in turn defaults to"always."Here's what each value means, bestie:alwaysโ always copy the data. This is the default. ๐neverโ never copy the data. This is basically a no-op, except inS3::PushandS3::Pullwhere the-deleteflag might make a difference.existsโ copy the data only if the destination already exists.missingโ copy the data only if the destination does not already exist.newerโ copy the data if the destination is missing, or if the date on the source is newer than the date on the destination by at leastS3::Configure -slop-secondsseconds. If the source is Amazon, the date is taken from theLast-Modifiedheader. If the source is local, it's taken as the mtime of the file. If the source data was specified as a string rather than a file, it's taken as right now, via[clock seconds]. โฐdateโ likenewer, except copy if the date is newer or older.checksumโ calculate the MD5 checksum on the local file or string, ask Amazon for the eTag of the resource, and copy the data if they're different. Also copy the data if the destination is missing. Heads up: this can be slow with big local files unless the C version of the MD5 support is available. ๐differentโ copy the data if the destination does not exist. If the destination does exist and an actual file name was specified (rather than a content string), and the date on the file differs from the date on the resource, copy the data. If the data is provided as a content string, the "date" is treated as "right now", so it'll likely always differ unless slop-seconds is large. If the dates are the same, the MD5 checksums get compared, and the data gets copied if the checksums differ.
Note that"newer"and"date"don't care about the contents, and"checksum"doesn't care about the dates, but"different"checks both. ๐ฏ
๐ S3::ListAllMyBuckets ๐
S3::ListAllMyBuckets ?-blocking boolean? ?-parse-xml xmlstring?
?-result-type REST|xml|pxml|dict|names|owner?
This routine performs a GET on the Amazon S3 service, which is defined to return a list of buckets owned by the account identified by the authorization header. (Blame Amazon for the dumb names, not us. ๐ญ)
-blocking booleanโ see above for the standard definition.-parse-xml xmlstringโ see above for the standard definition.-result-type RESTโ the dictionary returned byS3::RESTis the return value ofS3::ListAllMyBuckets. In this case, a non-2XXhttpstatuswill not throw an error. You may not combine this with-parse-xml. ๐ซ-result-type xmlโ the raw XML of the body is returned as the result (with no encoding applied).-result-type pxmlโ the XML of the body as parsed byxsxp::parseis returned.-result-type dictโ a dictionary of the interesting portions of the XML is returned. That dictionary contains these keys:Owner/IDโ the Amazon AWS ID (in hex) of the owner of the bucket.Owner/DisplayNameโ the Amazon AWS ID's Display Name.Bucket/Nameโ a list of names, one for each bucket.Bucket/CreationDateโ a list of dates, one for each bucket, in the same order asBucket/Name, in ISO format (as returned by Amazon).
-result-type namesโ a list of bucket names is returned with all other information stripped out. This is the default result type for this command. โจ-result-type ownerโ a list containing two elements is returned. The first element is the owner's ID, and the second is the owner's display name.
๐ฆ S3::PutBucket ๐ฆ
S3::PutBucket ?-bucket bucketname? ?-blocking boolean? ?-acl
{}|private|public-read|public-read-write|authenticated-read?
This command creates a bucket if it doesn't already exist. Bucket names are globally unique, so you may get a "Forbidden" error from Amazon even if you can't see the bucket in S3::ListAllMyBuckets. See S3::SuggestBucket for ways to minimize this risk. The x-amz-acl header comes from the -acl option, or from S3::Configure -default-acl if it wasn't specified. ๐
๐ S3::DeleteBucket ๐
S3::DeleteBucket ?-bucket bucketname? ?-blocking boolean?
This command deletes a bucket if it's empty and you have such permission. Note that Amazon's list of buckets is a global resource, requiring far-flung synchronization. So if you delete a bucket, it may be quite a few minutes (or hours ๐ญ) before you can recreate it, and you'll be getting "Conflict" errors until then. The way that this is giving "you did this to yourself"... but also, slay, we respect the ambition. ๐
๐ S3::GetBucket ๐
S3::GetBucket ?-bucket bucketname? ?-blocking boolean? ?-parse-xml
xmlstring? ?-max-count integer? ?-prefix prefixstring? ?-delimiter
delimiterstring? ?-result-type REST|xml|pxml|names|dict?
This lists the contents of a bucket. That is, it returns a directory listing of resources within a bucket, rather than transferring any user data. It's the "window shopping" of S3 calls, honestly. ๐๏ธ
-bucket bucketnameโ the standard bucket argument.-blocking booleanโ the standard blocking argument.-parse-xml xmlstringโ the standardparse-xmlargument.-max-count integerโ if supplied, this is the most number of records to be returned. If not supplied, the code will iterate until all records have been found. Not compatible with-parse-xml. Note that if this is supplied, only one call toS3::RESTwill be made. Otherwise, enough calls will be made to exhaust the listing, buffering results in memory โ so take care if you might have huge buckets. ๐ซฃ-prefix prefixstringโ if present, restricts the listing to resources with a particular prefix. One leading/is stripped if present.-delimiter delimiterstringโ if present, specifies a delimiter for the listing. The presence of this will summarize multiple resources into one entry, as if S3 supported directories. See the Amazon documentation for details. ๐๏ธ-result-type REST|xml|pxml|names|dictโ this indicates the format of the return result of the command.
okay so the return flavors all hit different, here's the breakdown bestie ๐
RESTโ if-max-countis specified, you get back the dictionary thatS3::RESTreturned. if-max-countis not specified, you get a list of all the dictionaries returned from the one or more calls toS3::REST. the whole haul. ๐xmlโ if-max-countis specified, you get the body returned fromS3::REST. if-max-countis not specified, you get a list of all the bodies returned from the one or more calls toS3::REST.pxmlโ if-max-countis specified, the body returned fromS3::RESTgets passed throughxsxp::parseand then returned. if-max-countis not specified, it's a list of all the bodies returned from the one or more calls toS3::REST, each one passed throughxsxp::parse, and then returned. โจnamesโ returns a list of every single name found in either theContents/Keyfields or theCommonPrefixes/Prefixfields. and if you didn't specify-delimiterand you didn't specify-max-count, this hands you a list of all the resources with the-prefixyou gave it. slay.dictโ returns a dictionary. (and yes, only one dictionary even if-max-countwasn't specified. it's giving one-and-done.) the keys of that dictionary are, in order:Nameโ the name of the bucket, from the final call toS3::REST.Prefixโ from the final call toS3::REST.Markerโ from the final call toS3::REST.MaxKeysโ from the final call toS3::REST.IsTruncatedโ from the final call toS3::REST, so it's always false if-max-countis not specified.NextMarkerโ always provided ifIsTruncatedis true, and calculated if Amazon doesn't provide it. may be empty ifIsTruncatedis false.Keyโ a list of names of resources in the bucket matching the-prefixand-delimiterrestrictions.LastModifiedโ a list of times of resources in the bucket, in the same order asKey, in the format returned by Amazon. (i.e., it is not parsed into a seconds-from-epoch.)ETagโ a list of entity tags (a.k.a. MD5 checksums) in the same order asKey.Sizeโ a list of sizes in bytes of the resources, in the same order asKey.Owner/IDโ a list of owners of the resources in the bucket, in the same order asKey.Owner/DisplayNameโ a list of owners of the resources in the bucket, in the same order asKey. these are the display names.CommonPrefixes/Prefixโ a list of prefixes common to multiple entities. this one's only present if-delimiterwas supplied. ๐
๐ S3::Put ๐
S3::Put ?-bucket bucketname? -resource resourcename ?-blocking boolean?
?-file filename? ?-content contentstring? ?-acl private|public-
read|public-read-write|authenticated-read|calc|keep? ?-content-type
contenttypestring? ?-x-amz-meta-* metadatatext? ?-compare comparemode?
this one sends data to a resource on Amazon's servers for storage, using the HTTP PUT command. the return? it hands back 0 if the -compare mode prevented the transfer, 1 if the transfer actually worked, or it throws an error if the transfer was attempted but failed. server 5XX errors and S3 socket errors get retried according to the S3:Configure -retries settings before it throws an error; other errors throw immediately, no waiting around. ๐ค
-bucketโ this specifies the bucket the resource gets written into. leading and/or trailing slashes are removed for you, and spaces too. we handle that, you're welcome ๐-resourceโ this is the full name of the resource within the bucket. a single leading slash gets removed, but not a trailing slash. spaces are not trimmed. note it. ๐-blockingโ the standard blocking flag.-fileโ if you specify this, the filename must exist, must be readable, and must not be a special file or a directory file.[file size]must apply to it and must not change for the lifetime of the call. the default content-type is calculated based on the name and/or contents of the file. specifying this is an error if-contentis also specified, but at least one of-fileor-contentmust be specified. (the file is allowed to not exist or not be readable if-compare neveris specified. just saying.)-contentโ if you specify this, the contentstring gets sent as the body of the resource. the content-type defaults to"application/octet-string". only the low bytes are sent, so non-ASCII should use the appropriate encoding (such as[encoding convertto utf-8]) before you pass it to this routine, if necessary. specifying this is an error if-fileis also specified, but at least one of-fileor-contentmust be specified.-aclโ defaults toS3::Configure -default-aclif you don't specify it. it sets thex-amz-aclheader on thePUToperation. if the value you give iscalc, thex-amz-aclheader is calculated based on the I/O permissions of the file to be uploaded; it is an error to specifycalcand-contenttogether. if the value iskeep, the acl of the resource is read before thePUT(or the default is used if the resource doesn't exist), then set back to what it was after thePUT(if it existed). an error will occur if the resource is successfully written but the kept ACL can't then be applied. this should never happen. ๐
Note: calc is not currently fully implemented. so likeโฆ heads up bestie.
-x-amz-meta-*โ if any header starts with-x-amz-meta-, its contents get added to thePUTcommand to be stored as metadata with the resource. again, no encoding is performed, and the metadata should not contain characters like newlines, carriage returns, and so on. it's best to stick with simple ASCII strings, or to fix the library in several places. your call. ๐ซถ-content-typeโ this overrides the content-type calculated by-file, or sets the content-type for-content.-compareโ this is the standard compare mode argument.S3::Putreturns1if the data was copied, or0if the data was skipped because the comparison mode said it should be skipped.
๐
S3::Get ๐
S3::Get ?-bucket bucketname? -resource resourcename ?-blocking boolean?
?-compare comparemode? ?-file filename? ?-content contentvarname?
?-timestamp aws|now? ?-headers headervarname?
this one retrieves data from a resource on Amazon's S3 servers, using the HTTP GET command. it returns 0 if the -compare mode prevented the transfer, 1 if the transfer worked, or throws an error if the transfer was attempted but failed. server 5XX errors and S3 socket errors are retried according to the S3:Configure settings before throwing an error; other errors throw immediately. also, note that this is always authenticated as the user configured via S3::Configure -accesskeyid. want an unauthenticated GET? use the Tcllib http for that. ๐ฅ
-bucketโ this specifies the bucket the resource gets read from. leading and/or trailing slashes are removed for you, and spaces too. ๐-resourceโ this is the full name of the resource within the bucket. a single leading slash gets removed, but not a trailing slash. spaces are not trimmed.-blockingโ the standard blocking flag.-fileโ if you specify this, the body of the resource gets read into this file, incrementally, without pulling it entirely into memory first. the parent directory must already exist. if the file already exists, it must be writable. if an error is thrown part-way through the process and the file already existed, it may be clobbered. ๐ if an error is thrown part-way through and the file did not already exist, any partial bits will be deleted. specifying this is an error if-contentis also specified, but at least one of-fileor-contentmust be specified.-timestampโ this is only valid in conjunction with-file. it may be specified asnoworaws. the default isnow. ifnow, the file's modification date is left up to the system. ifaws, the file's mtime is set to match theLast-Modifiedheader on the resource, synchronizing the two appropriately for-compare dateor-compare newer. โจ-contentโ if you specify this, contentvarname is a variable in the caller's scope (not necessarily global) that receives the value of the body of the resource. no encoding is done, so if the resource (for example) represents a UTF-8 byte sequence, use[encoding convertfrom utf-8]to get a valid UTF-8 string. if this is specified, the-compareis ignored unless it isnever, in which case no assignment to contentvarname is performed. specifying this is an error if-fileis also specified, but at least one of-fileor-contentmust be specified. ๐ฆ-compareโ bestie this is THE standard compare mode argument, okay?S3::Gethands you back1if the data actually got copied, or0if the data was skipped because of the comparison mode โ which is its little way of saying "yeah we're good, skip it." ๐ซถ-headersโ if you drop this, the headers that came back from the fetch get stashed in the variable you named, as a dictionary. It's giving the full package:content-typeandx-amz-meta-*headers, plus the usual HTTP headers, thex-amz-iddebugging headers, literally all of it. โญ And lowkey important: if no file got fetched (because of-compareor any other error), then no assignment to that variable happens at all. Nothing. Nada. ๐
๐ธ S3::Head ๐ธ
S3::Head ?-bucket bucketname? -resource resourcename ?-blocking boolean?
?-dict dictvarname? ?-headers headersvarname? ?-status statusvarname?
This one fires a HEAD at the resource, no cap. It tells you whether a 2XX code came back from the request โ and it will never throw an S3 remote error at you, it's way too chill for that. โจ So if it returns 1, the resource exists and you can access it. Periodt. If it returns 0, something went sideways, and you should go check the -status result for the tea. ๐
-bucketโ names the bucket you're reading the resource from. Leading and/or trailing slashes get removed for you, and so do spaces. It's self-cleaning, we love that. ๐ง-resourceโ the full name of the resource inside the bucket. A single leading slash gets removed, but NOT a trailing slash. And spaces? Not trimmed. Not even a little. ๐-blockingโ the standard blocking flag, same as always.-dictโ if you specify it, the resulting dictionary from theS3::RESTcall gets assigned to the variable you named (and it doesn't have to be global, bestie) in the caller's scope.-headersโ if you specify it, the dictionary of headers from the result gets assigned to the variable you named (again, not necessarily global) in the caller's scope.-statusโ if you specify it, that variable (not necessarily global!) in the caller's scope gets assigned a 2-element list. First element is the 3-digit HTTP status code. Second element is the HTTP message, like"OK"or"Forbidden". Two little pieces of info, chef's kiss. ๐
๐ S3::GetAcl ๐
S3::GetAcl ?-blocking boolean? ?-bucket bucketname? -resource
resourcename ?-result-type REST|xml|pxml?
This command gets the ACL of the resource you point at, or throws an error if it's just not available. Rude of it, but okay. ๐ญ
-blocking booleanโ see above for the standard definition, you already know.-bucketโ the bucket you're reading the resource from. Leading and/or trailing slashes get removed for you, as do spaces. โจ-resourceโ the full name of the resource within the bucket. A single leading slash is removed, but not a trailing slash. Spaces are not trimmed. Same deal as always. ๐-parse-xml xmlโ the XML from a previousGetACLcan be passed in here to get parsed into dictionary form. In this case,-result-typemust bepxmlordict. iykyk.-result-type RESTโ the dictionary returned byS3::RESTis the return value ofS3::GetAcl. And in this case, a non-2XXhttpstatus will not throw an error. It's giving forgiving. ๐ซถ-result-type xmlโ the raw XML of the body is returned as the result, with no encoding applied. Just the raw, untouched tea. ๐ธ-result-type pxmlโ the XML of the body as parsed byxsxp::parseis returned. Fancy. โจ-result-type dictโ this one fetches the ACL, parses it, and returns a dictionary with two elements. Obsessed.
The first element has the key "owner" whose value is the canonical ID of the owner of the resource. ๐
The second element has the key "acl" whose value is a dictionary. Each key in that dictionary is one of Amazon's permissions, namely "READ", "WRITE", "READ_ACP", "WRITE_ACP", or "FULL_CONTROL". Each value of each key is a list of canonical IDs or group URLs that have that permission. Elements are not in the list in any particular order, and not all keys are necessarily present โ so don't come for me about the order. Display names are not returned, because honestly they're not especially useful; use pxml to obtain them if you need them. ๐
๐ฆ S3::PutAcl ๐ฆ
S3::PutAcl ?-blocking boolean? ?-bucket bucketname? -resource
resourcename ?-acl new-acl?
This sets the ACL on the resource you named. It returns the XML that got written to the ACL, or throws an error if anything went wrong. Simple as that. ๐
-blocking booleanโ see above for the standard definition.-bucketโ the bucket you're reading the resource from. Leading and/or trailing slashes get removed for you, as are spaces. ๐ง-resourceโ the full name of the resource within the bucket. A single leading slash is removed, but not a trailing slash. Spaces are not trimmed.-ownerโ if you provide this, it's assumed to match the owner of the resource. Otherwise, aGETmay need to be issued against the resource to find the owner. If you already have the owner (say, from a call toS3::GetAcl), you can pass the value of the"owner"key as the value of this option, and it'll be used when constructing the XML. Efficient queen. ๐-aclโ if you specify this, it provides the ACL the caller wants to write to the resource. If it's not supplied or it's empty, the value is taken fromS3::Configure -default-acl. The ACL is written with aPUTto the?aclresource. Okay so here's how it decides what you mean:- If the value passed to this option starts with
"<", it's taken to be a body to bePUTto the ACL resource. - If the value matches one of the standard Amazon
x-amz-aclheaders (i.e., a canned access policy), that header is translated to XML and then applied. The canned access policies areprivate,public-read,public-read-write, andauthenticated-read(in lower case). - Otherwise, the value is assumed to be a dictionary formatted as the
"acl"sub-entry within the dict returned byS3::GetAcl -result-type dict. The proper XML is generated and applied to the resource. Note that a value containing"//"is assumed to be a group, a value containing"@"is assumed to be anAmazonCustomerByEmail, and otherwise the value is assumed to be a canonical Amazon ID. ๐
- If the value passed to this option starts with
Note that you cannot change the owner, so callingGetAclon a resource owned by one user and applying it viaPutAclon a resource owned by another user may not do exactly what you expect. Fr fr, be careful with that one bestie. ๐
๐ S3::Delete ๐
S3::Delete ?-bucket bucketname? -resource resourcename ?-blocking
boolean? ?-status statusvar?
This command deletes the specified resource from the specified bucket. It returns 1 if the resource was deleted successfully, 0 otherwise. And it returns 0 rather than throwing an S3 remote error โ no drama, just facts. โจ
-bucketโ the bucket you're deleting the resource from. Leading and/or trailing slashes get removed for you, as are spaces. ๐ง-resourceโ the full name of the resource within the bucket. A single leading slash is removed, but not a trailing slash. Spaces are not trimmed.-blockingโ the standard blocking flag. You know the vibe.-statusโ if specified, the variable you named (not necessarily global!) in the caller's scope gets set to a two-element list. First element is the 3-digit HTTP status code. Second element is the HTTP message, like"OK"or"Forbidden". And heads up: Amazon'sDELETEresult is204on success, that being the code indicating no content in the returned body. So don't panic when you see204, it's literally slaying. ๐
๐ S3::Push ๐
S3::Push ?-bucket bucketname? -directory directoryname ?-prefix
prefixstring? ?-compare comparemode? ?-x-amz-meta-* metastring? ?-acl
aclcode? ?-delete boolean? ?-error throw|break|continue? ?-progress
scriptprefix?
This synchronises a local directory with a remote bucket by pushing the differences using S3::Put. ๐
Note that if something has changed in the bucket but not locally, those changes could be lost. Thus, this is not a general two-way synchronization primitive. (See S3::Sync for that, bestie.) ๐
Also note that resource names are case sensitive, so changing the case of a file on a Windows machine may lead to otherwise-unnecessary transfers. And note that only regular files are considered โ so devices, pipes, symlinks, and directories are not copied. Sorry to the symlinks, they're just not invited. ๐
-bucketโ names the bucket you're pushing data into. ๐-directoryโ names the local directory the files get taken from. It must exist, be readable via[glob]and so on. And if only some of the files in there are readable,S3::PushwillPUTthose files that are readable and return, in its results, the list of files that could not be opened. Transparency queen. โจ-prefixโ names the prefix that gets added to all resources. That is, it's the remote equivalent of-directory. If you don't specify it, the root of the bucket gets treated as the remote directory. An example may clarify, so here you go:
S3::Push -bucket test -directory /tmp/xyz -prefix hello/world
In this example, /tmp/xyz/pdq.html will be stored as http://s3.amazonaws.com/test/hello/world/pdq.html in Amazon's servers. Also, /tmp/xyz/abc/def/Hello will be stored as http://s3.amazonaws.com/test/hello/world/abc/def/Hello in Amazon's servers. Without the -prefix option, /tmp/xyz/pdq.html would be stored as http://s3.amazonaws.com/test/pdq.html. See? Slay. ๐ธ
-blockingโ this is the standard blocking option. Same as always, you got this. ๐ซถ-compareโ if it's there, it gets passed to every single invocation ofS3::Put. And obvi, if you don't specify it,S3::Configure -default-compareis what gets used instead. โจ-x-amz-meta-*โ if present, this also rides along to every invocation ofS3::Put. Heads up: all copied files will have the same metadata. All of them. Same. ๐-aclโ if present, passed to each invocation ofS3::Put.-deleteโ defaults tofalse. If you set ittrue, resources chillin' in the destination that aren't in the source directory get yeeted withS3::Delete. And here's the tea: since only regular files are considered, the existence of a symlink, pipe, device, or directory in the local source will not stop a remote resource with a matching name from being deleted. ๐ญ-errorโ this controls howS3::Pushacts whenS3::Putthrows an error. Quick note first: errors on the local file system, or while reading the list of resources in the remote bucket, always throw errors โ no negotiating. This option is only about "partial" errors, aka when some files got copied and some didn't. Also,S3::Deletealways gets finished up, with its errors just recorded in the return result.throwโ the error is rethrown with the sameerrorCode.breakโ processing stops without throwing an error, the error is recorded in the return value, and the command returns with a normal return. The calls toS3::Deleteare not started.continueโ this is the default. Processing keeps going without throwing, the error gets recorded in the return result, and it resumes with the next file in the local directory to be copied.
-progressโ if you specify this and the indicated script prefix isn't empty, that script prefix gets invoked several times in the caller's context, with extra arguments, at various points in the processing. This lets you report progress without backgrounding anything. ๐
The prefix gets invoked with additional arguments, where the first extra argument tells you which part of the process is being reported on. Here's the whole sequence, bestie:
- First, the prefix is invoked with
argsas the first additional argument, and a dictionary representing the normalized arguments to theS3::Pushcall as the second additional argument. - Then the prefix is invoked with
localas the first additional argument, and a list of suffixes of the files to be considered as the second argument. - Then the prefix is invoked with
remoteas the first additional argument, and a list of suffixes existing in the remote bucket as the second argument. - Then, for each file in the local list, the prefix is invoked with
startas the first additional argument and the common suffix as the second additional argument. - When
S3::Putreturns for that file, the prefix is invoked withcopyas the first additional argument, the common suffix as the second, and a third argument that will be"copied"(ifS3::Putsent the resource),"skipped"(ifS3::Putdecided not to based on-compare), or theerrorCodethatS3::Putthrew due to unexpected errors โ in which case that third argument is a list that starts with"S3". - When all files have been transferred, the prefix may be invoked zero or more times with
deleteas the first additional argument and the suffix of the resource being deleted as the second, with a third argument that's either an empty string (if the delete worked) or theerrorCodefromS3::Deleteif it failed. - Finally, the prefix is invoked with
finishedas the first additional argument and the return value as the second additional argument. ๐ฆ
The return result from this command is a dictionary. The keys are the suffixes (i.e., the common portion of the path after the -directory and -prefix), while the values are either "copied", "skipped" (if -compare said not to copy the file), or the errorCode thrown by S3::Put, as appropriate. If -delete was true, there may also be entries for suffixes with the value "deleted" or "notdeleted", saying whether the attempted S3::Delete worked or not, respectively. ๐
There's one extra pair in the return result, whose key is the empty string and whose value is a nested dictionary. The keys of that nested dictionary include:
"filescopied"โ the number of files successfully copied"bytescopied"โ the number of data bytes in the files copied, excluding headers, metadata, etc."compareskipped"โ the number of files not copied due to-comparemode"errorskipped"โ the number of files not copied due to thrown errors"filesdeleted"โ the number of resources deleted due to not having corresponding files locally, or0if-deleteis false"filesnotdeleted"โ the number of resources whose deletion was attempted but failed
Ngl, this is currently implemented somewhat inefficiently. It fetches the bucket listing (including timestamps and eTags), then calls S3::Put, which uses HEAD to find the timestamps and eTags again. Correcting this with no API change is planned for a future upgrade. ๐
๐ธ S3::Pull ๐ธ
S3::Pull ?-bucket bucketname? -directory directoryname ?-prefix
prefixstring? ?-blocking boolean? ?-compare comparemode? ?-delete
boolean? ?-timestamp aws|now? ?-error throw|break|continue? ?-progress
scriptprefix?
This synchronises a remote bucket with a local directory by pulling the differences using S3::Get. โ ๏ธ But real talk: if something has been changed locally but not in the bucket, those differences may be lost. This is not a general two-way synchronization mechanism. (See S3::Sync for that, bestie.) It creates directories if needed, and new directories are created with default permissions. โจ
Also note that resource names are case sensitive, so changing the case of a file on a Windows machine may lead to otherwise-unnecessary transfers. And pls try not to store data in resources that end with a slash, or which are prefixes of resources that otherwise would start with a slash โ i.e., don't use this if you store data in resources whose names have to be directories locally. ๐
Yeah, this one's also currently implemented somewhat inefficiently. It fetches the bucket listing (including timestamps and eTags), then calls S3::Get, which uses HEAD to find the timestamps and eTags again. Correcting this with no API change is planned for a future upgrade.
-bucketโ names the bucket from which data will be pulled.-directoryโ names the local directory into which files will be written. It must exist, be readable via[glob], writable for file creation, and so on. If only some of the files in there are writable,S3::Pullwill GET the writable ones and return, in its results, the list of files that couldn't be opened. ๐ซถ-prefixโ the prefix of resources that will be considered for retrieval. SeeS3::Pushfor more details, examples, etc. (Of course,S3::Pullreads rather than writes, but the prefix is treated similarly.)-blockingโ this is the standard blocking option.-compareโ passed to each invocation ofS3::Getif provided. Naturally,S3::Configure -default-compareis used if this isn't provided.-timestampโ passed to each invocation ofS3::Getif provided.-deleteโ if specified and true, files that exist in the-directorythat aren't in the-prefixwill be deleted after all resources have been copied. Plus, empty directories (other than the top-level-directory) will be deleted, because Amazon S3 has no concept of an empty directory. ๐-errorโ seeS3::Pushfor a description of this option.-progressโ seeS3::Pushfor a description of this option. It differs slightly in that local directories may be included with a trailing slash to indicate they're directories. ๐
The return value from this command is a dictionary. It's identical in form and meaning to the description of the return result of S3::Push. It differs only in that directories may be included, with a trailing slash in their name, if they're empty and get deleted.
๐ S3::Toss ๐
S3::Toss ?-bucket bucketname? -prefix prefixstring ?-blocking boolean?
?-error throw|break|continue? ?-progress scriptprefix?
This deletes some or all resources within a bucket. It would be considered a "recursive delete" had Amazon implemented actual directories. ๐
-bucketโ the bucket from which resources will be deleted.-blockingโ the standard blocking option.-prefixโ the prefix for resources to be deleted. Any resource that starts with this string will be deleted. This is required. To delete everything in the bucket, pass an empty string for the prefix. ๐๏ธโจ-errorโ if this is"throw",S3::Tossrethrows any errors it encounters. If this is"break",S3::Tossreturns with a normal return after the first error, recording that error in the return result. If this is"continue", which is the default,S3::Tosscontinues on and lists all errors in the return result.-progressโ okay so if you set this and it's not an empty string, your script prefix gets called several times in the context of the caller, with extra arguments tacked on the end. Here's the whole lil sequence, bestie, don't skip it: first it's invoked with the first extra arg beingargsand the second being the processed list of arguments toS3::Toss. Then it's invoked withremoteas the first extra arg and the list of suffixes in the bucket to be deleted as the second extra arg. Then it's invoked with the first extra arg beingdelete, the second being the suffix deleted, and the third being"deleted"or"notdeleted"depending on whetherS3::Deletethrew an error. And finally ๐ the script prefix gets invoked with a first extra arg of"finished"and a second extra arg of the return value.
The return value is a dictionary. The keys are the suffixes of files that S3::Toss attempted to delete, and their values are either the string "deleted" or "notdeleted". There's also one extra pair in there โ its key is the empty string and its value is an embedded dictionary. The keys of that embedded dictionary include "filesdeleted" and "filesnotdeleted", and both of those have integer values. iykyk ๐ฆ
๐ LIMITATIONS ๐
- The pure-Tcl MD5 checking is slow. If you're processing files in the megabyte range, consider making sure binary support is available. fr fr.
- The commands
S3::PullandS3::Pushfetch a directory listing that includes timestamps and MD5 hashes, and then they invokeS3::GetandS3::Put. If a complex-comparemode is specified,S3::GetandS3::Putwill invoke a HEAD operation for each file to fetch timestamps and MD5 hashes of each resource <em>again</em>. It's expected that a future release of this package will solve this without any API changes. ๐ค - The commands
S3::PullandS3::Pushfetch a directory listing without using-max-count. The entire directory gets pulled into memory at once. For very large buckets, this could be a performance problem. The author, at this time, does not plan to change this behavior. Welcome to Open Source. ๐ S3::Syncis neither designed nor implemented yet. The intention would be to keep changes synchronised, so changes could be made to both the bucket and the local directory and get merged byS3::Sync.- Nor is
-compare calcfully implemented. This is primarily due to Windows not providing a convenient method for distinguishing between local files that are"public-read"or"public-read-write". Assistance figuring out TWAPI for this would be appreciated. The U**X semantics are difficult to map directly as well. See the source for details. Note that there are not tests forcalc, since it isn't done yet. - The HTTP processing is implemented within the library, rather than using a "real" HTTP package. Hence, multi-line headers are not (yet) handled correctly. Do not include carriage returns or linefeeds in
x-amz-meta-*headers,content-typevalues, and so on. The author does not at this time expect to improve this. - Internally,
S3::PushandS3::PullandS3::Tossare all very similar and should be refactored. (they're giving copy-paste sisters ๐) - The idea of using
-compare never -delete trueto delete files that have been deleted from one place but not the other, yet not copying changed files, is untested.
๐ USAGE SUGGESTIONS ๐
To fetch a "directory" out of a bucket, make changes, and store it back:
file mkdir ./tempfiles
S3::Pull -bucket sample -prefix of/interest -directory ./tempfiles \
-timestamp aws
do_my_process ./tempfiles other arguments
S3::Push -bucket sample -prefix of/interest -directory ./tempfiles \
-compare newer -delete true
To delete files locally that were deleted off of S3 but not otherwise update files:
S3::Pull -bucket sample -prefix of/interest -directory ./myfiles \
-compare never -delete true
๐ฎ FUTURE DEVELOPMENTS ๐ฎ
The author intends to work on several additional projects related to this package, in addition to finishing the unfinished features. ๐
First, a command-line program allowing browsing of buckets and transfer of files from shell scripts and command prompts is useful.
Second, a GUI-based program allowing visual manipulation of bucket and resource trees not unlike Windows Explorer would be useful.
Third, a command-line (and perhaps a GUI-based) program called "OddJob" that will use S3 to synchronize computation amongst multiple servers running OddJob. An S3 bucket will be set up with a number of scripts to run, and the OddJob program can be invoked on multiple machines to run scripts on all the machines, each moving on to the next unstarted task as it finishes each. This is still being designed, and it is intended primarily to be run on Amazon's Elastic Compute Cloud. ๐ง
๐ TLS SECURITY CONSIDERATIONS ๐
This package uses the TLS package to handle the security for https urls and other socket connections.
Policy decisions like the set of protocols to support and what ciphers to use are not the responsibility of TLS, nor of this package itself however. Such decisions are the responsibility of whichever application is using the package, and are likely influenced by the set of servers the application will talk to as well.
For example, in light of the recent POODLE attack [http://googleonlinesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-ssl-30.html] discovered by Google, many servers will disable support for the SSLv3 protocol. To handle this change the applications using TLS must be patched, and not this package, nor TLS itself. Such a patch may be as simple as generally activating tls1 support, as shown in the example below.
package require tls
tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol
... your own application code ...
๐ BUGS, IDEAS, FEEDBACK ๐
This document, and the package it describes, will undoubtedly contain bugs and other problems. Please report such in the category amazon-s3 of the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist]. Please also report any ideas for enhancements you may have for either package and/or documentation. ๐ซถ
When proposing code changes, please provide unified diffs, i.e the output of diff -u.
Note further that attachments are strongly preferred over inlined patches. Attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar.
๐ KEYWORDS ๐
amazon, cloud, s3
๐ CATEGORY ๐
Networking
ยฉ๏ธ COPYRIGHT ยฉ๏ธ
2006,2008 Darren New. All Rights Reserved. See LICENSE.TXT for terms.
And that's a wrap on the whole page, bestie! ๐ This one's from tcllib, version 1.0.5, dated S3(n) โ slay, go forth and sync your buckets responsibly. โจ๐ฆ
๐ฆ where this page comes from
- fedora 43: tcllib 2.0-3.fc43 ยท TCL
- fedora 44: tcllib 2.0-4.fc44 ยท TCL
- nixos 26.05: tcllib 2.0
- nixpkgs unstable: tcllib 2.0
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms