From 85ea8bf4630bd3760ab935c24c7b78cdd255f55b Mon Sep 17 00:00:00 2001 From: Ondrej Mular Date: Wed, 26 Aug 2015 10:55:57 +0200 Subject: [PATCH] fix tree view of resources in web UI --- pcsd/cluster_entity.rb | 15 +- pcsd/pcs.rb | 30 ++- pcsd/public/js/nodes-ember.js | 34 +++- pcsd/remote.rb | 12 +- pcsd/views/nodes.erb | 457 +++++++++++++++++++++--------------------- 5 files changed, 284 insertions(+), 264 deletions(-) diff --git a/pcsd/cluster_entity.rb b/pcsd/cluster_entity.rb index 182969f..b291937 100644 --- a/pcsd/cluster_entity.rb +++ b/pcsd/cluster_entity.rb @@ -895,7 +895,7 @@ module ClusterEntity class Node < JSONable attr_accessor :id, :error_list, :warning_list, :status, :quorum, :uptime, :name, :corosync, :pacemaker, :cman, :corosync_enabled, - :pacemaker_enabled, :pcsd_enabled, :attr, :fence_levels + :pacemaker_enabled, :pcsd_enabled def initialize @id = nil @@ -911,8 +911,6 @@ module ClusterEntity @corosync_enabled = false @pacemaker_enabled = false @pcsd_enabled = false - @attr = ClusterEntity::NvSet.new - @fence_levels = {} end def self.load_current_node(session, crm_dom=nil) @@ -923,7 +921,6 @@ module ClusterEntity node.pacemaker_enabled = pacemaker_enabled? node.cman = cman_running? node.pcsd_enabled = pcsd_enabled? - node.fence_levels = get_fence_levels(session) node_online = (node.corosync and node.pacemaker) node.status = node_online ? 'online' : 'offline' @@ -939,16 +936,6 @@ module ClusterEntity node.status = 'online' end node.quorum = !!crm_dom.elements['//current_dc[@with_quorum="true"]'] - - node_name = get_current_node_name() - all_nodes_attr = get_node_attributes(session) - if all_nodes_attr[node_name] - all_nodes_attr[node_name].each { |pair| - node.attr << ClusterEntity::NvPair.new( - nil, pair[:key], pair[:value] - ) - } - end else node.status = 'offline' end diff --git a/pcsd/pcs.rb b/pcsd/pcs.rb index 37f6b83..1fe9b99 100644 --- a/pcsd/pcs.rb +++ b/pcsd/pcs.rb @@ -1624,8 +1624,11 @@ def get_node_status(session, cib_dom) :need_ring1_address => need_ring1_address?, :is_cman_with_udpu_transport => is_cman_with_udpu_transport?, :acls => get_acls(session), - :username => session[:username] + :username => session[:username], + :fence_levels => get_fence_levels(session), + :node_attr => node_attrs_to_v2(get_node_attributes(session)) } + nodes = get_nodes_status() known_nodes = [] @@ -1742,14 +1745,31 @@ def get_cib_dom(session) return nil end +def node_attrs_to_v2(node_attrs) + all_nodes_attr = {} + node_attrs.each { |node, attrs| + all_nodes_attr[node] = [] + attrs.each { |attr| + all_nodes_attr[node] << { + :id => nil, + :name => attr[:key], + :value => attr[:value] + } + } + } + return all_nodes_attr +end + def status_v1_to_v2(status) new_status = status.select { |k,_| [:cluster_name, :username, :is_cman_with_udpu_transport, :need_ring1_address, :cluster_settings, :constraints, :groups, :corosync_online, :corosync_offline, :pacemaker_online, :pacemaker_standby, - :pacemaker_offline, :acls + :pacemaker_offline, :acls, :fence_levels ].include?(k) } + new_status[:node_attr] = node_attrs_to_v2(status[:node_attr]) + resources = ClusterEntity::make_resources_tree( ClusterEntity::get_primitives_from_status_v1(status[:resources]) ) @@ -1764,15 +1784,9 @@ def status_v1_to_v2(status) ].include?(k) } - node_attr = ClusterEntity::NvSet.new - status[:node_attr].each { |k,v| - node_attr << ClusterEntity::NvPair.new(nil, k, v) - } new_status[:node].update( { :id => status[:node_id], - :attr => node_attr.to_status, - :fence_levels => status[:fence_levels], :quorum => nil, :warning_list => [], :error_list => [], diff --git a/pcsd/public/js/nodes-ember.js b/pcsd/public/js/nodes-ember.js index 46e34fa..1f60adc 100644 --- a/pcsd/public/js/nodes-ember.js +++ b/pcsd/public/js/nodes-ember.js @@ -170,7 +170,7 @@ Pcs = Ember.Application.createWithMixins({ tree_view_onclick(self.get('cur_resource').get('id'), true); if (!fence_change && self.get('cur_fence')) tree_view_select(self.get('cur_fence').get('id')); - if (!resource_change && self.get('cur_fence')) + if (!resource_change && self.get('cur_resource')) tree_view_select(self.get('cur_resource').get('id')); Pcs.selectedNodeController.reset(); setup_node_links(); @@ -932,6 +932,9 @@ Pcs.Setting = Ember.Object.extend({ Pcs.Clusternode = Ember.Object.extend({ name: null, status: null, + status_unknown: function() { + return this.get('status') == "unknown"; + }.property("status"), status_val: function() { if (this.warnings && this.warnings.length) return get_status_value("warning"); @@ -1013,6 +1016,10 @@ Pcs.Clusternode = Ember.Object.extend({ return "color:red"; } }.property("up","pacemaker_standby"), + pacemaker_standby: null, + corosync_enabled: null, + pacemaker_enabled: null, + pcsd_enabled: null, standby_style: function () { if (this.pacemaker_standby) return "display: none;"; @@ -1043,7 +1050,12 @@ Pcs.Clusternode = Ember.Object.extend({ else return "Disabled"; }.property("pcsd_enabled"), - location_constraints: null + location_constraints: null, + node_attrs: [], + fence_levels: [], + pcsd: null, + corosync_daemon: null, + pacemaker_daemon: null, }); Pcs.Aclrole = Ember.Object.extend({ @@ -1509,8 +1521,8 @@ Pcs.nodesController = Ember.ArrayController.createWithMixins({ cur_node: null, cur_node_attr: function () { var nc = this; - if (nc.cur_node && "node_attrs" in nc.cur_node) { - return nc.cur_node.node_attrs; + if (nc.get('cur_node')) { + return nc.get('cur_node').get('node_attrs'); } return []; }.property("cur_node", "content.@each.node_attrs"), @@ -1599,7 +1611,7 @@ Pcs.nodesController = Ember.ArrayController.createWithMixins({ pacemaker_standby = false; } - if (node_obj["noresponse"] == true) { + if (node_obj["status"] == 'unknown') { pcsd_daemon = false } else { pcsd_daemon = true @@ -1618,9 +1630,9 @@ Pcs.nodesController = Ember.ArrayController.createWithMixins({ up_status = false; } - var node_attr = {}; - if (node_obj["attr"]) { - node_attr = node_obj["attr"]; + var node_attr = []; + if (data["node_attr"] && data["node_attr"][node_id]) { + node_attr = data["node_attr"][node_id]; } found = false; @@ -1646,7 +1658,8 @@ Pcs.nodesController = Ember.ArrayController.createWithMixins({ node.set("uptime", node_obj["uptime"]); node.set("node_id", node_obj["id"]); node.set("node_attrs", node_attr); - node.set("fence_levels", node_obj["fence_levels"]); + node.set("fence_levels", data["fence_levels"]); + node.set("status", node_obj["status"]); } }); @@ -1670,7 +1683,8 @@ Pcs.nodesController = Ember.ArrayController.createWithMixins({ uptime: node_obj["uptime"], node_id: node_obj["id"], node_attrs: node_attr, - fence_levels: node_obj["fence_levels"] + fence_levels: data["fence_levels"], + status: node_obj["status"] }); } var pathname = window.location.pathname.split('/'); diff --git a/pcsd/remote.rb b/pcsd/remote.rb index 22af38a..a40c1c7 100644 --- a/pcsd/remote.rb +++ b/pcsd/remote.rb @@ -1014,8 +1014,14 @@ def node_status(params, request, session) status[:cluster_settings] node_attr = {} - node.attr.each { |v| - node_attr[v.name.to_sym] = v.value + status[:node_attr].each { |node, attrs| + node_attr[node] = [] + attrs.each { |attr| + node_attr[node] << { + :key => attr[:name], + :value => attr[:value] + } + } } old_status = { @@ -1038,7 +1044,7 @@ def node_status(params, request, session) :cluster_settings => cluster_settings, :node_id => node.id, :node_attr => node_attr, - :fence_levels => node.fence_levels, + :fence_levels => status[:fence_levels], :need_ring1_address => status[:need_ring1_address], :is_cman_with_udpu_transport => status[:is_cman_with_udpu_transport], :acls => status[:acls], diff --git a/pcsd/views/nodes.erb b/pcsd/views/nodes.erb index b8ecf6d..19bba62 100644 --- a/pcsd/views/nodes.erb +++ b/pcsd/views/nodes.erb @@ -40,242 +40,241 @@ -
-
-
-
Edit Node 
-
-{{Pcs.nodesController.cur_node.name}} -
- -
- -
- - - - - - - - - - -
- -
- - {{#if Pcs.nodesController.cur_node.pacemaker}} -
- Pacemaker Connected - {{else}} - {{#if Pcs.nodesController.cur_node.pacemaker_standby}} -
- Pacemaker Standby - {{else}} -
- Pacemaker Not Connected - {{/if}} - {{/if}} -
-
- {{#if Pcs.nodesController.cur_node.corosync}} -
- Corosync Connected - {{else}} -
- Corosync Not Connected - {{/if}} -
-
-
- -
- - - - - -
- -
- -
- - - - - - -
Node ID:
{{Pcs.nodesController.cur_node.node_id}}
Uptime:
{{Pcs.nodesController.cur_node.uptime}}
-
+
+
+
+
Edit Node 
+
+ {{Pcs.nodesController.cur_node.name}} +
+
- - - - -
Cluster Daemons
-
- - - - - -
NAMESTATUS
pacemaker
-{{#if Pcs.nodesController.cur_node.pacemaker_daemon}} -Running ({{Pcs.nodesController.cur_node.pacemaker_startup}}) -{{else}} -{{#if Pcs.nodesController.cur_node.pcsd}} -Stopped ({{Pcs.nodesController.cur_node.pacemaker_startup}}) -{{else}} -Unknown ({{Pcs.nodesController.cur_node.pacemaker_startup}}) -{{/if}} -{{/if}} -
corosync
-{{#if Pcs.nodesController.cur_node.corosync_daemon}} -Running ({{Pcs.nodesController.cur_node.corosync_startup}}) -{{else}} -{{#if Pcs.nodesController.cur_node.pcsd}} -Stopped ({{Pcs.nodesController.cur_node.corosync_startup}}) -{{else}} -Unknown ({{Pcs.nodesController.cur_node.corosync_startup}}) -{{/if}} -{{/if}} -
pcsd
-{{#if Pcs.nodesController.cur_node.pcsd}} -Running ({{Pcs.nodesController.cur_node.pcsd_startup}}) -{{else}} - {{#if Pcs.nodesController.cur_node.authorized}} - Stopped ({{Pcs.nodesController.cur_node.pcsd_startup}}) - {{else}} - Running (not Authorized) ({{Pcs.nodesController.cur_node.pcsd_startup}}) - {{/if}} -{{/if}} -
-
-
- - - - -
Running Resources
-
- - - {{#if Pcs.nodesController.cur_node.running_resources}} - {{#each res in Pcs.nodesController.cur_node.running_resources}} - - {{/each}} - {{else}} - - {{/if}} -
NAME
- {{#unless res.stonith}} - {{#link-to 'Resources.index' res}}{{res.name}} ({{res.res_type}}){{/link-to}} - {{/unless}} -
NONE
-
-
- - - - -
Resource Location Preferences
-
- - - {{#if Pcs.nodesController.cur_node.location_constraints}} - {{#each Pcs.nodesController.cur_node.location_constraints}} - - {{/each}} - {{else}} - - {{/if}} -
NAMEScore
{{rsc}}{{score}}
NONE
-
-
- - - - - - - - + +
Node Attributes ({{#if Pcs.nodesController.cur_node_attr.length}}{{Pcs.nodesController.cur_node_attr.length}}{{else}}0{{/if}})
-
- - - {{#each Pcs.nodesController.cur_node_attr}} - - - - -
AttributeValueRemove
{{this.name}}{{this.value}} - X +
+ + + + + - {{/each}} - {{#unless Pcs.nodesController.cur_node_attr}} - - {{/unless}} - - - - + + + +
+ +
+ {{#if Pcs.nodesController.cur_node.pacemaker}} +
+ Pacemaker Connected +
+ {{else}} + {{#if Pcs.nodesController.cur_node.pacemaker_standby}} +
+ Pacemaker Standby +
+ {{else}} +
+ Pacemaker Not Connected +
+ {{/if}} + {{/if}}
NONE
+ {{#if Pcs.nodesController.cur_node.corosync}} +
+ Corosync Connected +
+ {{else}} +
+ Corosync Not Connected +
+ {{/if}} +
+
+ +
+ + + + + +
+ +
+
+ {{#unless Pcs.nodesController.cur_node.status_unknown}} + + + + + +
Node ID:
{{Pcs.nodesController.cur_node.node_id}}
Uptime:
{{Pcs.nodesController.cur_node.uptime}}
+ {{/unless}}
-
- - - - -
Fence Levels ({{#if Pcs.nodesController.cur_node_fence_levels.length}}{{Pcs.nodesController.cur_node_fence_levels.length}}{{else}}0{{/if}})
-
- - - {{#each Pcs.nodesController.cur_node_fence_levels}} - - - - - - {{/each}} - {{#unless Pcs.nodesController.cur_node_fence_levels}} - - {{/unless}} - - - - - -
LevelFence DevicesRemove
{{this.level}}{{this.devices}} - X -
NONE
-
-
-
+ + + +
Cluster Daemons
+
+ + + + + +
NAMESTATUS
pacemaker
+ {{#if Pcs.nodesController.cur_node.pacemaker_daemon}} + Running ({{Pcs.nodesController.cur_node.pacemaker_startup}}) + {{else}} + {{#if Pcs.nodesController.cur_node.pcsd}} + Stopped ({{Pcs.nodesController.cur_node.pacemaker_startup}}) + {{else}} + Unknown ({{Pcs.nodesController.cur_node.pacemaker_startup}}) + {{/if}} + {{/if}} +
corosync
+ {{#if Pcs.nodesController.cur_node.corosync_daemon}} + Running ({{Pcs.nodesController.cur_node.corosync_startup}}) + {{else}} + {{#if Pcs.nodesController.cur_node.pcsd}} + Stopped ({{Pcs.nodesController.cur_node.corosync_startup}}) + {{else}} + Unknown ({{Pcs.nodesController.cur_node.corosync_startup}}) + {{/if}} + {{/if}} +
pcsd
+ {{#if Pcs.nodesController.cur_node.pcsd}} + Running ({{Pcs.nodesController.cur_node.pcsd_startup}}) + {{else}} + {{#if Pcs.nodesController.cur_node.authorized}} + Stopped ({{Pcs.nodesController.cur_node.pcsd_startup}}) + {{else}} + Running (not Authorized) ({{Pcs.nodesController.cur_node.pcsd_startup}}) + {{/if}} + {{/if}} +
+
+
+ + + + +
Running Resources
+
+ + + {{#if Pcs.nodesController.cur_node.running_resources}} + {{#each res in Pcs.nodesController.cur_node.running_resources}} + + {{/each}} + {{else}} + + {{/if}} +
NAME
+ {{#unless res.stonith}} + {{#link-to 'Resources.index' res}}{{res.name}} ({{res.res_type}}){{/link-to}} + {{/unless}} +
NONE
+
+
+ + + + +
Resource Location Preferences
+
+ + + {{#if Pcs.nodesController.cur_node.location_constraints}} + {{#each Pcs.nodesController.cur_node.location_constraints}} + + {{/each}} + {{else}} + + {{/if}} +
NAMEScore
{{rsc}}{{score}}
NONE
+
+
+ + + + +
Node Attributes ({{#if Pcs.nodesController.cur_node_attr.length}}{{Pcs.nodesController.cur_node_attr.length}}{{else}}0{{/if}})
+
+ + + {{#each attr in Pcs.nodesController.cur_node_attr}} + + + + + {{else}} + + {{/each}} + + + + + +
AttributeValueRemove
{{attr.name}}{{attr.value}} + X +
NONE
+
+
+ + + + +
Fence Levels ({{#if Pcs.nodesController.cur_node_fence_levels.length}}{{Pcs.nodesController.cur_node_fence_levels.length}}{{else}}0{{/if}})
+
+ + + {{#each Pcs.nodesController.cur_node_fence_levels}} + + + + + + {{/each}} + {{#unless Pcs.nodesController.cur_node_fence_levels}} + + {{/unless}} + + + + + +
LevelFence DevicesRemove
{{this.level}}{{this.devices}} + X +
NONE
+
+
+
+
+ + <%= erb :_configure %> <%= erb :_acls %> <%= erb :_wizards %> -- 1.9.1