diff --git a/examples/installers/horus/coordinator.vsh b/examples/installers/horus/coordinator.vsh index ffc3c521..4370478b 100755 --- a/examples/installers/horus/coordinator.vsh +++ b/examples/installers/horus/coordinator.vsh @@ -4,25 +4,30 @@ import incubaid.herolib.installers.horus.coordinator // Example usage of coordinator installer // This will: -// 1. Check and install Redis if not running (required dependency) -// 2. Install Rust if not already installed -// 3. Clone the horus repository -// 4. Build the coordinator binary +// 1. Check if Rust is installed (installs if not present) +// 2. Clone the horus repository +// 3. Build the coordinator binary +// +// Note: Redis must be pre-installed and running before using the coordinator println('Building coordinator from horus repository...') -println('(This will install Redis and Rust if not already installed)\n') +println('(This will install Rust if not already installed)\n') -// Create coordinator instance - will auto-install Redis if needed +// Create coordinator instance mut coord := coordinator.new()! // Build and install +// Note: This will skip the build if the binary already exists coord.install()! +// To force a rebuild even if binary exists, use: +// coord.install(reset: true)! + println('\nCoordinator built and installed successfully!') println('Binary location: ${coord.binary_path}') // Note: To start the service, uncomment the lines below -// (requires proper zinit or screen session setup) +// (requires proper zinit or screen session setup and Redis running) // coord.start()! // if coord.running()! { // println('Coordinator is running!') diff --git a/lib/installers/horus/coordinator/coordinator_actions.v b/lib/installers/horus/coordinator/coordinator_actions.v index 6040ff97..04a2e0fd 100644 --- a/lib/installers/horus/coordinator/coordinator_actions.v +++ b/lib/installers/horus/coordinator/coordinator_actions.v @@ -6,7 +6,6 @@ import incubaid.herolib.core.pathlib import incubaid.herolib.osal.startupmanager import incubaid.herolib.installers.ulist import incubaid.herolib.installers.lang.rust -import incubaid.herolib.installers.base.redis import incubaid.herolib.develop.gittools import os @@ -80,30 +79,6 @@ fn upload() ! { // )! } -// Helper function to ensure Redis is installed and running -@[params] -struct EnsureRedisArgs { -pub mut: - redis_port int = 6379 - redis_addr string = 'localhost' - datadir string = '/var/lib/redis' -} - -fn ensure_redis_running(args EnsureRedisArgs) ! { - redis_config := redis.RedisInstall{ - port: args.redis_port - datadir: args.datadir - ipaddr: args.redis_addr - } - - if !redis.check(redis_config) { - println('Installing and starting Redis on ${args.redis_addr}:${args.redis_port}...') - redis.redis_install(redis_config)! - } else { - println('Redis is already running on ${args.redis_addr}:${args.redis_port}') - } -} - fn install() ! { console.print_header('install coordinator') // For coordinator, we build from source instead of downloading @@ -130,28 +105,20 @@ pub fn build() ! { println(' - HTTP port: ${cfg.http_port}') println(' - WS port: ${cfg.ws_port}\n') - // Ensure Redis is installed and running (required for coordinator) - println('Step 1/4: Checking Redis dependency...') - // Parse redis_addr to extract host - parts := cfg.redis_addr.split(':') - redis_host := if parts.len > 0 { parts[0] } else { 'localhost' } - ensure_redis_running(redis_port: cfg.redis_port, redis_addr: redis_host)! - println('Redis is ready\n') - // Ensure rust is installed - println('Step 2/4: Checking Rust dependency...') - mut rust_installer := rust.get()! - res := osal.exec(cmd: 'rustc -V', stdout: false, raise_error: false)! - if res.exit_code != 0 { - println('Installing Rust...') + println('Step 1/3: Checking Rust dependency...') + if !osal.cmd_exists('rustc') { + println('Rust not found, installing...') + mut rust_installer := rust.get()! rust_installer.install()! - println('Rust installed\n') + println('Rust installed successfully\n') } else { + res := osal.exec(cmd: 'rustc --version', stdout: false, raise_error: false)! println('Rust is already installed: ${res.output.trim_space()}\n') } // Clone or get the repository - println('Step 3/4: Cloning/updating horus repository...') + println('Step 2/3: Cloning/updating horus repository...') // Use the configured repo_path or default coderoot mut gs := gittools.new(coderoot: '/root/code')! mut repo := gs.get_repo( @@ -165,7 +132,7 @@ pub fn build() ! { println('Repository ready at: ${cfg.repo_path}\n') // Build the coordinator binary from the horus workspace - println('Step 4/4: Building coordinator binary...') + println('Step 3/3: Building coordinator binary...') println('WARNING: This may take several minutes (compiling Rust code)...') println('Running: cargo build -p hero-coordinator --release\n') diff --git a/lib/installers/horus/coordinator/coordinator_factory_.v b/lib/installers/horus/coordinator/coordinator_factory_.v index f1e74ef4..a77b2ac9 100644 --- a/lib/installers/horus/coordinator/coordinator_factory_.v +++ b/lib/installers/horus/coordinator/coordinator_factory_.v @@ -39,12 +39,10 @@ pub fn new(args ArgsGet) !&CoordinatorServer { repo_path: args.repo_path } - // Try to set in Redis, if it fails (Redis not available), build first + // Try to set in Redis, if it fails (Redis not available), use in-memory config set(obj) or { - console.print_header('Redis not available, installing dependencies first...') - build()! // build() now handles both factory and non-factory cases - // Now try again with Redis available - set(obj)! + console.print_debug('Redis not available, using in-memory configuration') + set_in_mem(obj)! } return get(name: args.name)! diff --git a/lib/installers/horus/coordinator/readme.md b/lib/installers/horus/coordinator/readme.md index 08e3874d..bb3c0441 100644 --- a/lib/installers/horus/coordinator/readme.md +++ b/lib/installers/horus/coordinator/readme.md @@ -58,15 +58,33 @@ coordinator.start()! ### Install Builds the coordinator binary from the horus workspace. This will: -1. Install and start Redis if not present -2. Install Rust if not present -3. Clone the horus repository from git.ourworld.tf -4. Build the coordinator binary with `cargo build -p hero-coordinator --release` +1. Check if Rust is installed (installs if not present) +2. Clone the horus repository from git.ourworld.tf +3. Build the coordinator binary with `cargo build -p hero-coordinator --release` + +**Note**: The installer skips the build if the binary already exists at the configured path. ```bash hero coordinator.install ``` +### Force Reinstall +To force a rebuild even if the binary already exists, use the `reset` flag: + +```v +import incubaid.herolib.installers.horus.coordinator as coordinator_installer + +mut coordinator := coordinator_installer.get()! +coordinator.install(reset: true)! // Force reinstall +``` + +Or manually delete the binary before running install: + +```bash +rm /hero/var/bin/coordinator +hero coordinator.install +``` + ### Start Starts the coordinator service using zinit: @@ -98,9 +116,9 @@ hero coordinator.destroy ## Requirements - **Dependencies**: - - Rust toolchain (automatically installed) + - Rust toolchain (automatically installed if not present) - Git (for cloning repository) - - Redis (automatically installed and started) + - Redis (must be pre-installed and running) - Mycelium (must be installed and running separately) ## Architecture @@ -114,8 +132,9 @@ The installer follows the standard herolib installer pattern: ## Notes - The installer builds from source rather than downloading pre-built binaries -- Mycelium is expected to be already installed and running in the environment -- Redis is automatically installed and started if not already running +- **Redis must be pre-installed and running** - the installer does not install Redis +- The installer checks if the binary already exists and skips rebuild unless `reset: true` is used +- Rust is automatically installed if not present (checks for `rustc` command) - The binary is built with `RUSTFLAGS="-A warnings"` to suppress warnings - Service management uses zinit by default