Skip to content

Commit 8e7b54f

Browse files
committed
Let users remove volumes
1 parent 9e57f47 commit 8e7b54f

16 files changed

+532
-231
lines changed

app/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ <h1>JavaScript Required</h1>
205205
<script src="scripts/services/quota.js"></script>
206206
<script src="scripts/services/labels.js"></script>
207207
<script src="scripts/services/catalog.js"></script>
208+
<script src="scripts/services/modals.js"></script>
208209
<script src="scripts/controllers/projects.js"></script>
209210
<script src="scripts/controllers/pods.js"></script>
210211
<script src="scripts/controllers/pod.js"></script>

app/scripts/controllers/deployment.js

+36
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ angular.module('openshiftConsole')
1616
DeploymentsService,
1717
HPAService,
1818
ImageStreamResolver,
19+
ModalsService,
1920
Navigate,
2021
Logger,
2122
ProjectsService,
23+
StorageService,
2224
keyValueEditorUtils) {
2325
var imageStreamImageRefByDockerReference = {}; // lets us determine if a particular container's docker image reference belongs to an imageStream
2426

@@ -241,6 +243,40 @@ angular.module('openshiftConsole')
241243
});
242244
};
243245

246+
$scope.removeVolume = function(volume) {
247+
var details;
248+
if (_.get($scope, 'deployment.spec.paused')) {
249+
details = "This will remove the volume from the deployment.";
250+
} else {
251+
details = "This will remove the volume from the deployment and start a new rollout.";
252+
}
253+
254+
var confirm = ModalsService.confirm({
255+
message: "Remove volume " + volume.name + "?",
256+
details: details,
257+
okButtonText: "Remove",
258+
okButtonClass: "btn-danger",
259+
cancelButtonText: "Cancel"
260+
});
261+
262+
var showError = function(e) {
263+
$scope.alerts["remove-volume-error"] = {
264+
type: "error",
265+
message: "An error occurred removing the volume.",
266+
details: $filter('getErrorDetails')(e)
267+
};
268+
};
269+
270+
var removeVolume = function() {
271+
// No-op on success since the page updates.
272+
StorageService
273+
.removeVolume($scope.deployment, volume, context)
274+
.then(_.noop, showError);
275+
};
276+
277+
confirm.then(removeVolume);
278+
};
279+
244280
$scope.$on('$destroy', function(){
245281
DataService.unwatchAll(watches);
246282
});

app/scripts/controllers/deploymentConfig.js

+47-4
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ angular.module('openshiftConsole')
1717
DeploymentsService,
1818
HPAService,
1919
ImageStreamResolver,
20+
ModalsService,
2021
Navigate,
2122
Logger,
2223
ProjectsService,
24+
StorageService,
2325
LabelFilter,
2426
labelNameFilter,
2527
keyValueEditorUtils) {
@@ -291,8 +293,7 @@ angular.module('openshiftConsole')
291293

292294
$scope.scale = function(replicas) {
293295
var showScalingError = function(result) {
294-
$scope.alerts = $scope.alerts || {};
295-
$scope.alerts["scale"] = {
296+
$scope.alerts["scale-error"] = {
296297
type: "error",
297298
message: "An error occurred scaling the deployment config.",
298299
details: $filter('getErrorDetails')(result)
@@ -309,15 +310,57 @@ angular.module('openshiftConsole')
309310
// Failure
310311
function(e) {
311312
$scope.updatingPausedState = false;
312-
$scope.alerts = $scope.alerts || {};
313-
$scope.alerts["scale"] = {
313+
$scope.alerts["pause-error"] = {
314314
type: "error",
315315
message: "An error occurred " + (paused ? "pausing" : "resuming") + " the deployment config.",
316316
details: $filter('getErrorDetails')(e)
317317
};
318318
});
319319
};
320320

321+
var isConfigChangeActive = function() {
322+
if (_.get($scope, 'deploymentConfig.spec.paused')) {
323+
return false;
324+
}
325+
326+
var triggers = _.get($scope, 'deploymentConfig.spec.triggers', []);
327+
return _.some(triggers, { type: 'ConfigChange' });
328+
};
329+
330+
$scope.removeVolume = function(volume) {
331+
var details;
332+
if (isConfigChangeActive()) {
333+
details = "This will remove the volume from the deployment config and trigger a new deployment.";
334+
} else {
335+
details = "This will remove the volume from the deployment config.";
336+
}
337+
338+
var confirm = ModalsService.confirm({
339+
message: "Remove volume " + volume.name + "?",
340+
details: details,
341+
okButtonText: "Remove",
342+
okButtonClass: "btn-danger",
343+
cancelButtonText: "Cancel"
344+
});
345+
346+
var showError = function(e) {
347+
$scope.alerts["remove-volume-error"] = {
348+
type: "error",
349+
message: "An error occurred removing the volume.",
350+
details: $filter('getErrorDetails')(e)
351+
};
352+
};
353+
354+
var removeVolume = function() {
355+
// No-op on success since the page updates.
356+
StorageService
357+
.removeVolume($scope.deploymentConfig, volume, context)
358+
.then(_.noop, showError);
359+
};
360+
361+
confirm.then(removeVolume);
362+
};
363+
321364
$scope.$on('$destroy', function(){
322365
DataService.unwatchAll(watches);
323366
});

app/scripts/controllers/replicaSet.js

+33-4
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ angular.module('openshiftConsole')
1414
AlertMessageService,
1515
BreadcrumbsService,
1616
DataService,
17-
HPAService,
18-
MetricsService,
19-
ProjectsService,
2017
DeploymentsService,
18+
HPAService,
2119
ImageStreamResolver,
22-
Navigate,
2320
Logger,
21+
MetricsService,
22+
ModalsService,
23+
Navigate,
24+
ProjectsService,
25+
StorageService,
2426
keyValueEditorUtils,
2527
kind) {
2628
var hasDC = false;
@@ -536,6 +538,33 @@ angular.module('openshiftConsole')
536538
return $scope.isActive && !inProgressDeployment;
537539
};
538540

541+
$scope.removeVolume = function(volume) {
542+
var confirm = ModalsService.confirm({
543+
message: "Remove volume " + volume.name + "?",
544+
details: "This will remove the volume from the " + $filter('humanizeKind')($scope.replicaSet.kind) + ".",
545+
okButtonText: "Remove",
546+
okButtonClass: "btn-danger",
547+
cancelButtonText: "Cancel"
548+
});
549+
550+
var showError = function(e) {
551+
$scope.alerts["remove-volume-error"] = {
552+
type: "error",
553+
message: "An error occurred removing the volume.",
554+
details: $filter('getErrorDetails')(e)
555+
};
556+
};
557+
558+
var removeVolume = function() {
559+
// No-op on success since the page updates.
560+
StorageService
561+
.removeVolume($scope.replicaSet, volume, context)
562+
.then(_.noop, showError);
563+
};
564+
565+
confirm.then(removeVolume);
566+
};
567+
539568
$scope.$on('$destroy', function(){
540569
DataService.unwatchAll(watches);
541570
});

app/scripts/directives/resources.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ angular.module('openshiftConsole')
120120
restrict: 'E',
121121
scope: {
122122
volumes: '=',
123-
namespace: '='
123+
namespace: '=',
124+
canRemove: '=?',
125+
removeFn: '&?'
124126
},
125127
templateUrl: 'views/_volumes.html'
126128
};

app/scripts/services/modals.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
angular.module("openshiftConsole")
4+
.factory("ModalsService", function($uibModal) {
5+
return {
6+
// Show a confirm dialog using the provided modal config and return a promise.
7+
// See app/scripts/controllers/modals/confirmModal.js
8+
confirm: function(modalConfig) {
9+
var modalInstance = $uibModal.open({
10+
animation: true,
11+
templateUrl: 'views/modals/confirm.html',
12+
controller: 'ConfirmModalController',
13+
resolve: {
14+
modalConfig: modalConfig
15+
}
16+
});
17+
18+
return modalInstance.result;
19+
}
20+
};
21+
});

app/scripts/services/storage.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
angular.module("openshiftConsole")
4-
.factory("StorageService", function() {
4+
.factory("StorageService", function(APIService, DataService) {
55
return {
66
createVolume: function(name, persistentVolumeClaim) {
77
return {
@@ -11,17 +11,20 @@ angular.module("openshiftConsole")
1111
}
1212
};
1313
},
14+
1415
createVolumeMount: function(name, mountPath) {
1516
return {
1617
name: name,
1718
mountPath: mountPath
1819
};
1920
},
21+
2022
// Gets the volume names currently defined in the pod template.
2123
getVolumeNames: function(podTemplate) {
2224
var volumes = _.get(podTemplate, 'spec.volumes', []);
2325
return _.map(volumes, 'name');
2426
},
27+
2528
// Gets the mount paths currently defined in the pod template. An
2629
// optional filter function for matching specific containers can be used.
2730
getMountPaths: function(podTemplate, /* optional function */ matchContainer) {
@@ -39,6 +42,22 @@ angular.module("openshiftConsole")
3942
});
4043

4144
return mountPaths;
45+
},
46+
47+
// Removes the volume and any container volume mounts.
48+
removeVolume: function(object, volume, context) {
49+
var copy = angular.copy(object);
50+
51+
var volumes = _.get(copy, 'spec.template.spec.volumes');
52+
_.remove(volumes, { name: volume.name });
53+
54+
var containers = _.get(copy, 'spec.template.spec.containers');
55+
_.each(containers, function(container) {
56+
_.remove(container.volumeMounts, { name: volume.name });
57+
});
58+
59+
var resource = APIService.objectToResourceGroupVersion(copy);
60+
return DataService.update(resource, copy.metadata.name, copy, context);
4261
}
4362
};
4463
});

app/styles/_core.less

+5
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,11 @@ a.disabled-link {
920920
vertical-align: middle;
921921
}
922922

923+
.header-actions {
924+
.small();
925+
margin-left: 5px;
926+
}
927+
923928
.modal-resource-action {
924929
background-color: @gray-lighter;
925930
h1 {

app/views/_volumes.html

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
namespace
55
-->
66
<div ng-repeat="volume in volumes">
7-
<h5>{{volume.name}}</h5>
7+
<h4>
8+
{{volume.name}}
9+
<span ng-if="canRemove" class="header-actions">
10+
<a href="" ng-click="removeFn({volume: volume})">Remove</a>
11+
</span>
12+
</h4>
813
<dl class="dl-horizontal left">
914
<div ng-if="volume.secret">
1015
<dt>Type:</dt>

app/views/browse/_replica-set-details.html

+25-7
Original file line numberDiff line numberDiff line change
@@ -89,41 +89,60 @@ <h3>Template</h3>
8989
add-health-check-url="{{((!deploymentConfig || isActive) && ('deploymentconfigs' | canI : 'update')) ? healthCheckURL : ''}}">
9090
</pod-template>
9191
<h4>Volumes</h4>
92-
<volumes volumes="replicaSet.spec.template.spec.volumes" namespace="project.metadata.name"></volumes>
9392
<div ng-if="kind === 'ReplicaSet'">
9493
<div ng-if="deployment">
94+
<volumes volumes="replicaSet.spec.template.spec.volumes" namespace="project.metadata.name"></volumes>
9595
<div ng-if="{ group: 'extensions', resource: 'deployments' } | canI : 'update'">
9696
<a ng-href="project/{{project.metadata.name}}/attach-pvc?kind=Deployment&name={{deployment.metadata.name}}&group=extensions">Add storage</a>
9797
<span class="action-divider" aria-hidden="true">|</span>
9898
<a ng-href="project/{{project.metadata.name}}/add-config-volume?kind=Deployment&name={{deployment.metadata.name}}">Add config files</a>
9999
</div>
100-
<span ng-if="!({ group: 'extensions', resource: 'deployments' } | canI : 'update')">none</span>
100+
<div ng-if="!replicaSet.spec.template.spec.volumes.length && !({ group: 'extensions', resource: 'deployments' } | canI : 'update')">none</div>
101101
</div>
102102
<div ng-if="!deployment">
103103
<div ng-if="resource | canI : 'update'">
104+
<volumes
105+
volumes="replicaSet.spec.template.spec.volumes"
106+
namespace="project.metadata.name"
107+
can-remove="true"
108+
remove-fn="removeVolume(volume)">
109+
</volumes>
104110
<a ng-href="project/{{project.metadata.name}}/attach-pvc?kind=ReplicaSet&name={{replicaSet.metadata.name}}&group=extensions">Add storage</a>
105111
<span class="action-divider" aria-hidden="true">|</span>
106-
<a ng-href="project/{{project.metadata.name}}/add-config-volume?kind=ReplicaSet&name={{replicaSet.metadata.name}}">Add config files</a>
112+
<a ng-href="project/{{project.metadata.name}}/add-config-volume?kind=ReplicaSet&name={{replicaSet.metadata.name}}&group=extensions">Add config files</a>
113+
</div>
114+
<div ng-if="!(resource | canI : 'update')">
115+
<volumes volumes="replicaSet.spec.template.spec.volumes" namespace="project.metadata.name"></volumes>
116+
<span ng-if="!replicaSet.spec.template.spec.volumes.length">none</span>
107117
</div>
108-
<span ng-if="!(resource | canI : 'update')">none</span>
109118
</div>
110119
</div>
111120
<div ng-if="kind === 'ReplicationController'">
112121
<div ng-if="deploymentConfigName">
122+
<volumes volumes="replicaSet.spec.template.spec.volumes" namespace="project.metadata.name"></volumes>
113123
<div ng-if="'deploymentconfigs' | canI : 'update'">
114124
<a ng-href="project/{{project.metadata.name}}/attach-pvc?kind=DeploymentConfig&name={{deploymentConfigName}}">Add storage to {{deploymentConfigName}}</a>
115125
<span class="action-divider" aria-hidden="true">|</span>
116126
<a ng-href="project/{{project.metadata.name}}/add-config-volume?kind=DeploymentConfig&name={{deploymentConfigName}}">Add config files to {{deploymentConfigName}}</a>
117127
</div>
118-
<span ng-if="!('deploymentconfigs' | canI : 'update')">none</span>
128+
<div ng-if="!replicaSet.spec.template.spec.volumes.length && !('deploymentconfigs' | canI : 'update')">none</div>
119129
</div>
120130
<div ng-if="!deploymentConfigName">
121131
<div ng-if="resource | canI : 'update'">
132+
<volumes
133+
volumes="replicaSet.spec.template.spec.volumes"
134+
namespace="project.metadata.name"
135+
can-remove="true"
136+
remove-fn="removeVolume(volume)">
137+
</volumes>
122138
<a ng-href="project/{{project.metadata.name}}/attach-pvc?kind=ReplicationController&name={{replicaSet.metadata.name}}">Add storage</a>
123139
<span class="action-divider" aria-hidden="true">|</span>
124140
<a ng-href="project/{{project.metadata.name}}/add-config-volume?kind=ReplicationController&name={{replicaSet.metadata.name}}">Add config files</a>
125141
</div>
126-
<span ng-if="!(resource | canI : 'update')">none</span>
142+
<div ng-if="!(resource | canI : 'update')">
143+
<volumes volumes="replicaSet.spec.template.spec.volumes" namespace="project.metadata.name"></volumes>
144+
<span ng-if="!replicaSet.spec.template.spec.volumes.length">none</span>
145+
</div>
127146
</div>
128147
</div>
129148
</div>
@@ -184,7 +203,6 @@ <h3>Autoscaling</h3>
184203

185204
<!-- HPA details -->
186205
<div ng-repeat="hpa in autoscalers | orderBy : 'name'">
187-
<h4>{{hpa.metadata.name}}</h4>
188206
<hpa hpa="hpa"
189207
show-scale-target="hpa.spec.scaleRef.kind !== 'ReplicationController'"
190208
alerts="alerts">

0 commit comments

Comments
 (0)