portainer/app/docker/views/containers/edit/container.html

369 lines
16 KiB
HTML

<page-header title="'Container details'" breadcrumbs="[{label:'Containers', link:'docker.containers'}, (container.Name | trimcontainername)]"> </page-header>
<div
class="row"
authorization="DockerContainerStart, DockerContainerStop, DockerContainerKill, DockerContainerRestart, DockerContainerPause, DockerContainerUnpause, DockerContainerDelete, DockerContainerCreate"
>
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="settings" title-text="Actions"></rd-widget-header>
<rd-widget-body classes="padding">
<div class="btn-group" role="group" aria-label="...">
<button authorization="DockerContainerStart" class="btn btn-light btn-sm" ng-click="start()" ng-disabled="container.State.Running || container.IsPortainer">
<pr-icon icon="'play'"></pr-icon>
Start
</button>
<button authorization="DockerContainerStop" class="btn btn-light btn-sm" ng-click="stop()" ng-disabled="!container.State.Running || container.IsPortainer">
<pr-icon icon="'square'"></pr-icon>
Stop
</button>
<button authorization="DockerContainerKill" class="btn btn-light btn-sm" ng-click="kill()" ng-disabled="!container.State.Running || container.IsPortainer">
<pr-icon icon="'bomb'"></pr-icon>
Kill
</button>
<button authorization="DockerContainerRestart" class="btn btn-light btn-sm" ng-click="restart()" ng-disabled="!container.State.Running || container.IsPortainer">
<pr-icon icon="'refresh-cw'"></pr-icon>
Restart</button
>
<button
authorization="DockerContainerPause"
class="btn btn-light btn-sm"
ng-click="pause()"
ng-disabled="!container.State.Running || container.State.Paused || container.IsPortainer"
>
<pr-icon icon="'pause'"></pr-icon>
Pause</button
>
<button authorization="DockerContainerUnpause" class="btn btn-light btn-sm" ng-click="unpause()" ng-disabled="!container.State.Paused || container.IsPortainer">
<pr-icon icon="'play'"></pr-icon>
Resume</button
>
<button authorization="DockerContainerDelete" class="btn btn-dangerlight btn-sm" ng-click="confirmRemove()" ng-disabled="container.IsPortainer">
<pr-icon icon="'trash-2'"></pr-icon>
Remove</button
>
</div>
<div class="btn-group" role="group" aria-label="..." ng-if="displayRecreateButton" authorization="DockerContainerCreate">
<button
type="button"
class="btn btn-light btn-sm"
ng-disabled="state.recreateContainerInProgress || container.IsPortainer"
ng-click="recreate()"
button-spinner="state.recreateContainerInProgress"
>
<span ng-hide="state.recreateContainerInProgress" class="flex items-center">
<pr-icon icon="'refresh-cw'" class-name="'!mr-1'"></pr-icon>
Recreate</span
>
<span ng-show="state.recreateContainerInProgress">Recreation in progress...</span>
</button>
<a class="btn btn-light btn-sm" type="button" ui-sref="docker.containers.new({ from: container.Id, nodeName: nodeName })" ng-disabled="container.IsPortainer">
<pr-icon icon="'copy'"></pr-icon>
Duplicate/Edit</a
>
</div>
</rd-widget-body>
</rd-widget>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="box" title-text="Container status"></rd-widget-header>
<rd-widget-body classes="no-padding">
<table class="table">
<tbody>
<tr>
<td class="col-xs-6 col-sm-4 col-md-3 col-lg-3">ID</td>
<td>{{ container.Id }}</td>
</tr>
<tr>
<td>Name</td>
<td ng-if="!container.edit">
{{ container.Name | trimcontainername }}
<a authorization="DockerContainerRename" href="" data-toggle="tooltip" title="Edit container name" ng-click="container.edit = true;"
><pr-icon icon="'edit'" class-name="'space-right'"></pr-icon
></a>
</td>
<td ng-if="container.edit">
<form ng-submit="renameContainer()">
<input type="text" class="containerNameInput" ng-model="container.newContainerName" />
<a href="" ng-click="container.edit = false;">
<pr-icon icon="'x'"></pr-icon>
</a>
<a href="" ng-click="renameContainer()">
<pr-icon icon="'check'"></pr-icon>
</a>
</form>
</td>
</tr>
<tr ng-if="container.NetworkSettings.IPAddress">
<td>IP address</td>
<td>{{ container.NetworkSettings.IPAddress }}</td>
</tr>
<tr>
<td>Status</td>
<td>
<pr-icon ng-if="container.State.Running" icon="'heart-pulse'" mode="'success'"></pr-icon>
<pr-icon ng-if="!container.State.Running && container.State.Status !== 'created'" icon="'heart-pulse'" mode="'danger'"></pr-icon>
{{ container.State | getstatetext }} for {{ activityTime
}}<span ng-if="!container.State.Running && container.State.Status !== 'created'"> with exit code {{ container.State.ExitCode }}</span>
</td>
</tr>
<tr>
<td>Created</td>
<td>{{ container.Created | getisodate }}</td>
</tr>
<tr ng-if="container.State.Running">
<td>Start time</td>
<td>{{ container.State.StartedAt | getisodate }}</td>
</tr>
<tr ng-if="!container.State.Running && container.State.Status !== 'created'">
<td>Finished</td>
<td>{{ container.State.FinishedAt | getisodate }}</td>
</tr>
<tr ng-if="isAdmin && displayCreateWebhookButton && applicationState.endpoint.type !== 4">
<td colspan="6">
<div class="form-group">
<div class="col-sm-12">
<por-switch-field
tooltip="'Webhook (or callback URI) used to automate the recreation of this container. Sending a POST request to this callback URI (without requiring any authentication) will pull the most up-to-date version of the associated image and recreate this container.'"
label-class="'col-sm-2'"
label="'Container webhook'"
feature-id="'container-webhook'"
></por-switch-field>
</div>
</div>
</td>
</tr>
<tr authorization="DockerContainerLogs, DockerContainerInspect, DockerContainerStats, DockerExecStart">
<td colspan="2">
<div class="btn-group" role="group" aria-label="...">
<a authorization="DockerContainerLogs" class="btn" type="button" ui-sref="docker.containers.container.logs({ id: container.Id })"
><pr-icon icon="'file-text'" class-name="'space-right'"></pr-icon>Logs</a
>
<a authorization="DockerContainerInspect" class="btn" type="button" ui-sref="docker.containers.container.inspect({ id: container.Id })"
><pr-icon icon="'info'" class-name="'space-right'"></pr-icon>Inspect</a
>
<a authorization="DockerContainerStats" class="btn" type="button" ui-sref="docker.containers.container.stats({ id: container.Id })"
><pr-icon icon="'bar-chart'" class-name="'space-right'"></pr-icon>Stats</a
>
<a authorization="DockerExecStart" class="btn" type="button" ui-sref="docker.containers.container.exec({ id: container.Id })"
><pr-icon icon="'terminal'" class-name="'space-right'"></pr-icon>Console</a
>
<a authorization="DockerContainerAttach" class="btn" type="button" ui-sref="docker.containers.container.attach({ id: container.Id })"
><pr-icon icon="'paperclip'" class-name="'space-right'"></pr-icon>Attach</a
>
</div>
</td>
</tr>
</tbody>
</table>
</rd-widget-body>
</rd-widget>
</div>
</div>
<!-- access-control-panel -->
<access-control-panel
ng-if="container"
resource-id="container.Id"
resource-control="container.ResourceControl"
resource-type="resourceType"
on-update-success="(onUpdateResourceControlSuccess)"
>
</access-control-panel>
<!-- !access-control-panel -->
<docker-health-status ng-if="container.State.Health" health="container.State.Health"></docker-health-status>
<div class="row" authorization="DockerImageCreate">
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="list" title-text="Create image"></rd-widget-header>
<rd-widget-body>
<form class="form-horizontal">
<!-- tag-description -->
<div class="form-group">
<div class="col-sm-12">
<span class="small text-muted">
You can create an image from this container, this allows you to backup important data or save helpful configurations. You'll be able to spin up another container
based on this image afterward.
</span>
</div>
</div>
<!-- !tag-description -->
<!-- image-and-registry -->
<por-image-registry
model="config.RegistryModel"
auto-complete="true"
label-class="col-sm-1"
input-class="col-sm-11"
endpoint="endpoint"
is-admin="isAdmin"
set-validity="setPullImageValidity"
check-rate-limits="true"
></por-image-registry>
<!-- !image-and-registry -->
<!-- tag-note -->
<div class="form-group">
<div class="col-sm-12">
<span class="small text-muted">Note: if you don't specify the tag in the image name, <span class="label label-default">latest</span> will be used.</span>
</div>
</div>
<!-- !tag-note -->
<div class="form-group">
<div class="col-sm-12">
<button
type="button"
class="btn btn-primary btn-sm"
ng-disabled="!state.pullImageValidity || !config.RegistryModel.Image || config.commitInProgress"
ng-click="commit()"
>
Create
</button>
</div>
</div>
</form>
</rd-widget-body>
</rd-widget>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="list" title-text="Container details"></rd-widget-header>
<rd-widget-body classes="no-padding">
<table class="container-details-table table">
<tbody>
<tr>
<td>Image</td>
<td
><a ui-sref="docker.images.image({ id: container.Image, nodeName: nodeName })">{{ container.Config.Image }}@{{ container.Image }}</a></td
>
</tr>
<tr ng-if="portBindings.length > 0">
<td>Port configuration</td>
<td>
<div ng-repeat="portMapping in portBindings">
{{ portMapping.host }}
<pr-icon icon="'arrow-right'"></pr-icon>
{{ portMapping.container }}
</div>
</td>
</tr>
<tr>
<td>CMD</td>
<td
><code>{{ container.Config.Cmd | command }}</code></td
>
</tr>
<tr>
<td>ENTRYPOINT</td>
<td
><code>{{ container.Config.Entrypoint ? (container.Config.Entrypoint | command) : 'null' }}</code></td
>
</tr>
<tr>
<td>ENV</td>
<td>
<table class="table-bordered table-condensed table">
<tr ng-repeat="var in container.Config.Env track by $index">
<td>{{ var|key: '=' }}</td>
<td>{{ var|value: '=' }}</td>
</tr>
</table>
</td>
</tr>
<tr ng-if="!(container.Config.Labels | emptyobject)">
<td>Labels</td>
<td>
<table class="table-bordered table-condensed table">
<tr ng-repeat="(k, v) in container.Config.Labels">
<td>{{ k }}</td>
<td>{{ v }}</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>Restart policies</td>
<td>
<container-restart-policy
ng-if="container"
name="container.HostConfig.RestartPolicy.Name"
maximum-retry-count="container.HostConfig.RestartPolicy.MaximumRetryCount"
update-restart-policy="updateRestartPolicy(name, maximumRetryCount)"
>
</container-restart-policy>
</td>
</tr>
<tr ng-if="!(container.HostConfig.Sysctls | emptyobject)">
<td>Sysctls</td>
<td>
<table class="table-bordered table-condensed table">
<tr ng-repeat="(k, v) in container.HostConfig.Sysctls">
<td>{{ k }}</td>
<td>{{ v }}</td>
</tr>
</table>
</td>
</tr>
<tr ng-if="container.HostConfig.DeviceRequests.length">
<td>GPUS</td>
<td>{{ computeDockerGPUCommand() }}</td>
</tr>
</tbody>
</table>
</rd-widget-body>
</rd-widget>
</div>
</div>
<div class="row" ng-if="container.Mounts.length > 0">
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="database" title-text="Volumes"></rd-widget-header>
<rd-widget-body classes="no-padding">
<table class="table">
<thead>
<tr>
<th>Host/volume</th>
<th>Path in container</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="vol in container.Mounts">
<td ng-if="vol.Type === 'bind'">{{ vol.Source }}</td>
<td ng-if="vol.Type === 'volume'"
><a ui-sref="docker.volumes.volume({ id: vol.Name, nodeName: nodeName })">{{ vol.Name }}</a></td
>
<td>{{ vol.Destination }}</td>
</tr>
</tbody>
</table>
</rd-widget-body>
</rd-widget>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<container-networks-datatable
ng-if="container.NetworkSettings.Networks"
title-text="Connected networks"
title-icon="share-2"
dataset="container.NetworkSettings.Networks"
table-key="container-networks"
container="container"
available-networks="availableNetworks"
join-network-action="containerJoinNetwork"
join-network-action-in-progress="state.joinNetworkInProgress"
leave-network-action="containerLeaveNetwork"
leave-network-action-in-progress="state.leaveNetworkInProgress"
node-name="nodeName"
></container-networks-datatable>
</div>
</div>