diff options
| author | Chris Lu <chris.lu@gmail.com> | 2018-07-19 01:21:44 -0700 |
|---|---|---|
| committer | Chris Lu <chris.lu@gmail.com> | 2018-07-19 01:21:44 -0700 |
| commit | c7228fefa70ef4f88d66484f4ac362b1be2d5a5c (patch) | |
| tree | 87a09312e3e7207aa42282b022fa3fdf8dea205b /weed/s3api | |
| parent | 702fbdf7310aa266bc0854492a83589d663d803e (diff) | |
| download | seaweedfs-c7228fefa70ef4f88d66484f4ac362b1be2d5a5c.tar.xz seaweedfs-c7228fefa70ef4f88d66484f4ac362b1be2d5a5c.zip | |
add bucket creation and deletion
1. option for "weed s3 -filer.dir.buckets" to choose a folder for buckets
2. create a bucket
3. delete a bucket, recursively delete all metadata on filer
Diffstat (limited to 'weed/s3api')
| -rw-r--r-- | weed/s3api/s3api_bucket_handlers.go | 82 | ||||
| -rw-r--r-- | weed/s3api/s3api_handlers.go | 4 | ||||
| -rw-r--r-- | weed/s3api/s3api_server.go | 104 |
3 files changed, 138 insertions, 52 deletions
diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go index 976bf857a..de77da7c8 100644 --- a/weed/s3api/s3api_bucket_handlers.go +++ b/weed/s3api/s3api_bucket_handlers.go @@ -7,6 +7,13 @@ import ( "time" "context" "fmt" + "github.com/gorilla/mux" + "os" +) + +var ( + OS_UID = uint32(os.Getuid()) + OS_GID = uint32(os.Getgid()) ) func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Request) { @@ -15,7 +22,7 @@ func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Reques err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { request := &filer_pb.ListEntriesRequest{ - Directory: "/buckets", + Directory: s3a.option.BucketsPath, } glog.V(4).Infof("read directory: %v", request) @@ -56,3 +63,76 @@ func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Reques writeSuccessResponseXML(w, encodeResponse(response)) } + +func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + bucket := vars["bucket"] + + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + request := &filer_pb.CreateEntryRequest{ + Directory: s3a.option.BucketsPath, + Entry: &filer_pb.Entry{ + Name: bucket, + IsDirectory: true, + Attributes: &filer_pb.FuseAttributes{ + Mtime: time.Now().Unix(), + Crtime: time.Now().Unix(), + FileMode: uint32(0777 | os.ModeDir), + Uid: OS_UID, + Gid: OS_GID, + }, + }, + } + + glog.V(1).Infof("create bucket: %v", request) + if _, err := client.CreateEntry(context.Background(), request); err != nil { + return fmt.Errorf("mkdir %s/%s: %v", s3a.option.BucketsPath, bucket, err) + } + + // TODO create collection + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeSuccessResponseEmpty(w) +} + +func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + bucket := vars["bucket"] + + // TODO delete collection + + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + request := &filer_pb.DeleteEntryRequest{ + Directory: s3a.option.BucketsPath, + Name: bucket, + IsDirectory: true, + IsDeleteData: false, + IsRecursive: true, + } + + glog.V(1).Infof("delete bucket: %v", request) + if _, err := client.DeleteEntry(context.Background(), request); err != nil { + return fmt.Errorf("delete bucket %s/%s: %v", s3a.option.BucketsPath, bucket, err) + } + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeResponse(w, http.StatusNoContent, nil, mimeNone) +} diff --git a/weed/s3api/s3api_handlers.go b/weed/s3api/s3api_handlers.go index 759478fe8..229b3a740 100644 --- a/weed/s3api/s3api_handlers.go +++ b/weed/s3api/s3api_handlers.go @@ -89,3 +89,7 @@ func writeResponse(w http.ResponseWriter, statusCode int, response []byte, mType func writeSuccessResponseXML(w http.ResponseWriter, response []byte) { writeResponse(w, http.StatusOK, response, mimeXML) } + +func writeSuccessResponseEmpty(w http.ResponseWriter) { + writeResponse(w, http.StatusOK, nil, mimeNone) +} diff --git a/weed/s3api/s3api_server.go b/weed/s3api/s3api_server.go index 2c23e62ef..267dc29ac 100644 --- a/weed/s3api/s3api_server.go +++ b/weed/s3api/s3api_server.go @@ -15,6 +15,7 @@ type S3ApiServerOption struct { Filer string FilerGrpcAddress string DomainName string + BucketsPath string } type S3ApiServer struct { @@ -40,65 +41,66 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) { } routers = append(routers, apiRouter.PathPrefix("/{bucket}").Subrouter()) - /* for _, bucket := range routers { - // HeadObject - bucket.Methods("HEAD").Path("/{object:.+}").HandlerFunc(s3a.HeadObjectHandler) - // GetObject - bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.GetObjectHandler) - // CopyObject - bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(s3a.CopyObjectHandler) - // PutObject - bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectHandler) - // DeleteObject - bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(s3a.DeleteObjectHandler) - - // CopyObjectPart - bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(s3a.CopyObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") - // PutObjectPart - bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") - // ListObjectPxarts - bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.ListObjectPartsHandler).Queries("uploadId", "{uploadId:.*}") - // CompleteMultipartUpload - bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(s3a.CompleteMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") - // NewMultipartUpload - bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(s3a.NewMultipartUploadHandler).Queries("uploads", "") - // AbortMultipartUpload - bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(s3a.AbortMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") - - // ListMultipartUploads - bucket.Methods("GET").HandlerFunc(s3a.ListMultipartUploadsHandler).Queries("uploads", "") - // ListObjectsV2 - bucket.Methods("GET").HandlerFunc(s3a.ListObjectsV2Handler).Queries("list-type", "2") - // ListObjectsV1 (Legacy) - bucket.Methods("GET").HandlerFunc(s3a.ListObjectsV1Handler) // PutBucket bucket.Methods("PUT").HandlerFunc(s3a.PutBucketHandler) - // HeadBucket - bucket.Methods("HEAD").HandlerFunc(s3a.HeadBucketHandler) - // DeleteMultipleObjects - bucket.Methods("POST").HandlerFunc(s3a.DeleteMultipleObjectsHandler).Queries("delete", "") // DeleteBucket bucket.Methods("DELETE").HandlerFunc(s3a.DeleteBucketHandler) - // not implemented - // GetBucketLocation - bucket.Methods("GET").HandlerFunc(s3a.GetBucketLocationHandler).Queries("location", "") - // GetBucketPolicy - bucket.Methods("GET").HandlerFunc(s3a.GetBucketPolicyHandler).Queries("policy", "") - // GetObjectACL - bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.GetObjectACLHandler).Queries("acl", "") - // GetBucketACL - bucket.Methods("GET").HandlerFunc(s3a.GetBucketACLHandler).Queries("acl", "") - // PutBucketPolicy - bucket.Methods("PUT").HandlerFunc(s3a.PutBucketPolicyHandler).Queries("policy", "") - // DeleteBucketPolicy - bucket.Methods("DELETE").HandlerFunc(s3a.DeleteBucketPolicyHandler).Queries("policy", "") - // PostPolicy - bucket.Methods("POST").HeadersRegexp("Content-Type", "multipart/form-data*").HandlerFunc(s3a.PostPolicyBucketHandler) + /* + // HeadObject + bucket.Methods("HEAD").Path("/{object:.+}").HandlerFunc(s3a.HeadObjectHandler) + // GetObject + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.GetObjectHandler) + // CopyObject + bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(s3a.CopyObjectHandler) + // PutObject + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectHandler) + // DeleteObject + bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(s3a.DeleteObjectHandler) + + // CopyObjectPart + bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(s3a.CopyObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") + // PutObjectPart + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") + // ListObjectPxarts + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.ListObjectPartsHandler).Queries("uploadId", "{uploadId:.*}") + // CompleteMultipartUpload + bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(s3a.CompleteMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") + // NewMultipartUpload + bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(s3a.NewMultipartUploadHandler).Queries("uploads", "") + // AbortMultipartUpload + bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(s3a.AbortMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") + + // ListMultipartUploads + bucket.Methods("GET").HandlerFunc(s3a.ListMultipartUploadsHandler).Queries("uploads", "") + // ListObjectsV2 + bucket.Methods("GET").HandlerFunc(s3a.ListObjectsV2Handler).Queries("list-type", "2") + // ListObjectsV1 (Legacy) + bucket.Methods("GET").HandlerFunc(s3a.ListObjectsV1Handler) + // HeadBucket + bucket.Methods("HEAD").HandlerFunc(s3a.HeadBucketHandler) + // DeleteMultipleObjects + bucket.Methods("POST").HandlerFunc(s3a.DeleteMultipleObjectsHandler).Queries("delete", "") + + // not implemented + // GetBucketLocation + bucket.Methods("GET").HandlerFunc(s3a.GetBucketLocationHandler).Queries("location", "") + // GetBucketPolicy + bucket.Methods("GET").HandlerFunc(s3a.GetBucketPolicyHandler).Queries("policy", "") + // GetObjectACL + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.GetObjectACLHandler).Queries("acl", "") + // GetBucketACL + bucket.Methods("GET").HandlerFunc(s3a.GetBucketACLHandler).Queries("acl", "") + // PutBucketPolicy + bucket.Methods("PUT").HandlerFunc(s3a.PutBucketPolicyHandler).Queries("policy", "") + // DeleteBucketPolicy + bucket.Methods("DELETE").HandlerFunc(s3a.DeleteBucketPolicyHandler).Queries("policy", "") + // PostPolicy + bucket.Methods("POST").HeadersRegexp("Content-Type", "multipart/form-data*").HandlerFunc(s3a.PostPolicyBucketHandler) + */ } - */ // ListBuckets apiRouter.Methods("GET").Path("/").HandlerFunc(s3a.ListBucketsHandler) |
