Compare commits
23 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a5535f945 | ||
|
|
0281c9d13c | ||
|
|
08eeb039b4 | ||
|
|
8401028756 | ||
|
|
2eebd5a104 | ||
|
|
e7b07682b3 | ||
|
|
2c58db376a | ||
| 340ceeef6b | |||
| 2cfabb93e2 | |||
| 80a118c07b | |||
| dddd4352f0 | |||
| 36c68a7067 | |||
| d3fd0f5cb1 | |||
| 4dfe48fa1b | |||
| 7e6230aa12 | |||
| 65afd0cdae | |||
| bd9f96f3a9 | |||
| 2a0053dee5 | |||
| 61f246bb25 | |||
| f62e31de62 | |||
| 0c6d4263d4 | |||
| 279c6ade30 | |||
| ab945b1caf |
13 changed files with 677 additions and 159 deletions
65
CHANGELOG.md
Normal file
65
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
---
|
||||
|
||||
## [0.4.0] - 2026-03-18
|
||||
|
||||
### Added
|
||||
|
||||
* Structured logging system with timestamps
|
||||
* Log levels: INFO, OK, ERR
|
||||
* Central log file: `/opt/update-manager/log/update-manager.log`
|
||||
* Log submenu in UI
|
||||
* Log viewing options:
|
||||
|
||||
* Full log
|
||||
* Live log (tail -f)
|
||||
* Last 20 lines
|
||||
* Log file location
|
||||
|
||||
### Changed
|
||||
|
||||
* Refactored UI to group log features into submenu
|
||||
* Improved menu structure and usability
|
||||
|
||||
### Improved
|
||||
|
||||
* Better error visibility for SSH failures
|
||||
* Consistent output across hosts
|
||||
* README updated with UI screenshots and logging documentation
|
||||
|
||||
---
|
||||
|
||||
## [0.3.0] - 2026-03-18
|
||||
|
||||
### Added
|
||||
|
||||
* CLI menu (`update-manager-ui.sh`)
|
||||
* Interactive host management
|
||||
* Dialog-based UI navigation
|
||||
|
||||
### Changed
|
||||
|
||||
* Project renamed from `lanx-update` to `update-manager`
|
||||
* Moved runtime files to `/opt/update-manager`
|
||||
|
||||
---
|
||||
|
||||
## [0.2.0] - 2026-03-18
|
||||
|
||||
### Added
|
||||
|
||||
* SSH-based update checking across multiple hosts
|
||||
* Support for `hosts.conf`
|
||||
* Config file support (`/etc/update-manager.conf`)
|
||||
|
||||
---
|
||||
|
||||
## [0.1.0] - 2026-03-17
|
||||
|
||||
### Added
|
||||
|
||||
* Initial version
|
||||
* Basic apt update check functionality
|
||||
85
README.md
85
README.md
|
|
@ -1,4 +1,7 @@
|
|||
# 🖥️ Update Manager
|
||||
<p align="center">
|
||||
<img src="images/updatemanager-logo.png" width="600">
|
||||
</p>
|
||||
|
||||
|
||||
Simple CLI tool to check and manage updates across multiple Ubuntu systems over SSH.
|
||||
|
||||
|
|
@ -26,10 +29,10 @@ Built for Lanx environments – lightweight, fast and no unnecessary dependencie
|
|||
## Features
|
||||
|
||||
* Check updates on multiple hosts
|
||||
* Run checks remotely over SSH
|
||||
* Run updates remotely over SSH
|
||||
* Interactive CLI menu (dialog-based UI)
|
||||
* Centralized logging
|
||||
* Simple config files
|
||||
* Built-in logging (file + terminal)
|
||||
* Dialog-based UI menu
|
||||
* No agents required
|
||||
* Works with existing SSH setup
|
||||
|
||||
|
|
@ -37,12 +40,20 @@ Built for Lanx environments – lightweight, fast and no unnecessary dependencie
|
|||
|
||||
## Update Manager UI
|
||||
|
||||
### Main menu
|
||||
|
||||
<p align="center">
|
||||
<img src="update-manager-ui.png" width="50%" alt="Update Manager CLI UI">
|
||||
<img src="docs/images/menu-main.png" width="50%" alt="Main menu">
|
||||
</p>
|
||||
|
||||
### Log menu
|
||||
|
||||
<p align="center">
|
||||
<img src="docs/images/menu-logs.png" width="50%" alt="Log menu">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<em>Lightweight • Terminal-based • Works over SSH</em>
|
||||
<em>Lightweight • No dependencies • Works over SSH</em>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
|
@ -57,7 +68,7 @@ sudo apt update
|
|||
sudo apt install dialog openssh-client
|
||||
|
||||
sudo mkdir -p /opt/update-manager
|
||||
sudo cp update-manager.sh update-manager-ui.sh /opt/update-manager/
|
||||
sudo cp update-manager.sh update-manager-ui.sh dialogrc /opt/update-manager/
|
||||
|
||||
sudo chmod +x /opt/update-manager/update-manager.sh
|
||||
sudo chmod +x /opt/update-manager/update-manager-ui.sh
|
||||
|
|
@ -134,6 +145,12 @@ server3 192.168.1.30 user
|
|||
|
||||
## Usage
|
||||
|
||||
### Check updates
|
||||
|
||||
```bash
|
||||
update-manager check
|
||||
```
|
||||
|
||||
### Start UI
|
||||
|
||||
```bash
|
||||
|
|
@ -142,42 +159,25 @@ update-manager-ui
|
|||
|
||||
---
|
||||
|
||||
### Check updates (CLI)
|
||||
|
||||
```bash
|
||||
update-manager check
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Logging
|
||||
|
||||
The tool logs both to terminal and file.
|
||||
|
||||
### Primary location
|
||||
Log file location:
|
||||
|
||||
```bash
|
||||
/opt/update-manager/log/update-manager.log
|
||||
```
|
||||
|
||||
### Fallback location
|
||||
View log:
|
||||
|
||||
```bash
|
||||
~/update-manager/log/update-manager.log
|
||||
less /opt/update-manager/log/update-manager.log
|
||||
```
|
||||
|
||||
### Notes
|
||||
Follow log:
|
||||
|
||||
* Log directory is created automatically
|
||||
* Log file is created automatically
|
||||
* Output is written to both terminal and file
|
||||
* Log levels:
|
||||
|
||||
* INFO
|
||||
* WARN
|
||||
* ERROR
|
||||
|
||||
Logs can be viewed directly from the UI.
|
||||
```bash
|
||||
tail -f /opt/update-manager/log/update-manager.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -189,8 +189,8 @@ Logs can be viewed directly from the UI.
|
|||
├── update-manager-ui.sh
|
||||
├── update-manager.conf
|
||||
├── hosts.conf
|
||||
└── log/
|
||||
└── update-manager.log
|
||||
├── log/
|
||||
│ └── update-manager.log
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -199,6 +199,7 @@ Logs can be viewed directly from the UI.
|
|||
|
||||
* Uses SSH to connect to each host
|
||||
* Runs `apt` commands remotely
|
||||
* Logs results locally
|
||||
* No agents or services needed
|
||||
* Designed for simple and efficient operations
|
||||
|
||||
|
|
@ -209,7 +210,6 @@ Logs can be viewed directly from the UI.
|
|||
* SSH access to all hosts
|
||||
* SSH keys recommended (no password prompts)
|
||||
* Ubuntu/Debian-based systems
|
||||
* `dialog` (for UI)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -218,7 +218,6 @@ Logs can be viewed directly from the UI.
|
|||
* 🔔 Notifications (ntfy / push alerts)
|
||||
* 🌐 Web interface
|
||||
* 📧 Email reporting
|
||||
* 📜 Advanced logging / audit trail
|
||||
* 📊 Basic monitoring (status, last check, pending updates)
|
||||
* 🧩 Plugin system (extensible modules)
|
||||
* 🔐 Security & compliance checks
|
||||
|
|
@ -226,6 +225,15 @@ Logs can be viewed directly from the UI.
|
|||
|
||||
---
|
||||
|
||||
## ❤️ Credits
|
||||
|
||||
Built with ❤️ for Lanx by [NodeFox 🦊](https://nodefox.lanx.dk)
|
||||
Maintained by [Eddie Nielsen](https://lanx.dk)
|
||||
|
||||
> Learn. Adopt. Survive. Share.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the GNU GPL v3 License.
|
||||
|
|
@ -233,10 +241,3 @@ This project is licensed under the GNU GPL v3 License.
|
|||
See the LICENSE file for full details.
|
||||
|
||||
---
|
||||
|
||||
## Author
|
||||
|
||||
Built with ❤️ for [Lanx](https://lanx.dk) by **NodeFox** 🦊
|
||||
|
||||
Maintained by Eddie Nielsen
|
||||
Feel free to contribute, suggest improvements or fork the project.
|
||||
|
|
|
|||
32
dialogrc
Normal file
32
dialogrc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
use_shadow = OFF
|
||||
use_colors = ON
|
||||
|
||||
screen_color = (WHITE,BLUE,OFF)
|
||||
dialog_color = (WHITE,BLUE,OFF)
|
||||
title_color = (YELLOW,BLUE,ON)
|
||||
border_color = (WHITE,BLUE,OFF)
|
||||
|
||||
button_active_color = (BLACK,WHITE,ON)
|
||||
button_inactive_color = (WHITE,BLUE,OFF)
|
||||
|
||||
button_key_active_color = (BLACK,WHITE,ON)
|
||||
button_key_inactive_color = (WHITE,BLUE,OFF)
|
||||
|
||||
button_label_active_color = (BLACK,WHITE,ON)
|
||||
button_label_inactive_color = (WHITE,BLUE,OFF)
|
||||
|
||||
menubox_color = (WHITE,BLUE,OFF)
|
||||
menubox_border_color = (WHITE,BLUE,OFF)
|
||||
|
||||
item_color = (WHITE,BLUE,OFF)
|
||||
item_selected_color = (BLACK,WHITE,ON)
|
||||
|
||||
tag_color = (WHITE,BLUE,OFF)
|
||||
tag_selected_color = (BLACK,WHITE,ON)
|
||||
|
||||
tag_key_color = (YELLOW,BLUE,OFF)
|
||||
tag_key_selected_color = (BLACK,WHITE,ON)
|
||||
|
||||
position_indicator_color = (WHITE,BLUE,OFF)
|
||||
uarrow_color = (WHITE,BLUE,OFF)
|
||||
darrow_color = (WHITE,BLUE,OFF)
|
||||
211
docs/architecture.md
Normal file
211
docs/architecture.md
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
<p align="center">
|
||||
<img src="images/architecture-diagram.png" width="50%" alt="Architecture Diagram">
|
||||
</p>
|
||||
|
||||
# 🧠 Update Manager Architecture
|
||||
|
||||
This document describes how Update Manager is structured internally and how data flows through the system.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Update Manager is a lightweight, SSH-based system for managing updates across multiple Linux hosts.
|
||||
|
||||
It consists of two main layers:
|
||||
|
||||
* **UI layer** – interactive menu (`update-manager-ui.sh`)
|
||||
* **Core engine** – update logic (`update-manager.sh`)
|
||||
|
||||
The system is designed to be simple, transparent, and dependency-light.
|
||||
|
||||
---
|
||||
|
||||
## High-Level Flow
|
||||
|
||||
```text
|
||||
User
|
||||
↓
|
||||
UI (update-manager-ui.sh)
|
||||
↓
|
||||
Core (update-manager.sh)
|
||||
↓
|
||||
SSH → Remote Hosts
|
||||
↓
|
||||
Results
|
||||
↓
|
||||
Logging (/opt/update-manager/log)
|
||||
↓
|
||||
UI / User
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Components
|
||||
|
||||
### UI Layer (`update-manager-ui.sh`)
|
||||
|
||||
Responsible for:
|
||||
|
||||
* Displaying menu (via `dialog`)
|
||||
* Handling user input
|
||||
* Managing hosts (add/remove/edit)
|
||||
* Providing access to logs
|
||||
* Delegating actions to core engine
|
||||
|
||||
The UI does **not perform updates directly**.
|
||||
|
||||
---
|
||||
|
||||
### Core Engine (`update-manager.sh`)
|
||||
|
||||
Responsible for:
|
||||
|
||||
* Reading configuration
|
||||
* Parsing hosts file
|
||||
* Executing SSH commands
|
||||
* Checking for updates (`apt list --upgradable`)
|
||||
* Handling connection errors
|
||||
* Writing structured logs
|
||||
|
||||
This is the **execution layer** of the system.
|
||||
|
||||
---
|
||||
|
||||
### Hosts Configuration
|
||||
|
||||
File:
|
||||
|
||||
```bash
|
||||
/opt/update-manager/hosts.conf
|
||||
```
|
||||
|
||||
Format:
|
||||
|
||||
```text
|
||||
name ip user
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
server1 192.168.1.10 user
|
||||
server2 192.168.1.20 user
|
||||
server3 192.168.1.30 user
|
||||
```
|
||||
|
||||
Each line represents a target system accessed via SSH.
|
||||
|
||||
---
|
||||
|
||||
### Logging System
|
||||
|
||||
Log file:
|
||||
|
||||
```bash
|
||||
/opt/update-manager/log/update-manager.log
|
||||
```
|
||||
|
||||
Log format:
|
||||
|
||||
```text
|
||||
YYYY-MM-DD HH:MM:SS [LEVEL] host - message
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
2026-03-18 20:45:01 [INFO] lanx-www - Checking updates
|
||||
2026-03-18 20:45:03 [OK] lanx-www - 3 updates available
|
||||
2026-03-18 20:45:05 [ERR] lanx-db - Connection failed
|
||||
```
|
||||
|
||||
#### Log Levels
|
||||
|
||||
* `INFO` – informational messages
|
||||
* `OK` – successful operations
|
||||
* `ERR` – errors or failures
|
||||
|
||||
Logging is centralized and written locally.
|
||||
|
||||
---
|
||||
|
||||
## Execution Flow
|
||||
|
||||
For each host:
|
||||
|
||||
1. Read host entry from `hosts.conf`
|
||||
2. Establish SSH connection
|
||||
3. Execute:
|
||||
|
||||
```bash
|
||||
apt list --upgradable
|
||||
```
|
||||
|
||||
4. Parse output
|
||||
5. Determine:
|
||||
|
||||
* Up-to-date
|
||||
* Updates available
|
||||
* Connection failure
|
||||
6. Write result to:
|
||||
|
||||
* terminal output
|
||||
* log file
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
Primary config:
|
||||
|
||||
```bash
|
||||
/etc/update-manager.conf
|
||||
```
|
||||
|
||||
Fallback:
|
||||
|
||||
```bash
|
||||
./update-manager.conf
|
||||
```
|
||||
|
||||
Supported options:
|
||||
|
||||
* `HOSTS_FILE`
|
||||
* `SSH_OPTIONS`
|
||||
|
||||
---
|
||||
|
||||
## Design Principles
|
||||
|
||||
* **No agents** – uses standard SSH only
|
||||
* **Simple over complex** – minimal dependencies
|
||||
* **Transparent behavior** – everything is visible/logged
|
||||
* **CLI-first** – designed for terminal environments
|
||||
* **Modular growth** – prepared for future extensions
|
||||
|
||||
---
|
||||
|
||||
## Future Architecture Direction
|
||||
|
||||
Planned extensions:
|
||||
|
||||
* Plugin system (modular features)
|
||||
* Web interface (optional UI layer)
|
||||
* Notification system (alerts)
|
||||
* Metrics / monitoring
|
||||
* Integration with Lanx AI
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Update Manager follows a clean separation:
|
||||
|
||||
* UI = interaction
|
||||
* Core = execution
|
||||
* Config = data
|
||||
* Log = output
|
||||
|
||||
This keeps the system predictable, debuggable, and easy to extend.
|
||||
|
||||
BIN
docs/images/architecture-diagram.png
Normal file
BIN
docs/images/architecture-diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 561 KiB |
BIN
docs/images/menu-logs.png
Normal file
BIN
docs/images/menu-logs.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
docs/images/menu-main.png
Normal file
BIN
docs/images/menu-main.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/images/update-manager-ui.png
Normal file
BIN
docs/images/update-manager-ui.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
BIN
images/updatemanager-logo.png
Normal file
BIN
images/updatemanager-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 196 KiB |
117
log/update-manager.sh
Normal file
117
log/update-manager.sh
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
UPDATE_MANAGER_SCRIPT="/opt/update-manager/update-manager.sh"
|
||||
|
||||
get_log_file() {
|
||||
local primary="/opt/update-manager/log/update-manager.log"
|
||||
local fallback="$HOME/update-manager/log/update-manager.log"
|
||||
|
||||
if [[ -f "$primary" ]]; then
|
||||
echo "$primary"
|
||||
else
|
||||
echo "$fallback"
|
||||
fi
|
||||
}
|
||||
|
||||
run_check() {
|
||||
echo
|
||||
bash "$UPDATE_MANAGER_SCRIPT" check
|
||||
echo
|
||||
read -rp "Press Enter to continue..."
|
||||
}
|
||||
|
||||
view_log() {
|
||||
local log_file
|
||||
log_file="$(get_log_file)"
|
||||
|
||||
echo
|
||||
if [[ -f "$log_file" ]]; then
|
||||
less "$log_file"
|
||||
else
|
||||
echo "Log file not found: $log_file"
|
||||
echo
|
||||
read -rp "Press Enter to continue..."
|
||||
fi
|
||||
}
|
||||
|
||||
follow_log() {
|
||||
local log_file
|
||||
log_file="$(get_log_file)"
|
||||
|
||||
echo
|
||||
if [[ -f "$log_file" ]]; then
|
||||
echo "Following log: $log_file"
|
||||
echo "Press Ctrl+C to stop."
|
||||
echo
|
||||
tail -f "$log_file"
|
||||
else
|
||||
echo "Log file not found: $log_file"
|
||||
fi
|
||||
|
||||
echo
|
||||
read -rp "Press Enter to continue..."
|
||||
}
|
||||
|
||||
show_log_location() {
|
||||
local log_file
|
||||
log_file="$(get_log_file)"
|
||||
|
||||
echo
|
||||
echo "Log file location:"
|
||||
echo "$log_file"
|
||||
echo
|
||||
read -rp "Press Enter to continue..."
|
||||
}
|
||||
|
||||
show_menu() {
|
||||
clear
|
||||
echo "=================================="
|
||||
echo " Update Manager UI"
|
||||
echo "=================================="
|
||||
echo
|
||||
echo "1) Run update check"
|
||||
echo "2) View full log"
|
||||
echo "3) Follow log live"
|
||||
echo "4) Show log location"
|
||||
echo "0) Exit"
|
||||
echo
|
||||
}
|
||||
|
||||
main() {
|
||||
if [[ ! -f "$UPDATE_MANAGER_SCRIPT" ]]; then
|
||||
echo "Update manager script not found: $UPDATE_MANAGER_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while true; do
|
||||
show_menu
|
||||
read -rp "Choose an option: " choice
|
||||
|
||||
case "$choice" in
|
||||
1)
|
||||
run_check
|
||||
;;
|
||||
2)
|
||||
view_log
|
||||
;;
|
||||
3)
|
||||
follow_log
|
||||
;;
|
||||
4)
|
||||
show_log_location
|
||||
;;
|
||||
0)
|
||||
echo
|
||||
echo "Bye."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo
|
||||
echo "Invalid choice."
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 409 KiB |
140
update-manager-ui.sh
Executable file
140
update-manager-ui.sh
Executable file
|
|
@ -0,0 +1,140 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
export DIALOGRC="/opt/update-manager/dialogrc"
|
||||
|
||||
UPDATE_MANAGER_SCRIPT="$HOME/update-manager/update-manager.sh"
|
||||
HOSTS_FILE="/opt/update-manager/hosts.conf"
|
||||
|
||||
get_log_file() {
|
||||
local primary="/opt/update-manager/log/update-manager.log"
|
||||
local fallback="$HOME/update-manager/log/update-manager.log"
|
||||
|
||||
if [[ -f "$primary" ]]; then
|
||||
echo "$primary"
|
||||
elif [[ -f "$fallback" ]]; then
|
||||
echo "$fallback"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
show_log_menu() {
|
||||
while true; do
|
||||
log_choice=$(dialog --clear \
|
||||
--backtitle "Update Manager" \
|
||||
--title "Log menu" \
|
||||
--menu "Select log action:" 18 60 10 \
|
||||
1 "View full log" \
|
||||
2 "Follow log live" \
|
||||
3 "Show log location" \
|
||||
4 "Show last 20 log lines" \
|
||||
0 "Back" \
|
||||
3>&1 1>&2 2>&3)
|
||||
|
||||
clear
|
||||
|
||||
case "$log_choice" in
|
||||
1)
|
||||
log_file="$(get_log_file)"
|
||||
if [[ -n "$log_file" ]]; then
|
||||
less "$log_file"
|
||||
else
|
||||
echo "No log file found yet."
|
||||
read -rp "Press Enter to continue..."
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
log_file="$(get_log_file)"
|
||||
if [[ -n "$log_file" ]]; then
|
||||
echo "Press Ctrl+C to stop"
|
||||
tail -n 20 -f "$log_file"
|
||||
else
|
||||
echo "No log file found yet."
|
||||
fi
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
3)
|
||||
log_file="$(get_log_file)"
|
||||
if [[ -n "$log_file" ]]; then
|
||||
echo "Log file:"
|
||||
echo "$log_file"
|
||||
else
|
||||
echo "No log file found yet."
|
||||
fi
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
4)
|
||||
log_file="$(get_log_file)"
|
||||
if [[ -n "$log_file" ]]; then
|
||||
tail -n 20 "$log_file"
|
||||
else
|
||||
echo "No log file found yet."
|
||||
fi
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
0|"")
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
while true; do
|
||||
choice=$(dialog --clear \
|
||||
--backtitle "Update Manager" \
|
||||
--title "Choose an action" \
|
||||
--menu "Select option:" 20 60 10 \
|
||||
1 "Check all hosts" \
|
||||
2 "View hosts file" \
|
||||
3 "Edit hosts file" \
|
||||
4 "Add host" \
|
||||
5 "Remove host" \
|
||||
6 "Log menu" \
|
||||
0 "Exit" \
|
||||
3>&1 1>&2 2>&3)
|
||||
|
||||
clear
|
||||
|
||||
case "$choice" in
|
||||
1)
|
||||
bash "$UPDATE_MANAGER_SCRIPT" check
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
2)
|
||||
less "$HOSTS_FILE"
|
||||
;;
|
||||
3)
|
||||
nano "$HOSTS_FILE"
|
||||
;;
|
||||
4)
|
||||
read -rp "Name: " name
|
||||
read -rp "IP: " ip
|
||||
read -rp "User: " user
|
||||
if [[ -z "$name" || -z "$ip" || -z "$user" ]]; then
|
||||
echo "All fields are required."
|
||||
else
|
||||
echo "$name $ip $user" >> "$HOSTS_FILE"
|
||||
echo "Host added."
|
||||
fi
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
5)
|
||||
nl -w2 -s'. ' "$HOSTS_FILE"
|
||||
read -rp "Line to remove: " line
|
||||
if [[ "$line" =~ ^[0-9]+$ ]]; then
|
||||
sed -i "${line}d" "$HOSTS_FILE"
|
||||
echo "Host removed."
|
||||
else
|
||||
echo "Invalid line number."
|
||||
fi
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
6)
|
||||
show_log_menu
|
||||
;;
|
||||
0|"")
|
||||
clear
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
|
@ -1,127 +1,79 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
CONFIG_FILE="/etc/update-manager.conf"
|
||||
[[ -f "$CONFIG_FILE" ]] || CONFIG_FILE="./update-manager.conf"
|
||||
UPDATE_MANAGER_SCRIPT="$HOME/update-manager/update-manager.sh"
|
||||
HOSTS_FILE="/opt/update-manager/hosts.conf"
|
||||
|
||||
if [[ -f "$CONFIG_FILE" ]]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "$CONFIG_FILE"
|
||||
fi
|
||||
get_log_file() {
|
||||
local primary="/opt/update-manager/log/update-manager.log"
|
||||
local fallback="$HOME/update-manager/log/update-manager.log"
|
||||
|
||||
DEFAULT_HOSTS_FILE="${HOSTS_FILE:-/opt/update-manager/hosts.conf}"
|
||||
SSH_OPTIONS="${SSH_OPTIONS:--o BatchMode=yes -o ConnectTimeout=5}"
|
||||
|
||||
########################################
|
||||
# Ensure hosts file exists
|
||||
########################################
|
||||
|
||||
ensure_hosts_file() {
|
||||
if [[ ! -f "$DEFAULT_HOSTS_FILE" ]]; then
|
||||
echo "Creating example hosts file: $DEFAULT_HOSTS_FILE"
|
||||
|
||||
mkdir -p "$(dirname "$DEFAULT_HOSTS_FILE")"
|
||||
|
||||
cat > "$DEFAULT_HOSTS_FILE" <<'EOF'
|
||||
# Example hosts file
|
||||
# Format:
|
||||
# name ip user
|
||||
#
|
||||
# server1 192.168.1.10 user
|
||||
# server2 192.168.1.20 user
|
||||
# server3 10.0.0.5 root
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
########################################
|
||||
# Helpers
|
||||
########################################
|
||||
|
||||
get_hosts_file() {
|
||||
if [[ -n "$2" ]]; then
|
||||
echo "$2"
|
||||
if [[ -f "$primary" ]]; then
|
||||
echo "$primary"
|
||||
else
|
||||
echo "$DEFAULT_HOSTS_FILE"
|
||||
echo "$fallback"
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<USAGE
|
||||
Usage:
|
||||
$0 check [hosts_file]
|
||||
while true; do
|
||||
choice=$(dialog --clear \
|
||||
--backtitle "Update Manager" \
|
||||
--title "Choose an action" \
|
||||
--menu "Select option:" 15 50 10 \
|
||||
1 "Check all hosts" \
|
||||
2 "View hosts file" \
|
||||
3 "Edit hosts file" \
|
||||
4 "Add host" \
|
||||
5 "Remove host" \
|
||||
6 "View log" \
|
||||
7 "Follow log live" \
|
||||
8 "Show log location" \
|
||||
0 "Exit" \
|
||||
3>&1 1>&2 2>&3)
|
||||
|
||||
Examples:
|
||||
$0 check
|
||||
$0 check /path/to/hosts.conf
|
||||
HOSTS_FILE=/path/to/hosts.conf $0 check
|
||||
USAGE
|
||||
}
|
||||
clear
|
||||
|
||||
########################################
|
||||
# Check single host
|
||||
########################################
|
||||
|
||||
check_host() {
|
||||
local name="$1"
|
||||
local ip="$2"
|
||||
local user="$3"
|
||||
local result
|
||||
local rc
|
||||
|
||||
result=$(ssh -n $SSH_OPTIONS "${user}@${ip}" \
|
||||
"apt list --upgradable 2>/dev/null | sed '/^Listing/d'" 2>&1)
|
||||
rc=$?
|
||||
|
||||
printf "===== %s (%s) =====\n" "$name" "$ip"
|
||||
|
||||
if [[ $rc -ne 0 ]]; then
|
||||
echo "❌ connection failed"
|
||||
echo "$result"
|
||||
echo
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -z "$result" ]]; then
|
||||
echo "Up-to-date"
|
||||
else
|
||||
echo "$result"
|
||||
fi
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
########################################
|
||||
# Check all hosts
|
||||
########################################
|
||||
|
||||
check_all() {
|
||||
local hosts_file="$1"
|
||||
|
||||
ensure_hosts_file
|
||||
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
|
||||
|
||||
local name ip user
|
||||
read -r name ip user <<< "$line"
|
||||
|
||||
[[ -z "$name" || -z "$ip" || -z "$user" ]] && continue
|
||||
|
||||
check_host "$name" "$ip" "$user"
|
||||
done < "$hosts_file"
|
||||
}
|
||||
|
||||
########################################
|
||||
# Main
|
||||
########################################
|
||||
|
||||
case "${1:-}" in
|
||||
check)
|
||||
HOSTS_FILE_TO_USE="$(get_hosts_file "$@")"
|
||||
check_all "$HOSTS_FILE_TO_USE"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
case $choice in
|
||||
1)
|
||||
bash "$UPDATE_MANAGER_SCRIPT" check
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
2)
|
||||
less "$HOSTS_FILE"
|
||||
;;
|
||||
3)
|
||||
nano "$HOSTS_FILE"
|
||||
;;
|
||||
4)
|
||||
read -rp "Name: " name
|
||||
read -rp "IP: " ip
|
||||
read -rp "User: " user
|
||||
echo "$name $ip $user" >> "$HOSTS_FILE"
|
||||
echo "Host added."
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
5)
|
||||
nl -w2 -s'. ' "$HOSTS_FILE"
|
||||
read -rp "Line to remove: " line
|
||||
sed -i "${line}d" "$HOSTS_FILE"
|
||||
echo "Host removed."
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
6)
|
||||
less "$(get_log_file)"
|
||||
;;
|
||||
7)
|
||||
echo "Press Ctrl+C to stop"
|
||||
tail -f "$(get_log_file)"
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
8)
|
||||
echo "Log file:"
|
||||
echo "$(get_log_file)"
|
||||
read -rp "Press Enter to continue..."
|
||||
;;
|
||||
0)
|
||||
clear
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue