This commit is contained in:
Vincent Fiduccia 2016-09-24 23:53:07 -07:00
parent 2939d59049
commit c35d2e7b52
17 changed files with 182 additions and 208 deletions

View File

@ -2,7 +2,7 @@
{{badge-state model=model}} {{badge-state model=model}}
</td> </td>
<td data-title="{{t 'generic.name'}}:" class="force-wrap"> <td data-title="{{t 'generic.name'}}:" class="force-wrap">
{{#link-to detailRoute model.id}}{{model.displayName}}{{/link-to}} <a href="{{href-to detailRoute model.id}}">{{model.displayName}}</a>
</td> </td>
<td data-title="{{t 'containersPage.table.ipAddress'}}:"> <td data-title="{{t 'containersPage.table.ipAddress'}}:">
{{format-ip ip=model.displayIp}} {{format-ip ip=model.displayIp}}
@ -10,7 +10,7 @@
{{#if showHost}} {{#if showHost}}
<td data-title="{{t 'containersPage.table.primaryHost'}}:"> <td data-title="{{t 'containersPage.table.primaryHost'}}:">
{{#if model.primaryHost}} {{#if model.primaryHost}}
{{#link-to "host" model.primaryHost.id}}{{model.primaryHost.displayName}}{{/link-to}} <a href="{{href-to "host" model.primaryHost.id}}">{{model.primaryHost.displayName}}</a>
{{else}} {{else}}
<span class="text-muted">{{t 'containersPage.table.primaryHostUnknown'}}</span> <span class="text-muted">{{t 'containersPage.table.primaryHostUnknown'}}</span>
{{/if}} {{/if}}

View File

@ -11,7 +11,7 @@ export default Ember.Component.extend(StrippedName, {
classNameBindings: ['model.isManaged:managed'], classNameBindings: ['model.isManaged:managed'],
stateBackground: function() { stateBackground: function() {
return this.get('model.stateColor').replace("text-","bg-"); return 'bg-'+this.get('model.stateColor').substr(5);
}.property('model.stateColor'), }.property('model.stateColor'),
isKubernetes: function() { isKubernetes: function() {

View File

@ -1,11 +1,11 @@
<div class="container-subpod"> <div class="container-subpod">
<div class="subpod-name clip"> <div class="subpod-name clip">
<i class="{{model.stateIcon}} {{model.stateColor}} dot "></i> <i class="{{model.stateIcon}} {{model.stateColor}} dot "></i>
{{#link-to (if model.isVm "virtualmachine" "container") model.id classNameBindings="showEllipsis:tiny-hellip"}} <a class="{{if showEllipsis 'tiny-hellip'}}" href="{{href-to (if model.isVm "virtualmachine" "container") model.id}}">
{{#tooltip-element tagName="span" inlineBlock=false type="tooltip-basic" model=model tooltipTemplate='tooltip-container-subpod' }} {{#tooltip-element tagName="span" inlineBlock=false type="tooltip-basic" model=model tooltipTemplate='tooltip-container-subpod' }}
{{displayName}} {{displayName}}
{{/tooltip-element}} {{/tooltip-element}}
{{/link-to}} </a>
</div> </div>
{{#if model.showTransitioningMessage}} {{#if model.showTransitioningMessage}}
<div class="subpod-detail clip {{if model.isError 'text-danger'}}"> <div class="subpod-detail clip {{if model.isError 'text-danger'}}">

View File

@ -184,7 +184,7 @@ export default Ember.Component.extend({
}); });
return list.sortBy('group','name','id'); return list.sortBy('group','name','id');
}.property('instance.requestedHostId','allHosts.@each.instancesUpdated'), }.property('instance.requestedHostId','allHosts.@each.instances'),
volumesFromArray: null, volumesFromArray: null,
initVolumesFrom: function() { initVolumesFrom: function() {

View File

@ -7,7 +7,7 @@
{{#if isMachine}} {{#if isMachine}}
{{model.displayName}} {{model.displayName}}
{{else}} {{else}}
{{#link-to "host" model.id}}{{model.displayName}}{{/link-to}} <a href="{{href-to 'host' model.id}}">{{model.displayName}}</a>
{{#if model.showTransitioningMessage}} {{#if model.showTransitioningMessage}}
<div class="pod-message {{if model.isError 'text-danger' 'text-muted'}}"> <div class="pod-message {{if model.isError 'text-danger' 'text-muted'}}">
{{model.transitioningMessage}} {{model.transitioningMessage}}

View File

@ -12,6 +12,7 @@ export default Ember.Component.extend({
language : Ember.inject.service('user-language'), language : Ember.inject.service('user-language'),
intl : Ember.inject.service(), intl : Ember.inject.service(),
session : Ember.inject.service(), session : Ember.inject.service(),
settings : Ember.inject.service(),
locales : Ember.computed.alias('language.locales'), locales : Ember.computed.alias('language.locales'),

View File

@ -2,6 +2,10 @@
<i class="icon icon-globe"></i> {{selectedLabel}} <i class="icon icon-chevron-down"></i> <i class="icon icon-globe"></i> {{selectedLabel}} <i class="icon icon-chevron-down"></i>
</a> </a>
<ul class="dropdown-menu dropdown-menu-right text-right" role="menu"> <ul class="dropdown-menu dropdown-menu-right text-right" role="menu">
{{#if settings.isRancher}}
<li><a href="http://translate.rancher.com" target="_blank" rel="noopener nofollow">{{t 'languageContribute'}}</a></li>
<li class="divider"></li>
{{/if}}
{{#each-in locales as |lang label|}} {{#each-in locales as |lang label|}}
<li class="{{if (eq selected lang) 'disabled selected'}}"> <li class="{{if (eq selected lang) 'disabled selected'}}">
<a {{action 'selectLanguage' lang}}> <a {{action 'selectLanguage' lang}}>
@ -9,8 +13,4 @@
</a> </a>
</li> </li>
{{/each-in}} {{/each-in}}
{{#if settings.isRancher}}
<li class="divider"></li>
<li><a href="http://translate.rancher.com" target="_blank" rel="noopener nofollow">{{t 'languageContribute'}}</a></li>
{{/if}}
</ul> </ul>

View File

@ -2,7 +2,7 @@
{{#if settings.isRancher}} {{#if settings.isRancher}}
{{#if projectId}} {{#if projectId}}
{{#link-to "authenticated.project.help" projectId role="button" class="btn btn-sm btn-link"}}{{t 'pageFooter.help'}}{{/link-to}} <a href="{{href-to 'authenticated.project.help' projectId}}" role="button" class="btn btn-sm btn-link">{{t 'pageFooter.help'}}</a>
{{/if}} {{/if}}
<a role="button" class="btn btn-sm btn-link" target="blank" href="{{settings.docsBase}}">{{t 'pageFooter.documentation'}}</a> <a role="button" class="btn btn-sm btn-link" target="blank" href="{{settings.docsBase}}">{{t 'pageFooter.documentation'}}</a>
<a role="button" class="btn btn-sm btn-link" target="blank" href="{{settings.docsBase}}/faqs/">{{t 'pageFooter.faq'}}</a> <a role="button" class="btn btn-sm btn-link" target="blank" href="{{settings.docsBase}}/faqs/">{{t 'pageFooter.faq'}}</a>

View File

@ -246,7 +246,7 @@ export default Ember.Component.extend({
}); });
return out.sortBy('name','id').uniq(); return out.sortBy('name','id').uniq();
}.property('allHosts.@each.instancesUpdated'), }.property('allHosts.@each.instances'),
normalizedContainerLabels: function() { normalizedContainerLabels: function() {
return normalizedLabels(this.get('allContainers')); return normalizedLabels(this.get('allContainers'));

View File

@ -6,6 +6,7 @@ export default Ember.Route.extend({
return Ember.RSVP.hash({ return Ember.RSVP.hash({
machines: store.findAll('machine'), machines: store.findAll('machine'),
hosts: store.findAll('host'), hosts: store.findAll('host'),
instances: store.findAll('instance'),
}).then((hash) => { }).then((hash) => {
return hash.hosts; return hash.hosts;
}); });

View File

@ -70,7 +70,7 @@ export default Ember.Mixin.create({
} }
return list.sortBy('group','name','id'); return list.sortBy('group','name','id');
}.property('allHosts.@each.instancesUpdated','intl._locale').volatile(), }.property('allHosts.@each.instances','intl._locale'),
containersOnRequestedHost: function() { containersOnRequestedHost: function() {
var requestedHostId = this.get('instance.requestedHostId'); var requestedHostId = this.get('instance.requestedHostId');

View File

@ -3,6 +3,8 @@ import Socket from 'ui/utils/socket';
import Util from 'ui/utils/util'; import Util from 'ui/utils/util';
import C from 'ui/utils/constants'; import C from 'ui/utils/constants';
let DEADTOME = ['removed','purging','purged'];
export default Ember.Mixin.create({ export default Ember.Mixin.create({
k8s : Ember.inject.service(), k8s : Ember.inject.service(),
projects : Ember.inject.service(), projects : Ember.inject.service(),
@ -18,11 +20,11 @@ export default Ember.Mixin.create({
this.set('k8sUidBlacklist', []); this.set('k8sUidBlacklist', []);
var store = this.get('store'); var store = this.get('store');
var boundTypeify = store._typeify.bind(store);
var socket = Socket.create(); var socket = Socket.create();
socket.on('message', (event) => { socket.on('message', (event) => {
Ember.run.schedule('actions', this, function() {
// Fail-safe: make sure the message is for this project // Fail-safe: make sure the message is for this project
var currentProject = this.get(`tab-session.${C.TABSESSION.PROJECT}`); var currentProject = this.get(`tab-session.${C.TABSESSION.PROJECT}`);
var metadata = socket.getMetadata(); var metadata = socket.getMetadata();
@ -33,12 +35,25 @@ export default Ember.Mixin.create({
return; return;
} }
var d = JSON.parse(event.data, boundTypeify); var d = JSON.parse(event.data);
let resource;
if ( d.data && d.data.resource ) {
resource = store._typeify(d.data.resource);
d.data.resource = resource;
}
//this._trySend('subscribeMessage',d); //this._trySend('subscribeMessage',d);
if ( d.name === 'resource.change' ) if ( d.name === 'resource.change' )
{ {
this._trySend(d.resourceType+'Changed', d); let key = d.resourceType+'Changed';
if ( this[key] ) {
this[key](d);
}
if ( resource && DEADTOME.contains(resource.state) ) {
store._remove(resource.type, resource);
}
} }
else if ( d.name === 'service.kubernetes.change' ) else if ( d.name === 'service.kubernetes.change' )
{ {
@ -46,21 +61,22 @@ export default Ember.Mixin.create({
var obj = Ember.get(d, 'data.object'); var obj = Ember.get(d, 'data.object');
if ( changeType && obj ) if ( changeType && obj )
{ {
this._trySend('k8sResourceChanged', changeType, obj); this.k8sResourceChanged(changeType, obj);
} }
} }
else if ( d.name === 'ping' ) else if ( d.name === 'ping' )
{ {
this._trySend('subscribePing', d); this.subscribePing(d);
} }
}); });
});
socket.on('connected', (tries, after) => { socket.on('connected', (tries, after) => {
this._trySend('subscribeConnected', tries, after); this.subscribeConnected(tries, after);
}); });
socket.on('disconnected', () => { socket.on('disconnected', () => {
this._trySend('subscribeDisconnected', this.get('tries')); this.subscribeDisconnected(this.get('tries'));
}); });
this.set('subscribeSocket', socket); this.set('subscribeSocket', socket);
@ -107,12 +123,6 @@ export default Ember.Mixin.create({
return out; return out;
}, },
actions: {
// Raw message from the WebSocket
//subscribeMessage: function(/*data*/) {
//console.log('subscribeMessage',data);
//},
// WebSocket connected // WebSocket connected
subscribeConnected: function(tries,msec) { subscribeConnected: function(tries,msec) {
this.set('connected', true); this.set('connected', true);
@ -146,28 +156,6 @@ export default Ember.Mixin.create({
console.log('Subscribe ping ' + this.forStr()); console.log('Subscribe ping ' + this.forStr());
}, },
hostChanged: function(change) {
// If the host has a physicalHostId, ensure it is in the machine's hosts array.
var host = change.data.resource;
var machine = this.get('store').getById('machine', host.get('physicalHostId'));
if ( machine )
{
machine.get('hosts').addObject(host);
}
},
containerChanged: function(change) {
this._includeChanged('host', 'instances', 'hosts', change.data.resource);
},
virtualMachineChanged: function(change) {
this._includeChanged('host', 'instances', 'hosts', change.data.resource);
},
instanceChanged: function(change) {
this._includeChanged('host', 'instances', 'hosts', change.data.resource);
},
ipAddressChanged: function(change) { ipAddressChanged: function(change) {
this._includeChanged('host', 'ipAddresses', 'hosts', change.data.resource); this._includeChanged('host', 'ipAddresses', 'hosts', change.data.resource);
// this._includeChanged('container', 'container', 'ipAddresses', 'containers', change.data.resource); // this._includeChanged('container', 'container', 'ipAddresses', 'containers', change.data.resource);
@ -236,25 +224,6 @@ export default Ember.Mixin.create({
this.get('k8sUidBlacklist').addObject(obj.metadata.uid); this.get('k8sUidBlacklist').addObject(obj.metadata.uid);
this.get('store')._remove(resource.get('type'), resource); this.get('store')._remove(resource.get('type'), resource);
} }
}
},
_trySend: function(/*arguments*/) {
try
{
this.send.apply(this,arguments);
}
catch (err)
{
if ( err instanceof Ember.Error && err.message.indexOf('Nothing handled the action') === 0 )
{
// Don't care
}
else
{
throw err;
}
}
}, },
// Update the `?include=`-ed arrays of a host, // Update the `?include=`-ed arrays of a host,
@ -268,6 +237,8 @@ export default Ember.Mixin.create({
return; return;
} }
let start = (new Date().getTime());
var changedId = changed.get('id'); var changedId = changed.get('id');
var store = this.get('store'); var store = this.get('store');
@ -342,5 +313,8 @@ export default Ember.Mixin.create({
} }
}).catch(() => {}); }).catch(() => {});
}); });
let diff = ((new Date()).getTime())-start;
console.log('includechanged:', resourceName, destProperty, expectedProperty, diff);
}, },
}); });

View File

@ -5,6 +5,15 @@ import { byId as serviceById } from 'ui/models/service';
import { formatMib } from 'ui/utils/util'; import { formatMib } from 'ui/utils/util';
import C from 'ui/utils/constants'; import C from 'ui/utils/constants';
function getByInstanceId(store,id) {
let obj = store.getById('container', id);
if ( !obj ) {
obj = store.getById('virtualmachine', id);
}
return obj;
}
var Host = Resource.extend({ var Host = Resource.extend({
type: 'host', type: 'host',
@ -78,10 +87,19 @@ var Host = Resource.extend({
}.property('actionLinks.{activate,deactivate,remove,purge,update}','machine','machine.links.config'), }.property('actionLinks.{activate,deactivate,remove,purge,update}','machine','machine.links.config'),
instancesUpdated: 0, instances: function() {
onInstanceChanged: function() { let out = [];
this.incrementProperty('instancesUpdated'); let store = this.get('store');
}.observes('instances.@each.{id,name,state}','instances.length'),
(this.get('instanceIds')||[]).forEach((id) => {
let obj = getByInstanceId(store,id);
if ( obj ) {
out.push(obj);
}
});
return out;
}.property('instanceIds.[]'),
state: function() { state: function() {
var host = this.get('hostState'); var host = this.get('hostState');
@ -233,20 +251,14 @@ var Host = Resource.extend({
endpoint.service = serviceById(endpoint.serviceId); endpoint.service = serviceById(endpoint.serviceId);
} }
if ( !endpoint.instance ) { endpoint.instance = getByInstanceId(store, endpoint.instanceId);
endpoint.instance = store.getById('container', endpoint.instanceId);
if ( !endpoint.instanceId ) {
endpoint.instance = store.getById('virtualmachine', endpoint.instanceId);
}
}
return endpoint; return endpoint;
}); });
}.property('publicEndpoints.@each.{ipAddress,port,serviceId,instanceId}'), }.property('publicEndpoints.@each.{ipAddress,port,serviceId,instanceId}'),
}); });
Host.reopenClass({ Host.reopenClass({
alwaysInclude: ['instances','ipAddresses'], alwaysInclude: ['ipAddresses'],
// Remap the host state to hostState so the regular state can be a computed combination of host+agent state. // Remap the host state to hostState so the regular state can be a computed combination of host+agent state.
mangleIn: function(data) { mangleIn: function(data) {

View File

@ -70,19 +70,6 @@ var Machine = Resource.extend(PolledResource, {
}); });
Machine.reopenClass({ Machine.reopenClass({
alwaysInclude: ['hosts'],
pollTransitioningDelay: 60000,
pollTransitioningInterval: 60000,
mangleIn: function(data) {
if ( !data.hosts )
{
data.hosts = [];
}
return data;
},
stateMap: { stateMap: {
'bootstrapping': {icon: 'icon icon-tag', color: 'text-info'}, 'bootstrapping': {icon: 'icon icon-tag', color: 'text-info'},
'active': {icon: 'icon icon-tag', color: 'text-info'}, 'active': {icon: 'icon icon-tag', color: 'text-info'},

View File

@ -6,7 +6,7 @@ var StoragePool = Resource.extend({
}); });
StoragePool.reopenClass({ StoragePool.reopenClass({
alwaysInclude: ['hosts','volumes'], alwaysInclude: ['volumes'],
}); });
export default StoragePool; export default StoragePool;

View File

@ -101,9 +101,7 @@ module.exports = function(environment) {
'?eventNames=resource.change' + '?eventNames=resource.change' +
'&eventNames=service.kubernetes.change' + '&eventNames=service.kubernetes.change' +
'&limit=-1' + '&limit=-1' +
'&include=hosts' +
'&include=services' + '&include=services' +
'&include=instances' +
'&include=instance' + '&include=instance' +
'&include=instanceLinks' + '&include=instanceLinks' +
'&include=ipAddresses', '&include=ipAddresses',

View File

@ -43,6 +43,7 @@
"ember-cli-uglify": "^1.2.0", "ember-cli-uglify": "^1.2.0",
"ember-cli-test-loader": "^1.1.0", "ember-cli-test-loader": "^1.1.0",
"ember-export-application-global": "^1.0.5", "ember-export-application-global": "^1.0.5",
"ember-href-to": "1.6.0",
"ember-intl": "2.13.0", "ember-intl": "2.13.0",
"ember-load-initializers": "^0.5.1", "ember-load-initializers": "^0.5.1",
"ember-power-select": "1.0.0-beta.19", "ember-power-select": "1.0.0-beta.19",