aws-cdk icon indicating copy to clipboard operation
aws-cdk copied to clipboard

(aws-lambda-python-alpha): Bundling breaks if cdk.out is in the entry path

Open alexjball opened this issue 1 year ago • 4 comments

Describe the bug

In a project using PythonFunction and the same directory for the lambda entrypoint and the cdk app root, when running cdk list, cdk fails to bundle the asset with RuntimeError: ENAMETOOLONG: name too long

Expected Behavior

cdk list lists the stack that uses the PythonFunction

Current Behavior

$ cdk list
jsii.errors.JavaScriptError: 
  Error: ENAMETOOLONG: name too long, copyfile '/home/me/project/cdk.out/asset.3e3d591ada9871847d85c2d73040bddd35f67408d096082f05a5b6d2e65f9ac6/cdk.out/asset.3e3d591ada9871847d85c2d73040bddd35f67408d096082f05a5b6d2e65f9ac6/cdk.out/asset.......
      at Object.copyFileSync (node:fs:2866:3)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1267)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1170)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1170)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1170)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1170)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1170)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1170)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1170)
      at copyDirectory (/tmp/jsii-kernel-c554A9/node_modules/aws-cdk-lib/core/lib/fs/copy.js:1:1170)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/me/project/app.py", line 11, in <module>
    CollectStack(
  File "/home/me/.cache/pypoetry/virtualenvs/project-py3.10/lib/python3.10/site-packages/jsii/_runtime.py", line 112, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/home/me/project/project/cdk/my_stack.py", line 28, in __init__
    self.handler = self.create_api_handler()
  File "/home/me/project/project/cdk/my_stack.py", line 31, in create_api_handler
    handler = python.PythonFunction(
  File "/home/me/.cache/pypoetry/virtualenvs/project-py3.10/lib/python3.10/site-packages/jsii/_runtime.py", line 112, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/home/me/.cache/pypoetry/virtualenvs/project-py3.10/lib/python3.10/site-packages/aws_cdk/aws_lambda_python_alpha/__init__.py", line 1004, in __init__
    jsii.create(self.__class__, self, [scope, id, props])
  File "/home/me/.cache/pypoetry/virtualenvs/project-py3.10/lib/python3.10/site-packages/jsii/_kernel/__init__.py", line 334, in create
    response = self.provider.create(
  File "/home/me/.cache/pypoetry/virtualenvs/project-py3.10/lib/python3.10/site-packages/jsii/_kernel/providers/process.py", line 363, in create
    return self._process.send(request, CreateResponse)
  File "/home/me/.cache/pypoetry/virtualenvs/project-py3.10/lib/python3.10/site-packages/jsii/_kernel/providers/process.py", line 340, in send
    raise RuntimeError(resp.error) from JavaScriptError(resp.stack)
RuntimeError: ENAMETOOLONG: name too long, copyfile .....

Subprocess exited with error 1

Reproduction Steps

from aws_cdk import CfnOutput, Stack
from aws_cdk import aws_lambda_python_alpha as python
from aws_cdk import aws_lambda as fn
from constructs import Construct


class MyStack(Stack):

    def __init__(
        self,
        scope: Construct,
        construct_id: str,
        **kwargs,
    ) -> None:
        super().__init__(scope, construct_id, **kwargs)

        self.handler = self.create_api_handler()

    def create_api_handler(self):
        handler = python.PythonFunction(
            self,
            "Function",
            entry=".",
            runtime=fn.Runtime.PYTHON_3_10,
            index="project/main.py",
            handler="handler",
            bundling=python.BundlingOptions(asset_excludes=["cdk.out"]),
        )

        return handler

Possible Solution

Add cdk.out to the exclude list used when bundling isn't required, or possibly copy the asset_excludes. The excludes list is ignored when bundling is required. This is consistent with other solutions to this error

Additional Information/Context

It is convenient to use one pyproject.toml for my whole application, including lambda handlers. So my repo looks like this:

  pyproject.toml
  poetry.lock
  app.py
  cdk.json
  my_project
    cdk
      my_stack.py
    handlers
      my_handlers.py

I need to set the entrypoint to the dir with the pyproject.toml, which causes cdk.out to get included in asset hashing during cdk list

CDK CLI Version

2.76.0 (build 78c411b)

Framework Version

No response

Node.js Version

v18.14.2

OS

Pop!_OS 22.04 LTS

Language

Python

Language Version

Python 3.10.7

Other information

No response

alexjball avatar May 04 '23 23:05 alexjball

Thank you for sharing your use case with pyproject.toml. I agree it would be great to exclude cdk.out in your case. I am not sure what is the best solution at this moment but I believe at this moment, you can run cdk deploy -o /alternative/path/to/cdk.out to redirect the cdk.out to an alternative path.

pahud avatar May 05 '23 12:05 pahud

Hi @pahud, I'm having the same issue even when trying with cdk deploy -o /alternative/path/to/cdk.out. I wonder if this issue is still in your radar to be fix. I'm using cdk 2.128.0. Thank you

pedro-patlan-monogram avatar Feb 15 '24 16:02 pedro-patlan-monogram

Have you found a workaround for this?

crbn60 avatar Feb 28 '24 01:02 crbn60

Currently facing this issue , any resolution?

EricaDos1 avatar May 09 '24 11:05 EricaDos1

Was facing this for half a day and here's what worked for us.

For the following code:

asset = aws_ecr_assets.DockerImageAsset(
            self,
            "docker-image",
            directory="../"
        )

For the following folder structure:

aws/
  - app.py
  - cdk.out/
src/
  - hello_world.py
Dockerfile
.dockerignore

Adding */cdk.out in .dockerignore fixed it for us.

harisibrahimkv avatar May 27 '24 10:05 harisibrahimkv