@knpkv/codecommit-core 0.11.0 → 0.14.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/README.md +44 -3
- package/dist/AwsClient/AwsClientGated.d.ts.map +1 -1
- package/dist/AwsClient/AwsClientGated.js +3 -3
- package/dist/AwsClient/AwsClientGated.js.map +1 -1
- package/dist/AwsClient/approvalRuleContent.js.map +1 -1
- package/dist/AwsClient/getCommentsForPullRequest.d.ts +1 -1
- package/dist/AwsClient/getCommentsForPullRequest.d.ts.map +1 -1
- package/dist/AwsClient/getCommentsForPullRequest.js +4 -4
- package/dist/AwsClient/getCommentsForPullRequest.js.map +1 -1
- package/dist/AwsClient/getDifferences.js +1 -1
- package/dist/AwsClient/getDifferences.js.map +1 -1
- package/dist/AwsClient/getPullRequest.d.ts.map +1 -1
- package/dist/AwsClient/getPullRequest.js +7 -1
- package/dist/AwsClient/getPullRequest.js.map +1 -1
- package/dist/AwsClient/getPullRequests.d.ts +2 -1
- package/dist/AwsClient/getPullRequests.d.ts.map +1 -1
- package/dist/AwsClient/getPullRequests.js +14 -12
- package/dist/AwsClient/getPullRequests.js.map +1 -1
- package/dist/AwsClient/index.d.ts +1 -0
- package/dist/AwsClient/index.d.ts.map +1 -1
- package/dist/AwsClient/internal.d.ts +36 -11
- package/dist/AwsClient/internal.d.ts.map +1 -1
- package/dist/AwsClient/internal.js +17 -14
- package/dist/AwsClient/internal.js.map +1 -1
- package/dist/AwsClientConfig/internal/ProfileCredentialProvider.d.ts +18 -0
- package/dist/AwsClientConfig/internal/ProfileCredentialProvider.d.ts.map +1 -0
- package/dist/AwsClientConfig/internal/ProfileCredentialProvider.js +7 -0
- package/dist/AwsClientConfig/internal/ProfileCredentialProvider.js.map +1 -0
- package/dist/AwsClientConfig.d.ts +16 -25
- package/dist/AwsClientConfig.d.ts.map +1 -1
- package/dist/AwsClientConfig.js +37 -0
- package/dist/AwsClientConfig.js.map +1 -1
- package/dist/CacheService/CacheError.js +1 -1
- package/dist/CacheService/CacheError.js.map +1 -1
- package/dist/CacheService/Database.d.ts +5 -4
- package/dist/CacheService/Database.d.ts.map +1 -1
- package/dist/CacheService/Database.js +8 -5
- package/dist/CacheService/Database.js.map +1 -1
- package/dist/CacheService/EventsHub.d.ts +2 -2
- package/dist/CacheService/EventsHub.d.ts.map +1 -1
- package/dist/CacheService/diff.js +2 -2
- package/dist/CacheService/diff.js.map +1 -1
- package/dist/CacheService/internal/PrivateDatabasePathNode.d.ts +34 -0
- package/dist/CacheService/internal/PrivateDatabasePathNode.d.ts.map +1 -0
- package/dist/CacheService/internal/PrivateDatabasePathNode.js +63 -0
- package/dist/CacheService/internal/PrivateDatabasePathNode.js.map +1 -0
- package/dist/CacheService/migrations/0016_sandbox_access_password.d.ts +5 -0
- package/dist/CacheService/migrations/0016_sandbox_access_password.d.ts.map +1 -0
- package/dist/CacheService/migrations/0016_sandbox_access_password.js +4 -0
- package/dist/CacheService/migrations/0016_sandbox_access_password.js.map +1 -0
- package/dist/CacheService/repos/CommentRepo.d.ts +3 -3
- package/dist/CacheService/repos/CommentRepo.d.ts.map +1 -1
- package/dist/CacheService/repos/NotificationRepo.d.ts +3 -3
- package/dist/CacheService/repos/NotificationRepo.d.ts.map +1 -1
- package/dist/CacheService/repos/PullRequestRepo/index.d.ts +108 -108
- package/dist/CacheService/repos/PullRequestRepo/index.d.ts.map +1 -1
- package/dist/CacheService/repos/PullRequestRepo/queries.d.ts +106 -106
- package/dist/CacheService/repos/PullRequestRepo/queries.d.ts.map +1 -1
- package/dist/CacheService/repos/SandboxRepo.d.ts +73 -67
- package/dist/CacheService/repos/SandboxRepo.d.ts.map +1 -1
- package/dist/CacheService/repos/SandboxRepo.js +3 -2
- package/dist/CacheService/repos/SandboxRepo.js.map +1 -1
- package/dist/CacheService/repos/StatsRepo/index.d.ts +3 -3
- package/dist/CacheService/repos/StatsRepo/index.d.ts.map +1 -1
- package/dist/CacheService/repos/SubscriptionRepo.d.ts +8 -8
- package/dist/CacheService/repos/SubscriptionRepo.d.ts.map +1 -1
- package/dist/CacheService/repos/SyncMetadataRepo.d.ts +3 -3
- package/dist/CacheService/repos/SyncMetadataRepo.d.ts.map +1 -1
- package/dist/CacheService/repos/commentLocations.d.ts.map +1 -1
- package/dist/CacheService/repos/commentLocations.js +9 -8
- package/dist/CacheService/repos/commentLocations.js.map +1 -1
- package/dist/ChildEnv.d.ts +80 -2
- package/dist/ChildEnv.d.ts.map +1 -1
- package/dist/ChildEnv.js +96 -14
- package/dist/ChildEnv.js.map +1 -1
- package/dist/ConfigService/SandboxPolicy.d.ts +37 -0
- package/dist/ConfigService/SandboxPolicy.d.ts.map +1 -0
- package/dist/ConfigService/SandboxPolicy.js +72 -0
- package/dist/ConfigService/SandboxPolicy.js.map +1 -0
- package/dist/ConfigService/index.d.ts +3 -1
- package/dist/ConfigService/index.d.ts.map +1 -1
- package/dist/ConfigService/index.js +10 -2
- package/dist/ConfigService/index.js.map +1 -1
- package/dist/ConfigService/internal.d.ts +15 -0
- package/dist/ConfigService/internal.d.ts.map +1 -1
- package/dist/ConfigService/internal.js +22 -9
- package/dist/ConfigService/internal.js.map +1 -1
- package/dist/ConfigService/load.d.ts +37 -23
- package/dist/ConfigService/load.d.ts.map +1 -1
- package/dist/ConfigService/load.js +2 -2
- package/dist/ConfigService/load.js.map +1 -1
- package/dist/ConfigService/reset.d.ts +36 -22
- package/dist/ConfigService/reset.d.ts.map +1 -1
- package/dist/ConfigService/save.d.ts +36 -22
- package/dist/ConfigService/save.d.ts.map +1 -1
- package/dist/Domain.d.ts +29 -0
- package/dist/Domain.d.ts.map +1 -1
- package/dist/Domain.js +77 -10
- package/dist/Domain.js.map +1 -1
- package/dist/Errors.d.ts +11 -1
- package/dist/Errors.d.ts.map +1 -1
- package/dist/Errors.js +19 -10
- package/dist/Errors.js.map +1 -1
- package/dist/ManagedReviewProtocol.d.ts +5 -0
- package/dist/ManagedReviewProtocol.d.ts.map +1 -0
- package/dist/ManagedReviewProtocol.js +5 -0
- package/dist/ManagedReviewProtocol.js.map +1 -0
- package/dist/MockTransport.d.ts +24 -0
- package/dist/MockTransport.d.ts.map +1 -0
- package/dist/MockTransport.js +58 -0
- package/dist/MockTransport.js.map +1 -0
- package/dist/PRService/index.d.ts +8 -7
- package/dist/PRService/index.d.ts.map +1 -1
- package/dist/PRService/index.js.map +1 -1
- package/dist/PRService/internal.d.ts +31 -31
- package/dist/PRService/internal.d.ts.map +1 -1
- package/dist/PRService/internal.js +5 -5
- package/dist/PRService/internal.js.map +1 -1
- package/dist/PRService/refresh.d.ts.map +1 -1
- package/dist/PRService/refresh.js +12 -3
- package/dist/PRService/refresh.js.map +1 -1
- package/dist/PRService/refreshFetch.d.ts +2 -1
- package/dist/PRService/refreshFetch.d.ts.map +1 -1
- package/dist/PRService/refreshFetch.js +24 -6
- package/dist/PRService/refreshFetch.js.map +1 -1
- package/dist/PRService/refreshResolve.d.ts +6 -6
- package/dist/PRService/refreshResolve.d.ts.map +1 -1
- package/dist/PRService/refreshResolve.js +3 -1
- package/dist/PRService/refreshResolve.js.map +1 -1
- package/dist/PRService/refreshSinglePR.d.ts +7 -1
- package/dist/PRService/refreshSinglePR.d.ts.map +1 -1
- package/dist/PRService/refreshSinglePR.js +8 -5
- package/dist/PRService/refreshSinglePR.js.map +1 -1
- package/dist/PermissionService/AuditLog.d.ts +3 -3
- package/dist/PermissionService/AuditLog.d.ts.map +1 -1
- package/dist/PermissionService/AuditLog.js +2 -2
- package/dist/PermissionService/AuditLog.js.map +1 -1
- package/dist/PermissionService/PermissionGateLive.d.ts +3 -0
- package/dist/PermissionService/PermissionGateLive.d.ts.map +1 -1
- package/dist/PermissionService/PermissionGateLive.js +9 -20
- package/dist/PermissionService/PermissionGateLive.js.map +1 -1
- package/dist/PermissionService/index.d.ts +2 -2
- package/dist/PermissionService/index.d.ts.map +1 -1
- package/dist/PermissionService/index.js +9 -1
- package/dist/PermissionService/index.js.map +1 -1
- package/dist/PermissionService/operations.d.ts +24 -2
- package/dist/PermissionService/operations.d.ts.map +1 -1
- package/dist/PermissionService/operations.js +18 -0
- package/dist/PermissionService/operations.js.map +1 -1
- package/dist/ReadClient/ReadClient.d.ts +18 -3
- package/dist/ReadClient/ReadClient.d.ts.map +1 -1
- package/dist/ReadClient/ReadClient.js +35 -7
- package/dist/ReadClient/ReadClient.js.map +1 -1
- package/dist/ReadClient/ReadProvider.d.ts +6 -0
- package/dist/ReadClient/ReadProvider.d.ts.map +1 -1
- package/dist/ReadClient/ReadProvider.js +4 -3
- package/dist/ReadClient/ReadProvider.js.map +1 -1
- package/dist/ReadClient/errors.js +3 -3
- package/dist/ReadClient/errors.js.map +1 -1
- package/dist/ReadClient/models.d.ts +15 -1
- package/dist/ReadClient/models.d.ts.map +1 -1
- package/dist/ReadClient/models.js +14 -1
- package/dist/ReadClient/models.js.map +1 -1
- package/dist/ReviewClient/ReviewClient.d.ts.map +1 -1
- package/dist/ReviewClient/ReviewClient.js +57 -4
- package/dist/ReviewClient/ReviewClient.js.map +1 -1
- package/dist/ReviewClient/ReviewProvider.d.ts +30 -0
- package/dist/ReviewClient/ReviewProvider.d.ts.map +1 -1
- package/dist/ReviewClient/ReviewProvider.js +67 -5
- package/dist/ReviewClient/ReviewProvider.js.map +1 -1
- package/dist/ReviewClient/errors.d.ts +3 -1
- package/dist/ReviewClient/errors.d.ts.map +1 -1
- package/dist/ReviewClient/errors.js +73 -2
- package/dist/ReviewClient/errors.js.map +1 -1
- package/dist/ReviewClient/index.d.ts +1 -1
- package/dist/ReviewClient/index.d.ts.map +1 -1
- package/dist/ReviewClient/index.js +1 -1
- package/dist/ReviewClient/index.js.map +1 -1
- package/dist/ReviewClient/models.d.ts +38 -1
- package/dist/ReviewClient/models.d.ts.map +1 -1
- package/dist/ReviewClient/models.js +15 -3
- package/dist/ReviewClient/models.js.map +1 -1
- package/dist/ReviewProfile.d.ts +42 -0
- package/dist/ReviewProfile.d.ts.map +1 -0
- package/dist/ReviewProfile.js +75 -0
- package/dist/ReviewProfile.js.map +1 -0
- package/dist/SandboxService/DockerService.d.ts +24 -15
- package/dist/SandboxService/DockerService.d.ts.map +1 -1
- package/dist/SandboxService/DockerService.js +22 -6
- package/dist/SandboxService/DockerService.js.map +1 -1
- package/dist/SandboxService/PluginService.d.ts +2 -2
- package/dist/SandboxService/PluginService.d.ts.map +1 -1
- package/dist/SandboxService/SandboxService.d.ts +88 -73
- package/dist/SandboxService/SandboxService.d.ts.map +1 -1
- package/dist/SandboxService/SandboxService.js +69 -21
- package/dist/SandboxService/SandboxService.js.map +1 -1
- package/dist/SandboxService/SandboxWorkerScope.d.ts +2 -2
- package/dist/SandboxService/SandboxWorkerScope.d.ts.map +1 -1
- package/dist/SandboxService/SandboxWorkerScope.js.map +1 -1
- package/package.json +8 -6
|
@@ -5,20 +5,23 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
|
-
import { Context, Effect, Layer
|
|
8
|
+
import { Context, Effect, Layer } from "effect";
|
|
9
9
|
import type { Success } from "effect/Effect";
|
|
10
10
|
import { ChildProcessSpawner } from "effect/unstable/process";
|
|
11
11
|
import { DockerError } from "../Errors.js";
|
|
12
12
|
export interface ContainerConfig {
|
|
13
13
|
readonly Image: string;
|
|
14
14
|
readonly Cmd: ReadonlyArray<string>;
|
|
15
|
+
readonly User?: string;
|
|
15
16
|
readonly ExposedPorts: Record<string, Record<string, never>>;
|
|
16
17
|
readonly HostConfig: {
|
|
17
18
|
readonly Binds: ReadonlyArray<string>;
|
|
18
19
|
readonly PortBindings: Record<string, ReadonlyArray<{
|
|
20
|
+
HostIp: string;
|
|
19
21
|
HostPort: string;
|
|
20
22
|
}>>;
|
|
21
23
|
readonly NetworkMode?: string;
|
|
24
|
+
readonly CapDrop?: ReadonlyArray<string>;
|
|
22
25
|
};
|
|
23
26
|
readonly Env?: ReadonlyArray<string>;
|
|
24
27
|
readonly Labels?: Record<string, string>;
|
|
@@ -40,6 +43,10 @@ interface DockerPsContainer {
|
|
|
40
43
|
readonly State: string;
|
|
41
44
|
readonly Labels: Record<string, string>;
|
|
42
45
|
}
|
|
46
|
+
export declare const renderDockerPortBinding: (containerPort: string, binding: {
|
|
47
|
+
readonly HostIp: string;
|
|
48
|
+
readonly HostPort: string;
|
|
49
|
+
}) => string;
|
|
43
50
|
declare const makeDockerService: Effect.Effect<{
|
|
44
51
|
isAvailable: () => Effect.Effect<boolean, import("effect/PlatformError").PlatformError, never>;
|
|
45
52
|
pullImage: (image: string) => Effect.Effect<void, DockerError, never>;
|
|
@@ -47,18 +54,20 @@ declare const makeDockerService: Effect.Effect<{
|
|
|
47
54
|
startContainer: (containerId: string) => Effect.Effect<void, DockerError, never>;
|
|
48
55
|
stopContainer: (containerId: string, timeout?: number) => Effect.Effect<void, DockerError, never>;
|
|
49
56
|
removeContainer: (containerId: string) => Effect.Effect<void, DockerError, never>;
|
|
50
|
-
inspectContainer: (containerId: string) => Effect.Effect<
|
|
51
|
-
readonly Id:
|
|
52
|
-
readonly State:
|
|
53
|
-
readonly Status:
|
|
54
|
-
readonly Running:
|
|
55
|
-
}
|
|
56
|
-
readonly NetworkSettings:
|
|
57
|
-
readonly Ports:
|
|
58
|
-
readonly
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
inspectContainer: (containerId: string) => Effect.Effect<{
|
|
58
|
+
readonly Id: string;
|
|
59
|
+
readonly State: {
|
|
60
|
+
readonly Status: string;
|
|
61
|
+
readonly Running: boolean;
|
|
62
|
+
};
|
|
63
|
+
readonly NetworkSettings: {
|
|
64
|
+
readonly Ports: {
|
|
65
|
+
readonly [x: string]: readonly {
|
|
66
|
+
readonly HostPort: string;
|
|
67
|
+
}[] | null;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
}, DockerError, never>;
|
|
62
71
|
exec: (containerId: string, cmd: ReadonlyArray<string>) => Effect.Effect<string, DockerError, never>;
|
|
63
72
|
listContainersByLabel: (label: string, value: string) => Effect.Effect<DockerPsContainer[] | {
|
|
64
73
|
Id: string;
|
|
@@ -66,9 +75,9 @@ declare const makeDockerService: Effect.Effect<{
|
|
|
66
75
|
Labels: any;
|
|
67
76
|
}[], DockerError, never>;
|
|
68
77
|
}, never, ChildProcessSpawner.ChildProcessSpawner>;
|
|
69
|
-
export interface
|
|
78
|
+
export interface DockerServiceContract extends Success<typeof makeDockerService> {
|
|
70
79
|
}
|
|
71
|
-
declare const DockerService_base: Context.ServiceClass<DockerService, "DockerService",
|
|
80
|
+
declare const DockerService_base: Context.ServiceClass<DockerService, "DockerService", DockerServiceContract>;
|
|
72
81
|
export declare class DockerService extends DockerService_base {
|
|
73
82
|
static readonly Default: Layer.Layer<DockerService, never, ChildProcessSpawner.ChildProcessSpawner>;
|
|
74
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DockerService.d.ts","sourceRoot":"","sources":["../../src/SandboxService/DockerService.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"DockerService.d.ts","sourceRoot":"","sources":["../../src/SandboxService/DockerService.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAA;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAgB,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IAC5D,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;QACrC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC,CAAA;QAC1F,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;QAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;KACzC,CAAA;IACD,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAC1B,CAAA;IACD,QAAQ,CAAC,eAAe,EAAE;QACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC,GAAG,IAAI,CAAC,CAAA;KAC3E,CAAA;CACF;AAsBD,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACxC;AAcD,eAAO,MAAM,uBAAuB,kBACnB,MAAM,WACZ;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,KAC9D,MAAsF,CAAA;AAEzF,QAAA,MAAM,iBAAiB;;uBAqBA,MAAM;8BAEC,eAAe;kCA+CX,MAAM;iCAGP,MAAM;mCAGJ,MAAM;oCAGL,MAAM;;;;;;;;;;;;;;wBAoBlB,MAAM,OAAO,aAAa,CAAC,MAAM,CAAC;mCAGvB,MAAM,SAAS,MAAM;;;;;kDAsBtD,CAAA;AAEF,MAAM,WAAW,qBAAsB,SAAQ,OAAO,CAAC,OAAO,iBAAiB,CAAC;CAAG;;AAEnF,qBAAa,aAAc,SAAQ,kBAGf;IAClB,MAAM,CAAC,QAAQ,CAAC,OAAO,6EAAiD;CACzE"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
|
-
import { Context, Effect, Layer, Schema } from "effect";
|
|
8
|
+
import { Context, Effect, Layer, Schema, Stream } from "effect";
|
|
9
9
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
10
10
|
import { DockerError } from "../Errors.js";
|
|
11
11
|
const ContainerInfoSchema = Schema.Struct({
|
|
@@ -28,9 +28,16 @@ const decodeDockerPsRow = Schema.decodeUnknownSync(DockerPsRow);
|
|
|
28
28
|
const emptyDockerPsContainers = () => [];
|
|
29
29
|
const dockerError = (operation) => (effect) => effect.pipe(Effect.mapError((cause) => new DockerError({ operation, cause })), Effect.withSpan(`DockerService.${operation}`));
|
|
30
30
|
const shellEscape = (s) => `'${s.replace(/'/g, "'\\''")}'`;
|
|
31
|
+
export const renderDockerPortBinding = (containerPort, binding) => `${binding.HostIp}:${binding.HostPort}:${containerPort.replace("/tcp", "")}`;
|
|
31
32
|
const makeDockerService = Effect.gen(function* () {
|
|
32
33
|
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
33
34
|
const docker = (...args) => spawner.string(ChildProcess.make("sh", ["-c", `docker ${args.map(shellEscape).join(" ")} 2>&1`]));
|
|
35
|
+
const dockerWithInput = (input, ...args) => spawner.string(ChildProcess.make("sh", ["-c", `docker ${args.map(shellEscape).join(" ")} 2>&1`], {
|
|
36
|
+
stdin: {
|
|
37
|
+
stream: Stream.make(input).pipe(Stream.encodeText),
|
|
38
|
+
endOnDone: true
|
|
39
|
+
}
|
|
40
|
+
}));
|
|
34
41
|
const service = {
|
|
35
42
|
isAvailable: () => docker("info").pipe(Effect.map(() => true), Effect.catchIf(() => true, () => Effect.succeed(false))),
|
|
36
43
|
pullImage: (image) => docker("pull", image).pipe(Effect.asVoid, dockerError("pullImage")),
|
|
@@ -39,7 +46,7 @@ const makeDockerService = Effect.gen(function* () {
|
|
|
39
46
|
// Port bindings
|
|
40
47
|
for (const [containerPort, bindings] of Object.entries(config.HostConfig.PortBindings)) {
|
|
41
48
|
for (const b of bindings) {
|
|
42
|
-
args.push("-p",
|
|
49
|
+
args.push("-p", renderDockerPortBinding(containerPort, b));
|
|
43
50
|
}
|
|
44
51
|
}
|
|
45
52
|
// Volume binds
|
|
@@ -50,10 +57,17 @@ const makeDockerService = Effect.gen(function* () {
|
|
|
50
57
|
if (config.HostConfig.NetworkMode) {
|
|
51
58
|
args.push("--network", config.HostConfig.NetworkMode);
|
|
52
59
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
args.push("-e", env);
|
|
60
|
+
for (const capability of config.HostConfig.CapDrop ?? []) {
|
|
61
|
+
args.push("--cap-drop", capability);
|
|
56
62
|
}
|
|
63
|
+
if (config.User) {
|
|
64
|
+
args.push("--user", config.User);
|
|
65
|
+
}
|
|
66
|
+
// Keep environment values, including the generated access password, out
|
|
67
|
+
// of process arguments. Docker reads the protected parent-child pipe.
|
|
68
|
+
const environment = config.Env ?? [];
|
|
69
|
+
if (environment.length > 0)
|
|
70
|
+
args.push("--env-file", "/dev/stdin");
|
|
57
71
|
// Labels
|
|
58
72
|
for (const [k, v] of Object.entries(config.Labels ?? {})) {
|
|
59
73
|
args.push("-l", `${k}=${v}`);
|
|
@@ -62,7 +76,9 @@ const makeDockerService = Effect.gen(function* () {
|
|
|
62
76
|
args.push(config.Image);
|
|
63
77
|
for (const c of config.Cmd)
|
|
64
78
|
args.push(c);
|
|
65
|
-
return
|
|
79
|
+
return (environment.length > 0
|
|
80
|
+
? dockerWithInput(`${environment.join("\n")}\n`, ...args)
|
|
81
|
+
: docker(...args)).pipe(dockerError("createContainer"));
|
|
66
82
|
},
|
|
67
83
|
startContainer: (containerId) => docker("start", containerId).pipe(Effect.asVoid, dockerError("startContainer")),
|
|
68
84
|
stopContainer: (containerId, timeout = 10) => docker("stop", "-t", String(timeout), containerId).pipe(Effect.asVoid, dockerError("stopContainer")),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DockerService.js","sourceRoot":"","sources":["../../src/SandboxService/DockerService.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"DockerService.js","sourceRoot":"","sources":["../../src/SandboxService/DockerService.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,9 +31,9 @@ declare const makePluginService: Effect.Effect<{
|
|
|
31
31
|
executeHook: (hook: "onSandboxCreate" | "onSandboxReady" | "onSandboxDestroy", ctx: SandboxContext) => Effect.Effect<void, never, never>;
|
|
32
32
|
listPlugins: () => Effect.Effect<string[], never, never>;
|
|
33
33
|
}, never, never>;
|
|
34
|
-
export interface
|
|
34
|
+
export interface PluginServiceContract extends Success<typeof makePluginService> {
|
|
35
35
|
}
|
|
36
|
-
declare const PluginService_base: Context.ServiceClass<PluginService, "PluginService",
|
|
36
|
+
declare const PluginService_base: Context.ServiceClass<PluginService, "PluginService", PluginServiceContract>;
|
|
37
37
|
export declare class PluginService extends PluginService_base {
|
|
38
38
|
static readonly Default: Layer.Layer<PluginService, never, never>;
|
|
39
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginService.d.ts","sourceRoot":"","sources":["../../src/SandboxService/PluginService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAS,OAAO,EAAE,MAAM,EAAE,KAAK,EAAO,MAAM,QAAQ,CAAA;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE;QACX,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAA;QAC1B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;QACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;KAC9B,CAAA;CACF;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACvE,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACtE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CACzE;AAED,QAAA,MAAM,iBAAiB;uBAIA,aAAa;wBAKZ,iBAAiB,GAAG,gBAAgB,GAAG,kBAAkB,OAAO,cAAc;;gBAoBpG,CAAA;AAEF,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"PluginService.d.ts","sourceRoot":"","sources":["../../src/SandboxService/PluginService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAS,OAAO,EAAE,MAAM,EAAE,KAAK,EAAO,MAAM,QAAQ,CAAA;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE;QACX,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAA;QAC1B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;QACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;KAC9B,CAAA;CACF;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACvE,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACtE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CACzE;AAED,QAAA,MAAM,iBAAiB;uBAIA,aAAa;wBAKZ,iBAAiB,GAAG,gBAAgB,GAAG,kBAAkB,OAAO,cAAc;;gBAoBpG,CAAA;AAEF,MAAM,WAAW,qBAAsB,SAAQ,OAAO,CAAC,OAAO,iBAAiB,CAAC;CAAG;;AAEnF,qBAAa,aAAc,SAAQ,kBAGf;IAClB,MAAM,CAAC,QAAQ,CAAC,OAAO,2CAAiD;CACzE"}
|
|
@@ -6,14 +6,15 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
-
import { Config, Context, Duration, Effect, Layer } from "effect";
|
|
9
|
+
import { Config, Context, Crypto, Duration, Effect, Layer } from "effect";
|
|
10
10
|
import type { Success } from "effect/Effect";
|
|
11
11
|
import * as FileSystem from "effect/FileSystem";
|
|
12
12
|
import { SandboxRepo } from "../CacheService/repos/SandboxRepo.js";
|
|
13
|
-
import
|
|
13
|
+
import * as ChildEnv from "../ChildEnv.js";
|
|
14
|
+
import { ConfigService, type SandboxConfig } from "../ConfigService/index.js";
|
|
14
15
|
import { SandboxId } from "../Domain.js";
|
|
15
16
|
import { SandboxError } from "../Errors.js";
|
|
16
|
-
import { DockerService } from "./DockerService.js";
|
|
17
|
+
import { type ContainerConfig, DockerService } from "./DockerService.js";
|
|
17
18
|
import { PluginService } from "./PluginService.js";
|
|
18
19
|
import { SandboxWorkerScope } from "./SandboxWorkerScope.js";
|
|
19
20
|
export interface CreateSandboxParams {
|
|
@@ -24,84 +25,98 @@ export interface CreateSandboxParams {
|
|
|
24
25
|
readonly profile: string;
|
|
25
26
|
readonly region: string;
|
|
26
27
|
}
|
|
28
|
+
export interface SandboxContainerIdentity {
|
|
29
|
+
readonly repairRootOwnedWorkspace: boolean;
|
|
30
|
+
readonly user: string;
|
|
31
|
+
}
|
|
32
|
+
/** Keep the container non-root while matching the bind-mounted workspace owner when available. */
|
|
33
|
+
export declare const sandboxContainerIdentityForWorkspaceOwner: (uid: number | undefined, gid: number | undefined) => SandboxContainerIdentity;
|
|
34
|
+
export declare const sandboxRuntimeHome = "/tmp";
|
|
35
|
+
export declare const sandboxRuntimeXdgDataHome = "/tmp/.local/share";
|
|
36
|
+
export declare const makeContainerConfig: (workspacePath: string, port: number, sandboxId: string, pullRequestId: string, sandboxConfig: SandboxConfig, homePath: string, containerUser: string, accessPassword: string) => ContainerConfig;
|
|
27
37
|
declare const makeSandboxService: Effect.Effect<{
|
|
28
|
-
create: (params: CreateSandboxParams) => Effect.Effect<
|
|
29
|
-
readonly id:
|
|
30
|
-
readonly pullRequestId:
|
|
31
|
-
readonly awsAccountId:
|
|
32
|
-
readonly repositoryName:
|
|
33
|
-
readonly sourceBranch:
|
|
34
|
-
readonly
|
|
35
|
-
readonly
|
|
36
|
-
readonly
|
|
37
|
-
readonly
|
|
38
|
-
readonly
|
|
39
|
-
readonly
|
|
40
|
-
readonly
|
|
41
|
-
readonly
|
|
42
|
-
readonly
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
readonly
|
|
47
|
-
readonly
|
|
48
|
-
readonly
|
|
49
|
-
readonly
|
|
50
|
-
readonly
|
|
51
|
-
readonly
|
|
52
|
-
readonly
|
|
53
|
-
readonly
|
|
54
|
-
readonly
|
|
55
|
-
readonly
|
|
56
|
-
readonly
|
|
57
|
-
readonly
|
|
58
|
-
readonly
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
readonly
|
|
64
|
-
readonly
|
|
65
|
-
readonly
|
|
66
|
-
readonly
|
|
67
|
-
readonly
|
|
68
|
-
readonly
|
|
69
|
-
readonly
|
|
70
|
-
readonly
|
|
71
|
-
readonly
|
|
72
|
-
readonly
|
|
73
|
-
readonly
|
|
74
|
-
readonly
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
readonly
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
readonly
|
|
81
|
-
readonly
|
|
82
|
-
readonly
|
|
83
|
-
readonly
|
|
84
|
-
readonly
|
|
85
|
-
readonly
|
|
86
|
-
readonly
|
|
87
|
-
readonly
|
|
88
|
-
readonly
|
|
89
|
-
readonly
|
|
90
|
-
readonly
|
|
91
|
-
|
|
38
|
+
create: (params: CreateSandboxParams) => Effect.Effect<{
|
|
39
|
+
readonly id: string;
|
|
40
|
+
readonly pullRequestId: string;
|
|
41
|
+
readonly awsAccountId: string;
|
|
42
|
+
readonly repositoryName: string;
|
|
43
|
+
readonly sourceBranch: string;
|
|
44
|
+
readonly accessPassword: string | null;
|
|
45
|
+
readonly containerId: string | null;
|
|
46
|
+
readonly port: number | null;
|
|
47
|
+
readonly workspacePath: string;
|
|
48
|
+
readonly status: string;
|
|
49
|
+
readonly statusDetail: string | null;
|
|
50
|
+
readonly logs: string | null;
|
|
51
|
+
readonly error: string | null;
|
|
52
|
+
readonly createdAt: string;
|
|
53
|
+
readonly lastActivityAt: string;
|
|
54
|
+
}, SandboxError, import("effect/unstable/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | ChildEnv.HostEnvironment | import("effect/Path").Path>;
|
|
55
|
+
get: (id: SandboxId) => Effect.Effect<{
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly pullRequestId: string;
|
|
58
|
+
readonly awsAccountId: string;
|
|
59
|
+
readonly repositoryName: string;
|
|
60
|
+
readonly sourceBranch: string;
|
|
61
|
+
readonly accessPassword: string | null;
|
|
62
|
+
readonly containerId: string | null;
|
|
63
|
+
readonly port: number | null;
|
|
64
|
+
readonly workspacePath: string;
|
|
65
|
+
readonly status: string;
|
|
66
|
+
readonly statusDetail: string | null;
|
|
67
|
+
readonly logs: string | null;
|
|
68
|
+
readonly error: string | null;
|
|
69
|
+
readonly createdAt: string;
|
|
70
|
+
readonly lastActivityAt: string;
|
|
71
|
+
}, SandboxError, never>;
|
|
72
|
+
list: () => Effect.Effect<{
|
|
73
|
+
readonly id: string;
|
|
74
|
+
readonly pullRequestId: string;
|
|
75
|
+
readonly awsAccountId: string;
|
|
76
|
+
readonly repositoryName: string;
|
|
77
|
+
readonly sourceBranch: string;
|
|
78
|
+
readonly accessPassword: string | null;
|
|
79
|
+
readonly containerId: string | null;
|
|
80
|
+
readonly port: number | null;
|
|
81
|
+
readonly workspacePath: string;
|
|
82
|
+
readonly status: string;
|
|
83
|
+
readonly statusDetail: string | null;
|
|
84
|
+
readonly logs: string | null;
|
|
85
|
+
readonly error: string | null;
|
|
86
|
+
readonly createdAt: string;
|
|
87
|
+
readonly lastActivityAt: string;
|
|
88
|
+
}[], import("../CacheService/CacheError.ts").CacheError, never>;
|
|
89
|
+
listAll: () => Effect.Effect<{
|
|
90
|
+
readonly id: string;
|
|
91
|
+
readonly pullRequestId: string;
|
|
92
|
+
readonly awsAccountId: string;
|
|
93
|
+
readonly repositoryName: string;
|
|
94
|
+
readonly sourceBranch: string;
|
|
95
|
+
readonly accessPassword: string | null;
|
|
96
|
+
readonly containerId: string | null;
|
|
97
|
+
readonly port: number | null;
|
|
98
|
+
readonly workspacePath: string;
|
|
99
|
+
readonly status: string;
|
|
100
|
+
readonly statusDetail: string | null;
|
|
101
|
+
readonly logs: string | null;
|
|
102
|
+
readonly error: string | null;
|
|
103
|
+
readonly createdAt: string;
|
|
104
|
+
readonly lastActivityAt: string;
|
|
105
|
+
}[], import("../CacheService/CacheError.ts").CacheError, never>;
|
|
92
106
|
stop: (id: SandboxId) => Effect.Effect<void, SandboxError, never>;
|
|
93
107
|
restart: (id: SandboxId) => Effect.Effect<undefined, SandboxError, never>;
|
|
94
108
|
cleanup: (id: SandboxId) => Effect.Effect<void, SandboxError, FileSystem.FileSystem>;
|
|
95
|
-
reconcile: () => Effect.Effect<
|
|
109
|
+
reconcile: () => Effect.Effect<boolean, never, never>;
|
|
110
|
+
hasLegacyUnauthenticated: () => Effect.Effect<boolean, import("../CacheService/CacheError.ts").CacheError, never>;
|
|
96
111
|
gcIdle: (idleTimeout?: Duration.Duration, cleanupDelay?: Duration.Duration) => Effect.Effect<void, never, FileSystem.FileSystem>;
|
|
97
|
-
}, never, ConfigService | DockerService | PluginService | SandboxRepo | SandboxWorkerScope>;
|
|
98
|
-
export interface
|
|
112
|
+
}, never, ConfigService | Crypto.Crypto | DockerService | PluginService | SandboxRepo | SandboxWorkerScope>;
|
|
113
|
+
export interface SandboxServiceContract extends Success<typeof makeSandboxService> {
|
|
99
114
|
}
|
|
100
|
-
declare const SandboxService_base: Context.ServiceClass<SandboxService, "SandboxService",
|
|
115
|
+
declare const SandboxService_base: Context.ServiceClass<SandboxService, "SandboxService", SandboxServiceContract>;
|
|
101
116
|
export declare class SandboxService extends SandboxService_base {
|
|
102
117
|
/** Dependency-requiring layer used by composition tests and custom runtimes. @internal */
|
|
103
|
-
static readonly layer: Layer.Layer<SandboxService, never, ConfigService | DockerService | PluginService | SandboxRepo | SandboxWorkerScope>;
|
|
104
|
-
static readonly Default: Layer.Layer<SandboxService, Config.ConfigError | import("@effect/sql-libsql/LibsqlMigrator").MigrationError | import("effect/
|
|
118
|
+
static readonly layer: Layer.Layer<SandboxService, never, ConfigService | Crypto.Crypto | DockerService | PluginService | SandboxRepo | SandboxWorkerScope>;
|
|
119
|
+
static readonly Default: Layer.Layer<SandboxService, import("../CacheService/CacheError.ts").CacheError | Config.ConfigError | import("@effect/sql-libsql/LibsqlMigrator").MigrationError | import("effect/unstable/sql/SqlError").SqlError, import("effect/unstable/process/ChildProcessSpawner").ChildProcessSpawner | ConfigService | Crypto.Crypto>;
|
|
105
120
|
}
|
|
106
121
|
export {};
|
|
107
122
|
//# sourceMappingURL=SandboxService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SandboxService.d.ts","sourceRoot":"","sources":["../../src/SandboxService/SandboxService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,MAAM,EACN,KAAK,EAON,MAAM,QAAQ,CAAA;AACf,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EAAE,WAAW,EAAmB,MAAM,sCAAsC,CAAA;
|
|
1
|
+
{"version":3,"file":"SandboxService.d.ts","sourceRoot":"","sources":["../../src/SandboxService/SandboxService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,MAAM,EACN,OAAO,EACP,MAAM,EACN,QAAQ,EACR,MAAM,EACN,KAAK,EAON,MAAM,QAAQ,CAAA;AACf,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EAAE,WAAW,EAAmB,MAAM,sCAAsC,CAAA;AACnF,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EACL,aAAa,EAEb,KAAK,aAAa,EAEnB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAiC,SAAS,EAAsB,MAAM,cAAc,CAAA;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,KAAK,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACxE,OAAO,EAAE,aAAa,EAAuB,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE5D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAA;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,kGAAkG;AAClG,eAAO,MAAM,yCAAyC,QAC/C,MAAM,GAAG,SAAS,OAClB,MAAM,GAAG,SAAS,KACtB,wBAKyD,CAAA;AAG5D,eAAO,MAAM,kBAAkB,SAAS,CAAA;AACxC,eAAO,MAAM,yBAAyB,sBAAuC,CAAA;AAY7E,eAAO,MAAM,mBAAmB,kBACf,MAAM,QACf,MAAM,aACD,MAAM,iBACF,MAAM,iBACN,aAAa,YAClB,MAAM,iBACD,MAAM,kBACL,MAAM,KACrB,eA2BD,CAAA;AAEF,QAAA,MAAM,kBAAkB;qBA6DH,mBAAmB;;;;;;;;;;;;;;;;;cAyM1B,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eASR,SAAS;kBAiBN,SAAS;kBAuCT,SAAS;;;;2GAiHzB,CAAA;AAEF,MAAM,WAAW,sBAAuB,SAAQ,OAAO,CAAC,OAAO,kBAAkB,CAAC;CAAG;;AAErF,qBAAa,cAAe,SAAQ,mBAGf;IACnB,0FAA0F;IAC1F,MAAM,CAAC,QAAQ,CAAC,KAAK,uIAAmD;IAExE,MAAM,CAAC,QAAQ,CAAC,OAAO,iUAItB;CACF"}
|
|
@@ -6,34 +6,49 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
-
import { Clock, Config, Context, Duration, Effect, Layer, Option, Predicate, Random, Result, Schedule, Stream } from "effect";
|
|
9
|
+
import { Clock, Config, Context, Crypto, Duration, Effect, Layer, Option, Predicate, Random, Result, Schedule, Stream } from "effect";
|
|
10
10
|
import * as FileSystem from "effect/FileSystem";
|
|
11
11
|
import { ChildProcess } from "effect/unstable/process";
|
|
12
12
|
import { SandboxRepo } from "../CacheService/repos/SandboxRepo.js";
|
|
13
13
|
import * as ChildEnv from "../ChildEnv.js";
|
|
14
|
-
import { ConfigService, defaultSandboxConfig } from "../ConfigService/index.js";
|
|
14
|
+
import { ConfigService, defaultSandboxConfig, validateSandboxConfig } from "../ConfigService/index.js";
|
|
15
15
|
import { PullRequestId, RepositoryName, SandboxId } from "../Domain.js";
|
|
16
16
|
import { SandboxError } from "../Errors.js";
|
|
17
17
|
import { DockerService } from "./DockerService.js";
|
|
18
18
|
import { PluginService } from "./PluginService.js";
|
|
19
19
|
import { SandboxWorkerScope } from "./SandboxWorkerScope.js";
|
|
20
|
+
/** Keep the container non-root while matching the bind-mounted workspace owner when available. */
|
|
21
|
+
export const sandboxContainerIdentityForWorkspaceOwner = (uid, gid) => uid === 0
|
|
22
|
+
? { user: "1000:1000", repairRootOwnedWorkspace: true }
|
|
23
|
+
: uid !== undefined
|
|
24
|
+
? { user: `${uid}:${gid ?? uid}`, repairRootOwnedWorkspace: false }
|
|
25
|
+
: { user: "1000:1000", repairRootOwnedWorkspace: false };
|
|
20
26
|
const SANDBOX_BASE_PORT = 18080;
|
|
27
|
+
export const sandboxRuntimeHome = "/tmp";
|
|
28
|
+
export const sandboxRuntimeXdgDataHome = `${sandboxRuntimeHome}/.local/share`;
|
|
21
29
|
const homeDir = Config.string("HOME").pipe(Config.orElse(() => Config.string("USERPROFILE")));
|
|
22
30
|
const sandboxesDir = homeDir.pipe(Config.map((h) => `${h}/.codecommit/sandboxes`));
|
|
23
31
|
const expandHome = (p, home) => p.startsWith("~/") ? `${home}${p.slice(1)}` : p;
|
|
24
|
-
const makeContainerConfig = (workspacePath, port, sandboxId, pullRequestId, sandboxConfig, homePath) => ({
|
|
32
|
+
export const makeContainerConfig = (workspacePath, port, sandboxId, pullRequestId, sandboxConfig, homePath, containerUser, accessPassword) => ({
|
|
25
33
|
Image: sandboxConfig.image,
|
|
26
|
-
|
|
34
|
+
User: containerUser,
|
|
35
|
+
Cmd: ["--bind-addr", "0.0.0.0:8080", "--auth", "password", "/workspace"],
|
|
27
36
|
ExposedPorts: { "8080/tcp": {} },
|
|
28
37
|
HostConfig: {
|
|
29
38
|
Binds: [
|
|
30
39
|
`${workspacePath}:/workspace`,
|
|
31
40
|
...sandboxConfig.volumeMounts.map((m) => `${expandHome(m.hostPath, homePath)}:${m.containerPath}${m.readonly ? ":ro" : ""}`)
|
|
32
41
|
],
|
|
33
|
-
PortBindings: { "8080/tcp": [{ HostPort: String(port) }] }
|
|
42
|
+
PortBindings: { "8080/tcp": [{ HostIp: "127.0.0.1", HostPort: String(port) }] },
|
|
43
|
+
CapDrop: ["ALL"]
|
|
34
44
|
},
|
|
35
45
|
Env: [
|
|
36
|
-
...Object.entries(sandboxConfig.env).map(([k, v]) => `${k}=${v}`)
|
|
46
|
+
...Object.entries(sandboxConfig.env).map(([k, v]) => `${k}=${v}`),
|
|
47
|
+
`HOME=${sandboxRuntimeHome}`,
|
|
48
|
+
`XDG_CACHE_HOME=${sandboxRuntimeHome}/.cache`,
|
|
49
|
+
`XDG_CONFIG_HOME=${sandboxRuntimeHome}/.config`,
|
|
50
|
+
`XDG_DATA_HOME=${sandboxRuntimeXdgDataHome}`,
|
|
51
|
+
`PASSWORD=${accessPassword}`
|
|
37
52
|
],
|
|
38
53
|
Labels: {
|
|
39
54
|
"codecommit.sandbox.id": sandboxId,
|
|
@@ -46,6 +61,7 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
46
61
|
const docker = yield* DockerService;
|
|
47
62
|
const plugins = yield* PluginService;
|
|
48
63
|
const configService = yield* ConfigService;
|
|
64
|
+
const cryptoService = yield* Crypto.Crypto;
|
|
49
65
|
const homePath = yield* homeDir.pipe(Effect.orDie);
|
|
50
66
|
const basePath = yield* sandboxesDir.pipe(Effect.orDie);
|
|
51
67
|
const loadSandboxConfig = configService.load.pipe(Effect.map((config) => config.sandbox), Effect.catch(() => Effect.succeed(defaultSandboxConfig)));
|
|
@@ -78,10 +94,13 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
78
94
|
if (Option.isSome(existing)) {
|
|
79
95
|
return existing.value;
|
|
80
96
|
}
|
|
97
|
+
const sandboxCfg = yield* loadSandboxConfig;
|
|
98
|
+
yield* validateSandboxConfig(sandboxCfg, homePath);
|
|
81
99
|
const nowMs = yield* Clock.currentTimeMillis;
|
|
82
100
|
const rand = yield* Random.nextIntBetween(0, 2176782336);
|
|
83
101
|
const id = SandboxId.make(`sbx-${nowMs}-${rand.toString(36).padStart(6, "0")}`);
|
|
84
102
|
const port = yield* allocatePort();
|
|
103
|
+
const accessPassword = yield* cryptoService.randomUUIDv4;
|
|
85
104
|
const workspacePath = `${basePath}/${id}`;
|
|
86
105
|
const now = new Date(nowMs).toISOString();
|
|
87
106
|
yield* repo.insert({
|
|
@@ -90,6 +109,7 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
90
109
|
awsAccountId: params.awsAccountId,
|
|
91
110
|
repositoryName: params.repositoryName,
|
|
92
111
|
sourceBranch: params.sourceBranch,
|
|
112
|
+
accessPassword,
|
|
93
113
|
workspacePath,
|
|
94
114
|
status: "creating",
|
|
95
115
|
createdAt: now,
|
|
@@ -98,10 +118,9 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
98
118
|
// Fork daemon for async lifecycle
|
|
99
119
|
yield* ownerScope.fork(Effect.gen(function* () {
|
|
100
120
|
const fs = yield* FileSystem.FileSystem;
|
|
121
|
+
const host = yield* ChildEnv.HostEnvironment;
|
|
101
122
|
const log = (detail) => progress(id, detail);
|
|
102
|
-
|
|
103
|
-
yield* log("Loading sandbox config");
|
|
104
|
-
const sandboxCfg = yield* loadSandboxConfig;
|
|
123
|
+
yield* log("Sandbox config validated");
|
|
105
124
|
// Clone via HTTPS + AWS credential helper
|
|
106
125
|
yield* updateStatus(id, "cloning");
|
|
107
126
|
yield* fs.makeDirectory(workspacePath, { recursive: true });
|
|
@@ -128,7 +147,7 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
128
147
|
// `git` and the `aws` credential helper both resolve from PATH, so the
|
|
129
148
|
// profile overrides must extend the inherited environment. Ambient AWS
|
|
130
149
|
// credentials would outrank them, so profileScopedEnv drops those.
|
|
131
|
-
env: ChildEnv.profileScopedEnv({
|
|
150
|
+
env: ChildEnv.profileScopedEnv(host.variables, {
|
|
132
151
|
AWS_PROFILE: params.profile,
|
|
133
152
|
AWS_DEFAULT_REGION: params.region,
|
|
134
153
|
AWS_REGION: params.region
|
|
@@ -150,27 +169,32 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
150
169
|
return;
|
|
151
170
|
}
|
|
152
171
|
yield* log("Clone complete");
|
|
172
|
+
const workspaceInfo = yield* fs.stat(workspacePath);
|
|
173
|
+
const containerIdentity = sandboxContainerIdentityForWorkspaceOwner(Option.getOrUndefined(workspaceInfo.uid), Option.getOrUndefined(workspaceInfo.gid));
|
|
174
|
+
if (containerIdentity.repairRootOwnedWorkspace) {
|
|
175
|
+
yield* log("Preparing root-owned workspace for the non-root sandbox user");
|
|
176
|
+
const chownExitCode = yield* Effect.scoped(ChildProcess.make("chown", ["-R", "1000:1000", "--", workspacePath]).pipe(Effect.flatMap((handle) => handle.exitCode)));
|
|
177
|
+
if (chownExitCode !== 0) {
|
|
178
|
+
return yield* new SandboxError({
|
|
179
|
+
sandboxId: id,
|
|
180
|
+
message: "Failed to prepare root-owned workspace for the non-root sandbox user"
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
153
184
|
// Pull image
|
|
154
185
|
yield* updateStatus(id, "starting");
|
|
155
186
|
yield* log(`Pulling image ${sandboxCfg.image}`);
|
|
156
187
|
yield* docker.pullImage(sandboxCfg.image).pipe(Effect.tap(() => log("Image ready")), Effect.catchIf(() => true, () => log("Image pull skipped (using cached)")));
|
|
157
188
|
// Create + start container
|
|
158
189
|
yield* log("Creating container");
|
|
159
|
-
|
|
190
|
+
yield* validateSandboxConfig(sandboxCfg, homePath);
|
|
191
|
+
const containerConfig = makeContainerConfig(workspacePath, port, id, params.pullRequestId, sandboxCfg, homePath, containerIdentity.user, accessPassword);
|
|
160
192
|
const containerId = yield* docker.createContainer(containerConfig);
|
|
161
193
|
const cid = containerId.trim();
|
|
162
194
|
yield* log(`Container ${cid.slice(0, 12)} created, starting`);
|
|
163
195
|
yield* docker.startContainer(cid);
|
|
164
196
|
yield* updateStatus(id, "starting", { containerId: cid, port });
|
|
165
197
|
yield* log(`Container started on port ${port}`);
|
|
166
|
-
// Fix ownership of dirs that Docker may have created as root (from volume mounts)
|
|
167
|
-
yield* docker.exec(cid, [
|
|
168
|
-
"sudo",
|
|
169
|
-
"chown",
|
|
170
|
-
"-R",
|
|
171
|
-
"coder:coder",
|
|
172
|
-
"/home/coder/.local"
|
|
173
|
-
]).pipe(Effect.catchIf(() => true, () => Effect.void));
|
|
174
198
|
// Wait for code-server to be ready (poll health)
|
|
175
199
|
yield* log("Waiting for code-server health check");
|
|
176
200
|
yield* docker.exec(cid, ["curl", "-sf", "http://localhost:8080/healthz"]).pipe(Effect.retry(Schedule.max([Schedule.recurs(30), Schedule.spaced(Duration.seconds(1))])), Effect.tap(() => log("code-server ready")), Effect.tapError((e) => log(`Health check failed: ${String(e)}`)), Effect.catchIf(() => true, () => Effect.void));
|
|
@@ -214,6 +238,12 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
214
238
|
}).pipe(Effect.mapError((cause) => new SandboxError({ sandboxId: id, message: "Failed to stop sandbox", cause }))),
|
|
215
239
|
restart: (id) => Effect.gen(function* () {
|
|
216
240
|
const row = yield* repo.findById(id);
|
|
241
|
+
if (row.accessPassword === null) {
|
|
242
|
+
return yield* Effect.fail(new SandboxError({
|
|
243
|
+
sandboxId: id,
|
|
244
|
+
message: "Legacy sandbox has no authenticated access credential; delete and recreate it"
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
217
247
|
if (!row.containerId) {
|
|
218
248
|
return yield* Effect.fail(new SandboxError({ sandboxId: id, message: "No container to restart" }));
|
|
219
249
|
}
|
|
@@ -241,7 +271,24 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
241
271
|
}).pipe(Effect.mapError((cause) => new SandboxError({ sandboxId: id, message: "Failed to cleanup sandbox", cause }))),
|
|
242
272
|
reconcile: () => Effect.gen(function* () {
|
|
243
273
|
const active = yield* repo.findActive();
|
|
244
|
-
|
|
274
|
+
const all = yield* repo.findAll();
|
|
275
|
+
const activeIds = new Set(active.map((row) => row.id));
|
|
276
|
+
const rows = all.filter((row) => row.accessPassword === null || activeIds.has(row.id));
|
|
277
|
+
yield* Effect.forEach(rows, (row) => Effect.gen(function* () {
|
|
278
|
+
if (row.accessPassword === null) {
|
|
279
|
+
const discovered = yield* docker.listContainersByLabel("codecommit.sandbox.id", row.id);
|
|
280
|
+
const containerIds = new Set([
|
|
281
|
+
...(row.containerId === null ? [] : [row.containerId]),
|
|
282
|
+
...discovered.map((container) => container.Id)
|
|
283
|
+
]);
|
|
284
|
+
// Do not consider any legacy row reconciled until every persisted
|
|
285
|
+
// or labeled passwordless container has confirmed shutdown.
|
|
286
|
+
yield* Effect.forEach(containerIds, (containerId) => docker.stopContainer(containerId), { discard: true });
|
|
287
|
+
yield* updateStatus(SandboxId.make(row.id), "error", {
|
|
288
|
+
error: "Legacy unauthenticated sandbox stopped; delete and recreate it"
|
|
289
|
+
});
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
245
292
|
if (!row.containerId) {
|
|
246
293
|
yield* updateStatus(SandboxId.make(row.id), "error", { error: "Orphaned (no container)" });
|
|
247
294
|
return;
|
|
@@ -252,7 +299,8 @@ const makeSandboxService = Effect.gen(function* () {
|
|
|
252
299
|
yield* Effect.logInfo(`Reconciled orphaned sandbox ${row.id}`);
|
|
253
300
|
}
|
|
254
301
|
}), { discard: true });
|
|
255
|
-
}).pipe(Effect.catch((cause) => Effect.logWarning("Sandbox reconcile failed", cause))),
|
|
302
|
+
}).pipe(Effect.as(true), Effect.catch((cause) => Effect.logWarning("Sandbox reconcile failed", cause).pipe(Effect.as(false)))),
|
|
303
|
+
hasLegacyUnauthenticated: () => repo.findAll().pipe(Effect.map((rows) => rows.some((row) => row.accessPassword === null))),
|
|
256
304
|
gcIdle: (idleTimeout = Duration.minutes(30), cleanupDelay = Duration.hours(24)) => Effect.gen(function* () {
|
|
257
305
|
const all = yield* repo.findAll();
|
|
258
306
|
const now = yield* Clock.currentTimeMillis;
|