<div id="tagContextMenu" class="dropdown clearfix" tabindex="-1"> <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu"> <li><a tabindex="-1" href="javascript:void(0)" ng-click="askDeleteTag(currentMenuTag)">Delete Tag</a></li> </ul> </div> <div class="resource-view" resource="repository" error-message="'No Repository Found'"> <div class="container-fluid repo repo-view"> <!-- Repo Header --> <div class="header"> <h3> <span class="repo-circle no-background" repo="repo"></span> <span class="repo-breadcrumb" repo="repo"></span> </h3> <div class="repo-controls"> <!-- Builds --> <div class="dropdown" data-placement="top" style="display: inline-block" bs-tooltip="" data-title="{{ runningBuilds.length ? 'Dockerfile Builds Running: ' + (runningBuilds.length) : 'Dockerfile Build' }}" ng-show="repo.can_write || buildHistory.length"> <button class="btn btn-default dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-tasks fa-lg"></i> <span class="count" ng-class="runningBuilds.length ? 'visible' : ''"><span>{{ runningBuilds.length ? runningBuilds.length : '' }}</span></span> <b class="caret"></b> </button> <ul class="dropdown-menu"> <li ng-show="repo.can_write"><a href="{{ '/repository/' + repo.namespace + '/' + repo.name + '/build' }}"> <i class="fa fa-tasks"></i>Dockerfile Build History</a> </li> <li ng-show="repo.can_write"> <a href="javascript:void(0)" ng-click="showNewBuildDialog()"> <i class="fa fa-plus" style="margin-left: 1px; margin-right: 8px;"></i>New Dockerfile Build </a> </li> <li ng-show="repo.can_admin"> <a href="/repository/{{ repo.namespace }}/{{ repo.name }}/admin?tab=trigger"> <i class="fa fa-bolt" style="margin-left: 3px; margin-right: 10px;"></i>Build Triggers </a> </li> <li role="presentation" class="divider" ng-show="buildHistory && repo.can_write"></li> <li role="presentation" class="dropdown-header" ng-show="buildHistory.length">Recent Builds</li> <li ng-repeat="buildInfo in buildHistory"> <div class="build-info" ng-class="repo.can_write ? 'clickable' : ''" ng-click="repo.can_write && showBuild(buildInfo)"> <span class="build-status" build="buildInfo"></span> </div> </li> </ul> </div> <!-- Admin --> <a id="admin-cog" href="{{ '/repository/' + repo.namespace + '/' + repo.name + '/admin' }}" ng-show="repo.can_admin"> <button class="btn btn-default" data-title="Repository Settings" bs-tooltip="tooltip" data-placement="top"> <i class="fa fa-cog fa-lg"></i></button></a> <!-- Pull Command --> <span class="pull-command visible-md-inline"> <div class="pull-container" data-title="Pull repository" bs-tooltip="tooltip.title"> <div class="input-group"> <div class="copy-box" hovering-message="true" value="'docker pull ' + Config.getDomain() + '/' + repo.namespace + '/' + repo.name"></div> </div> </div> </span> </div> </div> <!-- Description --> <div class="description markdown-input" content="repo.description" can-write="repo.can_write" content-changed="updateForDescription" field-title="'repository description'"></div> <!-- Empty messages --> <div ng-if="!currentTag.image_id && !currentImage"> <!-- !building && !pushing --> <div class="repo-content" ng-show="!repo.is_building && !isPushing(images)"> <div class="empty-message"> This repository is empty </div> <div class="empty-description" ng-show="repo.can_write"> <div class="panel-default"> <div class="panel-heading">How to push a new image to this repository:</div> <div class="panel-body"> First login to the registry (if you have not done so already): <pre class="command">sudo docker login {{ Config.getDomain() }}</pre> Tag an image to this repository: <pre class="command">sudo docker tag <i>0u123imageidgoeshere</i> {{ Config.getDomain() }}/{{repo.namespace}}/{{repo.name}}</pre> Push the image to this repository: <pre class="command">sudo docker push {{ Config.getDomain() }}/{{repo.namespace}}/{{repo.name}}</pre> </div> </div> </div> </div> <!-- building --> <div class="repo-content" ng-show="repo.is_building"> <div class="empty-message"> A build is currently processing. If this takes longer than an hour, please <a href="/contact">contact us</a> </div> </div> <!-- pushing --> <div class="repo-content" ng-show="!repo.is_building && isPushing(images)"> <div class="empty-message"> A push to this repository is in progress. </div> </div> </div> <!-- Content view --> <div class="repo-content" ng-show="currentTag.image_id || currentImage"> <!-- Image History --> <div id="image-history" style="max-height: 10px;"> <div class="row"> <!-- Tree View container --> <div class="col-md-8"> <div class="panel panel-default"> <!-- Image history tree --> <div class="resource-view" resource="imageHistory"> <div id="image-history-container" onresize="tree.notifyResized()"></div> </div> </div> </div> <!-- Side Panel --> <div class="col-md-4"> <div id="side-panel" class="panel panel-default"> <div class="panel-heading"> <!-- Dropdown --> <div id="side-panel-dropdown" class="tag-dropdown dropdown" data-placement="top"> <i class="fa fa-tag current-context-icon" ng-show="currentTag"></i> <i class="fa fa-archive current-context-icon" ng-show="!currentTag"></i> <a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown"> <span class="current-context"> {{currentTag ? currentTag.name : currentImage.id.substr(0, 12)}} </span> <b class="caret"></b></a> <ul class="dropdown-menu"> <li ng-repeat="tag in repo.tags"> <a href="javascript:void(0)" ng-click="setTag(tag.name, true)"> <i class="fa fa-tag"></i>{{tag.name}} </a> </li> <li class="divider"></li> <li ng-repeat="image in imageHistory.value"> <a href="javascript:void(0)" ng-click="setImage(image.id, true)"> {{image.id.substr(0, 12)}} </a> </li> </ul> </div> <span class="right-tag-controls"> <i class="fa fa-tag" data-title="Tags" bs-tooltip="title"> <span class="tag-count">{{getTagCount(repo)}}</span> </i> <i class="fa fa-archive" data-title="Images" bs-tooltip="title"> <span class="tag-count">{{imageHistory.value.length}}</span> </i> </span> </div> <div class="panel-body"> <!-- Current Tag --> <div id="current-tag" ng-show="currentTag"> <dl class="dl-normal"> <dt>Last Modified</dt> <dd ng-if="!findImageForTag(currentTag, images)"> <span class="quay-spinner"></span> </dd> <dd am-time-ago="parseDate(findImageForTag(currentTag, images).created)" ng-if="findImageForTag(currentTag, images)"> </dd> <dt>Total Compressed Size</dt> <dd><span class="context-tooltip" data-title="The amount of data sent between Docker and the registry when pushing/pulling" bs-tooltip="tooltip.title" data-container="body">{{ getTotalSize(currentTag) | bytes }}</span> </dd> </dl> <div class="tag-image-sizes"> <div class="tag-image-size" ng-repeat="image in getImagesForTagBySize(currentTag) | limitTo: 10"> <span class="size-limiter"> <span class="size-bar" style="{{ 'width:' + (image.size / getTotalSize(currentTag)) * 100 + '%' }}" bs-tooltip="" data-title="{{ image.size | bytes }}"></span> </span> <span class="size-title"> <a class="image-size-link" href="javascript:void(0)" ng-click="setImage(image.id, true)" data-image="{{ image.id.substr(0, 12) }}"> {{ image.id.substr(0, 12) }} </a> </span> </div> </div> <div class="control-bar" ng-show="repo.can_admin"> <button class="btn btn-default" ng-click="askDeleteTag(currentTag.name)"> Delete Tag </button> </div> </div> <!-- Current Image --> <div id="current-image" ng-show="currentImage && !currentTag"> <div class="image-comment" ng-if="currentImage.comment"> <blockquote style="margin-top: 10px;"> <span class="markdown-view" content="currentImage.comment"></span> </blockquote> </div> <div class="image-section"> <i class="fa fa-code section-icon" bs-tooltip="tooltip.title" data-title="Full Image ID"></i> <span class="section-info"> <a class="image-link" href="{{'/repository/' + repo.namespace + '/' + repo.name + '/image/' + currentImage.id}}">{{ currentImage.id }}</a> </span> </div> <div class="image-section"> <i class="fa fa-tag section-icon" bs-tooltip="tooltip.title" data-title="Current Tags"></i> <span class="section-info section-info-with-dropdown"> <a class="label tag label-default" ng-repeat="tag in currentImage.tags" href="/repository/{{ repo.namespace }}/{{ repo.name }}?tag={{ tag }}"> {{ tag }} </a> <span style="color: #ccc;" ng-if="!currentImage.tags.length">(No Tags)</span> <div class="dropdown" data-placement="top" ng-if="repo.can_write || currentImage.tags"> <a href="javascript:void(0)" class="dropdown-button" data-toggle="dropdown" bs-tooltip="tooltip.title" data-title="Manage Tags" data-container="body"> <b class="caret"></b> </a> <ul class="dropdown-menu pull-right"> <li ng-repeat="tag in currentImage.tags"> <a href="javascript:void(0)" ng-click="setTag(tag, true)"> <i class="fa fa-tag"></i>{{tag}} </a> </li> <li class="divider" role="presentation" ng-if="repo.can_write && currentImage.tags"></li> <li> <a href="javascript:void(0)" ng-click="showAddTag(currentImage)" ng-if="repo.can_write"> <i class="fa fa-plus"></i>Add New Tag </a> </li> </ul> </div> </span> </div> <div class="image-section" ng-if="currentImage.command && currentImage.command.length"> <i class="fa fa-terminal section-icon" bs-tooltip="tooltip.title" data-title="Image Command"></i> <span class="section-info"> <span class="formatted-command trimmed" data-html="true" bs-tooltip="" data-title="{{ getTooltipCommand(currentImage) }}" data-placement="top">{{ getFormattedCommand(currentImage) }}</span> </span> </div> <div class="image-section"> <i class="fa fa-calendar section-icon" bs-tooltip="tooltip.title" data-title="Created"></i> <span class="section-info"> <dd am-time-ago="parseDate(currentImage.created)"></dd> </span> </div> <div class="image-section"> <i class="fa fa-cloud-upload section-icon" bs-tooltip="tooltip.title" data-title="The amount of data sent between Docker and the registry when pushing/pulling"></i> <span class="section-info">{{ currentImage.size | bytes }}</span> </div> <div class="image-section"> <i class="fa fa-map-marker section-icon" bs-tooltip="tooltip.title" data-title="The geographic region(s) in which this image data is located"></i> <span class="section-info"> <span class="location-view" location="location" ng-repeat="location in currentImage.locations"></span> </span> </div> <!-- Image changes loading --> <div class="resource-view" resource="currentImageChangeResource"> <div class="changes-container small-changes-container section-info" ng-show="currentImageChanges.changed.length || currentImageChanges.added.length || currentImageChanges.removed.length"> <div class="changes-count-container image-section"> <i class="fa fa-code-fork section-icon" bs-tooltip="tooltip.title" data-title="File Changes"></i> <div style="float: right; display: inline-block"> <span class="change-count added" ng-show="currentImageChanges.added.length > 0" data-title="Files Added" bs-tooltip="tooltip.title" data-placement="top" data-container="body"> <i class="fa fa-plus-square"></i> <b>{{currentImageChanges.added.length}}</b> </span> <span class="change-count removed" ng-show="currentImageChanges.removed.length > 0" data-title="Files Removed" bs-tooltip="tooltip.title" data-placement="top" data-container="body"> <i class="fa fa-minus-square"></i> <b>{{currentImageChanges.removed.length}}</b> </span> <span class="change-count changed" ng-show="currentImageChanges.changed.length > 0" data-title="Files Changed" bs-tooltip="tooltip.title" data-placement="top" data-container="body"> <i class="fa fa-pencil-square"></i> <b>{{currentImageChanges.changed.length}}</b> </span> </div> <div id="collapseChanges" style="padding-top: 24px;"> <div class="well well-sm"> <div class="change added" ng-repeat="file in currentImageChanges.added | limitTo:2"> <i class="fa fa-plus-square"></i> <span title="{{file}}">{{file}}</span> </div> <div class="change removed" ng-repeat="file in currentImageChanges.removed | limitTo:2"> <i class="fa fa-minus-square"></i> <span title="{{file}}">{{file}}</span> </div> <div class="change changed" ng-repeat="file in currentImageChanges.changed | limitTo:2"> <i class="fa fa-pencil-square"></i> <span title="{{file}}">{{file}}</span> </div> </div> <div class="more-changes" ng-show="getMoreCount(currentImageChanges) > 0"> <a href="{{'/repository/' + repo.namespace + '/' + repo.name + '/image/' + currentImage.id}}"> And {{getMoreCount(currentImageChanges)}} more... </a> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> <div class="dockerfile-build-dialog" show-now="buildDialogShowCounter" repository="repo" build-started="handleBuildStarted(build)"> </div> <!-- Modal message dialog --> <div class="modal fade" id="addTagModal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-show="!creatingTag">×</button> <h4 class="modal-title">{{ isAnotherImageTag(toTagImage, tagToCreate) ? 'Move' : 'Add' }} Tag to Image {{ toTagImage.id.substr(0, 12) }}</h4> </div> <form name="addTagForm" ng-submit="createOrMoveTag(toTagImage, tagToCreate, addTagForm.$invalid); addTagForm.$setPristine(); tagToCreate=''"> <div class="modal-body"> <input type="text" class="form-control" id="tagName" placeholder="Enter tag name" ng-model="tagToCreate" ng-pattern="/^([a-z0-9_\.-]){3,30}$/" required ng-disabled="creatingTag" autofocus> <div style="margin: 10px; margin-top: 20px;" ng-show="isOwnedTag(toTagImage, tagToCreate)"> Note: <span class="label tag label-default">{{ tagToCreate }}</span> is already applied to this image. </div> <div style="margin: 10px; margin-top: 20px;" ng-show="isAnotherImageTag(toTagImage, tagToCreate)"> Note: <span class="label tag label-default">{{ tagToCreate }}</span> is already applied to another image. This will <b>move</b> the tag. </div> <div class="tag-specific-images-view" tag="tagToCreate" repository="repo" images="images" image-cutoff="toTagImage" style="margin: 10px; margin-top: 20px; margin-bottom: -10px;" ng-show="isAnotherImageTag(toTagImage, tagToCreate)"> This will also delete any unattach images and delete the following images: </div> </div> <div class="modal-footer"> <button type="submit" class="btn btn-primary" ng-disabled="!tagToCreate || addTagForm.$invalid || isOwnedTag(toTagImage, tagToCreate)" ng-class="isAnotherImageTag(toTagImage, tagToCreate) ? 'btn-warning' : 'btn-primary'" ng-show="!creatingTag"> {{ isAnotherImageTag(toTagImage, tagToCreate) ? 'Move Tag' : 'Create Tag' }} </button> <button class="btn btn-default" data-dismiss="modal" ng-show="!creatingTag">Cancel</button> <div class="quay-spinner" ng-show="creatingTag"></div> </div> </form> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal --> <!-- Modal message dialog --> <div class="modal fade" id="confirmdeleteTagModal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title">Delete tag <span class="label tag" ng-class="tagToDelete == currentTag.name ? 'label-success' : 'label-default'"> {{ tagToDelete }} </span>? </h4> </div> <div class="modal-body"> Are you sure you want to delete tag <span class="label tag" ng-class="tagToDelete == currentTag.name ? 'label-success' : 'label-default'"> {{ tagToDelete }} </span>? <div class="tag-specific-images-view" tag="tagToDelete" repository="repo" images="images" style="margin-top: 20px"> The following images and any other images not referenced by a tag will be deleted: </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" ng-click="deleteTag(tagToDelete)">Delete Tag</button> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->