-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add a platform variant for installing a musl binary #1836
Conversation
if (fs.readFileSync(process.execPath).indexOf('libc.musl-x86_64.so.1') != -1) { | ||
return 'musl'; | ||
} | ||
return 'glibc'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably better to just return empty unless it's musl. Would simplify the code above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, fair.
if (process.platform !== 'linux') { | ||
return ''; | ||
} | ||
if (fs.readFileSync(process.execPath).indexOf('libc.musl-x86_64.so.1') !== -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fs.readFileSync
can throw
var contents = '';
try {
contents = fs.readFileSync('foo.bar');
if (contents.indexOf('libc.musl-x86_64.so.1') !== -1) {
return 'musl';
}
} catch (err) { }
return ''
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess node 0.x readFileSync return Buffer and its Buffer don't have .indexOf, and ci is failing on those. You might need to do like
EDIT: OUTDATED
fs.readFileSync(process.execPath).toString().indexOf('libc.musl-x86_64.so.1') > 0
also why I used > 0 instead of !== -1 is that it should never be 0, becuase it is not a valid executable, if you match it at 0.
EDIT: .toString() is slower, and unneeded on non 0.x, so longer version here
EDIT2: OUTDATED
try {
var muslName = 'libc.musl-x86_64.so.1';
var contents = fs.readFileSync(process.execPath);
var hasMusl = contents.indexOf ? contents.indexOf(muslName) > 0 : contents.toString().indexOf(muslName) > 0;
if (hasMusl) {
return 'musl';
}
} catch (err) { console.log (err); }
return '';
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, both excellent points. Addressing.
var contents = ''; | ||
try { | ||
contents = fs.readFileSync('foo.bar').toString(); | ||
if (contents.indexOf('libc.musl-x86_64.so.1') !== -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I sent comment while you are updating this.
toString is slow on where Buffer.indexOf is available. so this would be longer version.
contents = fs.readFileSync('foo.bar');
if (!contents.indexOf) {
contents = contents.toString();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starts to get a bit micro-optimization-y for my tastes, but sure.
This last failure has me baffled. |
I think this test has timeout on that CI run. |
if (!contents.indexOf) { | ||
contents = contents.toString(); | ||
} | ||
if (contents.indexOf('libc.musl-x86_64.so.1') !== -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping @ncopa can you confirm it's ok to cover all Alpine releases or should we look for a wider pattern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you asking whether this test will work for all Alpine releases? If so, yes.
} | ||
var contents = ''; | ||
try { | ||
contents = fs.readFileSync('foo.bar'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, its not 'foo.bar'
, its process.execPath
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So much fail.
Hey guys, I've PR'ed on top of @lox because I've hit a few more issues down the road with the @lox can merge it in https://github.com/lox/node-sass/pull/3 and it's passing CI. |
fix getPlatformVariant, getHumanPlatform and getBinaryPath
Thanks @gmaliar! |
var contents = ''; | ||
try { | ||
contents = fs.readFileSync(process.execPath); | ||
if (!contents.indexOf) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were you able to figure out how contents wasn't a string or buffer? This intent of line isn't clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just tried on 0.10. 0.12 and 7, they all return Buffer, indexOf is not available in 0.10 and 0.12
%docker run --rm -it mhart/alpine-node:0.12 sh
# node
> fs.readFileSync(process.execPath)
<Buffer 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 03 00 3e 00 01 00 00 00 43 b3 2a 00 00 00 00 00 40 00 00 00 00 00 00 00 78 64 fa 00 00 00 00 00 00 00 ... >
> fs.readFileSync(process.execPath).indexOf
undefined
%docker run --rm -it mhart/alpine-node:7 sh
# node
> fs.readFileSync(process.execPath)
<Buffer 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 03 00 3e 00 01 00 00 00 11 03 57 00 00 00 00 00 40 00 00 00 00 00 00 00 f8 1d 26 02 00 00 00 00 00 00 ... >
> fs.readFileSync(process.execPath).indexOf
[Function: indexOf]
Docs says, buf.indexOf is added in v1.5.0
https://nodejs.org/api/buffer.html#buffer_buf_indexof_value_byteoffset_encoding
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and performance difference with/without .toString() on node 7.0
> console.time('find');fs.readFileSync(process.execPath).indexOf('libc.musl-x86_64.so.1') !== -1;console.timeEnd('find')
find: 15.800ms
> console.time('find');fs.readFileSync(process.execPath).toString().indexOf('libc.musl-x86_64.so.1') !== -1;console.timeEnd('find')
find: 325.538ms
Also I think toString will use additional memory like 20M binary x UTF16 = 40M, If I am not wrong.
Of course there will be better performance by reading file by chunks, stop when found, but that's too much code to add, in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarification @S-YOU. I've gone back to lazily tostring'ing.
Pushed some minor cleanups. Happy 🚢 this when CI is green. |
This adds a new element
platformvariant
to the naming scheme for precompiled binding binaries:This allows for statically compiled musl binaries to be made available for Alpine Linux.
The check for whether this is needed is done by detecting symbols in the node binary, as suggested in #1589 (comment). I don't love this approach, but it's a whole lot simpler than
exec
'ing out toldd
.See #1589 for more details on background.
Tests:
$ docker run -v "$PWD:/code" --rm -w /code node:7-alpine node scripts/install.js Downloading binary from https://github.com/sass/node-sass/releases/download/v4.0.0/linux_musl-x64-51_binding.node
$ docker run -v "$PWD:/code" --rm -w /code node:7 node scripts/install.js Downloading binary from https://github.com/sass/node-sass/releases/download/v4.0.0/linux-x64-51_binding.node