#! /bin/sh -e # genenetwork-machines --- Guix configuration for genenetwork machines # Copyright © 2025 Munyoki Kilyungi # # This file is part of genenetwork-machines. # # genenetwork-machines is free software: you can redistribute it # and/or modify it under the terms of the GNU General Public License # as published by the Free Software Foundation, either version 3 of # the License, or (at your option) any later version. # # genenetwork-machines is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with genenetwork-machines. If not, see # . # Build and install genenetwork container on your local machine. set -euo pipefail BASE_DIR="${HOME:-/home/$USER}/genenetwork" SYSTEM_DIRECTORIES=( "$BASE_DIR/var/log" "$BASE_DIR/var/genenetwork" "$BASE_DIR/etc/genenetwork/conf" "$BASE_DIR/etc/genenetwork" "$BASE_DIR/var/lib/redis" "$BASE_DIR/var/lib/virtuoso" "$BASE_DIR/var/lib/xapian" "$BASE_DIR/var/lib/genenetwork-sqlite" "$BASE_DIR/var/lib/genenetwork-gnqa" "/tmp/local-container" ) GN_PROJECTS=( "genenetwork2:git@github.com:genenetwork/genenetwork2" "genenetwork3:git@github.com:genenetwork/genenetwork3" "gn-auth:https://git.genenetwork.org/gn-auth" "gn-docs:https://git.genenetwork.org/gn-docs" ) CONTAINER_SCM="genenetwork-local-container.scm" CONTAINER_BIN="/usr/local/bin/genenetwork-local-container" GC_ROOT="/var/guix/gcroots/genenetwork-local-container" log() { local level="$1" shift echo "[$(date '+%Y-%m-%d %H:%M:%S')] $level: $*" >&2 } # Check dependencies for cmd in git guix sudo; do if ! command -v "$cmd" &>/dev/null; then log "ERROR" "Required command '$cmd' not found" exit 1 fi done # Validate HOME is set if [ -z "${HOME:-}" ]; then log "ERROR" "HOME environment variable is not set" exit 1 fi log "INFO" "Creating system directories..." for dir in "${SYSTEM_DIRECTORIES[@]}"; do # Check if directory exists and is accessible if [ -d "$dir" ]; then if [ -w "$dir" ]; then log "DEBUG" "Directory exists and is writable: $dir" else log "WARNING" "Directory exists but is not writable: $dir" fi continue fi # Attempt to create directory log "INFO" "Creating directory: $dir" if [ -w "$(dirname "$dir")" ]; then # Parent directory is writable, try without sudo if ! mkdir -p "$dir"; then log "ERROR" "Failed to create directory without sudo: $dir" exit 1 fi else # Parent directory requires root, use sudo if ! sudo mkdir -p "$dir"; then log "ERROR" "Failed to create directory with sudo: $dir" exit 1 fi # Set ownership to current user if created with sudo if ! sudo chown "$USER:$USER" "$dir"; then log "WARNING" "Failed to set ownership for: $dir" fi fi done is_git_repository() { local dir="$1" # Check for standard repository if [ -d "$dir/.git" ]; then if [ -f "$dir/.git/HEAD" ] && [ -d "$dir/.git/refs" ]; then log "DEBUG" "Detected standard Git repository: $dir" return 0 else log "ERROR" "Directory $dir/.git exists but is not a valid Git repository" return 1 fi # Check for bare repository elif [ -f "$dir/HEAD" ] && [ -d "$dir/refs" ] && [ -d "$dir/objects" ]; then log "DEBUG" "Detected bare Git repository: $dir" return 0 else log "ERROR" "$dir exists but is not a Git repository (neither standard nor bare)" return 1 fi } # Clone GeneNetwork projects log "INFO" "Cloning GeneNetwork projects..." for project_entry in "${GN_PROJECTS[@]}"; do IFS=':' read -r project repo_url <<< "$project_entry" dir="$BASE_DIR/$project" if [ ! -d "$dir" ]; then log "INFO" "Cloning $project from $repo_url to $dir" if ! git clone "$repo_url" "$dir"; then log "ERROR" "Failed to clone $project" exit 1 fi else log "DEBUG" "Directory exists, skipping clone: $dir" if ! is_git_repository "$dir"; then log "ERROR" "$dir exists but is not a Git repository" exit 1 fi fi done # Verify container SCM file exists if [ ! -f "$CONTAINER_SCM" ]; then log "ERROR" "Container SCM file not found: $CONTAINER_SCM" exit 1 fi # Create Guix system container log "INFO" "Creating Guix system container..." SHARE_OPTS=( "--share=$BASE_DIR/var/log=/var/log" "--share=$BASE_DIR/var/genenetwork=/var/genenetwork" "--share=$BASE_DIR/etc/genenetwork/conf=/etc/genenetwork/conf" "--share=$BASE_DIR/etc/genenetwork=/etc/genenetwork" "--share=$BASE_DIR/var/lib/redis=/var/lib/redis" "--share=$BASE_DIR/var/lib/virtuoso=/var/lib/virtuoso" "--share=$BASE_DIR/genenetwork2=/genenetwork2" "--share=$BASE_DIR/genenetwork3=/genenetwork3" "--share=$BASE_DIR/gn-auth=/gn-auth" "--share=$BASE_DIR/var/lib/xapian=/var/lib/xapian" "--share=$BASE_DIR/var/lib/genenetwork-sqlite=/var/lib/genenetwork-sqlite" "--share=$BASE_DIR/var/lib/genenetwork-gnqa=/var/lib/genenetwork-gnqa" "--share=/tmp/local-container=/tmp" "--share=$BASE_DIR/gn-docs=/var/lib/gn-docs" "--share=/run/mysqld=/run/mysqld" ) container_script=$(guix system container \ --network \ --load-path=. \ --verbosity=3 \ "${SHARE_OPTS[@]}" \ "$CONTAINER_SCM") log $container_script # Create symbolic links log "INFO" "Creating symbolic links..." if ! sudo ln -sf "$container_script" "$CONTAINER_BIN"; then log "ERROR" "Failed to create symbolic link: $CONTAINER_BIN" exit 1 fi if ! sudo ln -sf "$container_script" "$GC_ROOT"; then log "ERROR" "Failed to create GC root link: $GC_ROOT" exit 1 fi log "INFO" "Setup completed successfully!" log "INFO" "Container script: $container_script" log "INFO" "Run with: $CONTAINER_BIN"