diff --git a/README.md b/README.md index e69de29..58522e1 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,84 @@ +# PiDP 10 Services + +## Overview + +This repository combines a set of useful scripts and services, to run on the +PiDP-10 in order to make it easier to work with it and develop for it. These +services can be installed on the PiDP-10 and automate tasks such as copying +files onto the ITS operating system. These tools help automate processes, that +would require interaction with the Linux part of the PiDP-10 when developing on +another system. + +## git-monitor + +The git-monitor is a system service that monitors a target directory on the +PiDP-10. It contains a file with a list of git repositories to monitor, one at a +time. The service will check if any of the repositories changed, and pull them. +After a successful pull a script will be called, if it exists, that allows the +newly updated repository to interact with a running PDP-10 simulation. + +The monitor consists of a script, that needs to be installed to `/usr/local/bin` +and a systemd unit-file to run it as a service. + +### Installation + +To install the git-monitor, clone this repository to the target computer, and +run the install script: + +```bash +git clone https://gitea.orca-central.de/jali/PiDP10Services.git +sudo ./install.sh +``` + +This will install the service on your system and start it. If you want the +service to be enabled on system boot, enable the service: + +```bash +sudo systemctl enable git-monitor.service +``` + +### Configuration + +The service is usable immediately after installation. The service is configured +through a series of environment variables, that can be set to change the default +behaviour. There are five different environment variables to configure the +service with: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Environment VariableDescriptionDefault Value
GITMONITOR_URLSA file that contains the list of observed repositories in a directory by name and URL./opt/src/repository.list
GITMONITOR_LOCAL_PATHThe path in which the clone repositories will be stored./opt/src
GITMONITOR_BRANCH_NAMEThe name of the branch to observe.develop
GITMONITOR_POLL_INTERVALLThe number of seconds to wait until the next poll.30
GITMONITOR_LOCK_FILEThe lock file that is used to monitor the service. /run/lock/git-monitor.lock
+ +You can override these settings by creating an override file for the service +unit. Create a new file +`/etc/serviced/service/git-monitor.service.d/override.conf` by typing +`sudo systemctl edit git-monitor.service`. You can then uncomment the +`Environment` statements, and change the value of the variables accordingly. diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..c02a8d3 --- /dev/null +++ b/install.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Install the service on the target machine + +SERVICEDIR="/usr/local/bin" +SYSTEMDDIR="/etc/systemd/system" + +echo "- Installing the service files" +cp ./services/git-monitor $SERVICEDIR +cp ./units/git-monitor.service $SYSTEMDDIR + +echo "- Preparing the service files" +systemctl daemon-reload +systemctl start git-monitor.service + +echo "- Installation complete." diff --git a/services/git-monitor b/services/git-monitor new file mode 100755 index 0000000..3d59819 --- /dev/null +++ b/services/git-monitor @@ -0,0 +1,107 @@ +#!/bin/bash + +# Configuration +[[ "x${GITMONITOR_URLS}" == "x" ]] && GITMONITOR_URLS="/opt/src/repository.list" +[[ "x${GITMONITOR_LOCAL_PATH}" == "x" ]] && GITMONITOR_LOCAL_PATH="/opt/src" +[[ "x${GITMONITOR_BRANCH_NAME}" == "x" ]] && GITMONITOR_BRANCH_NAME="develop" +[[ "x${GITMONITOR_POLL_INTERVAL}" == "x" ]] && GITMONITOR_POLL_INTERVAL=60 # Seconds between checks +[[ "x${GITMONITOR_LOCK_FILE}" == "x" ]] && GITMONITOR_LOCK_FILE="/run/lock/git-monitor.lock" # File to prevent multiple instances + +IFS="|" + +# Functions +log_message() { + local level=$1 + local message=$2 + timestamp=$(date +'%Y-%m-%d %H:%M:%S') + #echo "$timestamp [$level] $message" >> "$LOG_FILE" + echo "$timestamp [$level] $message" # Also print to console (optional) +} + +check_lock() { + if [ -f "$GITMONITOR_LOCK_FILE" ]; then + log_message "WARN" "Another instance is already running. Exiting." + exit 1 + fi +} + +create_lock() { + touch "$GITMONITOR_LOCK_FILE" +} + +run_after() { + local after_pull_script=$1 + source $after_pull_script +} + +initialize_repos() { + while read -r repo_name repo_url; do + if [ ! -d "$GITMONITOR_LOCAL_PATH/$repo_name" ]; then + log_message "INFO" "Repository directory $GITMONITO_LOCAL_PATH/$repo_name does not exist. Cloning..." + mkdir -p "$GITMONITOR_LOCAL_PATH/$repo_name" + git clone --depth 1 "$repo_url" "$GITMONITOR_LOCAL_PATH/$repo_name" + if [ $? -ne 0 ]; then + log_message "ERROR" "Failed to clone repository. Exiting." + exit 1 + fi + log_message "INFO" "Repository cloned successfully." + fi + done <$GITMONITOR_URLS +} + +check_for_updates() { + local repo_name=$1 + local last_commit_hash + local current_commit_hash + + # Get the last known commit hash (from a file) + cd "$GITMONITOR +_LOCAL_PATH/$repo_name" + if [ -f "$GITMONITOR_LOCAL_PATH/$repo_name/.git-monitor-last-commit" ]; then + last_commit_hash=$(cat "$GITMONITOR_LOCAL_PATH/$repo_name/.git-monitor-last-commit") + else + last_commit_hash="" # Initialize if file doesn't exist + fi + + # Fetch the latest commit hash from the remote repository + git -C "$GITMONITOR_LOCAL_PATH/$repo_name" fetch origin $GITMONITOR_BRANCH_NAME + current_commit_hash=$(git -C "$GITMONITOR_LOCAL_PATH/$repo_name" rev-parse origin $GITMONITOR_BRANCH_NAME) + + if [ -z "$last_commit_hash" ] || [ "$current_commit_hash" != "$last_commit_hash" ]; then + log_message "INFO" "New commits detected. Pulling..." + git -C "$GITMONITOR + _LOCAL_PATH/$repo_name" pull origin $GITMONITOR_BRANCH_NAME + if [ $? -eq 0 ]; then + log_message "INFO" "Pull successful." + + # run local scripts + if [ -f "$GITMONITOR_LOCAL_PATH/$repo_name/.git-monitor_after.sh" ]; then + run_after "$GITMONITOR_LOCAL_PATH/$repo_name/.git-monitor_after.sh" + fi + + # Update the last commit hash file + echo "$current_commit_hash" > "$GITMONITOR_LOCAL_PATH/$repo_name/.git-monitor-last-commit" + else + log_message "ERROR" "Pull failed." + fi + fi +} + +# Main Execution + +trap 'rm -f $GITMONITOR_LOCK_FILE' EXIT + +check_lock +create_lock + +log_message "INFO" "Git monitor started." + +initialize_repos + +while true; do + while read -r repo_name repo_url; do + check_for_updates $repo_name + done < $GITMONITOR_URLS + sleep "$GITMONITOR_POLL_INTERVAL" +done + diff --git a/units/git-monitor.service b/units/git-monitor.service new file mode 100644 index 0000000..9a26484 --- /dev/null +++ b/units/git-monitor.service @@ -0,0 +1,17 @@ +[Unit] +Description=Get Repository Monitor +After=network.target + +[Service] +ExecStart=/usr/local/bin/git-monitor +Restart=on-failure +User=monitor +WorkingDirectory=/opt/src +Environment="GITMONITOR_URLS=/opt/src/repository.list" +Environment="GITMONITOR_LOCAL_PATH=/opt/src" +Environment="GITMONITOR_BRANCH_NAME=develop" +Environment="GITMONITOR_POLL_INTERVALL=30" +Environment="GITMONITOR_LOCK_FILE=/run/lock/git-monitor.lock" + +[Install] +WantedBy=multi-user.target