Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go-runner implementation #1320

Merged
merged 1 commit into from
Jan 25, 2022
Merged

Conversation

icarus-sullivan
Copy link
Contributor

Description

Clumsily added Go support for offline lambdas.

Motivation and Context

Why is this change required
Adding a new supported runtime isn't a requirement.

What problem does is solve?
Allows someone to run go lambdas offline.

How Has This Been Tested?

Please describe in detail how you tested your changes.

  • yarn linked a local copy of my changes to test in a go serverless project.
  • Tested api-based lambdas ONLY
  • Added a go integration test

Include details of your testing environment, and the tests you ran to
macOS Catalina
vs. 10.15.4

@icarus-sullivan icarus-sullivan changed the title Initial go-runner implementation WIP: go-runner implementation Jan 14, 2022
Comment on lines 140 to 149
const sts = new AWS.STS()

const { Credentials } = await sts
.getSessionToken({
DurationSeconds: MIN_ALLOWED_SESSION_DURATION_S, // 900-inf
})
.promise()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uncertain about this, but credentials are not passed into go without setting them in env.

Comment on lines +103 to +90
const out = handlerCode.replace(
'"github.com/aws/aws-lambda-go/lambda"',
'lambda "github.com/icarus-sullivan/mock-lambda"',
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clone code and swap out lambda import, mock-lambda looks for the LAMBDA_EVENT and LAMBDA_CONTEXT and tries to process it.

)
}

const cp = spawnSync(`go`, ['run', cwdPath], {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pros vs Cons of calling the handler like this:

Pros:

  • Always gets the latest code, you can modify the handler and rerun it and voila newest changes
  • It is less invasive in respect to copying and pre-compiling code elsewhere to be called

Cons:

  • It is somewhat slow as it compiles before it is run

... I'm sure there are more, this is just some ideas

@medikoo medikoo marked this pull request as draft January 14, 2022 10:52
@medikoo medikoo changed the title WIP: go-runner implementation go-runner implementation Jan 14, 2022
@icarus-sullivan
Copy link
Contributor Author

@medikoo What do I need to get this peer reviewed? What metrics should I be shooting for?

Comment on lines +170 to +138
IS_LAMBDA_AUTHORIZER:
event.type === 'REQUEST' || event.type === 'TOKEN',
IS_LAMBDA_REQUEST_AUTHORIZER: event.type === 'REQUEST',
IS_LAMBDA_TOKEN_AUTHORIZER: event.type === 'TOKEN',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added initial support for custom authorizers

@icarus-sullivan icarus-sullivan marked this pull request as ready for review January 17, 2022 00:15
Copy link
Collaborator

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @icarus-sullivan, that looks great. There's just one file that I believe was committed in by mistake, please remove it and we should be good

yarn.lock Outdated
@@ -0,0 +1,9593 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not add this file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I removed the file in the PR. Glad to contribute :D

}

// Clean up after we created the temporary file
this.cleanup()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this in to aggressively cleanup tmp files, but as a side-effect it might wipe sts session info on each call. One could argue that it is a good thing to only retain session credentials to the lambda invocation, but it might slowdown subsequent requests when obtaining new sessions. As a security concern I think it should be left in imo, but I'm open to changing it.

)

try {
mkdirSync(this.#tmpPath, { recursive: true })
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use just async functions (and async/await syntax)

}

// Make sure we have the mock-lambda runner
sync('go', ['get', 'github.com/icarus-sullivan/mock-lambda@e065469'])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructors aren't created in an async manner, so using sync here only.

Copy link
Collaborator

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @icarus-sullivan !

Copy link
Collaborator

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@icarus-sullivan unfortunately CI crashes, there must be some issues, please check the errors

@icarus-sullivan
Copy link
Contributor Author

@medikoo Saw that, tried to reproduce yesterday in some test pipelines. Still debugging but might be slow, just giving a status update.

@icarus-sullivan
Copy link
Contributor Author

@medikoo Found the issue, it's related to the sts call in the pipeline. Going to try to use the aws config env variable and see if that helps. Again, might be a while - its been a busy week.

@icarus-sullivan
Copy link
Contributor Author

@medikoo Okay, think I resolved the issue. Whenever you are ready to run the tests.

Copy link
Collaborator

@medikoo medikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @icarus-sullivan !

@medikoo medikoo merged commit 6bb54fd into dherault:master Jan 25, 2022
@Francismb
Copy link

Great to see this. I noticed that this is rather incompatible with the way the serverless template generates its code. When the serverless template generates its code, the yaml file points to bin files/built go lang files. It would be worth having something in the readme IMO.

@uh-zz
Copy link
Contributor

uh-zz commented Feb 21, 2022

@icarus-sullivan
Hi!
Thank you for adding the go runtime.
I saw your implementation.

Just recently, I was looking for an alternative to --useDocker
#1334

So, I thought I'd try this one.
After looking at the source, I confirmed that it refers to main.go in the project root and executes the go run command, instead of the handler defined in serverless.yml (or serverless.ts).

If I can make it so that it executes the binary file specified in the handler of serverless.yaml (or serverless.ts), it will behave as I expect.

@icarus-sullivan
Copy link
Contributor Author

@uh-zz

The runner copies the path and code outlined in the handler and generates a main.go file. So it should be referencing the handler path correctly but generating a mock lambda runner on-the-fly. Let me know if that makes sense.

@uh-zz
Copy link
Contributor

uh-zz commented Mar 7, 2022

@icarus-sullivan

Thank you for confirming and sorry for the late reply.

The runner copies the path and code outlined in the handler and generates a main.go file.

I checked and the handler path seems to point to the project root(same directory as serverless.ts).
(I checked the this.#handlerPath used here with print debugging)

const handlerCode = await readFile(`${this.#handlerPath}.go`, 'utf8')

From this, I am assuming that the following configuration is expected.

./project
├── go.mod
├── go.sum
├── main.go
└── serverless.ts

However, in my project, I am developing the following configuration.

./project
├── a
│   └── b
│       └── c
│           ├── go.mod
│           ├── go.sum
│           └── main.go
├── bin
│   └── go-binary // go-binary is binary of a/b/c/main.go
└── serverless.ts

Therefore, I want to run the handler(in this case, bin/go-binary) configured in serverless.ts when started with serverless-offline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants