aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.51k stars 1.17k forks source link

Debugging go functions works with VS Code but not Goland #886

Closed TheUncharted closed 5 years ago

TheUncharted commented 5 years ago

Description

I can debug go functions with VS Code but not with Goland. Is it related to api-version ?

Steps to reproduce

Observed result

It works on VS Code but I had to change the api-version to 1 in VS Code Settings (Default 2 : got a warning from VS Code). If not the function run but does not stop at breakpoint.

{
    "go.delveConfig": {
        "apiVersion":1
    }
}

Inside container ps : /tmp/lambci_debug_files/dlv --listen=:5986 --headless=true --api-version=1 --log exec /var/task/bin/hello

Console output

2018-12-26 11:24:41 Invoking bin/hello (go1.x)
2018-12-26 11:24:41 No environment variables found for function 'Hello'
2018-12-26 11:24:41 Environment variables overrides data is standard format
2018-12-26 11:24:41 Loading AWS credentials from session with profile 'default'
2018-12-26 11:24:41 Resolving code path. Cwd=/d/go/src/myserverless, CodeUri=.
2018-12-26 11:24:41 Resolved absolute path to code is /d/go/src/myserverless
2018-12-26 11:24:41 Code /d/go/src/myserverless is not a zip/jar file
2018-12-26 11:24:41 Skipping building an image since no layers were defined
2018-12-26 11:24:41 Trying paths: ['/home/myuser/.docker/config.json', '/home/myuser/.dockercfg']
2018-12-26 11:24:41 No config file found
2018-12-26 11:24:41 Trying paths: ['/home/myuser/.docker/config.json', '/home/myuser/.dockercfg']
2018-12-26 11:24:41 No config file found
2018-12-26 11:24:41 http://127.0.0.1:2375 "GET /v1.35/images/lambci/lambda:go1.x/json HTTP/1.1" 200 None
2018-12-26 11:24:41 Looking for auth config
2018-12-26 11:24:41 No auth config in memory - loading from filesystem
2018-12-26 11:24:41 Trying paths: ['/home/myuser/.docker/config.json', '/home/myuser/.dockercfg']
2018-12-26 11:24:41 No config file found
2018-12-26 11:24:41 Looking for auth entry for 'docker.io'
2018-12-26 11:24:41 No entry found
2018-12-26 11:24:41 No auth config found
2018-12-26 11:24:42 http://127.0.0.1:2375 "POST /v1.35/images/create?tag=go1.x&fromImage=lambci%2Flambda HTTP/1.1" 200 None

Fetching lambci/lambda:go1.x Docker container image......
2018-12-26 11:24:42 Mounting /d/go/src/myserverless as /var/task:ro inside runtime container
2018-12-26 11:24:42 Starting new HTTP connection (1): 127.0.0.1:2375
2018-12-26 11:24:42 http://127.0.0.1:2375 "POST /v1.35/containers/create HTTP/1.1" 201 90
2018-12-26 11:24:42 http://127.0.0.1:2375 "GET /v1.35/containers/5783a6cd6cfffcc66a25362980c4b7cc7fbd86c8b91458c0157f655293a3624f/json HTTP/1.1" 200 None
2018-12-26 11:24:42 http://127.0.0.1:2375 "GET /v1.35/containers/5783a6cd6cfffcc66a25362980c4b7cc7fbd86c8b91458c0157f655293a3624f/json HTTP/1.1" 200 None
2018-12-26 11:24:43 http://127.0.0.1:2375 "POST /v1.35/containers/5783a6cd6cfffcc66a25362980c4b7cc7fbd86c8b91458c0157f655293a3624f/start HTTP/1.1" 204 0
2018-12-26 11:24:43 Setting up SIGTERM interrupt handler
2018-12-26 11:24:43 http://127.0.0.1:2375 "GET /v1.35/containers/5783a6cd6cfffcc66a25362980c4b7cc7fbd86c8b91458c0157f655293a3624f/json HTTP/1.1" 200 None
2018-12-26 11:24:43 http://127.0.0.1:2375 "POST /containers/5783a6cd6cfffcc66a25362980c4b7cc7fbd86c8b91458c0157f655293a3624f/attach?stream=1&stdin=0&logs=1&stderr=1&stdout=1 HTTP/1.1" 101 0
Could not create config directory: mkdir /home/sbx_user1051: permission denied.API server listening at: [::]:5986
time="2018-12-26T10:24:43Z" level=info msg="launching process with args: [/var/task/bin/hello]" layer=debugger

Expected result

Expect to work on Goland as well If the reason is the api-version change it to 2 ? Or add an args ?

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS : Windows + WSL (Ubuntu 18.04)
  2. sam --version : SAM CLI, version 0.10.0
  3. IDE : latest VS Code an Goland
cfx commented 5 years ago

I get the same error with golang 1.11.4 linux/amd64 and sam 0.10.0:

~/go/src/picapp$ sam local start-api -d 5986 --debugger-path /home/cfx/go/bin/
2019-01-03 15:49:48 Found credentials in shared credentials file: ~/.aws/credentials
2019-01-03 15:49:48 Mounting ListPicsFunction at http://127.0.0.1:3000/list [GET]
2019-01-03 15:49:48 You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2019-01-03 15:49:48  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
2019-01-03 15:49:53 Invoking list-pics (go1.x)

Fetching lambci/lambda:go1.x Docker container image......
2019-01-03 15:49:55 Mounting /home/cfx/go/src/picapp/list-pics as /var/task:ro inside runtime container
Could not create config directory: mkdir /home/sbx_user1051: permission denied.API server listening at: [::]:5986
time="2019-01-03T14:49:56Z" level=info msg="launching process with args: [/var/task/list-pics]" layer=debugger
jayco commented 5 years ago

I am having the same problem as @cfx

$ go version
go version go1.11.4 darwin/amd64

$ sam --version
SAM CLI, version 0.10.0
$ GOARCH=amd64 go build -gcflags='-N -l' -o bin/hello hello/main.go
$ GOOS=linux GOARCH=amd64 go build -o bin/dlv github.com/derekparker/delve/cmd/dlv
$ sam local start-api --skip-pull-image --template ./sam-local-template.yml -d 5986 --debugger-path ./bin
2019-01-09 14:13:37 Found credentials in shared credentials file: ~/.aws/credentials
2019-01-09 14:13:37 Mounting Hello at http://127.0.0.1:3000/hello [GET]
2019-01-09 14:13:37 You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2019-01-09 14:13:37  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
2019-01-09 14:43:41 Invoking bin/hello (go1.x)
Fetching lambci/lambda:go1.x Docker container image......
2019-01-09 14:43:42 Mounting /private/var/folders/md/p9l0v2zd71537rfymrwplrcc0000gn/T/tmppb9Pa3 as /var/task:ro inside runtime container
Could not create config directory: user: Current not implemented on linux/amd64.API server listening at: [::]:5986
time="2019-01-09T04:13:43Z" level=info msg="launching process with args: [/var/task/bin/hello]" layer=debugger
jackmcguire1 commented 5 years ago

bump, maybe changing delve api-version to 2 may fix this issue.

sekulicd commented 5 years ago

I am facing same issue and it is related with api-version. Inside Docker container i can see two processes running:

  1. /var/runtime/aws-lambda-go -debug=true -delvePort=5986 -delvePath=/tmp/lambci_debug_files/dlv main
  2. /tmp/lambci_debug_files/dlv --listen=:5986 --headless=true --api-version=1 --log exec /var/task/main

And Goland is using api-version = 2. Can someone from support advise if we can pass api-version = 2 somehow?

jackmcguire1 commented 5 years ago

UPDATE 1: PR #170 has been merged, can someone please try the EXAMPLE command BELOW and see if they can get debugging working and comment back results, I am away this weekend so not in a position to test until Monday!

UPDATE 2: This issue has been fixed, pushed #1050 to officially document this solution.

HOW TO: Technically once #170 is merged, we can use Delve API version '2' by Passing Additional Runtime Debug Arguments to the SAM CLI by setting the environment variable 'DEBUGGER_ARGS' with ‘-delveAPI=2’

EXAMPLE: sam local start-api -d 5986 --debugger-path <delve folder path> --debug-args "-delveAPI=2". NOTE:- do not skip image build as, we want SAM to fetch the latest go docker image with the newly updated change!

it is vital now that #170 is merged, we create a PR for THIS repository to support for the ability to allow to pass a Delve API version via a pre-defined CLI param '--debuggerAPI'. For reference see This PR as a reference on how to add new GO debugging params with tests

Is anyone interested in collaborating with me to achieve this?

CC @sanathkr

jfuss commented 5 years ago

@jackmcguire1 There isn't a need to add an Option in SAM CLI for this, as you can pass it through the --debug-args. I haven't yet validate this works but looking at the code, there shouldn't be anything stopping it.

jackmcguire1 commented 5 years ago

@jfuss I’m of the opinion we still need a PR to add the default parameter, at the very least ... as I’m sure everyone will not want to have to declare the environment variable.

I.e add parameter here

jfuss commented 5 years ago

The container defaults to a value already. I don’t see the value in adding it, if the containter controls the default api version.

jackmcguire1 commented 5 years ago

The default value set by the container will be Devle API version 1 for backwards compatibility reasons, this whole issue here is regarding being able to apply API version 2, to which we could simply default ourselves within this repo...

But if not, then we should atleast document the additional parameter configuration in the appropriate places.

sekulicd commented 5 years ago

Hi,

I managed to connect to dlv debugger from Golang using bellow command: sam local start-api -d 5986 --debugger-path --debug-args "-delveAPI=2"

Tnx

jackmcguire1 commented 5 years ago

Great thanks for the update! @sekulid

TheUncharted commented 5 years ago

Great !

petrogko commented 5 years ago

Following this article aws-sam-setup

I was able to start the sam cli only to get a permission issue while attempting to curl at it. I have a template that defines functions, I was attempting a simple GET when all of a sudden - this... Fetching lambci/lambda:go1.x Docker container image......... 2019-03-18 21:45:46 Mounting /Users/x/go/src/x/x/invite-bp/bin as /var/task:ro inside runtime container Could not create config directory: mkdir /home/sbx_user1051: permission denied.API server listening at: [::]:5858 time="2019-03-19T01:45:47Z" level=info msg="launching process with args: [/var/task/invite]" layer=debugger could not launch process: fork/exec /var/task/invite: no such file or directory

sam version - SAM CLI, version 0.13.0 GoVersion - go version go1.12 darwin/amd64

Commands I run -

  1. GOARCH=amd64 go build -gcflags='-N -l' -o bin/main invite/main.go
  2. GOOS=linux GOARCH=amd64 go build -o bin/dlv ~/go/src/github.com/go-delve/delve/cmd/dlv
  3. sam local start-api -d 5858 --debugger-path ./bin --debug-args "-delveAPI=2"

But Im stuck, been attempting to find a solution for a while now. I think I'm totally blind but any support on this would be much appreciated.

jackmcguire1 commented 5 years ago

Hi @petrogdev, it appears this is more of an issue with SAM not being able to find your invite binary correctly.

  1. Please also build your invite/main.go file also using the Linux flag, like you’re with building the delve package!

  2. Can we see your template, perhaps you have not specificed codeURI properly? Or I think the problem is your handler is called invite in the template when it should be main

petrogko commented 5 years ago

@jackmcguire1 - This would be template. Using this based on some examples I've seen on the net.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  invite-bp

  Sample SAM Template for invite-bp

### More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 5

Resources:
  InviteGetFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: ./bin     
      Handler: dlv
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Events:
        CatchAll:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /invite
            Method: ANY
      Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
        Variables:
          PARAM1: VALUE

  InvitePostFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:      
      CodeUri: ./bin
      Handler: dlv
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Events:
        PutRequest:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /invite
            Method: POST
      Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
        Variables:
          PARAM1: VALUE

Outputs:
  ### ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  ### Find out more about other implicit resources you can reference within SAM
  ### https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  InviteAPI:
    Description: "API Gateway endpoint URL for Prod environment for First Function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/invite/"
  InviteGetFunction:
    Description: "Fetching Invite"
    Value: !GetAtt InviteGetFunction.Arn
  InviteGetFunctionIamRole:
    Description: "Implicit IAM Role created for Invite function"
    Value: !GetAtt InviteGetFunctionRole.Arn
  InvitePostFunction:
    Description: "Creating Invite"
    Value: !GetAtt InvitePostFunction.Arn
  InvitePostFunctionIamRole:
    Description: "Implicit IAM Role created for Invite function"
    Value: !GetAtt InvitePostFunctionRole.Arn

I will also rerun with linux and see if that fixes anything. Thanks for the tip.

jfuss commented 5 years ago

@petrogdev All of the Handler values are dlv. They should be the binary of each of your functions.

petrogko commented 5 years ago

@jfuss - Thank you for responding. So this may be crazy, but I'm attempting to have multiple functions / httpMethods point to a single lambda. I've seen the approach for every method being blown out into separate files but Im wondering if its possible to stick it into one. Have not seen any examples of this anywhere.

So for the purposes of this getting to work, I've switched back to a simple template for now following another tutorial. The following template is from that, also same issue occurs.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  hello-sam

  Sample SAM Template for hello-sam

### More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 5

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: hello-world
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Events:
        CatchAll:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: GET
      Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
        Variables:
          PARAM1: VALUE

Outputs:
  ### ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  ### Find out more about other implicit resources you can reference within SAM
  ### https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldAPI:
    Description: "API Gateway endpoint URL for Prod environment for First Function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "First Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn
jfuss commented 5 years ago

@petrogdev You can do that. What I was pointing out is your example above (the one with many lambda's) had all of the Handler fields as dlv. So you were saying that your function code binary is thedlv binary.

What OS are you on? Are the permissions of the binaries set correctly? Are you sharing the correct drive or folders to Docker? Are you able to invoke the function normally sam local invoke?

jackmcguire1 commented 5 years ago

@petrogdev

ok firstly, within your template you're providing the handlers Handler: hello-world, when it should be 'main' as you're running GOARCH=amd64 GOOS=linuxgo build -gcflags='-N -l' -o bin/main invite/main.go which produces a binary file main...

furthermore, this is no longer the place to discuss your issue, as the one at hand has been resolved.

petrogko commented 5 years ago

@jfuss - valid questions and Im glad that single lambda should be achievable.

  1. Mac OS - Mojave - 10.14.3
  2. by permissions, are you referring to the arn? or reads/writes to the binary? The binary and directory has 775 which was bumped from 755.
  3. I'm a little confused by this one; I don't believe I am manually specifying the drive/folders to docker. **Update on docker - I can inspect the lambda image running and it will provide a verbose output. I am able to see the mounts on there. the path seems accurate...
  4. Have not attempted this yet.
petrogko commented 5 years ago

@jackmcguire1 - Fair point, I can definitely create another issue for this. But to your point about hello-world point to main. I switched templates for the purpose of getting a sample to work instead of my original code. Sorry if I didn't make that clear.

For the context of pointing the right binaries in the template, I have followed examples and suggestions by you guys. Unfortunately the outcome is the same.

**Update - @jackmcguire1: I created a new issue for this. VSCode/GoLang/File Permission

jfuss commented 5 years ago

This was solved by Docker-Lambda supporting an option to configure which dlv-api version to use. You can now control this in sam cli by sam local start-api -d 5986 --debugger-path <delve folder path> --debug-args "-delveAPI=2".

Closing as the initial issue was solved.

jackmcguire1 commented 5 years ago

@jfuss As discussed I raised a new PR in the aws-docs REPO to publish official documentation about this, but it appears it has not been picked up, I would be happy if this functionality is atleast documented within this REPO at the earliest convenience as prior to the last PR, which did not get merged.

tweissin commented 5 years ago

I just tried this and I am seeing the behavior Could not create config directory even with the debug-args set as suggested here.