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

[rush] Improve rush deploy error message for symlinks outside of the source path #3774

Closed
maxdeviant opened this issue Nov 21, 2022 · 6 comments · Fixed by #4064
Closed

[rush] Improve rush deploy error message for symlinks outside of the source path #3774

maxdeviant opened this issue Nov 21, 2022 · 6 comments · Fixed by #4064

Comments

@maxdeviant
Copy link

maxdeviant commented Nov 21, 2022

Summary

This is a feature request for improving the error message that is emitted when rush deploy encounters a symlink outside of the source path.

After upgrading from Node 14.x to Node 16.x we started seeing the following error when running rush deploy:

ERROR: Source path is not under /tmp/build_202c776f
/usr/bin/python3

We were able to troubleshoot the issue, but it involved manually patching the installed DeployManager.js file to get the information needed to the debug the problem.

Details

Running rush --debug deploy yielded the following stack trace:

ERROR: Source path is not under /tmp/build_202c776f
/usr/bin/python3
Error: Source path is not under /tmp/build_202c776f
/usr/bin/python3
    at DeployManager._remapPathForDeployMetadata (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@microsoft/rush-lib/lib/logic/deploy/DeployManager.js:226:19)
    at DeployManager._writeDeployMetadata (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@microsoft/rush-lib/lib/logic/deploy/DeployManager.js:416:34)
    at DeployManager._prepareDeploymentAsync (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@microsoft/rush-lib/lib/logic/deploy/DeployManager.js:465:14)
    at DeployManager.deployAsync (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@microsoft/rush-lib/lib/logic/deploy/DeployManager.js:563:20)
    at DeployAction.runAsync (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@microsoft/rush-lib/lib/cli/actions/DeployAction.js:66:29)
    at DeployAction.onExecute (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@microsoft/rush-lib/lib/cli/actions/BaseRushAction.js:75:21)
    at DeployAction.onExecute (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@microsoft/rush-lib/lib/cli/actions/BaseRushAction.js:116:22)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async RushCommandLineParser.onExecute (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@rushstack/ts-command-line/lib/providers/CommandLineParser.js:211:13)
    at async RushCommandLineParser._wrapOnExecuteAsync (/tmp/build_202c776f/common/temp/install-run/@[email protected]/node_modules/@microsoft/rush-lib/lib/cli/RushCommandLineParser.js:199:9)

In order to track down the dependency causing the error we had to manipulate the installed DeployManager.js file to add additional logging, which eventually led us to the issue being this symlink:

/tmp/build_202c776f/common/temp/node_modules/.pnpm/[email protected]/node_modules/unix-dgram/build/node_gyp_bins/python3 to /usr/bin/python3

This was done by logging the absoluteLinkInfo.linkPath and absoluteLinkInfo.targetPath located here:

const relativeInfo: ILinkInfo = {
kind: absoluteLinkInfo.kind,
linkPath: this._remapPathForDeployMetadata(absoluteLinkInfo.linkPath, deployState),
targetPath: this._remapPathForDeployMetadata(absoluteLinkInfo.targetPath, deployState)
};

It would be nice if there was some additional logging built-in that would allow for debugging issues like this without having to resort to tampering with the installed JavaScript files.

Standard questions

Please answer these questions to help us investigate your issue more quickly:

Question Answer
@microsoft/rush globally installed version? 5.81.0
rushVersion from rush.json? 5.80.0
useWorkspaces from rush.json? not present
Operating system? Linux
Would you consider contributing a PR? Yes
Node.js version (node -v)? 16.18.1
@maxdeviant
Copy link
Author

For context, it seems that the root issue we were running into was the same one described here: nodejs/node-gyp#2713

@mgabeler-lee-6rs
Copy link

Any advice on how to fix this besides adding a step to find and delete these python3 symlinks before doing the deploy? Since rush treats stderr output as a failure, this is causing CI to fail for me in a few repos.

@PookMook
Copy link

PookMook commented Feb 11, 2023

Hey @mgabeler-lee-6rs , we had the same problem and until node-gyp fixes the issue on their end, we just run
find . -type l | grep python3 | xargs rm right before the deploy call while in the root folder. You can probably be more intentional with your grep if you happen to use python3 for other things but it seems to just work fine for us (just tracking a segfault in our stack)!

@nipunn1313
Copy link
Contributor

I took a stab at this with #4069

@microsoftly
Copy link

For anyone that's dealing with this, I recently ran into this issue (on rush 5.100.1) when trying to work with newrelic. I got around this by removing the symlink and copying python3.9 to the path where the symlink was.

rm /usr/src/app/common/temp/node_modules/.pnpm/@[email protected]/node_modules/@newrelic/native-metrics/build/node_gyp_bins/python3
cp /usr/bin/python3.9 /usr/src/app/common/temp/node_modules/.pnpm/@[email protected]/node_modules/@newrelic/native-metrics/build/node_gyp_bins/python3

and it worked like a charm. It makes your build more fragile to dependency changes ... but let's face it, node_gyp is the source of that fragility. This hack is just a bandaid around it.

@microsoftly
Copy link

I ran into this issue again when additional deps in my dependency graph pulled in a symlink for python3. To address this, I made the following script that you're free to use. It replaces all symlinked python3 references recursively within a directory

const fs = require('fs').promises;
const path = require('path');

// Function to recursively traverse the directory
async function replacePython3(directory) {
  const entries = await fs.readdir(directory, { withFileTypes: true });

  for (let entry of entries) {
    const fullPath = path.join(directory, entry.name);

    if (entry.isDirectory()) {
      // If the entry is a directory, recurse into it
      await replacePython3(fullPath);
    } else if ((entry.isFile() || entry.isSymbolicLink()) && entry.name === 'python3') {
      // If the entry is a file or symlink named 'python3', replace it
      try {
        await fs.unlink(fullPath); // Remove the file or symlink
        await fs.copyFile('/usr/bin/python3', fullPath); // Copy /usr/bin/python3 to the location
        console.log(`Replaced python3 at: ${fullPath}`);
      } catch (error) {
        console.error(`Failed to replace python3 at: ${fullPath}`, error);
      }
    }
  }
}

// Replace '/path/to/directory' with the actual path you want to search
replacePython3(__dirname + '/common/temp')
  .then(() => {
    console.log('Replacement process completed.');
  })
  .catch((error) => {
    console.error('An error occurred:', error);
  });

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