Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions applications/luci-app-ha-cluster/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SPDX-License-Identifier: Apache-2.0

include $(TOPDIR)/rules.mk

PKG_LICENSE:=Apache-2.0
PKG_MAINTAINER:=Pierre Gaufillet <pierre.gaufillet@bergamote.eu>

LUCI_TITLE:=LuCI support for HA Cluster
LUCI_DEPENDS:=+ha-cluster +luci-base +rpcd

include ../../luci.mk

# call BuildPackage - OpenWrt buildroot signature
135 changes: 135 additions & 0 deletions applications/luci-app-ha-cluster/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# LuCI Application for HA Cluster

Web interface for managing High Availability clusters on OpenWrt.

## Features

### Quick Setup Tab
- Simple multi-router HA configuration (2 or more nodes)
- Priority configuration
- Peer router management
- VRRP instance management (VIPs grouped by instance fail over atomically)
- Virtual IP (VIP) configuration per interface with instance selector
- Inline VRRP instance creation from VIP modal ("Add new..." option)
- Service synchronization selection
- One-click enable/disable

### Status Tab
- Real-time cluster state (MASTER/BACKUP/FAULT)
- Peer connectivity status
- Service health monitoring (keepalived, owsync, lease-sync)
- DHCP lease sync statistics
- Config sync statistics
- Auto-refresh every 5 seconds

### Advanced Pages
- **Keepalived (Advanced)**: VRRP instance tuning (timing/auth/tracking/unicast) and health checks
- **owsync (Advanced)**: Custom sync groups, exclusions, poll interval
- **DHCP Sync (Advanced)**: lease-sync tuning and logging

## Installation

```bash
apk update
apk add luci-app-ha-cluster
```

## Dependencies

- `ha-cluster` - HA cluster management package
- `luci-base` - LuCI base system
- `rpcd` - RPC daemon

## Files

```
/www/luci-static/resources/
├── view/ha-cluster/
│ ├── simple.js # Quick Setup interface
│ ├── status.js # Status dashboard
│ ├── keepalived-advanced.js # Advanced VRRP settings
│ ├── owsync-advanced.js # Advanced config sync settings
│ └── lease-sync-advanced.js # Advanced DHCP sync settings
└── ha-cluster.css # Styles

/usr/share/luci/menu.d/
└── luci-app-ha-cluster.json # Menu definition

/usr/share/rpcd/acl.d/
└── luci-app-ha-cluster.json # Access control

/usr/libexec/rpcd/
└── ha-cluster # RPC backend (shell script)
```

## Usage

1. Navigate to **Services → High Availability** in LuCI
2. Go to **Quick Setup** tab
3. Configure:
- Enable HA Cluster
- Set node name and priority
- Add peer router IP
- Configure Virtual IPs for each interface
- Select services to synchronize
4. Save & Apply

## Screenshots

### Quick Setup
Simple form-based configuration for typical multi-router setups:
- Cluster settings (name, priority, type)
- Peer configuration
- Virtual IP addresses
- Service sync options

### Status Dashboard
Real-time monitoring with:
- Cluster state indicator (color-coded)
- Peer health status
- Service status table
- Sync statistics

## Development

### Testing Locally

```bash
# Build the package
make package/luci-app-ha-cluster/compile

# Install on router
scp bin/packages/*/luci/luci-app-ha-cluster_*.apk root@router:/tmp/
ssh root@router apk add /tmp/luci-app-ha-cluster_*.apk

# Clear LuCI cache
ssh root@router rm -rf /tmp/luci-*
```

### Debugging

Enable debug mode in browser console:
```javascript
L.env.sessionid
```

Check RPC calls:
```bash
ubus call ha-cluster status
```

View logs:
```bash
logread | grep luci
logread | grep ha-cluster
```

## License

Apache-2.0

luci-app-ha-cluster has been developed using Claude Code from Anthropic.

## Maintainer

Pierre Gaufillet <pierre.gaufillet@bergamote.eu>
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright (c) 2025-2026 Pierre Gaufillet <pierre.gaufillet@bergamote.eu>
*/

/* HA Cluster Status Styles */

.ha-cluster-status-overview {
display: flex;
justify-content: space-around;
margin: 1em 0;
}

.ha-cluster-status-card {
flex: 1;
padding: 1em;
margin: 0 0.5em;
background: #f8f9fa;
border-radius: 4px;
border-left: 4px solid #007bff;
text-align: center;
}

.ha-cluster-status-card h4 {
margin: 0 0 0.5em 0;
color: #6c757d;
font-size: 0.9em;
text-transform: uppercase;
}

.ha-cluster-status-value {
font-size: 2em;
font-weight: bold;
}

.ha-cluster-state-master {
color: #28a745;
}

.ha-cluster-state-backup {
color: #ffc107;
}

.ha-cluster-state-fault {
color: #dc3545;
}

.ha-cluster-state-unknown {
color: #6c757d;
}

.ha-cluster-peer-online {
color: #28a745;
}

.ha-cluster-peer-offline {
color: #dc3545;
}

.ha-cluster-service-running {
color: #28a745;
}

.ha-cluster-service-stopped {
color: #dc3545;
}

/* Simple form hints */
.ha-cluster-hint {
display: block;
margin-top: 0.5em;
padding: 0.5em;
background: #e7f3ff;
border-left: 3px solid #2196f3;
font-size: 0.9em;
}

.ha-cluster-warning {
background: #fff3cd;
border-left-color: #ffc107;
color: #856404;
}

.ha-cluster-error {
background: #f8d7da;
border-left-color: #dc3545;
color: #721c24;
}

.ha-cluster-success {
background: #d4edda;
border-left-color: #28a745;
color: #155724;
}

/* Status indicators */
.ha-cluster-indicator {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 0.5em;
}

.ha-cluster-indicator.online {
background-color: #28a745;
}

.ha-cluster-indicator.offline {
background-color: #dc3545;
}

.ha-cluster-indicator.warning {
background-color: #ffc107;
}
Loading