Project

General

Profile

Download (137 KB) Statistics
| Branch: | Revision:
1
define([
2
"dojo/on",
3
"dojo/_base/connect",
4
"dojo/cookie",
5
"steam2/statusColorMap",
6
"steam2/stores",
7
"steam2/models/Server",
8
"steam2/models/Image",
9
"steam2/models/Network",
10
"stabile/stores",
11
"dojox/grid/DataGrid",
12
"dojox/grid/TreeGrid",
13
"dijit/tree/ForestStoreModel",
14
"steam2/ServersGrid",
15
"steam2/ServersGridFormatters",
16
'stabile/griddialog',
17
"steam2/user",
18
"stabile/formatters",
19
'helpers/uuid',
20
"dijit/form/FilteringSelect",
21
"dijit/form/Select",
22
'dijit/InlineEditBox',
23
'dijit/form/RadioButton',
24
'dijit/form/Select',
25
'dijit/layout/BorderContainer',
26
'dojox/widget/Wizard',
27
'stabile/stats',
28
'stabile/wizards',
29
//'stabile/menu',
30
'stabile/systembuilder',
31
'stabile/ui_update',
32
'steam2/StatsChart',
33
"dijit/form/HorizontalSlider",
34
"dijit/form/HorizontalRuleLabels",
35
"dijit/form/SimpleTextarea",
36
"dijit/layout/ContentPane",
37
"dijit/Tree"
38
], function(on, connect, cookie, statusColorMap, newStores, Server, Image, Network, stores, DataGrid, TreeGrid, ForestStoreModel,
39
            ServersGrid, serverFormatters, griddialog, user, formatters) {
40

    
41
    var home = {
42
        _inited: false,
43
        chartsid: null,
44
        sliderCreated: false,
45
        chartsShown: false,
46
        chartSlider: null,
47
        chartCpuLoad: null,
48
        chartIO: null,
49
        chartNetworkActivity: null,
50

    
51
        saveServerValue : function(uuid, key, value, identifier) {
52
            if (uuid) {
53
//                jvalue = value.replace(/\+/g, "\\u002b");
54
                jvalue = value;
55
                if (!identifier) identifier = "uuid";
56
                var url;
57
                var postData;
58
                if (key=='downloadmasters' ||key=='disablesnat' || key.indexOf('externalip')==0 || key.indexOf('proxy')==0 || key.indexOf('vm')==0) {
59
                    url = "/stabile/systems/";
60
                    postData = { "action": "updateengineinfo" };
61
                    postData[key] = jvalue;
62
                } else if (identifier == "username") {
63
                    url = "/stabile/systems/";
64
                    postData = { "username": uuid, "action": "updateaccountinfo" };
65
                    postData[key] = jvalue;
66
                } else {
67
                    url = "/stabile/systems";
68
                    var items = [];
69
                    items[0][key] = jvalue;
70
                    items[0][identifier] = uuid;
71
                    postData = {"identifier": identifier, "label": identifier, "items": items};
72
                }
73
                $.ajax({
74
                    url: url,
75
                    type: 'PUT',
76
                    data: postData,
77
                    dataType: 'json',
78
                    success: function(data) {
79
                        server.parseResponse(data);
80
                        if (identifier == "username") {
81
                            if (data.indexOf("ERROR")==-1) {
82
                                if (value == '--') value = '';
83
                                user[key] = value;
84
                                home.grid.refresh();
85
                            } else {
86
                                dijit.byId("info_"+key+"_field").set('value', user[key]); // revert
87
                            }
88
                        }
89
                    },
90
                    complete: function(data) {
91
                        console.log("not parsing", data);
92
                    }
93
                });
94
            }
95
        },
96
        resetToAccountInfo : function() {
97
            if (!IRIGO.user.is_readonly) {
98
                $.get("/stabile/systems/?action=resettoaccountinfo", function(res) {
99
                    home.grid.refresh();
100
                    server.parseResponse(res);
101
                });
102
            }
103
        },
104
        showResetInfo: function() {
105
            grid.actionConfirmDialog('resettoaccountinfo', 'resettoaccountinfo', user.fullname, "reset? Your systems and servers contact info will be set to your account's info.", 'reset info', 'home.resetToAccountInfo');
106
        },
107
        restoreEngine: function() {
108
            var restoreid = dijit.byId("enginerestore")._getSelectedOptionsAttr().item.id[0];
109
            var restoretext;
110
            if (restoreid != user.engineid) {
111
                restoretext = "overwrite this engine's entire configuration from a backup of another engine with id: " + restoreid;
112
            } else {
113
                restoretext = "overwrite this engine's entire configuration from a previous backup of this engine?";
114
            }
115
            grid.actionConfirmDialog('restoreengine', 'restore1', user.enginename, restoretext, 'restore', 'home.updateEngine');
116
        },
117
        updateEngine : function(action) {
118
            var irigouser;
119
            var irigopwd;
120
            var engineid = IRIGO.user.engineid;
121
            var enginename = dijit.byId('info_enginename_field').value || IRIGO.user.enginename;
122
            var engineurl = document.location.href.substring(0,document.location.href.lastIndexOf("/"));
123
            var data;
124
            if (!engineid) {
125
                console.log("No engine ID");
126
                return;
127
            }
128
            if (!action) action = (user.enginelinked?"unlinkengine":"linkengine");
129

    
130
            if (action == 'restoreengine') {
131
                data = {
132
                    "items": [{restorefile:dijit.byId("enginerestore").value, engineuser:user.engineuser}]
133
                };
134
            } else if (!user.enginelinked) {
135
                if (!dojo.byId('irigouser')) return;
136
                irigouser = dojo.byId('irigouser').value;
137
                irigopwd = dojo.byId('irigopwd').value;
138
                data = [{user:irigouser, pwd:irigopwd, enginename:enginename,
139
                        engineid:engineid, engineurl:engineurl}];
140
            } else {
141
                data = {
142
                    "items": [{enginename:enginename, engineid:engineid, engineurl:engineurl}]
143
                };
144
            }
145
            if (!action) {
146
                $('#linkenginebutton').html('Update&hellip; <i class="fa fa-cog fa-spin"></i>');
147
            } else if (action == 'updateenginename') {
148
                if (enginename == IRIGO.user.enginename) return; // do nothing if enginename not changed
149
                else action = 'updateengine';
150
            } else {
151
                $('#' + action + 'button').html($('#' + action + 'button').html() + '&hellip; <i class="fa fa-cog fa-spin"></i>');
152
            }
153
            $('.linkengine').attr('disabled', true);
154

    
155
            var message;
156
            dojo.xhrPost({
157
                url: "/stabile/users?action=" + action,
158
                postData: dojo.toJson(data),
159
                load: function(response){
160
                    if (response.indexOf("Invalid credentials")!=-1) {
161
                        message = "Invalid credentials";
162
                    } else if (response.indexOf("Engine linked")!=-1) {
163
                        user.load();
164
                        user.releasepressure();
165
                        home.updateVitals('update');
166
                        user.enginelinked = true;
167
                        user.enginename = enginename;
168
                        document.title = enginename;
169
                        message = "Engine is now linked to Stabile Registry";
170
                        dojo.byId("info_linkengine_button").innerHTML = home.unlinkenginemsg;
171
                        if (IRIGO.user.downloadmasters) $("#checkfordownloads").show();
172
                        stores.engines.close();
173
                        home.engines_field.setStore(stores.engines);
174
                        q = dojo.query('.irigo-tooltip'); q.irigoTooltip && q.irigoTooltip();
175
                    } else if (response.indexOf("Engine unlinked")!=-1 || response.indexOf("Unknown engine")!=-1) {
176
                        user.load();
177
                        user.releasepressure();
178
                        user.enginelinked = false;
179
                        dojo.byId("info_linkengine_button").innerHTML = home.linkenginemsg;
180
                        $("#engines_span").hide();
181
                        stores.engines.close();
182
                        home.engines_field.setStore(stores.engines);
183
                        q = dojo.query('.irigo-tooltip'); q.irigoTooltip && q.irigoTooltip();
184
                        message = "Engine is now unlinked";
185
                        if (!IRIGO.user.downloadmasters) $("#checkfordownloads").hide()
186
                    } else if (response.indexOf("Engine updated")!=-1) {
187
                        user.enginename = enginename;
188
                        document.title = enginename;
189
                        user.load();
190
                        user.releasepressure();
191
                        home.updateVitals('update');
192
                        message = "Engine updated";
193
                    } else if (response.indexOf("Engine and users updated")!=-1) {
194
                        user.load();
195
                        user.releasepressure();
196
                        document.title = user.enginename;
197
                        home.updateVitals('update');
198
                        message = "Engine and users updated on Stabile Registry";
199
                        stores.engines.close();
200
                        dijit.byId("engines").setStore(stores.engines);
201
                    } else if (response.indexOf("not linked")!=-1) {
202
                        message = "There was a problem. Is engine already linked with another account?";
203
                    } else if (response.indexOf("Invalid credentials")!=-1) {
204
                        message = "Invalid credentials";
205
                    } else {
206
                        if (response.indexOf('Status=')!=-1)
207
                            message = response.substring(response.indexOf('Status=')+7);
208
                        else
209
                        	message = response;
210
                    }
211
                    IRIGO.toaster([{
212
                        message: message,
213
                        type: "message",
214
                        duration: 3000
215
                    }]);
216
                    if (home.linkEngineDialog) home.linkEngineDialog.hide();
217
                    console.log(response);
218
                },
219
                error: function(error){
220
                    console.error("Problem linking engine!", error);
221
                }
222
            });
223
            return false;
224
        },
225
        changePassword : function() {
226
            if (!IRIGO.user.is_readonly) {
227
                var form = dijit.byId('changepasswordform');
228
                if(form.validate()) {
229
                    var newpassword = $("#newpassword").val();
230
                    $.get("/stabile/users/?action=changepassword&password=" + newpassword, function (res) {
231
                        var result = server.parseResponse(res);
232
                        if (result.status == 'OK') {
233
                            home.changePasswordDialog.hide();
234
                        }
235
                    });
236
                }
237
            }
238
        },
239
        showChangePassword : function() {
240
            if (!home.changePasswordDialog) {
241
                home.changePasswordDialog = new dijit.Dialog({ id: 'changePasswordDialog', style: "width: 520px; max-height:400px; overflow: auto;"
242
                });
243
            }
244
            home.changePasswordDialog.set('title',"Change your password");
245
            var one = [
246
                '<form method="#home" onsubmit="home.changePassword();return false;" class="wizardForm" id="changepasswordform" dojoType="dijit.form.Form">',
247
                '<table border="0" style="margin:20px;">',
248
                '<tr id="tr_newpassword"><td class="wizardLabel">',
249
                '<label>New password:</label>',
250
                '</td><td class="wizardLabel">',
251
                '<input id="newpassword" data-dojo-type="dijit.form.ValidationTextBox" required="true" type="password" autocomplete="new-password" style="width:300px;" value="" />',
252
                '</td></tr>'].join('');
253
            one += [
254
                '<tr id="tr_confirmpassword"><td class="wizardLabel">',
255
                '<label>Confirm password:</label>',
256
                '</td><td class="wizardLabel">',
257
                '<input id="confirmpassword" data-dojo-type="dijit.form.ValidationTextBox" required="true" type="password" autocomplete="new-password" style="width:300px;" value="" />',
258
                '</td></tr>'].join('');
259
            one += [
260
                '<tr><td colspan="2">&nbsp;</td></tr>',
261
                '<tr><td></td></td><td align="right">',
262
                '<button id="updateenginebutton" class="btn btn-sm btn-success linkengine" type="submit"',
263
                ' onClick="home.changePassword(); return false;"',
264
                '>',
265
                'Submit',
266
                '</button> ',
267
                '</td></tr>',
268
                '</table>',
269
                '</span>',
270
                '</form>'].join('');
271

    
272
            home.changePasswordDialog.set('content',one);
273
            home.changePasswordDialog.show();
274
        },
275
        showLinkEngine : function() {
276
            user.load(); // reload user.enginename
277
            if (!home.linkEngineDialog) {
278
                home.linkEngineDialog = new dijit.Dialog({ id: 'linkEngineDialog', style: "nowidth: 520px; max-height:400px; overflow: auto;"
279
                });
280
            }
281
            var helplink = '<a id="irigo-link-tooltip" href="https://www.origo.io/info/stabiledocs/web/dashboard/info-tab/linkengine" rel="help" target="_blank" class="irigo-tooltip">help</a>';
282
            if (!user.enginelinked) {
283
                home.linkEngineDialog.set('title',"Link this engine to Stabile Registry " + helplink);
284
            } else {
285
                home.linkEngineDialog.set('title',"Engine linking " + helplink);
286
            }
287
            var one = [
288
                '<form method="#home" onsubmit="home.updateEngine();return false;" class="wizardForm" id="linkengineForm" dojoType="dijit.form.Form">',
289
                '<table border="0" style="margin:20px;">',
290
                '<tr id="tr_engineid"><td class="wizardLabel">',
291
                '<label>Engine ID:</label>',
292
                '</td><td class="wizardLabel">',
293
                '<input id="engineid" style="width:280px;" readonly disabled value="' + user.engineid + '"/>',
294
                '</td></tr>',
295
                '<tr id="tr_enginename"><td class="wizardLabel">',
296
                '<label>Engine name:</label>',
297
                '</td><td class="wizardLabel">',
298
                '<input id="enginename" style="width:280px;" readonly disabled value="' + (user.enginename?user.enginename:user.username+"'s Engine") + '" />',
299
                '</td></tr>'].join('');
300
            if (!user.enginelinked) {
301
                one += [
302
                        '<tr id="tr_username"><td colspan="2">',
303
                        '<h4>Stabile Registry credentials</h4>',
304
                        '</td></tr>',
305
                        '<tr id="tr_username"><td class="wizardLabel">',
306
                        '<label>Username:</label>',
307
                        '</td><td class="wizardLabel">',
308
                        '<input id="irigouser" required disabled value="' + user.username + '" style="width:160px;" />',
309
                        '</td></tr>',
310
                        '<tr id="tr_password"><td class="wizardLabel">',
311
                        '<label>Password:</label>',
312
                        '</td><td class="wizardLabel">',
313
                        '<input id="irigopwd" required type="password" style="width:160px;" />',
314
                        '</td></tr>'].join('');
315
                one += ['<tr><td></td><td align="right">',
316
                    '<button id="linkenginebutton" class="btn btn-sm btn-success linkengine" type="submit" style="margin: 2px;">',
317
                    'Link',
318
                    '</button>',
319
                    '</td></tr>',
320
                    '</table>',
321
                    '</span>',
322
                    '</form>'].join('');
323
            } else {
324
                one += [
325
                '<tr id="tr_engineuser"><td class="wizardLabel" >',
326
                '<label>Engine owner:</label>',
327
                '</td><td class="wizardLabel">',
328
                '<input id="engineuser" style="width:280px;" readonly disabled value="' + (user.engineuser?user.engineuser:'') + '" />',
329
                '</td></tr>',
330
                '<tr id="tr_enginerestore"><td class="wizardLabel">',
331
                '<label>Restore config and DB:</label>',
332
                '</td><td class="wizardLabel">',
333
                '<select id="enginerestore" style="width:280px;" dojoType="dijit.form.Select" store="stores.engineBackups" sortbylabel="false"></select> ',
334
                '<button id="restoreenginebutton" class="btn btn-xs btn-info linkengine" disabled type="button"',
335
                ' onClick="home.restoreEngine();"',
336
                '>',
337
                'Restore&hellip;',
338

    
339
                '</button>',
340
                '</td></tr>',
341
                '<tr><td colspan="2">&nbsp;</td></tr>',
342
                '<tr><td></td></td><td align="left">',
343
                '<button id="updateenginebutton" class="btn btn-sm btn-success linkengine" type="button"',
344
                ' onClick="home.updateEngine(\'updateengine\');"',
345
                '>',
346
                'Push config',
347
                '</button> ',
348

    
349
                '<button id="backupenginebutton" class="btn btn-sm btn-primary linkengine" type="button"',
350
                ' onClick="home.updateEngine(\'backupengine\');"',
351
                '>',
352
                'Backup config and DB',
353
                '</button> ',
354
                '<button id="linkenginebutton" class="btn btn-sm btn-danger linkengine" type="button"',
355
                ' onClick="home.updateEngine();"',
356
                '>',
357
                'Unlink',
358
                '</button> ',
359
                '</td></tr>',
360
                '</table>',
361
                '</span>',
362
                '</form>'].join('');
363
            }
364

    
365
            home.linkEngineDialog.set('content',one);
366
            var q = dojo.query('#irigo-link-tooltip', home.linkEngineDialog.domNode);
367
            if(q.irigoTooltip){q.irigoTooltip();};
368
            home.linkEngineDialog.show();
369
            stores.engineBackups.close();
370
            stores.engineBackups.fetch({query:{path: "*"}, onComplete: function(items) {if (items[0].path[0]!="#") {$("#restoreenginebutton").prop("disabled", false); dijit.byId("enginerestore").setStore(stores.engineBackups);} }});
371
        },
372
        setNotesValue : function(notesval, gridItem, fieldid) {
373
            var field = dijit.byId("info_" + fieldid + "_field");
374
            if (field) {
375
                field.cancel();
376
                field.set('onChange', null);
377
                field.set('value', notesval);
378
                field.set('onChange', function(){
379
                    home.grid.updateSystem(fieldid);
380
                });
381
            } else {
382
                field = new dijit.InlineEditBox({
383
                    id: "info_" + fieldid + "_field",
384
                    autoSave: false,
385
                    buttonSave: "Save",
386
                    buttonCancel: "Cancel",
387
                    editor: "dijit.form.SimpleTextarea",
388
                    width: "100%", height: "360px",
389
                    value: notesval,
390
                    onChange : home.grid.updateSystem(fieldid),
391
                    editorParams: {height:'', extraPlugins: ['dijit._editor.plugins.AlwaysShowToolbar']},
392
                    renderAsHTML: true
393
                }, dojo.byId(fieldid));
394
            }
395
            document.getElementById("info_" + fieldid).style.display = "block";
396
            if (user.is_readonly) {
397
                if (!field.disabled) field.setDisabled(true);
398
            } else {
399
                if (field.disabled) field.setDisabled(false);
400
            }
401
        },
402
        setFieldValue : function(fieldname, value) {
403
            var field = dijit.byId(fieldname);
404
            if (!field) {
405
                console.log("field not found", fieldname);
406
            } else {
407
                var onch = field.get('onChange');
408
                field.set('onChange', null);
409
                if (fieldname=="info_lastlogin_field") {
410
                    var newval = home.timestampToLocaleString(value);
411
                    if (newval != field.get('value')) field.set('value', newval);
412
                } else if (fieldname=="info_lastloginfrom_field" && value=='') {
413
                    field.set('value', '--');
414
                } else if (fieldname.indexOf("vmreadlimit")!=-1 || fieldname.indexOf("vmwritelimit")!=-1) {
415
                    var newval = ""+Math.round(value/1024/1024);
416
                    if (newval!=field.get('value')) field.set('value', newval);
417
                } else if (field.type == 'checkbox') {
418
                    field.set('value', ((value && value!='--')?true:false));
419
                } else {
420
                    if (value!=field.get('value')) field.set('value', value);
421
                }
422
                field.set('onChange', onch);
423
                if (user.is_readonly) {
424
                    if (!field.disabled) field.setDisabled(true);
425
                } else {
426
                    if (field.disabled) field.setDisabled(false);
427
                }
428
            }
429
        },
430
        startServer : function(uuid) {
431
            home.saveServerValue(uuid, "action", "start");
432
        },
433
        grid: null,
434
        vitals: "",
435
        currentItem: null,
436
        currentCores: 0,
437
        totalServers: null,
438
        activeServers: null,
439
        currentUptimeMonth: null,
440
        currentUsageMonth: null,
441
        currentInternalip: null,
442
        currentExternalip: null,
443
        currentManagementlink: null,
444
        currentTerminallink: null,
445
        linkedNetworks: null,
446
        user: user,
447

    
448
        imagesOnShowItem: null,
449
        networksOnShowItem: null,
450
        servicesFilter: "service: '*'",
451
        userprops: ['fullname','email','phone','opfullname','opemail','opphone','alertemail','services','name','allowfrom',
452
                        'lastlogin','lastloginfrom', 'allowinternalapi', 'downloadmasters', 'disablesnat', 'enginename',
453
                        'externaliprangestart', 'externaliprangeend', 'proxyiprangestart', 'proxyiprangeend', 'proxygw',
454
                        'vmreadlimit', 'vmiopsreadlimit', 'vmwritelimit', 'vmiopswritelimit', 'autostart'],
455
        linkenginemsg: 'This engine is not linked to Stabile Registry <span style="float:right; display:block"><a href="#home" onClick="home.showLinkEngine()" >Link Engine...</a> <a id="irigo-externaliprangestart-tooltip" href="https://www.origo.io/info/stabiledocs/web/dashboard/info-tab/linkengine" rel="help" target="_blank" class="irigo-tooltip">help</a></span>',
456
        unlinkenginemsg: 'This engine is linked to Stabile Registry <span style="float:right; display:block"><a href="#home" onClick="home.showLinkEngine()">Engine linking...</a> <a id="irigo-externaliprangestart-tooltip" href="https://www.origo.io/info/stabiledocs/web/dashboard/info-tab/linkengine" rel="help" target="_blank" class="irigo-tooltip">help</a></span>',
457

    
458
        updateUser: function() {
459
            user.load();
460
            home.updateVitals('update');
461
        },
462
        updateVitals: function(gridItem) {
463
            home.vitals = document.getElementById('vitals');
464
            home.missingmonitors = document.getElementById('missingmonitors');
465
            home.missingbackups = document.getElementById('missingbackups');
466
            home.missingmonitors.innerHTML = "";
467
            home.currentCores = 0;
468
            //if (home.missingbackups) home.missingbackups.innerHTML = "";
469
            var vitals_system = document.getElementById('vitals_system');
470
            var vitals_server = document.getElementById('vitals_server');
471
            var info_server = document.getElementById('info_server');
472
            var info_notes = document.getElementById('info_notes');
473
            var info_contacts = document.getElementById('info_contacts');
474
            var info_security = document.getElementById('info_security');
475
            var info_name = document.getElementById('info_name');
476
            var info_recovery = document.getElementById('info_recovery');
477
            var appstatus = document.getElementById('appstatus');
478
            var appid = document.getElementById('appid');
479
            var info_resettoaccountinfo_tr = document.getElementById('info_resettoaccountinfo_tr');
480
            var info_linkengine_tr = document.getElementById("info_linkengine_tr");
481
            var info_linkengine = document.getElementById("info_linkengine_button");
482
            var info_downloadmasters_tr = document.getElementById("info_downloadmasters_tr");
483
            var home_add_empty = document.getElementById("home_add_empty");
484
            var v;
485
            var sysmemory = 0; var asysmemory = 0;
486
            var sysvcpu = 0; var asysvcpu = 0;
487
            var images=0; var images2=0; var aimages=0; var aimages2=0; var cdroms=0; var networks=0;
488

    
489
            if (gridItem=="update" || gridItem==null) {
490
                home.grid.store.fetch({query:{uuid: "*"}, onComplete: function(res) {
491
                    if (home.currentItem && home.currentItem!=null) {
492
                        home.updateVitals(home.currentItem);
493
                    } else {
494
                        home.updateVitals(res);
495
                    }
496
                }});
497

    
498
            // Display vitals - no items selected, gridItem contains array with all items
499
            } else if (gridItem && (gridItem.length || gridItem.length==0)) {
500
                var itemsHash = [];
501
                var nodesHash = [];
502
                var mac;
503
                var domstatus;
504
                var maccpucores;
505
                v = "<div id=\"vitalsHeader\"><h3>All stacks</h3></div>";
506
                for (i in gridItem) {
507
                    if (gridItem[i].issystem) {
508
                        var children = gridItem[i].children;
509
                        for (j in children) {
510
                            if (children[j].memory && !children[j].issystem & !itemsHash[children[j].uuid]) {
511
                                sysmemory += children[j].memory;
512
                                if (children[j].status!="inactive" && children[j].status!="shutoff") {
513
                                    asysmemory += children[j].memory;
514
                                    if (children[j].status=="running" || children[j].status=="paused") asysvcpu += children[j].vcpu;
515
                                    aimages++;
516
                                    if (children[j].image2!="--") aimages2++;
517
                                }
518
                                sysvcpu += children[j].vcpu;
519
                                images++;
520
                                if (children[j].image2!="--") images2++;
521
                                if (children[j].cdrom!="--") cdroms++;
522
                                networks++;
523
                                if (children[j].networkid2!="--") networks++;
524
                                itemsHash[children[j].uuid] = 1;
525

    
526
                                domstatus = children[j].status;
527
                                mac = children[j].macname;
528
                                maccpucores = parseInt(children[j].maccpucores);
529
                                if (domstatus!='shutoff' && domstatus!='inactive' &&
530
                                        mac && mac!='--' && maccpucores && maccpucores != '--') {
531
                                    if (nodesHash[mac]) {
532
                                        nodesHash[mac] = nodesHash[mac]+1;
533
                                    } else {
534
                                        nodesHash[mac] = 1;
535
                                        home.currentCores = home.currentCores+maccpucores;
536
                                    }
537
                                }
538
                            }
539
                        }
540
                    } else {
541
                        if (gridItem[i].memory && !gridItem[i].issystem && !itemsHash[gridItem[i].uuid]) {
542
                            sysmemory += parseInt(gridItem[i].memory);
543
                            sysvcpu += parseInt(gridItem[i].vcpu);
544
                            images++;
545
                            if (gridItem[i].image2!="--") images2++;
546
                            if (gridItem[i].cdrom!="--") cdroms++;
547
                            networks++;
548
                            if (gridItem[i].networkid2!="--") networks++;
549
                            itemsHash[gridItem[i].uuid] = 1;
550
                            if (gridItem[i].status!="inactive" && gridItem[i].status!="shutoff") {
551
                                asysmemory += parseInt(gridItem[i].memory);
552
                                if (gridItem[i].status=="running" || gridItem[i].status=="paused") asysvcpu += parseInt(gridItem[i].vcpu);
553
                                aimages++;
554
                                if (gridItem[i].image2!="--") aimages2++;
555
                            }
556
                            domstatus = gridItem[i].status;
557
                            mac = gridItem[i].macname;
558
                            maccpucores = parseInt(gridItem[i].maccpucores);
559
                            if (domstatus!='shutoff' && domstatus!='inactive' &&
560
                                    mac && mac!='--' && maccpucores && maccpucores != '--') {
561
                                if (nodesHash[mac]) {
562
                                    nodesHash[mac] = nodesHash[mac]+1;
563
                                } else {
564
                                    nodesHash[mac] = 1;
565
                                    home.currentCores = home.currentCores+maccpucores;
566
                                }
567
                            }
568
                        }
569
                    }
570
                }
571
                v += "<b>Total servers:</b> " + images + " (" + sysvcpu + " vCPU" + (sysvcpu>1?"s, ":", ") +
572
                        sysmemory + " MB memory" + ")<br>";
573
                v += "<b>Active servers:</b> " + aimages + " (" + asysvcpu + " vCPU" + (asysvcpu>1?"s, ":", ") +
574
                        asysmemory + " MB memory" + ")<br>";
575
                v += "<b>Images:</b> " + (images + images2);
576
                v += " (" + (aimages + aimages2) + " active) ";
577
                if (cdroms>0) v += "<b>CDs:</b> " + cdroms;
578
                v += "<br><b>Connections:</b> " + networks + "<br>";
579
                if (user.is_admin || user.node_storage_allowed) {
580
                    v += "<b>Active nodes:</b>  <span title=\"" + Object.keys(nodesHash).join(", ") + "\">" + Object.keys(nodesHash).length +
581
                            " (" + home.currentCores + " cores)</span><br>";
582
                }
583
                home.vitals.innerHTML = v;
584

    
585
                if (home.totalServers==null) {
586
                    home.totalServers = images;
587
                    home.activeServers = aimages;
588
                } else {
589
                    home.totalServers = images;
590
                    home.activeServers = aimages;
591
                }
592
//                home.monitoringGrid.updateMissingMonitors();
593
                appstatus.innerHTML = "";
594
                appid.innerHTML = "";
595
                for (var i in home.userprops) { // Set fullname, email, alertemail, etc.
596
                    var prop = home.userprops[i];
597
                    if (user[prop] && user[prop]!="--") {
598
                        home.setFieldValue("info_"+prop+"_field" , user[prop]);
599
                    } else {
600
                        home.setFieldValue("info_"+prop+"_field" , "");
601
                    }
602
                }
603
                home.setNotesValue("", null, "notes");
604
                home.setNotesValue("", null, "recovery");
605
                document.getElementById('info_header').innerHTML = "Account";
606
                info_name.style.display = "none";
607
                info_contacts.style.display = "block";
608
                info_security.style.display = "block";
609
                $("#info_rtfs").hide();
610
                info_recovery.style.display = "none";
611
                vitals_server.style.display = "none";
612
                vitals_system.style.display = "none";
613
                info_server.style.display = "none";
614
                info_notes.style.display = "none";
615
                if (user.is_readonly) info_resettoaccountinfo_tr.style.display = "none";
616
                else info_resettoaccountinfo_tr.style.display = "";
617
                if (user.is_readonly || !user.is_admin) {
618
                    info_linkengine_tr.style.display = "none";
619
                    info_downloadmasters_tr.style.display = "none";
620
                    //home_add_empty.style.display = "none";
621
                    $(".info-engine").hide();
622
                } else {
623
                    if (user.enginelinked) {
624
                        info_linkengine.innerHTML = home.unlinkenginemsg;
625
                    } else {
626
                        info_linkengine.innerHTML = home.linkenginemsg;
627
                    }
628
                    if (!IRIGO.user.downloadmasters) $("#checkfordownloads").hide();
629
                    else $("#checkfordownloads").show();
630

    
631
                    info_linkengine_tr.style.display = "table-row";
632
                    info_downloadmasters_tr.style.display = "table-row";
633
                    q = dojo.query('.irigo-tooltip'); q.irigoTooltip && q.irigoTooltip();
634
                    $(".info-engine").show();
635
                }
636
                $(".info-security").show();
637
                $(".info-account").show();
638
                $(".info-system").hide();
639
                $(".info-services").hide();
640
                if (user.enginelinked) $("#info_dnsdomain").html(IRIGO.user.dnsdomain).show();
641
                else $("#info_dnsdomain").hide();
642

    
643
                // Display vitals for a system
644
            } else if (gridItem.issystem == 1) {
645
                nodesHash = [];
646
                v = '<div id="vitalsHeader"><div style="width:97%;"><div class="row"><span class="col-sm-6" style="display:inline-block;"><h3>Stack: '+ gridItem.name + '</h3></span><span style="display:inline-block; text-align:right; float:right;">';
647
                v += '<span class="terminal"><button dojoType="dijit.form.Button" class="btn btn-info btn-xs" '
648
                    + ((user.is_readonly)?'disabled ':'')
649
                    + 'id="terminal_button" type="button" onclick="systembuilder.system.terminal();";>Terminal</button>';
650
                v += '<span style="padding: 0 0 4px 6px;"><a id="terminal_in_tab" class="manage_in_tab glyphicon glyphicon-new-window" href="#home" onclick="systembuilder.system.terminal_in_tab();"></a></span></span>';
651
                v += '<span class="manage_system"><button class="btn btn-success btn-xs" '
652
                    + ((user.is_readonly)?'disabled ':'')
653
                    + 'id="manage_system_button" type="button" onclick="systembuilder.system.manage();">Manage</button>';
654
                v += '<span style="padding: 0 0 4px 6px;"><a id="manage_in_tab" class="manage_in_tab glyphicon glyphicon-new-window" href="#home" onclick="systembuilder.system.manage_in_tab();"></a></span></span>';
655
                v += "</span></div></div>";
656
                for (i in gridItem.children) {
657
                    if (gridItem.children[i].memory && !gridItem.children[i].issystem) {
658
                        sysmemory += parseInt(gridItem.children[i].memory);
659
                        sysvcpu += parseInt(gridItem.children[i].vcpu);
660
                        images++;
661
                        if (gridItem.children[i].image2!="--") images2++;
662
                        if (gridItem.children[i].cdrom!="--") cdroms++;
663
                        networks++;
664
                        if (gridItem.children[i].networkid2!="--") networks++;
665

    
666
                        if (gridItem.children[i].status!="inactive" && gridItem.children[i].status!="shutoff") {
667
                            asysmemory += parseInt(gridItem.children[i].memory);
668
                            if (gridItem.children[i].status=="running" || gridItem.children[i].status=="paused") {
669
                                asysvcpu += parseInt(gridItem.children[i].vcpu);
670
                            }
671
                            aimages++;
672
                            if (gridItem.children[i].image2!="--") aimages2++;
673
                        }
674
                        domstatus = gridItem.children[i].status;
675
                        mac = gridItem.children[i].macname;
676
                        maccpucores = parseInt(gridItem.children[i].maccpucores);
677
                        if (domstatus!='shutoff' && domstatus!='inactive' &&
678
                                mac && mac!='--' && maccpucores && maccpucores != '--') {
679
                            if (nodesHash[mac]) {
680
                                nodesHash[mac] = nodesHash[mac]+1;
681
                            } else {
682
                                nodesHash[mac] = 1;
683
                                home.currentCores = home.currentCores+maccpucores;
684
                            }
685
                        }
686
                    }
687
                }
688
                if (gridItem.imageuuid) {
689
                    var imageItem = stores.images.fetchItemByIdentity({identity: gridItem.imageuuid});
690
                    if (imageItem) {
691
                        var serverLink = '<a href="#home" onclick="servers.grid.dialog.show(stores.servers.fetchItemByIdentity({identity:\'' + imageItem.domains + '\'}));">' + imageItem.domainnames + '</a>';
692
                        v += "<b>Administration server:</b> " + serverLink + "<br>";
693
                    }
694
                }
695
                v += "<b>Total servers:</b> " + images + " (" + sysvcpu + " vCPU" + (sysvcpu>1?"s, ":", ") +
696
                        sysmemory + " MB memory" + ")<br>";
697
                v += "<b>Active servers:</b> " + aimages + " (" + asysvcpu + " vCPU" + (asysvcpu>1?"s, ":", ") +
698
                        asysmemory + " MB memory" + ")<br>";
699
                v += "<b>Total images:</b> " + (images + images2);
700
                v += " (" + (aimages + aimages2) + " active)<br>";
701
                if (cdroms>0) v += "<b>CDs:</b> " + cdroms + ", ";
702
                if (networks>0) v += "<b>Connections:</b> " + networks + "<br>";
703
                if (user.is_admin || user.node_storage_allowed) v += "<b>Active nodes:</b>  <span title=\"" + Object.keys(nodesHash).join(", ") + "\">" + Object.keys(nodesHash).length + " (" + home.currentCores + " cores)</span><br>";
704
                home.vitals.innerHTML = v;
705
                v += "<b>Created:</b> " + home.timestampToLocaleString(gridItem.created) + "<br>";
706
                v += "<b>UUID:</b> " + gridItem.uuid + "<br>";
707
                v += '<span id="vitals_linkednetworks"></span>';
708
                home.vitals.innerHTML = v;
709
                home.totalServers = images;
710
                home.activeServers = aimages;
711
//                home.monitoringGrid.updateMissingMonitors();
712
                appid.innerHTML = "";
713

    
714
                for (var k in home.userprops) { // Set fullname, email, alertemail, etc.
715
                    var kprop = home.userprops[k];
716
                    if (gridItem[kprop] && gridItem[kprop]!="--") {
717
                        home.setFieldValue("info_"+kprop+"_field" , gridItem[kprop]);
718
                    } else if (user[kprop] && user[kprop]!="--") {
719
                        home.setFieldValue("info_"+kprop+"_field" , user[kprop]);
720
                    } else {
721
                        home.setFieldValue("info_"+kprop+"_field" , "");
722
                    }
723
                }
724
                if (gridItem.networkuuids && gridItem.networkuuids!=='--') {
725
                    home.linkedNetworks = '<b>Linked connections:</b> ';
726
                    home.updateVitals_linkednetworks(gridItem.networkuuids, gridItem.networknames);
727
                } else {
728
                    home.linkedNetworks = null;
729
                }
730

    
731
                var sysnotesval = (gridItem.notes && gridItem.notes!="--")?gridItem.notes:"";
732
                home.setNotesValue(sysnotesval, gridItem, "notes");
733
                var recoverynotesval = (gridItem.recovery && gridItem.recovery!="--")?gridItem.recovery:"";
734
                home.setNotesValue(recoverynotesval, gridItem, "recovery");
735
                document.getElementById('info_header').innerHTML = "Stack";
736
                info_name.style.display = "block";
737
                info_contacts.style.display = "block";
738
                info_security.style.display = "none";
739
                $("#info_rtfs").show();
740
                info_recovery.style.display = "block";
741
                vitals_server.style.display = "none";
742
                vitals_system.style.display = "inline";
743
                info_server.style.display = "none";
744
                info_notes.style.display = "inline";
745
                info_resettoaccountinfo_tr.style.display = "none";
746
                info_linkengine_tr.style.display = "none";
747
                info_downloadmasters_tr.style.display = "none";
748

    
749
                $(".info-services").show();
750
                $(".info-security").hide();
751
                $(".info-engine").hide();
752
                $(".info-account").hide();
753
                $(".info-system").show();
754

    
755
                var url = "/stabile/images?action=listimages"; //images&image=listall";
756
                if (stores.unusedImages2.url != url) {
757
                    stores.unusedImages2.url = url;
758
                }
759
                home.currentManagementlink = '';
760
                home.currentTerminallink = '';
761
                if (home.currentItem.imageuuid) {
762
                    $.get("/stabile/images/" + home.currentItem.imageuuid, function(item) {
763
                        home.updateManagementlink(item)
764
                    });
765
                } else {
766
                    home.updateManagementlink(null);
767
                }
768

    
769
                // Display vitals for a server
770
            } else {
771
                var serverLink = '<a href="#home" onclick="servers.grid.dialog.show(stores.servers.fetchItemByIdentity({identity: \'' + gridItem.uuid  + '\'}));">' + gridItem.name + '</a>';
772

    
773
                var imageLink = '<a href="#home" onclick="$.get(\'/stabile/images/' + gridItem.imageuuid + '\',  function(item) {home.showImageItemDialog(item)});">' + gridItem.imagename + '</a>';
774
                var image2Link = '<a href="#home" onclick="$.get(\'/stabile/images/' + gridItem.imageuuid2 + '\',  function(item) {home.showImageItemDialog(item)});">' + gridItem.image2name + '</a>';
775

    
776
                var cdrom = gridItem.cdrom;
777
                var networkLink = '<a href="#home" onclick="networks.grid.dialog.show(stores.networks.fetchItemByIdentity({identity: \'' + gridItem.networkuuid1  + '\'}));">' + gridItem.networkname1 + '</a>';
778
                var networkLink2 = '<a href="#home" onclick="networks.grid.dialog.show(stores.networks.fetchItemByIdentity({identity: \'' + gridItem.networkuuid2  + '\'}));">' + gridItem.networkname2 + '</a>';
779
                var status = gridItem.status;
780
                aimages = (status=="inactive" || status=="shutoff")?0:1;
781

    
782
                if (gridItem.cdrom && gridItem.cdrom!="--") cdrom = gridItem.cdrom.substring(gridItem.cdrom.lastIndexOf("/")+1);
783

    
784
                appstatus.innerHTML = "";
785
                appid.innerHTML = "";
786

    
787
                v = '<div id="vitalsHeader"><div style="width:97%;"><div class="row"><span class="col-sm-6" style="display:inline-block;"><h3>Server: '+ serverLink + '</h3></span><span class="col-sm-6" style="display:inline-block; text-align: right; float:right;">';
788
                v += '<span class="terminal"><button dojoType="dijit.form.Button" class="btn btn-info btn-xs" '
789
                    + ((user.is_readonly)?'disabled ':'')
790
                    + 'id="terminal_button" type="button" onclick="systembuilder.system.terminal();";>Terminal</button>';
791
                v += '<span style="padding: 0 0 4px 6px;"><a id="terminal_in_tab" class="manage_in_tab glyphicon glyphicon-new-window" href="#home" onclick="systembuilder.system.terminal_in_tab();"></a></span></span>';
792
                v += '<span class="manage_system"><button class="btn btn-success btn-xs" '
793
                    + ((user.is_readonly)?'disabled ':'')
794
                    + 'id="manage_system_button" type="button" onclick="systembuilder.system.manage();">Manage</button>';
795
                v += '<span style="padding: 0 0 4px 6px;"><a id="manage_in_tab" class="manage_in_tab glyphicon glyphicon-new-window" href="#home" onclick="systembuilder.system.manage_in_tab();"></a></span></span>';
796
                v += "</span></div></div>";
797
                v += (aimages>0?"<b>Active server:</b> ":"</h3></div><b>Inactive server</b>: ") + gridItem.vcpu + " vCPU" + (gridItem.vcpu>1?"s, ":", ") +
798
                gridItem.memory + " MB memory" + "<br>" +
799
                "<b>Primary image:</b> " + imageLink + "<br>" +
800
                (gridItem.image2=="--"?"":"<b>2nd image:</b> " + image2Link + "<br>") +
801
                (gridItem.cdrom=="--"?"":"<b>CD:</b> " + cdrom + (gridItem.boot=="hd"?"<br>":" (boot)<br>") ) +
802
                "<b>Connection:</b> " + networkLink + "<span id='vitals_network'></span><br>" +
803
                (gridItem.networkid2=="--"?"":"<b>2nd connection:</b> " + networkLink2 + "<span id='vitals_network2'></span><br>");
804
                v += '<span id="vitals_linkednetworks"></span>';
805

    
806
                if (gridItem.status!='shutoff' && gridItem.status!='inactive' &&
807
                        (user.is_admin || user.node_storage_allowed) && (gridItem.maccpucores && gridItem.maccpucores!='--'))
808
                    v += "<b>Node:</b> <span title=\"" + gridItem.mac + "\">" + gridItem.macname + " (" + gridItem.maccpucores + " cores)" + "</span><br>";
809

    
810
                v += "<b>Created:</b> " + home.timestampToLocaleString(gridItem.created) + "<br>";
811
                home.vitals.innerHTML = v;
812
                if (gridItem.networktype1 == "gateway" && gridItem.networkid1>1) {
813
                    stores.networks.fetchItemByIdentity({identity: gridItem.networkuuid1, onItem: home.updateVitals_network});
814
                    home.servicesFilter = "service: 'ping' OR service: 'diskspace'";
815
                //    stores.unusedImages2.url = url;
816
                } else if (gridItem.networkuuid1 && gridItem.networkuuid1!="0" && gridItem.networkuuid1!="1") {
817
                    stores.networks.fetchItemByIdentity({identity: gridItem.networkuuid1, onItem: home.updateVitals_network});
818
                    home.servicesFilter = "service: '*'";
819
                    var url = "/stabile/images?action=listimages"; //images&image=listall";
820
                    stores.unusedImages2.url = url;
821
                } else {
822
                    home.servicesFilter = "service: 'diskspace'";
823
                }
824

    
825
                if (gridItem.networkuuid2 && gridItem.networkuuid2!="--" &&
826
                        gridItem.networkuuid2!="0" && gridItem.networkuuid2!="1") {
827
                    stores.networks.fetchItemByIdentity({identity: gridItem.networkuuid2, onItem: home.updateVitals_network2});
828
                }
829

    
830
                if (home.info_system_field) {
831
                    home.info_system_field.set('value',gridItem.system);
832
                } else {
833
                    home.info_system_field = new dijit.form.FilteringSelect({
834
                        id: "info_system_field",
835
                        value: gridItem.system,
836
                        store: stores.systemsSelect
837
                    }, dojo.byId("info_system_field"));
838
                }
839
                if (user.is_readonly) {
840
                    if (!home.info_system_field.disabled) {
841
                        home.info_system_field.setDisabled(true);
842
                        document.getElementById("updateSystemButton").style.display = "none";
843
                    }
844
                } else {
845
                    if (home.info_system_field.disabled) {
846
                        home.info_system_field.setDisabled(false);
847
                        document.getElementById("updateSystemButton").style.display = "inline";
848
                    }
849
                }
850

    
851
                for (var j in home.userprops) { // Set fullname, email, alertemail, etc.
852
                    var uprop = home.userprops[j];
853
                    if (gridItem[uprop] && gridItem[uprop]!="--") {
854
                        home.setFieldValue("info_"+uprop+"_field" , gridItem[uprop]);
855
                    } else if (user[uprop] && user[uprop]!="--") {
856
                        home.setFieldValue("info_"+uprop+"_field" , user[uprop]);
857
                    } else {
858
                        home.setFieldValue("info_"+uprop+"_field" , "");
859
                    }
860
                }
861
                if (gridItem.networkuuids && gridItem.networkuuids!=='--') {
862
                    home.linkedNetworks = '<b>Linked connections:</b> ';
863
                    home.updateVitals_linkednetworks(gridItem.networkuuids, gridItem.networknames);
864
                } else {
865
                    home.linkedNetworks = null;
866
                }
867

    
868
                var notesval = (gridItem.notes && gridItem.notes!="--")?gridItem.notes:"";
869
                home.setNotesValue(notesval, gridItem, "notes");
870
                var recoveryval = (gridItem.recovery && gridItem.recovery!="--")?gridItem.recovery:"";
871
                home.setNotesValue(recoveryval, gridItem, "recovery");
872
                home.totalServers = 1;
873
                home.activeServers = aimages;
874
                document.getElementById('info_header').innerHTML = "Server";
875
//                home.monitoringGrid.updateMissingMonitors();
876

    
877
                info_name.style.display = "block";
878
                info_contacts.style.display = "block";
879
                info_security.style.display = "none";
880
                $("#info_rtfs").show();
881
                info_recovery.style.display = "block";
882
                vitals_server.style.display = "inline";
883
                vitals_system.style.display = "none";
884
                info_server.style.display = "inline";
885
                info_notes.style.display = "inline";
886
                info_resettoaccountinfo_tr.style.display = "none";
887
                info_linkengine_tr.style.display = "none";
888
                info_downloadmasters_tr.style.display = "none";
889

    
890
                $(".info-services").show();
891
                $(".info-security").hide();
892
                $(".info-engine").hide();
893
                $(".info-account").hide();
894
                $(".info-system").show();
895

    
896
                home.currentManagementlink = '';
897
                home.currentTerminallink = '';
898
                $.get("/stabile/images/" + home.currentItem.imageuuid, function(item) {home.updateManagementlink(item)});
899
            }
900
        },
901

    
902
        updateVitals_linkednetworks: function(networkuuids, networknames) {
903
            if (networkuuids && networkuuids!='--') {
904
                var nuuids = networkuuids.split(/, ?/);
905
                var nnames = networknames.split(/, ?/);
906
                var i;
907
                updatelinkednetwork = function(network, render) {
908
                    var networkLink = '<a onclick="networks.grid.dialog.show(stores.networks.fetchItemByIdentity({identity: \'' + network.uuid  + '\'}));">' + network.name + '</a>';
909
                    var content = networkLink;
910
                    if (!network) {
911
                        ;
912
                    } else if (network.type=="ipmapping") {
913
                        content += " (" + network.internalip +
914
                            " / <a href=\"http://" + network.externalip + "\" target=\"_blank\">" + network.externalip + "</a>)";
915
                    } else if (network.type=="externalip") {
916
                        content += " (<a href=\"http://" + network.externalip + "\" target=\"_blank\">" + network.externalip + "</a>)";
917
                    } else if (network.type=="internalip") {
918
                        content += " (" + network.internalip + ")";
919
                    }
920
                    if (network && (network.type=="ipmapping" || network.type=="externalip")) {
921
                        if (network.status == "down") {
922
                            content += " <span style=\"color:#CCCCCC\"> disabled</span>";
923
                        }
924
                    }
925
                    home.linkedNetworks += content + ", ";
926
                    if (render) {
927
                        $('#vitals_linkednetworks').html(home.linkedNetworks.slice(0,-2) + "<br>");
928
                    }
929
                };
930
                for (i = 0; i < nuuids.length; i++) {
931
                    stores.networks.fetchItemByIdentity({identity: nuuids[i], onItem: function(item) {
932
                        updatelinkednetwork(item, (i==nuuids.length-1));
933
                    }})
934
                };
935
            }
936
        },
937

    
938
        updateVitals_network: function(network) {
939
            var vitals_network = document.getElementById('vitals_network');
940
            var content = "";
941
            if (!network || !vitals_network) {
942
                ;
943
            } else if (network.type=="ipmapping") {
944
                home.currentExternalip = network.externalip;
945
                home.currentInternalip = network.internalip;
946
                content = " (" + network.internalip +
947
                        " / <a href=\"http://" + network.externalip + "\" target=\"_blank\">" + network.externalip + "</a>)";
948
            } else if (network.type=="externalip") {
949
                home.currentExternalip = network.externalip;
950
                home.currentInternalip = null;
951
                content = " (<a href=\"http://" + network.externalip + "\" target=\"_blank\">" + network.externalip + "</a>)";
952
            } else if (network.type=="internalip") {
953
                home.currentExternalip = null;
954
                home.currentInternalip = network.internalip;
955
                content = " (" + network.internalip + ")";
956
            } else {
957
                home.currentExternalip = null;
958
                home.currentInternalip = null;
959
            }
960
            if (network && (network.type=="ipmapping" || network.type=="externalip")) {
961
                if (network.status == "down" || network.status == "nat") {
962
                    content += " <span style=\"color:#CCCCCC\"> disabled</span>";
963
                }
964
            }
965
            if (vitals_network) vitals_network.innerHTML = content;
966
        },
967

    
968
        updateVitals_network2: function(network) {
969
            var vitals_network = document.getElementById('vitals_network2');
970
            var content = "";
971
            if (!network || !vitals_network) {
972
                ;
973
            } else if (network.type=="ipmapping") {
974
                content = " (" + network.internalip +
975
                        " / <a href=\"http://" + network.externalip + "\" target=\"_blank\">" + network.externalip + "</a>)";
976
            } else if (network.type=="externalip") {
977
                content = " (<a href=\"http://" + network.externalip + "\" target=\"_blank\">" + network.externalip + "</a>)";
978
            } else if (network.type=="internalip") {
979
                content = " (" + network.internalip + ")";
980
            }
981
            if (network.type=="ipmapping" || network.type=="externalip") {
982
                if (network.status == "down" || network.status == "nat") {
983
                    content += " <span style=\"color:#CCCCCC\"> disabled</span>))";
984
                }
985
            }
986
            if (vitals_network) vitals_network.innerHTML = content;
987
        },
988

    
989
        updateManagementlink: function(image) {
990
            var appstatus = document.getElementById('appstatus');
991
            var appid = document.getElementById('appid');
992
            var link = "";
993
            var tlink = "";
994
            var applink = "";
995
            var info = "";
996
            var appinfo = "";
997

    
998
            console.log("updating managementlink", image);
999
            if (image && image.appid) {
1000
                if (IRIGO.user.appstoreurl)
1001
                    applink = IRIGO.user.appstoreurl + "#app-" + image.appid;
1002
                else
1003
                    applink = "https://www.stabile.io/registry#app-" + image.appid;
1004
            }
1005
            if (image && image.managementlink && image.managementlink!='--' && home.currentItem) {
1006
                link = image.managementlink.replace(/\{uuid\}/, home.currentItem.networkuuid1);
1007
                link = link.replace(/\{externalip\}/, home.currentExternalip);
1008
                link = link.replace(/\{internalip\}/, home.currentInternalip);
1009
                if (link.indexOf("/")!=0) link = "/stabile/" + link;
1010
                //console.log("replacing", image.managementlink, home.currentItem.networkuuid1, link);
1011
            } else {
1012
                console.log("no managementlink");
1013
                home.currentManagementlink = '';
1014
            }
1015
            if (image && image.terminallink && image.terminallink!='--') {
1016
                tlink = image.terminallink.replace(/\{uuid\}/, home.currentItem.networkuuid1);
1017
                tlink = tlink.replace(/\{externalip\}/, home.currentExternalip);
1018
                tlink = tlink.replace(/\{internalip\}/, home.currentInternalip);
1019
                if (tlink.indexOf("/")!=0) tlink = "/stabile/" + tlink;
1020
                //console.log("got terminal", tlink, image.terminallink);
1021
            } else {
1022
                console.log("no terminallink");
1023
                home.currentTerminallink = '';
1024
            }
1025

    
1026
            $(".manage_system").hide();
1027
            $(".terminal").hide();
1028
            //document.getElementById("manage_system_button").style.display= 'none';
1029
            //document.getElementById("terminal_button").style.display= 'none';
1030
            if (tlink != "" && tlink != "--") {
1031
                if (home.currentItem.status == "running" || home.currentItem.status == "degraded" || home.currentItem.status == "upgrading") {
1032
                    home.currentTerminallink = tlink + "?nocache=" +  Math.random().toString(36).substring(7);
1033
                    $(".terminal").show();
1034
                    //document.getElementById("terminal_button").style.display= 'inline';
1035
                }
1036
            }
1037
            if (link != "" && link != "--") {
1038
                if (home.currentItem.status == "running" || home.currentItem.status == "degraded" || home.currentItem.status == "upgrading") {
1039
                    home.currentManagementlink = link + "?nocache=" +  Math.random().toString(36).substring(7);
1040
                    $(".manage_system").show();
1041
                    //document.getElementById("manage_system_button").style.display= 'inline';
1042
                } else {
1043
                    info = "<span style=\"color:#CCCCCC\">(Stack is currently " + home.currentItem.status + ").</span>";
1044
                    home.currentManagementlink = '';
1045
                }
1046
            }
1047
            appstatus.innerHTML = info;
1048
            if (image && image.version != "" && image.version != "--") {
1049
                appinfo = "You are running version " + image.version + " of this stack. ";
1050
            }
1051
            if (image && image.appid != "" && image.appid != "--") {
1052
                appinfo += "Read more at <a href=\"" + applink + "\" target=\"_blank\" id=\"appstorelink\">the registry</a>";
1053
            }
1054
            appid.innerHTML = appinfo;
1055
        },
1056

    
1057
        updateUptime: function() {
1058
            var param="";
1059
            if (home.currentItem && home.currentItem.issystem) {
1060
                var ym = home.currentUptimeMonth;
1061
                param = "&uuid=" + home.currentItem.uuid + "&yearmonth=" + ym + "&issystem=1";
1062
            } else {
1063
                var uuid = home.currentItem?home.currentItem.uuid:"";
1064
                var ym = home.currentUptimeMonth;
1065
                param = "&uuid=" + uuid + "&yearmonth=" + ym;
1066
            }
1067
            dojo.xhrGet({
1068
                url: "/stabile/systems?action=listuptime&format=html" + param,
1069
                load: function(response) {
1070
                    var uptime = document.getElementById("uptime");
1071
                    uptime.innerHTML = response;
1072
                }
1073
            });
1074
        },
1075

    
1076
        usageCSV: function() {
1077
            var param="";
1078
            var url="";
1079
            if (home.currentUsageMonth == "current") {
1080
                url = "/stabile/users?action=usage&format=csv";
1081
                param = home.currentItem?"&uuid="+home.currentItem.uuid:"";
1082
            } else {
1083
                url = "/stabile/users?action=usage&format=csv";
1084
                var year = home.currentUsageMonth.substr(0,4);
1085
                var month = home.currentUsageMonth.substr(5,2);
1086
                param = "&year=" + year + "&endmonth=" + month;
1087
            }
1088
            return url + param;
1089
        },
1090

    
1091
        updateUsage: function() {
1092
            var tabid;
1093
            if (dijit.byId('homeTabs')) tabid = dijit.byId('homeTabs').selectedChildWidget.id;
1094
            if (!home.currentItem) dijit.byId("usage_select").set("disabled", false);
1095
                var param="";
1096
                var url="";
1097
                if (home.currentUsageMonth == "current") {
1098
                    url = "/stabile/users?action=usagestatus&format=html";
1099
                    param = home.currentItem?"&uuid="+home.currentItem.uuid:"";
1100
                } else {
1101
                    url = "/stabile/users?action=usageavgstatus&format=html";
1102
                    var year = home.currentUsageMonth.substr(0,4);
1103
                    var month = home.currentUsageMonth.substr(5,2);
1104
                    param = "&year=" + year + "&month=" + month;
1105
                }
1106
                dojo.xhrGet({
1107
                    url: url + param,
1108
                    load: function(response) {
1109
                        var usage = document.getElementById("usage");
1110
                        usage.innerHTML = response;
1111
                    }
1112
                });
1113
                dojo.xhrGet({
1114
                    url: "/stabile/users?action=usage" + param,
1115
                    handleAs : "json",
1116
                    load: function(response) {
1117
                        var total_cost = document.getElementById("total_cost");
1118
                        if (response)
1119
                            total_cost.innerHTML = (home.currentUsageMonth == "current")?"Projected cost/month: " + response.totalcost : "Total cost for month: " + response.totalcostavg;
1120
                    }
1121
                });
1122
        },
1123

    
1124
        updateMonitoring: function() {
1125
            var tabid;
1126
            //if (dijit.byId('homeTabs')) tabid = dijit.byId('homeTabs').selectedChildWidget.id;
1127
            //if (tabid && tabid=="monitoringContentPane") {
1128
            //    console.log("updating monitoring for:", home.currentItem);
1129
                home.monitoringGrid.refresh();
1130
                if (!home.currentItem || home.currentItem.issystem) {
1131
                    $("#new_monitor_button").hide();
1132
                    //dijit.byId("new_monitor_button").set('style', 'display:none');
1133
                } else {
1134
                    $("#new_monitor_button").show();
1135
                    //dijit.byId("new_monitor_button").set('style', 'display:inline');
1136
                }
1137
                //dijit.byId('monitoringContentPane').set('style','width:500px'); // Adjust width...
1138
            //}
1139
        },
1140

    
1141
        updateOSList: function() {
1142
            var param="";
1143
            if (home.currentItem) {
1144
                param = "&uuid=" + home.currentItem.uuid;
1145
            }
1146
            dojo.xhrGet({
1147
                url: "/stabile/systems?action=register\&format=html" + param,
1148
                load: function(response) {
1149
                    var oslist = document.getElementById("oslist");
1150
                    oslist.innerHTML = response;
1151
                    $("#oslistcsv_link")[0].href ="/stabile/systems/?action=register&format=csv" + param;
1152
                }
1153
            });
1154
        },
1155

    
1156
        updatePackages: function() {
1157
            home.updateOSList();
1158
            var param="";
1159
            if (home.currentItem) {
1160
                param = "&uuid=" + home.currentItem.uuid;
1161
            }
1162
            dojo.xhrGet({
1163
                url: "/stabile/systems?action=packages\&format=html" + param,
1164
                load: function(response) {
1165
                    var packs = document.getElementById("packages");
1166
                    packs.innerHTML = response;
1167
                    $("#packlistcsv_link")[0].href ="/stabile/systems/?action=packages&format=csv" + param;
1168
                }
1169
            });
1170
        },
1171

    
1172
        loadPackages: function() {
1173
            if (home.currentItem) {
1174
                var data = {
1175
                    "items": [{uuid:home.currentItem.uuid, action:"load", issystem:home.currentItem.issystem}]
1176
                };
1177
                $("#load_packages").prop("disabled", true).html('Scanning&hellip; <i class="fa fa-cog fa-spin"></i>');;
1178
                $("#clear_packages").prop("disabled", true);
1179
                dojo.xhrPost({
1180
                    url: "/stabile/systems?action=packages", // + (ui_update.session?"&s="+ui_update.session:""),
1181
                    postData: dojo.toJson(data),
1182
                    load: function(response){
1183
                        home.updatePackages();
1184
                        server.parseResponse(response);
1185
                        $("#load_packages").prop("disabled", false).html('Rescan server(s)&hellip;');
1186
                        if (!user.is_readonly) $("#clear_packages").prop("disabled", false);
1187
                    },
1188
                    error: function(error){
1189
                        $("#load_packages").prop("disabled", false).html('Rescan server(s)&hellip;');
1190
                        $("#clear_packages").prop("disabled", false);
1191
                        er("grid::actionHandler", error);
1192
                    }
1193
                });
1194
            }
1195
        },
1196

    
1197
        clearPackages: function() {
1198
            var data;
1199
            if (home.currentItem) {
1200
                data = {
1201
                    "items": [{uuid:home.currentItem.uuid, action:"remove", issystem:home.currentItem.issystem}]
1202
                };
1203
            } else {
1204
                data = {
1205
                    "items": [{uuid:"*", action:"remove", issystem:1}]
1206
                };
1207
            }
1208

    
1209
            dojo.xhrPost({
1210
                url: "/stabile/systems?action=packages", // + (ui_update.session?"&s="+ui_update.session:""),
1211
                postData: dojo.toJson(data),
1212
                load: function(response){
1213
                    home.updatePackages();
1214
                    server.parseResponse(response);
1215
                },
1216
                error: function(error){
1217
                    er("grid::actionHandler", error);
1218
                }
1219
            });
1220
        },
1221

    
1222
        showImageItemDialog: function(item) {
1223
            if (images.grid.dialog) {
1224
                images.grid.dialog.show(item);
1225
            } else {
1226
                console.log("Error - no image dialog");
1227
            }
1228
        },
1229

    
1230
        showImageDialog: function(path) {
1231
            if (path == null && servers.grid.dialog) {
1232
                path = servers.grid.dialog.item.image;
1233
            } else if (path == null && images.grid.dialog) {
1234
                path = images.grid.dialog.item.master;
1235
            }
1236
            // var url = "/stabile/images?action=list"; //images&image=listall";
1237
            // if (stores.unusedImages2.url != url) {
1238
            //     stores.unusedImages2.url = url;
1239
            //     stores.unusedImages2.close();
1240
            // }
1241

    
1242
            // We need to translate the image path from server info to an image uuid
1243
            // unusedImages2 uses path as identifier
1244
            $.get('/stabile/images/?path=' + encodeURIComponent(path) ,function(item) {home.showImageItemDialog(item)});
1245

    
1246
            // stores.unusedImages2.fetchItemByIdentity({identity: path, onItem: function(item0) {
1247
            //     // images uses uuid as identifier
1248
            //     stores.images.fetchItemByIdentity({identity: item0.uuid, onItem: function(item) {
1249
            //         if (images.grid.dialog) {
1250
            //             images.grid.dialog.show(item);
1251
            //         } else {
1252
            //             home.imagesOnShowItem = item;
1253
            //             dijit.byId('tabs').selectChild(dijit.byId('images'));
1254
            //         }
1255
            //     }});
1256
            // }});
1257
        },
1258

    
1259
/*
1260
        showDialog: function(uuid, type) {
1261
            if (uuid == null) {
1262
                var ids;
1263
                if (type == "serverimage") {
1264
                    ids = images.grid.dialog.item.domains;
1265
                    type = "servers";
1266
                } else if (type == "networkimage") {
1267
                    ids = networks.grid.dialog.item.domains;
1268
                    type = "servers";
1269
                } else if (type == "image2server") {
1270
                    ids = servers.grid.dialog.item.image2;
1271
                    type = "images";
1272
                } else if (type == "network1server") {
1273
                    ids = servers.grid.dialog.item.networkuuid1;
1274
                    type = "networks";
1275
                } else if (type == "network2server") {
1276
                    ids = servers.grid.dialog.item.networkuuid2;
1277
                    type = "networks";
1278
                } else if (type == "nodeserver") {
1279
                    ids = servers.grid.dialog.item.mac;
1280
                    type = "nodes";
1281
                } else if (type == "nodeimage") {
1282
                    ids = images.grid.dialog.item.mac;
1283
                    type = "nodes";
1284
                }
1285
                if (ids.indexOf(", ")!=-1) ids = ids.substring(0,ids.indexOf(", "));
1286
                uuid = ids;
1287
            }
1288

    
1289
            require(['stabile/' + type, 'stabile/menu'], function(grid, menu){
1290
                stores[type].fetchItemByIdentity({identity: uuid, onItem: function(item) {
1291
                   var pane = menu[type + 'Pane'];
1292
                   if(!pane.isLoaded){
1293
                       // init the server grid and dialog
1294
                       var tabs = menu.tabs;
1295
                       var h = connect.connect(grid, 'init', function(evt) {
1296
                           grid.grid.dialog.show(item);
1297
                           dojo.disconnect(h);
1298
                       });
1299
                       tabs.selectChild(pane);
1300
                    }
1301
                    else{
1302
                        grid.grid.dialog.show(item);
1303
                    }
1304
                }});
1305
            });
1306
        },
1307
*/
1308

    
1309
        deviceHandler: function(item_id, action) {
1310
            var dev = dijit.byId(item_id).get("value");
1311
            var stortype = "backup";
1312
            if (action.indexOf("format")==0) {
1313
                if (action=="formatimagesdevice") stortype = "images";
1314
                $("#info_" + stortype + "zfs_button").html('Formatting&hellip; <i class="fa fa-cog fa-spin"></i>').prop("disabled", true);
1315
                var url = "/stabile/images?action=initializestorage&activate=1&type=" + stortype;
1316
                console.log("configuring storage...", dev, action, stortype);
1317
                url += "&device=" + dev;
1318
                $.get(url, function(response) {
1319
                    if (response.indexOf("Status=OK")==0) {
1320
                        home.user[stortype + "device"] = dev;
1321
                        if (stortype=="backup") {
1322
                            home.toggleBackupButtons(dijit.byId("info_backupdevice_field"));
1323
                            stores.backupDevices.close();
1324
                            dijit.byId("info_backupdevice_field").setStore(stores.backupDevices);
1325
                        } else {
1326
                            home.toggleImagesButtons(dijit.byId("info_imagesdevice_field"));
1327
                            stores.imagesDevices.close();
1328
                            dijit.byId("info_imagesdevice_field").setStore(stores.imagesDevices);
1329
                        }
1330
                        home.user.load();
1331
                    } else if (response.toLowerCase().indexOf("status=error")==0) {
1332
                        IRIGO.toast(response.substring(12));
1333
                        dijit.byId("info_backupdevice_field").setStore(stores.backupDevices);
1334
                        dijit.byId("info_imagesdevice_field").setStore(stores.imagesDevices);
1335
                    }
1336
                    $("#info_" + stortype + "zfs_button").html('Format this device').prop("disabled", false)
1337
                });
1338
            } else {
1339
                if (action=="setimagesdevice") stortype = "images";
1340
                $("#info_" + stortype + "device_button").html('Configuring&hellip; <i class="fa fa-cog fa-spin"></i>').prop("disabled", true);
1341
                var url = "/stabile/images?action=setstoragedevice&type=" + stortype;
1342
                console.log("configuring storage...", dev, action, stortype);
1343
                url += "&device=" + dev;
1344
                $.get(url, function(response) {
1345
                    if (response.indexOf("Status=OK")==0) {
1346
                        home.user[stortype + "device"] = dev;
1347
                        if (stortype=="backup") {
1348
                            home.toggleBackupButtons(dijit.byId("info_backupdevice_field"));
1349
                            stores.backupDevices.close();
1350
                            dijit.byId("info_backupdevice_field").setStore(stores.backupDevices);
1351
                        } else {
1352
                            home.toggleImagesButtons(dijit.byId("info_imagesdevice_field"));
1353
                            stores.imagesDevices.close();
1354
                            dijit.byId("info_imagesdevice_field").setStore(stores.imagesDevices);
1355
                        }
1356
                        home.user.load();
1357
                    } else if (response.toLowerCase().indexOf("status=error")==0) {
1358
                        IRIGO.toast(response.substring(12));
1359
                        dijit.byId("info_backupdevice_field").setStore(stores.backupDevices);
1360
                        dijit.byId("info_imagesdevice_field").setStore(stores.imagesDevices);
1361
                    }
1362
                    $("#info_" + stortype + "device_button").html('Use this device').prop("disabled", false)
1363
                });
1364
            }
1365
        },
1366

    
1367
        toggleImagesButtons: function(item) {
1368
            var label = item._getSelectedOptionsAttr().label;
1369
            $("#info_imagesdevice_button").toggle(home.user.imagesdevice!=item.get("value") && (label.indexOf("not mounted")==-1 || label.indexOf("zfs")!=-1));
1370
            $("#info_imageszfs_button").toggle(home.user.imagesdevice!=item.get("value") && label.indexOf("not mounted")!=-1);
1371
        },
1372
        toggleBackupButtons: function(item) {
1373
            var label = item._getSelectedOptionsAttr().label;
1374
            $("#info_backupdevice_button").toggle(home.user.backupdevice!=item.get("value") && (label.indexOf("not mounted")==-1 || label.indexOf("zfs")!=-1));
1375
            $("#info_backupzfs_button").toggle(home.user.backupdevice!=item.get("value") && label.indexOf("not mounted")!=-1);
1376
        }
1377

    
1378
    };
1379

    
1380
    home.charts = {
1381
    };
1382

    
1383
    home.createRegisterGrid = function(domId){
1384
        var layout = [
1385
            {
1386
                field: 'name',
1387
                name: 'Name',
1388
                width: '100px'
1389
            },
1390
            {
1391
                field: 'hostname',
1392
                name: 'Hostname',
1393
                width: '100px'
1394
            },
1395
            {
1396
                field: 'os',
1397
                name: 'OS',
1398
                width: '200px'
1399
            }
1400
        ];
1401

    
1402
        // create a new grid:
1403
        var grid = new dojox.grid.DataGrid({
1404
            store : stores.register,
1405
            structure : layout,
1406
            selectionMode: "single",
1407
            keepSelection: true,
1408
         //   sortInfo: 1,
1409
            autoHeight : true,
1410
            rowsPerPage: 2000,
1411
            clientSort: true
1412
        });
1413

    
1414
        grid.name = 'register';
1415

    
1416
        grid.refresh = function(){
1417
            var filter;
1418
            if (home.currentItem) {
1419
                if (home.currentItem.issystem) {
1420
                    filter = {uuid: home.currentItem.uuid};
1421
                } else {
1422
                    filter = {uuid: home.currentItem.uuid};
1423
                }
1424
            } else {
1425
                filter = {uuid: '*'};
1426
            }
1427
            //console.log("filtering", home.currentItem, filter);
1428
            grid.filter(filter, true);
1429
        };
1430

    
1431
        dojo.byId(domId).appendChild(grid.domNode);
1432
        grid.startup();
1433
        return grid;
1434
    }
1435

    
1436

    
1437
    home.createPackagesGrid = function(domId){
1438
        var layout = [
1439
            {
1440
                field: 'app_display_name',
1441
                name: 'Application',
1442
                width: '150px'
1443
            },
1444
            {
1445
                field: 'app_version',
1446
                name: 'Version',
1447
                width: '100px'
1448
            },
1449
            {
1450
                field: 'app_publisher',
1451
                name: 'Publisher',
1452
                width: '150px'
1453
            }
1454
        ];
1455

    
1456
        // create a new grid:
1457
        var grid = new dojox.grid.DataGrid({
1458
            store : stores.packages,
1459
            structure : layout,
1460
            selectionMode: "single",
1461
            keepSelection: true,
1462
            sortInfo: 1,
1463
            autoHeight : true,
1464
            rowsPerPage: 2000,
1465
            clientSort: true
1466
        });
1467

    
1468
        grid.name = 'packages';
1469

    
1470
        grid.loadPackages = function(){
1471
            if (home.currentItem) {
1472
                var data = {
1473
                    "items": [{uuid:home.currentItem.uuid, action:"load"}]
1474
                };
1475

    
1476
                dojo.xhrPost({
1477
                    url: "/stabile/systems?action=packages", // + (ui_update.session?"&s="+ui_update.session:""),
1478
                    postData: dojo.toJson(data),
1479
                    load: function(response){
1480
                        grid.refresh();
1481
                        server.parseResponse(response);
1482
                    },
1483
                    error: function(error){
1484
                        er("grid::actionHandler", error);
1485
                    }
1486
                });
1487
            }
1488
        }
1489

    
1490
        grid.refresh = function(){
1491
            var filter;
1492
            if (home.currentItem) {
1493
                filter = {uuid: home.currentItem.uuid};
1494
            } else {
1495
                filter = {uuid: '*'};
1496
            }
1497
            grid.filter(filter, true);
1498
        };
1499

    
1500
        dojo.byId(domId).appendChild(grid.domNode);
1501
        grid.startup();
1502
        return grid;
1503
    }
1504

    
1505
//** MONITORING GRID **//
1506

    
1507
    home.createMonitoringGrid = function(domId){
1508
        var layout = [
1509
            {
1510
                field: 'opstatus',
1511
                name: 'Opstatus',
1512
                hidden: true
1513
                //formatter: function(val, rowIdx, cell) {
1514
                //    var item = home.monitoringGrid.getItem(rowIdx);
1515
                //    return ((item.status=="disabled")?7:item.opstatus);
1516
                //}
1517
            },
1518
            {
1519
                field: 'id',
1520
                name: 'ID',
1521
                hidden: true
1522
            },
1523
            {
1524
                field: 'servername',
1525
                name: 'Server',
1526
                width: '140px'
1527
            },
1528
            {
1529
                field: 'service',
1530
                name: 'Service',
1531
                width: '80px'
1532
            },
1533
            {
1534
                field: 'status',
1535
                name: 'Status',
1536
                width: '60px'
1537
            },
1538
            {
1539
                field: 'last_check',
1540
                name: 'Last check',
1541
                formatter: timestampToTime,
1542
                width: '80px'
1543
            },
1544
            {
1545
                field: 'action',
1546
                name: 'Action',
1547
                width: '120px',
1548
                formatter: function(val, rowIdx, cell) {
1549
                    if (home.monitoringGrid) {
1550
                        var item = home.monitoringGrid.getItem(rowIdx);
1551
                        return home.monitoringGrid.getActionButtons(item);
1552
                    }
1553
                }
1554
            }
1555
        ];
1556

    
1557
        // create a new grid:
1558
        var grid = new dojox.grid.DataGrid({
1559
            store : stores.monitors,
1560
            structure : layout,
1561
            selectionMode: "single",
1562
            keepSelection: false,
1563
            sortInfo: 4,
1564
            autoHeight : false,
1565
            rowsPerPage: 2000,
1566
            height: "210px",
1567
            clientSort: true
1568
        });
1569

    
1570
        grid.name = 'monitors';
1571
        grid.currentServer = null;
1572

    
1573
        grid.dialogStructure = [
1574
            { field: "servername", name: "Server", type: "dijit.form.TextBox", attrs : {readonly :"readonly"}},
1575
            { field: "serveruuid", name: "Server uuid", type: "dijit.form.TextBox", attrs : {readonly :"readonly"}},
1576
            {
1577
                field:"service",
1578
                name:"Service",
1579
                type: "dijit.form.Select",
1580
                attrs:{ store: "stores.monitorsServices", searchAttr:"service", onChange: "home.monitoringGrid.adaptDialog(this.value);"}
1581
            },
1582
            { field: "email", name: "Alert email", type: "dijit.form.TextBox", required: true, attrs : {readonly :"readonly"}},
1583
            { field: "serverip", name: "IP address", type: "dijit.form.TextBox", attrs : {readonly :"readonly"}, style: "width: 120px;"},
1584
            { field: "port", name: "Port", type: "dijit.form.TextBox", style: "width: 40px;"},
1585
            { field: "request", name: "Request", type: "dijit.form.TextBox"},
1586
            { field: "okstring", name: "Look for", type: "dijit.form.TextBox"},
1587
            { field: "status", name: "Status", type: "dijit.form.TextBox" , attrs : {readonly :"readonly"}, style: "width: 40px;" },
1588
            { field: "last_detail", name: "Last result", type: "dijit.form.SimpleTextarea" ,
1589
                attrs : {readonly :"readonly"}, style: "height: 90px"
1590
            },
1591
            { field: "last_check", name: "Last check", type: "dijit.form.TextBox" , attrs : {readonly :"readonly"} },
1592
            { field: "first_failure", name: "Down since", type: "dijit.form.TextBox" , attrs : {readonly :"readonly"} },
1593
            { field: "desc", name: "Notes", type: "dijit.form.SimpleTextarea" ,
1594
                style: "height: 40px",
1595
                attrs : (user.is_readonly?{readonly :"readonly"}:{})
1596
            },
1597
            { field: "ack", name: "Acknowledged", type:  "dijit.form.TextBox", attrs : {readonly :"readonly"} },
1598
            { field: "ackcomment", name: "Ack.comment", type:  "dijit.form.TextBox",
1599
                attrs : (user.is_readonly?{readonly :"readonly"}:{})
1600
            }
1601
        ];
1602

    
1603
        grid.model = function(args){
1604
            var email = home.currentItem.alertemail;
1605
            if (!email || email == "" || email == "--") email = user.alertemail;
1606
            if (!email || email == "" || email == "--") email = home.currentItem.opemail;
1607
            if (!email || email == "" || email == "--") email = user.opemail;
1608
            if (!email || email == "" || email == "--") email = home.currentItem.email;
1609
            if (!email || email == "" || email == "--") email = user.email;
1610
            var serverip = home.currentInternalip;
1611
            if (!serverip  || serverip == '--') serverip = home.currentExternalip;
1612
            if (serverip == '--') serverip = '';
1613
            return dojo.mixin(
1614
                    {
1615
                        opstatus: "new",
1616
                        status: "new",
1617
                        id: home.currentItem.uuid + ":ping",
1618
                        desc: "",
1619
                        service: "ping",
1620
                        email: email,
1621
                        serverip: serverip,
1622
                        serveruuid: home.currentItem.uuid,
1623
                        servername: home.currentItem.name,
1624
                        port:'',
1625
                        request:'',
1626
                        okstring: ''
1627
                    //    last_check: Math.round((new Date())/1000)
1628
                    }, args || {});
1629
        }
1630

    
1631
        grid.actionButton = function(args){
1632
            var actionHandler;
1633
            args.title = args.title || args.action;
1634
            if(args.confirm){
1635
                actionHandler = "grid.actionConfirmDialog('" + args.id + "','" + args.action + "','" + args.name + "','" + args.title + "','" + args.type + "', 'home.monitoringGrid.actionHandler')";
1636
            }
1637
            else{
1638
                actionHandler = "home.monitoringGrid.actionHandler('" + args.id + "','" + args.action + "','" + args.type + "')";
1639
            }
1640
            // left out button text intentionally since image replacement didn't work out in IE
1641
            var t = '<button type="button" title="${title}" class="action_button ${action}_icon" id="${action}_${id}" onclick="${actionHandler};return false;"><span>${action}</span></button>';
1642
            args.actionHandler = actionHandler;
1643
            return dojo.string.substitute(t, args);
1644
        }
1645

    
1646
        grid.saveButton = function(type){
1647
            // returning false, to disable form submit
1648
            var actionHandler = "home.monitoringGrid.saveHandler('" + type + "'); return false;";
1649
            var t = '<button type="submit" title="Save" class="btn btn-sm btn-success pull-right" onclick="${actionHandler}">'
1650
                    + '<span>save</span></button>';
1651
            return dojo.string.substitute(t, {'actionHandler':actionHandler});
1652
        }
1653

    
1654
        grid.saveHandler = function(type) {
1655
            //grid.store.changing(grid.dialog.item);
1656
            grid.dialog.save();
1657
        }
1658

    
1659
        grid.actionHandler = function(id, action, type) {
1660
            var item = grid.store.fetchItemByIdentity({
1661
                identity: id,
1662
                onItem: function(item, request){
1663
                    if (action == 'delete') {
1664
                        //grid.store.changing(item);
1665
                        //grid.store.reset(item.id);
1666
                        grid.store.deleteItem(item);
1667
                        grid.store.save();
1668
                        home.updateUptime();
1669
                    } else {
1670
                        var data;
1671
                        var ackcomment = dojo.byId("ackcomment");
1672
                        if (action == 'acknowledge' && ackcomment && ackcomment.value) {
1673
                            data = {
1674
                                "items": [{id:id, action: action, ackcomment: ackcomment.value}]
1675
                            };
1676
                        } else {
1677
                            data = {
1678
                                "items": [{id:id, action: action}]
1679
                            };
1680
                        }
1681
                        // send action to server
1682
                        dojo.xhrPost({
1683
                        //    url: "/stabile/systems/monitors/?id=" + id, // + (ui_update.session?"&s="+ui_update.session:""),
1684
                            url: "/stabile/systems/monitors/" + id,
1685
                            postData: dojo.toJson(data),
1686
                            load: function(response){
1687
                                if (action=="disable" && response.indexOf("OK disable")!=-1) {
1688
                                    item.status = "disabled";
1689
                                    item.opstatus = "9";
1690
                                    grid.sort();
1691
                                } else if (action=="enable" && response.indexOf("OK enable")!=-1) {
1692
                                    item.status = "checking";
1693
                                    item.opstatus = "";
1694
                                    grid.sort();
1695
                                } else if (action=="acknowledge" && response.indexOf("OK acknowledge")!=-1) {
1696
                                    grid.refresh();
1697
                                }
1698
                                server.parseResponse(response);
1699
                            },
1700
                            error: function(error){
1701
                                er("grid::actionHandler", error);
1702
                            }
1703
                        });
1704
                        dojo.publish(type + ":" + action, [item]);
1705
                    }
1706
                }
1707
            });
1708

    
1709
            if(grid.dialog.isOpen()){grid.dialog.hide();}
1710
        }
1711

    
1712
        grid.itemClickHandler = function(event){
1713
            var item = home.monitoringGrid.selection.getSelected()[0];
1714
            if(!item){ // e.g. click on header
1715
                return;
1716
            }
1717
            if(event && event.cell && event.cell.field == 'action'){
1718
                ;
1719
            } else {
1720
                home.monitoringGrid.dialog.show(item);
1721
            }
1722
        };
1723

    
1724
        grid.onBeforeSave = function(item) {
1725
            if (item.status == "new") {
1726
                item.id = item.serveruuid + ":" + item.service;
1727
                item.status = 'checking';
1728
            }
1729
        }
1730

    
1731
        grid.adaptDialog = function(service) {
1732
            document.getElementById("requestlabel").innerHTML = "Request";
1733
            document.getElementById("okstringlabel").innerHTML = "Look for";
1734
            if (service == "ping") {
1735
                grid.hideRow("portlabel");
1736
                grid.hideRow("requestlabel");
1737
                grid.hideRow("okstringlabel");
1738
                grid.showRow("serveriplabel");
1739
            } else if (service == "imap" || service == "imaps") {
1740
                grid.showRow("portlabel");
1741
                grid.hideRow("requestlabel");
1742
                grid.hideRow("okstringlabel");
1743
                grid.showRow("serveriplabel");
1744
            } else if (service == "ldap") {
1745
                document.getElementById("requestlabel").innerHTML = "Base DN";
1746
                document.getElementById("okstringlabel").innerHTML = '<a href="https://www.origo.io/info/stabiledocs/web/dashboard/monitoring-tab/ldap/" rel="help" target="_blank" class="irigo-tooltip">help</a>' + "Attribute to look for";
1747
                grid.showRow("portlabel");
1748
                grid.showRow("requestlabel");
1749
                grid.showRow("okstringlabel");
1750
                grid.showRow("serveriplabel");
1751
            } else if (service == "telnet") {
1752
                grid.showRow("portlabel");
1753
                grid.hideRow("requestlabel");
1754
                grid.showRow("okstringlabel");
1755
                grid.showRow("serveriplabel");
1756
            } else if (service == "smtp" || service == "smtps") {
1757
                document.getElementById("requestlabel").innerHTML = "From";
1758
                document.getElementById("okstringlabel").innerHTML = "To";
1759
                grid.showRow("portlabel");
1760
                grid.showRow("okstringlabel");
1761
                grid.showRow("requestlabel");
1762
                grid.showRow("serveriplabel");
1763
            } else if (service == "diskspace") {
1764
                document.getElementById("requestlabel").innerHTML = "Min. free %";
1765
                document.getElementById("okstringlabel").innerHTML = '<a href="https://www.origo.io/info/stabiledocs/web/dashboard/monitoring-tab/partitions/" rel="help" target="_blank" class="irigo-tooltip">help</a>' + "Partitions";
1766
                grid.hideRow("portlabel");
1767
                grid.hideRow("serveriplabel");
1768
                grid.showRow("okstringlabel");
1769
                grid.showRow("requestlabel");
1770
            } else {
1771
                grid.showRow("portlabel");
1772
                grid.showRow("okstringlabel");
1773
                grid.showRow("requestlabel");
1774
                grid.showRow("serveriplabel");
1775
            }
1776
            if (home.currentItem && home.currentItem.networktype1 == 'gateway') {
1777
                $("#serverip").prop("readonly", false);
1778
            } else {
1779
                $("#serverip").prop("readonly", true);
1780
            }
1781
            q = dojo.query('.irigo-tooltip'); q.irigoTooltip && q.irigoTooltip();
1782
        }
1783

    
1784
        grid.onDialogButtons = function(item){
1785
            // helpers
1786
            var hide = function(dijitId){
1787
                var elm = dijit.byId(dijitId);
1788
                elm && elm.set('style', 'display:none');
1789
                return elm;
1790
            };
1791
            var show = function(dijitId){
1792
                var elm = dijit.byId(dijitId);
1793
                elm && elm.set('style', 'display:inline');
1794
                return elm;
1795
            };
1796
            var disable = function(dijitId){
1797
                var elm = dijit.byId(dijitId);
1798
                elm && elm.set('disabled', true);
1799
                return elm;
1800
            };
1801
            var enable = function(dijitId){
1802
                var elm = dijit.byId(dijitId);
1803
                elm && elm.set('disabled', false);
1804
                return elm;
1805
            };
1806
            var hideRow = grid.hideRow = function(domId){
1807
                // tr <- td <- input
1808
                dojo.query('#' + domId).parent().parent().style({display:"none"});
1809
            };
1810
            var showRow = grid.showRow = function(domId){
1811
                dojo.query('#' + domId).parent().parent().style({display: "table-row"});
1812
            };
1813
            var last_check = dojo.byId("last_check");
1814
            if (last_check) last_check.value = timestampToDatetime(item.last_check);
1815
            if (item.opstatus==0) {
1816
                var first_failure = dojo.byId("first_failure");
1817
                if (first_failure) first_failure.value = timestampToDatetime(item.first_failure);
1818
            } else {
1819
                hideRow("first_failurelabel");
1820
            }
1821
            if (item.opstatus>0) {
1822
                hideRow("ackcommentlabel");
1823
                hideRow("acklabel");
1824
            }
1825
            var ack = dojo.byId("ack");
1826
            if (ack) {
1827
                if (ack.value>0) {
1828
                    ack.value = timestampToDatetime(item.ack);
1829
                    disable("ackcomment");
1830
                } else {
1831
                    hideRow("acklabel");
1832
                }
1833
            }
1834

    
1835
            if(item.status == "new"){
1836
                hideRow("last_detail");
1837
                hideRow("last_checklabel");
1838
                hideRow("acklabel");
1839
                hideRow("ackcommentlabel");
1840
            } else {
1841
                disable("service");
1842
            }
1843

    
1844
            var service = dijit.byId('service');
1845
            if (service) {
1846
                // "service: 'http' OR service: 'ping'"
1847
                service.setStore(stores.monitorsServices, service.value, {query:home.servicesFilter});
1848
                //service.setStore(stores.monitorsServices, service.value, {query:home.servicesFilter});
1849
            }
1850
        }
1851

    
1852
        grid.refresh = function(){
1853
            var filter;
1854
        //    if (!home.currentItem) home.currentItem = home.grid.selection.getSelected()[0];
1855
            if (home.currentItem && home.currentItem.issystem) {
1856
                grid.store.clearCache();
1857
                filter = {system: home.currentItem.uuid};
1858
            } else if (home.currentItem) {
1859
                filter = {serveruuid: home.currentItem.uuid};
1860
            } else {
1861
                filter = {id: '*'};
1862
            }
1863
//            console.log("filtering:", filter);
1864
            grid.store.reset();
1865
            grid.filter(filter, true);
1866
            grid.updateMissingMonitors(filter);
1867
        };
1868

    
1869
        grid.updateMissingMonitors = function(filter) {
1870
            var tabid;
1871
            if (dijit.byId('homeTabs')) tabid = dijit.byId('homeTabs').selectedChildWidget.id;
1872

    
1873
            if (tabid=="monitoringContentPane") {
1874
                if (!filter) filter = {id: '*'};
1875
                grid.store.fetch({query:filter, onComplete: function(result){
1876
                    var pingmonitors=0;
1877
                    var diskmonitors=0;
1878
                    var pingmonitors_list="";
1879
                    var diskmonitors_list="";
1880
                    for (var i in result) {
1881
                        if (result[i].status!="inactive" && result[i].status!="shutoff") {
1882
                            if (result[i].service == "ping") {
1883
                                pingmonitors++;
1884
                            }
1885
                            if (result[i].service == "diskspace") {
1886
                                diskmonitors++;
1887
                            }
1888
                        }
1889
                    }
1890
                    var v = "";
1891
                    var ns = home.activeServers;
1892
                    if (ns-pingmonitors>0 || ns-diskmonitors>0) {
1893
                        v = "<span style=\"color:red;\"><span style=\"font-weight:bold;\">Missing monitors: </span>";
1894
                        if (ns-pingmonitors>0) v += "<span title=\"" + pingmonitors_list + "\">" + (ns-pingmonitors) + " ping</span>";
1895
                        if (ns-diskmonitors>0) v += ((ns-pingmonitors>0)?", ":"") + "<span title=\"" + diskmonitors_list + "\">" + (ns-diskmonitors) + " diskspace</span>";
1896
                        v += "</span>";
1897
                    }
1898
                    home.missingmonitors.innerHTML = v;
1899
                }});
1900
            }
1901
        }
1902

    
1903
        grid.save = function(args) {
1904
            if(grid.store.isDirty()){
1905
                grid.store.save({
1906
                    onComplete: function(res){
1907
                        if (!grid.store.isDirty()) {
1908
                            grid.refresh();
1909
                        }
1910
                        if(args.onComplete){
1911
                            args.onComplete();
1912
                        }
1913
                    },
1914
                    onError: function(e){
1915
                        console.log("ERROR saving", e);
1916
                        // Most likely error
1917
                        IRIGO.toast("Please use a valid IP address");
1918
                        grid.refresh();
1919
                    }
1920
                });
1921
            }
1922
            else{
1923
                IRIGO.toaster([{
1924
                    message: "Nothing new to commit!",
1925
                    type: "message",
1926
                    duration: 3000
1927
                }]);
1928
            }
1929
        }
1930

    
1931
        grid.getActionButtons = function(item, include_save){
1932
            if (user.is_readonly) return "";
1933
            var id = item.id;
1934
            var opstatus = item.opstatus;
1935
            var status = item.status;
1936
            var save = include_save ? grid.saveButton('monitor') : "";
1937

    
1938
            var delete_button = grid.actionButton({'action':"delete", 'id':id, 'confirm': false,
1939
                'name': item.name + ' on ' + item.servername, actionHandler: home.monitoringGrid.actionHandler,
1940
                    'title': 'delete', 'type': 'monitor'});
1941

    
1942
            var enable = grid.actionButton({'action':"enable", 'id':id, 'type': 'monitor'});
1943
            var disable = grid.actionButton({'action':"disable", 'id':id, 'type': 'monitor'});
1944
            var acknowledge = grid.actionButton({'action':"acknowledge", 'id':id, 'type': 'monitor'});
1945

    
1946
            var buttons = "";
1947
            if (status != "new") {
1948
                if (status == "disabled") buttons += enable;
1949
                else buttons += disable;
1950
                buttons += delete_button;
1951
            }
1952
            if (opstatus==0 && item.ack==0 && !item.checking) {
1953
                buttons += acknowledge;
1954
            }
1955
            buttons += save;
1956
            return buttons;
1957
        }
1958

    
1959
        grid.dialog = griddialog(grid);
1960

    
1961
        grid.newItem = function() {
1962
            var model = grid.model();
1963
            grid.dialog.show(model);
1964
        }
1965

    
1966
        grid.refreshRow = function(task, idprop) {
1967
            if (!idprop) idprop = "id";
1968
            grid.store.fetchItemByIdentity({identity: task[idprop],
1969
                onItem: function(item){
1970
                   for (var key in task) {
1971
                       if (key=='id' || key=='sender' || key=='timestamp' || key=='type' || key=='uuid') {;}
1972
                       else if (item[key]) {
1973
                            item[key] = task[key];
1974
                       }
1975
                   }
1976
                   grid.store.save();
1977
                   grid.refresh();
1978
// This does for some reason not work reliably - we update entire table instead.
1979
/*
1980
                   var i = grid.getItemIndex(item);
1981
                   console.log("refreshing monitor " + i + " " + statusColorMap.get(item.status), task, item);
1982
                   grid.updateRowStyles(i);
1983
                   grid.updateRow(i);
1984
                   dojo.setStyle(grid.getRowNode(i), "color", statusColorMap.get(item.status)); // ugly
1985
                   grid.render();
1986
*/
1987
                }
1988
            });
1989
        };
1990

    
1991
        grid.onStyleRow = function(row){
1992
            row.customStyles = "cursor:pointer;";
1993
            var item = grid.getItem(row.index);
1994
            if(item){
1995
                var status = item.status;
1996
                var color = statusColorMap.get(status);
1997
                row.customStyles += "color:" + color + ";";
1998
            }
1999
        };
2000
        dojo.byId(domId).appendChild(grid.domNode);
2001
        grid.startup();
2002

    
2003
        return grid;
2004
    }
2005

    
2006
//** SYSTEMS GRID **//
2007

    
2008
    home.createStatusGrid = function(domId){
2009

    
2010
        var layout = [
2011
            //{
2012
            //    type: "dojox.grid._CheckBoxSelector",
2013
            //    width: '10%'
2014
            //},
2015
            {
2016
                field: '_item',
2017
                name: 'Name',
2018
                width: (230+(user.is_readonly?80:0)) + 'px',
2019
                formatter: serverFormatters.viewerName
2020
            },
2021
            /*{
2022
                field: 'name',
2023
                name: 'Name',
2024
                width: 'auto',
2025
                editable: true
2026
            },*/
2027
            {
2028
                field: '_item',
2029
                name: 'Status',
2030
                width: '70px',
2031
                formatter: function(val, rowIdx) {
2032
                    if (val.issystem) {
2033
                        var inistatus;
2034
                        var status;
2035
                        var degraded = false;
2036
                        for (l in val.children) {
2037
                            status = val.children[l].status;
2038
                            if (status && !val.children[l].issystem) {
2039
                                if (!inistatus) inistatus = status;
2040
                                if (status != inistatus
2041
                                        && !(status+inistatus=='shutoffinactive')
2042
                                        && !(status+inistatus=='inactiveshutoff')) degraded = true;
2043
                            }
2044
                        }
2045
                        if (degraded) status = 'degraded';
2046
                        else status = inistatus;
2047
                        if (val.issystem) val.status = status;
2048
                        return status;
2049
                    } else {
2050
                        return(val.status);
2051
                    }
2052
                }
2053
            },
2054
            {
2055
                field: '_item',
2056
                hidden: user.is_readonly,
2057
                name: 'Action' + ' <a href="https://www.origo.io/info/stabiledocs/web/dashboard/actions/" rel="help" target="_blank" class="irigo-tooltip">help</a>',
2058
                width: 'auto',
2059
                formatter: function(item) {
2060
                    q = dojo.query('.irigo-tooltip'); q.irigoTooltip && q.irigoTooltip();
2061
                    return grid.getActionButtons(item);
2062
                }
2063
            }
2064
        ];
2065

    
2066
        var treeModel = new dijit.tree.ForestStoreModel({
2067
            store: newStores.systems,
2068
            deferItemLoadingUntilExpand: false,
2069
            rootId: 'systems',
2070
            rootLabel: 'root'
2071
        //    query:{nodetype: "parent"},
2072
        //    childrenAttrs: ['children']
2073
        });
2074
        newStores.systems.grid = home.grid;
2075

    
2076
        // create a new grid:
2077
        //var grid = new dojox.grid.DataGrid({
2078
        var grid = new dojox.grid.TreeGrid({
2079
            treeModel: treeModel,
2080
            structure : layout,
2081
            selectionMode: "single",
2082
            keepSelection: true,
2083
            rowsPerPage: 2000,
2084
            defaultOpen: false,
2085
        //    sortInfo: 2,
2086
            autoRender: true,
2087
            autoHeight : false
2088
        }, domId);
2089
        grid.canSort = function(col){ if(Math.abs(col) == 3) {
2090
            return false; } else { return false; } };
2091

    
2092
        grid.rendering = false,
2093
        grid.hasSelection = false,
2094

    
2095
        grid.getActionButtons = function(item){
2096
            var uuid = item.uuid;
2097
            var issystem = item.issystem;
2098
            var remove_button = grid.actionButton({'action':"delete_system", 'uuid':uuid, 'confirm': false,
2099
                'name': item.name , actionHandler: grid.actionHandler,
2100
                'title': 'remove stack', 'type': 'stack'});
2101
            var delete_button = grid.actionButton({'action':"removesystem", 'uuid':uuid, 'confirm': true,
2102
                'name': item.name , actionHandler: grid.actionHandler,
2103
                'title': 'completely delete stack and delete associated servers, images and connections', 'type': 'stack'});
2104
            var start_button = grid.actionButton({'action':"start", 'uuid':uuid, 'confirm': false,
2105
                'name': item.name , actionHandler: grid.actionHandler,
2106
                'title' : "start/resume" + (item.issystem?" all":""), 'type': 'stack'});
2107
            var shutdown_button = grid.actionButton({'action':"shutdown", 'uuid':uuid, 'confirm': false,
2108
                'name': item.name , actionHandler: grid.actionHandler,
2109
                'title' : "shutdown" + (item.issystem?" all":""), 'type': 'stack'});
2110
            var suspend_button = grid.actionButton({'action':"suspend", 'uuid':uuid, 'confirm': false,
2111
                'name': item.name , actionHandler: grid.actionHandler,
2112
                'title' : "suspend" + (item.issystem?" all":""), 'type': 'stack'});
2113
            var resume_button = grid.actionButton({'action':"resume", 'uuid':uuid, 'confirm': false,
2114
                'name': item.name , actionHandler: grid.actionHandler,
2115
                'title' : "resume" + (item.issystem?" all":""), 'type': 'stack'});
2116
            var destroy_button = grid.actionButton({'action':"destroy", 'uuid':uuid, 'confirm': true,
2117
                'name': item.name , actionHandler: grid.actionHandler,
2118
                'title' : "pull the plug" + (item.issystem?" on all":""), 'type': 'stack'});
2119
            var backup_button = grid.actionButton({'action':"backup", 'uuid':uuid, 'confirm': false,
2120
                'name': item.name , actionHandler: grid.actionHandler,
2121
                'title' : "backup" + (item.issystem?" all":""), 'type': 'stack'});
2122

    
2123

    
2124
            var buttons = "";
2125
            if (item.status=="running") {
2126
                buttons += shutdown_button;
2127
                buttons += suspend_button;
2128
                buttons += destroy_button;
2129
                buttons += backup_button;
2130
            } else if (item.status=="shutoff") {
2131
                buttons += start_button;
2132
//                if (issystem != 1) buttons += delete_button;
2133
                buttons += delete_button;
2134
                buttons += backup_button;
2135
            } else if (item.status=="paused") {
2136
                buttons += resume_button;
2137
                buttons += destroy_button;
2138
                buttons += backup_button;
2139
            } else if (item.status=="inactive") {
2140
                buttons += start_button;
2141
//                if (issystem != 1) buttons += delete_button;
2142
                buttons += destroy_button;
2143
                buttons += delete_button;
2144
            } else if (item.status=="shuttingdown" || item.status=="upgrading") {
2145
                buttons += destroy_button;
2146
            } else if (!item.status || item.status=="--") {
2147
            } else {
2148
                buttons += start_button;
2149
                buttons += shutdown_button;
2150
                buttons += destroy_button;
2151
                buttons += backup_button;
2152
            }
2153
            if (issystem == 1) {
2154
                buttons += remove_button;
2155
            }
2156
            return buttons;
2157
        },
2158

    
2159
        grid.actionButton = function(args){
2160
            var actionHandler;
2161
            args.title = args.title || args.action;
2162
            if(args.confirm){
2163
                actionHandler = "grid.actionConfirmDialog('" + args.uuid + "','" + args.action + "','" + args.name + "','" + args.title + "','" + args.type + "', 'home.grid.actionHandler')";
2164
            }
2165
            else{
2166
                actionHandler = "home.grid.actionHandler('" + args.uuid + "','" + args.action + "','" + args.type + "')";
2167
            }
2168
            // left out button text intentionally since image replacement didn't work out in IE
2169
            var t = '<button type="button" title="${title}" class="action_button ${action}_icon" uuid="${action}_${uuid}" onclick="${actionHandler};return false;"><span>${action}</span></button>';
2170
            args.actionHandler = actionHandler;
2171
            return dojo.string.substitute(t, args);
2172
        },
2173

    
2174
        grid.actionHandler = function(uuid, action, type) {
2175
            var item = grid.store.fetchItemByIdentity({
2176
                identity: uuid,
2177
                onItem: function(item, request){
2178
                    if (action == 'delete_system') {
2179
                        grid.deleteSystem(item);
2180
                    } else {
2181
                        var data;
2182
                        data = {
2183
                            "items": [{uuid:uuid, action:action, issystem: item.issystem}]
2184
                        };
2185
                        // send action to server
2186
                        dojo.xhrPost({
2187
                            url: "/stabile/systems/" + uuid, // + (ui_update.session?"?s="+ui_update.session:""),
2188
                            postData: dojo.toJson(data),
2189
                            load: function(response){
2190
                                if (action == 'removesystem') {
2191
                                    if (networks.grid && networks.grid.refresh) networks.grid.refresh();
2192
                                    if (images.grid && images.grid.refresh) images.grid.refresh();
2193
                                    if (servers.grid && servers.grid.refresh) servers.grid.refresh();
2194
                                //    grid.deleteSystem(item);
2195
                                    home.monitoringGrid.store.reset();
2196
                                    home.updateMonitoring();
2197
                                    home.updateUsage();
2198
                                }
2199
                                home.grid.updatePending = servers.grid.updatePending = images.grid.updatePending = networks.grid.updatePending = true;
2200
                                if (response) server.parseResponse(response);
2201
                            },
2202
                            error: function(error){
2203
                                console.error("grid::actionHandler", error);
2204
                            }
2205
                        });
2206
                        dojo.publish(type + ":" + action, [item]);
2207
                    }
2208
                }
2209
            });
2210
        },
2211

    
2212
        grid.deleteSystem = function(item) {
2213
            grid.selection.deselect(item);
2214
            var haschildren = (item.children)?true:false;
2215
            if (item == home.currentItem) home.currentItem = null;
2216
            grid.store.deleteItem(item);
2217
            grid.store.save({
2218
                onComplete: function() {
2219
                    home.updateUptime();
2220
                    home.updateVitals("update");
2221
                    home.updateUsage();
2222
                    stores.systemsSelect.close();
2223
                    if (haschildren) grid.refresh();
2224
                },
2225
                onError: function(err) { console.debug("error: ", err) }
2226
            });
2227
        },
2228

    
2229
        grid.addSystem = function() {
2230
            var model = {
2231
                uuid: Math.uuid().toLowerCase(),
2232
                systemstatus: "new",
2233
                issystem: 1,
2234
                name: "New Stack"
2235
            };
2236
            var item = grid.store.newItem(model);
2237
            grid.store.save({
2238
                onComplete: function() { grid.selection.select(item); stores.systemsSelect.close();},
2239
                onError: function(err) { console.debug("error: ", err) }
2240

    
2241
            });
2242
        };
2243

    
2244
        grid.updateSystem = function(prop) {
2245
            if (!home.currentItem) home.currentItem = home.grid.selection.getSelected()[0];
2246
            if (prop && dijit.byId("info_"+prop+"_field")) {
2247
                if (home.currentItem && (home.currentItem[prop] || home.currentItem[prop]=='')) {
2248
                    var curpropvalue = home.currentItem[prop];
2249
                    var curfieldvalue = dijit.byId("info_"+prop+"_field").value;
2250
                    if (dijit.byId("info_"+prop+"_field").checked===false) curfieldvalue = "";
2251
                    if (dijit.byId("info_"+prop+"_field").checked===true) curfieldvalue = "1";
2252
                    if (curpropvalue == "--") curpropvalue = "";
2253
                    if (!(curfieldvalue=="" && prop=="name") &&  curpropvalue != curfieldvalue) {
2254
                        console.log("saving item value",prop,curpropvalue,curfieldvalue,home.currentItem);
2255
                        grid.store.changing(home.currentItem);
2256
                        if (!curfieldvalue) curfieldvalue = "--";
2257
                        home.currentItem[prop] = curfieldvalue;
2258
                        grid.store.save({
2259
                            onComplete: function() {
2260
                                if (prop=="system") {
2261
                                    grid.refresh();
2262
                                    grid.selection.clear();
2263
                                } else if (!dijit.byId("info_"+prop+"_field").value) {
2264
                                    home.currentItem = home.grid.selection.getSelected()[0];
2265
                                    var field = dijit.byId("info_"+prop+"_field");
2266
                                    if (home.currentItem[prop] == '--' || home.currentItem.issystem) {
2267
                                        home.currentItem[prop] = user[prop];
2268
                                    }
2269
                                    field.set('value', home.currentItem[prop]);
2270
                                } else if (prop=="name") {
2271
                                    stores.systemsSelect.close();
2272
                                    grid.refresh();
2273
                                    servers.grid.updatePending = true;
2274
                                    networks.grid.updatePending = true;
2275
                                } else {
2276
                                }
2277
                            },
2278
                                onError: function(err) { console.debug("error: ", err) }
2279
                        });
2280
                    } else {
2281
                        console.log("Not saving", prop, curpropvalue,curfieldvalue,home.currentItem)
2282
                    }
2283
                } else if (user[prop] || user[prop]==="") {
2284
                    var value = dijit.byId("info_"+prop+"_field").value;
2285
                    if (prop.indexOf("vmreadlimit")==0 || prop.indexOf("vmwritelimit")==0) value = value*1024*1024;
2286
                    if (dijit.byId("info_"+prop+"_field").checked===false) value = "--";
2287
                    if (dijit.byId("info_"+prop+"_field").checked===true) value = "1";
2288
                    if (user[prop]=='' && value=='--') { // This is OK, do nothing
2289
                        ;
2290
                    } else if (value != user[prop]) {
2291
                        if (!value) value = '--';
2292
                        console.log("Saving server value", prop, user[prop], value, dijit.byId("info_"+prop+"_field").checked);
2293
                        home.saveServerValue(user.username, prop, value, "username");
2294
                        user[prop] = value;
2295
                        if (prop=="downloadmasters") {
2296
                            if (value && value != '--') $("#checkfordownloads").show();
2297
                            else $("#checkfordownloads").hide();
2298
                        }
2299

    
2300
                    }
2301
                } else {
2302
                    console.log("Not saving", prop);
2303
                }
2304
            } else {
2305
                console.log("Not Saving", prop);
2306
            }
2307
        };
2308

    
2309
        grid.refresh = function(){
2310
            treeModel.store.reset();
2311
//            treeModel.store.close();
2312
//            treeModel.store.fetch({query:{name:"*"},queryOptions:{cache:false}});
2313
//            var filter = {uuid: "*"};
2314
//            treeModel.store.fetch(filter);
2315
            treeModel.store.fetch({
2316
                    onItem: function(item) {
2317
                        home.currentItem = home.grid.selection.getSelected()[0];
2318
                        home.updateVitals(home.currentItem);
2319
                        servers.grid.refresh();
2320
                        stores.systemsSelect.close();
2321
                    }
2322
            })
2323
            //grid.filter(filter, true);
2324
            //treeModel.store = newStores.reloadSystems();
2325
            //grid.treeModel = treeModel;
2326
//            grid.render();
2327
        };
2328

    
2329
        grid.redraw = function(){
2330
            if (!home.currentItem) home.currentItem = home.grid.selection.getSelected()[0];
2331
            if (home.currentItem) {
2332
                grid.rendering = true;
2333
                grid.selection.deselect(home.currentItem);
2334
                grid.render();
2335
                grid.selection.select(home.currentItem);
2336
                grid.rendering = false;
2337
            }
2338
        };
2339

    
2340
        self.update = function(task){
2341
            console.log("updating systems " + task.uuid + " " + task.tab);
2342
            if (task.uuid && (task.tab=="servers" || task.tab=="systems")) {
2343
                grid.store.fetchItemByIdentity({identity: task.uuid,
2344
                    onItem: function(item){
2345
                        for (var key in task) {
2346
                            if (key=='id' || key=='sender' || key=='timestamp' || key=='type' || key=='uuid') {;}
2347
                            else if (item[key]) {
2348
                                 item[key] = task[key];
2349
                            }
2350
                        }
2351
                        grid.store.save();
2352
                        var i = grid.getItemIndex(item);
2353
                        grid.updateRow(i);
2354
                        grid.updateRowStyles(i);
2355
                        console.log("updating row",i, item.uuid, item.system);
2356
                    }
2357
                });
2358
            }
2359
            home.updateVitals("update");
2360

    
2361
        };
2362

    
2363
        grid.updatePending = false;
2364

    
2365
        //if (dojo.byId(domId)) dojo.byId(domId).appendChild(grid.domNode);
2366
        grid.startup();
2367

    
2368
        return grid;
2369
    };// end createStatusGrid
2370

    
2371
    home.changeAccount = function(account) {
2372
        if (account && account != user.username) {
2373
            var msg = "";
2374
            ui_update.logged_out = true;
2375
            if (account.indexOf("<span")==0) {
2376
                msg = "Logging out";
2377
                setTimeout(
2378
                    function() {document.location = "/stabile/auth/logout?s=" + ui_update.session},
2379
                    700
2380
                )
2381
            } else {
2382
                msg = "Switching to account: " + account
2383
                var back = '';
2384
                if (location.href.indexOf("index-i.html")!=-1) {
2385
                    back = "&back=/stabile/index-i.html";
2386
                }
2387
                setTimeout(
2388
                    function() {document.location = "/stabile/auth/autologin?account="+account+"&username="+user.username+back+"&s=" + ui_update.session},
2389
                    700
2390
                )
2391
            }
2392
            console.log(msg);
2393
            IRIGO.toaster([{message: msg, type: "message",duration: 2000}]);
2394

    
2395
        }
2396
    }
2397

    
2398
    home.logout = function() {
2399
        console.log("logging out of engine");
2400
        $.get("/stabile/auth/logout?s=" + ui_update.session);
2401
    }
2402

    
2403
    home.changeEngine = function(url) {
2404
        if (home.engines_field.getOptions().length>1) {
2405
            $("#engines_span").show();
2406
            if (url && url != "#" && document.location.href.indexOf(url)==-1) {
2407
                setTimeout(function() {document.location = url},700)
2408
                var msg = "Switching to engine " + url;
2409
                console.log(msg, url);
2410
                IRIGO.toaster([{message: msg, type: "message",duration: 2000}]);
2411
            }
2412
        }
2413
    }
2414

    
2415
    home.init = function() {
2416
        if (home._inited === true) return;
2417
        else home._inited = true;
2418

    
2419
        if ($('#tktuser')) $('#tktuser').prop('innerHTML', user.tktuser);
2420
        if ($('#tktuser')) $('#tktuser').prop('title', "User privileges: " + user.userprivileges);
2421

    
2422
        var grid = home.createStatusGrid("systemsGrid");
2423
        home.grid = grid;
2424
        home.grid.sort();
2425
        home.monitoringGrid = home.createMonitoringGrid("monitoringGrid");
2426
        home.monitoringGrid.sort();
2427

    
2428
        if (dojo.cookie('installaccount')) {
2429
            home.install_account = dojo.cookie('installaccount');
2430
        }
2431
        if (dojo.cookie('installsystem')) {
2432
            home.install_system = dojo.cookie('installsystem');
2433
            systembuilder.system.create();
2434
        }
2435

    
2436
        var month=new Array();
2437
        month[0]="Jan";
2438
        month[1]="Feb";
2439
        month[2]="Mar";
2440
        month[3]="Apr";
2441
        month[4]="May";
2442
        month[5]="Jun";
2443
        month[6]="Jul";
2444
        month[7]="Aug";
2445
        month[8]="Sep";
2446
        month[9]="Oct";
2447
        month[10]="Nov";
2448
        month[11]="Dec";
2449
        var d = new Date();
2450
        var m = d.getMonth();
2451
        var y = d.getYear() + 1900;
2452
        var m1;
2453
        var y1;
2454
        var ym;
2455
        var um = {yearmonth: "current", name: "Current usage"};
2456
        stores.usageMonths.newItem(um);
2457
        for (i=0; i<12; i++) {
2458
            y1 = (m-i<0)?y-1:y;
2459
            m1 = (m-i<0)?12+m-i:m-i;
2460
            ym = {yearmonth: y1+"-"+("0"+(m1+1)).substr(-2), name: month[m1]+" "+y1};
2461
            um = {yearmonth: y1+"-"+("0"+(m1+1)).substr(-2), name: "Average usage for: " + month[m1]+" "+y1};
2462
            stores.uptimeMonths.newItem(ym);
2463
            stores.usageMonths.newItem(um);
2464
        }
2465

    
2466
        var q = dojo.query('.irigo-tooltip');
2467
        if(q.irigoTooltip){q.irigoTooltip();};
2468

    
2469
        home.grid.store.fetch({query:{uuid: "*"}, onComplete: home.updateVitals});
2470

    
2471
        dojo.connect(grid,"onStyleRow",function(row){
2472
        //on(grid, "styleRow", function(row){
2473
            row.customStyles = "cursor:pointer;";
2474
            var item = grid.getItem(row.index);
2475
            if(item){
2476
                var status = grid.store.getValue(item,"status");
2477
                var color = statusColorMap.get(status);
2478
//                if (row.customStyles.indexOf(color)==-1) {
2479
//                    row.customStyles = "color:" + color + ";";
2480
//                }
2481
                if (row.over) {
2482
                    if (row.customClasses.indexOf("dojoxGridRowOver"))
2483
                        row.customClasses = row.customClasses.substring(0, row.customClasses.indexOf("dojoxGridRowOver"));
2484
                }
2485
                row.customClasses += " " + color;
2486
                //if (row.selected) {
2487
                //    row.customStyles += "font-weight:bold;";
2488
                //}
2489
            };
2490
        });
2491

    
2492
        home.account_field = new dijit.form.Select(
2493
        {
2494
            name: 'account',
2495
            sortByLabel: false,
2496
            onChange: home.changeAccount
2497
        }, 'account');
2498
        home.account_field.setStore(stores.accounts);
2499

    
2500
        home.engines_field = new dijit.form.Select(
2501
            {
2502
                name: 'engines',
2503
                sortByLabel: false,
2504
                onChange: home.changeEngine
2505
            }, 'engines');
2506
        home.engines_field.setStore(stores.engines);
2507

    
2508
        if (home.account_field) home.account_field.set('title',
2509
"Active account: " + user.username + "\n\
2510
Account privileges: " + user.privileges + "\n\
2511
Logged in as: " + user.tktuser + ((user.userprivileges)?"\n\Privileges: " + user.userprivileges:"")
2512
        );
2513

    
2514
        if (home.engines_field) {
2515
            home.engines_field.set('title',
2516
                "Active engine: " + user.enginename + "\n\
2517
Engine linked to Stabile Registry: " + ((user.enginelinked)?"yes":"no") + ((user.engineid)?"\nEngine ID: " + user.engineid:"")
2518
            );
2519
        }
2520
        if (user.enginename) document.title = user.enginename;
2521

    
2522
        if (user.is_readonly) {
2523
            document.getElementById("clear_packages").style.display = "none";
2524
            document.getElementById("add_system").style.display = "none";
2525
            $("#manage_system_button").attr("disabled", true);
2526
            $("#updateSystemButton").attr("disabled", true);
2527
            $("#new_monitor_button").attr("disabled", true);
2528
            $("#clear_packages").attr("disabled", true);
2529
            $("#info_resettoaccountinfo_button").removeAttr("onclick");
2530
        }
2531
        if (user.is_admin && window.innerWidth>840) {
2532
            $("#nodestab").show();
2533
            $("#userstab").show();
2534
            $("#clear_activity_button").show();
2535
        } else {
2536
            $("#nodestab").hide();
2537
            $("#userstab").hide();
2538
        }
2539

    
2540
        home.grid._onRowClicked = home.grid.onRowClick;
2541
        home.grid.onRowClick = function(ev) {
2542
            if (ev.target.localName == "button") {
2543
                ; // do nothing
2544
            } else {
2545
                home.grid._onRowClicked(ev);
2546
            }
2547
        }
2548
        on(grid, "click", function(ev){
2549
            if (ev.target.localName != "td" && ev.target.localName != "button") {
2550
                home.currentItem = null;
2551
                if (grid.hasSelection && grid.selection.getSelected()) {
2552
                    grid.hasSelection = false;
2553
                    home.updateMonitoring();
2554
                    home.updatePackages();
2555
                    home.updateUptime();
2556
                    home.updateUsage();
2557
                }
2558
                for (var i in grid.selection.getSelected()) {
2559
                    var selItem = grid.selection.getSelected()[i];
2560
                    grid.selection.deselect(selItem);
2561
                }
2562
            }
2563
        });
2564
        on(grid, "selected", function(rowIndex){
2565
            var item = grid.getItem(rowIndex);
2566
            if (item!=null && !grid.rendering) {
2567
                grid.hasSelection = true;
2568
                console.log("selected", item);
2569
                home.currentItem = item;
2570
                for (var i in grid.selection.getSelected()) {
2571
                    var selItem = grid.selection.getSelected()[i];
2572
                    if (selItem != item) {
2573
                        grid.selection.deselect(selItem);
2574
                        console.log("deselecting", selItem);
2575
                    }
2576
                }
2577
                if (!user.is_readonly) $("#load_packages").show();
2578
                dijit.byId("usage_select").set("value", "current");
2579
                dijit.byId("usage_select").set("disabled", true);
2580
                home.updateMonitoring();
2581
                home.updatePackages();
2582
                home.updateUptime();
2583
                home.updateUsage();
2584
                home.updateVitals(home.currentItem);
2585
            }
2586
        });
2587
        on(grid, "deselected", function(rowIndex){
2588
            var item = grid.getItem(rowIndex);
2589
            if (grid.selection.getSelected().length==0 && !grid.rendering
2590
                    && !grid.hasSelection
2591
                    ) {
2592
                console.log("deselected", item);
2593
                home.currentItem = null;
2594
                home.updateVitals("update");
2595
                $("#load_packages").hide()
2596
                dijit.byId("usage_select").set("disabled", false);
2597
                home.updateMonitoring();
2598
                home.updatePackages();
2599
                home.updateUptime();
2600
                home.updateUsage();
2601
            }
2602
        });
2603

    
2604
        connect.connect(home.monitoringGrid, "onRowClick", home.monitoringGrid, home.monitoringGrid.itemClickHandler);
2605

    
2606
        dojo.subscribe("systems:update", function(task){
2607
            console.log("systems update", task);
2608
            if (task.uuid) {
2609
                home.grid.update(task);
2610
            } else {
2611
                home.grid.refresh();
2612
            }
2613
        });
2614
        dojo.subscribe("monitors:update", function(task){
2615
//            console.log("monitors update", task);
2616
            if (task.uuid) {
2617
                home.monitoringGrid.refreshRow(task);
2618
            } else {
2619
                home.updateMonitoring();
2620
            }
2621
        });
2622
        dojo.subscribe("users:update", function(task){
2623
            console.log("users update", task);
2624
            home.updateUser();
2625
        });
2626
        dojo.subscribe("home:removal", function(task){
2627
            console.log("system removed", task.uuid);
2628
            var duuid = dijit.byId('createSystemDialog').get("sysuuid");
2629
            if(dijit.byId('createSystemDialog') !== undefined && (duuid == task.uuid || duuid == task.domuuid))
2630
                dijit.byId('createSystemDialog').hide();
2631
        });
2632

    
2633
        if (user.showcost && user.showcost!="0") {
2634
            document.getElementById("total_cost").style.display="inline";
2635
         //   document.getElementById("cost_warning").style.display="block";
2636
        }
2637

    
2638
        dojo.connect(grid, "onSelected", function(rowIndex){
2639
            home.initApexCharts();
2640
            home.updateApexCharts();
2641
        });
2642
        dojo.connect(grid, "onDeselected", function(rowIndex){
2643
            home.initApexCharts();
2644
        });
2645

    
2646
        dojo.subscribe("homeTabs-selectChild", function(child){
2647

    
2648
            if (child.id === "usageContentPane"){
2649
                home.updateUsage();
2650

    
2651
            } else if (child.id === "monitoringContentPane"){
2652
                home.updateMonitoring();
2653

    
2654
            } else if (child.id === "packagesContentPane"){
2655
                home.updatePackages();
2656

    
2657
            } else if(child.id === "statisticsContentPane"){
2658
                home.initApexCharts();
2659
                if (home.currentItem) home.updateApexCharts();
2660
            }
2661
        });
2662

    
2663
        $('#statisticsTab').on('shown.bs.tab', function (e) {
2664
            home.chartsShown=true;
2665
            home.initApexCharts();
2666
            if (home.currentItem) home.updateApexCharts();
2667
        })
2668
        home.bodyResize();
2669
    };
2670

    
2671
    window.home = home;
2672
    if (location.hash.substring(1) == 'chpwd') {
2673
        location = "#home";
2674
        home.showChangePassword();
2675
    } else if (location.hash.indexOf('installsystem')!=-1) {
2676
        home.install_system = location.hash.substr(location.hash.indexOf('installsystem') + 14);
2677
        if (home.install_system.indexOf("-name=")!=-1) {
2678
            home.install_name = home.install_system.substr(home.install_system.indexOf("-name=")+6);
2679
            home.install_system = home.install_system.substring(0, home.install_system.indexOf("-name="));
2680
        }
2681
        systembuilder.system.create();
2682
    }
2683

    
2684
    function bodyResize() {
2685
        console.log("body resized");
2686
        setTimeout(function() {q = dojo.query('.irigo-tooltip'); q.irigoTooltip && q.irigoTooltip();},1000);
2687
        document.getElementById("homeTabs").style.height =
2688
            (document.getElementById("homeContent").offsetHeight - document.getElementById("homeNav").offsetHeight) + "px";
2689
    }
2690
    home.bodyResize = bodyResize;
2691

    
2692
    home.initSlider = function() {
2693
        if((!home.sliderCreated || !home.currentItem) && home.chartsShown) {
2694
            if (!home.chartSlider) {
2695
                home.chartSlider = new dijit.form.HorizontalSlider({
2696
                    name: "slider",
2697
                    value: 0,
2698
                    minimum: 0,
2699
                    maximum: 11,
2700
                    discreteValues: 12,
2701
                    showButtons: false,
2702
                    intermediateChanges: true,
2703
                    style: {width: "84%", marginLeft: "32px", marginBottom: 0, marginTop: 0, display: "none"},
2704
                    onChange: function(value) {
2705
                    //    home.updateCharts();
2706
                        home.updateApexCharts();
2707
                    }
2708
                }, "slider");
2709
                var labels    = ['5min', '30', '60',   '2h',   '12',   '24',    '2d',    '14',    '28',      '2m',      '6',       '12'];
2710
                var sliderLabels = new dijit.form.HorizontalRuleLabels({
2711
                    container:"bottomDecoration",
2712
                    labels: labels
2713
                }, "rules" );
2714
            }
2715

    
2716
            document.getElementById("statsInfo").style.display = "block";
2717
            document.getElementById("slider").style.display = "none";
2718
            $("#chartsPanel").hide();
2719
            home.sliderCreated = true;
2720
        }
2721
    }
2722

    
2723
    function getStatsQuery(){
2724
        var secs = [ 300,  1800,  3600, 2*3600, 12*3600, 24*3600, 2*86400, 14*86400, 28*86400, 2*2592000, 6*2592000, 12*2592000 ];
2725
        var value = home.chartSlider.get('value');
2726
        var until = Math.round((new Date()).getTime() / 1000);
2727
        return {
2728
            from: new Date(new Date().getTime() - 1000 * secs[value]),
2729
            to: new Date(),
2730
            last_s: secs[value],
2731
            until_s: until,
2732
            from_s: until - secs[value]
2733
        };
2734
    }
2735
    home.getStatsQuery = getStatsQuery;
2736

    
2737
    function timestampToDatetime(timestamp){
2738
        if (timestamp == null || timestamp == ""|| timestamp == "--") return "--";
2739
        d = new Date(timestamp*1000);
2740
        return d.toLocaleDateString() + " " + d.toLocaleTimeString();
2741
        //return d.getMonth() + "/" + d.getDate() + "/" + (d.getYear()+1900) + " " + d.toLocaleTimeString();
2742
    };
2743

    
2744
    function timestampToTime(timestamp){
2745
        if (timestamp == null || timestamp == ""|| timestamp == "--") return "--";
2746
        d = new Date(timestamp*1000);
2747
        return d.toLocaleTimeString();
2748
    };
2749

    
2750
    home.timestampToLocaleString = function(timestamp) {
2751
        if (timestamp == null || timestamp == ""|| timestamp == "--") return "--";
2752
        d = new Date(timestamp*1000);
2753

    
2754
        function pad(n){return n<10 ? '0'+n : n}
2755
        return d.getFullYear()+'-'
2756
        + pad(d.getMonth()+1)+'-'
2757
        + pad(d.getDate())+'  '
2758
        + pad(d.getHours())+':'
2759
        + pad(d.getMinutes())+':'
2760
        + pad(d.getSeconds())+' '
2761

    
2762
//        return d.toLocaleString();
2763
    };
2764

    
2765
    home.formatters = formatters;
2766

    
2767
    home.initApexCharts = function() {
2768
        home.initSlider(); // old init function
2769
        if (home.apexsliderCreated) return;
2770
        var options = {
2771
          chart: {
2772
              height: 200,
2773
              type: 'area',
2774
              nogroup: 'metrics',
2775
              animations: {
2776
                enabled: false,
2777
                easing: 'linear',
2778
                dynamicAnimation: {
2779
                  speed: 1000
2780
                }
2781
              },
2782
              toolbar: {
2783
                  show: true,
2784
                  tools: {
2785
                    download: true,
2786
                    selection: true,
2787
                    zoom: true,
2788
                    zoomin: true,
2789
                    zoomout: false,
2790
                    pan: true
2791
                  },
2792
                  autoSelected: 'zoom'
2793
              }
2794
          },
2795
          markers: {
2796
            size: 3
2797
          },
2798
          colors: ['#008FFB'],
2799
          stroke: {
2800
              curve: 'smooth',
2801
              lineCap: 'butt',
2802
              width: 2
2803
          },
2804
          dataLabels: {enabled: false},
2805
          series: [],
2806
          noData: {text: 'Loading...'},
2807
          xaxis: {
2808
              type: 'datetime',
2809
              labels: {
2810
              formatter: function (value, timestamp) {
2811
                if (timestamp > 100000) {
2812
                  var d = new Date(timestamp * 1000);
2813
                  var h = ("0" + d.getHours()).substr(-2);
2814
                  var m = ("0" + d.getMinutes()).substr(-2);
2815
                  var s = ("0" + d.getSeconds()).substr(-2);
2816
                  var dstring = d.getDate() + "/" + (1+d.getMonth()) + " " + h + ":" + m + ":" + s;
2817
                  return dstring;
2818
                }
2819
              }
2820
            }
2821
          },
2822
          yaxis: {
2823
              labels: {
2824
                minWidth: "100px"
2825
              },
2826
              forceNiceScale: true,
2827
              decimalsInFloat: 2
2828
          }
2829
        }
2830

    
2831
        home.cpu_options = $.extend(true, {}, options); // Deep clone object
2832
        home.cpu_options.title = {text: 'CPU Load'};
2833
        home.cpu_options.chart.id = 'cpu';
2834
        home.cpu_options.colors = ['#008FFB'];
2835
        home.chart_cpu = new ApexCharts(document.querySelector("#chartCpuLoad"), home.cpu_options);
2836

    
2837
        home.disk_options = $.extend(true, {}, options); // Deep clone object
2838
        home.disk_options.title = {text: 'Disk I/O (kbytes/s)'};
2839
        home.disk_options.chart.id = 'disk';
2840
        home.disk_options.colors = ['#2980b9', '#e74c3c'];
2841
        home.chart_disk = new ApexCharts(document.querySelector("#chartIO"), home.disk_options);
2842

    
2843
        home.net_options = $.extend(true, {}, options); // Deep clone object
2844
        home.net_options.title = {text: 'Network traffic (kbytes/s)'};
2845
        home.net_options.chart.id = 'network';
2846
        home.net_options.colors = ['#f39c12', '#9b59b6'];
2847
        home.chart_net = new ApexCharts(document.querySelector("#chartNetworkActivity"), home.net_options);
2848

    
2849
        home.chart_cpu.render();
2850
        home.chart_disk.render();
2851
        home.chart_net.render();
2852

    
2853
        home.apexsliderCreated = true;
2854
    }
2855

    
2856
    home.updateApexCharts = function(uuid) {
2857
      if (!uuid && home.currentItem) uuid = home.currentItem.uuid;
2858
      if (!uuid) {console.log("Unable to chart - no uuid"); return;}
2859
      var until = Math.round((new Date()).getTime() / 1000);
2860
      var from = until - 60*5;
2861
      var last = 60*5;
2862
      var args;
2863
      if (home.chartSlider) args = getStatsQuery();
2864
      if (args) {
2865
        from = args.from_s;
2866
        until = args.until_s;
2867
        last = args.last_s;
2868
      }
2869
//      var url = "/graphite/graphite.wsgi/render?format=json&from=" + from + "&until=" + until + "&target=domains." + uuid + ".cpuLoad";
2870
      var url = "/stabile/systems?action=getmetrics&last=" + last + "&uuid=" + uuid + "&metric=cpuLoad";
2871
      $.getJSON(url, function(response) {
2872
        if (response.length > 0) {
2873
            var rawdata = response[0].datapoints;
2874
            home.chart_cpu.updateSeries([{
2875
              name: 'CPU load',
2876
              data: prepApexData(rawdata)
2877
            }]);
2878
            if (rawdata.length<2) home.chart_cpu.updateOptions({xaxis:{ max: 1 }});
2879
            else if (rawdata[rawdata.length-2][0] == null) home.chart_cpu.updateOptions({xaxis:{ max: rawdata[rawdata.length-2][1] }}); // update x-axis to compensate for possible missing last data point
2880
            home.chart_cpu.resetSeries(); // reset zoom - for some reason it gets bungled for this chart
2881
        } else {
2882
            home.chart_cpu.updateOptions({noData:{text:"No data"}, series:[]})
2883
        }
2884
      });
2885

    
2886
//      url = "/graphite/graphite.wsgi/render?format=json&from=" + from + "&until=" + until + "&target=domains." + uuid + ".wr_kbytes_s";
2887
      url = "/stabile/systems?action=getmetrics&last=" + last + "&uuid=" + uuid + "&metric=wr_kbytes_s";
2888
      $.getJSON(url, function(response) {
2889
        if (response.length > 0) {
2890
            var rawdata_1 = response[0].datapoints;
2891
        //    url = "/graphite/graphite.wsgi/render?format=json&from=" + from + "&until=" + until + "&target=domains." + uuid + ".rd_kbytes_s";
2892
            url = "/stabile/systems?action=getmetrics&last=" + last + "&uuid=" + uuid + "&metric=rd_kbytes_s";
2893
            $.getJSON(url, function(response) {
2894
              var rawdata_2 = response[0].datapoints;
2895
              home.chart_disk.updateSeries([
2896
                {
2897
                  name: 'Disk writes',
2898
                  data: prepApexData(rawdata_1)
2899
                },
2900
                {
2901
                  name: 'Disk reads',
2902
                  data: prepApexData(rawdata_2)
2903
                }
2904
              ])
2905
            });
2906
        } else {
2907
            home.chart_disk.updateOptions({noData:{text:"No data"}, series:[]})
2908
        }
2909
      });
2910

    
2911
//      url = "/graphite/graphite.wsgi/render?format=json&from=" + from + "&until=" + until + "&target=domains." + uuid + ".rx_kbytes_s";
2912
      url = "/stabile/systems?action=getmetrics&last=" + last + "&uuid=" + uuid + "&metric=rx_kbytes_s";
2913
      $.getJSON(url, function(response) {
2914
        if (response.length > 0) {
2915
            var rawdata_1 = response[0].datapoints;
2916
        //    url = "/graphite/graphite.wsgi/render?format=json&from=" + from + "&until=" + until + "&target=domains." + uuid + ".tx_kbytes_s";
2917
            url = "/stabile/systems?action=getmetrics&last=" + last + "&uuid=" + uuid + "&metric=tx_kbytes_s";
2918
            $.getJSON(url, function(response) {
2919
              var rawdata_2 = response[0].datapoints;
2920
              home.chart_net.updateSeries([
2921
                {
2922
                  name: 'Traffic in',
2923
                  data: prepApexData(rawdata_1)
2924
                },
2925
                {
2926
                  name: 'Traffic out',
2927
                  data: prepApexData(rawdata_2)
2928
                }
2929
              ])
2930
            });
2931
        } else {
2932
            home.chart_net.updateOptions({noData:{text:"No data"}, series:[]})
2933
        }
2934
      });
2935
        document.getElementById("statsInfo").style.display = "none";
2936
        document.getElementById("slider").style.display = "block";
2937
        $("#chartsPanel").show();
2938

    
2939
    }
2940

    
2941
    function prepApexData(rdata) {
2942
      var data = [];
2943
      rdata.forEach(
2944
        function(item, index) {
2945
          data.push({"x": item[1], "y": item[0]})
2946
        }
2947
      )
2948
//      return {series: [{name: "name", data: data}]};
2949
      return data;
2950
    };
2951

    
2952
});
(8-8/23)