[Kimchi-devel] [PATCH 1/3] Host tab functionality split into Dashboard and Updates

Aline Manera alinefm at linux.vnet.ibm.com
Thu Nov 26 19:10:04 UTC 2015


I removed the commented blocks I commented below and everything 
continued to work fine.

So I will remove them and apply all the patches.

On 26/11/2015 16:24, Aline Manera wrote:
>
>
> On 26/11/2015 10:53, chandra at linux.vnet.ibm.com wrote:
>> From: Chandra Shekhar Reddy Potula <chandra at linux.vnet.ibm.com>
>>
>> Splitting host tab functionality into two tabs
>> 1. Dashboard
>>       a. restart, shutdown buttons
>>       b. statistics
>>       c. debug reports
>> 2. Updates
>>       a. Repositories
>>       b. Software updates
>> ---
>>   src/wok/plugins/gingerbase/ui/config/tab-ext.xml   |  10 +-
>>   .../ui/js/src/gingerbase.host-dashboard.js         | 593 +++++++++++++
>>   .../gingerbase/ui/js/src/gingerbase.host-update.js | 405 +++++++++
>>   .../gingerbase/ui/js/src/gingerbase.host.js        | 928 
>> ---------------------
>>   .../gingerbase/ui/pages/host-dashboard.html.tmpl   | 135 +++
>>   .../gingerbase/ui/pages/host-update.html.tmpl      |  90 ++
>>   src/wok/plugins/gingerbase/ui/pages/host.html.tmpl | 156 ----
>>   7 files changed, 1231 insertions(+), 1086 deletions(-)
>>   create mode 100644 
>> src/wok/plugins/gingerbase/ui/js/src/gingerbase.host-dashboard.js
>>   create mode 100644 
>> src/wok/plugins/gingerbase/ui/js/src/gingerbase.host-update.js
>>   delete mode 100644 
>> src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
>>   create mode 100644 
>> src/wok/plugins/gingerbase/ui/pages/host-dashboard.html.tmpl
>>   create mode 100644 
>> src/wok/plugins/gingerbase/ui/pages/host-update.html.tmpl
>>   delete mode 100644 src/wok/plugins/gingerbase/ui/pages/host.html.tmpl
>>
>> diff --git a/src/wok/plugins/gingerbase/ui/config/tab-ext.xml 
>> b/src/wok/plugins/gingerbase/ui/config/tab-ext.xml
>> index 3d3f51e..f6f16d4 100644
>> --- a/src/wok/plugins/gingerbase/ui/config/tab-ext.xml
>> +++ b/src/wok/plugins/gingerbase/ui/config/tab-ext.xml
>> @@ -4,7 +4,13 @@
>>       <tab>
>>           <access role="admin" mode="admin"/>
>>           <access role="user" mode="none"/>
>> -        <title>Host</title>
>> -        <path>plugins/gingerbase/host.html</path>
>> +        <title>Dashboard</title>
>> + <path>plugins/gingerbase/host-dashboard.html</path>
>> +    </tab>
>> +    <tab>
>> +        <access role="admin" mode="admin"/>
>> +        <access role="user" mode="none"/>
>> +        <title>Updates</title>
>> + <path>plugins/gingerbase/host-update.html</path>
>>       </tab>
>>   </tabs-ext>
>> diff --git 
>> a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host-dashboard.js 
>> b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host-dashboard.js
>> new file mode 100644
>> index 0000000..047ba5b
>> --- /dev/null
>> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host-dashboard.js
>> @@ -0,0 +1,593 @@
>> +/*
>> + * Project Ginger Base
>> + *
>> + * Copyright IBM, Corp. 2013-2015
>> + *
>> + * Licensed under the Apache License, Version 2.0 (the "License");
>> + * you may not use this file except in compliance with the License.
>> + * You may obtain a copy of the License at
>> + *
>> + *     http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + */
>> +gingerbase.host = {};
>> +
>> +gingerbase.host_dashboard = function() {
>> +    "use strict";
>> +    var reportGridID = 'available-reports-grid';
>> +    var reportGrid = null;
>> +    var enableReportButtons = function(toEnable) {
>> +        var buttonID = '#{grid}-{btn}-button';
>> +        $.each(['rename', 'remove', 'download'], function(i, n) {
>> +            $(wok.substitute(buttonID, {
>> +                grid: reportGridID,
>> +                btn: n
>> +            })).prop('disabled', !toEnable);
>> +        });
>> +    };
>> +    var initReportGrid = function(reports) {
>> +        reportGrid = new wok.widget.List({
>> +            container: 'debug-report-section',
>> +            id: reportGridID,
>> +            title: i18n['GGBDR6002M'],
>> +            toolbarButtons: [{
>> +                id: reportGridID + '-generate-button',
>> +                class: 'fa fa-plus-circle',
>> +                label: i18n['GGBDR6006M'],
>> +                onClick: function(event) {
>> + wok.window.open('plugins/gingerbase/report-add.html');
>> +                }
>> +            }, {
>> +                id: reportGridID + '-rename-button',
>> +                class: 'fa fa-pencil',
>> +                label: i18n['GGBDR6008M'],
>> +                disabled: true,
>> +                onClick: function(event) {
>> +                    var report = reportGrid.getSelected();
>> +                    if (!report) {
>> +                        return;
>> +                    }
>> +
>> +                    gingerbase.selectedReport = report['name'];
>> + wok.window.open('plugins/gingerbase/report-rename.html');
>> +                }
>> +            }, {
>> +                id: reportGridID + '-download-button',
>> +                label: i18n['GGBDR6010M'],
>> +                class: 'fa fa-download',
>> +                disabled: true,
>> +                onClick: function(event) {
>> +                    var report = reportGrid.getSelected();
>> +                    if (!report) {
>> +                        return;
>> +                    }
>> +
>> +                    gingerbase.downloadReport({
>> +                        file: report['uri']
>> +                    });
>> +                }
>> +            }, {
>> +                id: reportGridID + '-remove-button',
>> +                class: 'fa fa-minus-circle',
>> +                label: i18n['GGBDR6009M'],
>> +                critical: true,
>> +                disabled: true,
>> +                onClick: function(event) {
>> +                    var report = reportGrid.getSelected();
>> +                    if (!report) {
>> +                        return;
>> +                    }
>> +
>> +                    var settings = {
>> +                        title: i18n['GGBAPI6004M'],
>> +                        content: i18n['GGBDR6001M'],
>> +                        confirm: i18n['GGBAPI6002M'],
>> +                        cancel: i18n['GGBAPI6003M']
>> +                    };
>> +
>> +                    wok.confirm(settings, function() {
>> +                        gingerbase.deleteReport({
>> +                            name: report['name']
>> +                        }, function(result) {
>> +                            listDebugReports();
>> +                        }, function(error) {
>> + wok.message.error(error.responseJSON.reason);
>> +                        });
>> +                    });
>> +                }
>> +            }],
>> +            onRowSelected: function(row) {
>> +                var report = reportGrid.getSelected();
>> +                // Only enable report buttons if the selected line 
>> is not a
>> +                // pending report
>> +                if (report['time'] === i18n['GGBDR6007M']) {
>> +                    var gridElement = $('#' + reportGridID);
>> +                    var row = $('tr:contains(' + report['name'] + 
>> ')', gridElement);
>> +                    enableReportButtons(false);
>> +                    row.attr('class', '');
>> +                } else {
>> +                    enableReportButtons(true);
>> +                }
>> +            },
>> +            frozenFields: [],
>> +            fields: [{
>> +                name: 'name',
>> +                label: i18n['GGBDR6003M'],
>> +                'class': 'debug-report-name',
>> +                type: 'name'
>> +            }, {
>> +                name: 'time',
>> +                label: i18n['GGBDR6005M'],
>> +                'class': 'debug-report-time',
>> +                type: 'description'
>> +            }],
>> +            data: reports
>> +        });
>> +    };
>> +
>> +    var getPendingReports = function() {
>> +        var reports = [];
>> +        var filter = 'status=running&target_uri=' + 
>> encodeURIComponent('^/plugins/gingerbase/debugreports/*');
>> +
>> +        gingerbase.getTasksByFilter(filter, function(tasks) {
>> +            for (var i = 0; i < tasks.length; i++) {
>> +                var reportName = 
>> tasks[i].target_uri.replace(/^\/plugins\/gingerbase\/debugreports\//, 
>> '') || i18n['GGBDR6012M'];
>> +                reports.push({
>> +                    'name': reportName,
>> +                    'time': i18n['GGBDR6007M']
>> +                });
>> +
>> +                if (gingerbase.trackingTasks.indexOf(tasks[i].id) >= 
>> 0) {
>> +                    continue;
>> +                }
>> +
>> +                gingerbase.trackTask(tasks[i].id, function(result) {
>> + wok.topic('gingerbase/debugReportAdded').publish();
>> +                }, function(result) {
>> +                    // Error message from Async Task status
>> +                    if (result['message']) {
>> +                        var errText = result['message'];
>> +                    }
>> +                    // Error message from standard gingerbase exception
>> +                    else {
>> +                        var errText = result['responseJSON']['reason'];
>> +                    }
>> +                    result && wok.message.error(errText);
>> + wok.topic('gingerbase/debugReportAdded').publish();
>> +                }, null);
>> +            }
>> +        }, null, true);
>> +
>> +        return reports;
>> +    };
>> +
>> +    var listDebugReports = function() {
>> +        gingerbase.listReports(function(reports) {
>> +            var pendingReports = getPendingReports();
>> +            var allReports = pendingReports.concat(reports);
>> +            $('#debug-report-section').removeClass('hidden');
>
>> +/*
>> +            if ((gingerbase.capabilities['repo_mngt_tool']) && 
>> (gingerbase.capabilities['repo_mngt_tool'] !== "None")) {
>> +                $('#debug-report-section, 
>> #repositories-section').removeClass('col-md-8');
>> +                $('#debug-report-section, 
>> #repositories-section').addClass('col-md-4');
>> +            } else {
>> + $('#content-sys-info').removeClass('col-md-12');
>> +                $('#content-sys-info').addClass('col-md-4');
>> +            }
>> +*/
>> +
>
> Can the above block be removed as it is commeted?
>
>> +
>> +            // Row selection will be cleared so disable buttons here
>> +            enableReportButtons(false);
>> +
>> +            if (reportGrid) {
>> +                reportGrid.setData(allReports);
>> +            } else {
>> +                initReportGrid(allReports);
>> +            }
>> +
>> +            if (!allReports.length) {
>> + $('#available-reports-grid-btn-group').removeClass('hidden');
>> +            } else {
>> + $('#available-reports-grid-btn-group').addClass('hidden');
>> +            }
>> +
>> +            // Set id-debug-img to pending reports
>> +            // It will display a loading icon
>> +            var gridElement = $('#' + reportGridID);
>> +            //  "Generating..."
>> +            $.each($('td:contains(' + i18n['GGBDR6007M'] + ')', 
>> gridElement), function(index, row) {
>> +                console.log(row);
>> +                $(row).parent().addClass('generating');
>> + $(row).parent().find('.dropdown-toggle').addClass('disabled');
>> +                //$(row).attr('id', 'id-debug-img');
>> +            });
>> +        }, function(error) {
>> +            if (error['status'] === 403) {
>> +                $('#debug-report-section').addClass('hidden');
>
>> +/*
>> +                // Check Repositories and resize column
>> +                if ((gingerbase.capabilities['repo_mngt_tool']) && 
>> (gingerbase.capabilities['repo_mngt_tool'] !== "None")) {
>> + $('#repositories-section').removeClass('col-md-4');
>> + $('#repositories-section').addClass('col-md-8');
>> +                } else {
>> + $('#content-sys-info').removeClass('col-md-4');
>> + $('#content-sys-info').addClass('col-md-12');
>> +                }
>> +*/
>
> Same here.
>
>> +                return;
>> +            }
>> +            $('#debug-report-section').removeClass('hidden');
>
>> +/*
>> +            if ((gingerbase.capabilities['repo_mngt_tool']) && 
>> (gingerbase.capabilities['repo_mngt_tool'] !== "None")) {
>> +                $('#debug-report-section, 
>> #repositories-section').removeClass('col-md-8');
>> +                $('#debug-report-section, 
>> #repositories-section').addClass('col-md-4');
>> +            } else {
>> + $('#content-sys-info').removeClass('col-md-12');
>> +                $('#content-sys-info').addClass('col-md-4');
>> +            }
>> +*/
>
> And here.
>
>> +        });
>> +    };
>> +
>> +    var shutdownButtonID = '#host-button-shutdown';
>> +    var restartButtonID = '#host-button-restart';
>> +    var shutdownHost = function(params) {
>> +        var settings = {
>> +            content: i18n['GGBHOST6008M'],
>> +            confirm: i18n['GGBAPI6002M'],
>> +            cancel: i18n['GGBAPI6003M']
>> +        };
>> +
>> +        wok.confirm(settings, function() {
>> +            $(shutdownButtonID).prop('disabled', true);
>> +            $(restartButtonID).prop('disabled', true);
>> +            // Check if there is any VM is running.
>> +            // Based on the success will shutdown/reboot
>> +            gingerbase.shutdown(params, function(success) {
>> +                wok.message.success(i18n['GGBHOST6009M'])
>> +                $(shutdownButtonID).prop('disabled', false);
>> +                $(restartButtonID).prop('disabled', false);
>> +                return;
>> +            }, function(error) {
>> +            // Looks like VMs are running.
>> +            wok.message.error.code('GGBHOST6001E');
>> +            $(shutdownButtonID).prop('disabled', false);
>> +            $(restartButtonID).prop('disabled', false);
>> +        });
>> +        }, function() {
>> +        });
>> +    };
>> +
>> +    var initPage = function() {
>> +
>> +        $('#host-button-shutdown').on('click', function(event) {
>> +            event.preventDefault();
>> +            shutdownHost(null);
>> +        });
>> +
>> +        $('#host-button-restart').on('click', function(event) {
>> +            event.preventDefault();
>> +            shutdownHost({
>> +                reboot: true
>> +            });
>> +        });
>> +
>> +        var setupUI = function() {
>> +            if (gingerbase.capabilities === undefined) {
>> +                setTimeout(setupUI, 2000);
>> +                return;
>> +            }
>> +
>> +            if (gingerbase.capabilities['system_report_tool']) {
>> +                listDebugReports();
>> +                wok.topic('gingerbase/debugReportAdded')
>> +                    .subscribe(listDebugReports);
>> +                wok.topic('gingerbase/debugReportRenamed')
>> +                    .subscribe(listDebugReports);
>> +            }
>> +        };
>> +        setupUI();
>> +    };
>> +
>> +    gingerbase.getHost(function(data) {
>> +        var htmlTmpl = $('#host-dashboard-tmpl').html();
>> +        data['logo'] = data['logo'] || '';
>> +        data['memory'] = wok.formatMeasurement(data['memory'], {
>> +            fixed: 2
>> +        });
>> +        var templated = wok.substitute(htmlTmpl, data);
>> +        $('#host-content-container').html(templated);
>> +
>> +        initPage();
>> +        initTracker();
>> +    });
>> +
>> +    var StatsMgr = function() {
>> +        var statsArray = {
>> +            cpu: {
>> +                u: {
>> +                    type: 'percent',
>> +                    legend: i18n['GGBHOST6002M'],
>> +                    points: []
>> +                }
>> +            },
>> +            memory: {
>> +                u: {
>> +                    type: 'value',
>> +                    base: 2,
>> +                    fixed: 2,
>> +                    legend: i18n['GGBHOST6003M'],
>> +                    points: []
>> +                }
>> +            },
>> +            diskIO: {
>> +                w: {
>> +                    type: 'value',
>> +                    base: 2,
>> +                    fixed: 2,
>> +                    unit: 'B/s',
>> +                    legend: i18n['GGBHOST6005M'],
>> +                    'class': 'disk-write',
>> +                    points: []
>> +                },
>> +                r: {
>> +                    type: 'value',
>> +                    base: 2,
>> +                    fixed: 2,
>> +                    unit: 'B/s',
>> +                    legend: i18n['GGBHOST6004M'],
>> +                    points: []
>> +                }
>> +            },
>> +            networkIO: {
>> +                s: {
>> +                    type: 'value',
>> +                    base: 2,
>> +                    fixed: 2,
>> +                    unit: 'B/s',
>> +                    legend: i18n['GGBHOST6007M'],
>> +                    'class': 'network-sent',
>> +                    points: []
>> +                },
>> +                r: {
>> +                    type: 'value',
>> +                    base: 2,
>> +                    fixed: 2,
>> +                    unit: 'B/s',
>> +                    legend: i18n['GGBHOST6006M'],
>> +                    points: []
>> +                }
>> +            }
>> +        };
>> +        var SIZE = 20;
>> +        var cursor = SIZE;
>> +
>> +        var add = function(stats) {
>> +            for (var key in stats) {
>> +                var item = stats[key];
>> +                for (var metrics in item) {
>> +                    var value = item[metrics]['v'];
>> +                    var max = item[metrics]['max'];
>> +                    var unifiedMetrics = statsArray[key][metrics];
>> +                    var ps = unifiedMetrics['points'];
>> +                    if (!Array.isArray(value)) {
>> +                        ps.push(value);
>> +                        if (ps.length > SIZE + 1) {
>> +                            ps.shift();
>> +                        }
>> +                    } else {
>> +                        ps = ps.concat(value);
>> +                        ps.splice(0, ps.length - SIZE - 1);
>> +                        unifiedMetrics['points'] = ps;
>> +                    }
>> +                    if (max !== undefined) {
>> +                        unifiedMetrics['max'] = max;
>> +                    } else {
>> +                        if (unifiedMetrics['type'] !== 'value') {
>> +                            continue;
>> +                        }
>> +                        max = -Infinity;
>> +                        $.each(ps, function(i, value) {
>> +                            if (value > max) {
>> +                                max = value;
>> +                            }
>> +                        });
>> +                        if (max === 0) {
>> +                            ++max;
>> +                        }
>> +                        max *= 1.1;
>> +                        unifiedMetrics['max'] = max;
>> +                    }
>> +                }
>> +            }
>> +            cursor++;
>> +        };
>> +
>> +        var get = function(which) {
>> +            var stats = statsArray[which];
>> +            var lines = [];
>> +            for (var k in stats) {
>> +                var obj = stats[k];
>> +                var line = {
>> +                    type: obj['type'],
>> +                    base: obj['base'],
>> +                    unit: obj['unit'],
>> +                    fixed: obj['fixed'],
>> +                    legend: obj['legend']
>> +                };
>> +                if (obj['max']) {
>> +                    line['max'] = obj['max'];
>> +                }
>> +                if (obj['class']) {
>> +                    line['class'] = obj['class'];
>> +                }
>> +                var ps = obj['points'];
>> +                var numStats = ps.length;
>> +                var unifiedPoints = [];
>> +                $.each(ps, function(i, value) {
>> +                    unifiedPoints.push({
>> +                        x: cursor - numStats + i,
>> +                        y: value
>> +                    });
>> +                });
>> +                line['points'] = unifiedPoints;
>> +                lines.push(line);
>> +            }
>> +            return lines;
>> +        };
>> +
>> +        return {
>> +            add: add,
>> +            get: get
>> +        };
>> +    };
>> +
>> +    var Tracker = function(charts) {
>> +        var charts = charts;
>> +        var timer = null;
>> +        var statsPool = new StatsMgr();
>> +        var setCharts = function(newCharts) {
>> +            charts = newCharts;
>> +            for (var key in charts) {
>> +                var chart = charts[key];
>> +                chart.updateUI(statsPool.get(key));
>> +            }
>> +        };
>> +
>> +        var self = this;
>> +
>> +        var UnifyStats = function(stats) {
>> +            var result = {
>> +                cpu: {
>> +                    u: {
>> +                        v: stats['cpu_utilization']
>> +                    }
>> +                },
>> +                memory: {
>> +                    u: {}
>> +                },
>> +                diskIO: {
>> +                    w: {
>> +                        v: stats['disk_write_rate']
>> +                    },
>> +                    r: {
>> +                        v: stats['disk_read_rate']
>> +                    }
>> +                },
>> +                networkIO: {
>> +                    s: {
>> +                        v: stats['net_sent_rate']
>> +                    },
>> +                    r: {
>> +                        v: stats['net_recv_rate']
>> +                    }
>> +                }
>> +            };
>> +            if (Array.isArray(stats['memory'])) {
>> +                result.memory.u['v'] = [];
>> +                result.memory.u['max'] = -Infinity;
>> +                for (var i = 0; i < stats['memory'].length; i++) {
>> + result.memory.u['v'].push(stats['memory'][i]['avail']);
>> +                    result.memory.u['max'] = 
>> Math.max(result.memory.u['max'], stats['memory'][i]['total']);
>> +                }
>> +            } else {
>> +                result.memory.u['v'] = stats['memory']['avail'],
>> +                    result.memory.u['max'] = stats['memory']['total']
>> +            }
>> +            return (result);
>> +        };
>> +
>> +
>> +        var statsCallback = function(stats) {
>> +            var unifiedStats = UnifyStats(stats);
>> +            statsPool.add(unifiedStats);
>> +            for (var key in charts) {
>> +                var chart = charts[key];
>> +                chart.updateUI(statsPool.get(key));
>> +            }
>> +            timer = setTimeout(function() {
>> +                continueTrack();
>> +            }, 1000);
>> +        };
>> +
>> +        var track = function() {
>> +            gingerbase.getHostStatsHistory(statsCallback,
>> +                function() {
>> +                    continueTrack();
>> +                });
>> +        };
>> +
>> +        var continueTrack = function() {
>> +            gingerbase.getHostStats(statsCallback,
>> +                function() {
>> +                    continueTrack();
>> +                });
>> +        };
>> +
>> +        var destroy = function() {
>> +            timer && clearTimeout(timer);
>> +            timer = null;
>> +        };
>> +
>> +        return {
>> +            setCharts: setCharts,
>> +            start: track,
>> +            stop: destroy
>> +        };
>> +    };
>> +
>> +    var initTracker = function() {
>> +        // TODO: Extend tabs with onUnload event to unregister timers.
>> +        if (gingerbase.hostTimer) {
>> +            gingerbase.hostTimer.stop();
>> +            delete gingerbase.hostTimer;
>> +        }
>> +
>> +        var trackedCharts = {
>> +            cpu: new wok.widget.LineChart({
>> +                id: 'chart-cpu',
>> +                node: 'container-chart-cpu',
>> +                type: 'percent'
>> +            }),
>> +            memory: new wok.widget.LineChart({
>> +                id: 'chart-memory',
>> +                node: 'container-chart-memory',
>> +                type: 'value'
>> +            }),
>> +            diskIO: new wok.widget.LineChart({
>> +                id: 'chart-disk-io',
>> +                node: 'container-chart-disk-io',
>> +                type: 'value'
>> +            }),
>> +            networkIO: new wok.widget.LineChart({
>> +                id: 'chart-network-io',
>> +                node: 'container-chart-network-io',
>> +                type: 'value'
>> +            })
>> +        };
>> +
>> +        if (gingerbase.hostTimer) {
>> +            gingerbase.hostTimer.setCharts(trackedCharts);
>> +        } else {
>> +            gingerbase.hostTimer = new Tracker(trackedCharts);
>> +            gingerbase.hostTimer.start();
>> +        }
>> +    };
>> +
>> +    $('#host-root-container').on('remove', function() {
>> +        if (gingerbase.hostTimer) {
>> +            gingerbase.hostTimer.stop();
>> +            delete gingerbase.hostTimer;
>> +        }
>> +
>> +        reportGrid && reportGrid.destroy();
>> + 
>> wok.topic('gingerbase/debugReportAdded').unsubscribe(listDebugReports);
>> + 
>> wok.topic('gingerbase/debugReportRenamed').unsubscribe(listDebugReports);
>> +    });
>> +};
>> diff --git 
>> a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host-update.js 
>> b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host-update.js
>> new file mode 100644
>> index 0000000..ee89625
>> --- /dev/null
>> +++ b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host-update.js
>> @@ -0,0 +1,405 @@
>> +/*
>> + * Project Ginger Base
>> + *
>> + * Copyright IBM, Corp. 2013-2015
>> + *
>> + * Licensed under the Apache License, Version 2.0 (the "License");
>> + * you may not use this file except in compliance with the License.
>> + * You may obtain a copy of the License at
>> + *
>> + *     http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + */
>> +gingerbase.host = {};
>> +
>> +gingerbase.host_update = function() {
>> +    "use strict";
>> +    var repositoriesGrid = null;
>> +    var initRepositoriesGrid = function(repo_type) {
>> +        var gridFields = [];
>> +        if (repo_type === "yum") {
>> +            gridFields = [{
>> +                name: 'repo_id',
>> +                label: i18n['GGBREPO6004M'],
>> +                'class': 'repository-id',
>> +                type: 'name'
>> +            }, {
>> +                name: 'config[display_repo_name]',
>> +                label: i18n['GGBREPO6005M'],
>> +                'class': 'repository-name',
>> +                type: 'description'
>> +            }, {
>> +                name: 'enabled',
>> +                label: i18n['GGBREPO6009M'],
>> +                'class': 'repository-enabled',
>> +                type: 'status'
>> +            }];
>> +        } else if (repo_type === "deb") {
>> +            gridFields = [{
>> +                name: 'baseurl',
>> +                label: i18n['GGBREPO6006M'],
>> +                makeTitle: true,
>> +                'class': 'repository-baseurl deb',
>> +                type: 'description'
>> +            }, {
>> +                name: 'enabled',
>> +                label: i18n['GGBREPO6009M'],
>> +                'class': 'repository-enabled deb',
>> +                type: 'status'
>> +            }, {
>> +                name: 'config[dist]',
>> +                label: "dist",
>> +                'class': 'repository-gpgcheck deb'
>> +            }, {
>> +                name: 'config[comps]',
>> +                label: "comps",
>> +                'class': 'repository-gpgcheck deb'
>> +            }];
>> +        } else {
>> +            gridFields = [{
>> +                name: 'repo_id',
>> +                label: i18n['GGBREPO6004M'],
>> +                'class': 'repository-id',
>> +                type: 'name'
>> +            }, {
>> +                name: 'enabled',
>> +                label: i18n['GGBREPO6009M'],
>> +                'class': 'repository-enabled',
>> +                type: 'status'
>> +            }, {
>> +                name: 'baseurl',
>> +                label: i18n['GGBREPO6006M'],
>> +                makeTitle: true,
>> +                'class': 'repository-baseurl',
>> +                type: 'description'
>> +            }];
>> +        }
>> +        repositoriesGrid = new wok.widget.List({
>> +            container: 'repositories-section',
>> +            id: 'repositories-grid',
>> +            title: i18n['GGBREPO6003M'],
>> +            toolbarButtons: [{
>> +                id: 'repositories-grid-add-button',
>> +                label: i18n['GGBREPO6012M'],
>> +                class: 'fa fa-plus-circle',
>> +                onClick: function(event) {
>> +                    wok.window.open({
>> +                        url: 'plugins/gingerbase/repository-add.html',
>> +                        class: repo_type
>> +                    });
>> +                }
>> +            }, {
>> +                id: 'repositories-grid-enable-button',
>> +                label: i18n['GGBREPO6016M'],
>> +                class: 'fa fa-play-circle-o',
>> +                disabled: true,
>> +                onClick: function(event) {
>> +                    var repository = repositoriesGrid.getSelected();
>> +                    if (!repository) {
>> +                        return;
>> +                    }
>> +                    var name = repository['repo_id'];
>> +                    var enable = !repository['enabled'];
>> +                    $(this).prop('disabled', true);
>> +                    gingerbase.enableRepository(name, enable, 
>> function() {
>> + wok.topic('gingerbase/repositoryUpdated').publish();
>> +                    });
>> +                }
>> +            }, {
>> +                id: 'repositories-grid-edit-button',
>> +                label: i18n['GGBREPO6013M'],
>> +                class: 'fa fa-pencil',
>> +                disabled: true,
>> +                onClick: function(event) {
>> +                    var repository = repositoriesGrid.getSelected();
>> +                    if (!repository) {
>> +                        return;
>> +                    }
>> +                    gingerbase.selectedRepository = 
>> repository['repo_id'];
>> +                    wok.window.open({
>> +                        url: 'plugins/gingerbase/repository-edit.html',
>> +                        class: repo_type
>> +                    });
>> +                }
>> +            }, {
>> +                id: 'repositories-grid-remove-button',
>> +                label: i18n['GGBREPO6014M'],
>> +                class: 'fa fa-minus-circle',
>> +                critical: true,
>> +                disabled: true,
>> +                onClick: function(event) {
>> +                    var repository = repositoriesGrid.getSelected();
>> +                    if (!repository) {
>> +                        return;
>> +                    }
>> +
>> +                    var settings = {
>> +                        title: i18n['GGBREPO6001M'],
>> +                        content: i18n['GGBREPO6002M'],
>> +                        confirm: i18n['GGBAPI6004M'],
>> +                        cancel: i18n['GGBAPI6003M']
>> +                    };
>> +
>> +                    wok.confirm(settings, function() {
>> +                        gingerbase.deleteRepository(
>> +                            repository['repo_id'],
>> +                            function(result) {
>> + wok.topic('gingerbase/repositoryDeleted').publish(result);
>> +                            },
>> +                            function(error) {}
>> +                        );
>> +                    });
>> +                }
>> +            }],
>> +            onRowSelected: function(row) {
>> +                var repository = repositoriesGrid.getSelected();
>> +                if (!repository) {
>> +                    return;
>> +                }
>> +                var selectedRow = 
>> $('tr',repositoriesGrid.bodyContainer);
>> + $('#repositories-grid-remove-button',selectedRow).prop('disabled', 
>> false);
>> + $('#repositories-grid-edit-button',selectedRow).prop('disabled', 
>> false);
>> +                var enabled = repository['enabled'];
>> +                var actionHtml,actionText,actionIcon ='';
>> +                if(enabled){
>> +                    actionText= i18n['GGBREPO6017M'];
>> +                    actionIcon = 'fa-pause';
>> +                }else{
>> +                    actionText= i18n['GGBREPO6016M'];
>> +                    actionIcon = 'fa-play-circle-o';
>> +                }
>> +                actionHtml = ['<i class="fa',' 
>> ',actionIcon,'"></i>','',actionText].join('');
>> + $('#repositories-grid-enable-button',selectedRow)
>> +                    .html(actionHtml)
>> +                    .prop('disabled', false);
>> +            },
>> +            frozenFields: [],
>> +            fields: gridFields,
>> +            data: listRepositories
>> +        });
>> +    };
>> +
>> +    var listRepositories = function(gridCallback) {
>> +        gingerbase.listRepositories(function(repositories) {
>> +                if ($.isFunction(gridCallback)) {
>> +                    gridCallback(repositories);
>> +                } else {
>> +                    if (repositoriesGrid) {
>> +                        repositoriesGrid.setData(repositories);
>> +                    } else {
>> +                        initRepositoriesGrid();
>> +                        repositoriesGrid.setData(repositories);
>> +                    }
>> +                }
>> +            },
>> +            function(error) {
>> +                var message = error && error['responseJSON'] && 
>> error['responseJSON']['reason'];
>> +
>> +                if ($.isFunction(gridCallback)) {
>> +                    gridCallback([]);
>> +                }
>> +                repositoriesGrid &&
>> +                    repositoriesGrid.showMessage(message || 
>> i18n['GGBUPD6008M']);
>> +            });
>> +
>> +        $('#repositories-grid-remove-button').prop('disabled', true);
>> +        $('#repositories-grid-edit-button').prop('disabled', true);
>> +        $('#repositories-grid-enable-button').prop('disabled', true);
>> +    };
>> +
>> +    var softwareUpdatesGridID = 'software-updates-grid';
>> +    var softwareUpdatesGrid = null;
>> +    var progressAreaID = 'software-updates-progress-textarea';
>> +    var reloadProgressArea = function(result) {
>> +        var progressArea = $('#' + progressAreaID)[0];
>> +        $(progressArea).text(result['message']);
>> +        var scrollTop = $(progressArea).prop('scrollHeight');
>> +        $(progressArea).prop('scrollTop', scrollTop);
>> +    };
>> +
>> +    var initSoftwareUpdatesGrid = function(softwareUpdates) {
>> +        softwareUpdatesGrid = new wok.widget.Grid({
>> +            container: 'software-updates-grid-container',
>> +            id: softwareUpdatesGridID,
>> +            title: i18n['GGBUPD6001M'],
>> +            rowSelection: 'disabled',
>> +            toolbarButtons: [{
>> +                id: softwareUpdatesGridID + '-update-button',
>> +                label: i18n['GGBUPD6006M'],
>> +                disabled: true,
>> +                onClick: function(event) {
>> +                    var updateButton = $(this);
>> +                    var progressArea = $('#' + progressAreaID)[0];
>> + $('#software-updates-progress-container').removeClass('hidden');
>> +                    $(progressArea).text('');
>> +                    !wok.isElementInViewport(progressArea) &&
>> +                        progressArea.scrollIntoView();
>> + $(updateButton).text(i18n['GGBUPD6007M']).prop('disabled', true);
>> +
>> +                    gingerbase.updateSoftware(function(result) {
>> +                        reloadProgressArea(result);
>> + $(updateButton).text(i18n['GGBUPD6006M']).prop('disabled', false);
>> + wok.topic('gingerbase/softwareUpdated').publish({
>> +                            result: result
>> +                        });
>> +                    }, function(error) {
>> +                        var message = error && error['responseJSON'] 
>> && error['responseJSON']['reason'];
>> +                        wok.message.error(message || 
>> i18n['GGBUPD6009M']);
>> + $(updateButton).text(i18n['GGBUPD6006M']).prop('disabled', false);
>> +                    }, reloadProgressArea);
>> +                }
>> +            }],
>> +            frozenFields: [],
>> +            fields: [{
>> +                name: 'package_name',
>> +                label: i18n['GGBUPD6002M'],
>> +                'class': 'software-update-name'
>> +            }, {
>> +                name: 'version',
>> +                label: i18n['GGBUPD6003M'],
>> +                'class': 'software-update-version'
>> +            }, {
>> +                name: 'arch',
>> +                label: i18n['GGBUPD6004M'],
>> +                'class': 'software-update-arch'
>> +            }, {
>> +                name: 'repository',
>> +                label: i18n['GGBUPD6005M'],
>> +                'class': 'software-update-repos'
>> +            }],
>> +            data: listSoftwareUpdates
>> +        });
>> +    };
>> +
>> +    var startSoftwareUpdateProgress = function() {
>> +        var progressArea = $('#' + progressAreaID)[0];
>> + $('#software-updates-progress-container').removeClass('hidden');
>> +        $(progressArea).text('');
>> +        !wok.isElementInViewport(progressArea) &&
>> +            progressArea.scrollIntoView();
>> +
>> +        gingerbase.softwareUpdateProgress(function(result) {
>> +            reloadProgressArea(result);
>> +            wok.topic('gingerbase/softwareUpdated').publish({
>> +                result: result
>> +            });
>> +            wok.message.warn(i18n['GGBUPD6010M']);
>> +        }, function(error) {
>> +            wok.message.error(i18n['GGBUPD6011M']);
>> +        }, reloadProgressArea);
>> +    };
>> +
>> +    var listSoftwareUpdates = function(gridCallback) {
>> + gingerbase.listSoftwareUpdates(function(softwareUpdates) {
>> +            if ($.isFunction(gridCallback)) {
>> +                gridCallback(softwareUpdates);
>> +            } else {
>> +                if (softwareUpdatesGrid) {
>> + softwareUpdatesGrid.setData(softwareUpdates);
>> +                } else {
>> +                    initSoftwareUpdatesGrid(softwareUpdates);
>> +                }
>> +            }
>> +
>> +            var updateButton = $('#' + softwareUpdatesGridID + 
>> '-update-button');
>> +            $(updateButton).prop('disabled', softwareUpdates.length 
>> === 0);
>> +        }, function(error) {
>> +            var message = error && error['responseJSON'] && 
>> error['responseJSON']['reason'];
>> +
>> +            // cannot get the list of packages because there is another
>> +            // package manager instance running, so follow that 
>> instance updates
>> +            if (message.indexOf("GGBPKGUPD0005E") !== -1) {
>> +                startSoftwareUpdateProgress();
>> +                if ($.isFunction(gridCallback)) {
>> +                    gridCallback([]);
>> +                }
>> +                return;
>> +            }
>> +
>> +            if ($.isFunction(gridCallback)) {
>> +                gridCallback([]);
>> +            }
>> +            softwareUpdatesGrid &&
>> +                softwareUpdatesGrid.showMessage(message || 
>> i18n['GGBUPD6008M']);
>> +        });
>> +    };
>> +
>> +    var initPage = function() {
>> +
>> +        var setupUI = function() {
>> +            if (gingerbase.capabilities === undefined) {
>> +                setTimeout(setupUI, 2000);
>> +                return;
>> +            }
>> +
>> +            if ((gingerbase.capabilities['repo_mngt_tool']) && 
>> (gingerbase.capabilities['repo_mngt_tool'] !== "None")) {
>> + initRepositoriesGrid(gingerbase.capabilities['repo_mngt_tool']);
>> + $('#repositories-section').switchClass('hidden', 
>> gingerbase.capabilities['repo_mngt_tool']);
>> +                $('#content-sys-info').removeClass('col-md-12', 
>> gingerbase.capabilities['repo_mngt_tool']);
>> +                $('#content-sys-info').addClass('col-md-4', 
>> gingerbase.capabilities['repo_mngt_tool']);
>> +                wok.topic('gingerbase/repositoryAdded')
>> +                    .subscribe(listRepositories);
>> +                wok.topic('gingerbase/repositoryUpdated')
>> +                    .subscribe(listRepositories);
>> +                wok.topic('gingerbase/repositoryDeleted')
>> +                    .subscribe(listRepositories);
>> +            }
>> +
>> +            if (gingerbase.capabilities['update_tool']) {
>> + $('#software-update-section').removeClass('hidden');
>> +                initSoftwareUpdatesGrid();
>> +                wok.topic('gingerbase/softwareUpdated')
>> +                    .subscribe(listSoftwareUpdates);
>> +            }
>> +
>> +        };
>> +        setupUI();
>> +    };
>> +
>> +    gingerbase.getHost(function(data) {
>> +        var htmlTmpl = $('#host-update-tmpl').html();
>> +        data['logo'] = data['logo'] || '';
>> +        data['memory'] = wok.formatMeasurement(data['memory'], {
>> +            fixed: 2
>> +        });
>> +        var templated = wok.substitute(htmlTmpl, data);
>> +        $('#host-content-container').html(templated);
>> +
>> +        initPage();
>> +    });
>> +
>> +    $('#host-root-container').on('remove', function() {
>> +        if (gingerbase.hostTimer) {
>> +            gingerbase.hostTimer.stop();
>> +            delete gingerbase.hostTimer;
>> +        }
>> +
>> +        repositoriesGrid && repositoriesGrid.destroy();
>> +        wok.topic('gingerbase/repositoryAdded')
>> +            .unsubscribe(listRepositories);
>> +        wok.topic('gingerbase/repositoryUpdated')
>> +            .unsubscribe(listRepositories);
>> +        wok.topic('gingerbase/repositoryDeleted')
>> +            .unsubscribe(listRepositories);
>> +
>> +        reportGrid && reportGrid.destroy();
>> + 
>> wok.topic('gingerbase/debugReportAdded').unsubscribe(listDebugReports);
>> + 
>> wok.topic('gingerbase/debugReportRenamed').unsubscribe(listDebugReports);
>> +    });
>> +
>> +     $('#host-root-container').on('remove', function() {
>> +        if (gingerbase.hostTimer) {
>> +            gingerbase.hostTimer.stop();
>> +            delete gingerbase.hostTimer;
>> +        }
>> +
>> +        softwareUpdatesGrid && softwareUpdatesGrid.destroy();
>> + 
>> wok.topic('gingerbase/softwareUpdated').unsubscribe(listSoftwareUpdates);
>> +
>> +    });
>> +};
>> diff --git a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js 
>> b/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
>> deleted file mode 100644
>> index 4a237df..0000000
>> --- a/src/wok/plugins/gingerbase/ui/js/src/gingerbase.host.js
>> +++ /dev/null
>> @@ -1,928 +0,0 @@
>> -/*
>> - * Project Ginger Base
>> - *
>> - * Copyright IBM, Corp. 2013-2015
>> - *
>> - * Licensed under the Apache License, Version 2.0 (the "License");
>> - * you may not use this file except in compliance with the License.
>> - * You may obtain a copy of the License at
>> - *
>> - *     http://www.apache.org/licenses/LICENSE-2.0
>> - *
>> - * Unless required by applicable law or agreed to in writing, software
>> - * distributed under the License is distributed on an "AS IS" BASIS,
>> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> - * See the License for the specific language governing permissions and
>> - * limitations under the License.
>> - */
>> -gingerbase.host = {};
>> -
>> -gingerbase.host_main = function() {
>> -    "use strict";
>> -    var repositoriesGrid = null;
>> -    var initRepositoriesGrid = function(repo_type) {
>> -        var gridFields = [];
>> -        if (repo_type === "yum") {
>> -            gridFields = [{
>> -                name: 'repo_id',
>> -                label: i18n['GGBREPO6004M'],
>> -                'class': 'repository-id',
>> -                type: 'name'
>> -            }, {
>> -                name: 'config[display_repo_name]',
>> -                label: i18n['GGBREPO6005M'],
>> -                'class': 'repository-name',
>> -                type: 'description'
>> -            }, {
>> -                name: 'enabled',
>> -                label: i18n['GGBREPO6009M'],
>> -                'class': 'repository-enabled',
>> -                type: 'status'
>> -            }];
>> -        } else if (repo_type === "deb") {
>> -            gridFields = [{
>> -                name: 'baseurl',
>> -                label: i18n['GGBREPO6006M'],
>> -                makeTitle: true,
>> -                'class': 'repository-baseurl deb',
>> -                type: 'description'
>> -            }, {
>> -                name: 'enabled',
>> -                label: i18n['GGBREPO6009M'],
>> -                'class': 'repository-enabled deb',
>> -                type: 'status'
>> -            }, {
>> -                name: 'config[dist]',
>> -                label: "dist",
>> -                'class': 'repository-gpgcheck deb'
>> -            }, {
>> -                name: 'config[comps]',
>> -                label: "comps",
>> -                'class': 'repository-gpgcheck deb'
>> -            }];
>> -        } else {
>> -            gridFields = [{
>> -                name: 'repo_id',
>> -                label: i18n['GGBREPO6004M'],
>> -                'class': 'repository-id',
>> -                type: 'name'
>> -            }, {
>> -                name: 'enabled',
>> -                label: i18n['GGBREPO6009M'],
>> -                'class': 'repository-enabled',
>> -                type: 'status'
>> -            }, {
>> -                name: 'baseurl',
>> -                label: i18n['GGBREPO6006M'],
>> -                makeTitle: true,
>> -                'class': 'repository-baseurl',
>> -                type: 'description'
>> -            }];
>> -        }
>> -        repositoriesGrid = new wok.widget.List({
>> -            container: 'repositories-section',
>> -            id: 'repositories-grid',
>> -            title: i18n['GGBREPO6003M'],
>> -            toolbarButtons: [{
>> -                id: 'repositories-grid-add-button',
>> -                label: i18n['GGBREPO6012M'],
>> -                class: 'fa fa-plus-circle',
>> -                onClick: function(event) {
>> -                    wok.window.open({
>> -                        url: 'plugins/gingerbase/repository-add.html',
>> -                        class: repo_type
>> -                    });
>> -                }
>> -            }, {
>> -                id: 'repositories-grid-enable-button',
>> -                label: i18n['GGBREPO6016M'],
>> -                class: 'fa fa-play-circle-o',
>> -                disabled: true,
>> -                onClick: function(event) {
>> -                    var repository = repositoriesGrid.getSelected();
>> -                    if (!repository) {
>> -                        return;
>> -                    }
>> -                    var name = repository['repo_id'];
>> -                    var enable = !repository['enabled'];
>> -                    $(this).prop('disabled', true);
>> -                    gingerbase.enableRepository(name, enable, 
>> function() {
>> - wok.topic('gingerbase/repositoryUpdated').publish();
>> -                    });
>> -                }
>> -            }, {
>> -                id: 'repositories-grid-edit-button',
>> -                label: i18n['GGBREPO6013M'],
>> -                class: 'fa fa-pencil',
>> -                disabled: true,
>> -                onClick: function(event) {
>> -                    var repository = repositoriesGrid.getSelected();
>> -                    if (!repository) {
>> -                        return;
>> -                    }
>> -                    gingerbase.selectedRepository = 
>> repository['repo_id'];
>> -                    wok.window.open({
>> -                        url: 'plugins/gingerbase/repository-edit.html',
>> -                        class: repo_type
>> -                    });
>> -                }
>> -            }, {
>> -                id: 'repositories-grid-remove-button',
>> -                label: i18n['GGBREPO6014M'],
>> -                class: 'fa fa-minus-circle',
>> -                critical: true,
>> -                disabled: true,
>> -                onClick: function(event) {
>> -                    var repository = repositoriesGrid.getSelected();
>> -                    if (!repository) {
>> -                        return;
>> -                    }
>> -
>> -                    var settings = {
>> -                        title: i18n['GGBREPO6001M'],
>> -                        content: i18n['GGBREPO6002M'],
>> -                        confirm: i18n['GGBAPI6004M'],
>> -                        cancel: i18n['GGBAPI6003M']
>> -                    };
>> -
>> -                    wok.confirm(settings, function() {
>> -                        gingerbase.deleteRepository(
>> -                            repository['repo_id'],
>> -                            function(result) {
>> - wok.topic('gingerbase/repositoryDeleted').publish(result);
>> -                            },
>> -                            function(error) {}
>> -                        );
>> -                    });
>> -                }
>> -            }],
>> -            onRowSelected: function(row) {
>> -                var repository = repositoriesGrid.getSelected();
>> -                if (!repository) {
>> -                    return;
>> -                }
>> -                var selectedRow = 
>> $('tr',repositoriesGrid.bodyContainer);
>> - $('#repositories-grid-remove-button',selectedRow).prop('disabled', 
>> false);
>> - $('#repositories-grid-edit-button',selectedRow).prop('disabled', 
>> false);
>> -                var enabled = repository['enabled'];
>> -                var actionHtml,actionText,actionIcon ='';
>> -                if(enabled){
>> -                    actionText= i18n['GGBREPO6017M'];
>> -                    actionIcon = 'fa-pause';
>> -                }else{
>> -                    actionText= i18n['GGBREPO6016M'];
>> -                    actionIcon = 'fa-play-circle-o';
>> -                }
>> -                actionHtml = ['<i class="fa',' 
>> ',actionIcon,'"></i>','',actionText].join('');
>> - $('#repositories-grid-enable-button',selectedRow)
>> -                    .html(actionHtml)
>> -                    .prop('disabled', false);
>> -            },
>> -            frozenFields: [],
>> -            fields: gridFields,
>> -            data: listRepositories
>> -        });
>> -    };
>> -
>> -    var listRepositories = function(gridCallback) {
>> -        gingerbase.listRepositories(function(repositories) {
>> -                if ($.isFunction(gridCallback)) {
>> -                    gridCallback(repositories);
>> -                } else {
>> -                    if (repositoriesGrid) {
>> -                        repositoriesGrid.setData(repositories);
>> -                    } else {
>> -                        initRepositoriesGrid();
>> -                        repositoriesGrid.setData(repositories);
>> -                    }
>> -                }
>> -            },
>> -            function(error) {
>> -                var message = error && error['responseJSON'] && 
>> error['responseJSON']['reason'];
>> -
>> -                if ($.isFunction(gridCallback)) {
>> -                    gridCallback([]);
>> -                }
>> -                repositoriesGrid &&
>> -                    repositoriesGrid.showMessage(message || 
>> i18n['GGBUPD6008M']);
>> -            });
>> -
>> -        $('#repositories-grid-remove-button').prop('disabled', true);
>> -        $('#repositories-grid-edit-button').prop('disabled', true);
>> -        $('#repositories-grid-enable-button').prop('disabled', true);
>> -    };
>> -
>> -    var softwareUpdatesGridID = 'software-updates-grid';
>> -    var softwareUpdatesGrid = null;
>> -    var progressAreaID = 'software-updates-progress-textarea';
>> -    var reloadProgressArea = function(result) {
>> -        var progressArea = $('#' + progressAreaID)[0];
>> -        $(progressArea).text(result['message']);
>> -        var scrollTop = $(progressArea).prop('scrollHeight');
>> -        $(progressArea).prop('scrollTop', scrollTop);
>> -    };
>> -
>> -    var initSoftwareUpdatesGrid = function(softwareUpdates) {
>> -        softwareUpdatesGrid = new wok.widget.Grid({
>> -            container: 'software-updates-grid-container',
>> -            id: softwareUpdatesGridID,
>> -            title: i18n['GGBUPD6001M'],
>> -            rowSelection: 'disabled',
>> -            toolbarButtons: [{
>> -                id: softwareUpdatesGridID + '-update-button',
>> -                label: i18n['GGBUPD6006M'],
>> -                disabled: true,
>> -                onClick: function(event) {
>> -                    var updateButton = $(this);
>> -                    var progressArea = $('#' + progressAreaID)[0];
>> - $('#software-updates-progress-container').removeClass('hidden');
>> -                    $(progressArea).text('');
>> -                    !wok.isElementInViewport(progressArea) &&
>> -                        progressArea.scrollIntoView();
>> - $(updateButton).text(i18n['GGBUPD6007M']).prop('disabled', true);
>> -
>> -                    gingerbase.updateSoftware(function(result) {
>> -                        reloadProgressArea(result);
>> - $(updateButton).text(i18n['GGBUPD6006M']).prop('disabled', false);
>> - wok.topic('gingerbase/softwareUpdated').publish({
>> -                            result: result
>> -                        });
>> -                    }, function(error) {
>> -                        var message = error && error['responseJSON'] 
>> && error['responseJSON']['reason'];
>> -                        wok.message.error(message || 
>> i18n['GGBUPD6009M']);
>> - $(updateButton).text(i18n['GGBUPD6006M']).prop('disabled', false);
>> -                    }, reloadProgressArea);
>> -                }
>> -            }],
>> -            frozenFields: [],
>> -            fields: [{
>> -                name: 'package_name',
>> -                label: i18n['GGBUPD6002M'],
>> -                'class': 'software-update-name'
>> -            }, {
>> -                name: 'version',
>> -                label: i18n['GGBUPD6003M'],
>> -                'class': 'software-update-version'
>> -            }, {
>> -                name: 'arch',
>> -                label: i18n['GGBUPD6004M'],
>> -                'class': 'software-update-arch'
>> -            }, {
>> -                name: 'repository',
>> -                label: i18n['GGBUPD6005M'],
>> -                'class': 'software-update-repos'
>> -            }],
>> -            data: listSoftwareUpdates
>> -        });
>> -    };
>> -
>> -    var startSoftwareUpdateProgress = function() {
>> -        var progressArea = $('#' + progressAreaID)[0];
>> - $('#software-updates-progress-container').removeClass('hidden');
>> -        $(progressArea).text('');
>> -        !wok.isElementInViewport(progressArea) &&
>> -            progressArea.scrollIntoView();
>> -
>> -        gingerbase.softwareUpdateProgress(function(result) {
>> -            reloadProgressArea(result);
>> -            wok.topic('gingerbase/softwareUpdated').publish({
>> -                result: result
>> -            });
>> -            wok.message.warn(i18n['GGBUPD6010M']);
>> -        }, function(error) {
>> -            wok.message.error(i18n['GGBUPD6011M']);
>> -        }, reloadProgressArea);
>> -    };
>> -
>> -    var listSoftwareUpdates = function(gridCallback) {
>> - gingerbase.listSoftwareUpdates(function(softwareUpdates) {
>> -            if ($.isFunction(gridCallback)) {
>> -                gridCallback(softwareUpdates);
>> -            } else {
>> -                if (softwareUpdatesGrid) {
>> - softwareUpdatesGrid.setData(softwareUpdates);
>> -                } else {
>> -                    initSoftwareUpdatesGrid(softwareUpdates);
>> -                }
>> -            }
>> -
>> -            var updateButton = $('#' + softwareUpdatesGridID + 
>> '-update-button');
>> -            $(updateButton).prop('disabled', softwareUpdates.length 
>> === 0);
>> -        }, function(error) {
>> -            var message = error && error['responseJSON'] && 
>> error['responseJSON']['reason'];
>> -
>> -            // cannot get the list of packages because there is another
>> -            // package manager instance running, so follow that 
>> instance updates
>> -            if (message.indexOf("GGBPKGUPD0005E") !== -1) {
>> -                startSoftwareUpdateProgress();
>> -                if ($.isFunction(gridCallback)) {
>> -                    gridCallback([]);
>> -                }
>> -                return;
>> -            }
>> -
>> -            if ($.isFunction(gridCallback)) {
>> -                gridCallback([]);
>> -            }
>> -            softwareUpdatesGrid &&
>> -                softwareUpdatesGrid.showMessage(message || 
>> i18n['GGBUPD6008M']);
>> -        });
>> -    };
>> -
>> -    var reportGridID = 'available-reports-grid';
>> -    var reportGrid = null;
>> -    var enableReportButtons = function(toEnable) {
>> -        var buttonID = '#{grid}-{btn}-button';
>> -        $.each(['rename', 'remove', 'download'], function(i, n) {
>> -            $(wok.substitute(buttonID, {
>> -                grid: reportGridID,
>> -                btn: n
>> -            })).prop('disabled', !toEnable);
>> -        });
>> -    };
>> -    var initReportGrid = function(reports) {
>> -        reportGrid = new wok.widget.List({
>> -            container: 'debug-report-section',
>> -            id: reportGridID,
>> -            title: i18n['GGBDR6002M'],
>> -            toolbarButtons: [{
>> -                id: reportGridID + '-generate-button',
>> -                class: 'fa fa-plus-circle',
>> -                label: i18n['GGBDR6006M'],
>> -                onClick: function(event) {
>> - wok.window.open('plugins/gingerbase/report-add.html');
>> -                }
>> -            }, {
>> -                id: reportGridID + '-rename-button',
>> -                class: 'fa fa-pencil',
>> -                label: i18n['GGBDR6008M'],
>> -                disabled: true,
>> -                onClick: function(event) {
>> -                    var report = reportGrid.getSelected();
>> -                    if (!report) {
>> -                        return;
>> -                    }
>> -
>> -                    gingerbase.selectedReport = report['name'];
>> - wok.window.open('plugins/gingerbase/report-rename.html');
>> -                }
>> -            }, {
>> -                id: reportGridID + '-download-button',
>> -                label: i18n['GGBDR6010M'],
>> -                class: 'fa fa-download',
>> -                disabled: true,
>> -                onClick: function(event) {
>> -                    var report = reportGrid.getSelected();
>> -                    if (!report) {
>> -                        return;
>> -                    }
>> -
>> -                    gingerbase.downloadReport({
>> -                        file: report['uri']
>> -                    });
>> -                }
>> -            }, {
>> -                id: reportGridID + '-remove-button',
>> -                class: 'fa fa-minus-circle',
>> -                label: i18n['GGBDR6009M'],
>> -                critical: true,
>> -                disabled: true,
>> -                onClick: function(event) {
>> -                    var report = reportGrid.getSelected();
>> -                    if (!report) {
>> -                        return;
>> -                    }
>> -
>> -                    var settings = {
>> -                        title: i18n['GGBAPI6004M'],
>> -                        content: i18n['GGBDR6001M'],
>> -                        confirm: i18n['GGBAPI6002M'],
>> -                        cancel: i18n['GGBAPI6003M']
>> -                    };
>> -
>> -                    wok.confirm(settings, function() {
>> -                        gingerbase.deleteReport({
>> -                            name: report['name']
>> -                        }, function(result) {
>> -                            listDebugReports();
>> -                        }, function(error) {
>> - wok.message.error(error.responseJSON.reason);
>> -                        });
>> -                    });
>> -                }
>> -            }],
>> -            onRowSelected: function(row) {
>> -                var report = reportGrid.getSelected();
>> -                // Only enable report buttons if the selected line 
>> is not a
>> -                // pending report
>> -                if (report['time'] === i18n['GGBDR6007M']) {
>> -                    var gridElement = $('#' + reportGridID);
>> -                    var row = $('tr:contains(' + report['name'] + 
>> ')', gridElement);
>> -                    enableReportButtons(false);
>> -                    row.attr('class', '');
>> -                } else {
>> -                    enableReportButtons(true);
>> -                }
>> -            },
>> -            frozenFields: [],
>> -            fields: [{
>> -                name: 'name',
>> -                label: i18n['GGBDR6003M'],
>> -                'class': 'debug-report-name',
>> -                type: 'name'
>> -            }, {
>> -                name: 'time',
>> -                label: i18n['GGBDR6005M'],
>> -                'class': 'debug-report-time',
>> -                type: 'description'
>> -            }],
>> -            data: reports
>> -        });
>> -    };
>> -
>> -    var getPendingReports = function() {
>> -        var reports = [];
>> -        var filter = 'status=running&target_uri=' + 
>> encodeURIComponent('^/plugins/gingerbase/debugreports/*');
>> -
>> -        gingerbase.getTasksByFilter(filter, function(tasks) {
>> -            for (var i = 0; i < tasks.length; i++) {
>> -                var reportName = 
>> tasks[i].target_uri.replace(/^\/plugins\/gingerbase\/debugreports\//, 
>> '') || i18n['GGBDR6012M'];
>> -                reports.push({
>> -                    'name': reportName,
>> -                    'time': i18n['GGBDR6007M']
>> -                });
>> -
>> -                if (gingerbase.trackingTasks.indexOf(tasks[i].id) >= 
>> 0) {
>> -                    continue;
>> -                }
>> -
>> -                gingerbase.trackTask(tasks[i].id, function(result) {
>> - wok.topic('gingerbase/debugReportAdded').publish();
>> -                }, function(result) {
>> -                    // Error message from Async Task status
>> -                    if (result['message']) {
>> -                        var errText = result['message'];
>> -                    }
>> -                    // Error message from standard gingerbase exception
>> -                    else {
>> -                        var errText = result['responseJSON']['reason'];
>> -                    }
>> -                    result && wok.message.error(errText);
>> - wok.topic('gingerbase/debugReportAdded').publish();
>> -                }, null);
>> -            }
>> -        }, null, true);
>> -
>> -        return reports;
>> -    };
>> -
>> -    var listDebugReports = function() {
>> -        gingerbase.listReports(function(reports) {
>> -            var pendingReports = getPendingReports();
>> -            var allReports = pendingReports.concat(reports);
>> -            $('#debug-report-section').removeClass('hidden');
>> -            if ((gingerbase.capabilities['repo_mngt_tool']) && 
>> (gingerbase.capabilities['repo_mngt_tool'] !== "None")) {
>> -                $('#debug-report-section, 
>> #repositories-section').removeClass('col-md-8');
>> -                $('#debug-report-section, 
>> #repositories-section').addClass('col-md-4');
>> -            } else {
>> - $('#content-sys-info').removeClass('col-md-12');
>> -                $('#content-sys-info').addClass('col-md-4');
>> -            }
>> -
>> -
>> -            // Row selection will be cleared so disable buttons here
>> -            enableReportButtons(false);
>> -
>> -            if (reportGrid) {
>> -                reportGrid.setData(allReports);
>> -            } else {
>> -                initReportGrid(allReports);
>> -            }
>> -
>> -            if (!allReports.length) {
>> - $('#available-reports-grid-btn-group').removeClass('hidden');
>> -            } else {
>> - $('#available-reports-grid-btn-group').addClass('hidden');
>> -            }
>> -
>> -            // Set id-debug-img to pending reports
>> -            // It will display a loading icon
>> -            var gridElement = $('#' + reportGridID);
>> -            //  "Generating..."
>> -            $.each($('td:contains(' + i18n['GGBDR6007M'] + ')', 
>> gridElement), function(index, row) {
>> -                console.log(row);
>> -                $(row).parent().addClass('generating');
>> - $(row).parent().find('.dropdown-toggle').addClass('disabled');
>> -                //$(row).attr('id', 'id-debug-img');
>> -            });
>> -        }, function(error) {
>> -            if (error['status'] === 403) {
>> -                $('#debug-report-section').addClass('hidden');
>> -                // Check Repositories and resize column
>> -                if ((gingerbase.capabilities['repo_mngt_tool']) && 
>> (gingerbase.capabilities['repo_mngt_tool'] !== "None")) {
>> - $('#repositories-section').removeClass('col-md-4');
>> - $('#repositories-section').addClass('col-md-8');
>> -                } else {
>> - $('#content-sys-info').removeClass('col-md-4');
>> - $('#content-sys-info').addClass('col-md-12');
>> -                }
>> -                return;
>> -            }
>> -            $('#debug-report-section').removeClass('hidden');
>> -            if ((gingerbase.capabilities['repo_mngt_tool']) && 
>> (gingerbase.capabilities['repo_mngt_tool'] !== "None")) {
>> -                $('#debug-report-section, 
>> #repositories-section').removeClass('col-md-8');
>> -                $('#debug-report-section, 
>> #repositories-section').addClass('col-md-4');
>> -            } else {
>> - $('#content-sys-info').removeClass('col-md-12');
>> -                $('#content-sys-info').addClass('col-md-4');
>> -            }
>> -        });
>> -    };
>> -
>> -    var shutdownButtonID = '#host-button-shutdown';
>> -    var restartButtonID = '#host-button-restart';
>> -    var shutdownHost = function(params) {
>> -        var settings = {
>> -            content: i18n['GGBHOST6008M'],
>> -            confirm: i18n['GGBAPI6002M'],
>> -            cancel: i18n['GGBAPI6003M']
>> -        };
>> -
>> -        wok.confirm(settings, function() {
>> -            $(shutdownButtonID).prop('disabled', true);
>> -            $(restartButtonID).prop('disabled', true);
>> -            // Check if there is any VM is running.
>> -            // Based on the success will shutdown/reboot
>> -            gingerbase.shutdown(params, function(success) {
>> -                wok.message.success(i18n['GGBHOST6009M'])
>> -                $(shutdownButtonID).prop('disabled', false);
>> -                $(restartButtonID).prop('disabled', false);
>> -                return;
>> -            }, function(error) {
>> -            // Looks like VMs are running.
>> -            wok.message.error.code('GGBHOST6001E');
>> -            $(shutdownButtonID).prop('disabled', false);
>> -            $(restartButtonID).prop('disabled', false);
>> -        });
>> -        }, function() {
>> -        });
>> -    };
>> -
>> -    var initPage = function() {
>> -
>> -        $('#host-button-shutdown').on('click', function(event) {
>> -            event.preventDefault();
>> -            shutdownHost(null);
>> -        });
>> -
>> -        $('#host-button-restart').on('click', function(event) {
>> -            event.preventDefault();
>> -            shutdownHost({
>> -                reboot: true
>> -            });
>> -        });
>> -
>> -        var setupUI = function() {
>> -            if (gingerbase.capabilities === undefined) {
>> -                setTimeout(setupUI, 2000);
>> -                return;
>> -            }
>> -
>> -            if ((gingerbase.capabilities['repo_mngt_tool']) && 
>> (gingerbase.capabilities['repo_mngt_tool'] !== "None")) {
>> - initRepositoriesGrid(gingerbase.capabilities['repo_mngt_tool']);
>> - $('#repositories-section').switchClass('hidden', 
>> gingerbase.capabilities['repo_mngt_tool']);
>> -                $('#content-sys-info').removeClass('col-md-12', 
>> gingerbase.capabilities['repo_mngt_tool']);
>> -                $('#content-sys-info').addClass('col-md-4', 
>> gingerbase.capabilities['repo_mngt_tool']);
>> -                wok.topic('gingerbase/repositoryAdded')
>> -                    .subscribe(listRepositories);
>> -                wok.topic('gingerbase/repositoryUpdated')
>> -                    .subscribe(listRepositories);
>> -                wok.topic('gingerbase/repositoryDeleted')
>> -                    .subscribe(listRepositories);
>> -            }
>> -
>> -            if (gingerbase.capabilities['update_tool']) {
>> - $('#software-update-section').removeClass('hidden');
>> -                initSoftwareUpdatesGrid();
>> -                wok.topic('gingerbase/softwareUpdated')
>> -                    .subscribe(listSoftwareUpdates);
>> -            }
>> -
>> -            if (gingerbase.capabilities['system_report_tool']) {
>> -                listDebugReports();
>> -                wok.topic('gingerbase/debugReportAdded')
>> -                    .subscribe(listDebugReports);
>> -                wok.topic('gingerbase/debugReportRenamed')
>> -                    .subscribe(listDebugReports);
>> -            }
>> -        };
>> -        setupUI();
>> -    };
>> -
>> -    gingerbase.getHost(function(data) {
>> -        var htmlTmpl = $('#host-tmpl').html();
>> -        data['logo'] = data['logo'] || '';
>> -        data['memory'] = wok.formatMeasurement(data['memory'], {
>> -            fixed: 2
>> -        });
>> -        var templated = wok.substitute(htmlTmpl, data);
>> -        $('#host-content-container').html(templated);
>> -
>> -        initPage();
>> -        initTracker();
>> -    });
>> -
>> -    var StatsMgr = function() {
>> -        var statsArray = {
>> -            cpu: {
>> -                u: {
>> -                    type: 'percent',
>> -                    legend: i18n['GGBHOST6002M'],
>> -                    points: []
>> -                }
>> -            },
>> -            memory: {
>> -                u: {
>> -                    type: 'value',
>> -                    base: 2,
>> -                    fixed: 2,
>> -                    legend: i18n['GGBHOST6003M'],
>> -                    points: []
>> -                }
>> -            },
>> -            diskIO: {
>> -                w: {
>> -                    type: 'value',
>> -                    base: 2,
>> -                    fixed: 2,
>> -                    unit: 'B/s',
>> -                    legend: i18n['GGBHOST6005M'],
>> -                    'class': 'disk-write',
>> -                    points: []
>> -                },
>> -                r: {
>> -                    type: 'value',
>> -                    base: 2,
>> -                    fixed: 2,
>> -                    unit: 'B/s',
>> -                    legend: i18n['GGBHOST6004M'],
>> -                    points: []
>> -                }
>> -            },
>> -            networkIO: {
>> -                s: {
>> -                    type: 'value',
>> -                    base: 2,
>> -                    fixed: 2,
>> -                    unit: 'B/s',
>> -                    legend: i18n['GGBHOST6007M'],
>> -                    'class': 'network-sent',
>> -                    points: []
>> -                },
>> -                r: {
>> -                    type: 'value',
>> -                    base: 2,
>> -                    fixed: 2,
>> -                    unit: 'B/s',
>> -                    legend: i18n['GGBHOST6006M'],
>> -                    points: []
>> -                }
>> -            }
>> -        };
>> -        var SIZE = 20;
>> -        var cursor = SIZE;
>> -
>> -        var add = function(stats) {
>> -            for (var key in stats) {
>> -                var item = stats[key];
>> -                for (var metrics in item) {
>> -                    var value = item[metrics]['v'];
>> -                    var max = item[metrics]['max'];
>> -                    var unifiedMetrics = statsArray[key][metrics];
>> -                    var ps = unifiedMetrics['points'];
>> -                    if (!Array.isArray(value)) {
>> -                        ps.push(value);
>> -                        if (ps.length > SIZE + 1) {
>> -                            ps.shift();
>> -                        }
>> -                    } else {
>> -                        ps = ps.concat(value);
>> -                        ps.splice(0, ps.length - SIZE - 1);
>> -                        unifiedMetrics['points'] = ps;
>> -                    }
>> -                    if (max !== undefined) {
>> -                        unifiedMetrics['max'] = max;
>> -                    } else {
>> -                        if (unifiedMetrics['type'] !== 'value') {
>> -                            continue;
>> -                        }
>> -                        max = -Infinity;
>> -                        $.each(ps, function(i, value) {
>> -                            if (value > max) {
>> -                                max = value;
>> -                            }
>> -                        });
>> -                        if (max === 0) {
>> -                            ++max;
>> -                        }
>> -                        max *= 1.1;
>> -                        unifiedMetrics['max'] = max;
>> -                    }
>> -                }
>> -            }
>> -            cursor++;
>> -        };
>> -
>> -        var get = function(which) {
>> -            var stats = statsArray[which];
>> -            var lines = [];
>> -            for (var k in stats) {
>> -                var obj = stats[k];
>> -                var line = {
>> -                    type: obj['type'],
>> -                    base: obj['base'],
>> -                    unit: obj['unit'],
>> -                    fixed: obj['fixed'],
>> -                    legend: obj['legend']
>> -                };
>> -                if (obj['max']) {
>> -                    line['max'] = obj['max'];
>> -                }
>> -                if (obj['class']) {
>> -                    line['class'] = obj['class'];
>> -                }
>> -                var ps = obj['points'];
>> -                var numStats = ps.length;
>> -                var unifiedPoints = [];
>> -                $.each(ps, function(i, value) {
>> -                    unifiedPoints.push({
>> -                        x: cursor - numStats + i,
>> -                        y: value
>> -                    });
>> -                });
>> -                line['points'] = unifiedPoints;
>> -                lines.push(line);
>> -            }
>> -            return lines;
>> -        };
>> -
>> -        return {
>> -            add: add,
>> -            get: get
>> -        };
>> -    };
>> -
>> -    var Tracker = function(charts) {
>> -        var charts = charts;
>> -        var timer = null;
>> -        var statsPool = new StatsMgr();
>> -        var setCharts = function(newCharts) {
>> -            charts = newCharts;
>> -            for (var key in charts) {
>> -                var chart = charts[key];
>> -                chart.updateUI(statsPool.get(key));
>> -            }
>> -        };
>> -
>> -        var self = this;
>> -
>> -        var UnifyStats = function(stats) {
>> -            var result = {
>> -                cpu: {
>> -                    u: {
>> -                        v: stats['cpu_utilization']
>> -                    }
>> -                },
>> -                memory: {
>> -                    u: {}
>> -                },
>> -                diskIO: {
>> -                    w: {
>> -                        v: stats['disk_write_rate']
>> -                    },
>> -                    r: {
>> -                        v: stats['disk_read_rate']
>> -                    }
>> -                },
>> -                networkIO: {
>> -                    s: {
>> -                        v: stats['net_sent_rate']
>> -                    },
>> -                    r: {
>> -                        v: stats['net_recv_rate']
>> -                    }
>> -                }
>> -            };
>> -            if (Array.isArray(stats['memory'])) {
>> -                result.memory.u['v'] = [];
>> -                result.memory.u['max'] = -Infinity;
>> -                for (var i = 0; i < stats['memory'].length; i++) {
>> - result.memory.u['v'].push(stats['memory'][i]['avail']);
>> -                    result.memory.u['max'] = 
>> Math.max(result.memory.u['max'], stats['memory'][i]['total']);
>> -                }
>> -            } else {
>> -                result.memory.u['v'] = stats['memory']['avail'],
>> -                    result.memory.u['max'] = stats['memory']['total']
>> -            }
>> -            return (result);
>> -        };
>> -
>> -
>> -        var statsCallback = function(stats) {
>> -            var unifiedStats = UnifyStats(stats);
>> -            statsPool.add(unifiedStats);
>> -            for (var key in charts) {
>> -                var chart = charts[key];
>> -                chart.updateUI(statsPool.get(key));
>> -            }
>> -            timer = setTimeout(function() {
>> -                continueTrack();
>> -            }, 1000);
>> -        };
>> -
>> -        var track = function() {
>> -            gingerbase.getHostStatsHistory(statsCallback,
>> -                function() {
>> -                    continueTrack();
>> -                });
>> -        };
>> -
>> -        var continueTrack = function() {
>> -            gingerbase.getHostStats(statsCallback,
>> -                function() {
>> -                    continueTrack();
>> -                });
>> -        };
>> -
>> -        var destroy = function() {
>> -            timer && clearTimeout(timer);
>> -            timer = null;
>> -        };
>> -
>> -        return {
>> -            setCharts: setCharts,
>> -            start: track,
>> -            stop: destroy
>> -        };
>> -    };
>> -
>> -    var initTracker = function() {
>> -        // TODO: Extend tabs with onUnload event to unregister timers.
>> -        if (gingerbase.hostTimer) {
>> -            gingerbase.hostTimer.stop();
>> -            delete gingerbase.hostTimer;
>> -        }
>> -
>> -        var trackedCharts = {
>> -            cpu: new wok.widget.LineChart({
>> -                id: 'chart-cpu',
>> -                node: 'container-chart-cpu',
>> -                type: 'percent'
>> -            }),
>> -            memory: new wok.widget.LineChart({
>> -                id: 'chart-memory',
>> -                node: 'container-chart-memory',
>> -                type: 'value'
>> -            }),
>> -            diskIO: new wok.widget.LineChart({
>> -                id: 'chart-disk-io',
>> -                node: 'container-chart-disk-io',
>> -                type: 'value'
>> -            }),
>> -            networkIO: new wok.widget.LineChart({
>> -                id: 'chart-network-io',
>> -                node: 'container-chart-network-io',
>> -                type: 'value'
>> -            })
>> -        };
>> -
>> -        if (gingerbase.hostTimer) {
>> -            gingerbase.hostTimer.setCharts(trackedCharts);
>> -        } else {
>> -            gingerbase.hostTimer = new Tracker(trackedCharts);
>> -            gingerbase.hostTimer.start();
>> -        }
>> -    };
>> -
>> -    $('#host-root-container').on('remove', function() {
>> -        if (gingerbase.hostTimer) {
>> -            gingerbase.hostTimer.stop();
>> -            delete gingerbase.hostTimer;
>> -        }
>> -
>> -        repositoriesGrid && repositoriesGrid.destroy();
>> -        wok.topic('gingerbase/repositoryAdded')
>> -            .unsubscribe(listRepositories);
>> -        wok.topic('gingerbase/repositoryUpdated')
>> -            .unsubscribe(listRepositories);
>> -        wok.topic('gingerbase/repositoryDeleted')
>> -            .unsubscribe(listRepositories);
>> -
>> -        softwareUpdatesGrid && softwareUpdatesGrid.destroy();
>> - 
>> wok.topic('gingerbase/softwareUpdated').unsubscribe(listSoftwareUpdates);
>> -
>> -        reportGrid && reportGrid.destroy();
>> - 
>> wok.topic('gingerbase/debugReportAdded').unsubscribe(listDebugReports);
>> - 
>> wok.topic('gingerbase/debugReportRenamed').unsubscribe(listDebugReports);
>> -    });
>> -};
>> diff --git 
>> a/src/wok/plugins/gingerbase/ui/pages/host-dashboard.html.tmpl 
>> b/src/wok/plugins/gingerbase/ui/pages/host-dashboard.html.tmpl
>> new file mode 100644
>> index 0000000..06b8088
>> --- /dev/null
>> +++ b/src/wok/plugins/gingerbase/ui/pages/host-dashboard.html.tmpl
>> @@ -0,0 +1,135 @@
>> +#*
>> + * Project Ginger Base
>> + *
>> + * Copyright IBM, Corp. 2013-2015
>> + *
>> + * Code derived from Project Kimchi
>> + *
>> + * Licensed under the Apache License, Version 2.0 (the "License");
>> + * you may not use this file except in compliance with the License.
>> + * You may obtain a copy of the License at
>> + *
>> + *     http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + *#
>> +
>> +#unicode UTF-8
>> +#import gettext
>> +#from wok.cachebust import href
>> +#silent t = gettext.translation($lang.domain, $lang.localedir, 
>> languages=$lang.lang, fallback=True)
>> +#silent _ = t.gettext
>> +#silent _t = t.gettext
>> +<!DOCTYPE html>
>> +<html>
>> +<head>
>> +<link rel="stylesheet" href="plugins/gingerbase/css/gingerbase.css">
>> +<script src="plugins/gingerbase/js/gingerbase.min.js"></script>
>> +</head>
>> +<body>
>> +<div id="host-root-container">
>> +<nav class="navbar navbar-default toolbar">
>> +  <div class="container">
>> +    <!-- Brand and toggle get grouped for better mobile display -->
>> +    <div class="navbar-header">
>> +      <button type="button" class="navbar-toggle collapsed" 
>> data-toggle="collapse" data-target="#toolbar" aria-expanded="false">
>> +        <span class="sr-only">Toggle navigation</span>
>> +        <span class="icon-bar"></span>
>> +        <span class="icon-bar"></span>
>> +        <span class="icon-bar"></span>
>> +      </button>
>> +    </div>
>> +
>> +    <!-- Collect the nav links, forms, and other content for 
>> toggling -->
>> +    <div class="collapse navbar-collapse" id="toolbar">
>> +      <ul class="nav navbar-nav navbar-right tools">
>> +        <li><a id="host-button-restart" 
>> href="javascript:void(0);"><i class="fa 
>> fa-undo"></i><span>$_("Restart")</span></a></li>
>> +        <li><a id="host-button-shutdown" 
>> href="javascript:void(0);"><i class="fa fa-ban"></i><span>$_("Shut 
>> down")</span></a></li>
>> +        <!-- <li><a href="javascript:void(0);"><i class="fa 
>> fa-desktop"></i><span>$_("Connect")</span></a></li> -->
>> +      </ul>
>> +    </div>
>> +  </div>
>> +</nav>
>> +    <div id="host-content-container" 
>> class="empty-when-logged-off"></div>
>> +</div>
>> +
>> +<script id="host-dashboard-tmpl" type="gingerbase/template">
>> +<div class="host-dashboard">
>> +    <div class="container">
>> +        <div id="alert-container"></div>
>> +        <div id="content-sys-statistics" class="row">
>> +            <div class="col-md-3">
>> +                <div id="cpu-dashboard">
>> +                    <h3 class="section-label">$_("CPU")</h3>
>> +                    <div class="section-value">
>> +                        <div id="container-chart-cpu" 
>> class="inline-block"></div>
>> +                    </div>
>> +                </div>
>> +            </div>
>> +            <div class="col-md-3">
>> +                <div id="memory-dashboard">
>> +                    <h3 class="section-label">$_("Memory")</h3>
>> +                    <div class="section-value">
>> +                        <div id="container-chart-memory" 
>> class="inline-block"></div>
>> +                    </div>
>> +                </div>
>> +            </div>
>> +            <div class="col-md-3">
>> +                <div id="disk-dashboard">
>> +                    <h3 class="section-label">$_("Disk I/O")</h3>
>> +                    <div class="section-value">
>> +                        <div id="container-chart-disk-io" 
>> class="inline-block"></div>
>> +                    </div>
>> +                </div>
>> +            </div>
>> +            <div class="col-md-3">
>> +                <div id="network-dashboard">
>> +                    <h3 class="section-label">$_("Network I/O")</h3>
>> +                    <div class="section-value">
>> +                        <div id="container-chart-network-io" 
>> class="inline-block"></div>
>> +                    </div>
>> +                </div>
>> +            </div>
>> +        </div>
>> +    </div>
>> +</div>
>> +<div class="host-panel">
>> +    <div class="container">
>> +        <div id="host-info-container" class="row">
>> +            <div id="content-sys-info" class="panel panel-default 
>> col-md-6">
>> +                <div class="panel-heading">
>> +                    <h3 class="panel-title">$_("Basic 
>> Information")</h3>
>> +                </div>
>> +                <div class="panel-body">
>> +                    <dl class="basic-information-list">
>> +                        <dt>{os_distro}</dt>
>> +                        <dd>$_("OS Distro")</dd>
>> +                        <dt>{os_version}</dt>
>> +                        <dd>$_("OS Version")</dd>
>> +                        <dt>{os_codename}</dt>
>> +                        <dd>$_("OS Code Name")</dd>
>> +                        <dt>{cpu_model}</dt>
>> +                        <dd>$_("Processor")</dd>
>> +                        <dt>{cpus}</dt>
>> +                        <dd>$_("CPU(s)")</dd>
>> +                        <dt>{memory}</dt>
>> +                        <dd>$_("Memory")</dd>
>> +                    </dl>
>> +                </div>
>> +            </div>
>> +            <div id="debug-report-section" class="col-md-6 
>> hidden"></div>
>> +        </div>
>> +    </div>
>> +</div>
>> +</script>
>> +<div id="modalWindow" class="modal fade host-modal" tabindex="-1" 
>> role="dialog" aria-labelledby="hostsModalLabel" aria-hidden="true">
>> +</div>
>> +<script type="text/javascript">
>> +    gingerbase.host_dashboard();
>> +</script>
>> +</body>
>> +</html>
>> diff --git 
>> a/src/wok/plugins/gingerbase/ui/pages/host-update.html.tmpl 
>> b/src/wok/plugins/gingerbase/ui/pages/host-update.html.tmpl
>> new file mode 100644
>> index 0000000..20790ed
>> --- /dev/null
>> +++ b/src/wok/plugins/gingerbase/ui/pages/host-update.html.tmpl
>> @@ -0,0 +1,90 @@
>> +#*
>> + * Project Ginger Base
>> + *
>> + * Copyright IBM, Corp. 2013-2015
>> + *
>> + * Code derived from Project Kimchi
>> + *
>> + * Licensed under the Apache License, Version 2.0 (the "License");
>> + * you may not use this file except in compliance with the License.
>> + * You may obtain a copy of the License at
>> + *
>> + *     http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + *#
>> +
>> +#unicode UTF-8
>> +#import gettext
>> +#from wok.cachebust import href
>> +#silent t = gettext.translation($lang.domain, $lang.localedir, 
>> languages=$lang.lang, fallback=True)
>> +#silent _ = t.gettext
>> +#silent _t = t.gettext
>> +<!DOCTYPE html>
>> +<html>
>> +<head>
>> +<link rel="stylesheet" href="plugins/gingerbase/css/gingerbase.css">
>> +<script src="plugins/gingerbase/js/gingerbase.min.js"></script>
>> +</head>
>> +<body>
>> +<div id="host-root-container">
>> +<nav class="navbar navbar-default toolbar">
>> +  <div class="container">
>> +    <!-- Brand and toggle get grouped for better mobile display -->
>> +    <div class="navbar-header">
>> +      <button type="button" class="navbar-toggle collapsed" 
>> data-toggle="collapse" data-target="#toolbar" aria-expanded="false">
>> +        <span class="sr-only">Toggle navigation</span>
>> +        <span class="icon-bar"></span>
>> +        <span class="icon-bar"></span>
>> +        <span class="icon-bar"></span>
>> +      </button>
>> +    </div>
>> +
>> +    <!-- Collect the nav links, forms, and other content for 
>> toggling -->
>> +    <div class="collapse navbar-collapse" id="toolbar">
>> +    </div>
>> +  </div>
>> +</nav>
>> +    <div id="host-content-container" 
>> class="empty-when-logged-off"></div>
>> +</div>
>> +
>> +<script id="host-update-tmpl" type="gingerbase/template">
>> +<div class="host-panel">
>> +    <div class="container">
>> +        <div  id="host-info-container" class="row">
>> +            <div id="repositories-section" class="col-md-12 
>> hidden"></div>
>> +        </div>
>> +        <div class="row">
>> +            <div id="software-update-section" class="panel 
>> panel-default col-md-12 hidden">
>> +                <div class="panel-heading">
>> +                    <h3 class="panel-title">$_("Software Updates")</h3>
>> +                </div>
>> +                <div id="content-software-update" class="panel 
>> panel-default">
>> +                    <div id="software-updates-grid-container"></div>
>> +                    <div id="software-updates-progress-container" 
>> class="hidden">
>> +                        <div class="software-updates-main">
>> +                            <h3>
>> +                                <a role="button" 
>> data-toggle="collapse" data-parent="#accordion" 
>> href="#software-updates-progress-textarea" aria-expanded="true" 
>> aria-controls="software-updates-progress-textarea" class="">
>> +                                <span 
>> class="accordion-icon"></span><span class="accordion-text">$_("Update 
>> Progress")</span>
>> +                            </a>
>> +                            </h3>
>> +                            <textarea class="collapse in" 
>> id="software-updates-progress-textarea" readonly></textarea>
>> +                        </div>
>> +                    </div>
>> +                </div>
>> +            </div>
>> +        </div>
>> +    </div>
>> +</div>
>> +</script>
>> +<div id="modalWindow" class="modal fade host-modal" tabindex="-1" 
>> role="dialog" aria-labelledby="hostsModalLabel" aria-hidden="true">
>> +</div>
>> +<script type="text/javascript">
>> +    gingerbase.host_update();
>> +</script>
>> +</body>
>> +</html>
>> diff --git a/src/wok/plugins/gingerbase/ui/pages/host.html.tmpl 
>> b/src/wok/plugins/gingerbase/ui/pages/host.html.tmpl
>> deleted file mode 100644
>> index d17f184..0000000
>> --- a/src/wok/plugins/gingerbase/ui/pages/host.html.tmpl
>> +++ /dev/null
>> @@ -1,156 +0,0 @@
>> -#*
>> - * Project Ginger Base
>> - *
>> - * Copyright IBM, Corp. 2013-2015
>> - *
>> - * Code derived from Project Kimchi
>> - *
>> - * Licensed under the Apache License, Version 2.0 (the "License");
>> - * you may not use this file except in compliance with the License.
>> - * You may obtain a copy of the License at
>> - *
>> - *     http://www.apache.org/licenses/LICENSE-2.0
>> - *
>> - * Unless required by applicable law or agreed to in writing, software
>> - * distributed under the License is distributed on an "AS IS" BASIS,
>> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> - * See the License for the specific language governing permissions and
>> - * limitations under the License.
>> - *#
>> -
>> -#unicode UTF-8
>> -#import gettext
>> -#from wok.cachebust import href
>> -#silent t = gettext.translation($lang.domain, $lang.localedir, 
>> languages=$lang.lang, fallback=True)
>> -#silent _ = t.gettext
>> -#silent _t = t.gettext
>> -<!DOCTYPE html>
>> -<html>
>> -<head>
>> -<link rel="stylesheet" href="plugins/gingerbase/css/gingerbase.css">
>> -<script src="plugins/gingerbase/js/gingerbase.min.js"></script>
>> -</head>
>> -<body>
>> -<div id="host-root-container">
>> -<nav class="navbar navbar-default toolbar">
>> -  <div class="container">
>> -    <!-- Brand and toggle get grouped for better mobile display -->
>> -    <div class="navbar-header">
>> -      <button type="button" class="navbar-toggle collapsed" 
>> data-toggle="collapse" data-target="#toolbar" aria-expanded="false">
>> -        <span class="sr-only">Toggle navigation</span>
>> -        <span class="icon-bar"></span>
>> -        <span class="icon-bar"></span>
>> -        <span class="icon-bar"></span>
>> -      </button>
>> -    </div>
>> -
>> -    <!-- Collect the nav links, forms, and other content for 
>> toggling -->
>> -    <div class="collapse navbar-collapse" id="toolbar">
>> -      <ul class="nav navbar-nav navbar-right tools">
>> -        <li><a id="host-button-restart" 
>> href="javascript:void(0);"><i class="fa 
>> fa-undo"></i><span>$_("Restart")</span></a></li>
>> -        <li><a id="host-button-shutdown" 
>> href="javascript:void(0);"><i class="fa fa-ban"></i><span>$_("Shut 
>> down")</span></a></li>
>> -        <!-- <li><a href="javascript:void(0);"><i class="fa 
>> fa-desktop"></i><span>$_("Connect")</span></a></li> -->
>> -      </ul>
>> -    </div>
>> -  </div>
>> -</nav>
>> -    <div id="host-content-container" 
>> class="empty-when-logged-off"></div>
>> -</div>
>> -
>> -<script id="host-tmpl" type="gingerbase/template">
>> -<div class="host-dashboard">
>> -    <div class="container">
>> -        <div id="alert-container"></div>
>> -        <div id="content-sys-statistics" class="row">
>> -            <div class="col-md-3">
>> -                <div id="cpu-dashboard">
>> -                    <h3 class="section-label">$_("CPU")</h3>
>> -                    <div class="section-value">
>> -                        <div id="container-chart-cpu" 
>> class="inline-block"></div>
>> -                    </div>
>> -                </div>
>> -            </div>
>> -            <div class="col-md-3">
>> -                <div id="memory-dashboard">
>> -                    <h3 class="section-label">$_("Memory")</h3>
>> -                    <div class="section-value">
>> -                        <div id="container-chart-memory" 
>> class="inline-block"></div>
>> -                    </div>
>> -                </div>
>> -            </div>
>> -            <div class="col-md-3">
>> -                <div id="disk-dashboard">
>> -                    <h3 class="section-label">$_("Disk I/O")</h3>
>> -                    <div class="section-value">
>> -                        <div id="container-chart-disk-io" 
>> class="inline-block"></div>
>> -                    </div>
>> -                </div>
>> -            </div>
>> -            <div class="col-md-3">
>> -                <div id="network-dashboard">
>> -                    <h3 class="section-label">$_("Network I/O")</h3>
>> -                    <div class="section-value">
>> -                        <div id="container-chart-network-io" 
>> class="inline-block"></div>
>> -                    </div>
>> -                </div>
>> -            </div>
>> -        </div>
>> -    </div>
>> -</div>
>> -<div class="host-panel">
>> -    <div class="container">
>> -        <div id="host-info-container" class="row">
>> -            <div id="content-sys-info" class="panel panel-default 
>> col-md-12">
>> -                <div class="panel-heading">
>> -                    <h3 class="panel-title">$_("Basic 
>> Information")</h3>
>> -                </div>
>> -                <div class="panel-body">
>> -                    <dl class="basic-information-list">
>> -                        <dt>{os_distro}</dt>
>> -                        <dd>$_("OS Distro")</dd>
>> -                        <dt>{os_version}</dt>
>> -                        <dd>$_("OS Version")</dd>
>> -                        <dt>{os_codename}</dt>
>> -                        <dd>$_("OS Code Name")</dd>
>> -                        <dt>{cpu_model}</dt>
>> -                        <dd>$_("Processor")</dd>
>> -                        <dt>{cpus}</dt>
>> -                        <dd>$_("CPU(s)")</dd>
>> -                        <dt>{memory}</dt>
>> -                        <dd>$_("Memory")</dd>
>> -                    </dl>
>> -                </div>
>> -            </div>
>> -            <div id="repositories-section" class="col-md-8 
>> hidden"></div>
>> -            <div id="debug-report-section" class="col-md-8 
>> hidden"></div>
>> -        </div>
>> -        <div class="row">
>> -            <div id="software-update-section" class="panel 
>> panel-default col-md-12 hidden">
>> -                <div class="panel-heading">
>> -                    <h3 class="panel-title">$_("Software Updates")</h3>
>> -                </div>
>> -                <div id="content-software-update" class="panel 
>> panel-default">
>> -                    <div id="software-updates-grid-container"></div>
>> -                    <div id="software-updates-progress-container" 
>> class="hidden">
>> -                        <div class="software-updates-main">
>> -                            <h3>
>> -                                <a role="button" 
>> data-toggle="collapse" data-parent="#accordion" 
>> href="#software-updates-progress-textarea" aria-expanded="true" 
>> aria-controls="software-updates-progress-textarea" class="">
>> -                                <span 
>> class="accordion-icon"></span><span class="accordion-text">$_("Update 
>> Progress")</span>
>> -                            </a>
>> -                            </h3>
>> -                            <textarea class="collapse in" 
>> id="software-updates-progress-textarea" readonly></textarea>
>> -                        </div>
>> -                    </div>
>> -                </div>
>> -            </div>
>> -        </div>
>> -    </div>
>> -</div>
>> -</script>
>> -<div id="modalWindow" class="modal fade host-modal" tabindex="-1" 
>> role="dialog" aria-labelledby="hostsModalLabel" aria-hidden="true">
>> -</div>
>> -<script type="text/javascript">
>> -    gingerbase.host_main();
>> -</script>
>> -</body>
>> -</html>
>
> _______________________________________________
> Kimchi-devel mailing list
> Kimchi-devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>




More information about the Kimchi-devel mailing list