Skip to content

Commit 3655b9e

Browse files
committed
CLI: make "bucket refresh" recurse on containers
Introduce --touch and --recompute parameters which will run the same code as "container touch" on all containers prefixed by the bucket name.
1 parent 5418d59 commit 3655b9e

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

oio/cli/container/container.py

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright (C) 2015-2020 OpenIO SAS, as part of OpenIO SDS
2+
# Copyright (C) 2021-2022 OVH SAS
23
#
34
# This program is free software: you can redistribute it and/or modify
45
# it under the terms of the GNU Affero General Public License as
@@ -27,7 +28,8 @@
2728
M2_PROP_BUCKET_NAME, M2_PROP_CTIME, M2_PROP_DAMAGED_OBJECTS, \
2829
M2_PROP_DEL_EXC_VERSIONS, M2_PROP_MISSING_CHUNKS, \
2930
M2_PROP_OBJECTS, M2_PROP_QUOTA, M2_PROP_STORAGE_POLICY, \
30-
M2_PROP_USAGE, M2_PROP_VERSIONING_POLICY
31+
M2_PROP_USAGE, M2_PROP_VERSIONING_POLICY, CH_ENCODED_SEPARATOR, \
32+
S3_MPU_CONTAINER_SUFFIX
3133
from oio.common.easy_value import boolean_value, int_value, float_value
3234

3335

@@ -857,26 +859,84 @@ class RefreshBucket(Command):
857859
Refresh the counters of a bucket.
858860
859861
Reset all statistics counters and recompute them by summing
860-
the counters of all shards (containers).
862+
the counters of all shards (containers) known by the account service.
863+
864+
Optionally trigger events (from meta2 services) to update the statistics
865+
known by the account service.
861866
"""
862867

863868
log = getLogger(__name__ + '.RefreshBucket')
864869

865870
def get_parser(self, prog_name):
866871
parser = super(RefreshBucket, self).get_parser(prog_name)
872+
parser.add_argument(
873+
'--touch',
874+
action='store_true',
875+
help='Ask each container (in meta2) to send a status event. (Slow)'
876+
)
877+
parser.add_argument(
878+
'--recompute',
879+
action='store_true',
880+
help=('Recompute the statistics of the containers (in meta2) '
881+
'before sending the event (requires --touch). (Slower)')
882+
)
867883
parser.add_argument(
868884
'bucket',
869885
help='Name of the bucket to refresh.'
870886
)
871887
return parser
872888

889+
def _touch_container(self, account, container, recompute=False):
890+
try:
891+
self.log.info('Triggering event for %s/%s',
892+
account, container)
893+
self.app.client_manager.storage.container_touch(
894+
account, container, recompute=recompute)
895+
except Exception as exc:
896+
self.log.error('Failed to touch %s/%s: %s',
897+
account, container, exc)
898+
873899
def take_action(self, parsed_args):
874900
self.log.debug('take_action(%s)', parsed_args)
875901

876902
reqid = request_id(prefix='CLI-BUCKET-')
877903
acct_client = self.app.client_manager.storage.account
904+
905+
# 1. Reset bucket counters
878906
acct_client.bucket_refresh(parsed_args.bucket, reqid=reqid)
879907

908+
if parsed_args.touch:
909+
bucket_meta = acct_client.bucket_show(parsed_args.bucket,
910+
reqid=reqid)
911+
op_count = 0
912+
for suffix in ('', S3_MPU_CONTAINER_SUFFIX):
913+
# 2. Recompute (or at least transmit) container counters
914+
self._touch_container(
915+
bucket_meta['account'], parsed_args.bucket + suffix,
916+
recompute=parsed_args.recompute)
917+
op_count += 1
918+
prefix = parsed_args.bucket + suffix + CH_ENCODED_SEPARATOR
919+
# 3. Recurse on all CH shards
920+
listing = depaginate(
921+
self.app.client_manager.storage.container_list,
922+
item_key=lambda x: x[0],
923+
marker_key=lambda x: x[-1][0],
924+
account=bucket_meta['account'],
925+
prefix=prefix,
926+
reqid=reqid)
927+
for container in listing:
928+
self._touch_container(bucket_meta['account'], container,
929+
recompute=parsed_args.recompute)
930+
op_count += 1
931+
# Show some progress (the whole operation can be long)
932+
if (op_count % 100) == 0:
933+
self.log.warning('%d events triggered so far',
934+
op_count)
935+
self.log.warning('%d events triggered', op_count)
936+
self.log.warning('After events have been consumed, you may '
937+
'need to run "bucket refresh" again (without '
938+
'--touch).')
939+
880940

881941
class RefreshContainer(ContainerCommandMixin, Command):
882942
""" Refresh counters of an account (triggers asynchronous treatments) """

oio/common/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright (C) 2015-2020 OpenIO SAS, as part of OpenIO SDS
2+
# Copyright (C) 2021-2022 OVH SAS
23
#
34
# This library is free software; you can redistribute it and/or
45
# modify it under the terms of the GNU Lesser General Public
@@ -147,6 +148,8 @@
147148
# Default separator used by swift's "container hierarchy" middleware
148149
CH_ENCODED_SEPARATOR = '%2F'
149150
CH_SEPARATOR = '/'
151+
# Suffix for containers hosting S3 multipart-upload parts
152+
S3_MPU_CONTAINER_SUFFIX = '+segments'
150153

151154
BUCKET_PROP_REPLI_ENABLED = 'replication_enabled'
152155

0 commit comments

Comments
 (0)