Skip to content

Commit 13702bc

Browse files
authored
containertool: Use epoch date in image metadata (#38)
Motivation ---------- The registry is a content-addressable store in which objects are identified by their hashes. Many objects, such as image manifests, contain timestamp fields. A difference in a timestamp field will cause otherwise identical objects to have different hashes, causing a variety of problems: * an image cannot be verified by rebuilding it from the same original parts and comparing the result * the registry cannot completely deduplicate two images with almost identical contents because their hashes do not match, wasting storage and network bandwidth (some block-level deduplication may still be possible, but clients which already have one image will have to pull the other in its entirety) These problems can be avoided by setting timestamp fields to fixed values, often the Unix epoch: https://reproducible-builds.org/docs/source-date-epoch/ Modifications ------------- Set the overall image manifest timestamp and the timestamp used in the image history log to the Unix epoch. `containertool` already sets file modification times to the epoch when creating image layers. Result ------ An image packaging the same executable will have the same hash when built at different times on the same machine or different machines. Test Plan --------- * All existing tests, including end to end tests, continue to pass. * Manually verified that repeated builds produces images with identical hashes.
1 parent bfdab0e commit 13702bc

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

Sources/containertool/containertool.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ enum AllowHTTP: String, ExpressibleByArgument, CaseIterable { case source, desti
144144

145145
// MARK: Create the application configuration
146146

147-
let now = Date.now.ISO8601Format()
147+
let timestamp = Date(timeIntervalSince1970: 0).ISO8601Format()
148148

149149
// Inherit the configuration of the base image - UID, GID, environment etc -
150150
// and override the entrypoint.
@@ -154,7 +154,7 @@ enum AllowHTTP: String, ExpressibleByArgument, CaseIterable { case source, desti
154154
inherited_config.WorkingDir = "/"
155155

156156
let configuration = ImageConfiguration(
157-
created: now,
157+
created: timestamp,
158158
architecture: architecture,
159159
os: os,
160160
config: inherited_config,
@@ -167,7 +167,7 @@ enum AllowHTTP: String, ExpressibleByArgument, CaseIterable { case source, desti
167167
digest(of: tardiff)
168168
] + baseimage_config.rootfs.diff_ids
169169
),
170-
history: [.init(created: now, created_by: "containertool")]
170+
history: [.init(created: timestamp, created_by: "containertool")]
171171
)
172172

173173
let config_blob = try await destination.putImageConfiguration(

0 commit comments

Comments
 (0)