Compare commits

..

9 commits

Author SHA1 Message Date
Chris Frankland-Wright
04165f2686 last chance saloon!
Some checks are pending
Build for Raspberry Pi / Build for aarch64 (push) Waiting to run
2025-08-31 00:19:24 +01:00
Chris Frankland-Wright
459e44250e ugh another try... 2025-08-31 00:06:32 +01:00
Chris Frankland-Wright
604d118d25 force dns and dhcp 2025-08-30 23:59:34 +01:00
Chris Frankland-Wright
320174fe53 final attempt for the night 2025-08-30 23:54:12 +01:00
Chris Frankland-Wright
8903d6d006 DHCP issues 2025-08-30 23:48:24 +01:00
Chris Frankland-Wright
32e785bd88 update installer with reinstall options 2025-08-30 23:39:05 +01:00
Chris Frankland-Wright
fb4ecc5f2a bug fix for AP captive 2025-08-30 23:25:06 +01:00
Chris Frankland-Wright
0c51fd77fa rename AP to Hachi 2025-08-30 23:15:47 +01:00
Chris Frankland-Wright
474e62d487 created updater 2025-08-30 23:02:48 +01:00
3 changed files with 173 additions and 32 deletions

View file

@ -86,6 +86,25 @@ The installation script automates the following steps:
After installation is complete, the script will provide instructions to start the service manually or to run the application in its interactive terminal mode. After installation is complete, the script will provide instructions to start the service manually or to run the application in its interactive terminal mode.
---
## 🔄 Updating
If you installed TimeTurner by cloning the repository with `git`, you can use the `update.sh` script to easily update to the latest version.
**Note**: This script will not work if you used the `curl` one-line command for installation, as that method does not create a Git repository.
To run the update script, navigate to the `NTP-Timeturner-main` directory and run:
```bash
chmod +x update.sh && ./update.sh
```
The update script automates the following:
1. Pulls the latest code from the `main` branch on GitHub.
2. Rebuilds the application binary.
3. Copies the new binary to `/opt/timeturner/`.
4. Restarts the `timeturner` service to apply the changes.
--- ---
## 🕰️ Chrony NTP ## 🕰️ Chrony NTP
```bash ```bash

158
setup.sh
View file

@ -3,6 +3,43 @@ set -e
echo "--- TimeTurner Setup ---" echo "--- TimeTurner Setup ---"
# Check if TimeTurner is already installed.
INSTALL_DIR="/opt/timeturner"
if [ -f "${INSTALL_DIR}/timeturner" ]; then
echo "✅ TimeTurner is already installed."
# Ask the user what to do
read -p "Do you want to (U)pdate, (R)einstall, or (A)bort? [U/r/a] " choice
case "$choice" in
r|R )
echo "Proceeding with full re-installation..."
# Stop the service to allow overwriting the binary, ignore errors if not running
echo "Stopping existing TimeTurner service..."
sudo systemctl stop timeturner.service || true
# The script will continue to the installation steps below.
;;
a|A )
echo "Aborting setup."
exit 0
;;
* ) # Default to Update
echo "Attempting to run the update script..."
# Ensure we are in a git repository and the update script exists
if [ -d ".git" ] && [ -f "update.sh" ]; then
chmod +x update.sh
./update.sh
# Exit cleanly after the update
exit 0
else
echo "⚠️ Could not find 'update.sh' or not in a git repository."
echo "Please re-clone the repository to get the update script, or remove the existing installation to run setup again:"
echo " sudo rm -rf ${INSTALL_DIR}"
exit 1
fi
;;
esac
fi
# Determine package manager # Determine package manager
PKG_MANAGER="" PKG_MANAGER=""
if command -v apt &> /dev/null; then if command -v apt &> /dev/null; then
@ -227,8 +264,9 @@ if [ "$PKG_MANAGER" == "apt" ]; then
echo "✅ nodogsplash installed successfully." echo "✅ nodogsplash installed successfully."
# Disable the standalone hostapd service to let NetworkManager manage it. # Disable the standalone hostapd service to let NetworkManager manage it.
sudo systemctl disable hostapd # We are now using the classic hostapd service, so unmask it.
sudo systemctl mask hostapd sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl enable nodogsplash sudo systemctl enable nodogsplash
else else
echo "This script is designed for Debian-based systems like Raspberry Pi OS." echo "This script is designed for Debian-based systems like Raspberry Pi OS."
@ -240,40 +278,71 @@ fi
sudo systemctl stop hostapd || true sudo systemctl stop hostapd || true
sudo systemctl stop dnsmasq || true sudo systemctl stop dnsmasq || true
# Ensure NetworkManager is managing wlan0 by removing any conflicting configurations. # --- Configure networking for AP mode ---
# This is the critical fix for the "No suitable device" error.
echo "Ensuring NetworkManager is managing wlan0..." # Set the WiFi country code to prevent radio issues. This is a critical step.
sudo rm -f /etc/NetworkManager/conf.d/99-unmanaged-wlan0.conf echo "Setting WiFi Country Code to US..."
sudo raspi-config nonint do_wifi_country US
# Tell NetworkManager to ignore wlan0 completely to prevent conflicts.
echo "Configuring NetworkManager to ignore wlan0..."
sudo tee /etc/NetworkManager/conf.d/99-unmanaged-wlan0.conf > /dev/null <<EOF
[keyfile]
unmanaged-devices=interface-name:wlan0
EOF
# Also remove the DNS disabling config as it's no longer relevant for this method
sudo rm -f /etc/NetworkManager/conf.d/99-disable-dns.conf
sudo systemctl reload NetworkManager sudo systemctl reload NetworkManager
# Configure static IP for wlan0 using NetworkManager (nmcli) # Configure a static IP for wlan0 using dhcpcd.
echo "Configuring static IP for wlan0 using NetworkManager..." echo "Configuring static IP for wlan0 via dhcpcd..."
# Ensure dhcpcd is installed
sudo apt install -y dhcpcd5
# Define the connection name # First, remove any existing configurations for wlan0 to prevent conflicts.
CON_NAME="TimeTurner-AP" # This is a more robust way to ensure our settings are applied.
sudo sed -i '/^interface wlan0/,/^\s*$/d' /etc/dhcpcd.conf
# If a connection with this name already exists, delete it to ensure a clean slate. # Now, add our static IP config to the end of the file.
if nmcli c show --active | grep -q "$CON_NAME"; then sudo tee -a /etc/dhcpcd.conf > /dev/null <<EOF
sudo nmcli c down "$CON_NAME" || true
fi
if nmcli c show | grep -q "$CON_NAME"; then
echo "Deleting existing '$CON_NAME' connection profile..."
sudo nmcli c delete "$CON_NAME" || true
fi
# Create a new connection profile for the Access Point with a static IP. # Static IP configuration for Hachi Time AP
echo "Creating new '$CON_NAME' connection profile..." interface wlan0
sudo nmcli c add type wifi ifname wlan0 con-name "$CON_NAME" autoconnect yes ssid "TimeTurner" static ip_address=10.0.252.1/24
sudo nmcli c modify "$CON_NAME" 802-11-wireless.mode ap 802-11-wireless.band bg nohook wpa_supplicant
sudo nmcli c modify "$CON_NAME" 802-11-wireless-security.key-mgmt wpa-psk EOF
sudo nmcli c modify "$CON_NAME" 802-11-wireless-security.psk "harry-ron-hermione"
sudo nmcli c modify "$CON_NAME" ipv4.method manual ipv4.addresses 10.0.252.1/24 # Configure hostapd for the Access Point
echo "Configuring hostapd..."
sudo tee /etc/hostapd/hostapd.conf > /dev/null <<EOF
interface=wlan0
driver=nl80211
ssid=Fetch-Hachi
hw_mode=g
channel=7
ieee80211n=1
wmm_enabled=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
EOF
# Point the hostapd service to the new config file.
sudo sed -i 's|#DAEMON_CONF=""|DAEMON_CONF="/etc/hostapd/hostapd.conf"|' /etc/default/hostapd
# Configure dnsmasq for DHCP # Configure dnsmasq for DHCP
echo "Configuring dnsmasq..." echo "Configuring dnsmasq..."
sudo tee /etc/dnsmasq.conf > /dev/null <<EOF sudo tee /etc/dnsmasq.conf > /dev/null <<EOF
# Listen only on this interface
interface=wlan0 interface=wlan0
# Don't bind to all interfaces, only the one specified above
bind-interfaces
# Set the IP range for DHCP clients
dhcp-range=10.0.252.10,10.0.252.50,255.255.255.0,24h dhcp-range=10.0.252.10,10.0.252.50,255.255.255.0,24h
# Provide a gateway address
dhcp-option=option:router,10.0.252.1
# Provide a DNS server address
dhcp-option=option:dns-server,10.0.252.1
# For captive portal, resolve all DNS queries to the AP itself
address=/#/10.0.252.1 address=/#/10.0.252.1
EOF EOF
@ -285,17 +354,30 @@ GatewayAddress 10.0.252.1
MaxClients 250 MaxClients 250
AuthIdleTimeout 480 AuthIdleTimeout 480
FirewallRuleSet preauthenticated-users { FirewallRuleSet preauthenticated-users {
FirewallRule allow tcp port 80 # Allow DHCP for clients to get an IP address
FirewallRule allow udp port 67
FirewallRule allow udp port 68
# Allow DNS for captive portal detection
FirewallRule allow tcp port 53 FirewallRule allow tcp port 53
FirewallRule allow udp port 53 FirewallRule allow udp port 53
# Allow HTTP for the captive portal redirect
FirewallRule allow tcp port 80
} }
RedirectURL http://10.0.252.1/static/index.html RedirectURL http://10.0.252.1/static/index.html
EOF EOF
# Restart services in the correct order and add delays to prevent race conditions # Restart services in the correct order and add delays to prevent race conditions
echo "Restarting services..." echo "Restarting services..."
# Bring up the new AP connection using nmcli
sudo nmcli c up "$CON_NAME" # Stop and disable systemd-resolved to prevent any DNS/DHCP conflicts
echo "Disabling systemd-resolved to ensure dnsmasq has full control..."
sudo systemctl stop systemd-resolved || true
sudo systemctl disable systemd-resolved || true
# Restart dhcpcd to apply the static IP
sudo systemctl restart dhcpcd
# Restart hostapd to create the access point
sudo systemctl restart hostapd
# Wait for the interface to come up and get the IP address # Wait for the interface to come up and get the IP address
echo "Waiting for wlan0 to be configured..." echo "Waiting for wlan0 to be configured..."
@ -314,7 +396,19 @@ done
# Check for the IP address before starting nodogsplash # Check for the IP address before starting nodogsplash
if [ "$IP_CHECK" == "10.0.252.1" ]; then if [ "$IP_CHECK" == "10.0.252.1" ]; then
echo "✅ wlan0 configured with IP $IP_CHECK." echo "✅ wlan0 configured with IP $IP_CHECK."
sudo systemctl restart dnsmasq
# Add a small delay to ensure the interface is fully ready for dnsmasq
sleep 2
echo "Attempting to start dnsmasq service..."
if ! sudo systemctl restart dnsmasq; then
echo "❌ dnsmasq service failed to start. Displaying logs..."
sleep 2
sudo journalctl -u dnsmasq.service --no-pager -n 50
exit 1
fi
echo "✅ dnsmasq service started successfully."
if command -v nodogsplash &> /dev/null; then if command -v nodogsplash &> /dev/null; then
echo "Attempting to start nodogsplash service..." echo "Attempting to start nodogsplash service..."
if ! sudo systemctl restart nodogsplash; then if ! sudo systemctl restart nodogsplash; then
@ -332,11 +426,11 @@ if [ "$IP_CHECK" == "10.0.252.1" ]; then
fi fi
else else
echo "❌ Error: wlan0 failed to get the static IP 10.0.252.1. Found: '$IP_CHECK'." echo "❌ Error: wlan0 failed to get the static IP 10.0.252.1. Found: '$IP_CHECK'."
echo "Please check 'sudo nmcli c show \"$CON_NAME\"' and 'ip addr show wlan0'." echo "Please check 'sudo systemctl status hostapd' and 'sudo systemctl status dhcpcd'."
exit 1 exit 1
fi fi
echo "✅ WiFi hotspot and captive portal configured. SSID: TimeTurner, IP: 10.0.252.1" echo "✅ WiFi hotspot and captive portal configured. SSID: Fetch-Hachi, IP: 10.0.252.1"
echo "Clients will be redirected to http://10.0.252.1/static/index.html" echo "Clients will be redirected to http://10.0.252.1/static/index.html"
# 1. Build the release binary # 1. Build the release binary
@ -389,7 +483,7 @@ if [[ "$(uname)" == "Linux" ]]; then
echo " sudo systemctl start timeturner.service" echo " sudo systemctl start timeturner.service"
echo "" echo ""
echo "To view live logs, run:" echo "To view live logs, run:"
echo " journalctl -u tim_turner.service -f" echo " journalctl -u timeturner.service -f"
echo "" echo ""
fi fi
echo "To run the interactive TUI instead, simply run from the project directory:" echo "To run the interactive TUI instead, simply run from the project directory:"

28
update.sh Normal file
View file

@ -0,0 +1,28 @@
#!/bin/bash
set -e
echo "--- TimeTurner Update Script ---"
# 1. Fetch the latest changes from the git repository
echo "🔄 Pulling latest changes from GitHub..."
git pull origin main
# 2. Rebuild the release binary
echo "📦 Building release binary with Cargo..."
cargo build --release
# 3. Stop the currently running service to release the file lock
echo "🛑 Stopping TimeTurner service..."
sudo systemctl stop timeturner.service
# 4. Copy the new binary to the installation directory
echo "🚀 Deploying new binary..."
sudo cp target/release/timeturner /opt/timeturner/timeturner
# 5. Restart the service with the new binary
echo "✅ Restarting TimeTurner service..."
sudo systemctl restart timeturner.service
echo ""
echo "Update complete. To check the status of the service, run:"
echo " systemctl status timeturner.service"