tier1/fix:re-sync file owner post upgrade
Resync file owner if there are any discrepancies after the system is upgraded from a different build system. The script is to iterate all the files except /sysroot in parallel to check for a change in the uid/gid post-upgrade. If there is any it will trigger chown/chgrp to sync them according to the new uid/gid. The script caches the unchanged uid/gid to skip files with unchanged pairs and optimize the execution time. The scripts run via a systemd unit which in turn requires ostree-finalized-stage.service to ensure that the sync script runs only when a system is upgraded.
This commit is contained in:
parent
2ed185f6d1
commit
082e9ca10b
|
|
@ -0,0 +1,83 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Log file for tracking changes
|
||||
LOGFILE="/var/log/fix-ownership.log"
|
||||
echo "Starting ownership change process on $(date)" > "$LOGFILE"
|
||||
|
||||
# Cache to track unchanged users and groups
|
||||
UNCHANGED_USERS=()
|
||||
UNCHANGED_GROUPS=()
|
||||
USER_EXISTS=false
|
||||
GROUP_EXISTS=false
|
||||
|
||||
# function to check if a user is unchanged
|
||||
is_user_unchanged() {
|
||||
local user="$1"
|
||||
[[ " ${UNCHANGED_USERS[@]} " =~ " ${user} " ]]
|
||||
}
|
||||
|
||||
# function to check if a group is unchanged
|
||||
is_group_unchanged() {
|
||||
local group="$1"
|
||||
[[ " ${UNCHANGED_GROUPS[@]} " =~ " ${group} " ]]
|
||||
}
|
||||
|
||||
# function to process a single file
|
||||
process_file() {
|
||||
local filepath="$1"
|
||||
|
||||
# gather username, UID, group name, and GID of the file/folder
|
||||
FILE_UID=$(stat -c "%u" "$filepath")
|
||||
FILE_GID=$(stat -c "%g" "$filepath")
|
||||
FILE_USER=$(stat -c "%U" "$filepath")
|
||||
FILE_GROUP=$(stat -c "%G" "$filepath")
|
||||
|
||||
# skip files owned by unchanged users and groups
|
||||
if is_user_unchanged "$FILE_USER" && is_group_unchanged "$FILE_GROUP"; then
|
||||
return
|
||||
fi
|
||||
|
||||
# check if the user exists in /lib/passwd
|
||||
if grep -q "^${FILE_USER}:" /lib/passwd; then
|
||||
EXPECTED_UID=$(getent passwd "$FILE_USER" | cut -d: -f3)
|
||||
USER_EXISTS=true
|
||||
fi
|
||||
|
||||
# check if the group exists in /lib/group
|
||||
if grep -q "^${FILE_GROUP}:" /lib/group; then
|
||||
EXPECTED_GID=$(getent group "$FILE_GROUP" | cut -d: -f3)
|
||||
GROUP_EXISTS=true
|
||||
fi
|
||||
|
||||
# compare UID
|
||||
if $USER_EXISTS then
|
||||
if [[ "$FILE_UID" != "$EXPECTED_UID" ]]; then
|
||||
echo "Fixing UID for $filepath: $FILE_UID -> $EXPECTED_UID" >> "$LOGFILE"
|
||||
chown "$EXPECTED_UID" "$filepath"
|
||||
else
|
||||
# mark user as unchanged
|
||||
UNCHANGED_USERS+=("$FILE_USER")
|
||||
fi
|
||||
fi
|
||||
|
||||
# compare GID
|
||||
if $GROUP_EXISTS then
|
||||
if [[ "$FILE_GID" != "$EXPECTED_GID" ]]; then
|
||||
echo "Fixing GID for $filepath: $FILE_GID -> $EXPECTED_GID" >> "$LOGFILE"
|
||||
chgrp "$EXPECTED_GID" "$filepath"
|
||||
else
|
||||
# mark group as unchanged
|
||||
UNCHANGED_GROUPS+=("$FILE_GROUP")
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
export -f process_file
|
||||
export LOGFILE
|
||||
export UNCHANGED_USERS
|
||||
export UNCHANGED_GROUPS
|
||||
|
||||
# Parallelized processing with find and xargs
|
||||
find / -path /sysroot -prune -o -print 2>/dev/null | xargs -P "$(nproc)" -I {} bash -c 'process_file "$@"' _ {}
|
||||
echo "ownership chnage process completed on $(date)" >> "$LOGFILE"
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=Bootc system migration file ownership sync
|
||||
# This helps verify that we're running in a bootc/ostree based target.
|
||||
ConditionPathIsMountPoint=/sysroot
|
||||
RequiresMountsFor=/boot
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/libexec/bootc-file-ownership
|
||||
# So we can temporarily remount the sysroot writable
|
||||
MountFlags=slave
|
||||
# Just to auto-cleanup our temporary files
|
||||
PrivateTmp=yes
|
||||
|
||||
|
||||
|
|
@ -13,6 +13,7 @@ include:
|
|||
- persistent-journal.yaml
|
||||
- initramfs-full.yaml
|
||||
- generic-growfs.yaml
|
||||
- ownership-sync.yaml
|
||||
|
||||
packages:
|
||||
# Include and set the default editor
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
add-files:
|
||||
- - bootc-file-ownership
|
||||
- /usr/libexec/bootc-file-ownership
|
||||
- - bootc-file-ownership.service
|
||||
- /usr/lib/systemd/system/bootc-file-ownership.service
|
||||
|
||||
postprocess:
|
||||
- |
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
mkdir -p /usr/lib/systemd/system/ostree-finalized-stage.service.requires
|
||||
ln -s ../bootc-file-ownership.service /usr/lib/systemd/system/ostree-finalized-stage.service.requires/bootc-file-ownership.service
|
||||
Loading…
Reference in New Issue