volta
volta copied to clipboard
[M1] Architecture (ARM -> X64) fallback issue
Using the latest version of volta:
$ volta -v
1.0.5
With a package.json that specifies node 14.x (with custom npm registry in .npmrc)
$ cat package.json | jq '.volta'
{
"node": "14.17.5",
"yarn": "1.22.4",
"extends": "/usr/local/XXXX/etc/volta/volta.json"
}
On an m1 mac, in a non-rosetta context:
$ arch
arm64
Running node attempts to download the arm64 binary (from our internal
$ node
Volta error: Could not download [email protected]
from http://volta-artifactory.corp.linkedin.com/node/distro/darwin/arm64/14.17.5
As you can see, we have a private registry which could be the issue. When I attempt to run node without the private registry the x64 variant installs correctly:
$ node -e "console.log(process.arch)"
x64
$ node -v
v14.17.5
Our `.volta/hooks.json`:
cat /usr/local/linkedin/etc/volta/.volta/hooks.json
{
"node": {
"index": {
"template": "http://volta-artifactory.corp.linkedin.com/node/index/{{os}}/{{arch}}"
},
"latest": {
"template": "http://volta-artifactory.corp.linkedin.com/node/index/{{os}}/{{arch}}"
},
"distro": {
"template": "http://volta-artifactory.corp.linkedin.com/node/distro/{{os}}/{{arch}}/{{version}}"
}
},
"yarn": {
"index": {
"template": "http://volta-artifactory.corp.linkedin.com/yarn/index"
},
"latest": {
"template": "http://volta-artifactory.corp.linkedin.com/yarn/latest"
},
"distro": {
"template": "http://volta-artifactory.corp.linkedin.com/yarn/distro/{{version}}"
}
},
"npm": {
"index": {
"prefix": "http://dev-artifactory.corp.linkedin.com:8081/artifactory/api/npm/npm-external-new/"
},
"distro": {
"template": "http://dev-artifactory.corp.linkedin.com:8081/artifactory/api/npm/npm-external-new/npm/-/npm-{{version}}.tgz"
}
},
"events": {
"publish": {
"bin": "/usr/local/linkedin/etc/volta/rtf.py"
}
}
}
Thanks for reporting @stefanpenner! I think I see the issue: Our hooks resolution uses the architecture of the system irrespective of the version, while our non-hook lookup is smart enough to detect that for versions of Node < 16, there is no ARM version and automatically fallback.
We'll need to update the hooks resolution to take the architecture as a parameter, rather than relying on the constant, since the hooks are tool- and version-agnostic.
~~A workaround is to force the current shell into x86_64 via:~~
arch -x86_64 $SHELL
This doesn't seem to work, volta doesn't seem to inherit the shells architecture
@charlespierce thanks for responding so quickly! That sounds like it could be it!
@charlespierce is there a way that comes to mind, where I can force the architecture volta pulls?
Unfortunately, the constants are hard-coded at compile time, so I don't believe there's a way at the moment to force the hook resolution to change. Depending on how big of a blocker this is, I can see a couple of possible workarounds:
- Use the x86_64 Volta binary, even on M1. That will mean that all calls to Volta go through Rosetta, and won't be quite as fast, but IIRC from some early tests right after M1 came out, the difference wasn't huge. This would also mean you wouldn't ever get the M1 Node, however, even on version 16+.
- Update the internal proxy script (
volta-artifactory) to be aware of the version issue and automatically redirect all requests for ARM Node < 16 to the intel one. This approach is a bit of duplicating work, but it may be faster to update / deploy the internal script than it is to get Volta working correctly, released, imported, and rolled out.
- sounds like a reasonable short-term work-around: How do you recommend one install this binary most cleanly?
- sounds like something we can pursue if we run out of time
- fix volta - this sounds like the best approach, but it requires effort.
For (1), you can download the x86_64 binaries from the volta-{version}-macos.tar.gz file: https://github.com/volta-cli/volta/releases/download/v1.0.5/volta-1.0.5-macos.tar.gz
You should then be able to drop those binaries in as replacements for the ARM ones directly (either in ~/.volta/bin or where they are installed internally).
@charlespierce thanks, I can confirm that worked around the blocking issue, keeping folks on m1 macs using Rosetta 2.