feat: add CUPS watchdog timers
This commit is contained in:
@@ -29,6 +29,7 @@ wget -qO- https://git.workyai.cn/237899745/S905L3A/raw/branch/master/setup_cups.
|
||||
- 多种打印机驱动可选(通用/HP/爱普生/兄弟/奔图)
|
||||
- 自动配置远程访问权限
|
||||
- 安装中文界面模板
|
||||
- 安装网络和打印服务守护脚本
|
||||
|
||||
---
|
||||
|
||||
@@ -39,6 +40,8 @@ wget -qO- https://git.workyai.cn/237899745/S905L3A/raw/branch/master/setup_cups.
|
||||
| CUPS | 631 | 打印服务/Web管理界面 |
|
||||
| Avahi | 5353 | mDNS/AirPrint 自动发现 |
|
||||
| 驱动管理器 | 632 | 内网上传安装打印机驱动(可选) |
|
||||
| 网络守护 | systemd timer | 断网后自动切换网卡为 DHCP |
|
||||
| 打印守护 | systemd timer | CUPS 卡死或异常后自动重启恢复 |
|
||||
|
||||
---
|
||||
|
||||
@@ -87,6 +90,10 @@ https://服务器IP:631
|
||||
| `/etc/cups/ssl/` | SSL 证书目录 |
|
||||
| `/usr/share/cups/templates-zh_CN/` | 中文界面模板 |
|
||||
| `/opt/cups-driver-manager/` | 驱动管理器安装目录(可选) |
|
||||
| `/opt/cups-watchdog/` | 守护脚本安装目录 |
|
||||
| `/etc/cups-watchdog/network-watchdog.conf` | 网络守护配置,可设置固定 IP、网关、DNS |
|
||||
| `/etc/cups-watchdog/print-watchdog.conf` | 打印服务守护配置 |
|
||||
| `/var/log/cups-watchdog/` | 守护脚本日志目录 |
|
||||
|
||||
---
|
||||
|
||||
@@ -133,6 +140,19 @@ tail -f /var/log/cups/error_log
|
||||
|
||||
# 检查端口监听
|
||||
ss -tlnp | grep -E "631|632"
|
||||
|
||||
# 查看守护状态
|
||||
systemctl status cups-network-watchdog.timer cups-print-watchdog.timer
|
||||
|
||||
# 手动切 DHCP
|
||||
/opt/cups-watchdog/network-watchdog.sh dhcp
|
||||
|
||||
# 按配置文件手动切回固定 IP
|
||||
/opt/cups-watchdog/network-watchdog.sh static
|
||||
|
||||
# 查看守护日志
|
||||
tail -f /var/log/cups-watchdog/network.log
|
||||
tail -f /var/log/cups-watchdog/print.log
|
||||
```
|
||||
|
||||
---
|
||||
@@ -168,6 +188,13 @@ ls /usr/share/cups/templates-zh_CN/
|
||||
locale -a | grep zh_CN
|
||||
```
|
||||
|
||||
### 问题5:网络守护自动切 DHCP 后要切回固定 IP
|
||||
**解决**:
|
||||
```bash
|
||||
nano /etc/cups-watchdog/network-watchdog.conf
|
||||
/opt/cups-watchdog/network-watchdog.sh static
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、文件清单
|
||||
@@ -175,6 +202,7 @@ locale -a | grep zh_CN
|
||||
```
|
||||
/root/yuyx/B863AV3.2M刷Armbian教程/
|
||||
├── setup_cups.sh # 一键安装脚本
|
||||
├── watchdog/ # 网络和打印服务守护脚本
|
||||
├── cups-templates-zh_CN/ # 中文界面模板(65个文件)
|
||||
├── 刷机教程.md # Armbian 刷机教程
|
||||
└── CUPS打印服务配置交接文档.md # 本文档
|
||||
@@ -188,6 +216,8 @@ locale -a | grep zh_CN
|
||||
- [ ] 局域网 macOS/iOS AirPrint 自动发现
|
||||
- [ ] 局域网 Android Mopria 打印
|
||||
- [ ] 真实 USB 打印机连接测试
|
||||
- [ ] 断网后网络守护自动切 DHCP
|
||||
- [ ] CUPS 异常后打印守护自动重启恢复
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -355,6 +355,7 @@ df -h
|
||||
- [ ] `apt update` 正常工作
|
||||
- [ ] 运行 CUPS 安装脚本成功
|
||||
- [ ] 浏览器能打开 https://IP:631
|
||||
- [ ] `cups-network-watchdog.timer` 和 `cups-print-watchdog.timer` 已启用
|
||||
|
||||
---
|
||||
|
||||
|
||||
34
README.md
34
README.md
@@ -11,6 +11,7 @@
|
||||
- 虚拟 PDF 打印机(测试连接用)
|
||||
- 多种打印机驱动可选
|
||||
- 驱动管理器(默认仅允许内网访问)
|
||||
- 网络和打印服务守护(断网自动切 DHCP,CUPS 卡死自动恢复)
|
||||
- 支持一键卸载
|
||||
|
||||
## 快速安装
|
||||
@@ -76,6 +77,34 @@ chmod +x setup_cups.sh
|
||||
| Avahi | 5353 | mDNS/AirPrint 自动发现 |
|
||||
| 驱动管理器 | 632 | 内网上传安装打印机驱动(可选) |
|
||||
|
||||
## 自动守护
|
||||
|
||||
安装脚本会自动启用两个 systemd timer:
|
||||
|
||||
| 守护 | 作用 |
|
||||
|------|------|
|
||||
| `cups-network-watchdog.timer` | 每分钟检测网络,连续失败后自动把网卡切回 DHCP |
|
||||
| `cups-print-watchdog.timer` | 每分钟检测 CUPS/Avahi/驱动管理器,卡死或异常后自动重启 |
|
||||
|
||||
配置文件:
|
||||
|
||||
```bash
|
||||
# 网络守护配置,可在里面设置固定 IP、网关、DNS
|
||||
nano /etc/cups-watchdog/network-watchdog.conf
|
||||
|
||||
# 手动切回配置里的固定 IP
|
||||
/opt/cups-watchdog/network-watchdog.sh static
|
||||
|
||||
# 手动切 DHCP
|
||||
/opt/cups-watchdog/network-watchdog.sh dhcp
|
||||
|
||||
# 打印服务守护配置
|
||||
nano /etc/cups-watchdog/print-watchdog.conf
|
||||
|
||||
# 查看守护状态
|
||||
systemctl status cups-network-watchdog.timer cups-print-watchdog.timer
|
||||
```
|
||||
|
||||
## 常用命令
|
||||
|
||||
```bash
|
||||
@@ -88,6 +117,10 @@ systemctl restart cups
|
||||
# 查看 CUPS 日志
|
||||
tail -f /var/log/cups/error_log
|
||||
|
||||
# 查看守护脚本日志
|
||||
tail -f /var/log/cups-watchdog/network.log
|
||||
tail -f /var/log/cups-watchdog/print.log
|
||||
|
||||
# 检查 USB 打印机
|
||||
lsusb | grep -i print
|
||||
lpinfo -v | grep usb
|
||||
@@ -103,6 +136,7 @@ lpinfo -v | grep usb
|
||||
|
||||
```
|
||||
├── setup_cups.sh # 一键安装/卸载脚本
|
||||
├── watchdog/ # 网络和打印服务守护脚本
|
||||
├── cups-templates-zh_CN/ # 中文界面模板(65个文件)
|
||||
├── README.md # 本文档
|
||||
└── 刷机教程.md # Armbian 刷机教程
|
||||
|
||||
127
setup_cups.sh
127
setup_cups.sh
@@ -1109,6 +1109,109 @@ EOF
|
||||
DRIVER_MANAGER_PASSWORD="$admin_pass"
|
||||
}
|
||||
|
||||
# 安装网络和打印服务守护脚本
|
||||
install_watchdogs() {
|
||||
info "安装 CUPS 守护脚本..."
|
||||
|
||||
apt install -y iproute2 iputils-ping curl 2>/dev/null || warn "守护脚本依赖安装失败,继续尝试使用系统已有命令"
|
||||
|
||||
local install_dir="/opt/cups-watchdog"
|
||||
local config_dir="/etc/cups-watchdog"
|
||||
local log_dir="/var/log/cups-watchdog"
|
||||
local source_dir=""
|
||||
local tmp_dir=""
|
||||
|
||||
mkdir -p "$install_dir" "$config_dir" "$log_dir"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" 2>/dev/null && pwd)" || SCRIPT_DIR=""
|
||||
|
||||
if [ -n "$SCRIPT_DIR" ] && [ -d "$SCRIPT_DIR/watchdog" ]; then
|
||||
source_dir="$SCRIPT_DIR/watchdog"
|
||||
info "从本地复制守护脚本"
|
||||
else
|
||||
info "从仓库下载守护脚本..."
|
||||
tmp_dir=$(mktemp -d)
|
||||
if download_repo_archive "$tmp_dir/repo.zip"; then
|
||||
unzip -q "$tmp_dir/repo.zip" -d "$tmp_dir" 2>/dev/null
|
||||
source_dir=$(find "$tmp_dir" -type d -name "watchdog" 2>/dev/null | head -1)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$source_dir" ] || [ ! -d "$source_dir" ]; then
|
||||
[ -n "$tmp_dir" ] && rm -rf "$tmp_dir"
|
||||
warn "未找到守护脚本目录,跳过安装"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cp -f "$source_dir/network-watchdog.sh" "$install_dir/"
|
||||
cp -f "$source_dir/print-watchdog.sh" "$install_dir/"
|
||||
chmod +x "$install_dir/network-watchdog.sh" "$install_dir/print-watchdog.sh"
|
||||
|
||||
cp -f "$source_dir/cups-network-watchdog.service" /etc/systemd/system/
|
||||
cp -f "$source_dir/cups-network-watchdog.timer" /etc/systemd/system/
|
||||
cp -f "$source_dir/cups-print-watchdog.service" /etc/systemd/system/
|
||||
cp -f "$source_dir/cups-print-watchdog.timer" /etc/systemd/system/
|
||||
|
||||
[ -n "$tmp_dir" ] && rm -rf "$tmp_dir"
|
||||
|
||||
local current_ip=$(get_ip)
|
||||
local current_gateway=$(get_gateway)
|
||||
local current_interface=$(get_interface)
|
||||
local current_netmask=$(get_netmask)
|
||||
local current_dns=$(get_dns)
|
||||
current_dns="${current_dns:-114.114.114.114 223.5.5.5}"
|
||||
|
||||
local ping_targets="223.5.5.5 114.114.114.114"
|
||||
if [ -n "$current_gateway" ]; then
|
||||
ping_targets="$current_gateway $ping_targets"
|
||||
fi
|
||||
|
||||
if [ ! -f "$config_dir/network-watchdog.conf" ]; then
|
||||
cat > "$config_dir/network-watchdog.conf" << EOF
|
||||
# CUPS network watchdog config.
|
||||
# Edit these values when you want to manually switch back to a fixed IP:
|
||||
# /opt/cups-watchdog/network-watchdog.sh static
|
||||
INTERFACE="$current_interface"
|
||||
STATIC_IP="$current_ip"
|
||||
STATIC_PREFIX="$current_netmask"
|
||||
STATIC_GATEWAY="$current_gateway"
|
||||
STATIC_DNS="$current_dns"
|
||||
PING_TARGETS="$ping_targets"
|
||||
FAIL_THRESHOLD=3
|
||||
DHCP_AFTER_FAILURE=1
|
||||
LOG_FILE="/var/log/cups-watchdog/network.log"
|
||||
EOF
|
||||
chmod 600 "$config_dir/network-watchdog.conf"
|
||||
else
|
||||
info "保留现有网络守护配置: $config_dir/network-watchdog.conf"
|
||||
fi
|
||||
|
||||
if [ ! -f "$config_dir/print-watchdog.conf" ]; then
|
||||
cat > "$config_dir/print-watchdog.conf" << EOF
|
||||
# CUPS print watchdog config.
|
||||
SERVICES="cups avahi-daemon cups-driver-manager"
|
||||
CUPS_URL="http://127.0.0.1:631/"
|
||||
CHECK_CUPS_HTTP=1
|
||||
CHECK_LPSTAT=1
|
||||
COMMAND_TIMEOUT=8
|
||||
FAIL_THRESHOLD=2
|
||||
RESTART_COOLDOWN=60
|
||||
LOG_FILE="/var/log/cups-watchdog/print.log"
|
||||
EOF
|
||||
chmod 600 "$config_dir/print-watchdog.conf"
|
||||
else
|
||||
info "保留现有打印守护配置: $config_dir/print-watchdog.conf"
|
||||
fi
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now cups-network-watchdog.timer
|
||||
systemctl enable --now cups-print-watchdog.timer
|
||||
|
||||
success "守护脚本安装完成"
|
||||
info "网络守护配置: $config_dir/network-watchdog.conf"
|
||||
info "打印守护配置: $config_dir/print-watchdog.conf"
|
||||
}
|
||||
|
||||
# 安装虚拟PDF打印机(用于测试连接)
|
||||
install_pdf_printer() {
|
||||
info "安装虚拟 PDF 打印机..."
|
||||
@@ -1333,6 +1436,8 @@ main() {
|
||||
((step++))
|
||||
fi
|
||||
echo " $step. 启动并设置开机自启"
|
||||
((step++))
|
||||
echo " $step. 安装网络和打印服务守护脚本"
|
||||
echo ""
|
||||
read -p "是否继续? [Y/n]: " confirm < /dev/tty
|
||||
confirm=${confirm:-Y}
|
||||
@@ -1425,6 +1530,9 @@ main() {
|
||||
systemctl enable avahi-daemon
|
||||
success "Avahi 服务已启动并设置开机自启"
|
||||
|
||||
# 8. 安装守护脚本
|
||||
install_watchdogs
|
||||
|
||||
# 更新IP地址(如果配置了静态IP)
|
||||
LOCAL_IP=$(get_ip)
|
||||
|
||||
@@ -1463,6 +1571,13 @@ main() {
|
||||
echo -e " ${GREEN} ${NC} PDF 输出目录: /var/spool/cups-pdf/"
|
||||
echo ""
|
||||
fi
|
||||
if systemctl is-enabled --quiet cups-network-watchdog.timer 2>/dev/null && \
|
||||
systemctl is-enabled --quiet cups-print-watchdog.timer 2>/dev/null; then
|
||||
echo -e " ${GREEN}[守护脚本]${NC} 已启用网络和打印服务自动恢复"
|
||||
echo -e " ${GREEN} ${NC} 配置目录: /etc/cups-watchdog/"
|
||||
echo -e " ${GREEN} ${NC} 日志目录: /var/log/cups-watchdog/"
|
||||
echo ""
|
||||
fi
|
||||
echo -e " ${YELLOW}下一步:${NC}"
|
||||
echo " 1. 用浏览器打开上面的地址"
|
||||
if lpstat -p PDF 2>/dev/null | grep -q "PDF"; then
|
||||
@@ -1508,6 +1623,7 @@ uninstall() {
|
||||
echo " - CUPS-PDF 虚拟打印机"
|
||||
echo " - 中文界面模板"
|
||||
echo " - 驱动管理器"
|
||||
echo " - 网络和打印服务守护脚本"
|
||||
echo " - 所有打印任务和配置"
|
||||
echo ""
|
||||
read -p "确定要卸载吗? [y/N]: " confirm < /dev/tty
|
||||
@@ -1526,9 +1642,13 @@ uninstall() {
|
||||
systemctl stop cups 2>/dev/null || true
|
||||
systemctl stop avahi-daemon 2>/dev/null || true
|
||||
systemctl stop cups-driver-manager 2>/dev/null || true
|
||||
systemctl stop cups-network-watchdog.timer cups-network-watchdog.service 2>/dev/null || true
|
||||
systemctl stop cups-print-watchdog.timer cups-print-watchdog.service 2>/dev/null || true
|
||||
systemctl disable cups 2>/dev/null || true
|
||||
systemctl disable avahi-daemon 2>/dev/null || true
|
||||
systemctl disable cups-driver-manager 2>/dev/null || true
|
||||
systemctl disable cups-network-watchdog.timer 2>/dev/null || true
|
||||
systemctl disable cups-print-watchdog.timer 2>/dev/null || true
|
||||
|
||||
# 卸载软件包
|
||||
info "卸载软件包..."
|
||||
@@ -1546,7 +1666,14 @@ uninstall() {
|
||||
rm -rf /usr/share/cups/templates-zh
|
||||
rm -rf /usr/share/cups/templates-en-backup
|
||||
rm -rf /opt/cups-driver-manager
|
||||
rm -rf /opt/cups-watchdog
|
||||
rm -rf /etc/cups-watchdog
|
||||
rm -rf /var/log/cups-watchdog
|
||||
rm -f /etc/systemd/system/cups-driver-manager.service
|
||||
rm -f /etc/systemd/system/cups-network-watchdog.service
|
||||
rm -f /etc/systemd/system/cups-network-watchdog.timer
|
||||
rm -f /etc/systemd/system/cups-print-watchdog.service
|
||||
rm -f /etc/systemd/system/cups-print-watchdog.timer
|
||||
systemctl daemon-reload 2>/dev/null || true
|
||||
|
||||
# 清理依赖
|
||||
|
||||
8
watchdog/cups-network-watchdog.service
Normal file
8
watchdog/cups-network-watchdog.service
Normal file
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=CUPS network watchdog
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/opt/cups-watchdog/network-watchdog.sh check
|
||||
11
watchdog/cups-network-watchdog.timer
Normal file
11
watchdog/cups-network-watchdog.timer
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Run CUPS network watchdog every minute
|
||||
|
||||
[Timer]
|
||||
OnBootSec=2min
|
||||
OnUnitActiveSec=1min
|
||||
AccuracySec=15s
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
8
watchdog/cups-print-watchdog.service
Normal file
8
watchdog/cups-print-watchdog.service
Normal file
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=CUPS print service watchdog
|
||||
After=cups.service
|
||||
Wants=cups.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/opt/cups-watchdog/print-watchdog.sh check
|
||||
11
watchdog/cups-print-watchdog.timer
Normal file
11
watchdog/cups-print-watchdog.timer
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Run CUPS print service watchdog every minute
|
||||
|
||||
[Timer]
|
||||
OnBootSec=2min
|
||||
OnUnitActiveSec=1min
|
||||
AccuracySec=15s
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
275
watchdog/network-watchdog.sh
Normal file
275
watchdog/network-watchdog.sh
Normal file
@@ -0,0 +1,275 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Network watchdog for the CUPS print server.
|
||||
# Default behavior: when connectivity checks fail repeatedly, switch the
|
||||
# configured interface back to DHCP so the box can regain network access.
|
||||
#
|
||||
# Edit /etc/cups-watchdog/network-watchdog.conf to set STATIC_IP,
|
||||
# STATIC_PREFIX, STATIC_GATEWAY and STATIC_DNS. You can also run:
|
||||
# /opt/cups-watchdog/network-watchdog.sh static
|
||||
# /opt/cups-watchdog/network-watchdog.sh dhcp
|
||||
#
|
||||
|
||||
set -u
|
||||
|
||||
CONFIG_FILE="${CUPS_NETWORK_WATCHDOG_CONFIG:-/etc/cups-watchdog/network-watchdog.conf}"
|
||||
STATE_DIR="/run/cups-watchdog"
|
||||
|
||||
INTERFACE=""
|
||||
STATIC_IP=""
|
||||
STATIC_PREFIX="24"
|
||||
STATIC_GATEWAY=""
|
||||
STATIC_DNS="114.114.114.114 223.5.5.5"
|
||||
PING_TARGETS="223.5.5.5 114.114.114.114"
|
||||
FAIL_THRESHOLD=3
|
||||
DHCP_AFTER_FAILURE=1
|
||||
LOG_FILE="/var/log/cups-watchdog/network.log"
|
||||
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true
|
||||
|
||||
log_msg() {
|
||||
local msg="$1"
|
||||
local line
|
||||
line="$(date '+%Y-%m-%d %H:%M:%S') [network-watchdog] $msg"
|
||||
echo "$line"
|
||||
echo "$line" >> "$LOG_FILE" 2>/dev/null || true
|
||||
}
|
||||
|
||||
detect_interface() {
|
||||
if [ -n "${INTERFACE:-}" ] && ip link show "$INTERFACE" >/dev/null 2>&1; then
|
||||
echo "$INTERFACE"
|
||||
return 0
|
||||
fi
|
||||
|
||||
ip route show default 2>/dev/null | awk '{print $5; exit}'
|
||||
}
|
||||
|
||||
nm_connection_for_interface() {
|
||||
local iface="$1"
|
||||
nmcli -t -f NAME,DEVICE con show --active 2>/dev/null | awk -F: -v iface="$iface" '$2 == iface {print $1; exit}'
|
||||
}
|
||||
|
||||
configure_dhcp_nmcli() {
|
||||
local iface="$1"
|
||||
local conn
|
||||
conn="$(nm_connection_for_interface "$iface")"
|
||||
[ -n "$conn" ] || conn="$iface"
|
||||
|
||||
nmcli con mod "$conn" ipv4.method auto ipv4.addresses "" ipv4.gateway "" ipv4.dns "" >/dev/null
|
||||
nmcli con down "$conn" >/dev/null 2>&1 || true
|
||||
nmcli con up "$conn" >/dev/null
|
||||
}
|
||||
|
||||
configure_dhcp_netplan() {
|
||||
local iface="$1"
|
||||
local target_file="/etc/netplan/99-cups-watchdog-dhcp.yaml"
|
||||
|
||||
cat > "$target_file" << EOF
|
||||
# DHCP recovery config generated by cups network watchdog.
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
$iface:
|
||||
dhcp4: yes
|
||||
EOF
|
||||
chmod 600 "$target_file"
|
||||
rm -f /etc/netplan/01-static-ip.yaml /etc/netplan/99-cups-static-ip.yaml /etc/netplan/99-cups-watchdog-static.yaml 2>/dev/null || true
|
||||
netplan apply
|
||||
}
|
||||
|
||||
configure_dhcp_interfaces() {
|
||||
local iface="$1"
|
||||
|
||||
if [ -f /etc/network/interfaces ]; then
|
||||
cp /etc/network/interfaces /etc/network/interfaces.cups-watchdog.bak
|
||||
fi
|
||||
|
||||
cat > /etc/network/interfaces << EOF
|
||||
# DHCP recovery config generated by cups network watchdog.
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
auto $iface
|
||||
iface $iface inet dhcp
|
||||
EOF
|
||||
systemctl restart networking 2>/dev/null || /etc/init.d/networking restart 2>/dev/null || true
|
||||
}
|
||||
|
||||
configure_dhcp() {
|
||||
local iface
|
||||
iface="$(detect_interface)"
|
||||
if [ -z "$iface" ]; then
|
||||
log_msg "cannot switch to DHCP: network interface not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_msg "switching $iface to DHCP"
|
||||
if command -v nmcli >/dev/null 2>&1 && systemctl is-active --quiet NetworkManager 2>/dev/null; then
|
||||
configure_dhcp_nmcli "$iface"
|
||||
elif [ -d /etc/netplan ] && command -v netplan >/dev/null 2>&1; then
|
||||
configure_dhcp_netplan "$iface"
|
||||
else
|
||||
configure_dhcp_interfaces "$iface"
|
||||
fi
|
||||
}
|
||||
|
||||
configure_static_nmcli() {
|
||||
local iface="$1"
|
||||
local conn
|
||||
conn="$(nm_connection_for_interface "$iface")"
|
||||
[ -n "$conn" ] || conn="$iface"
|
||||
|
||||
nmcli con mod "$conn" ipv4.method manual ipv4.addresses "$STATIC_IP/$STATIC_PREFIX" ipv4.gateway "$STATIC_GATEWAY" ipv4.dns "$STATIC_DNS" >/dev/null
|
||||
nmcli con down "$conn" >/dev/null 2>&1 || true
|
||||
nmcli con up "$conn" >/dev/null
|
||||
}
|
||||
|
||||
configure_static_netplan() {
|
||||
local iface="$1"
|
||||
local target_file="/etc/netplan/99-cups-watchdog-static.yaml"
|
||||
local dns_list=""
|
||||
local d
|
||||
|
||||
for d in $STATIC_DNS; do
|
||||
dns_list="$dns_list, $d"
|
||||
done
|
||||
dns_list="${dns_list#, }"
|
||||
|
||||
cat > "$target_file" << EOF
|
||||
# Static network config generated by cups network watchdog.
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
$iface:
|
||||
dhcp4: no
|
||||
addresses:
|
||||
- $STATIC_IP/$STATIC_PREFIX
|
||||
routes:
|
||||
- to: default
|
||||
via: $STATIC_GATEWAY
|
||||
nameservers:
|
||||
addresses: [$dns_list]
|
||||
EOF
|
||||
chmod 600 "$target_file"
|
||||
rm -f /etc/netplan/01-dhcp.yaml /etc/netplan/99-cups-dhcp.yaml /etc/netplan/99-cups-watchdog-dhcp.yaml 2>/dev/null || true
|
||||
netplan apply
|
||||
}
|
||||
|
||||
configure_static_interfaces() {
|
||||
local iface="$1"
|
||||
local netmask="255.255.255.0"
|
||||
|
||||
case "$STATIC_PREFIX" in
|
||||
8) netmask="255.0.0.0" ;;
|
||||
16) netmask="255.255.0.0" ;;
|
||||
24) netmask="255.255.255.0" ;;
|
||||
25) netmask="255.255.255.128" ;;
|
||||
26) netmask="255.255.255.192" ;;
|
||||
27) netmask="255.255.255.224" ;;
|
||||
28) netmask="255.255.255.240" ;;
|
||||
29) netmask="255.255.255.248" ;;
|
||||
30) netmask="255.255.255.252" ;;
|
||||
esac
|
||||
|
||||
if [ -f /etc/network/interfaces ]; then
|
||||
cp /etc/network/interfaces /etc/network/interfaces.cups-watchdog.bak
|
||||
fi
|
||||
|
||||
cat > /etc/network/interfaces << EOF
|
||||
# Static network config generated by cups network watchdog.
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
auto $iface
|
||||
iface $iface inet static
|
||||
address $STATIC_IP
|
||||
netmask $netmask
|
||||
gateway $STATIC_GATEWAY
|
||||
dns-nameservers $STATIC_DNS
|
||||
EOF
|
||||
systemctl restart networking 2>/dev/null || /etc/init.d/networking restart 2>/dev/null || true
|
||||
}
|
||||
|
||||
configure_static() {
|
||||
local iface
|
||||
iface="$(detect_interface)"
|
||||
|
||||
if [ -z "$iface" ]; then
|
||||
log_msg "cannot switch to static: network interface not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${STATIC_IP:-}" ] || [ -z "${STATIC_GATEWAY:-}" ]; then
|
||||
log_msg "cannot switch to static: STATIC_IP or STATIC_GATEWAY is empty in $CONFIG_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_msg "switching $iface to static $STATIC_IP/$STATIC_PREFIX"
|
||||
if command -v nmcli >/dev/null 2>&1 && systemctl is-active --quiet NetworkManager 2>/dev/null; then
|
||||
configure_static_nmcli "$iface"
|
||||
elif [ -d /etc/netplan ] && command -v netplan >/dev/null 2>&1; then
|
||||
configure_static_netplan "$iface"
|
||||
else
|
||||
configure_static_interfaces "$iface"
|
||||
fi
|
||||
}
|
||||
|
||||
connectivity_ok() {
|
||||
local target
|
||||
|
||||
for target in $PING_TARGETS; do
|
||||
[ -n "$target" ] || continue
|
||||
if ping -c 1 -W 2 "$target" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
check_network() {
|
||||
local count_file="$STATE_DIR/network.fail_count"
|
||||
local fail_count=0
|
||||
|
||||
if connectivity_ok; then
|
||||
echo 0 > "$count_file"
|
||||
log_msg "connectivity ok"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -f "$count_file" ]; then
|
||||
fail_count="$(cat "$count_file" 2>/dev/null || echo 0)"
|
||||
fi
|
||||
fail_count=$((fail_count + 1))
|
||||
echo "$fail_count" > "$count_file"
|
||||
|
||||
log_msg "connectivity failed ($fail_count/$FAIL_THRESHOLD)"
|
||||
if [ "$fail_count" -ge "$FAIL_THRESHOLD" ] && [ "$DHCP_AFTER_FAILURE" = "1" ]; then
|
||||
configure_dhcp
|
||||
echo 0 > "$count_file"
|
||||
fi
|
||||
}
|
||||
|
||||
case "${1:-check}" in
|
||||
check)
|
||||
check_network
|
||||
;;
|
||||
dhcp)
|
||||
configure_dhcp
|
||||
;;
|
||||
static)
|
||||
configure_static
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [check|dhcp|static]"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
162
watchdog/print-watchdog.sh
Normal file
162
watchdog/print-watchdog.sh
Normal file
@@ -0,0 +1,162 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Print service watchdog for the CUPS print server.
|
||||
# It checks systemd service state plus quick CUPS command/HTTP probes.
|
||||
# When checks fail repeatedly, it restarts CUPS and related services.
|
||||
#
|
||||
|
||||
set -u
|
||||
|
||||
CONFIG_FILE="${CUPS_PRINT_WATCHDOG_CONFIG:-/etc/cups-watchdog/print-watchdog.conf}"
|
||||
STATE_DIR="/run/cups-watchdog"
|
||||
|
||||
SERVICES="cups avahi-daemon cups-driver-manager"
|
||||
CUPS_URL="http://127.0.0.1:631/"
|
||||
CHECK_CUPS_HTTP=1
|
||||
CHECK_LPSTAT=1
|
||||
COMMAND_TIMEOUT=8
|
||||
FAIL_THRESHOLD=2
|
||||
RESTART_COOLDOWN=60
|
||||
LOG_FILE="/var/log/cups-watchdog/print.log"
|
||||
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true
|
||||
|
||||
log_msg() {
|
||||
local msg="$1"
|
||||
local line
|
||||
line="$(date '+%Y-%m-%d %H:%M:%S') [print-watchdog] $msg"
|
||||
echo "$line"
|
||||
echo "$line" >> "$LOG_FILE" 2>/dev/null || true
|
||||
}
|
||||
|
||||
unit_exists() {
|
||||
local service="$1"
|
||||
|
||||
systemctl list-unit-files --no-legend "$service.service" 2>/dev/null | awk '{print $1}' | grep -qx "$service.service" && return 0
|
||||
systemctl list-units --all --no-legend "$service.service" 2>/dev/null | awk '{print $1}' | grep -qx "$service.service"
|
||||
}
|
||||
|
||||
service_should_check() {
|
||||
local service="$1"
|
||||
|
||||
unit_exists "$service" || return 1
|
||||
if systemctl is-enabled --quiet "$service.service" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
if systemctl is-active --quiet "$service.service" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
check_systemd_services() {
|
||||
local service
|
||||
local failed=0
|
||||
|
||||
for service in $SERVICES; do
|
||||
service_should_check "$service" || continue
|
||||
if ! systemctl is-active --quiet "$service.service" 2>/dev/null; then
|
||||
log_msg "service not active: $service"
|
||||
failed=1
|
||||
fi
|
||||
done
|
||||
|
||||
return "$failed"
|
||||
}
|
||||
|
||||
check_lpstat() {
|
||||
[ "$CHECK_LPSTAT" = "1" ] || return 0
|
||||
command -v lpstat >/dev/null 2>&1 || return 0
|
||||
|
||||
timeout "$COMMAND_TIMEOUT" lpstat -r >/dev/null 2>&1
|
||||
}
|
||||
|
||||
check_http() {
|
||||
[ "$CHECK_CUPS_HTTP" = "1" ] || return 0
|
||||
command -v curl >/dev/null 2>&1 || return 0
|
||||
|
||||
curl -fsS --max-time "$COMMAND_TIMEOUT" "$CUPS_URL" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
restart_print_stack() {
|
||||
local now
|
||||
local last_file="$STATE_DIR/print.last_restart"
|
||||
local last=0
|
||||
local service
|
||||
|
||||
now="$(date +%s)"
|
||||
if [ -f "$last_file" ]; then
|
||||
last="$(cat "$last_file" 2>/dev/null || echo 0)"
|
||||
fi
|
||||
|
||||
if [ $((now - last)) -lt "$RESTART_COOLDOWN" ]; then
|
||||
log_msg "restart skipped: cooldown active"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_msg "restarting print stack"
|
||||
systemctl reset-failed cups.service >/dev/null 2>&1 || true
|
||||
systemctl restart cups.service
|
||||
|
||||
for service in avahi-daemon cups-driver-manager; do
|
||||
service_should_check "$service" || continue
|
||||
systemctl reset-failed "$service.service" >/dev/null 2>&1 || true
|
||||
systemctl restart "$service.service" >/dev/null 2>&1 || true
|
||||
done
|
||||
|
||||
echo "$now" > "$last_file"
|
||||
}
|
||||
|
||||
check_print_stack() {
|
||||
local count_file="$STATE_DIR/print.fail_count"
|
||||
local fail_count=0
|
||||
local failed=0
|
||||
|
||||
check_systemd_services || failed=1
|
||||
if ! check_lpstat; then
|
||||
log_msg "lpstat check failed or timed out"
|
||||
failed=1
|
||||
fi
|
||||
if ! check_http; then
|
||||
log_msg "CUPS HTTP check failed or timed out"
|
||||
failed=1
|
||||
fi
|
||||
|
||||
if [ "$failed" = "0" ]; then
|
||||
echo 0 > "$count_file"
|
||||
log_msg "print stack ok"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -f "$count_file" ]; then
|
||||
fail_count="$(cat "$count_file" 2>/dev/null || echo 0)"
|
||||
fi
|
||||
fail_count=$((fail_count + 1))
|
||||
echo "$fail_count" > "$count_file"
|
||||
|
||||
log_msg "print stack failed ($fail_count/$FAIL_THRESHOLD)"
|
||||
if [ "$fail_count" -ge "$FAIL_THRESHOLD" ]; then
|
||||
restart_print_stack
|
||||
echo 0 > "$count_file"
|
||||
fi
|
||||
}
|
||||
|
||||
case "${1:-check}" in
|
||||
check)
|
||||
check_print_stack
|
||||
;;
|
||||
restart)
|
||||
restart_print_stack
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [check|restart]"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user