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.
|
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
|
## Features
|
||||||
|
|
||||||
* Check updates on multiple hosts
|
* 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
|
* Simple config files
|
||||||
* Built-in logging (file + terminal)
|
|
||||||
* Dialog-based UI menu
|
|
||||||
* No agents required
|
* No agents required
|
||||||
* Works with existing SSH setup
|
* Works with existing SSH setup
|
||||||
|
|
||||||
|
|
@ -37,12 +40,20 @@ Built for Lanx environments – lightweight, fast and no unnecessary dependencie
|
||||||
|
|
||||||
## Update Manager UI
|
## Update Manager UI
|
||||||
|
|
||||||
|
### Main menu
|
||||||
|
|
||||||
<p align="center">
|
<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>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<em>Lightweight • Terminal-based • Works over SSH</em>
|
<em>Lightweight • No dependencies • Works over SSH</em>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -57,7 +68,7 @@ sudo apt update
|
||||||
sudo apt install dialog openssh-client
|
sudo apt install dialog openssh-client
|
||||||
|
|
||||||
sudo mkdir -p /opt/update-manager
|
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.sh
|
||||||
sudo chmod +x /opt/update-manager/update-manager-ui.sh
|
sudo chmod +x /opt/update-manager/update-manager-ui.sh
|
||||||
|
|
@ -134,6 +145,12 @@ server3 192.168.1.30 user
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Check updates
|
||||||
|
|
||||||
|
```bash
|
||||||
|
update-manager check
|
||||||
|
```
|
||||||
|
|
||||||
### Start UI
|
### Start UI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -142,42 +159,25 @@ update-manager-ui
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Check updates (CLI)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
update-manager check
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Logging
|
## Logging
|
||||||
|
|
||||||
The tool logs both to terminal and file.
|
Log file location:
|
||||||
|
|
||||||
### Primary location
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/opt/update-manager/log/update-manager.log
|
/opt/update-manager/log/update-manager.log
|
||||||
```
|
```
|
||||||
|
|
||||||
### Fallback location
|
View log:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
~/update-manager/log/update-manager.log
|
less /opt/update-manager/log/update-manager.log
|
||||||
```
|
```
|
||||||
|
|
||||||
### Notes
|
Follow log:
|
||||||
|
|
||||||
* Log directory is created automatically
|
```bash
|
||||||
* Log file is created automatically
|
tail -f /opt/update-manager/log/update-manager.log
|
||||||
* Output is written to both terminal and file
|
```
|
||||||
* Log levels:
|
|
||||||
|
|
||||||
* INFO
|
|
||||||
* WARN
|
|
||||||
* ERROR
|
|
||||||
|
|
||||||
Logs can be viewed directly from the UI.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -189,8 +189,8 @@ Logs can be viewed directly from the UI.
|
||||||
├── update-manager-ui.sh
|
├── update-manager-ui.sh
|
||||||
├── update-manager.conf
|
├── update-manager.conf
|
||||||
├── hosts.conf
|
├── hosts.conf
|
||||||
└── log/
|
├── log/
|
||||||
└── update-manager.log
|
│ └── update-manager.log
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -199,6 +199,7 @@ Logs can be viewed directly from the UI.
|
||||||
|
|
||||||
* Uses SSH to connect to each host
|
* Uses SSH to connect to each host
|
||||||
* Runs `apt` commands remotely
|
* Runs `apt` commands remotely
|
||||||
|
* Logs results locally
|
||||||
* No agents or services needed
|
* No agents or services needed
|
||||||
* Designed for simple and efficient operations
|
* Designed for simple and efficient operations
|
||||||
|
|
||||||
|
|
@ -209,7 +210,6 @@ Logs can be viewed directly from the UI.
|
||||||
* SSH access to all hosts
|
* SSH access to all hosts
|
||||||
* SSH keys recommended (no password prompts)
|
* SSH keys recommended (no password prompts)
|
||||||
* Ubuntu/Debian-based systems
|
* Ubuntu/Debian-based systems
|
||||||
* `dialog` (for UI)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -218,7 +218,6 @@ Logs can be viewed directly from the UI.
|
||||||
* 🔔 Notifications (ntfy / push alerts)
|
* 🔔 Notifications (ntfy / push alerts)
|
||||||
* 🌐 Web interface
|
* 🌐 Web interface
|
||||||
* 📧 Email reporting
|
* 📧 Email reporting
|
||||||
* 📜 Advanced logging / audit trail
|
|
||||||
* 📊 Basic monitoring (status, last check, pending updates)
|
* 📊 Basic monitoring (status, last check, pending updates)
|
||||||
* 🧩 Plugin system (extensible modules)
|
* 🧩 Plugin system (extensible modules)
|
||||||
* 🔐 Security & compliance checks
|
* 🔐 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
|
## License
|
||||||
|
|
||||||
This project is licensed under the GNU GPL v3 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.
|
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
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
CONFIG_FILE="/etc/update-manager.conf"
|
UPDATE_MANAGER_SCRIPT="$HOME/update-manager/update-manager.sh"
|
||||||
[[ -f "$CONFIG_FILE" ]] || CONFIG_FILE="./update-manager.conf"
|
HOSTS_FILE="/opt/update-manager/hosts.conf"
|
||||||
|
|
||||||
if [[ -f "$CONFIG_FILE" ]]; then
|
get_log_file() {
|
||||||
# shellcheck disable=SC1090
|
local primary="/opt/update-manager/log/update-manager.log"
|
||||||
source "$CONFIG_FILE"
|
local fallback="$HOME/update-manager/log/update-manager.log"
|
||||||
fi
|
|
||||||
|
|
||||||
DEFAULT_HOSTS_FILE="${HOSTS_FILE:-/opt/update-manager/hosts.conf}"
|
if [[ -f "$primary" ]]; then
|
||||||
SSH_OPTIONS="${SSH_OPTIONS:--o BatchMode=yes -o ConnectTimeout=5}"
|
echo "$primary"
|
||||||
|
|
||||||
########################################
|
|
||||||
# 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"
|
|
||||||
else
|
else
|
||||||
echo "$DEFAULT_HOSTS_FILE"
|
echo "$fallback"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
usage() {
|
while true; do
|
||||||
cat <<USAGE
|
choice=$(dialog --clear \
|
||||||
Usage:
|
--backtitle "Update Manager" \
|
||||||
$0 check [hosts_file]
|
--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:
|
clear
|
||||||
$0 check
|
|
||||||
$0 check /path/to/hosts.conf
|
|
||||||
HOSTS_FILE=/path/to/hosts.conf $0 check
|
|
||||||
USAGE
|
|
||||||
}
|
|
||||||
|
|
||||||
########################################
|
case $choice in
|
||||||
# Check single host
|
1)
|
||||||
########################################
|
bash "$UPDATE_MANAGER_SCRIPT" check
|
||||||
|
read -rp "Press Enter to continue..."
|
||||||
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"
|
|
||||||
;;
|
;;
|
||||||
*)
|
2)
|
||||||
usage
|
less "$HOSTS_FILE"
|
||||||
exit 1
|
;;
|
||||||
|
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
|
esac
|
||||||
|
done
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue