diff --git a/README.md b/README.md index 94eaca1..495c983 100644 --- a/README.md +++ b/README.md @@ -50,36 +50,37 @@ When running as a background daemon, TimeTurner provides a web interface for mon ## 🚀 Installation -The `setup.sh` script is provided to compile and install the TimeTurner application and its systemd service on a Debian-based system like Raspberry Pi OS. +The `setup.sh` script compiles and installs the TimeTurner application. You can run it by cloning the repository with `git` or by using the `curl` command below for a git-free installation. ### Prerequisites -- **Rust and Cargo**: The script requires the Rust programming language toolchain. If you don't have it, install it from [rustup.rs](https://rustup.rs/). +- **Internet Connection**: To download dependencies. +- **Curl and Unzip**: The script requires `curl` to download files and `unzip` for the git-free method. The setup script will attempt to install these if they are missing. -### Running the Installer +### Running the Installer (Recommended) -1. First, clone the repository: - ```bash - git clone https://github.com/cjfranko/NTP-Timeturner.git - cd NTP-Timeturner - ``` -2. Make the script executable and run it. The script will use `sudo` for commands that require root privileges, so it may ask for your password. - ```bash - chmod +x setup.sh - ./setup.sh - ``` +This command downloads the latest version, unpacks it, and runs the setup script. Paste it into your Raspberry Pi terminal: + +```bash +curl -L https://github.com/cjfranko/NTP-Timeturner/archive/refs/heads/main.zip -o NTP-Timeturner.zip && \ +unzip NTP-Timeturner.zip && \ +cd NTP-Timeturner-main && \ +chmod +x setup.sh && \ +./setup.sh +``` ### What the Script Does The installation script automates the following steps: -1. **Compiles the Binary**: Runs `cargo build --release` to create an optimised executable. -2. **Creates Directories**: Creates `/opt/timeturner` to store the application files. -3. **Installs Files**: +1. **Installs Dependencies**: Installs `git`, `curl`, `unzip`, and necessary build tools. +2. **Compiles the Binary**: Runs `cargo build --release` to create an optimised executable. +3. **Creates Directories**: Creates `/opt/timeturner` to store the application files. +4. **Installs Files**: - The compiled binary is copied to `/opt/timeturner/timeturner`. - The web interface assets from the `static/` directory are copied to `/opt/timeturner/static`. - A symbolic link is created from `/usr/local/bin/timeturner` to the binary, allowing it to be run from any location. -4. **Sets up Systemd Service**: +5. **Sets up Systemd Service**: - Copies the `timeturner.service` file to `/etc/systemd/system/`. - Enables the service to start automatically on system boot. diff --git a/config.yml b/config.yml index bf892f4..bc552ee 100644 --- a/config.yml +++ b/config.yml @@ -12,8 +12,8 @@ defaultNudgeMs: 2 # Time-turning offsets. All values are added to the incoming LTC time. # These can be positive or negative. timeturnerOffset: - hours: 1 - minutes: 2 - seconds: 3 - frames: 4 - milliseconds: 5 + hours: 0 + minutes: 0 + seconds: 0 + frames: 0 + milliseconds: 0 diff --git a/setup.sh b/setup.sh index eb1be25..3dffd84 100644 --- a/setup.sh +++ b/setup.sh @@ -21,7 +21,8 @@ echo "Detected package manager: $PKG_MANAGER" # --- Update System Packages --- echo "Updating system packages..." if [ "$PKG_MANAGER" == "apt" ]; then - sudo apt update && sudo apt upgrade -y + sudo apt update + sudo DEBIAN_FRONTEND=noninteractive apt upgrade -y -o Dpkg::Options::="--force-confold" elif [ "$PKG_MANAGER" == "dnf" ]; then sudo dnf upgrade -y elif [ "$PKG_MANAGER" == "pacman" ]; then @@ -48,14 +49,29 @@ fi echo "Installing common build dependencies..." if [ "$PKG_MANAGER" == "apt" ]; then sudo apt update - sudo apt install -y build-essential libudev-dev pkg-config curl + sudo apt install -y build-essential libudev-dev pkg-config curl wget elif [ "$PKG_MANAGER" == "dnf" ]; then - sudo dnf install -y gcc make perl-devel libudev-devel pkg-config curl + sudo dnf install -y gcc make perl-devel libudev-devel pkg-config curl wget elif [ "$PKG_MANAGER" == "pacman" ]; then sudo pacman -Sy --noconfirm base-devel libudev pkg-config curl fi echo "Common build dependencies installed." +# --- Install Python dependencies for testing --- +echo "🐍 Installing Python dependencies for test scripts..." +if [ "$PKG_MANAGER" == "apt" ]; then + # python3-serial is the name for pyserial in apt + sudo apt install -y python3 python3-pip python3-serial +elif [ "$PKG_MANAGER" == "dnf" ]; then + # python3-pyserial is the name for pyserial in dnf + sudo dnf install -y python3 python3-pip python3-pyserial +elif [ "$PKG_MANAGER" == "pacman" ]; then + # python-pyserial is the name for pyserial in pacman + sudo pacman -Sy --noconfirm python python-pip python-pyserial +fi +# sudo pip3 install pyserial # This is replaced by the native package manager installs above +echo "✅ Python dependencies installed." + # --- Apply custom splash screen --- if [[ "$(uname)" == "Linux" ]]; then echo "🖼️ Applying custom splash screen..." @@ -100,10 +116,10 @@ echo "Removing NTPD (if installed) and installing Chrony, NMTUI, Adjtimex..." if [ "$PKG_MANAGER" == "apt" ]; then sudo apt update sudo apt remove -y ntp || true # Remove ntp if it exists, ignore if not - sudo apt install -y chrony nmtui adjtimex + sudo apt install -y chrony network-manager adjtimex sudo systemctl enable chrony --now elif [ "$PKG_MANAGER" == "dnf" ]; then - sudo dnf remove -y ntp || true + sudo dnf remove -y ntp sudo dnf install -y chrony NetworkManager-tui adjtimex sudo systemctl enable chronyd --now elif [ "$PKG_MANAGER" == "pacman" ]; then @@ -116,29 +132,142 @@ fi echo "NTPD removed (if present). Chrony, NMTUI, and Adjtimex installed and configured." +# --- Configure Chrony to act as a local NTP server --- +echo "⚙️ Configuring Chrony to serve local time..." +# The path to chrony.conf can vary +if [ -f /etc/chrony/chrony.conf ]; then + CHRONY_CONF="/etc/chrony/chrony.conf" +elif [ -f /etc/chrony.conf ]; then + CHRONY_CONF="/etc/chrony.conf" +else + CHRONY_CONF="" +fi + +if [ -n "$CHRONY_CONF" ]; then + # Comment out any existing pool, server, or sourcedir lines to prevent syncing with external sources + echo "Disabling external NTP sources..." + sudo sed -i -E 's/^(pool|server|sourcedir)/#&/' "$CHRONY_CONF" + + # Add settings to the top of the file to serve local clock + # Using a temp file to prepend is safer than multiple sed calls + TEMP_CONF=$(mktemp) + cat < "$TEMP_CONF" +# Serve the system clock as a reference at stratum 1 +server 127.127.1.0 +allow 127.0.0.0/8 +local stratum 1 + +EOF + # Append the rest of the original config file after our new lines + cat "$CHRONY_CONF" >> "$TEMP_CONF" + sudo mv "$TEMP_CONF" "$CHRONY_CONF" + + + # Add settings to the bottom of the file to allow LAN clients + echo "Allowing LAN clients..." + sudo tee -a "$CHRONY_CONF" > /dev/null < /dev/null < /dev/null < /dev/null < /dev/null; then + echo "Attempting to start nodogsplash service..." + if ! sudo systemctl restart nodogsplash; then + echo "❌ nodogsplash service failed to start. Displaying logs..." + # Give a moment for logs to be written + sleep 2 + sudo journalctl -u nodogsplash.service --no-pager -n 50 + echo "" + echo "To debug further, run nodogsplash in the foreground with this command:" + echo " sudo /usr/bin/nodogsplash -f -d 7" + echo "" + exit 1 + fi + echo "✅ nodogsplash service started successfully." + fi +else + 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'." + exit 1 +fi echo "✅ WiFi hotspot and captive portal configured. SSID: TimeTurner, IP: 10.0.252.1" echo "Clients will be redirected to http://10.0.252.1/static/index.html" @@ -212,6 +361,7 @@ sudo ln -sf $INSTALL_DIR/timeturner $BIN_DIR/timeturner echo "✅ Binary and assets installed to $INSTALL_DIR, and binary linked to $BIN_DIR." # 4. Install systemd service file +# Only needed for Linux systems (e.g., Raspberry Pi OS) if [[ "$(uname)" == "Linux" ]]; then echo "⚙️ Installing systemd service for Linux..." sudo cp timeturner.service /etc/systemd/system/ @@ -226,14 +376,20 @@ echo "" echo "--- Setup Complete ---" echo "The TimeTurner daemon is now installed." echo "The working directory is $INSTALL_DIR." -echo "A default 'config.yml' will be created there on first run." +# Copy default config.yml from repo if it exists +if [ -f config.yml ]; then + sudo cp config.yml $INSTALL_DIR/ + echo "Default 'config.yml' installed to $INSTALL_DIR." +else + echo "⚠️ No default 'config.yml' found in repository. Please add one if needed." +fi echo "" if [[ "$(uname)" == "Linux" ]]; then echo "To start the service, run:" echo " sudo systemctl start timeturner.service" echo "" echo "To view live logs, run:" - echo " journalctl -u timeturner.service -f" + echo " journalctl -u tim_turner.service -f" echo "" fi echo "To run the interactive TUI instead, simply run from the project directory:"