Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions build-in-container-inner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ for repo in $repos; do
fi
done

# Pin embedded build timestamps so two builds of the same source produce
# identical binaries. Honored by OpenSSL, Apache httpd, Postgres, Python
# (.pyc mtimes), dpkg-buildpackage, and rpmbuild.
if [ -z "$SOURCE_DATE_EPOCH" ]; then
SOURCE_DATE_EPOCH=$(git -C "$BASEDIR/core" log -1 --format=%ct)
fi
export SOURCE_DATE_EPOCH
echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH"

install_mission_portal_deps() (
set -e

Expand All @@ -53,12 +62,12 @@ install_mission_portal_deps() (

if [ -f "$BASEDIR/mission-portal/composer.json" ]; then
echo "Installing Mission Portal PHP dependencies..."
(cd "$BASEDIR/mission-portal" && php /usr/bin/composer.phar install --no-dev --ignore-platform-reqs)
(cd "$BASEDIR/mission-portal" && php /usr/bin/composer.phar install --no-dev --ignore-platform-reqs --prefer-dist)
fi

if [ -f "$BASEDIR/nova/api/http/composer.json" ]; then
echo "Installing Nova API PHP dependencies..."
(cd "$BASEDIR/nova/api/http" && php /usr/bin/composer.phar install --no-dev --ignore-platform-reqs)
(cd "$BASEDIR/nova/api/http" && php /usr/bin/composer.phar install --no-dev --ignore-platform-reqs --prefer-dist)
fi

if [ -f "$BASEDIR/mission-portal/public/themes/default/bootstrap/cfengine_theme.less" ]; then
Expand All @@ -70,8 +79,13 @@ install_mission_portal_deps() (

if [ -f "$BASEDIR/mission-portal/ldap/composer.json" ]; then
echo "Installing LDAP API PHP dependencies..."
(cd "$BASEDIR/mission-portal/ldap" && php /usr/bin/composer.phar install --no-dev --ignore-platform-reqs)
(cd "$BASEDIR/mission-portal/ldap" && php /usr/bin/composer.phar install --no-dev --ignore-platform-reqs --prefer-dist)
fi

# Composer falls back to git clone when GitHub's anonymous zipball
# rate limit is hit, leaving non-reproducible .git directories in the
# vendor tree. Strip them.
find "$BASEDIR/mission-portal" "$BASEDIR/nova/api/http" -type d -name .git -path '*/vendor/*' -exec rm -rf {} +
)

# === Step runner with failure reporting ===
Expand Down
94 changes: 94 additions & 0 deletions deps-packaging/php/0002-Honor-SOURCE_DATE_EPOCH-in-phar.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
From: Lars Erik Wik <lars.erik.wik@northern.tech>
Subject: [PATCH] Honor SOURCE_DATE_EPOCH in phar timestamps

Phar embeds wall-clock time(NULL) into every manifest entry, making
phar.phar non-reproducible. Honor SOURCE_DATE_EPOCH (the standard
reproducible-builds mechanism) when set; fall back to time(NULL).

Signed-off-by: Lars Erik Wik <lars.erik.wik@northern.tech>
---
ext/phar/phar.c | 2 +-
ext/phar/phar_internal.h | 14 ++++++++++++++
ext/phar/tar.c | 2 +-
ext/phar/util.c | 2 +-
ext/phar/zip.c | 2 +-
5 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/ext/phar/phar.c b/ext/phar/phar.c
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -2950,7 +2950,7 @@
4: metadata-len
+: metadata
*/
- mytime = time(NULL);
+ mytime = phar_source_date_epoch();
phar_set_32(entry_buffer, entry->uncompressed_filesize);
phar_set_32(entry_buffer+4, mytime);
phar_set_32(entry_buffer+8, entry->compressed_filesize);
diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h
--- a/ext/phar/phar_internal.h
+++ b/ext/phar/phar_internal.h
@@ -22,12 +22,26 @@
#endif

#include <time.h>
+#include <stdlib.h>
#include "php.h"
#include "tar.h"
#include "pharzip.h"
#include "zend_hash.h"
#include "ext/spl/spl_directory.h"

+/* Reproducible-builds: honor SOURCE_DATE_EPOCH when set, else wall-clock time. */
+static inline time_t phar_source_date_epoch(void) {
+ const char *epoch = getenv("SOURCE_DATE_EPOCH");
+ if (epoch && *epoch) {
+ char *end;
+ long long t = strtoll(epoch, &end, 10);
+ if (*end == '\0' && t >= 0) {
+ return (time_t)t;
+ }
+ }
+ return time(NULL);
+}
+
/* PHP_ because this is public information via MINFO */
#define PHP_PHAR_API_VERSION "1.1.1"
/* x.y.z maps to 0xyz0 */
diff --git a/ext/phar/tar.c b/ext/phar/tar.c
--- a/ext/phar/tar.c
+++ b/ext/phar/tar.c
@@ -977,7 +977,7 @@
char *buf, *signature, sigbuf[8];

entry.flags = PHAR_ENT_PERM_DEF_FILE;
- entry.timestamp = time(NULL);
+ entry.timestamp = phar_source_date_epoch();
entry.is_modified = 1;
entry.is_crc_checked = 1;
entry.is_tar = 1;
diff --git a/ext/phar/util.c b/ext/phar/util.c
--- a/ext/phar/util.c
+++ b/ext/phar/util.c
@@ -700,7 +700,7 @@

phar_add_virtual_dirs(phar, path, path_len);
etemp.is_modified = 1;
- etemp.timestamp = time(0);
+ etemp.timestamp = phar_source_date_epoch();
etemp.is_crc_checked = 1;
etemp.phar = phar;
etemp.filename = zend_string_init(path, path_len, false);
diff --git a/ext/phar/zip.c b/ext/phar/zip.c
--- a/ext/phar/zip.c
+++ b/ext/phar/zip.c
@@ -1253,7 +1253,7 @@

pass.error = &temperr;
entry.flags = PHAR_ENT_PERM_DEF_FILE;
- entry.timestamp = time(NULL);
+ entry.timestamp = phar_source_date_epoch();
entry.is_modified = 1;
entry.is_zip = true;
entry.phar = phar;
2 changes: 2 additions & 0 deletions deps-packaging/php/cfbuild-php.spec
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ then
patch -p1 < %{_topdir}/SOURCES/0001-Disable-fancy-intrinsics-stuff.patch
fi

patch -p1 < %{_topdir}/SOURCES/0002-Honor-SOURCE_DATE_EPOCH-in-phar.patch

%if %{?rhel}%{!?rhel:0} == 8
CFLAGS="-fPIE"
LDFLAGS="-pie"
Expand Down
2 changes: 2 additions & 0 deletions deps-packaging/php/debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ build: build-stamp
build-stamp:
dh_testdir

patch -p1 < $(CURDIR)/0002-Honor-SOURCE_DATE_EPOCH-in-phar.patch

./configure --prefix=$(PREFIX)/httpd/php \
--with-config-file-scan-dir=$(PREFIX)/httpd/php/lib \
--without-apxs2 \
Expand Down
Loading