Longhorn support

This commit is contained in:
Vincent Fiduccia 2016-01-15 10:15:25 -07:00
parent 768b50a19e
commit 98e86ae1c3
23 changed files with 250 additions and 120 deletions

View File

@ -16,7 +16,7 @@ export default Ember.Controller.extend({
(this.get('model.stacks')||[]).forEach((stack) => {
var info = stack.get('externalIdInfo');
if ( info.kind === C.EXTERNALID.KIND_SYSTEM )
if ( C.EXTERNALID.SYSTEM_KINDS.indexOf(info.kind) >= 0 )
{
hasSystem = true;
}
@ -26,7 +26,6 @@ export default Ember.Controller.extend({
}
});
console.log('k8s:', hasKubernetes, 'sys:', hasSystem);
this.setProperties({
hasKubernetes: hasKubernetes,
hasSystem: hasSystem

View File

@ -2,17 +2,83 @@ import Ember from 'ember';
export default Ember.Component.extend({
instance: null,
availableDrivers: null,
errors: null,
disksArray: Ember.computed.alias('instance.disks'),
didInitAttrs() {
this.set('instance.disks', (this.get('instance.disks')||[]).slice());
var defaultDriver = this.get('availableDrivers').objectAt(0);
var disks = (this.get('instance.disks')||[]).slice();
disks.forEach((disk) => {
if ( !Ember.get(disk, 'driver') )
{
Ember.set(disk, 'driver', defaultDriver);
}
});
this.set('instance.disks', disks);
},
driverChoices: function() {
return this.get('availableDrivers').map((name) => {
return {label: name, value: name};
});
}.property('availableDrivers.[]'),
disksChanged: function() {
var errors = [];
this.get('instance.disks').forEach((disk) => {
var name = (Ember.get(disk,'name')||'').trim().toLowerCase();
Ember.set(disk, 'name', name);
if ( name.match(/([^a-z0-9._-])/) )
{
errors.push(`Disk name "${name}" contains invalid character(s). Names can only contain a-z, 0-9, dot, dash, and underscore.`);
}
else if ( !name )
{
errors.push('A name is required for each disk.');
}
});
if ( errors.length )
{
this.set('errors', errors);
}
else
{
this.set('errors', null);
}
}.observes('instance.disks.@each.name'),
hasRoot: function() {
return this.get('instance.disks').filterBy('root',true).length > 0;
}.property('instance.disks.@each.root'),
actions: {
addRootDisk() {
this.get('instance.disks').unshiftObject({
name: 'root',
root: true,
size: 80,
driver: this.get('availableDrivers').objectAt(0)
});
},
addDisk() {
this.get('instance.disks').pushObject({name: '', size: '', driver: 'convoy-gluster'});
this.get('instance.disks').pushObject({
name: '',
root: false,
size: 40,
driver: this.get('availableDrivers').objectAt(0)
});
},
setDiskSize(disk,size) {
Ember.set(disk, 'size', size+'g');
},
removeDisk(obj) {

View File

@ -1,33 +1,45 @@
<div class="form-control-static">
<button class="btn-circle-text" {{action "addDisk"}}><i class="icon icon-plus-circle"/> <span>Add Disk</span></button>
<button class="btn-circle-text r-ml20" {{action "addRootDisk"}} disabled={{hasRoot}}><i class="icon icon-plus-circle"/> <span>Add Root Disk</span></button>
</div>
{{#if disksArray.length}}
<table class="table fixed no-lines no-top-padding tight small">
<table class="table fixed no-lines no-top-padding tight">
<tr class="text-muted">
<th>Name*</th>
<th width="30">&nbsp;</th>
<th>Size*</th>
<th>Size</th>
<th width="30">&nbsp;</th>
<th>Driver*</th>
<th width="30"></th>
<th width="130">Driver</th>
<th width="50"></th>
</tr>
{{#each disksArray as |disk|}}
<tr>
<td>
{{input class="form-control input-sm" type="text" value=disk.name placeholder="e.g. data"}}
{{#if disk.root}}
Root Disk
{{else}}
{{input class="form-control input-sm" type="text" value=disk.name placeholder="e.g. data"}}
{{/if}}
</td>
<td>&nbsp;</td>
<td>
{{input class="form-control input-sm" type="text" value=disk.size placeholder="e.g. 20G"}}
<div class="row">
<div class="col-xs-8 col-sm-9">{{input-slider initialValue=disk.size changed=(action "setDiskSize" disk) valueMin=10 valueMax=500 scaleMin=0 step=10}}</div>
<div class="col-xs-4 col-sm-3">{{str-replace disk.size match="g" with=" GB"}}</div>
</div>
</td>
<td>&nbsp;</td>
<td>
{{input class="form-control input-sm" type="text" value=disk.driver placeholder="e.g. convoy-gluster"}}
{{new-select
classNames="form-control"
content=driverChoices
value=disk.driver
}}
</td>
<td class="text-right">

View File

@ -3,7 +3,7 @@ import C from 'ui/utils/constants';
import ManageLabels from 'ui/mixins/manage-labels';
import { debouncedObserver } from 'ui/utils/debounce';
// Subtract 1 (because 11...), round to the nearest 10, then double it
// Subtract 1 (because 11...), round up to the nearest 10, then double it
function roundScale(num) {
return Math.ceil((num-1)/10)*10*2;
}

View File

@ -29,7 +29,8 @@ export default Ember.Component.extend({
classNameBindings: ['disabled','active'],
disabled: false,
value: null, // Bind something to this to get the value
initialValue: null,
value: null, // Bind something to this to get the value, or use the action to get it
valueMin: 0, // The smallest and biggest value is allowed to be
valueMax: 100,
scaleMin: null, // The smallest and biggest values shown on the display. If these are not equal to valueMin/max then there will be
@ -40,6 +41,15 @@ export default Ember.Component.extend({
dragFn: null,
upFn: null,
didInitAttrs() {
console.log('didInit');
var initial = this.get('initialValue');
if ( initial !== null )
{
this.set('value', initial);
}
},
didInsertElement: function() {
this._super();
this.valueChanged();
@ -128,13 +138,11 @@ export default Ember.Component.extend({
}
var value = this.pointToValue(clientX(event));
console.log('set 1', value);
this.set('value', value);
this.$('.slider-handle').focus();
},
mouseDown: function(event) {
console.log('drag start');
if ( this.get('disabled') )
{
return false;
@ -157,7 +165,6 @@ export default Ember.Component.extend({
},
drag: function(event) {
console.log('drag');
event.preventDefault();
if ( this.get('disabled') )
{
@ -165,14 +172,12 @@ export default Ember.Component.extend({
}
var value = this.pointToValue(clientX(event));
console.log('drag', clientX(event), '=', value);
this.set('value', value);
},
mouseUp: function(/*event*/) {
$('BODY').off('mousemove', this.get('dragFn'));
$('BODY').off('mouseup', this.get('upFn'));
console.log('drag end');
this.set('active',false);
},
@ -207,9 +212,15 @@ export default Ember.Component.extend({
valueChanged: function() {
var orig = this.get('value');
var value = Math.max(this.get('valueMin'), Math.min(orig, this.get('valueMax')));
if ( orig !== value )
if ( isNaN(value) )
{
value = this.get('valueMin');
}
this.sendAction('changed',value);
if ( value && orig !== value )
{
console.log('valuechanged', value);
this.set('value', value);
return;
}

View File

@ -42,7 +42,7 @@ export default Ember.Component.extend(NewOrEdit, {
},
didReceiveAttrs() {
this._super.apply(this, arguments);
this._super();
this.set('editing', !!this.get('primaryResource.id'));
@ -54,8 +54,6 @@ export default Ember.Component.extend(NewOrEdit, {
} else {
this.set('selectedTemplateUrl', null);
}
this.templateChanged();
},
getReadme: function() {
@ -114,7 +112,7 @@ export default Ember.Component.extend(NewOrEdit, {
} else {
this.set('selectedTemplateModel', null);
}
},
}.observes('selectedTemplateUrl').on('init'),
answers: function() {
var out = {};
@ -161,6 +159,14 @@ export default Ember.Component.extend(NewOrEdit, {
return true;
},
newExternalId: function() {
var systemCategories = C.EXTERNALID.SYSTEM_CATEGORIES.map((str) => { return str.trim().toLowerCase(); });
var category = (this.get('templateResource.category')||'').trim().toLowerCase();
var externalId = ( systemCategories.indexOf(category) >= 0 ? C.EXTERNALID.KIND_SYSTEM_CATALOG : C.EXTERNALID.KIND_CATALOG );
externalId += C.EXTERNALID.KIND_SEPARATOR + this.get('selectedTemplateModel.uuid');
return externalId;
}.property('templateResource.category','selectedTemplateModel.uuid'),
willSave() {
this.set('errors', null);
var ok = this.validate();
@ -169,16 +175,11 @@ export default Ember.Component.extend(NewOrEdit, {
return false;
}
var systemCategories = C.EXTERNALID.SYSTEM_CATEGORIES.map((str) => { return str.trim().toLowerCase(); });
var category = (this.get('templateResource.category')||'').trim().toLowerCase();
var externalId = ( systemCategories.indexOf(category) >= 0 ? C.EXTERNALID.KIND_SYSTEM : C.EXTERNALID.KIND_CATALOG );
externalId += C.EXTERNALID.KIND_SEPARATOR + this.get('selectedTemplateModel.uuid');
this.get('environmentResource').setProperties({
dockerCompose: this.get('selectedTemplateModel.dockerCompose'),
rancherCompose: this.get('selectedTemplateModel.rancherCompose'),
environment: this.get('answers'),
externalId: externalId
externalId: this.get('newExternalId'),
});
return true;
@ -190,7 +191,7 @@ export default Ember.Component.extend(NewOrEdit, {
dockerCompose: this.get('environmentResource.dockerCompose'),
rancherCompose: this.get('environmentResource.rancherCompose'),
environment: this.get('environmentResource.environment'),
externalId: C.EXTERNALID.KIND_CATALOG + C.EXTERNALID.KIND_SEPARATOR + this.get('selectedTemplateModel.uuid')
externalId: this.get('newExternalId'),
});
} else {
return this._super.apply(this, arguments);

View File

@ -16,6 +16,7 @@ export default Ember.Component.extend(NewOrEdit, SelectTab, {
service: null,
allHosts: null,
allServices: null,
allStoragePools: null,
serviceLinksArray: null,
isGlobal: null,
@ -34,6 +35,7 @@ export default Ember.Component.extend(NewOrEdit, SelectTab, {
scaleErrors: null,
imageErrors: null,
portErrors: null,
diskErrors: null,
actions: {
selectLaunchConfig(index) {
@ -254,6 +256,17 @@ export default Ember.Component.extend(NewOrEdit, SelectTab, {
}
),
// ----------------------------------
// Disks
// ----------------------------------
storageDriverChoices: function() {
return (this.get('allStoragePools')||[])
.map((pool) => { return pool.get('driverName'); })
.filter((name) => { return C.VM_CAPABLE_STORAGE_DRIVERS.indexOf(name) >= 0; })
.uniq()
.sort();
}.property('allStoragePools.@each.driverName'),
// ----------------------------------
// Save
// ----------------------------------
@ -271,6 +284,7 @@ export default Ember.Component.extend(NewOrEdit, SelectTab, {
errors.pushObjects(this.get('scaleErrors')||[]);
errors.pushObjects(this.get('imageErrors')||[]);
errors.pushObjects(this.get('portErrors')||[]);
errors.pushObjects(this.get('diskErrors')||[]);
if ( errors.length )
{

View File

@ -7,7 +7,6 @@
{{if isVm 'Virtual Machine' 'Container'}}
{{/if}}
</h1>
{{top-errors errors=errors}}
</section>
<section class="horizontal-form container-fluid">
@ -119,7 +118,7 @@
<div class="horizontal-form well">
{{#if isVm}}
<div class="section container-fluid" data-section="disks">
{{form-disks instance=launchConfig}}
{{form-disks instance=launchConfig availableDrivers=storageDriverChoices errors=diskErrors}}
</div>
<div class="section container-fluid" data-section="userdata">
@ -217,6 +216,7 @@
{{#unless isSidekick}}
{{top-errors errors=errors}}
{{#save-cancel saveDisabled=noLaunchConfigsEnabled createLabel=(if isUpgrade 'Upgrade' 'Create') save="save" cancel="cancel"}}
{{#if (and (not isUpgrade) (not-eq launchConfigIndex -1))}}
<button class="btn btn-default" {{action "removeSidekick"}}>Remove this Sidekick</button>

View File

@ -6,6 +6,11 @@ export default Ember.Component.extend(Sortable, FilterState, {
model: null,
single: false,
init: function() {
this._super();
this.set('filterStates', ['purged']);
},
filterableContent: Ember.computed.alias('model.volumes'),
sortableContent: Ember.computed.alias('filtered'),

View File

@ -30,8 +30,8 @@
<div class="header-right right-divider stack-actions" style="width: auto">
{{#unless single}}
{{#action-menu model=model classNames='btn-group-sm'}}
{{#link-to "storagepools.new-volume" (query-params driverName=model.driverName) classNames="btn btn-default"}}Add Volume{{/link-to}}
{{#action-menu model=model size='sm'}}
{{#link-to "storagepools.new-volume" (query-params driverName=model.driverName) classNames="btn btn-primary btn-sm"}}Add Volume{{/link-to}}
{{/action-menu}}
{{/unless}}
</div>
@ -54,7 +54,7 @@
<tr>
{{sortable-th sortable=this action="changeSort" name="state" width="125"}}
{{sortable-th sortable=this action="changeSort" name="name"}}
{{sortable-th sortable=this action="changeSort" name="activeMounts" label="Mounts (Container:Path)"}}
{{sortable-th sortable=this action="changeSort" name="activeMounts" label="Mounts (Container: Path)"}}
<th width="70">&nbsp;</th>
</tr>
</thead>
@ -71,7 +71,12 @@
{{#if vol.activeMounts.length}}
{{#each vol.activeMounts as |mount|}}
<div>
{{#link-to "container" mount.instanceId}}{{mount.instance.name}}{{/link-to}}:{{mount.path}}
{{~#if mount.instance.isVm~}}
{{#link-to "virtualmachine" mount.instanceId}}{{mount.instance.displayName}}{{/link-to}}
{{~else~}}
{{#link-to "container" mount.instanceId}}{{mount.instance.displayName}}{{/link-to}}
{{~/if~}}
: {{mount.path}}
{{#if (eq mount.permissions "ro")}}
<span class="text-muted">(read-only)</span>
{{/if}}

View File

@ -4,22 +4,21 @@ export default Ember.Route.extend({
model: function(params/*, transition*/) {
var store = this.get('store');
var dependencies = [
store.findAll('host'), // Need inactive ones in case a link points to an inactive host
];
var dependencies = {
allHosts: store.findAll('host'), // Need inactive ones in case a link points to an inactive host
};
if ( params.containerId )
{
dependencies.pushObject(store.find('container', params.containerId, {include: ['ports','instanceLinks']}));
dependencies.existing = store.find('container', params.containerId, {include: ['ports','instanceLinks']});
}
return Ember.RSVP.all(dependencies, 'Load container dependencies').then(function(results) {
var allHosts = results[0];
return Ember.RSVP.hash(dependencies, 'Load container dependencies').then(function(results) {
var data, healthCheckData;
if ( params.containerId )
if ( results.existing )
{
data = results[1].serializeForNew();
data = results.existing.serializeForNew();
data.ports = (data.ports||[]).map((port) => {
delete port.id;
return port;
@ -56,7 +55,7 @@ export default Ember.Route.extend({
return Ember.Object.create({
instance: instance,
allHosts: allHosts,
allHosts: results.allHosts,
});
});
},

View File

@ -2,6 +2,7 @@
isStandalone=true
isService=false
isSidekick=false
editing=false
launchConfig=model.instance
primaryResource=model.instance
allHosts=model.allHosts

View File

@ -2,8 +2,6 @@ import Ember from 'ember';
import Sortable from 'ui/mixins/sortable';
import C from 'ui/utils/constants';
const notUser = [C.EXTERNALID.KIND_KUBERNETES, C.EXTERNALID.KIND_SYSTEM];
export default Ember.Controller.extend(Sortable, {
environments: Ember.inject.controller(),
projects: Ember.inject.service(),
@ -40,32 +38,27 @@ export default Ember.Controller.extend(Sortable, {
filteredStacks: function() {
var which = this.get('which');
var all = this.get('model');
var out;
var kubernetes = all.filterBy('externalIdInfo.kind', C.EXTERNALID.KIND_KUBERNETES);
var system = all.filterBy('externalIdInfo.kind', C.EXTERNALID.KIND_SYSTEM);
var user = all.filter((obj) => {
return notUser.indexOf(obj.get('externalIdInfo.kind')) === -1;
});
if ( which === C.EXTERNALID.KIND_ALL )
{
out = all;
return all;
}
else if ( which === C.EXTERNALID.KIND_KUBERNETES )
{
out = kubernetes;
return all.filterBy('externalIdInfo.kind', C.EXTERNALID.KIND_KUBERNETES);
}
else if ( which === C.EXTERNALID.KIND_SYSTEM )
{
out = system;
return all.filter((obj) => {
return C.EXTERNALID.SYSTEM_KINDS.indexOf(obj.get('externalIdInfo.kind')) >= 0;
});
}
else
{
out = user;
return all.filter((obj) => {
return C.EXTERNALID.NOT_USER_KINDS.indexOf(obj.get('externalIdInfo.kind')) === -1;
});
}
return out;
}.property('model.[]','which'),

View File

@ -11,6 +11,7 @@ export default Ember.Route.extend({
if (isExisting)
{
controller.set('showAddtlInfo', false);
controller.set('which', 'user');
}
},
});

View File

@ -0,0 +1,7 @@
import Ember from 'ember';
export function strReplace(params, options) {
return (params[0]+'').replace(options.match, options.with);
}
export default Ember.Helper.helper(strReplace);

View File

@ -5,31 +5,32 @@ import { normalizeType } from 'ember-api-store/utils/normalize';
import C from 'ui/utils/constants';
const defaultStateMap = {
'activating': {icon: 'icon icon-tag', color: 'text-info' },
'active': {icon: 'icon icon-circle-o', color: 'text-success'},
'created': {icon: 'icon icon-tag', color: 'text-info' },
'creating': {icon: 'icon icon-tag', color: 'text-info' },
'deactivating': {icon: 'icon icon-adjust', color: 'text-info' },
'degraded': {icon: 'icon icon-alert', color: 'text-warning'},
'error': {icon: 'icon icon-alert', color: 'text-danger' },
'inactive': {icon: 'icon icon-circle', color: 'text-danger' },
'initializing': {icon: 'icon icon-alert', color: 'text-warning'},
'purged': {icon: 'icon icon-purged', color: 'text-danger' },
'purging': {icon: 'icon icon-purged', color: 'text-info' },
'removed': {icon: 'icon icon-trash', color: 'text-danger' },
'removing': {icon: 'icon icon-trash', color: 'text-info' },
'requested': {icon: 'icon icon-tag', color: 'text-info' },
'registering': {icon: 'icon icon-tag', color: 'text-info' },
'restoring': {icon: 'icon icon-medicalcross', color: 'text-info' },
'running': {icon: 'icon icon-circle-o', color: 'text-success'},
'started-once': {icon: 'icon icon-dot-circlefill',color: 'text-success'},
'starting': {icon: 'icon icon-adjust', color: 'text-info' },
'stopped': {icon: 'icon icon-circle', color: 'text-danger' },
'stopping': {icon: 'icon icon-adjust', color: 'text-info' },
'unhealthy': {icon: 'icon icon-alert', color: 'text-danger' },
'updating': {icon: 'icon icon-tag', color: 'text-info' },
'updating-active': {icon: 'icon icon-tag', color: 'text-info' },
'updating-inactive':{icon: 'icon icon-tag', color: 'text-info' },
'activating': {icon: 'icon icon-tag', color: 'text-info' },
'active': {icon: 'icon icon-circle-o', color: 'text-success'},
'created': {icon: 'icon icon-tag', color: 'text-info' },
'creating': {icon: 'icon icon-tag', color: 'text-info' },
'deactivating': {icon: 'icon icon-adjust', color: 'text-info' },
'degraded': {icon: 'icon icon-alert', color: 'text-warning'},
'error': {icon: 'icon icon-alert', color: 'text-danger' },
'inactive': {icon: 'icon icon-circle', color: 'text-danger' },
'initializing': {icon: 'icon icon-alert', color: 'text-warning'},
'purged': {icon: 'icon icon-purged', color: 'text-danger' },
'purging': {icon: 'icon icon-purged', color: 'text-info' },
'removed': {icon: 'icon icon-trash', color: 'text-danger' },
'removing': {icon: 'icon icon-trash', color: 'text-info' },
'requested': {icon: 'icon icon-tag', color: 'text-info' },
'registering': {icon: 'icon icon-tag', color: 'text-info' },
'restoring': {icon: 'icon icon-medicalcross', color: 'text-info' },
'running': {icon: 'icon icon-circle-o', color: 'text-success'},
'started-once': {icon: 'icon icon-dot-circlefill',color: 'text-success'},
'starting': {icon: 'icon icon-adjust', color: 'text-info' },
'stopped': {icon: 'icon icon-circle', color: 'text-danger' },
'stopping': {icon: 'icon icon-adjust', color: 'text-info' },
'unhealthy': {icon: 'icon icon-alert', color: 'text-danger' },
'updating': {icon: 'icon icon-tag', color: 'text-info' },
'updating-active': {icon: 'icon icon-tag', color: 'text-info' },
'updating-reinitializing': {icon: 'icon icon-alert', color: 'text-info' },
'updating-inactive': {icon: 'icon icon-tag', color: 'text-info' },
};
const stateColorSortMap = {

View File

@ -6,9 +6,14 @@ var Mount = Resource.extend({
isReadOnly: Ember.computed.equal('permissions','ro'),
instance: function() {
// @TODO Better way to tell if the intance is going to be a container or a VM ahead of time
var proxy = Ember.ObjectProxy.create({content: {}});
this.get('store').find('container', this.get('instanceId')).then((container) => {
proxy.set('content', container);
}).catch(() => {
this.get('store').find('virtualmachine', this.get('instanceId')).then((vm) => {
proxy.set('content', vm);
});
});
return proxy;

View File

@ -23,20 +23,8 @@ var Volume = Resource.extend({
isRoot: Ember.computed.notEmpty('instanceId'),
canDelete: function() {
// This doesn't work in the API yet.
if ( true )
{
return false;
}
// Can't delete things that are already removed, or root volumes (with an instanceId)
if ( this.get('isDeleted') || this.get('isPurged') || this.get('isRoot') )
{
return false;
}
return this.get('activeMounts.length') === 0;
}.property('isDeleted','isPurged','isRoot','activeMounts.length'),
return this.get('state') === 'inactive' && !this.get('isRoot');
}.property('state','isRoot'),
activeMounts: function() {
var mounts = this.get('mounts')||[];

View File

@ -105,7 +105,6 @@ $singleCountWidth : 120px;
text-align: center;
}
.resource-actions BUTTON,
.collapser {
padding: 3px 5px;
}

View File

@ -1,3 +1,9 @@
const KIND_USER = 'user';
const KIND_CATALOG = 'catalog';
const KIND_SYSTEM = 'system';
const KIND_SYSTEM_CATALOG = 'system-catalog';
const KIND_KUBERNETES = 'kubernetes';
var C = {
COOKIE: {
TOKEN: 'token',
@ -7,18 +13,28 @@ var C = {
KIND_SEPARATOR: '://',
GROUP_SEPARATOR: ':',
KIND_ALL: 'all',
KIND_USER: 'user',
KIND_CATALOG: 'catalog',
KIND_SYSTEM: 'system',
KIND_KUBERNETES: 'kubernetes',
KIND_USER: KIND_USER,
KIND_CATALOG: KIND_CATALOG,
KIND_SYSTEM: KIND_SYSTEM,
KIND_SYSTEM_CATALOG: KIND_SYSTEM_CATALOG,
KIND_KUBERNETES: KIND_KUBERNETES,
UPGRADEABLE: [
'catalog',
'system'
KIND_CATALOG,
KIND_SYSTEM_CATALOG
],
SYSTEM_KINDS: [
KIND_SYSTEM,
KIND_SYSTEM_CATALOG,
],
NOT_USER_KINDS: [
KIND_SYSTEM,
KIND_SYSTEM_CATALOG,
KIND_KUBERNETES,
],
CATALOG_DEFAULT_GROUP: 'library',
SYSTEM_CATEGORIES: [
'Rancher services'
],
CATALOG_DEFAULT_GROUP: 'library',
},
GITHUB: {
@ -190,4 +206,9 @@ C.INITIALIZING_STATES = [
'reinitializing'
];
C.VM_CAPABLE_STORAGE_DRIVERS = [
'convoy-gluster',
'convoy-longhorn',
];
export default C;

View File

@ -4,22 +4,21 @@ export default Ember.Route.extend({
model: function(params/*, transition*/) {
var store = this.get('store');
var dependencies = [
store.findAll('host'), // Need inactive ones in case a link points to an inactive host
];
var dependencies = {
allHosts: store.findAll('host'), // Need inactive ones in case a link points to an inactive host
allStoragePools: store.findAllUnremoved('storagepool')
};
if ( params.virtualMachineId )
{
dependencies.pushObject(store.find('virtualmachine', params.virtualMachineId, {include: ['ports','instanceLinks']}));
dependencies['existing'] = store.find('virtualmachine', params.virtualMachineId, {include: ['ports','instanceLinks']});
}
return Ember.RSVP.all(dependencies, 'Load VM dependencies').then(function(results) {
var allHosts = results[0];
return Ember.RSVP.hash(dependencies, 'Load VM dependencies').then(function(results) {
var data, healthCheckData;
if ( params.virtualMachineId )
if ( dependencies.existing )
{
data = results[1].serializeForNew();
data = dependencies.existing.serializeForNew();
data.ports = (data.ports||[]).map((port) => {
delete port.id;
return port;
@ -56,7 +55,8 @@ export default Ember.Route.extend({
return Ember.Object.create({
instance: instance,
allHosts: allHosts,
allHosts: results.allHosts,
allStoragePools: results.allStoragePools,
});
});
},

View File

@ -3,9 +3,11 @@
isService=false
isSidekick=false
isVm=true
editing=false
launchConfig=model.instance
primaryResource=model.instance
allHosts=model.allHosts
allStoragePools=model.allStoragePools
done=(action 'done')
cancel=(action 'cancel')
}}

View File

@ -1,6 +1,6 @@
{
"name": "ui",
"version": "0.80.0",
"version": "0.81.0",
"private": true,
"directories": {
"doc": "doc",