From 1922a4272c85983ac67e325827e4afbfe313a7b7 Mon Sep 17 00:00:00 2001
From: Alexander Neumann <alexander@bumpern.de>
Date: Mon, 28 Dec 2015 18:55:15 +0100
Subject: [PATCH] s3: fix usage

Ignore error response for existing bucket, add more debug code.
---
 backend/s3/s3.go     | 13 ++++++++++++-
 cmd/restic/global.go | 15 +++++++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/backend/s3/s3.go b/backend/s3/s3.go
index 0b831b6db..62616a993 100644
--- a/backend/s3/s3.go
+++ b/backend/s3/s3.go
@@ -9,6 +9,7 @@ import (
 	"github.com/minio/minio-go"
 
 	"github.com/restic/restic/backend"
+	"github.com/restic/restic/debug"
 )
 
 const maxKeysInList = 1000
@@ -28,7 +29,8 @@ type S3Backend struct {
 	bucketname string
 }
 
-// Open opens the S3 backend at bucket and region. The bucket is created if it does not exist yet.
+// Open opens the S3 backend at bucket and region. The bucket is created if it
+// does not exist yet.
 func Open(cfg Config) (backend.Backend, error) {
 	mcfg := minio.Config{
 		AccessKeyID:     cfg.KeyID,
@@ -54,6 +56,15 @@ func Open(cfg Config) (backend.Backend, error) {
 	be.createConnections()
 
 	err = s3api.MakeBucket(cfg.Bucket, "")
+
+	if err != nil {
+		e, ok := err.(minio.ErrorResponse)
+		if ok && e.Code == "BucketAlreadyExists" {
+			debug.Log("s3.Open", "ignoring error that bucket %q already exists", cfg.Bucket)
+			err = nil
+		}
+	}
+
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/restic/global.go b/cmd/restic/global.go
index 9fdf52367..2c73da530 100644
--- a/cmd/restic/global.go
+++ b/cmd/restic/global.go
@@ -12,6 +12,7 @@ import (
 	"github.com/restic/restic/backend/local"
 	"github.com/restic/restic/backend/s3"
 	"github.com/restic/restic/backend/sftp"
+	"github.com/restic/restic/debug"
 	"github.com/restic/restic/location"
 	"github.com/restic/restic/repository"
 	"golang.org/x/crypto/ssh/terminal"
@@ -166,6 +167,7 @@ func (o GlobalOptions) OpenRepository() (*repository.Repository, error) {
 
 // Open the backend specified by a location config.
 func open(s string) (backend.Backend, error) {
+	debug.Log("open", "parsing location %v", s)
 	loc, err := location.Parse(s)
 	if err != nil {
 		return nil, err
@@ -173,8 +175,10 @@ func open(s string) (backend.Backend, error) {
 
 	switch loc.Scheme {
 	case "local":
+		debug.Log("open", "opening local repository at %#v", loc.Config)
 		return local.Open(loc.Config.(string))
 	case "sftp":
+		debug.Log("open", "opening sftp repository at %#v", loc.Config)
 		return sftp.OpenWithConfig(loc.Config.(sftp.Config))
 	case "s3":
 		cfg := loc.Config.(s3.Config)
@@ -186,14 +190,17 @@ func open(s string) (backend.Backend, error) {
 			cfg.Secret = os.Getenv("AWS_SECRET_ACCESS_KEY")
 		}
 
-		return s3.Open(loc.Config.(s3.Config))
+		debug.Log("open", "opening s3 repository at %#v", cfg)
+		return s3.Open(cfg)
 	}
 
+	debug.Log("open", "invalid repository location: %v", s)
 	return nil, fmt.Errorf("invalid scheme %q", loc.Scheme)
 }
 
 // Create the backend specified by URI.
 func create(s string) (backend.Backend, error) {
+	debug.Log("open", "parsing location %v", s)
 	loc, err := location.Parse(s)
 	if err != nil {
 		return nil, err
@@ -201,8 +208,10 @@ func create(s string) (backend.Backend, error) {
 
 	switch loc.Scheme {
 	case "local":
+		debug.Log("open", "create local repository at %#v", loc.Config)
 		return local.Create(loc.Config.(string))
 	case "sftp":
+		debug.Log("open", "create sftp repository at %#v", loc.Config)
 		return sftp.CreateWithConfig(loc.Config.(sftp.Config))
 	case "s3":
 		cfg := loc.Config.(s3.Config)
@@ -214,8 +223,10 @@ func create(s string) (backend.Backend, error) {
 			cfg.Secret = os.Getenv("AWS_SECRET_ACCESS_KEY")
 		}
 
-		return s3.Open(loc.Config.(s3.Config))
+		debug.Log("open", "create s3 repository at %#v", loc.Config)
+		return s3.Open(cfg)
 	}
 
+	debug.Log("open", "invalid repository scheme: %v", s)
 	return nil, fmt.Errorf("invalid scheme %q", loc.Scheme)
 }