Skip to content

Commit e6405c7

Browse files
efi: Respect SOURCE_DATE_EPOCH for reproducible builds
If SOURCE_DATE_EPOCH env is set, use it for EFI metadata timestamp, else fallback to SystemTime::now() The BIOS component derives its timestamp from RPM build times via so it is already deterministic Fixes: #1075 Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
1 parent e994131 commit e6405c7

2 files changed

Lines changed: 26 additions & 5 deletions

File tree

src/efi.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use camino::{Utf8Path, Utf8PathBuf};
1515
use cap_std::fs::Dir;
1616
use cap_std_ext::cap_std;
1717
use cap_std_ext::dirext::CapStdExtDirExt;
18-
use chrono::prelude::*;
1918
use fn_error_context::context;
2019
use openat_ext::OpenatDirExt;
2120
use os_release::OsRelease;
@@ -29,7 +28,7 @@ use crate::bootupd::RootContext;
2928
use crate::freezethaw::fsfreeze_thaw_cycle;
3029
use crate::model::*;
3130
use crate::ostreeutil;
32-
use crate::util;
31+
use crate::util::{self, get_metadata_timestamp};
3332
use crate::{component::*, packagesystem::*};
3433
use crate::{filetree, grubconfigs};
3534

@@ -817,10 +816,8 @@ fn generate_meta_from_usr_efi(sysroot_path: &Utf8Path) -> Result<ContentMetadata
817816
}
818817
modules_vec.sort_unstable();
819818

820-
// change to now to workaround https://github.com/coreos/bootupd/issues/933
821-
let timestamp = std::time::SystemTime::now();
822819
let meta = ContentMetadata {
823-
timestamp: chrono::DateTime::<Utc>::from(timestamp),
820+
timestamp: get_metadata_timestamp()?,
824821
version: packages.join(","),
825822
versions: Some(modules_vec),
826823
};

src/util.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use std::path::Path;
33
use std::process::Command;
44

55
use anyhow::{bail, Context, Result};
6+
use chrono::{DateTime, Utc};
7+
use fn_error_context::context;
68
use openat_ext::OpenatDirExt;
79

810
/// Parse an environment variable as UTF-8
@@ -121,3 +123,25 @@ impl Drop for SignalTerminationGuard {
121123
signal_hook_registry::unregister(self.0);
122124
}
123125
}
126+
127+
#[context("Getting timestamp for metadata")]
128+
pub fn get_metadata_timestamp() -> Result<DateTime<Utc>> {
129+
let ts = match std::env::var("SOURCE_DATE_EPOCH") {
130+
Ok(value) => {
131+
let unix_secs = value
132+
.parse::<i64>()
133+
.context("Parsing SOURCE_DATE_EPOCH as integer")?;
134+
135+
chrono::DateTime::from_timestamp_secs(unix_secs).ok_or_else(|| {
136+
anyhow::anyhow!("SOURCE_DATE_EPOCH value '{value}' is not a valid timestamp")
137+
})?
138+
}
139+
Err(std::env::VarError::NotPresent) => {
140+
let timestamp = std::time::SystemTime::now();
141+
chrono::DateTime::<Utc>::from(timestamp)
142+
}
143+
Err(e) => Err(e).context("Reading SOURCE_DATE_EPOCH")?,
144+
};
145+
146+
Ok(ts)
147+
}

0 commit comments

Comments
 (0)