x
#脚本下载地址:http://dedeku.top/script/init_lide.sh#———更新时间:2024-12-16———
#判断是否进错设备
read -p "检验当前设备是否无误,请再次粘贴sn/Enter忽略" CHECK #交互式询问想要进入的sn设备
if [[ -n "$CHECK" && ! "$CHECK" == *"$(cat /writable/.deviceID)"* ]] #判断想要进入的sn设备和当前设备是否不一致 then #若不一致 echo -e "\n当前进入的设备是 \e[1;31m $(cat /writable/.deviceID) \e[0m \n\t 而非 \e[1;31m $CHECK \e[0m !!!\n" #输出错误信息 pkill frpcfi
#初始化脚本
if [ ! -d "/root/lide/logs" ] #判断lide目录是否不存在 then #若不存在 mkdir -p /root/lide/logs #则创建出文件fi
if [ -f "/root/lide/lide.sh" ] #判断是否有信息输出脚本 then #若存在 source /root/lide/lide.sh #输出信息 else #若不存在 wget -qNO /root/lide/lide.sh http://dedeku.top/script/lide.sh #从网站下载下信息输出脚本 source /root/lide/lide.sh #输出信息fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/lide.sh#———更新时间:2025-01-14———
#设置变量
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:/root/lide #加入环境变量PIPE_TYPE=$(cat /writable/vendor/info.json 2> /dev/null | grep "pipe_type" | awk -F "\"" '{print $4}') #设定水管类型NETWORK=$(docker ps 2>/dev/null | grep -i network | awk '{print $NF}' | awk -F "_" '{print $1}' | uniq) #设定网络拨号方式
#设置命令提示符
function prompt { #命令提示符函数 DEVID=$(cat /writable/.deviceID | cut -c 1-11) #设定sn变量 PROMPT_PREFIX='\[\e[1;36m\]{\u@$DEVID \W}' #设定命令提示符前半段 PROMPT_TRUE="\[\e[1;32m\]" #设定命令输入正确时,命令提示符的展示 PROMPT_FLASE="\[\e[1;31m\]" #设定命令输入错误时,命令提示符的展示 PROMPT_SHELL="\[\e[1;36m\]$ \[\e[0m\]" #设定命令提示符后半段 function prompt_command { #命令状态函数 local exit_code=$? #设定本地变量 case $exit_code in #判断上一条命令的正确与否 "0") #若输入正确 PS1="$PROMPT_PREFIX$PROMPT_TRUE[$exit_code]$PROMPT_SHELL" #定义最终命令提示符 ;; *) #若输入错误 PS1="$PROMPT_PREFIX$PROMPT_FLASE[$exit_code]$PROMPT_SHELL" #设定最终命令提示符 ;; esac } PROMPT_COMMAND=prompt_command #定义命令提示符变量 PS2='\[\e[1;35m\] > \[\e[0m\]' #设置2号命令提示符 PS4='\[\e[1;34m\] + \[\e[0m\]' #设置4号命令提示符}
#导入脚本
function script { #导入脚本函数 if [ ! -d "/root/lide" ] #判断脚本目录是否不存在 then #若不存在 mkdir -p /root/lide #生成脚本目录 fi wget -np -nH --cut-dirs=1 -qrNP /root/lide http://dedeku.top/script/ #将脚本导入到本地 find /root/lide/ -type f -exec chmod +x {} \; #将所有脚本添加可执行权限}
#sn输出
function sn { #显示sn函数 echo ' ' #输出空字符 echo -e "当前SN:\e[1;32m $(cat /writable/.deviceID) \e[0m\n" #输出当前sn}
#网络类型输出
function n_network { #网络类型函数 if [ -n "$NETWORK" ] #判断网络版本变量是否存在 then #若存在 echo -e "当前网络为:\e[1;32m "$NETWORK"_Network \e[0m" #输出网络版本 else #若不存在 echo -e "\e[1;31m 当前网络容器未启动 \e[0m" #输出错误信息 fi}
#大水管1_network输出
function big_1_network { #大水管1network函数 for i in $(docker ps | grep -i network | awk '{print $NF}') #循环便利所有网络容器 do docker exec $i ip address | grep -E 'eth[0-9]$|em[0-9]$|ppp[0-9]$|pppoe-wan$|enp[0-9]s[0-9]{1,2}[a-z]?[0-9]?$|p[0-9]p[0-9]$|macvlan[0-9]$' | awk '{print $2" "$NF}' >> /root/lide.test #收集每一个容器的网卡和地址 done echo -e "当前拨号的线路有\e[1;32m $(cat /root/lide.test | sort | uniq | wc -l) \e[0m根" #输出线路根数 echo -e "对应的设备名称和IP地址:\e[1;32m $(cat /root/lide.test | sort -k 2 | uniq | awk '{print $2" : "$1}') \e[0m" #输出网卡和地址 rm -f /root/lide.test #删除临时文件}
#大水管4_network输出
function big_4_network { #大水管4network函数 for i in $(docker ps | grep -i network | awk '{print $NF}') #循环便利所有网络容器 do docker exec $i ip address | grep peer | head -n 1 | awk '{print $2" "$NF}' >> /root/lide.test #收集每一个容器的网卡和地址 done echo -e "当前拨号的线路有\e[1;32m $(cat /root/lide.test | sort | uniq | wc -l) \e[0m根" #输出线路根数 echo -e "对应的设备名称和IP地址:\e[1;32m $(cat /root/lide.test | sort -k 2 | uniq | awk '{print $2" : "$1}') \e[0m" #输出网卡和地址 rm -f /root/lide.test #删除临时文件}
#大水管6_network输出
function big_6_network { #大水管6network函数 echo -e "当前拨号的线路有\e[1;32m $(ip address | grep -E "ipfsbit\.[0-9]{1,2}$" | wc -l) \e[0m根" #输出线路根数 echo -e "对应的设备名称和IP地址:\e[1;32m $(ip address | grep -EB 1 "ipfsbit.[0-9]{1,2}$" | grep -v '\-\-' | awk '{if (NR % 2 == 1) printf $2 " : "; else print $NF " :" $2}') \e[0m" #输出网卡和地址}
#大水管设备,2、3、5_network输出
function big_else_network { #大水管2、3、5network函数 echo -e "当前拨号的线路有\e[1;32m $(ip address | grep peer | grep "inet " | wc -l) \e[0m根" #输出线路根数 echo -e "对应的设备名称和IP地址:\e[1;32m $(ip address | grep peer | grep "inet " | sort -k 7 | awk '{print $7" : "$2}') \e[0m" #输出网卡和地址}
#小水管6_network输出
function small_6_network { #小水管6network函数 echo -e "当前拨号的线路有\e[1;32m $(ip address | grep -E "ipfsbit\.[0-9]$" | wc -l) \e[0m根" #输出线路根数 echo -e "对应的设备名称和IP地址:\e[1;32m $(ip address | grep -E "ipfsbit\.[0-9]$" | awk '{print $NF" : "\$2}') \e[0m" #输出网卡和地址}
#小水管设备,除6_network以外输出
function small_else_network { #小水管除6以外network函数 echo -e "水管类型:\e[1;32m $PIPE_TYPE \e[0m" #输出水管类型 echo -e "当前拨号的线路有\e[1;32m 1 \e[0m根" #输出线路根数 echo -e "对应的设备名称和IP地址:\e[1;32m $(ip address | grep '/' | grep -E 'eth[0-9]$|ens[0-9]{1,3}$|em[0-9]$|ppp[0-9]$|pppoe-wan$|eno[0-9]$|enp[0-9]s[0-9]{1,2}[a-z]?[0-9]?$|p[0-9]p[0-9]$|macvlan[0-9]$' | awk '{print $NF" : "$2}' | grep '/') \e[0m" #输出网卡和地址}
#DNS信息输出
function dns { #DNS信息函数 echo -e "当前设备DNS信息:\e[1;32m $(cat /etc/resolv.conf | grep nameserver) \e[0m\n" #输出DNS信息}
#版本信息输出
function version { #版本信息函数 echo -e "当前设备架构:\e[1;32m $(arch) \e[0m" #输出当前架构 if [ -f "/writable/vendor/disk.json" ] #判断盘类型文件是否存在 then #若存在 echo -e "当前设备的盘是:\e[1;32m $(cat /writable/vendor/disk.json | egrep "more|onlyone" | awk -F '"' '{print $4}') \e[0m" #输出单盘或多盘 fi echo -e "当前内核版本:\e[1;32m $(uname -r) \e[0m" #输出内核版本 if [ "$(systemctl status docker 2> /dev/null | grep Active | awk '{print $3}')" = "(running)" ] #判断docker服务是否运行 then #若运行中 echo -e "docker服务的版本为:\e[1;32m$(docker --version | awk '{print $3}' | awk -F "," '{print $1}') \e[0m" #输出docker服务版本 else #若不在运行 echo -e "\e[1;31m docker容器未启动 \e[0m" #输出错误信息 fi if [ "$(systemctl status kdump 2> /dev/null | grep -i active | awk -F " " '{print $2}')" = "active" ] #判断kdump服务是否运行 then #若运行中 echo -e "\e[1;32m kdump 服务已部署 \e[0m" #输出运行信息 else #若不在运行 echo -e "\e[1;31m 未部署 kdump 服务 \e[0m" #输出错误信息 fi}
#x86版本信息输出
function version_x86 { #x86版本信息函数 if [ -f /writable/agent-plugin/devinfo ] #判devinfo是否存在 then #若存在 echo -e "devinfo版本为:\e[1;32m$(/writable/agent-plugin/devinfo -v | awk -F ":" '{print $2}') \e[0m" #输出devinfo版本信息 else #若不存在 echo -e "\e[1;31m devinfo未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/businessinfo ] #判devinfo是否存在 then #若存在 echo -e "businessinfo版本为:\e[1;32m$(/writable/agent-plugin/businessinfo -v | awk -F ":" '{print $2}') \e[0m" #输出businessinfo版本信息 else #若不存在 echo -e "\e[1;31m businessinfo未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/ebpf-tc ] #判devinfo是否存在 then #若存在 echo -e "ebpf-tc版本为:\e[1;32m$(/writable/agent-plugin/ebpf-tc -version) \e[0m" #输出ebpf-tc版本信息 else #若不存在 echo -e "\e[1;31m ebpf-tc未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/flowinfo ] #判devinfo是否存在 then #若存在 echo -e "flowinfo版本为:\e[1;32m$(/writable/agent-plugin/flowinfo -v | awk -F ":" '{print $2}') \e[0m" #输出flowinfo版本信息 else #若不存在 echo -e "\e[1;31m flowinfo未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/loginfo ] #判loginfo是否存在 then #若存在 echo -e "loginfo版本为:\e[1;32m$(/writable/agent-plugin/loginfo -v | awk -F ":" '{print $2}') \e[0m" #输出loginfo版本信息 else #若不存在 echo -e "\e[1;31m loginfo未下发 \e[0m" #输出错误信息 fi if grep version /writable/agent-plugin/band > /dev/null #判断是否有打点版本存在 then #若存在 echo -e "regedt打点版本为:\e[1;32m$(grep version /writable/agent-plugin/band | tail -n 1 | awk '{print $10}') \e[0m" #输出regedt打点版本信息 fi if [ -f /writable/agent-plugin/tx-regedt ] #判断tencent-regedt是否存在 then #若存在 echo -e "tencent-regedt版本为:\e[1;32m$(/writable/agent-plugin/tx-regedt -v | awk -F ":" '{print $2}') \e[0m" #输出tencent-regedt版本信息 else #若不存在 echo -e "\e[1;31m tencent-regedt未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/serviceinfo ] #判断serviceinfo是否存在 then #若存在 echo -e "serviceinfo版本为:\e[1;32m$(/writable/agent-plugin/serviceinfo -v | awk -F ":" '{print $2}') \e[0m" #输出serviceinfo版本信息 else #若不存在 echo -e "\e[1;31m serviceinfo未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/netinfo ] #判断netinfo是否存在 then #若存在 echo -e "netinfo版本为:\e[1;32m$(/writable/agent-plugin/netinfo -v | awk -F ":" '{print $2}') \e[0m" #输出netinfo版本信息 else #若不存在 echo -e "\e[1;31m netinfo未下发 \e[0m" #输出错误信息 fi}
#arm版本信息输出
function version_arm { #arm版本信息函数 if [ -f /writable/agent-plugin/devinfo.arm ] #判断devinfo是否存在 then #若存在 echo -e "devinfo版本为:\e[1;32m$(/writable/agent-plugin/devinfo.arm -v | awk -F ":" '{print $2}') \e[0m" #输出devinfo版本信息 else #若不存在 echo -e "\e[1;31m devinfo未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/businessinfo.arm ] #判断businessinfo是否存在 then #若存在 echo -e "businessinfo版本为:\e[1;32m$(/writable/agent-plugin/businessinfo.arm -v | awk -F ":" '{print $2}') \e[0m" #输出businessinfo版本信息 else #若不存在 echo -e "\e[1;31m businessinfo未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/flowinfo.arm ] #判断flowinfo是否存在 then #若存在 echo -e "flowinfo版本为:\e[1;32m$(/writable/agent-plugin/flowinfo.arm -v | awk -F ":" '{print $2}') \e[0m" #输出flowinfo版本信息 else #若不存在 echo -e "\e[1;31m flowinfo未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/loginfo.arm ] #判断loginfo是否存在 then #若存在 echo -e "loginfo版本为:\e[1;32m$(/writable/agent-plugin/loginfo.arm -v | awk -F ":" '{print $2}') \e[0m" #输出loginfo版本信息 else #若不存在 echo -e "\e[1;31m loginfo未下发 \e[0m" #输出错误信息 fi if grep version /writable/agent-plugin/band > /dev/null #判断是否有打点版本存在 then #若存在 echo -e "regedt打点版本为:\e[1;32m$(grep version /writable/agent-plugin/band 2> /dev/null | tail -n 1 | awk '{print $10}') \e[0m" #输出regedt打点版本信息 fi if [ -f /writable/agent-plugin/serviceinfo.arm ] #判断serviceinfo是否存在 then #若存在 echo -e "serviceinfo版本为:\e[1;32m$(/writable/agent-plugin/serviceinfo.arm -v | awk -F ":" '{print $2}') \e[0m" #输出serviceinfo版本信息 else #若不存在 echo -e "\e[1;31m serviceinfo未下发 \e[0m" #输出错误信息 fi if [ -f /writable/agent-plugin/netinfo.arm ] #判断netinfo是否存在 then #若存在 echo -e "netinfo版本为:\e[1;32m$(/writable/agent-plugin/netinfo.arm -v | awk -F ":" '{print $2}') \e[0m" #输出netinfo版本信息 else #若不存在 echo -e "\e[1;31m netinfo未下发 \e[0m" #输出错误信息 fi}
#zfs版本输出
function zfs_version { #zfs版本函数 if [ -f /usr/sbin/zfs ] #判断zfs函数是否存在 then #若存在 echo -e "当前zfs版本:\e[1;32m $(timeout 10s zfs --version 2> /dev/null | head -n 1 ) \e[0m" #输出当前版本 else #若不存在 echo -e "\e[1;31m zfs 模块未启动 \e[0m" #提示错误信息 fi}
#网络版本输出
function network { #网络版本函数 if [ -n "$NETWORK" ] #判断网络版本是否存在 then #若存在 echo -e "当前网络版本为:\e[1;32m $(docker images | grep $(docker ps | grep -i network | awk '{print $2}' | uniq) | awk '{print $2}') \e[0m\n" #输出当前网络版本 fi}
#判断btvdp状态
function btvdp { #btvdp检测函数 if [ "$(ps -ef | grep btvdp | wc -l)" -ge "2" ] #判断btvdp进程是否拉起 then #若拉起 echo -e "\e[1;32m btvdp 已成功拉起 \e[0m" #输出拉起信息 else #若未拉起 echo -e "\e[1;31m btvdp 未拉起 \e[0m" #输出错误信息 fi}
#业务信息输出
function business { #业务信息函数 echo -e "当前容器中运行着\e[1;32m $(docker ps | grep -viE "network|umi" | tail -n +2 | awk '{print $2" "$NF}' | awk -F "_" '{print $1"_"$2}'| sort -r | uniq | wc -l) \e[0m个业务" #输出业务数量 docker ps | grep -vi network | tail -n +2 | awk '{print $2" "$NF}' | awk -F "_" '{for(i=1; i<NF; i++) printf "%s%s", $i, (i==NF-1)?"\n":"_"}' | sort -r | uniq -c > /root/lide.test #收集实例数、镜像ID、业务容器名称等信息 cat lide.test 2> /dev/null | while read line #将收集到的信息逐行便利 do echo -e "运行当中的业务有:\e[1;32m $(echo "$line" | awk '{print $3}') \e[0m,并开启了\e[1;32m $(echo "$line" | awk '{print $1}') \e[0m个实例,业务版本为:\e[1;32m $(docker images | grep $(echo "$line" | awk '{print substr($2, length($2)-9)}') | awk '{print $2}') \e[0m" #输出业务信息 done rm -f /root/lide.test #删除临时文件 failed_business=$(docker ps -a | grep -viE "network|umi" | grep -vi up | tail -n +2 | awk '{print $2" "$NF}' | awk -F "_" '{print $1"_"$2}' | sort -r | uniq | wc -l) #将是否有停止业务的信息赋予变量 if [ "$failed_business" == "0" ] #判断停止的业务是否为0 then #若为0 echo -e "当前停止状态中有\e[1;32m $failed_business \e[0m个业务" #输出信息 else #若不为0 echo -e "当前停止状态中有\e[1;31m $failed_business \e[0m个业务" #输出错误信息 docker ps -a | grep -viE "network|umi" | grep -vi up | tail -n +2 | awk '{print $2" "$NF}' | awk -F "_" '{for(i=1; i<NF; i++) printf "%s%s", $i, (i==NF-1)?"\n":"_"}' | sort -r | uniq -c > /root/lide.test ##收集实例数、镜像ID、业务容器名称等信息 cat lide.test 2> /dev/null | while read line #将收集到的信息逐行便利 do echo -e "当前停止状态的业务有:\e[1;31m $(echo "$line" | awk '{print $3}') \e[0m,停止了\e[1;31m $(echo "$line" | awk '{print $1}') \e[0m个实例,业务版本为:\e[1;31m $(docker images | grep $(echo "$line" | awk '{print substr($2, length($2)-9)}') | awk '{print $2}') \e[0m" #输出业务信息 done rm -f /root/lide.test #删除临时文件 echo -e "当前停止状态中的实例有:\e[1;31m $(docker ps -a | grep -viE "network|umi" | grep -vi up | tail -n +2 | awk '{print $NF}') \e[0m" #列出异常实例 fi}
function x86_big { #大水管函数 n_network echo -e "水管类型:\e[1;32m $PIPE_TYPE \e[0m" #输出水管类型 case "$NETWORK" in #匹配网络版本 "1") #若为1network big_1_network #调用大水管1network函数 ;; "4") #若为4network big_4_network #调用大水管4network函数 ;; "6") #若为6network big_6_network #调用大水管6network函数 ;; *) #若为2、3、5network设备 big_else_network #调用大水管2、3、5network函数 ;; esac dns #DNS信息输出 version #调用版本信息函数 version_x86 #调用X86版本信息函数 zfs_version #调用zfs版本函数 network #调用btvdp #调用btvdp检测函数 btvdp #调用btvdp检测函数 business #调用业务信息函数}
function x86_small { #小水管函数 if [ "$NETWORK" = "6" ] #判断是否为6network then #若为6network small_6_network #输出6network函数 else #若不为6network small_else_network #输出其他network函数 fi dns #DNS信息输出 version #调用版本信息函数 version_x86 #调用x86版本信息函数 zfs_version #调用zfs版本函数 network #调用网络版本函数 btvdp #调用btvdp检测函数 business #调用业务信息函数}
function arm { #arm函数 small_else_network #输出其他network函数 dns #DNS信息输出 version #调用版本信息函数 version_arm #调用arm版本信息函数 zfs_version #调用zfs版本函数 network #调用网络版本函数 btvdp #调用btvdp检测函数 business #调用业务信息函数
}
function android { #安卓函数 echo -e "当前拨号的线路有\e[1;32m 1 \e[0m根" #输出当前线路根数 echo -e "对应的设备名称和IP地址:\e[1;32m $(ip address | grep 'eth0$\|macvlan0$\|ppp0$' | awk '{print $NF" : "$2}') \e[0m" #输出网络及地址信息 dns #DNS信息输出 version #调用版本信息函数 version_arm #调用arm版本信息函数 btvdp #调用btvdp检测函数}
function total { #总信息函数 if [[ ! "$(arch)" =~ armv[0-9]l ]] && [[ ! "$(arch)" =~ armv[0-9]1 ]] && [[ ! "$(arch)" =~ ARMv[0-9]1 ]] #判断设备架构是否为非安卓 then #若为非安卓设备 if [ "$PIPE_TYPE" = "big" ] #判断是否为大水管设备 then #若为大水管设备 x86_big #调用大水管函数 else #若为小水管设备 if [[ "$(arch)" == "x86_64" ]] #判断设备架构是否为X86 then x86_small #调用小水管函数 else arm #调用arm函数 fi fi else #若为安卓设备 android #调用安卓函数 fi}
#调用函数
prompt #调用命令提示符函数script #调用脚本导入函数sn #调用sn输出函数total #调用总信息输出函数
xxxxxxxxxx#/bin/bash
#脚本下载地址:http://dedeku.top/script/speedtest_lide.sh#———更新时间:2024-08-16———
#设定变量信息
PIPI_TYPE=$(cat /writable/vendor/info.json 2>/dev/null | grep pipe | awk -F '"' '{print $4}') #定义设备的水管类型NETWORK=$(docker ps 2>/dev/null | grep -i network | awk '{print $NF}' | awk -F "_" '{print $1}' | uniq) #定义设备的网络类型
#制作函数
function SPEEDTEST { #制定测速变量 SUM=0 #将初始总数变成0 COUNT=0 #将初始次数变成0 for (( i=1; i<=5; i++ )) #共循环5次 do SPEEDTEST=$(timeout 60s speedtest $OPTION_INTERFACE 2>/dev/null | grep Upload | awk '{print $3}') #将测速结果赋予变量 echo "$(date +'%m-%d %H:%M:%S') 压测结果:" #打印当前时间 if [ -n "$SPEEDTEST" ] && [ "$SPEEDTEST" != "FAILED" ] #判断测试数据是否存在 then #若存在 echo -e "\t上行速率:$SPEEDTEST Mbps \n" #输出测速结果 SUM=$(echo "$SUM + $SPEEDTEST" | bc) #将每次的测速相加 COUNT=$(($COUNT+1)) #计算压测成功的次数 else #若不存在 echo -e "\t \e[1;31m 压测失败!!! \e[0m\n" #输出错误信息 fi
done echo -e "\t 平均速率:$(echo "scale=2 ; $SUM / $COUNT" | bc 2> /dev/null) Mbps \n" #输出平均速率}
#脚本运行
echo -e "\n当前设备 sn :$(cat /writable/.deviceID)\n" #输出设备sn
if [ "$PIPI_TYPE" == "big" ] #判断设备是否为大水管 then #若为大水管 case "$NETWORK" in #判断网络类型 "1") #若为1network echo -e "\e[1;31m 当前设备为大节点设备,压测请使用 /root/lide/benchmark_lide.sh 脚本 \e[0m" #输出错误信息 ;; "4") #若为4network echo -e "\e[1;31m 当前设备为大节点设备,压测请使用 /root/lide/benchmark_lide.sh 脚本 \e[0m" #输出错误信息 ;; "6") #若为6network echo -e "当前设备网卡名称:\n\e[1;32m $(ip address | grep -E "ipfsbit\.[0-9]$" | awk '{print $NF}') \e[0m\n" #输出网卡名称 read -p "当前设备为大节点设备,压测请指定网卡名称,或使用 /root/lide/benchmark_lide.sh 脚本,网卡名称:" INTERFACE #交互式输入网卡名称 OPTION_INTERFACE="-I $INTERFACE" #定义speedtest命令选项和参数 SPEEDTEST #执行测速函数 ;; *) #若为2、3、5network echo -e "当前设备网卡名称:\n\e[1;32m $(ip address | grep peer | grep "inet " | sort -k 7 | awk '{print $7}') \e[0m\n" #输出网卡名称 read -p "当前设备为大节点设备,压测请指定网卡名称,或使用 /root/lide/benchmark_lide.sh 脚本,网卡名称:" INTERFACE #交互式输入网卡名称 OPTION_INTERFACE="-I $INTERFACE" #定义speedtest命令选项和参数 SPEEDTEST #执行测速函数 ;; esac else #若为小水管 SPEEDTEST #执行测速函数fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/benchmark_lide.sh#———更新时间:2024-11-08———
echo -e "\n当前设备 sn :$(cat /writable/.deviceID)\n" #输入当前设备snecho -e "$(date +'%m-%d %H:%M:%S') 压测结果:\n" #输出时间/writable/agent-plugin/bm4ask {"net":"true","tc":"true"} | jq . > /root/lide/logs/benchmark.log 2>/dev/null #录入环境检测信息
V4_SUM=$(cat /root/lide/logs/benchmark.log | grep 'upload\"' | awk '{print $2}' | awk -F ',' '{print $1}') #截取IPv4的每条测速信息V4_COUNT=$(echo $V4_SUM | awk '{print NF}') #截取到根数V4_AVE=$(echo $V4_SUM | awk '{sum=0; for(i=1; i<=NF; i++) sum+=$i; printf "%.2f\n", sum/NF}') #计算出单条的平均值V4_TOTAL=$(echo $V4_SUM | awk '{sum=0; for(i=1; i<=NF; i++) sum+=$i; printf "%.2f\n", sum}') #计算出总量值V6_SUM=$(cat /root/lide/logs/benchmark.log | grep 'uploadv' | awk '{print $2}' | awk -F ',' '{print $1}') #截取IPv6的每条测速信息V6_COUNT=$(echo $V6_SUM | awk '{print NF}') #截取到根数V6_AVE=$(echo $V6_SUM | awk '{sum=0; for(i=1; i<=NF; i++) sum+=$i; printf "%.2f\n", sum/NF}') #计算出单条的平均值V6_TOTAL=$(echo $V6_SUM | awk '{sum=0; for(i=1; i<=NF; i++) sum+=$i; printf "%.2f\n", sum}') #计算出总量值
cat /root/lide/logs/benchmark.log | egrep "acct|upload\"|uploadv" | sed 's/\"vlanacct\"/\n\"用户名\"/g' \ | sed 's/upload\"/IPv4测速上行\"/g' \ | sed 's/uploadv6/IPv6测速上行/g' #进行测速,并输出用户名、IPv4测速上行、IPv6测速上行等信息
echo -e "\n\t IPv4平均单根速率:$V4_AVE \n\t\t 根数: $V4_COUNT \n\t\t 总速率:$V4_TOTAL \n" #输出信息echo -e "\t IPv6平均单根速率:$V6_AVE \n\t\t 根数: $V6_COUNT \n\t\t 总速率:$V6_TOTAL \n" #输出信息
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/speedcheck_lide.sh#———更新时间:2025-03-25———
# 1 状态码:选项指定错误# 2 状态码:选项后需接必要参数# 3 状态码:指定的参数为非要求参数
#定义函数
function usage { echo "使用说明: $0 server 启用服务器端 -p, --port <端口(例:11206)> -c, --client <主机IP(例:150.138.153.68)> -P, --parallel <线程数(例:10)> -b, --bitrate <兆比特每秒(例:10)> -s, --server 服务器端 -6, --ipv6 仅测ipv6 -h, --help" #指定帮助文档}
#定义默认值
SERVER=""PORT="11206"CLIENT="150.138.153.68"PARALLEL="10"BITRATE="10"IPV6=""
#循环遍历所有选项
while true #做出无限循环 do #开始 case "$1" in #判断输入的选项 server) SERVER="true" break ;; -p|--port) if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$PORT" -ge 0 ] && [ "$PORT" -le 65535 ] then PORT="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数需指定端口 ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -c|--client) if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 CLIENT="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -P|--parallel) if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$PARALLEL" -ge 0 ] && [ "$PARALLEL" -le 40 ] then PARALLEL="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数需指定正确的线程数 ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -b|--bitrate) if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$BITRATE" -ge 0 ] && [ "$BITRATE" -le 40 ] then BITRATE="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数需指定正确的线程数 ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -6|--ipv6) IPV6="true" CLIENT="240e:944:8:4::9:2" shift ;; -h|--help) #若匹配为-h或者--help usage #输出帮助文档 exit 0 #以0状态码退出 ;; *) #若匹配其他字符 if [ $# -eq 0 ] #判断选项数量是否为0 then #若为0 break #退出循环 else #若不为0 echo "无效的选项: $1 !" #输出错误信息 usage #输出帮助文档 exit 1 #以1状态码退出 fi ;; esac done #结束
#脚本执行
if [ "$SERVER" == "true" ] then ip a show p7p1 | grep inet /root/pppoe/lw-speedcheck -s -p $PORT exit 0fi
echo -e "\n当前设备 sn :$(cat /writable/.deviceID)\n" #输入当前设备snecho "压测端口:$PORT"echo "压测服务器:${CLIENT:0:3}......${CLIENT: -3}"echo "压测启用线程数量:$PARALLEL"echo "每根线程压测大小:${BITRATE}m"echo "共计:$(($PARALLEL * $BITRATE))m"if [ "$IPV6" == "true" ] then echo "正在压测IPv6" if ! /root/pppoe/ipv6-check -debug > /dev/null then echo -e "\n当前IPv6不可用!!!" exit 4 fi else echo "正在压测IPv4"fiecho -e "\n$(date +'%m-%d %H:%M:%S') 压测结果:\n" #输出时间
/root/pppoe/lw-speedcheck -p $PORT -c $CLIENT -P $PARALLEL -b ${BITRATE}m > /root/lide/logs/speedcheck.log
if [ "$PARALLEL" == "1" ] then grep -i sec lide/logs/speedcheck.log | head -n 10 | awk '{print"传输: "$5,$6"\t重传: "$9"%"}' echo -e "\n统计:" grep -i sec lide/logs/speedcheck.log | tail -n 2 | head -n 1 | awk '{print"上行测速: "$5,$6"\t重传: "$9"%"}' grep -i sec lide/logs/speedcheck.log | tail -n 1 | awk '{print"下行测速: "$5,$6}'fi
grep -i sum lide/logs/speedcheck.log | head -n 10 | awk '{print"传输: "$4,$5"\t重传: "$8"%"}'echo -e "\n统计:"grep -i sum lide/logs/speedcheck.log | tail -n 2 | head -n 1 | awk '{print"上行测速: "$4,$5"\t重传: "$8"%"}'grep -i sum lide/logs/speedcheck.log | tail -n 1 | awk '{print"下行测速: "$4,$5}'
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/random-name_lide.sh#———更新时间:2024-12-09———
names=("王志伟" "孔庆松" "李景煇" "马超" "孙岩宏" "张琪") #定义FAE名字
index=$((RANDOM % 6)) #生成一个0到5之间的随机索引
selected_name=${names[$index]} #根据随机索引抽取名字
echo "抽取的名字是:$selected_name" #输出名字
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/pack-android_lide.sh#———更新时间:2025-03-20———
# 1 状态码:选项指定错误# 2 状态码:选项后需接必要参数# 3 状态码:指定的参数为非要求参数
#定义函数
function usage { echo "使用说明: $0 -v, --vendor <供应商(例:CH)> -o, --orgcode <渠道代码(例:A03)> -c, --channel-id <渠道ID(例:CBV9UHAA0320220905143123262)> -p, --package-type <例:owner|other> -e, --event <例:deploy|androidrom> -i, --install-qrcode-app -k, --keep-adbd-enabled -h, --help" #指定帮助文档} #使用方法函数
#定义默认值
VENDOR="CH" #设置默认供应商ORGCODE="A03" #设置默认渠道代码CHANNELID="CBV9UHAA0320220905143123262" #设置默认渠道IDPACK_TYPE="owner" #默认设置为自营EVENT="deploy" #将事件默认设置为部署INSTALL_QRCODE_APP="flase" #将安装二维码APP默认设为关闭KEEP_ADBD_ENABLED="flase" #将保持adb常开默认设为关闭
#循环遍历所有选项
while true #做出无限循环 do #开始 case "$1" in #判断输入的选项 -v|--vendor) #若匹配为-v或者--vendor if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 VENDOR="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -o|--orgcode) #若匹配为-o或者--orgcode if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 ORGCODE="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -c|--channel-id) #若匹配为-c或者--channel-id if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 CHANNELID="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -p|--package-type) #若匹配为-p或者--package-type if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "owner" ] || [ "$2" = "other" ] #判断参数是否为owner或者other then #若是 PACK_TYPE="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 owner 或 other ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -e|--event) #若匹配为-e或者--event if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "deploy" ] || [ "$2" = "androidrom" ] #判断参数是否为deploy或者androidrom then #若是 EVENT="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 deploy 或 androidrom ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -i|--install-qrcode-app) #若匹配为-i或者--install-qrcode-app INSTALL_QRCODE_APP="true" #定义安装二维码APP shift #左移 ;; -k|--keep-adbd-enabled) #若匹配为-k或者--keep-adbd-enabled KEEP_ADBD_ENABLED="true" #定义保持adb常开 shift #左移 ;; -h|--help) #若匹配为-h或者--help usage #输出帮助文档 exit 0 #以0状态码退出 ;; *) #若匹配其他字符 if [ $# -eq 0 ] #判断选项数量是否为0 then #若为0 break #退出循环 else #若不为0 echo "无效的选项: $1 !" #输出错误信息 usage #输出帮助文档 exit 1 #以1状态码退出 fi ;; esac done #结束
#循环遍历更改参数
while true #循环遍历上报信息 do #开始 echo -e "\n\t\t1、vendor:\t\t$VENDOR 2、orgcode:\t\t$ORGCODE 3、channel-id:\t\t$CHANNELID 4、package-type:\t$PACK_TYPE 5、event:\t\t$EVENT\n install-qrcode-app:\t$INSTALL_QRCODE_APP keep-adbd-enabled:\t$KEEP_ADBD_ENABLED" #输出上报信息 read -p "检查上报信息是否正确无误?(y/n)" CONFIRM #交互式询问信息是否无误 if [ "$CONFIRM" != "y" ] #判断信息是否错误 then #若信息错误 read -p "请输入要更改的序号?(1/2/3/4/5)" NUMBER #交互式询问更改的信息 case "$NUMBER" in #匹配输出的序号 1) #若为1 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 VENDOR="$MODIFY" #将参数定义到变量 ;; 2) #若为2 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 ORGCODE="$MODIFY" #将参数定义到变量 ;; 3) #若为3 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 CHANNELID="$MODIFY" #将参数定义到变量 ;; 4) #若为4 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 PACK_TYPE="$MODIFY" #将参数定义到变量 ;; 5) #若为5 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 EVENT="$MODIFY" #将参数定义到变量 ;; *) #若为其他 echo -e "\n请输入正确的序号(1/2/3/4/5)" #输出错误信息 ;; esac else #若信息无误 break #退出循环 fi done #结束
#向打包服务器上传信息
DATA='{"build_directory":"/build","vendor":"'$VENDOR'","orgcode":"'$ORGCODE'","channel_id":"'$CHANNELID'","package_type":"'$PACK_TYPE'","qrcode_app":"'$INSTALL_QRCODE_APP'","keep_adbd_enabled":"'$KEEP_ADBD_ENABLED'"}' #将定义出的数据存入变量echo $DATA | jq #输出数据信息DATA_ENCODED="$(echo "$DATA" | base64 -w0)" #将数据进行编码后存入变量curl -X POST \ -F token=05700b778df4bb62bed666166cf91d \ -F ref=main \ -F "variables[BUILD_PACKAGE_JSON]=$DATA_ENCODED" \ -F "variables[BUILD_PACKAGE_EVENT]=$EVENT" \ https://web.lueluesay.top/git/api/v4/projects/281/trigger/pipeline | \ jq #通过curl向GitLab服务器发送一个HTTP POST请求,触发ID为281的项目的CI/CD pipeline
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/pack-armbian_lide.sh#———更新时间:2025-03-21———
# 1 状态码:选项指定错误# 2 状态码:选项后需接必要参数# 3 状态码:指定的参数为非要求参数
#定义函数
function usage { echo "使用说明: $0 -s, --soc-family <芯片家族名称(例:s905l3a)> -k, --kernel-version <内核版本(例:6.1.71)> -P, --pipe-type <例:small|big> -f, --file-system <文件系统类型(例:lvm)> -n, --need-ai <例:true|false> -d, --deploy-mode <部署模式> -m, --platform <格式(例:armlogic)> -v, --vendor <供应商(例:AB)> -o, --orgcode <渠道代码(例:A03)> -c, --channel-id <渠道ID(例:CBV9UHAA0320220905143123262)> -p, --package-type <例:owner|other)> -l, --localserver-pwd <本地服务密码(例:admin)> -w, --webserver-tag <web服务标签(例:https://cdn2.linkfog.cn/local-web/lw/dist.zip)> -W, --webserver-logo <web服务logo> -b, --boxid <boxid标签(例:305)> -O, --only-one-disk <例:true|flase> -V, --version <版本(例:v1.1.100.57.9)> -i, --web-install <例:true|false> -F, --flash-install <例:true|false> -e, --event <例:deploy|androidrom> -u, --url-tag <url标签> -t, --testing <例:true|false> -h, --help" #指定帮助文档} #使用方法函数
#定义默认值
SOC_FAMILY="s905l3a" #芯片家族名称默认设为s905l3aKERNEL_VERSION="6.1.71" #内核版本默认设为6.1.71PIPE_TYPE="small" #水管类型默认设为smallFSTYPE="lvm" #文件系统类型默认设为lvmNEED_AI="true" #自动AI默认设为真DEPLOY_MODE="null" #部署模式默认设为空PLATFORM="amlogic" #格式默认设为amlogicVENDOR="AB" #供应商默认设为ABORGCODE="A03" #渠道代码默认设为A03CHANNELID="CBV9UHAA0320220905143123262" #渠道ID默认设为CBV9UHAA0320220905143123262PACK_TYPE="owner" #默认设置为自营LOCALSERVER_PWD="admin" #本地服务密码默认设置为adminWEBSERVER_TAG="https://cdn2.linkfog.cn/local-web/lw/dist.zip" #web服务标签默认设置为https://cdn2.linkfog.cn/local-web/lw/dist.zipWEBSERVER_LOGO="null" #web服务logo默认设为空BOXID_TAG="305" #boxid标签默认设置为305ONLY_ONE_DISK="false" #单盘默认设置为假VERSION="v1.1.100.57.9" #版本默认设置为v1.1.100.57.9WEB_INSTALL="false" #web安装默认设置为假FLASH_INSTALL="false" #flash安装默认设置为假EVENT="armbianrom" #将事件默认设置为armbianromURL_TAG="" #url标签默认设为空TESTING="false" #测试默认设为假
#循环遍历所有选项
while true #做出无限循环 do #开始 case "$1" in #判断输入的选项 -s|--soc-family) #若匹配为-s或者--soc-family if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 SOC_FAMILY="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -k|--kernel-version) #若匹配为-k或者--kernel-version if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 KERNEL_VERSION="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -P|--pipe-type) #若匹配为-P或者--pipe-type if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "small" ] || [ "$2" = "big" ] #判断参数是否为small或者big then #若是 PIPE_TYPE="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 small 或 big ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -f|--file-system) #若匹配为-f或者--file-system if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 FSTYPE="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -n|--need-ai) #若匹配为-n或者--need-ai if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 NEED_AI="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo " $1" 该选项参数只支持 ture 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -d|--deploy-mode) #若匹配为-d或者--deploy-mode if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 DEPLOY_MODE="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -m|--platform) #若匹配为-m或者--platform if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 PLATFORM="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -v|--vendor) #若匹配为-v或者--vendor if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 VENDOR="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -o|--orgcode) #若匹配为-o或者--orgcode if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 ORGCODE="$2" #将��数定义到变量 shift 2 #左移2位 fi ;; -c|--channel-id) #若匹配为-c或者--channel-id if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 CHANNELID="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -p|--package-type) #若匹配为-p或者--package-type if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "owner" ] || [ "$2" = "other" ] #判断参数是否为owner或者other then #若是 PACK_TYPE="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 owner 或 other ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -l|--localserver-pwd) #若匹配为-l或者--localserver-pwd if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 LOCALSERVER_PWD="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -w|--webserver-tag) #若匹配为-w或者--webserver-tag if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 WEBSERVER_TAG="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -W|--webserver-logo) #若匹配为-W或者----webserver-logo if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 WEBSERVER_LOGO="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -b|--boxid) #若匹配为-b或者--boxid if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 BOXID_TAG="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -O|--only-one-disk) #若匹配为-o或者--only-one-disk if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 ONLY_ONE_DISK="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 true 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -V|--version) #若匹配为-V或者--version if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 VERSION="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -i|--web-install) #若匹配为-W或者--web-install if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 WEB_INSTALL="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 true 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -F|--flash-install) #若匹配为-F或者--flash-install if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 FLASH_INSTALL="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 true 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -e|--event) #若匹配为-e或者--event if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "deploy" ] || [ "$2" = "armbianrom" ] #判断参数是否为deploy或者armbianrom then #若是 EVENT="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 deploy 或 armbianrom ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -u|--url-tag) #若匹配为-u或者--url-tag if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 URL_TAG="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -t|--testing) #若匹配为-t或者--testing if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 TESTING="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 true 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -h|--help) #若匹配为-h或者--help usage #输出帮助文档 exit 0 #以0状态码退出 ;; *) #若匹配其他字符 if [ $# -eq 0 ] #判断选项数量是否为0 then #若为0 break #退出循环 else #若不为0 echo "无效的选项: $1 !" #输出错误信息 usage #输出帮助文档 exit 1 #以1状态码退出 fi ;; esac done #结束
#循环遍历更改参数
while true #循环遍历上报信息 do #开始 echo -e "\n\t\t1、soc-family:\t\t$SOC_FAMILY 2、kernel-version:\t$KERNEL_VERSION 3、pipe-type:\t\t$PIPE_TYPE 4、file-system:\t$FSTYPE 5、need-ai:\t\t$NEED_AI 6、deploy-mode:\t$DEPLOY_MODE 7、platform:\t\t$PLATFORM 8、vendor:\t\t$VENDOR 9、orgcode:\t\t$ORGCODE 10、channel-id:\t$CHANNELID 11、package-type:\t$PACK_TYPE 12、localserver-pwd:\t$LOCALSERVER_PWD 13、webserver-tag:\t$WEBSERVER_TAG 14、webserver-logo:\t$WEBSERVER_LOGO 15、boxid:\t\t$BOXID_TAG 16、only-one-disk:\t$ONLY_ONE_DISK 17、version:\t\t$VERSION 18、web-install:\t$WEB_INSTALL 19、flash-install:\t$FLASH_INSTALL 20、event:\t\t$EVENT 21、url-tag:\t\t$URL_TAG 22、testing:\t\t$TESTING\n" #输出上报信息 read -p "检查上报信息是否正确无误?(y/n)" CONFIRM #交互式询问信息是否无误 if [ "$CONFIRM" != "y" ] #判断信息是否错误 then #若信息错误 read -p "请输入要更改的序号?(1/2/3...17/18)" NUMBER #交互式询问更改的信息 case "$NUMBER" in #匹配输出的序号 1) #若为1 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 SOC_FAMILY="$MODIFY" #将参数定义到变量 ;; 2) #若为2 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 KERNEL_VERSION="$MODIFY" #将参数定义到变量 ;; 3) #若为3 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 PIPE_TYPE="$MODIFY" #将参数定义到变量 ;; 4) #若为4 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 FSTYPE="$MODIFY" #将参数定义到变量 ;; 5) #若为5 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 NEED_AI="$MODIFY" #将参数定义到变量 ;; 6) #若为6 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 DEPLOY_MODE="$MODIFY" #将参数定义到变量 ;; 7) #若为7 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 PLATFORM="$MODIFY" #将参数定义到变量 ;; 8) #若为8 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 VENDOR="$MODIFY" #将参数定义到变量 ;; 9) #若为9 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 ORGCODE="$MODIFY" #将参数定义到变量 ;; 10) #若为10 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 CHANNELID="$MODIFY" #将参数定义到变量 ;; 11) #若为11 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 PACK_TYPE="$MODIFY" #将参数定义到变量 ;; 12) #若为12 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 LOCALSERVER_PWD="$MODIFY" #将参数定义到变量 ;; 13) #若为13 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 WEBSERVER_TAG="$MODIFY" #将参数定义到变量 ;; 14) #若为14 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 BOXID_TAG="$MODIFY" #将参数定义到变量 ;; 15) #若为15 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 WEBSERVER_LOGO="$MODIFY" #将参数定义到变量 ;; 16) #若为16 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 ONLY_ONE_DISK="$MODIFY" #将参数定义到变量 ;; 17) #若为17 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 VERSION="$MODIFY" #将参数定义到变量 ;; 18) #若为18 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 WEB_INSTALL="$MODIFY" #将参数定义到变量 ;; 19) #若为19 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 FLASH_INSTALL="$MODIFY" #将参数定义到变量 ;; 20) #若为20 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 EVENT="$MODIFY" #将参数定义到变量 ;; 21) #若为21 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 URL_TAG="$MODIFY" #将参数定义到变量 ;; 22) #若为22 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 TESTING="$MODIFY" #将参数定义到变量 ;; *) #若为其他 echo -e "\n请输入正确的序号(1/2/3/4/5)" #输出错误信息 ;; esac else #若信息无误 break #退出循环 fi done #结束
#补充处理
if [[ -n "$WEBSERVER_LOGO" ]] && [[ "$WEBSERVER_LOGO" != "null" ]] #判断web服务logo是否为非空并且不为null then #若都满足 webserver_logo="$(base64 -w0 $WEBSERVER_LOGO)" #将web服务logo编码后不换行,并赋予变量 else #若其一不满足 webserver_logo="" #将web服务logo设为空fi
#向打包服务器上传信息
DATA='{"soc_family":"'"$SOC_FAMILY"'","build_directory":"/build","kernel_version":"'"$KERNEL_VERSION"'","pipe_type":"'$PIPE_TYPE'","file_system":"'$FSTYPE'","need_ai":"'$NEED_AI'","deploy_mode":"'$DEPLOY_MODE'","soc_platform":"'"$PLATFORM"'","vendor":"'$VENDOR'","orgcode":"'$ORGCODE'","channel_id":"'$CHANNELID'","package_type":"'$PACK_TYPE'","localserver_pwd":"'$LOCALSERVER_PWD'","webserver_tag":"'$WEBSERVER_TAG'","boxid":"'"$BOXID_TAG"'","only_one_disk":"'$ONLY_ONE_DISK'","web_install":"'$WEB_INSTALL'","flash_install":"'$FLASH_INSTALL'","version":"'$VERSION'","url_tag":"'$URL_TAG'","webserver_logo":"'$webserver_logo'","testing":"'$TESTING'"}' #将定义出的数据存入变量echo $DATA | jq #输出数据信息DATA_ENCODED="$(echo "$DATA" | base64 -w0)" #将数据进行编码后存入变量curl -X POST \ -F token=77b12522cd6ae1687e65865d4f1e34 \ -F ref=main \ -F "variables[BUILD_PACKAGE_JSON]=$DATA_ENCODED" \ -F "variables[BUILD_PACKAGE_EVENT]=$EVENT" \ https://web.lueluesay.top/git/api/v4/projects/182/trigger/pipeline | \ jq #通过curl向GitLab服务器发送一个HTTP POST请求,触发ID为182的项目的CI/CD pipeline
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/pack-x86_lide.sh#———更新时间:2025-04-01———
# 1 状态码:选项指定错误# 2 状态码:选项后需接必要参数# 3 状态码:指定的参数为非要求参数
#定义函数
function usage { echo "使用说明: $0 -k, --kernel-version <内核版本(例:6.1.12-5)> -P, --pipe-type <例:small|big> -f, --file-system <文件系统类型(例:zfs)> -n, --need-ai <例:1|flase)> -m, --platform <格式(例:x86)> -v, --vendor <供应商(例:LW)> -o, --orgcode <渠道代码(例:A03)> -c, --channel-id <渠道ID(例:CBV9UHAA0320220905143123262)> -p, --package-type <例:owner|other)> -l, --localserver-pwd <本地服务密码(例:admin)> -w, --webserver-tag <web服务标签(例:https://cdn2.linkfog.cn/local-web/lw/dist.zip)> -W, --webserver-logo <web服务logo(例:aGVsbG8K)> -O, --only-one-disk <例:true|flase> -V, --version <版本(例:1.1.100.58.6)> -e, --event <事件(例:x86)> -N, --nopcdn <例:true|flase> -i, --vm_install <例:true|flase> -t, --testing <例:true|flase> -u, --url-tag <url标签> -h, --help" #指定帮助文档} #使用方法函数
#定义默认值
KERNEL_VERSION="6.1.12-5" #内核版本默认设为6.1.12-5PIPE_TYPE="small" #水管类型默认设为smallFSTYPE="zfs" #文件系统类型默认设为zfsNEED_AI="1" #自动AI默认设为1PLATFORM="x86" #格式默认设为x86VENDOR="LW" #供应商默认设为LWORGCODE="A03" #渠道代码默认设为A03CHANNELID="CBV9UHAA0320220905143123262" #渠道ID默认设为CBV9UHAA0320220905143123262PACK_TYPE="other" #默认设置为非自营LOCALSERVER_PWD="admin" #本地服务密码默认设置为adminWEBSERVER_TAG="https://cdn2.linkfog.cn/local-web/lw/dist.zip" #web服务标签默认设置为https://cdn2.linkfog.cn/local-web/lw/dist.zipWEBSERVER_LOGO="" #web服务logo默认设为空ONLY_ONE_DISK="false" #单盘默认设置为假VERSION="1.1.100.60.1" #版本默认设置为1.1.100.60.1EVENT="x86" #将事件默认设置为x86NOPCDN="false" #禁用pcdn默认设置为假VM_INSTALL="false" #虚拟机安装默认设为假TESTING="false" #测试默认设为假URL_TAG="" #url标签默认设为空
#循环遍历所有选项
while true #做出无限循环 do #开始 case "$1" in #判断输入的选项 -k|--kernel-version) #若匹配为-k或者--kernel-version if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 KERNEL_VERSION="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -P|--pipe-type) #若匹配为-P或者--pipe-type if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "small" ] || [ "$2" = "big" ] #判断参数是否为small或者big then #若是 PIPE_TYPE="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 small 或 big ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -f|--file-system) #若匹配为-f或者--file-system if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 FSTYPE="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -n|--need-ai) #若匹配为-n或者--need-ai if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 NEED_AI="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -m|--platform) #若匹配为-m或者--platform if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 PLATFORM="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -v|--vendor) #若匹配为-v或者--vendor if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 VENDOR="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -o|--orgcode) #若匹配为-o或者--orgcode if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 ORGCODE="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -c|--channel-id) #若匹配为-c或者--channel-id if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 CHANNELID="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -p|--package-type) #若匹配为-p或者--package-type if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "owner" ] || [ "$2" = "other" ] #判断参数是否为owner或者other then #若是 PACK_TYPE="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 owner 或 other ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -l|--localserver-pwd) #若匹配为-l或者--localserver-pwd if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 LOCALSERVER_PWD="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -w|--webserver-tag) #若匹配为-w或者--webserver-tag if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 WEBSERVER_TAG="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -W|--webserver-logo) #若匹配为-W或者--webserver-logo if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 WEBSERVER_LOGO="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -O|--only-one-disk) #若匹配为-o或者--only-one-disk if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 ONLY_ONE_DISK="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 true 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -V|--version) #若匹配为-V或者--version if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 VERSION="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -e|--event) #若匹配为-e或者--event if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 EVENT="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -N|--nopcdn) #若匹配为-o或者--nopcdn if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 NOPCDN="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 true 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -i|--vm-install) #若匹配为-i或者--vm-install if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 VM_INSTAL="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 true 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -t|--testing) #若匹配为-t或者--testing if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 elif [ "$2" = "true" ] || [ "$2" = "flase" ] #判断参数是否为true或者flase then #若是 TESTING="$2" #将参数定义到变量 shift 2 #左移2位 else #若不是 echo "$1" 该选项参数只支持 true 或 flase ! #输出错误信息 usage #输出帮助文档 exit 3 #以3状态码退出 fi ;; -u|--url-tag) #若匹配为-u或者--url-tag if [ -z "$2" ] #判断参数是否为空 then #若为空 echo " $1" 选项需后接参数! #输出错误信息 usage #输出帮助文档 exit 2 #以2状态码退出 else #若不为空 URL_TAG="$2" #将参数定义到变量 shift 2 #左移2位 fi ;; -h|--help) #若匹配为-h或者--help usage #输出帮助文档 exit 0 #以0状态码退出 ;; *) #若匹配其他字符 if [ $# -eq 0 ] #判断选项数量是否为0 then #若为0 break #退出循环 else #若不为0 echo "无效的选项: $1 !" #输出错误信息 usage #输出帮助文档 exit 1 #以1状态码退出 fi ;; esac done #结束
#循环遍历更改参数
while true #循环遍历上报信息 do #开始 echo -e "\n\t\t1、kernel-version:\t$KERNEL_VERSION 2、pipe-type:\t\t$PIPE_TYPE 3、file-system:\t$FSTYPE 4、need-ai:\t\t$NEED_AI 5、platform:\t\t$PLATFORM 6、vendor:\t\t$VENDOR 7、orgcode:\t\t$ORGCODE 8、channel-id:\t\t$CHANNELID 9、package-type:\t$PACK_TYPE 10、localserver-pwd:\t$LOCALSERVER_PWD 11、webserver-tag:\t$WEBSERVER_TAG 12、webserver-logo:\t$WEBSERVER_LOGO 13、only-one-disk:\t$ONLY_ONE_DISK 14、version:\t\t$VERSION 15、event:\t\t$EVENT 16、nopcdn:\t\t$NOPCDN 17、vm-install:\t$VM_INSTALL 18、testing:\t\t$TESTING 19、url-tag:\t$URL_TAG\n" #输出上报信息 read -p "检查上报信息是否正确无误?(y/n)" CONFIRM #交互式询问信息是否无误 if [ "$CONFIRM" != "y" ] #判断信息是否错误 then #若信息错误 read -p "请输入要更改的序号?(1/2/3...14/15)" NUMBER #交互式询问更改的信息 case "$NUMBER" in #匹配输出的序号 1) #若为1 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 KERNEL_VERSION="$MODIFY" #将参数定义到变量 ;; 2) #若为2 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 PIPE_TYPE="$MODIFY" #将参数定义到变量 ;; 3) #若为3 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 FSTYPE="$MODIFY" #将参数定义到变量 ;; 4) #若为4 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 NEED_AI="$MODIFY" #将参数定义到变量 ;; 5) #若为5 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 PLATFORM="$MODIFY" #将参数定义到变量 ;; 6) #若为6 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 VENDOR="$MODIFY" #将参数定义到变量 ;; 7) #若为7 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 ORGCODE="$MODIFY" #将参数定义到变量 ;; 8) #若为8 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 CHANNELID="$MODIFY" #将参数定义到变量 ;; 9) #若为9 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 PACK_TYPE="$MODIFY" #将参数定义到变量 ;; 10) #若为10 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 LOCALSERVER_PWD="$MODIFY" #将参数定义到变量 ;; 11) #若为11 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 WEBSERVER_TAG="$MODIFY" #将参数定义到变量 ;; 12) #若为12 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 WEBSERVER_LOGO="$MODIFY" #将参数定义到变量 ;; 13) #若为13 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 ONLY_ONE_DISK="$MODIFY" #将参数定义到变量 ;; 14) #若为14 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 VERSION="$MODIFY" #将参数定义到变量 ;; 15) #若为15 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 EVENT="$MODIFY" #将参数定义到变量 ;; 16) #若为16 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 NOPCDN="$MODIFY" #将参数定义到变量 ;; 17) #若为17 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 VM_INSTAL="$MODIFY" #将参数定义到变量 ;; 18) #若为18 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 TESTING="$MODIFY" #将参数定义到变量 ;; 19) #若为19 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 URL_TAG="$MODIFY" #将参数定义到变量 ;; *) #若为其他 echo -e "\n请输入正确的序号(1/2/3/4/5)" #输出错误信息 ;; esac else #若信息无误 break #退出循环 fi done #结束
#补充处理
if [[ -n "$WEBSERVER_LOGO" ]] && [[ "$WEBSERVER_LOGO" != "null" ]] #判断web服务logo是否为非空并且不为null then #若都满足 webserver_logo="$(base64 -w0 $WEBSERVER_LOGO)" #将web服务logo编码后不换行,并赋予变量 else #若其一不满足 webserver_logo="" #将web服务logo设为空fi
#向打包服务器上传信息
DATA='{"soc_family":"edgexos","build_directory":"/build","kernel_version":"'$KERNEL_VERSION'","pipe_type":"'$PIPE_TYPE'","file_system":"'$FSTYPE'","need_ai":"'$NEED_AI'","soc_platform":"'$PLATFORM'","vendor":"'$VENDOR'","orgcode":"'$ORGCODE'","channel_id":"'$CHANNELID'","package_type":"'$PACK_TYPE'","localserver_pwd":"'$LOCALSERVER_PWD'","webserver_tag":"'$WEBSERVER_TAG'","version":"'$VERSION'","nopcdn":"'$NOPCDN'","only_one_disk":"'$ONLY_ONE_DISK'","webserver_logo":"'$webserver_logo'","vps":"'$VM_INSTALL'","testing":"'$TESTING'","url_tag":"'$URL_TAG'"}' #将定义出的数据存入变量echo $DATA | jq #输出数据信息DATA_ENCODED="$(echo "$DATA" | base64 -w0)" #将数据进行编码后存入变量curl -X POST \ -F token=9dc729bb37782763c640491ec85771 \ -F ref=main \ -F "variables[BUILD_PACKAGE_JSON]=$DATA_ENCODED" \ -F "variables[BUILD_PACKAGE_EVENT]=$EVENT" \ https://web.lueluesay.top/git/api/v4/projects/81/trigger/pipeline | \ jq #通过curl向GitLab服务器发送一个HTTP POST请求,触发ID为81的项目的CI/CD pipeline
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/change-info_lide.sh#———更新时间:2024-12-23———
aio -m dec -i /writable/agent-new/config/vendor.yaml -o /writable/agent-new/config/vendor.yaml.bak #将源文件解压为备份文件
while true #循环遍历上报信息 do #开始 tail -n +2 /writable/agent-new/config/vendor.yaml.bak | cat -n #输出文件中的内容信息 read -p "检查上报信息是否正确无误?(y/n)" CONFIRM #交互式询问信息是否无误 if [ "$CONFIRM" != "y" ] #判断信息是否错误 then #若信息错误 read -p "请输入要更改的序号?(1/2/3...7/8)" NUMBER #交互式询问更改的信息 TARGET=$(sed -n $(($NUMBER+1))p /writable/agent-new/config/vendor.yaml.bak | awk -F ': ' '{print $2}') #定义要更改前的内容信息 case "$NUMBER" in #匹配输出的序号 1) #若为1 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 sed -i s/$TARGET/$MODIFY/g /writable/agent-new/config/vendor.yaml.bak #更改信息 ;; 2) #若为2 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 sed -i s/$TARGET/$MODIFY/g /writable/agent-new/config/vendor.yaml.bak #更改信息 ;; 3) #若为3 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 sed -i s/$TARGET/$MODIFY/g /writable/agent-new/config/vendor.yaml.bak #更改信息 ;; 4) #若为4 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 sed -i s/$TARGET/$MODIFY/g /writable/agent-new/config/vendor.yaml.bak #更改信息 ;; 5) #若为5 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 sed -i s/$TARGET/$MODIFY/g /writable/agent-new/config/vendor.yaml.bak #更改信息 ;; 6) #若为6 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 sed -i s/$TARGET/$MODIFY/g /writable/agent-new/config/vendor.yaml.bak #更改信息 ;; 7) #若为7 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 sed -i s/$TARGET/$MODIFY/g /writable/agent-new/config/vendor.yaml.bak #更改信息 ;; 8) #若为8 read -p "请输入更改后的内容?" MODIFY #交互式询问更改后的内容 sed -i s/$TARGET/$MODIFY/g /writable/agent-new/config/vendor.yaml.bak #更改信息 ;; *) #若为其他 echo -e "\n请输入正确的序号(1/2/3/4/5)" #输出错误信息 ;; esac else #若信息无误 break #退出循环 fi done
aio -m enc -i /writable/agent-new/config/vendor.yaml.bak -o /writable/agent-new/config/vendor.yaml #将备份文件压缩会源文件rm -f /writable/agent-new/config/vendor.yaml.bak #删除备份文件systemctl restart agent-new.service #重启agent-new服务echo "已更改" #输出更改完毕
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-11_lide.sh#———更新时间:2025-04-10———
# 状态码 1 近期未出现过报错# 状态码 2 当前设备盘质量出现问题
#定义环境变量
DOCKER_STATUS=$(systemctl status docker | grep Active | awk '{print $2}') #定义docker服务当前状态
#执行前的输出信息
echo -e "\n当前正在操作设备的 sn : $(cat /writable/.deviceID)" #输出设备snecho -e "当前设备架构: $(arch)\n" #输出设备架构
#判断是否需要执行脚本
if tail -n 500 /writable/agent-new/agent.log | grep -i 'exitcode 11' | tail -n 10 #判断业务部署日志是否有11的报错 then #有11报错的情况下 : #不做任何输出 else #无11报错的情况下 echo -e "\e[1;31m 该设备近期未出现过 11 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
#执行脚本
if [ "$DOCKER_STATUS" == "failed" ] #判断docker服务状态是否为failed then #docker服务状态是failed的情况 echo -e "\n当前设备 docker 服务状态:$DOCKER_STATUS \n" #输出当前状态 systemctl start docker 2> /dev/null #启动docker服务 if [ "$?" == "0" ] #判断docker是否重启成功 then #docker服务重启成功的情况 echo "docker服务启动成功" #输出重启成功 else #docker服务重启失败的情况 echo -e "\e[1;31m docker服务重启失败!!! \e[0m\n" #输出重启失败 fi else #docker服务状态不是failed的情况 echo -e "\n当前设备 docker 服务运行正常\n" #输出运行正常fi
#if dmesg -T | grep error | egrep "usb|EXT4-fs|I/O" > /dev/null #判断日志中是否有报错信息# then #有报错信息的情况# echo -e "\e[1;31m 当前设备盘质量出现问题,需更换硬盘!!! \e[0m\n" #输出问题信息# read -p "是否查看报错信息?(y/n)" ERROR #交互式询问# if [ "$ERROR" == "y" ] #判断是否查看报错信息# then #查看报错信息的情况# dmesg -T | grep error | egrep "usb|EXT4-fs|I/O" | tail #输出报错信息# fi# exit 2 #以2状态退出脚本# else #无报错信息的情况# echo "硬盘当前状态无异常" #输出无异常#fi
if [ "$(arch)" == "x86_64" ] #判断设备架构是否为x86_64 then #若为x86_64架构 yum -y update docker-ce #更新docker服务 docker restart $(docker ps -aq) #重启docker下所有容器 else apt -y update apt upgrade docker restart $(docker ps -aq) #重启docker下所有容器fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-116_lide.sh#———更新时间:2025-01-15———
#执行前的输出信息
echo -e "\n当前正在操作设备的 sn : $(cat /writable/.deviceID)" #输出设备snecho -e "当前设备架构: $(arch)\n" #输出设备架构
#判断是否需要执行脚本
if grep -i 'exitcode 116' /writable/agent-new/agent.log #判断业务部署日志是否有116的报错 then #若有116报错 : #不做任何输出 else #若无116报错 echo -e "\e[1;31m 该设备近日未出现过 116 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
#脚本执行
if dmesg -T | grep error | egrep "usb|EXT4-fs|I/O" > /dev/null then #有报错信息的情况 echo -e "\n\e[1;31m 当前设备盘出现报错信息!!! \e[0m\n" #输出问题信息 read -p "是否查看报错信息?(y/n)" ERROR #交互式询问 if [ "$ERROR" == "y" ] #判断是否查看报错信息 then #查看报错信息的情况 dmesg -T | grep error | egrep "usb|EXT4-fs|I/O" | tail #输出报错信息 fi read -p "是否尝试重启,若重启后仍116报错,需更换硬盘(y/n)" REBOOT if [ "$REBOOT" == "y" ] then for i in $(lvs | tail -n +2 | grep -v "docker_root" | awk '{print $1}') #将除docker_root以外的,所有正在占有空间的业务循环便利 do if docker ps | grep $i > /dev/null #检验占用空间的业务是否在容器中运行 then #若正在运行 echo " $i 正在容器中运行" #输出正在运行 else #若不在运行 echo -e "\e[1;31m $i 卸载以及清楚逻辑卷完毕! \e[0m" #输出已清理 umount $(lsblk | grep $i | awk '{print $NF}') 2> /dev/null #解除挂载 lvremove -f /dev/$(lvs | grep $i | awk '{print $2}')/$i #删除逻辑卷 fi done echo -e "\n已执行重启!!!" #输出重启 /sbin/reboot #重启 else echo -e "\n未重启" #输出不重启 fi else #无报错信息的情况 echo "硬盘当前状态无异常" #输出无异常fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-125_lide.sh#———更新时间:2024-12-19———
#判断是否需要执行脚本
if grep -i 'exitcode 125' /writable/agent-new/agent.log #判断业务部署日志是否有125的报错 then #有125报错的情况下 : #不做任何输出 else #无125报错的情况下 echo -e "\e[1;31m 该设备未出现过 125 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
#脚本执行
if dmesg -T | grep error | grep "EXT4-fs" > /dev/null #判断日志中是否有报错信息 then #有报错信息的情况 echo -e "\n\e[1;31m 当前设备盘质量出现问题,需更换硬盘!!! \e[0m\n" #输出问题信息 read -p "是否查看报错信息?(y/n)" ERROR #交互式询问 if [ "$ERROR" == "y" ] #判断是否查看报错信息 then #查看报错信息的情况 dmesg -T | grep error | grep "EXT4-fs" | tail -n 10 #输出报错信息 fi exit 1 #以1状态码退出 else #无报错信息的情况 echo "硬盘当前状态无异常" #输出无异常fi
systemctl stop docker.socket #关闭docker套接字服务systemctl stop docker #关闭docker服务rm -fr /var/lib/docker #清除掉docker下的镜像、容器、卷等信息rm -fr /writable/ipfsbit-518518 #清除到业务的docker数据信息
if [ -f "/sbin/reboot" ] #判断是否有重启命令 then #若可以重启 read -p "是否需要重启? (y/n)" REBOOT #交互式询问是否需要重启 if [ $REBOOT == "y" ] #判断是否需要重启 then #若需要重启 echo -e "\n已执行重启!!!" #输出重启 /sbin/reboot #重启 else #若不需要重启 #输出不重启 echo -e "\n未重启" #输出不重启 fi else #若不能重启 echo -e "\n无法重启,需重新下发" #输出错误信息fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-131_lide.sh#———更新时间:2025-02-07———
# 1 状态码:设备近期未出现过131报错信息# 2 状态码:网络容器正常运行,需重新下发业务# 3 状态码:网络容器重新拉取成功,需重新下发业务
#执行前的输出信息
echo -e "\n当前正在操作设备的 sn : $(cat /writable/.deviceID)" #输出设备snecho -e "当前设备架构: $(arch)\n" #输出设备架构
#判断是否需要执行脚本
if grep -i 'exitcode 131' /writable/agent-new/agent.log #判断业务部署日志是否有131的报错 then #有131报错的情况下 : #不做任何输出 else #无131报错的情况下 echo -e "\e[1;31m 该设备近期未出现过 131 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
if docker ps 2>/dev/null | grep -i network #判断网络容器是否在运行中 then #若在运行 echo -e "\n网络容器正常运行,需重新下发业务" #输出信息 exit 2 #以2状态码返回 else #若不在运行 echo -e "\n网络容器未在运行!!!" #输出错误信息fi
if docker ps -a 2>/dev/null | grep -i network > /dev/null #判断网络容器是否发生死亡 then #若存在死亡 if docker restart $(docker ps -a 2>/dev/null | grep -i network | awk '{print $NF}') #重新启动网络容器 then #若重启成功 sleep 1 #暂停一秒 if docker ps -a 2>/dev/null | grep -i network 2> /dev/null | grep -i exited > /dev/null #判断是否重启之后为退出状态 then #若退出状态 echo -e "\n网络容器重启失败" #输出错误信息 docker logs $(docker ps -a 2>/dev/null | grep -i network | awk '{print $NF}') #输出前台信息 else echo -e "\n网络容器重启成功,重新下发业务" #输出信息 exit 3 #以3状态码返回 fi else #若重启失败 echo -e "\n网络容器重启失败" #输出错误信息 docker logs $(docker ps -a 2>/dev/null | grep -i network | awk '{print $NF}') #输出前台信息 fifi
if [ -f "/sbin/reboot" ] #判断是否有重启命令 then #若可以重启 read -p "是否需要重启? (y/n)" REBOOT #交互式询问是否需要重启 if [ $REBOOT == "y" ] #判断是否需要重启 then #若需要重启 systemctl stop docker.socket #关闭docker套接字服务 systemctl stop docker #关闭docker服务 rm -fr /var/lib/docker #清除掉docker下的镜像、容器、卷等信息 rm -fr /writable/ipfsbit-518518 #清除到业务的docker数据信息 echo -e "\n已执行重启!!!" #输出重启 /sbin/reboot #重启 else #若不需要重启 #输出不重启 echo -e "\n未重启" #输出不重启 fi else #若不能重启 echo -e "\n无法重启,需重新下发" #输出错误信息fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-140_lide.sh#———更新时间:2025-01-02———
#执行前的输出信息
echo -e "\n当前正在操作设备的 sn : $(cat /writable/.deviceID)" #输出设备snecho -e "当前设备架构: $(arch)\n" #输出设备架构
#判断是否需要执行脚本
if grep -i 'exitcode 140' /writable/agent-new/agent.log #判断业务部署日志是否有140的报错 then #若有140报错 : #不做任何输出 else #若无140报错 echo -e "\e[1;31m 该设备近期未出现过 140 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
#执行脚本
if [ $(arch) == "aarch64" ] #判断架构是否为arm盒子 then #若为arm设备 VG_SIZE=$(vgs | tail -n +2 | awk '{print $6}' | awk '{gsub(/</, "", $1); print $1}') #定义逻辑卷的可用空间 BUSINESS=$(cat /writable/agent-new/agent.log | grep 'exitCode 140' | awk '{print $11}' | awk -F ']' '{print $1}' | tail -n 1) #截取到报140错误的业务 if [ -z "$BUSINESS" ] #判断截取的业务是否为空 then #若为空 for i in {1..7} #循环7次 do gunzip agent.log.$i.gz 2> /dev/null #解压业务日志压缩包 BUSINESS_FINAL=$(cat /writable/agent-new/agent.log.$i | grep 'exitCode 140' | awk '{print $11}' | awk -F ']' '{print $1}' | tail -n 1) #截取报错业务名称 if [ -n "BUSINESS_FINAL" ] #判断是否截取到业务名称 then #若截取到了 COUNT=".$i" #记录截取到的后缀 break #退出for循环 fi done else #若不为空 BUSINESS_FINAL=$BUSINESS #定义最终业务名称 fi
BUSINESS_SIZE=$(cat /writable/agent-new/agent.log$COUNT | grep "$BUSINESS_FINAL.*deploy-aarch64 " | awk -F 'deploy-aarch64 ' '{print $2}' | awk -F '\] ' '{print $1}' | jq | \ egrep '"name"|storage_size|"instance_number"' | awk -F '"' '{print $4}' | awk 'ORS=NR%3?" ":"\n"' | awk '{printf "%-30s %-10s %-0s\n",$1,$2,$3"g"}' | sort | uniq) #截取到140业务名称、实例数、占用大小信息 BUSINESS_SIZE_TOTAL=$(echo $BUSINESS_SIZE | awk '{for (i = 1; i <= NF; i += 3) {printf "%s %s %s\n", $i, $(i+1), $(i+2);}}' | awk '{print $2"\t"$3}' | awk -F 'g' '{print $1}' | awk '{product = 1;for (i=1; i<=NF; i++) {product *= $i;}sum += product;}END {print sum""}') #计算占用总和
echo -e "\n当前卷组可供使用的磁盘空间为:$VG_SIZE\n" #输出卷组空间 echo -e "正在下发报错的业务名称: $BUSINESS_FINAL\n" #输出报错业务名称 echo -e "正在下发的业务占用的空间:业务名称\t实例数\t单实例分配大小\n$BUSINESS_SIZE\n" #输出报错业务占用空间 echo -e "业务下发总大小占磁盘空间:$BUSINESS_SIZE_TOTAL g\n" #输出总占用空间
if [ $(echo "$(echo $VG_SIZE | awk -F 'g' '{print $1}') > $BUSINESS_SIZE_TOTAL" | bc) -eq 1 ] #判断卷组空间是否大于业务下发空间 then #若卷组空间大于业务下发空间 echo -e "磁盘空间充足\n" #输出空间充足 else #若卷组空间小于业务下发空间 echo -e "\e[1;31m $VG_SIZE 空间不够下发业务,需添加磁盘空间!!! \e[0m\n" #输出空间不足 fi
echo -e "当前正在占用磁盘空间的业务有:\n$(lvs | tail -n +2 | awk '{printf "%-30s %-30s\n", $1, $4""}')\n" #输出正在占用空间的业务
for i in $(lvs | tail -n +2 | grep -v "docker_root" | awk '{print $1}') #将除docker_root以外的,所有正在占有空间的业务循环便利 do if docker ps | grep $i > /dev/null #检验占用空间的业务是否在容器中运行 then #若正在运行 echo " $i 正在容器中运行" #输出正在运行 else #若不在运行 echo -e "\e[1;31m $i 卸载以及清楚逻辑卷完毕! \e[0m" #输出已清理 umount $(lsblk | grep $i | awk '{print $NF}') 2> /dev/null #解除挂载 lvremove -f /dev/$(lvs | grep $i | awk '{print $2}')/$i #删除逻辑卷 LVREMOVE=1 #标记为1 fi done
echo " " #换行 if [ "$LVREMOVE" == "1" ] #判断是否标记为1 then #若标记为1 read -p "逻辑卷清理成功,是否需要重启? (y/n)" REBOOT #交互式询问是否需要重启 if [ $REBOOT == "y" ] #判断是否需要重启 then #若需要重启 echo -e "\n已执行重启!!!" #输出重启 /sbin/reboot #重启 else #若不需要重启 echo -e "\n未重启" #输出不重启 fi else #若标记不是1 echo -e "\n无多余挂载,无需清理!!!" #输出无多余挂载 fi else #若非arm设备 ZPOOL_SIZE=$(zpool list | tail -n +2 | awk '{print $4}') #定义zpool池的可用空间
echo -e "\n当前zpool可供使用的磁盘空间为:$ZPOOL_SIZE\n" #输出zpool池空间 #问题点:如何截取业务下发需要占用的磁盘空间,方便与zpool池比较,好判断出是否因为磁盘空间不足引发的140fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-141_lide.sh#———更新时间:2024-10-22———
#执行前的输出信息
echo -e "\n当前正在操作设备的 sn : $(cat /writable/.deviceID)" #输出设备snecho -e "当前设备架构: $(arch)\n" #输出设备架构
#判断是否需要执行脚本
if grep -i 'exitcode 141' /writable/agent-new/agent.log #判断业务部署日志是否有141的报错 then #若有141报错 : #不做任何输出 else #若无141报错 echo -e "\e[1;31m 该设备近日未出现过 141 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
#脚本执行
if dmesg -Tl err | grep '\-fs' > /dev/null then #有报错信息的情况 echo -e "\n\e[1;31m 当前设备盘出现报错信息!!! \e[0m\n" #输出问题信息 read -p "是否查看报错信息?(y/n)" ERROR #交互式询问 if [ "$ERROR" == "y" ] #判断是否查看报错信息 then #查看报错信息的情况 dmesg -Tl err | grep '\-fs' #输出报错信息 fi read -p "是否尝试重启,若重启后仍141报错,需更换硬盘(y/n)" REBOOT if [ "$REBOOT" == "y" ] then for i in $(lvs | tail -n +2 | grep -v "docker_root" | awk '{print $1}') #将除docker_root以外的,所有正在占有空间的业务循环便利 do if docker ps | grep $i > /dev/null #检验占用空间的业务是否在容器中运行 then #若正在运行 echo " $i 正在容器中运行" #输出正在运行 else #若不在运行 echo -e "\e[1;31m $i 卸载以及清楚逻辑卷完毕! \e[0m" #输出已清理 umount $(lsblk | grep $i | awk '{print $NF}') 2> /dev/null #解除挂载 lvremove -f /dev/$(lvs | grep $i | awk '{print $2}')/$i #删除逻辑卷 fi done echo -e "\n已执行重启!!!" #输出重启 /sbin/reboot #重启 else echo -e "\n未重启" #输出不重启 fi else #无报错信息的情况 echo "硬盘当前状态无异常" #输出无异常fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-201_lide.sh#———更新时间:2025-03-18———
# 1 状态码,设备近期未出现报错# 2 状态码,docker服务下载失败
#定义环境变量
DOCKER_STATUS=$(systemctl status docker | grep Active | awk '{print $2}') #定义docker服务当前状态
#执行前的输出信息
echo -e "\n当前正在操作设备的 sn : $(cat /writable/.deviceID)" #输出设备snecho -e "当前设备架构: $(arch)\n" #输出设备架构
#判断是否需要执行脚本
if grep -i 'exitcode 201' /writable/agent-new/agent.log | tail -n 10 #判断业务部署日志是否有201的报错 then #有201报错的情况下 : #不做任何输出 else #无201报错的情况下 echo -e "\e[1;31m 该设备未出现过 201 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
#执行脚本
if dmesg -T | grep ' error ' | grep "EXT4-fs" > /dev/null #判断日志中是否有报错信息 then #有报错信息的情况 echo -e "\e[1;31m 当前设备盘质量出现问题,需更换硬盘!!! \e[0m\n" #输出问题信息 read -p "是否查看报错信息?(y/n)" ERROR #交互式询问 if [ "$ERROR" == "y" ] #判断是否查看报错信息 then #查看报错信息的情况 dmesg -T | grep error | grep "EXT4-fs" #输出报错信息 fi else #无报错信息的情况 echo "硬盘当前状态无异常" #输出无异常fi
if [ ! -f "/lib/systemd/system/docker.service" ] #判断docker的服务文件是否不存在 then #若不存在 echo -e "\e[1;31m docker服务不存在,需要下载docker!!! \e[0m\n" #输出报错信息 apt-get update #更新apt源 apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin #安装有关docker的软件包 if $(docker -v) #判断docker下载是否成功 then #若成功 echo "docker 服务下载完成,重新下发业务" #输出信息 exit 0 #正常返回 else #若失败 echo -e "\e[1;31m docker服务下载失败,需要下载docker!!! \e[0m\n" #输出报错信息 exit 2 #以2状态码返回 fifi
if [ "$DOCKER_STATUS" == "failed" ] #判断docker服务状态是否为failed then #docker服务状态是failed的情况 echo -e "\n当前设备 docker 服务状态:$DOCKER_STATUS \n" #输出当前状态 systemctl start docker 2> /dev/null #启动docker服务 if [ "$?" == "0" ] #判断docker是否重启成功 then #docker服务重启成功的情况 echo "docker服务启动成功" #输出重启成功 else #docker服务重启失败的情况 echo -e "\e[1;31m docker服务重启失败!!! \e[0m\n" #输出重启失败 apt update apt upgrade -y docker-ce fi else #docker服务状态不是failed的情况 echo -e "\n当前设备 docker 服务运行正常\n" #输出运行正常fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-223_lide.sh#———更新时间:2024-12-17———
#定义环境变量
LOG_FILE=$(ls -l /writable/agent-third/vdeploy-single.log.* | tail -n 1 | awk '{print $NF}') #定义业务部署脚本的最后一次日志输出
#执行前的输出信息
echo -e "\n当前正在操作设备的 sn : $(cat /writable/.deviceID)" #输出设备snecho -e "当前设备架构: $(arch)\n" #输出设备架构
#判断是否需要执行脚本
if grep '223:' $LOG_FILE #判断业务部署日志是否有223的报错 then #若有223报错 : #不做任何输出 else #若无223报错 echo -e "\e[1;31m 该设备未出现过 223 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
#执行脚本
if [ $(arch) == "aarch64" ] #判断架构是否为arm盒子 then #若为arm设备 VG_SIZE=$(vgs | tail -n +2 | awk '{print $6}' | awk '{gsub(/</, "", $1); print $1}') #定义逻辑卷的可用空间 BUSINESS=$(cat /writable/agent-new/agent.log | grep 'exitCode 140' | awk '{print $11}' | awk -F ']' '{print $1}' | tail -n 1) #截取到报140错误的业务 if [ -z "$BUSINESS" ] #判断截取的业务是否为空 then #若为空 for i in {1..7} #循环7次 do gunzip agent.log.$i.gz 2> /dev/null #解压业务日志压缩包 BUSINESS_FINAL=$(cat /writable/agent-new/agent.log.$i | grep 'exitCode 140' | awk '{print $11}' | awk -F ']' '{print $1}' | tail -n 1) #截取报错业务名称 if [ -n "BUSINESS_FINAL" ] #判断是否截取到业务名称 then #若截取到了 COUNT=".$i" #记录截取到的后缀 break #退出for循环 fi done else #若不为空 BUSINESS_FINAL=$BUSINESS #定义最终业务名称 fi
BUSINESS_SIZE=$(cat /writable/agent-new/agent.log$COUNT | grep "$BUSINESS_FINAL.*deploy-aarch64 " | awk -F 'deploy-aarch64 ' '{print $2}' | awk -F '\] ' '{print $1}' | jq | \ egrep '"name"|storage_size|"instance_number"' | awk -F '"' '{print $4}' | awk 'ORS=NR%3?" ":"\n"' | awk '{printf "%-30s %-10s %-0s\n",$1,$2,$3"g"}' | sort | uniq) #截取到140业务名称、实例数、占用大小信息 BUSINESS_SIZE_TOTAL=$(echo $BUSINESS_SIZE | awk '{for (i = 1; i <= NF; i += 3) {printf "%s %s %s\n", $i, $(i+1), $(i+2);}}' | awk '{print $2"\t"$3}' | awk -F 'g' '{print $1}' | awk '{product = 1;for (i=1; i<=NF; i++) {product *= $i;}sum += product;}END {print sum""}') #计算占用总和
echo -e "\n当前卷组可供使用的磁盘空间为:$VG_SIZE\n" #输出卷组空间 echo -e "正在下发报错的业务名称: $BUSINESS_FINAL\n" #输出报错业务名称 echo -e "正在下发的业务占用的空间:业务名称\t实例数\t单实例分配大小\n$BUSINESS_SIZE\n" #输出报错业务占用空间 echo -e "业务下发总大小占磁盘空间:$BUSINESS_SIZE_TOTAL g\n" #输出总占用空间
if [ $(echo "$(echo $VG_SIZE | awk -F 'g' '{print $1}') > $BUSINESS_SIZE_TOTAL" | bc) -eq 1 ] #判断卷组空间是否大于业务下发空间 then #若卷组空间大于业务下发空间 echo -e "磁盘空间充足\n" #输出空间充足 else #若卷组空间小于业务下发空间 echo -e "\e[1;31m $VG_SIZE 空间不够下发业务,需添加磁盘空间!!! \e[0m\n" #输出空间不足 fi
echo -e "当前正在占用磁盘空间的业务有:\n$(lvs | tail -n +2 | awk '{printf "%-30s %-30s\n", $1, $4""}')\n" #输出正在占用空间的业务
for i in $(lvs | tail -n +2 | grep -v "docker_root" | awk '{print $1}') #将除docker_root以外的,所有正在占有空间的业务循环便利 do if docker ps | grep $i > /dev/null #检验占用空间的业务是否在容器中运行 then #若正在运行 echo " $i 正在容器中运行" #输出正在运行 else #若不在运行 echo -e "\e[1;31m $i 卸载以及清楚逻辑卷完毕! \e[0m" #输出已清理 umount $(lsblk | grep $i | awk '{print $NF}') 2> /dev/null #解除挂载 lvremove -f /dev/$(lvs | grep $i | awk '{print $2}')/$i #删除逻辑卷 LVREMOVE=1 #标记为1 fi done
echo " " #换行 if [ "$LVREMOVE" == "1" ] #判断是否标记为1 then #若标记为1 read -p "逻辑卷清理成功,是否需要重启? (y/n)" REBOOT #交互式询问是否需要重启 if [ $REBOOT == "y" ] #判断是否需要重启 then #若需要重启 echo -e "\n已执行重启!!!" #输出重启 /sbin/reboot #重启 else #若不需要重启 echo -e "\n未重启" #输出不重启 fi else #若标记不是1 echo -e "\n无多余挂载,无需清理!!!" #输出无多余挂载 fi else #若非arm设备 ZPOOL_SIZE=$(zpool list | tail -n +2 | awk '{print $3}') #定义zpool池的可用空间
echo -e "\n当前zpool可供使用的磁盘空间为:$ZPOOL_SIZE\n" #输出zpool池空间 #问题点:如何截取业务下发需要占用的磁盘空间,方便与zpool池比较,好判断出是否因为磁盘空间不足引发的140fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/error-254_lide.sh#———更新时间:2025-02-06———
#定义环境变量
LOG_FILE=$(ls -l /writable/agent-third/vdeploy-single.log.* | tail -n 1 | awk '{print $NF}') #定义业务部署脚本的最后一次日志输出
#判断是否需要执行脚本
if grep '254:' $LOG_FILE #判断业务部署日志是否有254的报错 then #有254报错的情况下 : #不做任何输出 else #无254报错的情况下 echo -e "\e[1;31m 该设备近期未出现过 254 的报错,请检查设备!!! \e[0m\n" #错误提示 exit 1 #以1状态退出脚本fi
#脚本执行systemctl stop docker.socket #关闭docker套接字服务systemctl stop docker #关闭docker服务rm -fr /var/lib/docker #清除掉docker下的镜像、容器、卷等信息rm -fr /writable/ipfsbit-518518 #清除到业务的docker数据信息
if [ -f "/sbin/reboot" ] #判断是否有重启命令 then #若可以重启 read -p "是否需要重启? (y/n)" REBOOT #交互式询问是否需要重启 if [ $REBOOT == "y" ] #判断是否需要重启 then #若需要重启 echo -e "\n已执行重启!!!" #输出重启 /sbin/reboot #重启 else #若不需要重启 #输出不重启 echo -e "\n未重启" #输出不重启 fi else #若不能重启 echo -e "\n无法重启,需重新下发" #输出错误信息fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/clean-cache_lide.sh#———更新时间:2025-01-02———
#设置变量信息
VGS=$(vgs | tail -n +2 | awk '{print $1}') #截取卷组名称赋予变量LVS=$(lvs | tail -n +2 | awk '{print $1}') #截取逻辑卷名称赋予变量
systemctl stop docker.socket #停止docker套接字服务systemctl stop docker #停止docker服务
for i in $LVS #将逻辑卷名称遍历循环 do #循环开始 umount $(lsblk | grep $i | awk '{print $NF}') 2> /dev/null #解除挂载 lvremove -f /dev/$VGS/$i #删除逻辑卷 done #循环结束vgremove $VGS #删除卷组
if ! vgs | grep -i vg #判断卷组中是否无卷组 then #若无卷组 reboot #执行重启fi
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/container-line_lide.sh#———更新时间:2025-01-03———
#定义变量
BUSINESS=$(docker ps -a | grep -vi network | tail -n +2 | awk '{print $NF}') #将当前设备所有业务赋予变量
#脚本执行
for i in $BUSINESS #遍历所有业务 do #循环执行 echo -n $i #输出容器信息 echo " 容器在第 $(docker exec $i sh -c 'echo $LINE') 根线路" #输出该容器所在的线路 done #循环结束
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/byteone-publish_lide.sh#———更新时间:2025-01-24———
#定义环境变量
ARCH=$(arch) #定义设备架构NATWORK=$(docker ps | grep -i network | awk '{print $NF}') #截取网络容器名称FSTYPE=$(cat /writable/.fstype) #定义设备文件系统WORK_DIR=$(dirname $0)FLAG_FILE="/opt/byteone_flag"
#判断设备架构是否有误
if [ "$ARCH" == "x86_64" ] #判断设备架构是否为x86_64 then #若为x86_64 : #空运行 else #若不为x86_64 echo -e "\e[1;31m 该设备非X86设备,请检查设备!!! \e[0m\n" #输出错误信息 exit 1 #以1状态码返回fi
#脚本执行
mkdir /opt/oort > /dev/null 2>&1 #创建oopt目录echo "pi_province_support=$1" > /opt/oort/province_support_info #将调度信息写入文件echo "pi_slots_support=$2" >> /opt/oort/province_support_info #将跑量区间写入文件
if [ "$FSTYPE" != "xfs" ] #判断设备文件系统是否不为xfs then #若不为xfs echo xfs > /writable/.fstype #将文件系统设为xfs aio -m dec -i /writable/agent-new/config/vendor.yaml -o /writable/agent-new/config/vendor.yaml.bak #解压出vendor.yaml文件 sed -i 's/\<1\>/0/g' /writable/agent-new/config/vendor.yaml.bak #将自动AI的参数改为0 aio -m enc -i /writable/agent-new/config/vendor.yaml.bak -o /writable/agent-new/config/vendor.yaml #更改后压缩回vendor.yaml文件 rm -fr /writable/agent-new/config/vendor.yaml.bak #删除多余解压文件 systemctl restart agent-new #重启agent服务fi
if [ -n "$network" ] #判断网络容器是否存在 then #若存在 docker stop -t 45 $network #停止容器 echo > 76 /root/pppoe/.disable_mark_ip_rule #创建新的网络模式,采用IP分流 sleep 3 #暂停三秒 [[ -n "$network" ]] && docker start $network #启动容器fi
chmod +x $WORK_DIR/initlvmdevbox.sh $WORK_DIR/toutiao_info #加入可执行权限
if [ ! -f "/opt/byteone_flag" ] then $WORK_DIR/initlvmdevbox.sh init > /dev/null 2>&1 #执行检测脚本 echo 76 > /opt/byteone_flagfi
source /etc/profile #加载全局变量$WORK_DIR/toutiao_info #执行上机脚本
xxxxxxxxxx
#脚本下载地址:http://dedeku.top/script/byteone-clean_lide.sh#———更新时间:2025-01-21———
#定义环境变量
ARCH=$(arch) #定义设备架构FSTYPE=$(cat /writable/.fstype) #定义设备文件系统NATWORK=$(docker ps | grep -i network | awk '{print $NF}') #截取网络容器名称
#判断设备架构是否有误
if [ "$ARCH" == "x86_64" ] #判断设备架构是否为x86_64 then #若为x86_64 : #空运行 else #若不为x86_64 echo -e "\e[1;31m 该设备非X86设备,请检查设备!!! \e[0m\n" #输出错误信息 exit 1 #以1状态码返回fi
#脚本执行
if [ "$FSTYPE" = "xfs" ] ##判断设备架构是否为x86_64 then #若不为xfs echo zfs > /writable/.fstype #将文件系统设为zfs aio -m dec -i /writable/agent-new/config/vendor.yaml -o /writable/agent-new/config/vendor.yaml.bak #解压出vendor.yaml文件 sed -i 's/\<0\>/1/g' /writable/agent-new/config/vendor.yaml.bak #将自动AI的参数改为1 aio -m enc -i /writable/agent-new/config/vendor.yaml.bak -o /writable/agent-new/config/vendor.yaml #更改后压缩回vendor.yaml文件 rm -fr /writable/agent-new/config/vendor.yaml.bak /writable/agent-plugin/bm4ask #删除多余解压文件 systemctl restart agent-new #重启agent服务fi
if [ -n "$network" ] #判断网络容器是否存在 then #若存在 docker stop -t 45 $network #停止容器 rm -fr /root/pppoe/.disable_mark_ip_rule #创建新的网络模式,采用IP分流 sleep 3 #暂停三秒 [[ -n "$network" ]] && docker start $network #启动容器fi
/usr/bin/diskManager_zfs.sh > /dev/null 2>&1 #重组zpool池
xxxxxxxxxx
# 获取所有Docker容器名称containers=$(docker ps -a --format '{{.Names}}') #将所有在跑的业务名称赋予变量
# 存储不包含 "Network" 的分类categories=() #创建一个空数组
# 遍历所有容器名称for container in $containers; do #遍历所有在跑的业务 if [[ $container != *"Network"* ]]; then #判断若在跑的业务不为网络容器 category=$(echo "$container" | cut -d'_' -f1,2) #将末尾的实例数去掉,并赋予变量 if [[ ! " ${categories[@]} " =~ " ${category} " ]]; then #判断若业务数组的元素不包含当前业务 categories+=("$category") #将该业务加入数组当中 fi fidone
# 执行docker stop和docker rm命令for category in "${categories[@]}"; do #遍历业务数组中的所有业务 docker stop $(eval echo "${category}_{1..1000}") #将所有业务停止 docker rm $(eval echo "${category}_{1..1000}") #将所有业务容器删除done
docker rmi $(docker images --format '{{.Repository}}:{{.Tag}}' | grep -v "^network") #删除除网络外的其他业务镜像
FILE_SYSTEM_TYPE=$(cat /writable/.fstype) #将文件系统类型赋予变量
if [[ "$FILE_SYSTEM_TYPE" == "zfs" ]]; then #判断若文件系统为zfs while read -r line; do #将传递的内容逐行输出 dataset_name=$(echo $line | awk '{print $1}') #截取存储池名称赋予变量 if [[ "$dataset_name" != "storage_pool" ]]; then #判断若存储池名称不为storage_pool zfs destroy -r "$dataset_name" #递归删除该数据集及其所有的子数据集 fi done < <(zfs list -H) #将所有ZFS数据集,去掉标题行之后传递给whileelif [[ "$FILE_SYSTEM_TYPE" == "lvm" ]]; then #判断若文件系统为lvm lvdisplay --columns -o lv_path,lv_name | while read -r line; do #列出所有LVM逻辑卷的路径和名称信息 lv_path=$(echo $line | awk '{print $1}') #将逻辑卷的路径赋予变量 lv_name=$(echo $line | awk '{print $2}') #将逻辑卷的名称赋予变量 if [[ "$lv_name" != "docker_root" ]]; then #判断若逻辑卷的名称不为docker_root umount "$lv_path" || true #卸载该逻辑卷,如果卸载失败,则继续执行后续操作 lvremove -y "$lv_path" #删除该逻辑卷 fi donefi
#房老师让加的sqlite3 /writable/agent-new/agent.db "delete from tag where type='business' and id != 'network'" #从/writable/agent-new/agent.db数据库中的tag表删除所有type字段为'business'且id字段不等于'network'的记录
systemctl stop netbox_daemon.service > /dev/null 2>&1 #停止netbox_daemon.service的系统服务,并将其输出重定向if [ -e /usr/local/by-daemon/netbox_daemon.sh ];then #判断若/usr/local/by-daemon/netbox_daemon.sh脚本存在 /usr/local/by-daemon/netbox_daemon.sh stop > /dev/null 2>&1fisleep 10 #暂停10秒
rm -rf /opt/oort /etc/device.json /etc/deviceid /etc/cron.d/stop_ksc-kepler /usr/local/by-agent /usr/local/by-daemon /usr/local/by-network_proxy /usr/local/by-vapi /usr/local/by-watcher /usr/lib/systemd/system/netbox_daemon.service > /dev/null 2>&1 #删除文件及目录systemctl daemon-reload #重新加载systemdcontainer=$(/usr/bin/docker ps --filter name=byte-btvdp -q) #将byte-btvdp容器的容器ID赋予变量if [ -n "$container" ]; then #判断若容器ID变量为非空 docker rm -f $container #强制删除容器firm -rf /var/log.hdd/agent_plugin /var/log.hdd/daemon_log /var/log.hdd/by_agent_log /ddbr > /dev/null 2>&1 #删除文件及目录
xxxxxxxxxxzpool status -v > /opt/zpool2.log 2>&1 #将ZFS存储池的当前状态覆盖至/opt/zpool2.log文件当中(记录作用)zpool history > /opt/zpool.log 2>&1 #将ZFS存储池的历史信息覆盖至/opt/zpool2.log文件当中(记录作用)
yum -y remove zfs-dracut #使用yum包管理器来移除名为zfs-dracut软件包(zfs-dracut是一个用于在Linux系统中支持ZFS文件系统的软件包)rm -fr /usr/lib/dracut/modules.d/90zfs/ #将包含与ZFS文件系统相关的Dracut模块删除
wget -O /root/kernel-ml-6.1.12-5.el7.x86_64.rpm http://fae-cdn.linkfog.cn/huanglue/6.1.12-5-new/kernel-ml-6.1.12-5.el7.x86_64.rpm #下载内核6.1.12-5至本地yum localinstall --exclude=systemd --disablerepo=docker-ce* -y /root/kernel-ml-6.1.12-5.el7.x86_64.rpm > /opt/upgrade_kernel.log 2>&1 #采用本地安装内核rpm,在安装过程中排除systemd包的更新,禁用以docker-ce开头的所有仓库,并将输出信息记录在/opt/upgrade_kernel.log中ls /boot/*6.1.12-5* >> /opt/upgrade_kernel.log 2>&1 #将所有关于6.1.12-5的文件记录在/opt/upgrade_kernel.log中
rm -f /boot/vmlinuz-*-rescue-* #删除/boot/目录中与恢复模式相关的内核文件(恢复模式内核通常在系统启动时遇到问题时使用,用来修复系统)rm -f /boot/initramfs-*-rescue* #删除/boot/目录下与恢复模式相关的initramfs文件(initramfs文件通常包含启动内核所需要的必要文件,而恢复模式的initramfs映像用于在系统无法正常启动时提供修复工具)
sed -i'' 's/crashkernel=auto//g' /etc/default/grub #删除/etc/default/grub文件中所有的crashkernel=auto字段(crashkernel参数用于指定在启动时为内核崩溃转储预留的内存空间,删除该设置可能意味着系统不再自动分配该内存区域。)
wget https://cdn.linkfog.cn/kernel/10_linux -O /etc/grub.d/10_linux #从指定的URL下载文件并将其保存为/etc/grub.d/10_linux文件(是Linux系统中GRUB引导加载器的配置目录中的一个文件)
grub2-mkconfig -o /boot/grub2/grub.cfggrub2-editenv /boot/grub2/grubenv set saved_entry=0
for _dir in $(ls /boot/efi/EFI/) do grub2-mkconfig -o /boot/efi/EFI/"${_dir}"/grub.cfg grub2-editenv /boot/efi/EFI/"${_dir}"/grubenv set saved_entry=0 done
systemctl stop dockersystemctl stop docker.socket
systemctl disable dockersystemctl disable docker.socket
systemctl disable netbox_daemon
if ls /boot/ | grep -q "initramfs-6.1.12-5.*" then systemctl reboot else echo "没有找到匹配的 initramfs 文件。"fi
xxxxxxxxxx
overlay_mounts=$(mount | grep overlay | awk '{print $3}') #截取到overlay挂载信息,并赋予标量
if [ -z "$overlay_mounts" ]; then #判断若挂载信息为空 echo "没有找到任何 overlay 挂载点。" #输出信息else #若不为空 for mount_point in $overlay_mounts; do #将所有挂载信息循环遍历 if [[ $mount_point == *"docker_root"* ]]; then #若挂载信息中包含docker_root continue #跳过当前循环 fi echo "正在卸载 $mount_point ..." #输出信息 umount $mount_point #卸载 if [ $? -eq 0 ]; then #判断若上一条命令执行成功 echo "$mount_point 卸载成功。" #输出信息 else #若不成功 echo "$mount_point 卸载失败。" #输出信息 fi done
echo "所有 overlay 文件系统已卸载。" #输出信息
fi
systemctl stop docker.socket docker #停止docker的相关服务rm -rf /var/lib/docker #清理docker数据库
umount /writable/ipfsbit-518518/docker #卸载业务中的dockerrm -rf /writable/ipfsbit-518518/docker/* #删除业务中的dockerrm -rf /var/log.hdd #删除日志rm -rf /data0 #删除业务数据
available_space=$(df / | awk 'NR==2 {print $4}') #截取到根分区的可用空间,并赋予变量available_space_gb=$(echo "scale=2; $available_space / 1024 / 1024" | bc) #将可用空间转化为GB为单位,保留两位小数,并赋予变量echo $available_space_gb #输出可用空间threshold=3.0 #将门槛变量设为3.0result=$(echo "$available_space_gb > $threshold" | bc) #判断可用空间是否大于3.0G,并将结果赋予变量if [[ $result == 1 ]]; then #判断若可用变量大于3.0G echo "root disk available > 3G" #输出信息 exit 0 #以0状态码退出fi
parent_dir="hello" #将父目录默认定义为hellowhile read -r mount_point; do #从输入中逐行读取数据,并不会被转义处理,每次读取到一行时,将该行存储在变量中 parent_dir=$(dirname "$mount_point") #读取数据的父目录并赋予变量 if [[ $parent_dir == *"writable"* ]]; then #判断若父目录中包含writable echo "!!!!!!!! $parent_dir" #输出信息 break #退出循环,不再继续检查后续的挂载点 fidone < <(df -h | awk '/^\/dev\/mapper/ {print $6}') #将磁盘空间中截取以/dev/mapper开头的行,并向循环中传递数据
echo "Outside loop, parent_dir is: $parent_dir" #输出父目录信息
while read -r line; do #从输入中逐行读取数据,并不会被转义处理,每次读取到一行时,将该行存储在变量中 device=$(echo "$line" | awk '{print $1}') #截取挂载中的设备,并赋予变量 mount_point=$(echo "$line" | awk '{print $2}') #截取挂载中的挂载点,并赋予变量
if [[ "$device" == /dev/mapper/* ]]; then #判断若截取挂载中的设备以/dev/mapper/开头 echo "Unmounting $mount_point (device: $device)" #输出卸载的挂载点和设备 umount -l "$mount_point" #慢卸载挂载点
if [[ $? -eq 0 ]]; then #判断若上一条命令执行成功 echo "Successfully unmounted $mount_point" #输出信息 else #若不成功 echo "Failed to unmount $mount_point" #输出信息 fi fidone < /proc/mounts #将系统的挂载信息向循环中传递数据
if [[ "$parent_dir" == *"writable"* ]]; then #判断若父目录中包含writable echo "rm -rf ${parent_dir}/*" #输出删除信息 rm -rf "$parent_dir"/* #强制删除父目录下的所有数据 echo $? #输出执行的返回代码fi
available_space=$(df / | awk 'NR==2 {print $4}') #截取到根分区的可用空间,并赋予变量available_space_gb=$(echo "scale=2; $available_space / 1024 / 1024" | bc) #将可用空间转化为GB为单位,保留两位小数,并赋予变量echo $available_space_gb #输出可用空间threshold=3.0 #将门槛变量设为3.0result=$(echo "$available_space_gb > $threshold" | bc) #判断可用空间是否大于3.0G,并将结果赋予变量if [[ $result == 1 ]]; then #判断若可用变量大于3.0G echo "root disk available > 3G" #输出信息 exit 0 #以0状态码退出fi
xxxxxxxxxx
usage() { echo "check -v | --vendor) vendor -o | --organization) organization number -c | --channelid) channel id -h | --help) print this info " exit 0}
option=$(getopt -o v:p:o:m:t:c:l:h --long vendor:,pipe:,organization:,mode:,packtype:,channelid:,amlogic:,help -- "$@")
eval set -- "$option"
while truedo case $1 in -v | --vendor) shift; u_vendor=$1 ; shift ;; -o | --organization) shift; u_organization=$1 ; shift ;; -c | --channelid) shift; u_channelid=$1 ; shift ;; -h | --help ) usage ;; --) shift ; break ;; *) usage ;; esacdone
mkdir -p /etc/sysconfigcat << EOF > /etc/sysconfig/dianxin.envsCHANNELID="${u_channelid:-CBOCYIZA03B1420230808174053399}"ORGCODE="${u_organization:-A03B14}"STORAGE_DIRECTORY="/storage"STORAGE_SIZE="100"VENDOR="${u_vendor:-WKY}"ONLY_STORAGE_DISK="${u_only_disk:-false}"SWAPON="${u_swapon:-false}"ARCH="aarch64"EOF
install_arm64() { docker_version=$(docker --version | awk '{print $3}' | sed 's/,//g' 2>/dev/null) if [[ "$docker_version" < "20.00.00" ]] then apt update apt install -y jq bc ca-certificates gnupg lsb-release xz-utils bzip2 unzip zip curl -fsSL https://cdn.bkdomain.cn/product/terminal/get-docker.sh | bash -s docker --mirror Aliyun fi
wget https://cdn2.bkdomain.cn/system-scripts/dianxin-deploy.deb -O /tmp/dianxin-deploy.deb dpkg -i /tmp/dianxin-deploy.deb
if ! grep -q 'systemd.unified_cgroup_hierarchy=0' /proc/cmdline then reboot else systemctl start dianxin.service fi}
install_armhf() { docker_version=$(docker --version | awk '{print $3}' | sed 's/,//g' 2>/dev/null) if [[ "$docker_version" < "20.00.00" ]] then apt update apt install -y jq bc ca-certificates gnupg lsb-release xz-utils bzip2 unzip zip wget https://cdn2.bkdomain.cn/system-scripts/ubuntu_bionic_docker-ce_armhf_stable.tar.bz2 -o /opt/ubuntu_bionic_docker-ce_armhf_stable.tar.bz2 tar jxf /opt/ubuntu_bionic_docker-ce_armhf_stable.tar.bz2 cd /opt/ubuntu_bionic_docker-ce_armhf_stable dpkg -i containerd.io_1.6.9-1_armhf.deb \ docker-ce_24.0.2-1~ubuntu.18.04~bionic_armhf.deb \ docker-ce-rootless-extras_24.0.2-1~ubuntu.18.04~bionic_armhf.deb \ docker-ce-cli_24.0.2-1~ubuntu.18.04~bionic_armhf.deb \ docker-buildx-plugin_0.10.5-1~ubuntu.18.04~bionic_armhf.deb \ docker-compose-plugin_2.18.1-1~ubuntu.18.04~bionic_armhf.deb
systemctl eaneble --now docker.socket docker ps fi
wget https://cdn2.bkdomain.cn/system-scripts/dianxin-deploy-armhf.deb -O /tmp/dianxin-deploy-armhf.deb dpkg -i /tmp/dianxin-deploy-armhf.deb
if [[ ! -e /sys/fs/cgroup/net_cls/net_cls.classid ]] then reboot else systemctl start dianxin.service fi}
dpkg_arch=$(dpkg --print-architecture)
if [[ "$dpkg_arch" == "armhf" ]]then install_armhfelif [[ "$dpkg_arch" == "arm64" ]]then install_arm64fi
xxxxxxxxxx
usage() { echo "Usage: $0 [-s <publish/clean>] [-l <0/1/2>] [-r <00:00-23:59>] 或直接传递JSON参数" #输出使用师范 echo "示例:" #输出信息 echo " 传统参数: $0 -s publish -l 1 -r 04:00-06:00" #输出实例 echo " JSON参数: $0 '{\"s\":\"publish\",\"l\":\"1\",\"r\":\"04:00-06:00\"}'" #输出实例 exit 1 #以1状态码返回} #帮助函数
WORK_DIR=$(dirname "$0") #定义工作目录NETWORK=$(docker ps | grep -i network | awk '{print $NF}') #截取网络容器名称FSTYPE=$(cat /writable/.fstype) #定义设备文件系统FLAG_FILE="/opt/byteone_flag" #定义标记文件
LIMIT_AREA="0" #将默认调度范围为全国RUN_CONTROL="00:00-23:59" #默认运行时间为全天SIGNAL="" #将信号变量默认为空
MAIL_TARGET="" #定义邮箱地址为空
# 检查是否传递参数if [ $# -eq 0 ]; then #判断若传递的参数个数为0 usage #调用帮助函数fi
# 判断第一个参数是否是JSON格式if echo "$1" | jq -e . >/dev/null 2>&1; then #判断若第一个参数为json格式 # 解析JSON参数 JSON_PARAM="$1" shift # 移除JSON参数 #参数左移
# 检查是否还有其他参数 if [ $# -ne 0 ]; then #判断若传递的参数个数为0 echo "错误:JSON参数模式下不能混合使用其他参数" #输出错误信息 usage #调用帮助函数 fi
# 提取JSON字段(兼容大小写和不同键名) SIGNAL=$(echo "$JSON_PARAM" | jq -r '.s // .signal // empty') #截取信号参数,赋予变量 LIMIT_AREA=$(echo "$JSON_PARAM" | jq -r '.l // .limit_area // "0"') #截取调度范围参数,赋予变量 RUN_CONTROL=$(echo "$JSON_PARAM" | jq -r '.r // .run_control // "00:00-23:59"') #截取运行时间参数,赋予变量 MAIL_TARGET=$(echo "$JSON_PARAM" | jq -r '.r // .mail // empty') #截取邮箱地址参数,赋予变量
else # 解析传统参数 PARSED_ARGUMENTS=$(getopt -a -n "$0" -o s:l:r:m: --long help,signal:,limit_area:,run_control:,mail: -- "$@") #解析传入的命令行参数,并将解析后的结果存储在变量中 eval set -- "$PARSED_ARGUMENTS" #将getopt解析出的命令行参数重新设置为脚本的位置参数 while : #做出无限循环 do #执行 case "$1" in #判断输入的选项 -s | --signal) SIGNAL="$2"; shift 2 ;; #定义信号后左移 -l | --limit_area) LIMIT_AREA="$2"; shift 2 ;; #定义调度范围后左移 -r | --run_control) RUN_CONTROL="$2"; shift 2 ;; #定义运行时间后左移 -m | --mail) MAIL_TARGET="$2"; shift 2 ;; #定义邮箱地址后左移 --help) usage ;; #调用方法函数 --) shift; break ;; #左移后退出循环 *) echo "解析参数错误!"; usage ;; #输出错误信息,调用方法函数 esac done #结束
fi
# 检查必填参数if [ -z "$SIGNAL" ]; then #判断若信号变量为空值 echo "必须指定 signal 参数" #输出错误信息 usage #调用方法函数fi
restart_agent() { sleep 10 #暂停10秒 systemctl restart agent-new #重启agent-new服务} #重启agent函数
clean_business() { # 获取所有Docker容器名称 containers=$(docker ps -a --format '{{.Names}}') #将所有在跑的业务名称赋予变量 # 存储不包含 "Network" 的分类 categories=() #创建一个空数组
# 遍历所有容器名称 for container in $containers; do #遍历所有在跑的业务 if [[ $container != *"Network"* ]]; then #判断若在跑的业务不为网络容器 category=$(echo "$container" | cut -d'_' -f1,2) #将末尾的实例数去掉,并赋予变量 if [[ ! " ${categories[@]} " =~ " ${category} " ]]; then #判断若业务数组的元素不包含当前业务 categories+=("$category") #将该业务加入数组当中 fi fi done
# 执行docker stop和docker rm命令 for category in "${categories[@]}"; do #遍历业务数组中的所有业务 docker stop $(eval echo "${category}_{1..1000}") #将所有业务停止 docker rm $(eval echo "${category}_{1..1000}") #将所有业务容器删除 done
docker rmi $(docker images --format '{{.Repository}}:{{.Tag}}' | grep -v "^network") #删除除网络外的其他业务镜像
if [[ "$FSTYPE" == "zfs" ]]; then #判断若文件系统为zfs while read -r line; do #将传递的内容逐行输出 dataset_name=$(echo $line | awk '{print $1}') #截取存储池名称赋予变量 if [[ "$dataset_name" != "storage_pool" ]]; then #判断若存储池名称不为storage_pool zfs destroy -r "$dataset_name" #递归删除该数据集及其所有的子数据集 fi done < <(zfs list -H) #将所有ZFS数据集,去掉标题行之后传递给while elif [[ "$FSTYPE" == "lvm" ]]; then #判断若文件系统为lvm lvdisplay --columns -o lv_path,lv_name | while read -r line; do #列出所有LVM逻辑卷的路径和名称信息 lv_path=$(echo $line | awk '{print $1}') #将逻辑卷的路径赋予变量 lv_name=$(echo $line | awk '{print $2}') #将逻辑卷的名称赋予变量 if [[ "$lv_name" != "docker_root" ]]; then #判断若逻辑卷的名称不为docker_root umount "$lv_path" || true #卸载该逻辑卷,如果卸载失败,则继续执行后续操作 lvremove -y "$lv_path" #删除该逻辑卷 fi done fi
sqlite3 /writable/agent-new/agent.db "delete from tag where type='business' and id != 'network'" #从/writable/agent-new/agent.db数据库中的tag表删除所有type字段为'business'且id字段不等于'network'的记录
systemctl stop netbox_daemon.service > /dev/null 2>&1 #停止netbox_daemon.service的系统服务,并将其输出重定向 if [ -e /usr/local/by-daemon/netbox_daemon.sh ];then #判断若/usr/local/by-daemon/netbox_daemon.sh脚本存在 /usr/local/by-daemon/netbox_daemon.sh stop > /dev/null 2>&1 fi sleep 10 #暂停10秒
rm -rf /opt/oort /etc/device.json /etc/deviceid /etc/cron.d/stop_ksc-kepler /usr/local/by-agent /usr/local/by-daemon /usr/local/by-network_proxy /usr/local/by-vapi /usr/local/by-watcher /usr/lib/systemd/system/netbox_daemon.service > /dev/null 2>&1 #删除文件及目录 systemctl daemon-reload #重新加载systemd container=$(/usr/bin/docker ps --filter name=byte-btvdp -q) #将byte-btvdp容器的容器ID赋予变量 if [ -n "$container" ]; then #判断若容器ID变量为非空 docker rm -f $container #强制删除容器 fi rm -rf /var/log.hdd/agent_plugin /var/log.hdd/daemon_log /var/log.hdd/by_agent_log /ddbr > /dev/null 2>&1 #删除文件及目录} #清理业务函数
publish_byteone() { chmod +x $WORK_DIR/initlvmdevbox.sh $WORK_DIR/toutiao_info #加入可执行权限
if [ -f $FLAG_FILE ] && [ $FSTYPE == "xfs" ] #判断是否标志文件存在,并且文件系统为xfs then #若都满足 $WORK_DIR/toutiao_info $MAIL_TARGET exit 0 #正常退出 fi touch $FLAG_FILE #创建标记文件
aio -m dec -i /writable/agent-new/config/vendor.yaml -o /writable/agent-new/config/vendor.yaml.bak #解压出vendor.yaml文件 sed -i "s/isNeedAi: 1/isNeedAi: 0/g" /writable/agent-new/config/vendor.yaml.bak #将自动AI改为不AI aio -m enc -i /writable/agent-new/config/vendor.yaml.bak -o /writable/agent-new/config/vendor.yaml #更改后压缩回vendor.yaml文件 rm -fr /writable/agent-new/config/vendor.yaml.bak #删除多余解压文件
clean_business #调用情况业务函数 zpool destroy storage_pool #销毁zpool池
echo "判断是否有VG分区" #输出信息 if [ `docker ps -a | grep toutiao | wc -l` -gt 0 ]; #判断头条实例是否大于0 then #若大于0 echo -e "\033[1;31m 检测到字节业务停止进程 \033[0m" #输出错误信息 exit 8 #以8状态码退出 else #若不大于0 vg_name=$(vgdisplay | grep 'VG Name' | awk '{print $3}') #截取卷组名称赋予变量 if [ `vgdisplay | wc -l` -gt 0 ]; #判断卷组数量是否大于0 then #若大于0 vgremove $vgname #删除卷组 fi if [ `vgdisplay | wc -l` -gt 0 ]; #再次判断卷组数量是否大于0 then #若大于0 echo -e "\033[1;31m VG挂载未成功清除,使用vgdispaly检查 \033[0m" #输出错误信息 exit 7 #以7状态码返回 fi fi
echo "清除磁盘挂载" #输出信息 echo 1 > /writable/.disable-diskManager #标记默认硬盘管理文件 chmod -x /usr/bin/diskManager.sh #加入可执行权限 echo xfs > /writable/.fstype #将文件系统设为xfs disk_name=$(blkid -o list | grep "/writable/ipfsbit-" | awk '{print $1}') #将被使用的硬盘赋予变量 disk_name2=$(df -h | grep '/writable/ipfsbit' | awk '{print $1}') #将被挂载的硬盘赋予变量 for disk1 in $disk_name $disk_name2 #将被占用的盘遍历循环 do #循环 umount $disk1 #将盘卸载 done #结束 sys_dev=$(eval $(lsblk -o MOUNTPOINT,PKNAME -P | grep 'MOUNTPOINT="/"'); echo $PKNAME | sed 's/[0-9]*$//') #截取到系统盘,并赋予遍历 dev=$(lsblk -dpno name,tran | grep -v loop | grep -v $sys_dev | grep -v sr | grep -v fd | grep -v usb$ | grep -v mmc| grep -v zram| grep -v zd|awk '{print $1}') #截取到除系统盘以外的其他盘 for disk in $dev #将其他盘遍历循环 do #循环 mkfs.xfs -f $disk #将盘格式化 done #结束 #判断磁盘挂载 if [ `df -h | grep /writable |wc -l` -gt 0 ]; #判断被使用的挂载硬盘是否大于0 then #若大于0 echo -e "\033[1;31m 磁盘挂载未清除,退出脚本执行 \033[0m" #输出错误信息 exit 9 #以9状态码退出 fi
mkdir /opt/oort > /dev/null 2>&1 #创建oopt目录 echo "pi_province_support=$LIMIT_AREA" > /opt/oort/province_support_info #将调度信息写入文件 echo "pi_slots_support=$RUN_CONTROL" >> /opt/oort/province_support_info #将跑量区间写入文件
echo 76 > /root/pppoe/.disable_mark_ip_rule #创建新的网络模式,采用IP分流
if [ -n "$NETWORK" ] #判断网络容器是否存在 then #若存在 docker stop -t 45 $NETWORK #停止容器 sleep 3 #暂停三秒 docker start $NETWORK #启动容器 fi
$WORK_DIR/initlvmdevbox.sh init > /dev/null 2>&1 #执行检测脚本
source /etc/profile #加载全局变量 $WORK_DIR/toutiao_info $MAIL_TARGET #执行上机脚本} #业务下发函数
clean_byteone() {
clean_business #调用清理业务函数 echo 0 > /writable/.disable-diskManager #标记默认硬盘管理文件 chmod +x /usr/bin/diskManager.sh #加入可执行权限 echo zfs > /writable/.fstype #将文件系统设为zfs
if [ -n "$NETWORK" ] #判断网络容器是否存在 then #若存在 docker stop -t 45 $NETWORK #停止容器 rm -fr /root/pppoe/.disable_mark_ip_rule #创建新的网络模式,采用IP分流 sleep 3 #暂停三秒 docker start $NETWORK #启动容器 fi
/usr/bin/diskManager_zfs.sh #重组zpool池
aio -m dec -i /writable/agent-new/config/vendor.yaml -o /writable/agent-new/config/vendor.yaml.bak #解压出vendor.yaml文件 sed -i 's/\<0\>/1/g' /writable/agent-new/config/vendor.yaml.bak #将自动AI的参数改为1 aio -m enc -i /writable/agent-new/config/vendor.yaml.bak -o /writable/agent-new/config/vendor.yaml #更改后压缩回vendor.yaml文件 rm -fr /writable/agent-new/config/vendor.yaml.bak #输出解压文件
rm -rf $FLAG_FILE #删除标记文件
} #业务下机函数
# 输出解析结果echo "=============== 参数解析结果 ===============" #输出信息echo "操作类型 (SIGNAL): $SIGNAL" #输出信号echo "限制区域 (LIMIT_AREA): $LIMIT_AREA" #输出调度范围echo "运行时间 (RUN_CONTROL): $RUN_CONTROL" #输出运行时间
case $SIGNAL in #对信号进行匹配 "publish") #若信号匹配到下发 publish_byteone #调用业务下发函数 restart_agent & #后台调用重启agent函数 ;; "clean") #若信号匹配到清理 clean_byteone #调用业务清理函数 restart_agent & #后台调用重启agent函数 ;; *) #若为其他 printf "Error: param signal error!\n" #输出错误信息 usage #调用帮助函数 ;;esac
exit 0 #正常退出
xxxxxxxxxxset -e #设备脚本在遇到错误时立即退出# Docker Engine for Linux installation script. #Docker Engine for Linux安装脚本## This script is intended as a convenient way to configure docker's package #此脚本旨在作为配置docker包的便捷方式# repositories and to install Docker Engine, This script is not recommended #仓库和安装Docker引擎,不建议使用此脚本# for production environments. Before running this script, make yourself familiar #对于生产环境。在运行此脚本之前,熟悉# with potential risks and limitations, and refer to the installation manual #潜在的风险和局限性,并参考安装手册# at https://docs.docker.com/engine/install/ for alternative installation methods. #https://docs.docker.com/engine/install/用于替代安装方法。## The script: #脚本:## - Requires `root` or `sudo` privileges to run. #需要“root”或“sudo”权限才能运行。# - Attempts to detect your Linux distribution and version and configure your #尝试检测您的Linux发行版和版本,并配置您的# package management system for you. 您的包管理系统。# - Doesn't allow you to customize most installation parameters. #不允许您自定义大多数安装参数。# - Installs dependencies and recommendations without asking for confirmation. #无需确认即可安装依赖项和建议。# - Installs the latest stable release (by default) of Docker CLI, Docker Engine, #安装Docker CLI、Docker Engine的最新稳定版本(默认),# Docker Buildx, Docker Compose, containerd, and runc. When using this script #Docker Buildx、Docker Compose、containerd和runc。当使用此脚本# to provision a machine, this may result in unexpected major version upgrades #来配置机器时,这可能会导致意外的主要版本升级# of these packages. Always test upgrades in a test environment before #这些包。始终在测试环境中测试升级# deploying to your production systems. #部署到您的生产系统。# - Isn't designed to upgrade an existing Docker installation. When using the #不是为升级现有的Docker安装而设计的。使用时# script to update an existing installation, dependencies may not be updated #更新现有安装的脚本,依赖关系可能不会更新# to the expected version, resulting in outdated versions. #到预期版本,导致版本过时。## Source code is available at https://github.com/docker/docker-install/ #源代码可在https://github.com/docker/docker-install/## Usage #使用方法# ==============================================================================## To install the latest stable versions of Docker CLI, Docker Engine, and their #安装最新稳定版本的Docker CLI、Docker Engine及其# dependencies: #依赖关系:## 1. download the script #1.下载脚本## $ curl -fsSL https://get.docker.com -o install-docker.sh #下载脚本## 2. verify the script's content #2.验证脚本的内容## $ cat install-docker.sh #查看脚本## 3. run the script with --dry-run to verify the steps it executes #3.使用--dry-run运行脚本,以验证它执行的步骤## $ sh install-docker.sh --dry-run #空运行执行## 4. run the script either as root, or using sudo to perform the installation. #4.以root身份运行脚本,或使用sudo执行安装。## $ sudo sh install-docker.sh #sudo执行脚本## Command-line options #命令行选项# ==============================================================================## --version <VERSION> #选项# Use the --version option to install a specific version, for example: #使用--version选项安装特定版本,例如:## $ sudo sh install-docker.sh --version 23.0 #安装特定版本## --channel <stable|test> #选项## Use the --channel option to install from an alternative installation channel. #使用--channel选项从其他安装通道安装。# The following example installs the latest versions from the "test" channel, #以下示例从“测试”通道安装最新版本,# which includes pre-releases (alpha, beta, rc): #其中包括预发布(alpha、beta、rc):## $ sudo sh install-docker.sh --channel test #从“测试”通道安装最新版本## Alternatively, use the script at https://test.docker.com, which uses the test #或者,使用以下脚本https://test.docker.com,使用该测试# channel as default. #默认通道。## --mirror <Aliyun|AzureChinaCloud> #选项## Use the --mirror option to install from a mirror supported by this script. #使用--mirror选项从此脚本支持的镜像安装。# Available mirrors are "Aliyun" (https://mirrors.aliyun.com/docker-ce), and #可用的镜像是“阿里云”(https://mirrors.aliyun.com/docker-ce),和# "AzureChinaCloud" (https://mirror.azure.cn/docker-ce), for example: #AzureCloud”https://mirror.azure.cn/docker-ce例如:## $ sudo sh install-docker.sh --mirror AzureChinaCloud #采用AzureChinaCloud镜像安装## ==============================================================================
# Git commit from https://github.com/docker/docker-install when #Git提交自https://github.com/docker/docker-install# the script was uploaded (Should only be modified by upload job): #脚本已上传(只能由上传作业修改):SCRIPT_COMMIT_SHA="6d9743e9656cc56f699a64800b098d5ea5a60020" #定义脚本哈希值
# strip "v" prefix if present #带“v”前缀(如果存在)VERSION="${VERSION#v}" #将变量去V
# The channel to install from: #要从以下位置安装的通道:# * stable #稳定版# * test 测试版# * edge (deprecated) #边缘版(已弃用)# * nightly (deprecated) #夜间版(已弃用)DEFAULT_CHANNEL_VALUE="stable" #将默认channel设置为stableif [ -z "$CHANNEL" ]; then #如果CHANNEL变量为空 CHANNEL=$DEFAULT_CHANNEL_VALUE #设置该变量为默认值fi
DEFAULT_DOWNLOAD_URL="https://download.docker.com" #设置默认下载地址if [ -z "$DOWNLOAD_URL" ]; then #如果下载URL变量为空 DOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL #设置该变量为默认值fi
DEFAULT_REPO_FILE="docker-ce.repo" #设置默认下载仓库if [ -z "$REPO_FILE" ]; then #如果下载仓库变量为空 REPO_FILE="$DEFAULT_REPO_FILE" #设置该变量为默认值fi
mirror='' #初始化镜像变量为空DRY_RUN=${DRY_RUN:-} #若变量未设置,则设置为空值while [ $# -gt 0 ]; do #循环调用输入的每一个参数 case "$1" in #判断输入的选项 --channel) #若选项为--channel CHANNEL="$2" #定义输入的值 shift #左移 ;; --dry-run) #若选项为--dry-run DRY_RUN=1 #定义输入的值 ;; #左移 --mirror) #若选项为--mirror mirror="$2" #定义输入的值 shift #左移 ;; --version) #若选项为--version VERSION="${2#v}" #定义输入的值 shift #左移 ;; --*) #若输入其他选项 echo "Illegal option $1" #输出无效的选项 ;; esac shift $(( $# > 0 ? 1 : 0 )) #如果位置参数大于0,则左移done
case "$mirror" in #判断输入的镜像名称 Aliyun) #若为阿里云 DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce" #定义阿里云的下载URL地址 ;; AzureChinaCloud) #若为微软 DOWNLOAD_URL="https://mirror.azure.cn/docker-ce" #定义微软的下载URL地址 ;; "") #若为空,不做操作 ;; *) #若为其他 >&2 echo "unknown mirror '$mirror': use either 'Aliyun', or 'AzureChinaCloud'." #提示错误信息 exit 1 #以1状态码退出 ;;esac
case "$CHANNEL" in #判断输入的CHANNEL名称 stable|test) #若为稳定或者测试,则不做操作 ;; edge|nightly) #若为edge或者nightly >&2 echo "DEPRECATED: the $CHANNEL channel has been deprecated and is no longer supported by this script." #输出错误信息 exit 1 #以1状态码退出 ;; *) #若为其他 >&2 echo "unknown CHANNEL '$CHANNEL': use either stable or test." #提示错误信息 exit 1 #以1状态码退出 ;;esac
command_exists() { #命令存在性函数 command -v "$@" > /dev/null 2>&1 #检查传递的所有命令是否存在}
# version_gte checks if the version specified in $VERSION is at least the given #version_gte检查$version中指定的版本是否至少是给定的# SemVer (Maj.Minor[.Patch]), or CalVer (YY.MM) version.It returns 0 (success) #SemVer(Maj.Minor[.Patch]),或CalVer(YY.MM)版本。返回0(成功)# if $VERSION is either unset (=latest) or newer or equal than the specified #如果$VERSION未设置(=最新)或比指定版本更新或等于指定# version, or returns 1 (fail) otherwise. #版本,否则返回1(失败)。## examples: #示例:## VERSION=23.0 #版本为23.0# version_gte 23.0 // 0 (success) #返回0(成功)# version_gte 20.10 // 0 (success) #返回0(成功)# version_gte 19.03 // 0 (success) #返回0(成功)# version_gte 21.10 // 1 (fail) #返回1(失败)version_gte() { #版本比较函数 if [ -z "$VERSION" ]; then #若判断变量为空 return 0 #返回状态0 fi eval version_compare "$VERSION" "$1" #比较两个版本的大小}
# version_compare compares two version strings (either SemVer (Major.Minor.Path), #version_compare比较两个版本字符串(SemVer(Major.Minor.Path),# or CalVer (YY.MM) version strings. It returns 0 (success) if version A is newer #或CalVer(YY.MM)版本字符串。如果版本A更新,则返回0(成功)# or equal than version B, or 1 (fail) otherwise. Patch releases and pre-release #或等于版本B,否则为1(失败)。补丁发布和预发布# (-alpha/-beta) are not taken into account #(-alpha/beta)未被考虑在内## examples: #示例:## version_compare 23.0.0 20.10 // 0 (success) #返回0(成功)# version_compare 23.0 20.10 // 0 (success) #返回0(成功)# version_compare 20.10 19.03 // 0 (success) #返回0(成功)# version_compare 20.10 20.10 // 0 (success) #返回0(成功)# version_compare 19.03 20.10 // 1 (fail) #返回1(失败)version_compare() ( #版本比较函数 set +x #关闭命令跟踪模式
yy_a="$(echo "$1" | cut -d'.' -f1)" #截取选项参数的主版本号 yy_b="$(echo "$2" | cut -d'.' -f1)" #截取给定版本的主版本号 if [ "$yy_a" -lt "$yy_b" ]; then #判断选项参数的主版本号如果比给定版本的主版本号小 return 1 #返回状态码1 fi if [ "$yy_a" -gt "$yy_b" ]; then #判断选项参数的主版本号如果比给定版本的主版本号大 return 0 #返回状态码0 fi mm_a="$(echo "$1" | cut -d'.' -f2)" #截取选项参数的次版本号 mm_b="$(echo "$2" | cut -d'.' -f2)" #截取给定版本的次版本号
# trim leading zeros to accommodate CalVer #修剪前导零以适应CalVer mm_a="${mm_a#0}" #修剪掉选项参数次版本号前面的0 mm_b="${mm_b#0}" #修剪掉给定版本次版本号前面的0
if [ "${mm_a:-0}" -lt "${mm_b:-0}" ]; then #判断选项参数的次版本号如果比给定版本的次版本号小 return 1 #返回状态码1 fi
return 0 #无误后返回状态码0)
is_dry_run() { #空运行函数 if [ -z "$DRY_RUN" ]; then #判断空运行变量若为空 return 1 #返回状态码1 else #若不为空 return 0 #返回状态码0 fi}
is_wsl() { #判断操作系统函数 case "$(uname -r)" in #获取当前系统的内核版本信息进行匹配 *microsoft* ) true ;; # WSL 2 #若包含microsoft匹配真 *Microsoft* ) true ;; # WSL 1 #若包含Microsoft匹配真 * ) false;; #否则匹配假 esac}
is_darwin() { #判断操作系统是否是macOS函数 case "$(uname -s)" in #获取当前操作系统的名称进行匹配 *darwin* ) true ;; #若包含darwin匹配真 *Darwin* ) true ;; #若包含Darwin匹配真 * ) false;; #否则匹配假 esac}
deprecation_notice() { #弃用通知函数 distro=$1 #定义发行版变量 distro_version=$2 #定义版本变量 echo #换行 printf "\033[91;1mDEPRECATION WARNING\033[0m\n" #弃用警告 printf " This Linux distribution (\033[1m%s %s\033[0m) reached end-of-life and is no longer supported by this script.\n" "$distro" "$distro_version" #这个Linux发行版的【发行版】【版本】已达到生命周期末期,不再受此脚本支持 echo " No updates or security fixes will be released for this distribution, and users are recommended" #此发行版不会发布任何更新或安全修复程序,建议用户使用 echo " to upgrade to a currently maintained version of $distro." #升级到当前维护的【发行版】版本 echo #换行 printf "Press \033[1mCtrl+C\033[0m now to abort this script, or wait for the installation to continue." #立即按Ctrl+C中止此脚本,或等待安装继续 echo #换行 sleep 10 #等待用户思考十秒}
get_distribution() { #获取Linux发行版ID函数 lsb_dist="" #发行版ID变量设置为空 # Every system that we officially support has /etc/os-release #我们官方支持的每个系统都有/etc/os版本 if [ -r /etc/os-release ]; then #判断/etc/os-release文件存在并且可读 lsb_dist="$(. /etc/os-release && echo "$ID")" #将执行后的ID变量赋予发行版ID变量 fi # Returning an empty string here should be alright since the #在这里返回一个空字符串应该没问题,因为 # case statements don't act unless you provide an actual value #除非你提供一个实际值,否则case语句不会起作用 echo "$lsb_dist" #输出发行版ID}
echo_docker_as_nonroot() { #非root用户下执行Docker函数 if is_dry_run; then #判断空运行函数的返回若为真 return #返回 fi if command_exists docker && [ -e /var/run/docker.sock ]; then #判断docker命令存在,docker socket存在 ( set -x #启用命令跟踪 $sh_c 'docker version' #执行命令,显示Docker的版本信息 ) || true #若执行失败,则返回true fi
# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output #这里有意混合空格和制表符——制表符被“<<-EOF”剥离,空格保留在输出中 echo #换行 echo "================================================================================" #分割 echo #换行 if version_gte "20.10"; then #判断选项后的镜像若大于20.10 echo "To run Docker as a non-privileged user, consider setting up the" #要以非特权用户身份运行Docker,请考虑设置 echo "Docker daemon in rootless mode for your user:" #用户的Docker守护进程处于无根模式 echo #换行 echo " dockerd-rootless-setuptool.sh install" #输出脚本信息 echo #换行 echo "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode." #参观https://docs.docker.com/go/rootless/了解无根模式 echo #换行 fi echo #换行 echo "To run the Docker daemon as a fully privileged service, but granting non-root" #要将Docker守护进程作为完全特权服务运行,但授予非root echo "users access, refer to https://docs.docker.com/go/daemon-access/" #用户访问权限,请参阅https://docs.docker.com/go/daemon-access/ echo #换行 echo "WARNING: Access to the remote API on a privileged Docker daemon is equivalent" #警告:在特权Docker守护进程上访问远程API等同于 echo " to root access on the host. Refer to the 'Docker daemon attack surface'" #在主机上进行根访问。请参阅“Docker守护进程攻击面” echo " documentation for details: https://docs.docker.com/go/attack-surface/" #详细文档:https://docs.docker.com/go/attack-surface/ echo #换行 echo "================================================================================" #分割 echo #换行}
# Check if this is a forked Linux distro #检查这是否是一个分叉的Linux发行版check_forked() { #检查分支函数
# Check for lsb_release command existence, it usually exists in forked distros #检查lsb_release命令是否存在,它通常存在于分叉发行版中 if command_exists lsb_release; then #判断lsb_release若存在 # Check if the `-u` option is supported #检查是否支持“-u”选项 set +e #禁用脚本中的错误终止行为 lsb_release -a -u > /dev/null 2>&1 #执行命令,检验-u选项是否存在 lsb_release_exit_code=$? #将上次的返回码赋予变量 set -e #恢复脚本中的错误终止行为
# Check if the command has exited successfully, it means we're in a forked distro #检查命令是否已成功退出,这意味着我们处于分叉发行版中 if [ "$lsb_release_exit_code" = "0" ]; then #判断上次的返回码若为0 # Print info about current distro #打印当前发行版的信息 cat <<-EOF #输出文本 You're using '$lsb_dist' version '$dist_version'. EOF #您正在使用“【发行版】”版本“【版本号】”。
# Get the upstream release info #获取上游发布信息 lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]') #截取发行版ID赋予变量 dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]') #截取到代号信息赋予变量
# Print info about upstream distro #打印上游发行版信息 cat <<-EOF Upstream release is '$lsb_dist' version '$dist_version'. #上游版本为“【发行版】”版本“【版本号】”。 EOF #输出信息 else #若lsb_release不存在 if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then #判断若/etc/debian_version文件存在且可读,并且发行版ID为非ubuntu和raspbian if [ "$lsb_dist" = "osmc" ]; then #判断若发行版ID为osmc # OSMC runs Raspbian #OSMC运行Raspbian lsb_dist=raspbian #将raspbian赋予变量 else #若发行版ID不为osmc # We're Debian and don't even know it! #我们是Debian,甚至不知道! lsb_dist=debian #将debian赋予变量 fi dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" #更改/etc/debian_version文件,/后面的所有字符和.后面的所有字符,只保留主版本信息,并赋予变量 case "$dist_version" in #对主版本进行匹配 12) #若为12版本 dist_version="bookworm" #定义变量为bookworm ;; 11) #若为11版本 dist_version="bullseye" #定义变量为bullseye ;; 10) #若为10版本 dist_version="buster" #定义变量为buster ;; 9) #若为9版本 dist_version="stretch" #定义变量为stretch ;; 8) #若为8版本 dist_version="jessie" #定义变量为jessie ;; esac fi fi fi}
do_install() { #软件安装函数 echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA" ##正在执行docker安装脚本,提交:$script_commit_SHA
if command_exists docker; then #判断若存在docker命令 cat >&2 <<-'EOF' #输出警告脚本 Warning: the "docker" command appears to already exist on this system. #警告:此系统上似乎已经存在“docker”命令。
If you already have Docker installed, this script can cause trouble, which is #如果您已经安装了Docker,此脚本可能会造成问题,这就是 why we're displaying this warning and provide the opportunity to cancel the #为什么我们显示此警告并提供取消 installation. #安装。
If you installed the current Docker package using this script and are using it #If you installed the current Docker package using this script and are using it again to update Docker, you can safely ignore this message. #again to update Docker, you can safely ignore this message。
You may press Ctrl+C now to abort this script. #您现在可以按Ctrl+C中止此脚本。 EOF ( set -x; sleep 20 ) #暂停20秒,给用户时间考虑是否中止操作,在此期间,启用调试模式以显示命令 fi
user="$(id -un 2>/dev/null || true)" #获取当前用户名赋予变量,若执行失败不产生错误
sh_c='sh -c' #初始化变量,将变量设置为sh -c命令 if [ "$user" != 'root' ]; then #判断若当前用户名为非root用户 if command_exists sudo; then #判断若sudo命令存在 sh_c='sudo -E sh -c' #将sudo -E sh -c命令赋予变量 elif command_exists su; then #判断若su命令存在 sh_c='su -c' #将su -c命令赋予变量 else #否则 cat >&2 <<-'EOF' Error: this installer needs the ability to run commands as root. #错误:此安装程序需要能够以root身份运行命令。 We are unable to find either "sudo" or "su" available to make this happen. #我们无法找到“sudo”或“su”来实现这一点。 EOF #输出错误信息 exit 1 #以1状态码退出脚本 fi fi
if is_dry_run; then #判断若设备为空运行 sh_c="echo" #将echo命令赋予变量 fi
# perform some very rudimentary platform detection #执行一些非常基本的平台检测 lsb_dist=$( get_distribution ) #将发行版ID赋予变量 lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')" #再将所有大写字母转换为小写字母重新赋予变量
if is_wsl; then #判断若操作系统为微软 echo #换行 echo "WSL DETECTED: We recommend using Docker Desktop for Windows." #WSL检测:我们建议使用适用于Windows的Docker Desktop。 echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop/" #请从获取Docker桌面https://www.docker.com/products/docker-desktop/ echo #换行 cat >&2 <<-'EOF'
You may press Ctrl+C now to abort this script. #您现在可以按Ctrl+C中止此脚本。 EOF #输出信息 ( set -x; sleep 20 ) #启用Bash的调试模式,并暂停20秒 fi
case "$lsb_dist" in #判断匹配的发行版ID
ubuntu) #若为ubuntu系统 if command_exists lsb_release; then #判断若lsb_release命令存在 dist_version="$(lsb_release --codename | cut -f2)" #截取发行版的代号并赋予变量 fi if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then #判断若发行版的代号未截取到,并/etc/lsb-release文件存在且可读 dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")" #执行该文件,并获取发行版的代号赋予变量 fi ;;
debian|raspbian) #若为debian或者raspbian系统 dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" #更改/etc/debian_version文件,/后面的所有字符和.后面的所有字符,只保留主版本信息,并赋予变量 case "$dist_version" in #对主版本进行匹配 12) #若为12版本 dist_version="bookworm" #定义变量为bookworm ;; 11) #若为11版本 dist_version="bullseye" #定义变量为bullseye ;; 10) #若为10版本 dist_version="buster" #定义变量为bullseye ;; 9) #若为9版本 dist_version="stretch" #定义变量为stretch ;; 8) #若为8版本 dist_version="jessie" #定义变量为jessie ;; esac ;;
centos|rhel) if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then #判断若发行版的代号不存在,并/etc/lsb-release文件存在且可读 dist_version="$(. /etc/os-release && echo "$VERSION_ID")" #执行该文件,并获取发行版的代号赋予变量 fi ;;
*) if command_exists lsb_release; then #判断若lsb_release命令存在 dist_version="$(lsb_release --release | cut -f2)" #截取发行版的代号并赋予变量 fi if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then #判断若发行版的代号未截取到,并/etc/lsb-release文件存在且可读 dist_version="$(. /etc/os-release && echo "$VERSION_ID")" #执行该文件,并获取发行版的代号赋予变量 fi ;;
esac
# Check if this is a forked Linux distro #检查这是否是一个分叉的Linux发行版 check_forked #运行检查分支函数
# Print deprecation warnings for distro versions that recently reached EOL, #打印最近达到EOL的发行版版本的弃用警告, # but may still be commonly used (especially LTS versions). #但仍可能被普遍使用(尤其是LTS版本)。 case "$lsb_dist.$dist_version" in #匹配发行版ID和发行版版本 debian.stretch|debian.jessie) #若匹配debian.stretch或者debian.jessie deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 ;; raspbian.stretch|raspbian.jessie) #若匹配raspbian.stretch或者raspbian.jessie deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 ;; ubuntu.xenial|ubuntu.trusty) #若匹配ubuntu.xenial或者ubuntu.trusty deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 ;; ubuntu.lunar|ubuntu.kinetic|ubuntu.impish|ubuntu.hirsute|ubuntu.groovy|ubuntu.eoan|ubuntu.disco|ubuntu.cosmic) #若匹配ubuntu.lunar、ubuntu.kinetic、ubuntu.impish、ubuntu.hirsute、ubuntu.groovy、ubuntu.eoan、ubuntu.disco、ubuntu.cosmic其中之一 deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 ;; fedora.*) #若匹配fedora.任意 if [ "$dist_version" -lt 36 ]; then #判断若发行版版本小于等于36 deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 fi ;; esac
# Run setup for each distro accordingly #相应地运行每个发行版的安装程序 case "$lsb_dist" in #匹配发行版ID ubuntu|debian|raspbian) #若匹配ubuntu、debian或者raspbian pre_reqs="apt-transport-https ca-certificates curl" #将软件包赋予变量 apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL" #将Docker仓库的APT源赋予变量 ( if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c 'apt-get update -qq >/dev/null' #采用安静模式更新APT包索引 $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pre_reqs >/dev/null" #安静的无交互式的安装定义好的安装包 $sh_c 'install -m 0755 -d /etc/apt/keyrings' #创建目录/etc/apt/keyrings,并设置权限为0755 $sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" -o /etc/apt/keyrings/docker.asc" #下载Docker的GPG公钥文件并保存到/etc/apt/keyrings/docker.asc $sh_c "chmod a+r /etc/apt/keyrings/docker.asc" #设置/etc/apt/keyrings/docker.asc文件的权限,以便所有用户都能读取 $sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list" #将Docker APT仓库源写入到/etc/apt/sources.list.d/docker.list文件中 $sh_c 'apt-get update -qq >/dev/null' #再次更新APT包索引 ) #在子环境中运行 pkg_version="" #将软件包版本变量设置为空值 if [ -n "$VERSION" ]; then #判断若版本参数为非空 if is_dry_run; then #判断若为空运行 echo "# WARNING: VERSION pinning is not supported in DRY_RUN" #警告:DRY_RUN不支持版本固定 else #若不为空运行 # Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channel #适用于不完整的IE版本(17.12),但如果在测试通道中,可能无法获取“最新”版本 pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/~ce~.*/g' | sed 's/-/.*/g')" #将版本参数的-ce-替换为~ce~.*,-替换为.*,并赋予变量 search_command="apt-cache madison docker-ce | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" #列出docker-ce包,截取到版本信息,命令赋予变量 pkg_version="$($sh_c "$search_command")" #执行命令,截取到版本信息 echo "INFO: Searching repository for VERSION '$VERSION'" #信息:在存储库中搜索版本【版本号】 echo "INFO: $search_command" #输出搜索命令 if [ -z "$pkg_version" ]; then #判断若截取的版本信息为空 echo #换行 echo "ERROR: '$VERSION' not found amongst apt-cache madison results" #错误:在apt缓存madison结果中找不到【版本号】 echo #换行 exit 1 #以1状态码退出 fi if version_gte "18.09"; then #判断若版本参数大于18.09 search_command="apt-cache madison docker-ce-cli | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" #列出docker-ce包,截取到版本信息,命令赋予变量 echo "INFO: $search_command" #输出搜索命令 cli_pkg_version="=$($sh_c "$search_command")" #执行命令,截取到版本信息 fi pkg_version="=$pkg_version" #在版本前加入=,用于精确匹配 fi fi ( pkgs="docker-ce${pkg_version%=}" #将软件包去掉=,赋予变量 if version_gte "18.09"; then #判断若版本参数大于18.09 # older versions didn't ship the cli and containerd as separate packages #旧版本没有将cli和containerd作为单独的包提供 pkgs="$pkgs docker-ce-cli${cli_pkg_version%=} containerd.io" #定义软件包集合,赋予变量 fi if version_gte "20.10"; then #判断若版本参数大于18.09 pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" #定义软件包集合,赋予变量 fi if version_gte "23.0"; then #判断若版本参数大于23.0 pkgs="$pkgs docker-buildx-plugin" #定义软件包集合,赋予变量 fi if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pkgs >/dev/null" #安静的无交互式的安装定义好的安装包 ) #在子环境中运行 echo_docker_as_nonroot #非root用户下执行Docker exit 0 #0状态码返回 ;; centos|fedora|rhel) #若匹配centos、fedora或者rhel if [ "$(uname -m)" != "s390x" ] && [ "$lsb_dist" = "rhel" ]; then #判断若系统架构名称为非s390x,且发行版为rhel echo "Packages for RHEL are currently only available for s390x." #RHEL的软件包目前仅适用于s390x exit 1 #以1状态码返回 fi
if command_exists dnf; then #判断若dnf命令存在 pkg_manager="dnf" #设置包管理器变量为dnf pkg_manager_flags="--best" #设置dnf的选项为--best,表示在安装时优先选择最佳版本 config_manager="dnf config-manager" #设置配置管理命令为dnf config-manager enable_channel_flag="--set-enabled" #设置启用频道的选项为--set-enabled disable_channel_flag="--set-disabled" #设置禁用频道的选项为 --set-disabled pre_reqs="dnf-plugins-core" #设置前置依赖为dnf-plugins-core else #若dnf命令不存在 pkg_manager="yum" #设置包管理器变量为yum pkg_manager_flags="" #设置yum的选项为空,因为默认不需要特别选项 config_manager="yum-config-manager" #设置配置管理命令为yum-config-manager enable_channel_flag="--enable" #设置启用频道的选项为--enable disable_channel_flag="--disable" #设置禁用频道的选项为--disable pre_reqs="yum-utils" #设置前置依赖为yum-utils fi
if [ "$lsb_dist" = "fedora" ]; then #判断若发行版ID为fedora pkg_suffix="fc$dist_version" #设置包后缀为fc版本 else #若发行版ID不为fedora pkg_suffix="el" #设置包后缀为el fi repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" #设置仓库文件url ( if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "$pkg_manager $pkg_manager_flags install -y -q $pre_reqs" #安装前置依赖 $sh_c "$config_manager --add-repo $repo_file_url" #安装仓库源
if [ "$CHANNEL" != "stable" ]; then #判断若CHANNEL为非稳定版 $sh_c "$config_manager $disable_channel_flag 'docker-ce-*'" #管理禁用频道所有docker-ce- $sh_c "$config_manager $enable_channel_flag 'docker-ce-$CHANNEL'" #管理启用频道所有docker-ce-CHANNEL版本 fi $sh_c "$pkg_manager makecache" #安装makecache软件 ) #在子环境中运行 pkg_version="" #将软件包版本变量设置为空值 if [ -n "$VERSION" ]; then #判断若版本参数为非空 if is_dry_run; then #判断若为空运行 echo "# WARNING: VERSION pinning is not supported in DRY_RUN" #警告:DRY_RUN不支持版本固定 else #若不为空运行 pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g').*$pkg_suffix" #将版本参数的-ce-替换为.ce.*,-替换为.*,并赋予变量 search_command="$pkg_manager list --showduplicates docker-ce | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" #列出docker-ce包,截取到版本信息,命令赋予变量 pkg_version="$($sh_c "$search_command")" #执行构造的搜索命令,并将结果赋值变量 echo "INFO: Searching repository for VERSION '$VERSION'" #信息:在存储库中搜索版本【版本号】 echo "INFO: $search_command" #信息:【版本信息】 if [ -z "$pkg_version" ]; then #判断若软件包版本为空 echo #换行 echo "ERROR: '$VERSION' not found amongst $pkg_manager list results" #错误:在【软件包版本】列表结果中找不到【版本号】 echo #换行 exit 1 #以1状态码退出 fi if version_gte "18.09"; then #判断若版本参数大于18.09 # older versions don't support a cli package #旧版本不支持cli包 search_command="$pkg_manager list --showduplicates docker-ce-cli | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" #列出docker-ce包,截取到版本信息,命令赋予变量 cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)" #执行命令并提取docker-ce-cli的版本 fi # Cut out the epoch and prefix with a '-' #去掉纪元并在其前面加上一个“-” pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)" #将变量去掉前缀,并添加个“-” fi fi ( pkgs="docker-ce$pkg_version" #将docker-ce加上版本号赋予变量 if version_gte "18.09"; then #判断若版本参数大于18.09 # older versions didn't ship the cli and containerd as separate packages #旧版本没有将cli和containerd作为单独的包提供 if [ -n "$cli_pkg_version" ]; then #判断若设置了cli版本变量 pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io" #pkgs变量增加docker-ce-cli-版本号和containerd.io else #若未设置cli版本变量 pkgs="$pkgs docker-ce-cli containerd.io" #pkgs变量增加docker-ce-cli和containerd.io fi fi if version_gte "20.10"; then #判断若版本参数大于20.10 pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" #pkgs变量增加docker-compose-plugin和docker-ce-rootless-extras版本号 fi if version_gte "23.0"; then #判断若版本参数大于23.0 pkgs="$pkgs docker-buildx-plugin" #pkgs变量增加docker-buildx-plugin fi if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "$pkg_manager $pkg_manager_flags install -y -q $pkgs" #执行安装软件包 ) #在子环境中运行 echo_docker_as_nonroot #非root用户下执行Docker exit 0 #以0状态码返回 ;; sles) #若匹配sles if [ "$(uname -m)" != "s390x" ]; then #判断若当前架构不是s390x echo "Packages for SLES are currently only available for s390x" #SLES软件包目前仅适用于s390x exit 1 #以1状态码退出 fi repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" #定义存储库文件 pre_reqs="ca-certificates curl libseccomp2 awk" #定义预安装的软件包 ( if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "zypper install -y $pre_reqs" #使用zypper命令安装预定义的软件包 $sh_c "zypper addrepo $repo_file_url" #使用zypper命令将指定的存储库URL添加到系统中,以便后续可以从该源安装软件包 if ! is_dry_run; then #判断若为非空运行 cat >&2 <<-'EOF' WARNING!! #警告!! openSUSE repository (https://download.opensuse.org/repositories/security:/SELinux) will be enabled now. #openSUSE存储库(https://download.opensuse.org/repositories/security:/SELinux)现在将启用。 Do you wish to continue? #您想继续吗? You may press Ctrl+C now to abort this script. #您现在可以按Ctrl+C中止此脚本。 EOF #输出警告信息 ( set -x; sleep 30 ) #暂停30秒,给用户时间考虑是否中止操作,在此期间,启用调试模式以显示命令 fi opensuse_repo="https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/security:SELinux.repo" #添加另一个软件源并赋予标量 $sh_c "zypper addrepo $opensuse_repo" #使用zypper命令将其添加为软件源 $sh_c "zypper --gpg-auto-import-keys refresh" #使用zypper刷新软件源,并自动导入GPG密钥,以确保软件包的安全性 $sh_c "zypper lr -d" #使用命令列出所有配置的软件源及其详细信息,方便用户查看。 ) #在子环境中运行 pkg_version="" #将软件包版本变量定于为空 if [ -n "$VERSION" ]; then #判断若版本参数为非空 if is_dry_run; then #判断若为空运行 echo "# WARNING: VERSION pinning is not supported in DRY_RUN" ##警告:DRY_RUN不支持版本固定 else #若不为空运行 pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g')" #将版本参数的-ce-替换为.ce.*,-替换为.*,并赋予变量 search_command="zypper search -s --match-exact 'docker-ce' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'" #列出docker-ce包,截取到版本信息,命令赋予变量 pkg_version="$($sh_c "$search_command")" #执行构造的搜索命令,并将结果赋值变量 echo "INFO: Searching repository for VERSION '$VERSION'" #信息:在存储库中搜索版本【版本号】 echo "INFO: $search_command" #信息:【版本信息】 if [ -z "$pkg_version" ]; then #判断若软件包版本为空 echo #换行 echo "ERROR: '$VERSION' not found amongst zypper list results" #错误:在zypper列表结果中找不到【版本号】 echo #换行 exit 1 #以1状态码退出 fi search_command="zypper search -s --match-exact 'docker-ce-cli' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'" #列出docker-ce-cli包,截取到版本信息,命令赋予变量 # It's okay for cli_pkg_version to be blank, since older versions don't support a cli package #cli_pkg_version为空是可以的,因为旧版本不支持cli包 cli_pkg_version="$($sh_c "$search_command")" #执行构造的搜索命令,并将结果赋值变量 pkg_version="-$pkg_version" #将变量值前加-,并重新赋予变量 fi fi ( pkgs="docker-ce$pkg_version" #将docker-ce加版本赋予变量 if version_gte "18.09"; then #判断若版本参数大于18.09 if [ -n "$cli_pkg_version" ]; then #判断若设置了cli版本变量 # older versions didn't ship the cli and containerd as separate packages #旧版本没有将cli和containerd作为单独的包提供 pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io" #pkgs变量增加docker-ce-cli-版本号和containerd.io else #若未设置cli版本变量 pkgs="$pkgs docker-ce-cli containerd.io" #pkgs变量增加docker-ce-cli和containerd.io fi fi if version_gte "20.10"; then #判断若版本参数大于18.09 pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" #pkgs变量增加docker-compose-plugin和docker-ce-rootless-extras版本号 fi if version_gte "23.0"; then #判断若版本参数大于23.0 pkgs="$pkgs docker-buildx-plugin" #pkgs变量增加docker-buildx-plugin fi if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "zypper -q install -y $pkgs" #使用zypper命令安装软件包 ) echo_docker_as_nonroot #非root用户下执行Docker exit 0 #以0状态码返回 ;; *) #若未匹配到 if [ -z "$lsb_dist" ]; then #判断若发行版为空 if is_darwin; then #判断若操作系统是macOS echo #换行 echo "ERROR: Unsupported operating system 'macOS'" #错误:不支持的操作系统“macOS” echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop" #请从获取Docker桌面https://www.docker.com/products/docker-desktop echo #换行 exit 1 #以1状态码退出 fi fi echo #换行 echo "ERROR: Unsupported distribution '$lsb_dist'" #错误:不支持的分发【发行版】 echo #换行 exit 1 #以1状态码退出 ;; esac exit 1 #以1状态码退出}
# wrapped up in a function so that we have some protection against only getting #被包裹在一个函数中,这样我们就可以得到一些保护,防止只得到# half the file during "curl | sh" #“curl |sh” #期间文件的一半do_install #调用安装脚本
xxxxxxxxxx
usage() { echo "check -v | --vendor) vendor -o | --organization) organization number -c | --channelid) channel id -e | --external-disk) use external disk -s | --storage-size) storage size -d | --storage-directory) storage directory -S | --thirdparty-sn) thirdparty sn -n | --note) note -V | --version) version -h | --help) print this info " #指定帮助文档 exit 0 #以0状态码退出} #使用方法函数
option=$(getopt -o v:o:c:e:s:d:S:n:V:h --long vendor:,organization:,channelid:,external-disk:,storage-disk:,storage-directory:,thirdparty-sn:,note:,version:,help -- "$@") #解析传入的命令行参数,并将解析后的结果存储在变量中
eval set -- "$option" #将getopt解析出的命令行参数重新设置为脚本的位置参数
while true #做出无限循环do #开始 case $1 in #判断输入的选项 -v | --vendor) shift; u_vendor=$1 ; shift ;; #定义供应商后左移 -o | --organization) shift; u_organization=$1 ; shift ;; #定义渠道代码后左移 -c | --channelid) shift; u_channelid=$1 ; shift ;; #定义渠道ID后左移 -e | --external-disk) shift; u_external_disk=$1 ; shift ;; #定义外接盘后左移 -s | --storage-size) shift; u_storage_size=$1 ; shift ;; #定义缓存大小后左移 -d | --storage-directory) shift; u_storage_directory=$1 ; shift ;; #定义缓存目录后左移 -S | --thirdparty-sn) shift; u_thirdparty_sn=$1 ; shift ;; #定义三方sn后左移 -n | --note) shift; u_note=$1 ; shift ;; #定义节点后左移 -n | --version) shift; u_version=$1 ; shift ;; #定义版本后左移 -h | --help ) usage ;; #调用方法函数 --) shift ; break ;; #左移后退出循环 *) usage ;; #调用方法函数 esac done #结束
echo "version: 0.0.6" #输出版本信息
# install update scripts #安装更新脚本wget https://cdn2.bkdomain.cn/system-scripts/v0.2.4/update-armbian.deb -O /opt/update-armbian.deb #下载更新更新armbian包dpkg -i /opt/update-armbian.deb #安装更新armbian包rm -f /opt/update-armbian.deb #删除原下载的更新armbian包sleep 3 #暂停3秒
# install dot config #安装dot配置wget https://cdn2.bkdomain.cn/system-scripts/custom-dot-dns-config.deb -O /opt/custom-dot-dns-config.deb #下载dot配置包dpkg -i /opt/custom-dot-dns-config.deb #安装dot配置包rm -f /opt/custom-dot-dns-config.deb #删除原下载的dot配置包systemctl enable --now systemd-resolved.service #将resolved服务启动,并设置开机自启sleep 3 #暂停3秒
# enable dot #默认dotif dig @127.0.0.53 www.google.com && ! grep -q "nameserver 127.0.0.53" /etc/resolv.conf #判断dns是否能解析谷歌网站,且dns非127.0.0.53then #若都满足 cp /etc/resolv.conf /etc/resolv.conf.bak #备份dsn全局文件 echo 'nameserver 127.0.0.53' > /etc/resolv.conf #将dns全局文件的dns设置为127.0.0.53fi
# install docker #安装dockerapt update #更新软件源apt install -y jq bc ca-certificates gnupg lsb-release xz-utils bzip2 unzip zip #下载必要软件docker_version=$(docker --version | awk '{print $3}' | sed 's/,//g' 2>/dev/null) #将当前docker版本赋予变量if [[ "$docker_version" < "20.00.00" ]] #判断当前docker版本是否小于20then #若小于 curl -fsSL https://cdn2.bkdomain.cn/product/terminal/get-docker.sh | bash -s docker --mirror Aliyun #下在安装docker脚本,并采用阿里云源运行安装fisleep 3 #暂停3秒
# dianxian deploy configuration #点心部署配置mkdir -p /etc/sysconfig #创建sysconfig目录cat << EOF > /etc/sysconfig/dianxin.envsCHANNELID="${u_channelid:-CBV9UHAA0320220905143123262}"ORGCODE="${u_organization:-A03}"STORAGE_DIRECTORY="${u_storage_directory:-/storage}"STORAGE_SIZE="${u_storage_size:-100}"VENDOR="${u_vendor:-AB}"ONLY_STORAGE_DISK="${u_external_disk:-false}"THIRDPARTY_SN="${u_thirdparty_sn:-thirdpartysn}"NOTE="${u_note:-note}"SWAPON="false"MODE="deploy"LANG=en_US.UTF-8LC_CTYPE="en_US.UTF-8"LC_NUMERIC="en_US.UTF-8"LC_TIME="en_US.UTF-8"LC_COLLATE="en_US.UTF-8"LC_MONETARY="en_US.UTF-8"LC_MESSAGES="en_US.UTF-8"LC_PAPER="en_US.UTF-8"LC_NAME="en_US.UTF-8"LC_ADDRESS="en_US.UTF-8"LC_TELEPHONE="en_US.UTF-8"LC_MEASUREMENT="en_US.UTF-8"LC_IDENTIFICATION="en_US.UTF-8"LC_ALL=EOF #将参数信息存入点心环境配置文件ln -s /etc/sysconfig/dianxin.envs /etc/sysconfig/dianxin_env #做点心环境变量文件的软链接
{ echo "custom-dot-dns-config" echo "update-armbian"} > /etc/sysconfig/dianxin.packages #将需要更新的软件输入进列表文件
# install and start dianxin system #安装并开启点心系统if [[ -z "$u_version" ]] #判断输入的版本是否为空then #若为空 wget https://cdn2.bkdomain.cn/system-scripts/dianxin-deploy.deb -O /tmp/dianxin-deploy.deb #下载默认版本的点心部署包else wget https://cdn2.bkdomain.cn/system-scripts/dianxin-deploy-${u_version}.deb -O /tmp/dianxin-deploy.deb #下载指定版本的点心部署包fidpkg -i /tmp/dianxin-deploy.deb #安装点心部署包
xxxxxxxxxx
usage() { echo "check -v | --vendor) vendor -o | --organization) organization number -c | --channelid) channel id -e | --external-disk) use external disk -s | --storage-size) storage size -d | --storage-directory) storage directory -n | --need-ai) need ai -p | --pipe-type) pipe type -h | --help) print this info " #指定帮助文档 exit 0 #以0状态码退出} #使用方法函数
option=$(getopt -o v:o:c:e:s:d:n:p:h --long vendor:,organization:,channelid:,external-disk:,storage-disk:,storage-directory:,need-ai:,pipe-type:,help -- "$@") #解析传入的命令行参数,并将解析后的结果存储在变量中
eval set -- "$option" #将getopt解析出的命令行参数重新设置为脚本的位置参数
while true #做出无限循环do #开始 case $1 in #判断输入的选项 -v | --vendor) shift; u_vendor=$1 ; shift ;; #定义供应商后左移 -o | --organization) shift; u_organization=$1 ; shift ;; #定义渠道代码后左移 -c | --channelid) shift; u_channelid=$1 ; shift ;; #定义渠道ID后左移 -e | --external-disk) shift; u_external_disk=$1 ; shift ;; #定义外接盘后左移 -s | --storage-size) shift; u_storage_size=$1 ; shift ;; #定义缓存大小后左移 -d | --storage-directory) shift; u_storage_directory=$1 ; shift ;; #定义缓存目录后左移 -n | --need-ai) shift; u_need_ai=$1 ; shift ;; #定义自动AI后左移 -p | --pipe-type) shift; u_pipe_type=$1 ; shift ;; #定义包类型后左移 -h | --help ) usage ;; #调用方法函数 --) shift ; break ;; #左移后退出循环 *) usage ;; #调用方法函数 esacdone #结束
u_version="v0.0.5" #将版本默认设置为v0.0.5echo "version: $u_version" #输出版本信息
# install tools #安装工具包yum install -y jq bc ca-certificates gnupg xz bzip2 unzip zip wget #下载必要软件
# install update scripts #安装更新脚本wget https://cdn2.bkdomain.cn/system-scripts/update-edgexos-0.2.0-1.el7.x86_64.rpm -O /tmp/update-edgexos-0.2.0-1.el7.x86_64.rpm #下载更新更新edgexos包rpm -Uvh /tmp/update-edgexos-0.2.0-1.el7.x86_64.rpm #安装更新edgexos包rm -f /tmp/update-edgexos-0.2.0-1.el7.x86_64.rpm #删除原下载的更新edgexos包# only update pakages in this list #只更新软件列表{ echo "coredns" echo "update-edgexos" echo "nm-dispatcher"} > /etc/sysconfig/dianxin.packages #将需要更新的软件输入进列表文件sleep 3 #暂停3秒
# install dot config #安装工具包wget https://cdn2.bkdomain.cn/system-scripts/coredns-1.12.9-1.el7.x86_64.rpm -O /opt/coredns-1.12.9-1.el7.x86_64.rpm #下载dns配置包rpm -U /opt/coredns-1.12.9-1.el7.x86_64.rpm #安装dns配置包rm -f /opt/coredns-1.12.9-1.el7.x86_64.rpm #删除原下载的dns配置包systemctl reload NetworkManager #重新加载NetworkManager服务sleep 3 #暂停3秒
# enable dot #默认dotif dig @127.0.0.53 www.qq.com && ! grep -q "nameserver 127.0.0.53" /etc/resolv.conf #判断dns是否能解析谷歌网站,且dns非127.0.0.53then #若都满足 cp /etc/resolv.conf /etc/resolv.conf.bak #备份dsn全局文件 echo 'nameserver 127.0.0.53' > /etc/resolv.conf #将dns全局文件的dns设置为127.0.0.53fi
# install docker #安装dockerdocker_version=$(docker --version | awk '{print $3}' | sed 's/,//g' 2>/dev/null) #将当前docker版本赋予变量if [[ "$docker_version" < "20.00.00" ]] #判断当前docker版本是否小于20then #若小于 wget https://cdn2.bkdomain.cn/system-scripts/docker-ce-x86_64-centos.tar.bz2 -O /opt/docker-ce-x86_64-centos.tar.bz2 #下载docker压缩包 tar jxf /opt/docker-ce-x86_64-centos.tar.bz2 -C /opt #将docker压缩包解压 pushd /opt/docker-ce-x86_64-centos #将当前工作目录压入堆栈,并切换到/opt/docker-ce-x86_64-centos目录 yum localinstall -y containerd.io-1.6.33-3.1.el7.x86_64.rpm \ docker-ce-26.1.4-1.el7.x86_64.rpm \ docker-ce-cli-26.1.4-1.el7.x86_64.rpm \ docker-ce-rootless-extras-26.1.4-1.el7.x86_64.rpm \ docker-compose-plugin-2.27.1-1.el7.x86_64.rpm \ docker-buildx-plugin-0.14.1-1.el7.x86_64.rpm #安装docker所需的软件包 systemctl enable --now docker.socket #将docker服务启动,并设置自启 systemctl enable --now containerd.service #将容器服务启动,并设置自启 systemctl start docker.service #启动docker服务 popd #返回到原来目录 rm -rf /opt/docker-ce-x86_64-centos /opt/docker-ce-x86_64-centos.tar.bz2 #删除原下载的docker压缩包fi
# install netowrk manager disapatcher to support multiple ipv6 nic #安装netowrk管理器dispatcher以支持多个ipv6网卡wget https://cdn2.bkdomain.cn/system-scripts/nm-dispatcher-0.1.8-1.el7.x86_64.rpm -O /tmp/nm-dispatcher-0.1.8-1.el7.x86_64.rpm #下载dispatcher包rpm -Uvh /tmp/nm-dispatcher-0.1.8-1.el7.x86_64.rpm #安装dispatcher包rm -f /tmp/nm-dispatcher-0.1.8-1.el7.x86_64.rpm #删除原下载的dispatcher包sleep 3 #暂停3秒
# dianxian deploy configurationmkdir -p /etc/sysconfig #点心部署配置cat << EOF > /etc/sysconfig/dianxin.envsCHANNELID="${u_channelid:-CBV9UHAA0320220905143123262}"ORGCODE="${u_organization:-A03}"STORAGE_DIRECTORY="${u_storage_directory:-/storage}"STORAGE_SIZE="${u_storage_size:-100}"VENDOR="${u_vendor:-LW}"NEED_AI="${u_need_ai:-1}"PIPE_TYPE="${u_pipe_type:-small}"ONLY_STORAGE_DISK="${u_external_disk:-true}"SWAPON="false"LANG=en_US.UTF-8LC_CTYPE="en_US.UTF-8"LC_NUMERIC="en_US.UTF-8"LC_TIME="en_US.UTF-8"LC_COLLATE="en_US.UTF-8"LC_MONETARY="en_US.UTF-8"LC_MESSAGES="en_US.UTF-8"LC_PAPER="en_US.UTF-8"LC_NAME="en_US.UTF-8"LC_ADDRESS="en_US.UTF-8"LC_TELEPHONE="en_US.UTF-8"LC_MEASUREMENT="en_US.UTF-8"LC_IDENTIFICATION="en_US.UTF-8"LC_ALL=EOF #将参数信息存入点心环境配置文件
# install and start dianxin system #安装并开启点心系统wget https://cdn2.bkdomain.cn/system-scripts/dianxin-deploy-0.5.8-1.el7.x86_64.rpm -O /tmp/dianxin-deploy-0.5.8-1.el7.x86_64.rpm #下载点心部署包rpm -Uvh /tmp/dianxin-deploy-0.5.8-1.el7.x86_64.rpm #安装点心部署包rm -f /tmp/dianxin-deploy-0.5.8-1.el7.x86_64.rpm #删除原下载的点心部署包systemctl start dianxin.service #启动点心服务
# enable mutiple ipv6 route table #启用多个ipv6路由表nmcli con show --active | grep "ethernet" | awk '{print $2}' | while read -r uuid #截取到所有以太网设备的uuiddo #循环调用uuid nmcli conn up "$uuid" #启用对应uuid的网卡done & #循环结算,并后台进程执行循环过程
xxxxxxxxxxset -e #设备脚本在遇到错误时立即退出# Docker Engine for Linux installation script. #Docker Engine for Linux安装脚本## This script is intended as a convenient way to configure docker's package #此脚本旨在作为配置docker包的便捷方式# repositories and to install Docker Engine, This script is not recommended #仓库和安装Docker引擎,不建议使用此脚本# for production environments. Before running this script, make yourself familiar #对于生产环境。在运行此脚本之前,熟悉# with potential risks and limitations, and refer to the installation manual #潜在的风险和局限性,并参考安装手册# at https://docs.docker.com/engine/install/ for alternative installation methods. #https://docs.docker.com/engine/install/用于替代安装方法。## The script: #脚本:## - Requires `root` or `sudo` privileges to run. #需要“root”或“sudo”权限才能运行。# - Attempts to detect your Linux distribution and version and configure your #尝试检测您的Linux发行版和版本,并配置您的# package management system for you. 您的包管理系统。# - Doesn't allow you to customize most installation parameters. #不允许您自定义大多数安装参数。# - Installs dependencies and recommendations without asking for confirmation. #无需确认即可安装依赖项和建议。# - Installs the latest stable release (by default) of Docker CLI, Docker Engine, #安装Docker CLI、Docker Engine的最新稳定版本(默认),# Docker Buildx, Docker Compose, containerd, and runc. When using this script #Docker Buildx、Docker Compose、containerd和runc。当使用此脚本# to provision a machine, this may result in unexpected major version upgrades #来配置机器时,这可能会导致意外的主要版本升级# of these packages. Always test upgrades in a test environment before #这些包。始终在测试环境中测试升级# deploying to your production systems. #部署到您的生产系统。# - Isn't designed to upgrade an existing Docker installation. When using the #不是为升级现有的Docker安装而设计的。使用时# script to update an existing installation, dependencies may not be updated #更新现有安装的脚本,依赖关系可能不会更新# to the expected version, resulting in outdated versions. #到预期版本,导致版本过时。## Source code is available at https://github.com/docker/docker-install/ #源代码可在https://github.com/docker/docker-install/## Usage #使用方法# ==============================================================================## To install the latest stable versions of Docker CLI, Docker Engine, and their #安装最新稳定版本的Docker CLI、Docker Engine及其# dependencies: #依赖关系:## 1. download the script #1.下载脚本## $ curl -fsSL https://get.docker.com -o install-docker.sh #下载脚本## 2. verify the script's content #2.验证脚本的内容## $ cat install-docker.sh #查看脚本## 3. run the script with --dry-run to verify the steps it executes #3.使用--dry-run运行脚本,以验证它执行的步骤## $ sh install-docker.sh --dry-run #空运行执行## 4. run the script either as root, or using sudo to perform the installation. #4.以root身份运行脚本,或使用sudo执行安装。## $ sudo sh install-docker.sh #sudo执行脚本## Command-line options #命令行选项# ==============================================================================## --version <VERSION> #选项# Use the --version option to install a specific version, for example: #使用--version选项安装特定版本,例如:## $ sudo sh install-docker.sh --version 23.0 #安装特定版本## --channel <stable|test> #选项## Use the --channel option to install from an alternative installation channel. #使用--channel选项从其他安装通道安装。# The following example installs the latest versions from the "test" channel, #以下示例从“测试”通道安装最新版本,# which includes pre-releases (alpha, beta, rc): #其中包括预发布(alpha、beta、rc):## $ sudo sh install-docker.sh --channel test #从“测试”通道安装最新版本## Alternatively, use the script at https://test.docker.com, which uses the test #或者,使用以下脚本https://test.docker.com,使用该测试# channel as default. #默认通道。## --mirror <Aliyun|AzureChinaCloud> #选项## Use the --mirror option to install from a mirror supported by this script. #使用--mirror选项从此脚本支持的镜像安装。# Available mirrors are "Aliyun" (https://mirrors.aliyun.com/docker-ce), and #可用的镜像是“阿里云”(https://mirrors.aliyun.com/docker-ce),和# "AzureChinaCloud" (https://mirror.azure.cn/docker-ce), for example: #AzureCloud”https://mirror.azure.cn/docker-ce例如:## $ sudo sh install-docker.sh --mirror AzureChinaCloud #采用AzureChinaCloud镜像安装## ==============================================================================
# Git commit from https://github.com/docker/docker-install when #Git提交自https://github.com/docker/docker-install# the script was uploaded (Should only be modified by upload job): #脚本已上传(只能由上传作业修改):SCRIPT_COMMIT_SHA="6d9743e9656cc56f699a64800b098d5ea5a60020" #定义脚本哈希值
# strip "v" prefix if present #带“v”前缀(如果存在)VERSION="${VERSION#v}" #将变量去V
# The channel to install from: #要从以下位置安装的通道:# * stable #稳定版# * test 测试版# * edge (deprecated) #边缘版(已弃用)# * nightly (deprecated) #夜间版(已弃用)DEFAULT_CHANNEL_VALUE="stable" #将默认channel设置为stableif [ -z "$CHANNEL" ]; then #如果CHANNEL变量为空 CHANNEL=$DEFAULT_CHANNEL_VALUE #设置该变量为默认值fi
DEFAULT_DOWNLOAD_URL="https://download.docker.com" #设置默认下载地址if [ -z "$DOWNLOAD_URL" ]; then #如果下载URL变量为空 DOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL #设置该变量为默认值fi
DEFAULT_REPO_FILE="docker-ce.repo" #设置默认下载仓库if [ -z "$REPO_FILE" ]; then #如果下载仓库变量为空 REPO_FILE="$DEFAULT_REPO_FILE" #设置该变量为默认值fi
mirror='' #初始化镜像变量为空DRY_RUN=${DRY_RUN:-} #若变量未设置,则设置为空值while [ $# -gt 0 ]; do #循环调用输入的每一个参数 case "$1" in #判断输入的选项 --channel) #若选项为--channel CHANNEL="$2" #定义输入的值 shift #左移 ;; --dry-run) #若选项为--dry-run DRY_RUN=1 #定义输入的值 ;; #左移 --mirror) #若选项为--mirror mirror="$2" #定义输入的值 shift #左移 ;; --version) #若选项为--version VERSION="${2#v}" #定义输入的值 shift #左移 ;; --*) #若输入其他选项 echo "Illegal option $1" #输出无效的选项 ;; esac shift $(( $# > 0 ? 1 : 0 )) #如果位置参数大于0,则左移done
case "$mirror" in #判断输入的镜像名称 Aliyun) #若为阿里云 DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce" #定义阿里云的下载URL地址 ;; AzureChinaCloud) #若为微软 DOWNLOAD_URL="https://mirror.azure.cn/docker-ce" #定义微软的下载URL地址 ;; "") #若为空,不做操作 ;; *) #若为其他 >&2 echo "unknown mirror '$mirror': use either 'Aliyun', or 'AzureChinaCloud'." #提示错误信息 exit 1 #以1状态码退出 ;;esac
case "$CHANNEL" in #判断输入的CHANNEL名称 stable|test) #若为稳定或者测试,则不做操作 ;; edge|nightly) #若为edge或者nightly >&2 echo "DEPRECATED: the $CHANNEL channel has been deprecated and is no longer supported by this script." #输出错误信息 exit 1 #以1状态码退出 ;; *) #若为其他 >&2 echo "unknown CHANNEL '$CHANNEL': use either stable or test." #提示错误信息 exit 1 #以1状态码退出 ;;esac
command_exists() { #命令存在性函数 command -v "$@" > /dev/null 2>&1 #检查传递的所有命令是否存在}
# version_gte checks if the version specified in $VERSION is at least the given #version_gte检查$version中指定的版本是否至少是给定的# SemVer (Maj.Minor[.Patch]), or CalVer (YY.MM) version.It returns 0 (success) #SemVer(Maj.Minor[.Patch]),或CalVer(YY.MM)版本。返回0(成功)# if $VERSION is either unset (=latest) or newer or equal than the specified #如果$VERSION未设置(=最新)或比指定版本更新或等于指定# version, or returns 1 (fail) otherwise. #版本,否则返回1(失败)。## examples: #示例:## VERSION=23.0 #版本为23.0# version_gte 23.0 // 0 (success) #返回0(成功)# version_gte 20.10 // 0 (success) #返回0(成功)# version_gte 19.03 // 0 (success) #返回0(成功)# version_gte 21.10 // 1 (fail) #返回1(失败)version_gte() { #版本比较函数 if [ -z "$VERSION" ]; then #若判断变量为空 return 0 #返回状态0 fi eval version_compare "$VERSION" "$1" #比较两个版本的大小}
# version_compare compares two version strings (either SemVer (Major.Minor.Path), #version_compare比较两个版本字符串(SemVer(Major.Minor.Path),# or CalVer (YY.MM) version strings. It returns 0 (success) if version A is newer #或CalVer(YY.MM)版本字符串。如果版本A更新,则返回0(成功)# or equal than version B, or 1 (fail) otherwise. Patch releases and pre-release #或等于版本B,否则为1(失败)。补丁发布和预发布# (-alpha/-beta) are not taken into account #(-alpha/beta)未被考虑在内## examples: #示例:## version_compare 23.0.0 20.10 // 0 (success) #返回0(成功)# version_compare 23.0 20.10 // 0 (success) #返回0(成功)# version_compare 20.10 19.03 // 0 (success) #返回0(成功)# version_compare 20.10 20.10 // 0 (success) #返回0(成功)# version_compare 19.03 20.10 // 1 (fail) #返回1(失败)version_compare() ( #版本比较函数 set +x #关闭命令跟踪模式
yy_a="$(echo "$1" | cut -d'.' -f1)" #截取选项参数的主版本号 yy_b="$(echo "$2" | cut -d'.' -f1)" #截取给定版本的主版本号 if [ "$yy_a" -lt "$yy_b" ]; then #判断选项参数的主版本号如果比给定版本的主版本号小 return 1 #返回状态码1 fi if [ "$yy_a" -gt "$yy_b" ]; then #判断选项参数的主版本号如果比给定版本的主版本号大 return 0 #返回状态码0 fi mm_a="$(echo "$1" | cut -d'.' -f2)" #截取选项参数的次版本号 mm_b="$(echo "$2" | cut -d'.' -f2)" #截取给定版本的次版本号
# trim leading zeros to accommodate CalVer #修剪前导零以适应CalVer mm_a="${mm_a#0}" #修剪掉选项参数次版本号前面的0 mm_b="${mm_b#0}" #修剪掉给定版本次版本号前面的0
if [ "${mm_a:-0}" -lt "${mm_b:-0}" ]; then #判断选项参数的次版本号如果比给定版本的次版本号小 return 1 #返回状态码1 fi
return 0 #无误后返回状态码0)
is_dry_run() { #空运行函数 if [ -z "$DRY_RUN" ]; then #判断空运行变量若为空 return 1 #返回状态码1 else #若不为空 return 0 #返回状态码0 fi}
is_wsl() { #判断操作系统函数 case "$(uname -r)" in #获取当前系统的内核版本信息进行匹配 *microsoft* ) true ;; # WSL 2 #若包含microsoft匹配真 *Microsoft* ) true ;; # WSL 1 #若包含Microsoft匹配真 * ) false;; #否则匹配假 esac}
is_darwin() { #判断操作系统是否是macOS函数 case "$(uname -s)" in #获取当前操作系统的名称进行匹配 *darwin* ) true ;; #若包含darwin匹配真 *Darwin* ) true ;; #若包含Darwin匹配真 * ) false;; #否则匹配假 esac}
deprecation_notice() { #弃用通知函数 distro=$1 #定义发行版变量 distro_version=$2 #定义版本变量 echo #换行 printf "\033[91;1mDEPRECATION WARNING\033[0m\n" #弃用警告 printf " This Linux distribution (\033[1m%s %s\033[0m) reached end-of-life and is no longer supported by this script.\n" "$distro" "$distro_version" #这个Linux发行版的【发行版】【版本】已达到生命周期末期,不再受此脚本支持 echo " No updates or security fixes will be released for this distribution, and users are recommended" #此发行版不会发布任何更新或安全修复程序,建议用户使用 echo " to upgrade to a currently maintained version of $distro." #升级到当前维护的【发行版】版本 echo #换行 printf "Press \033[1mCtrl+C\033[0m now to abort this script, or wait for the installation to continue." #立即按Ctrl+C中止此脚本,或等待安装继续 echo #换行 sleep 10 #等待用户思考十秒}
get_distribution() { #获取Linux发行版ID函数 lsb_dist="" #发行版ID变量设置为空 # Every system that we officially support has /etc/os-release #我们官方支持的每个系统都有/etc/os版本 if [ -r /etc/os-release ]; then #判断/etc/os-release文件存在并且可读 lsb_dist="$(. /etc/os-release && echo "$ID")" #将执行后的ID变量赋予发行版ID变量 fi # Returning an empty string here should be alright since the #在这里返回一个空字符串应该没问题,因为 # case statements don't act unless you provide an actual value #除非你提供一个实际值,否则case语句不会起作用 echo "$lsb_dist" #输出发行版ID}
echo_docker_as_nonroot() { #非root用户下执行Docker函数 if is_dry_run; then #判断空运行函数的返回若为真 return #返回 fi if command_exists docker && [ -e /var/run/docker.sock ]; then #判断docker命令存在,docker socket存在 ( set -x #启用命令跟踪 $sh_c 'docker version' #执行命令,显示Docker的版本信息 ) || true #若执行失败,则返回true fi
# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output #这里有意混合空格和制表符——制表符被“<<-EOF”剥离,空格保留在输出中 echo #换行 echo "================================================================================" #分割 echo #换行 if version_gte "20.10"; then #判断选项后的镜像若大于20.10 echo "To run Docker as a non-privileged user, consider setting up the" #要以非特权用户身份运行Docker,请考虑设置 echo "Docker daemon in rootless mode for your user:" #用户的Docker守护进程处于无根模式 echo #换行 echo " dockerd-rootless-setuptool.sh install" #输出脚本信息 echo #换行 echo "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode." #参观https://docs.docker.com/go/rootless/了解无根模式 echo #换行 fi echo #换行 echo "To run the Docker daemon as a fully privileged service, but granting non-root" #要将Docker守护进程作为完全特权服务运行,但授予非root echo "users access, refer to https://docs.docker.com/go/daemon-access/" #用户访问权限,请参阅https://docs.docker.com/go/daemon-access/ echo #换行 echo "WARNING: Access to the remote API on a privileged Docker daemon is equivalent" #警告:在特权Docker守护进程上访问远程API等同于 echo " to root access on the host. Refer to the 'Docker daemon attack surface'" #在主机上进行根访问。请参阅“Docker守护进程攻击面” echo " documentation for details: https://docs.docker.com/go/attack-surface/" #详细文档:https://docs.docker.com/go/attack-surface/ echo #换行 echo "================================================================================" #分割 echo #换行}
# Check if this is a forked Linux distro #检查这是否是一个分叉的Linux发行版check_forked() { #检查分支函数
# Check for lsb_release command existence, it usually exists in forked distros #检查lsb_release命令是否存在,它通常存在于分叉发行版中 if command_exists lsb_release; then #判断lsb_release若存在 # Check if the `-u` option is supported #检查是否支持“-u”选项 set +e #禁用脚本中的错误终止行为 lsb_release -a -u > /dev/null 2>&1 #执行命令,检验-u选项是否存在 lsb_release_exit_code=$? #将上次的返回码赋予变量 set -e #恢复脚本中的错误终止行为
# Check if the command has exited successfully, it means we're in a forked distro #检查命令是否已成功退出,这意味着我们处于分叉发行版中 if [ "$lsb_release_exit_code" = "0" ]; then #判断上次的返回码若为0 # Print info about current distro #打印当前发行版的信息 cat <<-EOF #输出文本 You're using '$lsb_dist' version '$dist_version'. EOF #您正在使用“【发行版】”版本“【版本号】”。
# Get the upstream release info #获取上游发布信息 lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]') #截取发行版ID赋予变量 dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]') #截取到代号信息赋予变量
# Print info about upstream distro #打印上游发行版信息 cat <<-EOF Upstream release is '$lsb_dist' version '$dist_version'. #上游版本为“【发行版】”版本“【版本号】”。 EOF #输出信息 else #若lsb_release不存在 if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then #判断若/etc/debian_version文件存在且可读,并且发行版ID为非ubuntu和raspbian if [ "$lsb_dist" = "osmc" ]; then #判断若发行版ID为osmc # OSMC runs Raspbian #OSMC运行Raspbian lsb_dist=raspbian #将raspbian赋予变量 else #若发行版ID不为osmc # We're Debian and don't even know it! #我们是Debian,甚至不知道! lsb_dist=debian #将debian赋予变量 fi dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" #更改/etc/debian_version文件,/后面的所有字符和.后面的所有字符,只保留主版本信息,并赋予变量 case "$dist_version" in #对主版本进行匹配 12) #若为12版本 dist_version="bookworm" #定义变量为bookworm ;; 11) #若为11版本 dist_version="bullseye" #定义变量为bullseye ;; 10) #若为10版本 dist_version="buster" #定义变量为buster ;; 9) #若为9版本 dist_version="stretch" #定义变量为stretch ;; 8) #若为8版本 dist_version="jessie" #定义变量为jessie ;; esac fi fi fi}
do_install() { #软件安装函数 echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA" ##正在执行docker安装脚本,提交:$script_commit_SHA
if command_exists docker; then #判断若存在docker命令 cat >&2 <<-'EOF' #输出警告脚本 Warning: the "docker" command appears to already exist on this system. #警告:此系统上似乎已经存在“docker”命令。
If you already have Docker installed, this script can cause trouble, which is #如果您已经安装了Docker,此脚本可能会造成问题,这就是 why we're displaying this warning and provide the opportunity to cancel the #为什么我们显示此警告并提供取消 installation. #安装。
If you installed the current Docker package using this script and are using it #If you installed the current Docker package using this script and are using it again to update Docker, you can safely ignore this message. #again to update Docker, you can safely ignore this message。
You may press Ctrl+C now to abort this script. #您现在可以按Ctrl+C中止此脚本。 EOF ( set -x; sleep 20 ) #暂停20秒,给用户时间考虑是否中止操作,在此期间,启用调试模式以显示命令 fi
user="$(id -un 2>/dev/null || true)" #获取当前用户名赋予变量,若执行失败不产生错误
sh_c='sh -c' #初始化变量,将变量设置为sh -c命令 if [ "$user" != 'root' ]; then #判断若当前用户名为非root用户 if command_exists sudo; then #判断若sudo命令存在 sh_c='sudo -E sh -c' #将sudo -E sh -c命令赋予变量 elif command_exists su; then #判断若su命令存在 sh_c='su -c' #将su -c命令赋予变量 else #否则 cat >&2 <<-'EOF' Error: this installer needs the ability to run commands as root. #错误:此安装程序需要能够以root身份运行命令。 We are unable to find either "sudo" or "su" available to make this happen. #我们无法找到“sudo”或“su”来实现这一点。 EOF #输出错误信息 exit 1 #以1状态码退出脚本 fi fi
if is_dry_run; then #判断若设备为空运行 sh_c="echo" #将echo命令赋予变量 fi
# perform some very rudimentary platform detection #执行一些非常基本的平台检测 lsb_dist=$( get_distribution ) #将发行版ID赋予变量 lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')" #再将所有大写字母转换为小写字母重新赋予变量
if is_wsl; then #判断若操作系统为微软 echo #换行 echo "WSL DETECTED: We recommend using Docker Desktop for Windows." #WSL检测:我们建议使用适用于Windows的Docker Desktop。 echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop/" #请从获取Docker桌面https://www.docker.com/products/docker-desktop/ echo #换行 cat >&2 <<-'EOF'
You may press Ctrl+C now to abort this script. #您现在可以按Ctrl+C中止此脚本。 EOF #输出信息 ( set -x; sleep 20 ) #启用Bash的调试模式,并暂停20秒 fi
case "$lsb_dist" in #判断匹配的发行版ID
ubuntu) #若为ubuntu系统 if command_exists lsb_release; then #判断若lsb_release命令存在 dist_version="$(lsb_release --codename | cut -f2)" #截取发行版的代号并赋予变量 fi if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then #判断若发行版的代号未截取到,并/etc/lsb-release文件存在且可读 dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")" #执行该文件,并获取发行版的代号赋予变量 fi ;;
debian|raspbian) #若为debian或者raspbian系统 dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')" #更改/etc/debian_version文件,/后面的所有字符和.后面的所有字符,只保留主版本信息,并赋予变量 case "$dist_version" in #对主版本进行匹配 12) #若为12版本 dist_version="bookworm" #定义变量为bookworm ;; 11) #若为11版本 dist_version="bullseye" #定义变量为bullseye ;; 10) #若为10版本 dist_version="buster" #定义变量为bullseye ;; 9) #若为9版本 dist_version="stretch" #定义变量为stretch ;; 8) #若为8版本 dist_version="jessie" #定义变量为jessie ;; esac ;;
centos|rhel) if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then #判断若发行版的代号不存在,并/etc/lsb-release文件存在且可读 dist_version="$(. /etc/os-release && echo "$VERSION_ID")" #执行该文件,并获取发行版的代号赋予变量 fi ;;
*) if command_exists lsb_release; then #判断若lsb_release命令存在 dist_version="$(lsb_release --release | cut -f2)" #截取发行版的代号并赋予变量 fi if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then #判断若发行版的代号未截取到,并/etc/lsb-release文件存在且可读 dist_version="$(. /etc/os-release && echo "$VERSION_ID")" #执行该文件,并获取发行版的代号赋予变量 fi ;;
esac
# Check if this is a forked Linux distro #检查这是否是一个分叉的Linux发行版 check_forked #运行检查分支函数
# Print deprecation warnings for distro versions that recently reached EOL, #打印最近达到EOL的发行版版本的弃用警告, # but may still be commonly used (especially LTS versions). #但仍可能被普遍使用(尤其是LTS版本)。 case "$lsb_dist.$dist_version" in #匹配发行版ID和发行版版本 debian.stretch|debian.jessie) #若匹配debian.stretch或者debian.jessie deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 ;; raspbian.stretch|raspbian.jessie) #若匹配raspbian.stretch或者raspbian.jessie deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 ;; ubuntu.xenial|ubuntu.trusty) #若匹配ubuntu.xenial或者ubuntu.trusty deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 ;; ubuntu.lunar|ubuntu.kinetic|ubuntu.impish|ubuntu.hirsute|ubuntu.groovy|ubuntu.eoan|ubuntu.disco|ubuntu.cosmic) #若匹配ubuntu.lunar、ubuntu.kinetic、ubuntu.impish、ubuntu.hirsute、ubuntu.groovy、ubuntu.eoan、ubuntu.disco、ubuntu.cosmic其中之一 deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 ;; fedora.*) #若匹配fedora.任意 if [ "$dist_version" -lt 36 ]; then #判断若发行版版本小于等于36 deprecation_notice "$lsb_dist" "$dist_version" #输出弃用警告信息 fi ;; esac
# Run setup for each distro accordingly #相应地运行每个发行版的安装程序 case "$lsb_dist" in #匹配发行版ID ubuntu|debian|raspbian) #若匹配ubuntu、debian或者raspbian pre_reqs="apt-transport-https ca-certificates curl" #将软件包赋予变量 apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL" #将Docker仓库的APT源赋予变量 ( if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c 'apt-get update -qq >/dev/null' #采用安静模式更新APT包索引 $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pre_reqs >/dev/null" #安静的无交互式的安装定义好的安装包 $sh_c 'install -m 0755 -d /etc/apt/keyrings' #创建目录/etc/apt/keyrings,并设置权限为0755 $sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" -o /etc/apt/keyrings/docker.asc" #下载Docker的GPG公钥文件并保存到/etc/apt/keyrings/docker.asc $sh_c "chmod a+r /etc/apt/keyrings/docker.asc" #设置/etc/apt/keyrings/docker.asc文件的权限,以便所有用户都能读取 $sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list" #将Docker APT仓库源写入到/etc/apt/sources.list.d/docker.list文件中 $sh_c 'apt-get update -qq >/dev/null' #再次更新APT包索引 ) #在子环境中运行 pkg_version="" #将软件包版本变量设置为空值 if [ -n "$VERSION" ]; then #判断若版本参数为非空 if is_dry_run; then #判断若为空运行 echo "# WARNING: VERSION pinning is not supported in DRY_RUN" #警告:DRY_RUN不支持版本固定 else #若不为空运行 # Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channel #适用于不完整的IE版本(17.12),但如果在测试通道中,可能无法获取“最新”版本 pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/~ce~.*/g' | sed 's/-/.*/g')" #将版本参数的-ce-替换为~ce~.*,-替换为.*,并赋予变量 search_command="apt-cache madison docker-ce | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" #列出docker-ce包,截取到版本信息,命令赋予变量 pkg_version="$($sh_c "$search_command")" #执行命令,截取到版本信息 echo "INFO: Searching repository for VERSION '$VERSION'" #信息:在存储库中搜索版本【版本号】 echo "INFO: $search_command" #输出搜索命令 if [ -z "$pkg_version" ]; then #判断若截取的版本信息为空 echo #换行 echo "ERROR: '$VERSION' not found amongst apt-cache madison results" #错误:在apt缓存madison结果中找不到【版本号】 echo #换行 exit 1 #以1状态码退出 fi if version_gte "18.09"; then #判断若版本参数大于18.09 search_command="apt-cache madison docker-ce-cli | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3" #列出docker-ce包,截取到版本信息,命令赋予变量 echo "INFO: $search_command" #输出搜索命令 cli_pkg_version="=$($sh_c "$search_command")" #执行命令,截取到版本信息 fi pkg_version="=$pkg_version" #在版本前加入=,用于精确匹配 fi fi ( pkgs="docker-ce${pkg_version%=}" #将软件包去掉=,赋予变量 if version_gte "18.09"; then #判断若版本参数大于18.09 # older versions didn't ship the cli and containerd as separate packages #旧版本没有将cli和containerd作为单独的包提供 pkgs="$pkgs docker-ce-cli${cli_pkg_version%=} containerd.io" #定义软件包集合,赋予变量 fi if version_gte "20.10"; then #判断若版本参数大于18.09 pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" #定义软件包集合,赋予变量 fi if version_gte "23.0"; then #判断若版本参数大于23.0 pkgs="$pkgs docker-buildx-plugin" #定义软件包集合,赋予变量 fi if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pkgs >/dev/null" #安静的无交互式的安装定义好的安装包 ) #在子环境中运行 echo_docker_as_nonroot #非root用户下执行Docker exit 0 #0状态码返回 ;; centos|fedora|rhel) #若匹配centos、fedora或者rhel if [ "$(uname -m)" != "s390x" ] && [ "$lsb_dist" = "rhel" ]; then #判断若系统架构名称为非s390x,且发行版为rhel echo "Packages for RHEL are currently only available for s390x." #RHEL的软件包目前仅适用于s390x exit 1 #以1状态码返回 fi
if command_exists dnf; then #判断若dnf命令存在 pkg_manager="dnf" #设置包管理器变量为dnf pkg_manager_flags="--best" #设置dnf的选项为--best,表示在安装时优先选择最佳版本 config_manager="dnf config-manager" #设置配置管理命令为dnf config-manager enable_channel_flag="--set-enabled" #设置启用频道的选项为--set-enabled disable_channel_flag="--set-disabled" #设置禁用频道的选项为 --set-disabled pre_reqs="dnf-plugins-core" #设置前置依赖为dnf-plugins-core else #若dnf命令不存在 pkg_manager="yum" #设置包管理器变量为yum pkg_manager_flags="" #设置yum的选项为空,因为默认不需要特别选项 config_manager="yum-config-manager" #设置配置管理命令为yum-config-manager enable_channel_flag="--enable" #设置启用频道的选项为--enable disable_channel_flag="--disable" #设置禁用频道的选项为--disable pre_reqs="yum-utils" #设置前置依赖为yum-utils fi
if [ "$lsb_dist" = "fedora" ]; then #判断若发行版ID为fedora pkg_suffix="fc$dist_version" #设置包后缀为fc版本 else #若发行版ID不为fedora pkg_suffix="el" #设置包后缀为el fi repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" #设置仓库文件url ( if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "$pkg_manager $pkg_manager_flags install -y -q $pre_reqs" #安装前置依赖 $sh_c "$config_manager --add-repo $repo_file_url" #安装仓库源
if [ "$CHANNEL" != "stable" ]; then #判断若CHANNEL为非稳定版 $sh_c "$config_manager $disable_channel_flag 'docker-ce-*'" #管理禁用频道所有docker-ce- $sh_c "$config_manager $enable_channel_flag 'docker-ce-$CHANNEL'" #管理启用频道所有docker-ce-CHANNEL版本 fi $sh_c "$pkg_manager makecache" #安装makecache软件 ) #在子环境中运行 pkg_version="" #将软件包版本变量设置为空值 if [ -n "$VERSION" ]; then #判断若版本参数为非空 if is_dry_run; then #判断若为空运行 echo "# WARNING: VERSION pinning is not supported in DRY_RUN" #警告:DRY_RUN不支持版本固定 else #若不为空运行 pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g').*$pkg_suffix" #将版本参数的-ce-替换为.ce.*,-替换为.*,并赋予变量 search_command="$pkg_manager list --showduplicates docker-ce | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" #列出docker-ce包,截取到版本信息,命令赋予变量 pkg_version="$($sh_c "$search_command")" #执行构造的搜索命令,并将结果赋值变量 echo "INFO: Searching repository for VERSION '$VERSION'" #信息:在存储库中搜索版本【版本号】 echo "INFO: $search_command" #信息:【版本信息】 if [ -z "$pkg_version" ]; then #判断若软件包版本为空 echo #换行 echo "ERROR: '$VERSION' not found amongst $pkg_manager list results" #错误:在【软件包版本】列表结果中找不到【版本号】 echo #换行 exit 1 #以1状态码退出 fi if version_gte "18.09"; then #判断若版本参数大于18.09 # older versions don't support a cli package #旧版本不支持cli包 search_command="$pkg_manager list --showduplicates docker-ce-cli | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" #列出docker-ce包,截取到版本信息,命令赋予变量 cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)" #执行命令并提取docker-ce-cli的版本 fi # Cut out the epoch and prefix with a '-' #去掉纪元并在其前面加上一个“-” pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)" #将变量去掉前缀,并添加个“-” fi fi ( pkgs="docker-ce$pkg_version" #将docker-ce加上版本号赋予变量 if version_gte "18.09"; then #判断若版本参数大于18.09 # older versions didn't ship the cli and containerd as separate packages #旧版本没有将cli和containerd作为单独的包提供 if [ -n "$cli_pkg_version" ]; then #判断若设置了cli版本变量 pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io" #pkgs变量增加docker-ce-cli-版本号和containerd.io else #若未设置cli版本变量 pkgs="$pkgs docker-ce-cli containerd.io" #pkgs变量增加docker-ce-cli和containerd.io fi fi if version_gte "20.10"; then #判断若版本参数大于20.10 pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" #pkgs变量增加docker-compose-plugin和docker-ce-rootless-extras版本号 fi if version_gte "23.0"; then #判断若版本参数大于23.0 pkgs="$pkgs docker-buildx-plugin" #pkgs变量增加docker-buildx-plugin fi if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "$pkg_manager $pkg_manager_flags install -y -q $pkgs" #执行安装软件包 ) #在子环境中运行 echo_docker_as_nonroot #非root用户下执行Docker exit 0 #以0状态码返回 ;; sles) #若匹配sles if [ "$(uname -m)" != "s390x" ]; then #判断若当前架构不是s390x echo "Packages for SLES are currently only available for s390x" #SLES软件包目前仅适用于s390x exit 1 #以1状态码退出 fi repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" #定义存储库文件 pre_reqs="ca-certificates curl libseccomp2 awk" #定义预安装的软件包 ( if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "zypper install -y $pre_reqs" #使用zypper命令安装预定义的软件包 $sh_c "zypper addrepo $repo_file_url" #使用zypper命令将指定的存储库URL添加到系统中,以便后续可以从该源安装软件包 if ! is_dry_run; then #判断若为非空运行 cat >&2 <<-'EOF' WARNING!! #警告!! openSUSE repository (https://download.opensuse.org/repositories/security:/SELinux) will be enabled now. #openSUSE存储库(https://download.opensuse.org/repositories/security:/SELinux)现在将启用。 Do you wish to continue? #您想继续吗? You may press Ctrl+C now to abort this script. #您现在可以按Ctrl+C中止此脚本。 EOF #输出警告信息 ( set -x; sleep 30 ) #暂停30秒,给用户时间考虑是否中止操作,在此期间,启用调试模式以显示命令 fi opensuse_repo="https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/security:SELinux.repo" #添加另一个软件源并赋予标量 $sh_c "zypper addrepo $opensuse_repo" #使用zypper命令将其添加为软件源 $sh_c "zypper --gpg-auto-import-keys refresh" #使用zypper刷新软件源,并自动导入GPG密钥,以确保软件包的安全性 $sh_c "zypper lr -d" #使用命令列出所有配置的软件源及其详细信息,方便用户查看。 ) #在子环境中运行 pkg_version="" #将软件包版本变量定于为空 if [ -n "$VERSION" ]; then #判断若版本参数为非空 if is_dry_run; then #判断若为空运行 echo "# WARNING: VERSION pinning is not supported in DRY_RUN" ##警告:DRY_RUN不支持版本固定 else #若不为空运行 pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g')" #将版本参数的-ce-替换为.ce.*,-替换为.*,并赋予变量 search_command="zypper search -s --match-exact 'docker-ce' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'" #列出docker-ce包,截取到版本信息,命令赋予变量 pkg_version="$($sh_c "$search_command")" #执行构造的搜索命令,并将结果赋值变量 echo "INFO: Searching repository for VERSION '$VERSION'" #信息:在存储库中搜索版本【版本号】 echo "INFO: $search_command" #信息:【版本信息】 if [ -z "$pkg_version" ]; then #判断若软件包版本为空 echo #换行 echo "ERROR: '$VERSION' not found amongst zypper list results" #错误:在zypper列表结果中找不到【版本号】 echo #换行 exit 1 #以1状态码退出 fi search_command="zypper search -s --match-exact 'docker-ce-cli' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'" #列出docker-ce-cli包,截取到版本信息,命令赋予变量 # It's okay for cli_pkg_version to be blank, since older versions don't support a cli package #cli_pkg_version为空是可以的,因为旧版本不支持cli包 cli_pkg_version="$($sh_c "$search_command")" #执行构造的搜索命令,并将结果赋值变量 pkg_version="-$pkg_version" #将变量值前加-,并重新赋予变量 fi fi ( pkgs="docker-ce$pkg_version" #将docker-ce加版本赋予变量 if version_gte "18.09"; then #判断若版本参数大于18.09 if [ -n "$cli_pkg_version" ]; then #判断若设置了cli版本变量 # older versions didn't ship the cli and containerd as separate packages #旧版本没有将cli和containerd作为单独的包提供 pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io" #pkgs变量增加docker-ce-cli-版本号和containerd.io else #若未设置cli版本变量 pkgs="$pkgs docker-ce-cli containerd.io" #pkgs变量增加docker-ce-cli和containerd.io fi fi if version_gte "20.10"; then #判断若版本参数大于18.09 pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version" #pkgs变量增加docker-compose-plugin和docker-ce-rootless-extras版本号 fi if version_gte "23.0"; then #判断若版本参数大于23.0 pkgs="$pkgs docker-buildx-plugin" #pkgs变量增加docker-buildx-plugin fi if ! is_dry_run; then #判断若为非空运行 set -x #启用调试模式 fi $sh_c "zypper -q install -y $pkgs" #使用zypper命令安装软件包 ) echo_docker_as_nonroot #非root用户下执行Docker exit 0 #以0状态码返回 ;; *) #若未匹配到 if [ -z "$lsb_dist" ]; then #判断若发行版为空 if is_darwin; then #判断若操作系统是macOS echo #换行 echo "ERROR: Unsupported operating system 'macOS'" #错误:不支持的操作系统“macOS” echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop" #请从获取Docker桌面https://www.docker.com/products/docker-desktop echo #换行 exit 1 #以1状态码退出 fi fi echo #换行 echo "ERROR: Unsupported distribution '$lsb_dist'" #错误:不支持的分发【发行版】 echo #换行 exit 1 #以1状态码退出 ;; esac exit 1 #以1状态码退出}
# wrapped up in a function so that we have some protection against only getting #被包裹在一个函数中,这样我们就可以得到一些保护,防止只得到# half the file during "curl | sh" #“curl |sh” #期间文件的一半do_install #调用安装脚本
xxxxxxxxxx
usage() { echo "check -v | --vendor) vendor -o | --organization) organization number -c | --channelid) channel id -e | --external-disk) use external disk -s | --storage-size) storage size -d | --storage-directory) storage directory -n | --need-ai) need ai -p | --pipe-type) pipe type -h | --help) print this info " #指定帮助文档 exit 0 #以0状态码退出} #使用方法函数
option=$(getopt -o v:o:c:e:s:d:n:p:h --long vendor:,organization:,channelid:,external-disk:,storage-disk:,storage-directory:,need-ai:,pipe-type:,help -- "$@") #解析传入的命令行参数,并将解析后的结果存储在变量中
eval set -- "$option" #将getopt解析出的命令行参数重新设置为脚本的位置参数
while true #做出无限循环do #开始 case $1 in #判断输入的选项 -v | --vendor) shift; u_vendor=$1 ; shift ;; #定义供应商后左移 -o | --organization) shift; u_organization=$1 ; shift ;; #定义渠道代码后左移 -c | --channelid) shift; u_channelid=$1 ; shift ;; #定义渠道ID后左移 -e | --external-disk) shift; u_external_disk=$1 ; shift ;; #定义外接盘后左移 -s | --storage-size) shift; u_storage_size=$1 ; shift ;; #定义缓存大小后左移 -d | --storage-directory) shift; u_storage_directory=$1 ; shift ;; #定义缓存目录后左移 -n | --need-ai) shift; u_need_ai=$1 ; shift ;; #定义自动AI后左移 -p | --pipe-type) shift; u_pipe_type=$1 ; shift ;; #定义包类型后左移 -h | --help ) usage ;; #调用方法函数 --) shift ; break ;; #左移后退出循环 *) usage ;; #调用方法函数 esacdone #结束
u_version="v0.0.5" #将版本默认设置为v0.0.5echo "version: $u_version" #输出版本信息
# install tools #安装工具包sed -i'' 's/mirrors-internal.cmecloud.cn/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list #将/etc/apt/sources.list文件中的所有mirrors-internal.cmecloud.cn字符串替换为mirrors.tuna.tsinghua.edu.cnapt update #更新软件源apt install -y jq bc ca-certificates gnupg lsb-release xz-utils bzip2 unzip zip #下载必要软件
# install update scripts #安装更新脚本wget https://cdn2.bkdomain.cn/system-scripts/v0.2.4/update-armbian.deb -O /opt/update-armbian.deb #下载更新更新armbian包dpkg -i /opt/update-armbian.deb #安装更新armbian包rm -f /opt/update-armbian.deb #删除原下载的更新armbian包# only update pakages in this list #只更新软件列表{ echo "custom-dot-dns-config" echo "update-armbian" echo "nm-dispatcher"} > /etc/sysconfig/dianxin.packages #将需要更新的软件输入进列表文件sleep 3 #暂停3秒
# install dot config #安装dot配置wget https://cdn2.bkdomain.cn/system-scripts/custom-dot-dns-config-x86.deb -O /opt/custom-dot-dns-config-x86.deb #下载dot配置包dpkg -i /opt/custom-dot-dns-config-x86.deb #安装dot配置包rm -f /opt/custom-dot-dns-config-x86.deb #删除原下载的dot配置包systemctl enable --now systemd-resolved.service #将resolved服务启动,并设置开机自启sleep 3 #暂停3秒
# enable dot #默认dotif dig @127.0.0.53 www.google.com && ! grep -q "nameserver 127.0.0.53" /etc/resolv.conf #判断dns是否能解析谷歌网站,且dns非127.0.0.53then #若都满足 cp /etc/resolv.conf /etc/resolv.conf.bak #备份dsn全局文件 echo 'nameserver 127.0.0.53' > /etc/resolv.conf #将dns全局文件的dns设置为127.0.0.53fi
# install docker #安装dockerdocker_version=$(docker --version | awk '{print $3}' | sed 's/,//g' 2>/dev/null) #将当前docker版本赋予变量if [[ "$docker_version" < "20.00.00" ]] #判断当前docker版本是否小于20then #若小于 curl -fsSL https://cdn2.bkdomain.cn/product/terminal/get-docker_amd64.sh | bash -s docker --mirror Aliyun #下在安装docker脚本,并采用阿里云源运行安装fisleep 3 #暂停3秒
# install netowrk manager disapatcher to support multiple ipv6 nic #安装netowrk管理器dispatcher以支持多个ipv6网卡wget https://cdn2.bkdomain.cn/system-scripts/nm-dispatcher/v0.1.8/nm-dispatcher.deb -O /tmp/nm-dispatcher.deb #下载dispatcher包dpkg -i /tmp/nm-dispatcher.deb #安装dispatcher包rm -f /tmp/nm-dispatcher.deb #删除原下载的dispatcher包sleep 3 #暂停3秒
# dianxian deploy configuration #点心部署配置mkdir -p /etc/sysconfig #创建sysconfig目录cat << EOF > /etc/sysconfig/dianxin.envsCHANNELID="${u_channelid:-CBV9UHAA0320220905143123262}"ORGCODE="${u_organization:-A03}"STORAGE_DIRECTORY="${u_storage_directory:-/storage}"STORAGE_SIZE="${u_storage_size:-100}"VENDOR="${u_vendor:-LW}"NEED_AI="${u_need_ai:-1}"PIPE_TYPE="${u_pipe_type:-small}"ONLY_STORAGE_DISK="${u_external_disk:-true}"SWAPON="false"LANG=en_US.UTF-8LC_CTYPE="en_US.UTF-8"LC_NUMERIC="en_US.UTF-8"LC_TIME="en_US.UTF-8"LC_COLLATE="en_US.UTF-8"LC_MONETARY="en_US.UTF-8"LC_MESSAGES="en_US.UTF-8"LC_PAPER="en_US.UTF-8"LC_NAME="en_US.UTF-8"LC_ADDRESS="en_US.UTF-8"LC_TELEPHONE="en_US.UTF-8"LC_MEASUREMENT="en_US.UTF-8"LC_IDENTIFICATION="en_US.UTF-8"LC_ALL=EOF #将参数信息存入点心环境配置文件
# install and start dianxin system #安装并开启点心系统wget https://cdn2.bkdomain.cn/system-scripts/dianxin-deploy-amd64.deb -O /tmp/dianxin-deploy-amd64.deb #下载点心部署包dpkg -i /tmp/dianxin-deploy-amd64.deb #安装点心部署包rm -f /tmp/dianxin-deploy-amd64.deb #删除原下载的点心部署包
# disable nic dns #禁用网卡dnsif [[ -f /etc/netplan/00-installer-config.yaml ]] #判断00-installer-config.yaml文件是否存在then #若存在cat << EOF > /etc/netplan/00-installer-config.yamlnetwork: version: 2 renderer: NetworkManager ethernets: eth0: dhcp4: true dhcp6: true dhcp4-overrides: ipv4.ignore-auto-dns: yes dhcp6-overrides: ipv6.ignore-auto-dns: yes eth1: dhcp4: true dhcp6: true dhcp4-overrides: ipv4.ignore-auto-dns: yes dhcp6-overrides: ipv6.ignore-auto-dns: yes eth2: dhcp4: true dhcp6: trueEOF #将配置信息输入进配置文件fi
# enable mutiple ipv6 route table #启用多个ipv6路由表nmcli con show --active | grep "ethernet" | awk '{print $2}' | while read -r uuid #截取到所有以太网设备的uuiddo #循环调用uuid nmcli conn up "$uuid" #启用对应uuid的网卡done & #循环结算,并后台进程执行循环过程
xxxxxxxxxxusage(){ echo "Usage: deploy -s | --system-mountpoint <mountpoint> 指定系统挂载点 / --fstype <fstype> 指定数据盘所用文件系统:ext4 | xfs> --help " exit 2}
VERSION="v1.1.8"version() { echo "$VERSION" exit 0}
FSTYPE=SYSTEM_MOUNTPOINT=""
PARSED_ARGUMENTS=$(getopt -a -n arm-diskManager.sh -o s: --long help,system-mountpoint:,fstype:,version -- "$@")
VALID_ARGUMENTS=$?
if [ "${VALID_ARGUMENTS}" != "0" ]; then usagefi
eval set -- "${PARSED_ARGUMENTS}"while :do case "$1" in -s | --system-mountpoint) SYSTEM_MOUNTPOINT="$2"; shift 2 ;; -v | --version) version; shift;; --fstype) FSTYPE="$2"; shift 2 ;; --help) usage ; shift ;; --) shift; break ;; *) echo "Unexpected option: $1 - this should not happen." usage ;; esacdone
export SYSTEM_MOUNTPOINT="${SYSTEM_MOUNTPOINT}"export FSTYPE="${FSTYPE}"
do_use_system_disk_free_space() { local root_part local storage_size local storage_file local STORAGE_LOOPDEV local virtual_disk_type local available_disk_space=${AVAILABLE_DISK_SPACE:-${DISK_SIZE}}
if [[ -z "$available_disk_space" ]] then root_part=$(system_disk) available_disk_space=$(lsblk -dno size -b /dev/"$root_part") # 给docker和系统预留一部分 storage_size=$(echo "($available_disk_space - (4 * $__GBytes__)) * 0.92" | bc)
# 512 取整 storage_size=$(echo "scale=0; $storage_size / $__Sector_size__" | bc) storage_size=$(echo "scale=0; $storage_size * $__Sector_size__" | bc)
# GB 向上取整 storage_size=$(echo "scale=1; $storage_size / $__GBytes__" | bc) storage_size=$(printf "%.0f" "$storage_size") storage_size=$(echo "scale=0; $storage_size * $__GBytes__" | bc) else storage_size=$(echo "scale=0; $available_disk_space * $__GBytes__" | bc) fi
virtual_disk_type="$(jq -r '.virtual_disk_type' /writable/vendor/info.json 2>/dev/null)" virtual_disk_type=${virtual_disk_type:-raw}
if [[ "${virtual_disk_type}" == "raw" ]] then storage_file="${STORAGE_FILE:-/root/storage.raw}" [[ ! -e $storage_file ]] && qemu-img create -f raw "$storage_file" "$storage_size" if ! losetup | grep -q "$storage_file" then if [[ ! -f /writable/.agent_install ]] || ! losetup | grep "${storage_file#/storage/}" | grep -qvi "deleted" then STORAGE_LOOPDEV=$( losetup -f ) losetup "$STORAGE_LOOPDEV" "$storage_file" fi fi else storage_file="${STORAGE_FILE:-/root/storage.qcow2}" [[ ! -e $storage_file ]] && qemu-img create -f qcow2 "$storage_file" "$storage_size" local nbd_dev nbd_dev=$(connect_to_nbd "$storage_file") echo "$nbd_dev" fi}
do_mount_docker_root() { [[ -e /etc/docker/daemon.json.default ]] && mv /etc/docker/daemon.json.default /etc/docker/daemon.json source /usr/bin/lv_manager.sh local docker_lv_size=8 local docker_root_mnt docker_root_mnt=$(create_lv docker_root "$docker_lv_size" any 2>/dev/null) if [[ -n ${docker_root_mnt} ]] then rm -rf /writable/ipfsbit-518518/docker/ mkdir -p /writable/ipfsbit-518518/docker/ mount -o bind "$docker_root_mnt" /writable/ipfsbit-518518/docker fi}
clean_storage_file() { local storage_file
virtual_disk_type="$(jq -r '.virtual_disk_type' /writable/vendor/info.json 2>/dev/null)" virtual_disk_type=${virtual_disk_type:-raw} if [[ "${virtual_disk_type}" == "raw" ]] then storage_file="${STORAGE_FILE:-/root/storage.raw}" else storage_file="${STORAGE_FILE:-/root/storage.qcow2}" fi
rm -f "$storage_file"}
source /usr/bin/diskManager_core.sh
# worktile: #24925# get available disks and ignore loop deviceif [[ -n "$(available_disks true)" ]]then MIN_SIZE_REQ="${MIN_SIZE_REQ:-40}"else MIN_SIZE_REQ="-1"fi
if use_system_disk_free_space "$MIN_SIZE_REQ"then do_use_system_disk_free_spaceelse clean_storage_filefi# worktile #
source /usr/bin/lvm_core.sh
create_xpool "${HDD_XPOOL}"create_xpool "${SSD_XPOOL}"mount_lvm_disk
# worktile: #24925if need_mount_docker_root && external_xpool_exitsthen do_mount_docker_rootfi# worktile #
sleep 5
xxxxxxxxxx# zfs module is not loaded in initramfs#if [[ ! -e /sys/module/zfs ]]then sleep 1 /sbin/modprobe zfs sleep 1fi
if ! zfs version || ! lsmod | grep -q '^zfs\s'then exit 2fi
if ! zpool status | grep -q "state: ONLINE"then systemctl start zfs-import-cache sleep 3 if ! zpool status | grep -q "state: ONLINE" then zpool import -c /etc/zfs/zpool.cache storage_pool sleep 3 if ! zpool status | grep -q "state: ONLINE" then if [[ -f /writable/.disks-byid ]] then for id in $(cat /writable/.disks-byid) do args="$args -d $id" done zpool import $args storage_pool rm /writable/.disks-byid fi fi fi systemctl start zfs-mount systemctl start zfs-share systemctl start zfs-zed systemctl start zfs-volume-waitfi
system_disk_mount='/'if [[ "$1" != "" ]]then system_disk_mount="$1" SYSTEM_MOUNTPOINT="$1"fi
source /usr/bin/create_zfs_dataset.shsource /usr/bin/zfs_core.sh
# before check zpool to wait zpool be stable fist.sleep 2if zpool status storage_pool |grep -q "status: Mismatch between pool hostid and system hostid on imported pool."then echo "status: Mismatch between pool hostid and system hostid on imported pool." zpool destroy storage_poolfi
# 有少数合作伙伴的机器上只有一块硬盘,系统盘和数据盘只能用同一块盘。source /usr/bin/diskManager_core.shif use_system_disk_free_spacethen create_zpool_add_udev_one_diskelse create_zpool_add_udevfi
# after create zpool to wait zpool be stable again.sleep 2# sometimes zpool misses features, upgrade zpool again.
if zpool status | grep -q 'features are not enabled'then zpool upgrade storage_pool > /dev/null 2>&1fi
if use_system_disk_free_spacethen source /usr/bin/create_zfs_dataset.sh storage_pool_size=$(zpool get -Hp size 'storage_pool'|awk '{print $3}') docker_dataset_size=$(echo "$storage_pool_size / 1024 / 1024 / 1024 * 0.1" | bc) docker_dataset_size=$(printf "%.0f" $docker_dataset_size) [[ "$docker_dataset_size" -lt 5 ]] && docker_dataset_size=5 create_dataset --name 'docker-root' --quota-size $docker_dataset_size --parent-zfs 'storage_pool' --primarycache 'none' 2>/dev/null mkdir -p /writable/ipfsbit-518518/docker mount -o bind /writable/storage_pool/docker-root /writable/ipfsbit-518518/docker [[ -e /etc/docker/daemon.json.default ]] && mv /etc/docker/daemon.json.default /etc/docker/daemon.jsonfi
sleep 5
xxxxxxxxxx#0.7#字节云上提供如上两种系统供下载echo 判断是否有AIaio -m dec -i /writable/agent-new/config/vendor.yaml -o /writable/agent-new/config/tttAI_NUM=$(cat /writable/agent-new/config/ttt | grep isNeedAi |awk '{print $2}')if (($AI_NUM == 1))then sed -i "s/isNeedAi: 1/isNeedAi: 0/g" /writable/agent-new/config/ttt rm -rf /writable/agent-new/config/vendor.yaml aio -m enc -i /writable/agent-new/config/ttt -o /writable/agent-new/config/vendor.yaml rm -rf /writable/agent-new/config/ttt systemctl restart agent-new
else echo "AI已关闭"fi
zpool=$(zpool list -v|grep -v 'no pools available'|wc -l)if(($zpool == 0))then echo "无zpool池子"else zpool destroy storage_poolfi
echo "判断设备是否存在业务"if [ `docker ps -a | grep Up | grep -v Network | wc -l` -gt 0 ];then echo -e "\033[1;31m 检测到设备存在其他业务容器 \033[0m" exit 8fi
echo "判断是否有VG分区"if [ `docker ps -a | grep toutiao | wc -l` -gt 0 ];then echo -e "\033[1;31m 检测到字节业务停止进程 \033[0m" exit 8else vg_name=$(vgdisplay | grep 'VG Name' | awk '{print $3}') if [ `vgdisplay | wc -l` -gt 0 ]; then echo $vg_name vgremove $vgname fi if [ `vgdisplay | wc -l` -le 0 ]; then echo -e "\033[1;32m VG挂载以清除 \033[0m" else echo -e "\033[1;31m VG挂载未成功清除,使用vgdispaly检查 \033[0m" exit 7 echo "olddog" fifi
echo "清除磁盘挂载"disk_name=$(blkid -o list | grep "/writable/ipfsbit-" | awk '{print $1}')disk_name2=$(df -h | grep '/writable/ipfsbit' | awk '{print $1}')for disk1 in $disk_name $disk_name2do umount $disk1donesys_dev=$(eval $(lsblk -o MOUNTPOINT,PKNAME -P | grep 'MOUNTPOINT="/"'); echo $PKNAME | sed 's/[0-9]*$//')dev=$(lsblk -dpno name,tran | grep -v loop | grep -v $sys_dev | grep -v sr | grep -v fd | grep -v usb$ | grep -v mmc| grep -v zram| grep -v zd|awk '{print $1}')for disk in $devdo mkfs.xfs -f $diskdone#判断磁盘挂载if [ `df -h | grep /writable |wc -l` -le 0 ];then echo -e "\033[1;32m 磁盘挂载以清除 \033[0m"else echo -e "\033[1;31m 磁盘挂载未清除,退出脚本执行 \033[0m" exit 9 echo "olddog"fi
echo "更改网络参数变量"echo 5242880 > /proc/sys/net/core/wmem_maxecho 5242880 > /proc/sys/net/core/wmem_defaultecho 2621440 > /proc/sys/net/nf_conntrack_maxecho 2097152 > /proc/sys/net/core/rmem_defaultecho 2097152 > /proc/sys/net/core/rmem_maxsysctl -pwmem_max=$(cat /proc/sys/net/core/wmem_max)wmem_default=$(cat /proc/sys/net/core/wmem_default)nf_conntrack_max=$(cat /proc/sys/net/nf_conntrack_max)echo "开始初始化变量"echo 1 > /writable/.disable-diskManagerchmod -x /usr/bin/diskManager.shI=$(cat /writable/.deviceID)echo "export EXTERNAL_DEVICE_ID=$I" >> /etc/profileecho "export EXTERNAL_PROVIDER=linkfog" >> /etc/profileecho "export EXTERNAL_NW_MUL=1" >> /etc/profilesource /etc/profile
check_sysinfo() { if [ ! "$BASH_VERSION" ] ; then echo -e "\033[31m must be run shell script use bash,not others\033[0m" exit 1 fi cat /etc/os-release|grep -iE "centos|debian" if [ $? -ne 0 ];then echo -e "\033[31mcurrent System is Not Meet the Requirements \033[0m" echo -e "\033[31m 当前系统不满足要求, 不是centos 和 debian 系统 请更换 \033[0m" exit 1 fi if [ $(id -u) -eq 0 ] then echo -e "\033[31mcurrent user is root installing \033[0m" else echo -e "\033[31mcurrent is not root install failed \033[0m" echo -e "\033[31m 当前执行用户不是root 部分命令无法执行,请更换为 root 用户执行 \033[0m" exit 1 fi cat /etc/os-release|grep -i "centos" if [ $? -eq 0 ];then echo "centos" SysTem="centos" else echo "debian" SysTem="debian" fi}
check_device_file() {FILE='/opt/oort/sys-conf/pcdn_device_info' if [ -f "$FILE" ]; then echo "$FILE exists." echo "pcdn_device_info-设备文件存在" else echo "pcdn_device_info-设备文件不存在" #exit 1 fi}
# check cpu and mem cpumem_info() { cpunum=`cat /proc/cpuinfo| grep "processor"| wc -l` cpuinfo=`cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c` memnum=`grep MemTotal /proc/meminfo|awk '{print $2/(1024)/(1024)}'` if [ ${cpunum} -lt 16 ];then echo ${cpuinfo} echo -e "\033[31mcurrent cpu num is non-compliant \033[0m" echo -e "\033[31m 当前机器cpu 和 内存大小不符合设备募集要求 \033[0m" echo "this machine cpu count is" ${cpunum} echo "this machine mem size is" ${memnum} echo -e "\033[31m cpu 需求32以及以上 内存大小64以及以上 \033[0m" exit 1 else echo ${cpuinfo} echo "this machine cpu count is" ${cpunum} echo "this machine mem size is:" ${memnum} fi}
#change apt or yum repo to internal
debian_change_reposource() { cp /etc/apt/sources.list /etc/apt/sources.list_bak #grep debian /etc/apt/sources.list|grep http|awk -F "/" '{gsub($3,"mirrors.aliyun.com");print $0}' > /tmp/sources.list grep debian /etc/apt/sources.list|grep http|awk -F "/" '{gsub($3,"ftp.cn.debian.org");print $0}' > /tmp/sources.list rm -f /etc/apt/sources.list mv /tmp/sources.list /etc/apt/}
#fdisk disk parted disk
init_disk() { LVMDISK="" echo "显示磁盘设备信息:" echo "show disk sources:" #parted -l |grep -v 'sr0'|grep -w "unrecognised disk" ALLDISK=`lsblk -d|grep disk|grep -v M|grep -v K|awk '{print "/dev/"$1}'` echo "本台机器有如下磁盘设备可用,请确认是否正确" echo ${ALLDISK} echo "下面开始检查每个磁盘是否可用:" for i in ${ALLDISK} do Count=`lsblk ${i}|wc -l` MountType=`lsblk ${i}|grep -v NAME|awk '{print $7}'` if [ $Count -gt 2 ];then echo "${i} 已经挂载使用不可以用作lvm的设备" elif [ -n "$MountType" ]; then echo "${i} 已经挂载在${MountType},不可以用作lvm的设备" else LVMDISK="${i} ${LVMDISK}" fi done Vgcout=`vgs|wc -l` if [ ${Vgcout} -ge 1 ];then echo "vg name 如下:" vgs echo "vg 已经存在,请确认是否可用,否则请执行vgremove 删除vg,执行vgcreate bydata {设备名} 重新创建 VGname:--->bydata" exit 1 else echo ${LVMDISK} if [ -z "${LVMDISK}" ];then echo "Disk is NULL, so no disk to used, please 清理磁盘 or 新挂载磁盘" exit 1 else pvcreate ${LVMDISK} vgcreate bydata ${LVMDISK} vgdisplay fi fi}
initdeviceid() { mkdir -p /opt/oort/sys-conf/ rm -f /opt/oort/sys-conf/systemd_env_info EXTERNAL_PROVIDER=`env|grep -i EXTERNAL_PROVIDER|awk -F '=' '{print $2}'` EXTERNAL_DEVICE_ID=`env|grep -i EXTERNAL_DEVICE_ID|awk -F '=' '{print $2}'` OORT_ENV_PROVIDER=`env|grep -i EXTERNAL_PROVIDER|awk -F '=' '{print $2}'` OORT_ENV_POD_IF_MUL=`env|grep -i EXTERNAL_NW_MUL|awk -F '=' '{print $2}'` Md5deviceid=`echo ${EXTERNAL_DEVICE_ID}|md5sum|awk '{print $1}'` OwnDeviceid=${EXTERNAL_PROVIDER}-${Md5deviceid} touch /opt/oort/sys-conf/oort_deviceid_info touch /opt/oort/sys-conf/oort_provider_info touch /opt/oort/sys-conf/systemd_env_info touch /opt/oort/sys-conf/mul_env_info
echo "OORT_ENV_DEVICE_ID=${OwnDeviceid}" > /opt/oort/sys-conf/oort_deviceid_info echo "OORT_ENV_PROVIDER=${OORT_ENV_PROVIDER}" > /opt/oort/sys-conf/oort_provider_info echo "OORT_ENV_POD_IF_MUL=${OORT_ENV_POD_IF_MUL}" > /opt/oort/sys-conf/mul_env_info
echo "OORT_ENV_PROVIDER=${OORT_ENV_PROVIDER}" > /opt/oort/sys-conf/systemd_env_info echo "EXTERNAL_PROVIDER=${EXTERNAL_PROVIDER}" >> /opt/oort/sys-conf/systemd_env_info echo "OORT_ENV_DEVICE_ID=${OwnDeviceid}" >> /opt/oort/sys-conf/systemd_env_info echo "EXTERNAL_DEVICE_ID=${EXTERNAL_DEVICE_ID}" >> /opt/oort/sys-conf/systemd_env_info echo "OORT_ENV_POD_IF_MUL=${OORT_ENV_POD_IF_MUL}" >> /opt/oort/sys-conf/systemd_env_info
grep 'OORT_ENV_DEVICE_ID' /etc/profile if [ $? -eq 0 ];then sed -i '/OORT_ENV_DEVICE_ID/d' /etc/profile fi grep 'OORT_ENV_PROVIDER' /etc/profile if [ $? -eq 0 ];then sed -i '/OORT_ENV_PROVIDER/d' /etc/profile fi grep 'OORT_ENV_POD_IF_MUL' /etc/profile if [ $? -eq 0 ];then sed -i '/OORT_ENV_POD_IF_MUL/d' /etc/profile fi echo "export OORT_ENV_PROVIDER=${OORT_ENV_PROVIDER}" >> /etc/profile echo "export OORT_ENV_DEVICE_ID=${OwnDeviceid}" >> /etc/profile echo "export OORT_ENV_POD_IF_MUL=${OORT_ENV_POD_IF_MUL}" >> /etc/profile source /etc/profile if [ $? -eq 0 ] then echo "生效/etc/profile环境变量" else echo "设备环境变量存在问题,请查看 /etc/profile 是否存在问题" exit 1 fi export OORT_ENV_PROVIDER=${OORT_ENV_PROVIDER} export OORT_ENV_DEVICE_ID=${OwnDeviceid}
}
#remove docker debian_remove_pre_installed_docker() { status=$(dpkg-query -W -f='${Status}\n' docker-ce | awk '{print $3}') if [[ "$status" == "installed" ]];then print_msg "Removing pre-installed docker-ce" apt-get remove --purge -y docker-ce fi}############
debian_install_docker() { curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - apt-key fingerprint 0EBFCD88 add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" apt-get update apt-get install docker-ce docker-ce-cli containerd.io -y systemctl daemon-reload systemctl enable docker systemctl restart docker}
#change dns_serverchange_dnsserver() { chattr -i /etc/resolv.conf rm -f /etc/resolv.conf cat>/etc/resolv.conf<<EOFoptions timeout:1 attempts:3 rotatenameserver 119.29.29.29nameserver 180.76.76.76nameserver 223.5.5.5nameserver 114.114.114.114EOF lsattr /etc/resolv.conf chattr +i /etc/resolv.conf}
change_nf_max() { echo "net.nf_conntrack_max = 2621440" >> /etc/sysctl.conf echo "net.core.wmem_max = 5242880" >> /etc/sysctl.conf echo "net.core.wmem_default = 5242880" >> /etc/sysctl.conf echo "net.core.rmem_max = 2097152" >> /etc/sysctl.conf echo "net.core.rmem_default = 2097152" >> /etc/sysctl.conf echo "net.ipv4.tcp_mem = 2097152 3145728 5242880" >> /etc/sysctl.conf echo "net.ipv4.tcp_wmem = 2097152 3145728 5242880" >> /etc/sysctl.conf echo "net.ipv4.tcp_rmem = 2097152 3145728 5242880" >> /etc/sysctl.conf echo nf_conntrack > /usr/lib/modules-load.d/net.conf sysctl -p}
#change system core parameterschange_pars() { echo "net.netfilter.nf_conntrack_max=655350" >> /etc/sysctl.conf echo "net.netfilter.nf_conntrack_tcp_timeout_establishedi=1200" >> /etc/sysctl.conf sysctl -p}
#turnoff swapturnoff_swap() { swaptotal=$(grep SwapTotal /proc/meminfo | awk '{print $2}') if [ $swaptotal -gt 0 ];then echo "Turnning off SWAP" swapoff -a sed -i -e 's/.*swap/#&/' /etc/fstab echo "vm.swappiness=0" >>/etc/sysctl.conf sysctl -p fi}
#wget X86 run process file from tosX86PrepareLocalSoftware() { curl -o platform.json "http://is.snssdk.com/service/settings/v2/?caller_name=pcdn_netbox&app=254&device_id=1&device_platform=x86_64&os=linux&req_type=init" SoftNum=`cat platform.json |jq .data.app.update_module_platform|jq 'length'` if [ -z $SoftNum ]; then echo "获取配置错误 请重新执行 initlvmdevbox.sh" echo "get configure error please try again initlvmdevbox.sh" exit 1 fi index=0 while [ $index -lt $SoftNum ]; do SoftUrl=`cat platform.json |jq -r .data.app.update_module_platform[$index].md_dl_url` SoftName=`cat platform.json |jq -r .data.app.update_module_platform[$index].md_name` echo "=============================================================" sleep 2 #wget ${SoftUrl} -O ${SoftName}.tgz curl -o ${SoftName}.tgz ${SoftUrl} echo "=============================================================" SoftMd5=`cat platform.json |jq -r .data.app.update_module_platform[$index].md_md5` SoftPath=`cat platform.json |jq -r .data.app.update_module_platform[$index].md_path` LocalMd5=`md5sum ${SoftName}.tgz|awk '{print $1}'` echo ${LocalMd5} if [ "$LocalMd5" = "$SoftMd5" ] ; then mkdir -p ${SoftPath} tar -zxvf ${SoftName}.tgz -C ${SoftPath} else echo "wget file error md5sum value not equal" exit 1 fi ((index++)) done rm -f platform.json}
## debainStartdebainDaemon() { # start daemonPath=/usr/local/by-daemon/ chmod 754 ${daemonPath}netbox_daemon.service cp ${daemonPath}netbox_daemon.service /lib/systemd/system/ ln -fs /lib/systemd/system/netbox_daemon.service /etc/systemd/system/netbox_daemon.service systemctl daemon-reload systemctl enable netbox_daemon.service systemctl start netbox_daemon.service}
##centosStartcentosDaemon() { daemonPath=/usr/local/by-daemon/ chmod 754 ${daemonPath}netbox_daemon.service cp ${daemonPath}netbox_daemon.service /usr/lib/systemd/system/ systemctl daemon-reload systemctl enable netbox_daemon.service systemctl start netbox_daemon.service} #print helpPrintHelp() { printf "Usage:\n" printf "sh ProviderInit.sh [command]\n" printf "Available Commands:\n" printf " --init : init base info\n" printf " --help : show this help\n" printf " --note : support centos 7.0+ debain \n" printf " --initdisk : used lvm from disk create vg \n" exit 0}
change_mirrors() { if [[ "${SysTem}" = "centos" ]];then sed -e 's|^mirrorlist=|#mirrorlist=|g' \ -e 's|^#baseurl=http://mirror.centos.org/centos|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos|g' \ -i.bak \ /etc/yum.repos.d/CentOS-*.repo
if [[ -f /etc/yum.repos.d/epel.repo ]];then sed -e 's!^metalink=!#metalink=!g' \ -e 's!^#baseurl=!baseurl=!g' \ -e 's!http://download\.fedoraproject\.org/pub/epel!https://mirrors.tuna.tsinghua.edu.cn/epel!g' \ -e 's!http://download\.example/pub/epel!https://mirrors.tuna.tsinghua.edu.cn/epel!g' \ -i /etc/yum.repos.d/epel*.repo else yum -y install epel-release sed -e 's!^metalink=!#metalink=!g' \ -e 's!^#baseurl=!baseurl=!g' \ -e 's!http://download\.fedoraproject\.org/pub/epel!https://mirrors.tuna.tsinghua.edu.cn/epel!g' \ -e 's!http://download\.example/pub/epel!https://mirrors.tuna.tsinghua.edu.cn/epel!g' \ -i /etc/yum.repos.d/epel*.repo fi
if [[ -f /etc/yum.repos.d/elrepo.repo ]];then cat > /etc/yum.repos.d/elrepo.repo <<EOF### Name: ELRepo.org Community Enterprise Linux Repository for el7### URL: https://elrepo.org/
[elrepo]name=ELRepo.org Community Enterprise Linux Repository - el7baseurl=https://mirrors.tuna.tsinghua.edu.cn/elrepo/elrepo/el7/\$basearch/#mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo.el7enabled=1gpgcheck=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.orgprotect=0
[elrepo-testing]name=ELRepo.org Community Enterprise Linux Testing Repository - el7baseurl=https://mirrors.tuna.tsinghua.edu.cn/elrepo/elrepo/el7/\$basearch/#mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo.el7#mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo-testing.el7enabled=0gpgcheck=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.orgprotect=0
[elrepo-kernel]name=ELRepo.org Community Enterprise Linux Kernel Repository - el7baseurl=https://mirrors.tuna.tsinghua.edu.cn/elrepo/elrepo/el7/\$basearch/#mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo.el7#mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo-kernel.el7enabled=0gpgcheck=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.orgprotect=0
[elrepo-extras]name=ELRepo.org Community Enterprise Linux Extras Repository - el7baseurl=https://mirrors.tuna.tsinghua.edu.cn/elrepo/elrepo/el7/\$basearch/#mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo-extras.el7enabled=0gpgcheck=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.orgprotect=0EOF fi
yum makecache fi}
################main################
if [ $# -gt 0 ]; then action=${1} case ${action} in "init") check_sysinfo change_mirrors cpumem_info check_device_file change_dnsserver turnoff_swap change_nf_max Arch=`uname -m` #check arch if [ "${Arch}" = "x86_64" ] then echo "系统架构是 : ${Arch}" else echo "系统架构是 : ${Arch}" echo "系统架构不是x86架构, 服务部署会失败, 请使用x86架构的机器" exit 1 fi # create owner diviceid env|grep -i DEVICE_ID if [ $? -eq 0 ] then initdeviceid else echo "设备环境变量没有传递,请更新设备环境变量 EXTERNAL_PROVIDER and EXTERNAL_DEVICE_ID" exit 1 fi env|grep -i EXTERNAL_PROVIDER if [ $? -eq 0 ] then initdeviceid else echo "设备环境变量没有传递,请更新设备环境变量 EXTERNAL_PROVIDER and EXTERNAL_DEVICE_ID" exit 1 fi #check system if [ "${SysTem}" = "centos" ] then yum -y install redhat-lsb-core util-linux fio lshw yum -y install wget curl bind-utils yum-utils dmidecode yum install -y fio yum install -y ntpdate ntp yum install -y jq ipset yum install -y lvm2 yum install -y lvm docker --version systemctl enable docker systemctl enable ntpd systemctl enable ntpdate ntpdate time2.bytedance.com systemctl start ntpdate systemctl restart ntpd systemctl start docker DocVer=`docker --version|awk '{print $3}'|awk -F "." '{print $1}'` if [ "${DocVer}" -lt 18 ];then centos_remove_pre_installed_docker fi X86PrepareLocalSoftware StartcentosDaemon elif [ "${SysTem}" = "debian" ] then apt-get update apt-get install fio -y if [ $? -ne 0 ];then debian_change_reposource fi apt-get -y install lsb-release curl wget dnsutils util-linux systemd lshw dmidecode apt-get install -y lvm2 apt-get install -y jq ipset apt-get install -y update ntp apt-get install -y lvm docker --version if [ $? -ne 0 ];then apt-get -y install apt-transport-https ca-certificates gnupg-agent software-properties-common debian_remove_pre_installed_docker debian_install_docker fi systemctl enable docker systemctl enable ntp ntpdate time2.bytedance.com systemctl restart ntp #systemctl start docker DocVer=`docker --version|awk '{print $3}'|awk -F "." '{print $1}'` if [ "${DocVer}" -lt 18 ];then apt-get -y install apt-transport-https ca-certificates gnupg-agent software-properties-common debian_remove_pre_installed_docker debian_install_docker fi X86PrepareLocalSoftware StartdebainDaemon else echo -e "System check fail..........................." echo -e "\033[31mcurrent System is Not Meet the Requirements \033[0m" echo -e "\033[31m 当前系统不满足要求,请更换 centos 和 debian 系统 \033[0m" exit 1 fi wget http://lf9-netbox-package.bytetos.com/obj/netbox-update-package/initdevice/libstdcpp.tgz tar -zxvf libstdcpp.tgz cp libstdc++.so.6.0.26 /usr/lib64/ && cd /usr/lib64/ && ln -f -s libstdc++.so.6.0.26 libstdc++.so.6 echo "更新内核版本" grub2-mkconfig -o /boot/efi/EFI/BOOT/grub.cfg grub2-mkconfig -o /boot/grub2/grub.cfg /usr/bin/cp -f /opt/apps/systemd-cryptsetup /lib/systemd/systemd-cryptsetup partprobe device=$(blkid -o list | grep "crypto_LUKS" | awk '{print $1}') luks_uuid=$(blkid -o value -s UUID $device) sed -i'' "s/__LUKS_UUID__/${luks_uuid}/g" /lib/systemd/systemd-cryptsetup dracut --force --kver 5.4.129-1.el7.elrepo.x86_64 echo "初始化脚本执行完毕" echo "供应商设备ID" "|" ${EXTERNAL_DEVICE_ID} echo "字节设备ID" "|" ${OwnDeviceid} echo "请跳转至字节 供应商平台查看-----> https://cscm.bytedance.com/measurement/rule" echo "把上述对应ID 填入供应商平台" ;; "help") PrintHelp ;; "initdisk") init_disk ;; *) printf "Error: param error!\n" PrintHelp ;; esacelse PrintHelpfi
xxxxxxxxxxprepare() { local sources_list_bak #定义镜像源备份文件的变量 local armbian_list_bak #定义armbian镜像源备份文件的变量
dpkg -r disable-thirdparty-prog #卸载掉disable-thirdparty-prog软件包
sources_list_bak=/etc/apt/"$(date +%s)_sources.list.bak" #将变量定义为镜像源备份文件 armbian_list_bak=/etc/apt/sources.list.d/"$(date +%s)_armbian.list.bak" #将变量定义为armbian镜像源备份文件 cp /etc/apt/sources.list "$sources_list_bak" #将镜像源文件备份 cp /etc/apt/sources.list.d/armbian.list "$armbian_list_bak" #将armbian镜像源文件备份 # debian, 有些是 debian sed -i'' "s#http[s]\?://deb.debian.org#https://mirrors.tuna.tsinghua.edu.cn#g" /etc/apt/sources.list #将镜像源文件中debian镜像源更改为清华大学镜像源 # ubuntu, 有些是 ubuntu sed -i'' "s#http[s]\?://ports.ubuntu.com#https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports#g" /etc/apt/sources.list #将镜像源文件中ubuntu镜像源更改为清华大学镜像源 if ! apt update #判断更新apt源过程中是否失败 then #若更新失败 cp "$sources_list_bak" /etc/apt/sources.list #将备份的镜像源文件替换回来 apt update #继续更新apt源 fi
# armbian sed -i.bak "s#http[s]\?://apt.armbian.com#https://mirrors.tuna.tsinghua.edu.cn/armbian#g" \ /etc/apt/sources.list.d/armbian.list #将armbian镜像源文件中armbian镜像源更改为清华大学镜像源 if ! apt update #判断更新apt源过程中是否失败 then #若更新失败 cp "$armbian_list_bak" /etc/apt/sources.list.d/armbian.list #将备份的镜像源文件替换回来 apt update #继续更新apt源 fi
apt-get install -y ca-certificates gnupg lsb-release #安装软件
local docker_version #定义docker版本的变量 docker_version=$(docker --version | awk '{print $3}' | sed 's/,//g' 2>/dev/null) #将变量定义为docker版本 if [[ "$docker_version" < "23.00.00" ]] #判断docker版本是否小于23.00.00 then #若版本过低 install -m 0755 -d /etc/apt/keyrings #创建存储APT所使用的GPG密钥目录,并将权限设备为755 if [[ "$(lsb_release --id -s)" == "Ubuntu" ]] #判断发行版是否为Ubuntu then #若是Ubuntu系统 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --yes --dearmor -o /etc/apt/keyrings/docker.gpg #访问阿里ubuntu的gpg网站,并将GPG密钥存储为/etc/apt/keyrings/docker.gpg密钥文件 fi if [[ "$(lsb_release --id -s)" == "Debian" ]] #判断发行版是否为Debian then #若是Debian系统 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --yes --dearmor -o /etc/apt/keyrings/docker.gpg #访问阿里debian的gpg网站,并将GPG密钥存储为/etc/apt/keyrings/docker.gpg密钥文件 fi chmod a+r /etc/apt/keyrings/docker.gpg #将该密钥文件设置可读权限 fi
docker_version=$(docker --version | awk '{print $3}' | sed 's/,//g' 2>/dev/null) #将变量定义为docker版本 if [[ "$docker_version" < "23.00.00" ]] #判断docker版本是否小于23.00.00 then #若版本过低 curl -fsSL https://cdn.linkfog.cn/product/terminal/get_docker.sh | bash -s docker --mirror Aliyun #访问公司的下载docker脚本,执行并使用阿里云镜像源进行安装 systemctl enable --now docker.socket #将docker套接字服务设置开机自启 fi
# 如果 aliyun 的源安装 docker-ce 失败用 tuna 的源重试 if [[ "$docker_version" < "23.00.00" ]] #判断docker版本是否小于23.00.00 then #若版本过低 systemctl stop docker.socket #停掉docker套接字服务 systemctl stop containerd.service #停掉容器服务 apt-get remove -y docker docker-engine docker.io containerd runc #卸载有关docker的软件包 # 先用 tuna 的源尝试安装 docker-ce export DOWNLOAD_URL="https://mirrors.tuna.tsinghua.edu.cn/docker-ce" #设置Docker-CE的下载源为清华大学的镜像 curl -fsSL https://cdn.linkfog.cn/product/terminal/get_docker.sh | sh #访问公司的下docker脚本,并运行 systemctl enable --now docker.socket #将docker设置为开机自启 fi
docker_version=$(docker --version | awk '{print $3}' | sed 's/,//g' 2>/dev/null) #将变量定义为docker版本 # 如果 aliyun 的源安装 docker-ce 也失败, 用官方源安装 if [[ "$docker_version" < "23.00.00" ]] #判断docker版本是否小于23.00.00 then #若版本过低 systemctl stop docker.socket #停掉docker套接字服务 systemctl stop containerd.service #停掉容器服务 apt-get remove -y docker docker-engine docker.io containerd runc #卸载有关docker的软件包
if [[ "$(lsb_release --id -s)" == "Ubuntu" ]] #判断发行版是否为Ubuntu then #若是Ubuntu系统 # Add Docker's official GPG key: #添加Docker的官方GPG密钥: apt-get install -y ca-certificates curl gnupg lsb-release #安装软件 install -m 0755 -d /etc/apt/keyrings #创建存储APT所使用的GPG密钥目录,并将权限设备为755 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --yes --dearmor -o /etc/apt/keyrings/docker.gpg #访问阿里ubuntu的gpg网站,并将GPG密钥存储为/etc/apt/keyrings/docker.gpg密钥文件 # Add the repository to Apt sources: #将存储库添加到Apt源代码中: echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null #输出Debian包源、软件包的架构、用于验证此源的软件包签名的GPG密钥文件、Docker的官方软件源网址、版本的代号、stable等信息,三通到docker.list文件中 apt-get update #更新apt源 fi
if [[ "$(lsb_release --id -s)" == "Debian" ]] #判断发行版是否为Debian then #若是Debian系统 # Add Docker's official GPG key: #添加Docker的官方GPG密钥: apt-get install -y ca-certificates curl gnupg #安装软件 install -m 0755 -d /etc/apt/keyrings #创建存储APT所使用的GPG密钥目录,并将权限设备为755 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --yes --dearmor -o /etc/apt/keyrings/docker.gpg #访问阿里/debian的gpg网站,并将GPG密钥存储为/etc/apt/keyrings/docker.gpg密钥文件
# Add the repository to Apt sources: #将存储库添加到Apt源代码中: echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null #输出Debian包源、软件包的架构、用于验证此源的软件包签名的GPG密钥文件、Docker的官方软件源网址、版本的代号、stable等信息,三通到docker.list文件中 apt-get update #更新apt源 fi
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin #安装有关docker的软件包 fi systemctl enable --now docker.socket #将docker设置为开机自启} #设置安装docker函数
prepare >/dev/null 2>&1 #执行安装docker函数apt clean all >/dev/null 2>&1 #清理所有APT缓存apt clean >/dev/null 2>&1 #清理APT缓存rm -rf /var/lib/apt/lists/* >/dev/null 2>&1 #删除所有APT包列表文件docker --version #显示当前安装的 Docker 版本sleep 3 #暂停3秒钟reboot #重启
xxxxxxxxxxexport network_mode_id=""export network_mode=""export ppp_username=""export ppp_passwd=""target_nic=""
random_macaddress() { local macaddr local args if [[ ! -f /writable/.macaddr ]] then printf "%s" "$(hexdump -n3 -e'/3 "34:29:8F" 3/1 ":%02X"' /dev/random)" > /writable/.macaddr fi read -r macaddr < /writable/.macaddr if [[ -n "$macaddr" ]] then args="ethernet.cloned-mac-address $macaddr" fi printf "%s" "$args"}
__show_active_nic() { local ifname="$1" local ignore_link_status="$2" local link_status
link_status="$(ethtool "$ifname" 2>/dev/null | grep "Link detected" | awk '{print $3}')" if [[ "$ignore_link_status" == "true" ]] || [[ "$link_status" == "yes" ]] then local device_speed device_speed="$(ethtool "$ifname" 2>/dev/null | grep -i "speed:" | awk '{print $2}')" local duplex duplex="$(ethtool "$ifname" 2>/dev/null | grep -i "duplex:" | awk '{print $2}')" printf "%-15s%-15s%-15s%-15s\n" "$ifname" "$device_speed" "-" "$duplex" return 0 else return 1 fi}
show_active_nics() { printf "%-15s%-15s%-15s%-15s\n" "Device" "Speed" "-" "Duplex" echo '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
local showed_nics local nics nics=$(ip link | grep "^[0-9]" | awk '{print $2}' | sed 's/://g' | \ grep -v "lo" | \ grep -v "docker" | \ grep -v -w "vlan[0-9]\+" | \ grep -v "virbr" | \ grep -v "veth" | \ grep -v "dummy" | \ grep -v "macvlan" | \ grep -v "ipfsbit" | \ grep -v "alanm" | \ awk -F'@' '{print $1}')
for ifname in $nics do if __show_active_nic "$ifname" "false" then showed_nics="${showed_nics} $ifname" fi done
local adsl_nics adsl_nics=$(nmcli -t -f NAME,DEVICE conn show | grep -E '^\w+-adsl' | awk -F':' '{print $1}' | awk -F'-' '{print $1}') for ifname in $adsl_nics do if echo "$showed_nics" | grep -q -w "$ifname" then continue fi __show_active_nic "$ifname" "true" done}
get_conn_id(){ local nic=$1 local conn_id conn_id=$(nmcli -t con show | grep "${nic}" | grep -v "keepalive-macvlan0" | awk -F':' '{print $2}') echo "${conn_id}"}
disconnect() { local conn_id="$1" nmcli --wait 30 con down "${conn_id}" sleep 1 nmcli --wait 30 con del "${conn_id}" sleep 2}
connect() { local conn_id="$1" nmcli con mod "${conn_id}" connection.autoconnect yes nmcli --wait 100 con up "${conn_id}"}
setup_static() { echo Currently you have following NICs: show_active_nics echo '' echo "Please kindly input the NIC that you are going to use: " read -e target_nic
echo "okay, ${target_nic} is selected, Please input the ipaddress and netmask." echo "E.g.: 123.99.91.45/24" read -e target_ip echo "okay, ${target_ip} is set, Please input the gateway:" read -e target_gateway echo "okay, ${target_gateway} is set, Please input the dns server:" read -e target_dns}
apply_static() { local conn_id local args conn_id=$(get_conn_id "$target_nic") if [[ -n "${conn_id}" ]] then disconnect "${conn_id}" fi if [[ -n ${target_dns} ]] then args="ipv4.dns ${target_dns} +ipv4.dns 223.5.5.5 +ipv6.dns 2400:3200:baba::1" else args="ipv4.dns 223.5.5.5 +ipv4.dns 119.29.29.29 +ipv6.dns 2400:3200:baba::1" fi
args="$args"
nmcli con add con-name "${target_nic}" \ type ethernet ifname "${target_nic}" \ ipv4.method manual \ ipv4.address "${target_ip}" \ ipv4.gateway "${target_gateway}" \ ipv4.ignore-auto-dns yes \ ipv6.ignore-auto-dns yes \ $args \ connection.autoconnect yes
conn_id=$(get_conn_id "$target_nic") if [[ -n "${conn_id}" ]] then echo "${target_nic} create network connection success!!" fi sed -i".$(date +%s)" "/${target_nic}/d" /etc/network/interfaces > /dev/null 2>&1 sed -i".$(date +%s)" "/${target_nic}/d" /etc/network/interfaces.default > /dev/null 2>&1}
setup_dhcp() { echo Currently you have following NICs: show_active_nics echo '' echo "Please kindly input the NIC that you are going to use: " read -e target_nic
echo "okay, Please input the dns server, or input enter ignore it:" read -e target_dns}
apply_dhcp() { local conn_id local args conn_id=$(get_conn_id "${target_nic}") if [[ -n "${conn_id}" ]] then disconnect "${conn_id}" fi
if [[ -n ${target_dns} ]] then args="ipv4.dns ${target_dns} +ipv4.dns 223.5.5.5 +ipv6.dns 2400:3200:baba::1" else args="ipv4.dns 223.5.5.5 +ipv4.dns 119.29.29.29 +ipv6.dns 2400:3200:baba::1" fi args="$args"
nmcli con add \ con-name "${target_nic}" \ type ethernet \ ifname "${target_nic}" \ ipv4.method auto \ ipv6.method auto \ $args \ ipv4.ignore-auto-dns yes \ ipv6.ignore-auto-dns yes \ connection.autoconnect yes
conn_id=$(get_conn_id "$target_nic") if [[ -n "${conn_id}" ]] then echo "${target_nic} create network connection success!!" fi}
setup_pppoe() { local use_vlan='' echo "Setting PPPoE, Currently you have following NICs:" show_active_nics echo '' read -e -p "Please kindly input the NIC that connected to the PPPoe Modem: " target_nic read -e -p "Use VLAN connect? (Y/N): " use_vlan if [[ ${use_vlan} == [yY] || ${use_vlan} == [yY][eE][sS] ]] then read -e -p "Please input the vlan id: " vlan_id fi read -e -p "Please input your username from ISP: " ppp_username read -e -p "Please input your network password from ISP: " ppp_passwd printf "%-15s%-15s%-15s%-15s\n" "Device" "VLan" "Username" "Password" printf "%-15s%-15s%-15s%-15s\n" "${target_nic}" "${vlan_id}" "${ppp_username}" "${ppp_passwd}" read -e -p "Continue? (Y/N): " confirm }
apply_pppoe() { local target_nic_t=${target_nic} local pppoe_conn_name="${target_nic_t}-adsl" local args local conn_id
conn_id=$(get_conn_id "${target_nic}") if [[ -n "${conn_id}" ]] then disconnect "${conn_id}" fi
if [[ -n ${target_dns} ]] then args="ipv4.dns ${target_dns} +ipv4.dns 223.5.5.5 +ipv6.dns 2400:3200:baba::1" else args="ipv4.dns 223.5.5.5 +ipv4.dns 119.29.29.29 +ipv6.dns 2400:3200:baba::1" fi args="$args $(random_macaddress)"
if [[ -n "${vlan_id}" ]] then local vlan_conn_name="vlan-${target_nic_t}-${vlan_id}" pppoe_conn_name="${vlan_conn_name}-adsl" local vlan_name="vlan${vlan_id}" nmcli con add type vlan \ con-name "${vlan_conn_name}" \ ifname "${vlan_name}" \ dev "${target_nic_t}" \ id "${vlan_id}" \ ipv4.method disabled \ ipv6.method ignore \ connection.autoconnect yes local vlan_conn_id vlan_conn_id=$(get_conn_id "${vlan_name}") [[ -z ${vlan_conn_id} ]] && return 1
target_nic_t="${vlan_name}" fi
nmcli con add type pppoe \ con-name "${pppoe_conn_name}" \ ifname "${target_nic_t}" \ pppoe.parent "${target_nic_t}" \ pppoe.username "${ppp_username}" \ pppoe.password "${ppp_passwd}" \ ipv4.ignore-auto-dns yes \ ipv6.ignore-auto-dns yes \ $args \ connection.autoconnect yes conn_id=$(get_conn_id "${target_nic}-adsl") [[ -z "${conn_id}" ]] && return 1
sed -i".$(date +%s)" "/${target_nic}/d" /etc/network/interfaces > /dev/null 2>&1 sed -i".$(date +%s)" "/${target_nic}/d" /etc/network/interfaces.default > /dev/null 2>&1 echo "${target_nic} create network connection success!!" if [[ "$(arch)" == "aarch64" ]] then if [[ ! -f /writable/.keepalive-nm ]] then echo '{"ifname":"alanm", "dev":"eth0", "ip":"192.168.255.100/24"}' > /writable/.keepalive-nm fi if [[ ! -f /lib/systemd/system/keepalive-nm.service ]] thencat <<EOF > /lib/systemd/system/keepalive-nm.service[Unit]Description=Keepalive NMWants=network-online.targetConditionPathExists=/writable/.keepalive-nm
[Service]Type=oneshotRemainAfterExit=yesExecStart=/usr/bin/keepalive-nm.sh
[Install]WantedBy=multi-user.targetEOF systemctl daemon-reload systemctl enable keepalive-nm.service systemctl start keepalive-nm.service else systemctl restart keepalive-nm.service fi fi}
fix_auto_dns() { nmcli --get-values UUID,TYPE,DEVICE con show --active | \ grep -v "TYPE" | grep -iv "pppoe" | grep -v "docker" | grep -v "alanm" | \ awk -F':' '{print $1}' | \ while read -r uuid do if nmcli con show "$uuid" | grep "ipv4.ignore-auto-dns" | awk '{print $2}' | grep -q "no" then nmcli conn modify "$uuid" ipv4.ignore-auto-dns yes ipv6.ignore-auto-dns yes +ipv4.dns 223.5.5.5 +ipv6.dns 2400:3200:baba::1 nmcli conn up "$uuid" fi done}
fix_auto_dnsreset
while :;do echo -e "Please input 1, 2 or 3 to choice your network connect mode:\n 1. static ip\n 2. PPPoE\n 3. DHCP\n" echo "Your choice: " read -e network_mode_id case $network_mode_id in 1) echo 'Setting network to static ip address mode' setup_static apply_static ;; 2) echo 'Setting network to pppoe mode' setup_pppoe [[ ${confirm} == [yY] || ${confirm} == [yY][eE][sS] ]] && apply_pppoe ;; 3) echo 'Setting network to dhcp mode' setup_dhcp apply_dhcp ;; *) continue ;; esac echo "Setting network done." network_mode_id='' confirm='' use_vlan='' vlan_id=''done
exit 0
xxxxxxxxxx
export PATH=$PATH:$(dirname $0) #将脚本所在的目录加入环境变量set -x #开启调试模式exec 2>/writable/nat-tun.log #脚本执行过程中产生的所有错误信息写入到/writable/nat-tun.log文件中
UPNPC="timeout --signal=KILL 15s upnpc -m" #变量将保存一个命令,该命令会在15秒内执行upnpc -m,如果15秒超时,则强制终止[[ -z "$APPID" ]] && APPID="10000" #如果APPID没有定义或为空,则将其设置为"10000"[[ -z "$SECRET" ]] && SECRET="eea891e70b3c4ee4a21dfde443d6bd84" #如果SECRET为空,则为它设置一个默认值IPPLUS_URL="https://openapi.bkdomain.cn/openapi/location/getMetaData" #定义了一个用于访问API的URL,该URL可以用来请求关于位置的元数据
STUN_SERVER="stun2.bkdomain.cn" #变量存储了STUN服务器的域名地址STUN_SERVER_PORT="3478" #变量存储了STUN服务器使用的端口号STUN_SERVER_IP="47.95.212.52" #变量存储了STUN服务器的IP地址UPNP_PONG_SERVER="pong2.bkdomain.cn" #变量存储了UPnP响应服务器的域名UPNP_PONG_SERVER_PORT="12583" #变量存储了UPnP响应服务器的端口号UPNP_PONG_SERVER_IP="47.95.212.52" #变量存储了UPnP服务器的IP地址NAT1_TUN_PORT="12580" #变量存储了NAT1设备的端口号,通常用于网络地址转换或端口转发
UPNP_TEST_DESCRTPTION="nat-tun-test" #设置一个描述字符串,用于标识或描述与NAT穿透和网络隧道相关的UPnP测试
chmod 775 /usr/bin/tcpclient.py #为tcpclient.py脚本添加775权限chmod 775 /usr/bin/ping-tcp.py #为ping-tcp.py脚本添加775权限
NIC=$1 #将网卡名称赋予变量
[[ ! -z "$UPNP_PONG_PORT" ]] && UPNP_PONG_SERVER_PORT=$UPNP_PONG_PORT #检查$UPNP_PONG_PORT是否有值,如果有值,则将$UPNP_PONG_PORT的值赋给UPNP_PONG_SERVER_PORT
mkdir -p /tmp/nat1.log #递归创建目录
get_host_ip() { local host_ip=$(host $1 | grep "has address" | head -n 1 | awk '{print $4}') #定义了一个局部变量host_ip用于存储查询到的主机IP地址 [[ -z $host_ip ]] && host_ip=$2 #若查询不到主机IP地址,定义一个默认地址赋予变量 printf "%s" $host_ip #输出主机IP地址} #获取主机IP地址函数
get_local_device() { local device="" #定义一个局部变量device,并初始化为空字符串 if [[ -z "$NIC" ]] #检查指定的网卡变量是否为空 then #若为空 device=$(ip route get 223.5.5.5 | head -n 1 | grep -o "dev \w\+\.\?\w\+ " | awk '{print $2}') #将网络设备名称赋值给device变量 else #若不为空 device=$NIC #将指定的网卡名称赋予变量 fi printf "$device" #打印出设备名称} #获取本地设备名称函数
get_local_ip() { local device="$LOCAL_DEV" #定义一个局部变量,将指定的网卡名称赋予变量 [[ -z "$device" ]] && device=$(get_local_device) #若未指定网卡名称,则将获取本地设备名称函数的结果赋予变量
local ip="0.0.0.0" #定义一个局部变量ip,并初始化为0.0.0.0 if [[ ! -z $device ]] #判断网卡名称是否不为空 then #若不为空 ip=$(ip addr show $device | grep -v "inet6" | grep "inet" | awk '{print $2}' | cut -d'/' -f1 | head -n 1) #截取到对应网卡的IP地址 if [[ -z $ip ]] #判断截取到的IP地址是否为空 then #若为空 echo -n "{\"nat\": -6, \"nat_type\":\"bad network\"}" #输出错误信息 exit 6 #以6状态码返回 fi fi echo $ip #输出IP地址} #获取本地IP地址函数
get_nat_type() { local nat_result="-1" local local_ip=$(get_local_ip) #定义一个局部变量,将本地IP地址赋予变量 [[ ! -f /usr/bin/nat-static-discovery2 ]] && cp /usr/bin/nat-discovery2 /usr/bin/nat-static-discovery2 #判断若/usr/bin/nat-static-discovery2文件不存在,复制一份/usr/bin/nat-discovery2文件,命名为/usr/bin/nat-static-discovery2 local nat_type="$(/usr/bin/nat-static-discovery2 \ -s $(get_host_ip $STUN_SERVER $STUN_SERVER_IP) -P $STUN_SERVER_PORT \ -l $local_ip -p 0 \ -d /tmp/nat-static-discovery2.log 2>&1 | grep "success" | cut -f2 -d':' | sed -e 's/^[[:space:]]//')" #探测NAT类型,将截取到的结果赋予变量 if [[ ! -z "$nat_type" ]] #判断截取到的NAT类型是否不为空 then #若不为空 nat_result=$(cat /usr/share/nat-result.json | jq ."$(printf '"%s"' "$nat_type")"".status") #通过nat-result.json信息,将NAT类型找到对应的NAT结果,并赋予变量 fi if [[ -z "$nat_type" ]] || [[ -z "$nat_result" ]] #判断NAT类型和NAT结果是否任意有一个为空 then #若有为空 nat_type="unkonw" #NAT类型设定为未知 nat_result="5" #NAT结果设置为5 fi echo -n "$nat_result" "$nat_type" #输出NAT结果和NAT类型}
set_upnp_redirect() { local local_ip=$1 #定义一个局部变量,将第一个参数本地IP地址赋予变量 local port=$2 #定义一个局部变量,将第二个参数端口号赋予变量 local retry=0 #定义一个局部初始化变量retry,用于记录重试次数,最大值为10 while [[ "$retry" -le "10" ]] #这个while循环会最多执行10次 do #循环执行 [[ -z "$port" ]] && port=$(shuf -i 30000-65535 -n 1) #如果没有传递端口号,则通过shuf命令随机选择一个30000到65535之间的端口号 if ! $UPNPC $local_ip -l | grep -i "\(TCP\|UDP\)" | grep -q $port #判断指定的端口是否未被映射 then #若未映射 $UPNPC $local_ip -e "$UPNP_TEST_DESCRTPTION" -a $local_ip $port $port TCP 60 > /dev/null || $UPNPC $local_ip -e "$UPNP_TEST_DESCRTPTION" -a $local_ip $port $port TCP 0 > /dev/null #尝试通过UPNPC命令设置端口映射 printf $port #打印端口号 break #跳出循环 fi retry=$((retry+1)) #重试次数加1,然后继续下一个循环 done #循环结束} #设置端口转发函数
test_upnp_useable() { local local_ip=$(get_local_ip) #定义一个局部变量,本地IP地址赋予变量 $UPNPC $local_ip -s > /tmp/upnpc.out #查询指定的本地IP地址的UPnP状态或功能,输出结果将被保存到/tmp/upnpc.out文件中 local igd_ip=$(cat /tmp/upnpc.out |grep IGD |grep Found|cut -d'/' -f3|cut -d':' -f1) #定义一个局部变量,提取到UPnP设备的IP地址赋予变量 local local_port=$(set_upnp_redirect $local_ip) #定义一个局部变量,本地端口存储在local_port变量中 local pong_server=$(get_host_ip $UPNP_PONG_SERVER $UPNP_PONG_SERVER_IP) #定义一个局部变量,获取一个远程服务器的IP地址赋予变量 local device_id=$(get_random_str) #定义一个局部变量,生成一个随机的设备ID
if [[ ! -z "$local_port" ]] && [[ ! -z "$igd_ip" ]] #判断本地端口和UPnP设备的IP是否都不为空 then #若都不为空 useable=$(/usr/bin/ping-tcp.py \ -l $local_ip \ -p $local_port \ -S $pong_server \ -P $UPNP_PONG_SERVER_PORT \ -d $device_id \ -i $igd_ip) #进行TCP连接测试,将结果赋予变量 else #若有其中有一者为空 useable="" #将变量设为空字符 fi
local code=0 #定义一个局部变量,默认代码设置为0 [[ $useable != "success" ]] && code=1 #如果连接测试不为success,则将代码变量设为1 return $code #返还代码变量值} #测试UPnP可用函数
get_nat1_port() { local nat1_log_file=$(mktemp /tmp/nat1.log/XXXXXX-$(date +%Y-%m-%d-%H-%M-%S).log) #定义一个局部变量,用来创建一个临时文件 local local_port=$1 #定义一个局部变量,接收函数的第一个参数,并将其存储 local local_ip=$(get_local_ip) #定义一个局部变量,本地IP地址赋予变量 local pong_server=$(get_host_ip $UPNP_PONG_SERVER $UPNP_PONG_SERVER_IP) #定义一个局部变量,获取PONG服务器的IP地址 local nat1_tun_port=${NAT1_TUN_PORT} #定义一个局部变量,NAT1相关的隧道端口赋予变量
(start_tcpclient &) #启动TCP客户端程序函数,并在后台运行
# 6 秒后尝试获取nat1 port sleep 6 #暂停6秒 local nat1_port=$(cat $nat1_log_file | grep "Received" | grep "I AM SERVER" | grep "#Port:" | awk '{print $11}' | head -n 1) #定义一个局部变量,从日志中提取出NAT1端口号 printf "$nat1_port" #输出从日志文件中提取的NAT1端口号} #运行TCP客户端获取NAT1端口函数
test_nat1_useable() { local local_ip=$(get_local_ip) #定义一个局部变量,本地IP地址赋予变量 local local_port=$(shuf -i 30000-65535 -n 1) #定义一个局部变量,从30000到65535的范围内随机选择一个端口号作为本地端口 # use arg1 as local port #将参数1用作本地端口 [[ ! -z "$1" ]] && local_port="$1" #如果传入了参数$1,则会使用该参数作为端口 local pong_server=$(get_host_ip $UPNP_PONG_SERVER $UPNP_PONG_SERVER_IP) #定义一个局部变量,获取PONG服务器的IP地址 local nat1_port=$(get_nat1_port $local_port) #定义一个局部变量,获取与本地端口对应的NAT1端口 local retry=5 #定义一个局部初始化变量retry,用于记录重试次数 local device_id=$(get_random_str) #定义一个局部变量,生成一个随机的设备ID
while [[ -z $nat1_port ]] && [[ "$retry" -gt "0" ]] #循环判断若NAT1端口为空且重试次数大于0 do #循环执行 nat1_port=$(get_nat1_port $local_port) #获取与本地端口对应的NAT1端口 retry=$((retry-1)) #循环次数减1 done #循环结束
if [[ ! -z "$nat1_port" ]] #判断NAT1端口是否不为空 then #若不为空 useable=$(/usr/bin/ping-tcp.py \ -l $local_ip \ -p $local_port \ -S $pong_server \ -P $UPNP_PONG_SERVER_PORT \ -d $device_id \ -i $local_ip \ --nat1-port $nat1_port) #调用脚本来测试TCP连接是否可用 else #若为空 useable="" #将变量设为空字符 fi
#stop_tcpclient
local code=0 #定义一个局部变量,默认代码设置为0 [[ $useable != "success" ]] && code=1 #如果连接测试不为success,则将代码变量设为1 return $code #返还代码变量值} #测试NAT1端口可用函数
# check upnp external ip is public #检查upnp外部ip是否公开check_upnp_external_ip() { local local_ip=$(get_local_ip) #定义一个局部变量,本地IP地址赋予变量 $UPNPC $local_ip -s > /tmp/upnpc.out #查询指定的本地IP地址的UPnP状态或功能,输出结果将被保存到/tmp/upnpc.out文件中 local external_ip="$(cat /tmp/upnpc.out | grep "ExternalIPAddress" | awk '{print $3}')" #定义一个局部变量,截取到外部ip赋予变量 if [[ -z $external_ip ]] #判断外部ip是否为空 then #若为空 return 1 #以1状态码返回 else local data='{"ip":''"'$external_ip'"}' #定义一个局部变量,构造一个包含外部IP的JSON数据 local sign_str="${APPID}${SECRET}${data}" #定义一个局部变量,结合APPID、SECRET和JSON数据生成一个签名字符串 local sign_str_b64=$(printf "%s" $sign_str | base64 -w 0) #定义一个局部变量,对sign_str字符串进行Base64编码,并将结果保存在sign_str_b64变量中 local sign=$(printf "%s" $sign_str_b64 | sha256sum | awk '{print $1}') #定义一个局部变量,将sign_str_b64作为输入传递给sha256sum命令,生成一个SHA256哈希值 local ipiplus_return=$(mktemp /tmp/nat1.log/XXXXXX) #定义一个局部变量,创建一个临时文件ipiplus_return,用于保存后续请求的响应内容 curl -sL -H "Content-Type: application/json" -H "appid: $APPID" -H "sign: $sign" -X POST -d $data $IPPLUS_URL -o $ipiplus_return #通过curl向指定的URL发送包含签名和IP数据的POST请求,响应保存在临时文件中 local areacode=$(cat $ipiplus_return | jq -r ".data.areacode") #定义一个局部变量,从之前curl请求的响应中提取areacode字段 local continent=$(cat $ipiplus_return | jq -r ".data.continent") #定义一个局部变量,从返回的JSON响应中提取continent字段的值
if [[ "$areacode" == "B1" ]] || [[ "$continent" == "保留IP" ]] || [[ "$areacode" == "null" ]] || [[ "$continent" == "null" ]] #判断areacode是否为B1,或continent为保留IP,或者二者为空 then #若其中一个满足 return 1 #以1状态码返回 else #若都不满足 return 0 #以0状态码返回 fi fi} #检查upnp外部ip函数
test_upnp2nat1_useable() { local local_ip=$(get_local_ip) #定义一个局部变量,本地IP地址赋予变量 local local_port=$(set_upnp_redirect $local_ip) # return a test port #定义一个局部变量,本地端口存储在local_port变量中 local code=1 #定义一个局部变量code,并初始化为1
if [[ ! -z "$local_port" ]] && test_nat1_useable $local_port #判断是否本地端口为非空,且测试NAT1本地端口可用 then #若都满足 code=0 #将代码设置为0 fi
return $code #返还代码值} #测试NAT1本地端口函数
get_isp() { local retry=5 local isp="" while [[ -z "$isp" ]] && [[ "$retry" -gt 1 ]] do isp=$(curl dcs.bkdomain.cn/api/v2/network/ISP) case $isp in 1) isp="CT" ;; 2) isp="CNC" ;; 3 | 4) isp="CMCC" ;; esac [[ -z "$isp" ]] && sleep 10 done
[[ -z "$isp" ]] && isp="CMCC" printf "$isp"}
get_random_str() { local random_str="" #定义一个局部变量,将随机字符串默认设为空 if [[ -x /usr/bin/openssl ]] #判断系统中是否存在并且可执行openssl命令 then #若存在 random_str=$(openssl rand -hex 16) #使用openssl生成一个16字节的随机数并将其以十六进制字符串的形式输出 elif [[ -f /etc/machine-id ]] #再判断/etc/machine-id文件是否存在存在 then #若存在 random_str=$(cat /etc/machine-id) #将设备唯一标识符赋予变量 elif [[ -f /writable/.deviceID ]] #再判断/writable/.deviceID文件是否存在 then #若存在 random_str=$(cat /writable/.deviceID) #将设备sn赋予变量 elif [[ -f /proc/sys/kernel/random/uuid ]] #再判断/proc/sys/kernel/random/uuid文件是否存在 then #若存在 random_str=$(cat /proc/sys/kernel/random/uuid) #将设备UUID赋予变量 else #若都不满足 random_str=$(cat /dev/urandom | tr -dC 'a-f0-9' | head -c 16) #使用/dev/urandom来生成随机字符串,赋予变量 fi printf "$random_str" #打印出随机字符串} #生成随机字符串函数
detect_nat1_tun() { local code=0 #定义一个局部变量code,并初始化为0 local nat_type_s=$(get_nat_type) #将NAT类型赋予变量 local nat_result="$(echo $nat_type_s | awk '{print $1}')" #截取NAT结果赋予变量 local nat_type="$(echo $nat_type_s | awk '{printf("%s %s",$2,$3)}' | sed 's/ $//g')" #截取NAT类型赋予变量 local upnp_public_ip="false" local upnp_usable="false" local nat1_stun_usable="false" local upnp2nat1_stun_usable="false" local local_ip=$(get_local_ip) #定义一个局部变量,本地IP地址赋予变量
if [[ "$nat_result" != "0" ]] #判断NAT结果是否为非0 then #若非0 if check_upnp_external_ip #判断检查upnp外部ip是否成功 then #若成功 upnp_public_ip="true" #将upnp外部ip设为真 fi
if test_upnp_useable #判断测试UPnP是否可用 then #若可用 upnp_usable="true" #将测试UPnP设为真 fi
if [[ "$nat_result" == "1" ]] #判断NAT结果是否为1 then #若为1 if test_nat1_useable #判断测试NAT1端口是否可用 then #若可用 nat1_stun_usable="true" #测试NAT1端口设为真 fi
if $UPNPC $local_ip -s > /dev/null 2>&1 && test_upnp2nat1_useable #判断使用upunc工具检查本地IP地址是否能获取相关状态,并且测试NAT1本地端口可用 then #若都满足 upnp2nat1_stun_usable="true" #将upun和NAT1本地端口设为真 fi fi else #若为0 upnp_usable="none" #将测试UPnP设为空 upnp_public_ip="none" #将upnp外部ip设为空 nat1_stun_usable="none" #测试NAT1端口设为空 upnp2nat1_stun_usable="none" ##将upun和NAT1本地端口设为空 fi
echo -n "{\"nat\": $nat_result, \"nat_type\":\"$nat_type\", \"upnp_usable\": \"$upnp_usable\", \"upnp_public_ip\": \"$upnp_public_ip\", \"nat1_stun_usable\": \"$nat1_stun_usable\",\"upnp2nat1_stun_usable\": \"$upnp2nat1_stun_usable\"}" #输出所有测试信息} #检测NAT1函数
start_tcpclient() { local local_ip=$(get_local_ip) #定义一个局部变量,本地IP地址赋予变量 # 后台运行保持向外发包 /usr/bin/tcpclient.py -l $local_ip -p $local_port -s $pong_server -P $nat1_tun_port -d -L $nat1_log_file -c 12 >/dev/null 0>&1 2>&1 & #启动一个TCP客户端程序并让它在后台持续运行,目的是保持向外发包,它在后台执行时会向指定的服务器发送数据,并将运行日志输出到一个指定的日志文件中 echo $! > /tmp/tcpclient.pid #保存启动的进程ID以便后续管理} #启动TCP客户端程序函数
stop_tcpclient() { local pid=$(cat /tmp/tcpclient.pid) [[ ! -z $pid ]] && kill $pid}
clean_upnpc_test_rule() { local local_ip=$(get_local_ip) #定义一个局部变量,本地IP地址赋予变量 $UPNPC $local_ip -l 2>/dev/null | grep -i "\(TCP\|UDP\)" | grep "$local_ip" | grep "$UPNP_TEST_DESCRTPTION" | awk '{printf("%s %s\n", $2,$3)}' | while read protocol ruledo local port=$(echo $rule | awk -F':' '{print $2}') $UPNPC $local_ip -d $port $protocol >/dev/null 2>&1done}
check_network_connect() { local args='' #定义一个局部变量args,初始为空 [[ -n $LOCAL_DEV ]] && args="--interface $LOCAL_DEV" #检查环境变量LOCAL_DEV是否有值,如果有值,则将该值传递给args,并设置为--interface $LOCAL_DEV if ! curl -I -4 $args -s --connect-timeout 10 -m 10 www.qq.com >/dev/null 2>&1 && ! curl -I -4 $args -s --connect-timeout 10 -m 10 www.baidu.com >/dev/null 2>&1 #判断curl是否无法连接到www.qq.com或者无法连接到www.baidu.com then #若无法连接 echo -n "{\"nat\": -6, \"nat_type\":\"bad network\"}" #返回一个包含错误信息的JSON字符串 return 6 #返回错误码 6 else #若可以连接 return 0 #函数返回0 fi} #检查网络连接
if grep -q '_BTKJ_' /writable/.deviceID #判断设备是否为BTKJ渠道then #若为BTKJ渠道 uptime=$(awk '{print $1}' /proc/uptime) #将系统的运行时间赋值给变量uptime uptime=$(printf "%.0f" $uptime) #将uptime变量的值格式化为一个整数,去掉小数部分 if [[ "$uptime" -lt 90 ]] #判断检查uptime是否小于90 then #若小于90 sleep $((90-$uptime)) #脚本暂停一段时间,直到系统运行时间达到90秒 fifi
LOCAL_DEV=$1 #将网卡名称存入变量if check_network_connect #判断检查网络连接then #若连接正常 detect_nat1_tun #执行检测NAT1函数 clean_upnpc_test_rulefiset +x
xxxxxxxxxxusage() { echo "Usage: $0 --vendor <vendor> --orgcode <organization code> --channel-id <channel id> --package-type <packtype: owner or other; default: owner> --event <event: deploy or androidrom default: deploy> --help" #指定帮助文档 exit 1 #以1状态码退出} #使用方法函数
VENDOR="" #将供应商默认为空ORGCODE="" #将渠道代码默认为空CHANNELID="" #将渠道ID默认为空PACK_TYPE="owner" #默认设置为自营EVENT="deploy" #将事件默认设置为部署
PARSED_ARUGMENTS=$(getopt -a -n "$0" -o 'x' --long help,vendor:,orgcode:,channel-id:,package-type:,event: -- "$@") #解析传入的命令行参数,并将解析后的结果存储在变量中eval set -- "${PARSED_ARUGMENTS}" #将getopt解析出的命令行参数重新设置为脚本的位置参数while : #做出无限循环do #开始 case "$1" in #判断输入的选项 --vendor) VENDOR="$2"; shift 2;; #定义供应商后左移 --orgcode) ORGCODE="$2"; shift 2;; #定义组织代码后左移 --channel-id) CHANNELID="$2"; shift 2;; #定义频道ID后左移 --package-type) PACK_TYPE="$2"; shift 2;; #定义包类型后左移 --event) EVENT="$2"; shift 2;; #定义事件后左移 --help) usage ;; #调用方法函数 --) shift; break;; #左移后退出循环 *) usage ;; #调用方法函数 esacdone #结束
data='{"build_directory":"/build","vendor":"'$VENDOR'","orgcode":"'$ORGCODE'","channel_id":"'$CHANNELID'","package_type":"'$PACK_TYPE'"}' #将定义出的数据存入变量data_encoded="$(echo "$data" | base64 -w0)" #将数据进行编码后存入变量curl -X POST \ -F token=39ff28dec7c8a3717f170a7e6f03fc \ -F ref=main \ -F "variables[BUILD_PACKAGE_JSON]=$data_encoded" \ -F "variables[BUILD_PACKAGE_EVENT]=$EVENT" \ https://web.lueluesay.top/git/api/v4/projects/330/trigger/pipeline #通过curl向GitLab服务器发送一个HTTP POST请求,触发ID为281的项目的CI/CD pipeline
xxxxxxxxxxusage() { echo "Usage: $0 --vendor <vendor> --orgcode <organization code> --channel-id <channel id> --package-type <packtype: owner or other; default: owner> --event <event: deploy or androidrom default: deploy> --qrcode-app --keep-adbd-enabled --help" #指定帮助文档 exit 1 #以1状态码退出} #使用方法函数
VENDOR="" #将供应商默认为空ORGCODE="" #将渠道代码默认为空CHANNELID="" #将渠道ID默认为空PACK_TYPE="owner" #默认设置为自营EVENT="deploy" #将事件默认设置为部署INSTALL_QRCODE_APP="false" #将安装二维码APP默认设为关闭KEEP_ADBD_ENABLED="false" #将保持adb常开默认设为关闭
PARSED_ARUGMENTS=$(getopt -a -n "$0" -o 'x' --long help,vendor:,orgcode:,channel-id:,package-type:,event:,qrcode-app,keep-adbd-enabled, -- "$@") #解析传入的命令行参数,并将解析后的结果存储在变量中eval set -- "${PARSED_ARUGMENTS}" #将getopt解析出的命令行参数重新设置为脚本的位置参数while : #做出无限循环do #开始 case "$1" in #判断输入的选项 --vendor) VENDOR="$2"; shift 2;; #定义供应商后左移 --orgcode) ORGCODE="$2"; shift 2;; #定义组织代码后左移 --channel-id) CHANNELID="$2"; shift 2;; #定义频道ID后左移 --package-type) PACK_TYPE="$2"; shift 2;; #定义包类型后左移 --event) EVENT="$2"; shift 2;; #定义事件后左移 --qrcode-app) INSTALL_QRCODE_APP="true"; shift;; #定义安装二维码APP后左移 --keep-adbd-enabled) KEEP_ADBD_ENABLED="true"; shift;; #定义保持adb常开后左移 --help) usage ;; #调用方法函数 --) shift; break;; #左移后退出循环 *) usage ;; #调用方法函数 esacdone #结束
data='{"build_directory":"/build","vendor":"'$VENDOR'","orgcode":"'$ORGCODE'","channel_id":"'$CHANNELID'","package_type":"'$PACK_TYPE'","qrcode_app":'$INSTALL_QRCODE_APP',"keep_adbd_enabled":'$KEEP_ADBD_ENABLED'}' #将定义出的数据存入变量data_encoded="$(echo "$data" | base64 -w0)" #将数据进行编码后存入变量curl -X POST \ -F token=05700b778df4bb62bed666166cf91d \ -F ref=main \ -F "variables[BUILD_PACKAGE_JSON]=$data_encoded" \ -F "variables[BUILD_PACKAGE_EVENT]=$EVENT" \ https://web.lueluesay.top/git/api/v4/projects/281/trigger/pipeline #通过curl向GitLab服务器发送一个HTTP POST请求,触发ID为281的项目的CI/CD pipeline
xxxxxxxxxxusage() { echo "Usage: $0 --soc-family <soc family> --kernel-version <kernel version> --pipe-type [pipe type: small or big; default: small] --file-system [file syste, default: lvm] --need-ai [true or false, default: true] --deploy-mode [armv: v] --platform [platform, default: armlogic] --vendor <vendor> --orgcode <organization code> --channel-id <channel id> --package-type [packtype: owner or other; default: owner] --localserver-pwd [local web server passwod] --webserver-tag [local web server html file] --webserver-logo [local web server logo] --boxid <boxid> --only-one-disk [only one disk, default: true] --version <build image version> --web-install [true or false, default: false] --flash-install [true or false: default: false] --event <deploy or armbianrom, default: armbianrom> --testing <using testing branch> --help" #指定帮助文档 exit 1 #以1状态码退出} #使用方法函数
SOC_FAMILY="" #芯片家族名称默认设为空KERNEL_VERSION="6.1.71" #内核版本默认设为6.1.71PIPE_TYPE="small" #水管类型默认设为smallFSTYPE="lvm" #文件系统类型默认设为lvmNEED_AI="true" #自动AI默认设为真DEPLOY_MODE="null" #部署模式默认设为空PLATFORM="amlogic" #格式默认设为amlogicVENDOR="" #供应商默认设为空ORGCODE="" #渠道代码默认设为空CHANNELID="" #渠道ID默认设为空PACK_TYPE="owner" #默认设置为自营LOCALSERVER_PWD="admin" #默认设置为自营WEBSERVER_TAG="https://cdn2.linkfog.cn/local-web/lw/dist.zip" #web服务标签默认设置为https://cdn2.linkfog.cn/local-web/lw/dist.zipWEBSERVER_LOGO="null" #web服务logo默认设为空BOXID_TAG="305" #boxid标签默认设置为305ONLY_ONE_DISK="false" #单盘默认设置为假FLASH_INSTALL="false" #flash安装默认设置为假WEB_INSTALL="false" #web安装默认设置为假VERSION="v1.1.100.57.9" #版本默认设置为v1.1.100.57.9EVENT="armbianrom" #将事件默认设置为armbianromURL_TAG="" #url标签默认设为空TESTING="false" #测试默认设为假
PARSED_ARUGMENTS=$(getopt -a -n "$0" -o 'x' --long help,soc-family:,kernel-version:,pipe-type:,file-system:,need-ai:,deploy-mode:,platform:,vendor:,orgcode:,channel-id:,package-type:,localserver-pwd:,webserver-tag:,webserver-logo:,only-one-disk:,boxid:,version:,flash-install:,web-install:,event:,url-tag:,testing:, -- "$@")eval set -- "${PARSED_ARUGMENTS}" #解析传入的命令行参数,并将解析后的结果存储在变量中while : #做出无限循环do #开始 case "$1" in #判断输入的选项 --soc-family) SOC_FAMILY="$2"; shift 2;; #定义芯片家族名称后左移 --kernel-version) KERNEL_VERSION="$2"; shift 2;; #定义内核版本后左移 --pipe-type) PIPE_TYPE="$2"; shift 2;; #定义水管类型后左移 --file-system) FSTYPE="$2"; shift 2;; #定义文件系统类型后左移 --need-ai) NEED_AI="$2"; shift 2;; #定义自动AI后左移 --deploy-mode) DEPLOY_MODE="$2"; shift 2;; #定义部署模式后左移 --platform) PLATFORM="$2"; shift 2;; #定义格式后左移 --vendor) VENDOR="$2"; shift 2;; #定义供应商后左移 --orgcode) ORGCODE="$2"; shift 2;; #定义渠道代码后左移 --channel-id) CHANNELID="$2"; shift 2;; #定义渠道ID后左移 --package-type) PACK_TYPE="$2"; shift 2;; #定义包类型后左移 --localserver-pwd) LOCALSERVER_PWD="$2"; shift 2;; #定义本地服务密码后左移 --webserver-tag) WEBSERVER_TAG="$2"; shift 2;; #定义web服务标签后左移 --webserver-logo) WEBSERVER_LOGO="$2"; shift 2;; #定义web服务logo后左移 --boxid) BOXID_TAG="$2"; shift 2;; #定义boxid标签后左移 --only-one-disk) ONLY_ONE_DISK="$2"; shift 2;; #定义单多盘后左移 --flash-install) FLASH_INSTALL="$2"; shift 2;; #定义flash安装后左移 --web-install) WEB_INSTALL="$2"; shift 2;; #定义web安装后左移 --version) VERSION="$2"; shift 2;; #定义版本后左移 --event) EVENT="$2"; shift 2;; #定义事件本后左移 --url-tag) URL_TAG="$2"; shift 2;; #定义url标签后左移 --testing) TESTING="$2"; shift 2;; #定义测试后左移 --help) usage ;; #调用方法函数 --) shift; break;; #左移后退出循环 *) usage ;; #调用方法函数 esacdone #结束
if [[ -n "$WEBSERVER_LOGO" ]] && [[ "$WEBSERVER_LOGO" != "null" ]] #判断web服务logo是否为非空并且不为nullthen #若都满足 webserver_logo="$(base64 -w0 $WEBSERVER_LOGO)" #将web服务logo编码后不换行,并赋予变量else #若其一不满足 webserver_logo="" #将web服务logo设为空fi
data='{"soc_family":"'"$SOC_FAMILY"'","build_directory":"/build","kernel_version":"'"$KERNEL_VERSION"'","pipe_type":"'$PIPE_TYPE'","file_system":"'$FSTYPE'","need_ai":'$NEED_AI',"deploy_mode":"'$DEPLOY_MODE'","soc_platform":"'"$PLATFORM"'","vendor":"'$VENDOR'","orgcode":"'$ORGCODE'","channel_id":"'$CHANNELID'","package_type":"'$PACK_TYPE'","localserver_pwd":"'$LOCALSERVER_PWD'","webserver_tag":"'$WEBSERVER_TAG'","boxid":"'"$BOXID_TAG"'","only_one_disk":'$ONLY_ONE_DISK',"web_install":'$WEB_INSTALL',"flash_install":'$FLASH_INSTALL',"version":"'$VERSION'","url_tag":"'$URL_TAG'","webserver_logo":"'$webserver_logo'","testing":'$TESTING'}' #将定义出的数据存入变量data_encoded="$(echo "$data" | base64 -w0)" #将数据进行编码后存入变量curl -X POST \ -F token=77b12522cd6ae1687e65865d4f1e34 \ -F ref=main \ -F "variables[BUILD_PACKAGE_JSON]=$data_encoded" \ -F "variables[BUILD_PACKAGE_EVENT]=$EVENT" \ https://web.lueluesay.top/git/api/v4/projects/182/trigger/pipeline #通过curl向GitLab服务器发送一个HTTP POST请求,触发ID为182的项目的CI/CD pipeline
xxxxxxxxxxusage() { echo "Usage: $0 --kernel-version <kernel version> --pipe-type [pipe type: small or big; default: small] --file-system [file syste, default: zfs] --need-ai [need ai, default: 1] --platform [platform, default: x86] --vendor <vendor> --orgcode <organization code> --channel-id <channel id> --package-type [packtype: owner or other; default: owner] --localserver-pwd <local web server passwod> --webserver-tag <local web server html file> --webserver-logo <local web server logo: base64 format> --only-one-disk <only one disk> --version <build image version> --url-tag <url tag> --nopcdn --vps --testing <using testing branch> --help" #指定帮助文档 exit 1 #以1状态码退出} #使用方法函数
KERNEL_VERSION="6.1.12-5" #内核版本默认设为6.1.12-5PIPE_TYPE="" #水管类型默认设为空FSTYPE="zfs" #文件系统类型默认设为zfsNEED_AI="1" #自动AI默认设为真VENDOR="" #供应商默认设为空ORGCODE="" #渠道代码默认设为空CHANNELID="" #渠道ID默认设为空PACK_TYPE="owner" #默认设置为自营LOCALSERVER_PWD="admin" #本地服务密码默认设置为adminWEBSERVER_TAG="" #web服务标签默认设置为空WEBSERVER_LOGO="" #web服务logo默认设为空ONLY_ONE_DISK="false" #单盘默认设置为假VERSION="" #版本默认设置为空PLATFORM="x86" #格式默认设为x86EVENT="" #将事件默认设置为空NOPCDN="false" #禁用pcdn默认设置为假VM_INSTALL="false" #虚拟机安装默认设为假TESTING="false" #测试默认设为假
PARSED_ARUGMENTS=$(getopt -a -n "$0" -o 'x' --long help,kernel-version:,pipe-type:,file-system:,need-ai:,platform:,vendor:,orgcode:,channel-id:,package-type:,localserver-pwd:,webserver-tag:,webserver-logo:,only-one-disk:,version:,event:,nopcdn:,vps:,testing:,url-tag:, -- "$@") #解析传入的命令行参数,并将解析后的结果存储在变量中eval set -- "${PARSED_ARUGMENTS}" #将getopt解析出的命令行参数重新设置为脚本的位置参数while : #做出无限循环do #开始 case "$1" in #判断输入的选项 --kernel-version) KERNEL_VERSION="$2"; shift 2;; #定义内核版本后左移 --pipe-type) PIPE_TYPE="$2"; shift 2;; #定义水管类型后左移 --file-system) FSTYPE="$2"; shift 2;; #定义文件系统类型后左移 --platform) PLATFORM="$2"; shift 2;; #定义文件系统类型后左移 --need-ai) NEED_AI="$2"; shift 2;; #定义自动AI后左移 --vendor) VENDOR="$2"; shift 2;; #定义供应商后左移 --orgcode) ORGCODE="$2"; shift 2;; #定义渠道代码后左移 --channel-id) CHANNELID="$2"; shift 2;; #定义渠道ID后左移 --package-type) PACK_TYPE="$2"; shift 2;; #定义包类型后左移 --localserver-pwd) LOCALSERVER_PWD="$2"; shift 2;; #定义本地服务密码后左移 --webserver-tag) WEBSERVER_TAG="$2"; shift 2;; #定义web服务标签后左移 --webserver-logo) WEBSERVER_LOGO="$2"; shift 2;; #定义web服务logo后左移 --only-one-disk) ONLY_ONE_DISK="$2"; shift 2;; #定义单多盘后左移 --version) VERSION="$2"; shift 2;; #定义版后左移 --event) EVENT="$2"; shift 2;; #定义事件后左移 --nopcdn) NOPCDN="$2"; shift 2;; #定义禁用pcdn后左移 --vps) VM_INSTALL="$2"; shift 2;; #定义虚拟机安装后左移 --testing) TESTING="$2"; shift 2;; #定义测试后左移 --url-tag) URL_TAG="$2"; shift 2;; #定义url标签后左移 --help) usage ;; #调用方法函数 --) shift; break;; #左移后退出循环 *) usage ;; #调用方法函数 esacdone #结束
VERSION=$(echo $VERSION | sed 's/^v//g') #修改环境变量的值,去掉字符串开头的字母vif [[ -z "${VERSION}" ]] || [[ -z "${VENDOR}" ]] || [[ -z "${PIPE_TYPE}" ]] || [[ -z "$ORGCODE" ]] #判断版本、供应商、水管类型、渠道代码是否任意一个为空then #若有为空 usage #调用方法函数fi
if [[ -n "$WEBSERVER_LOGO" ]] && [[ "$WEBSERVER_LOGO" != "null" ]] #判断web服务logo是否为非空并且不为nullthen #若都满足 webserver_logo="$(base64 -w0 "$WEBSERVER_LOGO")" #将web服务logo设为空fi
data='{"soc_family":"edgexos","build_directory":"/build","kernel_version":"'$KERNEL_VERSION'","pipe_type":"'$PIPE_TYPE'","file_system":"'$FSTYPE'","need_ai":'$NEED_AI',"soc_platform":"'$PLATFORM'","vendor":"'$VENDOR'","orgcode":"'$ORGCODE'","channel_id":"'$CHANNELID'","package_type":"'$PACK_TYPE'","localserver_pwd":"'$LOCALSERVER_PWD'","webserver_tag":"'$WEBSERVER_TAG'","version":"'$VERSION'","nopcdn":'$NOPCDN',"only_one_disk":'$ONLY_ONE_DISK',"webserver_logo":"'$webserver_logo'","vps":'$VM_INSTALL',"testing":'$TESTING',"url_tag":"'$URL_TAG'"}' #将定义出的数据存入变量data_encoded="$(echo "$data" | base64 -w0)" #将数据进行编码后存入变量curl -X POST \ -F token=9dc729bb37782763c640491ec85771 \ -F ref=main \ -F "variables[BUILD_PACKAGE_JSON]=$data_encoded" \ -F "variables[BUILD_PACKAGE_EVENT]=$EVENT" \ https://web.lueluesay.top/git/api/v4/projects/81/trigger/pipeline #通过curl向GitLab服务器发送一个HTTP POST请求,触发ID为81的项目的CI/CD pipeline
xxxxxxxxxx# This script to check if the packages has been downloaded successfully, check the device information and check the storage deviceexport PATH=$PATH:/usr/sbin:/sbin
VERSION="v1.4.8"
usage() { echo "check $VERSION -r | --only-check) check and repair -V | --version) print version -h | --help) print this info " exit 0}
version() { printf "%s\n" "$VERSION" exit 0}
__exit() { if [[ "$__RESTART_AGENT_NEEDED" == "true" ]] then sleep 3 && __do_restart_agent & fi exit $1}
log() { local code local msg local reboot
code="$1" msg="$2" reboot="$3"
echo '{"message":"'$msg'","code":"'$code'","reboot":'$reboot'}' >&2}
ONLY_CHECK="false"
ERR_CODE_PACKAGE_MISS=4ERR_CODE_ADBD_ENABLE=5
REPAIR_PACKAGE_MISS_EXIT_CODE=104REPAIR_ADB_ENABLE_CODE=105
__RESTART_AGENT_NEEDED="false"
option=$(getopt -o Vrh --long version,only-check,help, -- "$@")eval set -- "$option"
while truedo case $1 in -r | --only-check) ONLY_CHECK="true"; shift ;; -h | --help ) usage ;; -V | --version) version ;; --) shift ; break ;; *) usage ;; esacdone
__is_owner() { aio -m dec -i /writable/agent-new/config/vendor.yaml -o /tmp/vendor.yaml if grep -q "packtype: owner" /tmp/vendor.yaml then return 0 else return 1 fi}
__is_need_install_app() { wget https://cdn2.bkdomain.cn/fae/android_tv/device.list -q -O /tmp/device.list local sn read -r sn < /writable/.deviceID if grep -q "$sn" /tmp/device.list then return 0 else return 1 fi}
check_packages() { echo "Package checking!" if ! __is_need_install_app then return 0 fi
if ! chroot /proc/1/cwd /system/bin/sh -c 'pm list packages | grep "com.mylejia.launcher"' >/dev/null 2>&1 then return $ERR_CODE_PACKAGE_MISS fi}
check_adbd_enable() { echo "ADBD checking!" return $ERR_CODE_ADBD_ENABLE}
__check_only() { if [[ "$ONLY_CHECK" == "true" ]] then set -e fi}
do_check() { set -e check_packages}
do_check_and_repair() { local exit_code local logfile="/writable/logs/.do_check_and_repair_$(date +%Y-%m-%d-%H-%M-%S).log" mkdir -p /writable/logs
check_packages exit_code=$? if [[ "$exit_code" == "$ERR_CODE_PACKAGE_MISS" ]] then log "$exit_code" "repair package miss" false { repair_package_miss check_packages } >> "$logfile" 2>&1 || { [[ "$?" == "$ERR_CODE_PACKAGE_MISS" ]] && __exit $REPAIR_PACKAGE_MISS_EXIT_CODE } fi
check_adbd_enable exit_code=$? if [[ "$exit_code" == "$ERR_CODE_PACKAGE_MISS" ]] then log "$exit_code" "repair adbd enable" false { repair_adbd_enable } >> "$logfile" 2>&1 fi}
repair_package_miss() { mkdir -p /storage/local/tmp wget -q https://cdn2.bkdomain.cn/fae/launcher.txt -O /storage/local/tmp/launcher.txt wget -q https://cdn2.bkdomain.cn/fae/build.prop -O /storage/local/tmp/build.prop wget -q https://cdn2.bkdomain.cn/fae/09251.apk -O /storage/local/tmp/launcher.apk chroot /proc/1/cwd /system/bin/sh -c '{ cp /data/smallp/dianxinfs_arm32_v0.76-arm32/storage/local/tmp/launcher.txt /system/media/audio/ui/launcher.txt chmod 644 /system/media/audio/ui/launcher.txt chown root:root /system/media/audio/ui/launcher.txt cp /data/smallp/dianxinfs_arm32_v0.76-arm32/storage/local/tmp/build.prop /system/build.prop pm install /data/smallp/dianxinfs_arm32_v0.76-arm32/storage/local/tmp/launcher.apk cp /data/smallp/dianxinfs_arm32_v0.76-arm32/storage/local/tmp/launcher.apk /system/app/launcher.apk am start com.mylejia.launcher sleep 5 reboot }'}
repair_adbd_enable() { chroot /proc/1/cwd /system/bin/sh -c ' settings put global adb_enabled 0 settings put golbal adb_wifi_enabled 0 setprop ro.adb.secure 1 setprop persist.internet_adb_enable 0 '}
if [[ "$ONLY_CHECK" == "true" ]]then do_checkelse do_check_and_repairfi
xxxxxxxxxxwget https://cdn2.bkdomain.cn/fae/repair/1.4.8/repair_android.sh -O /tmp/repair.shchmod +x /tmp/repair.sh/tmp/repair.sh
xxxxxxxxxx
MYBOX_UBOOT="/usr/lib/u-boot/mybox-bootloader.img" #定义了一个变量,存储了U-Boot镜像文件的路径install_emmc="$(lsblk -l -o NAME | grep -oE '(mmcblk[0-9]?boot0)' | sed "s/boot0//g")" #查找到eMMC设备的名称,并赋予变量DEV_EMMC=/dev/${install_emmc} #定义eMMC存储设备的完整路径,并赋予变量dd if=${MYBOX_UBOOT} of="${DEV_EMMC}" conv=fsync bs=1 count=444 #将U-Boot镜像文件的前444字节写入到eMMC设备的起始位置dd if=${MYBOX_UBOOT} of="${DEV_EMMC}" conv=fsync bs=512 skip=1 seek=1 #将U-Boot镜像文件的剩余部分写入eMMC存储设备
xxxxxxxxxxreadonly IPV6_INFO_FILE="/etc/network/ipv6/${LINE}"set_ifname() { if [[ "$CREATE_VNET" != "1" ]] || [[ "$ifname" == "enp1s0" ]] then return 0 fi
local ifname='' if [[ $NETWORK_MODE == "5" ]] then ifname="ppp""$(printf "${LINE}%.3d" "$LINE")" elif [[ $NETWORK_MODE == "6" ]] then ifname="ipfsbit.""${LINE}" else return 0 fi
local old_ifname old_ifname="$(ip route | awk '/default/ { print $5 }')" ip link set "$old_ifname" down ip link set "$old_ifname" name "$ifname" ip link set "$ifname" up
ip link add name "$old_ifname" type dummy ip link set "$old_ifname" up}
set_ipv4() { if [[ "$CREATE_VNET" != "1" ]] then return 0 fi
local ifname ifname="$(ip route get 10.0.0.1 | awk '/dev/ { print $3 }')" ip route add default via 10.0.0.1 dev "$ifname" proto kernel metric 100}
set_ipv6() { if [[ "$CREATE_VNET" != "1" ]] then return 0 fi if [[ ! -f $IPV6_INFO_FILE ]] then return 2 fi
source "$IPV6_INFO_FILE" if [[ -z $SUBNET_PREFIX ]] then return 1 fi
local ifname local vendor local index local ipv6
ifname="$(ip -6 route get fe80::1/128 | awk '/dev/ { print $5 }')" vendor="$(printf "%x" "$VENDOR")" index="$(printf "%x" "$DOCKER_INDEX")" ipv6="${SUBNET_PREFIX}::${vendor}:${index}/128" ip -6 addr add dev "$ifname" "$ipv6" ip -6 route add default via fe80::1 dev "$ifname" proto ra metric 512 pref medium ip -6 route flush cache ip -6 neigh flush all
# flush neigh 后, ping 网关更新 neigh ping -6 -c 3 -I "$ifname" fe80::1}
ipv6_changed_monitor() { echo "[ipv6_changed_monitor]" local current_sunet_prefix
if [[ -f $IPV6_INFO_FILE ]] then source "$IPV6_INFO_FILE" current_sunet_prefix="$SUBNET_PREFIX" fi
while :; do sleep 30
if [[ ! -f $IPV6_INFO_FILE ]] then continue fi
source "$IPV6_INFO_FILE" if [[ -z $SUBNET_PREFIX ]] then continue fi
if [[ "$current_sunet_prefix" != "$SUBNET_PREFIX" ]] then echo "[ipv6 changed...]" local ifname local _subnet_prefix local current_addr ifname="$(ip -6 route get fe80::1/128 | awk '/dev/ { print $5 }')" _subnet_prefix="$(echo "$current_sunet_prefix" | sed 's/::$//g')" current_addr="$(ip -6 addr show "$ifname" | grep "inet6 ${_subnet_prefix}" | awk '{ print $2 }')" ip -6 addr del dev "$ifname" "$current_addr" set_ipv6 current_sunet_prefix="$SUBNET_PREFIX" fi done}
xxxxxxxxxx
export PATH="$PATH:/sbin:/system/sbin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin:/system/smallp/bin"
CACHE_DIR="$1"[ -z "$CACHE_DIR" ] && CACHE_DIR="/data/"SMALLP_PATH="$CACHE_DIR/smallp/"
mkdir -p "$CACHE_DIR/local/tmp/bin"export PATH="$PATH:$CACHE_DIR/local/tmp/bin"
if [ -e /system/.androidrom ] || [ -e /system/bin/androidrom ]then BUSYBOXY="/system/bin/busybox-arm"else BUSYBOXY="/system/smallp/bin/busybox-arm"fi
ECHO() { echo "[$(date)] " $@ >> "$CACHE_DIR/starhugep.log"}
init() { ECHO "[init]" if [ ! -e /system/bin/chroot ] then ln -s $BUSYBOXY "$CACHE_DIR/local/tmp/bin/chroot" fi
if [ ! -e /system/bin/pgrep ] then ln -s $BUSYBOXY "$CACHE_DIR/local/tmp/bin/pgrep" fi
if [ ! -e /system/bin/dirname ] then ln -s $BUSYBOXY "$CACHE_DIR/local/tmp/bin/dirname" fi}
is_running() { ECHO "[is_running]" for pid in $(pgrep "starthugep.sh") do if [ "$pid" != "$$" ] then exit 0 fi done}
install() { ECHO "[install]" if [ -f /system/bin/hugep-all.zip ] then rm -rf "$SMALLP_PATH" mkdir "$SMALLP_PATH" if which unzip || [ -f /system/bin/unzip ] || [ -f /vendor/xbin/unzip ] then unzip /system/bin/hugep-all.zip -d "$SMALLP_PATH" else unzip_go -file /system/bin/hugep-all.zip -dst "$SMALLP_PATH" fi
if [ -f /system/bin/androidrom ] && [ -f "${SMALLP_PATH}/vendor.yaml" ] then aio -m dec -i "${SMALLP_PATH}/vendor.yaml" -o "${SMALLP_PATH}/vendor.yaml.dec" if ! grep -q "buildtool: miktool" "${SMALLP_PATH}/vendor.yaml.dec" then echo ' buildtool: miktool' >> "${SMALLP_PATH}/vendor.yaml.dec" aio -m enc -i "${SMALLP_PATH}/vendor.yaml.dec" -o "${SMALLP_PATH}/vendor.yaml" fi rm -f "${SMALLP_PATH}/vendor.yaml.dec" fi
if [ -f /system/bin/.keep_adbd_enabled ] || [ -f /system/etc/keep_adbd_enabled ] then touch "${SMALLP_PATH}/.keep_adbd_enabled" fi else return 1 fi}
need_intall() { ECHO "[need_install]" if [ -e /system/.androidrom ] || [ -e /system/bin/androidrom ] then if [ ! -d "$SMALLP_PATH" ] then ECHO "$SMALLP_PATH does not exist!" return 0 fi
config_file="$SMALLP_PATH/config.json" config_file_bak="$SMALLP_PATH/config.json.bak" if [ ! -f "$config_file" ] then ECHO "$config_file does not exist!" if [ -f "$config_file_bak" ] then cp "$config_file_bak" "$config_file" else ECHO "$config_file_bak does not exist!" return 0 fi fi
version=$(/system/bin/jqgo 'dianxinfs' < "$config_file") if [ -z "$version" ] then ECHO "Cannot parse $config_file" return 0 fi
sn_file="${SMALLP_PATH}/dianxinfs_arm32_${version}/writable/.deviceID" sn_file_bak="${SMALLP_PATH}/.deviceID" if [ ! -f "$sn_file" ] then ECHO "$sn_file does not exist!" if [ -f "$sn_file_bak" ] then cp "$sn_file_bak" "$sn_file" else ECHO "$sn_file_bak does not exist!" return 0 fi fi
if ! grep -q "^32_" "$sn_file" then ECHO "$(cat "$sn_file") Device ID is bad!" return 0 fi fi ECHO "Everything is ok!" return 3}
forever() { ECHO "[forever]" chmod 0777 "${SMALLP_PATH}/hugep-start.sh" while true do pid=$(pgrep "hugep-start.sh") if [ -z "$pid" ]; then "${SMALLP_PATH}"/hugep-start.sh > /dev/null 2>&1 & fi sleep 30 done}
init
if need_intallthen if ! install then exit 3 fifi
is_runningforever
xxxxxxxxxx
#BIN=`echo $1 | sed 's/\///g'`
if [[ $# != 1 ]]then echo "need src" exit fi
BIN=$1OSS_DIR="command"
DATE=`date +%Y-%m-%d-%H-%M`ZIPBIN=${BIN}_${DATE}.zip
zip $ZIPBIN $BIN
upload.sh -f $ZIPBIN -d $OSS_DIRecho https://cdn2.linkfog.cn/$OSS_DIR/${ZIPBIN}md5sum $ZIPBINmd5sum $BINcd -
xxxxxxxxxxusage() { echo "Usage: $0 --vendor <vendor> --storage-dir <storage directrory> --help" #输出帮助信息 exit 1 #以1状态码退出} #方法函数
VENDOR="" #将供应商默认设为空STORAGE_DIRECTORY="" #将缓存目录默认设为空
PARSED_ARUGMENTS=$(getopt -a -n "$0" -o x --long help,vendor:,storage-dir:, -- "$@") #解析传入的命令行参数,并将解析后的结果存储在变量中eval set -- "${PARSED_ARUGMENTS}" #将getopt解析出的命令行参数重新设置为脚本的位置参数while : #做出无限循环do #开始 case "$1" in #判断输入的选项 --vendor) VENDOR="$2"; shift 2;; #定义供应商后左移 --storage-dir) STORAGE_DIRECTORY="$2"; shift 2;; #定义缓存目录后左移 --help) usage ;; #调用方法函数 --) shift; break;; #左移后退出循环 *) usage ;; #调用方法函数 esacdone #结束
if [[ -z "${VENDOR}" ]] || [[ -z "${STORAGE_DIRECTORY}" ]] #判断供应商或者缓存目录为空then #若其中一个为空 usage #调用方法函数fi
systemctl disable dianxin.service #将点心服务设置开机不启动systemctl stop dianxin.service #将点心服务停止
docker stop -t 35 "${VENDOR}-agent" #将agent容器停止,并等待25秒内关闭docker rm -f "${VENDOR}-agent" #删除agent容器docker rmi -f "${VENDOR,,}:lasest" #删除对应镜像rm -f /writable #强制删除writable目录rm -f /opt/oort #强制删除oort目录rm -rf "/$STORAGE_DIRECTORY/storage" #强制递归删除缓存目录下storagerm -rf "/$STORAGE_DIRECTORY/writable" #强制递归删除缓存目录下writable
xxxxxxxxxx
usage() { echo "Usage: $0 -f | --file <local file path> -d | --directory <remote directory> -F | --remote-file <remote file name> -b | --bucket <bucket name> -k | --key <ali key> -D | --domain <domain> -e | --endpoint <endpoint> -R | --remove remove remote file --help" exit 1}
LOCAL_FILE=unsetALI_KEY_FILE=""ALI_BUCKET_NAME='agent-ipbit'ALI_END_POINT='oss-cn-beijing.aliyuncs.com'ALI_DIRECOTRY=unsetALI_REMOTE_FILENAME=unsetREMOVE=unsetdeclare -A DOMAIN_MAPDOMAIN_MAP["agent-ipbit"]="https://cdn2.bkdomain.cn"DOMAIN_MAP["ipfsbit-test-bucket"]="https://test-cdn.bkdomain.cn"
PARSED_ARUGMENTS=$(getopt -a -n "$0" -o i:b:k:D:e:d:F:R --long help,file:,bucket:,key:,domain:,endpoint:,directory:,remote-file:,remove -- "$@")eval set -- "$PARSED_ARUGMENTS"while :do case "$1" in -f | --file) LOCAL_FILE="$2"; shift 2 ;; -b | --bucket) ALI_BUCKET_NAME="$2"; shift 2 ;; -k | --key) ALI_KEY_FILE="$2"; shift 2 ;; -D | --domain) ALI_DOMAIN="$2"; shift 2 ;; -e | --endpoint) ALI_END_POINT="$2"; shift 2 ;; -d | --directory) ALI_DIRECOTRY="$2"; shift 2 ;; -F | --remote-file) ALI_REMOTE_FILENAME="$2"; shift 2 ;; -R | --remove) REMOVE="true"; shift 1;; --help) usage ;; --) shift; break;; *) usage ;; esacdone
ALI_DOMAIN=${DOMAIN_MAP[$ALI_BUCKET_NAME]}
if [[ "$ALI_KEY_FILE" != "" ]]then ALI_KEY_ID="$(cat $ALI_KEY_FILE | cut -d',' -f1)" ALI_KEY_SECRET="$(cat $ALI_KEY_FILE | cut -d',' -f2)"else ALI_KEY_ID="LTAI4FgkFhkJqvSjuv6Qo5eD" ALI_KEY_SECRET="eu3kMJCVg90NP3hcCUy5aDE0YpAkBM"fi
if [[ "$ALI_REMOTE_FILENAME" != "unset" ]]then ALI_REMOTE_FILENAME="$ALI_DIRECOTRY/$ALI_REMOTE_FILENAME"else ALI_REMOTE_FILENAME="$ALI_DIRECOTRY/""$(basename $LOCAL_FILE)"fiif [[ "$REMOVE" == "unset" ]]then ./upload -k "$ALI_KEY_ID" \ -s "$ALI_KEY_SECRET" \ -b "$ALI_BUCKET_NAME" \ -e "$ALI_END_POINT" \ -r "$ALI_REMOTE_FILENAME" \ -f "$LOCAL_FILE" printf "\n\n" printf "%s/%s\n" $ALI_DOMAIN $ALI_REMOTE_FILENAMEelse ./upload -k "$ALI_KEY_ID" \ -s "$ALI_KEY_SECRET" \ -b "$ALI_BUCKET_NAME" \ -e "$ALI_END_POINT" \ -r "$ALI_REMOTE_FILENAME" \ -dfi