From 60f4592b2c316c40d1adbf0d6622116283675be0 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Wed, 24 Apr 2024 21:37:13 -0600 Subject: [PATCH] repo: Make summary and signature mtime match HTTP servers derive Last-Modified from the modification time of the file. When used in combination with a Cache-Control max-age value, having the modification times match means that caches will consider them expired at the same time. This helps make it more likely that clients won't receive a cached summary and fresh signature or vice versa. This makes more sense to do now that the summary and signature are created in a temporary directory and renamed into place. In the old days where they were created directly in the repo root, it would be strange to change the summary mtime when it wasn't actually modified. --- src/libostree/ostree-repo.c | 17 +++++++++++++++++ tests/test-summary-update.sh | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 04a54029..2f4e836c 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -6092,6 +6092,23 @@ regenerate_metadata (OstreeRepo *self, gboolean do_metadata_commit, GVariant *ad && !_ostree_sign_summary_at (sign, self, summary_tmpdir.fd, sign_keys, cancellable, error)) return FALSE; + /* If a signature was made, sync the summary times to it. This way an + * HTTP client will consider the files expired at the same time. + */ + if (gpg_key_ids != NULL || sign_keys != NULL) + { + struct stat stbuf; + if (!glnx_fstatat (summary_tmpdir.fd, "summary.sig", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return glnx_prefix_error (error, "Unable to get summary.sig status"); + + struct timespec ts[2]; + ts[0] = stbuf.st_atim; + ts[1] = stbuf.st_mtim; + if (TEMP_FAILURE_RETRY (utimensat (summary_tmpdir.fd, "summary", ts, AT_SYMLINK_NOFOLLOW)) + != 0) + return glnx_throw_errno_prefix (error, "Unable to change summary timestamps"); + } + /* Rename them into place */ if (!glnx_renameat (summary_tmpdir.fd, "summary", self->repo_dir_fd, "summary", error)) return glnx_prefix_error (error, "Unable to rename summary file: "); diff --git a/tests/test-summary-update.sh b/tests/test-summary-update.sh index 6cf5fccb..643502cd 100755 --- a/tests/test-summary-update.sh +++ b/tests/test-summary-update.sh @@ -51,6 +51,14 @@ ${CMD_PREFIX} ostree --repo=repo summary --update # Generate a signed summary file. ${CMD_PREFIX} ostree --repo=repo summary --update ${COMMIT_SIGN} +# If the signature file was created, it should have the same +# modification time as the summary file. +if [ -n "${COMMIT_SIGN}" ]; then + stat -c '%y' repo/summary > summary-mtime + stat -c '%y' repo/summary.sig > summary.sig-mtime + assert_files_equal summary-mtime summary.sig-mtime +fi + # Try various ways of adding additional data. ${CMD_PREFIX} ostree --repo=repo summary --update --add-metadata key="'value'" --add-metadata=key2=true ${CMD_PREFIX} ostree --repo=repo summary --update -m some-int='@t 123' @@ -87,6 +95,14 @@ ${CMD_PREFIX} ostree --repo=repo summary --update # Generate a signed summary file. ${CMD_PREFIX} ostree --repo=repo summary --update ${COMMIT_SIGN} +# If the signature file was created, it should have the same +# modification time as the summary file. +if [ -n "${COMMIT_SIGN}" ]; then + stat -c '%y' repo/summary > summary-mtime + stat -c '%y' repo/summary.sig > summary.sig-mtime + assert_files_equal summary-mtime summary.sig-mtime +fi + # Try various ways of adding additional data. ${CMD_PREFIX} ostree --repo=repo summary --update --add-metadata key="'value'" --add-metadata=key2=true ${CMD_PREFIX} ostree --repo=repo summary --update -m some-int='@t 123' -- 2.30.2