Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
<script src="scripts/directives/nav.js"></script>
<script src="scripts/directives/alerts.js"></script>
<script src="scripts/directives/popups.js"></script>
<script src="scripts/directives/util.js"></script>
<script src="scripts/filters/date.js"></script>
<script src="scripts/filters/resources.js"></script>
<script src="scripts/filters/util.js"></script>
Expand Down
9 changes: 8 additions & 1 deletion assets/app/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ angular
for (var i = 0; i < tabs.length; i++) {
HawtioNav.add(tabs[i]);
}
}]);
}])
.run(function($interval, dateRelativeFilter) {
$interval(function() {
$('.timestamp[data-timestamp]').text(function(i, existing) {
return dateRelativeFilter($(this).attr("data-timestamp")) || existing;
});
}, 30000);
});

hawtioPluginLoader.addModule('openshiftConsole');
20 changes: 20 additions & 0 deletions assets/app/scripts/controllers/builds.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ angular.module('openshiftConsole')
.controller('BuildsController', function ($scope, DataService, $filter, LabelFilter) {
$scope.builds = {};
$scope.unfilteredBuilds = {};
$scope.buildConfigs = {};
$scope.labelSuggestions = {};
$scope.alerts = $scope.alerts || {};
$scope.emptyMessage = "Loading...";

$scope.buildsByBuildConfig = {};

var watches = [];

watches.push(DataService.watch("builds", $scope, function(builds) {
Expand All @@ -23,7 +27,23 @@ angular.module('openshiftConsole')
$scope.builds = LabelFilter.getLabelSelector().select($scope.unfilteredBuilds);
$scope.emptyMessage = "No builds to show";
updateFilterWarning();

$scope.buildsByBuildConfig = {};
angular.forEach($scope.builds, function(build, buildName) {
var buildConfigName = "";
if (build.metadata.labels) {
buildConfigName = build.metadata.labels.buildconfig || "";
}
$scope.buildsByBuildConfig[buildConfigName] = $scope.buildsByBuildConfig[buildConfigName] || {};
$scope.buildsByBuildConfig[buildConfigName][buildName] = build;
});

console.log("builds (subscribe)", $scope.unfilteredBuilds);
}));

watches.push(DataService.watch("buildConfigs", $scope, function(buildConfigs) {
$scope.buildConfigs = buildConfigs.by("metadata.name");
console.log("buildConfigs (subscribe)", $scope.buildConfigs);
}));

var updateFilterWarning = function() {
Expand Down
2 changes: 1 addition & 1 deletion assets/app/scripts/directives/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ angular.module('openshiftConsole')
scope: {
timestamp: '='
},
template: '<span class="timestamp" title="{{timestamp | date : \'short\'}}">{{timestamp | dateRelative}}</span>'
template: '<span data-timestamp="{{timestamp}}" class="timestamp" title="{{timestamp | date : \'short\'}}">{{timestamp | dateRelative}}</span>'
};
});
11 changes: 11 additions & 0 deletions assets/app/scripts/directives/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
angular.module('openshiftConsole')
.directive('selectOnFocus', function() {
return {
restrict: 'A',
link: function($scope, element, attrs) {
$(element).focus(function () {
$(this).select();
});
}
};
});
3 changes: 3 additions & 0 deletions assets/app/scripts/filters/date.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
angular.module('openshiftConsole')
.filter('dateRelative', function() {
return function(timestamp) {
if (!timestamp) {
return timestamp;
}
return moment(timestamp).fromNow();
};
})
Expand Down
11 changes: 11 additions & 0 deletions assets/app/scripts/filters/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,15 @@ angular.module('openshiftConsole')
}
return null;
};
})
.filter('webhookURL', function(DataService) {
return function(buildConfig, type, secret, project) {
return DataService.url({
type: "buildConfigHooks",
id: buildConfig,
namespace: project,
secret: secret,
hookType: type,
});
};
});
10 changes: 10 additions & 0 deletions assets/app/scripts/filters/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,14 @@ angular.module('openshiftConsole')
}
return amount + (unit != "" ? " " + unit : "");
}
})
.filter('helpLink', function() {
return function(type) {
switch(type) {
case "webhooks":
return "http://docs.openshift.org/latest/using_openshift/builds.html#webhook-triggers"
default:
return "http://docs.openshift.org/latest/welcome/index.html";
}
};
});
49 changes: 37 additions & 12 deletions assets/app/scripts/services/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@ angular.module('openshiftConsole')
var URL_NAMESPACED_WATCH_LIST = URL_ROOT_TEMPLATE + "watch/namespaces/{namespace}/{type}{?q*}";
var URL_NAMESPACED_GET_LIST = URL_ROOT_TEMPLATE + "namespaces/{namespace}/{type}{?q*}";
var URL_NAMESPACED_GET_OBJECT = URL_ROOT_TEMPLATE + "namespaces/{namespace}/{type}/{id}{?q*}";
// TODO is there a better way to get this template instead of building it, introspection?
var BUILD_HOOKS_URL = URL_ROOT_TEMPLATE + "{type}/{id}/{secret}/{hookType}{?q*}";

// Set the api version the console is currently able to talk to
API_CFG.openshift.version = "v1beta1";
Expand All @@ -549,6 +551,8 @@ angular.module('openshiftConsole')
// https://github.com/openshift/origin/issues/230
var SERVER_TYPE_MAP = {
builds: API_CFG.openshift,
buildConfigs: API_CFG.openshift,
buildConfigHooks: API_CFG.openshift,
deploymentConfigs: API_CFG.openshift,
images: API_CFG.openshift,
oAuthAccessTokens: API_CFG.openshift,
Expand Down Expand Up @@ -580,27 +584,48 @@ angular.module('openshiftConsole')
delete params.namespace;
}
var template;
var templateOptions = {
protocol: protocol,
serverUrl: SERVER_TYPE_MAP[type].hostPort,
apiPrefix: SERVER_TYPE_MAP[type].prefix,
apiVersion: SERVER_TYPE_MAP[type].version,
type: type,
id: id,
namespace: namespace
};
if (isWebsocket) {
template = namespaceInPath ? URL_NAMESPACED_WATCH_LIST : URL_WATCH_LIST;
}
else if (id) {
template = namespaceInPath ? URL_NAMESPACED_GET_OBJECT : URL_GET_OBJECT;
if (type == "buildConfigHooks") {
templateOptions.secret = params.secret;
templateOptions.hookType = params.hookType;
params = angular.copy(params);
delete params.secret;
delete params.hookType;
template = BUILD_HOOKS_URL;
}
else
{
template = namespaceInPath ? URL_NAMESPACED_GET_OBJECT : URL_GET_OBJECT;
}
}
else {
template = namespaceInPath ? URL_NAMESPACED_GET_LIST : URL_GET_LIST;
}

// TODO where do we specify what the server URL and api version should be
return URI.expand(template, {
protocol: protocol,
serverUrl: SERVER_TYPE_MAP[type].hostPort,
apiPrefix: SERVER_TYPE_MAP[type].prefix,
apiVersion: SERVER_TYPE_MAP[type].version,
type: type,
id: id,
namespace: namespace,
q: params
});
templateOptions.q = params;
return URI.expand(template, templateOptions);
};

DataService.prototype.url = function(options) {
if (options && options.type) {
var opts = angular.copy(options);
delete opts.type;
delete opts.id;
return this._urlForType(options.type, options.id, null, false, opts).toString();
}
return null;
};

return new DataService();
Expand Down
161 changes: 148 additions & 13 deletions assets/app/views/builds.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,160 @@
<div ng-controller="BuildsController">
<h1>Builds</h1>
<alerts alerts="alerts"></alerts>
<div ng-if="(builds | hashSize) == 0">
<div ng-if="(builds | hashSize) == 0 && (buildConfigs | hashSize) == 0">
<div>
<em>{{emptyMessage}}</em>
</div>
</div>
<div style="margin-bottom: 10px;" ng-repeat="build in builds">
<h3>{{build.metadata.labels.buildconfig}} <span class="small">({{build.metadata.name}})</span></h3>
<div>Created: <relative-timestamp timestamp="build.metadata.creationTimestamp"></relative-timestamp></div>
<div>Status: {{build.status}}</div>
<div>Build strategy: {{build.parameters.strategy.type}}</div>
<div ng-if="build.parameters.strategy.type == 'STI'">
Builder image: {{build.parameters.strategy.stiStrategy.builderImage}}
<div ng-repeat="(buildConfigName, buildConfig) in buildConfigs">
<h2>{{buildConfigName}}</h2>
<div>Build strategy: {{buildConfig.parameters.strategy.type}}</div>
<div ng-switch="buildConfig.parameters.strategy.type">
<div ng-switch-when="STI">
Builder image: {{buildConfig.parameters.strategy.stiStrategy.image}}
</div>
<div ng-switch-when="Docker">
<div ng-if="buildConfig.parameters.strategy.dockerStrategy.image">
Builder image: {{buildConfig.parameters.strategy.dockerStrategy.image}}
</div>
</div>
<div ng-switch-when="Custom">
Builder image: {{buildConfig.parameters.strategy.customStrategy.image}}
</div>
</div>
<div ng-if="build.parameters.source">
<div ng-if="build.parameters.source.type == 'Git'">Source repo: {{build.parameters.source.git.uri}}</div>
<!-- TODO add git ref details -->
<div ng-if="buildConfig.parameters.source">
<div ng-if="buildConfig.parameters.source.type == 'Git'">Source repo: {{buildConfig.parameters.source.git.uri}}</div>
</div>
<div ng-if="buildConfig.parameters.output">
<div ng-switch="buildConfig.parameters.output.to.kind">
<div ng-switch-when="ImageRepository">
Output image: {{buildConfig.parameters.output.to.name}}
</div>
</div>
<div ng-if="!buildConfig.parameters.output.to && buildConfig.parameters.output.dockerImageReference">
Output image: {{buildConfig.parameters.output.dockerImageReference}}
</div>
</div>
<div>
Triggers:
<ul>
<li ng-repeat="trigger in buildConfig.triggers">
<span ng-switch="trigger.type">
<span ng-switch-when="github">
GitHub webhook URL: <input class="small" readonly="readonly" value="{{buildConfigName | webhookURL : trigger.type : trigger.github.secret : project.metadata.name}}" select-on-focus />
<a href="{{'webhooks' | helpLink}}" target="_blank"><i class="pficon pficon-help"></i></a>
</span>
<span ng-switch-when="generic">
Generic webhook URL: <input class="small" readonly="readonly" value="{{buildConfigName | webhookURL : trigger.type : trigger.generic.secret : project.metadata.name}}" select-on-focus />
<a href="{{'webhooks' | helpLink}}" target="_blank"><i class="pficon pficon-help"></i></a>
</span>
<span ng-switch-when="imageChange">
Image change on image repository {{trigger.imageChange.from.name}}:{{trigger.imageChange.tag}}
</span>
<span ng-switch-default>{{trigger.type}}</span>
</span>
</li>
<li>Manual: <code>osc start-build {{buildConfigName}} -n {{project.metadata.name}}</code></li>
</ul>
</div>
<div style="margin-bottom: 10px;" ng-repeat="build in buildsByBuildConfig[buildConfigName] | orderObjectsByDate : true">
<h3>{{build.metadata.name}}</h3>
<div>Created: <relative-timestamp timestamp="build.metadata.creationTimestamp"></relative-timestamp></div>
<div>
<span style="margin-right: 5px;">Status: {{build.status}}</span>
<span ng-switch="build.status" class="hide-ng-leave">
<span ng-switch-when="Complete" class="fa fa-check text-success" aria-hidden="true"></span>
<span ng-switch-when="Failed" class="fa fa-times text-danger" aria-hidden="true"></span>
<span ng-switch-default class="fa fa-refresh fa-spin" aria-hidden="true"></span>
</span>
</div>
<div ng-if="buildConfig.parameters.strategy.type != build.parameters.strategy.type">
<div>Build strategy: {{build.parameters.strategy.type}}</div>
</div>
<div ng-switch="build.parameters.strategy.type">
<div ng-switch-when="STI" ng-if="buildConfig.parameters.strategy.stiStrategy.image != build.parameters.strategy.stiStrategy.image">
Builder image: {{build.parameters.strategy.stiStrategy.image}}
</div>
<div ng-switch-when="Docker">
<div ng-if="build.parameters.strategy.dockerStrategy.image && buildConfig.parameters.strategy.dockerStrategy.image != build.parameters.strategy.dockerStrategy.image">
Builder image: {{build.parameters.strategy.dockerStrategy.image}}
</div>
</div>
<div ng-switch-when="Custom" ng-if="buildConfig.parameters.strategy.customStrategy.image != build.parameters.strategy.customStrategy.image">
Builder image: {{build.parameters.strategy.customStrategy.image}}
</div>
</div>
<div ng-if="build.parameters.source">
<div ng-if="build.parameters.source.type == 'Git'">
<div ng-if="buildConfig.parameters.source.git.uri != build.parameters.source.git.uri">
Source repo: {{build.parameters.source.git.uri}}
</div>
</div>
<!-- TODO add git ref details -->
</div>
<div ng-if="build.parameters.output">
<div ng-if="buildConfig.parameters.output.to.kind != build.parameters.output.to.kind && buildConfig.parameters.output.to.name != build.parameters.output.to.name">
<div ng-switch="build.parameters.output.to.kind">
<div ng-switch-when="ImageRepository">
Output image: {{buildConfig.parameters.output.to.name}}
</div>
</div>
</div>
<div ng-if="!build.parameters.output.to && build.parameters.output.dockerImageReference && buildConfig.parameters.output.dockerImageReference != build.parameters.output.dockerImageReference">
Output image: {{build.parameters.output.dockerImageReference}}
</div>
</div>
</div>
</div>
<!-- render any builds whose build configs no longer exist -->
<div ng-repeat="(buildConfigName, blds) in buildsByBuildConfig" ng-if="!buildConfigs[buildConfigName]">
<h2 ng-if="buildConfigName != ''">
{{buildConfigName}}
<span class="pficon-layered" data-toggle="tooltip" data-placement="right" title="This build config no longer exists" style="cursor: help;">
<span class="pficon pficon-warning-triangle"></span>
<span class="pficon pficon-warning-exclamation"></span>
</span>
</h2>
<div ng-repeat="build in blds | orderObjectsByDate : true">
<h3>{{build.metadata.name}}</h3>
<div>Created: <relative-timestamp timestamp="build.metadata.creationTimestamp"></relative-timestamp></div>
<div>
<span style="margin-right: 5px;">Status: {{build.status}}</span>
<span ng-switch="build.status" class="hide-ng-leave">
<span ng-switch-when="Complete" class="fa fa-check text-success" aria-hidden="true"></span>
<span ng-switch-when="Failed" class="fa fa-times text-danger" aria-hidden="true"></span>
<span ng-switch-default class="fa fa-refresh fa-spin" aria-hidden="true"></span>
</span>
</div>
<div>Build strategy: {{build.parameters.strategy.type}}</div>
<div ng-switch="build.parameters.strategy.type">
<div ng-switch-when="STI">
Builder image: {{build.parameters.strategy.stiStrategy.image}}
</div>
<div ng-switch-when="Docker">
<div ng-if="build.parameters.strategy.dockerStrategy.image">
Builder image: {{build.parameters.strategy.dockerStrategy.image}}
</div>
</div>
<div ng-switch-when="Custom">
Builder image: {{build.parameters.strategy.customStrategy.image}}
</div>
</div>
<div ng-if="build.parameters.source">
<div ng-if="build.parameters.source.type == 'Git'">Source repo: {{build.parameters.source.git.uri}}</div>
<!-- TODO add git ref details -->
</div>
<div ng-if="build.parameters.output">
<div ng-switch="build.parameters.output.to.kind">
<div ng-switch-when="ImageRepository">
Output image: {{build.parameters.output.to.name}}
</div>
</div>
<div ng-if="!build.parameters.output.to && build.parameters.output.dockerImageReference">
Output image: {{build.parameters.output.dockerImageReference}}
</div>
</div>
</div>
<div>Output image: {{build.parameters.output.imageTag}}</div>
<div>Output image registry: {{build.parameters.output.registry}}</div>
</div>
</div>
</project-page>
Expand Down
Loading