#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

# Zap the root password if debug-tweaks and empty-root-password features are not enabled
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'empty-root-password' ], "", "zap_empty_root_password ",d)}'

# Allow dropbear/openssh to accept logins from accounts with an empty password string if debug-tweaks or allow-empty-password is enabled
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'allow-empty-password' ], "ssh_allow_empty_password ", "",d)}'

# Allow dropbear/openssh to accept root logins if debug-tweaks or allow-root-login is enabled
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'allow-root-login' ], "ssh_allow_root_login ", "",d)}'

# Autologin the root user on the serial console, if empty-root-password and serial-autologin-root are active
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("IMAGE_FEATURES", [ 'empty-root-password', 'serial-autologin-root' ], "serial_autologin_root ", "",d)}'

# Enable postinst logging if debug-tweaks or post-install-logging is enabled
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'post-install-logging' ], "postinst_enable_logging ", "",d)}'

# Create /etc/timestamp during image construction to give a reasonably sane default time setting
ROOTFS_POSTPROCESS_COMMAND += "rootfs_update_timestamp "

# Tweak files in /etc if read-only-rootfs is enabled
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", "read_only_rootfs_hook ", "",d)}'

# We also need to do the same for the kernel boot parameters,
# otherwise kernel or initramfs end up mounting the rootfs read/write
# (the default) if supported by the underlying storage.
#
# We do this with :append because the default value might get set later with ?=
# and we don't want to disable such a default that by setting a value here.
APPEND:append = '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", " ro", "", d)}'

# Generates test data file with data store variables expanded in json format
ROOTFS_POSTPROCESS_COMMAND += "write_image_test_data "

# Write manifest
IMAGE_MANIFEST = "${IMGDEPLOYDIR}/${IMAGE_NAME}.manifest"
ROOTFS_POSTUNINSTALL_COMMAND =+ "write_image_manifest"
# Set default postinst log file
POSTINST_LOGFILE ?= "${localstatedir}/log/postinstall.log"
# Set default target for systemd images
SYSTEMD_DEFAULT_TARGET ?= '${@bb.utils.contains_any("IMAGE_FEATURES", [ "x11-base", "weston" ], "graphical.target", "multi-user.target", d)}'
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("DISTRO_FEATURES", "systemd", "set_systemd_default_target systemd_sysusers_check", "", d)}'

ROOTFS_POSTPROCESS_COMMAND += 'empty_var_volatile'

ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("DISTRO_FEATURES", "overlayfs", "overlayfs_qa_check overlayfs_postprocess", "", d)}'

inherit image-artifact-names

# Sort the user and group entries in /etc by ID in order to make the content
# deterministic. Package installs are not deterministic, causing the ordering
# of entries to change between builds. In case that this isn't desired,
# the command can be overridden.
SORT_PASSWD_POSTPROCESS_COMMAND ??= "tidy_shadowutils_files"
ROOTFS_POSTPROCESS_COMMAND += '${SORT_PASSWD_POSTPROCESS_COMMAND}'

#
# Note that useradd-staticids.bbclass has to be used to ensure that
# the numeric IDs of dynamically created entries remain stable.
#
ROOTFS_POSTPROCESS_COMMAND += 'rootfs_reproducible'

# Resolve the ID as described in the sysusers.d(5) manual: ID can be a numeric
# uid, a couple uid:gid or uid:groupname or it is '-' meaning leaving it
# automatic or it can be a path. In the latter, the uid/gid matches the
# user/group owner of that file.
def resolve_sysusers_id(d, sid):
    # If the id is a path, the uid/gid matchs to the target's uid/gid in the
    # rootfs.
    if '/' in sid:
        try:
            osstat = os.stat(os.path.join(d.getVar('IMAGE_ROOTFS'), sid))
        except FileNotFoundError:
            bb.error('sysusers.d: file %s is required but it does not exist in the rootfs', sid)
            return ('-', '-')
        return (osstat.st_uid, osstat.st_gid)
    # Else it is a uid:gid or uid:groupname syntax
    if ':' in sid:
        return sid.split(':')
    else:
        return (sid, '-')

# Check a user exists in the rootfs password file and return its properties
def check_user_exists(d, uname=None, uid=None):
    with open(os.path.join(d.getVar('IMAGE_ROOTFS'), 'etc/passwd'), 'r') as pwfile:
        for line in pwfile:
            (name, _, u_id, gid, comment, homedir, ushell) = line.strip().split(':')
            if uname == name or uid == u_id:
                return (name, u_id, gid, comment or '-', homedir or '/', ushell or '-')
    return None

# Check a group exists in the rootfs group file and return its properties
def check_group_exists(d, gname=None, gid=None):
    with open(os.path.join(d.getVar('IMAGE_ROOTFS'), 'etc/group'), 'r') as gfile:
        for line in gfile:
            (name, _, g_id, _) = line.strip().split(':')
            if name == gname or g_id == gid:
                return (name, g_id)
    return None

def compare_users(user, e_user):
    # user and e_user must not have None values. Unset values must be '-'.
    (name, uid, gid, comment, homedir, ushell) = user
    (e_name, e_uid, e_gid, e_comment, e_homedir, e_ushell) = e_user
    # Ignore 'uid', 'gid' or 'homedir' if they are not set
    # Ignore 'shell' and 'ushell' if one is not set
    return name == e_name \
        and (uid == '-' or uid == e_uid) \
        and (gid == '-' or gid == e_gid) \
        and (homedir == '-' or e_homedir == '-' or homedir == e_homedir) \
        and (ushell == '-' or e_ushell == '-' or ushell == e_ushell)

# Open sysusers.d configuration files and parse each line to check the users and
# groups are already defined in /etc/passwd and /etc/groups with similar
# properties. Refer to the sysusers.d(5) manual for its syntax.
python systemd_sysusers_check() {
    import glob
    import re

    pattern_comment = r'(-|\"[^:\"]+\")'
    pattern_word    = r'[^\s]+'
    pattern_line   = r'(' + pattern_word + r')\s+(' + pattern_word + r')\s+(' + pattern_word + r')(\s+' \
        + pattern_comment + r')?' + r'(\s+(' + pattern_word + r'))?' + r'(\s+(' + pattern_word + r'))?'

    for conffile in glob.glob(os.path.join(d.getVar('IMAGE_ROOTFS'), 'usr/lib/sysusers.d/*.conf')):
        with open(conffile, 'r') as f:
            for line in f:
                line = line.strip()
                if not len(line) or line[0] == '#': continue
                ret = re.fullmatch(pattern_line, line.strip())
                if not ret: continue
                (stype, sname, sid, _, scomment, _, shomedir, _, sshell) = ret.groups()
                if stype == 'u':
                    if sid:
                        (suid, sgid) = resolve_sysusers_id(d, sid)
                        if sgid.isalpha():
                            sgid = check_group_exists(d, gname=sgid)
                        elif sgid.isdigit():
                            check_group_exists(d, gid=sgid)
                        else:
                            sgid = '-'
                    else:
                        suid = '-'
                        sgid = '-'
                    scomment = scomment.replace('"', '') if scomment else '-'
                    shomedir = shomedir or '-'
                    sshell = sshell or '-'
                    e_user = check_user_exists(d, uname=sname)
                    if not e_user:
                        bb.warn('User %s has never been defined' % sname)
                    elif not compare_users((sname, suid, sgid, scomment, shomedir, sshell), e_user):
                        bb.warn('User %s has been defined as (%s) but sysusers.d expects it as (%s)'
                                % (sname, ', '.join(e_user),
                                ', '.join((sname, suid, sgid, scomment, shomedir, sshell))))
                elif stype == 'g':
                    gid = sid or '-'
                    if '/' in gid:
                        (_, gid) = resolve_sysusers_id(d, sid)
                    e_group = check_group_exists(d, gname=sname)
                    if not e_group:
                        bb.warn('Group %s has never been defined' % sname)
                    elif gid != '-':
                        (_, e_gid) = e_group
                        if gid != e_gid:
                            bb.warn('Group %s has been defined with id (%s) but sysusers.d expects gid (%s)'
                                    % (sname, e_gid, gid))
                elif stype == 'm':
                    check_user_exists(d, sname)
                    check_group_exists(d, sid)
}

#
# A hook function to support read-only-rootfs IMAGE_FEATURES
#
read_only_rootfs_hook () {
	# Tweak the mount option and fs_passno for rootfs in fstab
	if [ -f ${IMAGE_ROOTFS}/etc/fstab ]; then
		sed -i -e '/^[#[:space:]]*\/dev\/root/{s/defaults/ro/;s/\([[:space:]]*[[:digit:]]\)\([[:space:]]*\)[[:digit:]]$/\1\20/}' ${IMAGE_ROOTFS}/etc/fstab
	fi

	# Tweak the "mount -o remount,rw /" command in busybox-inittab inittab
	if [ -f ${IMAGE_ROOTFS}/etc/inittab ]; then
		sed -i 's|/bin/mount -o remount,rw /|/bin/mount -o remount,ro /|' ${IMAGE_ROOTFS}/etc/inittab
	fi

	# If we're using openssh and the /etc/ssh directory has no pre-generated keys,
	# we should configure openssh to use the configuration file /etc/ssh/sshd_config_readonly
	# and the keys under /var/run/ssh.
	# If overlayfs-etc is used this is not done as /etc is treated as writable
	# If stateless-rootfs is enabled this is always done as we don't want to save keys then
	if ${@ 'true' if not bb.utils.contains('IMAGE_FEATURES', 'overlayfs-etc', True, False, d) or bb.utils.contains('IMAGE_FEATURES', 'stateless-rootfs', True, False, d) else 'false'}; then
		if [ -d ${IMAGE_ROOTFS}/etc/ssh ]; then
			if [ -e ${IMAGE_ROOTFS}/etc/ssh/ssh_host_rsa_key ]; then
				echo "SYSCONFDIR=\${SYSCONFDIR:-/etc/ssh}" >> ${IMAGE_ROOTFS}/etc/default/ssh
				echo "SSHD_OPTS=" >> ${IMAGE_ROOTFS}/etc/default/ssh
			else
				echo "SYSCONFDIR=\${SYSCONFDIR:-/var/run/ssh}" >> ${IMAGE_ROOTFS}/etc/default/ssh
				echo "SSHD_OPTS='-f /etc/ssh/sshd_config_readonly'" >> ${IMAGE_ROOTFS}/etc/default/ssh
			fi
		fi

		# Also tweak the key location for dropbear in the same way.
		if [ -d ${IMAGE_ROOTFS}/etc/dropbear ]; then
			if [ ! -e ${IMAGE_ROOTFS}/etc/dropbear/dropbear_rsa_host_key ]; then
				echo "DROPBEAR_RSAKEY_DIR=/var/lib/dropbear" >> ${IMAGE_ROOTFS}/etc/default/dropbear
			fi
		fi
	fi

	if ${@bb.utils.contains("DISTRO_FEATURES", "sysvinit", "true", "false", d)}; then
		# Change the value of ROOTFS_READ_ONLY in /etc/default/rcS to yes
		if [ -e ${IMAGE_ROOTFS}/etc/default/rcS ]; then
			sed -i 's/ROOTFS_READ_ONLY=no/ROOTFS_READ_ONLY=yes/' ${IMAGE_ROOTFS}/etc/default/rcS
		fi
		# Run populate-volatile.sh at rootfs time to set up basic files
		# and directories to support read-only rootfs.
		if [ -x ${IMAGE_ROOTFS}/etc/init.d/populate-volatile.sh ]; then
			${IMAGE_ROOTFS}/etc/init.d/populate-volatile.sh
		fi
	fi

	if ${@bb.utils.contains("DISTRO_FEATURES", "systemd", "true", "false", d)}; then
	# Create machine-id
	# 20:12 < mezcalero> koen: you have three options: a) run systemd-machine-id-setup at install time, b) have / read-only and an empty file there (for stateless) and c) boot with / writable
		touch ${IMAGE_ROOTFS}${sysconfdir}/machine-id
	fi
}

#
# This function disallows empty root passwords
#
zap_empty_root_password () {
	if [ -e ${IMAGE_ROOTFS}/etc/shadow ]; then
		sed --follow-symlinks -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/shadow
        fi
	if [ -e ${IMAGE_ROOTFS}/etc/passwd ]; then
		sed --follow-symlinks -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/passwd
	fi
}

#
# allow dropbear/openssh to accept logins from accounts with an empty password string
#
ssh_allow_empty_password () {
	for config in sshd_config sshd_config_readonly; do
		if [ -e ${IMAGE_ROOTFS}${sysconfdir}/ssh/$config ]; then
			sed -i 's/^[#[:space:]]*PermitEmptyPasswords.*/PermitEmptyPasswords yes/' ${IMAGE_ROOTFS}${sysconfdir}/ssh/$config
		fi
	done

	if [ -e ${IMAGE_ROOTFS}${sbindir}/dropbear ] ; then
		if grep -q DROPBEAR_EXTRA_ARGS ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear 2>/dev/null ; then
			if ! grep -q "DROPBEAR_EXTRA_ARGS=.*-B" ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear ; then
				sed -i 's/^DROPBEAR_EXTRA_ARGS="*\([^"]*\)"*/DROPBEAR_EXTRA_ARGS="\1 -B"/' ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear
			fi
		else
			printf '\nDROPBEAR_EXTRA_ARGS="-B"\n' >> ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear
		fi
	fi

	if [ -d ${IMAGE_ROOTFS}${sysconfdir}/pam.d ] ; then
		for f in `find ${IMAGE_ROOTFS}${sysconfdir}/pam.d/* -type f -exec test -e {} \; -print`
		do
			sed -i 's/nullok_secure/nullok/' $f
		done
	fi
}

#
# allow dropbear/openssh to accept root logins
#
ssh_allow_root_login () {
	for config in sshd_config sshd_config_readonly; do
		if [ -e ${IMAGE_ROOTFS}${sysconfdir}/ssh/$config ]; then
			sed -i 's/^[#[:space:]]*PermitRootLogin.*/PermitRootLogin yes/' ${IMAGE_ROOTFS}${sysconfdir}/ssh/$config
		fi
	done

	if [ -e ${IMAGE_ROOTFS}${sbindir}/dropbear ] ; then
		if grep -q DROPBEAR_EXTRA_ARGS ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear 2>/dev/null ; then
			sed -i '/^DROPBEAR_EXTRA_ARGS=/ s/-w//' ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear
			sed -i '/^# Disallow root/d' ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear
		fi
	fi
}

#
# Autologin the 'root' user on the serial terminal,
# if empty-root-password' AND 'serial-autologin-root are enabled
#
serial_autologin_root () {
	if ${@bb.utils.contains("DISTRO_FEATURES", "sysvinit", "true", "false", d)}; then
		# add autologin option to util-linux getty only
		sed -i 's/options="/&--autologin root /' \
			"${IMAGE_ROOTFS}${base_bindir}/start_getty"
	elif ${@bb.utils.contains("DISTRO_FEATURES", "systemd", "true", "false", d)}; then
		if [ -e ${IMAGE_ROOTFS}${systemd_system_unitdir}/serial-getty@.service ]; then
			sed -i '/^\s*ExecStart\b/ s/getty /&--autologin root /' \
				"${IMAGE_ROOTFS}${systemd_system_unitdir}/serial-getty@.service"
		fi
	fi
}

python tidy_shadowutils_files () {
    import rootfspostcommands
    rootfspostcommands.tidy_shadowutils_files(d.expand('${IMAGE_ROOTFS}${sysconfdir}'))
}

python sort_passwd () {
    """
    Deprecated in the favour of tidy_shadowutils_files.
    """
    import rootfspostcommands
    bb.warn('[sort_passwd] You are using a deprecated function for '
        'SORT_PASSWD_POSTPROCESS_COMMAND. The default one is now called '
        '"tidy_shadowutils_files".')
    rootfspostcommands.tidy_shadowutils_files(d.expand('${IMAGE_ROOTFS}${sysconfdir}'))
}

#
# Enable postinst logging
#
postinst_enable_logging () {
	mkdir -p ${IMAGE_ROOTFS}${sysconfdir}/default
	echo "POSTINST_LOGGING=1" >> ${IMAGE_ROOTFS}${sysconfdir}/default/postinst
	echo "LOGFILE=${POSTINST_LOGFILE}" >> ${IMAGE_ROOTFS}${sysconfdir}/default/postinst
}

#
# Modify systemd default target
#
set_systemd_default_target () {
	if [ -d ${IMAGE_ROOTFS}${sysconfdir}/systemd/system -a -e ${IMAGE_ROOTFS}${systemd_system_unitdir}/${SYSTEMD_DEFAULT_TARGET} ]; then
		ln -sf ${systemd_system_unitdir}/${SYSTEMD_DEFAULT_TARGET} ${IMAGE_ROOTFS}${sysconfdir}/systemd/system/default.target
	fi
}

# If /var/volatile is not empty, we have seen problems where programs such as the
# journal make assumptions based on the contents of /var/volatile. The journal
# would then write to /var/volatile before it was mounted, thus hiding the
# items previously written.
#
# This change is to attempt to fix those types of issues in a way that doesn't
# affect users that may not be using /var/volatile.
empty_var_volatile () {
	if [ -e ${IMAGE_ROOTFS}/etc/fstab ]; then
		match=`awk '$1 !~ "#" && $2 ~ /\/var\/volatile/{print $2}' ${IMAGE_ROOTFS}/etc/fstab 2> /dev/null`
		if [ -n "$match" ]; then
			find ${IMAGE_ROOTFS}/var/volatile -mindepth 1 -delete
		fi
	fi
}

# Turn any symbolic /sbin/init link into a file
remove_init_link () {
	if [ -h ${IMAGE_ROOTFS}/sbin/init ]; then
		LINKFILE=${IMAGE_ROOTFS}`readlink ${IMAGE_ROOTFS}/sbin/init`
		rm ${IMAGE_ROOTFS}/sbin/init
		cp $LINKFILE ${IMAGE_ROOTFS}/sbin/init
	fi
}

make_zimage_symlink_relative () {
	if [ -L ${IMAGE_ROOTFS}/boot/zImage ]; then
		(cd ${IMAGE_ROOTFS}/boot/ && for i in `ls zImage-* | sort`; do ln -sf $i zImage; done)
	fi
}

python write_image_manifest () {
    from oe.rootfs import image_list_installed_packages
    from oe.utils import format_pkg_list

    deploy_dir = d.getVar('IMGDEPLOYDIR')
    link_name = d.getVar('IMAGE_LINK_NAME')
    manifest_name = d.getVar('IMAGE_MANIFEST')

    if not manifest_name:
        return

    pkgs = image_list_installed_packages(d)
    with open(manifest_name, 'w+') as image_manifest:
        image_manifest.write(format_pkg_list(pkgs, "ver"))

    if os.path.exists(manifest_name) and link_name:
        manifest_link = deploy_dir + "/" + link_name + ".manifest"
        if manifest_link != manifest_name:
            if os.path.lexists(manifest_link):
                os.remove(manifest_link)
            os.symlink(os.path.basename(manifest_name), manifest_link)
}

# Can be used to create /etc/timestamp during image construction to give a reasonably
# sane default time setting
rootfs_update_timestamp () {
	if [ "${REPRODUCIBLE_TIMESTAMP_ROOTFS}" != "" ]; then
		# Convert UTC into %4Y%2m%2d%2H%2M%2S
		sformatted=`date -u -d @${REPRODUCIBLE_TIMESTAMP_ROOTFS} +%4Y%2m%2d%2H%2M%2S`
	else
		sformatted=`date -u +%4Y%2m%2d%2H%2M%2S`
	fi
	echo $sformatted > ${IMAGE_ROOTFS}/etc/timestamp
	bbnote "rootfs_update_timestamp: set /etc/timestamp to $sformatted"
}

# Prevent X from being started
rootfs_no_x_startup () {
	if [ -f ${IMAGE_ROOTFS}/etc/init.d/xserver-nodm ]; then
		chmod a-x ${IMAGE_ROOTFS}/etc/init.d/xserver-nodm
	fi
}

rootfs_trim_schemas () {
	for schema in ${IMAGE_ROOTFS}/etc/gconf/schemas/*.schemas
	do
		# Need this in case no files exist
		if [ -e $schema ]; then
			oe-trim-schemas $schema > $schema.new
			mv $schema.new $schema
		fi
	done
}

rootfs_check_host_user_contaminated () {
	contaminated="${S}/host-user-contaminated.txt"
	HOST_USER_UID="$(PSEUDO_UNLOAD=1 id -u)"
	HOST_USER_GID="$(PSEUDO_UNLOAD=1 id -g)"

	find "${IMAGE_ROOTFS}" -path "${IMAGE_ROOTFS}/home" -prune -o \
	    -user "$HOST_USER_UID" -print -o -group "$HOST_USER_GID" -print >"$contaminated"

	sed -e "s,${IMAGE_ROOTFS},," $contaminated | while read line; do
		bbwarn "Path in the rootfs is owned by the same user or group as the user running bitbake:" $line `ls -lan ${IMAGE_ROOTFS}/$line`
	done

	if [ -s "$contaminated" ]; then
		bbwarn "/etc/passwd:" `cat ${IMAGE_ROOTFS}/etc/passwd`
		bbwarn "/etc/group:" `cat ${IMAGE_ROOTFS}/etc/group`
	fi
}

# Make any absolute links in a sysroot relative
rootfs_sysroot_relativelinks () {
	sysroot-relativelinks.py ${SDK_OUTPUT}/${SDKTARGETSYSROOT}
}

# Generated test data json file
python write_image_test_data() {
    from oe.data import export2json

    deploy_dir = d.getVar('IMGDEPLOYDIR')
    link_name = d.getVar('IMAGE_LINK_NAME')
    testdata_name = os.path.join(deploy_dir, "%s.testdata.json" % d.getVar('IMAGE_NAME'))

    searchString = "%s/"%(d.getVar("TOPDIR")).replace("//","/")
    export2json(d, testdata_name, searchString=searchString, replaceString="")

    if os.path.exists(testdata_name) and link_name:
        testdata_link = os.path.join(deploy_dir, "%s.testdata.json" % link_name)
        if testdata_link != testdata_name:
            if os.path.lexists(testdata_link):
                os.remove(testdata_link)
            os.symlink(os.path.basename(testdata_name), testdata_link)
}
write_image_test_data[vardepsexclude] += "TOPDIR"

# Check for unsatisfied recommendations (RRECOMMENDS)
python rootfs_log_check_recommends() {
    log_path = d.expand("${T}/log.do_rootfs")
    with open(log_path, 'r') as log:
        for line in log:
            if 'log_check' in line:
                continue

            if 'unsatisfied recommendation for' in line:
                bb.warn('[log_check] %s: %s' % (d.getVar('PN'), line))
}

# Perform any additional adjustments needed to make rootf binary reproducible
rootfs_reproducible () {
	if [ "${REPRODUCIBLE_TIMESTAMP_ROOTFS}" != "" ]; then
		# Convert UTC into %4Y%2m%2d%2H%2M%2S
		sformatted=`date -u -d @${REPRODUCIBLE_TIMESTAMP_ROOTFS} +%4Y%2m%2d%2H%2M%2S`
		echo $sformatted > ${IMAGE_ROOTFS}/etc/version
		bbnote "rootfs_reproducible: set /etc/version to $sformatted"

		if [ -d ${IMAGE_ROOTFS}${sysconfdir}/gconf ]; then
			find ${IMAGE_ROOTFS}${sysconfdir}/gconf -name '%gconf.xml' -print0 | xargs -0r \
			sed -i -e 's@\bmtime="[0-9][0-9]*"@mtime="'${REPRODUCIBLE_TIMESTAMP_ROOTFS}'"@g'
		fi
	fi
}

# Perform a dumb check for unit existence, not its validity
python overlayfs_qa_check() {
    from oe.overlayfs import mountUnitName

    overlayMountPoints = d.getVarFlags("OVERLAYFS_MOUNT_POINT") or {}
    imagepath = d.getVar("IMAGE_ROOTFS")
    sysconfdir = d.getVar("sysconfdir")
    searchpaths = [oe.path.join(imagepath, sysconfdir, "systemd", "system"),
                   oe.path.join(imagepath, d.getVar("systemd_system_unitdir"))]
    fstabpath = oe.path.join(imagepath, sysconfdir, "fstab")

    if not any(os.path.exists(path) for path in [*searchpaths, fstabpath]):
        return

    fstabDevices = []
    if os.path.isfile(fstabpath):
        with open(fstabpath, 'r') as f:
            for line in f:
                if line[0] == '#':
                    continue
                path = line.split(maxsplit=2)
                if len(path) > 2:
                    fstabDevices.append(path[1])

    allUnitExist = True;
    for mountPoint in overlayMountPoints:
        qaSkip = (d.getVarFlag("OVERLAYFS_QA_SKIP", mountPoint) or "").split()
        if "mount-configured" in qaSkip:
            continue

        mountPath = d.getVarFlag('OVERLAYFS_MOUNT_POINT', mountPoint)
        if mountPath in fstabDevices:
            continue

        mountUnit = mountUnitName(mountPath)
        if any(os.path.isfile(oe.path.join(dirpath, mountUnit))
               for dirpath in searchpaths):
            continue

        bb.warn(f'Mount path {mountPath} not found in fstab and unit '
                f'{mountUnit} not found in systemd unit directories.')
        bb.warn(f'Skip this check by setting OVERLAYFS_QA_SKIP[{mountPoint}] = '
                '"mount-configured"')
        allUnitExist = False;

    if not allUnitExist:
        bb.fatal('Not all mount paths and units are installed in the image')
}

python overlayfs_postprocess() {
    import shutil

    # install helper script
    helperScriptName = "overlayfs-create-dirs.sh"
    helperScriptSource = oe.path.join(d.getVar("COREBASE"), "meta/files", helperScriptName)
    helperScriptDest = oe.path.join(d.getVar("IMAGE_ROOTFS"), "/usr/sbin/", helperScriptName)
    shutil.copyfile(helperScriptSource, helperScriptDest)
    os.chmod(helperScriptDest, 0o755)
}
