aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/download.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-02-14 14:20:00 +0100
committerEelco Dolstra <edolstra@gmail.com>2017-02-14 14:20:00 +0100
commit9ff9c3f2f80ba4108e9c945bbfda2c64735f987b (patch)
tree7ce169da649ca6e0a0cd88d6b85544d5c6038e95 /src/libstore/download.cc
parent62ff5ad424547630e70f35406da85fbb5ec3445a (diff)
Add support for s3:// URIs
This adds support for s3:// URIs in all places where Nix allows URIs, e.g. in builtins.fetchurl, builtins.fetchTarball, <nix/fetchurl.nix> and NIX_PATH. It allows fetching resources from private S3 buckets, using credentials obtained from the standard places (i.e. AWS_* environment variables, ~/.aws/credentials and the EC2 metadata server). This may not be super-useful in general, but since we already depend on aws-sdk-cpp, it's a cheap feature to add.
Diffstat (limited to 'src/libstore/download.cc')
-rw-r--r--src/libstore/download.cc28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/libstore/download.cc b/src/libstore/download.cc
index 074e0ca66..85215439a 100644
--- a/src/libstore/download.cc
+++ b/src/libstore/download.cc
@@ -4,6 +4,7 @@
#include "hash.hh"
#include "store-api.hh"
#include "archive.hh"
+#include "s3.hh"
#include <unistd.h>
#include <fcntl.h>
@@ -480,6 +481,31 @@ struct CurlDownloader : public Downloader
std::function<void(const DownloadResult &)> success,
std::function<void(std::exception_ptr exc)> failure) override
{
+ /* Ugly hack to support s3:// URIs. */
+ if (hasPrefix(request.uri, "s3://")) {
+ // FIXME: do this on a worker thread
+ sync2async<DownloadResult>(success, failure, [&]() {
+#ifdef ENABLE_S3
+ S3Helper s3Helper;
+ auto slash = request.uri.find('/', 5);
+ if (slash == std::string::npos)
+ throw nix::Error("bad S3 URI ‘%s’", request.uri);
+ std::string bucketName(request.uri, 5, slash - 5);
+ std::string key(request.uri, slash + 1);
+ // FIXME: implement ETag
+ auto s3Res = s3Helper.getObject(bucketName, key);
+ DownloadResult res;
+ if (!s3Res.data)
+ throw DownloadError(NotFound, fmt("S3 object ‘%s’ does not exist", request.uri));
+ res.data = s3Res.data;
+ return res;
+#else
+ throw nix::Error("cannot download ‘%s’ because Nix is not built with S3 support", request.uri);
+#endif
+ });
+ return;
+ }
+
auto item = std::make_shared<DownloadItem>(*this, request);
item->success = success;
item->failure = failure;
@@ -629,7 +655,7 @@ bool isUri(const string & s)
size_t pos = s.find("://");
if (pos == string::npos) return false;
string scheme(s, 0, pos);
- return scheme == "http" || scheme == "https" || scheme == "file" || scheme == "channel" || scheme == "git";
+ return scheme == "http" || scheme == "https" || scheme == "file" || scheme == "channel" || scheme == "git" || scheme == "s3";
}