@theia/dev-container 1.49.0 → 1.50.0
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/lib/dev-container-server/dev-container-server.js.map +1 -1
- package/lib/electron-browser/container-connection-contribution.js +15 -15
- package/lib/electron-browser/container-connection-contribution.js.map +1 -1
- package/lib/electron-browser/container-info-contribution.d.ts +11 -0
- package/lib/electron-browser/container-info-contribution.d.ts.map +1 -0
- package/lib/electron-browser/container-info-contribution.js +50 -0
- package/lib/electron-browser/container-info-contribution.js.map +1 -0
- package/lib/electron-browser/container-output-provider.js +4 -4
- package/lib/electron-browser/container-output-provider.js.map +1 -1
- package/lib/electron-browser/dev-container-frontend-module.d.ts.map +1 -1
- package/lib/electron-browser/dev-container-frontend-module.js +4 -0
- package/lib/electron-browser/dev-container-frontend-module.js.map +1 -1
- package/lib/electron-common/remote-container-connection-provider.d.ts +2 -0
- package/lib/electron-common/remote-container-connection-provider.d.ts.map +1 -1
- package/lib/electron-common/remote-container-connection-provider.js.map +1 -1
- package/lib/electron-node/dev-container-backend-module.d.ts.map +1 -1
- package/lib/electron-node/dev-container-backend-module.js +10 -0
- package/lib/electron-node/dev-container-backend-module.js.map +1 -1
- package/lib/electron-node/dev-container-file-service.js +4 -4
- package/lib/electron-node/dev-container-file-service.js.map +1 -1
- package/lib/electron-node/devcontainer-contributions/cli-enhancing-creation-contributions.d.ts +17 -0
- package/lib/electron-node/devcontainer-contributions/cli-enhancing-creation-contributions.d.ts.map +1 -0
- package/lib/electron-node/devcontainer-contributions/cli-enhancing-creation-contributions.js +69 -0
- package/lib/electron-node/devcontainer-contributions/cli-enhancing-creation-contributions.js.map +1 -0
- package/lib/electron-node/devcontainer-contributions/main-container-creation-contributions.d.ts +10 -1
- package/lib/electron-node/devcontainer-contributions/main-container-creation-contributions.d.ts.map +1 -1
- package/lib/electron-node/devcontainer-contributions/main-container-creation-contributions.js +99 -46
- package/lib/electron-node/devcontainer-contributions/main-container-creation-contributions.js.map +1 -1
- package/lib/electron-node/devcontainer-contributions/profile-file-modification-contribution.d.ts +11 -0
- package/lib/electron-node/devcontainer-contributions/profile-file-modification-contribution.d.ts.map +1 -0
- package/lib/electron-node/devcontainer-contributions/profile-file-modification-contribution.js +37 -0
- package/lib/electron-node/devcontainer-contributions/profile-file-modification-contribution.js.map +1 -0
- package/lib/electron-node/devcontainer-file.d.ts +29 -2
- package/lib/electron-node/devcontainer-file.d.ts.map +1 -1
- package/lib/electron-node/docker-container-service.d.ts +12 -6
- package/lib/electron-node/docker-container-service.d.ts.map +1 -1
- package/lib/electron-node/docker-container-service.js +20 -29
- package/lib/electron-node/docker-container-service.js.map +1 -1
- package/lib/electron-node/remote-container-connection-provider.d.ts +7 -3
- package/lib/electron-node/remote-container-connection-provider.d.ts.map +1 -1
- package/lib/electron-node/remote-container-connection-provider.js +37 -21
- package/lib/electron-node/remote-container-connection-provider.js.map +1 -1
- package/package.json +7 -7
- package/src/electron-browser/container-info-contribution.ts +46 -0
- package/src/electron-browser/dev-container-frontend-module.ts +5 -0
- package/src/electron-common/remote-container-connection-provider.ts +2 -0
- package/src/electron-node/dev-container-backend-module.ts +11 -0
- package/src/electron-node/devcontainer-contributions/cli-enhancing-creation-contributions.ts +68 -0
- package/src/electron-node/devcontainer-contributions/main-container-creation-contributions.ts +82 -31
- package/src/electron-node/devcontainer-contributions/profile-file-modification-contribution.ts +35 -0
- package/src/electron-node/devcontainer-file.ts +32 -1
- package/src/electron-node/docker-container-service.ts +31 -23
- package/src/electron-node/remote-container-connection-provider.ts +26 -9
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { ContributionProvider, URI } from '@theia/core';
|
|
17
|
+
import { ContributionProvider, MaybePromise, URI } from '@theia/core';
|
|
18
18
|
import { inject, injectable, named } from '@theia/core/shared/inversify';
|
|
19
19
|
import { WorkspaceServer } from '@theia/workspace/lib/common';
|
|
20
20
|
import * as fs from '@theia/core/shared/fs-extra';
|
|
@@ -23,14 +23,29 @@ import { LastContainerInfo } from '../electron-common/remote-container-connectio
|
|
|
23
23
|
import { DevContainerConfiguration } from './devcontainer-file';
|
|
24
24
|
import { DevContainerFileService } from './dev-container-file-service';
|
|
25
25
|
import { ContainerOutputProvider } from '../electron-common/container-output-provider';
|
|
26
|
+
import { RemoteDockerContainerConnection } from './remote-container-connection-provider';
|
|
26
27
|
|
|
27
28
|
export const ContainerCreationContribution = Symbol('ContainerCreationContributions');
|
|
28
29
|
|
|
29
30
|
export interface ContainerCreationContribution {
|
|
30
|
-
handleContainerCreation(createOptions: Docker.ContainerCreateOptions,
|
|
31
|
+
handleContainerCreation?(createOptions: Docker.ContainerCreateOptions,
|
|
31
32
|
containerConfig: DevContainerConfiguration,
|
|
32
33
|
api: Docker,
|
|
33
|
-
outputProvider?: ContainerOutputProvider):
|
|
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>;
|
|
34
49
|
}
|
|
35
50
|
|
|
36
51
|
@injectable()
|
|
@@ -70,6 +85,15 @@ export class DockerContainerService {
|
|
|
70
85
|
return container;
|
|
71
86
|
}
|
|
72
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
|
+
|
|
73
97
|
protected async buildContainer(docker: Docker, devcontainerFile: string, workspace: URI, outputProvider?: ContainerOutputProvider): Promise<Docker.Container> {
|
|
74
98
|
const devcontainerConfig = await this.devContainerFileService.getConfiguration(devcontainerFile);
|
|
75
99
|
|
|
@@ -92,33 +116,17 @@ export class DockerContainerService {
|
|
|
92
116
|
};
|
|
93
117
|
|
|
94
118
|
for (const containerCreateContrib of this.containerCreationContributions.getContributions()) {
|
|
95
|
-
await containerCreateContrib.handleContainerCreation(containerCreateOptions, devcontainerConfig, docker, outputProvider);
|
|
119
|
+
await containerCreateContrib.handleContainerCreation?.(containerCreateOptions, devcontainerConfig, docker, outputProvider);
|
|
96
120
|
}
|
|
97
121
|
|
|
98
122
|
// TODO add more config
|
|
99
123
|
const container = await docker.createContainer(containerCreateOptions);
|
|
100
124
|
await container.start();
|
|
101
125
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
protected getPortBindings(forwardPorts: (string | number)[]): { exposedPorts: {}, portBindings: {} } {
|
|
106
|
-
const res: { exposedPorts: { [key: string]: {} }, portBindings: { [key: string]: {} } } = { exposedPorts: {}, portBindings: {} };
|
|
107
|
-
for (const port of forwardPorts) {
|
|
108
|
-
let portKey: string;
|
|
109
|
-
let hostPort: string;
|
|
110
|
-
if (typeof port === 'string') {
|
|
111
|
-
const parts = port.split(':');
|
|
112
|
-
portKey = isNaN(+parts[0]) ? parts[0] : `${parts[0]}/tcp`;
|
|
113
|
-
hostPort = parts[1] ?? parts[0];
|
|
114
|
-
} else {
|
|
115
|
-
portKey = `${port}/tcp`;
|
|
116
|
-
hostPort = port.toString();
|
|
117
|
-
}
|
|
118
|
-
res.exposedPorts[portKey] = {};
|
|
119
|
-
res.portBindings[portKey] = [{ HostPort: hostPort }];
|
|
126
|
+
for (const containerCreateContrib of this.containerCreationContributions.getContributions()) {
|
|
127
|
+
await containerCreateContrib.handlePostCreate?.(devcontainerConfig, container, docker, outputProvider);
|
|
120
128
|
}
|
|
121
129
|
|
|
122
|
-
return
|
|
130
|
+
return container;
|
|
123
131
|
}
|
|
124
132
|
}
|
|
@@ -56,6 +56,9 @@ export class DevContainerConnectionProvider implements RemoteContainerConnection
|
|
|
56
56
|
@inject(DevContainerFileService)
|
|
57
57
|
protected readonly devContainerFileService: DevContainerFileService;
|
|
58
58
|
|
|
59
|
+
@inject(RemoteConnectionService)
|
|
60
|
+
protected readonly remoteService: RemoteConnectionService;
|
|
61
|
+
|
|
59
62
|
protected outputProvider: ContainerOutputProvider | undefined;
|
|
60
63
|
|
|
61
64
|
setClient(client: ContainerOutputProvider): void {
|
|
@@ -77,12 +80,13 @@ export class DevContainerConnectionProvider implements RemoteContainerConnection
|
|
|
77
80
|
});
|
|
78
81
|
try {
|
|
79
82
|
const container = await this.containerService.getOrCreateContainer(dockerConnection, options.devcontainerFile, options.lastContainerInfo, this.outputProvider);
|
|
83
|
+
const devContainerConfig = await this.devContainerFileService.getConfiguration(options.devcontainerFile);
|
|
80
84
|
|
|
81
85
|
// create actual connection
|
|
82
86
|
const report: RemoteStatusReport = message => progress.report({ message });
|
|
83
87
|
report('Connecting to remote system...');
|
|
84
88
|
|
|
85
|
-
const remote = await this.createContainerConnection(container, dockerConnection);
|
|
89
|
+
const remote = await this.createContainerConnection(container, dockerConnection, devContainerConfig.name);
|
|
86
90
|
const result = await this.remoteSetup.setup({
|
|
87
91
|
connection: remote,
|
|
88
92
|
report,
|
|
@@ -100,6 +104,9 @@ export class DevContainerConnectionProvider implements RemoteContainerConnection
|
|
|
100
104
|
});
|
|
101
105
|
const localPort = (server.address() as net.AddressInfo).port;
|
|
102
106
|
remote.localPort = localPort;
|
|
107
|
+
|
|
108
|
+
await this.containerService.postConnect(options.devcontainerFile, remote, this.outputProvider);
|
|
109
|
+
|
|
103
110
|
return {
|
|
104
111
|
containerId: container.id,
|
|
105
112
|
workspacePath: (await container.inspect()).Mounts[0].Destination,
|
|
@@ -118,16 +125,24 @@ export class DevContainerConnectionProvider implements RemoteContainerConnection
|
|
|
118
125
|
return this.devContainerFileService.getAvailableFiles();
|
|
119
126
|
}
|
|
120
127
|
|
|
121
|
-
async createContainerConnection(container: Docker.Container, docker: Docker): Promise<RemoteDockerContainerConnection> {
|
|
128
|
+
async createContainerConnection(container: Docker.Container, docker: Docker, name?: string): Promise<RemoteDockerContainerConnection> {
|
|
122
129
|
return Promise.resolve(new RemoteDockerContainerConnection({
|
|
123
130
|
id: generateUuid(),
|
|
124
|
-
name: 'dev-container',
|
|
125
|
-
type: '
|
|
131
|
+
name: name ?? 'dev-container',
|
|
132
|
+
type: 'Dev Container',
|
|
126
133
|
docker,
|
|
127
134
|
container,
|
|
128
135
|
}));
|
|
129
136
|
}
|
|
130
137
|
|
|
138
|
+
async getCurrentContainerInfo(port: number): Promise<Docker.ContainerInspectInfo | undefined> {
|
|
139
|
+
const connection = this.remoteConnectionService.getConnectionFromPort(port);
|
|
140
|
+
if (!connection || !(connection instanceof RemoteDockerContainerConnection)) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
return connection.container.inspect();
|
|
144
|
+
}
|
|
145
|
+
|
|
131
146
|
dispose(): void {
|
|
132
147
|
|
|
133
148
|
}
|
|
@@ -167,8 +182,6 @@ export class RemoteDockerContainerConnection implements RemoteConnection {
|
|
|
167
182
|
docker: Docker;
|
|
168
183
|
container: Docker.Container;
|
|
169
184
|
|
|
170
|
-
containerInfo: Docker.ContainerInspectInfo | undefined;
|
|
171
|
-
|
|
172
185
|
remoteSetupResult: RemoteSetupResult;
|
|
173
186
|
|
|
174
187
|
protected activeTerminalSession: ContainerTerminalSession | undefined;
|
|
@@ -180,10 +193,13 @@ export class RemoteDockerContainerConnection implements RemoteConnection {
|
|
|
180
193
|
this.id = options.id;
|
|
181
194
|
this.type = options.type;
|
|
182
195
|
this.name = options.name;
|
|
183
|
-
this.onDidDisconnect(() => this.dispose());
|
|
184
196
|
|
|
185
197
|
this.docker = options.docker;
|
|
186
198
|
this.container = options.container;
|
|
199
|
+
|
|
200
|
+
this.docker.getEvents({ filters: { container: [this.container.id], event: ['stop'] } }).then(stream => {
|
|
201
|
+
stream.on('data', () => this.onDidDisconnectEmitter.fire());
|
|
202
|
+
});
|
|
187
203
|
}
|
|
188
204
|
|
|
189
205
|
async forwardOut(socket: Socket, port?: number): Promise<void> {
|
|
@@ -287,8 +303,9 @@ export class RemoteDockerContainerConnection implements RemoteConnection {
|
|
|
287
303
|
return deferred.promise;
|
|
288
304
|
}
|
|
289
305
|
|
|
290
|
-
dispose(): void {
|
|
291
|
-
this
|
|
306
|
+
async dispose(): Promise<void> {
|
|
307
|
+
// cant use dockerrode here since this needs to happen on one tick
|
|
308
|
+
exec(`docker stop ${this.container.id}`);
|
|
292
309
|
}
|
|
293
310
|
|
|
294
311
|
}
|