rules_js icon indicating copy to clipboard operation
rules_js copied to clipboard

Issue with `readonly` package directory under node_modules

Open duarten opened this issue 2 years ago • 7 comments

I have a js_binary rule that I'm running outside of bazel, where a dependency copies a file from one place to another. However, the directory where the copy happens is readonly:

  errno: -13,
  syscall: 'copyfile',
  code: 'EACCES',
  path: '/private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modules/.aspect_rules_js/[email protected][email protected]/node_modules/aws-cdk-lib/core/lib/custom-resource-provider/nodejs-entrypoint.js',
  dest: '/private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modules/.aspect_rules_js/[email protected][email protected]/node_modules/aws-cdk-lib/aws-s3/lib/auto-delete-objects-handler/__entrypoint__.js'

Specifically, the bazel-out/darwin-fastbuild/bin/node_modules/.aspect_rules_js/[email protected][email protected]/node_modules/aws-cdk-lib directory is readonly:

╭────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────┬──────────╮
│ #  │                                                              name                                                              │  type   │ readonly │
├────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────┼──────────┤
│  0 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ dir     │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/@balena                                                 │         │          │
│  1 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ dir     │ true     │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/aws-cdk-lib                                             │         │          │
│  2 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/case                                                    │         │          │
│  3 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/constructs                                              │         │          │
│  4 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/fs-extra                                                │         │          │
│  5 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/ignore                                                  │         │          │
│  6 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/jsonschema                                              │         │          │
│  7 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/minimatch                                               │         │          │
│  8 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/punycode                                                │         │          │
│  9 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/semver                                                  │         │          │
│ 10 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/node_modul │ symlink │ false    │
│    │ es/.aspect_rules_js/[email protected][email protected]/node_modules/yaml                                                    │         │          │
╰────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────┴──────────╯

Interestingly, another package, @balena, is not readonly. Also, going to the main node_modules folder, we can see the directory isn't readonly:

❯ : ls -l /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/deploy/node_modules/ | select name type readonly | where name =~ aws-cdk-lib
╭───┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────┬──────────╮
│ # │                                                              name                                                               │  type   │ readonly │
├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────┼──────────┤
│ 0 │ /private/var/tmp/_bazel_duarte.nunes/f66c51e6a3394c97f40c1dcafe76e7fd/execroot/umani/bazel-out/darwin-fastbuild/bin/deploy/node │ symlink │ false    │
│   │ _modules/aws-cdk-lib                                                                                                            │         │          │
╰───┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────┴──────────╯

Is there any reason for the directory to be readonly under [email protected][email protected]?

duarten avatar Jul 10 '22 06:07 duarten

Bazel will generally write-protect files in the bazel-out tree so they can not be accidentally over-written. .aspect_rules_js/[email protected][email protected]/node_modules/aws-cdk-lib is a tree artifact output put there by Bazel which is why it ends up write protected.

.aspect_rules_js/[email protected][email protected]/node_modules/@balena OTOH is a directory that contains some symlink outputs (@balena is the scope name of some packages in this context). There should be one or more symlinks in that folder which are transitive deps of aws-cdk-lib. Under the main node_modules folder bazel-out/darwin-fastbuild/bin/deploy/node_modules/aws-cdk-lib is a symlink output file as well. It seems that Bazel doesn't make the symlinks it outputs write-protected.

gregmagolan avatar Jul 11 '22 19:07 gregmagolan

It would be unexpected for a js_binary to copy files into a tree artifact in the output tree. What is the use case?

gregmagolan avatar Jul 11 '22 19:07 gregmagolan

Deploying a stack with AWS CDK. This copy is made by the lib itself.

duarten avatar Jul 11 '22 20:07 duarten

I see. aws cdk is trying to modify itself when it is run. That is unfortunate and not very compatible with how bazel manages npm packages in rules_js. Could the copy be done in a postinstall instead?

gregmagolan avatar Jul 11 '22 20:07 gregmagolan

The copy is happening through a general mechanism and fixing this specific use-case would be a bit of a hack, but I guess doable.

Note I'm running the resulting js_library from bazel-bin manually, not by doing bazel run.

duarten avatar Jul 11 '22 20:07 duarten

Guess you mean resulting js_binary? Either way the bazel-out tree is going to be write protected by Bazel.

gregmagolan avatar Jul 11 '22 20:07 gregmagolan

If you wanted to be super hacky you could chmod the directory that you want to modify in the bazel-out tree before running the tool. By default Bazel will see changes to the output-tree and re-generate outputs if they change so the next time you run a bazel command that requires that package is will stomp over the changes; that behaviour can be turned off with a flag too. Turning that off can be useful if you're debugging and want to make change to an npm package in the process.

gregmagolan avatar Jul 11 '22 20:07 gregmagolan

For reference, the flag to disable Bazel checking the output tree for changes is --noexperimental_check_output_files.

gregmagolan avatar Feb 05 '23 00:02 gregmagolan

Leaving this open as a reminder to document how to make local changes to the npm packages for testing & debugging. Will close once those docs are added since it looks like the original question is answered.

gregmagolan avatar Feb 05 '23 00:02 gregmagolan