Skip to content

Commit

Permalink
Merge pull request #2358 from vincent99/master
Browse files Browse the repository at this point in the history
Drain should be bulkable and make more sense
  • Loading branch information
westlywright authored Oct 26, 2018
2 parents 1788c06 + 68577cf commit a68f996
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 83 deletions.
51 changes: 30 additions & 21 deletions app/components/modal-drain-node/component.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,48 @@
import { inject as service } from '@ember/service';
import { get, set } from '@ember/object';
import { get } from '@ember/object';
import { alias } from '@ember/object/computed';
import Component from '@ember/component';
import ModalBase from 'shared/mixins/modal-base';
import layout from './template';
import { eachLimit } from 'async';

export default Component.extend(ModalBase, {
growl: service(),

layout,
classNames: ['large-modal'],

model: alias('modalService.modalOpts.originalModel'),
aggressive: false,
usePodGracePeriod: true,
gracePeriod: 30,
unlimitedTimeout: false,
timeout: 60,

didReceiveAttrs() {
const options = {
force: false,
ignoreDaemonSets: true,
deleteLocalData: false,
gracePeriod: -1,
timeout: 60,
};

set(this, 'options', options);
},
resources: alias('modalService.modalOpts.resources'),

actions: {
save(cb) {
get(this, 'model').doAction('drain', get(this, 'options'))
.then(() => {
this.send('cancel');
})
.finally(() => {
cb();
});
drain() {
const aggressive = get(this, 'aggressive');

const opts = {
deleteLocalData: aggressive,
force: aggressive,
ignoreDaemonSets: true,
gracePeriod: get(this, 'usePodGracePeriod') ? -1 : get(this, 'gracePeriod'),
timeout: get(this, 'unlimitedTimeout') ? 0 : get(this, 'timeout'),
};

const resources = get(this, 'resources').slice();

eachLimit(resources, 5, (resource, cb) => {
if ( !resource ) {
return cb();
}

resource.doAction('drain', opts).finally(cb);
});

this.send('cancel');
},
},
});
96 changes: 52 additions & 44 deletions app/components/modal-drain-node/template.hbs
Original file line number Diff line number Diff line change
@@ -1,65 +1,73 @@
<h2>
{{t 'modalDrainNode.title' nodeName=model.displayName}}
</h2>
<div class="container-header-text">
<h3>
{{#if (eq resources.length 1)}}
{{t 'modalDrainNode.titleOne' name=resources.firstObject.displayName}}
{{else}}
{{t 'modalDrainNode.titleMultiple' count=resources.length}}
{{/if}}
</h3>
<hr/>
</div>

<section class="p-20">
<label class="acc-label">{{t 'modalDrainNode.drain'}}</label>
<section class="p-20 pt-0">
<div class="row">
<div class="col span-12">
<div class="checkbox" style="position: absolute">
<label>
{{input type="checkbox" classNames="form-control" checked=options.force}}
{{t 'modalDrainNode.force.helpText'}}
<div class="col span-11-of-23">
<label class="acc-label">{{t 'modalDrainNode.mode'}}</label>
<div>
<label class="radio mt-0">
{{radio-button selection=aggressive value=false}}
{{t 'modalDrainNode.safe.label'}}
<p class="help-block">{{t 'modalDrainNode.safe.helpText'}}</p>
</label>
</div>
</div>
</div>

<div class="row mt-5">
<div class="col span-12">
<div class="checkbox" style="position: absolute">
<label>
{{input type="checkbox" classNames="form-control" checked=options.ignoreDaemonSets}}
{{t 'modalDrainNode.ignoreDaemonSets.helpText'}}
<div>
<label class="radio text-error">
{{radio-button selection=aggressive value=true}}
{{t 'modalDrainNode.aggressive.label'}}
<p class="help-block text-error">{{t 'modalDrainNode.aggressive.helpText' htmlSafe=true}}</p>
</label>
</div>
</div>
</div>

<div class="row mt-5">
<div class="col span-12">
<div class="checkbox" style="position: absolute">
<label>
{{input type="checkbox" classNames="form-control" checked=options.deleteLocalData}}
{{t 'modalDrainNode.deleteLocalData.helpText'}}
<div class="col span-11-of-23 offset-1-of-23">
<label class="acc-label">{{t 'modalDrainNode.gracePeriod.title'}}</label>
<div>
<label class="radio mt-0">
{{radio-button selection=usePodGracePeriod value=true}}
{{t 'modalDrainNode.gracePeriod.default'}}
</label>
</div>
<div>
<label class="radio">
{{radio-button selection=usePodGracePeriod value=false}}
{{t 'modalDrainNode.gracePeriod.custom'}}
</label>
</div>
</div>
</div>

<div class="row mt-20">
<div class="col span-6">
<label class="acc-label">{{t 'modalDrainNode.gracePeriod.label'}}</label>
<div class="input-group">
{{input-integer value=options.gracePeriod classNames="form-control" placeholder=(t 'modalDrainNode.gracePeriod.placeholder')}}
{{input-integer value=gracePeriod disabled=usePodGracePeriod min=1 classNames="form-control" placeholder=(t 'modalDrainNode.gracePeriod.placeholder')}}
<span class="input-group-addon bg-default">{{t 'generic.seconds'}}</span>
</div>
<p class="help-block">{{t 'modalDrainNode.gracePeriod.helpText'}}</p>
</div>

<div class="col span-6">
<label class="acc-label">{{t 'modalDrainNode.timeout.label'}}</label>

<label class="acc-label mt-10">{{t 'modalDrainNode.timeout.title'}}</label>
<div>
<label class="radio mt-0">
{{radio-button selection=unlimitedTimeout value=true}}
{{t 'modalDrainNode.timeout.default'}}
</label>
</div>
<div>
<label class="radio">
{{radio-button selection=unlimitedTimeout value=false}}
{{t 'modalDrainNode.timeout.custom'}}
</label>
</div>
<div class="input-group">
{{input-integer min=1 max=10800 value=options.timeout classNames="form-control" placeholder=(t 'modalDrainNode.timeout.placeholder')}}
{{input-integer min=1 max=10800 disabled=unlimitedTimeout value=timeout classNames="form-control" placeholder=(t 'modalDrainNode.timeout.placeholder')}}
<span class="input-group-addon bg-default">{{t 'generic.seconds'}}</span>
</div>
<p class="help-block">{{t 'modalDrainNode.timeout.helpText'}}</p>
</div>
</div>
</section>

{{#unless options.ignoreDaemonSets}}
{{banner-message color='bg-info' message=(t 'modalDrainNode.ignoreDaemonSets.warning')}}
{{/unless}}

{{save-cancel editing=true editLabel="modalDrainNode.action" save="save" cancel="cancel"}}
{{save-cancel editing=true editLabel="modalDrainNode.action" save="drain" cancel="cancel"}}
7 changes: 5 additions & 2 deletions app/models/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var Node = Resource.extend(StateCounts, ResourceUsage, {
icon: 'icon icon-snapshot',
action: 'drain',
enabled: !!a.drain,
bulkable: false
bulkable: true
},
{
label: 'action.stopDrain',
Expand Down Expand Up @@ -198,7 +198,10 @@ var Node = Resource.extend(StateCounts, ResourceUsage, {
},

drain() {
get(this, 'modalService').toggleModal('modal-drain-node', { originalModel: this });
get(this, 'modalService').toggleModal('modal-drain-node', {
escToClose: true,
resources: this
});
},

stopDrain() {
Expand Down
17 changes: 15 additions & 2 deletions lib/shared/addon/bulk-action-handler/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,24 @@ export default Service.extend({
modalService: service('modal'),
app: service(),
promptStop(nodes) {
this.get('modalService').toggleModal('modal-container-stop', { model: nodes });
this.get('modalService').toggleModal('modal-container-stop', {
escToClose: true,
model: nodes
});
},

promptDelete(nodes) {
this.get('modalService').toggleModal('confirm-delete', { resources: nodes });
this.get('modalService').toggleModal('confirm-delete', {
escToClose: true,
resources: nodes
});
},

drain(nodes) {
this.get('modalService').toggleModal('modal-drain-node', {
escToClose: true,
resources: nodes
});
},

move(nodes) {
Expand Down
30 changes: 16 additions & 14 deletions translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4629,24 +4629,26 @@ modalProcessError:
close: Close

modalDrainNode:
title: 'Drain "{nodeName}"'
titleOne: 'Drain "{name}"'
titleMultiple: 'Drain {count} Nodes'
action: Drain
drain: 'Drain this node:'
force:
helpText: Even if there are pods not managed by a ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet.
ignoreDaemonSets:
helpText: Even if there are DaemonSet-managed pods.
warning: Ingress DaemonSet is on each node by default. Drain might never succeed if you don't select ignore DaemonSet option.
deleteLocalData:
helpText: Even if there are pods using emptyDir (local data that will be deleted when the node is drained).
mode: Mode
safe:
label: Safe
helpText: If a node has standalone pods or ephemeral data it will be cordoned but not drained.
aggressive:
label: Aggressive
helpText: <b>Permanently delete</b>:<ul class="m-0"><li>Standalone Pods and their data</li><li>Pods with "Empty Dir" volumes and their data.</li></ul>
gracePeriod:
helpText: Period of time in seconds given to each pod to terminate gracefully. If negative, the default value specified in the pod will be used.
placeholder: e.g. 60
label: Grace Period
title: Grace period for pods to terminate themselves
default: Honor the default from each pod
placeholder: e.g. 30
custom: "Ignore the defaults and give each pod:"
timeout:
helpText: The length of time to wait before giving up, zero means infinite
title: "Drain timeout"
default: Keep trying forever
placeholder: e.g. 60
label: Timeout
custom: "Give up after:"

modalRollbackService:
title: 'Rollback "{instanceName}"'
Expand Down

0 comments on commit a68f996

Please sign in to comment.