feat: wire ansible blueprint, startup interrupted-run marker, git-pull task, cleanup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ def create_app(
|
||||
PLUGINS=cfg.get("plugins", {}),
|
||||
SMTP=cfg.get("smtp", {}),
|
||||
WEBHOOK=cfg.get("webhook", {}),
|
||||
ANSIBLE=cfg.get("ansible", {}),
|
||||
TESTING=testing,
|
||||
_RAW_CFG=cfg,
|
||||
)
|
||||
@@ -43,11 +44,13 @@ def create_app(
|
||||
from .dashboard.routes import dashboard_bp
|
||||
from .hosts.routes import hosts_bp
|
||||
from .alerts.routes import alerts_bp
|
||||
from .ansible.routes import ansible_bp
|
||||
|
||||
app.register_blueprint(auth_bp)
|
||||
app.register_blueprint(dashboard_bp)
|
||||
app.register_blueprint(hosts_bp)
|
||||
app.register_blueprint(alerts_bp)
|
||||
app.register_blueprint(ansible_bp)
|
||||
|
||||
# Build task registry
|
||||
app._task_registry = []
|
||||
@@ -64,6 +67,7 @@ def create_app(
|
||||
@app.before_serving
|
||||
async def startup():
|
||||
if not testing:
|
||||
await _mark_interrupted_runs(app)
|
||||
asyncio.create_task(_run_scheduler(app))
|
||||
|
||||
return app
|
||||
@@ -130,6 +134,45 @@ def _register_core_tasks(app: Quart, cfg: dict) -> None:
|
||||
),
|
||||
])
|
||||
|
||||
# Register git-pull tasks for each git source
|
||||
ansible_cfg = cfg.get("ansible", {})
|
||||
from .ansible.sources import get_sources
|
||||
for source in get_sources(ansible_cfg):
|
||||
if source["type"] != "git":
|
||||
continue
|
||||
_source = source # capture for closure
|
||||
|
||||
async def run_git_pull(src=_source):
|
||||
from .ansible.sources import git_pull
|
||||
await git_pull(src)
|
||||
|
||||
app._task_registry.append(
|
||||
ScheduledTask(
|
||||
name=f"ansible_git_pull_{_source['name']}",
|
||||
coro_factory=run_git_pull,
|
||||
interval_seconds=_source["pull_interval_seconds"],
|
||||
run_on_startup=True,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def _mark_interrupted_runs(app: Quart) -> None:
|
||||
"""Mark any runs still in 'running' state as 'interrupted' (process restart)."""
|
||||
from sqlalchemy import update
|
||||
from .models.ansible import AnsibleRun, AnsibleRunStatus
|
||||
from datetime import datetime, timezone
|
||||
|
||||
async with app.db_sessionmaker() as session:
|
||||
async with session.begin():
|
||||
await session.execute(
|
||||
update(AnsibleRun)
|
||||
.where(AnsibleRun.status == AnsibleRunStatus.running)
|
||||
.values(
|
||||
status=AnsibleRunStatus.interrupted,
|
||||
finished_at=datetime.now(timezone.utc),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def _run_scheduler(app: Quart) -> None:
|
||||
from .core.scheduler import start_scheduler
|
||||
|
||||
@@ -7,6 +7,7 @@ from sqlalchemy import delete
|
||||
|
||||
from fablednetmon.models.monitors import DnsResult, PingResult
|
||||
from fablednetmon.models.metrics import PluginMetric
|
||||
from fablednetmon.models.ansible import AnsibleRun
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from quart import Quart
|
||||
@@ -25,6 +26,7 @@ async def run_cleanup(app: "Quart") -> None:
|
||||
(PingResult, PingResult.probed_at),
|
||||
(DnsResult, DnsResult.resolved_at),
|
||||
(PluginMetric, PluginMetric.recorded_at),
|
||||
(AnsibleRun, AnsibleRun.started_at),
|
||||
]:
|
||||
result = await session.execute(
|
||||
delete(model).where(ts_col < cutoff)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<a href="/">Dashboard</a>
|
||||
<a href="/hosts/">Hosts</a>
|
||||
<a href="/alerts/">Alerts</a>
|
||||
<a href="/ansible/">Ansible</a>
|
||||
<a href="/logout">Logout ({{ session.username }})</a>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3 style="color:#8080ff;margin-bottom:0.75rem;">Ansible</h3>
|
||||
<p style="color:#606080;font-size:0.9rem;">Coming in Plan 3.</p>
|
||||
<p style="color:#606080;font-size:0.9rem;">
|
||||
<a href="/ansible/browse" style="color:#a0a0ff;">Browse playbooks</a> or view
|
||||
<a href="/ansible/" style="color:#a0a0ff;">run history</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user