mirror of
https://github.com/podman-desktop/podman-desktop
synced 2026-04-21 17:47:22 +00:00
chore: remove CRC extension from the assembly
it has been moved to a separate repository https://github.com/crc-org/crc-extension Change-Id: Ib3a0ed0bc81a04cba35575a652e1351270d71793 Signed-off-by: Florent Benoit <fbenoit@redhat.com>
This commit is contained in:
parent
c089238b06
commit
2a75673123
11 changed files with 1 additions and 592 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
|
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
"name": "crc",
|
||||
"displayName": "CRC",
|
||||
"description": "Allows the ability to start and stop CRC and use Podman Desktop to interact with it",
|
||||
"version": "0.0.1",
|
||||
"icon": "icon.png",
|
||||
"publisher": "benoitf",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"podman-desktop": "^0.0.1"
|
||||
},
|
||||
"main": "./dist/extension.js",
|
||||
"source": "./src/extension.ts",
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "crc.info",
|
||||
"title": "crc: Specific info about crc"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup --bundleConfigAsCjs --config rollup.config.js --compact --environment BUILD:production && node ./scripts/build.js",
|
||||
"watch": "rollup --bundleConfigAsCjs --config rollup.config.js -w"
|
||||
},
|
||||
"dependencies": {
|
||||
"@podman-desktop/api": "^0.0.1",
|
||||
"got": "^12.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"7zip-min": "^1.4.4",
|
||||
"mkdirp": "^2.1.5",
|
||||
"zip-local": "^0.3.5"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
// rollup.config.js
|
||||
import typescript from '@rollup/plugin-typescript';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import json from '@rollup/plugin-json';
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||
|
||||
export default {
|
||||
input: 'src/extension.ts',
|
||||
output: {
|
||||
dir: 'dist',
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
},
|
||||
external: [
|
||||
'@podman-desktop/api',
|
||||
'node:stream',
|
||||
'node:http',
|
||||
'node:url',
|
||||
'node:process',
|
||||
'node:tls',
|
||||
'node:util',
|
||||
'node:buffer',
|
||||
'node:https',
|
||||
'node:events',
|
||||
'node:net',
|
||||
'node:process',
|
||||
'node:path',
|
||||
'node:os',
|
||||
'node:fs',
|
||||
'node:child_process',
|
||||
],
|
||||
plugins: [
|
||||
typescript(),
|
||||
commonjs({ extensions: ['.js', '.ts'] }), // the ".ts" extension is required],
|
||||
json(),
|
||||
nodeResolve({preferBuiltins: true}),
|
||||
],
|
||||
};
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
#!/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
|
||||
***********************************************************************/
|
||||
|
||||
const zipper = require('zip-local');
|
||||
const path = require('path');
|
||||
const package = require('../package.json');
|
||||
const { mkdirp } = require('mkdirp');
|
||||
const fs = require('fs');
|
||||
|
||||
const destFile = path.resolve(__dirname, `../${package.name}.cdix`);
|
||||
const builtinDirectory = path.resolve(__dirname, '../builtin');
|
||||
const unzippedDirectory = path.resolve(builtinDirectory, `${package.name}.cdix`);
|
||||
// remove the .cdix file before zipping
|
||||
if (fs.existsSync(destFile)) {
|
||||
fs.rmSync(destFile);
|
||||
}
|
||||
// remove the builtin folder before zipping
|
||||
if (fs.existsSync(builtinDirectory)) {
|
||||
fs.rmSync(builtinDirectory, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
zipper.sync.zip(path.resolve(__dirname, '../')).compress().save(destFile);
|
||||
|
||||
// create unzipped built-in
|
||||
mkdirp(unzippedDirectory).then(() => {
|
||||
zipper.sync.unzip(destFile).save(unzippedDirectory);
|
||||
});
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/**********************************************************************
|
||||
* 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<Status> {
|
||||
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<string> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,261 +0,0 @@
|
|||
/**********************************************************************
|
||||
* 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 '@podman-desktop/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<void> {
|
||||
// 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<boolean> {
|
||||
// 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<void> {
|
||||
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<void> {
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/**********************************************************************
|
||||
* 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 '@podman-desktop/api';
|
||||
import type { DaemonCommander } from './daemon-commander';
|
||||
|
||||
export class LogProvider {
|
||||
private timeout: NodeJS.Timeout;
|
||||
constructor(private readonly commander: DaemonCommander) {}
|
||||
|
||||
async startSendingLogs(logger: Logger): Promise<void> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/**********************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"ES2017",
|
||||
"webworker"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"rootDir": "src",
|
||||
"outDir": "dist",
|
||||
"skipLibCheck": true,
|
||||
"types": [
|
||||
"node",
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
|
|
@ -21,8 +21,7 @@
|
|||
"scripts": {
|
||||
"build": "npm run build:main && npm run build:preload && npm run build:preload-docker-extension && npm run build:renderer && npm run build:extensions",
|
||||
"build:main": "cd ./packages/main && vite build",
|
||||
"build:extensions": "npm run build:extensions:docker && npm run build:extensions:lima && npm run build:extensions:crc && npm run build:extensions:podman && npm run build:extensions:kubecontext && npm run build:extensions:kind && npm run build:extensions:registries",
|
||||
"build:extensions:crc": "cd ./extensions/crc && npm run build",
|
||||
"build:extensions": "npm run build:extensions:docker && npm run build:extensions:lima && npm run build:extensions:podman && npm run build:extensions:kubecontext && npm run build:extensions:kind && npm run build:extensions:registries",
|
||||
"build:extensions:docker": "cd ./extensions/docker && npm run build",
|
||||
"build:extensions:kubecontext": "cd ./extensions/kube-context && npm run build",
|
||||
"build:extensions:kind": "cd ./extensions/kind && npm run build",
|
||||
|
|
|
|||
|
|
@ -159,7 +159,6 @@ const setupExtensionApiWatcher = name => {
|
|||
});
|
||||
|
||||
await viteDevServer.listen();
|
||||
await setupExtensionApiWatcher('crc');
|
||||
await setupExtensionApiWatcher('docker');
|
||||
await setupExtensionApiWatcher('kube-context');
|
||||
await setupExtensionApiWatcher('lima');
|
||||
|
|
|
|||
Loading…
Reference in a new issue