diff --git a/.gitignore b/.gitignore index 97b322a1..de561c7b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,8 @@ base/dump-dotnetcore21/bin base/dump-dotnetcore21/obj base/dump-dotnetcore31/bin base/dump-dotnetcore31/obj +base/dump-dotnet6/bin +base/dump-dotnet6/obj base/dump-providedal2/bootstrap base/dump-providedal2/bootstrap.zip dotnetcore2.0/run/MockBootstraps/bin @@ -34,6 +36,9 @@ examples/dotnetcore2.1/pub examples/dotnetcore3.1/bin examples/dotnetcore3.1/obj examples/dotnetcore3.1/pub +examples/dotnet6.0/bin +examples/dotnet6.0/obj +examples/dotnet6.0/pub examples/java/bin examples/java/build examples/go1.x/handler diff --git a/README.md b/README.md index bb211d1f..b71f3c99 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,22 @@ the [AWS CLI](https://aws.amazon.com/cli/). ## Contents -* [Usage](#usage) -* [Run Examples](#run-examples) -* [Build Examples](#build-examples) -* [Using a Dockerfile to build](#using-a-dockerfile-to-build) -* [Docker tags](#docker-tags) -* [Verifying images](#verifying-images) -* [Environment variables](#environment-variables) -* [Build environment](#build-environment) -* [Questions](#questions) +- [docker-lambda](#docker-lambda) + - [Contents](#contents) + - [Usage](#usage) + - [Running Lambda functions](#running-lambda-functions) + - [Running in "stay-open" API mode](#running-in-stay-open-api-mode) + - [Developing in "stay-open" mode](#developing-in-stay-open-mode) + - [Building Lambda functions](#building-lambda-functions) + - [Run Examples](#run-examples) + - [Build Examples](#build-examples) + - [Using a Dockerfile to build](#using-a-dockerfile-to-build) + - [Node.js module](#nodejs-module) + - [Docker tags](#docker-tags) + - [Verifying images](#verifying-images) + - [Environment variables](#environment-variables) + - [Build environment](#build-environment) + - [Questions](#questions) --- @@ -313,6 +320,7 @@ These follow the Lambda runtime names: - `java8.al2` - `java11` - `go1.x` + - `dotnet6` - `dotnetcore2.0` - `dotnetcore2.1` - `dotnetcore3.1` @@ -333,6 +341,7 @@ These follow the Lambda runtime names: - `build-java8.al2` - `build-java11` - `build-go1.x` + - `build-dotnet6` - `build-dotnetcore2.0` - `build-dotnetcore2.1` - `build-dotnetcore3.1` diff --git a/base/dump-dotnet6/Function.cs b/base/dump-dotnet6/Function.cs new file mode 100644 index 00000000..0fdaa82f --- /dev/null +++ b/base/dump-dotnet6/Function.cs @@ -0,0 +1,78 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; + +using Amazon.Lambda.Core; +using Amazon.S3; + +[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))] + +namespace dump_dotnet6 +{ + public class Function + { + /// + /// Lambda function to dump the container directories /var/lang + /// and /var/runtime and upload the resulting archive to S3 + /// + /// + public async Task FunctionHandler(object invokeEvent, ILambdaContext context) + { + string filename = "dotnet6.0.tgz"; + string cmd = $"tar -cpzf /tmp/{filename} --numeric-owner --ignore-failed-read /var/runtime /var/lang"; + + Console.WriteLine($"invokeEvent: {invokeEvent}"); + Console.WriteLine($"context.RemainingTime: {context.RemainingTime}"); + + Console.WriteLine("Parent cmdline:"); + Console.WriteLine(File.ReadAllText("/proc/1/cmdline").Replace("\0", " ")); + + Console.WriteLine("Parent env:"); + RunShell("xargs --null --max-args=1 < /proc/1/environ"); + + Console.WriteLine("This cmdline:"); + Console.WriteLine(File.ReadAllText($"/proc/{Process.GetCurrentProcess().Id}/cmdline").Replace("\0", " ")); + + Console.WriteLine("This env:"); + RunShell($"xargs --null --max-args=1 < /proc/{Process.GetCurrentProcess().Id}/environ"); + + Console.WriteLine($"Current working directory: {Directory.GetCurrentDirectory()}"); + + RunShell(cmd); + + Console.WriteLine("Zipping done! Uploading..."); + + var s3Client = new AmazonS3Client(); + var response = await s3Client.PutObjectAsync(new Amazon.S3.Model.PutObjectRequest + { + BucketName = "lambci", + Key = $"fs/{filename}", + FilePath = $"/tmp/{filename}", + CannedACL = S3CannedACL.PublicRead, + }); + + Console.WriteLine("Uploading done!"); + + return response.HttpStatusCode.ToString(); + } + + private static Process RunShell(string cmd) + { + var escapedArgs = cmd.Replace("\"", "\\\""); + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "/bin/sh", + Arguments = $"-c \"{escapedArgs}\"", + UseShellExecute = false, + CreateNoWindow = true, + } + }; + process.Start(); + process.WaitForExit(); + return process; + } + } +} diff --git a/base/dump-dotnet6/aws-lambda-tools-defaults.json b/base/dump-dotnet6/aws-lambda-tools-defaults.json new file mode 100644 index 00000000..031aa17c --- /dev/null +++ b/base/dump-dotnet6/aws-lambda-tools-defaults.json @@ -0,0 +1,8 @@ +{ + "configuration": "Release", + "framework": "net6.0", + "function-runtime": "dotnet6", + "function-memory-size": 3008, + "function-timeout": 60, + "function-handler": "dump_dotnet6::dump_dotnet6.Function::FunctionHandler" +} diff --git a/base/dump-dotnet6/dump-dotnet6.csproj b/base/dump-dotnet6/dump-dotnet6.csproj new file mode 100644 index 00000000..304e19ed --- /dev/null +++ b/base/dump-dotnet6/dump-dotnet6.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + dump_dotnet6 + true + dump_dotnet6 + + + + + + + + + + + + + diff --git a/base/runtimes.sh b/base/runtimes.sh index 80891dd4..5cbdd603 100644 --- a/base/runtimes.sh +++ b/base/runtimes.sh @@ -1 +1 @@ -RUNTIMES="provided go1.x nodejs4.3 nodejs6.10 nodejs8.10 python2.7 python3.6 python3.7 ruby2.5 java8 dotnetcore2.0 dotnetcore2.1 provided.al2 nodejs10.x nodejs12.x python3.8 ruby2.7 java8.al2 java11 dotnetcore3.1" +RUNTIMES="provided go1.x nodejs4.3 nodejs6.10 nodejs8.10 python2.7 python3.6 python3.7 ruby2.5 java8 dotnetcore2.0 dotnetcore2.1 provided.al2 nodejs10.x nodejs12.x python3.8 ruby2.7 java8.al2 java11 dotnetcore3.1 dotnet6.0" diff --git a/base/test-all.sh b/base/test-all.sh index c6a40c0e..7e814535 100755 --- a/base/test-all.sh +++ b/base/test-all.sh @@ -51,6 +51,10 @@ cd ${EXAMPLES_DIR}/dotnetcore3.1 docker run --rm -v "$PWD":/var/task lambci/lambda:build-dotnetcore3.1 dotnet publish -c Release -o pub docker run --rm -v "$PWD"/pub:/var/task lambci/lambda:dotnetcore3.1 test::test.Function::FunctionHandler '{"some": "event"}' +cd ${EXAMPLES_DIR}/dotnet6.0 +docker run --rm -v "$PWD":/var/task lambci/lambda:build-dotnet6.0 dotnet publish -c Release -o pub +docker run --rm -v "$PWD"/pub:/var/task lambci/lambda:dotnet6.0 test::test.Function::FunctionHandler '{"some": "event"}' + cd ${EXAMPLES_DIR}/go1.x docker run --rm -v "$PWD":/go/src/handler lambci/lambda:build-go1.x sh -c 'go mod download && go build handler.go' docker run --rm -v "$PWD":/var/task lambci/lambda:go1.x handler '{"Records": []}' diff --git a/dotnet6/build/Dockerfile b/dotnet6/build/Dockerfile new file mode 100644 index 00000000..71abf0b8 --- /dev/null +++ b/dotnet6/build/Dockerfile @@ -0,0 +1,32 @@ +FROM lambci/lambda:dotnet6 + +FROM lambci/lambda-base-2:build + +# Run: docker run --rm --entrypoint dotnet lambci/lambda:dotnet6 --info +# Check https://dotnet.microsoft.com/download/dotnet-core/6.0 for versions +ENV DOTNET_ROOT=/var/lang/bin +ENV PATH=/root/.dotnet/tools:$DOTNET_ROOT:$PATH \ + LD_LIBRARY_PATH=/var/lang/lib:$LD_LIBRARY_PATH \ + AWS_EXECUTION_ENV=AWS_Lambda_dotnet6 \ + DOTNET_SDK_VERSION=6.0.201 \ + DOTNET_CLI_TELEMETRY_OPTOUT=1 \ + NUGET_XMLDOC_MODE=skip + +COPY --from=0 /var/runtime /var/runtime +COPY --from=0 /var/lang /var/lang +COPY --from=0 /var/rapid /var/rapid + +RUN curl -L https://dot.net/v1/dotnet-install.sh | bash -s -- -v $DOTNET_SDK_VERSION -i $DOTNET_ROOT && \ + mkdir /tmp/warmup && \ + cd /tmp/warmup && \ + dotnet new && \ + cd / && \ + rm -rf /tmp/warmup /tmp/NuGetScratch /tmp/.dotnet + +# Add these as a separate layer as they get updated frequently +RUN pipx install awscli==1.* && \ + pipx install aws-lambda-builders==1.2.0 && \ + pipx install aws-sam-cli==1.15.0 && \ + dotnet tool install --global Amazon.Lambda.Tools --version 4.0.0 + +CMD ["dotnet", "build"] diff --git a/dotnet6/run/Dockerfile b/dotnet6/run/Dockerfile new file mode 100644 index 00000000..4f215729 --- /dev/null +++ b/dotnet6/run/Dockerfile @@ -0,0 +1,21 @@ +FROM lambci/lambda-base + +RUN curl https://lambci.s3.amazonaws.com/fs/dotnet6.tgz | tar -zx -C /opt + + +FROM lambci/lambda:provided + + +FROM lambci/lambda-base-2 + +ENV PATH=/var/lang/bin:$PATH \ + LD_LIBRARY_PATH=/var/lang/lib:$LD_LIBRARY_PATH \ + AWS_EXECUTION_ENV=AWS_Lambda_dotnet6 + +COPY --from=0 /opt/* /var/ + +COPY --from=1 /var/runtime/init /var/rapid/init + +USER sbx_user1051 + +ENTRYPOINT ["/var/rapid/init", "--bootstrap", "/var/runtime/bootstrap", "--enable-msg-logs"] diff --git a/examples/dotnet6.0/Function.cs b/examples/dotnet6.0/Function.cs new file mode 100644 index 00000000..4d3a1877 --- /dev/null +++ b/examples/dotnet6.0/Function.cs @@ -0,0 +1,30 @@ +// Compile with: +// docker run --rm -v "$PWD":/var/task lambci/lambda:build-dotnet6.0 dotnet publish -c Release -o pub + +// Run with: +// docker run --rm -v "$PWD"/pub:/var/task lambci/lambda:dotnet6.0 test::test.Function::FunctionHandler '{"some": "event"}' + +using System; +using System.Collections; +using Amazon.Lambda.Core; + +[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))] + +namespace test +{ + public class Function + { + public string FunctionHandler(object inputEvent, ILambdaContext context) + { + Console.WriteLine($"inputEvent: {inputEvent}"); + Console.WriteLine($"RemainingTime: {context.RemainingTime}"); + + foreach (DictionaryEntry kv in Environment.GetEnvironmentVariables()) + { + Console.WriteLine($"{kv.Key}={kv.Value}"); + } + + return "Hello World!"; + } + } +} diff --git a/examples/dotnet6.0/README.md b/examples/dotnet6.0/README.md new file mode 100644 index 00000000..b0137d07 --- /dev/null +++ b/examples/dotnet6.0/README.md @@ -0,0 +1,9 @@ +# .NET 6.0 docker-lambda example + +```sh +# Will place the compiled code in `./pub` +docker run --rm -v "$PWD":/var/task lambci/lambda:build-dotnet6.0 dotnet publish -c Release -o pub + +# Then you can run using that as the task directory +docker run --rm -v "$PWD"/pub:/var/task lambci/lambda:dotnet6.0 test::test.Function::FunctionHandler '{"some": "event"}' +``` diff --git a/examples/dotnet6.0/test.csproj b/examples/dotnet6.0/test.csproj new file mode 100644 index 00000000..8b4e14c1 --- /dev/null +++ b/examples/dotnet6.0/test.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + true + + + + + + + + diff --git a/examples/dotnet6.0/test.sln b/examples/dotnet6.0/test.sln new file mode 100644 index 00000000..2de30541 --- /dev/null +++ b/examples/dotnet6.0/test.sln @@ -0,0 +1,17 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test.csproj", "{0A83D120-2336-4F30-86F1-DC045C3C9B90}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0A83D120-2336-4F30-86F1-DC045C3C9B90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A83D120-2336-4F30-86F1-DC045C3C9B90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A83D120-2336-4F30-86F1-DC045C3C9B90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A83D120-2336-4F30-86F1-DC045C3C9B90}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal