{% extends "base.html" %} {% from "_macros.html" import crumbs, empty_state, page_header %} {% block title %}Maintenance — Steward{% endblock %} {% block breadcrumb %}{{ crumbs([("Hosts", "/hosts/"), ("Maintenance", "")]) }}{% endblock %} {% block content %} {# A group's updates and reboots on a weekly cadence, one host at a time (#5768). What needs attention first: a run going now, a run that failed; then the plans with their recent runs. #} {% macro run_hosts(rows) -%}
{% for r in rows %}
{{ r.name }} {{ r.text }}
{% endfor %}
{%- endmacro %} {{ page_header("Maintenance") }}

Each plan updates an inventory group's hosts once a week, one host at a time. A host reboots only when its update needs it, unless the plan says otherwise; a swarm node is drained first and made active again after. The next host starts once the last is back in service. A failure stops the run, and the host's Maintenance failed figure can drive an alert rule.

{% if live %} {% for l in live %}

Running: {{ l.plan }} · started {{ l.run.started_at|ago }}{% if l.run.manual %} · run now{% endif %}

{{ run_hosts(l.rows) }}
{% endfor %} {% endif %} {% for f in failed %}
Failed: {{ f.plan }} · {{ f.run.finished_at|ago }} · {{ f.run.detail or "no detail" }}
{% endfor %} {% if plans %} {% for p in plans %}

{{ p.plan.name }}{% if not p.plan.enabled %} · paused{% endif %}

{% if session.user_role == 'admin' %}
{{ csrf_field() }}
{{ csrf_field() }}
{{ csrf_field() }}
{% endif %}
Group {{ p.group }} ({{ p.hosts }} host{{ 's' if p.hosts != 1 }}) · {{ p.when }} · reboot {{ {'if_required': 'only when required', 'always': 'always', 'never': 'never'}[p.plan.reboot_policy] }} {% if p.next %}· next {{ p.next|when }}{% endif %}
{% for r in p.runs %}
{{ {'running': 'Running', 'done': 'Done', 'failed': 'Failed', 'stopped': 'Stopped'}[r.run.state] }} · {{ r.run.started_at|when }}{% if r.run.manual %} · run now{% endif %}{% if r.run.detail %} · {{ r.run.detail|truncate(100) }}{% endif %}
{{ run_hosts(r.rows) }}
{% else %}

No runs yet.

{% endfor %}
{% endfor %} {% else %}
{{ empty_state("No maintenance plans yet." ~ (" Add one below." if session.user_role == 'admin' else "")) }}
{% endif %} {% if session.user_role == 'admin' %}

Add a plan

{% if groups %}
{{ csrf_field() }}

Hosts whose agent has no maintenance helper are skipped and listed; run Update agent on them. No host is started once the window has passed.

{% else %}

Plans work on inventory groups. Add one under Ansible → Inventory.

{% endif %}
{% endif %} {% endblock %}