mirror of
https://github.com/portainer/portainer.git
synced 2025-08-02 20:35:25 +02:00
feat(service-details): add ability to edit service details (#453)
This commit is contained in:
parent
ab91ffe12c
commit
a8f70d7f59
17 changed files with 1057 additions and 296 deletions
66
app/components/service/includes/constraints.html
Normal file
66
app/components/service/includes/constraints.html
Normal file
|
@ -0,0 +1,66 @@
|
|||
<div ng-if="service.ServiceConstraints">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tasks" title="Placement constraints">
|
||||
<div class="nopadding">
|
||||
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating || addPlacementConstraint(service)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> placement constraint
|
||||
</a>
|
||||
</div>
|
||||
</rd-widget-header>
|
||||
<rd-widget-body ng-if="service.ServiceConstraints.length === 0">
|
||||
<p>There are no placement constraints for this service.</p>
|
||||
</rd-widget-body>
|
||||
<rd-widget-body ng-if="service.ServiceConstraints.length > 0" classes="no-padding">
|
||||
<table class="table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Operator</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="constraint in service.ServiceConstraints">
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control" ng-model="constraint.key" placeholder="e.g. node.role" ng-change="updatePlacementConstraint(service, constraint)" ng-disabled="isUpdating">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<select name="constraintOperator" class="form-control" ng-model="constraint.operator" ng-change="updatePlacementConstraint(service, constraint)" ng-disabled="isUpdating">
|
||||
<option value="==">==</option>
|
||||
<option value="!=">!=</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control" ng-model="constraint.value" placeholder="e.g. manager" ng-change="updatePlacementConstraint(service, constraint)" ng-disabled="isUpdating">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" ng-click="removePlacementConstraint(service, $index)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-minus" aria-hidden="true"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
<rd-widget-footer>
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="!hasChanges(service, ['ServiceConstraints'])" ng-click="updateService(service)">Apply changes</button>
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="cancelChanges(service, ['ServiceConstraints'])">Reset changes</a></li>
|
||||
<li><a ng-click="cancelChanges(service)">Reset all changes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-footer>
|
||||
</rd-widget>
|
||||
</div>
|
56
app/components/service/includes/container-specs.html
Normal file
56
app/components/service/includes/container-specs.html
Normal file
|
@ -0,0 +1,56 @@
|
|||
<div>
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-list-alt" title="Container spec"></rd-widget-header>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>CMD</td>
|
||||
<td><code ng-if="service.Command">{{ service.Command|command }}</code></td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Command to execute.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Args</td>
|
||||
<td><code ng-if="service.Arguments">{{ service.Arguments }}</code></td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Arguments passed to command in container.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>User</td>
|
||||
<td>{{ service.User }}</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Username or UID.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Working directory</td>
|
||||
<td>{{ service.Dir }}</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Working directory inside the container.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stop grace period</td>
|
||||
<td>{{ service.StopGracePeriod }}</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Time to wait before force killing a container (default none).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
59
app/components/service/includes/containerlabels.html
Normal file
59
app/components/service/includes/containerlabels.html
Normal file
|
@ -0,0 +1,59 @@
|
|||
<div>
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tasks" title="Container labels">
|
||||
<div class="nopadding">
|
||||
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating ||addContainerLabel(service)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> container label
|
||||
</a>
|
||||
</div>
|
||||
</rd-widget-header>
|
||||
<rd-widget-body ng-if="service.ServiceContainerLabels.length === 0">
|
||||
<p>There are no container labels for this service.</p>
|
||||
</rd-widget-body>
|
||||
<rd-widget-body ng-if="service.ServiceContainerLabels.length > 0" classes="no-padding">
|
||||
<table class="table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Label</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="label in service.ServiceContainerLabels">
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon fit-text-size">name</span>
|
||||
<input type="text" class="form-control" ng-model="label.key" placeholder="e.g. com.example.foo" ng-change="updateContainerLabel(service, label)" ng-disabled="isUpdating">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon fit-text-size">value</span>
|
||||
<input type="text" class="form-control" ng-model="label.value" placeholder="e.g. bar" ng-change="updateContainerLabel(service, label)" ng-disabled="isUpdating">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" ng-click="removeContainerLabel(service, $index)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-minus" aria-hidden="true"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
<rd-widget-footer>
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="!hasChanges(service, ['ServiceContainerLabels'])" ng-click="updateService(service)">Apply changes</button>
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="cancelChanges(service, ['ServiceContainerLabels'])">Reset changes</a></li>
|
||||
<li><a ng-click="cancelChanges(service)">Reset all changes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-footer>
|
||||
</rd-widget>
|
||||
</div>
|
59
app/components/service/includes/environmentvariables.html
Normal file
59
app/components/service/includes/environmentvariables.html
Normal file
|
@ -0,0 +1,59 @@
|
|||
<div ng-if="service.EnvironmentVariables">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tasks" title="Environment variables">
|
||||
<div class="nopadding">
|
||||
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating ||addEnvironmentVariable(service)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> environment variable
|
||||
</a>
|
||||
</div>
|
||||
</rd-widget-header>
|
||||
<rd-widget-body ng-if="service.EnvironmentVariables.length === 0">
|
||||
<p>There are no environment variables for this service.</p>
|
||||
</rd-widget-body>
|
||||
<rd-widget-body ng-if="service.EnvironmentVariables.length > 0" classes="no-padding">
|
||||
<table class="table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="var in service.EnvironmentVariables">
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon fit-text-size">name</span>
|
||||
<input type="text" class="form-control" ng-model="var.key" ng-disabled="var.added || isUpdating" placeholder="e.g. FOO">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon fit-text-size">value</span>
|
||||
<input type="text" class="form-control" ng-model="var.value" ng-change="updateEnvironmentVariable(service, var)" placeholder="e.g. bar" ng-disabled="isUpdating">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" ng-click="removeEnvironmentVariable(service, $index)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-minus" aria-hidden="true"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
<rd-widget-footer>
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="!hasChanges(service, ['EnvironmentVariables'])" ng-click="updateService(service)">Apply changes</button>
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="cancelChanges(service, ['EnvironmentVariables'])">Reset changes</a></li>
|
||||
<li><a ng-click="cancelChanges(service)">Reset all changes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-footer>
|
||||
</rd-widget>
|
||||
</div>
|
67
app/components/service/includes/mounts.html
Normal file
67
app/components/service/includes/mounts.html
Normal file
|
@ -0,0 +1,67 @@
|
|||
<div ng-if="service.ServiceMounts">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tasks" title="Mounts">
|
||||
<div class="nopadding">
|
||||
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating ||addMount(service)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> mount
|
||||
</a>
|
||||
</div>
|
||||
</rd-widget-header>
|
||||
<rd-widget-body ng-if="service.ServiceMounts.length === 0">
|
||||
<p>There are no mounts for this service.</p>
|
||||
</rd-widget-body>
|
||||
<rd-widget-body ng-if="service.ServiceMounts.length > 0" classes="no-padding">
|
||||
<table class="table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Source</th>
|
||||
<th>Target</th>
|
||||
<th>Read only</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="mount in service.ServiceMounts">
|
||||
<td>
|
||||
<select name="mountType" class="form-control" ng-model="mount.Type" ng-disabled="isUpdating">
|
||||
<option value="volume">Volume</option>
|
||||
<option value="bind">Bind</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="form-control" ng-model="mount.Source" placeholder="e.g. /tmp/portainer/data" ng-change="updateMount(service, mount)" ng-disabled="isUpdating">
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="form-control" ng-model="mount.Target" placeholder="e.g. /tmp/portainer/data" ng-change="updateMount(service, mount)" ng-disabled="isUpdating">
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" class="form-control" ng-model="mount.ReadOnly" ng-change="updateMount(service, mount)" ng-disabled="isUpdating">
|
||||
</td>
|
||||
<td>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" ng-click="removeMount(service, $index)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-minus" aria-hidden="true"></i>
|
||||
</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
<rd-widget-footer>
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="!hasChanges(service, ['ServiceMounts'])" ng-click="updateService(service)">Apply changes</button>
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="cancelChanges(service, ['ServiceMounts'])">Reset changes</a></li>
|
||||
<li><a ng-click="cancelChanges(service)">Reset all changes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-footer>
|
||||
</rd-widget>
|
||||
</div>
|
26
app/components/service/includes/networks.html
Normal file
26
app/components/service/includes/networks.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
<div>
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tasks" title="Networks"></rd-widget-header>
|
||||
<rd-widget-body ng-if="!service.VirtualIPs || service.VirtualIPs.length === 0">
|
||||
<p>This service is not connected to any networks.</p>
|
||||
</rd-widget-body>
|
||||
<rd-widget-body ng-if="service.VirtualIPs && service.VirtualIPs.length > 0" classes="no-padding">
|
||||
<table class="table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>IP address</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="network in service.VirtualIPs">
|
||||
<td>
|
||||
<a ui-sref="network({id: network.NetworkID})">{{ network.NetworkID }}</a>
|
||||
</td>
|
||||
<td>{{ network.Addr }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
71
app/components/service/includes/ports.html
Normal file
71
app/components/service/includes/ports.html
Normal file
|
@ -0,0 +1,71 @@
|
|||
<div>
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tasks" title="Published ports">
|
||||
<div class="nopadding">
|
||||
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating ||addPublishedPort(service)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> port mapping
|
||||
</a>
|
||||
</div>
|
||||
</rd-widget-header>
|
||||
<rd-widget-body ng-if="!service.Ports || service.Ports.length === 0">
|
||||
<p>This service has no ports published.</p>
|
||||
</rd-widget-body>
|
||||
<rd-widget-body ng-if="service.Ports && service.Ports.length > 0" classes="no-padding">
|
||||
<table class="table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Host port</th>
|
||||
<th>Container port</th>
|
||||
<th>Protocol</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="portBinding in service.Ports">
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">host</span>
|
||||
<input type="number" class="form-control" ng-model="portBinding.PublishedPort" placeholder="e.g. 8080" ng-change="updatePublishedPort(service, mapping)" ng-disabled="isUpdating">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">container</span>
|
||||
<input type="number" class="form-control" ng-model="portBinding.TargetPort" placeholder="e.g. 80" ng-change="updatePublishedPort(service, mapping)" ng-disabled="isUpdating">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<select class="selectpicker form-control" ng-model="portBinding.Protocol" ng-change="updatePublishedPort(service, mapping)" ng-disabled="isUpdating">
|
||||
<option value="tcp">tcp</option>
|
||||
<option value="udp">udp</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" ng-click="removePortPublishedBinding(service, $index)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-minus" aria-hidden="true"></i>
|
||||
</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
<rd-widget-footer>
|
||||
<div class="btn-toolbar" role="toolbar"
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="!hasChanges(service, ['Ports'])" ng-click="updateService(service)">Apply changes</button>
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="cancelChanges(service, ['Ports'])">Reset changes</a></li>
|
||||
<li><a ng-click="cancelChanges(service)">Reset all changes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-footer>
|
||||
</rd-widget>
|
||||
</div>
|
36
app/components/service/includes/resources.html
Normal file
36
app/components/service/includes/resources.html
Normal file
|
@ -0,0 +1,36 @@
|
|||
<div>
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-list-alt" title="Resource limits and reservations">
|
||||
</rd-widget-header>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>CPU limits</td>
|
||||
<td ng-if="service.LimitNanoCPUs">
|
||||
{{ service.LimitNanoCPUs / 1000000000 }}
|
||||
</td>
|
||||
<td ng-if="!service.LimitNanoCPUs">None</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Memory limits</td>
|
||||
<td ng-if="service.LimitMemoryBytes">{{service.LimitMemoryBytes|humansize}}</td>
|
||||
<td ng-if="!service.LimitMemoryBytes">None</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CPU reservation</td>
|
||||
<td ng-if="service.ReservationNanoCPUs">
|
||||
{{service.ReservationNanoCPUs / 1000000000}}
|
||||
</td>
|
||||
<td ng-if="!service.ReservationNanoCPUs">None</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Memory reservation</td>
|
||||
<td ng-if="service.ReservationMemoryBytes">{{service.ReservationMemoryBytes|humansize}}</td>
|
||||
<td ng-if="!service.ReservationMemoryBytes">None</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
76
app/components/service/includes/restart.html
Normal file
76
app/components/service/includes/restart.html
Normal file
|
@ -0,0 +1,76 @@
|
|||
<div>
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-list-alt" title="Restart policy">
|
||||
</rd-widget-header>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Restart condition</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<select class="selectpicker form-control" ng-model="service.RestartCondition" ng-change="updateServiceAttribute(service, 'RestartCondition')" ng-disabled="isUpdating">
|
||||
<option value="none">None</option>
|
||||
<option value="on-failure">On failure</option>
|
||||
<option value="any">Any</option>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Condition for restart.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Restart delay</td>
|
||||
<td>
|
||||
<input class="input-sm" type="number" ng-model="service.RestartDelay" ng-change="updateServiceAttribute(service, 'RestartDelay')" ng-disabled="isUpdating"/>
|
||||
</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Delay between restart attempts. Time in seconds.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Restart max attempts</td>
|
||||
<td>
|
||||
<input class="input-sm" type="number" ng-model="service.RestartMaxAttempts" ng-change="updateServiceAttribute(service, 'RestartMaxAttempts')" ng-disabled="isUpdating"/>
|
||||
</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Maximum attempts to restart a given container before giving up (default value is 0, which is ignored).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Restart window</td>
|
||||
<td>
|
||||
<input class="input-sm" type="number" ng-model="service.RestartWindow" ng-change="updateServiceAttribute(service, 'RestartWindow')" ng-disabled="isUpdating"/>
|
||||
</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
The time window used to evaluate the restart policy (default value is 0, which is unbounded).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
<rd-widget-footer>
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="!hasChanges(service, ['RestartCondition', 'RestartDelay', 'RestartMaxAttempts', 'RestartWindow'])" ng-click="updateService(service)">Apply changes</button>
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="cancelChanges(service, ['RestartCondition', 'RestartDelay', 'RestartMaxAttempts', 'RestartWindow'])">Reset changes</a></li>
|
||||
<li><a ng-click="cancelChanges(service)">Reset all changes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-footer>
|
||||
</rd-widget>
|
||||
</div>
|
63
app/components/service/includes/servicelabels.html
Normal file
63
app/components/service/includes/servicelabels.html
Normal file
|
@ -0,0 +1,63 @@
|
|||
<div>
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tasks" title="Service labels">
|
||||
<div class="nopadding">
|
||||
<a class="btn btn-default btn-sm pull-right" ng-click="isUpdating || addLabel(service)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> label
|
||||
</a>
|
||||
</div>
|
||||
</rd-widget-header>
|
||||
<rd-widget-body ng-if="service.ServiceLabels.length === 0">
|
||||
<p>There are no labels for this service.</p>
|
||||
</rd-widget-body>
|
||||
<rd-widget-body classes="no-padding" ng-if="service.ServiceLabels.length > 0">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Label
|
||||
</th>
|
||||
<th>
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="label in service.ServiceLabels">
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon fit-text-size">name</span>
|
||||
<input type="text" class="form-control" ng-model="label.key" placeholder="e.g. com.example.foo" ng-change="updateLabel(service, label)" ng-disabled="isUpdating">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon fit-text-size">value</span>
|
||||
<input type="text" class="form-control" ng-model="label.value" placeholder="e.g. bar" ng-change="updateLabel(service, label)" ng-disabled="isUpdating">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" ng-click="removeLabel(service, $index)" ng-disabled="isUpdating">
|
||||
<i class="fa fa-minus" aria-hidden="true"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
<rd-widget-footer>
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="!hasChanges(service, ['ServiceLabels'])" ng-click="updateService(service)">Apply changes</button>
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="cancelChanges(service, ['ServiceLabels'])">Reset changes</a></li>
|
||||
<li><a ng-click="cancelChanges(service)">Reset all changes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-footer>
|
||||
</rd-widget>
|
||||
</div>
|
65
app/components/service/includes/tasks.html
Normal file
65
app/components/service/includes/tasks.html
Normal file
|
@ -0,0 +1,65 @@
|
|||
<div ng-if="tasks.length > 0">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tasks" title="Associated tasks">
|
||||
<div class="pull-right">
|
||||
Items per page:
|
||||
<select ng-model="state.pagination_count" ng-change="changePaginationCount()">
|
||||
<option value="0">All</option>
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
</div>
|
||||
</rd-widget-header>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>
|
||||
<a ui-sref="service" ng-click="order('Status')">
|
||||
Status
|
||||
<span ng-show="sortType == 'Status' && !sortReverse" class="glyphicon glyphicon-chevron-down"></span>
|
||||
<span ng-show="sortType == 'Status' && sortReverse" class="glyphicon glyphicon-chevron-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a ui-sref="service" ng-click="order('Slot')">
|
||||
Slot
|
||||
<span ng-show="sortType == 'Slot' && !sortReverse" class="glyphicon glyphicon-chevron-down"></span>
|
||||
<span ng-show="sortType == 'Slot' && sortReverse" class="glyphicon glyphicon-chevron-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th ng-if="displayNode">
|
||||
<a ui-sref="service" ng-click="order('Node')">
|
||||
Node
|
||||
<span ng-show="sortType == 'Node' && !sortReverse" class="glyphicon glyphicon-chevron-down"></span>
|
||||
<span ng-show="sortType == 'Node' && sortReverse" class="glyphicon glyphicon-chevron-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a ui-sref="service" ng-click="order('Updated')">
|
||||
Last update
|
||||
<span ng-show="sortType == 'Updated' && !sortReverse" class="glyphicon glyphicon-chevron-down"></span>
|
||||
<span ng-show="sortType == 'Updated' && sortReverse" class="glyphicon glyphicon-chevron-up"></span>
|
||||
</a>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr dir-paginate="task in (filteredTasks = ( tasks | orderBy:sortType:sortReverse | itemsPerPage: state.pagination_count))">
|
||||
<td><a ui-sref="task({ id: task.Id })">{{ task.Id }}</a></td>
|
||||
<td><span class="label label-{{ task.Status|taskstatusbadge }}">{{ task.Status }}</span></td>
|
||||
<td>{{ task.Slot }}</td>
|
||||
<td ng-if="displayNode">{{ task.Node }}</td>
|
||||
<td>{{ task.Updated|getisodate }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div ng-if="tasks" class="pagination-controls">
|
||||
<dir-pagination-controls></dir-pagination-controls>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
68
app/components/service/includes/updateconfig.html
Normal file
68
app/components/service/includes/updateconfig.html
Normal file
|
@ -0,0 +1,68 @@
|
|||
<div>
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-list-alt" title="Update configuration">
|
||||
</rd-widget-header>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Update Parallelism</td>
|
||||
<td>
|
||||
<input class="input-sm" type="number" ng-model="service.UpdateParallelism" ng-change="updateServiceAttribute(service, 'UpdateParallelism')" ng-disabled="isUpdating"/>
|
||||
</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Maximum number of tasks to be updated simultaneously (0 to update all at once).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Update Delay</td>
|
||||
<td>
|
||||
<input class="input-sm" type="number" ng-model="service.UpdateDelay" ng-change="updateServiceAttribute(service, 'UpdateDelay')" ng-disabled="isUpdating"/>
|
||||
</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Amount of time between updates.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Update Failure Action</td>
|
||||
<td>
|
||||
<div class="form-group">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="failure_action" ng-model="service.UpdateFailureAction" value="continue" ng-change="updateServiceAttribute(service, 'UpdateFailureAction')" ng-disabled="isUpdating">
|
||||
Continue
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="failure_action" ng-model="service.UpdateFailureAction" value="pause" ng-change="updateServiceAttribute(service, 'UpdateFailureAction')" ng-disabled="isUpdating">
|
||||
Pause
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<p class="small text-muted" style="margin-top: 10px;">
|
||||
Action taken on failure to start after update.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</rd-widget-body>
|
||||
<rd-widget-footer>
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="!hasChanges(service, ['UpdateFailureAction', 'UpdateDelay', 'UpdateParallelism'])" ng-click="updateService(service)">Apply changes</button>
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="cancelChanges(service, ['UpdateFailureAction', 'UpdateDelay', 'UpdateParallelism'])">Reset changes</a></li>
|
||||
<li><a ng-click="cancelChanges(service)">Reset all changes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-footer>
|
||||
</rd-widget>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue