aboutsummaryrefslogtreecommitdiff
path: root/weed/admin
diff options
context:
space:
mode:
Diffstat (limited to 'weed/admin')
-rw-r--r--weed/admin/dash/admin_server.go111
1 files changed, 71 insertions, 40 deletions
diff --git a/weed/admin/dash/admin_server.go b/weed/admin/dash/admin_server.go
index c62b9da07..0e5886cfa 100644
--- a/weed/admin/dash/admin_server.go
+++ b/weed/admin/dash/admin_server.go
@@ -30,10 +30,41 @@ import (
"github.com/seaweedfs/seaweedfs/weed/worker/tasks"
)
-const (
- // DefaultBucketsPath is the default path for S3 buckets in the filer
- DefaultBucketsPath = "/buckets"
-)
+// FilerConfig holds filer configuration needed for bucket operations
+type FilerConfig struct {
+ BucketsPath string
+ FilerGroup string
+}
+
+// getFilerConfig retrieves the filer configuration (buckets path and filer group)
+func (s *AdminServer) getFilerConfig() (*FilerConfig, error) {
+ config := &FilerConfig{
+ BucketsPath: s3_constants.DefaultBucketsPath,
+ FilerGroup: "",
+ }
+
+ err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
+ resp, err := client.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{})
+ if err != nil {
+ return fmt.Errorf("get filer configuration: %w", err)
+ }
+ if resp.DirBuckets != "" {
+ config.BucketsPath = resp.DirBuckets
+ }
+ config.FilerGroup = resp.FilerGroup
+ return nil
+ })
+
+ return config, err
+}
+
+// getCollectionName returns the collection name for a bucket, prefixed with filer group if configured
+func getCollectionName(filerGroup, bucketName string) string {
+ if filerGroup != "" {
+ return fmt.Sprintf("%s_%s", filerGroup, bucketName)
+ }
+ return bucketName
+}
type AdminServer struct {
masterClient *wdclient.MasterClient
@@ -255,28 +286,17 @@ func (s *AdminServer) GetS3Buckets() ([]S3Bucket, error) {
return nil, fmt.Errorf("failed to get volume information: %w", err)
}
- // Get filer configuration to determine FilerGroup
- var filerGroup string
- err = s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
- configResp, err := client.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{})
- if err != nil {
- glog.Warningf("Failed to get filer configuration: %v", err)
- // Continue without filer group
- return nil
- }
- filerGroup = configResp.FilerGroup
- return nil
- })
-
+ // Get filer configuration (buckets path and filer group)
+ filerConfig, err := s.getFilerConfig()
if err != nil {
- return nil, fmt.Errorf("failed to get filer configuration: %w", err)
+ glog.Warningf("Failed to get filer configuration, using defaults: %v", err)
}
// Now list buckets from the filer and match with collection data
err = s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
- // List buckets by looking at the /buckets directory
+ // List buckets by looking at the buckets directory
stream, err := client.ListEntries(context.Background(), &filer_pb.ListEntriesRequest{
- Directory: DefaultBucketsPath,
+ Directory: filerConfig.BucketsPath,
Prefix: "",
StartFromFileName: "",
InclusiveStartFrom: false,
@@ -299,12 +319,7 @@ func (s *AdminServer) GetS3Buckets() ([]S3Bucket, error) {
bucketName := resp.Entry.Name
// Determine collection name for this bucket
- var collectionName string
- if filerGroup != "" {
- collectionName = fmt.Sprintf("%s_%s", filerGroup, bucketName)
- } else {
- collectionName = bucketName
- }
+ collectionName := getCollectionName(filerConfig.FilerGroup, bucketName)
// Get size and object count from collection data
var size int64
@@ -373,7 +388,13 @@ func (s *AdminServer) GetS3Buckets() ([]S3Bucket, error) {
// GetBucketDetails retrieves detailed information about a specific bucket
func (s *AdminServer) GetBucketDetails(bucketName string) (*BucketDetails, error) {
- bucketPath := fmt.Sprintf("/buckets/%s", bucketName)
+ // Get filer configuration (buckets path)
+ filerConfig, err := s.getFilerConfig()
+ if err != nil {
+ glog.Warningf("Failed to get filer configuration, using defaults: %v", err)
+ }
+
+ bucketPath := fmt.Sprintf("%s/%s", filerConfig.BucketsPath, bucketName)
details := &BucketDetails{
Bucket: S3Bucket{
@@ -383,10 +404,10 @@ func (s *AdminServer) GetBucketDetails(bucketName string) (*BucketDetails, error
UpdatedAt: time.Now(),
}
- err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
+ err = s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
// Get bucket info
bucketResp, err := client.LookupDirectoryEntry(context.Background(), &filer_pb.LookupDirectoryEntryRequest{
- Directory: DefaultBucketsPath,
+ Directory: filerConfig.BucketsPath,
Name: bucketName,
})
if err != nil {
@@ -434,7 +455,7 @@ func (s *AdminServer) GetBucketDetails(bucketName string) (*BucketDetails, error
details.Bucket.Owner = owner
// List objects in bucket (recursively)
- return s.listBucketObjects(client, bucketPath, "", details)
+ return s.listBucketObjects(client, bucketPath, bucketPath, "", details)
})
if err != nil {
@@ -445,7 +466,8 @@ func (s *AdminServer) GetBucketDetails(bucketName string) (*BucketDetails, error
}
// listBucketObjects recursively lists all objects in a bucket
-func (s *AdminServer) listBucketObjects(client filer_pb.SeaweedFilerClient, directory, prefix string, details *BucketDetails) error {
+// bucketBasePath is the full path to the bucket (e.g., /buckets/mybucket)
+func (s *AdminServer) listBucketObjects(client filer_pb.SeaweedFilerClient, bucketBasePath, directory, prefix string, details *BucketDetails) error {
stream, err := client.ListEntries(context.Background(), &filer_pb.ListEntriesRequest{
Directory: directory,
Prefix: prefix,
@@ -470,16 +492,16 @@ func (s *AdminServer) listBucketObjects(client filer_pb.SeaweedFilerClient, dire
if entry.IsDirectory {
// Recursively list subdirectories
subDir := fmt.Sprintf("%s/%s", directory, entry.Name)
- err := s.listBucketObjects(client, subDir, "", details)
+ err := s.listBucketObjects(client, bucketBasePath, subDir, "", details)
if err != nil {
return err
}
} else {
// Add file object
objectKey := entry.Name
- if directory != fmt.Sprintf("/buckets/%s", details.Bucket.Name) {
+ if directory != bucketBasePath {
// Remove bucket prefix to get relative path
- relativePath := directory[len(fmt.Sprintf("/buckets/%s", details.Bucket.Name))+1:]
+ relativePath := directory[len(bucketBasePath)+1:]
objectKey = fmt.Sprintf("%s/%s", relativePath, entry.Name)
}
@@ -511,10 +533,17 @@ func (s *AdminServer) CreateS3Bucket(bucketName string) error {
// DeleteS3Bucket deletes an S3 bucket and all its contents
func (s *AdminServer) DeleteS3Bucket(bucketName string) error {
- // First, check if bucket has Object Lock enabled and if there are locked objects
ctx := context.Background()
- err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
- return s3api.CheckBucketForLockedObjects(ctx, client, DefaultBucketsPath, bucketName)
+
+ // Get filer configuration (buckets path and filer group)
+ filerConfig, err := s.getFilerConfig()
+ if err != nil {
+ return fmt.Errorf("failed to get filer configuration: %w", err)
+ }
+
+ // Check if bucket has Object Lock enabled and if there are locked objects
+ err = s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
+ return s3api.CheckBucketForLockedObjects(ctx, client, filerConfig.BucketsPath, bucketName)
})
if err != nil {
return err
@@ -522,21 +551,23 @@ func (s *AdminServer) DeleteS3Bucket(bucketName string) error {
// Delete the collection first (same as s3.bucket.delete shell command)
// This ensures volume data is cleaned up properly
+ // Collection name must be prefixed with filer group if configured
+ collectionName := getCollectionName(filerConfig.FilerGroup, bucketName)
err = s.WithMasterClient(func(client master_pb.SeaweedClient) error {
_, err := client.CollectionDelete(ctx, &master_pb.CollectionDeleteRequest{
- Name: bucketName,
+ Name: collectionName,
})
return err
})
if err != nil {
- return fmt.Errorf("failed to delete collection: %w", err)
+ return fmt.Errorf("failed to delete collection %s: %w", collectionName, err)
}
// Then delete bucket directory recursively from filer
// Use same parameters as s3.bucket.delete shell command and S3 API
return s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
_, err := client.DeleteEntry(ctx, &filer_pb.DeleteEntryRequest{
- Directory: DefaultBucketsPath,
+ Directory: filerConfig.BucketsPath,
Name: bucketName,
IsDeleteData: false, // Collection already deleted, just remove metadata
IsRecursive: true,