cpee-model-management 1.0.16 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/cpee-model-management.gemspec +1 -1
- data/lib/cpee-model-management/commit.rb +1 -3
- data/lib/cpee-model-management/implementation.rb +293 -26
- data/lib/cpee-model-management/implementation.xml +133 -0
- data/lib/cpee-model-management/moma.xml +19 -98
- data/server/moma.conf +1 -0
- data/ui/css/design.css +5 -0
- data/ui/css/stats.css +55 -0
- data/ui/css/stats_standalone.css +7 -0
- data/ui/index.html +69 -10
- data/ui/instances.html +84 -0
- data/ui/js/design.js +11 -5
- data/ui/js/stats.js +223 -0
- data/ui/resources.html +91 -0
- metadata +9 -4
- data/ui/design.js +0 -239
@@ -1,98 +1,19 @@
|
|
1
|
-
<
|
2
|
-
<
|
3
|
-
<
|
4
|
-
|
5
|
-
|
6
|
-
<
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
<message name="dirname">
|
21
|
-
<parameter name="dir" type="string">
|
22
|
-
<param name="pattern">([a-zA-Z0-9öäüÖÄÜ _-]+)\.dir|</param>
|
23
|
-
</parameter>
|
24
|
-
</message>
|
25
|
-
<message name="duplicate">
|
26
|
-
<parameter name="new" type="string">
|
27
|
-
<param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+</param>
|
28
|
-
</parameter>
|
29
|
-
<parameter name="old" type="string">
|
30
|
-
<param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+\.xml</param>
|
31
|
-
</parameter>
|
32
|
-
</message>
|
33
|
-
<message name="stages">
|
34
|
-
<parameter name="stages" type="string"/>
|
35
|
-
</message>
|
36
|
-
<message name="newstage">
|
37
|
-
<parameter name="stage" type="string">
|
38
|
-
<xi:include href="stages"/>
|
39
|
-
</parameter>
|
40
|
-
</message>
|
41
|
-
<message name="stage">
|
42
|
-
<optional>
|
43
|
-
<parameter name="stage" type="string">
|
44
|
-
<xi:include href="stages"/>
|
45
|
-
</parameter>
|
46
|
-
</optional>
|
47
|
-
</message>
|
48
|
-
<message name="full">
|
49
|
-
<parameter name="full" type="string"/>
|
50
|
-
<optional>
|
51
|
-
<parameter name="stage" type="string">
|
52
|
-
<xi:include href="stages"/>
|
53
|
-
</parameter>
|
54
|
-
</optional>
|
55
|
-
</message>
|
56
|
-
<message name="list">
|
57
|
-
<parameter name="list" mimetype="application/json"/>
|
58
|
-
</message>
|
59
|
-
<message name="content">
|
60
|
-
<parameter name="content" mimetype="application/xml"/>
|
61
|
-
</message>
|
62
|
-
<resource>
|
63
|
-
<post in="item"/>
|
64
|
-
<post in="dir"/>
|
65
|
-
<post in="duplicate"/>
|
66
|
-
<get in="stage" out="list"/>
|
67
|
-
<get in="full" out="list"/>
|
68
|
-
<get in="stages" out="list"/>
|
69
|
-
<sse/>
|
70
|
-
<resource relative="[a-zA-Z0-9öäüÖÄÜ _-]+\.dir">
|
71
|
-
<post in="item"/>
|
72
|
-
<post in="duplicate"/>
|
73
|
-
<get in="stage" out="list"/>
|
74
|
-
<delete/>
|
75
|
-
<put in="name"/> <!-- rename -->
|
76
|
-
<resource relative="[a-zA-Z0-9öäüÖÄÜ _-]+\.xml">
|
77
|
-
<get out='content'/>
|
78
|
-
<delete/>
|
79
|
-
<put in="content"/>
|
80
|
-
<put in="name"/> <!-- rename -->
|
81
|
-
<put in="dirname"/> <!-- move -->
|
82
|
-
<put in="newstage"/> <!-- shift -->
|
83
|
-
<resource relative="open"><get in="stage"/></resource>
|
84
|
-
<resource relative="open-new"><get in="stage"/></resource>
|
85
|
-
</resource>
|
86
|
-
</resource>
|
87
|
-
<resource relative="[a-zA-Z0-9öäüÖÄÜ _-]+\.xml">
|
88
|
-
<get out='content'/>
|
89
|
-
<delete/>
|
90
|
-
<put in="content"/>
|
91
|
-
<put in="name"/> <!-- rename -->
|
92
|
-
<put in="dirname"/> <!-- move -->
|
93
|
-
<put in="newstage"/> <!-- shift -->
|
94
|
-
<resource relative="open"><get in="stage"/></resource>
|
95
|
-
<resource relative="open-new"><get in="stage"/></resource>
|
96
|
-
</resource>
|
97
|
-
</resource>
|
98
|
-
</description>
|
1
|
+
<declaration xmlns="http://riddl.org/ns/declaration/1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
|
2
|
+
<interface name="implementation">
|
3
|
+
<xi:include href="implementation.xml"/>
|
4
|
+
</interface>
|
5
|
+
<interface name="events">
|
6
|
+
<xi:include href="http://www.riddl.org/ns/common-patterns/notifications-consumer/2.0/consumer.xml"/>
|
7
|
+
</interface>
|
8
|
+
|
9
|
+
<facade>
|
10
|
+
<tile>
|
11
|
+
<layer name="implementation">
|
12
|
+
<apply-to>/</apply-to>
|
13
|
+
</layer>
|
14
|
+
<layer name="events">
|
15
|
+
<apply-to>/dash/events</apply-to>
|
16
|
+
</layer>
|
17
|
+
</tile>
|
18
|
+
</facade>
|
19
|
+
</declaration>
|
data/server/moma.conf
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
:models: models
|
3
3
|
:location: https://cpee.org/design/server/
|
4
4
|
:instantiate: https://cpee.org/flow/start/
|
5
|
+
:show: https://cpee.org/flow/index.html?monitor=
|
5
6
|
:cockpit:
|
6
7
|
draft: https://cpee.org/flow/model.html?monitor=
|
7
8
|
development: https://cpee.org/flow/edit.html?monitor=
|
data/ui/css/design.css
CHANGED
data/ui/css/stats.css
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#resources h1 {
|
2
|
+
font-size: 1.2em;
|
3
|
+
border-bottom: 0.1em solid var(--x-ui-border-color);
|
4
|
+
}
|
5
|
+
|
6
|
+
#resources table {
|
7
|
+
margin-left: 1.3em;
|
8
|
+
}
|
9
|
+
|
10
|
+
#instances h1 {
|
11
|
+
font-size: 1.2em;
|
12
|
+
border-bottom: 0.1em solid var(--x-ui-border-color);
|
13
|
+
}
|
14
|
+
|
15
|
+
.instances .text {
|
16
|
+
white-space: nowrap;
|
17
|
+
}
|
18
|
+
.instances .text > td {
|
19
|
+
display: inline-block;
|
20
|
+
white-space: nowrap;
|
21
|
+
overflow: hidden;
|
22
|
+
text-overflow: ellipsis;
|
23
|
+
padding-right: 0.5em;
|
24
|
+
padding-left: 0.5em;
|
25
|
+
}
|
26
|
+
|
27
|
+
.instances .name {
|
28
|
+
width: 12em;
|
29
|
+
}
|
30
|
+
.instances .state {
|
31
|
+
width: 7em
|
32
|
+
}
|
33
|
+
.instances .state:not([data-state=ready]):not([data-state=stopped]) > span.abandon {
|
34
|
+
display: none;
|
35
|
+
}
|
36
|
+
.instances .author {
|
37
|
+
width: 12em
|
38
|
+
}
|
39
|
+
|
40
|
+
.instances tr.sub, .instances tr.sub > td {
|
41
|
+
margin:0;
|
42
|
+
padding:0;
|
43
|
+
}
|
44
|
+
|
45
|
+
.instances .sub table {
|
46
|
+
margin-left: 0.8em;
|
47
|
+
}
|
48
|
+
.instances .sub table > tr.text > td:first-child::before {
|
49
|
+
content: '⤷';
|
50
|
+
margin-right: 0.5em;
|
51
|
+
}
|
52
|
+
|
53
|
+
.instances tr.text.even td {
|
54
|
+
background-color: var(--x-ui-content-light-background);
|
55
|
+
}
|
data/ui/index.html
CHANGED
@@ -35,6 +35,7 @@
|
|
35
35
|
<script type="text/javascript" src="/js_libs/underscore.min.js"></script>
|
36
36
|
<script type="text/javascript" src="/js_libs/jquery.caret.min.js"></script>
|
37
37
|
<script type="text/javascript" src="/js_libs/jquery.cookie.js"></script>
|
38
|
+
<script type="text/javascript" src="/js_libs/plotly.min.js"></script>
|
38
39
|
|
39
40
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>
|
40
41
|
|
@@ -52,20 +53,22 @@
|
|
52
53
|
|
53
54
|
<!-- custom stuff, play arround -->
|
54
55
|
<link rel="stylesheet" href="css/design.css" type="text/css"/>
|
56
|
+
<link rel="stylesheet" href="css/stats.css" type="text/css"/>
|
55
57
|
<script type="text/javascript" src="js/design.js"></script>
|
58
|
+
<script type="text/javascript" src="js/stats.js"></script>
|
56
59
|
</head>
|
57
60
|
<body is="x-ui-">
|
58
61
|
<ui-rest id="main">
|
59
62
|
<ui-tabbar>
|
60
|
-
<ui-before
|
61
|
-
<ui-tab class="" data-tab="models"
|
62
|
-
<ui-tab class="inactive" data-tab="newmodel">New Model</ui-tab>
|
63
|
-
<ui-tab class="inactive" data-tab="newdir"
|
64
|
-
<ui-space
|
65
|
-
<ui-tab class="inactive" data-tab="
|
66
|
-
<ui-tab class="inactive" data-tab="
|
67
|
-
<ui-behind
|
68
|
-
<ui-last
|
63
|
+
<ui-before ></ui-before>
|
64
|
+
<ui-tab class="" data-tab="models" >Models</ui-tab>
|
65
|
+
<ui-tab class="inactive" data-tab="newmodel" >New Model</ui-tab>
|
66
|
+
<ui-tab class="inactive" data-tab="newdir" >New Dir</ui-tab>
|
67
|
+
<ui-space ></ui-space>
|
68
|
+
<ui-tab class="inactive" data-tab="instances">Instances</ui-tab>
|
69
|
+
<ui-tab class="inactive" data-tab="resources">Resources</ui-tab>
|
70
|
+
<ui-behind ><span></span></ui-behind>
|
71
|
+
<ui-last ><a class="logo" href=".."></a></ui-last>
|
69
72
|
</ui-tabbar>
|
70
73
|
<ui-content class="noselect">
|
71
74
|
<ui-area data-belongs-to-tab="models">
|
@@ -160,7 +163,63 @@
|
|
160
163
|
<p>
|
161
164
|
<button>New Directory</button>
|
162
165
|
</p>
|
163
|
-
</
|
166
|
+
</form>
|
167
|
+
</ui-area>
|
168
|
+
<ui-area data-belongs-to-tab="instances" class="inactive">
|
169
|
+
<p>
|
170
|
+
Show ready, running and stopped instances.
|
171
|
+
</p>
|
172
|
+
<template id="stats_instances">
|
173
|
+
<h1 class="stats_title">Engine: </h1>
|
174
|
+
<table class='instances'></table>
|
175
|
+
</template>
|
176
|
+
<template id="stats_instance">
|
177
|
+
<tr class="text">
|
178
|
+
<td class="name"><a href='' target='_blank'><em>no name</em></a></td>
|
179
|
+
<td class="num">(<span></span>)</td>
|
180
|
+
<td class="state"><span class='value'></span> <span class='abandon'>[<a href='#' title='abandon'>a</a>]</span></td>
|
181
|
+
<td class="author"><em>unknown</em></td>
|
182
|
+
<td class="cpu"></td>
|
183
|
+
<td>/</td>
|
184
|
+
<td class="mem"></em></td>
|
185
|
+
</tr>
|
186
|
+
<tr class="sub">
|
187
|
+
<td colspan="6"><table></table></td>
|
188
|
+
</tr>
|
189
|
+
</template>
|
190
|
+
<div id='instances'></div>
|
191
|
+
</ui-area>
|
192
|
+
<ui-area data-belongs-to-tab="resources" class="inactive">
|
193
|
+
<p>
|
194
|
+
Show statistics about instances per server, and metrics about the health of the environment.
|
195
|
+
</p>
|
196
|
+
<template id="stats_engine">
|
197
|
+
<h1 class="stats_title">Engine: </h1>
|
198
|
+
<div class="stats_plot"></div>
|
199
|
+
<div class="stats_text">
|
200
|
+
<table>
|
201
|
+
<tbody>
|
202
|
+
<tr>
|
203
|
+
<td>Total Instances <strong>Created</strong> / <strong>Finished</strong> / <strong>Abandoned</strong>:</td>
|
204
|
+
<td class='total_created'></td>
|
205
|
+
<td>/</td>
|
206
|
+
<td class='total_finished'></td>
|
207
|
+
<td>/</td>
|
208
|
+
<td class='total_abandoned'></td>
|
209
|
+
</tr>
|
210
|
+
<tr>
|
211
|
+
<td>Instances Currently <strong>Ready</strong> / <strong>Running</strong> / <strong>Stopped</strong>:</td>
|
212
|
+
<td class='current_ready'></td>
|
213
|
+
<td>/</td>
|
214
|
+
<td class='current_running'></td>
|
215
|
+
<td>/</td>
|
216
|
+
<td class='current_stopped'></td>
|
217
|
+
</tr>
|
218
|
+
</tbody>
|
219
|
+
</table>
|
220
|
+
</div>
|
221
|
+
</template>
|
222
|
+
<div id='resources'></div>
|
164
223
|
</ui-area>
|
165
224
|
</ui-content>
|
166
225
|
</ui-rest>
|
data/ui/instances.html
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
<!--
|
2
|
+
This file is part of CPEE-MODEL-MANAGEMENT.
|
3
|
+
|
4
|
+
CPEE-MODEL-MANAGEMENT is free software: you can redistribute it and/or
|
5
|
+
modify it under the terms of the GNU General Public License as published by
|
6
|
+
the Free Software Foundation, either version 3 of the License, or (at your
|
7
|
+
option) any later version.
|
8
|
+
|
9
|
+
CPEE-MODEL-MANAGEMENT is distributed in the hope that it will be useful, but
|
10
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
11
|
+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
12
|
+
more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License along with
|
15
|
+
CPEE-MODEL-MANAGEMENT (file LICENSE in the main directory). If not, see
|
16
|
+
<http://www.gnu.org/licenses/>.
|
17
|
+
-->
|
18
|
+
|
19
|
+
<!DOCTYPE html>
|
20
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
21
|
+
<head>
|
22
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
23
|
+
<title>Instances</title>
|
24
|
+
|
25
|
+
<!-- libs, do not modify. When local than load local libs. -->
|
26
|
+
<script type="text/javascript" src="/js_libs/jquery.min.js"></script>
|
27
|
+
<script type="text/javascript" src="/js_libs/jquery.browser.js"></script>
|
28
|
+
<script type="text/javascript" src="/js_libs/jquery.svg.min.js"></script>
|
29
|
+
<script type="text/javascript" src="/js_libs/jquery.svgdom.min.js"></script>
|
30
|
+
<script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
|
31
|
+
<script type="text/javascript" src="/js_libs/util.js"></script>
|
32
|
+
<script type="text/javascript" src="/js_libs/printf.js"></script>
|
33
|
+
<script type="text/javascript" src="/js_libs/strftime.min.js"></script>
|
34
|
+
<script type="text/javascript" src="/js_libs/parsequery.js"></script>
|
35
|
+
<script type="text/javascript" src="/js_libs/underscore.min.js"></script>
|
36
|
+
<script type="text/javascript" src="/js_libs/jquery.caret.min.js"></script>
|
37
|
+
<script type="text/javascript" src="/js_libs/jquery.cookie.js"></script>
|
38
|
+
<script type="text/javascript" src="/js_libs/plotly.min.js"></script>
|
39
|
+
|
40
|
+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>
|
41
|
+
|
42
|
+
<script type="text/javascript" src="/js_libs/relaxngui.js"></script>
|
43
|
+
|
44
|
+
<script type="text/javascript" src="/js_libs/uidash.js"></script>
|
45
|
+
<script type="text/javascript" src="/js_libs/custommenu.js"></script>
|
46
|
+
|
47
|
+
<link rel="stylesheet" href="/js_libs/custommenu.css" type="text/css"/>
|
48
|
+
<link rel="stylesheet" href="/js_libs/uidash.css" type="text/css"/>
|
49
|
+
|
50
|
+
<link rel="stylesheet" href="/global_ui/ui.css" type="text/css"/>
|
51
|
+
|
52
|
+
<link rel="stylesheet" href="/js_libs/relaxngui.css" type="text/css"/>
|
53
|
+
|
54
|
+
<!-- custom stuff, play arround -->
|
55
|
+
<link rel="stylesheet" href="css/design.css" type="text/css"/>
|
56
|
+
<link rel="stylesheet" href="css/stats.css" type="text/css"/>
|
57
|
+
<link rel="stylesheet" href="css/stats_standalone.css" type="text/css"/>
|
58
|
+
<script type="text/javascript" src="js/stats.js"></script>
|
59
|
+
</head>
|
60
|
+
<body is="x-ui-">
|
61
|
+
<p>
|
62
|
+
Show ready, running and stopped instances.
|
63
|
+
</p>
|
64
|
+
<template id="stats_instances">
|
65
|
+
<h1 class="stats_title">Engine: </h1>
|
66
|
+
<table class='instances'></table>
|
67
|
+
</template>
|
68
|
+
<template id="stats_instance">
|
69
|
+
<tr class="text">
|
70
|
+
<td class="name"><a href='' target='_blank'><em>no name</em></a></td>
|
71
|
+
<td class="num">(<span></span>)</td>
|
72
|
+
<td class="state"><span class='value'></span> <span class='abandon'>[<a href='#' title='abandon'>a</a>]</span></td>
|
73
|
+
<td class="author"><em>unknown</em></td>
|
74
|
+
<td class="cpu"></td>
|
75
|
+
<td>/</td>
|
76
|
+
<td class="mem"></em></td>
|
77
|
+
</tr>
|
78
|
+
<tr class="sub">
|
79
|
+
<td colspan="6"><table></table></td>
|
80
|
+
</tr>
|
81
|
+
</template>
|
82
|
+
<div id='instances'></div>
|
83
|
+
</body>
|
84
|
+
</html>
|
data/ui/js/design.js
CHANGED
@@ -44,17 +44,17 @@ function delete_it(name) {
|
|
44
44
|
}
|
45
45
|
}
|
46
46
|
|
47
|
-
function
|
47
|
+
function design_init(gdir,gstage) {
|
48
48
|
var es = new EventSource('server/');
|
49
49
|
es.onopen = function() {
|
50
|
-
console.log('
|
50
|
+
console.log('design open');
|
51
51
|
};
|
52
52
|
es.onmessage = function(e) {
|
53
53
|
paint(gdir,gstage);
|
54
54
|
};
|
55
55
|
es.onerror = function() {
|
56
|
-
console.log('
|
57
|
-
//
|
56
|
+
console.log('design error');
|
57
|
+
// design_init();
|
58
58
|
};
|
59
59
|
}
|
60
60
|
|
@@ -88,6 +88,12 @@ function paint(gdir,gstage) {
|
|
88
88
|
$('[data-class=guarded] abbr',clone).attr('title',data['guarded'] || '');
|
89
89
|
$('[data-class=guarded] abbr',clone).text((data['guarded'] || '').match(/none/i) ? '' : (data['guarded'] || '').charAt(0).toUpperCase());
|
90
90
|
$('[data-class=resource]',clone).text(data['guarded_id'] || '');
|
91
|
+
|
92
|
+
if (data['guarded']) {
|
93
|
+
$('[data-class=guarded] abbr',clone).attr('title',data['guarded']);
|
94
|
+
$('[data-class=guarded] abbr',clone).text(data['guarded'].match(/none/i) ? '' : data['guarded'].charAt(0).toUpperCase());
|
95
|
+
$('[data-class=resource]',clone).text(data['guarded_what']);
|
96
|
+
}
|
91
97
|
}
|
92
98
|
$('[data-class=author]',clone).text(data['author']);
|
93
99
|
$('[data-class=date]',clone).text(new Date(data['date']).strftime('%Y-%m-%d, %H:%M:%S'));
|
@@ -108,7 +114,7 @@ $(document).ready(function() {
|
|
108
114
|
gstage = urlParams.get('stage') || 'draft';
|
109
115
|
gdir = urlParams.get('dir') ? (urlParams.get('dir') + '/').replace(/\/+/,'/') : '';
|
110
116
|
|
111
|
-
|
117
|
+
design_init(gdir,gstage);
|
112
118
|
|
113
119
|
var shifts = []
|
114
120
|
$.ajax({
|
data/ui/js/stats.js
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
var value_count = 100
|
2
|
+
|
3
|
+
function resource_update(ename) {
|
4
|
+
var iname = ename.replace(/[^a-z0-9A-Z]/g,'-').replace(/-$/,'')
|
5
|
+
$.get('server/dash/stats/',{ engine: ename },function(data){
|
6
|
+
$('#resource_utilization_text_' + iname + ' .total_created').text(data.total_created)
|
7
|
+
$('#resource_utilization_text_' + iname + ' .total_finished').text(data.total_finished)
|
8
|
+
$('#resource_utilization_text_' + iname + ' .total_abandoned').text(data.total_abandoned)
|
9
|
+
$('#resource_utilization_text_' + iname + ' .current_ready').text(data.ready)
|
10
|
+
$('#resource_utilization_text_' + iname + ' .current_running').text(data.running)
|
11
|
+
$('#resource_utilization_text_' + iname + ' .current_stopped').text(data.stopped)
|
12
|
+
});
|
13
|
+
}
|
14
|
+
|
15
|
+
function resource_add(ename) {
|
16
|
+
let inode = document.importNode($("#stats_engine")[0].content,true);
|
17
|
+
var iname = ename.replace(/[^a-z0-9A-Z]/g,'-').replace(/-$/,'')
|
18
|
+
$('.stats_title',inode).text($('.stats_title',inode).text() + ename)
|
19
|
+
$('.stats_plot',inode).attr('id','resource_utilization_plot_'+iname)
|
20
|
+
$('.stats_text',inode).attr('id','resource_utilization_text_'+iname)
|
21
|
+
|
22
|
+
$('#resources').append(inode)
|
23
|
+
|
24
|
+
resource_update(ename);
|
25
|
+
|
26
|
+
var trace1 = {
|
27
|
+
y: Array(value_count).fill(0),
|
28
|
+
type: 'scatter',
|
29
|
+
name: '% CPU'
|
30
|
+
};
|
31
|
+
|
32
|
+
var trace2 = {
|
33
|
+
y: Array(value_count).fill(0),
|
34
|
+
type: 'scatter',
|
35
|
+
name: '% Mem Used'
|
36
|
+
};
|
37
|
+
|
38
|
+
var layout = {
|
39
|
+
margin: {t:0,r:0,b:0,l:20},
|
40
|
+
height: 200,
|
41
|
+
width: 700,
|
42
|
+
yaxis: {
|
43
|
+
range: [-5, 105]
|
44
|
+
},
|
45
|
+
xaxis: {
|
46
|
+
showticklabels: false,
|
47
|
+
fixedrange: true
|
48
|
+
}
|
49
|
+
};
|
50
|
+
|
51
|
+
var data = [trace1, trace2];
|
52
|
+
|
53
|
+
Plotly.newPlot('resource_utilization_plot_' + iname, data, layout, {displayModeBar: false});
|
54
|
+
}
|
55
|
+
|
56
|
+
function instance_change(d) {
|
57
|
+
const ename = d.engine
|
58
|
+
const iname = d.engine.replace(/[^a-z0-9A-Z]/g,'-').replace(/-$/,'')
|
59
|
+
|
60
|
+
if (d.state == "ready") {
|
61
|
+
if ($('[data-id=' + d.uuid + ']').length > 0) {
|
62
|
+
if ($('[data-id=' + d.uuid + ']').attr('data-parent') != parent) {
|
63
|
+
$('[data-id=' + d.uuid + ']').remove()
|
64
|
+
instance_add(iname,d.uuid,d.url,d.name,d.state,d.author,0,0,d.parent)
|
65
|
+
} else {
|
66
|
+
instance_upd(d.uuid,d.name,d.state,d.author,0,0,d.parent)
|
67
|
+
}
|
68
|
+
} else {
|
69
|
+
instance_add(iname,d.uuid,d.url,d.name,d.state,d.author,0,0,d.parent)
|
70
|
+
}
|
71
|
+
} else if (d.state == 'abandoned' || d.state == 'finished') {
|
72
|
+
if ($('tr.sub[data-id=' + d.uuid + '] > td > table > tr').length > 0) {
|
73
|
+
$('tr.text[data-id=' + d.uuid + ']').replaceWith($('tr.sub[data-id=' + d.uuid + '] > td > table > tr'))
|
74
|
+
}
|
75
|
+
$('[data-id=' + d.uuid + ']').remove()
|
76
|
+
instances_striping(iname)
|
77
|
+
} else {
|
78
|
+
if ($('tr.sub[data-id=' + d.uuid + ']').attr('data-parent') != d.parent) {
|
79
|
+
$('[data-id=' + d.uuid + ']').remove()
|
80
|
+
instance_add(iname,d.uuid,d.url,d.name,d.state,d.author,0,0,d.parent)
|
81
|
+
} else {
|
82
|
+
instance_upd(d.uuid,d.name,d.state,d.author,0,0,d.parent)
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
function instance_upd(uuid,name,state,author,cpu,mem,parent) {
|
88
|
+
if (name != "") {
|
89
|
+
$('[data-id=' + uuid + '] > .name a').text(name)
|
90
|
+
}
|
91
|
+
$('[data-id=' + uuid + '] > .state span.value').text(state)
|
92
|
+
$('[data-id=' + uuid + '] > .state').attr('data-state',state)
|
93
|
+
if (author != "") {
|
94
|
+
$('[data-id=' + uuid + '] > .author').text(author)
|
95
|
+
}
|
96
|
+
instance_res(uuid,cpu,mem)
|
97
|
+
}
|
98
|
+
function instance_res(uuid,cpu,mem) {
|
99
|
+
$('[data-id=' + uuid + '] > .cpu').text($.sprintf('%05.2f',cpu))
|
100
|
+
$('[data-id=' + uuid + '] > .mem').text($.sprintf('%05.2f',mem))
|
101
|
+
}
|
102
|
+
function instance_add(iname,uuid,url,name,state,author,cpu,mem,parent) {
|
103
|
+
let inode = document.importNode($("#stats_instance")[0].content,true);
|
104
|
+
$('.sub',inode).attr('id',uuid)
|
105
|
+
$('.sub',inode).attr('data-id',uuid)
|
106
|
+
$('.sub',inode).attr('data-parent',parent)
|
107
|
+
$('.text',inode).attr('data-id',uuid)
|
108
|
+
$('.text',inode).attr('data-url',url)
|
109
|
+
$('.name a',inode).attr('href','server/dash/show?url=' + url)
|
110
|
+
$('.num span',inode).text(url.split(/[\\/]/).pop())
|
111
|
+
if (name != "") {
|
112
|
+
$('.name a',inode).text(name)
|
113
|
+
}
|
114
|
+
$('.state span.value',inode).text(state)
|
115
|
+
$('.state',inode).attr('data-state',state)
|
116
|
+
if (author != "") {
|
117
|
+
$('.author',inode).text(author)
|
118
|
+
}
|
119
|
+
$('.cpu',inode).text($.sprintf('%05.2f',cpu))
|
120
|
+
$('.mem',inode).text($.sprintf('%05.2f',mem))
|
121
|
+
if (parent == "") {
|
122
|
+
$('#instances_' + iname).append(inode)
|
123
|
+
} else {
|
124
|
+
$('#' + parent + ' > td > table').append(inode)
|
125
|
+
}
|
126
|
+
instances_striping(iname)
|
127
|
+
}
|
128
|
+
|
129
|
+
function instances_striping(iname) {
|
130
|
+
let even = true
|
131
|
+
$('#instances_' + iname + ' tr.text').removeClass('even')
|
132
|
+
$('#instances_' + iname + ' tr.text').each((i,e)=>{
|
133
|
+
if (even) {
|
134
|
+
$(e).addClass('even')
|
135
|
+
}
|
136
|
+
even = (even == true ? false : true)
|
137
|
+
})
|
138
|
+
}
|
139
|
+
|
140
|
+
function instances_init(ename) {
|
141
|
+
const iname = ename.replace(/[^a-z0-9A-Z]/g,'-').replace(/-$/,'')
|
142
|
+
let inode = document.importNode($("#stats_instances")[0].content,true);
|
143
|
+
$('.stats_title',inode).text($('.stats_title',inode).text() + ename)
|
144
|
+
$('table',inode).attr('id','instances_'+iname)
|
145
|
+
$('#instances').append(inode)
|
146
|
+
$.ajax({
|
147
|
+
type: "GET",
|
148
|
+
url: 'server/dash/instances',
|
149
|
+
data: { engine: ename },
|
150
|
+
success: (result) => {
|
151
|
+
$('instance',result).each((i,ele)=>{
|
152
|
+
const e = $(ele);
|
153
|
+
instance_add(iname,e.attr('uuid'),e.attr('url'),e.attr('name'),e.attr('state'),e.attr('author'),e.attr('cpu'),e.attr('mem'),e.attr('parent'))
|
154
|
+
})
|
155
|
+
}
|
156
|
+
})
|
157
|
+
}
|
158
|
+
|
159
|
+
function resource_paint(iname,data,count) {
|
160
|
+
count[iname]++
|
161
|
+
Plotly.extendTraces('resource_utilization_plot_' + iname, {y: [[data.cpu_usage], [(data.mem_total-data.mem_available)/data.mem_total * 100]]}, [0,1])
|
162
|
+
Plotly.relayout('resource_utilization_plot_' + iname, {
|
163
|
+
xaxis: {
|
164
|
+
range: [count[iname]-value_count,count[iname]],
|
165
|
+
showticklabels: false,
|
166
|
+
fixedrange: true
|
167
|
+
}
|
168
|
+
});
|
169
|
+
}
|
170
|
+
|
171
|
+
function stats_init() {
|
172
|
+
let es = new EventSource('server/dash/events/');
|
173
|
+
let count = {};
|
174
|
+
es.onopen = function() {
|
175
|
+
console.log('stats open');
|
176
|
+
};
|
177
|
+
es.onmessage = function(e) {
|
178
|
+
let data = JSON.parse(e.data)
|
179
|
+
const iname = data.engine.replace(/[^a-z0-9A-Z]/g,'-').replace(/-$/,'')
|
180
|
+
if ($('#instances').length > 0) {
|
181
|
+
if ($('#instances_' + iname).length == 0) {
|
182
|
+
instances_init(data.engine);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
if (data.topic == "node" && data.event == "resource_utilization") {
|
186
|
+
if ($('#resources').length > 0) {
|
187
|
+
if ($('#resource_utilization_plot_' + iname).length == 0) {
|
188
|
+
resource_add(data.engine);
|
189
|
+
count[iname] = value_count;
|
190
|
+
}
|
191
|
+
resource_paint(iname,data,count)
|
192
|
+
}
|
193
|
+
} else if (data.topic == "state" && data.event == "change") {
|
194
|
+
if ($('#resources').length > 0) {
|
195
|
+
resource_update(data.engine)
|
196
|
+
}
|
197
|
+
if ($('#instances').length > 0) {
|
198
|
+
instance_change(data)
|
199
|
+
}
|
200
|
+
} else if (data.topic == "status" && data.event == "resource_utilization") {
|
201
|
+
if ($('#instances').length > 0) {
|
202
|
+
instance_res(data.uuid,data.cpu,data.mem)
|
203
|
+
}
|
204
|
+
} else {
|
205
|
+
console.log(data);
|
206
|
+
}
|
207
|
+
};
|
208
|
+
es.onerror = function() {
|
209
|
+
console.log('stats error');
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
$(document).ready(function() {
|
214
|
+
stats_init();
|
215
|
+
$('#instances').on('click','.abandon',function(e){
|
216
|
+
const par = $(e.target).parents('[data-url]').first()
|
217
|
+
$.ajax({
|
218
|
+
type: "PUT",
|
219
|
+
url: 'server/dash/abandon',
|
220
|
+
data: { url: par.attr('data-url') }
|
221
|
+
})
|
222
|
+
})
|
223
|
+
});
|