150 lines
7.6 KiB
HTML
150 lines
7.6 KiB
HTML
{{define "config_preview"}}
|
||
{{template "device_nav" .}}
|
||
<div class="card">
|
||
<div class="section-title">
|
||
<div>
|
||
<h2>配置预览</h2>
|
||
<div class="muted small">基于模板、Profile 和 Overlay 生成完整配置预览;此页面不会下发到设备。</div>
|
||
</div>
|
||
<a class="btn ghost" href="/ui/devices/{{.Device.DeviceID}}">返回节点详情</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>生成配置预览</h2>
|
||
{{if .ConfigSources.Root}}<div class="muted small">Media 仓库:<span class="mono">{{.ConfigSources.Root}}</span></div>{{end}}
|
||
<div class="muted small" style="margin-top:8px">
|
||
<span class="mono">config_id</span> 是配置名,默认会带上 <span class="mono">device_id</span>(当前设备:<span class="mono">{{.Device.DeviceID}}</span>);<span class="mono">config_version</span> 表示本次生成版本;<span class="mono">SHA256</span> 是最终文件内容指纹。
|
||
</div>
|
||
<form method="post" action="/ui/devices/{{.Device.DeviceID}}/config-preview" style="margin-top:12px">
|
||
<div class="row">
|
||
<div>
|
||
<div class="muted small">模板</div>
|
||
<select name="template">
|
||
{{range .ConfigSources.Templates}}
|
||
<option value="{{.Name}}" {{if eq .Name $.SelectedTemplate}}selected{{end}}>{{.Name}}</option>
|
||
{{end}}
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<div class="muted small">Profile</div>
|
||
<select name="profile">
|
||
{{range .ConfigSources.Profiles}}
|
||
<option value="{{.Name}}" {{if eq .Name $.SelectedProfile}}selected{{end}}>{{.Name}}</option>
|
||
{{end}}
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<div class="muted small">config_id</div>
|
||
<input name="config_id" value="{{.SelectedConfigID}}" />
|
||
</div>
|
||
<div>
|
||
<div class="muted small">config_version</div>
|
||
<input name="config_version" value="{{.SelectedVersion}}" placeholder="留空自动生成" />
|
||
</div>
|
||
</div>
|
||
<div style="margin-top:12px">
|
||
<div class="muted small">Overlay</div>
|
||
<div class="actions" style="margin-top:6px">
|
||
{{range .ConfigSources.Overlays}}
|
||
<label class="btn ghost">
|
||
<input type="checkbox" name="overlay" value="{{.Name}}" {{if hasString $.SelectedOverlays .Name}}checked{{end}} />
|
||
{{.Name}}
|
||
</label>
|
||
{{end}}
|
||
</div>
|
||
</div>
|
||
<div class="actions" style="margin-top:12px">
|
||
<button type="submit">生成预览</button>
|
||
<button type="button" disabled>上传为候选配置</button>
|
||
{{if and .ConfigStatus .ConfigStatus.Candidate .ConfigStatus.Candidate.Exists}}
|
||
<button type="submit" formaction="/ui/devices/{{.Device.DeviceID}}/config-candidate/apply">应用候选配置</button>
|
||
{{else}}
|
||
<button type="button" disabled>应用候选配置</button>
|
||
{{end}}
|
||
<a class="btn ghost" href="/ui/devices/{{.Device.DeviceID}}">查看当前运行配置</a>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
{{if .ConfigPreview}}
|
||
<div class="card">
|
||
<h2>预览摘要</h2>
|
||
<div class="row" style="margin-top:10px">
|
||
<div><div class="muted small">配置 ID</div><div class="mono">{{index .ConfigPreview.Metadata "config_id"}}</div></div>
|
||
<div><div class="muted small">版本</div><div class="mono">{{index .ConfigPreview.Metadata "config_version"}}</div></div>
|
||
<div><div class="muted small">模板</div><div class="mono">{{index .ConfigPreview.Metadata "template"}}</div></div>
|
||
<div><div class="muted small">Profile</div><div class="mono">{{index .ConfigPreview.Metadata "profile"}}</div></div>
|
||
<div><div class="muted small">大小</div><div class="mono">{{.ConfigPreview.Size}} bytes</div></div>
|
||
</div>
|
||
<div style="margin-top:10px">
|
||
<div class="muted small">Overlay</div>
|
||
<div class="mono">{{if index .ConfigPreview.Metadata "overlays"}}{{range $i, $name := index .ConfigPreview.Metadata "overlays"}}{{if $i}}, {{end}}{{$name}}{{end}}{{else}}-{{end}}</div>
|
||
</div>
|
||
<div style="margin-top:10px">
|
||
<div class="muted small">SHA256</div>
|
||
<div class="mono small">{{.ConfigPreview.Sha256}}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2>完整 JSON</h2>
|
||
<form method="post" action="/ui/devices/{{.Device.DeviceID}}/config-candidate" class="actions" style="margin-bottom:10px">
|
||
<input type="hidden" name="json" value="{{.ConfigPreview.JSON}}" />
|
||
<button type="submit">上传为候选配置</button>
|
||
<button type="submit" formaction="/ui/devices/{{.Device.DeviceID}}/config-candidate/apply">应用候选配置</button>
|
||
<a class="btn ghost" href="/ui/devices/{{.Device.DeviceID}}">查看当前运行配置</a>
|
||
</form>
|
||
{{if .RawText}}
|
||
<details>
|
||
<summary class="muted small">展开完整 JSON</summary>
|
||
<pre>{{.ConfigPreview.JSON}}</pre>
|
||
</details>
|
||
{{else}}
|
||
<details open>
|
||
<summary class="muted small">展开完整 JSON</summary>
|
||
<pre>{{.ConfigPreview.JSON}}</pre>
|
||
</details>
|
||
{{end}}
|
||
</div>
|
||
{{end}}
|
||
|
||
{{if and (eq .ResultTitle "应用候选配置结果") .ConfigStatus}}
|
||
<div class="card">
|
||
<h2>应用结果摘要</h2>
|
||
<div class="row" style="margin-top:10px">
|
||
<div>
|
||
<div class="muted small">当前运行</div>
|
||
<div class="mono">{{if .ConfigStatus.Metadata.ConfigID}}{{.ConfigStatus.Metadata.ConfigID}} / {{if .ConfigStatus.Metadata.ConfigVersion}}{{.ConfigStatus.Metadata.ConfigVersion}}{{else}}未标记{{end}}{{else}}未标记{{end}}</div>
|
||
<div class="muted small mono" style="margin-top:6px">{{if .ConfigStatus.Metadata.Overlays}}{{range $i, $name := .ConfigStatus.Metadata.Overlays}}{{if $i}}, {{end}}{{$name}}{{end}}{{else}}-{{end}}</div>
|
||
<div class="muted small mono" style="margin-top:6px">sha: {{shortHash .ConfigStatus.Sha256}}</div>
|
||
</div>
|
||
<div>
|
||
<div class="muted small">上一份配置</div>
|
||
<div class="mono">{{if and .ConfigStatus.LastGood .ConfigStatus.LastGood.Exists .ConfigStatus.LastGood.Metadata.ConfigID}}{{.ConfigStatus.LastGood.Metadata.ConfigID}} / {{if .ConfigStatus.LastGood.Metadata.ConfigVersion}}{{.ConfigStatus.LastGood.Metadata.ConfigVersion}}{{else}}未标记{{end}}{{else}}-{{end}}</div>
|
||
<div class="muted small mono" style="margin-top:6px">{{if and .ConfigStatus.LastGood .ConfigStatus.LastGood.Metadata.Overlays}}{{range $i, $name := .ConfigStatus.LastGood.Metadata.Overlays}}{{if $i}}, {{end}}{{$name}}{{end}}{{else}}-{{end}}</div>
|
||
<div class="muted small mono" style="margin-top:6px">sha: {{if .ConfigStatus.LastGood}}{{shortHash .ConfigStatus.LastGood.Sha256}}{{end}}</div>
|
||
</div>
|
||
<div>
|
||
<div class="muted small">candidate</div>
|
||
<div>{{if and .ConfigStatus.Candidate .ConfigStatus.Candidate.Exists}}<span class="pill">仍存在</span>{{else}}<span class="pill ok">已清空</span>{{end}}</div>
|
||
</div>
|
||
<div>
|
||
<div class="muted small">media-server</div>
|
||
<div>{{if .ConfigStatus.MediaServer.Running}}<span class="pill ok">运行中</span>{{else}}<span class="pill bad">未运行</span>{{end}}</div>
|
||
</div>
|
||
</div>
|
||
{{if and .ConfigStatus.LastGood .ConfigStatus.Sha256 .ConfigStatus.LastGood.Sha256 (eq .ConfigStatus.Metadata.ConfigID .ConfigStatus.LastGood.Metadata.ConfigID) (eq .ConfigStatus.Metadata.ConfigVersion .ConfigStatus.LastGood.Metadata.ConfigVersion) (ne .ConfigStatus.Sha256 .ConfigStatus.LastGood.Sha256)}}
|
||
<div class="muted small" style="margin-top:10px">当前运行与上一份配置回滚点的 <span class="mono">config_id/config_version</span> 相同,但文件内容不同,请以 <span class="mono">overlay</span> 和 <span class="mono">sha</span> 为准。</div>
|
||
{{end}}
|
||
</div>
|
||
{{end}}
|
||
|
||
{{if .RawText}}
|
||
<div class="card">
|
||
<h2>{{if .ResultTitle}}{{.ResultTitle}}{{else}}执行结果{{end}}</h2>
|
||
<pre>{{.RawText}}</pre>
|
||
</div>
|
||
{{end}}
|
||
{{end}}
|