───────────────────────────────(mahmoud@Mahmouds-Laptop:s142)─┐ └─(08:55:05 on development_codewalker ✖ ✹)──> /Users/mahmoud/code/github/freeflowuniverse/herolib/examples/develop/heroprompt/heroprompt_example.vsh Using the selected files, i want you to get all print statments /Users/mahmoud/code/github/freeflowuniverse/herolib # Selected Files: 21 | Total Content: 40967 chars | Extensions: md(2), yml(2), sh(14), dockerfile(1), gitignore(1), vsh(1) └── docker ├── docker_ubuntu_install.sh * ├── herolib │ └── herolib │ ├── .gitignore * │ ├── Dockerfile * │ ├── README.md * │ ├── build.sh * │ ├── debug.sh * │ ├── docker-compose.yml * │ ├── export.sh * │ ├── shell.sh * │ ├── ssh.sh * │ ├── ssh_init.sh * │ ├── start.sh * │ └── scripts │ └── scripts │ ├── cleanup.sh * │ ├── install_herolib.vsh * │ ├── install_v.sh * │ ├── install_vscode.sh * │ └── ourinit.sh * └── postgresql └── postgresql ├── docker-compose.yml * ├── readme.md * └── start.sh * /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/docker_ubuntu_install.sh * /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/docker_ubuntu_install.sh ```sh #!/bin/bash # Exit immediately if a command exits with a non-zero status set -e # Function to display an error message and exit error_exit() { echo "Error: $1" >&2 exit 1 } # Update package index and upgrade system echo "Updating system packages..." sudo apt update && sudo apt upgrade -y || error_exit "Failed to update system packages." # Install required packages for repository setup echo "Installing prerequisites..." sudo apt install -y ca-certificates curl gnupg || error_exit "Failed to install prerequisites." # Create directory for Docker GPG key echo "Setting up GPG keyring..." sudo mkdir -p /etc/apt/keyrings || error_exit "Failed to create keyring directory." # Add Docker's official GPG key DOCKER_GPG_KEY=/etc/apt/keyrings/docker.gpg echo "Adding Docker GPG key..." curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o $DOCKER_GPG_KEY || error_exit "Failed to add Docker GPG key." sudo chmod a+r $DOCKER_GPG_KEY # Set up Docker repository echo "Adding Docker repository..." REPO_ENTRY="deb [arch=$(dpkg --print-architecture) signed-by=$DOCKER_GPG_KEY] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" if ! grep -Fxq "$REPO_ENTRY" /etc/apt/sources.list.d/docker.list; then echo "$REPO_ENTRY" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null || error_exit "Failed to add Docker repository." fi # Update package index echo "Updating package index..." sudo apt update || error_exit "Failed to update package index." # Install Docker Engine, CLI, and dependencies echo "Installing Docker Engine and dependencies..." sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin || error_exit "Failed to install Docker packages." # Verify Docker installation echo "Verifying Docker installation..." if ! docker --version; then error_exit "Docker installation verification failed." fi # Run a test container echo "Running Docker test container..." if ! sudo docker run --rm hello-world; then error_exit "Docker test container failed to run." fi # Add current user to Docker group (if not already added) echo "Configuring Docker group..." if ! groups $USER | grep -q '\bdocker\b'; then sudo usermod -aG docker $USER || error_exit "Failed to add user to Docker group." echo "User added to Docker group. Please log out and back in for this change to take effect." else echo "User is already in the Docker group." fi # Enable Docker service on boot echo "Enabling Docker service on boot..." sudo systemctl enable docker || error_exit "Failed to enable Docker service." # Success message echo "Docker installation completed successfully!" ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/docker_ubuntu_install.sh ```sh #!/bin/bash # Exit immediately if a command exits with a non-zero status set -e # Function to display an error message and exit error_exit() { echo "Error: $1" >&2 exit 1 } # Update package index and upgrade system echo "Updating system packages..." sudo apt update && sudo apt upgrade -y || error_exit "Failed to update system packages." # Install required packages for repository setup echo "Installing prerequisites..." sudo apt install -y ca-certificates curl gnupg || error_exit "Failed to install prerequisites." # Create directory for Docker GPG key echo "Setting up GPG keyring..." sudo mkdir -p /etc/apt/keyrings || error_exit "Failed to create keyring directory." # Add Docker's official GPG key DOCKER_GPG_KEY=/etc/apt/keyrings/docker.gpg echo "Adding Docker GPG key..." curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o $DOCKER_GPG_KEY || error_exit "Failed to add Docker GPG key." sudo chmod a+r $DOCKER_GPG_KEY # Set up Docker repository echo "Adding Docker repository..." REPO_ENTRY="deb [arch=$(dpkg --print-architecture) signed-by=$DOCKER_GPG_KEY] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" if ! grep -Fxq "$REPO_ENTRY" /etc/apt/sources.list.d/docker.list; then echo "$REPO_ENTRY" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null || error_exit "Failed to add Docker repository." fi # Update package index echo "Updating package index..." sudo apt update || error_exit "Failed to update package index." # Install Docker Engine, CLI, and dependencies echo "Installing Docker Engine and dependencies..." sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin || error_exit "Failed to install Docker packages." # Verify Docker installation echo "Verifying Docker installation..." if ! docker --version; then error_exit "Docker installation verification failed." fi # Run a test container echo "Running Docker test container..." if ! sudo docker run --rm hello-world; then error_exit "Docker test container failed to run." fi # Add current user to Docker group (if not already added) echo "Configuring Docker group..." if ! groups $USER | grep -q '\bdocker\b'; then sudo usermod -aG docker $USER || error_exit "Failed to add user to Docker group." echo "User added to Docker group. Please log out and back in for this change to take effect." else echo "User is already in the Docker group." fi # Enable Docker service on boot echo "Enabling Docker service on boot..." sudo systemctl enable docker || error_exit "Failed to enable Docker service." # Success message echo "Docker installation completed successfully!" ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/Dockerfile ```dockerfile # Use Ubuntu 24.04 as the base image FROM ubuntu:24.04 # Set the working directory WORKDIR /root # Copy local installation scripts into the container COPY scripts/install_v.sh /tmp/install_v.sh COPY scripts/install_herolib.vsh /tmp/install_herolib.vsh COPY scripts/install_vscode.sh /tmp/install_vscode.sh COPY scripts/ourinit.sh /usr/local/bin/ # Make the scripts executable RUN chmod +x /tmp/install_v.sh /tmp/install_herolib.vsh RUN apt-get update && apt-get install -y \ curl bash sudo mc wget tmux htop openssh-server RUN bash /tmp/install_v.sh RUN yes y | bash /tmp/install_v.sh --analyzer RUN bash /tmp/install_vscode.sh #SSH RUN mkdir -p /var/run/sshd && \ echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config && \ echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config && \ chown -R root:root /root/.ssh && \ chmod -R 700 /root/.ssh/ && \ touch /root/.ssh/authorized_keys \ chmod 600 /root/.ssh/authorized_keys && \ service ssh start RUN /tmp/install_herolib.vsh && \ apt-get clean && \ echo "PS1='HERO: \w \$ '" >> ~/.bashrc \ rm -rf /var/lib/apt/lists/* ENTRYPOINT ["/bin/bash"] CMD ["/bin/bash"] ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/README.md ```md # HeroLib Docker Environment This directory contains the Docker configuration and scripts for setting up and managing the HeroLib development environment. The environment includes a containerized setup with VSCode server, SSH access, and PostgreSQL database. ## Key Components ### Docker Configuration Files - `Dockerfile`: Defines the container image based on Ubuntu 24.04, installing necessary dependencies including: - V language and its analyzer - VSCode server - SSH server - Development tools (curl, tmux, htop, etc.) - HeroLib installation - `docker-compose.yml`: Orchestrates the multi-container setup with: - PostgreSQL database service - HeroLib development environment - Port mappings for various services - Volume mounting for code persistence ## Scripts ### Container Management - `shell.sh`: Interactive shell access script that: - Checks if the container is running - Starts the container if it's stopped - Verifies port accessibility (default: 4000) - Provides interactive bash session inside the container - `debug.sh`: Launches the container in debug mode with: - Interactive terminal - Volume mounts for scripts and code - Port mappings for various services (4000-4379) - Custom entrypoint using ourinit.sh - `export.sh`: Creates a compressed export of the container: - Stops any running instances - Launches a temporary container - Runs cleanup script - Exports and compresses the container to ~/Downloads/herolib.tar.gz ### SSH Access - `ssh.sh`: Simple SSH connection script to access the container via port 4022 - `ssh_init.sh`: Configures SSH access by: - Collecting public keys from local ~/.ssh directory - Setting up authorized_keys in the container - Installing and configuring SSH server - Setting appropriate permissions - Enabling root login with key authentication ### Internal Scripts (in scripts/) - `cleanup.sh`: Comprehensive system cleanup script that: - Removes unused packages and dependencies - Cleans APT cache - Removes old log files - Clears temporary files and caches - Performs system maintenance tasks - `install_herolib.vsh`: V script for HeroLib installation: - Sets up necessary symlinks - Configures V module structure - Adds useful shell aliases (e.g., vtest) - `ourinit.sh`: Container initialization script that: - Starts Redis server in daemon mode - Launches VSCode server in a tmux session - Starts SSH service - Provides interactive bash shell ## Port Mappings - 4000:3000 - Main application port - 4022:22 - SSH access - 4100:8100 - Additional service port - 4101:8101 - Additional service port - 4102:8102 - Additional service port - 4379:6379 - Redis port ## Usage 1. Build and start the environment: ```bash docker compose up -d ``` 2. Access the container shell: ```bash ./shell.sh ``` 3. Connect via SSH: ```bash ./ssh.sh ``` 4. Debug mode (interactive with direct terminal): ```bash ./debug.sh ``` 5. Create container export: ```bash ./export.sh ``` ## Development The environment mounts your local `~/code` directory to `/root/code` inside the container, allowing for seamless development between host and container. The PostgreSQL database persists data using a named volume. ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/build.sh ```sh #!/bin/bash -e # Get the directory where the script is located SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "$SCRIPT_DIR" # Copy installation files cp ../../install_v.sh ./scripts/install_v.sh cp ../../install_herolib.vsh ./scripts/install_herolib.vsh # Docker image and container names DOCKER_IMAGE_NAME="herolib" DEBUG_CONTAINER_NAME="herolib" function cleanup { if docker ps -aq -f name="$DEBUG_CONTAINER_NAME" &>/dev/null; then echo "Cleaning up leftover debug container..." docker rm -f "$DEBUG_CONTAINER_NAME" &>/dev/null || true fi } trap cleanup EXIT # Attempt to build the Docker image BUILD_LOG=$(mktemp) set +e docker build --name herolib --progress=plain -t "$DOCKER_IMAGE_NAME" . BUILD_EXIT_CODE=$? set -e # Handle build failure if [ $BUILD_EXIT_CODE -ne 0 ]; then echo -e "\\n[ERROR] Docker build failed.\n" echo -e "remove the part which didn't build in the Dockerfile, the run again and to debug do:" echo docker run --name herolib -it --entrypoint=/bin/bash "herolib" exit $BUILD_EXIT_CODE else echo -e "\\n[INFO] Docker build completed successfully." fi ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/debug.sh ```sh #!/bin/bash -ex # Get the directory where the script is located SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" # Remove any existing container named 'debug' (ignore errors) docker rm -f herolib > /dev/null 2>&1 docker run --name herolib -it \ --entrypoint="/usr/local/bin/ourinit.sh" \ -v "${SCRIPT_DIR}/scripts:/scripts" \ -v "$HOME/code:/root/code" \ -p 4100:8100 \ -p 4101:8101 \ -p 4102:8102 \ -p 4379:6379 \ -p 4022:22 \ -p 4000:3000 herolib ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/docker-compose.yml ```yml services: postgres: image: postgres:latest container_name: postgres_service environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: planetfirst POSTGRES_DB: mydb ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data herolib: build: context: . dockerfile: Dockerfile image: herolib:latest container_name: herolib volumes: - ~/code:/root/code stdin_open: true tty: true ports: - "4100:8100" - "4101:8101" - "4102:8102" - "4379:6379" - "4000:3000" - "4022:22" command: ["/usr/local/bin/ourinit.sh"] volumes: postgres_data: ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/export.sh ```sh #!/bin/bash -ex # Get the directory where the script is located SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" docker compose down docker rm herolib --force # Start the container in detached mode (-d) docker run --name herolib \ --entrypoint="/bin/bash" \ -v "${SCRIPT_DIR}/scripts:/scripts" \ -p 4022:22 \ -d herolib -c "while true; do sleep 1; done" docker exec -it herolib /scripts/cleanup.sh # Detect the OS detect_os() { if [[ "$(uname)" == "Darwin" ]]; then echo "osx" elif [[ -f /etc/os-release ]]; then . /etc/os-release if [[ "$ID" == "ubuntu" ]]; then echo "ubuntu" fi else echo "unknown" fi } OS=$(detect_os) if [[ "$OS" == "osx" ]]; then echo "Running on macOS..." docker export herolib | gzip > "${HOME}/Downloads/herolib.tar.gz" echo "Docker image exported to ${HOME}/Downloads/herolib.tar.gz" elif [[ "$OS" == "ubuntu" ]]; then echo "Running on Ubuntu..." export TEMP_TAR="/tmp/herolib.tar" # Export the Docker container to a tar file docker export herolib > "$TEMP_TAR" echo "Docker container exported to $TEMP_TAR" # Import the tar file back as a single-layer image docker import "$TEMP_TAR" herolib:single-layer echo "Docker image imported as single-layer: herolib:single-layer" # Log in to Docker Hub and push the image docker login --username despiegk docker tag herolib:single-layer despiegk/herolib:single-layer docker push despiegk/herolib:single-layer echo "Docker image pushed to Docker Hub as despiegk/herolib:single-layer" # Optionally remove the tar file after importing rm -f "$TEMP_TAR" echo "Temporary file $TEMP_TAR removed" else echo "Unsupported OS detected. Exiting." exit 1 fi docker kill herolib # Test the pushed Docker image locally echo "Testing the Docker image locally..." TEST_CONTAINER_NAME="test_herolib_container" docker pull despiegk/herolib:single-layer if [[ $? -ne 0 ]]; then echo "Failed to pull the Docker image from Docker Hub. Exiting." exit 1 fi docker run --name "$TEST_CONTAINER_NAME" -d despiegk/herolib:single-layer if [[ $? -ne 0 ]]; then echo "Failed to run the Docker image as a container. Exiting." exit 1 fi docker ps | grep "$TEST_CONTAINER_NAME" if [[ $? -eq 0 ]]; then echo "Container $TEST_CONTAINER_NAME is running successfully." else echo "Container $TEST_CONTAINER_NAME is not running. Check the logs for details." fi ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/scripts/cleanup.sh ```sh #!/bin/bash -e # Log file for cleanup operations LOG_FILE="/var/log/cleanup_script.log" exec > >(tee -a $LOG_FILE) 2>&1 # Function to check and execute commands safely safe_run() { echo "Running: $*" eval "$*" } # Update package lists safe_run "apt update" # Remove unused packages and dependencies safe_run "apt autoremove -y" # Clean up APT cache safe_run "apt clean" safe_run "apt autoclean" # Remove old kernels (keeping the current and latest one) safe_run "apt remove --purge -y $(dpkg --list | grep linux-image | awk '{print $2}' | grep -v $(uname -r | sed 's/[^-]*-[^-]*-//') | sort | head -n -1)" # Clear systemd journal logs, keeping only the latest 7 days safe_run "journalctl --vacuum-time=7d" # Remove orphaned packages safe_run "deborphan | xargs apt-get -y remove --purge" # Clear thumbnail cache safe_run "rm -rf ~/.cache/thumbnails/*" # Remove old log files safe_run "find /var/log -type f -name '*.log' -delete" # Clear temporary files safe_run "rm -rf /tmp/*" safe_run "rm -rf /var/tmp/*" # Remove user-specific temporary files (adjust for other users as needed) safe_run "rm -rf ~/.cache/*" # Remove .pyc files safe_run "find / -type f -name '*.pyc' -delete" # Remove unused snap versions #safe_run "snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do snap remove "$snapname" --revision="$revision"; done" # Clear trash for all users safe_run "rm -rf /home/*/.local/share/Trash/*/**" safe_run "rm -rf /root/.local/share/Trash/*/**" # Free up swap space #safe_run "swapoff -a && swapon -a" # Update GRUB (in case old kernels were removed) #safe_run "update-grub" # # Final system update and upgrade # safe_run "apt upgrade -y" # Report completion echo "System cleanup completed successfully." ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/scripts/install_herolib.vsh ```vsh #!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run import os import flag fn addtoscript(tofind string, toadd string) ! { home_dir := os.home_dir() mut rc_file := '${home_dir}/.zshrc' if !os.exists(rc_file) { rc_file = '${home_dir}/.bashrc' if !os.exists(rc_file) { return error('No .zshrc or .bashrc found in home directory') } } // Read current content mut content := os.read_file(rc_file)! // Remove existing alias if present lines := content.split('\n') mut new_lines := []string{} mut prev_is_emtpy := false for line in lines { if prev_is_emtpy { if line.trim_space() == '' { continue } else { prev_is_emtpy = false } } if line.trim_space() == '' { prev_is_emtpy = true } if !line.contains(tofind) { new_lines << line } } new_lines << toadd new_lines << '' // Write back to file new_content := new_lines.join('\n') os.write_file(rc_file, new_content)! } vroot := @VROOT abs_dir_of_script := dir(@FILE) // Reset symlinks if requested println('Resetting all symlinks...') os.rm('${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or {} // Create necessary directories os.mkdir_all('${os.home_dir()}/.vmodules/freeflowuniverse') or { panic('Failed to create directory ~/.vmodules/freeflowuniverse: ${err}') } // Create new symlinks os.symlink('${abs_dir_of_script}/lib', '${os.home_dir()}/.vmodules/freeflowuniverse/herolib') or { panic('Failed to create herolib symlink: ${err}') } println('Herolib installation completed successfully!') // Add vtest alias addtoscript('alias vtest=', "alias vtest='v -stats -enable-globals -n -w -cg -gc none -cc tcc test' ") or { eprintln('Failed to add vtest alias: ${err}') } println('Added vtest alias to shell configuration') ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/scripts/install_v.sh ```sh #!/bin/bash -e # Help function print_help() { echo "V & HeroLib Installer Script" echo echo "Usage: $0 [options]" echo echo "Options:" echo " -h, --help Show this help message" echo " --reset Force reinstallation of V" echo " --remove Remove V installation and exit" echo " --analyzer Install/update v-analyzer" echo " --herolib Install our herolib" echo echo "Examples:" echo " $0" echo " $0 --reset " echo " $0 --remove " echo " $0 --analyzer " echo " $0 --herolib " echo " $0 --reset --analyzer # Fresh install of both" echo } # Parse arguments RESET=false REMOVE=false INSTALL_ANALYZER=false HEROLIB=false for arg in "$@"; do case $arg in -h|--help) print_help exit 0 ;; --reset) RESET=true ;; --remove) REMOVE=true ;; --herolib) HEROLIB=true ;; --analyzer) INSTALL_ANALYZER=true ;; *) echo "Unknown option: $arg" echo "Use -h or --help to see available options" exit 1 ;; esac done # Function to check if command exists command_exists() { command -v "$1" >/dev/null 2>&1 } export DIR_BASE="$HOME" export DIR_BUILD="/tmp" export DIR_CODE="$DIR_BASE/code" export DIR_CODE_V="$DIR_BASE/_code" function sshknownkeysadd { mkdir -p ~/.ssh touch ~/.ssh/known_hosts if ! grep github.com ~/.ssh/known_hosts > /dev/null then ssh-keyscan github.com >> ~/.ssh/known_hosts fi if ! grep git.threefold.info ~/.ssh/known_hosts > /dev/null then ssh-keyscan git.threefold.info >> ~/.ssh/known_hosts fi git config --global pull.rebase false } function package_check_install { local command_name="$1" if command -v "$command_name" >/dev/null 2>&1; then echo "command '$command_name' is already installed." else package_install '$command_name' fi } function package_install { local command_name="$1" if [[ "${OSNAME}" == "ubuntu" ]]; then apt -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-confdef" install $1 -q -y --allow-downgrades --allow-remove-essential elif [[ "${OSNAME}" == "darwin"* ]]; then brew install $command_name elif [[ "${OSNAME}" == "alpine"* ]]; then apk add $command_name elif [[ "${OSNAME}" == "arch"* ]]; then pacman --noconfirm -Su $command_name else echo "platform : ${OSNAME} not supported" exit 1 fi } is_github_actions() { [ -d "/home/runner" ] || [ -d "$HOME/runner" ] } function myplatform { if [[ "${OSTYPE}" == "darwin"* ]]; then export OSNAME='darwin' elif [ -e /etc/os-release ]; then # Read the ID field from the /etc/os-release file export OSNAME=$(grep '^ID=' /etc/os-release | cut -d= -f2) if [ "${os_id,,}" == "ubuntu" ]; then export OSNAME="ubuntu" fi if [ "${OSNAME}" == "archarm" ]; then export OSNAME="arch" fi if [ "${OSNAME}" == "debian" ]; then export OSNAME="ubuntu" fi else echo "Unable to determine the operating system." exit 1 fi # if [ "$(uname -m)" == "x86_64" ]; then # echo "This system is running a 64-bit processor." # else # echo "This system is not running a 64-bit processor." # exit 1 # fi } myplatform function os_update { echo ' - os update' if [[ "${OSNAME}" == "ubuntu" ]]; then if is_github_actions; then echo "github actions" else rm -f /var/lib/apt/lists/lock rm -f /var/cache/apt/archives/lock rm -f /var/lib/dpkg/lock* fi export TERM=xterm export DEBIAN_FRONTEND=noninteractive dpkg --configure -a apt update -y if is_github_actions; then echo "** IN GITHUB ACTIONS, DON'T DO UPDATE" else set +e echo "** UPDATE" apt-mark hold grub-efi-amd64-signed set -e apt upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" --force-yes apt autoremove -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" --force-yes fi #apt install apt-transport-https ca-certificates curl software-properties-common -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" --force-yes package_install "apt-transport-https ca-certificates curl wget software-properties-common tmux" package_install "rclone rsync mc redis-server screen net-tools git dnsutils htop ca-certificates screen lsb-release binutils pkg-config" elif [[ "${OSNAME}" == "darwin"* ]]; then if command -v brew >/dev/null 2>&1; then echo ' - homebrew installed' else export NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" unset NONINTERACTIVE fi set +e brew install mc redis curl tmux screen htop wget rclone tcc set -e elif [[ "${OSNAME}" == "alpine"* ]]; then apk update screen git htop tmux apk add mc curl rsync htop redis bash bash-completion screen git rclone sed -i 's#/bin/ash#/bin/bash#g' /etc/passwd elif [[ "${OSNAME}" == "arch"* ]]; then pacman -Syy --noconfirm pacman -Syu --noconfirm pacman -Su --noconfirm arch-install-scripts gcc mc git tmux curl htop redis wget screen net-tools git sudo htop ca-certificates lsb-release screen rclone # Check if builduser exists, create if not if ! id -u builduser > /dev/null 2>&1; then useradd -m builduser echo "builduser:$(openssl rand -base64 32 | sha256sum | base64 | head -c 32)" | chpasswd echo 'builduser ALL=(ALL) NOPASSWD: ALL' | tee /etc/sudoers.d/builduser fi if [[ -n "${DEBUG}" ]]; then execute_with_marker "paru_install" paru_install fi fi echo ' - os update done' } function hero_lib_pull { pushd $DIR_CODE/github/freeflowuniverse/herolib 2>&1 >> /dev/null if [[ $(git status -s) ]]; then echo "There are uncommitted changes in the Git repository herolib." return 1 fi git pull popd 2>&1 >> /dev/null } function hero_lib_get { mkdir -p $DIR_CODE/github/freeflowuniverse if [[ -d "$DIR_CODE/github/freeflowuniverse/herolib" ]] then hero_lib_pull else pushd $DIR_CODE/github/freeflowuniverse 2>&1 >> /dev/null git clone --depth 1 --no-single-branch https://github.com/freeflowuniverse/herolib.git popd 2>&1 >> /dev/null fi } function install_secp256k1 { echo "Installing secp256k1..." if [[ "${OSNAME}" == "darwin"* ]]; then brew install secp256k1 elif [[ "${OSNAME}" == "ubuntu" ]]; then # Install build dependencies apt-get install -y build-essential wget autoconf libtool # Download and extract secp256k1 cd "${DIR_BUILD}" wget https://github.com/bitcoin-core/secp256k1/archive/refs/tags/v0.3.2.tar.gz tar -xvf v0.3.2.tar.gz # Build and install cd secp256k1-0.3.2/ ./autogen.sh ./configure make -j 5 make install # Cleanup cd .. rm -rf secp256k1-0.3.2 v0.3.2.tar.gz else echo "secp256k1 installation not implemented for ${OSNAME}" exit 1 fi echo "secp256k1 installation complete!" } remove_all() { echo "Removing V installation..." # Set reset to true to use existing reset functionality RESET=true # Call reset functionality sudo rm -rf ~/code/v sudo rm -rf ~/_code/v sudo rm -rf ~/.config/v-analyzer if command_exists v; then echo "Removing V from system..." sudo rm -f $(which v) fi if command_exists v-analyzer; then echo "Removing v-analyzer from system..." sudo rm -f $(which v-analyzer) fi # Remove v-analyzer path from rc files for RC_FILE in ~/.zshrc ~/.bashrc; do if [ -f "$RC_FILE" ]; then echo "Cleaning up $RC_FILE..." # Create a temporary file TMP_FILE=$(mktemp) # Remove lines containing v-analyzer/bin path sed '/v-analyzer\/bin/d' "$RC_FILE" > "$TMP_FILE" # Remove empty lines at the end of file sed -i.bak -e :a -e '/^\n*$/{$d;N;ba' -e '}' "$TMP_FILE" # Replace original file mv "$TMP_FILE" "$RC_FILE" echo "Cleaned up $RC_FILE" fi done echo "V removal complete" } # Function to check if a service is running and start it if needed check_and_start_redis() { # Normal service management for non-container environments if [[ "${OSNAME}" == "ubuntu" ]] || [[ "${OSNAME}" == "debian" ]]; then # Check if running inside a container if grep -q "/docker/" /proc/1/cgroup || [ ! -d "/run/systemd/system" ]; then echo "Running inside a container. Starting redis directly." if pgrep redis-server > /dev/null; then echo "redis is already running." else echo "redis is not running. Starting it in the background..." redis-server --daemonize yes if pgrep redis-server > /dev/null; then echo "redis started successfully." else echo "Failed to start redis. Please check logs for details." exit 1 fi fi return fi if systemctl is-active --quiet "redis"; then echo "redis is already running." else echo "redis is not running. Starting it..." sudo systemctl start "redis" if systemctl is-active --quiet "redis"; then echo "redis started successfully." else echo "Failed to start redis. Please check logs for details." exit 1 fi fi elif [[ "${OSNAME}" == "darwin"* ]]; then if brew services list | grep -q "^redis.*started"; then echo "redis is already running." else echo "redis is not running. Starting it..." brew services start redis fi elif [[ "${OSNAME}" == "alpine"* ]]; then if rc-service "redis" status | grep -q "running"; then echo "redis is already running." else echo "redis is not running. Starting it..." rc-service "redis" start fi elif [[ "${OSNAME}" == "arch"* ]]; then if systemctl is-active --quiet "redis"; then echo "redis is already running." else echo "redis is not running. Starting it..." sudo systemctl start "redis" fi else echo "Service management for redis is not implemented for platform: $OSNAME" exit 1 fi } # Handle remove if requested if [ "$REMOVE" = true ]; then remove_all exit 0 fi # Handle reset if requested if [ "$RESET" = true ]; then remove_all echo "Reset complete" fi # Create code directory if it doesn't exist mkdir -p ~/code # Check if v needs to be installed if [ "$RESET" = true ] || ! command_exists v; then os_update sshknownkeysadd # Only clone and install if directory doesn't exist if [ ! -d ~/code/v ]; then echo "Installing V..." mkdir -p ~/_code cd ~/_code git clone --depth=1 https://github.com/vlang/v cd v make sudo ./v symlink fi # Verify v is in path if ! command_exists v; then echo "Error: V installation failed or not in PATH" echo "Please ensure ~/code/v is in your PATH" exit 1 fi echo "V installation successful!" fi # Install v-analyzer if requested if [ "$INSTALL_ANALYZER" = true ]; then echo "Installing v-analyzer..." v download -RD https://raw.githubusercontent.com/vlang/v-analyzer/main/install.vsh # Check if v-analyzer bin directory exists if [ ! -d "$HOME/.config/v-analyzer/bin" ]; then echo "Error: v-analyzer bin directory not found at $HOME/.config/v-analyzer/bin" echo "Please ensure v-analyzer was installed correctly" exit 1 fi echo "v-analyzer installation successful!" fi # Add v-analyzer to PATH if installed if [ -d "$HOME/.config/v-analyzer/bin" ]; then V_ANALYZER_PATH='export PATH="$PATH:$HOME/.config/v-analyzer/bin"' # Function to add path to rc file if not present add_to_rc() { local RC_FILE="$1" if [ -f "$RC_FILE" ]; then if ! grep -q "v-analyzer/bin" "$RC_FILE"; then echo "" >> "$RC_FILE" echo "$V_ANALYZER_PATH" >> "$RC_FILE" echo "Added v-analyzer to $RC_FILE" else echo "v-analyzer path already exists in $RC_FILE" fi fi } # Add to both .zshrc and .bashrc if they exist add_to_rc ~/.zshrc if [ "$(uname)" = "Darwin" ] && [ -f ~/.bashrc ]; then add_to_rc ~/.bashrc fi fi # Final verification if ! command_exists v; then echo "Error: V is not accessible in PATH" echo "Please add ~/code/v to your PATH and try again" exit 1 fi check_and_start_redis if [ "$HEROLIB" = true ]; then hero_lib_get ~/code/github/freeflowuniverse/herolib/install_herolib.vsh fi # if [ "$INSTALL_ANALYZER" = true ]; then # echo "Run 'source ~/.bashrc' or 'source ~/.zshrc' to update PATH for v-analyzer" # fi echo "Installation complete!" ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/scripts/install_vscode.sh ```sh #!/bin/bash -e # Set version and file variables OPENVSCODE_SERVER_VERSION="1.97.0" TMP_DIR="/tmp" FILENAME="openvscode.tar.gz" FILE_PATH="$TMP_DIR/$FILENAME" INSTALL_DIR="/opt/openvscode" BIN_PATH="/usr/local/bin/openvscode-server" TMUX_SESSION="openvscode-server" # Function to detect architecture get_architecture() { ARCH=$(uname -m) case "$ARCH" in x86_64) echo "x64" ;; aarch64) echo "arm64" ;; *) echo "Unsupported architecture: $ARCH" >&2 exit 1 ;; esac } # Check if OpenVSCode Server is already installed if [ -d "$INSTALL_DIR" ] && [ -x "$BIN_PATH" ]; then echo "OpenVSCode Server is already installed at $INSTALL_DIR. Skipping download and installation." else # Determine architecture-specific URL ARCH=$(get_architecture) if [ "$ARCH" == "x64" ]; then DOWNLOAD_URL="https://github.com/gitpod-io/openvscode-server/releases/download/openvscode-server-insiders-v${OPENVSCODE_SERVER_VERSION}/openvscode-server-insiders-v${OPENVSCODE_SERVER_VERSION}-linux-x64.tar.gz" elif [ "$ARCH" == "arm64" ]; then DOWNLOAD_URL="https://github.com/gitpod-io/openvscode-server/releases/download/openvscode-server-insiders-v${OPENVSCODE_SERVER_VERSION}/openvscode-server-insiders-v${OPENVSCODE_SERVER_VERSION}-linux-arm64.tar.gz" fi # Navigate to temporary directory cd "$TMP_DIR" # Remove existing file if it exists if [ -f "$FILE_PATH" ]; then rm -f "$FILE_PATH" fi # Download file using curl curl -L "$DOWNLOAD_URL" -o "$FILE_PATH" # Verify file size is greater than 40 MB (40 * 1024 * 1024 bytes) FILE_SIZE=$(stat -c%s "$FILE_PATH") if [ "$FILE_SIZE" -le $((40 * 1024 * 1024)) ]; then echo "Error: Downloaded file size is less than 40 MB." >&2 exit 1 fi # Extract the tar.gz file EXTRACT_DIR="openvscode-server-insiders-v${OPENVSCODE_SERVER_VERSION}-linux-${ARCH}" tar -xzf "$FILE_PATH" # Move the extracted directory to the install location if [ -d "$INSTALL_DIR" ]; then rm -rf "$INSTALL_DIR" fi mv "$EXTRACT_DIR" "$INSTALL_DIR" # Create a symlink for easy access ln -sf "$INSTALL_DIR/bin/openvscode-server" "$BIN_PATH" # Verify installation if ! command -v openvscode-server >/dev/null 2>&1; then echo "Error: Failed to create symlink for openvscode-server." >&2 exit 1 fi # Install default plugins PLUGINS=("ms-python.python" "esbenp.prettier-vscode" "saoudrizwan.claude-dev" "yzhang.markdown-all-in-one" "ms-vscode-remote.remote-ssh" "ms-vscode.remote-explorer" "charliermarsh.ruff" "qwtel.sqlite-viewer" "vosca.vscode-v-analyzer" "tomoki1207.pdf") for PLUGIN in "${PLUGINS[@]}"; do "$INSTALL_DIR/bin/openvscode-server" --install-extension "$PLUGIN" done echo "Default plugins installed: ${PLUGINS[*]}" # Clean up temporary directory if [ -d "$TMP_DIR" ]; then find "$TMP_DIR" -maxdepth 1 -type f -name "openvscode*" -exec rm -f {} \; fi fi # Start OpenVSCode Server in a tmux session if tmux has-session -t "$TMUX_SESSION" 2>/dev/null; then tmux kill-session -t "$TMUX_SESSION" fi tmux new-session -d -s "$TMUX_SESSION" "$INSTALL_DIR/bin/openvscode-server" echo "OpenVSCode Server is running in a tmux session named '$TMUX_SESSION'." ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/scripts/ourinit.sh ```sh #!/bin/bash -e redis-server --daemonize yes TMUX_SESSION="vscode" # Start OpenVSCode Server in a tmux session if tmux has-session -t "$TMUX_SESSION" 2>/dev/null; then tmux kill-session -t "$TMUX_SESSION" fi tmux new-session -d -s "$TMUX_SESSION" "/usr/local/bin/openvscode-server --host 0.0.0.0 --without-connection-token" service ssh start exec /bin/bash ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/shell.sh ```sh #!/bin/bash -e # Get the directory where the script is located SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "$SCRIPT_DIR" CONTAINER_NAME="herolib" TARGET_PORT=4000 # Function to check if a container is running is_container_running() { docker ps --filter "name=$CONTAINER_NAME" --filter "status=running" -q } # Function to check if a port is accessible is_port_accessible() { nc -zv 127.0.0.1 "$1" &>/dev/null } # Check if the container exists and is running if ! is_container_running; then echo "Container $CONTAINER_NAME is not running." # Check if the container exists but is stopped if docker ps -a --filter "name=$CONTAINER_NAME" -q | grep -q .; then echo "Starting existing container $CONTAINER_NAME..." docker start "$CONTAINER_NAME" else echo "Container $CONTAINER_NAME does not exist. Attempting to start with start.sh..." if [[ -f "$SCRIPT_DIR/start.sh" ]]; then bash "$SCRIPT_DIR/start.sh" else echo "Error: start.sh not found in $SCRIPT_DIR." exit 1 fi fi # Wait for the container to be fully up sleep 5 fi # Verify the container is running if ! is_container_running; then echo "Error: Failed to start container $CONTAINER_NAME." exit 1 fi echo "Container $CONTAINER_NAME is running." # Check if the target port is accessible if is_port_accessible "$TARGET_PORT"; then echo "Port $TARGET_PORT is accessible." else echo "Port $TARGET_PORT is not accessible. Please check the service inside the container." fi # Enter the container echo echo " ** WE NOW LOGIN TO THE CONTAINER ** " echo docker exec -it herolib bash ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/ssh.sh ```sh #!/bin/bash -e ssh root@localhost -p 4022 ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/ssh_init.sh ```sh #!/bin/bash -e # Get the directory where the script is located SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "$SCRIPT_DIR" # Define variables CONTAINER_NAME="herolib" CONTAINER_SSH_DIR="/root/.ssh" AUTHORIZED_KEYS="authorized_keys" TEMP_AUTH_KEYS="/tmp/authorized_keys" # Step 1: Create a temporary file to store public keys > $TEMP_AUTH_KEYS # Clear the file if it exists # Step 2: Add public keys from ~/.ssh/ if they exist if ls ~/.ssh/*.pub 1>/dev/null 2>&1; then cat ~/.ssh/*.pub >> $TEMP_AUTH_KEYS fi # Step 3: Check if ssh-agent is running and get public keys from it if pgrep ssh-agent >/dev/null; then echo "ssh-agent is running. Fetching keys..." ssh-add -L >> $TEMP_AUTH_KEYS 2>/dev/null else echo "ssh-agent is not running or no keys loaded." fi # Step 4: Ensure the temporary file is not empty if [ ! -s $TEMP_AUTH_KEYS ]; then echo "No public keys found. Exiting." exit 1 fi # Step 5: Ensure the container's SSH directory exists docker exec -it $CONTAINER_NAME mkdir -p $CONTAINER_SSH_DIR docker exec -it $CONTAINER_NAME chmod 700 $CONTAINER_SSH_DIR # Step 6: Copy the public keys into the container's authorized_keys file docker cp $TEMP_AUTH_KEYS $CONTAINER_NAME:$CONTAINER_SSH_DIR/$AUTHORIZED_KEYS # Step 7: Set proper permissions for authorized_keys docker exec -it $CONTAINER_NAME chmod 600 $CONTAINER_SSH_DIR/$AUTHORIZED_KEYS # Step 8: Install and start the SSH server inside the container docker exec -it $CONTAINER_NAME bash -c " apt-get update && apt-get install -y openssh-server && mkdir -p /var/run/sshd && echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config && echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config && chown -R root:root /root/.ssh && chmod -R 700 /root/.ssh/ && chmod 600 /root/.ssh/authorized_keys && service ssh start " # Step 9: Clean up temporary file on the host rm $TEMP_AUTH_KEYS echo "SSH keys added and SSH server configured. You can now SSH into the container." ssh root@localhost -p 4022 ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/herolib/start.sh ```sh #!/bin/bash -e # Get the directory where the script is located SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "$SCRIPT_DIR" docker rm herolib --force docker compose up -d ./ssh_init.sh ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/postgresql/docker-compose.yml ```yml version: '3.9' services: db: image: 'postgres:17.2-alpine3.21' restart: always ports: - 5432:5432 environment: POSTGRES_PASSWORD: 1234 networks: - my_network adminer: image: adminer restart: always ports: - 8080:8080 networks: - my_network networks: my_network: ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/postgresql/readme.md ```md Server (Host): db (because Docker Compose creates an internal network and uses service names as hostnames) Username: postgres (default PostgreSQL username) Password: 1234 (as set in your POSTGRES_PASSWORD environment variable) Database: Leave it empty or enter postgres (default database) ``` /Users/mahmoud/code/github/freeflowuniverse/herolib/docker/postgresql/start.sh ```sh #!/bin/bash -e # Get the directory where the script is located SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "$SCRIPT_DIR" # Stop any existing containers and remove them docker compose down # Start the services in detached mode docker compose up -d echo "PostgreSQL is ready" ```