mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-02 18:17:11 +09:00
The agent (serverkit-agent bbaf4e2) now sends install_dir and config_dir in system_info. Panel side: - servers.agent_install_dir + agent_config_dir columns (migration 047, idempotent guard like its siblings) with the same coalesce contract as the other system_info fields — a transient payload gap never wipes a stored value - exposed in Server.to_dict and /servers/available; TargetPicker passes them on the agent target - the File Manager rail prefers the reported config dir over the installer convention (backslash-normalized for Windows agents; agent-logs link derives <config_dir>/logs) - proving test: full system_info -> DB -> available round trip + coalesce survival Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
75 lines
2.8 KiB
Python
75 lines
2.8 KiB
Python
"""/servers/available feeds the target pickers (File Manager, Cron, …) — it
|
|
must carry os_type so target-aware UIs can offer paths that actually exist on
|
|
the selected box (a Windows agent has no /var/www)."""
|
|
from app import db
|
|
from app.models.server import Server
|
|
from app.services.remote_docker_service import RemoteDockerService
|
|
|
|
|
|
def _make_server(**overrides):
|
|
data = dict(
|
|
name='Test Agent',
|
|
hostname='agent.example.com',
|
|
ip_address='203.0.113.20',
|
|
status='online',
|
|
)
|
|
data.update(overrides)
|
|
server = Server(**data)
|
|
db.session.add(server)
|
|
db.session.commit()
|
|
return server
|
|
|
|
|
|
def test_available_servers_include_os_type(app):
|
|
with app.app_context():
|
|
_make_server(name='Win Agent', os_type='windows')
|
|
|
|
servers = RemoteDockerService.get_available_servers()
|
|
remote = [s for s in servers if not s['is_local']]
|
|
assert remote, 'online server missing from the available list'
|
|
assert remote[0]['os_type'] == 'windows'
|
|
|
|
|
|
def test_available_servers_os_type_null_for_legacy_agents(app):
|
|
"""Agents enrolled before sysinfo reporting have no os_type — the field
|
|
must still be present (null), not absent, so consumers can key off it."""
|
|
with app.app_context():
|
|
_make_server(name='Old Agent', os_type=None)
|
|
|
|
servers = RemoteDockerService.get_available_servers()
|
|
remote = [s for s in servers if not s['is_local']]
|
|
assert remote
|
|
assert 'os_type' in remote[0]
|
|
assert remote[0]['os_type'] is None
|
|
|
|
|
|
def test_agent_footprint_round_trip(app):
|
|
"""The agent's self-reported install_dir/config_dir (system_info) land on
|
|
the Server row via update_system_info and surface in /servers/available —
|
|
the chain the File Manager's per-target quick links ride on."""
|
|
from app.services.agent_registry import agent_registry
|
|
|
|
with app.app_context():
|
|
server = _make_server(name='Reporting Agent', os_type='linux')
|
|
|
|
agent_registry.update_system_info(server.id, {
|
|
'install_dir': '/usr/local/bin',
|
|
'config_dir': '/etc/serverkit-agent',
|
|
})
|
|
|
|
db.session.refresh(server)
|
|
assert server.agent_install_dir == '/usr/local/bin'
|
|
assert server.agent_config_dir == '/etc/serverkit-agent'
|
|
|
|
remote = [s for s in RemoteDockerService.get_available_servers()
|
|
if not s['is_local']]
|
|
assert remote[0]['agent_install_dir'] == '/usr/local/bin'
|
|
assert remote[0]['agent_config_dir'] == '/etc/serverkit-agent'
|
|
|
|
# A later payload without the keys (transient probe gap) must not
|
|
# wipe the stored values — same coalesce contract as the other
|
|
# system_info columns.
|
|
agent_registry.update_system_info(server.id, {'hostname': 'still-here'})
|
|
db.session.refresh(server)
|
|
assert server.agent_config_dir == '/etc/serverkit-agent'
|