@mavogel/cdk-vscode-server 0.0.63 → 0.0.64
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/.jsii +18 -11
- package/API.md +9 -1
- package/CLAUDE.md +75 -2
- package/README.md +1 -1
- package/examples/auto-stop/main.ts +1 -1
- package/examples/custom/main.ts +1 -1
- package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.assets.json +2 -2
- package/integ-tests/integ.custom-domain.ts.snapshot/IntegSetupVSCodeOnCustomDomainDefaultTestDeployAssert6982D514.template.json +1 -1
- package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.assets.json +2 -2
- package/integ-tests/integ.custom-domain.ts.snapshot/IntegTestStackCustomDomain.template.json +3 -3
- package/integ-tests/integ.custom-domain.ts.snapshot/integ.json +1 -1
- package/integ-tests/integ.custom-domain.ts.snapshot/manifest.json +8 -5
- package/integ-tests/integ.custom-domain.ts.snapshot/tree.json +1 -1
- package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegStopOnIdleFunctionalityDefaultTestDeployAssertEECF3FC0.assets.json +2 -2
- package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegStopOnIdleFunctionalityDefaultTestDeployAssertEECF3FC0.template.json +4 -4
- package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegTestStackStopOnIdle.assets.json +2 -2
- package/integ-tests/integ.stop-on-idle.ts.snapshot/IntegTestStackStopOnIdle.template.json +3 -3
- package/integ-tests/integ.stop-on-idle.ts.snapshot/manifest.json +12 -6
- package/integ-tests/integ.stop-on-idle.ts.snapshot/tree.json +1 -1
- package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.assets.json +2 -2
- package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.template.json +1 -1
- package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.assets.json +2 -2
- package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.template.json +3 -3
- package/integ-tests/integ.ubuntu.ts.snapshot/integ.json +1 -1
- package/integ-tests/integ.ubuntu.ts.snapshot/manifest.json +8 -5
- package/integ-tests/integ.ubuntu.ts.snapshot/tree.json +1 -1
- package/integ-tests/integ.ubuntu25.ts +69 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/IntegSetupVSCodeOnUbuntu25DefaultTestDeployAssert48DBCF35.assets.json +33 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/IntegSetupVSCodeOnUbuntu25DefaultTestDeployAssert48DBCF35.template.json +337 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/IntegTestStackUbuntu25.assets.json +118 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/IntegTestStackUbuntu25.template.json +2725 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d/index.js +1 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.2f99f38311da357eaaea1284d67c759759324dec4a1cd11621d9c59eea9e81df.lambda/index.js +180 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.530055f7515b3f0a47900f5df37e729ba40ca977b2d07b952bdefa2b8f883f42.bundle/index.js +30676 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b.lambda/index.js +57 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/__entrypoint__.js +1 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.7fa1e366ee8a9ded01fc355f704cff92bfd179574e6f9cfee800a3541df1b200/index.js +1 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.9d043014be736e8162bcc7ec5590cc6d2ff24fd0d9c73a5c5d595151c5fdad00/index.js +1 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/cfn-response.js +1 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/consts.js +1 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/framework.js +3 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/outbound.js +1 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.bdc104ed9cab1b5b6421713c8155f0b753380595356f710400609664d3635eca/util.js +1 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/asset.efac30c7091c58fed492058fa6403c14f7e58aab8cf4fd595d838b8d5eeec2b9/index.js +6017 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/integ.json +23 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/manifest.json +1473 -0
- package/integ-tests/integ.ubuntu25.ts.snapshot/tree.json +1 -0
- package/lib/idle-monitor/idle-monitor.js +1 -1
- package/lib/installer/installer.d.ts +5 -0
- package/lib/installer/installer.js +3 -2
- package/lib/mappings.js +11 -3
- package/lib/vscode-server.d.ts +5 -1
- package/lib/vscode-server.js +10 -3
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var h=Object.create,d=Object.defineProperty,P=Object.getOwnPropertyDescriptor,C=Object.getOwnPropertyNames,b=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty,E=(e,o)=>{for(var n in o)d(e,n,{get:o[n],enumerable:!0})},p=(e,o,n,t)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of C(o))!S.call(e,r)&&r!==n&&d(e,r,{get:()=>o[r],enumerable:!(t=P(o,r))||t.enumerable});return e},G=(e,o,n)=>(n=e!=null?h(b(e)):{},p(o||!e||!e.__esModule?d(n,"default",{value:e,enumerable:!0}):n,e)),x=e=>p(d({},"__esModule",{value:!0}),e),O={};E(O,{disableSleepForTesting:()=>I,handler:()=>q}),module.exports=x(O);var i=G(require("@aws-sdk/client-cloudwatch-logs")),w=!1;function I(){w=!0}async function R(e,o,n){await n(async()=>{try{let t={logGroupName:e},r=new i.CreateLogGroupCommand(t);await o.send(r)}catch(t){if(t.name==="ResourceAlreadyExistsException")return;throw t}})}async function k(e,o,n){await n(async()=>{try{let t={logGroupName:e},r=new i.DeleteLogGroupCommand(t);await o.send(r)}catch(t){if(t.name==="ResourceNotFoundException")return;throw t}})}async function y(e,o,n,t){await n(async()=>{if(t){let r={logGroupName:e,retentionInDays:t},s=new i.PutRetentionPolicyCommand(r);await o.send(s)}else{let r={logGroupName:e},s=new i.DeleteRetentionPolicyCommand(r);await o.send(s)}})}async function q(e,o){try{console.log(JSON.stringify({...e,ResponseURL:"..."}));let t=e.ResourceProperties.LogGroupName,r=e.ResourceProperties.LogGroupRegion,s=L(e.ResourceProperties.SdkRetry?.maxRetries)??10,a=N(s),m={logger:console,region:r},c=new i.CloudWatchLogsClient(m);if((e.RequestType==="Create"||e.RequestType==="Update")&&(await R(t,c,a),await y(t,c,a,L(e.ResourceProperties.RetentionInDays)),e.RequestType==="Create")){let g=new i.CloudWatchLogsClient({logger:console,region:process.env.AWS_REGION});await R(`/aws/lambda/${o.functionName}`,g,a),await y(`/aws/lambda/${o.functionName}`,g,a,1)}e.RequestType==="Delete"&&e.ResourceProperties.RemovalPolicy==="destroy"&&await k(t,c,a),await n("SUCCESS","OK",t)}catch(t){console.log(t),await n("FAILED",t.message,e.ResourceProperties.LogGroupName)}function n(t,r,s){let a=JSON.stringify({Status:t,Reason:r,PhysicalResourceId:s,StackId:e.StackId,RequestId:e.RequestId,LogicalResourceId:e.LogicalResourceId,Data:{LogGroupName:e.ResourceProperties.LogGroupName}});console.log("Responding",a);let m=require("url").parse(e.ResponseURL),c={hostname:m.hostname,path:m.path,method:"PUT",headers:{"content-type":"","content-length":Buffer.byteLength(a,"utf8")}};return new Promise((g,l)=>{try{let u=require("https").request(c,g);u.on("error",l),u.write(a),u.end()}catch(u){l(u)}})}}function L(e,o=10){if(e!==void 0)return parseInt(e,o)}function N(e,o=1e3,n=6e4){return async t=>{let r=0;do try{return await t()}catch(s){if(f("OperationAbortedException",s)||f("ThrottlingException",s))if(r<e){r++,await D(W(r,o,n));continue}else throw new Error("Out of attempts to change log group");throw s}while(!0)}}function f(e,o){return o.name===e||o.message.includes(e)}function W(e,o,n){return Math.min(Math.round(Math.random()*o*2**e),n)}async function D(e){w&&(e=0),await new Promise(o=>setTimeout(o,e))}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/installer/installer.lambda.ts
|
|
21
|
+
var installer_lambda_exports = {};
|
|
22
|
+
__export(installer_lambda_exports, {
|
|
23
|
+
handler: () => handler
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(installer_lambda_exports);
|
|
26
|
+
var import_client_ssm = require("@aws-sdk/client-ssm");
|
|
27
|
+
var ssm = new import_client_ssm.SSM();
|
|
28
|
+
var SLEEP_MS = 2900;
|
|
29
|
+
var handler = async (event, context) => {
|
|
30
|
+
console.log("Event: %j", { ...event, ResponseURL: "..." });
|
|
31
|
+
if (event.RequestType !== "Create") {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
const resourceProperties = event.ResourceProperties;
|
|
35
|
+
const instanceId = event.ResourceProperties.InstanceId;
|
|
36
|
+
const documentName = event.ResourceProperties.DocumentName;
|
|
37
|
+
const cloudWatchLogGroupName = event.ResourceProperties.CloudWatchLogGroupName;
|
|
38
|
+
console.log("ResourceProperties raw: %j", resourceProperties);
|
|
39
|
+
console.log("InstanceId: %s", event.ResourceProperties.InstanceId);
|
|
40
|
+
console.log("VSCodePassword: %s", event.ResourceProperties.VSCodePassword);
|
|
41
|
+
const resourcePropertiesPartial = resourceProperties;
|
|
42
|
+
console.log("ResourceProperties before: %j", resourcePropertiesPartial);
|
|
43
|
+
delete resourcePropertiesPartial.ServiceToken;
|
|
44
|
+
if (resourcePropertiesPartial.ServiceTimeout) {
|
|
45
|
+
delete resourcePropertiesPartial.ServiceTimeout;
|
|
46
|
+
}
|
|
47
|
+
delete resourcePropertiesPartial.InstanceId;
|
|
48
|
+
delete resourcePropertiesPartial.DocumentName;
|
|
49
|
+
delete resourcePropertiesPartial.CloudWatchLogGroupName;
|
|
50
|
+
if (resourcePropertiesPartial.PhysicalResourceId) {
|
|
51
|
+
delete resourcePropertiesPartial.PhysicalResourceId;
|
|
52
|
+
}
|
|
53
|
+
console.log(
|
|
54
|
+
"ResourceProperties filtered after: %j",
|
|
55
|
+
resourcePropertiesPartial
|
|
56
|
+
);
|
|
57
|
+
const parameters = {};
|
|
58
|
+
for (const [key, value] of Object.entries(resourcePropertiesPartial)) {
|
|
59
|
+
parameters[key] = [value];
|
|
60
|
+
}
|
|
61
|
+
console.log("mapped parameters: %j", parameters);
|
|
62
|
+
console.log(
|
|
63
|
+
`Running SSM Document '${documentName}' on EC2 instance '${instanceId}'. Logging to '${cloudWatchLogGroupName}' with parameters: '${JSON.stringify(parameters)}'`
|
|
64
|
+
);
|
|
65
|
+
let commandId;
|
|
66
|
+
let attemptNo = 0;
|
|
67
|
+
while (true) {
|
|
68
|
+
attemptNo += 1;
|
|
69
|
+
const timeRemaining = context.getRemainingTimeInMillis();
|
|
70
|
+
console.log(
|
|
71
|
+
`Send attempt: ${attemptNo}. Time Remaining: ${timeRemaining / 1e3}s`
|
|
72
|
+
);
|
|
73
|
+
try {
|
|
74
|
+
const response = await ssm.send(
|
|
75
|
+
new import_client_ssm.SendCommandCommand({
|
|
76
|
+
DocumentName: documentName,
|
|
77
|
+
InstanceIds: [instanceId],
|
|
78
|
+
CloudWatchOutputConfig: {
|
|
79
|
+
CloudWatchLogGroupName: cloudWatchLogGroupName,
|
|
80
|
+
CloudWatchOutputEnabled: true
|
|
81
|
+
},
|
|
82
|
+
Parameters: parameters
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
console.log(`sendCommand response: ${JSON.stringify(response)}`);
|
|
86
|
+
const command = response.Command;
|
|
87
|
+
commandId = command.CommandId;
|
|
88
|
+
console.log(`Command sent successfully. CommandId: ${commandId}`);
|
|
89
|
+
break;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.log("Error sending command:", error);
|
|
92
|
+
const isUnauthorized = error.name === "UnauthorizedException" || error.name === "AccessDeniedException" || error.message && error.message.includes("not authorized");
|
|
93
|
+
const isThrottled = error.name === "ThrottlingException" || error.name === "TooManyRequestsException";
|
|
94
|
+
const isRetryable = isUnauthorized || isThrottled;
|
|
95
|
+
const remainingTime = context.getRemainingTimeInMillis();
|
|
96
|
+
if (isRetryable && remainingTime > SLEEP_MS) {
|
|
97
|
+
console.log(
|
|
98
|
+
`Retryable error encountered (${error.name}). Attempt ${attemptNo}. Sleeping: ${SLEEP_MS / 1e3}s before retry`
|
|
99
|
+
);
|
|
100
|
+
await new Promise((resolve) => setTimeout(resolve, SLEEP_MS));
|
|
101
|
+
} else {
|
|
102
|
+
console.log("Non-retryable error or timeout. Failing...");
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
let pollAttemptNo = 0;
|
|
108
|
+
const responseData = { CommandId: commandId };
|
|
109
|
+
while (true) {
|
|
110
|
+
pollAttemptNo += 1;
|
|
111
|
+
const timeRemaining = context.getRemainingTimeInMillis();
|
|
112
|
+
console.log(
|
|
113
|
+
`Poll attempt: ${pollAttemptNo}. Time Remaining: ${timeRemaining / 1e3}s`
|
|
114
|
+
);
|
|
115
|
+
try {
|
|
116
|
+
const invocationResponse = await ssm.send(
|
|
117
|
+
new import_client_ssm.GetCommandInvocationCommand({
|
|
118
|
+
CommandId: commandId,
|
|
119
|
+
InstanceId: instanceId
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
console.log(
|
|
123
|
+
`getCommandInvocation response: ${JSON.stringify(invocationResponse)}`
|
|
124
|
+
);
|
|
125
|
+
const status = invocationResponse.Status;
|
|
126
|
+
switch (status) {
|
|
127
|
+
case "Pending":
|
|
128
|
+
case "InProgress":
|
|
129
|
+
case "Delayed":
|
|
130
|
+
if (timeRemaining > SLEEP_MS) {
|
|
131
|
+
console.log(
|
|
132
|
+
`Command ${commandId} status: '${status}'. Sleeping: ${SLEEP_MS / 1e3}s`
|
|
133
|
+
);
|
|
134
|
+
await new Promise((resolve) => setTimeout(resolve, SLEEP_MS));
|
|
135
|
+
break;
|
|
136
|
+
} else {
|
|
137
|
+
throw new Error(
|
|
138
|
+
`SSM Document ${documentName} on EC2 instance ${instanceId} timed out while lambda waiting (status: ${status})`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
case "Success":
|
|
142
|
+
console.log(
|
|
143
|
+
`Instance ${instanceId} successfully bootstrapped. Command ${commandId} completed.`
|
|
144
|
+
);
|
|
145
|
+
return { Data: responseData };
|
|
146
|
+
case "TimedOut":
|
|
147
|
+
throw new Error(
|
|
148
|
+
`SSM Document ${documentName} on EC2 instance ${instanceId} timed out`
|
|
149
|
+
);
|
|
150
|
+
case "Cancelled":
|
|
151
|
+
throw new Error(
|
|
152
|
+
`SSM Document ${documentName} on EC2 instance ${instanceId} cancelled`
|
|
153
|
+
);
|
|
154
|
+
case "Failed":
|
|
155
|
+
throw new Error(
|
|
156
|
+
`SSM Document ${documentName} on EC2 instance ${instanceId} failed`
|
|
157
|
+
);
|
|
158
|
+
default:
|
|
159
|
+
throw new Error(
|
|
160
|
+
`SSM Document ${documentName} on EC2 instance ${instanceId} unknown status: ${status}`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
} catch (error) {
|
|
164
|
+
const remainingTime = context.getRemainingTimeInMillis();
|
|
165
|
+
if (error.name === "InvocationDoesNotExist" && remainingTime > SLEEP_MS) {
|
|
166
|
+
console.log(
|
|
167
|
+
`Invocation not yet available. Sleeping: ${SLEEP_MS / 1e3}s`
|
|
168
|
+
);
|
|
169
|
+
await new Promise((resolve) => setTimeout(resolve, SLEEP_MS));
|
|
170
|
+
} else {
|
|
171
|
+
console.log("Error checking command status:", error);
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
178
|
+
0 && (module.exports = {
|
|
179
|
+
handler
|
|
180
|
+
});
|