New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

docker-lambda

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

docker-lambda - npm Package Compare versions

Comparing version
0.13.4
to
0.15.0
+20
dotnetcore2.0/build/Dockerfile
FROM lambci/lambda-base:build
ENV PATH=/var/lang/bin:/usr/local/bin:/usr/bin/:/bin \
LD_LIBRARY_PATH=/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib \
AWS_EXECUTION_ENV=AWS_Lambda_dotnetcore2.0 \
DOTNET_SDK_VERSION=2.1.3 \
DOTNET_CLI_TELEMETRY_OPTOUT=1 \
NUGET_XMLDOC_MODE=skip
RUN rm -rf /var/runtime /var/lang && \
curl https://lambci.s3.amazonaws.com/fs/dotnetcore2.0.tgz | tar -zx -C / && \
yum install -y libunwind && \
curl https://dot.net/v1/dotnet-install.sh | bash -s -- -v $DOTNET_SDK_VERSION -i /var/lang/bin && \
mkdir /tmp/warmup && \
cd /tmp/warmup && \
dotnet new && \
cd / && \
rm -rf /tmp/warmup /tmp/NuGetScratch
CMD ["dotnet", "build"]
FROM microsoft/dotnet:2.0-sdk
WORKDIR /source
# cache restore result
COPY MockBootstraps/*.csproj .
RUN dotnet restore
# copy the rest of the code
COPY MockBootstraps/ .
RUN dotnet publish --output /app/ --configuration Release
FROM lambci/lambda-base
ENV PATH=/var/lang/bin:/usr/local/bin:/usr/bin/:/bin \
LD_LIBRARY_PATH=/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib \
AWS_EXECUTION_ENV=AWS_Lambda_dotnetcore2.0
RUN rm -rf /var/runtime /var/lang && \
curl https://lambci.s3.amazonaws.com/fs/dotnetcore2.0.tgz | tar -zx -C /
COPY --from=0 /app/MockBootstraps.* /var/runtime/
ENTRYPOINT ["/var/lang/bin/dotnet", "/var/runtime/MockBootstraps.dll"]

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<RootNamespace>MockLambdaRuntime</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Reference Include="Bootstrap">
<HintPath>lib\Bootstrap.dll</HintPath>
</Reference>
<Reference Include="Amazon.Lambda.Core">
<HintPath>lib\Amazon.Lambda.Core.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

Sorry, the diff of this file is not supported yet

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace MockLambdaRuntime
{
public class MockLambdaContext
{
static Random random = new Random();
/// Creates a mock context from a given Lambda handler and event
public MockLambdaContext(string handler, string eventBody)
{
RequestId = Guid.NewGuid().ToString();
StartTime = DateTime.Now;
InputStream = new MemoryStream();
OutputStream = new MemoryStream();
var eventData = Encoding.UTF8.GetBytes(eventBody);
InputStream.Write(eventData, 0, eventData.Length);
InputStream.Position = 0;
Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", FunctionName);
Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", FunctionVersion);
Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", MemorySize.ToString());
Environment.SetEnvironmentVariable("AWS_LAMBDA_LOG_GROUP_NAME", LogGroup);
Environment.SetEnvironmentVariable("AWS_LAMBDA_LOG_STREAM_NAME", LogStream);
Environment.SetEnvironmentVariable("AWS_REGION", Region);
Environment.SetEnvironmentVariable("AWS_DEFAULT_REGION", Region);
Environment.SetEnvironmentVariable("_HANDLER", handler);
}
/// Calculates the remaining time using current time and timeout
public TimeSpan RemainingTime()
{
return StartTime + TimeSpan.FromSeconds(Timeout) - DateTime.Now;
}
public long Duration => (long)(DateTime.Now - StartTime).TotalMilliseconds;
public long BilledDuration => (long)(Math.Ceiling((DateTime.Now - StartTime).TotalMilliseconds / 100)) * 100;
public long MemoryUsed => Process.GetCurrentProcess().WorkingSet64;
public Stream InputStream { get; }
public Stream OutputStream { get; }
public string OutputText
{
get
{
OutputStream.Position = 0;
using (TextReader reader = new StreamReader(OutputStream))
{
return reader.ReadToEnd();
}
}
}
public string RequestId { get; }
public DateTime StartTime { get; }
public int Timeout => Convert.ToInt32(EnvHelper.GetOrDefault("AWS_LAMBDA_FUNCTION_TIMEOUT", "300"));
public int MemorySize => Convert.ToInt32(EnvHelper.GetOrDefault("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "1536"));
public string FunctionName => EnvHelper.GetOrDefault("AWS_LAMBDA_FUNCTION_NAME", "test");
public string FunctionVersion => EnvHelper.GetOrDefault("AWS_LAMBDA_FUNCTION_VERSION", "$LATEST");
public string LogGroup => EnvHelper.GetOrDefault("AWS_LAMBDA_LOG_GROUP_NAME", $"/aws/lambda/{FunctionName}");
public string LogStream => EnvHelper.GetOrDefault("AWS_LAMBDA_LOG_STREAM_NAME", RandomLogStreamName);
public string Region => EnvHelper.GetOrDefault("AWS_REGION", EnvHelper.GetOrDefault("AWS_DEFAULT_REGION", "us-east-1"));
public string AccountId => EnvHelper.GetOrDefault("AWS_ACCOUNT_ID", "000000000000");
public string Arn => $"arn:aws:lambda:{Region}:{AccountId}:function:{FunctionName}";
string RandomLogStreamName => $"{DateTime.Now.ToString("yyyy/MM/dd")}/[{FunctionVersion}]{random.Next().ToString("x") + random.Next().ToString("x")}";
}
}

Sorry, the diff of this file is not supported yet

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">/Users/michael/github/docker-lambda/dotnetcore2.0/run/MockBootstraps/obj/project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/Users/michael/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/Users/michael/.nuget/packages/;/usr/local/share/dotnet/sdk/NuGetFallbackFolder</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">4.3.1</NuGetToolVersion>
</PropertyGroup>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.netcore.app/2.0.0/build/netcoreapp2.0/Microsoft.NETCore.App.props" Condition="Exists('$(NuGetPackageRoot)microsoft.netcore.app/2.0.0/build/netcoreapp2.0/Microsoft.NETCore.App.props')" />
</ImportGroup>
</Project>
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)netstandard.library/2.0.0/build/netstandard2.0/NETStandard.Library.targets" Condition="Exists('$(NuGetPackageRoot)netstandard.library/2.0.0/build/netstandard2.0/NETStandard.Library.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.netcore.app/2.0.0/build/netcoreapp2.0/Microsoft.NETCore.App.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.netcore.app/2.0.0/build/netcoreapp2.0/Microsoft.NETCore.App.targets')" />
</ImportGroup>
</Project>

Sorry, the diff of this file is too big to display

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using AWSLambda.Internal.Bootstrap;
using AWSLambda.Internal.Bootstrap.Context;
namespace MockLambdaRuntime
{
class Program
{
/// Task root of lambda task
static string lambdaTaskRoot = EnvHelper.GetOrDefault("LAMBDA_TASK_ROOT", "/var/task");
/// Program entry point
static void Main(string[] args)
{
AssemblyLoadContext.Default.Resolving += OnAssemblyResolving;
var handler = GetFunctionHandler(args);
var body = GetEventBody(args);
var lambdaContext = new MockLambdaContext(handler, body);
var userCodeLoader = new UserCodeLoader(handler, InternalLogger.NO_OP_LOGGER);
userCodeLoader.Init(Console.Error.WriteLine);
var lambdaContextInternal = new LambdaContextInternal(lambdaContext.RemainingTime,
LogAction, new Lazy<CognitoClientContextInternal>(),
lambdaContext.RequestId,
new Lazy<string>(lambdaContext.Arn),
new Lazy<string>(string.Empty),
new Lazy<string>(string.Empty),
Environment.GetEnvironmentVariables());
Exception lambdaException = null;
LogRequestStart(lambdaContext);
try
{
userCodeLoader.Invoke(lambdaContext.InputStream, lambdaContext.OutputStream, lambdaContextInternal);
}
catch (Exception ex)
{
lambdaException = ex;
}
LogRequestEnd(lambdaContext);
if (lambdaException == null)
{
Console.WriteLine(lambdaContext.OutputText);
}
else
{
Console.Error.WriteLine(lambdaException);
}
}
/// Called when an assembly could not be resolved
private static Assembly OnAssemblyResolving(AssemblyLoadContext context, AssemblyName assembly)
{
return context.LoadFromAssemblyPath(Path.Combine(lambdaTaskRoot, $"{assembly.Name}.dll"));
}
/// Try to log everything to stderr except the function result
private static void LogAction(string text)
{
Console.Error.WriteLine(text);
}
static void LogRequestStart(MockLambdaContext context)
{
Console.Error.WriteLine($"START RequestId: {context.RequestId} Version: {context.FunctionVersion}");
}
static void LogRequestEnd(MockLambdaContext context)
{
Console.Error.WriteLine($"END RequestId: {context.RequestId}");
Console.Error.WriteLine($"REPORT RequestId {context.RequestId}\t" +
$"Duration: {context.Duration} ms\t" +
$"Billed Duration: {context.BilledDuration} ms\t" +
$"Memory Size {context.MemorySize} MB\t" +
$"Max Memory Used: {context.MemoryUsed / (1024 * 1024)} MB");
}
/// Gets the function handler from arguments or environment
static string GetFunctionHandler(string[] args)
{
return args.Length > 0 ? args[0] : EnvHelper.GetOrDefault("AWS_LAMBDA_FUNCTION_HANDLER", string.Empty);
}
/// Gets the event body from arguments or environment
static string GetEventBody(string[] args)
{
return args.Length > 1 ? args[1] : (Environment.GetEnvironmentVariable("AWS_LAMBDA_EVENT_BODY") ??
(Environment.GetEnvironmentVariable("DOCKER_LAMBDA_USE_STDIN") != null ? Console.In.ReadToEnd() : "{}"));
}
}
class EnvHelper
{
/// Gets the given environment variable with a fallback if it doesn't exist
public static string GetOrDefault(string name, string fallback)
{
return Environment.GetEnvironmentVariable(name) ?? fallback;
}
}
}
#!/bin/sh
curl https://lambci.s3.amazonaws.com/fs/dotnetcore2.0.tgz | \
tar -xz var/runtime/Amazon.Lambda.Core.dll var/runtime/Bootstrap.dll
mv ./var/runtime/*.dll ./MockBootstraps/lib/
rm -rf ./var
FROM lambci/lambda-base:build
ENV GOLANG_VERSION=1.10 \
GOPATH=/go \
PATH=/go/bin:/usr/local/go/bin:$PATH
WORKDIR /go/src/handler
RUN rm -rf /var/runtime /var/lang && \
curl https://lambci.s3.amazonaws.com/fs/go1.x.tgz | tar -zx -C / && \
curl https://dl.google.com/go/go${GOLANG_VERSION}.linux-amd64.tar.gz | tar -zx -C /usr/local && \
go get github.com/golang/dep/cmd/dep && \
go install github.com/golang/dep/cmd/dep
CMD ["dep", "ensure"]
package main
import (
"bufio"
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/lambda/messages"
"io/ioutil"
"math"
"math/rand"
"net"
"net/rpc"
"os"
"os/exec"
"reflect"
"regexp"
"strconv"
"syscall"
"time"
)
func main() {
rand.Seed(time.Now().UTC().UnixNano())
var handler string
if len(os.Args) > 1 {
handler = os.Args[1]
} else {
handler = getEnv("AWS_LAMBDA_FUNCTION_HANDLER", getEnv("_HANDLER", "handler"))
}
var eventBody string
if len(os.Args) > 2 {
eventBody = os.Args[2]
} else {
eventBody = os.Getenv("AWS_LAMBDA_EVENT_BODY")
if eventBody == "" {
if os.Getenv("DOCKER_LAMBDA_USE_STDIN") != "" {
stdin, _ := ioutil.ReadAll(os.Stdin)
eventBody = string(stdin)
} else {
eventBody = "{}"
}
}
}
mockContext := &MockLambdaContext{
RequestId: fakeGuid(),
EventBody: eventBody,
FnName: getEnv("AWS_LAMBDA_FUNCTION_NAME", "test"),
Version: getEnv("AWS_LAMBDA_FUNCTION_VERSION", "$LATEST"),
MemSize: getEnv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "1536"),
Timeout: getEnv("AWS_LAMBDA_FUNCTION_TIMEOUT", "300"),
Region: getEnv("AWS_REGION", getEnv("AWS_DEFAULT_REGION", "us-east-1")),
AccountId: getEnv("AWS_ACCOUNT_ID", strconv.FormatInt(int64(rand.Int31()), 10)),
Start: time.Now(),
Pid: 1,
}
mockContext.ParseTimeout()
awsAccessKey := getEnv("AWS_ACCESS_KEY", getEnv("AWS_ACCESS_KEY_ID", "SOME_ACCESS_KEY_ID"))
awsSecretKey := getEnv("AWS_SECRET_KEY", getEnv("AWS_SECRET_ACCESS_KEY", "SOME_SECRET_ACCESS_KEY"))
awsSessionToken := getEnv("AWS_SESSION_TOKEN", os.Getenv("AWS_SECURITY_TOKEN"))
port := getEnv("_LAMBDA_SERVER_PORT", "54321")
os.Setenv("AWS_LAMBDA_FUNCTION_NAME", mockContext.FnName)
os.Setenv("AWS_LAMBDA_FUNCTION_VERSION", mockContext.Version)
os.Setenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", mockContext.MemSize)
os.Setenv("AWS_LAMBDA_LOG_GROUP_NAME", "/aws/lambda/"+mockContext.FnName)
os.Setenv("AWS_LAMBDA_LOG_STREAM_NAME", logStreamName(mockContext.Version))
os.Setenv("AWS_REGION", mockContext.Region)
os.Setenv("AWS_DEFAULT_REGION", mockContext.Region)
os.Setenv("_HANDLER", handler)
cmd := exec.Command("/var/task/" + handler)
cmd.Env = append(os.Environ(),
"_LAMBDA_SERVER_PORT="+port,
"AWS_ACCESS_KEY="+awsAccessKey,
"AWS_ACCESS_KEY_ID="+awsAccessKey,
"AWS_SECRET_KEY="+awsSecretKey,
"AWS_SECRET_ACCESS_KEY="+awsSecretKey,
)
if len(awsSessionToken) > 0 {
cmd.Env = append(cmd.Env,
"AWS_SESSION_TOKEN="+awsSessionToken,
"AWS_SECURITY_TOKEN="+awsSessionToken,
)
}
cmd.Stdout = os.Stderr
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
var err error
if err = cmd.Start(); err != nil {
defer abortRequest(mockContext, err)
return
}
mockContext.Pid = cmd.Process.Pid
defer syscall.Kill(-mockContext.Pid, syscall.SIGKILL)
var conn net.Conn
for {
conn, err = net.Dial("tcp", ":"+port)
if mockContext.HasExpired() {
defer abortRequest(mockContext, mockContext.TimeoutErr())
return
}
if err == nil {
break
}
if oerr, ok := err.(*net.OpError); ok {
// Connection refused, try again
if oerr.Op == "dial" && oerr.Net == "tcp" {
time.Sleep(5 * time.Millisecond)
continue
}
}
defer abortRequest(mockContext, err)
return
}
client := rpc.NewClient(conn)
for {
err = client.Call("Function.Ping", messages.PingRequest{}, &messages.PingResponse{})
if mockContext.HasExpired() {
defer abortRequest(mockContext, mockContext.TimeoutErr())
return
}
if err == nil {
break
}
time.Sleep(5 * time.Millisecond)
}
// XXX: The Go runtime seems to amortize the startup time, reset it here
mockContext.Start = time.Now()
logStartRequest(mockContext)
err = client.Call("Function.Invoke", mockContext.Request(), &mockContext.Reply)
// We want the process killed before this, so defer it
defer logEndRequest(mockContext, err)
}
func abortRequest(mockContext *MockLambdaContext, err error) {
logStartRequest(mockContext)
logEndRequest(mockContext, err)
}
func logStartRequest(mockContext *MockLambdaContext) {
systemLog("START RequestId: " + mockContext.RequestId + " Version: " + mockContext.Version)
}
func logEndRequest(mockContext *MockLambdaContext, err error) {
curMem, _ := calculateMemoryInMb(mockContext.Pid)
diffMs := math.Min(float64(time.Now().Sub(mockContext.Start).Nanoseconds()),
float64(mockContext.TimeoutDuration.Nanoseconds())) / 1e6
systemLog("END RequestId: " + mockContext.RequestId)
systemLog(fmt.Sprintf(
"REPORT RequestId: %s\t"+
"Duration: %.2f ms\t"+
"Billed Duration: %.f ms\t"+
"Memory Size: %s MB\t"+
"Max Memory Used: %d MB\t",
mockContext.RequestId, diffMs, math.Ceil(diffMs/100)*100, mockContext.MemSize, curMem))
if err == nil && mockContext.HasExpired() {
err = mockContext.TimeoutErr()
}
if err != nil {
responseErr := messages.InvokeResponse_Error{
Message: err.Error(),
Type: getErrorType(err),
}
if responseErr.Type == "errorString" {
responseErr.Type = ""
if responseErr.Message == "unexpected EOF" {
responseErr.Message = "RequestId: " + mockContext.RequestId + " Process exited before completing request"
}
}
systemErr(&responseErr)
os.Exit(1)
}
if mockContext.Reply.Error != nil {
systemErr(mockContext.Reply.Error)
os.Exit(1)
}
fmt.Println(string(mockContext.Reply.Payload))
}
func getEnv(key, fallback string) string {
value := os.Getenv(key)
if value != "" {
return value
}
return fallback
}
func fakeGuid() string {
randBuf := make([]byte, 16)
rand.Read(randBuf)
hexBuf := make([]byte, hex.EncodedLen(len(randBuf))+4)
hex.Encode(hexBuf[0:8], randBuf[0:4])
hexBuf[8] = '-'
hex.Encode(hexBuf[9:13], randBuf[4:6])
hexBuf[13] = '-'
hex.Encode(hexBuf[14:18], randBuf[6:8])
hexBuf[18] = '-'
hex.Encode(hexBuf[19:23], randBuf[8:10])
hexBuf[23] = '-'
hex.Encode(hexBuf[24:], randBuf[10:])
hexBuf[14] = '1' // Make it look like a v1 guid
return string(hexBuf)
}
func logStreamName(version string) string {
randBuf := make([]byte, 16)
rand.Read(randBuf)
hexBuf := make([]byte, hex.EncodedLen(len(randBuf)))
hex.Encode(hexBuf, randBuf)
return time.Now().Format("2006/01/02") + "/[" + version + "]" + string(hexBuf)
}
func arn(region string, accountId string, fnName string) string {
nonDigit := regexp.MustCompile(`[^\d]`)
return "arn:aws:lambda:" + region + ":" + nonDigit.ReplaceAllString(accountId, "") + ":function:" + fnName
}
// Thanks to https://stackoverflow.com/a/31881979
func calculateMemoryInMb(pid int) (uint64, error) {
f, err := os.Open(fmt.Sprintf("/proc/%d/smaps", pid))
if err != nil {
return 0, err
}
defer f.Close()
res := uint64(0)
pfx := []byte("Pss:")
r := bufio.NewScanner(f)
for r.Scan() {
line := r.Bytes()
if bytes.HasPrefix(line, pfx) {
var size uint64
_, err := fmt.Sscanf(string(line[4:]), "%d", &size)
if err != nil {
return 0, err
}
res += size
}
}
if err := r.Err(); err != nil {
return 0, err
}
return res / 1024, nil
}
func getErrorType(err interface{}) string {
if errorType := reflect.TypeOf(err); errorType.Kind() == reflect.Ptr {
return errorType.Elem().Name()
} else {
return errorType.Name()
}
}
func systemLog(msg string) {
fmt.Fprintln(os.Stderr, "\033[32m"+msg+"\033[0m")
}
// Try to match the output of the Lambda web console
func systemErr(err *messages.InvokeResponse_Error) {
jsonBytes, _ := json.MarshalIndent(LambdaError{
Message: err.Message,
Type: err.Type,
StackTrace: err.StackTrace,
}, "", " ")
fmt.Fprintln(os.Stderr, "\033[31m"+string(jsonBytes)+"\033[0m")
}
type LambdaError struct {
Message string `json:"errorMessage"`
Type string `json:"errorType,omitempty"`
StackTrace []*messages.InvokeResponse_Error_StackFrame `json:"stackTrace,omitempty"`
}
type MockLambdaContext struct {
RequestId string
EventBody string
FnName string
Version string
MemSize string
Timeout string
Region string
AccountId string
Start time.Time
TimeoutDuration time.Duration
Pid int
Reply *messages.InvokeResponse
}
func (mc *MockLambdaContext) ParseTimeout() {
timeoutDuration, err := time.ParseDuration(mc.Timeout + "s")
if err != nil {
panic(err)
}
mc.TimeoutDuration = timeoutDuration
}
func (mc *MockLambdaContext) Deadline() time.Time {
return mc.Start.Add(mc.TimeoutDuration)
}
func (mc *MockLambdaContext) HasExpired() bool {
return time.Now().After(mc.Deadline())
}
func (mc *MockLambdaContext) Request() *messages.InvokeRequest {
return &messages.InvokeRequest{
Payload: []byte(mc.EventBody),
RequestId: mc.RequestId,
XAmznTraceId: getEnv("_X_AMZN_TRACE_ID", ""),
InvokedFunctionArn: arn(mc.Region, mc.AccountId, mc.FnName),
Deadline: messages.InvokeRequest_Timestamp{
Seconds: mc.Deadline().Unix(),
Nanos: int64(mc.Deadline().Nanosecond()),
},
}
}
func (mc *MockLambdaContext) TimeoutErr() error {
return fmt.Errorf("%s %s Task timed out after %s.00 seconds", time.Now().Format("2006-01-02T15:04:05.999Z"),
mc.RequestId, mc.Timeout)
}
FROM golang:1
WORKDIR /go/src/github.com/lambci/docker-lambda
RUN curl -sSL -o /usr/local/bin/dep https://github.com/golang/dep/releases/download/v0.3.2/dep-linux-amd64 && chmod +x /usr/local/bin/dep
COPY aws-lambda-mock.go Gopkg.toml Gopkg.lock ./
RUN dep ensure
RUN GOARCH=amd64 GOOS=linux go build aws-lambda-mock.go
FROM lambci/lambda-base
RUN rm -rf /var/runtime /var/lang && \
curl https://lambci.s3.amazonaws.com/fs/go1.x.tgz | tar -zx -C /
COPY --from=0 /go/src/github.com/lambci/docker-lambda/aws-lambda-mock /var/runtime/aws-lambda-go
USER sbx_user1051
ENTRYPOINT ["/var/runtime/aws-lambda-go"]
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/aws/aws-lambda-go"
packages = ["lambda/messages"]
revision = "6e2e37798efbb1dfd8e9c6681702e683a6046517"
version = "v1.0.1"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "2c19b35c52e708394e6cc46c177e57a8379c3ab6e44aab67e2f9074218f861e9"
solver-name = "gps-cdcl"
solver-version = 1
[[constraint]]
name = "github.com/aws/aws-lambda-go"
version = "1.0.1"
FROM lambci/lambda-base:build
ENV AWS_EXECUTION_ENV=AWS_Lambda_java8
WORKDIR /
RUN rm -rf /var/runtime /var/lang && \
curl https://lambci.s3.amazonaws.com/fs/java8.tgz | tar -zx -C / && \
yum install -y java-1.8.0-openjdk-devel
FROM openjdk:8-alpine
WORKDIR /src
COPY ./lambda-runtime-mock /src
RUN apk add --no-cache curl && ./build.sh
FROM lambci/lambda-base
ENV AWS_EXECUTION_ENV=AWS_Lambda_java8
RUN rm -rf /var/runtime /var/lang && \
curl https://lambci.s3.amazonaws.com/fs/java8.tgz | tar -zx -C /
COPY --from=0 /src/LambdaSandboxJava-1.0.jar /var/runtime/lib/
WORKDIR /
USER sbx_user1051
ENTRYPOINT ["/usr/bin/java", "-XX:MaxHeapSize=1336935k", "-XX:MaxMetaspaceSize=157286k", "-XX:ReservedCodeCacheSize=78643k", \
"-XX:+UseSerialGC", "-Xshare:on", "-XX:-TieredCompilation", "-jar", "/var/runtime/lib/LambdaJavaRTEntry-1.0.jar"]

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

#!/bin/sh
cd $(dirname "$0")
mkdir -p ./target/classes
javac -target 1.8 -d ./target/classes ./src/main/java/lambdainternal/LambdaRuntime.java
curl -s https://lambci.s3.amazonaws.com/fs/java8.tgz | tar -zx -- var/runtime/lib/LambdaSandboxJava-1.0.jar
mv var/runtime/lib/LambdaSandboxJava-1.0.jar ./
cp -R ./target/classes/lambdainternal ./
jar uf LambdaSandboxJava-1.0.jar lambdainternal/LambdaRuntime*.class
rm -rf ./var ./lambdainternal
package lambdainternal;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.UUID;
import sun.misc.Unsafe;
public class LambdaRuntime {
private static Unsafe unsafe;
private static final String INVOKE_ID = UUID.randomUUID().toString();
private static final String AWS_ACCESS_KEY_ID;
private static final String AWS_SECRET_ACCESS_KEY;
private static final String AWS_SESSION_TOKEN;
private static final String AWS_REGION;
private static final String HANDLER;
private static final String EVENT_BODY;
private static final int TIMEOUT;
private static final String X_AMZN_TRACE_ID;
private static final String CLIENT_CONTEXT = null;
private static final String COGNITO_IDENTITY_ID = "";
private static final String COGNITO_IDENTITY_POOL_ID = "";
private static final String TRACE_ID = "";
private static final String PARENT_ID = "";
private static final String FUNCTION_ARN;
private static final String ACCOUNT_ID;
private static boolean alreadyInvoked = false;
private static long invokeStart;
public static final int MEMORY_LIMIT;
public static final String LOG_GROUP_NAME;
public static final String LOG_STREAM_NAME;
public static final String FUNCTION_NAME;
public static final String FUNCTION_VERSION;
public static volatile boolean needsDebugLogs;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
TIMEOUT = Integer.parseInt(getEnvOrDefault("AWS_LAMBDA_FUNCTION_TIMEOUT", "300"));
MEMORY_LIMIT = Integer.parseInt(getEnvOrDefault("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "1536"));
FUNCTION_NAME = getEnvOrDefault("AWS_LAMBDA_FUNCTION_NAME", "test");
FUNCTION_VERSION = getEnvOrDefault("AWS_LAMBDA_FUNCTION_VERSION", "$LATEST");
LOG_GROUP_NAME = getEnvOrDefault("AWS_LAMBDA_LOG_GROUP_NAME", "/aws/lambda/" + FUNCTION_NAME);
LOG_STREAM_NAME = getEnvOrDefault("AWS_LAMBDA_LOG_STREAM_NAME", randomLogStreamName(FUNCTION_VERSION));
AWS_ACCESS_KEY_ID = getEnvOrDefault("AWS_ACCESS_KEY_ID", "SOME_ACCESS_KEY_ID");
AWS_SECRET_ACCESS_KEY = getEnvOrDefault("AWS_SECRET_ACCESS_KEY", "SOME_SECRET_ACCESS_KEY");
AWS_SESSION_TOKEN = getEnv("AWS_SESSION_TOKEN");
AWS_REGION = getEnvOrDefault("AWS_REGION", getEnvOrDefault("AWS_DEFAULT_REGION", "us-east-1"));
ACCOUNT_ID = getEnvOrDefault("AWS_ACCOUNT_ID", "000000000000");
FUNCTION_ARN = "arn:aws:lambda:" + AWS_REGION + ":" + ACCOUNT_ID + ":function:" + FUNCTION_NAME;
X_AMZN_TRACE_ID = getEnvOrDefault("_X_AMZN_TRACE_ID", "");
String[] args = getCmdLineArgs();
HANDLER = args.length > 1 ? args[1] : getEnvOrDefault("AWS_LAMBDA_FUNCTION_HANDLER", getEnvOrDefault("_HANDLER", "index.Handler"));
EVENT_BODY = args.length > 2 ? args[2] : getEventBody();
LambdaRuntime.needsDebugLogs = false;
setenv("AWS_LAMBDA_FUNCTION_NAME", FUNCTION_NAME, 1);
setenv("AWS_LAMBDA_FUNCTION_VERSION", FUNCTION_VERSION, 1);
setenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", Integer.toString(MEMORY_LIMIT), 1);
setenv("AWS_LAMBDA_LOG_GROUP_NAME", LOG_GROUP_NAME, 1);
setenv("AWS_LAMBDA_LOG_STREAM_NAME", LOG_STREAM_NAME, 1);
setenv("AWS_REGION", AWS_REGION, 1);
setenv("AWS_DEFAULT_REGION", AWS_REGION, 1);
setenv("_HANDLER", HANDLER, 1);
}
private static String getEventBody() {
String eventBody = getEnv("AWS_LAMBDA_EVENT_BODY");
if (eventBody == null) {
eventBody = getEnv("DOCKER_LAMBDA_USE_STDIN") != null ?
new Scanner(System.in).useDelimiter("\\A").next() : "{}";
}
return eventBody;
}
private static String getEnvOrDefault(String key, String defaultVal) {
String envVal = getEnv(key);
return envVal != null ? envVal : defaultVal;
}
private static String randomLogStreamName(String functionVersion) {
byte[] randomBuf = new byte[16];
new Random().nextBytes(randomBuf);
return String.format("%s/[%s]%016x", new SimpleDateFormat("yyyy/MM/dd").format(new Date()), functionVersion,
new BigInteger(1, randomBuf));
}
private static void systemLog(String str) {
System.err.println("\033[32m" + str + "\033[0m");
}
private static void systemErr(String str) {
System.err.println("\033[31m" + str + "\033[0m");
}
public static String getEnv(final String envVariableName) {
return System.getenv(envVariableName);
}
public static void initRuntime() {
}
public static void reportRunning(final String p0) {
}
public static void reportDone(final String invokeid, final byte[] result, final int resultLength, final int p3) {
if (!alreadyInvoked) {
return;
}
double durationMs = (System.nanoTime() - invokeStart) / 1_000_000d;
long billedMs = Math.min(100 * ((long) Math.floor(durationMs / 100) + 1), TIMEOUT * 1000);
long maxMemory = Math.round((Runtime.getRuntime().totalMemory() -
Runtime.getRuntime().freeMemory()) / (1024 * 1024));
systemLog("END RequestId: " + invokeid);
systemLog(String.join("\t",
"REPORT RequestId: " + invokeid,
"Duration: " + String.format("%.2f", durationMs) + " ms",
"Billed Duration: " + billedMs + " ms",
"Memory Size: " + MEMORY_LIMIT + " MB",
"Max Memory Used: " + maxMemory + " MB",
""));
if (result != null) {
System.out.println("\n" + new String(result, 0, resultLength));
}
}
public static void reportException(final String p0) {
}
public static void reportUserInitStart() {
}
public static void reportUserInitEnd() {
}
public static void reportUserInvokeStart() {
}
public static void reportUserInvokeEnd() {
}
public static void reportFault(final String invokeid, final String msg, final String exceptionClass,
final String stack) {
systemErr(stack);
}
public static void setenv(final String key, final String val, final int p2) {
getMutableEnv().put(key, val);
}
public static void unsetenv(final String key) {
getMutableEnv().remove(key);
}
public static WaitForStartResult waitForStart() {
return new WaitForStartResult(INVOKE_ID, HANDLER, "event", AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
AWS_SESSION_TOKEN, false);
}
public static InvokeRequest waitForInvoke() {
if (alreadyInvoked) {
System.exit(0);
}
alreadyInvoked = true;
long address = 0;
byte[] eventBodyBytes = EVENT_BODY.getBytes(StandardCharsets.UTF_8);
try {
address = unsafe.allocateMemory(eventBodyBytes.length);
for (int i = 0; i < eventBodyBytes.length; i++) {
unsafe.putByte(address + i, eventBodyBytes[i]);
}
} catch (Exception e) {
// Not sure, could happen if memory is exhausted?
throw new RuntimeException(e);
}
invokeStart = System.nanoTime();
systemLog("START RequestId: " + INVOKE_ID + " Version: " + FUNCTION_VERSION);
return new InvokeRequest(-1, INVOKE_ID, X_AMZN_TRACE_ID, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
AWS_SESSION_TOKEN, CLIENT_CONTEXT, COGNITO_IDENTITY_ID, COGNITO_IDENTITY_POOL_ID, address,
eventBodyBytes.length, false, FUNCTION_ARN, TRACE_ID, false, PARENT_ID);
}
public static int getRemainingTime() {
return (int) ((TIMEOUT * 1000) - Math.round((System.nanoTime() - invokeStart) / 1_000_000d));
}
public static void sendContextLogs(final byte[] msg, final int length) {
System.err.print(new String(msg, 0, length, StandardCharsets.UTF_8));
}
public static synchronized void streamLogsToSlicer(final byte[] p0, final int p1, final int p2) {
}
private static String[] getCmdLineArgs() {
return System.getProperty("sun.java.command").split(" ", 3);
}
private static Map<String, String> getMutableEnv() {
Class[] classes = Collections.class.getDeclaredClasses();
Map<String, String> env = System.getenv();
for (Class cl : classes) {
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
try {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
return (Map<String, String>) obj;
} catch (Exception e) {
// Should never happen on Lambda
throw new RuntimeException(e);
}
}
}
// Should never happen on Lambda
throw new RuntimeException("Could not find java.util.Collections$UnmodifiableMap class");
}
public static class AWSCredentials {
public final String key;
public final String secret;
public final String session;
public AWSCredentials(final String key, final String secret, final String session) {
this.key = key;
this.secret = secret;
this.session = session;
}
}
public static class InvokeRequest {
public final int sockfd;
public final String invokeid;
public final String xAmznTraceId;
public final AWSCredentials credentials;
public final String clientContext;
public final String cognitoIdentityId;
public final String cognitoPoolId;
public final long eventBodyAddr;
public final int eventBodyLen;
public final boolean needsDebugLogs;
public final String invokedFunctionArn;
public final String traceId;
public final boolean isSampled;
public final String parentId;
public InvokeRequest(final int sockfd, final String invokeid, final String xAmznTraceId, final String awskey,
final String awssecret, final String awssession, final String clientcontext,
final String cognitoidentityid, final String cognitopoolid, final long addr, final int len,
final boolean needsDebugLogs, final String invokedFunctionArn, final String traceId,
final boolean isSampled, final String parentId) {
this.sockfd = sockfd;
this.invokeid = invokeid;
this.xAmznTraceId = xAmznTraceId;
this.eventBodyAddr = addr;
this.eventBodyLen = len;
this.clientContext = clientcontext;
this.cognitoIdentityId = cognitoidentityid;
this.cognitoPoolId = cognitopoolid;
this.traceId = traceId;
this.isSampled = isSampled;
this.parentId = parentId;
this.credentials = new AWSCredentials(awskey, awssecret, awssession);
this.needsDebugLogs = needsDebugLogs;
this.invokedFunctionArn = invokedFunctionArn;
}
}
public static class WaitForStartResult {
public final String invokeid;
public final String handler;
public final String mode;
public final AWSCredentials credentials;
public final boolean suppressInit;
public WaitForStartResult(final String invokeid, final String handler, final String mode, final String awskey,
final String awssecret, final String awssession, final boolean suppressInit) {
this.invokeid = invokeid;
this.handler = handler;
this.mode = mode;
this.credentials = new AWSCredentials(awskey, awssecret, awssession);
this.suppressInit = suppressInit;
}
}
}
# Java 8 Build Instructions
As the Java 8 Lambda libraries are statically compiled into jars, it's not
possible to just swap in a mock interface source file, as it is in the other
dynamic runtimes, without compiling first.
The `Dockerfile` here will build using a patched `LambdaSandboxJava-1.0.jar`,
which is checked into git. This jar was built using the jar from the Lambda runtime,
`/var/runtime/lib/LambdaSandboxJava-1.0.jar`, with a single class
(`lambdainternal/LambdaRuntime.class`) updated to use local/mock methods
instead of native ones.
The build script to perform this patch/update is at
[./lambda-runtime-mock/build.sh](./lambda-runtime-mock/build.sh)
+1
-0

@@ -16,2 +16,3 @@ var spawnSync = require('child_process').spawnSync

'AWS_LAMBDA_EVENT_BODY',
'DOCKER_LAMBDA_USE_STDIN',
]

@@ -18,0 +19,0 @@ var ENV_ARGS = [].concat.apply([], ENV_VARS.map(function(x) { return ['-e', x] }))

+1
-1
{
"name": "docker-lambda",
"version": "0.13.4",
"version": "0.15.0",
"description": "A Docker image and test runner that (very closely) mimics the live AWS Lambda environment",

@@ -5,0 +5,0 @@ "main": "index.js",

+61
-29

@@ -18,3 +18,3 @@ docker-lambda

This project consists of a set of Docker images for each of the supported Lambda runtimes
(Node.js 0.10, 4.3 and 6.10, Python 2.7 and 3.6, and Java 8\*).
(Node.js 0.10, 4.3 and 6.10, Python 2.7 and 3.6, Java 8, .NET Core 2.0, and Go 1.x).

@@ -26,5 +26,2 @@ There are also a set of build images that include packages like gcc-c++, git,

\* NB: The Java 8 test runner is not yet complete, but the
language is installed in the images so can be manually tested
Prerequisites

@@ -43,20 +40,43 @@ -------------

# Test an index.handler function from the current directory on Node.js v4.3
docker run -v "$PWD":/var/task lambci/lambda
docker run --rm -v "$PWD":/var/task lambci/lambda
# If using a function other than index.handler, with a custom event
docker run -v "$PWD":/var/task lambci/lambda index.myHandler '{"some": "event"}'
docker run --rm -v "$PWD":/var/task lambci/lambda index.myHandler '{"some": "event"}'
# Use the original Node.js v0.10 runtime
docker run -v "$PWD":/var/task lambci/lambda:nodejs
docker run --rm -v "$PWD":/var/task lambci/lambda:nodejs
# Use the Node.js v6.10 runtime
docker run -v "$PWD":/var/task lambci/lambda:nodejs6.10
docker run --rm -v "$PWD":/var/task lambci/lambda:nodejs6.10
# Test a lambda_function.lambda_handler function from the current directory on Python2.7
docker run -v "$PWD":/var/task lambci/lambda:python2.7
# Test a default function (lambda_function.lambda_handler) from the current directory on Python 2.7
docker run --rm -v "$PWD":/var/task lambci/lambda:python2.7
# Test on Python 3.6 with a custom file named my_module.py containing a my_handler function
docker run --rm -v "$PWD":/var/task lambci/lambda:python3.6 my_module.my_handler
# Test on Go 1.x with a compiled handler named my_handler and a custom event
docker run --rm -v "$PWD":/var/task lambci/lambda:go1.x my_handler '{"some": "event"}'
# Test a function from the current directory on Java 8
# The directory must be laid out in the same way the Lambda zip file is,
# with top-level package source directories and a `lib` directory for third-party jars
# http://docs.aws.amazon.com/lambda/latest/dg/create-deployment-pkg-zip-java.html
# The default handler is "index.Handler", but you'll likely have your own package and class
docker run --rm -v "$PWD":/var/task lambci/lambda:java8 org.myorg.MyHandler
# Test on .NET Core 2.0 given a test.dll assembly in the current directory,
# a class named Function with a FunctionHandler method, and a custom event
docker run --rm -v "$PWD":/var/task lambci/lambda:dotnetcore2.0 test::test.Function::FunctionHandler '{"some": "event"}'
# Run custom commands on the default container
docker run --entrypoint node lambci/lambda -v
docker run --rm --entrypoint node lambci/lambda -v
# For large events you can pipe them into stdin if you set DOCKER_LAMBDA_USE_STDIN (on any runtime)
echo '{"some": "event"}' | docker run --rm -v "$PWD":/var/task -i -e DOCKER_LAMBDA_USE_STDIN=1 lambci/lambda
```
You can see more examples of how to build docker images and run different
runtimes in the [examples](./examples) directory.
To use the build images, for compilation, deployment, etc:

@@ -66,12 +86,19 @@

# To compile native deps in node_modules (runs `npm rebuild`)
docker run -v "$PWD":/var/task lambci/lambda:build
docker run --rm -v "$PWD":/var/task lambci/lambda:build
# To use a different runtime from the default Node.js v4.3
docker run -v "$PWD":/var/task lambci/lambda:build-nodejs6.10
docker run --rm -v "$PWD":/var/task lambci/lambda:build-nodejs6.10
# Run custom commands on the build container
docker run lambci/lambda:build java -version
# To resolve dependencies on go1.x (working directory is /go/src/handler, will run `dep ensure`)
docker run --rm -v "$PWD":/go/src/handler lambci/lambda:build-go1.x
# To run an interactive session on the build container
docker run -it lambci/lambda:build bash
# For .NET Core 2.0, this will publish the compiled code to `./pub`,
# which you can then use to run with `-v "$PWD"/pub:/var/task`
docker run --rm -v "$PWD":/var/task lambci/lambda:build-dotnetcore2.0 dotnet publish -c Release -o pub
# Run custom commands on a build container
docker run --rm lambci/lambda:build aws --version
# To run an interactive session on a build container
docker run -it lambci/lambda:build-python3.6 bash
```

@@ -101,3 +128,3 @@

ADD . .
COPY . .

@@ -110,3 +137,3 @@ RUN npm install

# docker build -t mylambda .
# docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY mylambda
# docker run --rm -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY mylambda
```

@@ -131,10 +158,10 @@

By tarring the full filesystem in Lambda, uploading that to S3, and then
piping into Docker to create a new image from scratch – then creating
mock modules that will be required/included in place of the actual native
modules that communicate with the real Lambda coordinating services. Only the
native modules are mocked out – the actual parent JS/PY runner files are left
alone, so their behaviors don't need to be replicated (like the
overriding of `console.log`, and custom defined properties like
`callbackWaitsForEmptyEventLoop`)
By [tarring the full filesystem in Lambda, uploading that to S3](./base/dump-nodejs43.js),
and then [piping into Docker to create a new image from scratch](./base/create-base.sh) –
then [creating mock modules](./nodejs4.3/run/awslambda-mock.js) that will be
required/included in place of the actual native modules that communicate with
the real Lambda coordinating services. Only the native modules are mocked
out – the actual parent JS/PY/Java runner files are left alone, so their behaviors
don't need to be replicated (like the overriding of `console.log`, and custom
defined properties like `callbackWaitsForEmptyEventLoop`)

@@ -162,4 +189,2 @@ * *What's missing from the images?*

TODO
Docker tags (follow the Lambda runtime names):

@@ -171,2 +196,5 @@ - `latest` / `nodejs4.3`

- `python3.6`
- `java8`
- `go1.x`
- `dotnetcore2.0`
- `build` / `build-nodejs4.3`

@@ -177,2 +205,5 @@ - `build-nodejs`

- `build-python3.6`
- `build-java8`
- `build-go1.x`
- `build-dotnetcore2.0`

@@ -192,2 +223,3 @@ Env vars:

- `AWS_SESSION_TOKEN`
- `DOCKER_LAMBDA_USE_STDIN`

@@ -194,0 +226,0 @@ Options to pass to `dockerLambda()`:

@@ -84,2 +84,7 @@ var should = require('should')

// Should not fail if stdout contains extra newlines
resetMock({status: 0, stdout: 'Test\nResult\n\n{"success":true}\n\n'})
result = dockerLambda()
result.should.eql({success: true})
// Should return undefined if last stdout entry cannot be parsed

@@ -86,0 +91,0 @@ resetMock({status: 0, stdout: 'Test\nResult\nsuccess'})

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet