From 0046803534bf41cd3fb55b449a97cc18c2d3840c Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Mon, 4 Oct 2021 11:22:11 -0400 Subject: [PATCH] qa/rgw: use local runner with cmdline radosgw_admin.py Restore ability to run radosgw_admin.py unit standalone--improved to use vstart_runner hooks. Local rgwadmin(...) wrapper suggested as a cleanup in review by Casey. Fixes: https://tracker.ceph.com/issues/52837 Signed-off-by: Matt Benjamin --- qa/tasks/radosgw_admin.py | 102 +++++++++++++++++++++++++++++--------- qa/tasks/util/rgw.py | 13 +++-- qa/tasks/vstart_runner.py | 5 +- 3 files changed, 92 insertions(+), 28 deletions(-) diff --git a/qa/tasks/radosgw_admin.py b/qa/tasks/radosgw_admin.py index e803249cff1..780dae1e15a 100644 --- a/qa/tasks/radosgw_admin.py +++ b/qa/tasks/radosgw_admin.py @@ -7,7 +7,7 @@ Rgw admin testing against a running instance # grep '^ *# TESTCASE' | sed 's/^ *# TESTCASE //' # # to run this standalone: -# python qa/tasks/radosgw_admin.py [USER] HOSTNAME +# python qa/tasks/radosgw_admin.py [--user=uid] --host=host --port=port # import json @@ -16,7 +16,7 @@ import time import datetime import sys -from io import BytesIO +from io import StringIO from queue import Queue import boto.exception @@ -25,11 +25,22 @@ import boto.s3.acl import httplib2 +#import pdb -from tasks.util.rgw import rgwadmin, get_user_summary, get_user_successful_ops +import tasks.vstart_runner +from tasks.rgw import RGWEndpoint +from tasks.util.rgw import rgwadmin as tasks_util_rgw_rgwadmin +from tasks.util.rgw import get_user_summary, get_user_successful_ops log = logging.getLogger(__name__) +def rgwadmin(*args, **kwargs): + ctx = args[0] + # Is this a local runner? + omit_sudo = hasattr(ctx.rgw, 'omit_sudo') and ctx.rgw.omit_sudo == True + omit_tdir = hasattr(ctx.rgw, 'omit_tdir') and ctx.rgw.omit_tdir == True + return tasks_util_rgw_rgwadmin(*args, **kwargs, omit_sudo=omit_sudo, omit_tdir=omit_tdir) + def usage_acc_findentry2(entries, user, add=True): for e in entries: if e['user'] == user: @@ -257,6 +268,36 @@ def get_acl(key): remove_newlines(raw_acl) ) +def cleanup(ctx, client): + # remove objects and buckets + (err, out) = rgwadmin(ctx, client, ['bucket', 'list'], check_status=True) + try: + for bucket in out: + (err, out) = rgwadmin(ctx, client, [ + 'bucket', 'rm', '--bucket', bucket, '--purge-objects'], + check_status=True) + except: + pass + + # remove test user(s) + users = ['foo', 'fud', 'bar', 'bud'] + users.reverse() + for user in users: + try: + (err, out) = rgwadmin(ctx, client, [ + 'user', 'rm', '--uid', user], + check_status=True) + except: + pass + + # remove custom placement + try: + zonecmd = ['zone', 'placement', 'rm', '--rgw-zone', 'default', + '--placement-id', 'new-placement'] + (err, out) = rgwadmin(ctx, client, zonecmd, check_status=True) + except: + pass + def task(ctx, config): """ Test radosgw-admin functionality against a running rgw instance. @@ -277,6 +318,8 @@ def task(ctx, config): # the role_endpoints that were assigned by the rgw task endpoint = ctx.rgw.role_endpoints[client] + cleanup(ctx, client) + ## user1='foo' user2='fud' @@ -309,6 +352,8 @@ def task(ctx, config): host=endpoint.hostname, calling_format=boto.s3.connection.OrdinaryCallingFormat(), ) + connection.auth_region_name='us-east-1' + connection2 = boto.s3.connection.S3Connection( aws_access_key_id=access_key2, aws_secret_access_key=secret_key2, @@ -317,6 +362,8 @@ def task(ctx, config): host=endpoint.hostname, calling_format=boto.s3.connection.OrdinaryCallingFormat(), ) + connection2.auth_region_name='us-east-1' + connection3 = boto.s3.connection.S3Connection( aws_access_key_id=access_key3, aws_secret_access_key=secret_key3, @@ -325,6 +372,7 @@ def task(ctx, config): host=endpoint.hostname, calling_format=boto.s3.connection.OrdinaryCallingFormat(), ) + connection3.auth_region_name='us-east-1' acc = usage_acc() rl = requestlog_queue(acc.generate_make_entry()) @@ -760,17 +808,19 @@ def task(ctx, config): # wait a bit to give the garbage collector time to cycle time.sleep(15) - (err, out) = rgwadmin(ctx, client, ['gc', 'list']) - + (err, out) = rgwadmin(ctx, client, ['gc', 'list', '--include-all']) assert len(out) > 0 # TESTCASE 'gc-process', 'gc', 'process', 'manually collect garbage' (err, out) = rgwadmin(ctx, client, ['gc', 'process'], check_status=True) #confirm - (err, out) = rgwadmin(ctx, client, ['gc', 'list']) + (err, out) = rgwadmin(ctx, client, ['gc', 'list', '--include-all']) - assert len(out) == 0 + # don't assume rgw_gc_obj_min_wait has been overridden + omit_tdir = hasattr(ctx.rgw, 'omit_tdir') and ctx.rgw.omit_tdir == True + if omit_tdir==False: + assert len(out) == 0 # TESTCASE 'rm-user-buckets','user','rm','existing user','fails, still has buckets' (err, out) = rgwadmin(ctx, client, ['user', 'rm', '--uid', user1]) @@ -1023,8 +1073,6 @@ def task(ctx, config): assert err # TESTCASE 'zone-info', 'zone', 'get', 'get zone info', 'succeeds, has default placement rule' - # - (err, out) = rgwadmin(ctx, client, ['zone', 'get','--rgw-zone','default']) orig_placement_pools = len(out['placement_pools']) @@ -1042,7 +1090,7 @@ def task(ctx, config): out['placement_pools'].append(rule) (err, out) = rgwadmin(ctx, client, ['zone', 'set'], - stdin=BytesIO(json.dumps(out).encode()), + stdin=StringIO(json.dumps(out)), check_status=True) (err, out) = rgwadmin(ctx, client, ['zone', 'get']) @@ -1059,32 +1107,40 @@ def task(ctx, config): (err, out) = rgwadmin(ctx, client, ['zonegroup', 'get'], check_status=True) from teuthology.config import config -from teuthology.orchestra import cluster, remote +from teuthology.orchestra import cluster + import argparse; def main(): - if len(sys.argv) == 3: - user = sys.argv[1] + "@" - host = sys.argv[2] - elif len(sys.argv) == 2: - user = "" - host = sys.argv[1] + parser = argparse.ArgumentParser() + parser.add_argument('--uid') + parser.add_argument('--host', required=True) + parser.add_argument('--port', type=int) + + args = parser.parse_args() + host = args.host + if args.port: + port = args.port else: - sys.stderr.write("usage: radosgw_admin.py [user] host\n") - exit(1) - client0 = remote.Remote(user + host) + port = 80 + + client0 = tasks.vstart_runner.LocalRemote() ctx = config ctx.cluster=cluster.Cluster(remotes=[(client0, - [ 'ceph.client.rgw.%s' % (host), ]),]) + [ 'ceph.client.rgw.%s' % (port), ]),]) ctx.rgw = argparse.Namespace() endpoints = {} - endpoints['ceph.client.rgw.%s' % host] = (host, 80) + endpoints['ceph.client.rgw.%s' % port] = RGWEndpoint( + hostname=host, + port=port) ctx.rgw.role_endpoints = endpoints ctx.rgw.realm = None ctx.rgw.regions = {'region0': { 'api name': 'api1', 'is master': True, 'master zone': 'r0z0', 'zones': ['r0z0', 'r0z1'] }} - ctx.rgw.config = {'ceph.client.rgw.%s' % host: {'system user': {'name': '%s-system-user' % host}}} + ctx.rgw.omit_sudo = True + ctx.rgw.omit_tdir = True + ctx.rgw.config = {'ceph.client.rgw.%s' % port: {'system user': {'name': '%s-system-user' % port}}} task(config, None) exit() diff --git a/qa/tasks/util/rgw.py b/qa/tasks/util/rgw.py index c955f3150a8..59c801028f9 100644 --- a/qa/tasks/util/rgw.py +++ b/qa/tasks/util/rgw.py @@ -9,27 +9,32 @@ from teuthology import misc as teuthology log = logging.getLogger(__name__) def rgwadmin(ctx, client, cmd, stdin=StringIO(), check_status=False, - format='json', decode=True, log_level=logging.DEBUG): + omit_sudo=False, omit_tdir=False, format='json', decode=True, + log_level=logging.DEBUG): log.info('rgwadmin: {client} : {cmd}'.format(client=client,cmd=cmd)) testdir = teuthology.get_testdir(ctx) cluster_name, daemon_type, client_id = teuthology.split_role(client) client_with_id = daemon_type + '.' + client_id pre = [ 'adjust-ulimits', - 'ceph-coverage', - '{tdir}/archive/coverage'.format(tdir=testdir), + 'ceph-coverage'] + if not omit_tdir: + pre.append( + '{tdir}/archive/coverage'.format(tdir=testdir)) + pre.extend([ 'radosgw-admin', '--log-to-stderr', '--format', format, '-n', client_with_id, '--cluster', cluster_name, - ] + ]) pre.extend(cmd) log.log(log_level, 'rgwadmin: cmd=%s' % pre) (remote,) = ctx.cluster.only(client).remotes.keys() proc = remote.run( args=pre, check_status=check_status, + omit_sudo=omit_sudo, stdout=StringIO(), stderr=StringIO(), stdin=stdin, diff --git a/qa/tasks/vstart_runner.py b/qa/tasks/vstart_runner.py index 63976fc9d6e..9a173846fd6 100644 --- a/qa/tasks/vstart_runner.py +++ b/qa/tasks/vstart_runner.py @@ -466,6 +466,8 @@ class LocalRemote(object): subproc.stdin.write(stdin.encode()) elif stdin == subprocess.PIPE or stdin == PIPE: pass + elif isinstance(stdin, StringIO): + subproc.stdin.write(bytes(stdin.getvalue(),encoding='utf8')) else: subproc.stdin.write(stdin) @@ -1059,7 +1061,6 @@ def load_tests(modules, loader): def scan_tests(modules): overall_suite = load_tests(modules, loader.TestLoader()) - max_required_mds = 0 max_required_clients = 0 max_required_mgr = 0 @@ -1330,6 +1331,8 @@ def exec_test(): # tools that the tests might want to use (add more here if needed) require_binaries = ["ceph-dencoder", "cephfs-journal-tool", "cephfs-data-scan", "cephfs-table-tool", "ceph-fuse", "rados", "cephfs-meta-injection"] + # What binaries may be required is task specific + require_binaries = ["ceph-dencoder", "rados"] missing_binaries = [b for b in require_binaries if not os.path.exists(os.path.join(BIN_PREFIX, b))] if missing_binaries and not opt_ignore_missing_binaries: log.error("Some ceph binaries missing, please build them: {0}".format(" ".join(missing_binaries))) -- 2.39.5