From 81e09bee540b353e26e165dea175e59934adc79d Mon Sep 17 00:00:00 2001 From: Yuval Lifshitz Date: Tue, 20 May 2025 08:44:05 +0000 Subject: [PATCH] rgw/logging: add mtime to get-bucket-logging response Fixes: https://tracker.ceph.com/issues/71385 Signed-off-by: Yuval Lifshitz --- doc/radosgw/s3/bucketops.rst | 3 ++- src/rgw/rgw_common.h | 1 + src/rgw/rgw_rest_bucket_logging.cc | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/doc/radosgw/s3/bucketops.rst b/doc/radosgw/s3/bucketops.rst index 8153d7e57e5fb..0002c1c750d14 100644 --- a/doc/radosgw/s3/bucketops.rst +++ b/doc/radosgw/s3/bucketops.rst @@ -862,7 +862,8 @@ Syntax Response Entities ~~~~~~~~~~~~~~~~~ -Response is XML encoded in the body of the request, in the following format: +Response header contains ``Last-Modified`` date/time of the logging configuration. +Logging configuration is XML encoded in the body of the response, in the following format: :: diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 45814fb341e3a..a01377a1eb4d9 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -110,6 +110,7 @@ using ceph::crypto::MD5; #define RGW_ATTR_X_ROBOTS_TAG RGW_ATTR_PREFIX "x-robots-tag" #define RGW_ATTR_STORAGE_CLASS RGW_ATTR_PREFIX "storage_class" #define RGW_ATTR_BUCKET_LOGGING RGW_ATTR_PREFIX "logging" +#define RGW_ATTR_BUCKET_LOGGING_MTIME RGW_ATTR_PREFIX "logging-mtime" #define RGW_ATTR_BUCKET_LOGGING_SOURCES RGW_ATTR_PREFIX "logging-sources" /* S3 Object Lock*/ diff --git a/src/rgw/rgw_rest_bucket_logging.cc b/src/rgw/rgw_rest_bucket_logging.cc index 60a4b5b2b66bf..e0b8d4cb06fd2 100644 --- a/src/rgw/rgw_rest_bucket_logging.cc +++ b/src/rgw/rgw_rest_bucket_logging.cc @@ -32,12 +32,21 @@ namespace { } return 0; } + + void update_mtime_attribute(const DoutPrefixProvider* dpp, rgw::sal::Attrs& attrs) { + bufferlist mtime_bl; + const auto mtime = ceph::coarse_real_time::clock::now(); + encode(mtime, mtime_bl); + attrs[RGW_ATTR_BUCKET_LOGGING_MTIME] = std::move(mtime_bl); + ldpp_dout(dpp, 20) << "INFO: logging config modified at: " << mtime << dendl; + } } // GET //?logging // reply is XML encoded class RGWGetBucketLoggingOp : public RGWOp { rgw::bucketlogging::configuration configuration; + std::optional mtime; public: int verify_permission(optional_yield y) override { @@ -73,6 +82,20 @@ public: try { configuration.enabled = true; decode(configuration, iter->second); + if (auto mtime_it = src_bucket->get_attrs().find(RGW_ATTR_BUCKET_LOGGING_MTIME); + mtime_it != src_bucket->get_attrs().end()) { + try { + ceph::real_time tmp_mtime; + decode(tmp_mtime, mtime_it->second); + mtime = std::move(tmp_mtime); + } catch (buffer::error& err) { + ldpp_dout(this, 5) << "WARNING: failed to decode logging mtime attribute '" << RGW_ATTR_BUCKET_LOGGING_MTIME + << "' for bucket '" << src_bucket_id << "', error: " << err.what() << dendl; + } + } else { + ldpp_dout(this, 5) << "WARNING: no logging mtime attribute '" << RGW_ATTR_BUCKET_LOGGING_MTIME + << "' for bucket '" << src_bucket_id << "'" << dendl; + } } catch (buffer::error& err) { ldpp_dout(this, 1) << "WARNING: failed to decode logging attribute '" << RGW_ATTR_BUCKET_LOGGING << "' for bucket '" << src_bucket_id << "', error: " << err.what() << dendl; @@ -89,6 +112,9 @@ public: void send_response() override { dump_errno(s); + if (mtime) { + dump_last_modified(s, *mtime); + } end_header(s, this, to_mime_type(s->format)); dump_start(s); @@ -253,6 +279,7 @@ class RGWPutBucketLoggingOp : public RGWDefaultResponseOp { if (!old_conf || (old_conf && *old_conf != configuration)) { // conf changed (or was unknown) - update it->second = conf_bl; + update_mtime_attribute(this, attrs); return src_bucket->merge_and_store_attrs(this, attrs, y); } // nothing to update @@ -260,6 +287,7 @@ class RGWPutBucketLoggingOp : public RGWDefaultResponseOp { } // conf was added attrs.insert(std::make_pair(RGW_ATTR_BUCKET_LOGGING, conf_bl)); + update_mtime_attribute(this, attrs); return src_bucket->merge_and_store_attrs(this, attrs, y); }, y); if (op_ret < 0) { -- 2.39.5