This guide assumes that you have a GlusterFS cluster with volumes exported over Swift API using gluster-swift.
Install swift3 middleware from source or via whatever packaging system you may be using. Here is how you can install from source:
git clone https://github.com/openstack/swift3
cd swift3
python setup.py install
Modify /etc/swift/proxy-server.conf
to add swift3 middleware in the pipeline to the left of auth middleware (tempauth/gswauth) and add swift3 filter section as illustrated below:
[pipeline:main]
pipeline = catch_errors cache swift3 tempauth proxy-server
[filter:swift3]
use = egg:swift3#swift3
If you are using gswauth, insert swift3 to the left of gswauth similar to the tempauth example above. You can also configure swift3 middleware to work with keystone. You can also configure tunables in the swift3 middleware filter section.
Reload the proxy server process for the change in pipeline to take effect:
swift-init proxy reload
If you are not using any authentication filters, refer to this section for example.
The examples below use the s3curl perl script which is a S3 authentication wrapper around curl command. Modify s3curl.pl
to point to node running proxy server in your cluster.
# begin customizing here
my @endpoints = ( 'localhost');
These examples assume you have an account (GlusterFS volume) named test
and an admin user named tester
with password testing
:
Create a bucket
./s3curl.pl --id 'test:tester' --key 'testing' --put /dev/null -- -k -v -s http://localhost:8080/bucket1
Upload object to the bucket
./s3curl.pl --id 'test:tester' --key 'testing' --put ./README -- -k -v -s http://localhost:8080/bucket1/a/b/c
Download an object from the bucket
./s3curl.pl --id 'test:tester' --key 'testing' --get -- -k -v -s http://localhost:8080/bucket1/a/b/c
List buckets
./s3curl.pl --id 'test:tester' --key 'testing' --get -- -k -v -s http://localhost:8080
List objects in bucket
./s3curl.pl --id 'test:tester' --key 'testing' --get -- -k -v -s http://localhost:8080/bucket1
Delete object
./s3curl.pl --id 'test:tester' --key 'testing' --del -- -k -v -s http://localhost:8080/bucket1/a/b/c
Delete bucket (should be empty)
./s3curl.pl --id 'test:tester' --key 'testing' --del -- -k -v -s http://localhost:8080/bucket1
Multi-part upload an object to the bucket
a. Initiate multi part
./s3curl.pl --id 'test:tester' --key 'testing' --post -- "http://localhost:8080/bucket/mobject?uploads"
b.upload the multi parts upload all the parts by changing partNumber. get the uploadId from the output of Initiate multipart
./s3curl.pl --id 'test:tester' --key 'testing' --put xaa -s 'http://localhost:8080/bucket/mobject?uploadId=<uploaIdFromPreviousStep>&partNumber=<partNumber>'
c.complete the multi part
c.1 List the part numbers and Etags
./s3curl.pl --id 'test:tester' --key 'testing' -- "http://localhost:8080/bucket/mobject?uploadId=<uploadId>"
c.2 make a xml file with following format and do a POST request
example: cat ./complete_multi_tag
<CompleteMultipartUpload>
<Part>
<PartNumber>1</PartNumber>
<ETag>"9dff188990a9831c5255d342895832df"</ETag>
</Part>
<Part>
<PartNumber>2</PartNumber>
<ETag>"72e117e4266579616ad295f399ae10a3"</ETag>
</Part>
<Part>
<PartNumber>3</PartNumber>
<ETag>"85c6e4487367f279926ad5da495a1d20"</ETag>
</Part>
</CompleteMultipartUpload>
./s3curl.pl --id 'test:tester' --key 'testing' --post ./complete_multi_tag -- http://localhost:8080/bucket/mobject?uploadId=<uploadId>
d.download the multi part object
./s3curl.pl --id 'test:tester' --key 'testing' -- "http://localhost:8080/bucket/mobject" > output_file
Using boto module in python to access GlusterFS cluster over S3 API
#!/usr/bin/env python
from boto.s3.connection import S3Connection
from boto.s3.connection import OrdinaryCallingFormat
conn = S3Connection(aws_access_key_id='test:tester',
aws_secret_access_key='testing',
host='localhost', port=8080, is_secure=False,
calling_format=OrdinaryCallingFormat())
# List buckets example
buckets_list = conn.get_all_buckets()
for bucket in buckets_list:
print(bucket.name)
Swift3 middleware can be easily used with gswauth when auth_type
in gswauth is configured to be Plaintext
.
The AWS S3 client uses password in plaintext to compute HMAC signature.
However, when auth_type
in gswauth is configured to be Sha1
or Sha512
, gswauth can only use the stored hashed password to compute HMAC signature. This results in signature mismatch although the user credentials are correct. The only way for S3 clients to authenticate is by providing SHA1/SHA512 of password as input to it’s HMAC function. To generate hash of password, the S3 clients will have to know auth_type
and auth_type_salt
beforehand. Here is an example of gswauth configuration:
[filter:gswauth]
use = egg:gluster_swift#gswauth
set log_name = gswauth
super_admin_key = gswauthkey
metadata_volume = gsmetadata
token_life = 86400
max_token_life = 86400
auth_type = sha1
auth_type_salt = gswauthsalt
s3_support = on
Note that you have to explicitly set s3_support
to on.
Example: Create a bucket
Generate key
#!/usr/bin/env python
import hashlib
key = 'testing'
salt = 'gswauthsalt'
enc_key = '%s%s' % ('gswauthsalt', 'testing')
enc_val = hashlib.sha1(enc_key).hexdigest()
print(enc_val) # f636f4ecc148efdce89ac471f805d7f51cec348f
This is not required when auth_type
is set to Plaintext
./s3curl.pl --id 'test:tester' --key 'f636f4ecc148efdce89ac471f805d7f51cec348f' --put /dev/null -- -k -v -s http://localhost:8080/bucket1
In local and insecure deployments such as within an organization/department where no authentication middleware is in the proxy pipeline, you should just use glusterfs volume name as id
or AWSAccessKeyId
.
Example: Create a bucket
./s3curl.pl --id 'test' --key 'blah' --put /dev/null -- -k -v -s http://localhost:8080/bucket1
In this example, test
is the name of glusterfs volume and key can be any string and is ignored.