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

v8.2.0: TypeError: stat.isSocket is not a function #208

Open
pdcastro opened this issue Jun 14, 2019 · 2 comments
Open

v8.2.0: TypeError: stat.isSocket is not a function #208

pdcastro opened this issue Jun 14, 2019 · 2 comments

Comments

@pdcastro
Copy link
Contributor

I was investigating balena-cli issue balena-io/balena-cli/issues/1306 and my preliminary findings suggest that:

  • balena-cli v10.16.0 works OK with balena-preload v8.1.4
  • balena-cli v10.17.1 and later (also v11.2.1) fail with balena-preload v8.2.0, with the error:
./balena-cli-11.2.1/balena preload test.img -a test-rpi -c current
Building Docker preloader image. [                        ] 0%
TypeError: stat.isSocket is not a function
    at onstat (/snapshot/balena-cli/node_modules/balena-preload/node_modules/tar-fs/index.js:103:14)
    at /snapshot/balena-cli/node_modules/balena-preload/node_modules/tar-fs/index.js:32:39
    at zalgoSafe (pkg/prelude/bootstrap.js:261:10)
    at pkg/prelude/bootstrap.js:901:9
    at pkg/prelude/bootstrap.js:337:5
    at pkg/prelude/bootstrap.js:315:14
    at FSReqWrap.wrapper [as oncomplete] (fs.js:603:17)

Interestingly, I've only reproduced the failure on Linux (Docker image debian:9.9), not macOS, so it looks like a system-dependent issue.

The offending pull request may be:
https://github.com/balena-io/balena-preload/pull/206/files

@pdcastro
Copy link
Contributor Author

pdcastro commented Jun 16, 2019

I patched balena-cli/node_modules/balena-preload/node_modules/tar-fs/index.js for debugging, and added these console.log calls:

console.log(`[preload/tar-fs] onstat() filename="${filename}" stat=${require('util').inspect(stat)}`);
console.log(`
  isFile()="${stat.isFile()}"
  isDirectory()="${stat.isDirectory()}"
  isSymbolicLink()="${stat.isSymbolicLink()}"
  isFIFO()="${stat.isFIFO()}"`
);
if (stat.isSocket()) return onnextentry() // tar does not support sockets...

The result was:

[preload/tar-fs] onstat() filename="Dockerfile" stat={ mode: 33188,
  size: 361,
  blksize: 4096,
  blocks: 0,
  dev: 0,
  gid: 20,
  ino: 0,
  nlink: 0,
  rdev: 0,
  uid: 500,
  atime: 2019-06-16T13:37:18.530Z,
  mtime: 2019-06-16T13:36:44.320Z,
  ctime: 2019-06-16T13:36:44.320Z,
  birthtime: 2019-06-16T13:36:44.320Z,
  atimeMs: 1560692238530,
  mtimeMs: 1560692204320,
  ctimeMs: 1560692204320,
  birthtimeMs: 1560692204320,
  isFile: [Function],
  isDirectory: [Function],
  isSymbolicLink: [Function],
  isFIFO: [Function] }

      isFile()="true"
      isDirectory()="false"
      isSymbolicLink()="false"
      isFIFO()="false"
TypeError: stat.isSocket is not a function
    at onstat (/snapshot/balena-cli/node_modules/balena-preload/node_modules/tar-fs/index.js:114:14)
    at /snapshot/balena-cli/node_modules/balena-preload/node_modules/tar-fs/index.js:32:39
    at zalgoSafe (pkg/prelude/bootstrap.js:261:10)
    at pkg/prelude/bootstrap.js:901:9
    at pkg/prelude/bootstrap.js:337:5
    at pkg/prelude/bootstrap.js:315:14
    at FSReqWrap.wrapper [as oncomplete] (fs.js:658:17)

I have further checked these tar-fs lines:

var xfs = opts.fs || fs
var statNext = statAll(xfs, opts.dereference ? xfs.stat : xfs.lstat, cwd, ignore, opts.entries, opts.sort)

And found that opts.fs and opts.dereference are undefined, meaning it should be using the standard fs.lstat() function. I tried setting opts.dereference=true, so it used fs.stat() instead of fs.lstat(), and it made no difference (still results in the same TypeError).

So a seemingly standard fs.lstat('Dockerfile') call returns an object that does not have the isSocket() function, apparently in violation of the Node.js documented API. But we can't say it's a Node.js bug, because:

  • It works OK with a balena-cli npm installation on Linux and macOS.
  • It works OK with a balena-cli standalone (pkg) installation on macOS.
    Edit/correction: it fails on macOS too.
  • It does not work with a balena-cli standalone (pkg) installation on Linux.

So it's the combination of pkg and Linux that causes it to fail. So it's down to pkg (the tool that generates the standalone package). I have also investigated the version of Node.js used by pkg on Linux. It seems to use pre-selected minor/patch releases for a given major Node release, namely v10.4.1 for Node 10 and v8.11.3 for Node 8. pkg caches the fetched Node in the homedir:

/root/.pkg-cache/v2.5/fetched-v10.4.1-linux-x64
/root/.pkg-cache/v2.5/fetched-v8.11.3-linux-x64

I am not sure how / whether pkg modifies those fetched versions of Node, but I have tested with both of those (Node 8 and Node 10) and both equally result in that same TypeError.

Although I am none the wiser on the root cause of the problem, I have found that the following very simple tar-fs patch avoids the TypeError and allows balena preload to work:

    // if (stat.isSocket()) return onnextentry()
    if (stat.isSocket && stat.isSocket()) return onnextentry()

Given that neither tar-fs nor balena-preload use pkg but balena-cli does, a patch fix would perhaps belong to balena-cli rather than balena-preload or upstream. I am planning to create a balena-cli PR with that patch, so we can move on.

@pdcastro
Copy link
Contributor Author

Related pkg pull request: vercel/pkg#720

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

No branches or pull requests

1 participant