This is a fun, small nbdkit Python plugin using the Boto3 AWS SDK:
#!/usr/sbin/nbdkit python
import nbdkit
import boto3
from contextlib import closing
API_VERSION = 2
def thread_model():
return nbdkit.THREAD_MODEL_PARALLEL
def config(key, value):
global access_key, secret_key, endpoint_url, bucket_name, key_name
if key == "access-key" or key == "access_key":
access_key = value
elif key == "secret-key" or key == "secret_key":
secret_key = value
elif key == "endpoint-url" or key == "endpoint_url":
endpoint_url = value
elif key == "bucket":
bucket_name = value
elif key == "key":
key_name = value
else:
raise Exception("unknown parameter %s" % key)
def open(readonly):
global access_key, secret_key, endpoint_url
s3 = boto3.client("s3",
aws_access_key_id = access_key,
aws_secret_access_key = secret_key,
endpoint_url = endpoint_url)
if s3 is None:
raise Exception("could not connect to S3")
return s3
def get_size(s3):
global bucket_name, key_name
resp = s3.get_object(Bucket = bucket_name, Key = key_name)
size = resp['ResponseMetadata']['HTTPHeaders']['content-length']
return int(size)
def pread(s3, buf, offset, flags):
global bucket_name, key_name
size = len(buf)
rnge = 'bytes=%d-%d' % (offset, offset+size-1)
resp = s3.get_object(Bucket = bucket_name, Key = key_name, Range = rnge)
body = resp['Body']
with closing(body):
buf[:] = body.read(size)
This lets you loop mount a single object (file):
$ ./nbdkit-S3-plugin -f -v -U /tmp/sock \
access_key="XYZ" secret_key="XYZ" \
bucket="my_files" key="fedora-28.iso"
$ sudo nbd-client -b 2048 -unix /tmp/sock /dev/nbd0
Negotiation: ..size = 583MB
$ ls /dev/nbd0
nbd0 nbd0p1 nbd0p2
$ sudo mount -o ro /dev/nbd0p1 /tmp/mnt
$ ls -l /tmp/mnt
total 11
dr-xr-xr-x. 3 root root 2048 Apr 25 2018 EFI
-rw-r--r--. 1 root root 2532 Apr 23 2018 Fedora-Legal-README.txt
dr-xr-xr-x. 3 root root 2048 Apr 25 2018 images
drwxrwxr-x. 2 root root 2048 Apr 25 2018 isolinux
-rw-r--r--. 1 root root 1063 Apr 21 2018 LICENSE
-r--r--r--. 1 root root 454 Apr 25 2018 TRANS.TBL
I should note this is a bit different from s3fs which is a FUSE driver that mounts all the files in a bucket.