diff --git a/dist/image-widgets.js b/dist/image-widgets.js index 475294c..5932e08 100644 --- a/dist/image-widgets.js +++ b/dist/image-widgets.js @@ -63,7 +63,7 @@ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 19); +/******/ return __webpack_require__(__webpack_require__.s = 20); /******/ }) /************************************************************************/ /******/ ([ @@ -437,7 +437,8 @@ angular.module('registryUI.images', [ .directive('registryImageBody', [ 'imageLayers', 'imageDockerConfig', - function(imageLayers, imageDockerConfig) { + 'imageSignatures', + function(imageLayers, imageDockerConfig, imageSignatures) { return { restrict: 'E', scope: { @@ -450,6 +451,7 @@ angular.module('registryUI.images', [ scope.layers = imageLayers(image); scope.config = imageDockerConfig(image); scope.labels = scope.config.Labels; + scope.signatures = imageSignatures(image); if (angular.equals({ }, scope.labels)) scope.labels = null; }); @@ -504,6 +506,37 @@ angular.module('registryUI.images', [ } ]) +.directive('registryImageSignatures', [ + 'imageSignatures', + function(imageSignatures) { + return { + restrict: 'E', + scope: { + image: '=', + }, + templateUrl: 'registry-image-widgets/views/image-signatures.html', + link: function(scope, element, attrs) { + scope.signatureDetails = function signatureDetails(signature) { + var result = ""; + if (signature.conditions) { + var condition = signature.conditions.find(function (condition) { + return condition.type === "Trusted"; + }); + if (condition !== undefined) { + result = condition.reason + " / " + condition.message; + } + } + return result; + }; + + scope.$watch("image", function(image) { + scope.signatures = imageSignatures(image); + }); + } + }; + } +]) + .directive('registryImageMeta', [ 'imageDockerConfig', function(imageDockerConfig) { @@ -582,11 +615,65 @@ angular.module('registryUI.images', [ } ]) +.factory('imageSignatures', [ + 'WeakMap', + function(WeakMap) { + var weak = new WeakMap(); + + return function(image) { + if (!image) + return []; + var signatures = weak.get(image); + + + var signatureStatus = function(signature) { + var trusted = "Unverified"; + if (signature.conditions) { + var condition = signature.conditions.find(function (condition) { + return condition.type === "Trusted"; + }); + if (condition !== undefined) { + trusted = "Verified"; + } else { + // Failed info not available + // https://github.com/openshift/origin/issues/16301 + trusted = "Failed verification"; + } + } + return trusted; + }; + + /* + signatures = []; + if (image.signatures) { + image.signatures.forEach(function(signature) { + signature.verified = signatureStatus(signature); + signatures.push(signature); + }); + } + weak.set(image, signatures); + */ + + if (!signatures && image.signatures) { + signatures = []; + image.signatures.forEach(function(signature) { + signature.verified = signatureStatus(signature); + signatures.push(signature); + }); + weak.set(image, signatures); + } + + return signatures || []; + }; + } +]) + .factory('registryImageListingFunc', [ 'imagestreamTags', 'imagestreamTagFromName', + 'imageSignatures', '$location', - function(imagestreamTags, imagestreamTagFromName, $location) { + function(imagestreamTags, imagestreamTagFromName, imageSignatures, $location) { return function(scope, element, attrs) { scope.imagestreamTags = imagestreamTags; scope.imagestreamPath = scope.imagestreamFunc(); @@ -594,6 +681,64 @@ angular.module('registryUI.images', [ scope.imageTagNames = scope.imageTagNamesFunc(); scope.sharedImages = scope.sharedImagesFunc(); scope.imagestreamTagFromName = imagestreamTagFromName; + scope.imageSignatures = imageSignatures; + + scope.overallVerification = function overallVerification(tag) { + var image, signature, signatures; + var overall = "Unverified"; + + image = scope.imageByTag(tag.status); + signatures = scope.imageSignatures(image); + + if (signatures.length === 0) { + return "Unsigned"; + } else { + signatures.forEach(function(signature) { + var status = signature.verified; + if (status === "Failed verification" || overall === "Failed verification" || overall === undefined) { + overall = status; + } else if (status !== "Failed verification") { + overall = status; + } + }); + } + + return overall; + }; + + /* + scope.imageSignatures = function imageSignatures(imagestream, tag) { + var image, signatures, signature; + + image = scope.imageByTag(tag.status); + signatures = []; + if (image.signatures) { + image.signatures.forEach(function(signature) { + signature.verified = scope.signatureVerification(signature); + signatures.push(signature); + }); + } + + return signatures; + }; + + scope.signatureVerification = function signatureVerification(signature) { + var trusted = "Unverified"; + if (signature.conditions) { + var condition = signature.conditions.find(function (condition) { + return condition.type === "Trusted"; + }); + if (condition !== undefined) { + trusted = "Verified"; + } else { + // Failed info not available + // https://github.com/openshift/origin/issues/16301 + trusted = "Failed verification"; + } + } + return trusted; + }; + */ /* Called when someone clicks on a row */ scope.imagestreamActivate = function imagestreamActivate(imagestream, tag, ev) { @@ -680,7 +825,8 @@ angular.module('registryUI.images', [ .directive('registryImagePanel', [ 'imageDockerConfig', 'imageLayers', - function(imageDockerConfig, imageLayers) { + 'imageSignatures', + function(imageDockerConfig, imageLayers, imageSignatures) { return { restrict: 'E', transclude: true, @@ -705,6 +851,7 @@ angular.module('registryUI.images', [ scope.layers = imageLayers(scope.image); scope.config = imageDockerConfig(scope.image); scope.labels = scope.config.Labels; + scope.signatures = imageSignatures(scope.image); if (scope.imageTagNames) scope.names = scope.imageTagNames(scope.image); } @@ -883,8 +1030,11 @@ angular.module('registryUI.images', [ var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
Annotations
{{name}}: {{value}}
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/annotations.html",v1)}]); +var v1="
Annotations
\n
{{name}}: {{value}}
\n"; +var id1="registry-image-widgets/views/annotations.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -894,8 +1044,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
Name
{{ labels.name }}
Summary
{{ labels.summary }}
Description
{{ labels.description }}
Source URL
{{ labels.url }}
Author
{{config.author}}
{{image.dockerImageMetadata.Author}}
{{labels['MAINTAINER']}}
Unknown
Built
{{ layers[0].v1Compatibility.created | dateRelative}}
{{image.dockerImageMetadata.Created | dateRelative}}
{{ labels['build-date'] | dateRelative}}
Digest
{{ image.metadata.name }}
Identifier
{{ config.Image }}
Tags
{{name}} 
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/image-body.html",v1)}]); +var v1="
\n
Name
\n
{{ labels.name }}
\n
Summary
\n
{{ labels.summary }}
\n
Description
\n
{{ labels.description }}
\n
Source URL
\n
\n {{ labels.url }}\n
\n
Author
\n
{{config.author}}
\n
{{image.dockerImageMetadata.Author}}
\n
{{labels['MAINTAINER']}}
\n
Unknown
\n
Built
\n
{{ layers[0].v1Compatibility.created | dateRelative}}
\n
{{image.dockerImageMetadata.Created | dateRelative}}
\n
{{ labels['build-date'] | dateRelative}}
\n
Digest
\n
{{ image.metadata.name }}
\n
Identifier
\n
{{ config.Image }}
\n
\n
0\">\n
Signatures
\n
\n{{ signature.type }} / {{ signature.metadata.creationTimestamp }} / {{ signature.metadata.name }} / {{ signature.metadata.uid }}\n
\n
\n
\n
Tags
\n
{{name}} 
\n
\n"; +var id1="registry-image-widgets/views/image-body.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -905,8 +1058,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
Command
{{ configCommand(config) }}
Run as
{{config.User}}
Default
Directory
{{config.WorkingDir}}
/
Stop with
{{config.StopSignal}}
Architecture
{{config.architecture}}
{{image.dockerImageMetadata.Architecture}}
Environment
{{env}}
Ports
{{port}}
None
Volumes
{{volume}}
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/image-config.html",v1)}]); +var v1="
\n
Command
\n
{{ configCommand(config) }}
\n
\n
\n
\n
Run as
\n
{{config.User}}
\n
Default
\n
Directory
\n
{{config.WorkingDir}}
\n
/
\n
Stop with
\n
{{config.StopSignal}}
\n
Architecture
\n
{{config.architecture}}
\n
{{image.dockerImageMetadata.Architecture}}
\n
\n
\n
Environment
\n
{{env}}
\n
\n
\n
\n
\n
Ports
\n
{{port}}
\n
None
\n
\n
\n
Volumes
\n
{{volume}}
\n
\n
\n"; +var id1="registry-image-widgets/views/image-config.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -916,8 +1072,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1=""; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/image-layers.html",v1)}]); +var v1="\n"; +var id1="registry-image-widgets/views/image-layers.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -927,8 +1086,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
Tag From Identifier Last Updated
{{ tag.name }}
pushed image
{{tag.spec.from.name}}\n {{name.qualified}}\n {{tag.spec.from.name}}
\nUnable to resolve
Not yet synced \nUnresolved
{{tag.status.items[0].image}} \nnone
{{ tag.status.items[0].created | dateRelative }}
No tags are present. {{failure}}
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/image-listing.html",v1)}]); +var v1="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TagFromIdentifierSignaturesLast Updated
\n\n\n{{ tag.name }}\n\n
pushed image
\n
\n{{tag.spec.from.name}}\n\n{{name.qualified}}\n\n{{tag.spec.from.name}}\n\n\n
\n
\n
\n
\n
\n\nUnable to resolve\n
\n
\nNot yet synced\nUnresolved\n
\n
\n
\n\n{{tag.status.items[0].image}}\n\nnone\n
\n
\n
\n
\n\n\n\n{{ overallVerification(tag) }}\n
\n
\n
\n\n{{ tag.status.items[0].created | dateRelative }}\n\n
\n
\n\n
No tags are present.{{failure}}
\n"; +var id1="registry-image-widgets/views/image-listing.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -938,8 +1100,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
Labels
{{name}}={{value}}
On Build
{{line}}
Docker Version
{{image.dockerImageMetadata.DockerVersion}}
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/image-meta.html",v1)}]); +var v1="
\n
\n
Labels
\n
\n{{name}}={{value}}\n
\n
On Build
\n
{{line}}
\n\n
Docker Version
\n
{{image.dockerImageMetadata.DockerVersion}}
\n
\n
\n"; +var id1="registry-image-widgets/views/image-meta.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -949,8 +1114,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/image-panel.html",v1)}]); +var v1="
\n
\n
\n\n
\n\n
\n
\n\n\n\n\n
\n
\n\n\n
\n
\n\n\n\n\n
\n
\n\n\n
\n
\n"; +var id1="registry-image-widgets/views/image-panel.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -960,8 +1128,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="

\nTo pull this image:

$ sudo docker pull {{imagestream.status.publicDockerImageRepository}}/{{names[0]}}\n$ sudo docker pull registry/{{names[0]}}\n$ sudo docker pull {{settings.registry.host}}/{{names[0]}}
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/image-pull.html",v1)}]); +var v1="
\n

\n\nTo pull this image:\n

\n$ sudo docker pull {{imagestream.status.publicDockerImageRepository}}/{{names[0]}}\n$ sudo docker pull registry/{{names[0]}}\n$ sudo docker pull {{settings.registry.host}}/{{names[0]}}\n
\n"; +var id1="registry-image-widgets/views/image-pull.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -971,8 +1142,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
\n{{ condition.message }}. Timestamp: {{ condition.lastTransitionTime }} Error count: {{ condition.generation }}\nEdit image stream
Access Policy
Images may be pulled by anonymous users\nImages may be pulled by anonymous users\n
Images may be pulled by any authenticated user or group\nImages may be pulled by any authenticated user or group\n
Images may only be pulled by specific users or groups\nImages may only be pulled by specific users or groups\n
Unknown\nUnknown\n
Follows docker repo
{{imagestream.spec.dockerImageRepository}}
Pulling repository
{{imagestream.status.dockerImageRepository}}
Public pulling repo
{{imagestream.status.publicDockerImageRepository}}
Image count
{{imagestream.status.tags.length}}
0
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/imagestream-body.html",v1)}]); +var v1="
\n
Signature
\n
{{ signature.metadata.name }}
\n
Verified
\n
\n\n\n\n{{ signature.verified }}\n
\n\n
Details
\n
{{signatureDetails(signature)}}
\n
\n
\n
\nNo signatures\n
\n"; +var id1="registry-image-widgets/views/image-signatures.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -982,8 +1156,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
Name Tags Repository
{{ imagestream.metadata.namespace + '/' + imagestream.metadata.name }}
{{ tag.name }}\n 4\" translate-n=\"tag_count - 4\" translate translate-plural=\"and {{ $count }} others\">and {{ $count }} other unknown\n{{imagestream.status.dockerImageRepository || imagestream.spec.dockerImageRepository}}
No image streams are present. {{failure}}
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/imagestream-listing.html",v1)}]); +var v1="
\n
\n\n{{ condition.message }}. Timestamp: {{ condition.lastTransitionTime }} Error count: {{ condition.generation }}\nEdit image stream\n
\n
\n
\n
Access Policy
\n
\n
\nImages may be pulled by anonymous users\nImages may be pulled by anonymous users\n\n
\n
\nImages may be pulled by any authenticated user or group\nImages may be pulled by any authenticated user or group\n\n
\n
\nImages may only be pulled by specific users or groups\nImages may only be pulled by specific users or groups\n\n
\n
\nUnknown\nUnknown\n\n
\n
\n
Follows docker repo
\n
{{imagestream.spec.dockerImageRepository}}
\n
Pulling repository
\n
{{imagestream.status.dockerImageRepository}}
\n
Public pulling repo
\n
{{imagestream.status.publicDockerImageRepository}}
\n
Image count
\n
{{imagestream.status.tags.length}}
\n
0
\n
\n"; +var id1="registry-image-widgets/views/imagestream-body.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -993,8 +1170,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/imagestream-meta.html",v1)}]); +var v1="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
NameTagsRepository
\n\n\n{{ imagestream.metadata.namespace + '/' + imagestream.metadata.name }}\n
\n\n
\n
\n{{ tag.name }}\n 4\" translate-n=\"tag_count - 4\" translate translate-plural=\"and {{ $count }} others\">and {{ $count }} other\n\nunknown\n{{imagestream.status.dockerImageRepository || imagestream.spec.dockerImageRepository}}\n
\n\n
No image streams are present.{{failure}}
\n"; +var id1="registry-image-widgets/views/imagestream-listing.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -1004,8 +1184,11 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="
\n
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/imagestream-panel.html",v1)}]); +var v1="
\n\n
\n"; +var id1="registry-image-widgets/views/imagestream-meta.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), @@ -1015,12 +1198,29 @@ module.exports=v1; var angular=window.angular,ngModule; try {ngModule=angular.module(["ng"])} catch(e){ngModule=angular.module("ng",[])} -var v1="

\nTo push an image to this image stream:

$ sudo docker tag myimage {{imagestream.status.publicDockerImageRepository}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker push {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker tag myimage {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker push {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker tag myimage registry/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker push registry/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag
"; -ngModule.run(["$templateCache",function(c){c.put("registry-image-widgets/views/imagestream-push.html",v1)}]); +var v1="
\n
\n
\n\n\n
\n\n
\n
\n\n\n\n\n
\n
\n\n\n
\n
\n
\n\n\n
\n
\n
\n"; +var id1="registry-image-widgets/views/imagestream-panel.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} module.exports=v1; /***/ }), /* 19 */ +/***/ (function(module, exports) { + +var angular=window.angular,ngModule; +try {ngModule=angular.module(["ng"])} +catch(e){ngModule=angular.module("ng",[])} +var v1="
\n

\n\nTo push an image to this image stream:\n

\n$ sudo docker tag myimage {{imagestream.status.publicDockerImageRepository}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker push {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker tag myimage {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker push {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker tag myimage registry/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n$ sudo docker push registry/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\n
\n"; +var id1="registry-image-widgets/views/imagestream-push.html"; +var inj=angular.element(window.document).injector(); +if(inj){inj.get("$templateCache").put(id1,v1);} +else{ngModule.run(["$templateCache",function(c){c.put(id1,v1)}]);} +module.exports=v1; + +/***/ }), +/* 20 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(4); @@ -1034,14 +1234,15 @@ __webpack_require__(7); __webpack_require__(8); __webpack_require__(11); __webpack_require__(9); +__webpack_require__(14); __webpack_require__(12); __webpack_require__(13); __webpack_require__(10); -__webpack_require__(14); __webpack_require__(15); __webpack_require__(16); __webpack_require__(17); -module.exports = __webpack_require__(18); +__webpack_require__(18); +module.exports = __webpack_require__(19); /***/ }) diff --git a/dist/image-widgets.js.map b/dist/image-widgets.js.map index bc2dd6f..0f4f3fe 100644 --- a/dist/image-widgets.js.map +++ b/dist/image-widgets.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 6c60f748eedf244ffe2f","webpack:///./images.less?51af","webpack:///./layers.less?5f5c","webpack:///./client.js","webpack:///./date.js","webpack:///./images.js","webpack:///./layers.js","webpack:///./views/annotations.html","webpack:///./views/image-body.html","webpack:///./views/image-config.html","webpack:///./views/image-layers.html","webpack:///./views/image-listing.html","webpack:///./views/image-meta.html","webpack:///./views/image-panel.html","webpack:///./views/image-pull.html","webpack:///./views/imagestream-body.html","webpack:///./views/imagestream-listing.html","webpack:///./views/imagestream-meta.html","webpack:///./views/imagestream-panel.html","webpack:///./views/imagestream-push.html"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;AChEA,yC;;;;;;ACAA,yC;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,gCAAgC;AAChC;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;;AAEA;AACA,CAAC;;;;;;;ACrFD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,CAAC;;;;;;;ACvFD;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,gCAAgC;AAChC;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C,iCAAiC,QAAQ;AACzC;AACA,sCAAsC,QAAQ;AAC9C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,qEAAqE,EAAE;AACvE;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,yDAAyD;AACzD;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,0DAA0D;AAC1D;AACA,iBAAiB;AACjB;AACA,wDAAwD;AACxD;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,EAAE;AAC1C;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,wCAAwC,EAAE;AAC1C;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,CAAC;;;;;;;ACpdD;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,gCAAgC;AAChC;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,yBAAyB;AACzB;AACA,yEAAyE,EAAE,QAAQ,EAAE,gBAAgB,EAAE;AACvG,yBAAyB;AACzB,yEAAyE,EAAE,UAAU,EAAE,mBAAmB,EAAE;AAC5G;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB;;AAErB;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;;AAEA,CAAC;;;;;;;AClID;AACA,KAAK;AACL,SAAS;AACT,8GAA8G,MAAM,IAAI,OAAO;AAC/H,2CAA2C,0DAA0D;AACrG,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,oHAAoH,eAAe,yFAAyF,kBAAkB,qGAAqG,sBAAsB,kJAAkJ,cAAc,mEAAmE,eAAe,yEAAyE,kCAAkC,kGAAkG,sBAAsB,6TAA6T,mCAAmC,KAAK,mDAAmD,sGAAsG,mCAAmC,KAAK,kDAAkD,+HAA+H,sBAAsB,KAAK,sCAAsC,gEAAgE,uBAAuB,gHAAgH,gBAAgB,iKAAiK,MAAM,aAAa;AACj+D,2CAA2C,yDAAyD;AACpG,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,4EAA4E,yBAAyB,uJAAuJ,aAAa,gIAAgI,mBAAmB,yIAAyI,mBAAmB,0EAA0E,qBAAqB,2CAA2C,wCAAwC,sLAAsL,KAAK,uLAAuL,MAAM,0PAA0P,QAAQ;AACp2C,2CAA2C,2DAA2D;AACtG,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,8FAA8F,cAAc,oBAAoB,cAAc,KAAK,0BAA0B,aAAa,cAAc;AACxM,2CAA2C,2DAA2D;AACtG,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,oXAAoX,qFAAqF,eAAe,wEAAwE,2RAA2R,qCAAqC,aAAa,WAAW,KAAK,YAAY,uLAAuL,oBAAoB,+BAA+B,oBAAoB,0FAA0F,gBAAgB,mGAAmG,YAAY,qDAAqD,uBAAuB,oBAAoB,4WAA4W,yDAAyD,oYAAoY,KAAK,4CAA4C,2BAA2B,KAAK,2BAA2B,uIAAuI,wBAAwB,+CAA+C,KAAK,uCAAuC,wBAAwB,MAAM,8CAA8C,0cAA0c,SAAS;AAC9mG,2CAA2C,4DAA4D;AACvG,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,gMAAgM,MAAM,GAAG,OAAO,uHAAuH,MAAM,4IAA4I,yCAAyC;AAClgB,2CAA2C,yDAAyD;AACpG,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,wSAAwS,oBAAoB,kFAAkF,sBAAsB,wFAAwF,oBAAoB;AAChhB,2CAA2C,0DAA0D;AACrG,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,+OAA+O,gDAAgD,UAAU,UAAU,qKAAqK,UAAU,8HAA8H,wBAAwB,UAAU,UAAU;AAC5oB,2CAA2C,yDAAyD;AACpG,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,ySAAyS,qBAAqB,eAAe,gCAAgC,gBAAgB,wBAAwB,+4DAA+4D,wCAAwC,iDAAiD,0CAA0C,qIAAqI,gDAAgD,yFAAyF,gCAAgC;AACrtF,2CAA2C,+DAA+D;AAC1G,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,wVAAwV,oEAAoE,gCAAgC,uCAAuC,mPAAmP,oEAAoE,iKAAiK,KAAK,2VAA2V,WAAW,KAAK,YAAY,qGAAqG,UAAU,gBAAgB,UAAU,sQAAsQ,oFAAoF,qaAAqa,SAAS;AACxsE,2CAA2C,kEAAkE;AAC7G,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT;AACA,2CAA2C,+DAA+D;AAC1G,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,6dAA6d,oBAAoB,uFAAuF,oBAAoB,+HAA+H,oBAAoB;AAC/uB,2CAA2C,gEAAgE;AAC3G,kB;;;;;;ACLA;AACA,KAAK;AACL,SAAS;AACT,wQAAwQ,gDAAgD,UAAU,kCAAkC,GAAG,4BAA4B,0CAA0C,wBAAwB,UAAU,kCAAkC,GAAG,4BAA4B,2JAA2J,wBAAwB,UAAU,kCAAkC,GAAG,4BAA4B,0CAA0C,wBAAwB,UAAU,kCAAkC,GAAG,4BAA4B,kMAAkM,kCAAkC,GAAG,4BAA4B,gFAAgF,kCAAkC,GAAG,4BAA4B;AAC/yC,2CAA2C,+DAA+D;AAC1G,kB","file":"image-widgets.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 19);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 6c60f748eedf244ffe2f","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./images.less\n// module id = 0\n// module chunks = 0","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./layers.less\n// module id = 1\n// module chunks = 0","/*\n * This file is part of Cockpit.\n *\n * Copyright (C) 2016 Red Hat, Inc.\n *\n * Cockpit is free software; you can redistribute it and/or modify it\n * under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2.1 of the License, or\n * (at your option) any later version.\n *\n * Cockpit is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Cockpit; If not, see .\n */\n\nangular.module('registryUI.client', [ ])\n\n.factory('WeakMap', function() {\n if (typeof window.WeakMap === 'function')\n return window.WeakMap;\n\n /*\n * A WeakMap implementation\n *\n * This works on ES5 browsers, with the caveat that the mapped\n * items are discoverable with enough work.\n *\n * To be clear, the principal use of a WeakMap is to associate\n * an value with an object, the object is the key. And then have\n * that value go away when the object does. This is very, very\n * similar to properties.\n *\n * The main difference is that any assigned values are not\n * garbage collected if the *weakmap* itself is collected,\n * and of course one can actually access the non-enumerable\n * property that makes this work.\n */\n\n var weak_property, local_seed = 1;\n function SimpleWeakMap() {\n var local_property = \"weakmap\" + local_seed;\n local_seed += 1;\n\n if (!weak_property)\n weak_property = Math.random().toString(36).slice(2);\n\n var self = this;\n\n self.delete = function delete_(obj) {\n var x, map = obj[weak_property];\n if (map)\n delete map[local_property];\n };\n\n self.has = function has(obj) {\n var map = obj[weak_property];\n return (map && local_property in map);\n };\n\n self.get = function get(obj) {\n var map = obj[weak_property];\n if (!map)\n return undefined;\n return map[local_property];\n };\n\n self.set = function set(obj, value) {\n var map = obj[weak_property];\n if (!map) {\n map = function WeakMapData() { };\n Object.defineProperty(obj, weak_property, {\n enumerable: false, configurable: false,\n writable: false, value: map,\n });\n }\n\n map[local_property] = value;\n };\n }\n\n return SimpleWeakMap;\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client.js\n// module id = 2\n// module chunks = 0","/* globals moment */\n\n(function() {\n\nangular.module('registryUI.date', [])\n\n.provider(\"MomentLib\", [\n function() {\n var self = this;\n\n /* Until we come up with a good default implementation, must be provided */\n self.MomentLibFactory = \"globalMoment\";\n\n function load(injector, name) {\n if (angular.isString(name))\n return injector.get(name, \"MomentLib\");\n else\n return injector.invoke(name);\n }\n\n self.$get = [\n \"$injector\",\n function($injector) {\n return load($injector, self.MomentLibFactory);\n }\n ];\n }\n])\n\n.factory(\"globalMoment\", [\n function() {\n return moment;\n }\n])\n\n.factory('dateRefreshMinute', [\n \"$rootScope\",\n function($rootScope) {\n var interval = null;\n return {\n enable: function() {\n if (interval === null) {\n interval = window.setInterval(function() {\n $rootScope.$applyAsync();\n }, 60000);\n }\n },\n disable: function() {\n if (interval !== null) {\n window.clearInterval(interval);\n interval = null;\n }\n },\n };\n }\n])\n\n.filter('dateRelative', [\n \"MomentLib\",\n \"dateRefreshMinute\",\n function(momentLib) {\n if (typeof(momentLib) === 'function') {\n momentLib.createFromInputFallback = function(config) {\n config._d = new Date(config._i);\n };\n }\n\n function dateRelative(timestamp) {\n if (!timestamp)\n return timestamp;\n\n return momentLib(timestamp).fromNow();\n }\n\n /* When moment is not loaded fall back to simple behavior */\n function dateAbsolute(timestamp) {\n return timestamp;\n }\n\n dateRelative.$stateful = true;\n if (typeof(momentLib) === 'function')\n return dateRelative;\n else\n return dateAbsolute;\n }\n]);\n\n}());\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./date.js\n// module id = 3\n// module chunks = 0","/*\n * This file is part of Cockpit.\n *\n * Copyright (C) 2016 Red Hat, Inc.\n *\n * Cockpit is free software; you can redistribute it and/or modify it\n * under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2.1 of the License, or\n * (at your option) any later version.\n *\n * Cockpit is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Cockpit; If not, see .\n */\n\n(function() {\n\"use strict\";\n\n/*\n * Executes callback for each stream.status.tag[x].item[y]\n * in a stream. Similar behavior to angular.forEach()\n */\nfunction imagestreamEachTagItem(imagestream, callback, context) {\n var i, il, items;\n var t, tl, tags = (imagestream.status || {}).tags || [];\n for (t = 0, tl = tags.length; t < tl; t++) {\n items = (tags[t].items) || [];\n for (i = 0, il = items.length; i < il; i++)\n callback.call(context || null, tags[t], items[i]);\n }\n}\n\nangular.module('registryUI.images', [\n 'registryUI.client',\n 'registryUI.date',\n 'gettext',\n])\n\n.factory('imageDockerManifest', [\n 'WeakMap',\n function(WeakMap) {\n var weak = new WeakMap();\n\n return function imageDockerManifest(image) {\n if (!image)\n return { };\n var manifest = weak.get(image);\n if (!manifest) {\n manifest = JSON.parse(image.dockerImageManifest || \"{ }\");\n angular.forEach(manifest.history || [], function(item) {\n if (typeof item.v1Compatibility == \"string\")\n item.v1Compatibility = JSON.parse(item.v1Compatibility);\n });\n weak.set(image, manifest);\n }\n return manifest;\n };\n }\n])\n\n.factory('imageDockerConfig', [\n 'WeakMap',\n 'imageLayers',\n function(WeakMap, imageLayers) {\n var weak = new WeakMap();\n return function imageDockerConfig(image) {\n if (!image)\n return { };\n var meta, layers, compat, config = weak.get(image);\n if (!config) {\n layers = imageLayers(image);\n if (layers.length)\n compat = layers[0].v1Compatibility;\n if (compat && compat.config) {\n config = compat.config;\n } else {\n meta = image.dockerImageMetadata || { };\n if (meta.Config)\n config = meta.Config;\n }\n weak.set(image, config);\n }\n return config || { };\n };\n }\n])\n\n.factory('imageLayers', [\n 'WeakMap',\n 'imageDockerManifest',\n function(WeakMap, imageDockerManifest) {\n var weak = new WeakMap();\n return function imageLayers(image) {\n if (!image)\n return [];\n var manifest, layers = weak.get(image);\n if (!layers) {\n manifest = imageDockerManifest(image);\n if (manifest.history)\n layers = manifest.history;\n else if (image.dockerImageLayers)\n layers = image.dockerImageLayers;\n else\n layers = [];\n weak.set(image, layers);\n }\n return layers;\n };\n }\n])\n\n.factory('imagestreamTags', [\n 'WeakMap',\n function(WeakMap) {\n var weak = new WeakMap();\n return function imagestreamTags(imagestream) {\n if (!imagestream)\n return [ ];\n var name, build, tags = weak.get(imagestream);\n if (!tags) {\n build = { };\n angular.forEach(imagestream.spec.tags, function(tag) {\n build[tag.name] = build[tag.name] || { name: tag.name, imagestream: imagestream };\n build[tag.name].spec = angular.copy(tag);\n });\n angular.forEach(imagestream.status.tags, function(tag) {\n build[tag.tag] = build[tag.tag] || { name: tag.tag, imagestream: imagestream };\n build[tag.tag].status = angular.copy(tag);\n });\n tags = [ ];\n for (name in build)\n tags.push(build[name]);\n weak.set(imagestream, tags);\n }\n return tags;\n };\n }\n])\n\n.factory('imagestreamTagFromName', [\n function() {\n return function imagestreamFromName(imagestream, from) {\n var parts, result = [ ];\n if (from && from.kind === \"ImageStreamImage\")\n result.delimiter = \"@\";\n else if (from && from.kind === \"ImageStreamTag\")\n result.delimiter = \":\";\n if (result.delimiter) {\n parts = from.name.split(result.delimiter);\n if (parts.length === 1) {\n result.push(imagestream.spec.name, parts[0]);\n } else {\n result.push(parts.shift());\n result.push(parts.join(result.delimiter));\n }\n result.qualified = result.join(result.delimiter);\n }\n return result;\n };\n }\n])\n\n.directive('registryImageBody', [\n 'imageLayers',\n 'imageDockerConfig',\n function(imageLayers, imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n names: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-body.html',\n link: function(scope, element, attrs) {\n scope.$watch(\"image\", function(image) {\n scope.layers = imageLayers(image);\n scope.config = imageDockerConfig(image);\n scope.labels = scope.config.Labels;\n if (angular.equals({ }, scope.labels))\n scope.labels = null;\n });\n }\n };\n }\n])\n\n.directive('registryImagePull', [\n function() {\n return {\n restrict: 'E',\n scope: {\n settings: '=',\n names: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-pull.html'\n };\n }\n])\n\n.directive('registryImageConfig', [\n 'imageDockerConfig',\n function(imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-config.html',\n link: function(scope, element, attrs) {\n scope.configCommand = function configCommand(config) {\n var result = [ ];\n if (!config)\n return \"\";\n if (config.Entrypoint)\n result.push.apply(result, config.Entrypoint);\n if (config.Cmd)\n result.push.apply(result, config.Cmd);\n var string = result.join(\" \");\n if (config.User && config.User.split(\":\")[0] != \"root\")\n return \"$ \" + string;\n else\n return \"# \" + string;\n };\n\n scope.$watch(\"image\", function(image) {\n scope.config = imageDockerConfig(image);\n });\n }\n };\n }\n])\n\n.directive('registryImageMeta', [\n 'imageDockerConfig',\n function(imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-meta.html',\n link: function(scope, element, attrs) {\n scope.$watch(\"image\", function(image) {\n scope.config = imageDockerConfig(image);\n scope.labels = scope.config.Labels;\n if (angular.equals({ }, scope.labels))\n scope.labels = null;\n });\n }\n };\n }\n])\n\n.directive('registryImagestreamBody', [\n function() {\n return {\n restrict: 'E',\n scope: {\n imagestream: '=',\n imagestreamFunc: '&imagestreamModify',\n projectFunc: '&projectModify',\n sharingFunc: '&projectSharing',\n },\n templateUrl: 'registry-image-widgets/views/imagestream-body.html',\n link: function(scope, element, attrs) {\n scope.projectModify = scope.projectFunc();\n scope.projectSharing = scope.sharingFunc();\n scope.imagestreamModify = scope.imagestreamFunc();\n }\n };\n }\n])\n\n.directive('registryImagestreamPush', [\n function(imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n imagestream: '=',\n settings: '=',\n },\n templateUrl: 'registry-image-widgets/views/imagestream-push.html',\n };\n }\n])\n\n.directive('registryAnnotations', [\n function() {\n return {\n restrict: 'E',\n scope: {\n annotations: '=',\n },\n templateUrl: 'registry-image-widgets/views/annotations.html',\n };\n }\n])\n\n.directive('registryImagestreamMeta', [\n function(imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n imagestream: '=',\n },\n templateUrl: 'registry-image-widgets/views/imagestream-meta.html',\n };\n }\n])\n\n.factory('registryImageListingFunc', [\n 'imagestreamTags',\n 'imagestreamTagFromName',\n '$location',\n function(imagestreamTags, imagestreamTagFromName, $location) {\n return function(scope, element, attrs) {\n scope.imagestreamTags = imagestreamTags;\n scope.imagestreamPath = scope.imagestreamFunc();\n scope.imageByTag = scope.imageByTagFunc();\n scope.imageTagNames = scope.imageTagNamesFunc();\n scope.sharedImages = scope.sharedImagesFunc();\n scope.imagestreamTagFromName = imagestreamTagFromName;\n\n /* Called when someone clicks on a row */\n scope.imagestreamActivate = function imagestreamActivate(imagestream, tag, ev) {\n var event;\n if (scope.imagestreamExpanded(imagestream, tag)) {\n scope.imagestreamToggle(imagestream, tag, ev);\n } else {\n event = scope.$emit(\"activate\", imagestream, tag, ev);\n if (!event.defaultPrevented && scope.imagestreamPath)\n $location.path(scope.imagestreamPath(imagestream, tag));\n }\n ev.preventDefault();\n ev.stopPropagation();\n };\n\n /* A list of all the expanded rows */\n var expanded = { };\n\n function identifier(imagestream, tag) {\n var id = imagestream.metadata.namespace + \"/\" + imagestream.metadata.name;\n if (tag)\n id += \"/\" + tag.name;\n return id;\n }\n\n /* Called to check the state of an expanded row */\n scope.imagestreamExpanded = function imagestreamExpanded(imagestream, tag) {\n return identifier(imagestream, tag) in expanded;\n };\n\n /* Called when someone toggles a row */\n scope.imagestreamToggle = function imagestreamToggle(imagestream, tag, ev) {\n var id = identifier(imagestream, tag);\n if (id in expanded)\n delete expanded[id];\n else\n expanded[id] = true;\n ev.stopPropagation();\n };\n };\n }\n])\n\n.directive('registryImagestreamListing', [\n 'registryImageListingFunc',\n function(imageListingFunc) {\n return {\n restrict: 'E',\n scope: {\n imagestreams: '=',\n imagestreamFunc: '&imagestreamPath',\n settings: '=',\n actions: '=',\n imageByTagFunc: '&imageByTag',\n imageTagNamesFunc: '&imageTagNames',\n sharedImagesFunc: '&sharedImages'\n },\n templateUrl: 'registry-image-widgets/views/imagestream-listing.html',\n link: imageListingFunc\n };\n }\n])\n\n.directive('registryImageListing', [\n 'registryImageListingFunc',\n function(imageListingFunc) {\n return {\n restrict: 'E',\n scope: {\n imagestream: '=',\n imagestreamFunc: '&imagestreamPath',\n settings: '=',\n actions: '=',\n imageByTagFunc: '&imageByTag',\n imageTagNamesFunc: '&imageTagNames',\n sharedImagesFunc: '&sharedImages'\n },\n templateUrl: 'registry-image-widgets/views/image-listing.html',\n link: imageListingFunc\n };\n }\n])\n\n.directive('registryImagePanel', [\n 'imageDockerConfig',\n 'imageLayers',\n function(imageDockerConfig, imageLayers) {\n return {\n restrict: 'E',\n transclude: true,\n scope: true,\n templateUrl: 'registry-image-widgets/views/image-panel.html',\n link: function(scope, element, attrs) {\n var tab = 'main';\n scope.tab = function(name, ev) {\n if (ev) {\n tab = name;\n ev.stopPropagation();\n }\n return tab === name;\n };\n\n scope.$watch(function() {\n scope.image = scope.imageByTag(scope.tag);\n });\n\n scope.$watch(\"image\", function(image) {\n if (scope.image) {\n scope.layers = imageLayers(scope.image);\n scope.config = imageDockerConfig(scope.image);\n scope.labels = scope.config.Labels;\n if (scope.imageTagNames)\n scope.names = scope.imageTagNames(scope.image);\n }\n });\n }\n };\n }\n])\n\n.directive('registryImagestreamPanel', [\n function() {\n return {\n restrict: 'E',\n transclude: true,\n scope: true,\n templateUrl: 'registry-image-widgets/views/imagestream-panel.html',\n link: function(scope, element, attrs) {\n var tab = 'main';\n scope.tab = function(name, ev) {\n if (ev) {\n tab = name;\n ev.stopPropagation();\n }\n return tab === name;\n };\n }\n };\n }\n]);\n\n\n}());\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./images.js\n// module id = 4\n// module chunks = 0","/*\n * This file is part of Cockpit.\n *\n * Copyright (C) 2016 Red Hat, Inc.\n *\n * Cockpit is free software; you can redistribute it and/or modify it\n * under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2.1 of the License, or\n * (at your option) any later version.\n *\n * Cockpit is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Cockpit; If not, see .\n */\n\n/* globals cockpit */\n\n(function() {\n \"use strict\";\n\n function v1CompatibilityLabel(layer, lower) {\n var cmd, last;\n if (layer.v1Compatibility.container_config) {\n cmd = layer.v1Compatibility.container_config.Cmd;\n if (cmd) {\n last = cmd[cmd.length - 1];\n if (last.indexOf(\"#(nop)\") === 0)\n return last.substring(6).trim();\n else if (cmd.length == 1 && cmd[0].indexOf(\"/bin/sh -c #(nop)\") === 0)\n return cmd[0].substring(17).trim();\n else\n return cmd.join(\" \");\n }\n }\n\n return layer.v1Compatibility.id;\n }\n\n angular.module('registryUI.images')\n\n .factory('prepareLayer', [\n 'gettextCatalog',\n function(gettextCatalog) {\n return function prepareLayer(layer, index, layers) {\n var result;\n /* DockerImageManifest */\n if (layer.v1Compatibility) {\n result = {\n id: layer.v1Compatibility.id,\n size: layer.v1Compatibility.Size || 0,\n label: v1CompatibilityLabel(layer, layers[index + 1])\n };\n\n /* DockerImageLayers */\n } else if (layer.name && layer.size) {\n result = {\n id: layer.name,\n size: layer.size || 0,\n label: layer.name,\n };\n\n /* Unsupported layer type */\n } else {\n result = {\n size: 0,\n id: index,\n label: gettextCatalog.getString(\"Unknown layer\"),\n };\n }\n\n /* Some hints for coloring the display */\n if (result.label.indexOf(\"RUN \") === 0)\n result.hint = \"run\";\n else if (result.label.indexOf(\"ADD \") === 0 || result.size > 8192)\n result.hint = \"add\";\n else\n result.hint = \"other\";\n\n return result;\n };\n }\n ])\n\n .directive('registryImageLayers', [\n 'imageLayers',\n 'prepareLayer',\n 'gettextCatalog',\n function(imageLayers, prepareLayer, gettextCatalog) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n data: '=?layers',\n },\n templateUrl: 'registry-image-widgets/views/image-layers.html',\n link: function($scope, element, attributes) {\n $scope.formatSize = function(bytes) {\n var n;\n if (!bytes) {\n return \"\";\n } else if (bytes > 1024 && typeof cockpit != \"undefined\") {\n return cockpit.format_bytes(bytes);\n } else if (bytes > 1024 * 1024) {\n n = (bytes / (1024 * 1024)).toFixed(1);\n return gettextCatalog.getPlural(n, $scope, \"{0} MB\", \"{0} MB\").replace(\"{0}\", n);\n } else {\n return gettextCatalog.getPlural(n, $scope, \"{0} byte\", \"{0} bytes\").replace(\"{0}\", bytes);\n }\n };\n\n $scope.$watch('data', function(layers) {\n if (layers && layers.length)\n layers = layers.map(prepareLayer).reverse();\n $scope.layers = layers;\n });\n\n $scope.$watch('image', function(image) {\n /* Only digest layers if image is set, or null */\n if (!angular.isUndefined(image))\n $scope.data = imageLayers(image);\n });\n }\n };\n }\n ]);\n\n}());\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./layers.js\n// module id = 5\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
Annotations
{{name}}: {{value}}
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/annotations.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/annotations.html\n// module id = 6\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
Name
{{ labels.name }}
Summary
{{ labels.summary }}
Description
{{ labels.description }}
Source URL
{{ labels.url }}
Author
{{config.author}}
{{image.dockerImageMetadata.Author}}
{{labels['MAINTAINER']}}
Unknown
Built
{{ layers[0].v1Compatibility.created | dateRelative}}
{{image.dockerImageMetadata.Created | dateRelative}}
{{ labels['build-date'] | dateRelative}}
Digest
{{ image.metadata.name }}
Identifier
{{ config.Image }}
Tags
{{name}} 
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/image-body.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-body.html\n// module id = 7\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
Command
{{ configCommand(config) }}
Run as
{{config.User}}
Default
Directory
{{config.WorkingDir}}
/
Stop with
{{config.StopSignal}}
Architecture
{{config.architecture}}
{{image.dockerImageMetadata.Architecture}}
Environment
{{env}}
Ports
{{port}}
None
Volumes
{{volume}}
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/image-config.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-config.html\n// module id = 8\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
  • {{ formatSize(layer.size) }}

    {{ layer.label}}

\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/image-layers.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-layers.html\n// module id = 9\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
Tag From Identifier Last Updated
{{ tag.name }}
pushed image
{{tag.spec.from.name}}\\n {{name.qualified}}\\n {{tag.spec.from.name}}
\\nUnable to resolve
Not yet synced \\nUnresolved
{{tag.status.items[0].image}} \\nnone
{{ tag.status.items[0].created | dateRelative }}
No tags are present. {{failure}}
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/image-listing.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-listing.html\n// module id = 10\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
Labels
{{name}}={{value}}
On Build
{{line}}
Docker Version
{{image.dockerImageMetadata.DockerVersion}}
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/image-meta.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-meta.html\n// module id = 11\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/image-panel.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-panel.html\n// module id = 12\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"

\\nTo pull this image:

$ sudo docker pull {{imagestream.status.publicDockerImageRepository}}/{{names[0]}}\\n$ sudo docker pull registry/{{names[0]}}\\n$ sudo docker pull {{settings.registry.host}}/{{names[0]}}
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/image-pull.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-pull.html\n// module id = 13\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n{{ condition.message }}. Timestamp: {{ condition.lastTransitionTime }} Error count: {{ condition.generation }}\\nEdit image stream
Access Policy
Images may be pulled by anonymous users\\nImages may be pulled by anonymous users\\n
Images may be pulled by any authenticated user or group\\nImages may be pulled by any authenticated user or group\\n
Images may only be pulled by specific users or groups\\nImages may only be pulled by specific users or groups\\n
Unknown\\nUnknown\\n
Follows docker repo
{{imagestream.spec.dockerImageRepository}}
Pulling repository
{{imagestream.status.dockerImageRepository}}
Public pulling repo
{{imagestream.status.publicDockerImageRepository}}
Image count
{{imagestream.status.tags.length}}
0
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/imagestream-body.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-body.html\n// module id = 14\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
Name Tags Repository
{{ imagestream.metadata.namespace + '/' + imagestream.metadata.name }}
{{ tag.name }}\\n 4\\\" translate-n=\\\"tag_count - 4\\\" translate translate-plural=\\\"and {{ $count }} others\\\">and {{ $count }} other unknown\\n{{imagestream.status.dockerImageRepository || imagestream.spec.dockerImageRepository}}
No image streams are present. {{failure}}
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/imagestream-listing.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-listing.html\n// module id = 15\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/imagestream-meta.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-meta.html\n// module id = 16\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/imagestream-panel.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-panel.html\n// module id = 17\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"

\\nTo push an image to this image stream:

$ sudo docker tag myimage {{imagestream.status.publicDockerImageRepository}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker push {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker tag myimage {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker push {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker tag myimage registry/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker push registry/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag
\";\nngModule.run([\"$templateCache\",function(c){c.put(\"registry-image-widgets/views/imagestream-push.html\",v1)}]);\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-push.html\n// module id = 18\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap adc350ee55538afed628","webpack:///./images.less?50d8","webpack:///./layers.less?d714","webpack:///./client.js","webpack:///./date.js","webpack:///./images.js","webpack:///./layers.js","webpack:///./views/annotations.html","webpack:///./views/image-body.html","webpack:///./views/image-config.html","webpack:///./views/image-layers.html","webpack:///./views/image-listing.html","webpack:///./views/image-meta.html","webpack:///./views/image-panel.html","webpack:///./views/image-pull.html","webpack:///./views/image-signatures.html","webpack:///./views/imagestream-body.html","webpack:///./views/imagestream-listing.html","webpack:///./views/imagestream-meta.html","webpack:///./views/imagestream-panel.html","webpack:///./views/imagestream-push.html"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;AChEA,yC;;;;;;ACAA,yC;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,gCAAgC;AAChC;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA,iBAAiB;AACjB;;AAEA;AACA;AACA;;AAEA;AACA,CAAC;;;;;;;ACrFD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,CAAC;;;;;;;ACvFD;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,gCAAgC;AAChC;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C,iCAAiC,QAAQ;AACzC;AACA,sCAAsC,QAAQ;AAC9C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,qEAAqE,EAAE;AACvE;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,yDAAyD;AACzD;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,0DAA0D;AAC1D;AACA,iBAAiB;AACjB;AACA,wDAAwD;AACxD;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,EAAE;AAC1C;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,wCAAwC,EAAE;AAC1C;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,qBAAqB;AACrB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA,CAAC;;;;;;;ACvmBD;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,gCAAgC;AAChC;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,yBAAyB;AACzB;AACA,yEAAyE,EAAE,QAAQ,EAAE,gBAAgB,EAAE;AACvG,yBAAyB;AACzB,yEAAyE,EAAE,UAAU,EAAE,mBAAmB,EAAE;AAC5G;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB;;AAErB;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;;AAEA,CAAC;;;;;;;AClID;AACA,KAAK;AACL,SAAS;AACT,+GAA+G,MAAM,IAAI,OAAO;AAChI;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,sHAAsH,eAAe,2FAA2F,kBAAkB,uGAAuG,sBAAsB,qJAAqJ,cAAc,sEAAsE,eAAe,0EAA0E,kCAAkC,mGAAmG,sBAAsB,gUAAgU,mCAAmC,KAAK,mDAAmD,uGAAuG,mCAAmC,KAAK,kDAAkD,gIAAgI,sBAAsB,KAAK,sCAAsC,kEAAkE,uBAAuB,kHAAkH,gBAAgB,+JAA+J,kBAAkB,KAAK,wCAAwC,KAAK,2BAA2B,KAAK,0BAA0B,uKAAuK,MAAM,aAAa;AAC3xE;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,8EAA8E,yBAAyB,4JAA4J,aAAa,mIAAmI,mBAAmB,4IAA4I,mBAAmB,4EAA4E,qBAAqB,4CAA4C,wCAAwC,0LAA0L,KAAK,6LAA6L,MAAM,+PAA+P,QAAQ;AACn4C;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,+FAA+F,cAAc,qBAAqB,cAAc,KAAK,0BAA0B,cAAc,cAAc;AAC3M;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,qaAAqa,qFAAqF,eAAe,wEAAwE,kTAAkT,qCAAqC,aAAa,WAAW,KAAK,YAAY,2LAA2L,oBAAoB,gCAAgC,oBAAoB,2FAA2F,gBAAgB,oGAAoG,YAAY,qDAAqD,uBAAuB,oBAAoB,qXAAqX,yDAAyD,0YAA0Y,KAAK,6CAA6C,2BAA2B,KAAK,2BAA2B,6IAA6I,wBAAwB,gDAAgD,KAAK,uCAAuC,wBAAwB,OAAO,8CAA8C,8dAA8d,4BAA4B,sdAAsd,SAAS;AAC3tH;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,oMAAoM,MAAM,GAAG,OAAO,0HAA0H,MAAM,+IAA+I,yCAAyC;AAC5gB;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,8SAA8S,oBAAoB,qFAAqF,sBAAsB,2FAA2F,oBAAoB,wFAAwF,0BAA0B;AAC9oB;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,mPAAmP,gDAAgD,UAAU,UAAU,qKAAqK,UAAU,8HAA8H,wBAAwB,UAAU,UAAU;AAChpB;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,uGAAuG,2BAA2B,icAAic,sBAAsB,qGAAqG,6BAA6B;AAC3tB;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,2SAA2S,qBAAqB,eAAe,gCAAgC,gBAAgB,wBAAwB,m6DAAm6D,wCAAwC,mDAAmD,0CAA0C,uIAAuI,gDAAgD,2FAA2F,gCAAgC;AACjvF;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,iWAAiW,oEAAoE,gCAAgC,uCAAuC,yPAAyP,oEAAoE,mKAAmK,KAAK,+VAA+V,WAAW,KAAK,YAAY,qGAAqG,UAAU,gBAAgB,UAAU,yQAAyQ,oFAAoF,ibAAib,SAAS;AAC5uE;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT;AACA;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,meAAme,oBAAoB,wFAAwF,oBAAoB,iIAAiI,oBAAoB;AACxvB;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB;;;;;;ACRA;AACA,KAAK;AACL,SAAS;AACT,4QAA4Q,gDAAgD,UAAU,kCAAkC,GAAG,4BAA4B,0CAA0C,wBAAwB,UAAU,kCAAkC,GAAG,4BAA4B,2JAA2J,wBAAwB,UAAU,kCAAkC,GAAG,4BAA4B,0CAA0C,wBAAwB,UAAU,kCAAkC,GAAG,4BAA4B,kMAAkM,kCAAkC,GAAG,4BAA4B,gFAAgF,kCAAkC,GAAG,4BAA4B;AACnzC;AACA;AACA,QAAQ;AACR,KAAK,2CAA2C,cAAc;AAC9D,kB","file":"image-widgets.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 20);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap adc350ee55538afed628","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./images.less\n// module id = 0\n// module chunks = 0","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./layers.less\n// module id = 1\n// module chunks = 0","/*\n * This file is part of Cockpit.\n *\n * Copyright (C) 2016 Red Hat, Inc.\n *\n * Cockpit is free software; you can redistribute it and/or modify it\n * under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2.1 of the License, or\n * (at your option) any later version.\n *\n * Cockpit is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Cockpit; If not, see .\n */\n\nangular.module('registryUI.client', [ ])\n\n.factory('WeakMap', function() {\n if (typeof window.WeakMap === 'function')\n return window.WeakMap;\n\n /*\n * A WeakMap implementation\n *\n * This works on ES5 browsers, with the caveat that the mapped\n * items are discoverable with enough work.\n *\n * To be clear, the principal use of a WeakMap is to associate\n * an value with an object, the object is the key. And then have\n * that value go away when the object does. This is very, very\n * similar to properties.\n *\n * The main difference is that any assigned values are not\n * garbage collected if the *weakmap* itself is collected,\n * and of course one can actually access the non-enumerable\n * property that makes this work.\n */\n\n var weak_property, local_seed = 1;\n function SimpleWeakMap() {\n var local_property = \"weakmap\" + local_seed;\n local_seed += 1;\n\n if (!weak_property)\n weak_property = Math.random().toString(36).slice(2);\n\n var self = this;\n\n self.delete = function delete_(obj) {\n var x, map = obj[weak_property];\n if (map)\n delete map[local_property];\n };\n\n self.has = function has(obj) {\n var map = obj[weak_property];\n return (map && local_property in map);\n };\n\n self.get = function get(obj) {\n var map = obj[weak_property];\n if (!map)\n return undefined;\n return map[local_property];\n };\n\n self.set = function set(obj, value) {\n var map = obj[weak_property];\n if (!map) {\n map = function WeakMapData() { };\n Object.defineProperty(obj, weak_property, {\n enumerable: false, configurable: false,\n writable: false, value: map,\n });\n }\n\n map[local_property] = value;\n };\n }\n\n return SimpleWeakMap;\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client.js\n// module id = 2\n// module chunks = 0","/* globals moment */\n\n(function() {\n\nangular.module('registryUI.date', [])\n\n.provider(\"MomentLib\", [\n function() {\n var self = this;\n\n /* Until we come up with a good default implementation, must be provided */\n self.MomentLibFactory = \"globalMoment\";\n\n function load(injector, name) {\n if (angular.isString(name))\n return injector.get(name, \"MomentLib\");\n else\n return injector.invoke(name);\n }\n\n self.$get = [\n \"$injector\",\n function($injector) {\n return load($injector, self.MomentLibFactory);\n }\n ];\n }\n])\n\n.factory(\"globalMoment\", [\n function() {\n return moment;\n }\n])\n\n.factory('dateRefreshMinute', [\n \"$rootScope\",\n function($rootScope) {\n var interval = null;\n return {\n enable: function() {\n if (interval === null) {\n interval = window.setInterval(function() {\n $rootScope.$applyAsync();\n }, 60000);\n }\n },\n disable: function() {\n if (interval !== null) {\n window.clearInterval(interval);\n interval = null;\n }\n },\n };\n }\n])\n\n.filter('dateRelative', [\n \"MomentLib\",\n \"dateRefreshMinute\",\n function(momentLib) {\n if (typeof(momentLib) === 'function') {\n momentLib.createFromInputFallback = function(config) {\n config._d = new Date(config._i);\n };\n }\n\n function dateRelative(timestamp) {\n if (!timestamp)\n return timestamp;\n\n return momentLib(timestamp).fromNow();\n }\n\n /* When moment is not loaded fall back to simple behavior */\n function dateAbsolute(timestamp) {\n return timestamp;\n }\n\n dateRelative.$stateful = true;\n if (typeof(momentLib) === 'function')\n return dateRelative;\n else\n return dateAbsolute;\n }\n]);\n\n}());\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./date.js\n// module id = 3\n// module chunks = 0","/*\n * This file is part of Cockpit.\n *\n * Copyright (C) 2016 Red Hat, Inc.\n *\n * Cockpit is free software; you can redistribute it and/or modify it\n * under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2.1 of the License, or\n * (at your option) any later version.\n *\n * Cockpit is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Cockpit; If not, see .\n */\n\n(function() {\n\"use strict\";\n\n/*\n * Executes callback for each stream.status.tag[x].item[y]\n * in a stream. Similar behavior to angular.forEach()\n */\nfunction imagestreamEachTagItem(imagestream, callback, context) {\n var i, il, items;\n var t, tl, tags = (imagestream.status || {}).tags || [];\n for (t = 0, tl = tags.length; t < tl; t++) {\n items = (tags[t].items) || [];\n for (i = 0, il = items.length; i < il; i++)\n callback.call(context || null, tags[t], items[i]);\n }\n}\n\nangular.module('registryUI.images', [\n 'registryUI.client',\n 'registryUI.date',\n 'gettext',\n])\n\n.factory('imageDockerManifest', [\n 'WeakMap',\n function(WeakMap) {\n var weak = new WeakMap();\n\n return function imageDockerManifest(image) {\n if (!image)\n return { };\n var manifest = weak.get(image);\n if (!manifest) {\n manifest = JSON.parse(image.dockerImageManifest || \"{ }\");\n angular.forEach(manifest.history || [], function(item) {\n if (typeof item.v1Compatibility == \"string\")\n item.v1Compatibility = JSON.parse(item.v1Compatibility);\n });\n weak.set(image, manifest);\n }\n return manifest;\n };\n }\n])\n\n.factory('imageDockerConfig', [\n 'WeakMap',\n 'imageLayers',\n function(WeakMap, imageLayers) {\n var weak = new WeakMap();\n return function imageDockerConfig(image) {\n if (!image)\n return { };\n var meta, layers, compat, config = weak.get(image);\n if (!config) {\n layers = imageLayers(image);\n if (layers.length)\n compat = layers[0].v1Compatibility;\n if (compat && compat.config) {\n config = compat.config;\n } else {\n meta = image.dockerImageMetadata || { };\n if (meta.Config)\n config = meta.Config;\n }\n weak.set(image, config);\n }\n return config || { };\n };\n }\n])\n\n.factory('imageLayers', [\n 'WeakMap',\n 'imageDockerManifest',\n function(WeakMap, imageDockerManifest) {\n var weak = new WeakMap();\n return function imageLayers(image) {\n if (!image)\n return [];\n var manifest, layers = weak.get(image);\n if (!layers) {\n manifest = imageDockerManifest(image);\n if (manifest.history)\n layers = manifest.history;\n else if (image.dockerImageLayers)\n layers = image.dockerImageLayers;\n else\n layers = [];\n weak.set(image, layers);\n }\n return layers;\n };\n }\n])\n\n.factory('imagestreamTags', [\n 'WeakMap',\n function(WeakMap) {\n var weak = new WeakMap();\n return function imagestreamTags(imagestream) {\n if (!imagestream)\n return [ ];\n var name, build, tags = weak.get(imagestream);\n if (!tags) {\n build = { };\n angular.forEach(imagestream.spec.tags, function(tag) {\n build[tag.name] = build[tag.name] || { name: tag.name, imagestream: imagestream };\n build[tag.name].spec = angular.copy(tag);\n });\n angular.forEach(imagestream.status.tags, function(tag) {\n build[tag.tag] = build[tag.tag] || { name: tag.tag, imagestream: imagestream };\n build[tag.tag].status = angular.copy(tag);\n });\n tags = [ ];\n for (name in build)\n tags.push(build[name]);\n weak.set(imagestream, tags);\n }\n return tags;\n };\n }\n])\n\n.factory('imagestreamTagFromName', [\n function() {\n return function imagestreamFromName(imagestream, from) {\n var parts, result = [ ];\n if (from && from.kind === \"ImageStreamImage\")\n result.delimiter = \"@\";\n else if (from && from.kind === \"ImageStreamTag\")\n result.delimiter = \":\";\n if (result.delimiter) {\n parts = from.name.split(result.delimiter);\n if (parts.length === 1) {\n result.push(imagestream.spec.name, parts[0]);\n } else {\n result.push(parts.shift());\n result.push(parts.join(result.delimiter));\n }\n result.qualified = result.join(result.delimiter);\n }\n return result;\n };\n }\n])\n\n.directive('registryImageBody', [\n 'imageLayers',\n 'imageDockerConfig',\n 'imageSignatures',\n function(imageLayers, imageDockerConfig, imageSignatures) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n names: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-body.html',\n link: function(scope, element, attrs) {\n scope.$watch(\"image\", function(image) {\n scope.layers = imageLayers(image);\n scope.config = imageDockerConfig(image);\n scope.labels = scope.config.Labels;\n scope.signatures = imageSignatures(image);\n if (angular.equals({ }, scope.labels))\n scope.labels = null;\n });\n }\n };\n }\n])\n\n.directive('registryImagePull', [\n function() {\n return {\n restrict: 'E',\n scope: {\n settings: '=',\n names: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-pull.html'\n };\n }\n])\n\n.directive('registryImageConfig', [\n 'imageDockerConfig',\n function(imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-config.html',\n link: function(scope, element, attrs) {\n scope.configCommand = function configCommand(config) {\n var result = [ ];\n if (!config)\n return \"\";\n if (config.Entrypoint)\n result.push.apply(result, config.Entrypoint);\n if (config.Cmd)\n result.push.apply(result, config.Cmd);\n var string = result.join(\" \");\n if (config.User && config.User.split(\":\")[0] != \"root\")\n return \"$ \" + string;\n else\n return \"# \" + string;\n };\n\n scope.$watch(\"image\", function(image) {\n scope.config = imageDockerConfig(image);\n });\n }\n };\n }\n])\n\n.directive('registryImageSignatures', [\n 'imageSignatures',\n function(imageSignatures) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-signatures.html',\n link: function(scope, element, attrs) {\n scope.signatureDetails = function signatureDetails(signature) {\n var result = \"\";\n if (signature.conditions) {\n var condition = signature.conditions.find(function (condition) {\n return condition.type === \"Trusted\";\n });\n if (condition !== undefined) {\n result = condition.reason + \" / \" + condition.message;\n }\n }\n return result;\n };\n\n scope.$watch(\"image\", function(image) {\n scope.signatures = imageSignatures(image);\n });\n }\n };\n }\n])\n\n.directive('registryImageMeta', [\n 'imageDockerConfig',\n function(imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n },\n templateUrl: 'registry-image-widgets/views/image-meta.html',\n link: function(scope, element, attrs) {\n scope.$watch(\"image\", function(image) {\n scope.config = imageDockerConfig(image);\n scope.labels = scope.config.Labels;\n if (angular.equals({ }, scope.labels))\n scope.labels = null;\n });\n }\n };\n }\n])\n\n.directive('registryImagestreamBody', [\n function() {\n return {\n restrict: 'E',\n scope: {\n imagestream: '=',\n imagestreamFunc: '&imagestreamModify',\n projectFunc: '&projectModify',\n sharingFunc: '&projectSharing',\n },\n templateUrl: 'registry-image-widgets/views/imagestream-body.html',\n link: function(scope, element, attrs) {\n scope.projectModify = scope.projectFunc();\n scope.projectSharing = scope.sharingFunc();\n scope.imagestreamModify = scope.imagestreamFunc();\n }\n };\n }\n])\n\n.directive('registryImagestreamPush', [\n function(imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n imagestream: '=',\n settings: '=',\n },\n templateUrl: 'registry-image-widgets/views/imagestream-push.html',\n };\n }\n])\n\n.directive('registryAnnotations', [\n function() {\n return {\n restrict: 'E',\n scope: {\n annotations: '=',\n },\n templateUrl: 'registry-image-widgets/views/annotations.html',\n };\n }\n])\n\n.directive('registryImagestreamMeta', [\n function(imageDockerConfig) {\n return {\n restrict: 'E',\n scope: {\n imagestream: '=',\n },\n templateUrl: 'registry-image-widgets/views/imagestream-meta.html',\n };\n }\n])\n\n.factory('imageSignatures', [\n 'WeakMap',\n function(WeakMap) {\n var weak = new WeakMap();\n\n return function(image) {\n if (!image)\n return [];\n var signatures = weak.get(image);\n\n\n var signatureStatus = function(signature) {\n var trusted = \"Unverified\";\n if (signature.conditions) {\n var condition = signature.conditions.find(function (condition) {\n return condition.type === \"Trusted\";\n });\n if (condition !== undefined) {\n trusted = \"Verified\";\n } else {\n // Failed info not available\n // https://github.com/openshift/origin/issues/16301\n trusted = \"Failed verification\";\n }\n }\n return trusted;\n };\n\n /*\n signatures = [];\n if (image.signatures) {\n image.signatures.forEach(function(signature) {\n signature.verified = signatureStatus(signature);\n signatures.push(signature);\n });\n }\n weak.set(image, signatures);\n */\n\n if (!signatures && image.signatures) {\n signatures = [];\n image.signatures.forEach(function(signature) {\n signature.verified = signatureStatus(signature);\n signatures.push(signature);\n });\n weak.set(image, signatures);\n }\n\n return signatures || [];\n };\n }\n])\n\n.factory('registryImageListingFunc', [\n 'imagestreamTags',\n 'imagestreamTagFromName',\n 'imageSignatures',\n '$location',\n function(imagestreamTags, imagestreamTagFromName, imageSignatures, $location) {\n return function(scope, element, attrs) {\n scope.imagestreamTags = imagestreamTags;\n scope.imagestreamPath = scope.imagestreamFunc();\n scope.imageByTag = scope.imageByTagFunc();\n scope.imageTagNames = scope.imageTagNamesFunc();\n scope.sharedImages = scope.sharedImagesFunc();\n scope.imagestreamTagFromName = imagestreamTagFromName;\n scope.imageSignatures = imageSignatures;\n\n scope.overallVerification = function overallVerification(tag) {\n var image, signature, signatures;\n var overall = \"Unverified\";\n\n image = scope.imageByTag(tag.status);\n signatures = scope.imageSignatures(image);\n\n if (signatures.length === 0) {\n return \"Unsigned\";\n } else {\n signatures.forEach(function(signature) {\n var status = signature.verified;\n if (status === \"Failed verification\" || overall === \"Failed verification\" || overall === undefined) {\n overall = status;\n } else if (status !== \"Failed verification\") {\n overall = status;\n }\n });\n }\n\n return overall;\n };\n\n /*\n scope.imageSignatures = function imageSignatures(imagestream, tag) {\n var image, signatures, signature;\n\n image = scope.imageByTag(tag.status);\n signatures = [];\n if (image.signatures) {\n image.signatures.forEach(function(signature) {\n signature.verified = scope.signatureVerification(signature);\n signatures.push(signature);\n });\n }\n\n return signatures;\n };\n\n scope.signatureVerification = function signatureVerification(signature) {\n var trusted = \"Unverified\";\n if (signature.conditions) {\n var condition = signature.conditions.find(function (condition) {\n return condition.type === \"Trusted\";\n });\n if (condition !== undefined) {\n trusted = \"Verified\";\n } else {\n // Failed info not available\n // https://github.com/openshift/origin/issues/16301\n trusted = \"Failed verification\";\n }\n }\n return trusted;\n };\n */\n\n /* Called when someone clicks on a row */\n scope.imagestreamActivate = function imagestreamActivate(imagestream, tag, ev) {\n var event;\n if (scope.imagestreamExpanded(imagestream, tag)) {\n scope.imagestreamToggle(imagestream, tag, ev);\n } else {\n event = scope.$emit(\"activate\", imagestream, tag, ev);\n if (!event.defaultPrevented && scope.imagestreamPath)\n $location.path(scope.imagestreamPath(imagestream, tag));\n }\n ev.preventDefault();\n ev.stopPropagation();\n };\n\n /* A list of all the expanded rows */\n var expanded = { };\n\n function identifier(imagestream, tag) {\n var id = imagestream.metadata.namespace + \"/\" + imagestream.metadata.name;\n if (tag)\n id += \"/\" + tag.name;\n return id;\n }\n\n /* Called to check the state of an expanded row */\n scope.imagestreamExpanded = function imagestreamExpanded(imagestream, tag) {\n return identifier(imagestream, tag) in expanded;\n };\n\n /* Called when someone toggles a row */\n scope.imagestreamToggle = function imagestreamToggle(imagestream, tag, ev) {\n var id = identifier(imagestream, tag);\n if (id in expanded)\n delete expanded[id];\n else\n expanded[id] = true;\n ev.stopPropagation();\n };\n };\n }\n])\n\n.directive('registryImagestreamListing', [\n 'registryImageListingFunc',\n function(imageListingFunc) {\n return {\n restrict: 'E',\n scope: {\n imagestreams: '=',\n imagestreamFunc: '&imagestreamPath',\n settings: '=',\n actions: '=',\n imageByTagFunc: '&imageByTag',\n imageTagNamesFunc: '&imageTagNames',\n sharedImagesFunc: '&sharedImages'\n },\n templateUrl: 'registry-image-widgets/views/imagestream-listing.html',\n link: imageListingFunc\n };\n }\n])\n\n.directive('registryImageListing', [\n 'registryImageListingFunc',\n function(imageListingFunc) {\n return {\n restrict: 'E',\n scope: {\n imagestream: '=',\n imagestreamFunc: '&imagestreamPath',\n settings: '=',\n actions: '=',\n imageByTagFunc: '&imageByTag',\n imageTagNamesFunc: '&imageTagNames',\n sharedImagesFunc: '&sharedImages'\n },\n templateUrl: 'registry-image-widgets/views/image-listing.html',\n link: imageListingFunc\n };\n }\n])\n\n.directive('registryImagePanel', [\n 'imageDockerConfig',\n 'imageLayers',\n 'imageSignatures',\n function(imageDockerConfig, imageLayers, imageSignatures) {\n return {\n restrict: 'E',\n transclude: true,\n scope: true,\n templateUrl: 'registry-image-widgets/views/image-panel.html',\n link: function(scope, element, attrs) {\n var tab = 'main';\n scope.tab = function(name, ev) {\n if (ev) {\n tab = name;\n ev.stopPropagation();\n }\n return tab === name;\n };\n\n scope.$watch(function() {\n scope.image = scope.imageByTag(scope.tag);\n });\n\n scope.$watch(\"image\", function(image) {\n if (scope.image) {\n scope.layers = imageLayers(scope.image);\n scope.config = imageDockerConfig(scope.image);\n scope.labels = scope.config.Labels;\n scope.signatures = imageSignatures(scope.image);\n if (scope.imageTagNames)\n scope.names = scope.imageTagNames(scope.image);\n }\n });\n }\n };\n }\n])\n\n.directive('registryImagestreamPanel', [\n function() {\n return {\n restrict: 'E',\n transclude: true,\n scope: true,\n templateUrl: 'registry-image-widgets/views/imagestream-panel.html',\n link: function(scope, element, attrs) {\n var tab = 'main';\n scope.tab = function(name, ev) {\n if (ev) {\n tab = name;\n ev.stopPropagation();\n }\n return tab === name;\n };\n }\n };\n }\n]);\n\n\n}());\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./images.js\n// module id = 4\n// module chunks = 0","/*\n * This file is part of Cockpit.\n *\n * Copyright (C) 2016 Red Hat, Inc.\n *\n * Cockpit is free software; you can redistribute it and/or modify it\n * under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2.1 of the License, or\n * (at your option) any later version.\n *\n * Cockpit is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Cockpit; If not, see .\n */\n\n/* globals cockpit */\n\n(function() {\n \"use strict\";\n\n function v1CompatibilityLabel(layer, lower) {\n var cmd, last;\n if (layer.v1Compatibility.container_config) {\n cmd = layer.v1Compatibility.container_config.Cmd;\n if (cmd) {\n last = cmd[cmd.length - 1];\n if (last.indexOf(\"#(nop)\") === 0)\n return last.substring(6).trim();\n else if (cmd.length == 1 && cmd[0].indexOf(\"/bin/sh -c #(nop)\") === 0)\n return cmd[0].substring(17).trim();\n else\n return cmd.join(\" \");\n }\n }\n\n return layer.v1Compatibility.id;\n }\n\n angular.module('registryUI.images')\n\n .factory('prepareLayer', [\n 'gettextCatalog',\n function(gettextCatalog) {\n return function prepareLayer(layer, index, layers) {\n var result;\n /* DockerImageManifest */\n if (layer.v1Compatibility) {\n result = {\n id: layer.v1Compatibility.id,\n size: layer.v1Compatibility.Size || 0,\n label: v1CompatibilityLabel(layer, layers[index + 1])\n };\n\n /* DockerImageLayers */\n } else if (layer.name && layer.size) {\n result = {\n id: layer.name,\n size: layer.size || 0,\n label: layer.name,\n };\n\n /* Unsupported layer type */\n } else {\n result = {\n size: 0,\n id: index,\n label: gettextCatalog.getString(\"Unknown layer\"),\n };\n }\n\n /* Some hints for coloring the display */\n if (result.label.indexOf(\"RUN \") === 0)\n result.hint = \"run\";\n else if (result.label.indexOf(\"ADD \") === 0 || result.size > 8192)\n result.hint = \"add\";\n else\n result.hint = \"other\";\n\n return result;\n };\n }\n ])\n\n .directive('registryImageLayers', [\n 'imageLayers',\n 'prepareLayer',\n 'gettextCatalog',\n function(imageLayers, prepareLayer, gettextCatalog) {\n return {\n restrict: 'E',\n scope: {\n image: '=',\n data: '=?layers',\n },\n templateUrl: 'registry-image-widgets/views/image-layers.html',\n link: function($scope, element, attributes) {\n $scope.formatSize = function(bytes) {\n var n;\n if (!bytes) {\n return \"\";\n } else if (bytes > 1024 && typeof cockpit != \"undefined\") {\n return cockpit.format_bytes(bytes);\n } else if (bytes > 1024 * 1024) {\n n = (bytes / (1024 * 1024)).toFixed(1);\n return gettextCatalog.getPlural(n, $scope, \"{0} MB\", \"{0} MB\").replace(\"{0}\", n);\n } else {\n return gettextCatalog.getPlural(n, $scope, \"{0} byte\", \"{0} bytes\").replace(\"{0}\", bytes);\n }\n };\n\n $scope.$watch('data', function(layers) {\n if (layers && layers.length)\n layers = layers.map(prepareLayer).reverse();\n $scope.layers = layers;\n });\n\n $scope.$watch('image', function(image) {\n /* Only digest layers if image is set, or null */\n if (!angular.isUndefined(image))\n $scope.data = imageLayers(image);\n });\n }\n };\n }\n ]);\n\n}());\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./layers.js\n// module id = 5\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
Annotations
\\n
{{name}}: {{value}}
\\n\";\nvar id1=\"registry-image-widgets/views/annotations.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/annotations.html\n// module id = 6\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n
Name
\\n
{{ labels.name }}
\\n
Summary
\\n
{{ labels.summary }}
\\n
Description
\\n
{{ labels.description }}
\\n
Source URL
\\n
\\n {{ labels.url }}\\n
\\n
Author
\\n
{{config.author}}
\\n
{{image.dockerImageMetadata.Author}}
\\n
{{labels['MAINTAINER']}}
\\n
Unknown
\\n
Built
\\n
{{ layers[0].v1Compatibility.created | dateRelative}}
\\n
{{image.dockerImageMetadata.Created | dateRelative}}
\\n
{{ labels['build-date'] | dateRelative}}
\\n
Digest
\\n
{{ image.metadata.name }}
\\n
Identifier
\\n
{{ config.Image }}
\\n
\\n
0\\\">\\n
Signatures
\\n
\\n{{ signature.type }} / {{ signature.metadata.creationTimestamp }} / {{ signature.metadata.name }} / {{ signature.metadata.uid }}\\n
\\n
\\n
\\n
Tags
\\n
{{name}} 
\\n
\\n\";\nvar id1=\"registry-image-widgets/views/image-body.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-body.html\n// module id = 7\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n
Command
\\n
{{ configCommand(config) }}
\\n
\\n
\\n
\\n
Run as
\\n
{{config.User}}
\\n
Default
\\n
Directory
\\n
{{config.WorkingDir}}
\\n
/
\\n
Stop with
\\n
{{config.StopSignal}}
\\n
Architecture
\\n
{{config.architecture}}
\\n
{{image.dockerImageMetadata.Architecture}}
\\n
\\n
\\n
Environment
\\n
{{env}}
\\n
\\n
\\n
\\n
\\n
Ports
\\n
{{port}}
\\n
None
\\n
\\n
\\n
Volumes
\\n
{{volume}}
\\n
\\n
\\n\";\nvar id1=\"registry-image-widgets/views/image-config.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-config.html\n// module id = 8\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
    \\n
  • \\n{{ formatSize(layer.size) }}\\n

    {{ layer.label}}

    \\n
  • \\n
\\n\";\nvar id1=\"registry-image-widgets/views/image-layers.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-layers.html\n// module id = 9\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
TagFromIdentifierLast UpdatedSignatures
\\n\\n\\n{{ tag.name }}\\n\\n
pushed image
\\n
\\n{{tag.spec.from.name}}\\n\\n{{name.qualified}}\\n\\n{{tag.spec.from.name}}\\n\\n\\n
\\n
\\n
\\n
\\n
\\n\\nUnable to resolve\\n
\\n
\\nNot yet synced\\nUnresolved\\n
\\n
\\n
\\n\\n{{tag.status.items[0].image}}\\n\\nnone\\n
\\n
\\n
\\n
\\n\\n{{ tag.status.items[0].created | dateRelative }}\\n\\n
\\n
\\n
\\n\\n\\n\\n{{ overallVerification(tag) }}\\n
\\n
\\n\\n
No tags are present.{{failure}}
\\n\";\nvar id1=\"registry-image-widgets/views/image-listing.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-listing.html\n// module id = 10\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n
\\n
Labels
\\n
\\n{{name}}={{value}}\\n
\\n
On Build
\\n
{{line}}
\\n\\n
Docker Version
\\n
{{image.dockerImageMetadata.DockerVersion}}
\\n
\\n
\\n\";\nvar id1=\"registry-image-widgets/views/image-meta.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-meta.html\n// module id = 11\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n
\\n
\\n\\n
\\n\\n
\\n
\\n\\n\\n\\n\\n
\\n
\\n\\n\\n
\\n
\\n\\n\\n\\n\\n
\\n
\\n\\n\\n
\\n
\\n\";\nvar id1=\"registry-image-widgets/views/image-panel.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-panel.html\n// module id = 12\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n

\\n\\nTo pull this image:\\n

\\n$ sudo docker pull {{imagestream.status.publicDockerImageRepository}}/{{names[0]}}\\n$ sudo docker pull registry/{{names[0]}}\\n$ sudo docker pull {{settings.registry.host}}/{{names[0]}}\\n
\\n\";\nvar id1=\"registry-image-widgets/views/image-pull.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-pull.html\n// module id = 13\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n
Signature
\\n
{{ signature.metadata.name }}
\\n
Verified
\\n
\\n\\n\\n\\n{{ signature.verified }}\\n
\\n\\n
Details
\\n
{{signatureDetails(signature)}}
\\n
\\n
\\n
\\nNo signatures\\n
\\n\";\nvar id1=\"registry-image-widgets/views/image-signatures.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/image-signatures.html\n// module id = 14\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n
\\n\\n{{ condition.message }}. Timestamp: {{ condition.lastTransitionTime }} Error count: {{ condition.generation }}\\nEdit image stream\\n
\\n
\\n
\\n
Access Policy
\\n
\\n
\\nImages may be pulled by anonymous users\\nImages may be pulled by anonymous users\\n\\n
\\n
\\nImages may be pulled by any authenticated user or group\\nImages may be pulled by any authenticated user or group\\n\\n
\\n
\\nImages may only be pulled by specific users or groups\\nImages may only be pulled by specific users or groups\\n\\n
\\n
\\nUnknown\\nUnknown\\n\\n
\\n
\\n
Follows docker repo
\\n
{{imagestream.spec.dockerImageRepository}}
\\n
Pulling repository
\\n
{{imagestream.status.dockerImageRepository}}
\\n
Public pulling repo
\\n
{{imagestream.status.publicDockerImageRepository}}
\\n
Image count
\\n
{{imagestream.status.tags.length}}
\\n
0
\\n
\\n\";\nvar id1=\"registry-image-widgets/views/imagestream-body.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-body.html\n// module id = 15\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
NameTagsRepository
\\n\\n\\n{{ imagestream.metadata.namespace + '/' + imagestream.metadata.name }}\\n
\\n\\n
\\n
\\n{{ tag.name }}\\n 4\\\" translate-n=\\\"tag_count - 4\\\" translate translate-plural=\\\"and {{ $count }} others\\\">and {{ $count }} other\\n\\nunknown\\n{{imagestream.status.dockerImageRepository || imagestream.spec.dockerImageRepository}}\\n
\\n\\n
No image streams are present.{{failure}}
\\n\";\nvar id1=\"registry-image-widgets/views/imagestream-listing.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-listing.html\n// module id = 16\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n\\n
\\n\";\nvar id1=\"registry-image-widgets/views/imagestream-meta.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-meta.html\n// module id = 17\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n
\\n
\\n\\n\\n
\\n\\n
\\n
\\n\\n\\n\\n\\n
\\n
\\n\\n\\n
\\n
\\n
\\n\\n\\n
\\n
\\n
\\n\";\nvar id1=\"registry-image-widgets/views/imagestream-panel.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-panel.html\n// module id = 18\n// module chunks = 0","var angular=window.angular,ngModule;\ntry {ngModule=angular.module([\"ng\"])}\ncatch(e){ngModule=angular.module(\"ng\",[])}\nvar v1=\"
\\n

\\n\\nTo push an image to this image stream:\\n

\\n$ sudo docker tag myimage {{imagestream.status.publicDockerImageRepository}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker push {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker tag myimage {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker push {{settings.registry.host}}/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker tag myimage registry/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n$ sudo docker push registry/{{ imagestream.metadata.namespace }}/{{ imagestream.metadata.name}}:tag\\n
\\n\";\nvar id1=\"registry-image-widgets/views/imagestream-push.html\";\nvar inj=angular.element(window.document).injector();\nif(inj){inj.get(\"$templateCache\").put(id1,v1);}\nelse{ngModule.run([\"$templateCache\",function(c){c.put(id1,v1)}]);}\nmodule.exports=v1;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./views/imagestream-push.html\n// module id = 19\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/images.js b/images.js index 870bc11..956d0d6 100644 --- a/images.js +++ b/images.js @@ -167,7 +167,8 @@ angular.module('registryUI.images', [ .directive('registryImageBody', [ 'imageLayers', 'imageDockerConfig', - function(imageLayers, imageDockerConfig) { + 'imageSignatures', + function(imageLayers, imageDockerConfig, imageSignatures) { return { restrict: 'E', scope: { @@ -180,6 +181,7 @@ angular.module('registryUI.images', [ scope.layers = imageLayers(image); scope.config = imageDockerConfig(image); scope.labels = scope.config.Labels; + scope.signatures = imageSignatures(image); if (angular.equals({ }, scope.labels)) scope.labels = null; }); @@ -234,6 +236,37 @@ angular.module('registryUI.images', [ } ]) +.directive('registryImageSignatures', [ + 'imageSignatures', + function(imageSignatures) { + return { + restrict: 'E', + scope: { + image: '=', + }, + templateUrl: 'registry-image-widgets/views/image-signatures.html', + link: function(scope, element, attrs) { + scope.signatureDetails = function signatureDetails(signature) { + var result = ""; + if (signature.conditions) { + var condition = signature.conditions.find(function (condition) { + return condition.type === "Trusted"; + }); + if (condition !== undefined) { + result = condition.reason + " / " + condition.message; + } + } + return result; + }; + + scope.$watch("image", function(image) { + scope.signatures = imageSignatures(image); + }); + } + }; + } +]) + .directive('registryImageMeta', [ 'imageDockerConfig', function(imageDockerConfig) { @@ -312,11 +345,54 @@ angular.module('registryUI.images', [ } ]) +.factory('imageSignatures', [ + 'WeakMap', + function(WeakMap) { + var weak = new WeakMap(); + + return function(image) { + if (!image) + return []; + var signatures = weak.get(image); + + + var signatureStatus = function(signature) { + var trusted = "Unverified"; + if (signature.conditions) { + var condition = signature.conditions.find(function (condition) { + return condition.type === "Trusted"; + }); + if (condition !== undefined) { + trusted = "Verified"; + } else { + // Failed info not available + // https://github.com/openshift/origin/issues/16301 + trusted = "Failed verification"; + } + } + return trusted; + }; + + if (!signatures && image.signatures) { + signatures = []; + image.signatures.forEach(function(signature) { + signature.verified = signatureStatus(signature); + signatures.push(signature); + }); + weak.set(image, signatures); + } + + return signatures || []; + }; + } +]) + .factory('registryImageListingFunc', [ 'imagestreamTags', 'imagestreamTagFromName', + 'imageSignatures', '$location', - function(imagestreamTags, imagestreamTagFromName, $location) { + function(imagestreamTags, imagestreamTagFromName, imageSignatures, $location) { return function(scope, element, attrs) { scope.imagestreamTags = imagestreamTags; scope.imagestreamPath = scope.imagestreamFunc(); @@ -324,6 +400,30 @@ angular.module('registryUI.images', [ scope.imageTagNames = scope.imageTagNamesFunc(); scope.sharedImages = scope.sharedImagesFunc(); scope.imagestreamTagFromName = imagestreamTagFromName; + scope.imageSignatures = imageSignatures; + + scope.overallVerification = function overallVerification(tag) { + var image, signature, signatures; + var overall = "Unverified"; + + image = scope.imageByTag(tag.status); + signatures = scope.imageSignatures(image); + + if (signatures.length === 0) { + return "Unsigned"; + } else { + signatures.forEach(function(signature) { + var status = signature.verified; + if (status === "Failed verification" || overall === "Failed verification" || overall === undefined) { + overall = status; + } else if (status !== "Failed verification") { + overall = status; + } + }); + } + + return overall; + }; /* Called when someone clicks on a row */ scope.imagestreamActivate = function imagestreamActivate(imagestream, tag, ev) { @@ -410,7 +510,8 @@ angular.module('registryUI.images', [ .directive('registryImagePanel', [ 'imageDockerConfig', 'imageLayers', - function(imageDockerConfig, imageLayers) { + 'imageSignatures', + function(imageDockerConfig, imageLayers, imageSignatures) { return { restrict: 'E', transclude: true, @@ -435,6 +536,7 @@ angular.module('registryUI.images', [ scope.layers = imageLayers(scope.image); scope.config = imageDockerConfig(scope.image); scope.labels = scope.config.Labels; + scope.signatures = imageSignatures(scope.image); if (scope.imageTagNames) scope.names = scope.imageTagNames(scope.image); } diff --git a/images.less b/images.less index 6eb46da..63dff70 100644 --- a/images.less +++ b/images.less @@ -113,6 +113,10 @@ registry-image-listing table.listing-ct { } } + td.image-signature { + margin-right: 5px; + } + tbody.open .listing-ct-panel .listing-ct-body { border-right: 1px solid #ccc; } diff --git a/views/image-body.html b/views/image-body.html index 9981cac..3151519 100644 --- a/views/image-body.html +++ b/views/image-body.html @@ -24,7 +24,6 @@
Identifier
{{ config.Image }}
-
Tags
{{name}} 
diff --git a/views/image-listing.html b/views/image-listing.html index cb94073..23b2bab 100644 --- a/views/image-listing.html +++ b/views/image-listing.html @@ -5,6 +5,7 @@ Tag From Identifier + Signatures Last Updated @@ -54,6 +55,17 @@ + +
+ + + + {{ overallVerification(tag) }} +
+
@@ -63,15 +75,15 @@ - + - No tags are present. - {{failure}} + No tags are present. + {{failure}} diff --git a/views/image-panel.html b/views/image-panel.html index 97c1fb4..5d1dcaa 100644 --- a/views/image-panel.html +++ b/views/image-panel.html @@ -14,6 +14,9 @@
  • Metadata
  • +
  • + Signatures +
  • @@ -35,4 +38,9 @@ + +
    + + +
    diff --git a/views/image-signatures.html b/views/image-signatures.html new file mode 100644 index 0000000..c2fd470 --- /dev/null +++ b/views/image-signatures.html @@ -0,0 +1,21 @@ +
    +
    Signature
    +
    {{ signature.metadata.name }}
    +
    Verified
    +
    + + + + {{ signature.verified }} +
    + +
    Details
    +
    {{signatureDetails(signature)}}
    +
    +
    +
    + No signatures +
    diff --git a/views/imagestream-listing.html b/views/imagestream-listing.html index ababfee..1df0d7d 100644 --- a/views/imagestream-listing.html +++ b/views/imagestream-listing.html @@ -33,15 +33,15 @@ - + - No image streams are present. - {{failure}} + No image streams are present. + {{failure}} diff --git a/webpack.config.js b/webpack.config.js index 8551ab6..cc519a2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -24,6 +24,7 @@ module.exports = { srcdir + "views/image-config.html", srcdir + "views/image-meta.html", srcdir + "views/image-layers.html", + srcdir + "views/image-signatures.html", srcdir + "views/image-panel.html", srcdir + "views/image-pull.html", srcdir + "views/image-listing.html",