AbdulElahGwaith's picture
Upload folder using huggingface_hub
6582e08 verified
Raw
History Blame Contribute Delete
10.5 kB
/*!
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
import * as os from 'os'
import * as path from 'path'
import {
DotNetDebugConfiguration,
dotnetDebuggerPath,
getCodeRoot,
isImageLambdaConfig,
} from '../../../lambda/local/debugConfiguration'
import { RuntimeFamily } from '../../../lambda/models/samLambdaRuntime'
import * as pathutil from '../../../shared/utilities/pathUtils'
import { ExtContext } from '../../extensions'
import { DefaultSamLocalInvokeCommand, waitForDebuggerMessages } from '../cli/samCliLocalInvoke'
import { runLambdaFunction, waitForPort } from '../localLambdaRunner'
import { SamLaunchRequestArgs } from './awsSamDebugger'
import { ChildProcess } from '../../utilities/processUtils'
import { HttpResourceFetcher } from '../../resourcefetcher/httpResourceFetcher'
import { getLogger } from '../../logger/logger'
import * as vscode from 'vscode'
import * as nls from 'vscode-nls'
import globals from '../../extensionGlobals'
import fs from '../../fs/fs'
const localize = nls.loadMessageBundle()
/**
* Gathers and sets launch-config info by inspecting the workspace and creating
* temp files/directories as needed.
*
* Does NOT execute/invoke SAM, docker, etc.
*/
export async function makeCsharpConfig(config: SamLaunchRequestArgs): Promise<SamLaunchRequestArgs> {
if (!config.baseBuildDir) {
throw Error('invalid state: config.baseBuildDir was not set')
}
config.codeRoot = (await getCodeRoot(config.workspaceFolder, config))!
// TODO: avoid the reassignment
// TODO: walk the tree to find .sln, .csproj ?
const originalCodeRoot = config.codeRoot
config.codeRoot = getSamProjectDirPathForFile(config.templatePath)
config = {
...config,
// https://github.com/dotnet/vscode-csharp/blob/a270be4f2f1236d9bc1b31b6214f1672096788b7/src/lsptoolshost/debugger.ts#L45C1-L54
// The "ms-dotnettools.csharp" extension declares:
// - "coreclr" as the debugger type for ".NET 5+ and .NET Core"
// - "dotnet" as the debugger type for "C#"
// but haven't found the actual circumstances when "dotnet" works while "coreclr" doesn't.
// type: config.runtime == 'dotnet5.0' ? 'coreclr' : 'dotnet',
type: 'coreclr',
request: config.noDebug ? 'launch' : 'attach',
runtimeFamily: RuntimeFamily.DotNet,
}
if (config.sam?.containerBuild) {
config.mountWith = 'write'
}
if (!config.noDebug) {
config = await makeDotnetDebugConfiguration(config, originalCodeRoot)
}
return config
}
/**
* Launches and attaches debugger to a SAM dotnet (csharp) project.
*
* We spin up a C# Lambda Docker container, download and build the debugger for
* Linux, then mount it with the SAM app on run. User's C# workspace dir will
* have a `.vsdbg` dir after the first run.
*/
export async function invokeCsharpLambda(ctx: ExtContext, config: SamLaunchRequestArgs): Promise<SamLaunchRequestArgs> {
config.samLocalInvokeCommand = new DefaultSamLocalInvokeCommand([waitForDebuggerMessages.DOTNET])
// eslint-disable-next-line @typescript-eslint/unbound-method
config.onWillAttachDebugger = waitForPort
const platformArchitecture = os.arch()
if (!config.noDebug) {
if ([config.architecture, platformArchitecture].includes('arm64')) {
void vscode.window.showWarningMessage(
localize(
'AWS.sam.noArm.dotnet.debug',
'The vsdbg debugger does not currently support the arm64 architecture. Function will run locally without debug.'
)
)
getLogger().warn('SAM Invoke: Attempting to debug dotnet on ARM - removing debug flag.')
config.noDebug = true
}
}
return await runLambdaFunction(ctx, config, async () => {
if (!config.noDebug) {
await _installDebugger({
debuggerPath: config.debuggerPath!,
})
}
})
}
interface InstallDebuggerArgs {
debuggerPath: string
}
function getDebuggerPath(parentFolder: string): string {
return path.resolve(parentFolder, '.vsdbg')
}
async function _installDebugger({ debuggerPath }: InstallDebuggerArgs): Promise<void> {
await fs.mkdir(debuggerPath)
try {
getLogger().info(
localize(
'AWS.samcli.local.invoke.debugger.install',
'Installing .NET Core Debugger to {0}...',
debuggerPath
)
)
const vsDbgVersion = 'latest'
// TODO: If vsdbg works with qemu, have this detect Architecture and swap to `linux-arm64` if ARM.
// See https://github.com/OmniSharp/omnisharp-vscode/issues/3277 ;
// qemu appears to set PrivateTmp=true : https://github.com/qemu/qemu/blob/326ff8dd09556fc2e257196c49f35009700794ac/contrib/systemd/qemu-pr-helper.service#L8 ?
const vsDbgRuntime = 'linux-x64'
const installScriptPath = await downloadInstallScript(debuggerPath)
let installCommand: string
let installArgs: string[]
if (os.platform() === 'win32') {
const windir = process.env['WINDIR']
if (!windir) {
throw new Error('Environment variable `WINDIR` not defined')
}
installCommand = `${windir}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`
installArgs = [
'-NonInteractive',
'-NoProfile',
'-WindowStyle',
'Hidden',
'-ExecutionPolicy',
'RemoteSigned',
'-File',
installScriptPath,
'-Version',
vsDbgVersion,
'-RuntimeID',
vsDbgRuntime,
'-InstallPath',
debuggerPath,
]
} else {
installCommand = installScriptPath
installArgs = ['-v', vsDbgVersion, '-r', vsDbgRuntime, '-l', debuggerPath]
}
const childProcess = new ChildProcess(installCommand, installArgs)
const install = await childProcess.run({
onStdout: (text: string) => {
globals.outputChannel.append(text)
},
onStderr: (text: string) => {
globals.outputChannel.append(text)
},
})
if (install.exitCode) {
throw new Error(`command failed (exit code: ${install.exitCode}): ${installCommand}`)
}
} catch (err) {
getLogger().info(
localize(
'AWS.samcli.local.invoke.debugger.install.failed',
'Error installing .NET Core Debugger: {0}',
err instanceof Error ? (err as Error).message : String(err)
)
)
throw err
}
}
async function downloadInstallScript(debuggerPath: string): Promise<string> {
let installScriptUrl: string
let installScriptPath: string
if (os.platform() === 'win32') {
installScriptUrl = 'https://aka.ms/getvsdbgps1'
installScriptPath = path.join(debuggerPath, 'installVsdbgScript.ps1')
} else {
installScriptUrl = 'https://aka.ms/getvsdbgsh'
installScriptPath = path.join(debuggerPath, 'installVsdbgScript.sh')
}
const installScriptFetcher = await new HttpResourceFetcher(installScriptUrl, { showUrl: true }).get()
const installScript = await installScriptFetcher?.text()
if (!installScript) {
throw Error(`Failed to download ${installScriptUrl}`)
}
await fs.writeFile(installScriptPath, installScript, 'utf8')
await fs.chmod(installScriptPath, 0o700)
return installScriptPath
}
function getSamProjectDirPathForFile(filepath: string): string {
return pathutil.normalize(path.dirname(filepath))
}
/**
* Creates a .NET launch-config composed with the given `config`.
*/
export async function makeDotnetDebugConfiguration(
config: SamLaunchRequestArgs,
codeUri: string
): Promise<DotNetDebugConfiguration> {
if (config.noDebug) {
throw Error(`SAM debug: invalid config: ${config.name}`)
}
const pipeArgs = ['-c', `docker exec -i $(docker ps -q -f publish=${config.debugPort}) \${debuggerCommand}`]
config.debuggerPath = pathutil.normalize(getDebuggerPath(codeUri))
await fs.mkdir(config.debuggerPath)
const isImageLambda = await isImageLambdaConfig(config)
if (isImageLambda && !config.noDebug) {
config.containerEnvVars = {
_AWS_LAMBDA_DOTNET_DEBUGGING: '1',
}
}
if (os.platform() === 'win32') {
// Coerce drive letter to uppercase. While Windows is case-insensitive, sourceFileMap is case-sensitive.
codeUri = codeUri.replace(pathutil.driveLetterRegex, (match) => match.toUpperCase())
}
if (isImageLambda) {
// default build path, in dotnet image-based templates
// Not needed for ZIP lambdas, because SAM prevents dotnet from being
// built in-container thus PDBs already point to the user workspace.
if (!config.sourceFileMap) {
config.sourceFileMap = {}
}
config.sourceFileMap['/build'] = codeUri
}
if (config.lambda?.pathMappings !== undefined) {
if (!config.sourceFileMap) {
config.sourceFileMap = {}
}
// we could safely leave this entry in, but might as well give the user full control if they're specifying mappings
delete config.sourceFileMap['/build']
for (const mapping of config.lambda.pathMappings) {
// this looks weird because we're mapping the PDB path to the local workspace
config.sourceFileMap[mapping.remoteRoot] = mapping.localRoot
}
}
return {
...config,
runtimeFamily: RuntimeFamily.DotNet,
request: 'attach',
// Since SAM CLI 1.0 we cannot assume PID=1. So use processName=dotnet
// instead of processId=1.
processName: 'dotnet',
pipeTransport: {
pipeProgram: 'sh',
pipeArgs,
debuggerPath: dotnetDebuggerPath,
pipeCwd: codeUri,
},
windows: {
pipeTransport: {
pipeProgram: 'powershell',
pipeArgs,
debuggerPath: dotnetDebuggerPath,
pipeCwd: codeUri,
},
},
}
}