Example #1
0
                $q.when(connect, function connected(options) {
                    cockpit.event_target(ws);

                    channel = cockpit.channel(angular.extend({ }, options, {
                        payload: "websocket-stream1",
                        path: url,
                        protocols: protocols,
                    }));

                    channel.addEventListener("close", function(ev, options) {
                        var problem = options.problem || "";
                        channel = null;

                        state = 3;
                        var cev = document.createEvent('Event');
                        cev.initEvent('close', false, false, !!problem, 1000, problem);
                        ws.dispatchEvent(cev);
                    });

                    channel.addEventListener("message", function(ev, data) {
                        var mev = document.createEvent('MessageEvent');
                        if (!mev.initMessageEvent)
                            mev = new window.MessageEvent('message', { 'data': data });
                        else
                            mev.initMessageEvent('message', false, false, data, null, null, window, null);
                        ws.dispatchEvent(mev);
                    });

                    state = 1;
                    var oev = document.createEvent('Event');
                    oev.initEvent('open', false, false);
                    ws.dispatchEvent(oev);
                });
Example #2
0
    constructor() {
        this.state = {
            installed: undefined,
            enabled: undefined,
            state: undefined,
            config: undefined,
            target: undefined,
        };
        cockpit.event_target(this);

        // listen to service status changes
        this.kdumpService = serviceProxy("kdump");
        this.kdumpService.addEventListener('changed', () => {
            this.state.installed = this.kdumpService.exists;
            this.state.enabled = this.kdumpService.enabled;
            this.state.state = this.kdumpService.state;
            this.dispatchEvent("kdumpStatusChanged", this.state);
        });

        // watch the config file
        this.configClient = new ConfigFile("/etc/kdump.conf", true);
        // catch config changes
        this.configClient.addEventListener('kdumpConfigChanged', () => {
            this.state.config = this.configClient.settings;
            this.state.target = this.targetFromSettings(this.configClient.settings);
            this.dispatchEvent("kdumpStatusChanged", this.state);
        });
    }
Example #3
0
function Packages(promise, transform) {
    var self = this;
    self.error = null;
    self.ready = false;
    self.empty = false;

    cockpit.event_target(self);

    promise
        .done(function(result) {
            var empty = true;
            if (transform)
                result = transform(result);

            for (var k in result) {
                self[k] = result[k];
                empty = false;
            }

            self.empty = empty;
            self.valid = true;
        })
        .fail(function(ex) {
            self.error = cockpit.message(ex);
        })
        .always(function() {
            self.ready = true;
            self.dispatchEvent("changed");
        });
}
Example #4
0
function get_metainfo_db() {
    if (!metainfo_db) {
        metainfo_db = cockpit.event_target({
            ready: false,
            components: [ ],
            origin_files: [ ]
        });

        var buf = "";
        cockpit.spawn(pyinvoke,
                      { environ: [ "LANGUAGE=" + (cockpit.language || "en") ]
                      })
            .input(watch_appstream_py)
            .stream(function (data) {
                var lines, metadata;

                buf += data;
                lines = buf.split("\n");
                buf = lines[lines.length-1];
                if (lines.length >= 2) {
                    metadata = JSON.parse(lines[lines.length-2]);
                    metainfo_db.components = metadata.components;
                    metainfo_db.origin_files = metadata.origin_files;
                    metainfo_db.ready = true;
                    metainfo_db.dispatchEvent("changed");
                }
            }).
            fail(function (error) {
                if (error != "closed") {
                    console.warn(error);
                }
            });
    }

    return metainfo_db;
}
Example #5
0
            return function KubeFakeWebSocket(url, protocols) {
                var cmd = parser(url);
                var base64 = false;

                /* A fake WebSocket */
                var channel;
                var state = 0; /* CONNECTING */
                var ws = { };
                cockpit.event_target(ws);

                function open() {
                    channel = cockpit.channel({
                        payload: "stream",
                        spawn: cmd,
                        pty: true
                    });

                    channel.addEventListener("close", function(ev, options) {
                        var problem = options.problem || "";
                        channel = null;

                        state = 3;
                        var cev = document.createEvent('Event');
                        cev.initEvent('close', false, false, !!problem, 1000, problem);
                        ws.dispatchEvent(cev);
                    });

                    channel.addEventListener("message", function(ev, data) {
                        if (base64)
                            data = "1" + window.btoa(data);
                        var mev = document.createEvent('MessageEvent');
                        if (!mev.initMessageEvent)
                            mev = new window.MessageEvent('message', { 'data': data });
                        else
                            mev.initMessageEvent('message', false, false, data, null, null, window, null);
                        ws.dispatchEvent(mev);
                    });

                    state = 1;
                    var oev = document.createEvent('Event');
                    oev.initEvent('open', false, false);
                    ws.dispatchEvent(oev);
                }

                function fail() {
                    var ev = document.createEvent('Event');
                    ev.initEvent('close', false, false, false, 1002, "protocol-error");
                    ws.dispatchEvent(ev);
                }

                function close(code, reason) {
                    if (channel)
                        channel.close(reason);
                }

                function send(data) {
                    if (base64)
                        data = window.atob(data.slice(1));
                    if (channel)
                        channel.send(data);
                }

                /* A fake WebSocket */
                Object.defineProperties(ws, {
                    binaryType: { value: "arraybuffer" },
                    bufferedAmount: { value: 0 },
                    extensions: { value: "" },
                    protocol: { value: base64 ? "base64.channel.k8s.io" : "" },
                    readyState: { get: function() { return state; } },
                    url: { value: url },
                    close: { value: close },
                    send: { value: send },
                });

                var valid = true;
                if (protocols) {
                    if (angular.isArray(protocols))
                        valid = base64 = protocols.indexOf("base64.channel.k8s.io") !== -1;
                    else
                        valid = base64 = "base64.channel.k8s.io";
                }

                if (valid) {
                    window.setTimeout(open);
                } else {
                    console.warn("Unsupported kubernetes container WebSocket subprotocol: " + protocols);
                    window.setTimeout(fail);
                }

                return ws;
            };
Example #6
0
 * (at your option) any later version.
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

var cockpit = require("cockpit");
var moment = require("moment");

var atomic = {};
cockpit.event_target(atomic);

var bus = cockpit.dbus();
var intervalId;

function sanitizeVulnerableInfo (id, info) {
    return {
        id: id,
        successful: info.Successful === true || info.Successful === "true",
        scanType: info["Scan Type"],
        finishedTime: moment(info.FinishedTime),
        vulnerabilities: info.Vulnerabilities.map(function (v) {
            return {
                title: v.Title,
                description: v.Description,
                severity: v.Severity
Example #7
0
 *
 * Cockpit is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
 */

import cockpit from "cockpit";
const _ = cockpit.gettext;

export var client = { };

cockpit.event_target(client);

client.subscriptionStatus = {
    serviceStatus: undefined,
    status: undefined,
    products: [],
    error: undefined,
};

// we trigger an event called "dataChanged" when the data has changed

// DBUS service
var service;

function needRender() {
    var ev = document.createEvent("Event");
Example #8
0
function RPMOSTreeDBusClient() {
    var self = this;

    cockpit.event_target(self);

    self.connection_error = null;
    self.os_list = [];

    var sysroot = null;
    var os_proxies = {};
    var os_proxies_added = null;

    var os_names = {};
    var packages_cache = {};

    var local_running = null;
    var booted_id = null;

    var client = null;
    var waits = null;
    var timer = null;
    var skipped = false;

    Object.defineProperty(this, "running_method", {
        enumerable: false,
        get: function() {
            if (local_running) {
                return local_running;
            } else if (sysroot && sysroot.ActiveTransaction) {
                var active = sysroot.ActiveTransaction[0];
                var proxy = os_proxies[sysroot.ActiveTransaction[2]];

                if (proxy && active)
                    active = active + ":" + proxy.Name;

                return active;
            } else {
                return null;
            }
        }
    });

    function resolve_nested(obj, path) {
        return path.split('.').reduce( function( prev, curr ) {
            if (prev !== undefined)
                return prev[curr];
            else
                return prev;
        }, obj || {} );
    }

    function trigger_changed() {
        if (!timer) {
            self.dispatchEvent("changed");
            timer = window.setTimeout(function() {
                timer = null;
                if (skipped)
                    self.dispatchEvent("changed");
                skipped = false;
            }, 300);
        } else {
            skipped = true;
        }
    }


    function get_client() {
        if (!client) {
            self.connection_error = null;
            self.os_list = [];

            sysroot = null;
            os_proxies = {};
            os_proxies_added = null;

            os_names = {};
            packages_cache = {};

            local_running = null;
            booted_id = null;

            var timer = null;
            var skipped = false;

            waits = cockpit.defer();
            waits.promise.done(trigger_changed);

            client = cockpit.dbus(DEST, {"superuser" : true,
                                         "capabilities" : ["address"]});

            /* Watch before listening for close because watch fires first */
            client.watch(PATH).fail(tear_down);
            client.addEventListener("close", closing);

            sysroot = client.proxy(SYSROOT, SYSROOT_PATH);
            sysroot.addEventListener("changed", on_sysroot_changed);
            sysroot.wait(function() {
                if (sysroot && sysroot.valid)
                    build_os_list(sysroot.Deployments);

                if (client) {
                    os_proxies = client.proxies(OS, PATH);
                    os_proxies_added = function(event, proxy) {
                        if (proxy.Name)
                            os_names[proxy.Name] = proxy.path;
                        trigger_changed();
                    };
                    os_proxies.addEventListener("changed", trigger_changed);
                    os_proxies.addEventListener("added", os_proxies_added);

                    os_proxies.wait(function() {
                        for (var path in os_proxies) {
                            var proxy = os_proxies[path];
                            os_names[path] = path;
                        }
                        waits.resolve();
                    });
                } else {
                    waits.resolve();
                }
            });



       }
       return client;
    }

    function tear_down(ex) {
        client = null;
        self.connection_error = ex;
        if (sysroot) {
            sysroot.removeEventListener("changed", on_sysroot_changed);
            sysroot = null;
        }
        if (os_proxies) {
            if (os_proxies_added)
                os_proxies.removeEventListener("added", os_proxies_added);
            os_proxies_added = null;
            os_proxies = {};
        }
    }

    function closing(event, ex) {
        tear_down(ex);
        self.dispatchEvent("connectionLost", [ ex ]);
    }

    /* The order of deployments indicates
     * the order the OS names should be in.
     */
    function build_os_list(data) {
        var seen = {};
        var os_list = [];
        if (data) {
            for (var i = 0; i < data.length; i++) {
                var deployment = data[i];
                var id = deployment.id.v;
                var os = deployment.osname.v;

                if (!seen[os])
                    os_list.push(os);
                seen[os] = true;
            }
        }

        self.os_list = os_list;
        trigger_changed();
    }

    function on_sysroot_changed(ev, data) {
        if (data["Deployments"]) {
            build_os_list(data["Deployments"]);
        } else if ("ActiveTransaction" in data) {
            trigger_changed();
        }
    }

    self.connect = function() {
        var dp = cockpit.defer();
        get_client();
        waits.promise.done(function() {
            if (self.connection_error)
                dp.reject(self.connection_error);
            else
                dp.resolve(client);
        });
        return dp.promise;
    };

    self.known_versions_for = function(os_name) {
        /* The number of deployments should always be a small
         * number. If that turns out to not be the case we
         * can cache this on a local property.
         */
        var deployments = sysroot ? sysroot.Deployments : [];
        var list = [];
        var upgrade_checksum;

        var proxy = self.get_os_proxy(os_name);
        if (proxy)
            upgrade_checksum = resolve_nested(proxy, "CachedUpdate.checksum.v");

        for (var i = 0; i < deployments.length; i++) {
            var deployment = deployments[i];
            var checksum = resolve_nested(deployment, "checksum.v");

            // always show the default deployment,
            // skip showing the upgrade if it is the
            // same as the default.
            if (self.item_matches(deployment, "DefaultDeployment")) {
                if (upgrade_checksum && checksum !== upgrade_checksum)
                    list.push(proxy.CachedUpdate);
                list.push(deployment);

            // skip other deployments if it is the same as the upgrade
            } else if (resolve_nested(deployment, "checksum.v") !== upgrade_checksum) {
                list.push(deployment);
            }
        }

        return list;
    };

    self.get_os_proxy = function(os_name) {
        var path = os_names[os_name];
        var proxy = null;
        if (path)
            proxy = os_proxies[path];
        return proxy;
    };

    /* Because all our deployment package diffs can only
     * change when the machine is rebooted we
     * fetch and store them once here and
     * never fetch them again.
     * Pending updates are tracked by checksum since those
     * can change.
     */
    self.packages = function(item) {
        var id = resolve_nested(item, "id.v");
        var checksum = resolve_nested(item, "checksum.v");
        var key = id;

        if (!id && checksum)
            key = checksum;

        if (!booted_id) {
            var root_proxy = os_proxies[sysroot.Booted];
            if (root_proxy)
                booted_id = root_proxy.BootedDeployment.id.v;
            else
                return;
        }

        if (key && !packages_cache[key]) {
            var proxy = self.get_os_proxy(item.osname.v);
            var packages;
            var promise;
            if (proxy) {
                if (id === booted_id) {
                    promise = cockpit.spawn(['rpm', '-qa']);
                    packages = new Packages(promise,
                                            process_rpm_list);
                } else if (id) {
                    promise = proxy.call("GetDeploymentsRpmDiff",
                                             [booted_id, id]);
                    packages = new Packages(promise,
                                            process_diff_list);
                } else {
                    promise = proxy.call("GetCachedUpdateRpmDiff", [""]);
                    packages = new Packages(promise,
                                            process_diff_list);
                }
                packages_cache[key] = packages;
            }
        }
        return packages_cache[key];
    };

    self.item_matches = function(item, attr) {
        var os_name = resolve_nested(item, "osname.v");
        var proxy = null;
        var item2 = null;

        if (!os_name)
            return false;

        proxy = self.get_os_proxy(os_name);
        item2 = resolve_nested(proxy, attr);

        return resolve_nested(item, "checksum.v") === resolve_nested(item2, "checksum.v");
    };

    self.run_transaction = function(method, method_args, os) {
        local_running = method + ":" + os;
        var transaction_client = null;
        var subscription = null;
        var dp = cockpit.defer();
        var i;
        var reboot = false;

        if (Array.isArray(method_args)) {
            for (i = 0; i < method_args.length; i++) {
                var val = method_args[i];
                if (val !== null && typeof val === 'object' && "reboot" in val) {
                    reboot = method_args[i].reboot;
                    break;
                }
            }
        }

        function cleanup(ex) {
            local_running = null;
            if (transaction_client) {
                if (subscription)
                    subscription.remove();

                transaction_client.removeEventListener("close", on_close);
                transaction_client.close();
            }
            transaction_client = null;
            subscription = null;
            trigger_changed();
        }

        function fail(ex) {
            dp.reject(ex);
            cleanup();
        }

        function on_close(event, ex) {
            fail(ex);
        }

        self.connect()
            .fail(fail)
            .done(function () {
                var proxy = self.get_os_proxy(os);

                if (!proxy)
                    return fail(cockpit.format(_("OS $0 not found"), os));

                proxy.call(method, method_args)
                    .fail(fail)
                    .done(function(result) {
                        var connect_args = {
                            "superuser" : true,
                            "address": result[0],
                            "bus": "none"
                        };

                        if (reboot)
                            cockpit.hint('restart');

                        transaction_client = cockpit.dbus(null, connect_args);
                        transaction_client.addEventListener("close", on_close);

                        subscription = transaction_client.subscribe({ 'path' : "/", },
                            function(path, iface, signal, args) {
                                if (signal == "DownloadProgress") {
                                    var line = build_progress_line(args);
                                    if (line)
                                        dp.notify(line);
                                } else if (signal == "Message") {
                                    dp.notify(args[0]);
                                } else if (signal == "Finished") {
                                    if (args) {
                                        if (args[0]) {
                                            dp.resolve(args[1]);
                                            cleanup();
                                        } else {
                                            fail(args[1]);
                                        }
                                    } else {
                                        console.warn("Unexpected transaction response", args);
                                        fail({ "problem": "protocol-error" });
                                    }
                                }
                            });
                        transaction_client.call("/", TRANSACTION, "Start");
                    });
            });

        return dp.promise();
    };
}