Remove user-installed package if builtin
The previous blog post explained how APT is sync'ed with what is actually installed in the overlayfs layered filesystem:
https://bkgome.org/news/202608/continuing-getting-apt-to-work-in-a-layered-filesystem.html
The 'sync-dpkg-layers' script previously had some code to delete a user-installed package if it is now builtin. However, it did not work properly in that context.
What can happen is that a user installs a package, but at the next version update of EasyOS, that package is builtin to easy.sfs or devx.sfs. This may be a "corner case" but it does happen. In that situation, the user-installed package needs to be removed; however, it cannot be done while EasyOS is running. It has to be done before the layered filesystem is created, in the initrd.
I have created /sbin/zrem-user-pkgs in the initrd, called from /sbin/fixlayers. Script 'fixlayers' has this code:
#20260809 rem user-installed pkg if builtin...
if [ -n "$prevVER" ];then #prevVER set if a version update.
/sbin/zrem-user-pkgs ${WKG_DEV} ${WKG_DIR} ${prevVER}
fi
Here is script 'zrem-user-pkgs':
#!/bin/ash
#20260808 called from fixlayers
#situation where user has installed a package, then at next EasyOS version, same pkg
#is builtin to easy.sfs (or dev.sfs). Then need to remove the user-installed pkg.
#passed in...
WKG_DEV="$1" #ex: sda2
WKG_DIR="$2" #ex: easyos/
VER="$3" #previous version. ex: 7.4.6
#########
#containers...
Cpaths="$(find /mnt/${WKG_DEV}/${WKG_DIR}containers -mindepth 1 -maxdepth 1 -type d)"
#...ex: /mnt/nvme0n1p2/excalibur/containers/devx
for aS in ${Cpaths}
do
[ -z "$aS" ] && continue
[ ! -d "$aS/.session" ] && continue
[ ! -f "$aS/configuration" ] && continue
grep -q '^EASY_LAYER_RO.*devx' ${aS}/configuration
if [ $? -ne 0 ];then
#devx not loaded.
WOOFpkgs='/easy_ro/easy_sfs/root/.packages/woof-installed-packages'
else
#devx loaded.
WOOFpkgs='/easy_ro/easy_sfs/root/.packages/woof-installed-packages /easy_ro/easy_sfs/root/.packages/devx-only-installed-packages'
fi
for aU in $(cut -f 2 -d '|' ${aS}/.session/root/.packages/user-installed-packages | busybox tr '\n' ' ')
do
grep -q -F "|${aU}|" ${WOOFpkgs}
if [ $? -eq 0 ];then
if [ -f ${aS}/.session/var/lib/dpkg/info/${aU}.list ];then
FLIST="${aS}/.session/var/lib/dpkg/info/${aU}.list"
else
FLIST="$(find ${aS}/.session/root/.packages/filesdb -maxdepth 1 -name "${aU}_*.files" | head -n 1)"
fi
if [ -n "$FLIST" ];then
while read aF
do
[ -z "$aF" ] && continue
[ "$aF" == "/." ] && continue
if [ -f "${aS}/.session${aF}" ];then
rm -f "${aS}/.session${aF}"
fi
done <${FLIST}
#also delete empty folder...
while read aF
do
[ -z "$aF" ] && continue
[ "$aF" == "/." ] && continue
if [ -d "${aS}/.session${aF}" ];then
find "${aS}/.session${aF}" -maxdepth 0 -type d -empty -delete
fi
done <${FLIST}
sed -i "/|${aU}|/d" ${aS}/.session/root/.packages/user-installed-packages
fi
fi
done
done
############
#main desktop
#'configuration' file in this location:
#/mnt/${WKG_DEV}/${WKG_DIR}releases/easy-<version>/configuration
#with entry like this: "EASY_LAYER_RO1=devx.sfs"
[ ! -f /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${VER}/configuration ] && exit
grep -q '^EASY_LAYER_RO.*devx' /mnt/${WKG_DEV}/${WKG_DIR}releases/easy-${VER}/configuration
if [ $? -eq 0 ];then
#devx loaded.
WOOFpkgs='/easy_ro/easy_sfs/root/.packages/woof-installed-packages /easy_ro/easy_sfs/root/.packages/devx-only-installed-packages'
else
#devx not loaded.
WOOFpkgs='/easy_ro/easy_sfs/root/.packages/woof-installed-packages'
fi
for aU in $(cut -f 2 -d '|' /mnt/${WKG_DEV}/${WKG_DIR}.session/session1/root/.packages/user-installed-packages | busybox tr '\n' ' ')
do
grep -q -F "|${aU}|" ${WOOFpkgs}
if [ $? -eq 0 ];then
if [ -f /mnt/${WKG_DEV}/${WKG_DIR}.session/session1/var/lib/dpkg/info/${aU}.list ];then
FLIST="/mnt/${WKG_DEV}/${WKG_DIR}.session/session1/var/lib/dpkg/info/${aU}.list"
else
FLIST="$(find /mnt/${WKG_DEV}/${WKG_DIR}.session/session1/root/.packages/filesdb -maxdepth 1 -name "${aU}_*.files" | head -n 1)"
fi
if [ -n "$FLIST" ];then
while read aF
do
[ -z "$aF" ] && continue
[ "$aF" == "/." ] && continue
if [ -f "/mnt/${WKG_DEV}/${WKG_DIR}.session/session1${aF}" ];then
rm -f "/mnt/${WKG_DEV}/${WKG_DIR}.session/session1${aF}"
fi
done <${FLIST}
#also delete empty folder...
while read aF
do
[ -z "$aF" ] && continue
[ "$aF" == "/." ] && continue
if [ -d "/mnt/${WKG_DEV}/${WKG_DIR}.session/session1${aF}" ];then
find "/mnt/${WKG_DEV}/${WKG_DIR}.session/session1${aF}" -maxdepth 0 -type d -empty -delete
fi
done <${FLIST}
sed -i "/|${aU}|/d" /mnt/${WKG_DEV}/${WKG_DIR}.session/session1/root/.packages/user-installed-packages
fi
fi
done
###end###
It is another hack to get APT and dpkg to play nice in the
layered filesystem.
Tags: easy