sync upstream update

This commit is contained in:
awalol
2025-08-26 11:09:07 +00:00
parent 4da38afb14
commit 7183cc4f04

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env bash
set -Eeuo pipefail
STORAGE=$(pwd)/workdir
COUNTRY="CN"
DEBUG="Y"
@@ -19,27 +18,66 @@ info(){
printf "%b%s%b \E[1;34m \E[1;36m Info: $1 \E[0m\n"
}
formatBytes() {
local result
result=$(numfmt --to=iec --suffix=B "$1" | sed -r 's/([A-Z])/ \1/' | sed 's/ B/ bytes/g;')
local unit="${result//[0-9. ]}"
result="${result//[a-zA-Z ]/}"
if [[ "${2:-}" == "up" ]]; then
if [[ "$result" == *"."* ]]; then
result="${result%%.*}"
result=$((result+1))
fi
else
if [[ "${2:-}" == "down" ]]; then
result="${result%%.*}"
fi
fi
echo "$result $unit"
return 0
}
: "${URL:=""}" # URL of the PAT file to be downloaded.
if [ -f "$STORAGE/dsm.ver" ]; then
BASE=$(<"$STORAGE/dsm.ver")
BASE="${BASE//[![:print:]]/}"
[ -z "$BASE" ] && BASE="DSM_VirtualDSM_69057"
else
# Fallback for old installs
BASE="DSM_VirtualDSM_42962"
fi
if [ -n "$URL" ]; then
FN="boot.pat"
DIR=$(find / -maxdepth 1 -type d -iname "$FN" -print -quit)
[ ! -d "$DIR" ] && DIR=$(find "$STORAGE" -maxdepth 1 -type d -iname "$FN" -print -quit)
if [ -d "$DIR" ]; then
BASE="DSM_VirtualDSM" && URL="file://$DIR"
if [[ ! -s "$STORAGE/$BASE.boot.img" ]] || [[ ! -s "$STORAGE/$BASE.system.img" ]]; then
error "The bind $DIR maps to a file that does not exist!" && exit 65
fi
fi
FILE=$(find / -maxdepth 1 -type f -iname "$FN" -print -quit)
[ ! -s "$FILE" ] && FILE=$(find "$STORAGE" -maxdepth 1 -type f -iname "$FN" -print -quit)
[ -s "$FILE" ] && BASE="DSM_VirtualDSM" && URL="file://$FILE"
if [ -n "$URL" ] && [ ! -s "$FILE" ] && [ ! -d "$DIR" ]; then
BASE=$(basename "$URL" .pat)
if [ ! -f "$STORAGE/$BASE.system.img" ]; then
if [ ! -s "$STORAGE/$BASE.system.img" ]; then
BASE=$(basename "${URL%%\?*}" .pat)
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g')
fi
if [[ "${URL,,}" != "http"* ]] && [[ "${URL,,}" != "file:"* ]] ; then
[ ! -s "$STORAGE/$BASE.pat" ] && error "Invalid URL: $URL" && exit 65
URL="file://$STORAGE/$BASE.pat"
fi
fi
if [[ -f "$STORAGE/$BASE.boot.img" ]] && [[ -f "$STORAGE/$BASE.system.img" ]]; then
info "Previous installation found"
exit 0 # Previous installation found
if [[ -s "$STORAGE/$BASE.boot.img" ]] && [[ -s "$STORAGE/$BASE.system.img" ]]; then
return 0 # Previous installation found
fi
html "Please wait while Virtual DSM is being installed..."
@@ -57,11 +95,15 @@ if [ -z "$DL" ]; then
[[ "${COUNTRY^^}" == "CN" ]] && DL="$DL_CHINA" || DL="$DL_GLOBAL"
fi
[ -z "$URL" ] && URL="$DL/release/7.2.1/69057-1/DSM_VirtualDSM_69057.pat"
if [ -z "$URL" ]; then
URL="$DL/release/7.2.2/72806/DSM_VirtualDSM_72806.pat"
fi
BASE=$(basename "${URL%%\?*}" .pat)
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g')
if [ ! -s "$FILE" ]; then
BASE=$(basename "${URL%%\?*}" .pat)
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g')
fi
if [[ "$URL" != "file://$STORAGE/$BASE.pat" ]]; then
rm -f "$STORAGE/$BASE.pat"
@@ -71,8 +113,6 @@ rm -f "$STORAGE/$BASE.agent"
rm -f "$STORAGE/$BASE.boot.img"
rm -f "$STORAGE/$BASE.system.img"
[[ "$DEBUG" == [Yy1]* ]] && set -x
# Check filesystem
FS=$(stat -f -c %T "$STORAGE")
@@ -84,15 +124,23 @@ if [[ "${FS,,}" == "fuse"* ]]; then
info "Warning: the filesystem of $STORAGE is FUSE, this extra layer will negatively affect performance!"
fi
if [[ "${FS,,}" != "fat"* && "${FS,,}" != "vfat"* && "${FS,,}" != "exfat"* && "${FS,,}" != "ntfs"* && "${FS,,}" != "msdos"* ]]; then
if [[ "${FS,,}" == "ecryptfs" ]] || [[ "${FS,,}" == "tmpfs" ]]; then
info "Warning: the filesystem of $STORAGE is $FS, which does not support O_DIRECT mode, adjusting settings..."
fi
if [[ "${FS,,}" == "fat"* || "${FS,,}" == "vfat"* || "${FS,,}" == "msdos"* ]]; then
error "Unable to install on $FS filesystems, please use a different filesystem for /storage." && exit 61
fi
if [[ "${FS,,}" != "exfat"* && "${FS,,}" != "ntfs"* && "${FS,,}" != "unknown"* ]]; then
TMP="$STORAGE/tmp"
else
TMP="/tmp/dsm"
TMP_SPACE=2147483648
SPACE=$(df --output=avail -B 1 /tmp | tail -n 1)
SPACE_MB=$(( (SPACE + 1048575)/1048576 ))
SPACE_MB=$(formatBytes "$SPACE")
if (( TMP_SPACE > SPACE )); then
error "Not enough free space inside the container, have $SPACE_MB MB available but need at least 2 GB." && exit 93
error "Not enough free space inside the container, have $SPACE_MB available but need at least 2 GB." && exit 93
fi
fi
@@ -101,13 +149,13 @@ rm -rf "$TMP" && mkdir -p "$TMP"
# Check free diskspace
ROOT_SPACE=536870912
SPACE=$(df --output=avail -B 1 / | tail -n 1)
SPACE_MB=$(( (SPACE + 1048575)/1048576 ))
(( ROOT_SPACE > SPACE )) && error "Not enough free space inside the container, have $SPACE_MB MB available but need at least 500 MB." && exit 96
SPACE_MB=$(formatBytes "$SPACE" "down")
(( ROOT_SPACE > SPACE )) && error "Not enough free space inside the container, have $SPACE_MB available but need at least 500 MB." && exit 96
MIN_SPACE=8589934592
MIN_SPACE=15032385536
SPACE=$(df --output=avail -B 1 "$STORAGE" | tail -n 1)
SPACE_GB=$(( (SPACE + 1073741823)/1073741824 ))
(( MIN_SPACE > SPACE )) && error "Not enough free space for installation in $STORAGE, have $SPACE_GB GB available but need at least 8 GB." && exit 94
SPACE_GB=$(formatBytes "$SPACE")
(( MIN_SPACE > SPACE )) && error "Not enough free space for installation in $STORAGE, have $SPACE_GB available but need at least 14 GB." && exit 94
# Check if output is to interactive TTY
if [ -t 1 ]; then
@@ -116,99 +164,50 @@ else
PROGRESS="--progress=dot:giga"
fi
# Download the required files from the Synology website
ROOT="Y"
RDC="$STORAGE/dsm.rd"
if [ ! -f "$RDC" ]; then
MSG="Downloading installer..."
PRG="Downloading installer ([P])..."
info "Install: $MSG" && html "$MSG"
RD="$TMP/rd.gz"
POS="65627648-71021835"
VERIFY="b4215a4b213ff5154db0488f92c87864"
LOC="$DL/release/7.0.1/42218/DSM_VirtualDSM_42218.pat"
rm -f "$RD"
#/run/progress.sh "$RD" "$PRG" &
{ curl -r "$POS" -sfk -S -o "$RD" "$LOC"; rc=$?; } || :
#fKill "progress.sh"
(( rc != 0 )) && error "Failed to download $LOC, reason: $rc" && exit 60
SUM=$(md5sum "$RD" | cut -f 1 -d " ")
if [ "$SUM" != "$VERIFY" ]; then
PAT="/install.pat"
rm "$RD"
rm -f "$PAT"
html "$MSG"
#/run/progress.sh "$PAT" "$PRG" &
{ wget "$LOC" -O "$PAT" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || :
#fKill "progress.sh"
(( rc != 0 )) && error "Failed to download $LOC , reason: $rc" && exit 60
tar --extract --file="$PAT" --directory="$(dirname "$RD")"/. "$(basename "$RD")"
rm "$PAT"
fi
cp "$RD" "$RDC"
if [[ "$URL" == "file://"* ]]; then
MSG="Copying DSM"
ERR="Failed to copy ${URL:7}"
info "Install: Copying installation image..."
else
MSG="Downloading DSM"
ERR="Failed to download $URL"
info "Install: Downloading $BASE.pat..."
fi
if [ -f "$RDC" ]; then
html "$MSG..."
{ xz -dc <"$RDC" >"$TMP/rd" 2>/dev/null; rc=$?; } || :
(( rc != 1 )) && error "Failed to unxz $RDC, reason $rc" && exit 91
{ (cd "$TMP" && cpio -idm <"$TMP/rd" 2>/dev/null); rc=$?; } || :
if (( rc != 0 )); then
ROOT="N"
{ (cd "$TMP" && fakeroot cpio -idmu <"$TMP/rd" 2>/dev/null); rc=$?; } || :
(( rc != 0 )) && error "Failed to extract $RDC, reason $rc" && exit 92
fi
git clone https://mirror.ghproxy.com/https://github.com/technorabilia/syno-extract-system-patch $TMP/syno-extract-system-patch
docker build --tag syno-extract-system-patch $TMP/syno-extract-system-patch
fi
rm -rf "$TMP" && mkdir -p "$TMP"
info "Install: Downloading $BASE.pat..."
MSG="Downloading DSM..."
PRG="Downloading DSM ([P])..."
html "$MSG"
PAT="$TMP/$BASE.pat"
PAT="/$BASE.pat"
rm -f "$PAT"
if [[ "$URL" == "file://"* ]]; then
if [ ! -f "${URL:7}" ]; then
error "File '${URL:7}' does not exist!" && exit 65
fi
cp "${URL:7}" "$PAT"
else
#/run/progress.sh "$PAT" "$PRG" &
SIZE=0
[[ "${URL,,}" == *"_72806.pat" ]] && SIZE=361010261
[[ "${URL,,}" == *"_69057.pat" ]] && SIZE=363837333
[[ "${URL,,}" == *"_42218.pat" ]] && SIZE=379637760
{ wget "$URL" -O "$PAT" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || :
# /run/progress.sh "$PAT" "$SIZE" "$MSG ([P])..." &
#fKill "progress.sh"
(( rc != 0 )) && error "Failed to download $URL , reason: $rc" && exit 69
{ wget "$URL" -O "$PAT" -q --no-check-certificate --timeout=10 --no-http-keep-alive --show-progress "$PROGRESS"; rc=$?; } || :
# fKill "progress.sh"
(( rc == 3 )) && error "$ERR , cannot write file (disk full?)" && exit 69
(( rc == 4 )) && error "$ERR , network failure!" && exit 69
(( rc == 8 )) && error "$ERR , server issued an error response!" && exit 69
(( rc != 0 )) && error "$ERR , reason: $rc" && exit 69
fi
[ ! -f "$PAT" ] && error "Failed to download $URL" && exit 69
[ ! -s "$PAT" ] && error "$ERR" && exit 69
SIZE=$(stat -c%s "$PAT")
@@ -216,7 +215,7 @@ if ((SIZE<250000000)); then
error "The specified PAT file is probably an update pack as it's too small." && exit 62
fi
MSG="Extracting downloaded image..."
MSG="Extracting installation image..."
info "Install: $MSG" && html "$MSG"
if { tar tf "$PAT"; } >/dev/null 2>&1; then
@@ -224,10 +223,14 @@ if { tar tf "$PAT"; } >/dev/null 2>&1; then
tar xpf "$PAT" -C "$TMP/."
else
pip install dissect.cstruct msgpack pysodium
wget https://raw.githubusercontent.com/sud0woodo/patology/refs/heads/main/patology.py -O $TMP/extract.py
{ (cd "$TMP" && python3 extract.py -i "$PAT" -d 2>extract.log); rc=$?; } || :
docker run --rm -v $TMP:/data syno-extract-system-patch \
/data/$BASE.pat \
/data/.
if (( rc != 0 )); then
cat $TMP/extract.log
error "Failed to extract PAT file, reason $rc" && exit 63
fi
fi
@@ -235,7 +238,7 @@ MSG="Preparing system partition..."
info "Install: $MSG" && html "$MSG"
BOOT=$(find "$TMP" -name "*.bin.zip")
[ ! -f "$BOOT" ] && error "The PAT file contains no boot image." && exit 67
[ ! -s "$BOOT" ] && error "The PAT file contains no boot image." && exit 67
BOOT=$(echo "$BOOT" | head -c -5)
unzip -q -o "$BOOT".zip -d "$TMP"
@@ -244,30 +247,32 @@ SYSTEM="$STORAGE/$BASE.system.img"
rm -f "$SYSTEM"
# Check free diskspace
SYSTEM_SIZE=4954537983
SYSTEM_SIZE=10738466816
SPACE=$(df --output=avail -B 1 "$STORAGE" | tail -n 1)
SPACE_MB=$(( (SPACE + 1048575)/1048576 ))
SPACE_MB=$(formatBytes "$SPACE")
if (( SYSTEM_SIZE > SPACE )); then
error "Not enough free space in $STORAGE to create a 5 GB system disk, have only $SPACE_MB MB available." && exit 97
error "Not enough free space in $STORAGE to create a 10 GB system disk, have only $SPACE_MB available." && exit 97
fi
if ! touch "$SYSTEM"; then
error "Could not create file $SYSTEM for the system disk." && exit 98
fi
if [[ "${FS,,}" == "xfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
if [[ "${FS,,}" == "btrfs" ]]; then
{ chattr +C "$SYSTEM"; } || :
FA=$(lsattr "$SYSTEM")
if [[ "$FA" != *"C"* ]]; then
error "Failed to disable COW for system image $SYSTEM on ${FS^^} filesystem (returned $FA)"
error "Failed to disable COW for system image $SYSTEM on ${FS^^} filesystem."
fi
fi
if ! fallocate -l "$SYSTEM_SIZE" "$SYSTEM"; then
if ! truncate -s "$SYSTEM_SIZE" "$SYSTEM"; then
rm -f "$SYSTEM"
error "Could not allocate file $SYSTEM for the system disk." && exit 98
if ! fallocate -l "$SYSTEM_SIZE" "$SYSTEM" &>/dev/null; then
if ! fallocate -l -x "$SYSTEM_SIZE" "$SYSTEM"; then
if ! truncate -s "$SYSTEM_SIZE" "$SYSTEM"; then
rm -f "$SYSTEM"
error "Could not allocate file $SYSTEM for the system disk." && exit 98
fi
fi
fi
@@ -279,8 +284,8 @@ PART="$TMP/partition.fdisk"
echo "unit: sectors"
echo "sector-size: 512"
echo ""
echo "${SYSTEM}1 : start= 2048, size= 4980480, type=83"
echo "${SYSTEM}2 : start= 4982528, size= 4194304, type=82"
echo "${SYSTEM}1 : start= 2048, size= 16777216, type=83"
echo "${SYSTEM}2 : start= 16779264, size= 4194304, type=82"
} > "$PART"
sfdisk -q "$SYSTEM" < "$PART"
@@ -296,41 +301,28 @@ IDB="$TMP/indexdb"
PKG="$TMP/packages"
HDP="$TMP/synohdpack_img"
[ ! -f "$HDA.tgz" ] && error "The PAT file contains no OS image." && exit 64
[ ! -s "$HDA.tgz" ] && error "The PAT file contains no OS image." && exit 64
mv "$HDA.tgz" "$HDA.txz"
[ -d "$PKG" ] && mv "$PKG/" "$MOUNT/.SynoUpgradePackages/"
rm -f "$MOUNT/.SynoUpgradePackages/ActiveInsight-"*
[ -f "$HDP.txz" ] && tar xpfJ "$HDP.txz" --absolute-names -C "$MOUNT/"
if [ -f "$IDB.txz" ]; then
INDEX_DB="$MOUNT/usr/syno/synoman/indexdb/"
if [ -s "$IDB.txz" ]; then
INDEX_DB="$MOUNT/usr/syno/synoman/indexdb"
mkdir -p "$INDEX_DB"
tar xpfJ "$IDB.txz" --absolute-names -C "$INDEX_DB"
fi
LABEL="1.44.1-42218"
OFFSET="1048576" # 2048 * 512
NUMBLOCKS="622560" # (4980480 * 512) / 4096
OFFSET="1048576" # 2048 * 512
NUMBLOCKS="2097152" # (16777216 * 512) / 4096
MSG="Installing system partition..."
if [[ "$ROOT" != [Nn]* ]]; then
tar xpfJ "$HDA.txz" --absolute-names --skip-old-files -C "$MOUNT/"
info "Install: $MSG" && html "$MSG"
mke2fs -q -t ext4 -b 4096 -d "$MOUNT/" -L "$LABEL" -F -E "offset=$OFFSET" "$SYSTEM" "$NUMBLOCKS"
else
fakeroot -- bash -c "set -Eeu;\
tar xpfJ $HDA.txz --absolute-names --skip-old-files -C $MOUNT/;\
printf '%b%s%b' '\E[1;34m \E[1;36m' 'Install: $MSG' '\E[0m\n';\
mke2fs -q -t ext4 -b 4096 -d $MOUNT/ -L $LABEL -F -E offset=$OFFSET $SYSTEM $NUMBLOCKS"
fi
fakeroot -- bash -c "set -Eeu;\
[ -s $HDP.txz ] && tar xpfJ $HDP.txz --absolute-names -C $MOUNT/;\
[ -s $IDB.txz ] && tar xpfJ $IDB.txz --absolute-names -C $INDEX_DB/;\
tar xpfJ $HDA.txz --absolute-names --skip-old-files -C $MOUNT/;\
printf '%b%s%b' '\E[1;34m \E[1;36m' 'Install: $MSG' '\E[0m\n';\
mke2fs -q -t ext4 -b 4096 -d $MOUNT/ -L $LABEL -F -E offset=$OFFSET $SYSTEM $NUMBLOCKS"
rm -rf "$MOUNT"
echo "$BASE" > "$STORAGE/dsm.ver"
@@ -344,7 +336,7 @@ fi
mv -f "$BOOT" "$STORAGE/$BASE.boot.img"
rm -rf "$TMP"
{ set +x; } 2>/dev/null
[[ "$DEBUG" == [Yy1]* ]] && echo
html "Booting DSM instance..."
sleep 1.2
html "Installation finished successfully..."
return 0