mirror of https://github.com/rancher/ui.git
978 lines
24 KiB
JavaScript
978 lines
24 KiB
JavaScript
import Ember from 'ember';
|
|
import NewOrEdit from 'ui/mixins/new-or-edit';
|
|
import ShellQuote from 'npm:shell-quote';
|
|
import Util from 'ui/utils/util';
|
|
import EditHealthCheck from 'ui/mixins/edit-healthcheck';
|
|
import EditScheduling from 'ui/mixins/edit-scheduling';
|
|
|
|
export default Ember.Mixin.create(NewOrEdit, EditHealthCheck, EditScheduling, {
|
|
needs: ['hosts'],
|
|
queryParams: ['tab','hostId','advanced'],
|
|
tab: 'command',
|
|
hostId: null,
|
|
advanced: false,
|
|
|
|
primaryResource: Ember.computed.alias('model.instance'),
|
|
|
|
actions: {
|
|
toggleAdvanced: function() {
|
|
this.set('advanced', !this.get('advanced'));
|
|
},
|
|
|
|
addEnvironment: function() {
|
|
this.get('environmentArray').pushObject({key: '', value: ''});
|
|
},
|
|
removeEnvironment: function(obj) {
|
|
this.get('environmentArray').removeObject(obj);
|
|
},
|
|
|
|
addPort: function() {
|
|
this.get('portsArray').pushObject({public: '', private: '', protocol: 'tcp'});
|
|
},
|
|
removePort: function(obj) {
|
|
this.get('portsArray').removeObject(obj);
|
|
},
|
|
|
|
addLink: function() {
|
|
this.get('linksArray').pushObject({name: '', targetInstanceId: null});
|
|
},
|
|
removeLink: function(obj) {
|
|
this.get('linksArray').removeObject(obj);
|
|
},
|
|
|
|
addVolume: function() {
|
|
this.get('volumesArray').pushObject({value: ''});
|
|
},
|
|
removeVolume: function(obj) {
|
|
this.get('volumesArray').removeObject(obj);
|
|
},
|
|
|
|
addVolumeFrom: function() {
|
|
this.get('volumesFromArray').pushObject({value: ''});
|
|
},
|
|
removeVolumeFrom: function(obj) {
|
|
this.get('volumesFromArray').removeObject(obj);
|
|
},
|
|
|
|
addVolumeFromService: function() {
|
|
this.get('volumesFromServiceArray').pushObject({value: ''});
|
|
},
|
|
removeVolumeFromService: function(obj) {
|
|
this.get('volumesFromServiceArray').removeObject(obj);
|
|
},
|
|
|
|
addDns: function() {
|
|
this.get('dnsArray').pushObject({value: ''});
|
|
},
|
|
removeDns: function(obj) {
|
|
this.get('dnsArray').removeObject(obj);
|
|
},
|
|
|
|
addDnsSearch: function() {
|
|
this.get('dnsSearchArray').pushObject({value: ''});
|
|
},
|
|
removeDnsSearch: function(obj) {
|
|
this.get('dnsSearchArray').removeObject(obj);
|
|
},
|
|
|
|
addDevice: function() {
|
|
this.get('devicesArray').pushObject({host: '', container: '', permissions: 'rwm'});
|
|
},
|
|
removeDevice: function(obj) {
|
|
this.get('devicesArray').removeObject(obj);
|
|
},
|
|
|
|
pastedEnviromentVars: function(str, target) {
|
|
var ary = this.get('environmentArray');
|
|
str = str.trim();
|
|
if ( str.indexOf('=') === -1 )
|
|
{
|
|
// Just pasting a key
|
|
$(target).val(str);
|
|
return;
|
|
}
|
|
|
|
var lines = str.split(/\r?\n/);
|
|
lines.forEach((line) => {
|
|
line = line.trim();
|
|
if ( !line )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var idx = line.indexOf('=');
|
|
var key = '';
|
|
var val = '';
|
|
if ( idx > 0 )
|
|
{
|
|
key = line.substr(0,idx).trim();
|
|
val = line.substr(idx+1).trim();
|
|
}
|
|
else
|
|
{
|
|
key = line.trim();
|
|
val = '';
|
|
}
|
|
|
|
var existing = ary.filterBy('key',key)[0];
|
|
if ( existing )
|
|
{
|
|
Ember.set(existing,'value',val);
|
|
}
|
|
else
|
|
{
|
|
ary.pushObject({key: key, value: val});
|
|
}
|
|
});
|
|
|
|
ary.forEach((item) => {
|
|
if ( !item.key && !item.value )
|
|
{
|
|
ary.removeObject(item);
|
|
}
|
|
});
|
|
},
|
|
},
|
|
|
|
// ----------------------------------
|
|
// Setup
|
|
// ----------------------------------
|
|
initFields: function() {
|
|
this._super();
|
|
this.initPorts();
|
|
this.initLinks();
|
|
|
|
if ( !this.get('editing') )
|
|
{
|
|
this.initNetwork();
|
|
this.initEnvironment();
|
|
this.initVolumes();
|
|
this.initVolumesFrom();
|
|
this.initDns();
|
|
this.initDnsSearch();
|
|
this.initCapability();
|
|
this.initDevices();
|
|
this.initUuid();
|
|
this.initTerminal();
|
|
this.initRestart();
|
|
this.initCommand();
|
|
this.initEntryPoint();
|
|
this.initMemory();
|
|
this.initScheduling();
|
|
this.initPidMode();
|
|
}
|
|
},
|
|
|
|
// ----------------------------------
|
|
// Image
|
|
// ----------------------------------
|
|
userImageUuid: 'ubuntu:14.04.3',
|
|
initUuid: function() {
|
|
if ( this.get('instance.imageUuid') )
|
|
{
|
|
this.set('userImageUuid', (this.get('instance.imageUuid')||'').replace(/^docker:/,''));
|
|
}
|
|
this.userImageUuidDidChange();
|
|
},
|
|
userImageUuidDidChange: function() {
|
|
var input = (this.get('userImageUuid')||'').trim();
|
|
var uuid = 'docker:';
|
|
|
|
// Look for a redundant docker: pasted in
|
|
if ( input.indexOf(uuid) === 0 )
|
|
{
|
|
//this.set('userImageUuid', input.substr(uuid.length));
|
|
//return;
|
|
uuid = input;
|
|
this.set('instance.imageUuid', input);
|
|
}
|
|
else if ( input && input.length )
|
|
{
|
|
this.set('instance.imageUuid', uuid+input);
|
|
}
|
|
else
|
|
{
|
|
this.set('instance.imageUuid', null);
|
|
}
|
|
}.observes('userImageUuid'),
|
|
|
|
|
|
// ----------------------------------
|
|
// Restart
|
|
// ----------------------------------
|
|
restart: null, //'no',
|
|
restartLimit: null, //5,
|
|
|
|
initRestart: function() {
|
|
var name = this.get('instance.restartPolicy.name');
|
|
var count = this.get('instance.restartPolicy.maximumRetryCount');
|
|
if ( name === 'on-failure' && count !== undefined )
|
|
{
|
|
this.setProperties({
|
|
'restart': 'on-failure-cond',
|
|
'restartLimit': parseInt(count, 10),
|
|
});
|
|
}
|
|
else
|
|
{
|
|
this.set('restartLimit',5);
|
|
this.set('restart', name || 'no');
|
|
}
|
|
},
|
|
|
|
restartDidChange: function() {
|
|
var policy = {};
|
|
var name = this.get('restart');
|
|
var limit = parseInt(this.get('restartLimit'),10);
|
|
|
|
if ( name === 'on-failure-cond' )
|
|
{
|
|
name = 'on-failure';
|
|
if ( limit > 0 )
|
|
{
|
|
policy.maximumRetryCount = limit;
|
|
}
|
|
}
|
|
|
|
policy.name = name;
|
|
this.set('instance.restartPolicy', policy);
|
|
}.observes('restart','restartLimit'),
|
|
|
|
restartLimitDidChange: function() {
|
|
this.set('restart', 'on-failure-cond');
|
|
}.observes('restartLimit'),
|
|
|
|
// ----------------------------------
|
|
// Network
|
|
// ----------------------------------
|
|
networkChoices: null,
|
|
isManagedNetwork: Ember.computed.equal('instance.networkMode','managed'),
|
|
isContainerNetwork: Ember.computed.equal('instance.networkMode','container'),
|
|
initNetwork: function() {
|
|
var isService = this.get('isService')||false;
|
|
var choices = this.get('store').getById('schema','container').get('resourceFields.networkMode').options.sort();
|
|
var out = [];
|
|
choices.forEach((option) => {
|
|
if ( isService && option === 'container' )
|
|
{
|
|
return;
|
|
}
|
|
|
|
out.push({label: Util.ucFirst(option), value: option});
|
|
});
|
|
|
|
this.set('networkChoices', out);
|
|
},
|
|
|
|
networkModeChanged: function() {
|
|
if ( this.get('instance.networkMode') !== 'container' )
|
|
{
|
|
this.set('instance.networkContainerId', null);
|
|
}
|
|
}.observes('instance.networkMode'),
|
|
|
|
// ----------------------------------
|
|
// Links
|
|
// ----------------------------------
|
|
containerChoices: function() {
|
|
var list = [];
|
|
var id = this.get('id');
|
|
|
|
var expectContainerIds = (this.get('linksArray')||[]).map(function(obj) {
|
|
return Ember.get(obj,'targetInstanceId');
|
|
});
|
|
|
|
this.get('allHosts').map((host) => {
|
|
var containers = (host.get('instances')||[]).filter(function(instance) {
|
|
// You can't link to yourself, or to other types of instances, or to system containers
|
|
return instance.get('id') !== id &&
|
|
instance.get('kind') === 'container' &&
|
|
!instance.get('systemContainer');
|
|
});
|
|
|
|
var hostLabel = 'Host: ' + (host.get('name') || '('+host.get('id')+')');
|
|
if ( host.get('state') !== 'active' )
|
|
{
|
|
hostLabel += ' (' + host.get('state') + ')';
|
|
}
|
|
|
|
list.pushObjects(containers.map(function(container) {
|
|
expectContainerIds.removeObject(container.get('id'));
|
|
|
|
var containerLabel = (container.get('name') || '('+container.get('id')+')');
|
|
if ( container.get('state') !== 'running' )
|
|
{
|
|
containerLabel += ' (' + container.get('state') + ')';
|
|
}
|
|
|
|
return {
|
|
group: hostLabel,
|
|
hostId: host.get('id'),
|
|
id: container.get('id'),
|
|
name: containerLabel,
|
|
};
|
|
}));
|
|
});
|
|
|
|
if ( expectContainerIds.get('length') )
|
|
{
|
|
// There are some links to containers which are not in the list somehow..
|
|
expectContainerIds.forEach((id) => {
|
|
var container = this.get('store').getById('container',id);
|
|
return {
|
|
group: 'Host: ???',
|
|
hostId: null,
|
|
id: id,
|
|
name: (container && container.get('name') ? container.get('name') : '('+id+')')
|
|
};
|
|
});
|
|
}
|
|
|
|
return list.sortBy('group','name','id');
|
|
}.property('allHosts.@each.instancesUpdated').volatile(),
|
|
|
|
containersOnRequestedHost: function() {
|
|
var requestedHostId = this.get('instance.requestedHostId');
|
|
var all = this.get('containerChoices');
|
|
|
|
if ( requestedHostId )
|
|
{
|
|
return all.filterBy('hostId', requestedHostId);
|
|
}
|
|
else
|
|
{
|
|
return all;
|
|
}
|
|
}.property('containerChoices.@each.hostId','instance.requestedHostId'),
|
|
|
|
containersOnRequestedHostIfUnmanaged: function() {
|
|
var requestedHostId = this.get('instance.requestedHostId');
|
|
var all = this.get('containerChoices');
|
|
var isManagedNetwork = this.get('isManagedNetwork');
|
|
|
|
if ( requestedHostId && !isManagedNetwork )
|
|
{
|
|
return all.filterBy('hostId', requestedHostId);
|
|
}
|
|
else
|
|
{
|
|
return all;
|
|
}
|
|
}.property('containerChoices.@each.hostId','instance.requestedHostId','isManagedNetwork'),
|
|
|
|
linksArray: null,
|
|
initLinks: function() {
|
|
var out = [];
|
|
var links = this.get('instanceLinks')||[];
|
|
|
|
if ( Ember.isArray(links) )
|
|
{
|
|
links.forEach(function(value) {
|
|
// Objects, from edit
|
|
if ( typeof value === 'object' )
|
|
{
|
|
out.push({
|
|
existing: (value.id ? true : false),
|
|
obj: value,
|
|
name: value.linkName || value.name,
|
|
targetInstanceId: value.targetInstanceId,
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// Strings, from create maybe
|
|
var match = value.match(/^([^:]+):(.*)$/);
|
|
if ( match )
|
|
{
|
|
out.push({name: match[1], targetInstanceId: match[2], existing: false});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
this.set('linksArray', out);
|
|
},
|
|
|
|
// ----------------------------------
|
|
// Environment Vars
|
|
// ----------------------------------
|
|
environmentArray: null,
|
|
initEnvironment: function() {
|
|
var obj = this.get('instance.environment')||{};
|
|
var keys = Object.keys(obj);
|
|
var out = [];
|
|
keys.forEach(function(key) {
|
|
out.push({ key: key, value: obj[key] });
|
|
});
|
|
|
|
this.set('environmentArray', out);
|
|
},
|
|
|
|
environmentChanged: function() {
|
|
// Sync with the actual environment object
|
|
var out = {};
|
|
this.get('environmentArray').forEach(function(row) {
|
|
if ( row.key )
|
|
{
|
|
out[row.key] = row.value;
|
|
}
|
|
});
|
|
this.set('instance.environment', out);
|
|
}.observes('environmentArray.@each.{key,value}'),
|
|
|
|
// ----------------------------------
|
|
// Ports
|
|
// ----------------------------------
|
|
portsAsStrArray: null,
|
|
portsArrayDidChange: function() {
|
|
var out = [];
|
|
this.get('portsArray').forEach(function(row) {
|
|
if ( row.private && row.protocol )
|
|
{
|
|
var str = row.private+'/'+row.protocol;
|
|
if ( row.public )
|
|
{
|
|
str = row.public + ':' + str;
|
|
}
|
|
|
|
out.push(str);
|
|
}
|
|
});
|
|
|
|
this.set('portsAsStrArray', out);
|
|
}.observes('portsArray.@each.{public,private,protocol}'),
|
|
|
|
protocolOptions: [
|
|
{label: 'TCP', value: 'tcp'},
|
|
{label: 'UDP', value: 'udp'}
|
|
],
|
|
|
|
portsArray: null,
|
|
initPorts: function() {
|
|
var out = [];
|
|
|
|
var ports = this.get('ports');
|
|
if ( ports )
|
|
{
|
|
// Objects, from edit
|
|
ports.forEach(function(value) {
|
|
out.push({
|
|
existing: (value.id ? true : false),
|
|
obj: value,
|
|
public: value.publicPort,
|
|
private: value.privatePort,
|
|
protocol: value.protocol,
|
|
});
|
|
});
|
|
}
|
|
else
|
|
{
|
|
ports = this.get('instance.ports')||[];
|
|
ports.forEach(function(value) {
|
|
if ( typeof value === 'object' )
|
|
{
|
|
// Objects, from clone
|
|
out.push({
|
|
existing: false,
|
|
public: value.publicPort,
|
|
private: value.privatePort,
|
|
protocol: value.protocol,
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// Strings, from create maybe
|
|
var match = value.match(/^(\d+):(\d+)\/(.*)$/);
|
|
if ( match )
|
|
{
|
|
out.push({
|
|
existing: false,
|
|
public: match[1],
|
|
private: match[2],
|
|
protocol: match[3],
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
this.set('portsArray', out);
|
|
},
|
|
|
|
// ----------------------------------
|
|
// Volumes
|
|
// ----------------------------------
|
|
volumesArray: null,
|
|
initVolumes: function() {
|
|
var ary = this.get('instance.dataVolumes');
|
|
if ( !ary )
|
|
{
|
|
ary = [];
|
|
this.set('instance.dataVolumes',ary);
|
|
}
|
|
|
|
this.set('volumesArray', ary.map(function(vol) {
|
|
return {value: vol};
|
|
}));
|
|
},
|
|
|
|
volumesDidChange: function() {
|
|
var out = this.get('instance.dataVolumes');
|
|
out.beginPropertyChanges();
|
|
out.clear();
|
|
this.get('volumesArray').forEach(function(row) {
|
|
if ( row.value )
|
|
{
|
|
out.push(row.value);
|
|
}
|
|
});
|
|
out.endPropertyChanges();
|
|
}.observes('volumesArray.@each.value'),
|
|
|
|
// ----------------------------------
|
|
// Volumes From
|
|
// ----------------------------------
|
|
hostContainerChoices: function() {
|
|
var list = [];
|
|
|
|
this.get('allHosts').filter((host) => {
|
|
return host.get('id') === this.get('instance.requestedHostId');
|
|
}).map((host) => {
|
|
var containers = (host.get('instances')||[]).filter(function(instance) {
|
|
// You can't mount volumes from other types of instances
|
|
return instance.get('type') === 'container';
|
|
});
|
|
|
|
list.pushObjects(containers.map(function(container) {
|
|
return {
|
|
group: 'Host: ' + (host.get('name') || '('+host.get('id')+')'),
|
|
id: container.get('id'),
|
|
name: container.get('name')
|
|
};
|
|
}));
|
|
});
|
|
|
|
return list.sortBy('group','name','id');
|
|
}.property('instance.requestedHostId','allHosts.@each.instancesUpdated'),
|
|
|
|
volumesFromArray: null,
|
|
initVolumesFrom: function() {
|
|
var ary = this.get('instance.dataVolumesFrom');
|
|
if ( !ary )
|
|
{
|
|
ary = [];
|
|
this.set('instance.dataVolumesFrom',ary);
|
|
}
|
|
|
|
this.set('volumesFromArray', ary.map(function(vol) {
|
|
return {value: vol};
|
|
}));
|
|
},
|
|
|
|
volumesFromDidChange: function() {
|
|
var out = this.get('instance.dataVolumesFrom');
|
|
out.beginPropertyChanges();
|
|
out.clear();
|
|
this.get('volumesFromArray').forEach(function(row) {
|
|
if ( row.value )
|
|
{
|
|
out.push(row.value);
|
|
}
|
|
});
|
|
out.endPropertyChanges();
|
|
}.observes('volumesFromArray.@each.value'),
|
|
|
|
// ----------------------------------
|
|
// DNS
|
|
// ----------------------------------
|
|
dnsArray: null,
|
|
initDns: function() {
|
|
var ary = this.get('instance.dns');
|
|
if ( !ary )
|
|
{
|
|
ary = [];
|
|
this.set('instance.dns',ary);
|
|
}
|
|
|
|
this.set('dnsArray', ary.map(function(entry) {
|
|
return {value: entry};
|
|
}));
|
|
},
|
|
|
|
dnsDidChange: function() {
|
|
var out = this.get('instance.dns');
|
|
out.beginPropertyChanges();
|
|
out.clear();
|
|
this.get('dnsArray').forEach(function(row) {
|
|
if ( row.value )
|
|
{
|
|
out.push(row.value);
|
|
}
|
|
});
|
|
out.endPropertyChanges();
|
|
}.observes('dnsArray.@each.value'),
|
|
|
|
// ----------------------------------
|
|
// DNS Search
|
|
// ----------------------------------
|
|
dnsSearchArray: null,
|
|
initDnsSearch: function() {
|
|
var ary = this.get('instance.dnsSearch');
|
|
if ( !ary )
|
|
{
|
|
ary = [];
|
|
this.set('instance.dnsSearch',ary);
|
|
}
|
|
|
|
this.set('dnsSearchArray', ary.map(function(entry) {
|
|
return {value: entry};
|
|
}));
|
|
},
|
|
dnsSearchDidChange: function() {
|
|
var out = this.get('instance.dnsSearch');
|
|
out.beginPropertyChanges();
|
|
out.clear();
|
|
this.get('dnsSearchArray').forEach(function(row) {
|
|
if ( row.value )
|
|
{
|
|
out.push(row.value);
|
|
}
|
|
});
|
|
out.endPropertyChanges();
|
|
}.observes('dnsSearchArray.@each.value'),
|
|
|
|
// ----------------------------------
|
|
// Capability
|
|
// ----------------------------------
|
|
capabilityChoices: null,
|
|
initCapability: function() {
|
|
this.set('instance.capAdd', this.get('instance.capAdd') || []);
|
|
this.set('instance.capDrop', this.get('instance.capDrop') || []);
|
|
var choices = this.get('store').getById('schema','container').get('resourceFields.capAdd').options.sort();
|
|
this.set('capabilityChoices',choices);
|
|
},
|
|
|
|
// ----------------------------------
|
|
// Memory
|
|
// ----------------------------------
|
|
memoryMb: null,
|
|
swapMb: null,
|
|
initMemory: function() {
|
|
var memBytes = this.get('instance.memory') || 0;
|
|
var memPlusSwapBytes = this.get('instance.memorySwap') || 0;
|
|
var swapBytes = Math.max(0, memPlusSwapBytes - memBytes);
|
|
|
|
if ( memBytes )
|
|
{
|
|
this.set('memoryMb', parseInt(memBytes,10)/1048576);
|
|
}
|
|
else
|
|
{
|
|
this.set('memoryMb','');
|
|
}
|
|
|
|
if ( swapBytes )
|
|
{
|
|
this.set('swapMb', parseInt(swapBytes,10)/1048576);
|
|
}
|
|
else
|
|
{
|
|
this.set('swapMb','');
|
|
}
|
|
|
|
},
|
|
|
|
memoryDidChange: function() {
|
|
// The actual parameter we're interested in is 'memory', in bytes.
|
|
var mem = parseInt(this.get('memoryMb'),10);
|
|
if ( isNaN(mem) || mem <= 0)
|
|
{
|
|
this.setProperties({
|
|
'memoryMb': '',
|
|
'swapMb': '',
|
|
'instance.memory': null,
|
|
'instance.memorySwap': null,
|
|
});
|
|
}
|
|
else
|
|
{
|
|
this.set('instance.memory', mem * 1048576);
|
|
|
|
var swap = parseInt(this.get('swapMb'),10);
|
|
if ( isNaN(swap) || swap <= 0)
|
|
{
|
|
this.setProperties({
|
|
'swapMb': '',
|
|
'instance.memorySwap': null
|
|
});
|
|
}
|
|
else
|
|
{
|
|
this.set('instance.memorySwap', (mem+swap) * 1048576);
|
|
}
|
|
}
|
|
}.observes('memoryMb','swapMb'),
|
|
|
|
// ----------------------------------
|
|
// PID Mode
|
|
// ----------------------------------
|
|
pidHost: null,
|
|
initPidMode: function() {
|
|
this.set('pidHost', this.get('instance.pidMode') === 'host');
|
|
},
|
|
pidModeDidChange: function() {
|
|
this.set('instance.pidMode', this.get('pidHost') ? 'host' : null);
|
|
}.observes('pidHost'),
|
|
|
|
// ----------------------------------
|
|
// Hosts
|
|
// ----------------------------------
|
|
hostChoices: function() {
|
|
var list = this.get('allHosts').map((host) => {
|
|
var hostLabel = (host.get('name') || '('+host.get('id')+')');
|
|
if ( host.get('state') !== 'active' )
|
|
{
|
|
hostLabel += ' (' + host.get('state') + ')';
|
|
}
|
|
|
|
return {
|
|
id: host.get('id'),
|
|
name: hostLabel,
|
|
};
|
|
});
|
|
|
|
return list.sortBy('name','id');
|
|
}.property('allHosts.@each.{id,name,state}'),
|
|
|
|
// ----------------------------------
|
|
// Terminal
|
|
// ----------------------------------
|
|
terminal: null, //'both',
|
|
initTerminal: function() {
|
|
var instance = this.get('instance');
|
|
var tty = instance.get('tty');
|
|
var stdin = instance.get('stdinOpen');
|
|
var out = 'both';
|
|
|
|
if ( tty !== undefined || stdin !== undefined )
|
|
{
|
|
if ( tty && stdin )
|
|
{
|
|
out = 'both';
|
|
}
|
|
else if ( tty )
|
|
{
|
|
out = 'terminal';
|
|
}
|
|
else if ( stdin )
|
|
{
|
|
out = 'interactive';
|
|
}
|
|
else
|
|
{
|
|
out = 'none';
|
|
}
|
|
}
|
|
|
|
this.set('terminal', out);
|
|
this.terminalDidChange();
|
|
},
|
|
terminalDidChange: function() {
|
|
var val = this.get('terminal');
|
|
var stdinOpen = ( val === 'interactive' || val === 'both' );
|
|
var tty = (val === 'terminal' || val === 'both');
|
|
this.set('instance.tty', tty);
|
|
this.set('instance.stdinOpen', stdinOpen);
|
|
}.observes('terminal'),
|
|
|
|
// ----------------------------------
|
|
// Devices
|
|
// ----------------------------------
|
|
devicesArray: null,
|
|
initDevices: function() {
|
|
var ary = this.get('instance.devices');
|
|
if ( !ary )
|
|
{
|
|
ary = [];
|
|
this.set('instance.devices',ary);
|
|
}
|
|
|
|
this.set('devicesArray', ary.map(function(dev) {
|
|
var parts = dev.split(':');
|
|
return {host: parts[0], container: parts[1], permissions: parts[2]};
|
|
}));
|
|
},
|
|
devicesDidChange: function() {
|
|
var out = this.get('instance.devices');
|
|
out.beginPropertyChanges();
|
|
out.clear();
|
|
this.get('devicesArray').forEach(function(row) {
|
|
if ( row.host )
|
|
{
|
|
out.push(row.host+":"+row.container+":"+row.permissions);
|
|
}
|
|
});
|
|
out.endPropertyChanges();
|
|
}.observes('devicesArray.@each.{host,container,permissions}'),
|
|
|
|
// ----------------------------------
|
|
// Command
|
|
// ----------------------------------
|
|
strCommand: '',
|
|
initCommand: function() {
|
|
var ary = this.get('instance.command');
|
|
if ( ary )
|
|
{
|
|
this.set('strCommand', ShellQuote.quote(ary));
|
|
}
|
|
else
|
|
{
|
|
this.set('strCommand','');
|
|
}
|
|
},
|
|
strCommandDidChange: function() {
|
|
var str = this.get('strCommand').trim()||'';
|
|
// @TODO remove after v0.18
|
|
if ( this.get('store').getById('schema','container').get('resourceFields.command.type') === 'string' )
|
|
{
|
|
this.set('instance.command', str);
|
|
}
|
|
else
|
|
{
|
|
var out = ShellQuote.parse(str).map(function(piece) {
|
|
if ( typeof piece === 'object' && piece && piece.op )
|
|
{
|
|
return piece.op;
|
|
}
|
|
else
|
|
{
|
|
return piece;
|
|
}
|
|
});
|
|
if ( out.length )
|
|
{
|
|
this.set('instance.command', out);
|
|
}
|
|
else
|
|
{
|
|
this.set('instance.command', null);
|
|
}
|
|
}
|
|
}.observes('strCommand'),
|
|
|
|
// ----------------------------------
|
|
// Entry Point
|
|
// ----------------------------------
|
|
strEntryPoint: '',
|
|
initEntryPoint: function() {
|
|
var ary = this.get('instance.entryPoint');
|
|
if ( ary )
|
|
{
|
|
this.set('strEntryPoint', ShellQuote.quote(ary));
|
|
}
|
|
else
|
|
{
|
|
this.set('strEntryPoint','');
|
|
}
|
|
},
|
|
strEntryPointDidChange: function() {
|
|
var out = ShellQuote.parse(this.get('strEntryPoint').trim()||'');
|
|
if ( out.length )
|
|
{
|
|
this.set('instance.entryPoint', out);
|
|
}
|
|
else
|
|
{
|
|
this.set('instance.entryPoint', null);
|
|
}
|
|
}.observes('strEntryPoint'),
|
|
|
|
// ----------------------------------
|
|
// Scheduling
|
|
// ----------------------------------
|
|
initScheduling: function() {
|
|
if ( this.get('instance.requestedHostId') )
|
|
{
|
|
this.set('isRequestedHost',true);
|
|
}
|
|
else
|
|
{
|
|
this.set('isRequestedHost',false);
|
|
}
|
|
|
|
this._super();
|
|
},
|
|
|
|
isRequestedHostDidChange: function() {
|
|
if ( this.get('isRequestedHost') )
|
|
{
|
|
if ( !this.get('instance.requestedHostId') )
|
|
{
|
|
this.set('instance.requestedHostId', this.get('hostChoices.firstObject.id'));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.set('instance.requestedHostId', null);
|
|
}
|
|
}.observes('isRequestedHost'),
|
|
|
|
// ----------------------------------
|
|
// Save
|
|
// ----------------------------------
|
|
willSave: function() {
|
|
var errors = [];
|
|
if ( !this.get('editing') )
|
|
{
|
|
// 'ports' and 'instanceLinks' need to be strings for create
|
|
this.set('instance.ports', this.get('portsAsStrArray'));
|
|
|
|
var linksAsMap = {};
|
|
this.get('linksArray').forEach((row) => {
|
|
if ( row.targetInstanceId )
|
|
{
|
|
var name = row.name;
|
|
// Lookup the container name if an "as name" wasn't given
|
|
if ( !name )
|
|
{
|
|
var container = this.get('store').getById('container', row.targetInstanceId);
|
|
if ( container )
|
|
{
|
|
name = container.name;
|
|
}
|
|
}
|
|
|
|
if ( name )
|
|
{
|
|
linksAsMap[ name ] = row.targetInstanceId;
|
|
}
|
|
else
|
|
{
|
|
errors.push('Link to container ' + row.targetInstanceId + ' must have an "as name".');
|
|
}
|
|
}
|
|
});
|
|
|
|
if ( errors.length )
|
|
{
|
|
this.set('errors', errors);
|
|
return false;
|
|
}
|
|
|
|
this.set('instance.instanceLinks', linksAsMap);
|
|
|
|
var healthCheck = this.get('healthCheck');
|
|
if ( healthCheck.get('port') )
|
|
{
|
|
this.set('instance.healthCheck', healthCheck);
|
|
}
|
|
else
|
|
{
|
|
this.set('instance.healthCheck', null);
|
|
}
|
|
}
|
|
|
|
return this._super();
|
|
},
|
|
});
|