mirror of
https://github.com/cuigh/swirl
synced 2024-12-31 16:23:13 +00:00
519 lines
19 KiB
Go
519 lines
19 KiB
Go
{{ extends "_base" }}
|
|
{{ import "../_modules/detail" }}
|
|
|
|
{{ block script() }}
|
|
<script>$(() => new Swirl.Service.DetailPage())</script>
|
|
{{ end }}
|
|
|
|
{{ block body_content() }}
|
|
<div class="container">
|
|
<nav class="breadcrumb has-succeeds-separator is-small is-marginless" aria-label="breadcrumbs">
|
|
<ul>
|
|
<li><a href="/">{{ i18n("menu.home") }}</a></li>
|
|
<li><a href="/service/">{{ i18n("menu.service") }}</a></li>
|
|
<li class="is-active"><a>{{ i18n("menu.detail") }}</a></li>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
|
|
<section class="hero is-small is-light">
|
|
<div class="hero-body">
|
|
<div class="container">
|
|
<h2 id="h2-name" class="title is-2">
|
|
{{ .Service.Spec.Name }}
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<nav class="navbar has-shadow">
|
|
<div class="container">
|
|
<div class="navbar-brand">
|
|
<a class="navbar-item is-tab is-active" href="/service/{{.Service.Spec.Name}}/detail">{{ i18n("menu.detail") }}</a>
|
|
<a class="navbar-item is-tab" href="/service/{{.Service.Spec.Name}}/raw">{{ i18n("menu.raw") }}</a>
|
|
<a class="navbar-item is-tab" href="/service/{{.Service.Spec.Name}}/logs">{{ i18n("menu.log") }}</a>
|
|
<a class="navbar-item is-tab" href="/service/{{.Service.Spec.Name}}/edit">{{ i18n("menu.edit") }}</a>
|
|
<a class="navbar-item is-tab" href="/service/{{.Service.Spec.Name}}/perm">{{ i18n("menu.perm") }}</a>
|
|
<a class="navbar-item is-tab" href="/service/{{.Service.Spec.Name}}/stats">{{ i18n("menu.stats") }}</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<section class="section">
|
|
<div class="container">
|
|
<div class="buttons">
|
|
{{ if .Service.Spec.Mode.Replicated }}
|
|
<button id="btn-scale" class="button is-dark">
|
|
<span class="icon"><i class="fas fa-adjust"></i></span><span>{{ i18n("button.scale") }}</span>
|
|
</button>
|
|
{{ end }}
|
|
<button id="btn-restart" class="button is-dark">
|
|
<span class="icon"><i class="fas fa-redo"></i></span><span>{{ i18n("button.restart") }}</span>
|
|
</button>
|
|
<button id="btn-rollback" class="button is-dark">
|
|
<span class="icon"><i class="fas fa-reply"></i></span><span>{{ i18n("button.rollback") }}</span>
|
|
</button>
|
|
<button id="btn-delete" class="button is-danger">
|
|
<span class="icon"><i class="far fa-trash-alt"></i></span><span>{{ i18n("button.delete") }}</span>
|
|
</button>
|
|
</div>
|
|
<div class="message is-primary">
|
|
<div class="message-body">
|
|
<dl class="is-horizontal is-marginless">
|
|
<dt class="has-text-left">ID</dt>
|
|
<dd>{{ .Service.ID }}</dd>
|
|
<dt class="has-text-left">{{ i18n("field.image") }}</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.ContainerSpec.Image }}</dd>
|
|
<dt class="has-text-left">Mode</dt>
|
|
<dd>
|
|
<div class="tags has-addons">
|
|
<span class="tag is-info">{{if .Service.Spec.Mode.Replicated}}replicated{{else}}global{{end}}</span>
|
|
{{if .Service.Spec.Mode.Replicated}}
|
|
<span id="span-replicas" class="tag is-success">{{.Service.Replicas}}</span>
|
|
{{end}}
|
|
</div>
|
|
</dd>
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.Command }}
|
|
<dt class="has-text-left">Command</dt>
|
|
<dd>{{ json(.Service.Spec.TaskTemplate.ContainerSpec.Command) }}</dd>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.Args }}
|
|
<dt class="has-text-left">Args</dt>
|
|
<dd>{{ json(.Service.Spec.TaskTemplate.ContainerSpec.Args) }}</dd>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.Dir }}
|
|
<dt class="has-text-left">Work directory</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.ContainerSpec.Dir }}</dd>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.User }}
|
|
<dt class="has-text-left">User</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.ContainerSpec.User }}</dd>
|
|
{{ end }}
|
|
<dt class="has-text-left">{{ i18n("field.created-at") }}</dt>
|
|
<dd>{{ time(.Service.CreatedAt) }}</dd>
|
|
<dt class="has-text-left">{{ i18n("field.updated-at") }}</dt>
|
|
<dd>{{ time(.Service.UpdatedAt) }}</dd>
|
|
{{ if .Service.UpdateStatus }}
|
|
<dt class="has-text-left">{{ i18n("service.field.update-status") }}</dt>
|
|
<dd>{{ .Service.UpdateStatus.State }}({{ .Service.UpdateStatus.Message }})</dd>
|
|
{{ end }}
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="block">
|
|
<div class="block-header">
|
|
<p>Command line</p>
|
|
</div>
|
|
<div class="block-body is-bordered">
|
|
{{ .Command }}
|
|
</div>
|
|
</div>
|
|
|
|
{{if .Service.Endpoint.VirtualIPs}}
|
|
<div class="block">
|
|
<div class="block-header">
|
|
<p>Networks</p>
|
|
</div>
|
|
<div class="block-body is-paddingless">
|
|
<table class="table is-bordered is-narrow is-fullwidth is-marginless">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>ID</th>
|
|
<th>Address</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Service.Networks}}
|
|
<tr>
|
|
<td><a href="/network/{{.Name}}/detail">{{.Name}}</a></td>
|
|
<td>{{.ID}}</td>
|
|
<td>{{.Address}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{ yield tags(title="Environment variables", tags=.Service.Env) }}
|
|
{{ yield tags(title="Service labels", tags=.Service.Spec.Annotations.Labels) }}
|
|
{{ yield tags(title="Container labels", tags=.Service.Spec.TaskTemplate.ContainerSpec.Labels) }}
|
|
|
|
{{if .Service.Spec.TaskTemplate.ContainerSpec.Mounts}}
|
|
<div class="block">
|
|
<div class="block-header">
|
|
<p>Mounts</p>
|
|
</div>
|
|
<div class="block-body is-paddingless">
|
|
<table class="table is-bordered is-striped is-narrow is-fullwidth is-marginless">
|
|
<thead>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Source</th>
|
|
<th>Target</th>
|
|
<th>Read only</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Service.Spec.TaskTemplate.ContainerSpec.Mounts}}
|
|
<tr>
|
|
<td>{{.Type}}</td>
|
|
<td>{{.Source}}</td>
|
|
<td>{{.Target}}</td>
|
|
<td>{{.ReadOnly ? "Yes" : "No"}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<div class="tabs is-toggle is-fullwidth is-marginless" data-target="tab-content">
|
|
<ul>
|
|
<li class="is-active">
|
|
<a>
|
|
<span>Ports</span>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a>
|
|
<span>Configurations</span>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a>
|
|
<span>Resources</span>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a>
|
|
<span>Placement</span>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a>
|
|
<span>Schedule policy</span>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a>
|
|
<span>Log driver</span>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a>
|
|
<span>Host & DNS</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div id="tab-content" class="tabs-content has-no-top-border">
|
|
<div>
|
|
<dl class="is-horizontal1 is-marginless">
|
|
<dt class="has-text-left">Resolution mode</dt>
|
|
<dd>{{ .Service.Endpoint.Spec.Mode }}</dd>
|
|
<dt class="has-text-left">Port config</dt>
|
|
<dd>
|
|
<table class="table is-bordered is-narrow is-fullwidth is-marginless">
|
|
<thead>
|
|
<tr>
|
|
<th>Host</th>
|
|
<th>Container</th>
|
|
<th>Protocol</th>
|
|
<th>Mode</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range i, p := .Service.Endpoint.Spec.Ports}}
|
|
<tr>
|
|
<td>{{p.PublishedPort}}</td>
|
|
<td>{{p.TargetPort}}</td>
|
|
<td>{{p.Protocol}}</td>
|
|
<td>{{p.PublishMode}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div style="display: none">
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.Secrets }}
|
|
<div class="field">
|
|
<p class="lead is-5">Secrets</p>
|
|
<table class="table is-bordered is-narrow is-fullwidth is-marginless">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>File name</th>
|
|
<th>UID</th>
|
|
<th>GID</th>
|
|
<th>Mode</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{ range .Service.Spec.TaskTemplate.ContainerSpec.Secrets }}
|
|
<tr>
|
|
<td>{{ .SecretName }}</td>
|
|
<td>{{ .File.Name }}</td>
|
|
<td>{{ .File.UID }}</td>
|
|
<td>{{ .File.GID }}</td>
|
|
<td>{{ .File.Mode }}</td>
|
|
</tr>
|
|
{{ end }}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.Configs }}
|
|
<div class="field">
|
|
<p class="lead is-5">Configs</p>
|
|
<table class="table is-bordered is-narrow is-fullwidth is-marginless">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>File name</th>
|
|
<th>UID</th>
|
|
<th>GID</th>
|
|
<th>Mode</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{ range .Service.Spec.TaskTemplate.ContainerSpec.Configs }}
|
|
<tr>
|
|
<td>{{ .ConfigName }}</td>
|
|
<td>{{ .File.Name }}</td>
|
|
<td>{{ .File.UID }}</td>
|
|
<td>{{ .File.GID }}</td>
|
|
<td>{{ .File.Mode }}</td>
|
|
</tr>
|
|
{{ end }}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
<div style="display: none">
|
|
{{ if .Service.Spec.TaskTemplate.Resources }}
|
|
<div class="columns">
|
|
<div class="column">
|
|
<p class="lead is-5">Limits</p>
|
|
{{ if .Service.Spec.TaskTemplate.Resources.Limits }}
|
|
<dl class="is-horizontal is-marginless">
|
|
<dt class="has-text-left">CPU</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.Resources.Limits.NanoCPUs / 1e9 }}</dd>
|
|
<dt class="has-text-left">Memory</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.Resources.Limits.MemoryBytes / 1024 / 1024 }}M</dd>
|
|
</dl>
|
|
{{ end }}
|
|
</div>
|
|
<div class="is-divider-vertical" data-content=""></div>
|
|
<div class="column">
|
|
<p class="lead is-5">Reservations</p>
|
|
{{ if .Service.Spec.TaskTemplate.Resources.Reservations }}
|
|
<dl class="is-horizontal is-marginless">
|
|
<dt class="has-text-left">CPU</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.Resources.Reservations.NanoCPUs / 1e9 }}</dd>
|
|
<dt class="has-text-left">Memory</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.Resources.Reservations.MemoryBytes / 1024 / 1024 }}M</dd>
|
|
</dl>
|
|
{{ end }}
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
<div style="display: none">
|
|
{{ if .Service.Spec.TaskTemplate.Placement }}
|
|
<div class="columns">
|
|
<div class="column">
|
|
<p class="lead is-5">Constraints</p>
|
|
<table class="table is-bordered is-narrow is-fullwidth is-marginless">
|
|
<tbody>
|
|
{{ range .Service.Spec.TaskTemplate.Placement.Constraints }}
|
|
<tr>
|
|
<td>{{ . }}</td>
|
|
</tr>
|
|
{{ end }}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="column">
|
|
<p class="lead is-5">Preferences</p>
|
|
<table class="table is-bordered is-narrow is-fullwidth is-marginless">
|
|
<tbody>
|
|
{{ range .Service.Spec.TaskTemplate.Placement.Preferences }}
|
|
<tr>
|
|
<td>{{ .Spread }}</td>
|
|
</tr>
|
|
{{ end }}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
<div style="display: none">
|
|
<div class="columns">
|
|
<div class="column">
|
|
<p class="lead is-5">Update</p>
|
|
{{ if .Service.Spec.UpdateConfig }}
|
|
<dl class="is-horizontal is-marginless">
|
|
<dt class="has-text-left">Parallelism</dt>
|
|
<dd>{{ .Service.Spec.UpdateConfig.Parallelism }}</dd>
|
|
<dt class="has-text-left">Delay</dt>
|
|
<dd>{{ .Service.Spec.UpdateConfig.Delay }}</dd>
|
|
<dt class="has-text-left">Failure action</dt>
|
|
<dd>{{ .Service.Spec.UpdateConfig.FailureAction }}</dd>
|
|
<dt class="has-text-left">Order</dt>
|
|
<dd>{{ .Service.Spec.UpdateConfig.Order }}</dd>
|
|
</dl>
|
|
{{ end }}
|
|
</div>
|
|
<div class="is-divider-vertical" data-content=""></div>
|
|
<div class="column">
|
|
<p class="lead is-5">Rollback</p>
|
|
{{ if .Service.Spec.RollbackConfig }}
|
|
<dl class="is-horizontal is-marginless">
|
|
<dt class="has-text-left">Parallelism</dt>
|
|
<dd>{{ .Service.Spec.RollbackConfig.Parallelism }}</dd>
|
|
<dt class="has-text-left">Delay</dt>
|
|
<dd>{{ .Service.Spec.RollbackConfig.Delay }}</dd>
|
|
<dt class="has-text-left">Failure action</dt>
|
|
<dd>{{ .Service.Spec.RollbackConfig.FailureAction }}</dd>
|
|
<dt class="has-text-left">Order</dt>
|
|
<dd>{{ .Service.Spec.RollbackConfig.Order }}</dd>
|
|
</dl>
|
|
{{ end }}
|
|
</div>
|
|
<div class="is-divider-vertical" data-content=""></div>
|
|
<div class="column">
|
|
<p class="lead is-5">Restart</p>
|
|
{{ if .Service.Spec.TaskTemplate.RestartPolicy }}
|
|
<dl class="is-horizontal is-marginless">
|
|
<dt class="has-text-left">Condition</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.RestartPolicy.Condition }}</dd>
|
|
{{ if .Service.Spec.TaskTemplate.RestartPolicy.MaxAttempts }}
|
|
<dt class="has-text-left">Max attempts</dt>
|
|
<dd>{{ elem(.Service.Spec.TaskTemplate.RestartPolicy.MaxAttempts) }}</dd>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.RestartPolicy.Delay }}
|
|
<dt class="has-text-left">Delay</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.RestartPolicy.Delay }}</dd>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.RestartPolicy.Window }}
|
|
<dt class="has-text-left">Window</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.RestartPolicy.Window }}</dd>
|
|
{{ end }}
|
|
</dl>
|
|
{{ end }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div style="display: none">
|
|
{{ if .Service.Spec.TaskTemplate.LogDriver }}
|
|
<dl class="is-horizontal is-marginless">
|
|
<dt class="has-text-left">Name</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.LogDriver.Name }}</dd>
|
|
<dt class="has-text-left">Options</dt>
|
|
<dd>
|
|
<table class="table is-bordered is-narrow is-fullwidth is-marginless">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range k, v := .Service.Spec.TaskTemplate.LogDriver.Options}}
|
|
<tr>
|
|
<td>{{ k }}</td>
|
|
<td>{{ v }}</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
{{end}}
|
|
</div>
|
|
<div style="display: none">
|
|
<dl class="is-horizontal is-marginless">
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.Hostname }}
|
|
<dt class="has-text-left">Hostname</dt>
|
|
<dd>{{ .Service.Spec.TaskTemplate.ContainerSpec.Hostname }}</dd>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.Hosts }}
|
|
<dt class="has-text-left">Hosts</dt>
|
|
{{ range .Service.Spec.TaskTemplate.ContainerSpec.Hosts }}
|
|
<dd>{{ . }}</dd>
|
|
{{ end }}
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.DNSConfig }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.DNSConfig.Nameservers }}
|
|
<dt class="has-text-left">Name servers</dt>
|
|
<dd>{{ join(.Service.Spec.TaskTemplate.ContainerSpec.DNSConfig.Nameservers, ",") }}</dd>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.DNSConfig.Search }}
|
|
<dt class="has-text-left">Search</dt>
|
|
<dd>{{ join(.Service.Spec.TaskTemplate.ContainerSpec.DNSConfig.Search, ",") }}</dd>
|
|
{{ end }}
|
|
{{ if .Service.Spec.TaskTemplate.ContainerSpec.DNSConfig.Options }}
|
|
<dt class="has-text-left">Options</dt>
|
|
<dd>{{ join(.Service.Spec.TaskTemplate.ContainerSpec.DNSConfig.Options, ",") }}</dd>
|
|
{{ end }}
|
|
{{ end }}
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
|
|
{{if .Tasks}}
|
|
<div class="block">
|
|
<div class="block-header">
|
|
<p>Tasks</p>
|
|
</div>
|
|
<div class="block-body is-paddingless">
|
|
<table class="table is-bordered is-striped is-narrow is-fullwidth">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Status</th>
|
|
<th>Node</th>
|
|
<th>Networks</th>
|
|
<th>Updated</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Tasks}}
|
|
<tr>
|
|
<td><a href="/task/{{.ID}}/detail">{{.ID}}</a></td>
|
|
<td><span class="tag is-{{ .Status.State == "running" ? "success" : (.Status.State == "preparing" ? "warning": "danger") }}">{{.Status.State}}</span></td>
|
|
<td>{{ if .NodeName }}<a href="/node/{{.NodeID}}/detail">{{.NodeName}}</a>{{ end }}</td>
|
|
<td>
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
{{ range .NetworksAttachments }}
|
|
<div class="control">
|
|
<div class="tags has-addons"><span class="tag is-grey">{{ .Network.Spec.Name }}</span><span class="tag is-warning">{{ .Addresses }}</span></div>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
</td>
|
|
<td>{{time(.UpdatedAt)}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<a href="/service/" class="button is-primary">
|
|
<span class="icon"><i class="fas fa-reply"></i></span>
|
|
<span>{{ i18n("button.return") }}</span>
|
|
</a>
|
|
</div>
|
|
</section>
|
|
{{ end }} |