You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
4.5 KiB
121 lines
4.5 KiB
-- Purpose: Minimal log watcher using `docker logs -f` as input.
|
|
-- Requirements: lua 5.4 + luasocket + docker CLI inside the container.
|
|
-- Notes:
|
|
-- - Pattern match is plain substring (fast & simple).
|
|
-- - Optional Wake-on-LAN is native (no external tools).
|
|
-- - Optional port-wait is provided but commented out (mirrors original bash idea).
|
|
|
|
-- Import modules
|
|
local config = require("config")
|
|
local utils = require("utils")
|
|
local network = require("network")
|
|
local ollama_manager = require("ollama_manager")
|
|
local session_check = require("session_check")
|
|
|
|
-- Handle error pattern detection and recovery
|
|
local function handle_error_pattern(config, powered_on, service_started)
|
|
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, service_started -- Return current states 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
|
|
if config.WOL_MAC ~= "" then
|
|
utils.log(("Sending WOL to %s via %s:%d"):format(config.WOL_MAC, config.WOL_BCAST, config.WOL_PORT))
|
|
local ok, err = network.send_wol(config.WOL_MAC, config.WOL_BCAST, config.WOL_PORT)
|
|
if ok then
|
|
powered_on = true
|
|
utils.log(("Successfully sent WOL to %s via %s:%d"):format(config.WOL_MAC, config.WOL_BCAST, config.WOL_PORT))
|
|
else
|
|
utils.log("WOL failed: " .. tostring(err))
|
|
end
|
|
end
|
|
|
|
-- Wait for SSH and start service
|
|
utils.log("Waiting for SSH to become reachable...")
|
|
if network.port_is_up(config.OLLAMA_HOST, config.SSH_PORT, 60) then
|
|
-- If SSH is reachable, the host is powered on (regardless of WOL status)
|
|
powered_on = true
|
|
utils.log("SSH is reachable - host is powered on")
|
|
if ollama_manager.start_service(config) then
|
|
service_started = true
|
|
end
|
|
else
|
|
utils.log("SSH timeout - host may not be powered on")
|
|
end
|
|
return powered_on, service_started
|
|
end
|
|
|
|
-- Handle finish pattern detection and shutdown
|
|
local function handle_finish_pattern(config, powered_on, service_started)
|
|
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))
|
|
|
|
-- If service was started, stop it since user is now active
|
|
if service_started then
|
|
utils.log("Stopping Ollama service since user is now active on desktop")
|
|
ollama_manager.stop_service(config)
|
|
service_started = false
|
|
end
|
|
|
|
return powered_on, service_started -- Exit without shutting down host
|
|
end
|
|
|
|
utils.log(("User '%s' is not logged into a desktop session. Proceeding with shutdown."):format(config.SSH_USER))
|
|
if service_started then
|
|
ollama_manager.stop_service(config)
|
|
end
|
|
ollama_manager.shutdown_host(config)
|
|
powered_on = false
|
|
service_started = false
|
|
return powered_on, service_started
|
|
end
|
|
|
|
-- Main application logic
|
|
local function main()
|
|
utils.log(("Watching container='%s' since='%s'"):format(config.CONTAINER_NAME, config.SINCE))
|
|
utils.log(("Looking for pattern: %q"):format(config.ERROR_PATTERN))
|
|
|
|
local cmd = ("docker logs -f --since %q %q 2>&1"):format(config.SINCE, config.CONTAINER_NAME)
|
|
local powered_on = false
|
|
local service_started = false
|
|
|
|
while true do
|
|
local fh = assert(io.popen(cmd, "r"))
|
|
|
|
for line in fh:lines() do
|
|
-- Handle error pattern detection
|
|
if line:find(config.ERROR_PATTERN, 1, true) ~= nil then
|
|
powered_on, service_started = handle_error_pattern(config, powered_on, service_started)
|
|
end
|
|
|
|
-- Handle finish pattern detection
|
|
if line:find(config.FINISH_PATTERN, 1, true) ~= nil and powered_on == true then
|
|
powered_on, service_started = handle_finish_pattern(config, powered_on, service_started)
|
|
break
|
|
end
|
|
end
|
|
|
|
fh:close()
|
|
utils.log("Restarting log watch loop...")
|
|
end
|
|
end
|
|
|
|
-- Run the application
|
|
main()
|
|
|