diff --git a/assets/app/scripts/app.js b/assets/app/scripts/app.js index 44400d787d32..ac1fe9397262 100644 --- a/assets/app/scripts/app.js +++ b/assets/app/scripts/app.js @@ -70,7 +70,7 @@ angular .href(projectHref("browse")) .subPath("Builds", "builds", builder.join(templatePath, 'builds.html')) .subPath("Deployments", "deployments", builder.join(templatePath, 'deployments.html')) - .subPath("Images", "images", builder.join(templatePath, 'images.html')) + .subPath("Image Streams", "images", builder.join(templatePath, 'images.html')) .subPath("Pods", "pods", builder.join(templatePath, 'pods.html')) .subPath("Services", "services", builder.join(templatePath, 'services.html')) .build(); diff --git a/assets/app/scripts/controllers/images.js b/assets/app/scripts/controllers/images.js index b157f75d3408..92df2d3a5e91 100644 --- a/assets/app/scripts/controllers/images.js +++ b/assets/app/scripts/controllers/images.js @@ -9,46 +9,40 @@ */ angular.module('openshiftConsole') .controller('ImagesController', function ($scope, DataService, $filter, LabelFilter, Logger) { - $scope.images = {}; - $scope.unfilteredImages = {}; + $scope.imageStreams = {}; + $scope.unfilteredImageStreams = {}; $scope.builds = {}; $scope.labelSuggestions = {}; $scope.alerts = $scope.alerts || {}; $scope.emptyMessage = "Loading..."; var watches = []; - watches.push(DataService.watch("images", $scope, function(images) { - $scope.unfilteredImages = images.by("metadata.name"); - LabelFilter.addLabelSuggestionsFromResources($scope.unfilteredImages, $scope.labelSuggestions); + watches.push(DataService.watch("imageStreams", $scope, function(imageStreams) { + $scope.unfilteredImageStreams = imageStreams.by("metadata.name"); + LabelFilter.addLabelSuggestionsFromResources($scope.unfilteredImageStreams, $scope.labelSuggestions); LabelFilter.setLabelSuggestions($scope.labelSuggestions); - $scope.images = LabelFilter.getLabelSelector().select($scope.unfilteredImages); - $scope.emptyMessage = "No images to show"; + $scope.imageStreams = LabelFilter.getLabelSelector().select($scope.unfilteredImageStreams); + $scope.emptyMessage = "No image streams to show"; updateFilterWarning(); - Logger.log("images (subscribe)", $scope.images); - })); - - // Also load builds so we can link out to builds associated with images - watches.push(DataService.watch("builds", $scope, function(builds) { - $scope.builds = builds.by("metadata.name"); - Logger.log("builds (subscribe)", $scope.builds); - })); + Logger.log("image streams (subscribe)", $scope.imageStreams); + })); var updateFilterWarning = function() { - if (!LabelFilter.getLabelSelector().isEmpty() && $.isEmptyObject($scope.images) && !$.isEmptyObject($scope.unfilteredImages)) { - $scope.alerts["images"] = { + if (!LabelFilter.getLabelSelector().isEmpty() && $.isEmptyObject($scope.imageStreams) && !$.isEmptyObject($scope.unfilteredImageStreams)) { + $scope.alerts["imageStreams"] = { type: "warning", - details: "The active filters are hiding all images." + details: "The active filters are hiding all image streams." }; } else { - delete $scope.alerts["images"]; + delete $scope.alerts["imageStreams"]; } }; LabelFilter.onActiveFiltersChanged(function(labelSelector) { // trigger a digest loop $scope.$apply(function() { - $scope.images = labelSelector.select($scope.unfilteredImages); + $scope.imageStreams = labelSelector.select($scope.unfilteredImageStreams); updateFilterWarning(); }); }); diff --git a/assets/app/scripts/directives/util.js b/assets/app/scripts/directives/util.js index e93228dd5854..4e3d1674b80a 100644 --- a/assets/app/scripts/directives/util.js +++ b/assets/app/scripts/directives/util.js @@ -56,4 +56,13 @@ angular.module('openshiftConsole') } } } + }) + .directive('shortId', function() { + return { + restrict:'E', + scope: { + id: '@' + }, + template: '{{id.substring(0, 6)}}' + } }); \ No newline at end of file diff --git a/assets/app/scripts/services/data.js b/assets/app/scripts/services/data.js index a39d082af06f..64168a79fc31 100644 --- a/assets/app/scripts/services/data.js +++ b/assets/app/scripts/services/data.js @@ -228,8 +228,14 @@ angular.module('openshiftConsole') var deferred = $q.defer(); - if (!force && this._watchInFlight(type, context) && this._resourceVersion(type, context)) { - var obj = this._data(type, context).by('metadata.name')[name]; + var existingData = this._data(type, context); + + // If this is a cached type (immutable types only), ignore the force parameter + if (this._isTypeCached(type) && existingData && existingData.by('metadata.name')[name]) { + return existingData.by('metadata.name')[name]; + } + else if (!force && this._watchInFlight(type, context) && this._resourceVersion(type, context)) { + var obj = existingData.by('metadata.name')[name]; if (obj) { $rootScope.$apply(function(){ deferred.resolve(obj); @@ -255,6 +261,14 @@ angular.module('openshiftConsole') url: self._urlForType(type, name, context, false, ns) }, opts.http || {})) .success(function(data, status, headerFunc, config, statusText) { + if (self._isTypeCached(type)) { + if (!existingData) { + self._data(type, context, [data]); + } + else { + existingData.update(data, "ADDED"); + } + } deferred.resolve(data); }) .error(function(data, status, headers, config) { @@ -654,8 +668,10 @@ angular.module('openshiftConsole') buildConfigHooks: API_CFG.openshift, deploymentConfigs: API_CFG.openshift, images: API_CFG.openshift, - imageRepositories: API_CFG.openshift, + imageRepositories: API_CFG.openshift, // DEPRECATED, leave here until removed from API imageStreams: API_CFG.openshift, + imageStreamImages: API_CFG.openshift, + imageStreamTags: API_CFG.openshift, oAuthAccessTokens: API_CFG.openshift, oAuthAuthorizeTokens: API_CFG.openshift, oAuthClients: API_CFG.openshift, @@ -748,7 +764,7 @@ angular.module('openshiftConsole') BuildConfig: "buildConfigs", DeploymentConfig: "deploymentConfigs", Image: "images", - ImageRepository: "imageRepositories", + ImageRepository: "imageRepositories", // DEPRECATED, leave here until removed from API ImageStream: "imageStreams", OAuthAccessToken: "oAuthAccessTokens", OAuthAuthorizeToken: "oAuthAuthorizeTokens", @@ -773,6 +789,14 @@ angular.module('openshiftConsole') return OBJECT_KIND_MAP[kind]; }; + var CACHED_TYPE = { + imageStreamImages: true + }; + + DataService.prototype._isTypeCached = function(type) { + return !!CACHED_TYPE[type]; + }; + DataService.prototype._getNamespace = function(type, context, opts) { var deferred = $q.defer(); if (opts.namespace) { diff --git a/assets/app/styles/_core.less b/assets/app/styles/_core.less index 0e65c3bb1e69..fab9d16fe419 100644 --- a/assets/app/styles/_core.less +++ b/assets/app/styles/_core.less @@ -320,4 +320,7 @@ select:invalid { font-weight: normal; } - +.short-id { + background-color: #f1f1f1; + color: #666; +} \ No newline at end of file diff --git a/assets/app/views/_pod-template.html b/assets/app/views/_pod-template.html index da3a76b0fd67..061e72cf355a 100644 --- a/assets/app/views/_pod-template.html +++ b/assets/app/views/_pod-template.html @@ -14,14 +14,14 @@

{{container.name}}

Image: {{container.image | imageName}} - ({{imagesByDockerReference[container.image].metadata.name.substr(0, 10)}}) + ({{imagesByDockerReference[container.image].metadata.name.substr(0, 10)}})
- Build: {{build.metadata.labels.buildconfig}} ({{build.metadata.name.substr(0, 10)}}) + Build: {{build.metadata.labels.buildconfig}} ({{build.metadata.name}})
@@ -31,7 +31,7 @@

{{container.name}}

{{build.parameters.revision.git.message}} - ({{build.parameters.revision.git.commit.substr(0, 10)}}) + ({{build.parameters.revision.git.commit.substr(0, 10)}}) authored by {{build.parameters.revision.git.author.name}} diff --git a/assets/app/views/images.html b/assets/app/views/images.html index 3059255c5058..55377bf6e758 100644 --- a/assets/app/views/images.html +++ b/assets/app/views/images.html @@ -1,17 +1,45 @@
-

Images

+

Image Streams

-
+
{{emptyMessage}}
-
-

{{image.dockerImageReference | imageName}} ({{image.metadata.name}})

-
Created:
-
Created from: Build {{build.metadata.labels.buildconfig}} ({{build.metadata.name.substr(0, 10)}}) +
+
+
+ {{imageStream.metadata.name}}:{{tag.tag}} + No images for this tag + + + + created + + +
+
+
From Docker repository: {{imageStream.spec.dockerImageRepository}}:{{tag.tag}}
+
+
+
From Docker repository: {{specTag.dockerImageReference}}
+
From image stream: {{specTag.from.namespace}}/{{specTag.from.name}}
+
+
+
+
+
+
+ + {{image.dockerImageReference}} + created + +
+
+
+
diff --git a/pkg/assets/bindata.go b/pkg/assets/bindata.go index 8ba524c2f21f..f29f32bb6365 100644 --- a/pkg/assets/bindata.go +++ b/pkg/assets/bindata.go @@ -12074,6 +12074,10 @@ select:invalid { font-size: 11px; font-weight: normal; } +.short-id { + background-color: #f1f1f1; + color: #666; +} `) func css_main_css() ([]byte, error) { @@ -12835,7 +12839,7 @@ return c.join(f, "project.html"); }).build(); h.icon = "dashboard", a.push(h), h = c.create().id(c.join(g, "browse")).title(function() { return "Browse"; -}).template(d).href(e("browse")).subPath("Builds", "builds", c.join(f, "builds.html")).subPath("Deployments", "deployments", c.join(f, "deployments.html")).subPath("Images", "images", c.join(f, "images.html")).subPath("Pods", "pods", c.join(f, "pods.html")).subPath("Services", "services", c.join(f, "services.html")).build(), h.icon = "sitemap", a.push(h), h = c.create().id(c.join(g, "settings")).title(function() { +}).template(d).href(e("browse")).subPath("Builds", "builds", c.join(f, "builds.html")).subPath("Deployments", "deployments", c.join(f, "deployments.html")).subPath("Image Streams", "images", c.join(f, "images.html")).subPath("Pods", "pods", c.join(f, "pods.html")).subPath("Services", "services", c.join(f, "services.html")).build(), h.icon = "sitemap", a.push(h), h = c.create().id(c.join(g, "settings")).title(function() { return "Settings"; }).template(d).href(e("settings")).page(function() { return c.join(f, "settings.html"); @@ -13249,11 +13253,12 @@ h.push(a), j--, e(); h = h || {}; var i = !!h.force; delete h.force; -var j = d.defer(); +var j = d.defer(), k = this._data(b, g); +if (this._isTypeCached(b) && k && k.by("metadata.name")[e]) return k.by("metadata.name")[e]; if (!i && this._watchInFlight(b, g) && this._resourceVersion(b, g)) { -var k = this._data(b, g).by("metadata.name")[e]; -c.$apply(k ? function() { -j.resolve(k); +var l = k.by("metadata.name")[e]; +c.$apply(l ? function() { +j.resolve(l); } :function() { j.reject({ data:{}, @@ -13265,13 +13270,13 @@ config:{} }); }); } else { -var l = this; +var m = this; this._getNamespace(b, g, h).then(function(c) { a(angular.extend({ method:"GET", -url:l._urlForType(b, e, g, !1, c) +url:m._urlForType(b, e, g, !1, c) }, h.http || {})).success(function(a) { -j.resolve(a); +m._isTypeCached(b) && (k ? k.update(a, "ADDED") :m._data(b, g, [ a ])), j.resolve(a); }).error(function(a, c, d, g) { if (h.errorNotification !== !1) { var i = "Failed to get " + b + "/" + e; @@ -13424,6 +13429,8 @@ deploymentConfigs:e.openshift, images:e.openshift, imageRepositories:e.openshift, imageStreams:e.openshift, +imageStreamImages:e.openshift, +imageStreamTags:e.openshift, oAuthAccessTokens:e.openshift, oAuthAuthorizeTokens:e.openshift, oAuthClients:e.openshift, @@ -13489,8 +13496,14 @@ Service:"services", ResourceQuota:"resourcequotas", LimitRange:"limitranges" }; -return i.prototype._objectType = function(a) { +i.prototype._objectType = function(a) { return t[a]; +}; +var u = { +imageStreamImages:!0 +}; +return i.prototype._isTypeCached = function(a) { +return !!u[a]; }, i.prototype._getNamespace = function(a, b, c) { var e = d.defer(); return c.namespace ? e.resolve({ @@ -13862,22 +13875,20 @@ a.builds = b.select(a.unfilteredBuilds), g(); b.unwatchAll(f); }); } ]), angular.module("openshiftConsole").controller("ImagesController", [ "$scope", "DataService", "$filter", "LabelFilter", "Logger", function(a, b, c, d, e) { -a.images = {}, a.unfilteredImages = {}, a.builds = {}, a.labelSuggestions = {}, a.alerts = a.alerts || {}, a.emptyMessage = "Loading..."; +a.imageStreams = {}, a.unfilteredImageStreams = {}, a.builds = {}, a.labelSuggestions = {}, a.alerts = a.alerts || {}, a.emptyMessage = "Loading..."; var f = []; -f.push(b.watch("images", a, function(b) { -a.unfilteredImages = b.by("metadata.name"), d.addLabelSuggestionsFromResources(a.unfilteredImages, a.labelSuggestions), d.setLabelSuggestions(a.labelSuggestions), a.images = d.getLabelSelector().select(a.unfilteredImages), a.emptyMessage = "No images to show", g(), e.log("images (subscribe)", a.images); -})), f.push(b.watch("builds", a, function(b) { -a.builds = b.by("metadata.name"), e.log("builds (subscribe)", a.builds); +f.push(b.watch("imageStreams", a, function(b) { +a.unfilteredImageStreams = b.by("metadata.name"), d.addLabelSuggestionsFromResources(a.unfilteredImageStreams, a.labelSuggestions), d.setLabelSuggestions(a.labelSuggestions), a.imageStreams = d.getLabelSelector().select(a.unfilteredImageStreams), a.emptyMessage = "No image streams to show", g(), e.log("image streams (subscribe)", a.imageStreams); })); var g = function() { -d.getLabelSelector().isEmpty() || !$.isEmptyObject(a.images) || $.isEmptyObject(a.unfilteredImages) ? delete a.alerts.images :a.alerts.images = { +d.getLabelSelector().isEmpty() || !$.isEmptyObject(a.imageStreams) || $.isEmptyObject(a.unfilteredImageStreams) ? delete a.alerts.imageStreams :a.alerts.imageStreams = { type:"warning", -details:"The active filters are hiding all images." +details:"The active filters are hiding all image streams." }; }; d.onActiveFiltersChanged(function(b) { a.$apply(function() { -a.images = b.select(a.unfilteredImages), g(); +a.imageStreams = b.select(a.unfilteredImageStreams), g(); }); }), a.$on("$destroy", function() { b.unwatchAll(f); @@ -14289,6 +14300,14 @@ placement:"bottom" })); } }; +}).directive("shortId", function() { +return { +restrict:"E", +scope:{ +id:"@" +}, +template:'{{id.substring(0, 6)}}' +}; }), angular.module("openshiftConsole").directive("labels", function() { return { restrict:"E", @@ -59856,7 +59875,8 @@ select:invalid{box-shadow:none} .well h1:first-child,.well h2:first-child,.well h3:first-child,.well h4:first-child,.well h5:first-child{margin-top:0} .attention-message{background-color:#79cef2;border:1px solid #138cbf;position:absolute;top:20%;left:50%;transform:translate(-50%,-50%);padding:1em 1em 2em;min-width:85%} .attention-message h1,.attention-message p{text-align:center} -.learn-more-block{display:block;font-size:11px;font-weight:400}`) +.learn-more-block{display:block;font-size:11px;font-weight:400} +.short-id{background-color:#f1f1f1;color:#666}`) func styles_main_css() ([]byte, error) { return _styles_main_css, nil @@ -60129,14 +60149,14 @@ var _views_pod_template_html = []byte(`
Image: {{container.image | imageName}} - ({{imagesByDockerReference[container.image].metadata.name.substr(0, 10)}}) + ({{imagesByDockerReference[container.image].metadata.name.substr(0, 10)}})
-Build: {{build.metadata.labels.buildconfig}} ({{build.metadata.name.substr(0, 10)}}) +Build: {{build.metadata.labels.buildconfig}} ({{build.metadata.name}})
@@ -60146,7 +60166,7 @@ var _views_pod_template_html = []byte(`
{{build.parameters.revision.git.message}} -({{build.parameters.revision.git.commit.substr(0, 10)}}) +({{build.parameters.revision.git.commit.substr(0, 10)}}) authored by {{build.parameters.revision.git.author.name}} @@ -60766,20 +60786,48 @@ func views_directives_copy_to_clipboard_html() ([]byte, error) { var _views_images_html = []byte(`
-

Images

+

Image Streams

-
+
{{emptyMessage}}
-
-

{{image.dockerImageReference | imageName}} ({{image.metadata.name}})

-
Created:
-
Created from: Build {{build.metadata.labels.buildconfig}} ({{build.metadata.name.substr(0, 10)}}) +
+
+
+{{imageStream.metadata.name}}:{{tag.tag}} +No images for this tag + + + + created + + +
+
+
From Docker repository: {{imageStream.spec.dockerImageRepository}}:{{tag.tag}}
+
+
+
From Docker repository: {{specTag.dockerImageReference}}
+
From image stream: {{specTag.from.namespace}}/{{specTag.from.name}}
-
+
+
+
+
+ +{{image.dockerImageReference}} + created + +
+
+
+
+
+
+
`) func views_images_html() ([]byte, error) {