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.
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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
Normal file
45
scripts/session_check.lua
Normal file
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user