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.
This commit is contained in:
Harshavardhana 2016-11-26 23:17:30 -08:00 коммит произвёл Ted Mielczarek
Родитель decd0b1a99
Коммит aa5e965ac8
3 изменённых файлов: 17 добавлений и 13 удалений

12
src/cache/cache.rs поставляемый
Просмотреть файл

@ -182,8 +182,16 @@ fn parse_size(val: &str) -> Option<usize> {
/// Get a suitable `Storage` implementation from the environment. /// Get a suitable `Storage` implementation from the environment.
pub fn storage_from_environment() -> Box<Storage> { pub fn storage_from_environment() -> Box<Storage> {
if let Ok(bucket) = env::var("SCCACHE_BUCKET") { if let Ok(bucket) = env::var("SCCACHE_BUCKET") {
trace!("Trying S3Cache({})", bucket); let endpoint = match env::var("SCCACHE_ENDPOINT") {
match S3Cache::new(&bucket) { 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) => { Ok(s) => {
trace!("Using S3Cache"); trace!("Using S3Cache");
return Box::new(s); return Box::new(s);

4
src/cache/s3.rs поставляемый
Просмотреть файл

@ -50,7 +50,7 @@ pub struct S3Cache {
impl S3Cache { impl S3Cache {
/// Create a new `S3Cache` storing data in `bucket`. /// Create a new `S3Cache` storing data in `bucket`.
pub fn new(bucket: &str) -> io::Result<S3Cache> { pub fn new(bucket: &str, endpoint: &str) -> io::Result<S3Cache> {
let home = try!(env::home_dir().ok_or(Error::new(ErrorKind::Other, "Couldn't find home directory"))); let home = try!(env::home_dir().ok_or(Error::new(ErrorKind::Other, "Couldn't find home directory")));
let profile_providers = vec![ let profile_providers = vec![
ProfileProvider::with_configuration(home.join(".aws").join("credentials"), "default"), 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); let provider = AutoRefreshingProviderSync::with_mutex(ChainProvider::with_profile_providers(profile_providers)).ok().map(Arc::new);
//TODO: configurable SSL //TODO: configurable SSL
let bucket = Arc::new(Bucket::new(bucket, Ssl::No)); let bucket = Arc::new(Bucket::new(bucket, endpoint, Ssl::No));
Ok(S3Cache { Ok(S3Cache {
bucket: bucket, bucket: bucket,
provider: provider, provider: provider,

Просмотреть файл

@ -26,17 +26,13 @@ pub enum Ssl {
No, No,
} }
fn base_url(bucket_name: &str, ssl: Ssl, region: Option<&str>) -> String { fn base_url(endpoint: &str, ssl: Ssl) -> String {
format!("{}://{}.s3{}.amazonaws.com/", format!("{}://{}/",
match ssl { match ssl {
Ssl::Yes => "https", Ssl::Yes => "https",
Ssl::No => "http", Ssl::No => "http",
}, },
bucket_name, endpoint)
match region {
Some(ref r) => format!("-{}", r),
None => String::new(),
})
} }
fn hmac<D: Digest>(d: D, key: &[u8], data: &[u8]) -> Vec<u8> { fn hmac<D: Digest>(d: D, key: &[u8], data: &[u8]) -> Vec<u8> {
@ -71,8 +67,8 @@ pub enum S3Error {
} }
impl Bucket { impl Bucket {
pub fn new(name: &str, ssl: Ssl) -> Bucket { pub fn new(name: &str, endpoint: &str, ssl: Ssl) -> Bucket {
let base_url = base_url(&name, ssl, None); let base_url = base_url(&endpoint, ssl);
Bucket { Bucket {
name: name.to_owned(), name: name.to_owned(),
base_url: base_url, base_url: base_url,