]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
qa/rgw: use local runner with cmdline radosgw_admin.py
authorMatt Benjamin <mbenjamin@redhat.com>
Mon, 4 Oct 2021 15:22:11 +0000 (11:22 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Wed, 17 Nov 2021 16:22:32 +0000 (11:22 -0500)
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 <mbenjamin@redhat.com>
qa/tasks/radosgw_admin.py
qa/tasks/util/rgw.py
qa/tasks/vstart_runner.py

index e803249cff1273e1f162d57e412fe991c35701b0..780dae1e15a6d15cfce2ef8523beb42cd3eac50f 100644 (file)
@@ -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()
 
index c955f3150a8657384cb9cb4b4ae55a054f86ccc3..59c801028f937f343e8ea14546dc350a6d702a2d 100644 (file)
@@ -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,
index 63976fc9d6e3801c3738e32d7443b1f571fb7a95..9a173846fd6f198e2695648dc33c02c5c39bc908 100644 (file)
@@ -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)))