mirror of
https://git.yoctoproject.org/poky
synced 2026-06-02 01:19:52 +00:00
sstate.bbclass: Only sign packages at the time of their creation
The purpose of the change is to never sign a package not created by the build itself. sstate_create_package is refactored into Python and re-designed to handle signing inside the function. Thus, the signing should never apply to existing sstate packages. The function is therefore renamed into sstate_create_and_sign_package. The creation of the archive remains in a separate shellscript function. Co-authored-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com> (From OE-Core rev: ba223f8fff19ea59440d56cf3fe46200f3f71e22) Signed-off-by: Tobias Hagelborn <tobias.hagelborn@axis.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
a277d1f7a0
commit
f909d235c9
@@ -703,9 +703,7 @@ def sstate_package(ss, d):
|
|||||||
if d.getVar('SSTATE_SKIP_CREATION') == '1':
|
if d.getVar('SSTATE_SKIP_CREATION') == '1':
|
||||||
return
|
return
|
||||||
|
|
||||||
sstate_create_package = ['sstate_report_unihash', 'sstate_create_pkgdirs', 'sstate_create_package']
|
sstate_create_package = ['sstate_report_unihash', 'sstate_create_and_sign_package']
|
||||||
if d.getVar('SSTATE_SIG_KEY'):
|
|
||||||
sstate_create_package.append('sstate_sign_package')
|
|
||||||
|
|
||||||
for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
|
for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
|
||||||
sstate_create_package + \
|
sstate_create_package + \
|
||||||
@@ -810,26 +808,100 @@ python sstate_task_postfunc () {
|
|||||||
}
|
}
|
||||||
sstate_task_postfunc[dirs] = "${WORKDIR}"
|
sstate_task_postfunc[dirs] = "${WORKDIR}"
|
||||||
|
|
||||||
python sstate_create_pkgdirs () {
|
# Create a sstate package
|
||||||
# report_unihash can change SSTATE_PKG and mkdir -p in shell doesn't own intermediate directories
|
# If enabled, sign the package.
|
||||||
# correctly so do this in an intermediate python task
|
# Package and signature are created in a sub-directory
|
||||||
with bb.utils.umask(0o002):
|
# and renamed in place once created.
|
||||||
bb.utils.mkdirhier(os.path.dirname(d.getVar('SSTATE_PKG')))
|
python sstate_create_and_sign_package () {
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Best effort touch
|
||||||
|
def touch(file):
|
||||||
|
try:
|
||||||
|
file.touch()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_file(src, dst, force=False):
|
||||||
|
if dst.is_symlink() and not dst.exists():
|
||||||
|
force=True
|
||||||
|
try:
|
||||||
|
# This relies on that src is a temporary file that can be renamed
|
||||||
|
# or left as is.
|
||||||
|
if force:
|
||||||
|
src.rename(dst)
|
||||||
|
else:
|
||||||
|
os.link(src, dst)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if dst.exists():
|
||||||
|
touch(dst)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
sign_pkg = (
|
||||||
|
bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG")) and
|
||||||
|
bool(d.getVar("SSTATE_SIG_KEY"))
|
||||||
|
)
|
||||||
|
|
||||||
|
sstate_pkg = Path(d.getVar("SSTATE_PKG"))
|
||||||
|
sstate_pkg_sig = Path(str(sstate_pkg) + ".sig")
|
||||||
|
if sign_pkg:
|
||||||
|
if sstate_pkg.exists() and sstate_pkg_sig.exists():
|
||||||
|
touch(sstate_pkg)
|
||||||
|
touch(sstate_pkg_sig)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if sstate_pkg.exists():
|
||||||
|
touch(sstate_pkg)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create the required sstate directory if it is not present.
|
||||||
|
if not sstate_pkg.parent.is_dir():
|
||||||
|
with bb.utils.umask(0o002):
|
||||||
|
bb.utils.mkdirhier(str(sstate_pkg.parent))
|
||||||
|
|
||||||
|
if sign_pkg:
|
||||||
|
from tempfile import TemporaryDirectory
|
||||||
|
with TemporaryDirectory(dir=sstate_pkg.parent) as tmp_dir:
|
||||||
|
tmp_pkg = Path(tmp_dir) / sstate_pkg.name
|
||||||
|
d.setVar("TMP_SSTATE_PKG", str(tmp_pkg))
|
||||||
|
bb.build.exec_func('sstate_archive_package', d)
|
||||||
|
|
||||||
|
from oe.gpg_sign import get_signer
|
||||||
|
signer = get_signer(d, 'local')
|
||||||
|
signer.detach_sign(str(tmp_pkg), d.getVar('SSTATE_SIG_KEY'), None,
|
||||||
|
d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
|
||||||
|
|
||||||
|
tmp_pkg_sig = Path(tmp_dir) / sstate_pkg_sig.name
|
||||||
|
if not update_file(tmp_pkg_sig, sstate_pkg_sig):
|
||||||
|
# If the created signature file could not be copied into place,
|
||||||
|
# then we should not use the sstate package either.
|
||||||
|
return
|
||||||
|
|
||||||
|
# If the .sig file was updated, then the sstate package must also
|
||||||
|
# be updated.
|
||||||
|
update_file(tmp_pkg, sstate_pkg, force=True)
|
||||||
|
else:
|
||||||
|
from tempfile import NamedTemporaryFile
|
||||||
|
with NamedTemporaryFile(prefix=sstate_pkg.name, dir=sstate_pkg.parent) as tmp_pkg_fd:
|
||||||
|
tmp_pkg = tmp_pkg_fd.name
|
||||||
|
d.setVar("TMP_SSTATE_PKG", str(tmp_pkg))
|
||||||
|
bb.build.exec_func('sstate_archive_package',d)
|
||||||
|
update_file(tmp_pkg, sstate_pkg)
|
||||||
|
# update_file() may have renamed tmp_pkg, which must exist when the
|
||||||
|
# NamedTemporaryFile() context handler ends.
|
||||||
|
touch(Path(tmp_pkg))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Shell function to generate a sstate package from a directory
|
# Shell function to generate a sstate package from a directory
|
||||||
# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
|
# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
|
||||||
#
|
# The calling function handles moving the sstate package into the final
|
||||||
sstate_create_package () {
|
# destination.
|
||||||
# Exit early if it already exists
|
sstate_archive_package () {
|
||||||
if [ -e ${SSTATE_PKG} ]; then
|
|
||||||
touch ${SSTATE_PKG} 2>/dev/null || true
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
TFILE=`mktemp ${SSTATE_PKG}.XXXXXXXX`
|
|
||||||
|
|
||||||
OPT="-cS"
|
OPT="-cS"
|
||||||
ZSTD="zstd -${SSTATE_ZSTD_CLEVEL} -T${ZSTD_THREADS}"
|
ZSTD="zstd -${SSTATE_ZSTD_CLEVEL} -T${ZSTD_THREADS}"
|
||||||
# Use pzstd if available
|
# Use pzstd if available
|
||||||
@@ -840,42 +912,18 @@ sstate_create_package () {
|
|||||||
# Need to handle empty directories
|
# Need to handle empty directories
|
||||||
if [ "$(ls -A)" ]; then
|
if [ "$(ls -A)" ]; then
|
||||||
set +e
|
set +e
|
||||||
tar -I "$ZSTD" $OPT -f $TFILE *
|
tar -I "$ZSTD" $OPT -f ${TMP_SSTATE_PKG} *
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
|
if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
set -e
|
set -e
|
||||||
else
|
else
|
||||||
tar -I "$ZSTD" $OPT --file=$TFILE --files-from=/dev/null
|
tar -I "$ZSTD" $OPT --file=${TMP_SSTATE_PKG} --files-from=/dev/null
|
||||||
fi
|
fi
|
||||||
chmod 0664 $TFILE
|
chmod 0664 ${TMP_SSTATE_PKG}
|
||||||
# Skip if it was already created by some other process
|
|
||||||
if [ -h ${SSTATE_PKG} ] && [ ! -e ${SSTATE_PKG} ]; then
|
|
||||||
# There is a symbolic link, but it links to nothing.
|
|
||||||
# Forcefully replace it with the new file.
|
|
||||||
ln -f $TFILE ${SSTATE_PKG} || true
|
|
||||||
elif [ ! -e ${SSTATE_PKG} ]; then
|
|
||||||
# Move into place using ln to attempt an atomic op.
|
|
||||||
# Abort if it already exists
|
|
||||||
ln $TFILE ${SSTATE_PKG} || true
|
|
||||||
else
|
|
||||||
touch ${SSTATE_PKG} 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
rm $TFILE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
python sstate_sign_package () {
|
|
||||||
from oe.gpg_sign import get_signer
|
|
||||||
|
|
||||||
|
|
||||||
signer = get_signer(d, 'local')
|
|
||||||
sstate_pkg = d.getVar('SSTATE_PKG')
|
|
||||||
if os.path.exists(sstate_pkg + '.sig'):
|
|
||||||
os.unlink(sstate_pkg + '.sig')
|
|
||||||
signer.detach_sign(sstate_pkg, d.getVar('SSTATE_SIG_KEY', False), None,
|
|
||||||
d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
|
|
||||||
}
|
|
||||||
|
|
||||||
python sstate_report_unihash() {
|
python sstate_report_unihash() {
|
||||||
report_unihash = getattr(bb.parse.siggen, 'report_unihash', None)
|
report_unihash = getattr(bb.parse.siggen, 'report_unihash', None)
|
||||||
|
|||||||
Reference in New Issue
Block a user