Skip to content

Commit

Permalink
feat: make Podman machine editable (podman-desktop#4999)
Browse files Browse the repository at this point in the history
* feat: make Podman machine editable

Fixes podman-desktop#4113

Signed-off-by: Jeff MAURY <[email protected]>
  • Loading branch information
jeffmaury authored Dec 6, 2023
1 parent 5b6a27a commit dbf6e9c
Show file tree
Hide file tree
Showing 20 changed files with 703 additions and 368 deletions.
16 changes: 12 additions & 4 deletions extensions/podman/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,41 +43,49 @@
"format": "cpu",
"minimum": 1,
"default": 2,
"maximum": "HOST_TOTAL_CPU",
"scope": "ContainerConnection",
"description": "CPU(s)"
},
"podman.machine.cpusUsage": {
"type": "number",
"format": "cpuUsage",
"scope": "ContainerConnection",
"description": "CPU(s) usage"
"description": "CPU(s) usage",
"readonly": true
},
"podman.machine.memory": {
"type": "number",
"format": "memory",
"minimum": 1000000000,
"default": 4000000000,
"maximum": "HOST_TOTAL_MEMORY",
"scope": "ContainerConnection",
"step": 500000000,
"description": "Memory"
},
"podman.machine.memoryUsage": {
"type": "number",
"format": "memoryUsage",
"scope": "ContainerConnection",
"description": "Memory usage"
"description": "Memory usage",
"readonly": true
},
"podman.machine.diskSize": {
"type": "array",
"type": "number",
"format": "diskSize",
"default": 100000000000,
"maximum": "HOST_TOTAL_DISKSIZE",
"scope": "ContainerConnection",
"step": 500000000,
"description": "Disk size"
},
"podman.machine.diskSizeUsage": {
"type": "number",
"format": "diskSizeUsage",
"scope": "ContainerConnection",
"description": "Disk size usage"
"description": "Disk size usage",
"readonly": true
},
"podman.factory.machine.name": {
"type": "string",
Expand Down
31 changes: 31 additions & 0 deletions extensions/podman/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,37 @@ async function registerProviderFor(provider: extensionApi.Provider, machineInfo:
delete: async (logger): Promise<void> => {
await extensionApi.process.exec(getPodmanCli(), ['machine', 'rm', '-f', machineInfo.name], { logger });
},
edit: async (context, params, logger, _token): Promise<void> => {
let effective = false;
const args = ['machine', 'set', machineInfo.name];
for (const key of Object.keys(params)) {
if (key === 'podman.machine.cpus') {
args.push('--cpus', params[key]);
effective = true;
} else if (key === 'podman.machine.memory') {
args.push('--memory', Math.floor(params[key] / (1024 * 1024)).toString());
effective = true;
} else if (key === 'podman.machine.diskSize') {
args.push('--disk-size', Math.floor(params[key] / (1024 * 1024 * 1024)).toString());
effective = true;
}
}
if (effective) {
const state = podmanMachinesStatuses.get(machineInfo.name);
try {
if (state === 'started') {
await lifecycle.stop(context, logger);
}
await extensionApi.process.exec(getPodmanCli(), args, {
logger: new LoggerDelegator(context, logger),
});
} finally {
if (state === 'started') {
await lifecycle.start(context, logger);
}
}
}
},
};

const containerProviderConnection: extensionApi.ContainerProviderConnection = {
Expand Down
7 changes: 7 additions & 0 deletions packages/extension-api/src/extension-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,13 @@ declare module '@podman-desktop/api' {
start?(startContext: LifecycleContext, logger?: Logger): Promise<void>;
stop?(stopContext: LifecycleContext, logger?: Logger): Promise<void>;
delete?(logger?: Logger): Promise<void>;
edit?(
editContext: LifecycleContext,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
params: { [key: string]: any },
logger?: Logger,
token?: CancellationToken,
): Promise<void>;
}

export interface ContainerProviderConnectionEndpoint {
Expand Down
2 changes: 1 addition & 1 deletion packages/main/src/plugin/api/provider-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import type {
ProviderInformation,
} from '@podman-desktop/api';

export type LifecycleMethod = 'start' | 'stop' | 'delete';
export type LifecycleMethod = 'start' | 'stop' | 'delete' | 'edit';

export interface ProviderContainerConnectionInfo {
name: string;
Expand Down
22 changes: 22 additions & 0 deletions packages/main/src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,28 @@ export class PluginSystem {
},
);

this.ipcHandle(
'provider-registry:editProviderConnectionLifecycle',
async (
_listener: Electron.IpcMainInvokeEvent,
providerId: string,
providerConnectionInfo: ProviderContainerConnectionInfo | ProviderKubernetesConnectionInfo,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
params: { [key: string]: any },
loggerId: string,
tokenId?: number,
): Promise<void> => {
const logger = this.getLogHandler('provider-registry:taskConnection-onData', loggerId);
let token;
if (tokenId) {
const tokenSource = cancellationTokenRegistry.getCancellationTokenSource(tokenId);
token = tokenSource?.token;
}
await providerRegistry.editProviderConnection(providerId, providerConnectionInfo, params, logger, token);
logger.onEnd();
},
);

this.ipcHandle(
'provider-registry:deleteProviderConnectionLifecycle',
async (
Expand Down
37 changes: 37 additions & 0 deletions packages/main/src/plugin/provider-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,9 @@ export class ProviderRegistry {
if (connection.lifecycle.stop) {
lifecycleMethods.push('stop');
}
if (connection.lifecycle.edit) {
lifecycleMethods.push('edit');
}
providerConnection.lifecycleMethods = lifecycleMethods;
}
return providerConnection;
Expand Down Expand Up @@ -903,6 +906,40 @@ export class ProviderRegistry {
}
}

async editProviderConnection(
internalProviderId: string,
providerConnectionInfo: ProviderContainerConnectionInfo | ProviderKubernetesConnectionInfo,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
params: { [key: string]: any },
logHandler?: Logger,
token?: CancellationToken,
): Promise<void> {
// grab the correct provider
const connection = this.getMatchingConnectionFromProvider(internalProviderId, providerConnectionInfo);

const lifecycle = connection.lifecycle;
if (!lifecycle?.edit) {
throw new Error('The container connection does not support edit lifecycle');
}

const context = this.connectionLifecycleContexts.get(connection);
if (!context) {
throw new Error('The connection does not have context to edit');
}

const provider = this.providers.get(internalProviderId);
if (!provider) {
throw new Error('Cannot find provider');
}

try {
await lifecycle.edit(context, params, logHandler, token);
} catch (err) {
console.warn(`Can't edit connection ${provider.id}.${providerConnectionInfo.name}`, err);
throw err;
}
}

async stopProviderConnection(
internalProviderId: string,
providerConnectionInfo: ProviderContainerConnectionInfo | ProviderKubernetesConnectionInfo,
Expand Down
25 changes: 25 additions & 0 deletions packages/preload/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,31 @@ function initExposure(): void {
},
);

contextBridge.exposeInMainWorld(
'editProviderConnectionLifecycle',
async (
providerId: string,
providerConnectionInfo: ProviderContainerConnectionInfo | ProviderKubernetesConnectionInfo,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
params: { [key: string]: any },
key: symbol,
keyLogger: (key: symbol, eventName: 'log' | 'warn' | 'error' | 'finish', args: string[]) => void,
tokenId?: number,
): Promise<void> => {
onDataCallbacksTaskConnectionId++;
onDataCallbacksTaskConnectionKeys.set(onDataCallbacksTaskConnectionId, key);
onDataCallbacksTaskConnectionLogs.set(onDataCallbacksTaskConnectionId, keyLogger);
return ipcInvoke(
'provider-registry:editProviderConnectionLifecycle',
providerId,
providerConnectionInfo,
params,
onDataCallbacksTaskConnectionId,
tokenId,
);
},
);

contextBridge.exposeInMainWorld(
'deleteProviderConnectionLifecycle',
async (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { configurationProperties } from '/@/stores/configurationProperties';
import { providerInfos } from '/@/stores/providers';
import type { IConfigurationPropertyRecordedSchema } from '../../../../main/src/plugin/configuration-registry';
import type { ProviderInfo } from '../../../../main/src/plugin/api/provider-info';
import PreferencesConnectionCreationRendering from '../preferences/PreferencesConnectionCreationRendering.svelte';
import PreferencesConnectionCreationOrEditRendering from '../preferences/PreferencesConnectionCreationOrEditRendering.svelte';
import type { OnboardingEmbeddedComponentType } from '../../../../main/src/plugin/api/onboarding';
import { faTriangleExclamation } from '@fortawesome/free-solid-svg-icons';
import Fa from 'svelte-fa';
Expand Down Expand Up @@ -43,15 +43,15 @@ onMount(() => {
Create a {providerDisplayName}
</h1>
{#if component === 'createContainerProviderConnection' && providerInfo?.containerProviderConnectionCreation === true}
<PreferencesConnectionCreationRendering
<PreferencesConnectionCreationOrEditRendering
providerInfo="{providerInfo}"
properties="{configurationItems}"
propertyScope="ContainerProviderConnectionFactory"
callback="{window.createContainerProviderConnection}"
disableEmptyScreen="{true}"
hideCloseButton="{true}" />
{:else if component === 'createKubernetesProviderConnection' && providerInfo?.kubernetesProviderConnectionCreation === true}
<PreferencesConnectionCreationRendering
<PreferencesConnectionCreationOrEditRendering
providerInfo="{providerInfo}"
properties="{configurationItems}"
propertyScope="KubernetesProviderConnectionFactory"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { faPlay, faRotateRight, faStop, faTrash } from '@fortawesome/free-solid-svg-icons';
import { faEdit, faPlay, faRotateRight, faStop, faTrash } from '@fortawesome/free-solid-svg-icons';
import type {
ProviderContainerConnectionInfo,
ProviderInfo,
Expand All @@ -8,6 +8,8 @@ import type {
import LoadingIconButton from '../ui/LoadingIconButton.svelte';
import { type ConnectionCallback, eventCollect, startTask } from './preferences-connection-rendering-task';
import { type IConnectionRestart, type IConnectionStatus } from './Util';
import { router } from 'tinro';
import { Buffer } from 'buffer';
export let connectionStatus: IConnectionStatus | undefined;
export let provider: ProviderInfo;
Expand Down Expand Up @@ -97,6 +99,17 @@ async function stopConnectionProvider(
}
}
async function editConnectionProvider(
provider: ProviderInfo,
providerConnectionInfo: ProviderContainerConnectionInfo | ProviderKubernetesConnectionInfo,
): Promise<void> {
router.goto(
`/preferences/container-connection/edit/${provider.internalId}/${Buffer.from(providerConnectionInfo.name).toString(
'base64',
)}`,
);
}
async function deleteConnectionProvider(
provider: ProviderInfo,
providerConnectionInfo: ProviderContainerConnectionInfo | ProviderKubernetesConnectionInfo,
Expand Down Expand Up @@ -169,6 +182,14 @@ function getLoggerHandler(
state="{connectionStatus}"
leftPosition="left-[0.22rem]" />
{/if}
{#if connection.lifecycleMethods.includes('edit')}
<LoadingIconButton
clickAction="{() => editConnectionProvider(provider, connection)}"
action="edit"
icon="{faEdit}"
state="{connectionStatus}"
leftPosition="left-[0.22rem]" />
{/if}
{#if connection.lifecycleMethods.includes('delete')}
<div class="mr-2 text-sm">
<LoadingIconButton
Expand Down
Loading

0 comments on commit dbf6e9c

Please sign in to comment.