mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-22 03:04:03 +00:00
feat: add automatic stable update system
- Add systemd timer for daily update checks (2-6 AM window) - Create pulse-auto-update.sh script with safe rollback on failure - Add --enable-auto-updates flag to install script - Prompt users during fresh install to enable auto-updates - Respect autoUpdateEnabled flag in system.json - Only install stable releases, never RCs - Full logging to systemd journal - Tested and verified working in container
This commit is contained in:
+140
-1
@@ -870,6 +870,99 @@ setup_directories() {
|
||||
chmod 700 "$CONFIG_DIR"
|
||||
}
|
||||
|
||||
setup_auto_updates() {
|
||||
print_info "Setting up automatic updates..."
|
||||
|
||||
# Copy auto-update script if it exists in the release
|
||||
if [[ -f "$INSTALL_DIR/scripts/pulse-auto-update.sh" ]]; then
|
||||
cp "$INSTALL_DIR/scripts/pulse-auto-update.sh" /usr/local/bin/pulse-auto-update.sh
|
||||
chmod +x /usr/local/bin/pulse-auto-update.sh
|
||||
else
|
||||
# Download from GitHub if not in release
|
||||
print_info "Downloading auto-update script..."
|
||||
if ! curl -fsSL "https://raw.githubusercontent.com/$GITHUB_REPO/main/scripts/pulse-auto-update.sh" -o /usr/local/bin/pulse-auto-update.sh; then
|
||||
print_error "Failed to download auto-update script"
|
||||
return 1
|
||||
fi
|
||||
chmod +x /usr/local/bin/pulse-auto-update.sh
|
||||
fi
|
||||
|
||||
# Install systemd timer and service
|
||||
cat > /etc/systemd/system/pulse-update.service << 'EOF'
|
||||
[Unit]
|
||||
Description=Automatic Pulse update check and install
|
||||
Documentation=https://github.com/rcourtman/Pulse
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=root
|
||||
Group=root
|
||||
ExecStart=/usr/local/bin/pulse-auto-update.sh
|
||||
Restart=no
|
||||
TimeoutStartSec=600
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=pulse-update
|
||||
PrivateTmp=yes
|
||||
ProtectHome=yes
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/opt/pulse /etc/pulse /tmp
|
||||
PrivateNetwork=no
|
||||
Nice=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat > /etc/systemd/system/pulse-update.timer << 'EOF'
|
||||
[Unit]
|
||||
Description=Daily check for Pulse updates
|
||||
Documentation=https://github.com/rcourtman/Pulse
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Timer]
|
||||
OnCalendar=daily
|
||||
OnCalendar=02:00
|
||||
RandomizedDelaySec=4h
|
||||
Persistent=true
|
||||
AccuracySec=1h
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload >/dev/null 2>&1
|
||||
|
||||
# Enable timer but don't start it yet
|
||||
systemctl enable pulse-update.timer >/dev/null 2>&1
|
||||
|
||||
# Update system.json to enable auto-updates
|
||||
if [[ -f "$CONFIG_DIR/system.json" ]]; then
|
||||
# Update existing file
|
||||
local temp_file="/tmp/system_$$.json"
|
||||
if command -v jq &> /dev/null; then
|
||||
jq '.autoUpdateEnabled = true' "$CONFIG_DIR/system.json" > "$temp_file" && mv "$temp_file" "$CONFIG_DIR/system.json"
|
||||
else
|
||||
# Fallback to sed if jq not available
|
||||
sed -i 's/"pollingInterval"/"autoUpdateEnabled":true,"pollingInterval"/' "$CONFIG_DIR/system.json" 2>/dev/null || \
|
||||
sed -i 's/^{/{"autoUpdateEnabled":true,/' "$CONFIG_DIR/system.json" 2>/dev/null || true
|
||||
fi
|
||||
else
|
||||
# Create new file with auto-updates enabled
|
||||
echo '{"autoUpdateEnabled":true,"pollingInterval":5}' > "$CONFIG_DIR/system.json"
|
||||
fi
|
||||
|
||||
chown pulse:pulse "$CONFIG_DIR/system.json" 2>/dev/null || true
|
||||
|
||||
# Start the timer
|
||||
systemctl start pulse-update.timer >/dev/null 2>&1
|
||||
|
||||
print_success "Automatic updates enabled (daily check with 2-6 hour random delay)"
|
||||
}
|
||||
|
||||
install_systemd_service() {
|
||||
print_info "Installing systemd service..."
|
||||
|
||||
@@ -965,6 +1058,20 @@ print_completion() {
|
||||
echo " Update: curl -sSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash"
|
||||
echo " Reset: curl -sSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash -s -- --reset"
|
||||
echo " Uninstall: curl -sSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash -s -- --uninstall"
|
||||
|
||||
# Show auto-update status if timer exists
|
||||
if systemctl list-unit-files --no-legend | grep -q "^pulse-update.timer"; then
|
||||
echo
|
||||
echo -e "${YELLOW}Auto-updates:${NC}"
|
||||
if systemctl is-enabled --quiet pulse-update.timer 2>/dev/null; then
|
||||
echo " Status: ${GREEN}Enabled${NC} (daily check between 2-6 AM)"
|
||||
echo " Disable: systemctl disable --now pulse-update.timer"
|
||||
else
|
||||
echo " Status: Disabled"
|
||||
echo " Enable: systemctl enable --now pulse-update.timer"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
@@ -1222,7 +1329,7 @@ main() {
|
||||
# This is an update/reinstall, don't prompt for port
|
||||
FRONTEND_PORT=${FRONTEND_PORT:-7655}
|
||||
else
|
||||
# Fresh installation - ask for port configuration
|
||||
# Fresh installation - ask for port configuration and auto-updates
|
||||
FRONTEND_PORT=${FRONTEND_PORT:-}
|
||||
if [[ -z "$FRONTEND_PORT" ]]; then
|
||||
if [[ "$IN_CONTAINER" == "true" ]]; then
|
||||
@@ -1238,6 +1345,17 @@ main() {
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ask about auto-updates for fresh installation (unless forced by flag)
|
||||
if [[ "$ENABLE_AUTO_UPDATES" != "true" ]] && [[ "$IN_CONTAINER" != "true" ]]; then
|
||||
echo
|
||||
echo "Enable automatic updates?"
|
||||
echo "Pulse can automatically install stable updates daily (between 2-6 AM)"
|
||||
safe_read "Enable auto-updates? [y/N]: " enable_updates
|
||||
if [[ "$enable_updates" =~ ^[Yy]$ ]]; then
|
||||
ENABLE_AUTO_UPDATES=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
install_dependencies
|
||||
@@ -1245,6 +1363,12 @@ main() {
|
||||
setup_directories
|
||||
download_pulse
|
||||
install_systemd_service
|
||||
|
||||
# Setup auto-updates if requested
|
||||
if [[ "$ENABLE_AUTO_UPDATES" == "true" ]]; then
|
||||
setup_auto_updates
|
||||
fi
|
||||
|
||||
start_pulse
|
||||
print_completion
|
||||
fi
|
||||
@@ -1271,13 +1395,22 @@ uninstall_pulse() {
|
||||
systemctl disable $SERVICE_NAME
|
||||
fi
|
||||
|
||||
# Stop and disable auto-update timer if it exists
|
||||
if systemctl is-enabled --quiet pulse-update.timer 2>/dev/null; then
|
||||
echo "Disabling auto-update timer..."
|
||||
systemctl disable --now pulse-update.timer
|
||||
fi
|
||||
|
||||
# Remove files
|
||||
echo "Removing Pulse files..."
|
||||
rm -rf /opt/pulse
|
||||
rm -rf /etc/pulse
|
||||
rm -f /etc/systemd/system/pulse.service
|
||||
rm -f /etc/systemd/system/pulse-backend.service
|
||||
rm -f /etc/systemd/system/pulse-update.service
|
||||
rm -f /etc/systemd/system/pulse-update.timer
|
||||
rm -f /usr/local/bin/pulse
|
||||
rm -f /usr/local/bin/pulse-auto-update.sh
|
||||
|
||||
# Remove user (if it exists and isn't being used by other services)
|
||||
if id "pulse" &>/dev/null; then
|
||||
@@ -1327,6 +1460,7 @@ reset_pulse() {
|
||||
FORCE_VERSION=""
|
||||
FORCE_CHANNEL=""
|
||||
IN_CONTAINER=false
|
||||
ENABLE_AUTO_UPDATES=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
@@ -1352,6 +1486,10 @@ while [[ $# -gt 0 ]]; do
|
||||
IN_CONTAINER=true
|
||||
shift
|
||||
;;
|
||||
--enable-auto-updates)
|
||||
ENABLE_AUTO_UPDATES=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
@@ -1359,6 +1497,7 @@ while [[ $# -gt 0 ]]; do
|
||||
echo " --rc, --pre Install latest RC/pre-release version"
|
||||
echo " --stable Install latest stable version (default)"
|
||||
echo " --version VERSION Install specific version (e.g., v4.4.0-rc.1)"
|
||||
echo " --enable-auto-updates Enable automatic stable updates (via systemd timer)"
|
||||
echo ""
|
||||
echo "Management options:"
|
||||
echo " --reset Reset Pulse to fresh configuration"
|
||||
|
||||
Executable
+295
@@ -0,0 +1,295 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Pulse Automatic Update Script
|
||||
# This script checks for and installs stable Pulse updates
|
||||
# It is designed to be run by systemd timer
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
GITHUB_REPO="rcourtman/Pulse"
|
||||
INSTALL_DIR="/opt/pulse"
|
||||
CONFIG_DIR="/etc/pulse"
|
||||
LOG_TAG="pulse-auto-update"
|
||||
MAX_LOG_SIZE=10485760 # 10MB
|
||||
|
||||
# Logging function
|
||||
log() {
|
||||
local level=$1
|
||||
shift
|
||||
logger -t "$LOG_TAG" -p "user.$level" "$@"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $@"
|
||||
}
|
||||
|
||||
# Check if auto-updates are enabled
|
||||
check_auto_updates_enabled() {
|
||||
# Check system.json for autoUpdateEnabled flag (note: no 's' - matches Go struct)
|
||||
if [[ -f "$CONFIG_DIR/system.json" ]]; then
|
||||
local enabled=$(cat "$CONFIG_DIR/system.json" 2>/dev/null | grep -o '"autoUpdateEnabled"[[:space:]]*:[[:space:]]*true' || true)
|
||||
if [[ -z "$enabled" ]]; then
|
||||
log info "Auto-updates disabled in configuration"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Also check if timer is enabled (belt and suspenders)
|
||||
if ! systemctl is-enabled --quiet pulse-update.timer 2>/dev/null; then
|
||||
log info "Auto-update timer is disabled"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Get current version
|
||||
get_current_version() {
|
||||
local version=""
|
||||
|
||||
# Try to get version from binary
|
||||
if [[ -f "$INSTALL_DIR/bin/pulse" ]]; then
|
||||
version=$("$INSTALL_DIR/bin/pulse" --version 2>/dev/null | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9\.]+)?' | head -1 || true)
|
||||
elif [[ -f "$INSTALL_DIR/pulse" ]]; then
|
||||
version=$("$INSTALL_DIR/pulse" --version 2>/dev/null | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9\.]+)?' | head -1 || true)
|
||||
fi
|
||||
|
||||
# Fallback to VERSION file
|
||||
if [[ -z "$version" ]] && [[ -f "$INSTALL_DIR/VERSION" ]]; then
|
||||
version=$(cat "$INSTALL_DIR/VERSION" 2>/dev/null | tr -d '\n' || true)
|
||||
fi
|
||||
|
||||
echo "${version:-unknown}"
|
||||
}
|
||||
|
||||
# Get latest stable release from GitHub
|
||||
get_latest_stable_version() {
|
||||
local latest_version=""
|
||||
|
||||
# Get latest stable release (not pre-releases)
|
||||
latest_version=$(curl -s "https://api.github.com/repos/$GITHUB_REPO/releases/latest" | \
|
||||
grep '"tag_name":' | \
|
||||
sed -E 's/.*"([^"]+)".*/\1/' || true)
|
||||
|
||||
# Check if we got rate limited or failed
|
||||
if [[ -z "$latest_version" ]] || [[ "$latest_version" == *"rate limit"* ]]; then
|
||||
# Try direct GitHub latest URL as fallback
|
||||
latest_version=$(curl -sI "https://github.com/$GITHUB_REPO/releases/latest" | \
|
||||
grep -i '^location:' | \
|
||||
sed -E 's|.*tag/([^[:space:]]+).*|\1|' | \
|
||||
tr -d '\r' || true)
|
||||
fi
|
||||
|
||||
echo "${latest_version:-}"
|
||||
}
|
||||
|
||||
# Compare versions (returns 0 if v1 > v2, 1 if v1 <= v2)
|
||||
version_greater_than() {
|
||||
local v1="${1#v}" # Remove 'v' prefix
|
||||
local v2="${2#v}"
|
||||
|
||||
# Don't update if current version is unknown
|
||||
if [[ "$2" == "unknown" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Split versions into parts
|
||||
IFS='.' read -ra V1_PARTS <<< "${v1%%-*}" # Remove pre-release suffix
|
||||
IFS='.' read -ra V2_PARTS <<< "${v2%%-*}"
|
||||
|
||||
# Compare major.minor.patch
|
||||
for i in 0 1 2; do
|
||||
local p1="${V1_PARTS[$i]:-0}"
|
||||
local p2="${V2_PARTS[$i]:-0}"
|
||||
if [[ "$p1" -gt "$p2" ]]; then
|
||||
return 0
|
||||
elif [[ "$p1" -lt "$p2" ]]; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Versions are equal in major.minor.patch
|
||||
# Now check pre-release suffixes
|
||||
local has_suffix1=false
|
||||
local has_suffix2=false
|
||||
|
||||
[[ "$v1" == *-* ]] && has_suffix1=true
|
||||
[[ "$v2" == *-* ]] && has_suffix2=true
|
||||
|
||||
# Stable (no suffix) > pre-release (has suffix)
|
||||
if [[ "$has_suffix1" == "false" ]] && [[ "$has_suffix2" == "true" ]]; then
|
||||
return 0 # v1 (stable) > v2 (pre-release)
|
||||
elif [[ "$has_suffix1" == "true" ]] && [[ "$has_suffix2" == "false" ]]; then
|
||||
return 1 # v1 (pre-release) < v2 (stable)
|
||||
elif [[ "$has_suffix1" == "true" ]] && [[ "$has_suffix2" == "true" ]]; then
|
||||
# Both are pre-releases, compare suffixes lexicographically
|
||||
local suffix1="${v1#*-}"
|
||||
local suffix2="${v2#*-}"
|
||||
if [[ "$suffix1" > "$suffix2" ]]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1 # v1 <= v2
|
||||
}
|
||||
|
||||
# Detect service name (could be pulse or pulse-backend)
|
||||
detect_service_name() {
|
||||
if systemctl list-unit-files --no-legend | grep -q "^pulse-backend.service"; then
|
||||
echo "pulse-backend"
|
||||
elif systemctl list-unit-files --no-legend | grep -q "^pulse.service"; then
|
||||
echo "pulse"
|
||||
else
|
||||
echo "pulse" # Default
|
||||
fi
|
||||
}
|
||||
|
||||
# Perform the update
|
||||
perform_update() {
|
||||
local new_version=$1
|
||||
local service_name=$(detect_service_name)
|
||||
|
||||
log info "Starting update to $new_version"
|
||||
|
||||
# Create backup of current installation
|
||||
local backup_dir="/tmp/pulse-backup-$(date +%Y%m%d-%H%M%S)"
|
||||
log info "Creating backup in $backup_dir"
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
# Backup binary
|
||||
if [[ -f "$INSTALL_DIR/bin/pulse" ]]; then
|
||||
cp -a "$INSTALL_DIR/bin/pulse" "$backup_dir/" || true
|
||||
elif [[ -f "$INSTALL_DIR/pulse" ]]; then
|
||||
cp -a "$INSTALL_DIR/pulse" "$backup_dir/" || true
|
||||
fi
|
||||
|
||||
# Backup VERSION file
|
||||
if [[ -f "$INSTALL_DIR/VERSION" ]]; then
|
||||
cp -a "$INSTALL_DIR/VERSION" "$backup_dir/" || true
|
||||
fi
|
||||
|
||||
# Download update using install script (safest method)
|
||||
log info "Downloading and installing update"
|
||||
|
||||
# Run install script with specific version
|
||||
if curl -sSL "https://raw.githubusercontent.com/$GITHUB_REPO/main/install.sh" | \
|
||||
bash -s -- --version "$new_version" 2>&1 | \
|
||||
while IFS= read -r line; do
|
||||
log info "installer: $line"
|
||||
done; then
|
||||
|
||||
log info "Update successfully installed"
|
||||
|
||||
# Verify new version
|
||||
local installed_version=$(get_current_version)
|
||||
if [[ "$installed_version" == "$new_version" ]]; then
|
||||
log info "Version verified: $installed_version"
|
||||
|
||||
# Clean up backup
|
||||
rm -rf "$backup_dir"
|
||||
|
||||
return 0
|
||||
else
|
||||
log error "Version mismatch after update. Expected: $new_version, Got: $installed_version"
|
||||
|
||||
# Restore from backup
|
||||
log info "Restoring from backup"
|
||||
if [[ -f "$backup_dir/pulse" ]]; then
|
||||
if [[ -f "$INSTALL_DIR/bin/pulse" ]]; then
|
||||
cp -f "$backup_dir/pulse" "$INSTALL_DIR/bin/pulse"
|
||||
else
|
||||
cp -f "$backup_dir/pulse" "$INSTALL_DIR/pulse"
|
||||
fi
|
||||
fi
|
||||
if [[ -f "$backup_dir/VERSION" ]]; then
|
||||
cp -f "$backup_dir/VERSION" "$INSTALL_DIR/VERSION"
|
||||
fi
|
||||
|
||||
# Restart service with old version
|
||||
systemctl restart "$service_name" || true
|
||||
|
||||
# Clean up backup
|
||||
rm -rf "$backup_dir"
|
||||
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log error "Update installation failed"
|
||||
|
||||
# Restore from backup
|
||||
log info "Restoring from backup"
|
||||
if [[ -f "$backup_dir/pulse" ]]; then
|
||||
if [[ -f "$INSTALL_DIR/bin/pulse" ]]; then
|
||||
cp -f "$backup_dir/pulse" "$INSTALL_DIR/bin/pulse"
|
||||
else
|
||||
cp -f "$backup_dir/pulse" "$INSTALL_DIR/pulse"
|
||||
fi
|
||||
fi
|
||||
if [[ -f "$backup_dir/VERSION" ]]; then
|
||||
cp -f "$backup_dir/VERSION" "$INSTALL_DIR/VERSION"
|
||||
fi
|
||||
|
||||
# Clean up backup
|
||||
rm -rf "$backup_dir"
|
||||
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main update check
|
||||
main() {
|
||||
log info "Starting Pulse auto-update check"
|
||||
|
||||
# Check if auto-updates are enabled
|
||||
check_auto_updates_enabled
|
||||
|
||||
# Check if we're in Docker (updates not supported)
|
||||
if [[ -f /.dockerenv ]] || grep -q docker /proc/1/cgroup 2>/dev/null; then
|
||||
log info "Docker environment detected, skipping auto-update"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get current version
|
||||
local current_version=$(get_current_version)
|
||||
log info "Current version: $current_version"
|
||||
|
||||
if [[ "$current_version" == "unknown" ]]; then
|
||||
log error "Could not determine current version, skipping update"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get latest stable version
|
||||
local latest_version=$(get_latest_stable_version)
|
||||
|
||||
if [[ -z "$latest_version" ]]; then
|
||||
log error "Could not determine latest version from GitHub"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log info "Latest stable version: $latest_version"
|
||||
|
||||
# Compare versions
|
||||
if version_greater_than "$latest_version" "$current_version"; then
|
||||
log info "New version available: $latest_version (current: $current_version)"
|
||||
|
||||
# Perform update
|
||||
if perform_update "$latest_version"; then
|
||||
log info "Update completed successfully to $latest_version"
|
||||
|
||||
# Send notification if webhooks are configured
|
||||
if [[ -f "$CONFIG_DIR/webhooks.enc" ]] || [[ -f "$CONFIG_DIR/webhooks.json" ]]; then
|
||||
# Create a simple notification via the Pulse API
|
||||
curl -s -X POST "http://localhost:7655/api/internal/notification" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"type\":\"update\",\"message\":\"Pulse automatically updated from $current_version to $latest_version\"}" \
|
||||
2>/dev/null || true
|
||||
fi
|
||||
else
|
||||
log error "Update failed"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log info "Already running latest version"
|
||||
fi
|
||||
|
||||
log info "Auto-update check completed"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
@@ -0,0 +1,35 @@
|
||||
[Unit]
|
||||
Description=Automatic Pulse update check and install
|
||||
Documentation=https://github.com/rcourtman/Pulse
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
# Don't run if pulse service is not running
|
||||
Requisite=pulse.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# Run as root to allow service restart
|
||||
User=root
|
||||
Group=root
|
||||
# Use the update script
|
||||
ExecStart=/opt/pulse/scripts/pulse-auto-update.sh
|
||||
# Restart policy for the update service itself
|
||||
Restart=no
|
||||
# Timeout for the update process (10 minutes should be plenty)
|
||||
TimeoutStartSec=600
|
||||
# Log to journal
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=pulse-update
|
||||
# Security hardening
|
||||
PrivateTmp=yes
|
||||
ProtectHome=yes
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/opt/pulse /etc/pulse /tmp
|
||||
# Network access needed for GitHub
|
||||
PrivateNetwork=no
|
||||
# Nice level to run updates at lower priority
|
||||
Nice=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=Daily check for Pulse updates
|
||||
Documentation=https://github.com/rcourtman/Pulse
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Timer]
|
||||
# Run daily at 2 AM with a random delay up to 4 hours
|
||||
# This spreads the load on GitHub and prevents all instances updating at once
|
||||
OnCalendar=daily
|
||||
OnCalendar=02:00
|
||||
RandomizedDelaySec=4h
|
||||
# Persist the last trigger time during downtime
|
||||
Persistent=true
|
||||
# Ensure we run if the system was off when scheduled
|
||||
AccuracySec=1h
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Reference in New Issue
Block a user