Prepara l'architettura multi-nodo (MediaMTX+ffmpeg) con assignment URL per sessione, admin di provision/drain e provider Cloud/DNS astratti verso mltv-stream.net. Co-authored-by: Cursor <cursoragent@cursor.com>
55 lines
2.3 KiB
ERB
55 lines
2.3 KiB
ERB
<% content_for :body_class, "admin-body" %>
|
|
<h2><%= t("admin.stream_nodes.title") %></h2>
|
|
<p class="admin-muted">
|
|
<%= t("admin.stream_nodes.providers", cloud: @cloud_provider, dns: @dns_provider) %>
|
|
</p>
|
|
|
|
<p>
|
|
<%= button_to t("admin.stream_nodes.provision_lab"), admin_stream_nodes_path, method: :post, params: { kind: "lab" }, class: "admin-btn" %>
|
|
<% if @hetzner_configured %>
|
|
<%= button_to t("admin.stream_nodes.provision_cloud"), admin_stream_nodes_path, method: :post, params: { kind: "cloud" }, class: "admin-btn",
|
|
form: { data: { confirm: t("admin.stream_nodes.provision_cloud_confirm") } } %>
|
|
<% else %>
|
|
<span class="admin-muted"><%= t("admin.stream_nodes.hetzner_token_missing") %></span>
|
|
<% end %>
|
|
</p>
|
|
|
|
<table class="admin-table">
|
|
<thead>
|
|
<tr>
|
|
<th><%= t("admin.stream_nodes.col.slug") %></th>
|
|
<th><%= t("admin.stream_nodes.col.role") %></th>
|
|
<th><%= t("admin.stream_nodes.col.status") %></th>
|
|
<th><%= t("admin.stream_nodes.col.slots") %></th>
|
|
<th><%= t("admin.stream_nodes.col.hostname") %></th>
|
|
<th><%= t("admin.stream_nodes.col.provider") %></th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% @nodes.each do |node| %>
|
|
<tr>
|
|
<td><code><%= node.slug %></code></td>
|
|
<td><%= node.role %></td>
|
|
<td><%= node.status %></td>
|
|
<td><%= node.active_publishers %> / <%= node.max_publishers %> (free <%= node.free_slots %>)</td>
|
|
<td><code><%= node.hostname %></code></td>
|
|
<td><%= node.provider %><% if node.provider_instance_id.present? %> · <%= node.provider_instance_id %><% end %></td>
|
|
<td class="admin-actions">
|
|
<% if node.slug != "home" %>
|
|
<% if node.status == "ready" %>
|
|
<%= button_to t("admin.stream_nodes.drain"), drain_admin_stream_node_path(node), method: :post, class: "admin-btn admin-btn-secondary" %>
|
|
<% end %>
|
|
<%= button_to t("admin.stream_nodes.destroy"), admin_stream_node_path(node), method: :delete, class: "admin-btn admin-btn-danger", form: { data: { confirm: t("admin.stream_nodes.destroy_confirm", slug: node.slug) } } %>
|
|
<% end %>
|
|
</td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
|
|
<% if @lab_hosts.present? %>
|
|
<h3><%= t("admin.stream_nodes.hosts_title") %></h3>
|
|
<pre class="admin-pre"><%= @lab_hosts %></pre>
|
|
<% end %>
|