Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ca9bf47fb | ||
|
|
57d0cb2bf1 | ||
|
|
05c6edbd0d |
1
.github/workflows/custom.yml
vendored
1
.github/workflows/custom.yml
vendored
@@ -138,6 +138,7 @@ jobs:
|
||||
writeConfigKey "addons.\"${A}\"" "${VALUE}" "${PRESET_CONFIG_FILE}"
|
||||
done
|
||||
fi
|
||||
writeConfigKey "automated" "true" "${PRESET_CONFIG_FILE}"
|
||||
echo "$(cat "${PRESET_CONFIG_FILE}")"
|
||||
sudo echo "arc-${MODEL}-${PRODUCTVER:0:3}-${TAG}" >"/tmp/automated"
|
||||
sudo mv -f "/tmp/automated" "/tmp/p3/automated"
|
||||
|
||||
@@ -124,7 +124,6 @@ function arcModel() {
|
||||
writeConfigKey "smallnum" "" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "sn" "" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "zimage-hash" "" "${USER_CONFIG_FILE}"
|
||||
rm -f "${ORI_ZIMAGE_FILE}" "${ORI_RDGZ_FILE}" "${MOD_ZIMAGE_FILE}" "${MOD_RDGZ_FILE}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
PLATFORM="$(grep -w "${MODEL}" "${TMP_PATH}/modellist" | awk '{print $2}' | head -1)"
|
||||
writeConfigKey "platform" "${PLATFORM}" "${USER_CONFIG_FILE}"
|
||||
@@ -173,7 +172,6 @@ function arcVersion() {
|
||||
writeConfigKey "ramdisk-hash" "" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "smallnum" "" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "zimage-hash" "" "${USER_CONFIG_FILE}"
|
||||
rm -f "${ORI_ZIMAGE_FILE}" "${ORI_RDGZ_FILE}" "${MOD_ZIMAGE_FILE}" "${MOD_RDGZ_FILE}" >/dev/null 2>&1 || true
|
||||
fi
|
||||
dialog --backtitle "$(backtitle)" --title "Version" \
|
||||
--infobox "Reading DSM Build..." 3 25
|
||||
@@ -2053,20 +2051,17 @@ function credits() {
|
||||
###############################################################################
|
||||
# Setting Static IP for Loader
|
||||
function staticIPMenu() {
|
||||
ETHX="$(ls /sys/class/net/ 2>/dev/null | grep eth)"
|
||||
ETHX=$(ls /sys/class/net/ 2>/dev/null | grep eth)
|
||||
IPCON=""
|
||||
for N in ${ETHX}; do
|
||||
MACR="$(cat /sys/class/net/${N}/address 2>/dev/null | sed 's/://g')"
|
||||
IPR="$(readConfigKey "network.${MACR}" "${USER_CONFIG_FILE}")"
|
||||
IFS='/' read -r -a IPRA <<<"${IPR}"
|
||||
|
||||
MSG="Set ${N}(${MACR}) IP to: (Delete if empty)"
|
||||
while true; do
|
||||
IPR="$(readConfigKey "network.${MACR}" "${USER_CONFIG_FILE}")"
|
||||
IFS='/' read -r -a IPRA <<<"${IPR}"
|
||||
dialog --backtitle "$(backtitle)" --title "StaticIP" \
|
||||
--form "${MSG}" 10 60 4 \
|
||||
"address" 1 1 "${IPRA[0]}" 1 9 36 16 \
|
||||
"netmask" 2 1 "${IPRA[1]}" 2 9 36 16 \
|
||||
"gateway" 3 1 "${IPRA[2]}" 3 9 36 16 \
|
||||
"dns" 4 1 "${IPRA[3]}" 4 9 36 16 \
|
||||
--form "${MSG}" 10 60 4 "address" 1 1 "${IPRA[0]}" 1 9 36 16 "netmask" 2 1 "${IPRA[1]}" 2 9 36 16 "gateway" 3 1 "${IPRA[2]}" 3 9 36 16 "dns" 4 1 "${IPRA[3]}" 4 9 36 16 \
|
||||
2>"${TMP_PATH}/resp"
|
||||
RET=$?
|
||||
case ${RET} in
|
||||
@@ -2077,10 +2072,9 @@ function staticIPMenu() {
|
||||
dnsname="$(sed -n '4p' "${TMP_PATH}/resp" 2>/dev/null)"
|
||||
(
|
||||
if [ -z "${address}" ]; then
|
||||
echo "Deleting IP for ${N}(${MACR})"
|
||||
if [ -n "$(readConfigKey "network.${MACR}" "${USER_CONFIG_FILE}")" ]; then
|
||||
if [ "1" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
|
||||
ip addr flush dev ${N}
|
||||
ip addr flush dev "${N}"
|
||||
fi
|
||||
deleteConfigKey "network.${MACR}" "${USER_CONFIG_FILE}"
|
||||
IP="$(getIP)"
|
||||
@@ -2088,38 +2082,37 @@ function staticIPMenu() {
|
||||
sleep 1
|
||||
fi
|
||||
else
|
||||
echo "Setting IP for ${N}(${MACR}) to ${address}/${netmask}/${gateway}/${dnsname}"
|
||||
if [ "1" = "$(cat /sys/class/net/${N}/carrier 2>/dev/null)" ]; then
|
||||
ip addr flush dev ${N}
|
||||
ip addr add ${address}/${netmask:-"255.255.255.0"} dev ${N} || exit 1
|
||||
ip addr flush dev "${N}"
|
||||
ip addr add "${address}/${netmask:-"255.255.255.0"}" dev "${N}"
|
||||
if [ -n "${gateway}" ]; then
|
||||
ip route add default via ${gateway} dev ${N} || exit 1
|
||||
ip route add default via "${gateway}" dev "${N}"
|
||||
fi
|
||||
if [ -n "${dnsname:-${gateway}}" ]; then
|
||||
sed -i "/nameserver ${dnsname:-${gateway}}/d" /etc/resolv.conf
|
||||
echo "nameserver ${dnsname:-${gateway}}" >>/etc/resolv.conf || exit 1
|
||||
echo "nameserver ${dnsname:-${gateway}}" >>/etc/resolv.conf
|
||||
fi
|
||||
fi
|
||||
writeConfigKey "network.${MACR}" "${address}/${netmask}/${gateway}/${dnsname}" "${USER_CONFIG_FILE}"
|
||||
sleep 3
|
||||
IP="$(getIP)"
|
||||
[ -z "${IPCON}" ] && IPCON="${IP}"
|
||||
sleep 1
|
||||
fi
|
||||
writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}"
|
||||
BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")"
|
||||
) 2>&1 | dialog --backtitle "$(backtitle)" --title "StaticIP" \
|
||||
--progressbox "Setting IP for ${N}" 20 100
|
||||
writeConfigKey "arc.builddone" "false" "${USER_CONFIG_FILE}"
|
||||
BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")"
|
||||
getnetinfo
|
||||
--progressbox "Setting IP ..." 20 100
|
||||
break
|
||||
;;
|
||||
1)
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
break 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
return
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
@@ -2661,11 +2654,10 @@ function resetLoader() {
|
||||
[ -d "${UNTAR_PAT_PATH}" ] && rm -rf "${UNTAR_PAT_PATH}" >/dev/null
|
||||
[ -f "${USER_CONFIG_FILE}" ] && rm -f "${USER_CONFIG_FILE}" >/dev/null
|
||||
[ -f "${ARC_RAMDISK_USER_FILE}" ] && rm -f "${ARC_RAMDISK_USER_FILE}" >/dev/null
|
||||
[ -f "${HOME}/.initialized" ] && rm -f "${HOME}/.initialized" >/dev/null
|
||||
dialog --backtitle "$(backtitle)" --title "Reset Loader" --aspect 18 \
|
||||
--yesno "Reset successful.\nReboot required!" 0 0
|
||||
[ $? -ne 0 ] && return
|
||||
exec init.sh
|
||||
rebootTo config
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -53,7 +53,7 @@ elif [ "${ARCMODE}" = "automated" ]; then
|
||||
fi
|
||||
elif [ "${ARCMODE}" = "config" ]; then
|
||||
[ "${CONFDONE}" = "true" ] && NEXT="2" || NEXT="1"
|
||||
[ "${BUILDDONE}" = "true" ] && NEXT="4" || NEXT="1"
|
||||
[ "${BUILDDONE}" = "true" ] && NEXT="3" || NEXT="1"
|
||||
while true; do
|
||||
rm -f "${TMP_PATH}/menu" "${TMP_PATH}/resp" >/dev/null 2>&1 || true
|
||||
|
||||
@@ -71,13 +71,10 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
else
|
||||
write_menu "2" "Build Loader"
|
||||
fi
|
||||
if [ -f "${MOD_ZIMAGE_FILE}" ] && [ -f "${MOD_RDGZ_FILE}" ]; then
|
||||
write_menu "3" "Rebuild Loader with clean Image"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${BUILDDONE}" = "true" ]; then
|
||||
write_menu "4" "Boot Loader"
|
||||
write_menu "3" "Boot Loader"
|
||||
fi
|
||||
|
||||
write_menu "=" "\Z4===== Info =====\Zn"
|
||||
@@ -86,7 +83,7 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
|
||||
if [ "${CONFDONE}" = "true" ]; then
|
||||
if [ "${ARCOPTS}" = "true" ]; then
|
||||
write_menu "5" "\Z1Hide Arc DSM Options\Zn"
|
||||
write_menu "4" "\Z1Hide Arc DSM Options\Zn"
|
||||
write_menu "b" "Addons"
|
||||
write_menu "d" "Modules"
|
||||
write_menu "e" "Version"
|
||||
@@ -120,7 +117,7 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
write_menu_value "h" "USB as Internal" "${USBMOUNT}"
|
||||
fi
|
||||
else
|
||||
write_menu "5" "\Z1Show Arc DSM Options\Zn"
|
||||
write_menu "4" "\Z1Show Arc DSM Options\Zn"
|
||||
fi
|
||||
|
||||
if [ "${BOOTOPTS}" = "true" ]; then
|
||||
@@ -180,8 +177,8 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
write_menu "I" "Power/Service Menu"
|
||||
write_menu "V" "Credits"
|
||||
[ "$TERM" != "xterm-256color" ] && WEBCONFIG="Webconfig: http://${IPCON}${HTTPPORT:+:$HTTPPORT}" || WEBCONFIG=""
|
||||
dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Advanced UI" --colors \
|
||||
--cancel-label "Easy UI" --help-button --help-label "Exit" \
|
||||
dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Classic UI" --colors \
|
||||
--cancel-label "Evo" --help-button --help-label "Exit" \
|
||||
--menu "${WEBCONFIG}" 0 0 0 --file "${TMP_PATH}/menu" \
|
||||
2>"${TMP_PATH}/resp"
|
||||
RET=$?
|
||||
@@ -193,20 +190,16 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
# Main Section
|
||||
0) genHardwareID; NEXT="0" ;;
|
||||
1) arcModel; NEXT="2" ;;
|
||||
2) arcSummary; NEXT="4" ;;
|
||||
3) rm -f "${MOD_ZIMAGE_FILE}" "${MOD_RDGZ_FILE}" >/dev/null 2>&1 || true
|
||||
arcSummary;
|
||||
NEXT="4"
|
||||
;;
|
||||
4) boot; NEXT="4" ;;
|
||||
2) arcSummary; NEXT="3" ;;
|
||||
3) boot; NEXT="3" ;;
|
||||
# Info Section
|
||||
a) sysinfo; NEXT="a" ;;
|
||||
A) networkdiag; NEXT="A" ;;
|
||||
# System Section
|
||||
# Arc Section
|
||||
5) [ "${ARCOPTS}" = "true" ] && ARCOPTS='false' || ARCOPTS='true'
|
||||
4) [ "${ARCOPTS}" = "true" ] && ARCOPTS='false' || ARCOPTS='true'
|
||||
ARCOPTS="${ARCOPTS}"
|
||||
NEXT="5"
|
||||
NEXT="4"
|
||||
;;
|
||||
b) addonMenu; NEXT="b" ;;
|
||||
d) modulesMenu; NEXT="d" ;;
|
||||
@@ -353,9 +346,7 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
done
|
||||
clear
|
||||
else
|
||||
echo "Unknown Mode: ${ARCMODE} - Rebooting to Config Mode"
|
||||
sleep 3
|
||||
rebootTo config
|
||||
echo "Unknown Mode: ${ARCMODE} - Exiting..."
|
||||
fi
|
||||
|
||||
# Inform user
|
||||
|
||||
@@ -13,7 +13,7 @@ rm -rf "${PART1_PATH}/logs" >/dev/null 2>&1 || true
|
||||
# Get Loader Disk Bus
|
||||
[ -z "${LOADER_DISK}" ] && die "Loader Disk not found!"
|
||||
BUS=$(getBus "${LOADER_DISK}")
|
||||
[ -d /sys/firmware/efi ] && EFI="1" || EFI="0"
|
||||
EFI=$([ -d /sys/firmware/efi ] && echo 1 || echo 0)
|
||||
|
||||
# Print Title centralized
|
||||
clear
|
||||
@@ -60,23 +60,21 @@ HWIDINFO="$(readConfigKey "bootscreen.hwidinfo" "${USER_CONFIG_FILE}")"
|
||||
GOVERNOR="$(readConfigKey "governor" "${USER_CONFIG_FILE}")"
|
||||
USBMOUNT="$(readConfigKey "usbmount" "${USER_CONFIG_FILE}")"
|
||||
BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")"
|
||||
ARCPATCH="$(readConfigKey "arc.patch" "${USER_CONFIG_FILE}")"
|
||||
|
||||
# Build Sanity Check
|
||||
[ "${BUILDDONE}" = "false" ] && die "Loader build not completed!"
|
||||
[[ -z "${MODELID}" || "${MODELID}" != "${MODEL}" ]] && die "Loader build not completed! Model mismatch! -> Rebuild loader!"
|
||||
|
||||
[[ -z "${MODELID}" || "${MODELID}" != "${MODEL}" ]] && die "Loader build not completed! Model mismatch!"
|
||||
# HardwareID Check
|
||||
if [ "${ARCPATCH}" = "true" ] || [ -n "${ARCCONF}" ]; then
|
||||
if [ "${ARCPATCH}" = "true" ]; then
|
||||
HARDWAREID="$(readConfigKey "arc.hardwareid" "${USER_CONFIG_FILE}")"
|
||||
HWID="$(genHWID)"
|
||||
if [ "${HARDWAREID}" != "${HWID}" ]; then
|
||||
echo -e "\033[1;31m*** HardwareID does not match! - Loader can't verfify your System! You need to reconfigure your Loader - Rebooting to Config Mode! ***\033[0m"
|
||||
rm -f "${USER_CONFIG_FILE}" 2>/dev/null || true
|
||||
[ -f "${S_FILE}.bak" ] && mv -f "${S_FILE}.bak" "${S_FILE}" 2>/dev/null || true
|
||||
echo -e "\033[1;31m*** HardwareID does not match! - Loader can't boot to DSM! You need to reconfigure your Loader - Rebooting to Config Mode! ***\033[0m"
|
||||
writeConfigKey "arc.patch" "false" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "arc.hardwareid" "" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "arc.userid" "" "${USER_CONFIG_FILE}"
|
||||
sleep 5
|
||||
rebootTo "config"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -101,7 +99,6 @@ fi
|
||||
if [ "${DISKINFO}" = "true" ]; then
|
||||
echo -e "\033[1;37mDisks:\033[0m"
|
||||
echo -e "Disks: \033[1;37m$(lsblk -dpno NAME | grep -v "${LOADER_DISK}" | wc -l)\033[0m"
|
||||
echo
|
||||
fi
|
||||
if [ "${HWIDINFO}" = "true" ]; then
|
||||
echo -e "\033[1;37mHardwareID:\033[0m"
|
||||
@@ -153,7 +150,7 @@ ETHM=${ETHM:-${ETHN}}
|
||||
NIC=0
|
||||
for N in ${ETHX}; do
|
||||
MAC=$(readConfigKey "${N}" "${USER_CONFIG_FILE}" 2>/dev/null)
|
||||
[ -z ${MAC} ] && MAC="$(cat /sys/class/net/${N}/address 2>/dev/null)"
|
||||
MAC=${MAC:-$(cat /sys/class/net/${N}/address 2>/dev/null | tr '[:upper:]' '[:lower:]')}
|
||||
CMDLINE["mac$((++NIC))"]="${MAC}"
|
||||
[ ${NIC} -ge ${ETHM} ] && break
|
||||
done
|
||||
@@ -276,6 +273,7 @@ for KEY in "${!CMDLINE[@]}"; do
|
||||
[ -n "${VALUE}" ] && CMDLINE_LINE+="=${VALUE}"
|
||||
done
|
||||
CMDLINE_LINE=$(echo "${CMDLINE_LINE}" | sed 's/^ //') # Remove leading space
|
||||
echo "${CMDLINE_LINE}" >"${PART1_PATH}/cmdline.yml"
|
||||
|
||||
# Boot
|
||||
DIRECTBOOT="$(readConfigKey "directboot" "${USER_CONFIG_FILE}")"
|
||||
@@ -293,14 +291,17 @@ elif [ "${DIRECTBOOT}" = "false" ]; then
|
||||
BOOTIPWAIT="$(readConfigKey "bootipwait" "${USER_CONFIG_FILE}")"
|
||||
[ -z "${BOOTIPWAIT}" ] && BOOTIPWAIT=30
|
||||
IPCON=""
|
||||
echo
|
||||
if [ "${ARCPATCH}" = "true" ]; then
|
||||
echo -e "\033[1;37mDetected ${ETHN} NIC\033[0m | \033[1;34mUsing ${NIC} NIC for Arc Patch:\033[0m"
|
||||
else
|
||||
echo -e "\033[1;37mDetected ${ETHN} NIC:\033[0m"
|
||||
fi
|
||||
echo
|
||||
|
||||
[ ! -f /var/run/dhcpcd/pid ] && /etc/init.d/S09dhcpcd restart >/dev/null 2>&1 && sleep 3 || true
|
||||
checkNIC || true
|
||||
[ ! -f /var/run/dhcpcd/pid ] && /etc/init.d/S09dhcpcd restart >/dev/null 2>&1 || true
|
||||
sleep 3
|
||||
checkNIC
|
||||
echo
|
||||
|
||||
DSMLOGO="$(readConfigKey "bootscreen.dsmlogo" "${USER_CONFIG_FILE}")"
|
||||
@@ -321,13 +322,22 @@ elif [ "${DIRECTBOOT}" = "false" ]; then
|
||||
fi
|
||||
done
|
||||
|
||||
# # Unload all network interfaces
|
||||
# for D in $(realpath /sys/class/net/*/device/driver); do rmmod -f "$(basename ${D})" 2>/dev/null || true; done
|
||||
|
||||
# Unload all graphics drivers
|
||||
# for D in $(lsmod | grep -E '^(nouveau|amdgpu|radeon|i915)' | awk '{print $1}'); do rmmod -f "${D}" 2>/dev/null || true; done
|
||||
# for I in $(find /sys/devices -name uevent -exec bash -c 'cat {} 2>/dev/null | grep -Eq "PCI_CLASS=0?30[0|1|2]00" && dirname {}' \;); do
|
||||
# [ -e ${I}/reset ] && cat ${I}/vendor >/dev/null | grep -iq 0x10de && echo 1 >${I}/reset || true # Proc open nvidia driver when booting
|
||||
# done
|
||||
|
||||
echo -e "\033[1;37mLoading DSM Kernel...\033[0m"
|
||||
KEXECARGS="kexecboot"
|
||||
if [ ${EFI} -eq 0 ]; then
|
||||
KEXECARGS="-a"
|
||||
if [ $(echo "${KVER:-4}" | cut -d'.' -f1) -lt 4 ] && [ ${EFI} -eq 1 ]; then
|
||||
echo -e "\033[1;33mWarning, running kexec with --noefi param, strange things will happen!!\033[0m"
|
||||
KEXECARGS+=" --noefi"
|
||||
fi
|
||||
|
||||
kexec -l "${MOD_ZIMAGE_FILE}" --initrd "${MOD_RDGZ_FILE}" --command-line="${CMDLINE_LINE} ${KEXECARGS}" >"${PART1_PATH}/cmdline.yml" || die "Failed to load DSM Kernel!"
|
||||
kexec ${KEXECARGS} -l "${MOD_ZIMAGE_FILE}" --initrd "${MOD_RDGZ_FILE}" --command-line="${CMDLINE_LINE} kexecboot" >"${LOG_FILE}" 2>&1 || dieLog
|
||||
|
||||
echo -e "\033[1;37mBooting DSM...\033[0m"
|
||||
[ "${KERNELLOAD}" = "kexec" ] && kexec -e || poweroff
|
||||
|
||||
@@ -91,7 +91,7 @@ function advancedMenu() {
|
||||
write_menu "8" "\Z1Show Loader Options\Zn"
|
||||
fi
|
||||
|
||||
dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Easy UI Advanced" --colors \
|
||||
dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Evo UI Advanced" --colors \
|
||||
--cancel-label "Back" \
|
||||
--menu "" 0 0 0 --file "${TMP_PATH}/menu" \
|
||||
2>"${TMP_PATH}/resp"
|
||||
@@ -229,7 +229,7 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
fi
|
||||
|
||||
if [ "${PLATFORM}" = "epyc7002" ]; then
|
||||
CPUINFO="$(cat /proc/cpuinfo | grep MHz | wc -l)"
|
||||
CPUINFO="$(cat /proc/cpuinfo | wc -l)"
|
||||
if [ ${CPUINFO} -gt 24 ]; then
|
||||
write_menu "=" "Custom Kernel should be used for this CPU"
|
||||
fi
|
||||
@@ -286,8 +286,8 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
else
|
||||
WEBCONFIG=""
|
||||
fi
|
||||
dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Easy UI" --colors \
|
||||
--cancel-label "Advanced UI" --help-button --help-label "Exit" \
|
||||
dialog --clear --default-item ${NEXT} --backtitle "$(backtitle)" --title "Evo UI" --colors \
|
||||
--cancel-label "Classic" --help-button --help-label "Exit" \
|
||||
--extra-button --extra-label "${EXTRA_LABEL}" \
|
||||
--menu "${WEBCONFIG}" 0 0 0 --file "${TMP_PATH}/menu" \
|
||||
2>"${TMP_PATH}/resp"
|
||||
@@ -379,9 +379,7 @@ elif [ "${ARCMODE}" = "config" ]; then
|
||||
esac
|
||||
done
|
||||
else
|
||||
echo "Unknown Mode: ${ARCMODE} - Rebooting to Config Mode"
|
||||
sleep 3
|
||||
rebootTo config
|
||||
echo "Unknown Mode: ${ARCMODE} - Exiting..."
|
||||
fi
|
||||
|
||||
# Inform user
|
||||
|
||||
@@ -67,10 +67,14 @@ function installAddon() {
|
||||
fi
|
||||
local ADDON="${1}"
|
||||
mkdir -p "${TMP_PATH}/${ADDON}"
|
||||
local HAS_FILES=0
|
||||
# First check generic files
|
||||
if [ -f "${ADDONS_PATH}/${ADDON}/all.tgz" ]; then
|
||||
tar -zxf "${ADDONS_PATH}/${ADDON}/all.tgz" -C "${TMP_PATH}/${ADDON}"
|
||||
HAS_FILES=1
|
||||
fi
|
||||
# If has files to copy, copy it, else return error
|
||||
[ ${HAS_FILES} -ne 1 ] && return 1
|
||||
cp -f "${TMP_PATH}/${ADDON}/install.sh" "${RAMDISK_PATH}/addons/${ADDON}.sh" 2>"${LOG_FILE}"
|
||||
chmod +x "${RAMDISK_PATH}/addons/${ADDON}.sh"
|
||||
[ -d ${TMP_PATH}/${ADDON}/root ] && (cp -rnf "${TMP_PATH}/${ADDON}/root/"* "${RAMDISK_PATH}/" 2>"${LOG_FILE}")
|
||||
|
||||
@@ -14,7 +14,7 @@ arc_mode || die "No bootmode found!"
|
||||
[ -f "${USER_CONFIG_FILE}" ] && sed -i "s/'/\"/g" "${USER_CONFIG_FILE}" >/dev/null 2>&1 || true
|
||||
|
||||
BUS=$(getBus "${LOADER_DISK}")
|
||||
[ -d /sys/firmware/efi ] && EFI="1" || EFI="0"
|
||||
EFI=$([ -d /sys/firmware/efi ] && echo 1 || echo 0)
|
||||
|
||||
# Print Title centralized
|
||||
clear
|
||||
@@ -131,15 +131,15 @@ elif ! echo "${BUSLIST}" | grep -wq "${BUS}"; then
|
||||
die "$(printf "The boot disk does not support the current %s, only %s are supported." "${BUS}" "${BUSLIST// /\/}")"
|
||||
fi
|
||||
|
||||
# Save variables to user config file
|
||||
writeConfigKey "vid" "${VID}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "pid" "${PID}" "${USER_CONFIG_FILE}"
|
||||
|
||||
# Inform user and check bus
|
||||
echo -e "Loader Disk: \033[1;34m${LOADER_DISK}\033[0m"
|
||||
echo -e "Loader Disk Type: \033[1;34m${BUS}\033[0m"
|
||||
echo
|
||||
|
||||
# Save variables to user config file
|
||||
writeConfigKey "vid" "${VID}" "${USER_CONFIG_FILE}"
|
||||
writeConfigKey "pid" "${PID}" "${USER_CONFIG_FILE}"
|
||||
|
||||
# Decide if boot automatically
|
||||
BUILDDONE="$(readConfigKey "arc.builddone" "${USER_CONFIG_FILE}")"
|
||||
if [ "${ARCMODE}" = "config" ]; then
|
||||
@@ -158,11 +158,12 @@ echo
|
||||
|
||||
BOOTIPWAIT="$(readConfigKey "bootipwait" "${USER_CONFIG_FILE}")"
|
||||
[ -z "${BOOTIPWAIT}" ] && BOOTIPWAIT=30
|
||||
IPCON=""
|
||||
echo -e "\033[1;37mDetected ${ETHN} NIC:\033[0m"
|
||||
echo
|
||||
|
||||
[ ! -f /var/run/dhcpcd/pid ] && /etc/init.d/S09dhcpcd restart >/dev/null 2>&1 && sleep 3 || true
|
||||
echo -e "\033[1;37mDetected ${ETHN} NIC:\033[0m"
|
||||
IPCON=""
|
||||
echo
|
||||
[ ! -f /var/run/dhcpcd/pid ] && /etc/init.d/S09dhcpcd restart >/dev/null 2>&1 || true
|
||||
sleep 3
|
||||
checkNIC
|
||||
echo
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ RD_COMPRESSED="$(readConfigKey "rd-compressed" "${USER_CONFIG_FILE}")"
|
||||
PRODUCTVER="$(readConfigKey "productver" "${USER_CONFIG_FILE}")"
|
||||
BUILDNUM="$(readConfigKey "buildnum" "${USER_CONFIG_FILE}")"
|
||||
SMALLNUM="$(readConfigKey "smallnum" "${USER_CONFIG_FILE}")"
|
||||
ARCBRANCH="$(readConfigKey "arc.branch" "${USER_CONFIG_FILE}")"
|
||||
# Read new PAT Info from Config
|
||||
PAT_URL="$(readConfigKey "paturl" "${USER_CONFIG_FILE}")"
|
||||
PAT_HASH="$(readConfigKey "pathash" "${USER_CONFIG_FILE}")"
|
||||
@@ -116,16 +117,6 @@ for PATCH in "${PATCHES[@]}"; do
|
||||
done
|
||||
done
|
||||
|
||||
# Add serial number to synoinfo.conf, to help to recovery a installed DSM
|
||||
echo "Set synoinfo SN" >"${LOG_FILE}"
|
||||
_set_conf_kv "SN" "${SN}" "${RAMDISK_PATH}/etc/synoinfo.conf" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
_set_conf_kv "SN" "${SN}" "${RAMDISK_PATH}/etc.defaults/synoinfo.conf" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
for KEY in "${!SYNOINFO[@]}"; do
|
||||
echo "Set synoinfo ${KEY}" >>"${LOG_FILE}"
|
||||
_set_conf_kv "${KEY}" "${SYNOINFO[${KEY}]}" "${RAMDISK_PATH}/etc/synoinfo.conf" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
_set_conf_kv "${KEY}" "${SYNOINFO[${KEY}]}" "${RAMDISK_PATH}/etc.defaults/synoinfo.conf" >>"${LOG_FILE}" 2>&1 || exit 1
|
||||
done
|
||||
|
||||
# Patch /sbin/init.post
|
||||
grep -v -e '^[\t ]*#' -e '^$' "${PATCH_PATH}/config-manipulators.sh" >"${TMP_PATH}/rp.txt"
|
||||
sed -e "/@@@CONFIG-MANIPULATORS-TOOLS@@@/ {" -e "r ${TMP_PATH}/rp.txt" -e 'd' -e '}' -i "${RAMDISK_PATH}/sbin/init.post"
|
||||
@@ -161,7 +152,7 @@ mkdir -p "${RAMDISK_PATH}/addons"
|
||||
echo "export LOADERLABEL=\"ARC\""
|
||||
echo "export LOADERVERSION=\"${ARC_VERSION}\""
|
||||
echo "export LOADERBUILD=\"${ARC_BUILD}\""
|
||||
echo "export LOADERBRANCH=\"${ARC_BRANCH}\""
|
||||
echo "export LOADERBRANCH=\"${ARCBRANCH}\""
|
||||
echo "export PLATFORM=\"${PLATFORM}\""
|
||||
echo "export MODEL=\"${MODEL}\""
|
||||
echo "export MODELID=\"${MODELID}\""
|
||||
@@ -173,20 +164,12 @@ mkdir -p "${RAMDISK_PATH}/addons"
|
||||
} >"${RAMDISK_PATH}/addons/addons.sh"
|
||||
chmod +x "${RAMDISK_PATH}/addons/addons.sh"
|
||||
|
||||
# Add redpill Addon if Platform is epyc7002
|
||||
if [ "${PLATFORM}" = "epyc7002" ]; then
|
||||
installAddon "redpill" "${PLATFORM}" || exit 1
|
||||
echo "/addons/redpill.sh \${1}" >>"${RAMDISK_PATH}/addons/addons.sh" 2>>"${LOG_FILE}" || exit 1
|
||||
fi
|
||||
|
||||
# System Addons
|
||||
for ADDON in "revert" "misc" "eudev" "disks" "localrss" "notify" "wol" "mountloader"; do
|
||||
for ADDON in redpill revert misc eudev disks localrss notify wol mountloader; do
|
||||
PARAMS=""
|
||||
if [ "${ADDON}" = "disks" ]; then
|
||||
HDDSORT="$(readConfigKey "hddsort" "${USER_CONFIG_FILE}")"
|
||||
if [ -n "${HDDSORT}" ]; then
|
||||
PARAMS="${HDDSORT}"
|
||||
fi
|
||||
PARAMS="${HDDSORT}"
|
||||
[ -f "${USER_UP_PATH}/${MODEL}.dts" ] && cp -f "${USER_UP_PATH}/${MODEL}.dts" "${RAMDISK_PATH}/addons/model.dts"
|
||||
fi
|
||||
installAddon "${ADDON}" "${PLATFORM}" || exit 1
|
||||
@@ -204,6 +187,8 @@ done
|
||||
echo "inetd" >>"${RAMDISK_PATH}/addons/addons.sh"
|
||||
|
||||
echo "Modify files" >"${LOG_FILE}"
|
||||
# Remove function from scripts
|
||||
[ "2" = "${PRODUCTVER:2:1}" ] && sed -i 's/function //g' $(find "${RAMDISK_PATH}/addons/" -type f -name "*.sh")
|
||||
|
||||
# Build modules dependencies
|
||||
# ${ARC_PATH}/depmod -a -b ${RAMDISK_PATH} 2>/dev/null
|
||||
|
||||
@@ -104,7 +104,7 @@ if [ -s /zImage-dsm -a -s /initrd-dsm ]; then
|
||||
menuentry 'Arc DSM Mode' ${menuentry_id_option} boot {
|
||||
gfxmode
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE}
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline}
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
@@ -119,7 +119,7 @@ if [ -e /automated ]; then
|
||||
menuentry 'Arc Automated Mode' ${menuentry_id_option} automated {
|
||||
gfxmode
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} automated_arc
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} automated_arc
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
@@ -133,7 +133,7 @@ fi
|
||||
menuentry 'Arc Config Mode' ${menuentry_id_option} config {
|
||||
gfxmode
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} force_arc
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} force_arc
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
@@ -147,7 +147,7 @@ if [ -s /zImage-dsm -a -s /initrd-dsm ]; then
|
||||
menuentry 'Arc Update Mode' ${menuentry_id_option} update {
|
||||
gfxmode
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} update_arc
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} update_arc
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
@@ -159,7 +159,7 @@ if [ -s /zImage-dsm -a -s /initrd-dsm ]; then
|
||||
menuentry 'DSM Recovery Mode' ${menuentry_id_option} recovery {
|
||||
gfxmode
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} recovery
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} recovery
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
@@ -171,7 +171,7 @@ if [ -s /zImage-dsm -a -s /initrd-dsm ]; then
|
||||
menuentry 'DSM Reinstall Mode' ${menuentry_id_option} junior {
|
||||
gfxmode
|
||||
echo "Loading Arc Kernel..."
|
||||
linux /bzImage-arc ${ARC_CMDLINE} force_junior
|
||||
linux /bzImage-arc ${ARC_CMDLINE} ${arc_cmdline} force_junior
|
||||
echo "Loading Arc Initramfs..."
|
||||
if [ -e /initrd-user ]; then
|
||||
initrd /initrd-arc /initrd-user
|
||||
|
||||
@@ -6,62 +6,42 @@
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
import os, click
|
||||
|
||||
WORK_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
import os, re, sys, glob, json, yaml, click, shutil, tarfile, kmodule, requests, urllib3
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
from openpyxl import Workbook
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
"""
|
||||
The CLI is a commands to Arc.
|
||||
The CLI is a commands to ARC.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def mutually_exclusive_options(ctx, param, value):
|
||||
other_option = "file" if param.name == "data" else "data"
|
||||
if value is not None and ctx.params.get(other_option) is not None:
|
||||
raise click.UsageError(f"Illegal usage: `{param.name}` is mutually exclusive with `{other_option}`.")
|
||||
return value
|
||||
|
||||
|
||||
def validate_required_param(ctx, param, value):
|
||||
if not value and "file" not in ctx.params and "data" not in ctx.params:
|
||||
raise click.MissingParameter(param_decls=[param.name])
|
||||
return value
|
||||
|
||||
def __fullversion(ver):
|
||||
out = ver
|
||||
arr = ver.split('-')
|
||||
if len(arr) > 0:
|
||||
a = arr[0].split('.')[0] if len(arr[0].split('.')) > 0 else '0'
|
||||
b = arr[0].split('.')[1] if len(arr[0].split('.')) > 1 else '0'
|
||||
c = arr[0].split('.')[2] if len(arr[0].split('.')) > 2 else '0'
|
||||
d = arr[1] if len(arr) > 1 else '00000'
|
||||
e = arr[2] if len(arr) > 2 else '0'
|
||||
out = '{}.{}.{}-{}-{}'.format(a,b,c,d,e)
|
||||
return out
|
||||
|
||||
@cli.command()
|
||||
@click.option("-p", "--platforms", type=str, help="The platforms of Syno.")
|
||||
def getmodels(platforms=None):
|
||||
"""
|
||||
Get Syno Models.
|
||||
"""
|
||||
import re, json, requests, urllib3
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
@click.option("-w", "--workpath", type=str, required=True, help="The workpath of ARC.")
|
||||
@click.option("-j", "--jsonpath", type=str, required=True, help="The output path of jsonfile.")
|
||||
def getmodels(workpath, jsonpath):
|
||||
models = {}
|
||||
platforms_yml = os.path.join(workpath, "mnt", "p3", "configs", "platforms.yml")
|
||||
with open(platforms_yml, "r") as f:
|
||||
P_data = yaml.safe_load(f)
|
||||
P_platforms = P_data.get("platforms", [])
|
||||
for P in P_platforms:
|
||||
productvers = {}
|
||||
for V in P_platforms[P]["productvers"]:
|
||||
kpre = P_platforms[P]["productvers"][V].get("kpre", "")
|
||||
kver = P_platforms[P]["productvers"][V].get("kver", "")
|
||||
productvers[V] = f"{kpre}-{kver}" if kpre else kver
|
||||
models[P] = {"productvers": productvers, "models": []}
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
PS = platforms.lower().replace(",", " ").split() if platforms else []
|
||||
|
||||
models = []
|
||||
|
||||
try:
|
||||
url = "http://update7.synology.com/autoupdate/genRSS.php?include_beta=1"
|
||||
#url = "https://update7.synology.com/autoupdate/genRSS.php?include_beta=1"
|
||||
@@ -69,42 +49,76 @@ def getmodels(platforms=None):
|
||||
req = session.get(url, timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
p = re.compile(r"<mUnique>(.*?)</mUnique>.*?<mLink>(.*?)</mLink>", re.MULTILINE | re.DOTALL)
|
||||
|
||||
data = p.findall(req.text)
|
||||
for item in data:
|
||||
if not "DSM" in item[1]:
|
||||
continue
|
||||
arch = item[0].split("_")[1]
|
||||
name = item[1].split("/")[-1].split("_")[1].replace("%2B", "+")
|
||||
if PS and arch.lower() not in PS:
|
||||
continue
|
||||
if not any(m["name"] == name for m in models):
|
||||
models.append({"name": name, "arch": arch})
|
||||
|
||||
models.sort(key=lambda k: (k["arch"], k["name"]))
|
||||
|
||||
except Exception as e:
|
||||
# click.echo(f"Error: {e}")
|
||||
pass
|
||||
click.echo(f"Error: {e}")
|
||||
return
|
||||
|
||||
print(json.dumps(models, indent=4))
|
||||
for item in data:
|
||||
if not "DSM" in item[1]:
|
||||
continue
|
||||
arch = item[0].split("_")[1]
|
||||
name = item[1].split("/")[-1].split("_")[1].replace("%2B", "+")
|
||||
if arch not in models:
|
||||
continue
|
||||
if name in (A for B in models for A in models[B]["models"]):
|
||||
continue
|
||||
models[arch]["models"].append(name)
|
||||
|
||||
if jsonpath:
|
||||
with open(jsonpath, "w") as f:
|
||||
json.dump(models, f, indent=4, ensure_ascii=False)
|
||||
|
||||
@cli.command()
|
||||
@click.option("-m", "--model", type=str, required=True, help="The model of Syno.")
|
||||
@click.option("-v", "--version", type=str, required=True, help="The version of Syno.")
|
||||
def getpats4mv(model, version):
|
||||
import json, requests, urllib3
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
@click.option("-w", "--workpath", type=str, required=True, help="The workpath of ARC.")
|
||||
@click.option("-j", "--jsonpath", type=str, required=True, help="The output path of jsonfile.")
|
||||
def getpats(workpath, jsonpath):
|
||||
def __fullversion(ver):
|
||||
arr = ver.split('-')
|
||||
a, b, c = (arr[0].split('.') + ['0', '0', '0'])[:3]
|
||||
d = arr[1] if len(arr) > 1 else '00000'
|
||||
e = arr[2] if len(arr) > 2 else '0'
|
||||
return f'{a}.{b}.{c}-{d}-{e}'
|
||||
|
||||
platforms_yml = os.path.join(workpath, "mnt", "p3", "configs", "platforms.yml")
|
||||
with open(platforms_yml, "r") as f:
|
||||
data = yaml.safe_load(f)
|
||||
platforms = data.get("platforms", [])
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
try:
|
||||
url = "http://update7.synology.com/autoupdate/genRSS.php?include_beta=1"
|
||||
#url = "https://update7.synology.com/autoupdate/genRSS.php?include_beta=1"
|
||||
|
||||
req = session.get(url, timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
p = re.compile(r"<mUnique>(.*?)</mUnique>.*?<mLink>(.*?)</mLink>", re.MULTILINE | re.DOTALL)
|
||||
data = p.findall(req.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
return
|
||||
|
||||
models = []
|
||||
for item in data:
|
||||
if not "DSM" in item[1]:
|
||||
continue
|
||||
arch = item[0].split("_")[1]
|
||||
name = item[1].split("/")[-1].split("_")[1].replace("%2B", "+")
|
||||
if arch not in platforms:
|
||||
continue
|
||||
if name in models:
|
||||
continue
|
||||
models.append(name)
|
||||
|
||||
pats = {}
|
||||
try:
|
||||
for M in models:
|
||||
pats[M] = {}
|
||||
version = '7'
|
||||
urlInfo = "https://www.synology.com/api/support/findDownloadInfo?lang=en-us"
|
||||
urlSteps = "https://www.synology.com/api/support/findUpgradeSteps?"
|
||||
#urlInfo = "https://www.synology.cn/api/support/findDownloadInfo?lang=zh-cn"
|
||||
@@ -112,16 +126,20 @@ def getpats4mv(model, version):
|
||||
|
||||
major = f"&major={version.split('.')[0]}" if len(version.split('.')) > 0 else ""
|
||||
minor = f"&minor={version.split('.')[1]}" if len(version.split('.')) > 1 else ""
|
||||
req = session.get(f"{urlInfo}&product={model.replace('+', '%2B')}{major}{minor}", timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
data = json.loads(req.text)
|
||||
try:
|
||||
req = session.get(f"{urlInfo}&product={M.replace('+', '%2B')}{major}{minor}", timeout=10, verify=False)
|
||||
req.encoding = "utf-8"
|
||||
data = json.loads(req.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
continue
|
||||
|
||||
build_ver = data['info']['system']['detail'][0]['items'][0]['build_ver']
|
||||
build_num = data['info']['system']['detail'][0]['items'][0]['build_num']
|
||||
buildnano = data['info']['system']['detail'][0]['items'][0]['nano']
|
||||
V = __fullversion(f"{build_ver}-{build_num}-{buildnano}")
|
||||
if V not in pats:
|
||||
pats[V] = {
|
||||
if V not in pats[M]:
|
||||
pats[M][V] = {
|
||||
'url': data['info']['system']['detail'][0]['items'][0]['files'][0]['url'].split('?')[0],
|
||||
'sum': data['info']['system']['detail'][0]['items'][0]['files'][0]['checksum']
|
||||
}
|
||||
@@ -134,120 +152,100 @@ def getpats4mv(model, version):
|
||||
if not major or not minor:
|
||||
majorTmp = f"&major={I['version'].split('.')[0]}" if len(I['version'].split('.')) > 0 else ""
|
||||
minorTmp = f"&minor={I['version'].split('.')[1]}" if len(I['version'].split('.')) > 1 else ""
|
||||
reqTmp = session.get(f"{urlInfo}&product={model.replace('+', '%2B')}{majorTmp}{minorTmp}", timeout=10, verify=False)
|
||||
reqTmp.encoding = "utf-8"
|
||||
dataTmp = json.loads(reqTmp.text)
|
||||
try:
|
||||
reqTmp = session.get(f"{urlInfo}&product={M.replace('+', '%2B')}{majorTmp}{minorTmp}", timeout=10, verify=False)
|
||||
reqTmp.encoding = "utf-8"
|
||||
dataTmp = json.loads(reqTmp.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
continue
|
||||
|
||||
build_ver = dataTmp['info']['system']['detail'][0]['items'][0]['build_ver']
|
||||
build_num = dataTmp['info']['system']['detail'][0]['items'][0]['build_num']
|
||||
buildnano = dataTmp['info']['system']['detail'][0]['items'][0]['nano']
|
||||
V = __fullversion(f"{build_ver}-{build_num}-{buildnano}")
|
||||
if V not in pats:
|
||||
pats[V] = {
|
||||
if V not in pats[M]:
|
||||
pats[M][V] = {
|
||||
'url': dataTmp['info']['system']['detail'][0]['items'][0]['files'][0]['url'].split('?')[0],
|
||||
'sum': dataTmp['info']['system']['detail'][0]['items'][0]['files'][0]['checksum']
|
||||
}
|
||||
|
||||
for J in I['versions']:
|
||||
to_ver = J['build']
|
||||
reqSteps = session.get(f"{urlSteps}&product={model.replace('+', '%2B')}&from_ver={from_ver}&to_ver={to_ver}", timeout=10, verify=False)
|
||||
if reqSteps.status_code != 200:
|
||||
try:
|
||||
reqSteps = session.get(f"{urlSteps}&product={M.replace('+', '%2B')}&from_ver={from_ver}&to_ver={to_ver}", timeout=10, verify=False)
|
||||
if reqSteps.status_code != 200:
|
||||
continue
|
||||
reqSteps.encoding = "utf-8"
|
||||
dataSteps = json.loads(reqSteps.text)
|
||||
except Exception as e:
|
||||
click.echo(f"Error: {e}")
|
||||
continue
|
||||
reqSteps.encoding = "utf-8"
|
||||
dataSteps = json.loads(reqSteps.text)
|
||||
|
||||
for S in dataSteps['upgrade_steps']:
|
||||
if not S.get('full_patch') or not S['build_ver'].startswith(version):
|
||||
continue
|
||||
V = __fullversion(f"{S['build_ver']}-{S['build_num']}-{S['nano']}")
|
||||
if V not in pats:
|
||||
pats[V] = {
|
||||
if V not in pats[M]:
|
||||
pats[M][V] = {
|
||||
'url': S['files'][0]['url'].split('?')[0],
|
||||
'sum': S['files'][0]['checksum']
|
||||
}
|
||||
except Exception as e:
|
||||
# click.echo(f"Error: {e}")
|
||||
pass
|
||||
|
||||
pats = {k: pats[k] for k in sorted(pats.keys(), reverse=True)}
|
||||
print(json.dumps(pats, indent=4))
|
||||
if jsonpath:
|
||||
with open(jsonpath, "w") as f:
|
||||
json.dump(pats, f, indent=4, ensure_ascii=False)
|
||||
|
||||
@cli.command()
|
||||
@click.option("-w", "--workpath", type=str, required=True, help="The workpath of ARC.")
|
||||
@click.option("-j", "--jsonpath", type=str, required=True, help="The output path of jsonfile.")
|
||||
def getaddons(workpath, jsonpath):
|
||||
AS = glob.glob(os.path.join(workpath, "mnt", "p3", "addons", "*", "manifest.yml"))
|
||||
AS.sort()
|
||||
addons = {}
|
||||
for A in AS:
|
||||
with open(A, "r") as file:
|
||||
A_data = yaml.safe_load(file)
|
||||
A_name = A_data.get("name", "")
|
||||
A_system = A_data.get("system", False)
|
||||
A_description = A_data.get("description", "")
|
||||
addons[A_name] = {"system": A_system, "description": A_description}
|
||||
if jsonpath:
|
||||
with open(jsonpath, "w") as f:
|
||||
json.dump(addons, f, indent=4, ensure_ascii=False)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-p", "--models", type=str, help="The models of Syno.")
|
||||
def getpats(models=None):
|
||||
import re, json, requests, urllib3
|
||||
from bs4 import BeautifulSoup
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry # type: ignore
|
||||
@click.option("-w", "--workpath", type=str, required=True, help="The workpath of ARC.")
|
||||
@click.option("-j", "--jsonpath", type=str, required=True, help="The output path of jsonfile.")
|
||||
def getmodules(workpath, jsonpath):
|
||||
MS = glob.glob(os.path.join(workpath, "mnt", "p3", "modules", "*.tgz"))
|
||||
MS.sort()
|
||||
modules = {}
|
||||
TMP_PATH = "/tmp/modules"
|
||||
if os.path.exists(TMP_PATH):
|
||||
shutil.rmtree(TMP_PATH)
|
||||
for M in MS:
|
||||
M_name = os.path.splitext(os.path.basename(M))[0]
|
||||
M_modules = {}
|
||||
os.makedirs(TMP_PATH)
|
||||
with tarfile.open(M, "r") as tar:
|
||||
tar.extractall(TMP_PATH)
|
||||
KS = glob.glob(os.path.join(TMP_PATH, "*.ko"))
|
||||
KS.sort()
|
||||
for K in KS:
|
||||
K_name = os.path.splitext(os.path.basename(K))[0]
|
||||
K_info = kmodule.modinfo(K, basedir=os.path.dirname(K), kernel=None)[0]
|
||||
K_description = K_info.get("description", "")
|
||||
K_depends = K_info.get("depends", "")
|
||||
M_modules[K_name] = {"description": K_description, "depends": K_depends}
|
||||
modules[M_name] = M_modules
|
||||
if os.path.exists(TMP_PATH):
|
||||
shutil.rmtree(TMP_PATH)
|
||||
if jsonpath:
|
||||
with open(jsonpath, "w") as file:
|
||||
json.dump(modules, file, indent=4, ensure_ascii=False)
|
||||
|
||||
adapter = HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504]))
|
||||
session = requests.Session()
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
MS = models.lower().replace(",", " ").split() if models else []
|
||||
|
||||
pats = {}
|
||||
try:
|
||||
req = session.get('https://archive.synology.com/download/Os/DSM', timeout=10, verify=False)
|
||||
req.encoding = 'utf-8'
|
||||
bs = BeautifulSoup(req.text, 'html.parser')
|
||||
p = re.compile(r"(.*?)-(.*?)", re.MULTILINE | re.DOTALL)
|
||||
l = bs.find_all('a', string=p)
|
||||
for i in l:
|
||||
ver = i.attrs['href'].split('/')[-1]
|
||||
if not ver.startswith('7'):
|
||||
continue
|
||||
req = session.get(f'https://archive.synology.com{i.attrs["href"]}', timeout=10, verify=False)
|
||||
req.encoding = 'utf-8'
|
||||
bs = BeautifulSoup(req.text, 'html.parser')
|
||||
p = re.compile(r"DSM_(.*?)_(.*?).pat", re.MULTILINE | re.DOTALL)
|
||||
data = bs.find_all('a', string=p)
|
||||
for item in data:
|
||||
rels = p.search(item.attrs['href'])
|
||||
if rels:
|
||||
model, _ = rels.groups()
|
||||
model = model.replace('%2B', '+')
|
||||
if MS and model.lower() not in MS:
|
||||
continue
|
||||
if model not in pats:
|
||||
pats[model] = {}
|
||||
pats[model][__fullversion(ver)] = item.attrs['href']
|
||||
except Exception as e:
|
||||
# click.echo(f"Error: {e}")
|
||||
pass
|
||||
|
||||
print(json.dumps(pats, indent=4))
|
||||
|
||||
@cli.command()
|
||||
@click.option("-p", "--platforms", type=str, help="The platforms of Syno.")
|
||||
def getmodelsoffline(platforms=None):
|
||||
"""
|
||||
Get Syno Models.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
|
||||
PS = platforms.lower().replace(",", " ").split() if platforms else []
|
||||
|
||||
with open(os.path.join('/mnt/p3/configs', "offline.json")) as user_file:
|
||||
data = json.load(user_file)
|
||||
|
||||
models = []
|
||||
for item in data["channel"]["item"]:
|
||||
if not item["title"].startswith("DSM"):
|
||||
continue
|
||||
for model in item["model"]:
|
||||
arch = model["mUnique"].split("_")[1]
|
||||
name = model["mLink"].split("/")[-1].split("_")[1].replace("%2B", "+")
|
||||
if PS and arch.lower() not in PS:
|
||||
continue
|
||||
if not any(m["name"] == name for m in models):
|
||||
models.append({"name": name, "arch": arch})
|
||||
|
||||
models = sorted(models, key=lambda k: (k["arch"], k["name"]))
|
||||
print(json.dumps(models, indent=4))
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
Reference in New Issue
Block a user