From 2e0ee62530ee457dd465ef42caa74068bef9d0b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Jul 2024 07:29:10 +0200 Subject: [PATCH] Warn if $SOURCE_DATE_EPOCH is in the future If $SOURCE_DATE_EPOCH < 0, warn and ignore. If $SOURCE_DATE_EPOCH > now, warn and continue. In a build of fityk-1.3.2-8.fc41, the result was: fityk-devel-1.3.2-8.fc41.x86_64 modified-..........T /usr/include/fityk modified-..........T /usr/include/fityk/fityk.h modified-..........T /usr/include/fityk/ui_api.h modified-..........T /usr/lib64/libfityk.so modified-..........T /usr/share/fityk/samples/hello.cc Since we clamp mtimes to $SOURCE_DATE_EPOCH, we don't see a T mismatch very often. This result was a combination of two factors: - the package has "bespoke" autotools-based build system which doesn't preserve timestamps when copying files, - the maintainer made an off-by-one in the changelog datestamp and at the time of the koji build, $SOURCE_DATE_EPOCH which was generated from the changelog entry was higher than the system clock. (It's possible that the date _appeared_ correct in the maintainer's local time zone and it was already after midnight.) So in the koji build, we got the time of the build as final mtimes, because clamping was not performed on timestamps which were lower than the $SOURCE_DATE_EPOCH. When the build was repeated later, the build timestamps were higher than $SOURCE_DATE_EPOCH, so clamping was performed, and we got $SOURCE_DATE_EPOCH as mtimes. It took me much longer to figure this out than it should have. Add a warning when $SOURCE_DATE_EPOCH is either negative or in the future to make such cases easier to diagnose. --- src/options.rs | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/options.rs b/src/options.rs index 516c9f7..74474cb 100644 --- a/src/options.rs +++ b/src/options.rs @@ -3,10 +3,11 @@ use anyhow::{anyhow, Result}; use chrono::{TimeZone, Utc}; use clap::Parser; -use log::{debug, info, LevelFilter}; +use log::{debug, info, log, warn, Level, LevelFilter}; use std::env; use std::os::fd::RawFd; use std::path::PathBuf; +use std::time; use crate::handlers; use crate::simplelog; @@ -149,18 +150,29 @@ impl Config { // $SOURCE_DATE_EPOCH - let source_date_epoch = match env::var("SOURCE_DATE_EPOCH") { + let mut source_date_epoch = match env::var("SOURCE_DATE_EPOCH") { Ok(val) => Some(val.parse::()?), Err(_) => None, }; - match source_date_epoch { - None => debug!("SOURCE_DATE_EPOCH timestamp: {}", "(unset)"), - Some(v) => { - debug!("SOURCE_DATE_EPOCH timestamp: {} ({})", - v, - Utc.timestamp_opt(v, 0).unwrap()); - }, + if let Some(v) = source_date_epoch { + let now = time::SystemTime::now(); + let now_sec = now.duration_since(time::UNIX_EPOCH).unwrap().as_secs(); + + let neg = v < 0; + let pos = v > 0 && v as u64 > now_sec; + + log!(if neg || pos { Level::Warn } else { Level::Debug }, + "SOURCE_DATE_EPOCH timestamp: {v} ({})", + Utc.timestamp_opt(v, 0).unwrap()); + if neg { + warn!("SOURCE_DATE_EPOCH timestamp is negative, ignoring: {v}"); + source_date_epoch = None; + } else if pos { + warn!("SOURCE_DATE_EPOCH timestamp is in the future: {v} > {now_sec}"); + } + } else { + debug!("SOURCE_DATE_EPOCH timestamp: {}", "(unset)"); } Ok(Some(Self {