$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); });
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); }); }
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"); }); }
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; }
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; };
* (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
* * 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");
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(); }; }