From 138ad785ecb45ab979b2456915500fe601e36784 Mon Sep 17 00:00:00 2001 From: Andreas Joachim Peters Date: Wed, 22 May 2024 13:20:45 +0200 Subject: [PATCH] S3: implement 'deletebucket' subcommand in xs3 --- src/XrdS3/app/xs3 | 94 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/XrdS3/app/xs3 b/src/XrdS3/app/xs3 index 3e5befe97e1..d9146b19642 100755 --- a/src/XrdS3/app/xs3 +++ b/src/XrdS3/app/xs3 @@ -58,6 +58,11 @@ def main(): addbucket_parser.add_argument('bucketname', help='Bucket name') addbucket_parser.add_argument('bucketpath', help='Bucket path') + # Add the 'deletebucket' subcommand + deletebucket_parser = subparsers.add_parser('deletebucket', help='Delete an existing bucket') + deletebucket_parser.add_argument('username', help='Username') + deletebucket_parser.add_argument('bucketname', help='Bucket name') + # Parse the arguments args = parser.parse_args() @@ -70,6 +75,8 @@ def main(): handle_deleteuser(args) elif args.subcommand == 'addbucket': handle_addbucket(args) + elif args.subcommand == 'deletebucket': + handle_deletebucket(args) else: parser.print_help() @@ -354,6 +361,20 @@ def handle_addbucket(args): print(f"Error: Failed to read the config file '{config_file}'. {e}") return + # Check if the bucket file already exists + buckets_dir = os.path.join(base_path, 'buckets') + bucket_file = os.path.join(buckets_dir, bucketname) + if os.path.exists(bucket_file): + try: + owner_attr = os.getxattr(bucket_file, 'user.s3.owner') + path_attr = os.getxattr(bucket_file, 'user.s3.path') + owner = owner_attr.decode() + path = path_attr.decode() + print(f"Error: Bucket '{bucketname}' already exists. Owner: {owner}, Path: {path}") + except OSError as e: + print(f"Error: Failed to retrieve extended attributes from bucket file '{bucket_file}'. {e}") + return + # Check if the user directory exists users_dir = os.path.join(base_path, 'users') user_dir = os.path.join(users_dir, username) @@ -361,6 +382,16 @@ def handle_addbucket(args): print("Error: User does not exist - use 'adduser' first.") return + # Create an empty file under the users directory with the username + user_bucket_file = os.path.join(user_dir, bucketname) + if not os.path.exists(user_bucket_file): + try: + with open(user_bucket_file, 'w') as f: + f.write('') + print(f"Info: Empty file '{user_bucket_file}' created successfully under users directory.") + except OSError as e: + print(f"Error: Failed to create empty file '{user_bucket_file}' under users directory. {e}") + # Create the bucket directory buckets_dir = os.path.join(base_path, 'buckets') bucket_file = os.path.join(buckets_dir, bucketname) @@ -384,6 +415,69 @@ def handle_addbucket(args): except OSError as e: print(f"Error: Failed to set extended attributes on '{bucket_file}'. {e}") +def handle_deletebucket(args): + username = args.username + bucketname = args.bucketname + + # Determine the base path from the config file + config_dir = os.path.join(os.path.expanduser('~'), '.xs3') + config_file = os.path.join(config_dir, 'config') + + if not os.path.exists(config_file): + print("Error: Configuration file does not exist. Please run 'config' subcommand first.") + return + + try: + with open(config_file, 'r') as f: + config_data = json.load(f) + base_path = config_data.get('base_path') + if not base_path: + print("Error: Base path is not configured properly.") + return + except (IOError, json.JSONDecodeError) as e: + print(f"Error: Failed to read the config file '{config_file}'. {e}") + return + + # Check if the user directory exists + users_dir = os.path.join(base_path, 'users') + user_dir = os.path.join(users_dir, username) + if not os.path.exists(user_dir): + print("Error: User does not exist - use adduser first.") + return + + # Check if the bucket file exists + buckets_dir = os.path.join(base_path, 'buckets') + bucket_file = os.path.join(buckets_dir, bucketname) + if not os.path.exists(bucket_file): + print(f"Error: Bucket '{bucketname}' does not exist.") + return + + # Check if the user is the owner of the bucket + try: + owner_attr = os.getxattr(bucket_file, 'user.s3.owner') + if owner_attr.decode() != username: + print("Error: User is not the owner of the given bucket.") + return + except OSError as e: + print(f"Error: Failed to retrieve extended attribute from bucket file '{bucket_file}'. {e}") + return + + # Delete the bucket file + try: + os.remove(bucket_file) + print(f"Info: Bucket file '{bucket_file}' deleted successfully.") + except OSError as e: + print(f"Error: Failed to delete bucket file '{bucket_file}'. {e}") + + # Delete the empty file under the users directory with the bucket name + user_bucket_file = os.path.join(user_dir, bucketname) + if os.path.exists(user_bucket_file): + try: + os.remove(user_bucket_file) + print(f"Info: Empty file '{user_bucket_file}' deleted successfully from users directory.") + except OSError as e: + print(f"Error: Failed to delete empty file '{user_bucket_file}' from users directory. {e}") + if __name__ == '__main__': main()