mirror of
https://github.com/podman-desktop/podman-desktop
synced 2026-05-24 10:18:53 +00:00
feat(dd): add support for backend extensions of Docker Desktop (#3435)
fix https://github.com/containers/podman-desktop/issues/2397 Signed-off-by: Florent Benoit <fbenoit@redhat.com>
This commit is contained in:
parent
eaa8a87afd
commit
97239a78f7
5 changed files with 78 additions and 19 deletions
|
|
@ -36,9 +36,15 @@ let dockerDesktopInstallation: TestDockerDesktopInstallation;
|
|||
|
||||
const contributionManagerLoadMetadataMock = vi.fn();
|
||||
const contributionManagerInitMock = vi.fn();
|
||||
const contributionManagerFindComposeBinaryMock = vi.fn();
|
||||
const contributionManagerEnhanceComposeFileMock = vi.fn();
|
||||
const containerProviderStartVMMock = vi.fn();
|
||||
const contributionManager = {
|
||||
init: contributionManagerInitMock,
|
||||
loadMetadata: contributionManagerLoadMetadataMock,
|
||||
findComposeBinary: contributionManagerFindComposeBinaryMock,
|
||||
enhanceComposeFile: contributionManagerEnhanceComposeFileMock,
|
||||
startVM: containerProviderStartVMMock,
|
||||
} as unknown as ContributionManager;
|
||||
|
||||
const containerProviderGetFirstRunningConnectionMock = vi.fn();
|
||||
|
|
@ -318,8 +324,17 @@ test('Check handlePluginInstall', async () => {
|
|||
// mock extractDockerDesktopFiles
|
||||
vi.spyOn(dockerDesktopInstallation, 'extractDockerDesktopFiles').mockResolvedValue();
|
||||
|
||||
// mock findComposeBinary
|
||||
contributionManagerFindComposeBinaryMock.mockResolvedValue('/my-compose-binary');
|
||||
|
||||
// mock enhanceComposeFile
|
||||
contributionManagerEnhanceComposeFileMock.mockResolvedValue('/my-enhanced-compose-file.yaml');
|
||||
|
||||
contributionManagerLoadMetadataMock.mockResolvedValue({
|
||||
name: 'My Extension',
|
||||
vm: {
|
||||
composefile: 'docker-compose.yaml',
|
||||
},
|
||||
});
|
||||
|
||||
const logCallbackId = 2503;
|
||||
|
|
@ -336,4 +351,6 @@ test('Check handlePluginInstall', async () => {
|
|||
|
||||
// contribution manager is called
|
||||
expect(contributionManagerInitMock).toBeCalled();
|
||||
|
||||
expect(containerProviderStartVMMock).toBeCalledWith('My Extension', '/my-enhanced-compose-file.yaml', true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ export class DockerDesktopInstallation {
|
|||
});
|
||||
}
|
||||
|
||||
if (metadata.vm?.composefile) {
|
||||
files.push(metadata.vm.composefile);
|
||||
}
|
||||
|
||||
// host binaries
|
||||
const hostFiles: string[] = [];
|
||||
if (metadata?.host?.binaries) {
|
||||
|
|
@ -377,6 +381,7 @@ export class DockerDesktopInstallation {
|
|||
|
||||
await this.extractDockerDesktopFiles(tmpFolderPath, finalFolderPath, reportLog);
|
||||
|
||||
event.reply('docker-desktop-plugin:install-log', logCallbackId, 'Loading metadata...');
|
||||
// check metadata. If name is missing, add the one from the image
|
||||
const metadata = await this.contributionManager.loadMetadata(finalFolderPath);
|
||||
if (!metadata.name) {
|
||||
|
|
@ -385,8 +390,41 @@ export class DockerDesktopInstallation {
|
|||
await this.contributionManager.saveMetadata(finalFolderPath, metadata);
|
||||
}
|
||||
|
||||
// if there is a VM, need to generate the updated compose file
|
||||
let enhancedComposeFile;
|
||||
if (metadata.vm) {
|
||||
// check compose presence
|
||||
event.reply('docker-desktop-plugin:install-log', logCallbackId, 'Check compose being setup...');
|
||||
const foundPath = await this.contributionManager.findComposeBinary();
|
||||
if (!foundPath) {
|
||||
event.reply('docker-desktop-plugin:install-error', logCallbackId, 'Compose binary not found.');
|
||||
return;
|
||||
} else {
|
||||
event.reply('docker-desktop-plugin:install-log', logCallbackId, `Compose binary found at ${foundPath}.`);
|
||||
}
|
||||
|
||||
event.reply('docker-desktop-plugin:install-log', logCallbackId, 'Enhance compose file...');
|
||||
// need to update the compose file
|
||||
try {
|
||||
enhancedComposeFile = await this.contributionManager.enhanceComposeFile(finalFolderPath, imageName, metadata);
|
||||
} catch (error) {
|
||||
event.reply('docker-desktop-plugin:install-error', logCallbackId, error);
|
||||
return;
|
||||
}
|
||||
|
||||
// try to start the VM
|
||||
event.reply('docker-desktop-plugin:install-log', logCallbackId, 'Starting compose project...');
|
||||
await this.contributionManager.startVM(metadata.name, enhancedComposeFile, true);
|
||||
}
|
||||
|
||||
event.reply('docker-desktop-plugin:install-end', logCallbackId, 'Extension Successfully installed.');
|
||||
|
||||
// refresh contributions
|
||||
await this.contributionManager.init();
|
||||
try {
|
||||
await this.contributionManager.init();
|
||||
} catch (error) {
|
||||
event.reply('docker-desktop-plugin:install-error', logCallbackId, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -295,40 +295,44 @@ export class DockerExtensionPreload {
|
|||
hostname,
|
||||
};
|
||||
|
||||
const vmServicePort = urlParams.get('vmServicePort') || undefined;
|
||||
|
||||
// do we have a service being exposed ?
|
||||
const doRequest = async (config: RequestConfig): Promise<unknown> => {
|
||||
if (vmServicePort) {
|
||||
return ipcRenderer.invoke('docker-desktop-adapter:extensionVMServiceRequest', vmServicePort, config);
|
||||
} else {
|
||||
throw new Error(`no service port defined for request ${config}`);
|
||||
}
|
||||
};
|
||||
|
||||
const extensionVMService: dockerDesktopAPI.HttpService = {
|
||||
get: async (url: string): Promise<unknown> => {
|
||||
console.error('extensionVMService.get not implemented', url);
|
||||
return {} as any;
|
||||
return doRequest({ url, method: 'GET', headers: {}, data: undefined });
|
||||
},
|
||||
post: async (url: string, data: any): Promise<unknown> => {
|
||||
console.error('extensionVMService.post not implemented', url, data);
|
||||
return {} as any;
|
||||
return doRequest({ url, method: 'POST', headers: {}, data });
|
||||
},
|
||||
put: async (url: string, data: any): Promise<unknown> => {
|
||||
console.error('extensionVMService.put not implemented', url, data);
|
||||
return {} as any;
|
||||
return doRequest({ url, method: 'PUT', headers: {}, data });
|
||||
},
|
||||
patch: async (url: string, data: any): Promise<unknown> => {
|
||||
console.error('extensionVMService.patch not implemented', url, data);
|
||||
return {} as any;
|
||||
return doRequest({ url, method: 'PATCH', headers: {}, data });
|
||||
},
|
||||
delete: async (url: string): Promise<unknown> => {
|
||||
console.error('extensionVMService.delete not implemented', url);
|
||||
return {} as any;
|
||||
return doRequest({ url, method: 'DELETE', headers: {}, data: undefined });
|
||||
},
|
||||
head: async (url: string): Promise<unknown> => {
|
||||
console.error('extensionVMService.head not implemented', url);
|
||||
return {} as any;
|
||||
return doRequest({ url, method: 'HEAD', headers: {}, data: undefined });
|
||||
},
|
||||
request: async (config: RequestConfig): Promise<unknown> => {
|
||||
console.error('extensionVMService.request not implemented', config);
|
||||
return {} as any;
|
||||
return doRequest(config);
|
||||
},
|
||||
};
|
||||
|
||||
const extensionCliVM: dockerDesktopAPI.ExtensionCli = {
|
||||
//FIXME:
|
||||
exec: {} as any,
|
||||
// need to call exec inside a container for the VM service
|
||||
exec: this.getExec('VM_SERVICE'),
|
||||
};
|
||||
|
||||
const extensionVM: dockerDesktopAPI.ExtensionVM = {
|
||||
|
|
|
|||
|
|
@ -1229,7 +1229,7 @@ function initExposure(): void {
|
|||
});
|
||||
|
||||
contextBridge.exposeInMainWorld('ddExtensionDelete', async (extensionName: string): Promise<void> => {
|
||||
return ipcRenderer.invoke('docker-desktop-plugin:delete', extensionName);
|
||||
return ipcInvoke('docker-desktop-plugin:delete', extensionName);
|
||||
});
|
||||
|
||||
contextBridge.exposeInMainWorld('getDDPreloadPath', async (): Promise<string> => {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ window.events?.receive('dev-tools:open-extension', extensionId => {
|
|||
<Route path="/*" breadcrumb="{name}">
|
||||
<webview
|
||||
id="dd-webview-{webviewId}"
|
||||
src="{source}?extensionName={currentContrib.extensionId}&arch={arch}&hostname={hostname}&platform={platform}"
|
||||
src="{source}?extensionName={currentContrib.extensionId}&arch={arch}&hostname={hostname}&platform={platform}&vmServicePort={currentContrib.vmServicePort}"
|
||||
preload="{preloadPath}"
|
||||
style="height: 100%; width: 100%"></webview>
|
||||
</Route>
|
||||
|
|
|
|||
Loading…
Reference in a new issue