softprops / serverless-rust

⚡ 🦀 a serverless framework plugin for rustlang applications
https://www.npmjs.com/package/serverless-rust
MIT License
548 stars 82 forks source link

Cannot deploy selected functions #82

Open selmeci opened 4 years ago

selmeci commented 4 years ago

🐛 Bug description

Cannot deploy selected functions from sls configuration.

🤔 Expected Behavior

Deploying selected functions

👟 Steps to reproduce

slss --stage=stage --region=eu-west-1 deploy --config=some-config.yaml --function=echo

result into error:

Error: ENOENT: no such file or directory, open 'C:\Users\abc\IdeaProjects\sls-project\C:\Users\abc\IdeaProjects\sls-project\target\lambda\release\echo.zip'

There is duplicated file path.

🌍 Your environment

Operating System: win32 Node Version: 12.18.3 Framework Version: 1.78.1 Plugin Version: 3.7.0 SDK Version: 2.3.1 Components Version: 2.34.3

rust-plugin version: 0.3.8

rib commented 4 years ago

I hit this same issue and wrote up a bunch of details as I chased down what was going on over here: https://github.com/serverless/serverless/issues/6752

It looks like there are two ways to potentially fix this - though it might be best to apply a fix here and in serverless since the issue in serverless might cause other similar failures in any case where a user or plugin sets an absolute path for a package artifact.

In serverless-rust/index.js there is this code:

      //
      // The AWS "provided" lambda runtime requires executables to be named
      // "bootstrap" -- https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
      //
      // To avoid artifact naming conflicts when we potentially have more than one function
      // we leverage the ability to declare a package artifact directly
      // see https://serverless.com/framework/docs/providers/aws/guide/packaging/
      // for more information
      const artifactPath = path.join(
        this.srcPath,
        `target/lambda/${"dev" === profile ? "debug" : "release"}`,
        `${binary}.zip`
      );
      console.log("AP: " + artifactPath); // DEBUG
      func.package = func.package || {};
      func.package.artifact = artifactPath;

which I think would ideally set a relative artifactPath instead of an absolute path. The basic issue here is that serverless is later on assuming a relative artifact path and joins it to the service path.

Specifically in serverless, in lib/plugins/package/lib/packageService.js there is this code:

packageFunction(functionName) {
    const functionObject = this.serverless.service.getFunction(functionName);
    const funcPackageConfig = functionObject.package || {};

    // use the artifact in function config if provided
    if (funcPackageConfig.artifact) {
      const filePath = path.join(this.serverless.config.servicePath, funcPackageConfig.artifact);
      console.log("filePath: join(" + this.serverless.config.servicePath + "," + funcPackageConfig.artifact + ")" ); // DEBUG
      functionObject.package.artifact = filePath;
      return BbPromise.resolve(filePath);
    }

which joins the above absolute path with the servicePath leading to this issue.

I found that this modification fixed the issue for me:

    // use the artifact in function config if provided
    if (funcPackageConfig.artifact) {
      const filePath = path.isAbsolute(funcPackageConfig.artifact) ?
            funcPackageConfig.artifact :
            path.join(this.serverless.config.servicePath, funcPackageConfig.artifact);
      console.log("filePath: join(" + this.serverless.config.servicePath + "," + funcPackageConfig.artifact + ")" );
      functionObject.package.artifact = filePath;
      return BbPromise.resolve(filePath);
    }
rib commented 4 years ago

From the pov of the serverless framework it sounds like they see this as a serverless-rust plugin bug and it wasn't intended to be possible to set absolute artifact paths. (https://github.com/serverless/serverless/pull/8315#pullrequestreview-500281907)