From 9b606ad89683c2f196603fc094eb8d4ae96bb5f2 Mon Sep 17 00:00:00 2001 From: Afreen Misbah Date: Tue, 21 Oct 2025 23:50:19 +0530 Subject: [PATCH] mgr/dashboard: Fix timestamps in APIs - remove 'Z' from rbd APIs which are returning now `aware` timestamp - `datetime.utcfromtimestamp` is deprectated so using `datetime.fromtimestamp(timestamp, tz=tz=timezone.utc)` thereby returning only `aware` timestamp and removing 'Z'. - similarly `datetime.utcnow()` is deprecated , migrated to `datetime.now(timezone.utc)` https://docs.python.org/3/library/datetime.html#datetime.datetime.utcnow https://docs.python.org/3/library/datetime.html#datetime.datetime.utcfromtimestamp Signed-off-by: Afreen Misbah --- src/pybind/mgr/dashboard/controllers/rbd.py | 9 ++++----- src/pybind/mgr/dashboard/services/progress.py | 14 +++++++------- src/pybind/mgr/dashboard/services/rbd.py | 10 ++++------ src/pybind/mgr/dashboard/tests/test_rbd_service.py | 12 ++++++------ src/pybind/mgr/dashboard/tools.py | 8 ++++---- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/rbd.py b/src/pybind/mgr/dashboard/controllers/rbd.py index abcbb111a6d..90437cada70 100644 --- a/src/pybind/mgr/dashboard/controllers/rbd.py +++ b/src/pybind/mgr/dashboard/controllers/rbd.py @@ -4,7 +4,7 @@ import logging import math -from datetime import datetime +from datetime import datetime, timezone from functools import partial from typing import Any, Dict @@ -347,9 +347,8 @@ class RbdTrash(RESTController): for trash in images: trash['pool_name'] = pool_name trash['namespace'] = namespace - trash['deletion_time'] = "{}Z".format(trash['deletion_time'].isoformat()) - trash['deferment_end_time'] = "{}Z".format( - trash['deferment_end_time'].isoformat()) + trash['deletion_time'] = trash['deletion_time'].isoformat() + trash['deferment_end_time'] = trash['deferment_end_time'].isoformat() result.append(trash) return result @@ -385,7 +384,7 @@ class RbdTrash(RESTController): @allow_empty_body def purge(self, pool_name=None): """Remove all expired images from trash.""" - now = "{}Z".format(datetime.utcnow().isoformat()) + now = datetime.now(timezone.utc).isoformat() pools = self._trash_list(pool_name) for pool in pools: diff --git a/src/pybind/mgr/dashboard/services/progress.py b/src/pybind/mgr/dashboard/services/progress.py index d1afefbac0c..baf1f92695f 100644 --- a/src/pybind/mgr/dashboard/services/progress.py +++ b/src/pybind/mgr/dashboard/services/progress.py @@ -9,7 +9,7 @@ using the same structure of dashboard tasks import logging -from datetime import datetime +from datetime import datetime, timezone from .. import mgr from . import rbd # pylint: disable=no-name-in-module @@ -40,8 +40,8 @@ def _progress_event_to_dashboard_task_common(event, task): task.update({ 'name': "rbd/{}".format(action), 'metadata': metadata, - 'begin_time': "{}Z".format(datetime.fromtimestamp(event["started_at"]) - .isoformat()), + 'begin_time': datetime.fromtimestamp( + event["started_at"], tz=timezone.utc).isoformat(), }) return @@ -50,8 +50,8 @@ def _progress_event_to_dashboard_task_common(event, task): # from the progress module 'name': "progress/{}".format(event['message']), 'metadata': dict(event.get('refs', {})), - 'begin_time': "{}Z".format(datetime.fromtimestamp(event["started_at"]) - .isoformat()), + 'begin_time': datetime.fromtimestamp( + event["started_at"], tz=timezone.utc).isoformat(), }) @@ -64,8 +64,8 @@ def _progress_event_to_dashboard_task(event, completed=False): }) else: task.update({ - 'end_time': "{}Z".format(datetime.fromtimestamp(event['finished_at']) - .isoformat()), + 'end_time': datetime.fromtimestamp( + event['finished_at'], tz=timezone.utc).isoformat(), 'duration': event['finished_at'] - event['started_at'], 'progress': 100, 'success': 'failed' not in event, diff --git a/src/pybind/mgr/dashboard/services/rbd.py b/src/pybind/mgr/dashboard/services/rbd.py index 667b0e28f8e..07b86988ba3 100644 --- a/src/pybind/mgr/dashboard/services/rbd.py +++ b/src/pybind/mgr/dashboard/services/rbd.py @@ -349,8 +349,7 @@ class RbdService(object): del stat['parent_pool'] del stat['parent_name'] - stat['timestamp'] = "{}Z".format(img.create_timestamp() - .isoformat()) + stat['timestamp'] = img.create_timestamp().isoformat() stat['stripe_count'] = img.stripe_count() stat['stripe_unit'] = img.stripe_unit() @@ -373,8 +372,7 @@ class RbdService(object): if mirror_mode: snap['mirror_mode'] = mirror_mode - snap['timestamp'] = "{}Z".format( - img.get_snap_timestamp(snap['id']).isoformat()) + snap['timestamp'] = img.get_snap_timestamp(snap['id']).isoformat() snap['is_protected'] = None if snap['namespace'] == rbd.RBD_SNAP_NAMESPACE_TYPE_USER: @@ -471,8 +469,8 @@ class RbdService(object): img['unique_id'] = img_spec img['pool_name'] = pool_name img['namespace'] = namespace - img['deletion_time'] = "{}Z".format(img['deletion_time'].isoformat()) - img['deferment_end_time'] = "{}Z".format(img['deferment_end_time'].isoformat()) + img['deletion_time'] = img['deletion_time'].isoformat() + img['deferment_end_time'] = img['deferment_end_time'].isoformat() return img raise rbd.ImageNotFound('No image {} in status `REMOVING` found.'.format(img_spec), errno=errno.ENOENT) diff --git a/src/pybind/mgr/dashboard/tests/test_rbd_service.py b/src/pybind/mgr/dashboard/tests/test_rbd_service.py index 6d780c81651..6624c9e43c8 100644 --- a/src/pybind/mgr/dashboard/tests/test_rbd_service.py +++ b/src/pybind/mgr/dashboard/tests/test_rbd_service.py @@ -78,8 +78,8 @@ class RbdServiceTest(unittest.TestCase): 'unique_id': 'test_pool/3c1a5ee60a88', 'name': 'test_rbd', 'source': 'REMOVING', - 'deletion_time': '{}Z'.format(time.isoformat()), - 'deferment_end_time': '{}Z'.format(time.isoformat()), + 'deletion_time': time.isoformat(), + 'deferment_end_time': time.isoformat(), 'pool_name': 'test_pool', 'namespace': '' }) @@ -124,8 +124,8 @@ class RbdServiceTest(unittest.TestCase): 'unique_id': 'test_pool/3c1a5ee60a88', 'name': 'test_rbd', 'source': 'REMOVING', - 'deletion_time': '{}Z'.format(time.isoformat()), - 'deferment_end_time': '{}Z'.format(time.isoformat()), + 'deletion_time': time.isoformat(), + 'deferment_end_time': time.isoformat(), 'pool_name': 'test_pool', 'namespace': '' } @@ -142,8 +142,8 @@ class RbdServiceTest(unittest.TestCase): 'unique_id': 'test_pool/3c1a5ee60a88', 'name': 'test_rbd', 'source': 'REMOVING', - 'deletion_time': '{}Z'.format(time.isoformat()), - 'deferment_end_time': '{}Z'.format(time.isoformat()), + 'deletion_time': time.isoformat(), + 'deferment_end_time': time.isoformat(), 'pool_name': 'test_pool', 'namespace': '' }], 1)) diff --git a/src/pybind/mgr/dashboard/tools.py b/src/pybind/mgr/dashboard/tools.py index 14de970cceb..fbf1e26bf41 100644 --- a/src/pybind/mgr/dashboard/tools.py +++ b/src/pybind/mgr/dashboard/tools.py @@ -8,7 +8,7 @@ import logging import threading import time import urllib -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone import cherrypy from ceph.utils import strtobool @@ -491,13 +491,13 @@ class TaskManager(object): return [{ 'name': t.name, 'metadata': t.metadata, - 'begin_time': "{}Z".format(datetime.fromtimestamp(t.begin_time).isoformat()), + 'begin_time': datetime.fromtimestamp(t.begin_time, tz=timezone.utc).isoformat(), 'progress': t.progress } for t in ex_t if t.begin_time], [{ 'name': t.name, 'metadata': t.metadata, - 'begin_time': "{}Z".format(datetime.fromtimestamp(t.begin_time).isoformat()), - 'end_time': "{}Z".format(datetime.fromtimestamp(t.end_time).isoformat()), + 'begin_time': datetime.fromtimestamp(t.begin_time, tz=timezone.utc).isoformat(), + 'end_time': datetime.fromtimestamp(t.end_time, tz=timezone.utc).isoformat(), 'duration': t.duration, 'progress': t.progress, 'success': not t.exception, -- 2.39.5