mirror of
https://github.com/flatcar/scripts.git
synced 2025-09-23 22:51:03 +02:00
Always use our dpkg wrapper when mastering an image.
This changes install_packages to always have apt use our dpkg wrapper when building an image. The dpkg_no_scripts.sh has been modified to check if a package's maintainer scripts have been whitelisted. If so, it will install without maintainer scripts. If any relevant maintainer script has not been whitelisted it will fall back to standard dpkg which will process the maintainer scripts. This will allow us to transition to installing packages without maintainer scripts in batches rather than all at once. Once everything is switched over we will have dpkg_no_scripts.sh throw an error if it encounters a package with maintainer scripts that have not been whitelisted. Move postinst stuff from install_packages.sh to actual postinst scripts. Review URL: http://codereview.chromium.org/549017
This commit is contained in:
parent
55d1c59a58
commit
3d9b18913c
@ -22,6 +22,8 @@
|
||||
# Flags
|
||||
DEFINE_string root "" \
|
||||
"The target rootfs directory in which to install packages."
|
||||
DEFINE_boolean dpkg_fallback $FLAGS_TRUE \
|
||||
"Run normal dpkg if maintainer scripts are not whitelisted."
|
||||
DEFINE_string status_fd "" \
|
||||
"The file descriptor to report status on; ignored."
|
||||
DEFINE_boolean unpack $FLAGS_FALSE "Is the action 'unpack'?"
|
||||
@ -43,52 +45,144 @@ eval set -- "${FLAGS_ARGV}"
|
||||
# Die on any errors.
|
||||
set -e
|
||||
|
||||
if [ $FLAGS_configure -eq $FLAGS_TRUE ]; then
|
||||
# We ignore configure requests.
|
||||
exit 0
|
||||
fi
|
||||
if [ $FLAGS_remove -eq $FLAGS_TRUE ]; then
|
||||
# We log but ignore remove requests.
|
||||
echo "dpkg_no_scripts, remove: $@"
|
||||
exit 0
|
||||
fi
|
||||
if [ $FLAGS_unpack -ne $FLAGS_TRUE ]; then
|
||||
# Ignore unknown command line.
|
||||
echo "Unexpected command line: $@"
|
||||
exit 0
|
||||
fi
|
||||
if [ -z "$FLAGS_root" ]; then
|
||||
echo "Missing root directory."
|
||||
exit 0
|
||||
fi
|
||||
# Returns true if the input file is whitelisted.
|
||||
#
|
||||
# $1 - The file to check
|
||||
is_whitelisted() {
|
||||
local whitelist="${SRC_ROOT}/package_scripts/package.whitelist"
|
||||
test -f "$whitelist" || return
|
||||
|
||||
DPKG_STATUS=""
|
||||
if [ -d "$FLAGS_root/var/lib/dpkg" ]; then
|
||||
DPKG_STATUS="$FLAGS_root/var/lib/dpkg/status"
|
||||
DPKG_INFO="$FLAGS_root/var/lib/dpkg/info/"
|
||||
fi
|
||||
local checksum=$(md5sum "$1" | awk '{ print $1 }')
|
||||
local count=$(grep -c "$checksum" "${whitelist}" || /bin/true)
|
||||
test $count -ne 0
|
||||
}
|
||||
|
||||
for p in "$@"; do
|
||||
echo "Extracting $p"
|
||||
dpkg-deb --extract "$p" "$FLAGS_root"
|
||||
# Returns true if either of the two given files exist and are not whitelisted.
|
||||
#
|
||||
# $1 - The package name.
|
||||
# $2 - The path to the preinst file if it were to exist.
|
||||
# $3 - The path to the postinst file if it were to exist.
|
||||
has_missing_whitelist() {
|
||||
local package=$1
|
||||
local preinst=$2
|
||||
local postinst=$3
|
||||
local missing_whitelist=0
|
||||
|
||||
if [ -n "$DPKG_STATUS" ]; then
|
||||
TMPDIR=$(mktemp -d)
|
||||
dpkg-deb --control "$p" "$TMPDIR"
|
||||
if [ -f "$preinst" ]; then
|
||||
if ! is_whitelisted "$preinst"; then
|
||||
missing_whitelist=1
|
||||
echo "Warning: Missing whitelist entry for ${package}.preinst"
|
||||
fi
|
||||
fi
|
||||
if [ -f "$postinst" ]; then
|
||||
if ! is_whitelisted "$postinst"; then
|
||||
missing_whitelist=1
|
||||
echo "Warning: Missing whitelist entry for ${package}.postinst"
|
||||
fi
|
||||
fi
|
||||
test $missing_whitelist -ne 0
|
||||
}
|
||||
|
||||
do_configure() {
|
||||
local dpkg_info="$FLAGS_root/var/lib/dpkg/info/"
|
||||
local fallback_packages=""
|
||||
|
||||
for p in "$@"; do
|
||||
echo "Configuring: $p"
|
||||
|
||||
# Make sure that any .preinst or .postinst files are whitelisted.
|
||||
local preinst="${dpkg_info}/${p}.preinst"
|
||||
local postinst="${dpkg_info}/${p}.postinst"
|
||||
if has_missing_whitelist "$p" "$preinst" "$postinst"; then
|
||||
if [ $FLAGS_dpkg_fallback -eq $FLAGS_TRUE ]; then
|
||||
echo "** Warning: Will run full maintainer scripts for ${p}."
|
||||
fallback_packages="$fallback_packages $p"
|
||||
continue
|
||||
else
|
||||
# TODO: Eventually should be upgraded to a full error.
|
||||
echo "** Warning: Ignoring missing whitelist for ${p}."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run our maintainer script for this package if we have one.
|
||||
local chromium_postinst="${SRC_ROOT}/package_scripts/${p}.postinst"
|
||||
if [ -f "$chromium_postinst" ]; then
|
||||
echo "Running: $chromium_postinst"
|
||||
ROOT="$FLAGS_root" SRC_ROOT="$SRC_ROOT" sh -x $chromium_postinst
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$fallback_packages" ]; then
|
||||
dpkg --root="$FLAGS_root" --configure $fallback_packages
|
||||
fi
|
||||
}
|
||||
|
||||
do_unpack() {
|
||||
local dpkg_status="$FLAGS_root/var/lib/dpkg/status"
|
||||
local dpkg_info="$FLAGS_root/var/lib/dpkg/info/"
|
||||
|
||||
for p in "$@"; do
|
||||
local package=$(dpkg-deb --field "$p" Package)
|
||||
local tmpdir=$(mktemp -d)
|
||||
|
||||
dpkg-deb --control "$p" "$tmpdir"
|
||||
|
||||
local preinst="${tmpdir}/preinst"
|
||||
local postinst="${tmpdir}/postinst"
|
||||
if has_missing_whitelist "$package" "$preinst" "$postinst"; then
|
||||
if [ $FLAGS_dpkg_fallback -eq $FLAGS_TRUE ]; then
|
||||
echo "** Warning: Running full maintainer scripts for ${package}."
|
||||
dpkg --root="$FLAGS_root" --unpack --auto-deconfigure "$p"
|
||||
rm -rf "$tmpdir"
|
||||
continue
|
||||
else
|
||||
# TODO: Eventually should be upgraded to a full error.
|
||||
echo "** Warning: Ignoring missing whitelist for ${p}."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Copy the info files
|
||||
PACKAGE=$(dpkg-deb --field "$p" Package)
|
||||
FILES=$(ls "$TMPDIR" | grep -v control)
|
||||
for f in $FILES; do
|
||||
cp "${TMPDIR}/$f" "${DPKG_INFO}/$PACKAGE.$f"
|
||||
local files=$(ls "$tmpdir" | grep -v control)
|
||||
for f in $files; do
|
||||
cp "${tmpdir}/${f}" "${dpkg_info}/${package}.${f}"
|
||||
done
|
||||
touch "${DPKG_INFO}/$PACKAGE.list"
|
||||
touch "${dpkg_info}/${package}.list" # TODO: Proper .list files.
|
||||
|
||||
# Mark the package as installed successfully.
|
||||
echo "Status: install ok installed" >> "$DPKG_STATUS"
|
||||
cat "${TMPDIR}/control" >> "$DPKG_STATUS"
|
||||
echo "" >> "$DPKG_STATUS"
|
||||
echo "Status: install ok installed" >> "$dpkg_status"
|
||||
cat "${tmpdir}/control" >> "$dpkg_status"
|
||||
echo "" >> "$dpkg_status"
|
||||
|
||||
rm -rf "$TMPDIR"
|
||||
fi
|
||||
done
|
||||
rm -rf "$tmpdir"
|
||||
|
||||
# Run our maintainer script for this package if we have one.
|
||||
local chromium_postinst="${SRC_ROOT}/package_scripts/${package}.preinst"
|
||||
if [ -f "$chromium_preinst" ]; then
|
||||
echo "Running: ${chromium_preinst}"
|
||||
ROOT="$FLAGS_root" SRC_ROOT="$SRC_ROOT" $chromium_preinst
|
||||
fi
|
||||
|
||||
echo "Unpacking: $p"
|
||||
dpkg-deb --extract "$p" "$FLAGS_root"
|
||||
done
|
||||
}
|
||||
|
||||
# This script requires at least "--root="
|
||||
if [ -z "$FLAGS_root" ]; then
|
||||
echo "dpkg_no_scripts: Missing root directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $FLAGS_configure -eq $FLAGS_TRUE ]; then
|
||||
do_configure $@
|
||||
elif [ $FLAGS_unpack -eq $FLAGS_TRUE ]; then
|
||||
do_unpack $@
|
||||
elif [ $FLAGS_remove -eq $FLAGS_TRUE ]; then
|
||||
# We log but ignore remove requests.
|
||||
echo "Ignoring remove: $@"
|
||||
else
|
||||
echo "dpkg_no_scripts.sh: Unknown or missing command."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
@ -101,10 +101,6 @@ APT_CACHE_DIR="${FLAGS_build_root}/apt_cache-${FLAGS_target}/"
|
||||
mkdir -p "${APT_CACHE_DIR}/archives/partial"
|
||||
|
||||
# Create the apt configuration file. See "man apt.conf"
|
||||
NO_MAINTAINER_SCRIPTS=""
|
||||
if [ -n "$EXPERIMENTAL_NO_MAINTAINER_SCRIPTS" ]; then
|
||||
NO_MAINTAINER_SCRIPTS="Bin { dpkg \"${SCRIPTS_DIR}/dpkg_no_scripts.sh\"; };"
|
||||
fi
|
||||
APT_PARTS="${OUTPUT_DIR}/apt.conf.d"
|
||||
mkdir -p "$APT_PARTS" # An empty apt.conf.d to avoid other configs.
|
||||
export APT_CONFIG="${OUTPUT_DIR}/apt.conf"
|
||||
@ -121,7 +117,9 @@ APT
|
||||
};
|
||||
Dir
|
||||
{
|
||||
$NO_MAINTAINER_SCRIPTS
|
||||
Bin {
|
||||
dpkg "${SCRIPTS_DIR}/dpkg_no_scripts.sh";
|
||||
};
|
||||
Cache "$APT_CACHE_DIR";
|
||||
Cache {
|
||||
archives "${APT_CACHE_DIR}/archives";
|
||||
@ -185,59 +183,24 @@ for p in $PACKAGES $EXTRA_PACKAGES; do
|
||||
PKG=$(ls "${REPO}"/${p}_*_all.deb)
|
||||
fi
|
||||
sudo "${SCRIPTS_DIR}"/dpkg_no_scripts.sh \
|
||||
--root="$ROOT_FS_DIR" --unpack "$PKG"
|
||||
--root="$ROOT_FS_DIR" --nodpkg_fallback --unpack "$PKG"
|
||||
sudo "${SCRIPTS_DIR}"/dpkg_no_scripts.sh \
|
||||
--root="$ROOT_FS_DIR" --nodpkg_fallback --configure "$p"
|
||||
done
|
||||
|
||||
# Make sure that apt is ready to work. We use --fix-broken to trigger apt
|
||||
# to install additional critical packages. If there are any of these, we
|
||||
# disable the maintainer scripts so they install ok.
|
||||
TMP_FORCE_NO_SCRIPTS="-o=Dir::Bin::dpkg=${SCRIPTS_DIR}/dpkg_no_scripts.sh"
|
||||
TMP_FORCE_NO_SCRIPTS="-o=DPkg::options::=--nodpkg_fallback"
|
||||
sudo APT_CONFIG="$APT_CONFIG" DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get $TMP_FORCE_NO_SCRIPTS --force-yes --fix-broken install
|
||||
|
||||
# ----- MAINTAINER SCRIPT FIXUPS -----
|
||||
|
||||
# TODO: Remove when we stop having maintainer scripts altogether.
|
||||
# TODO: Remove these hacks when we stop having maintainer scripts altogether.
|
||||
sudo cp -a /dev/* "${ROOT_FS_DIR}/dev"
|
||||
sudo cp -a /etc/resolv.conf "${ROOT_FS_DIR}/etc/resolv.conf"
|
||||
sudo ln -sf /bin/true "${ROOT_FS_DIR}/usr/sbin/invoke-rc.d"
|
||||
sudo ln -sf /bin/true "${ROOT_FS_DIR}/usr/sbin/update-rc.d"
|
||||
|
||||
# base-files
|
||||
# TODO: Careful audit of the postinst; this isn't all that is there.
|
||||
sudo cp -a "${ROOT_FS_DIR}/usr/share/base-files/networks" \
|
||||
"${ROOT_FS_DIR}/usr/share/base-files/nsswitch.conf" \
|
||||
"${ROOT_FS_DIR}/usr/share/base-files/profile" \
|
||||
"${ROOT_FS_DIR}/etc/"
|
||||
|
||||
# base-passwd
|
||||
sudo cp "${ROOT_FS_DIR}/usr/share/base-passwd/passwd.master" \
|
||||
"${ROOT_FS_DIR}/etc/passwd"
|
||||
sudo cp "${ROOT_FS_DIR}/usr/share/base-passwd/group.master" \
|
||||
"${ROOT_FS_DIR}/etc/group"
|
||||
|
||||
# libpam-runtime
|
||||
# The postinst script calls pam-auth-update, which is a perl script that
|
||||
# expects to run within the targetfs. Until we fix this, we just copy
|
||||
# from the build chroot.
|
||||
sudo cp -a /etc/pam.d/common-* \
|
||||
/etc/pam.d/login \
|
||||
/etc/pam.d/newusers \
|
||||
/etc/pam.d/su \
|
||||
/etc/pam.d/sudo \
|
||||
"${ROOT_FS_DIR}/etc/pam.d/"
|
||||
|
||||
# mawk
|
||||
sudo ln -s mawk "${ROOT_FS_DIR}/usr/bin/awk"
|
||||
|
||||
# base-files?
|
||||
sudo touch "${ROOT_FS_DIR}/etc/fstab"
|
||||
|
||||
# sysv-rc needs this
|
||||
sudo mkdir -p "${ROOT_FS_DIR}/etc/init.d"
|
||||
|
||||
# ----- END MAINTAINER SCRIPT FIXUPS -----
|
||||
|
||||
# Set up mounts for working within the rootfs. We copy some basic
|
||||
# network information from the host so that maintainer scripts can
|
||||
# access the network as needed.
|
||||
|
Loading…
x
Reference in New Issue
Block a user