diff --git a/README.md b/README.md index 44cc56d..2c2cc15 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ```bash # Download and execute in one command apt update -y && apt install curl -y -curl -s https://git.threefold.info/ourworld_web/itenv_tools/raw/branch/main/tools/git_checkout.sh | bash +curl -s https://git.threefold.info/ourworld_web/itenv_tools/raw/branch/main/tools/git_checkout.sh > /root/git_checkout.sh +bash /root/git_checkout.sh ``` diff --git a/tools/install_rust.sh b/tools/install_rust.sh new file mode 100755 index 0000000..023749f --- /dev/null +++ b/tools/install_rust.sh @@ -0,0 +1,160 @@ +#!/bin/bash + +# Rust Installation Script +# Installs Rust programming language using rustup +# Compatible with Ubuntu/Debian systems + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log() { + echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" +} + +warn() { + echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" +} + +error() { + echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" + exit 1 +} + +# Check if running as root +if [ "$EUID" -eq 0 ]; then + warn "Running as root. Rust will be installed system-wide." + INSTALL_DIR="/usr/local" + CARGO_HOME="/usr/local/cargo" + RUSTUP_HOME="/usr/local/rustup" +else + log "Installing Rust for current user" + INSTALL_DIR="$HOME" + CARGO_HOME="$HOME/.cargo" + RUSTUP_HOME="$HOME/.rustup" +fi + +# Check if Rust is already installed +if command -v rustc &> /dev/null; then + RUST_VERSION=$(rustc --version) + warn "Rust is already installed: $RUST_VERSION" + read -p "Do you want to update/reinstall? (y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + log "Installation cancelled" + exit 0 + fi +fi + +# Check for required dependencies +log "Checking system dependencies..." +MISSING_DEPS=() + +# Check for curl +if ! command -v curl &> /dev/null; then + MISSING_DEPS+=("curl") +fi + +# Check for build essentials +if ! dpkg -l | grep -q build-essential; then + MISSING_DEPS+=("build-essential") +fi + +# Install missing dependencies +if [ ${#MISSING_DEPS[@]} -gt 0 ]; then + log "Installing missing dependencies: ${MISSING_DEPS[*]}" + if [ "$EUID" -eq 0 ]; then + apt update + apt install -y "${MISSING_DEPS[@]}" + else + log "Please install the following packages and run this script again:" + log "sudo apt update && sudo apt install -y ${MISSING_DEPS[*]}" + exit 1 + fi +fi + +# Set environment variables for installation +export CARGO_HOME="$CARGO_HOME" +export RUSTUP_HOME="$RUSTUP_HOME" + +log "Starting Rust installation..." +log "CARGO_HOME: $CARGO_HOME" +log "RUSTUP_HOME: $RUSTUP_HOME" + +# Download and run rustup installer +log "Downloading rustup installer..." +if [ "$EUID" -eq 0 ]; then + # For root installation, we need to handle it differently + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path + + # Create symlinks for system-wide access + ln -sf "$CARGO_HOME/bin/cargo" /usr/local/bin/cargo + ln -sf "$CARGO_HOME/bin/rustc" /usr/local/bin/rustc + ln -sf "$CARGO_HOME/bin/rustup" /usr/local/bin/rustup + ln -sf "$CARGO_HOME/bin/rustdoc" /usr/local/bin/rustdoc + ln -sf "$CARGO_HOME/bin/rust-gdb" /usr/local/bin/rust-gdb + ln -sf "$CARGO_HOME/bin/rust-lldb" /usr/local/bin/rust-lldb + + # Set up environment for all users + cat > /etc/profile.d/rust.sh << 'EOF' +export CARGO_HOME="/usr/local/cargo" +export RUSTUP_HOME="/usr/local/rustup" +export PATH="/usr/local/cargo/bin:$PATH" +EOF + + log "Rust installed system-wide. All users can now use Rust." + log "Environment variables set in /etc/profile.d/rust.sh" +else + # Standard user installation + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + + # Source the cargo environment + source "$CARGO_HOME/env" + + log "Rust installed for current user." + log "To use Rust in new shells, run: source ~/.cargo/env" + log "Or add ~/.cargo/bin to your PATH in your shell profile" +fi + +# Verify installation +log "Verifying Rust installation..." +if [ "$EUID" -eq 0 ]; then + RUST_VERSION=$(/usr/local/bin/rustc --version 2>/dev/null || echo "") + CARGO_VERSION=$(/usr/local/bin/cargo --version 2>/dev/null || echo "") +else + RUST_VERSION=$("$CARGO_HOME/bin/rustc" --version 2>/dev/null || echo "") + CARGO_VERSION=$("$CARGO_HOME/bin/cargo" --version 2>/dev/null || echo "") +fi + +if [ -n "$RUST_VERSION" ] && [ -n "$CARGO_VERSION" ]; then + log "✅ Rust installation successful!" + log "Rust compiler: $RUST_VERSION" + log "Cargo package manager: $CARGO_VERSION" + + # Install common components + log "Installing common Rust components..." + if [ "$EUID" -eq 0 ]; then + /usr/local/bin/rustup component add clippy rustfmt + else + "$CARGO_HOME/bin/rustup" component add clippy rustfmt + fi + + log "✅ Rust installation completed successfully!" + log "" + log "Next steps:" + if [ "$EUID" -eq 0 ]; then + log "- Rust is available system-wide" + log "- Users may need to log out and back in for PATH changes to take effect" + else + log "- Run 'source ~/.cargo/env' to use Rust in this session" + log "- Restart your terminal or add ~/.cargo/bin to your PATH" + fi + log "- Create a new Rust project: cargo new my_project" + log "- Build and run: cd my_project && cargo run" +else + error "Rust installation failed. Please check the output above for errors." +fi \ No newline at end of file diff --git a/tools/install_rust_sal.sh b/tools/install_rust_sal.sh new file mode 100755 index 0000000..ffd7526 --- /dev/null +++ b/tools/install_rust_sal.sh @@ -0,0 +1,223 @@ +#!/bin/bash + +# Rust and SAL Installation Script +# Defensively installs Rust and clones/updates SAL repository +# Compatible with Ubuntu/Debian systems + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +log() { + echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" +} + +warn() { + echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" +} + +error() { + echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" + exit 1 +} + +info() { + echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $1${NC}" +} + +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +log "Script directory: $SCRIPT_DIR" + +# Define target directory for SAL repository +SAL_TARGET_DIR="/root/code/git.threefold.info/herocode/sal" +SAL_REPO_URL="git@git.ourworld.tf:herocode/sal.git" + +# Function to check if ssh-agent is loaded and has keys +check_ssh_agent() { + log "Checking SSH agent status..." + + if [ -z "$SSH_AUTH_SOCK" ]; then + warn "SSH_AUTH_SOCK is not set. SSH agent may not be running." + return 1 + fi + + if ! ssh-add -l &>/dev/null; then + warn "SSH agent is running but no keys are loaded or agent is not accessible." + info "You may need to run: ssh-add ~/.ssh/id_rsa (or your key file)" + return 1 + fi + + log "✅ SSH agent is loaded and has keys available" + return 0 +} + +# Function to test SSH connection to git server +test_ssh_connection() { + log "Testing SSH connection to git.ourworld.tf..." + + if ssh -T -o ConnectTimeout=10 -o StrictHostKeyChecking=no git@git.ourworld.tf 2>&1 | grep -q "successfully authenticated"; then + log "✅ SSH connection to git.ourworld.tf successful" + return 0 + else + warn "SSH connection test failed. Continuing anyway..." + return 1 + fi +} + +# Function to defensively install Rust +install_rust_defensively() { + log "Starting defensive Rust installation..." + + # Check if install_rust.sh exists in the same directory + RUST_INSTALLER="$SCRIPT_DIR/install_rust.sh" + + if [ ! -f "$RUST_INSTALLER" ]; then + error "install_rust.sh not found at: $RUST_INSTALLER" + fi + + if [ ! -x "$RUST_INSTALLER" ]; then + log "Making install_rust.sh executable..." + chmod +x "$RUST_INSTALLER" + fi + + log "Calling install_rust.sh from: $RUST_INSTALLER" + + # Run the Rust installer defensively + if ! "$RUST_INSTALLER"; then + error "Rust installation failed" + fi + + log "✅ Rust installation completed successfully" +} + +# Function to clone or update SAL repository +handle_sal_repository() { + log "Handling SAL repository at: $SAL_TARGET_DIR" + + # Create parent directories if they don't exist + SAL_PARENT_DIR="$(dirname "$SAL_TARGET_DIR")" + if [ ! -d "$SAL_PARENT_DIR" ]; then + log "Creating parent directory: $SAL_PARENT_DIR" + mkdir -p "$SAL_PARENT_DIR" + fi + + if [ -d "$SAL_TARGET_DIR" ]; then + log "SAL directory exists. Checking if it's a git repository..." + + if [ -d "$SAL_TARGET_DIR/.git" ]; then + log "Found existing git repository. Pulling latest changes..." + cd "$SAL_TARGET_DIR" + + # Check if we're in a clean state + if ! git status --porcelain | grep -q .; then + log "Repository is clean. Pulling changes..." + if git pull origin main 2>/dev/null || git pull origin master 2>/dev/null; then + log "✅ Successfully pulled latest changes" + else + warn "Pull failed. Repository may be up to date or have conflicts." + fi + else + warn "Repository has uncommitted changes. Skipping pull." + git status --short + fi + else + warn "Directory exists but is not a git repository. Removing and cloning fresh..." + rm -rf "$SAL_TARGET_DIR" + clone_sal_repository + fi + else + log "SAL directory does not exist. Cloning repository..." + clone_sal_repository + fi +} + +# Function to clone SAL repository +clone_sal_repository() { + log "Cloning SAL repository from: $SAL_REPO_URL" + log "Target directory: $SAL_TARGET_DIR" + + # Ensure parent directory exists + mkdir -p "$(dirname "$SAL_TARGET_DIR")" + + if git clone "$SAL_REPO_URL" "$SAL_TARGET_DIR"; then + log "✅ Successfully cloned SAL repository" + cd "$SAL_TARGET_DIR" + log "Repository cloned to: $(pwd)" + log "Current branch: $(git branch --show-current 2>/dev/null || echo 'unknown')" + else + error "Failed to clone SAL repository. Check SSH keys and network connectivity." + fi +} + +# Function to verify SAL repository +verify_sal_repository() { + log "Verifying SAL repository..." + + if [ ! -d "$SAL_TARGET_DIR" ]; then + error "SAL directory does not exist: $SAL_TARGET_DIR" + fi + + if [ ! -d "$SAL_TARGET_DIR/.git" ]; then + error "SAL directory is not a git repository: $SAL_TARGET_DIR" + fi + + cd "$SAL_TARGET_DIR" + + # Get repository information + REPO_URL=$(git remote get-url origin 2>/dev/null || echo "unknown") + CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") + LAST_COMMIT=$(git log -1 --format="%h - %s (%cr)" 2>/dev/null || echo "unknown") + + log "✅ SAL repository verification successful" + log "Repository URL: $REPO_URL" + log "Current branch: $CURRENT_BRANCH" + log "Last commit: $LAST_COMMIT" +} + +# Main execution +main() { + log "Starting Rust and SAL installation process..." + log "==========================================" + + # Step 1: Install Rust defensively + install_rust_defensively + + # Step 2: Check SSH agent + if ! check_ssh_agent; then + warn "SSH agent issues detected. Continuing anyway..." + warn "You may need to set up SSH keys and agent before git operations." + fi + + # Step 3: Test SSH connection (optional, continues on failure) + test_ssh_connection + + # Step 4: Handle SAL repository (clone or pull) + handle_sal_repository + + # Step 5: Verify SAL repository + verify_sal_repository + + log "==========================================" + log "✅ Installation process completed successfully!" + log "" + log "Summary:" + log "- Rust: Installed and verified" + log "- SAL repository: Available at $SAL_TARGET_DIR" + log "" + log "Next steps:" + log "- Source Rust environment: source ~/.cargo/env (if not root)" + log "- Navigate to SAL: cd $SAL_TARGET_DIR" + log "- Build SAL project: cargo build" +} + +# Trap to handle script interruption +trap 'error "Script interrupted"' INT TERM + +# Run main function +main "$@" diff --git a/tools/readme.md b/tools/readme.md index 8122cad..fd28beb 100644 --- a/tools/readme.md +++ b/tools/readme.md @@ -5,22 +5,9 @@ This directory contains various utility scripts for server management, disk oper ## Tools Overview ### 1. erase.sh + **Purpose**: Secure disk erasure utility for SSD drives -**What it does**: -- Detects all SSD drives on the system (excludes traditional HDDs) -- Provides interactive menu to erase specific disks or all detected SSDs -- Handles RAID array detection and cleanup before erasure -- Removes RAID superblocks from partitions -- Securely wipes the first 1GB and last 1MB of selected disks -- Destroys partition tables and filesystem headers - -**Safety Features**: -- Multiple confirmation prompts before destructive operations -- Root privilege verification -- Automatic unmounting of active filesystems -- RAID array stopping before disk erasure - **Usage**: ```bash sudo ./erase.sh @@ -29,9 +16,11 @@ sudo ./erase.sh **⚠️ WARNING**: This tool permanently destroys all data on selected disks. Use with extreme caution! ### 2. git_checkout.sh + **Purpose**: Git repository management for itenv projects **What it does**: + - Verifies SSH agent has loaded keys for git authentication - Checks and configures git user.name and user.email if not set - Creates the standard directory structure: `/root/code/git.threefold.info/ourworld_web` @@ -50,24 +39,19 @@ sudo ./erase.sh ``` ### 3. git_push.sh + **Purpose**: Quick git commit and push utility -**What it does**: -- Navigates to the parent directory of the tools folder -- Stages all changes (`git add . -A`) -- Creates a commit with message "init" -- Pushes changes to the remote repository - -**Usage**: ```bash ./git_push.sh ``` - **Note**: This is a simple automation script for quick commits. For production use, consider more descriptive commit messages. ### 4. ubuntu_install.sh **Purpose**: Automated Ubuntu 24.04 installation for Hetzner dedicated servers +> only do this on rescue system for hetzner servers + **What it does**: - Detects available NVMe drives (requires minimum 2 drives) - Creates Hetzner installimage configuration for Ubuntu 24.04 @@ -103,57 +87,3 @@ sudo ./erase.sh ``` **⚠️ WARNING**: This script will completely wipe the selected drives and install a fresh Ubuntu system. - -### 5. example_autoconfig/autoconfig -**Purpose**: Example configuration file for Hetzner installimage - -**What it contains**: -- Sample configuration for Ubuntu 24.04 installation -- RAID 1 setup with two Samsung NVMe drives -- Standard partition layout: - - 4GB swap partition - - 1024MB /boot partition (ext3) - - Remaining space for root filesystem (ext4) -- Network and hostname configuration examples -- Comments explaining all configuration options - -**Usage**: -This file serves as a template and reference for creating custom installimage configurations. Copy and modify as needed for specific server setups. - -## Directory Structure - -``` -itenv_tools/tools/ -├── readme.md # This documentation file -├── erase.sh # Disk erasure utility -├── git_checkout.sh # Git repository management -├── git_push.sh # Quick git commit/push -├── ubuntu_install.sh # Ubuntu installation script -└── example_autoconfig/ # Example configurations - └── autoconfig # Sample installimage config -``` - -## Security Considerations - -- **erase.sh**: Requires root privileges and permanently destroys data -- **git_checkout.sh**: Requires SSH key access to private repositories -- **ubuntu_install.sh**: Must be run in Hetzner rescue environment -- All scripts include error handling and safety checks where appropriate - -## Prerequisites - -### System Requirements -- Linux environment (tested on Ubuntu/Debian) -- Bash shell -- Root access for disk operations -- Git for repository management -- SSH access for private repositories - -### For Hetzner Operations -- Hetzner rescue system access -- installimage utility -- Minimum 2 NVMe drives for RAID setup - -## Support - -These tools are designed for infrastructure automation and server management. Ensure you understand the implications of each script before execution, especially those involving disk operations or system installation.