@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.
- package/README.md +43 -43
- package/package.json +7 -7
- package/src/dev-container-server/dev-container-server.ts +53 -53
- package/src/electron-browser/container-connection-contribution.ts +103 -103
- package/src/electron-browser/container-info-contribution.ts +46 -46
- package/src/electron-browser/container-output-provider.ts +36 -36
- package/src/electron-browser/dev-container-frontend-module.ts +38 -38
- package/src/electron-common/container-output-provider.ts +19 -19
- package/src/electron-common/remote-container-connection-provider.ts +51 -51
- package/src/electron-node/dev-container-backend-module.ts +58 -58
- package/src/electron-node/dev-container-file-service.ts +72 -72
- package/src/electron-node/devcontainer-contributions/cli-enhancing-creation-contributions.ts +68 -68
- package/src/electron-node/devcontainer-contributions/main-container-creation-contributions.ts +191 -191
- package/src/electron-node/devcontainer-contributions/profile-file-modification-contribution.ts +35 -35
- package/src/electron-node/devcontainer-file.ts +411 -411
- package/src/electron-node/docker-container-service.ts +132 -132
- package/src/electron-node/remote-container-connection-provider.ts +311 -311
- package/src/package.spec.ts +28 -28
|
@@ -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
|
+
}
|