@theia/dev-container 1.52.0 → 1.53.0-next.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,132 +1,132 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2024 Typefox and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import { ContributionProvider, MaybePromise, URI } from '@theia/core';
18
- import { inject, injectable, named } from '@theia/core/shared/inversify';
19
- import { WorkspaceServer } from '@theia/workspace/lib/common';
20
- import * as fs from '@theia/core/shared/fs-extra';
21
- import * as Docker from 'dockerode';
22
- import { LastContainerInfo } from '../electron-common/remote-container-connection-provider';
23
- import { DevContainerConfiguration } from './devcontainer-file';
24
- import { DevContainerFileService } from './dev-container-file-service';
25
- import { ContainerOutputProvider } from '../electron-common/container-output-provider';
26
- import { RemoteDockerContainerConnection } from './remote-container-connection-provider';
27
-
28
- export const ContainerCreationContribution = Symbol('ContainerCreationContributions');
29
-
30
- export interface ContainerCreationContribution {
31
- handleContainerCreation?(createOptions: Docker.ContainerCreateOptions,
32
- containerConfig: DevContainerConfiguration,
33
- api: Docker,
34
- outputProvider?: ContainerOutputProvider): MaybePromise<void>;
35
-
36
- /**
37
- * executed after creating and starting the container
38
- */
39
- handlePostCreate?(containerConfig: DevContainerConfiguration,
40
- container: Docker.Container,
41
- api: Docker,
42
- outputProvider?: ContainerOutputProvider): MaybePromise<void>;
43
-
44
- /**
45
- * executed after a connection has been established with the container and theia has been setup
46
- */
47
- handlePostConnect?(containerConfig: DevContainerConfiguration, connection: RemoteDockerContainerConnection,
48
- outputProvider?: ContainerOutputProvider): MaybePromise<void>;
49
- }
50
-
51
- @injectable()
52
- export class DockerContainerService {
53
-
54
- @inject(WorkspaceServer)
55
- protected readonly workspaceServer: WorkspaceServer;
56
-
57
- @inject(ContributionProvider) @named(ContainerCreationContribution)
58
- protected readonly containerCreationContributions: ContributionProvider<ContainerCreationContribution>;
59
-
60
- @inject(DevContainerFileService)
61
- protected readonly devContainerFileService: DevContainerFileService;
62
-
63
- async getOrCreateContainer(docker: Docker, devcontainerFile: string,
64
- lastContainerInfo?: LastContainerInfo, outputProvider?: ContainerOutputProvider): Promise<Docker.Container> {
65
- let container;
66
-
67
- const workspace = new URI(await this.workspaceServer.getMostRecentlyUsedWorkspace());
68
-
69
- if (lastContainerInfo && fs.statSync(devcontainerFile).mtimeMs < lastContainerInfo.lastUsed) {
70
- try {
71
- container = docker.getContainer(lastContainerInfo.id);
72
- if ((await container.inspect()).State.Running) {
73
- await container.restart();
74
- } else {
75
- await container.start();
76
- }
77
- } catch (e) {
78
- container = undefined;
79
- console.warn('DevContainer: could not find last used container');
80
- }
81
- }
82
- if (!container) {
83
- container = await this.buildContainer(docker, devcontainerFile, workspace, outputProvider);
84
- }
85
- return container;
86
- }
87
-
88
- async postConnect(devcontainerFile: string, connection: RemoteDockerContainerConnection, outputProvider?: ContainerOutputProvider): Promise<void> {
89
- const devcontainerConfig = await this.devContainerFileService.getConfiguration(devcontainerFile);
90
-
91
- for (const containerCreateContrib of this.containerCreationContributions.getContributions()) {
92
- await containerCreateContrib.handlePostConnect?.(devcontainerConfig, connection, outputProvider);
93
- }
94
-
95
- }
96
-
97
- protected async buildContainer(docker: Docker, devcontainerFile: string, workspace: URI, outputProvider?: ContainerOutputProvider): Promise<Docker.Container> {
98
- const devcontainerConfig = await this.devContainerFileService.getConfiguration(devcontainerFile);
99
-
100
- if (!devcontainerConfig) {
101
- // TODO add ability for user to create new config
102
- throw new Error('No devcontainer.json');
103
- }
104
-
105
- const containerCreateOptions: Docker.ContainerCreateOptions = {
106
- Tty: true,
107
- ExposedPorts: {},
108
- HostConfig: {
109
- PortBindings: {},
110
- Mounts: [{
111
- Source: workspace.path.toString(),
112
- Target: `/workspaces/${workspace.path.name}`,
113
- Type: 'bind'
114
- }],
115
- },
116
- };
117
-
118
- for (const containerCreateContrib of this.containerCreationContributions.getContributions()) {
119
- await containerCreateContrib.handleContainerCreation?.(containerCreateOptions, devcontainerConfig, docker, outputProvider);
120
- }
121
-
122
- // TODO add more config
123
- const container = await docker.createContainer(containerCreateOptions);
124
- await container.start();
125
-
126
- for (const containerCreateContrib of this.containerCreationContributions.getContributions()) {
127
- await containerCreateContrib.handlePostCreate?.(devcontainerConfig, container, docker, outputProvider);
128
- }
129
-
130
- return container;
131
- }
132
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 Typefox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { ContributionProvider, MaybePromise, URI } from '@theia/core';
18
+ import { inject, injectable, named } from '@theia/core/shared/inversify';
19
+ import { WorkspaceServer } from '@theia/workspace/lib/common';
20
+ import * as fs from '@theia/core/shared/fs-extra';
21
+ import * as Docker from 'dockerode';
22
+ import { LastContainerInfo } from '../electron-common/remote-container-connection-provider';
23
+ import { DevContainerConfiguration } from './devcontainer-file';
24
+ import { DevContainerFileService } from './dev-container-file-service';
25
+ import { ContainerOutputProvider } from '../electron-common/container-output-provider';
26
+ import { RemoteDockerContainerConnection } from './remote-container-connection-provider';
27
+
28
+ export const ContainerCreationContribution = Symbol('ContainerCreationContributions');
29
+
30
+ export interface ContainerCreationContribution {
31
+ handleContainerCreation?(createOptions: Docker.ContainerCreateOptions,
32
+ containerConfig: DevContainerConfiguration,
33
+ api: Docker,
34
+ outputProvider?: ContainerOutputProvider): MaybePromise<void>;
35
+
36
+ /**
37
+ * executed after creating and starting the container
38
+ */
39
+ handlePostCreate?(containerConfig: DevContainerConfiguration,
40
+ container: Docker.Container,
41
+ api: Docker,
42
+ outputProvider?: ContainerOutputProvider): MaybePromise<void>;
43
+
44
+ /**
45
+ * executed after a connection has been established with the container and theia has been setup
46
+ */
47
+ handlePostConnect?(containerConfig: DevContainerConfiguration, connection: RemoteDockerContainerConnection,
48
+ outputProvider?: ContainerOutputProvider): MaybePromise<void>;
49
+ }
50
+
51
+ @injectable()
52
+ export class DockerContainerService {
53
+
54
+ @inject(WorkspaceServer)
55
+ protected readonly workspaceServer: WorkspaceServer;
56
+
57
+ @inject(ContributionProvider) @named(ContainerCreationContribution)
58
+ protected readonly containerCreationContributions: ContributionProvider<ContainerCreationContribution>;
59
+
60
+ @inject(DevContainerFileService)
61
+ protected readonly devContainerFileService: DevContainerFileService;
62
+
63
+ async getOrCreateContainer(docker: Docker, devcontainerFile: string,
64
+ lastContainerInfo?: LastContainerInfo, outputProvider?: ContainerOutputProvider): Promise<Docker.Container> {
65
+ let container;
66
+
67
+ const workspace = new URI(await this.workspaceServer.getMostRecentlyUsedWorkspace());
68
+
69
+ if (lastContainerInfo && fs.statSync(devcontainerFile).mtimeMs < lastContainerInfo.lastUsed) {
70
+ try {
71
+ container = docker.getContainer(lastContainerInfo.id);
72
+ if ((await container.inspect()).State.Running) {
73
+ await container.restart();
74
+ } else {
75
+ await container.start();
76
+ }
77
+ } catch (e) {
78
+ container = undefined;
79
+ console.warn('DevContainer: could not find last used container');
80
+ }
81
+ }
82
+ if (!container) {
83
+ container = await this.buildContainer(docker, devcontainerFile, workspace, outputProvider);
84
+ }
85
+ return container;
86
+ }
87
+
88
+ async postConnect(devcontainerFile: string, connection: RemoteDockerContainerConnection, outputProvider?: ContainerOutputProvider): Promise<void> {
89
+ const devcontainerConfig = await this.devContainerFileService.getConfiguration(devcontainerFile);
90
+
91
+ for (const containerCreateContrib of this.containerCreationContributions.getContributions()) {
92
+ await containerCreateContrib.handlePostConnect?.(devcontainerConfig, connection, outputProvider);
93
+ }
94
+
95
+ }
96
+
97
+ protected async buildContainer(docker: Docker, devcontainerFile: string, workspace: URI, outputProvider?: ContainerOutputProvider): Promise<Docker.Container> {
98
+ const devcontainerConfig = await this.devContainerFileService.getConfiguration(devcontainerFile);
99
+
100
+ if (!devcontainerConfig) {
101
+ // TODO add ability for user to create new config
102
+ throw new Error('No devcontainer.json');
103
+ }
104
+
105
+ const containerCreateOptions: Docker.ContainerCreateOptions = {
106
+ Tty: true,
107
+ ExposedPorts: {},
108
+ HostConfig: {
109
+ PortBindings: {},
110
+ Mounts: [{
111
+ Source: workspace.path.toString(),
112
+ Target: `/workspaces/${workspace.path.name}`,
113
+ Type: 'bind'
114
+ }],
115
+ },
116
+ };
117
+
118
+ for (const containerCreateContrib of this.containerCreationContributions.getContributions()) {
119
+ await containerCreateContrib.handleContainerCreation?.(containerCreateOptions, devcontainerConfig, docker, outputProvider);
120
+ }
121
+
122
+ // TODO add more config
123
+ const container = await docker.createContainer(containerCreateOptions);
124
+ await container.start();
125
+
126
+ for (const containerCreateContrib of this.containerCreationContributions.getContributions()) {
127
+ await containerCreateContrib.handlePostCreate?.(devcontainerConfig, container, docker, outputProvider);
128
+ }
129
+
130
+ return container;
131
+ }
132
+ }