From 5961657a477ebaf6351711b535591932d2848a82 Mon Sep 17 00:00:00 2001 From: Yevhen Vydolob Date: Fri, 3 Mar 2023 10:51:31 +0200 Subject: [PATCH] Copy code frm podman-desktop repository Signed-off-by: Yevhen Vydolob --- .gitignore | 10 ++ LICENSE | 202 +++++++++++++++++++++++++++++++ README.md | 27 +++++ icon.png | Bin 0 -> 1394 bytes package.json | 39 ++++++ rollup.config.js | 38 ++++++ scripts/build.js | 43 +++++++ scripts/run.mjs | 116 ++++++++++++++++++ src/daemon-commander.ts | 119 ++++++++++++++++++ src/extension.ts | 261 ++++++++++++++++++++++++++++++++++++++++ src/log-provider.ts | 43 +++++++ src/util.ts | 32 +++++ tsconfig.json | 18 +++ 13 files changed, 948 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 icon.png create mode 100644 package.json create mode 100644 rollup.config.js create mode 100755 scripts/build.js create mode 100644 scripts/run.mjs create mode 100644 src/daemon-commander.ts create mode 100644 src/extension.ts create mode 100644 src/log-provider.ts create mode 100644 src/util.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1007f72 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +node_modules +.DS_Store +dist +.eslintcache +*.cdix +.idea +**/test-resources +**/coverage +yarn-error.log +builtin diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md index a14925d..fe28d6c 100644 --- a/README.md +++ b/README.md @@ -1 +1,28 @@ # CRC extension + +This repo copied from [podman-desktop crc extension](https://github.com/containers/podman-desktop/tree/main/extensions/crc) + +# Run and build + +To build this extension use: + +```shell + yarn desk:build +``` + +>Note: all command will check that parent directory contains [podman-desktop](https://github.com/containers/podman-desktop) repo, and if its doesn't, it will clone it. + +If you want to prepare dev environment, use: + +```shell +yarn desk:prepare +``` +This command check/clone podman-desktop and replace existing crc extension with this one. + +To launch podman-desktop with this crc extension use: + +```shell +yarn desk:run +``` + +>Note: If you do any modification of code inside this repo, you need to rerun any command described above to copy your changes in to podman-desktop repo. Automatic update not implemented yet. diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7db6eba9c86fbf13dc4afcd39fd15657cb2fbb7f GIT binary patch literal 1394 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k2}mkgS)OEIV72sgaSW-L^XBepFX?>d;~(c} zm}GkIe$i-Da$iSBB#L88%eAQ$5gck?A14OcJXY?ty3FyNUtMNr7sebanzX7=Qmu+7k z9&SH*@??!&{p;*Y@rMr|UcGvCz5M0dw|8&bW@cjY#OTTQ_xE?kv3{FSO>8QCCA-){XJrB*y^y= zv9Yl)zc=@Z@vz13ttwrgzb1O!si#F|v$yJ;?v7n7UGwLM;q0^1yi~sz-8p1sYy0=t z*VXsg9o1jGd}(QES?L2zqf3G`_kZs{XKG}Wbo*QL;Z)y-EefQ_jo>=?b_guaI zmk9iy7qBANK3Csm@x_@lC2vl<@YQIhkBL-n_06ZB!tYAwY9ZVy^gBR zv;MbpVboeZJv}v{&Ip}n-y { + zipper.sync.unzip(destFile).save(unzippedDirectory); +}); diff --git a/scripts/run.mjs b/scripts/run.mjs new file mode 100644 index 0000000..b03b14c --- /dev/null +++ b/scripts/run.mjs @@ -0,0 +1,116 @@ +#!/usr/bin/env node +/********************************************************************** + * Copyright (C) 2022 Red Hat, Inc. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import * as fs from 'fs'; +import * as path from 'path'; +import * as cp from 'node:child_process'; +import * as util from 'node:util'; + +// const exec = util.promisify(cp.exec); + +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const desktopPath = path.join(__dirname, '..', '..', 'podman-desktop'); +let isNeedToInstallDependencies = false; + +async function exec(command, args, options) { + return new Promise((resolve, reject) => { + const proc = cp.spawn(command, args, options); + proc.stderr.pipe(process.stderr); + proc.stdout.pipe(process.stdout); + proc.on('close', () => { + resolve(); + }); + + proc.on('error', () => { + reject(); + }) + }); +} + +async function checkAndCloneDesktopRepo() { + if(!fs.existsSync(desktopPath)) { + console.log('Cloning podman-desktop repository...'); + await exec('git', ['clone', 'git@github.com:containers/podman-desktop.git'], {cwd: path.join(__dirname, '..', '..')}) + isNeedToInstallDependencies = true; + } else { + console.log('desktop repo already exist...'); + } +} + +function copyExt() { + const crcExtPath = path.join(desktopPath, 'extensions', 'crc'); + if(fs.existsSync(crcExtPath)){ + console.log('Deleting old crc extensions'); + fs.rmSync(crcExtPath, {recursive: true}); + } + fs.mkdirSync(crcExtPath); + const ourExtensionPath = path.join(__dirname, '..', '..', 'crc-extension'); + console.log('Copying own crc extension...'); + fs.cpSync(ourExtensionPath + path.sep, crcExtPath, {recursive: true}); + + console.log('All done, go ' + desktopPath + ' and run "yarn watch" to start podman-desktop with this extension.'); +} + +async function prepareDev() { + await checkAndCloneDesktopRepo(); + copyExt(); + if(isNeedToInstallDependencies){ + console.warn('But first you need to call "yarn" to install dependencies'); + } +} + +async function build() { + await checkAndCloneDesktopRepo(); + copyExt(); + + await exec('yarn',undefined, {cwd: path.join(__dirname, '..', '..', 'podman-desktop'), }); + await exec('yarn',['build'], {cwd: path.join(__dirname, '..', '..', 'podman-desktop')}); +} + +async function run() { + copyExt(); + await exec('yarn',['watch'], {cwd: path.join(__dirname, '..', '..', 'podman-desktop')}); +} + +async function watch() { + throw new Error('Implement watch'); +} + +const firstArg = process.argv[2]; + +switch(firstArg) { + case 'watch': + await watch(); + break; + case 'build': + await build(); + break; + + case 'run': + await run(); + break; + + case 'prepare' : + default: + await prepareDev(); +} diff --git a/src/daemon-commander.ts b/src/daemon-commander.ts new file mode 100644 index 0000000..0c0dbbb --- /dev/null +++ b/src/daemon-commander.ts @@ -0,0 +1,119 @@ +/********************************************************************** + * Copyright (C) 2022 Red Hat, Inc. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import got from 'got'; +import { isWindows } from './util'; + +export interface Status { + readonly CrcStatus: string; + readonly Preset?: string; + readonly OpenshiftStatus?: string; + readonly OpenshiftVersion?: string; + readonly PodmanVersion?: string; + readonly DiskUse?: number; + readonly DiskSize?: number; +} + +export class DaemonCommander { + private apiPath: string; + + constructor() { + this.apiPath = `http://unix:${process.env.HOME}/.crc/crc-http.sock:/api`; + + if (isWindows()) { + this.apiPath = 'http://unix://?/pipe/crc-http:/api'; + } + } + + async status(): Promise { + const url = this.apiPath + '/status'; + + try { + const { body } = await got.get(url); + return JSON.parse(body); + } catch (error) { + // ignore status error, as it may happen when no cluster created + return { + CrcStatus: 'No Cluster', + }; + } + } + + async logs() { + const url = this.apiPath + '/logs'; + const { body } = await got.get(url); + return JSON.parse(body); + } + + async version() { + const url = this.apiPath + '/version'; + + const { body } = await got(url); + return JSON.parse(body); + } + + async start() { + const url = this.apiPath + '/start'; + const { body } = await got.get(url); + return JSON.parse(body); + } + + async stop() { + const url = this.apiPath + '/stop'; + + const { body } = await got.get(url); + return body; + } + + async delete() { + const url = this.apiPath + '/delete'; + + const { body } = await got.get(url); + return body; + } + + async configGet() { + const url = this.apiPath + '/config'; + + const { body } = await got(url); + return JSON.parse(body); + } + + async consoleUrl() { + const url = this.apiPath + '/webconsoleurl'; + + const { body } = await got(url); + return JSON.parse(body); + } + + async pullSecretStore(value: unknown): Promise { + const url = this.apiPath + '/pull-secret'; + + await got.post(url, { + json: value, + }); + return 'OK'; + } + + async pullSecretAvailable() { + const url = this.apiPath + '/pull-secret'; + + const { body } = await got.get(url); + return body; + } +} diff --git a/src/extension.ts b/src/extension.ts new file mode 100644 index 0000000..a6e7598 --- /dev/null +++ b/src/extension.ts @@ -0,0 +1,261 @@ +/********************************************************************** + * Copyright (C) 2022 Red Hat, Inc. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import * as extensionApi from '@tmpwip/extension-api'; +import * as path from 'node:path'; +import * as os from 'node:os'; +import * as fs from 'node:fs'; +import * as childProcess from 'node:child_process'; +import type { Status } from './daemon-commander'; +import { DaemonCommander } from './daemon-commander'; +import { LogProvider } from './log-provider'; +import { isMac, isWindows } from './util'; + +const commander = new DaemonCommander(); +let daemonProcess: childProcess.ChildProcess; +let statusFetchTimer: NodeJS.Timer; + +let crcStatus: Status; + +const crcLogProvider = new LogProvider(commander); + +const defaultStatus = { CrcStatus: 'Unknown', Preset: 'Unknown' }; + +export async function activate(extensionContext: extensionApi.ExtensionContext): Promise { + // crc is installed or not ? + if (!fs.existsSync(crcBinary())) { + console.warn('Can not find CRC binary!'); + return; + } + + // create CRC provider + const provider = extensionApi.provider.createProvider({ + name: 'CRC', + id: 'crc', + status: 'unknown', + images: { + icon: './icon.png', + logo: './icon.png', + }, + }); + extensionContext.subscriptions.push(provider); + + const daemonStarted = await daemonStart(); + if (!daemonStarted) { + return; + } + + try { + // initial status + crcStatus = await commander.status(); + } catch (err) { + console.error('error in CRC extension', err); + crcStatus = defaultStatus; + } + + // detect preset of CRC + const preset = readPreset(crcStatus); + + const providerLifecycle: extensionApi.ProviderLifecycle = { + status: () => convertToProviderStatus(crcStatus?.CrcStatus), + + start: async context => { + try { + crcLogProvider.startSendingLogs(context.log); + await commander.start(); + } catch (err) { + console.error(err); + } + }, + stop: async () => { + console.log('extension:crc: receive the call stop'); + try { + await commander.stop(); + crcLogProvider.stopSendingLogs(); + } catch (err) { + console.error(err); + } + }, + }; + + provider.registerLifecycle(providerLifecycle); + if (preset === 'Podman') { + // podman connection ? + registerPodmanConnection(provider, extensionContext); + } else if (preset === 'OpenShift') { + // OpenShift + registerOpenShiftLocalCluster(provider, extensionContext); + } + + startStatusUpdateTimer(); +} + +function crcBinary(): string { + if (isWindows()) { + // This returns `crc` as located in c:\Program Files\OpenShift Local\ + return path.join('C:\\Program Files\\Red Hat OpenShift Local\\crc.exe'); + } + + if (isMac()) { + // This returns `crc` as located in /usr/local/bin/crc + return '/usr/local/bin/crc'; + } + + // No path provided + return 'crc'; +} + +async function daemonStart(): Promise { + // launching the daemon + daemonProcess = childProcess.spawn(crcBinary(), ['daemon', '--watchdog'], { + detached: true, + windowsHide: true, + }); + + daemonProcess.on('error', err => { + const msg = `Backend failure, Backend failed to start: ${err}`; + // TODO: show error on UI! + console.error('Backend failure', msg); + }); + + daemonProcess.stdout.on('date', () => { + // noop + }); + + daemonProcess.stderr.on('data', () => { + // noop + }); + + return true; +} + +function registerPodmanConnection(provider: extensionApi.Provider, extensionContext: extensionApi.ExtensionContext) { + let socketPath; + + if (isWindows()) { + socketPath = '//./pipe/crc-podman'; + } else { + socketPath = path.resolve(os.homedir(), '.crc/machines/crc/docker.sock'); + } + + if (fs.existsSync(socketPath)) { + const status = () => convertToConnectionStatus(crcStatus?.CrcStatus); + + const containerConnection: extensionApi.ContainerProviderConnection = { + name: 'Podman', + type: 'podman', + endpoint: { + socketPath, + }, + status, + }; + + const disposable = provider.registerContainerProviderConnection(containerConnection); + extensionContext.subscriptions.push(disposable); + } else { + console.error(`Could not find crc podman socket at ${socketPath}`); + } +} + +export function deactivate(): void { + console.log('stopping crc extension'); + if (daemonProcess) { + daemonProcess.kill(); + } + if (statusFetchTimer) { + clearInterval(statusFetchTimer); + } +} + +async function registerOpenShiftLocalCluster( + provider: extensionApi.Provider, + extensionContext: extensionApi.ExtensionContext, +): Promise { + const status = () => convertToConnectionStatus(crcStatus?.CrcStatus); + const apiURL = 'https://api.crc.testing:6443'; + const kubernetesProviderConnection: extensionApi.KubernetesProviderConnection = { + name: 'OpenShift', + endpoint: { + apiURL, + }, + status, + }; + + const disposable = provider.registerKubernetesProviderConnection(kubernetesProviderConnection); + extensionContext.subscriptions.push(disposable); +} + +function convertToConnectionStatus(crcStatus: string): extensionApi.ProviderConnectionStatus { + switch (crcStatus) { + case 'Running': + return 'started'; + case 'Starting': + return 'starting'; + case 'Stopping': + return 'stopping'; + case 'Stopped': + case 'No Cluster': + return 'stopped'; + default: + return 'unknown'; + } +} + +function convertToProviderStatus(crcStatus: string): extensionApi.ProviderStatus { + switch (crcStatus) { + case 'Running': + return 'started'; + case 'Starting': + return 'starting'; + case 'Stopping': + return 'stopping'; + case 'Stopped': + return 'stopped'; + case 'No Cluster': + return 'configured'; + default: + return 'unknown'; + } +} + +async function startStatusUpdateTimer(): Promise { + statusFetchTimer = setInterval(async () => { + try { + crcStatus = await commander.status(); + } catch (e) { + console.error('CRC Status tick: ' + e); + crcStatus = defaultStatus; + } + }, 1000); +} + +function readPreset(crcStatus: Status): 'Podman' | 'OpenShift' | 'unknown' { + try { + switch (crcStatus.Preset) { + case 'podman': + return 'Podman'; + case 'openshift': + return 'OpenShift'; + default: + return 'unknown'; + } + } catch (err) { + console.log('error while getting preset', err); + return 'unknown'; + } +} diff --git a/src/log-provider.ts b/src/log-provider.ts new file mode 100644 index 0000000..5f12b73 --- /dev/null +++ b/src/log-provider.ts @@ -0,0 +1,43 @@ +/********************************************************************** + * Copyright (C) 2022 Red Hat, Inc. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import type { Logger } from '@tmpwip/extension-api'; +import type { DaemonCommander } from './daemon-commander'; + +export class LogProvider { + private timeout: NodeJS.Timeout; + constructor(private readonly commander: DaemonCommander) {} + + async startSendingLogs(logger: Logger): Promise { + let lastLogLine = 0; + this.timeout = setInterval(async () => { + try { + const logs = await this.commander.logs(); + const logsDiff: string[] = logs.Messages.slice(lastLogLine, logs.Messages.length - 1); + lastLogLine = logs.Messages.length; + logger.log(logsDiff.join('\n')); + } catch (e) { + console.log('Logs tick: ' + e); + } + }, 3000); + } + + stopSendingLogs(): void { + clearInterval(this.timeout); + } +} diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..ef87b14 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,32 @@ +/********************************************************************** + * Copyright (C) 2022 Red Hat, Inc. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import * as os from 'node:os'; + +const windows = os.platform() === 'win32'; +export function isWindows(): boolean { + return windows; +} +const mac = os.platform() === 'darwin'; +export function isMac(): boolean { + return mac; +} +const linux = os.platform() === 'linux'; +export function isLinux(): boolean { + return linux; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..398e3bf --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "lib": [ + "ES2017", + "webworker" + ], + "sourceMap": true, + "rootDir": "src", + "outDir": "dist", + "skipLibCheck": true, + "types": [ + "node", + ] +}, +"include": [ + "src" +] +}