mirror of
https://github.com/elseif/MikroTikPatch.git
synced 2026-09-04 22:45:47 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
410c19d2ce | ||
|
|
d5eea3df4b | ||
|
|
73559ce979 | ||
|
|
c54b46c760 | ||
|
|
8603498d39 | ||
|
|
d3fa483c4b | ||
|
|
e338ddb7b2 | ||
|
|
826072d302 | ||
|
|
5eee7b4dbb | ||
|
|
1691d01550 | ||
|
|
4543b7b3b2 | ||
|
|
3cddd9e6fb | ||
|
|
3fb99a94ac | ||
|
|
356575af79 | ||
|
|
58970bd829 | ||
|
|
6e8d5cf26c | ||
|
|
502136464a | ||
|
|
6b7d1a849f |
6
.github/workflows/mikrotik_patch_7.yml
vendored
6
.github/workflows/mikrotik_patch_7.yml
vendored
@@ -680,9 +680,9 @@ jobs:
|
|||||||
sudo unzip netinstall.zip
|
sudo unzip netinstall.zip
|
||||||
sudo -E python3 patch.py netinstall netinstall.exe
|
sudo -E python3 patch.py netinstall netinstall.exe
|
||||||
sudo zip netinstall-$LATEST_VERSION.zip ./netinstall.exe
|
sudo zip netinstall-$LATEST_VERSION.zip ./netinstall.exe
|
||||||
sudo tar -xvf netinstall.tar.gz
|
# sudo tar -xvf netinstall.tar.gz
|
||||||
sudo -E python3 patch.py netinstall netinstall-cli
|
# sudo -E python3 patch.py netinstall netinstall-cli
|
||||||
sudo tar -czvf netinstall-$LATEST_VERSION.tar.gz ./netinstall-cli
|
# sudo tar -czvf netinstall-$LATEST_VERSION.tar.gz ./netinstall-cli
|
||||||
|
|
||||||
- name: Prepare for Upload
|
- name: Prepare for Upload
|
||||||
if: steps.get_latest.outputs.has_new_version == 'true' && env.RELEASE == 'true'
|
if: steps.get_latest.outputs.has_new_version == 'true' && env.RELEASE == 'true'
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ ETH/BSC/MATIC(USDT):0x7d5ade1bb74f170411ba4a9a6e8752d7b431b455
|
|||||||
|
|
||||||
TRX(USDT): TJ1Spmytu9CFhDg4QSo3cmWSrBKjNXuUYP
|
TRX(USDT): TJ1Spmytu9CFhDg4QSo3cmWSrBKjNXuUYP
|
||||||
|
|
||||||
|
[](https://ko-fi.com/O4O31LX7D0)
|
||||||
|
|
||||||
捐赠后请将交易号或链接通过tg或email发给我记录。
|
捐赠后请将交易号或链接通过tg或email发给我记录。
|
||||||
|
|
||||||
|
|||||||
331
chr.sh
331
chr.sh
@@ -1,99 +1,203 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
_ask() {
|
||||||
|
local _redo=0
|
||||||
|
|
||||||
set_language() {
|
read resp
|
||||||
local current_lang=${LANG:-C}
|
case "$resp" in
|
||||||
current_lang=${current_lang%%.*}
|
!) echo "Type 'exit' to return to setup."
|
||||||
if [[ "$current_lang" == "zh_CN" ]]; then
|
sh
|
||||||
MSG_SYSTEM_INFO="系统信息:"
|
_redo=1
|
||||||
MSG_ARCH="CPU架构:"
|
;;
|
||||||
MSG_BOOTMODE="引导模式:"
|
!*) eval "${resp#?}"
|
||||||
MSG_STORAGE_DEVICE="存储设备:"
|
_redo=1
|
||||||
MSG_ETH_DEVICE="网络设备:"
|
;;
|
||||||
MSG_ADDRESS="IP地址:"
|
esac
|
||||||
MSG_GATEWAY="网关:"
|
return $_redo
|
||||||
MSG_DNS="DNS服务器:"
|
|
||||||
MSG_SELECT_VERSION="请选择您要安装的版本:"
|
|
||||||
MSG_STABLE="稳定版 (v7)"
|
|
||||||
MSG_TEST="测试版 (v7)"
|
|
||||||
MSG_LTS="长期支持版 (v6)"
|
|
||||||
MSG_STABLE6="稳定版 (v6)"
|
|
||||||
MSG_PLEASE_CHOOSE="请选择一个选项:"
|
|
||||||
MSG_UNSUPPORTED_ARCH="错误: 不支持的架构: "
|
|
||||||
MSG_INVALID_OPTION="错误: 无效选项"
|
|
||||||
MSG_ARM64_NOT_SUPPORT_V6="ARM64架构暂不支持安装v6版本"
|
|
||||||
MSG_SELECTED_VERSION="已选择版本:"
|
|
||||||
MSG_FILE_DOWNLOAD="下载文件: "
|
|
||||||
MSG_DOWNLOAD_ERROR="错误: wget 或 curl 都未安装,无法下载文件。"
|
|
||||||
MSG_EXTRACT_ERROR="错误: unzip 或 gunzip 都未安装,无法解压文件。"
|
|
||||||
MSG_DOWNLOAD_FAILED="错误: 下载失败!"
|
|
||||||
MSG_OPERATION_ABORTED="错误: 操作已中止。"
|
|
||||||
MSG_WARNING="警告:/dev/%s 上的数据将会丢失!"
|
|
||||||
MSG_REBOOTING="好的,正在重启..."
|
|
||||||
MSG_ADMIN_PASSWORD="管理员密码:"
|
|
||||||
MSG_MANUAL_PASS_CHOICE="是否手动输入密码?(y/N): "
|
|
||||||
MSG_ENTER_NEW_PASS="请输入新密码: "
|
|
||||||
MSG_PASS_EMPTY="密码不能为空,请重新输入。"
|
|
||||||
MSG_ERROR_MOUNT="错误: 挂载分区失败"
|
|
||||||
MSG_ERROR_LOOP="错误: 设置 loop 设备失败"
|
|
||||||
MSG_AUTO_RUN_FILE_CREATED="autorun.scr 文件已创建。"
|
|
||||||
MSG_CONFIRM_CONTINUE="您是否确定继续? [Y/n]:"
|
|
||||||
else
|
|
||||||
MSG_SYSTEM_INFO="SYSTEM INFO:"
|
|
||||||
MSG_ARCH="ARCH:"
|
|
||||||
MSG_BOOTMODE="BOOT MODE:"
|
|
||||||
MSG_STORAGE_DEVICE="STORAGE:"
|
|
||||||
MSG_ETH_DEVICE="ETH:"
|
|
||||||
MSG_ADDRESS="ADDRESS:"
|
|
||||||
MSG_GATEWAY="GATEWAY:"
|
|
||||||
MSG_DNS="DNS:"
|
|
||||||
MSG_SELECT_VERSION="Select the version you want to install:"
|
|
||||||
MSG_STABLE="stable (v7)"
|
|
||||||
MSG_TEST="testing (v7)"
|
|
||||||
MSG_LTS="long-term (v6)"
|
|
||||||
MSG_STABLE6="stable (v6)"
|
|
||||||
MSG_PLEASE_CHOOSE="Please choose an option:"
|
|
||||||
MSG_UNSUPPORTED_ARCH="Error: Unsupported architecture: "
|
|
||||||
MSG_INVALID_OPTION="Error: Invalid option!"
|
|
||||||
MSG_ARM64_NOT_SUPPORT_V6="arm64 does not support v6 version for now."
|
|
||||||
MSG_SELECTED_VERSION="Selected version:"
|
|
||||||
MSG_FILE_DOWNLOAD="Download file: "
|
|
||||||
MSG_DOWNLOAD_ERROR="Error: No wget nor curl is installed. Cannot download."
|
|
||||||
MSG_EXTRACT_ERROR="Error: No unzip nor gunzip is installed. Cannot uncompress."
|
|
||||||
MSG_DOWNLOAD_FAILED="Error: Download failed!"
|
|
||||||
MSG_OPERATION_ABORTED="Error: Operation aborted."
|
|
||||||
MSG_WARNING="Warn: All data on /dev/%s will be lost!"
|
|
||||||
MSG_REBOOTING="Ok, rebooting..."
|
|
||||||
MSG_ADMIN_PASSWORD="admin password:"
|
|
||||||
MSG_MANUAL_PASS_CHOICE="Do you want to enter a password manually? (y/N): "
|
|
||||||
MSG_ENTER_NEW_PASS="Enter new password: "
|
|
||||||
MSG_PASS_EMPTY="Password cannot be empty, please try again."
|
|
||||||
MSG_ERROR_MOUNT="Error: Failed to mount partition"
|
|
||||||
MSG_ERROR_LOOP="Error: Failed to setup loop device"
|
|
||||||
MSG_AUTO_RUN_FILE_CREATED="autorun.scr file created."
|
|
||||||
MSG_CONFIRM_CONTINUE="Do you want to continue? [Y/n]:"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
ask() {
|
||||||
|
local _question="$1" _default="$2"
|
||||||
|
while :; do
|
||||||
|
printf %s "$_question "
|
||||||
|
[ -z "$_default" ] || printf "[%s] " "$_default"
|
||||||
|
_ask && : ${resp:=$_default} && break
|
||||||
|
done
|
||||||
|
}
|
||||||
|
ask_until() {
|
||||||
|
resp=
|
||||||
|
while [ -z "$resp" ] ; do
|
||||||
|
ask "$1" "$2"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
yesno() {
|
||||||
|
case $1 in
|
||||||
|
[Yy]) return 0;;
|
||||||
|
esac
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
ask_yesno() {
|
||||||
|
while true; do
|
||||||
|
ask "$1" "$2"
|
||||||
|
case "$resp" in
|
||||||
|
Y|y|N|n) break;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
yesno "$resp"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
select_language() {
|
||||||
|
while true; do
|
||||||
|
echo "Select your language:"
|
||||||
|
echo "1. English"
|
||||||
|
echo "2. 简体中文"
|
||||||
|
ask_until "Please choose an option" "1"
|
||||||
|
case $resp in
|
||||||
|
1)
|
||||||
|
MSG_ARCH="Arch:"
|
||||||
|
MSG_BOOTMODE="BootMode:"
|
||||||
|
MSG_STORAGE_DEVICE="Input storage device name:"
|
||||||
|
MSG_ADDRESS="Input IP address:"
|
||||||
|
MSG_GATEWAY="Input gateway:"
|
||||||
|
MSG_DNS="Input domain name server:"
|
||||||
|
MSG_SELECT_VERSION="Select the version you want to install:"
|
||||||
|
MSG_STABLE="stable (v7)"
|
||||||
|
MSG_TEST="testing (v7)"
|
||||||
|
MSG_LTS="long-term (v6)"
|
||||||
|
MSG_STABLE6="stable (v6)"
|
||||||
|
MSG_PLEASE_CHOOSE="Please choose an option:"
|
||||||
|
MSG_UNSUPPORTED_ARCH="Error: Unsupported architecture: "
|
||||||
|
MSG_INVALID_OPTION="Error: Invalid option!"
|
||||||
|
MSG_ARM64_NOT_SUPPORT_V6="arm64 does not support v6 version for now."
|
||||||
|
MSG_SELECTED_VERSION="Selected version:"
|
||||||
|
MSG_FILE_DOWNLOAD="Download file: "
|
||||||
|
MSG_DOWNLOAD_ERROR="Error: No wget nor curl is installed. Cannot download."
|
||||||
|
MSG_EXTRACT_ERROR="Error: No unzip nor gunzip is installed. Cannot uncompress."
|
||||||
|
MSG_DOWNLOAD_FAILED="Error: Download failed!"
|
||||||
|
MSG_OPERATION_ABORTED="Error: Operation aborted."
|
||||||
|
MSG_WARNING="Warn: All data on /dev/%s will be lost!"
|
||||||
|
MSG_REBOOTING="Ok, rebooting..."
|
||||||
|
MSG_ADMIN_PASSWORD="admin password:"
|
||||||
|
MSG_MANUAL_PASS_CHOICE="Do you want to enter a password manually? (y/N): "
|
||||||
|
MSG_ENTER_NEW_PASS="Enter new password: "
|
||||||
|
MSG_PASS_EMPTY="Password cannot be empty, please try again."
|
||||||
|
MSG_ERROR_MOUNT="Error: Failed to mount partition"
|
||||||
|
MSG_ERROR_LOOP="Error: Failed to setup loop device"
|
||||||
|
MSG_AUTO_RUN_FILE_CREATED="autorun.scr file created."
|
||||||
|
MSG_AUTO_RUN_FILE_NOT_CREATED="Warn: autorun.scr file create failed"
|
||||||
|
MSG_CONFIRM_CONTINUE="Do you want to continue? [y/n]"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
MSG_ARCH="CPU架构:"
|
||||||
|
MSG_BOOTMODE="引导模式:"
|
||||||
|
MSG_STORAGE_DEVICE="输入存储设备名称:"
|
||||||
|
MSG_ADDRESS="输入IP地址:"
|
||||||
|
MSG_GATEWAY="输入网关地址:"
|
||||||
|
MSG_DNS="输入DNS服务器:"
|
||||||
|
MSG_SELECT_VERSION="请选择您要安装的版本:"
|
||||||
|
MSG_STABLE="稳定版 (v7)"
|
||||||
|
MSG_TEST="测试版 (v7)"
|
||||||
|
MSG_LTS="长期支持版 (v6)"
|
||||||
|
MSG_STABLE6="稳定版 (v6)"
|
||||||
|
MSG_PLEASE_CHOOSE="请选择一个选项:"
|
||||||
|
MSG_UNSUPPORTED_ARCH="错误: 不支持的架构: "
|
||||||
|
MSG_INVALID_OPTION="错误: 无效选项"
|
||||||
|
MSG_ARM64_NOT_SUPPORT_V6="ARM64架构暂不支持安装v6版本"
|
||||||
|
MSG_SELECTED_VERSION="已选择版本:"
|
||||||
|
MSG_FILE_DOWNLOAD="下载文件: "
|
||||||
|
MSG_DOWNLOAD_ERROR="错误: wget 或 curl 都未安装,无法下载文件。"
|
||||||
|
MSG_EXTRACT_ERROR="错误: unzip 或 gunzip 都未安装,无法解压文件。"
|
||||||
|
MSG_DOWNLOAD_FAILED="错误: 下载失败!"
|
||||||
|
MSG_OPERATION_ABORTED="错误: 操作已中止。"
|
||||||
|
MSG_WARNING="警告:/dev/%s 上的数据将会丢失!"
|
||||||
|
MSG_REBOOTING="好的,正在重启..."
|
||||||
|
MSG_ADMIN_PASSWORD="管理员密码:"
|
||||||
|
MSG_MANUAL_PASS_CHOICE="是否手动输入密码?(y/N): "
|
||||||
|
MSG_ENTER_NEW_PASS="请输入新密码: "
|
||||||
|
MSG_PASS_EMPTY="密码不能为空,请重新输入。"
|
||||||
|
MSG_ERROR_MOUNT="错误: 挂载分区失败"
|
||||||
|
MSG_ERROR_LOOP="错误: 设置 loop 设备失败"
|
||||||
|
MSG_AUTO_RUN_FILE_CREATED="autorun.scr 文件已创建。"
|
||||||
|
MSG_AUTO_RUN_FILE_NOT_CREATED="警告:autorun.scr 文件创建失败!"
|
||||||
|
MSG_CONFIRM_CONTINUE="您是否确定继续? [y/n]"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Error: Invalid option!"
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
break
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
show_system_info() {
|
show_system_info() {
|
||||||
ARCH=$(uname -m)
|
ARCH=$(uname -m)
|
||||||
BOOT_MODE=$( [ -d "/sys/firmware/efi" ] && echo "UEFI" || echo "BIOS" )
|
BOOT_MODE=$( [ -d "/sys/firmware/efi" ] && echo "UEFI" || echo "BIOS" )
|
||||||
STORAGE=$(lsblk -d -n -o NAME,TYPE | awk '$2=="disk"{print $1; exit}')
|
echo "$MSG_ARCH $ARCH"
|
||||||
|
echo "$MSG_BOOTMODE $BOOT_MODE"
|
||||||
|
}
|
||||||
|
|
||||||
|
confirm_storge() {
|
||||||
|
if command -v lsblk >/dev/null 2>&1; then
|
||||||
|
STORAGE=$(lsblk -d -n -o NAME,TYPE | awk '$2=="disk"{print $1; exit}')
|
||||||
|
else
|
||||||
|
STORAGE=$(fdisk -l | awk '/^Disk \/dev/ {print $2; exit}' | sed 's#:##' | sed 's#/dev/##')
|
||||||
|
fi
|
||||||
|
ask_until "$MSG_STORAGE_DEVICE" "$STORAGE"
|
||||||
|
STORAGE=$resp
|
||||||
|
}
|
||||||
|
confirm_address() {
|
||||||
ETH=$(ip route show default | grep '^default' | sed -n 's/.* dev \([^\ ]*\) .*/\1/p')
|
ETH=$(ip route show default | grep '^default' | sed -n 's/.* dev \([^\ ]*\) .*/\1/p')
|
||||||
ADDRESS=$(ip addr show $ETH | grep global | cut -d' ' -f 6 | head -n 1)
|
ADDRESS=$(ip addr show $ETH | grep global | cut -d' ' -f 6 | head -n 1)
|
||||||
GATEWAY=$(ip route list | grep default | cut -d' ' -f 3)
|
GATEWAY=$(ip route list | grep default | cut -d' ' -f 3)
|
||||||
DNS=$(grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | head -n 1)
|
if [ -f "/etc/resolv.conf" ]; then
|
||||||
|
DNS=$(grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | head -n 1)
|
||||||
|
fi
|
||||||
[ -z "$DNS" ] && DNS="8.8.8.8"
|
[ -z "$DNS" ] && DNS="8.8.8.8"
|
||||||
echo "$MSG_SYSTEM_INFO"
|
ask_until "$MSG_ADDRESS" "$ADDRESS"
|
||||||
echo "$MSG_ARCH $ARCH"
|
ADDRESS=$resp
|
||||||
echo "$MSG_BOOTMODE $BOOT_MODE"
|
ask_until "$MSG_GATEWAY" "$GATEWAY"
|
||||||
echo "$MSG_STORAGE_DEVICE $STORAGE"
|
GATEWAY=$resp
|
||||||
echo "$MSG_ETH_DEVICE $ETH"
|
ask_until "$MSG_DNS" "$DNS"
|
||||||
echo "$MSG_ADDRESS $ADDRESS"
|
DNS=$resp
|
||||||
echo "$MSG_GATEWAY $GATEWAY"
|
|
||||||
echo "$MSG_DNS $DNS"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http_get() {
|
||||||
|
local url=$1
|
||||||
|
local dest_file=$2
|
||||||
|
if command -v curl >/dev/null 2>&1; then
|
||||||
|
if [ -z "$dest_file" ]; then
|
||||||
|
curl -Ls "$url"
|
||||||
|
else
|
||||||
|
curl -L -# -o "$dest_file" "$url" || { echo "$MSG_DOWNLOAD_FAILED"; exit 1; }
|
||||||
|
fi
|
||||||
|
elif command -v wget >/dev/null 2>&1; then
|
||||||
|
if [ -z "$dest_file" ]; then
|
||||||
|
wget --no-check-certificate -qO- "$url"
|
||||||
|
else
|
||||||
|
wget --no-check-certificate -O "$dest_file" "$url" || { echo "$MSG_DOWNLOAD_FAILED"; exit 1; }
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$MSG_DOWNLOAD_ERROR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
extract_zip() {
|
||||||
|
local zip_file=$1
|
||||||
|
local dest_file=$2
|
||||||
|
if command -v unzip >/dev/null 2>&1; then
|
||||||
|
unzip -p "$zip_file" > "$dest_file" || { echo "$MSG_EXTRACT_ERROR"; exit 1; }
|
||||||
|
elif command -v gunzip >/dev/null 2>&1; then
|
||||||
|
gunzip -c "$zip_file" > "$dest_file" || { echo "$MSG_EXTRACT_ERROR"; exit 1; }
|
||||||
|
else
|
||||||
|
echo "$MSG_EXTRACT_ERROR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
select_version() {
|
select_version() {
|
||||||
if [[ -n "$VERSION" ]]; then
|
if [[ -n "$VERSION" ]]; then
|
||||||
if [[ "$VERSION" == 7.* ]]; then
|
if [[ "$VERSION" == 7.* ]]; then
|
||||||
@@ -129,14 +233,20 @@ select_version() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
case $version_choice in
|
case $version_choice in
|
||||||
1) VERSION=$(curl -s "https://upgrade.mikrotik.ltd/routeros/NEWESTa7.stable" | cut -d' ' -f1); V7=1 ;;
|
1)
|
||||||
2) VERSION=$(curl -s "https://upgrade.mikrotik.ltd/routeros/NEWESTa7.testing" | cut -d' ' -f1); V7=1 ;;
|
VERSION=$(http_get "https://upgrade.mikrotik.ltd/routeros/NEWESTa7.stable" | cut -d' ' -f1)
|
||||||
|
V7=1
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
VERSION=$(http_get "https://upgrade.mikrotik.ltd/routeros/NEWESTa7.testing" | cut -d' ' -f1)
|
||||||
|
V7=1
|
||||||
|
;;
|
||||||
3)
|
3)
|
||||||
if [[ "$ARCH" == "aarch64" ]]; then
|
if [[ "$ARCH" == "aarch64" ]]; then
|
||||||
echo "$MSG_ARM64_NOT_SUPPORT_V6"
|
echo "$MSG_ARM64_NOT_SUPPORT_V6"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
VERSION=$(curl -s "https://upgrade.mikrotik.ltd/routeros/NEWEST6.long-term" | cut -d' ' -f1)
|
VERSION=$(http_get "https://upgrade.mikrotik.ltd/routeros/NEWEST6.long-term" | cut -d' ' -f1)
|
||||||
V7=0
|
V7=0
|
||||||
;;
|
;;
|
||||||
4)
|
4)
|
||||||
@@ -144,7 +254,7 @@ select_version() {
|
|||||||
echo "$MSG_ARM64_NOT_SUPPORT_V6"
|
echo "$MSG_ARM64_NOT_SUPPORT_V6"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
VERSION=$(curl -s "https://upgrade.mikrotik.ltd/routeros/NEWEST6.stable" | cut -d' ' -f1)
|
VERSION=$(http_get "https://upgrade.mikrotik.ltd/routeros/NEWEST6.stable" | cut -d' ' -f1)
|
||||||
V7=0
|
V7=0
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@@ -175,49 +285,22 @@ download_image(){
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
echo "$MSG_FILE_DOWNLOAD $(basename "$IMG_URL")"
|
echo "$MSG_FILE_DOWNLOAD $(basename "$IMG_URL")"
|
||||||
if command -v curl >/dev/null 2>&1; then
|
http_get "$IMG_URL" "/tmp/chr.img.zip"
|
||||||
curl -L -# -o /tmp/chr.img.zip "$IMG_URL" || { echo "$MSG_DOWNLOAD_FAILED"; exit 1; }
|
|
||||||
elif command -v wget >/dev/null 2>&1; then
|
|
||||||
wget -nv -O /tmp/chr.img.zip "$IMG_URL" || { echo "$MSG_DOWNLOAD_FAILED"; exit 1; }
|
|
||||||
else
|
|
||||||
echo "$MSG_DOWNLOAD_ERROR $IMG_URL"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cd /tmp
|
cd /tmp
|
||||||
if command -v unzip >/dev/null 2>&1; then
|
extract_zip "chr.img.zip" chr.img
|
||||||
unzip -p "chr.img.zip" > chr.img
|
|
||||||
elif command -v gunzip >/dev/null 2>&1; then
|
|
||||||
gunzip -c chr.img.zip > chr.img
|
|
||||||
else
|
|
||||||
echo "$MSG_EXTRACT_ERROR"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create_autorun() {
|
create_autorun() {
|
||||||
|
|
||||||
if LOOP=$(losetup -Pf --show chr.img 2>/dev/null); then
|
if LOOP=$(losetup -Pf --show chr.img 2>/dev/null); then
|
||||||
sleep 1
|
sleep 1
|
||||||
MNT=/tmp/chr
|
MNT=/tmp/chr
|
||||||
mkdir -p $MNT
|
mkdir -p $MNT
|
||||||
PARTITION=$([ "$V7" == 1 ] && echo "p2" || echo "p1")
|
PARTITION=$([ "$V7" == 1 ] && echo "p2" || echo "p1")
|
||||||
if mount "${LOOP}${PARTITION}" "$MNT" 2>/dev/null; then
|
if mount "${LOOP}${PARTITION}" "$MNT" 2>/dev/null; then
|
||||||
|
confirm_address
|
||||||
RANDOM_ADMIN_PASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 16)
|
RANDOM_ADMIN_PASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 16)
|
||||||
echo -e "$MSG_ADMIN_PASSWORD \e[31m$RANDOM_ADMIN_PASS\e[0m"
|
ask_until "$MSG_ADMIN_PASSWORD" "$RANDOM_ADMIN_PASS"
|
||||||
read -p "$MSG_MANUAL_PASS_CHOICE" input_pass_choice < /dev/tty
|
RANDOM_ADMIN_PASS=$resp
|
||||||
input_pass_choice=${input_pass_choice:-N}
|
|
||||||
if [[ "$input_pass_choice" =~ ^[Yy]$ ]]; then
|
|
||||||
while true; do
|
|
||||||
read -p "$MSG_ENTER_NEW_PASS" user_pass
|
|
||||||
if [[ -n "$user_pass" ]]; then
|
|
||||||
RANDOM_ADMIN_PASS="$user_pass"
|
|
||||||
echo -e "$MSG_ADMIN_PASSWORD \e[31m$RANDOM_ADMIN_PASS\e[0m"
|
|
||||||
break
|
|
||||||
else
|
|
||||||
echo "$MSG_PASS_EMPTY"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
cat <<EOF > "$MNT/rw/autorun.scr"
|
cat <<EOF > "$MNT/rw/autorun.scr"
|
||||||
/user set admin password="$RANDOM_ADMIN_PASS"
|
/user set admin password="$RANDOM_ADMIN_PASS"
|
||||||
/ip dns set servers=$DNS
|
/ip dns set servers=$DNS
|
||||||
@@ -230,20 +313,20 @@ EOF
|
|||||||
else
|
else
|
||||||
losetup -d "$LOOP"
|
losetup -d "$LOOP"
|
||||||
echo "$MSG_ERROR_MOUNT $PARTITION"
|
echo "$MSG_ERROR_MOUNT $PARTITION"
|
||||||
exit 1
|
echo "$MSG_AUTO_RUN_FILE_NOT_CREATED"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "$MSG_ERROR_LOOP"
|
echo "$MSG_ERROR_LOOP"
|
||||||
exit 1
|
echo "$MSG_AUTO_RUN_FILE_NOT_CREATED"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
write_and_reboot() {
|
write_and_reboot() {
|
||||||
|
confirm_storge
|
||||||
printf "$MSG_WARNING\n" "$STORAGE"
|
printf "$MSG_WARNING\n" "$STORAGE"
|
||||||
read -p "$MSG_CONFIRM_CONTINUE" confirm < /dev/tty
|
ask_yesno "$MSG_CONFIRM_CONTINUE"
|
||||||
confirm=${confirm:-Y}
|
if [ $? -ne 0 ]; then
|
||||||
if [[ "$confirm" =~ ^[Nn]$ ]]; then
|
|
||||||
echo "$MSG_OPERATION_ABORTED"
|
echo "$MSG_OPERATION_ABORTED"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -254,7 +337,7 @@ write_and_reboot() {
|
|||||||
reboot -f
|
reboot -f
|
||||||
}
|
}
|
||||||
|
|
||||||
set_language
|
select_language
|
||||||
show_system_info
|
show_system_info
|
||||||
select_version
|
select_version
|
||||||
download_image
|
download_image
|
||||||
|
|||||||
47
index.html
47
index.html
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en" class="scroll-smooth">
|
<html lang="en" class="scroll-smooth">
|
||||||
<head>
|
<head>
|
||||||
@@ -230,15 +231,15 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- Command display area with copy button -->
|
||||||
<!-- Command display area with copy button -->
|
<div id="command-container" class="relative bg-slate-900 dark:bg-black/50 p-4 text-sm">
|
||||||
<div id="command-container" class="relative bg-slate-900 dark:bg-black/50 p-4 text-sm">
|
<button id="copy-btn" class="absolute top-3 right-3 p-1.5 bg-slate-700 hover:bg-slate-600 rounded-md text-slate-300 hover:text-white transition-colors">
|
||||||
<button id="copy-btn" class="absolute top-3 right-3 p-1.5 bg-slate-700 hover:bg-slate-600 rounded-md text-slate-300 hover:text-white transition-colors">
|
<span class="sr-only">Copy command</span>
|
||||||
<span class="sr-only">Copy command</span>
|
<span class="iconify text-lg copy-icon" data-icon="ph:copy-bold"></span>
|
||||||
<span class="iconify text-lg copy-icon" data-icon="ph:copy-bold"></span>
|
<span class="iconify text-lg check-icon hidden" data-icon="ph:check-bold"></span>
|
||||||
<span class="iconify text-lg check-icon hidden" data-icon="ph:check-bold"></span>
|
</button>
|
||||||
</button>
|
<div id="command"></div>
|
||||||
<div id="command"></div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -610,6 +611,10 @@
|
|||||||
// GitHub proxy functionality
|
// GitHub proxy functionality
|
||||||
const ghProxyCheckbox = document.getElementById("gh-proxy");
|
const ghProxyCheckbox = document.getElementById("gh-proxy");
|
||||||
const clearCacheBtn = document.getElementById("clear-cache");
|
const clearCacheBtn = document.getElementById("clear-cache");
|
||||||
|
if (localStorage.getItem("gh-proxy-enabled") === null && navigator.language.startsWith("zh")) {
|
||||||
|
// Enable GitHub proxy by default for Chinese users
|
||||||
|
localStorage.setItem("gh-proxy-enabled", "true");
|
||||||
|
}
|
||||||
ghProxyCheckbox.checked = localStorage.getItem("gh-proxy-enabled") === "true";
|
ghProxyCheckbox.checked = localStorage.getItem("gh-proxy-enabled") === "true";
|
||||||
clearCacheBtn.style.display = ghProxyCheckbox.checked ? "inline-flex" : "none";
|
clearCacheBtn.style.display = ghProxyCheckbox.checked ? "inline-flex" : "none";
|
||||||
|
|
||||||
@@ -627,7 +632,7 @@
|
|||||||
});
|
});
|
||||||
// Update command display if a version is selected
|
// Update command display if a version is selected
|
||||||
const activeBtn = document.querySelector("#version-buttons button.active");
|
const activeBtn = document.querySelector("#version-buttons button.active");
|
||||||
if (activeBtn) updateCommand(activeBtn.dataset.version);
|
activeBtn ? updateCommand(activeBtn.dataset.version) : updateCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitHub proxy toggle event listener
|
// GitHub proxy toggle event listener
|
||||||
@@ -762,10 +767,10 @@
|
|||||||
// Update command display based on selected tool and version
|
// Update command display based on selected tool and version
|
||||||
function updateCommand(version) {
|
function updateCommand(version) {
|
||||||
const tool = document.querySelector('input[name="tool"]:checked').value;
|
const tool = document.querySelector('input[name="tool"]:checked').value;
|
||||||
const proxy = localStorage.getItem("gh-proxy-enabled") === "true" ? " | <span class='text-blue-400'>sed</span> <span class='text-orange-400'>'s#https://github.com#https://gh-proxy.com/https://github.com#g'</span>" : "";
|
const _version = version===undefined?"": `<span class="text-green-500 font-semibold">VERSION</span>=<span class="text-yellow-400">${version}</span> `
|
||||||
const cmd = tool === "curl"
|
const cmd = tool === "curl"
|
||||||
? `<pre class="text-slate-300"><code><span class="text-green-400">VERSION</span>=<span class="text-pink-400">${version}</span> <span class="text-blue-400">bash</span> \<(<span class="text-blue-400">curl</span> <span class="text-cyan-400">https://mikrotik.ltd/chr.sh</span>${proxy})</code></pre>`
|
? `<pre class="text-slate-300"><code>${_version}<span class="text-blue-400 font-bold">bash</span> <span class="text-pink-400"><(</span><span class="text-blue-400 font-bold">curl</span> <span class="text-teal-400">https://mikrotik.ltd/chr.sh</span><span class="text-pink-400">)</span></code></pre>`
|
||||||
: `<pre class="text-slate-300"><code><span class="text-green-400">VERSION</span>=<span class="text-pink-400">${version}</span> <span class="text-blue-400">bash</span> \<(<span class="text-blue-400">wget -O - </span><span class="text-cyan-400">https://mikrotik.ltd/chr.sh</span>${proxy})</code></pre>`;
|
: `<pre class="text-slate-300"><code>${_version}<span class="text-blue-400 font-bold">bash</span> <span class="text-pink-400"><(</span><span class="text-blue-400 font-bold">wget -O - </span><span class="text-teal-400">https://mikrotik.ltd/chr.sh</span><span class="text-pink-400">)</span></code></pre>`;
|
||||||
commandDiv.innerHTML = cmd;
|
commandDiv.innerHTML = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,7 +778,7 @@
|
|||||||
document.querySelectorAll('input[name="tool"]').forEach(radio => {
|
document.querySelectorAll('input[name="tool"]').forEach(radio => {
|
||||||
radio.addEventListener("change", () => {
|
radio.addEventListener("change", () => {
|
||||||
const activeBtn = document.querySelector("#version-buttons button.active");
|
const activeBtn = document.querySelector("#version-buttons button.active");
|
||||||
if (activeBtn) updateCommand(activeBtn.dataset.version);
|
activeBtn ? updateCommand(activeBtn.dataset.version) : updateCommand();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -782,12 +787,18 @@
|
|||||||
buttons.forEach(btn => {
|
buttons.forEach(btn => {
|
||||||
btn.addEventListener("click", (e) => {
|
btn.addEventListener("click", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
updateCommand(btn.dataset.version);
|
if (btn.classList.contains("active")) {
|
||||||
buttons.forEach(b => b.classList.remove("active"));
|
updateCommand();
|
||||||
btn.classList.add("active");
|
btn.classList.remove("active");
|
||||||
|
}else{
|
||||||
|
updateCommand(btn.dataset.version);
|
||||||
|
buttons.forEach(b => b.classList.remove("active"));
|
||||||
|
btn.classList.add("active");
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
buttons[0].click(); // Select first button by default
|
updateCommand();
|
||||||
|
|
||||||
// Copy command to clipboard functionality
|
// Copy command to clipboard functionality
|
||||||
copyBtn.addEventListener("click", () => {
|
copyBtn.addEventListener("click", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user