From aa5e965ac80840a20806dd7cdd2167fd7ebeb305 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 26 Nov 2016 23:17:30 -0800 Subject: [PATCH] Add support for custom s3 endpoint url Specify a new endpoint with `SCCACHE_ENDPOINT` such as Minio https://github.com/minio/minio. If not defaults to 's3.amazonaws.com'. Current code for some reason was not working with custom regions. Introduced a new ENV called `SCCACHE_REGION` to handle cross region s3 URLs. --- src/cache/cache.rs | 12 ++++++++++-- src/cache/s3.rs | 4 ++-- src/simples3/s3.rs | 14 +++++--------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/cache/cache.rs b/src/cache/cache.rs index ea0ebe13..8723791d 100644 --- a/src/cache/cache.rs +++ b/src/cache/cache.rs @@ -182,8 +182,16 @@ fn parse_size(val: &str) -> Option { /// Get a suitable `Storage` implementation from the environment. pub fn storage_from_environment() -> Box { if let Ok(bucket) = env::var("SCCACHE_BUCKET") { - trace!("Trying S3Cache({})", bucket); - match S3Cache::new(&bucket) { + let endpoint = match env::var("SCCACHE_ENDPOINT") { + Ok(endpoint) => format!("{}/{}", endpoint, bucket), + _ => match env::var("SCCACHE_REGION") { + Ok(ref region) if region != "us-east-1" => + format!("{}.s3-{}.amazonaws.com", bucket, region), + _ => String::from("s3.amazonaws.com"), + }, + }; + debug!("Trying S3Cache({})", endpoint); + match S3Cache::new(&bucket, &endpoint) { Ok(s) => { trace!("Using S3Cache"); return Box::new(s); diff --git a/src/cache/s3.rs b/src/cache/s3.rs index fe0ee475..e2786ee8 100644 --- a/src/cache/s3.rs +++ b/src/cache/s3.rs @@ -50,7 +50,7 @@ pub struct S3Cache { impl S3Cache { /// Create a new `S3Cache` storing data in `bucket`. - pub fn new(bucket: &str) -> io::Result { + pub fn new(bucket: &str, endpoint: &str) -> io::Result { let home = try!(env::home_dir().ok_or(Error::new(ErrorKind::Other, "Couldn't find home directory"))); let profile_providers = vec![ ProfileProvider::with_configuration(home.join(".aws").join("credentials"), "default"), @@ -61,7 +61,7 @@ impl S3Cache { ]; let provider = AutoRefreshingProviderSync::with_mutex(ChainProvider::with_profile_providers(profile_providers)).ok().map(Arc::new); //TODO: configurable SSL - let bucket = Arc::new(Bucket::new(bucket, Ssl::No)); + let bucket = Arc::new(Bucket::new(bucket, endpoint, Ssl::No)); Ok(S3Cache { bucket: bucket, provider: provider, diff --git a/src/simples3/s3.rs b/src/simples3/s3.rs index 21893c12..753d7f46 100644 --- a/src/simples3/s3.rs +++ b/src/simples3/s3.rs @@ -26,17 +26,13 @@ pub enum Ssl { No, } -fn base_url(bucket_name: &str, ssl: Ssl, region: Option<&str>) -> String { - format!("{}://{}.s3{}.amazonaws.com/", +fn base_url(endpoint: &str, ssl: Ssl) -> String { + format!("{}://{}/", match ssl { Ssl::Yes => "https", Ssl::No => "http", }, - bucket_name, - match region { - Some(ref r) => format!("-{}", r), - None => String::new(), - }) + endpoint) } fn hmac(d: D, key: &[u8], data: &[u8]) -> Vec { @@ -71,8 +67,8 @@ pub enum S3Error { } impl Bucket { - pub fn new(name: &str, ssl: Ssl) -> Bucket { - let base_url = base_url(&name, ssl, None); + pub fn new(name: &str, endpoint: &str, ssl: Ssl) -> Bucket { + let base_url = base_url(&endpoint, ssl); Bucket { name: name.to_owned(), base_url: base_url,