Browse Source

Add desktop session detection to auto-boot-ollama-host script

Implement a new module for checking if the user is logged into a Windows desktop session. The script now skips Ollama startup and shutdown if the user is currently logged in, preventing interruptions. Update README to reflect new features and module structure.
main
Bastian (BaM) 3 months ago
parent
commit
eb83c4ccbd
  1. 31
      scripts/README.md
  2. 23
      scripts/auto-boot-ollama-host.lua
  3. 45
      scripts/session_check.lua
  4. 60
      scripts/ssh.lua

31
scripts/README.md

@ -5,13 +5,16 @@ This directory contains the refactored version of the auto-boot-ollama-host scri
## File Structure ## File Structure
### Main Script ### Main Script
- `auto-boot-ollama-host.lua` - Original monolithic script - `auto-boot-ollama-host.lua` - Original monolithic script
- `auto-boot-ollama-host-refactored.lua` - New modular main script - `auto-boot-ollama-host-refactored.lua` - New modular main script
### Modules ### Modules
#### `config.lua` #### `config.lua`
Handles all environment variable configuration with sensible defaults: Handles all environment variable configuration with sensible defaults:
- Docker configuration (container name, since time) - Docker configuration (container name, since time)
- Ollama service configuration (host, port) - Ollama service configuration (host, port)
- SSH configuration (port, user, identity file) - SSH configuration (port, user, identity file)
@ -19,24 +22,39 @@ Handles all environment variable configuration with sensible defaults:
- Wake-on-LAN configuration - Wake-on-LAN configuration
#### `utils.lua` #### `utils.lua`
Provides utility functions: Provides utility functions:
- `log(msg)` - Timestamped logging - `log(msg)` - Timestamped logging
- `getenv(name, def)` - Environment variable with default - `getenv(name, def)` - Environment variable with default
#### `network.lua` #### `network.lua`
Network-related functionality: Network-related functionality:
- `port_is_up(host, port, timeout)` - Check if TCP port is accessible - `port_is_up(host, port, timeout)` - Check if TCP port is accessible
- `send_wol(mac, bcast_ip, port)` - Send Wake-on-LAN magic packet - `send_wol(mac, bcast_ip, port)` - Send Wake-on-LAN magic packet
#### `ssh.lua` #### `ssh.lua`
SSH command execution: SSH command execution:
- `execute(command, user, host, port, identity_file)` - Execute remote SSH command - `execute(command, user, host, port, identity_file)` - Execute remote SSH command
- `execute_with_output(command, user, host, port, identity_file)` - Execute SSH command and return output
#### `ollama_manager.lua` #### `ollama_manager.lua`
Ollama service management: Ollama service management:
- `start_service(config)` - Start Ollama service via SSH - `start_service(config)` - Start Ollama service via SSH
- `stop_service_and_shutdown(config)` - Stop service and shutdown host - `stop_service_and_shutdown(config)` - Stop service and shutdown host
#### `session_check.lua`
Windows desktop session detection:
- `is_user_logged_in_enhanced(config)` - Check if user is logged into desktop session
## Benefits of Refactoring ## Benefits of Refactoring
1. **Separation of Concerns**: Each module has a single responsibility 1. **Separation of Concerns**: Each module has a single responsibility
@ -46,11 +64,22 @@ Ollama service management:
5. **Readability**: Clear structure and organization 5. **Readability**: Clear structure and organization
6. **Configuration**: Centralized configuration management 6. **Configuration**: Centralized configuration management
## New Features
### Desktop Session Detection
The refactored version now includes Windows desktop session detection:
- Checks if the SSH_USER is currently logged into a Windows desktop session
- If user is logged in, skips Ollama startup/shutdown to avoid interruption
- If user is not logged in, proceeds with normal operation
## Usage ## Usage
To use the refactored version, simply run: To use the refactored version, simply run:
```bash ```bash
lua auto-boot-ollama-host-refactored.lua lua auto-boot-ollama-host.lua
``` ```
The refactored version maintains full compatibility with the original script while providing better structure and maintainability. The refactored version maintains full compatibility with the original script while providing better structure and maintainability.

23
scripts/auto-boot-ollama-host.lua

@ -13,11 +13,23 @@ local utils = require("utils")
local network = require("network") local network = require("network")
local ssh = require("ssh") local ssh = require("ssh")
local ollama_manager = require("ollama_manager") local ollama_manager = require("ollama_manager")
local session_check = require("session_check")
-- Handle error pattern detection and recovery -- Handle error pattern detection and recovery
local function handle_error_pattern(config, powered_on) local function handle_error_pattern(config, powered_on)
utils.log(("Detected EHOSTUNREACH for Ollama (%s:%d)."):format(config.OLLAMA_HOST, config.OLLAMA_PORT)) utils.log(("Detected EHOSTUNREACH for Ollama (%s:%d)."):format(config.OLLAMA_HOST, config.OLLAMA_PORT))
-- Check if user is currently logged into a desktop session
utils.log("Checking if user is currently logged into desktop session...")
local user_logged_in = session_check.is_user_logged_in(config)
if user_logged_in then
utils.log(("User '%s' is currently logged into a desktop session. Skipping Ollama startup to avoid interruption."):format(config.SSH_USER))
return powered_on -- Return current powered_on state without changes
end
utils.log(("User '%s' is not logged into a desktop session. Proceeding with Ollama startup."):format(config.SSH_USER))
-- Send Wake-on-LAN if configured -- Send Wake-on-LAN if configured
if config.WOL_MAC ~= "" then if config.WOL_MAC ~= "" then
utils.log(("Sending WOL to %s via %s:%d"):format(config.WOL_MAC, config.WOL_BCAST, config.WOL_PORT)) utils.log(("Sending WOL to %s via %s:%d"):format(config.WOL_MAC, config.WOL_BCAST, config.WOL_PORT))
@ -40,6 +52,17 @@ end
-- Handle finish pattern detection and shutdown -- Handle finish pattern detection and shutdown
local function handle_finish_pattern(config) local function handle_finish_pattern(config)
utils.log(("Detected finish pattern: %q"):format(config.FINISH_PATTERN)) utils.log(("Detected finish pattern: %q"):format(config.FINISH_PATTERN))
-- Check if user is currently logged into a desktop session
utils.log("Checking if user is currently logged into desktop session before shutdown...")
local user_logged_in = session_check.is_user_logged_in(config)
if user_logged_in then
utils.log(("User '%s' is currently logged into a desktop session. Skipping shutdown to avoid interruption."):format(config.SSH_USER))
return -- Exit without shutting down
end
utils.log(("User '%s' is not logged into a desktop session. Proceeding with shutdown."):format(config.SSH_USER))
ollama_manager.stop_service_and_shutdown(config) ollama_manager.stop_service_and_shutdown(config)
end end

45
scripts/session_check.lua

@ -0,0 +1,45 @@
-- Windows desktop session check module for auto-boot-ollama-host
-- Checks if a specific user is currently logged into a Windows desktop session
local utils = require("utils")
local ssh = require("ssh")
local session_check = {}
-- Check if user is currently logged into a Windows desktop session using quser
-- Returns true if user is logged in, false otherwise
function session_check.is_user_logged_in(config)
utils.log(("Checking if user '%s' is logged into desktop session using quser..."):format(config.SSH_USER))
-- Use quser command to check for active sessions
-- This works regardless of Windows language (looks for console/rdp sessions)
local command = "quser 2>nul | findstr /i \"console rdp-tcp#\" >nul && echo 1 || echo 0"
local ok, output, err = ssh.execute_with_output(command, config.SSH_USER, config.OLLAMA_HOST, config.SSH_PORT, config.SSH_IDENTITY_FILE)
if not ok then
utils.log(("Failed to execute quser session check command: %s"):format(tostring(err)))
return false
end
if output and output ~= "" then
utils.log("Quser session check output received: " .. output)
-- Parse the result (remove any whitespace/newlines)
local clean_output = output:gsub("%s+", "")
local result = tonumber(clean_output)
if result == 1 then
utils.log(("User '%s' has an active desktop session"):format(config.SSH_USER))
return true
else
utils.log(("User '%s' has no active desktop sessions"):format(config.SSH_USER))
return false
end
else
utils.log("No output received from quser session check command")
return false
end
end
return session_check

60
scripts/ssh.lua

@ -66,4 +66,64 @@ function ssh_module.execute(command, user, host, port, identity_file)
end end
end end
-- Execute a remote command over SSH and return the output
-- Signature: ssh.execute_with_output(command, user, host, port, identity_file)
-- Returns: success, output, error_message
function ssh_module.execute_with_output(command, user, host, port, identity_file)
-- Basic validation and defaults
user = tostring(user or "")
host = tostring(host or "")
port = tonumber(port or 22) or 22
identity_file = tostring(identity_file or "")
-- Build base ssh command (run locally)
local dest = (user ~= "" and (user .. "@" .. host) or host)
local pieces = {
"ssh",
"-p", tostring(port),
"-o", "BatchMode=yes",
"-o", "ConnectTimeout=30",
"-o", "ServerAliveInterval=5",
"-o", "ServerAliveCountMax=1",
"-o", "UserKnownHostsFile=/root/.ssh/known_hosts",
"-o", "StrictHostKeyChecking=yes",
}
if identity_file ~= "" then
table.insert(pieces, "-i")
table.insert(pieces, identity_file)
end
table.insert(pieces, dest)
-- Pass remote command as provided
table.insert(pieces, "--")
table.insert(pieces, command)
-- Join with spaces for io.popen
local function join(args)
return table.concat(args, " ")
end
local full = join(pieces)
utils.log("SSH exec (with output): " .. full)
-- Use io.popen to capture output
local fh = io.popen(full, "r")
if not fh then
return false, "", "Failed to open SSH command"
end
local output = fh:read("*a")
local success, reason, code = fh:close()
if success then
utils.log("SSH command completed successfully with output")
return true, output, nil
else
local msg = string.format("SSH failed: reason=%s code=%s", tostring(reason), tostring(code))
utils.log(msg)
return false, output, msg
end
end
return ssh_module return ssh_module

Loading…
Cancel
Save