Skip to content

Commit e1ed265

Browse files
authored
Added support for the use container option when running lamdas locally (#913)
* Added support for the use container option when running lamdas locally * Changed description text to SAM Docker container * Revert "Changed description text to SAM Docker container" This reverts commit 003a889. * Moved and renamed getConfig function Changed terminology in useContainer descripition to be more accurate
1 parent 993ba82 commit e1ed265

File tree

6 files changed

+97
-68
lines changed

6 files changed

+97
-68
lines changed

src/lambda/config/templates.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { mkdir } from '../../shared/filesystem'
1515
import * as fsUtils from '../../shared/filesystemUtilities'
1616
import { getLogger, Logger } from '../../shared/logger'
1717
import { getTabSizeSetting } from '../../shared/utilities/editorUtilities'
18+
import { getNormalizedRelativePath } from '../../shared/utilities/pathUtils'
1819
import { saveDocumentIfDirty } from '../../shared/utilities/textDocumentUtilities'
1920

2021
const localize = nls.loadMessageBundle()
@@ -40,13 +41,66 @@ export interface HandlerConfig {
4041
[name: string]: string
4142
}
4243
dockerNetwork?: string
44+
useContainer?: boolean
4345
}
4446

4547
export function generateDefaultHandlerConfig(): HandlerConfig {
4648
return {
4749
event: {},
4850
environmentVariables: {},
49-
dockerNetwork: undefined
51+
dockerNetwork: undefined,
52+
useContainer: undefined
53+
}
54+
}
55+
56+
export async function getHandlerConfig(params: {
57+
handlerName: string
58+
documentUri: vscode.Uri
59+
samTemplate: vscode.Uri
60+
}): Promise<HandlerConfig> {
61+
const workspaceFolder = vscode.workspace.getWorkspaceFolder(params.documentUri)
62+
if (!workspaceFolder) {
63+
return generateDefaultHandlerConfig()
64+
}
65+
66+
const config: HandlerConfig = await getLocalLambdaConfiguration(
67+
workspaceFolder,
68+
params.handlerName,
69+
params.samTemplate
70+
)
71+
72+
return config
73+
}
74+
75+
async function getLocalLambdaConfiguration(
76+
workspaceFolder: vscode.WorkspaceFolder,
77+
handler: string,
78+
samTemplate: vscode.Uri
79+
): Promise<HandlerConfig> {
80+
try {
81+
const configPath: string = getTemplatesConfigPath(workspaceFolder.uri.fsPath)
82+
const templateRelativePath = getNormalizedRelativePath(workspaceFolder.uri.fsPath, samTemplate.fsPath)
83+
84+
await saveDocumentIfDirty(configPath)
85+
86+
let rawConfig: string = '{}'
87+
if (await fsUtils.fileExists(configPath)) {
88+
rawConfig = await fsUtils.readFileAsString(configPath)
89+
}
90+
91+
const configPopulationResult = new TemplatesConfigPopulator(rawConfig)
92+
.ensureTemplateHandlerSectionExists(templateRelativePath, handler)
93+
.getResults()
94+
95+
const config: TemplatesConfig = loadTemplatesConfigFromJson(configPopulationResult.json)
96+
97+
return config.templates[templateRelativePath]!.handlers![handler]!
98+
} catch (e) {
99+
if (e instanceof TemplatesConfigFieldTypeError) {
100+
showTemplatesConfigurationError(e)
101+
}
102+
103+
throw e
50104
}
51105
}
52106

src/lambda/local/configureLocalLambda.ts

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,15 @@
44
*/
55

66
import * as vscode from 'vscode'
7-
import * as fsUtils from '../../shared/filesystemUtilities'
87
import { getLogger, Logger } from '../../shared/logger'
98
import { recordLambdaConfigure, Result } from '../../shared/telemetry/telemetry'
109
import { getNormalizedRelativePath } from '../../shared/utilities/pathUtils'
1110
import { getChildrenRange } from '../../shared/utilities/symbolUtilities'
12-
import { getTabSize, saveDocumentIfDirty } from '../../shared/utilities/textDocumentUtilities'
11+
import { getTabSize } from '../../shared/utilities/textDocumentUtilities'
1312
import {
1413
ensureTemplatesConfigFileExists,
1514
getTemplatesConfigPath,
16-
HandlerConfig,
17-
loadTemplatesConfigFromJson,
1815
showTemplatesConfigurationError,
19-
TemplatesConfig,
2016
TemplatesConfigFieldTypeError,
2117
TemplatesConfigPopulator
2218
} from '../config/templates'
@@ -90,38 +86,6 @@ export async function configureLocalLambda(
9086
}
9187
}
9288

93-
export async function getLocalLambdaConfiguration(
94-
workspaceFolder: vscode.WorkspaceFolder,
95-
handler: string,
96-
samTemplate: vscode.Uri
97-
): Promise<HandlerConfig> {
98-
try {
99-
const configPath: string = getTemplatesConfigPath(workspaceFolder.uri.fsPath)
100-
const templateRelativePath = getNormalizedRelativePath(workspaceFolder.uri.fsPath, samTemplate.fsPath)
101-
102-
await saveDocumentIfDirty(configPath)
103-
104-
let rawConfig: string = '{}'
105-
if (await fsUtils.fileExists(configPath)) {
106-
rawConfig = await fsUtils.readFileAsString(configPath)
107-
}
108-
109-
const configPopulationResult = new TemplatesConfigPopulator(rawConfig)
110-
.ensureTemplateHandlerSectionExists(templateRelativePath, handler)
111-
.getResults()
112-
113-
const config: TemplatesConfig = loadTemplatesConfigFromJson(configPopulationResult.json)
114-
115-
return config.templates[templateRelativePath]!.handlers![handler]!
116-
} catch (e) {
117-
if (e instanceof TemplatesConfigFieldTypeError) {
118-
showTemplatesConfigurationError(e)
119-
}
120-
121-
throw e
122-
}
123-
}
124-
12589
async function getEventRange(
12690
editor: vscode.TextEditor,
12791
relativeTemplatePath: string,

src/shared/codelens/csharpCodeLensProvider.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as path from 'path'
77
import * as vscode from 'vscode'
88

99
import { access } from 'fs-extra'
10+
import { getHandlerConfig } from '../../lambda/config/templates'
1011
import { makeCoreCLRDebugConfiguration } from '../../lambda/local/debugConfiguration'
1112
import { DefaultDockerClient, DockerClient } from '../clients/dockerClient'
1213
import { CloudFormation } from '../cloudformation/cloudformation'
@@ -170,12 +171,19 @@ async function onLocalInvokeCommand(
170171
properties: resource.Properties
171172
})
172173

174+
const config = await getHandlerConfig({
175+
handlerName: handlerName,
176+
documentUri: documentUri,
177+
samTemplate: vscode.Uri.file(lambdaLocalInvokeParams.samTemplate.fsPath)
178+
})
179+
173180
const buildArgs: ExecuteSamBuildArguments = {
174181
baseBuildDir,
175182
channelLogger,
176183
codeDir: codeUri,
177184
inputTemplatePath,
178-
samProcessInvoker: processInvoker
185+
samProcessInvoker: processInvoker,
186+
useContainer: config.useContainer
179187
}
180188
if (lambdaLocalInvokeParams.isDebug) {
181189
buildArgs.environmentVariables = {

src/shared/codelens/localLambdaRunner.ts

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import * as path from 'path'
77
import * as tcpPortUsed from 'tcp-port-used'
88
import * as vscode from 'vscode'
9-
import { getLocalLambdaConfiguration } from '../../lambda/local/configureLocalLambda'
109
import { detectLocalLambdas, LocalLambda } from '../../lambda/local/detectLocalLambdas'
1110
import { CloudFormation } from '../cloudformation/cloudformation'
1211
import { makeTemporaryToolkitFolder } from '../filesystemUtilities'
@@ -22,7 +21,7 @@ import { SamTemplateGenerator } from '../templates/sam/samTemplateGenerator'
2221
import { ExtensionDisposableFiles } from '../utilities/disposableFiles'
2322

2423
import { writeFile } from 'fs-extra'
25-
import { generateDefaultHandlerConfig, HandlerConfig } from '../../lambda/config/templates'
24+
import { getHandlerConfig, HandlerConfig } from '../../lambda/config/templates'
2625
import { DebugConfiguration } from '../../lambda/local/debugConfiguration'
2726
import { getFamily, RuntimeFamily } from '../../lambda/models/samLambdaRuntime'
2827
import { getLogger } from '../logger'
@@ -91,12 +90,20 @@ export class LocalLambdaRunner {
9190
)
9291

9392
const inputTemplate: string = await this.generateInputTemplate(this.codeRootDirectoryPath)
93+
94+
const config = await getHandlerConfig({
95+
handlerName: this.localInvokeParams.handlerName,
96+
documentUri: this.localInvokeParams.document.uri,
97+
samTemplate: this.localInvokeParams.samTemplate
98+
})
99+
94100
const samBuildTemplate: string = await executeSamBuild({
95101
baseBuildDir: await this.getBaseBuildFolder(),
96102
channelLogger: this.channelLogger,
97103
codeDir: this.codeRootDirectoryPath,
98104
inputTemplatePath: inputTemplate,
99-
samProcessInvoker: this.processInvoker
105+
samProcessInvoker: this.processInvoker,
106+
useContainer: config.useContainer
100107
})
101108

102109
await this.invokeLambdaFunction(samBuildTemplate)
@@ -177,7 +184,7 @@ export class LocalLambdaRunner {
177184

178185
const eventPath: string = path.join(await this.getBaseBuildFolder(), 'event.json')
179186
const environmentVariablePath = path.join(await this.getBaseBuildFolder(), 'env-vars.json')
180-
const config = await getConfig({
187+
const config = await getHandlerConfig({
181188
handlerName: this.localInvokeParams.handlerName,
182189
documentUri: this.localInvokeParams.document.uri,
183190
samTemplate: this.localInvokeParams.samTemplate
@@ -316,6 +323,7 @@ export interface ExecuteSamBuildArguments {
316323
manifestPath?: string
317324
environmentVariables?: NodeJS.ProcessEnv
318325
samProcessInvoker: SamCliProcessInvoker
326+
useContainer?: boolean
319327
}
320328

321329
export async function executeSamBuild({
@@ -325,7 +333,8 @@ export async function executeSamBuild({
325333
inputTemplatePath,
326334
manifestPath,
327335
environmentVariables,
328-
samProcessInvoker
336+
samProcessInvoker,
337+
useContainer
329338
}: ExecuteSamBuildArguments): Promise<string> {
330339
channelLogger.info('AWS.output.building.sam.application', 'Building SAM Application...')
331340

@@ -337,7 +346,8 @@ export async function executeSamBuild({
337346
templatePath: inputTemplatePath,
338347
invoker: samProcessInvoker,
339348
manifestPath,
340-
environmentVariables
349+
environmentVariables,
350+
useContainer
341351
}
342352
await new SamCliBuildInvocation(samCliArgs).execute()
343353

@@ -389,7 +399,7 @@ export async function invokeLambdaFunction(
389399

390400
const eventPath: string = path.join(invokeArgs.baseBuildDir, 'event.json')
391401
const environmentVariablePath = path.join(invokeArgs.baseBuildDir, 'env-vars.json')
392-
const config = await getConfig({
402+
const config = await getHandlerConfig({
393403
handlerName: invokeArgs.originalHandlerName,
394404
documentUri: invokeArgs.documentUri,
395405
samTemplate: vscode.Uri.file(invokeArgs.originalSamTemplatePath)
@@ -446,25 +456,6 @@ export async function invokeLambdaFunction(
446456
}
447457
}
448458

449-
const getConfig = async (params: {
450-
handlerName: string
451-
documentUri: vscode.Uri
452-
samTemplate: vscode.Uri
453-
}): Promise<HandlerConfig> => {
454-
const workspaceFolder = vscode.workspace.getWorkspaceFolder(params.documentUri)
455-
if (!workspaceFolder) {
456-
return generateDefaultHandlerConfig()
457-
}
458-
459-
const config: HandlerConfig = await getLocalLambdaConfiguration(
460-
workspaceFolder,
461-
params.handlerName,
462-
params.samTemplate
463-
)
464-
465-
return config
466-
}
467-
468459
const getEnvironmentVariables = (
469460
config: Pick<HandlerConfig, 'environmentVariables'>
470461
): SAMTemplateEnvironmentVariables => {

src/shared/codelens/pythonCodeLensProvider.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { unlink, writeFile } from 'fs-extra'
77
import * as os from 'os'
88
import * as path from 'path'
99
import * as vscode from 'vscode'
10+
import { getHandlerConfig } from '../../lambda/config/templates'
1011
import { PythonDebugConfiguration, PythonPathMapping } from '../../lambda/local/debugConfiguration'
1112
import { CloudFormation } from '../cloudformation/cloudformation'
1213
import { VSCODE_EXTENSION_ID } from '../extensions'
@@ -262,14 +263,20 @@ export async function initialize({
262263
)}`
263264
)
264265

265-
const codeDir = samProjectCodeRoot
266+
const config = await getHandlerConfig({
267+
handlerName: args.handlerName,
268+
documentUri: args.document.uri,
269+
samTemplate: vscode.Uri.file(args.samTemplate.fsPath)
270+
})
271+
266272
const samTemplatePath: string = await executeSamBuild({
267273
baseBuildDir,
268274
channelLogger,
269-
codeDir,
275+
codeDir: samProjectCodeRoot,
270276
inputTemplatePath,
271277
manifestPath,
272-
samProcessInvoker: processInvoker
278+
samProcessInvoker: processInvoker,
279+
useContainer: config.useContainer
273280
})
274281

275282
const invokeArgs: InvokeLambdaFunctionArguments = {

src/templates/templates.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
"type": "string",
4444
"default": null,
4545
"description": "If specified, adds a --docker-network parameter to the SAM CLI. If not specified, no parameter will be sent."
46+
},
47+
"useContainer": {
48+
"type": "boolean",
49+
"default": false,
50+
"description": "If specified, adds a --use-container parameter to the SAM CLI. If not specified, no parameter will be sent. If your functions depend on packages that have natively compiled dependencies use this flag to build your function inside a SAM Docker container."
4651
}
4752
}
4853
}

0 commit comments

Comments
 (0)