-
Notifications
You must be signed in to change notification settings - Fork 493
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
feature(@embark/core): IPC adapts when run in Docker Linux on Win #1202
Conversation
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.
Codewise this looks pretty solid!
Left some minor comments.
src/lib/core/env.js
Outdated
@@ -2,7 +2,7 @@ | |||
|
|||
const {execSync} = require('child_process'); | |||
const {delimiter} = require('path'); | |||
const {joinPath} = require('../utils/utils.js'); | |||
const {join} = require('path'); |
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.
👍 great move!
Also, can we combine the required symbols for path
? There's another one already for delimiter
.
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.
Good catch, will combine them.
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.
Done.
).test( | ||
execSync( | ||
"cat /proc/self/cgroup", | ||
{stdio: ["ignore", "pipe", "ignore"]}, |
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.
@michaelsbradleyjr just out of curiosity: why are we doing ignore, pipe, ignore
here and not just pipe
?
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.
For the execSync
calls in this module, all we care about is stdout
, so it seems more correct to 'ignore'
stdin
and stderr
. It would, though, work with the default: 'pipe'
, which is equivalent to ['pipe', 'pipe', 'pipe']
.
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.
Yea, that makes sense!
.toString() | ||
.split("\n") | ||
.filter((line) => /nounix/.test(line)) | ||
.some((line) => { |
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 some cosmetics that can be ignored: we can get rid of the parenthesis here in filter()
and some
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 didn't have them originally but tslint said it was an error to not use parens around line
.
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.
When removed, I get something like this:
$ yarn lint:ts
yarn run v1.12.3
$ tslint -c tslint.json 'src/**/*.ts'
ERROR: src/lib/utils/host.ts[42, 15]: Parentheses are required around the parameters of an arrow function definition
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Maybe it's something we can relax in the linter, and/or we could have another team discussion about adopting use of the prettier
tool?
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.
Wow I'm surprised tslint is complaining about that. Definitely something we should relax in the future.
f6bbbb1
to
6f219e2
Compare
When embark is running on Linux and macOS, unix socket files are used for geth's and embark's IPC files. If the context is a Linux container running on a Windows Docker host, and if the DApp is mounted from the host's file system, there is a problem: unix socket files are incompatible with the Windows file system. Detect the problematic scenario and use a path outside of the mounted directory for embark's and geth's IPC files. To avoid a circular dependency problem, remove the `utils/utils.js` dependency from `core/env.js`, don't have `utils/host.ts` depdend on `core/fs.js`, and implement the `ipcPath()` helper as a static method on the class exported from `core/ipc.js`.
6f219e2
to
af79595
Compare
@@ -1,8 +1,7 @@ | |||
/* global __dirname module process require */ | |||
|
|||
const {execSync} = require('child_process'); | |||
const {delimiter} = require('path'); | |||
const {joinPath} = require('../utils/utils.js'); | |||
const {delimiter, join} = require('path'); |
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.
Not a big fan of extracting these off of path. delimiter
and join
are concepts used in a lot more ways than just path, so it'll get a bit confusing down below.
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.
Given the usage context (args and neighboring variables/literals always have something do to w/ paths), I thought it wasn't too confusing, but willing to reconsider.
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.
We can just do const {delimiter as pathDelimiter, join as pathJoin} = require('path');
if we want them to be more clear
return `\\\\.\\pipe\\${basename}`; | ||
} else if (isDappMountedFromWindowsDockerHost) { | ||
ipcDir = utils.joinPath( | ||
os.tmpdir(), `embark-${utils.sha512(fs.dappPath()).slice(0, 8)}` |
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.
This is almost exactly what I was thinking! I was thinking:
embark-<dapp_dir>-<dapp_full_path_sha512.substring(0,5)>
So, as an example:
Name | Full path | Path |
---|---|---|
embark_demo | /Users/andremedeiros/src/_sandbox/embark_demo | embark-embark_demo-f47bb |
embark_demo | /tmp/embark_demo | embark-embark_demo-74a67 |
test_app | /Users/andremedeiros/src/github.com/embark-framework/embark/test_apps/test_app | embark-test_app-17efd |
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.
Interesting idea to put the original path itself into the directory name. I worry that things might get weird if spaces were in the dirname, though maybe not a problem in practice.
function sha512(arg) { | ||
const crypto = require('crypto'); | ||
const hash = crypto.createHash('sha512'); | ||
return hash.update(arg, 'utf8').digest('hex'); |
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.
Here, just as a precaution, you want to make sure that arg
is a string, so we might want it to read
return hash.update(arg.toString(), 'utf8').digest('hex');
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.
https://nodejs.org/dist/latest-v10.x/docs/api/crypto.html#crypto_hash_update_data_inputencoding
Maybe we should just throw if it's not a string?
> ({a: 1}).toString()
'[object Object]'
> ({a: 2}).toString()
'[object Object]'
Closing in favor of a forthcoming PR that makes saving the |
This PR replaces #1202. When embark is running on Linux and macOS, unix socket files are used for geth's and embark's IPC files. A problem can arise if a DApp is in a deeply nested directory structure such that the character-length of the path to a socket file exceeds the maximum supported length. See #450. Also, if the DApp context is a Linux container running on a Windows Docker host, and if the DApp is mounted from the host's file system, there is a problem: unix socket files are incompatible with the Windows file system. Solve both problems at once by storing a DApp's `.ipc` files in a directory within `os.tmpdir()`. Use a truncated sha512 hash of the DApp's path in the name of the temporary directory created for that purpose so that DApps won't collide (with an acceptably low probability of collision). Remove the `utils/utils.js` dependency from `core/env.js` and implement the `ipcPath()` helper as a static method on the class exported from `core/ipc.js`.
Replaced by #1214. |
This PR replaces #1202. When embark is running on Linux and macOS, unix socket files are used for geth's and embark's IPC files. A problem can arise if a DApp is in a deeply nested directory structure such that character-length of the path to a socket file exceeds the maximum supported length. See #450. Also, if the DApp context is a Linux container running on a Windows Docker host, and if the DApp is mounted from the host's file system, there is a problem: unix socket files are incompatible with the Windows file system. Solve both problems at once by storing a DApp's `.ipc` files in a directory within `os.tmpdir()`. Introduce `ipcPath()` in `core/fs.js` and use a truncated SHA-512 hash of the DApp's path in the name of the temporary directory created for that purpose so that DApps won't collide (with an acceptably low probability of collision).
This PR replaces #1202. When embark is running on Linux and macOS, unix socket files are used for geth's and embark's IPC files. A problem can arise if a DApp is in a deeply nested directory structure such that character-length of the path to a socket file exceeds the maximum supported length. See #450. Also, if the DApp context is a Linux container running on a Windows Docker host, and if the DApp is mounted from the host's file system, there is a problem: unix socket files are incompatible with the Windows file system. Solve both problems at once by storing a DApp's `.ipc` files in a directory within `os.tmpdir()`. Introduce `ipcPath()` in `core/fs.js` and use a truncated SHA-512 hash of the DApp's path in the name of the temporary directory created for that purpose so that DApps won't collide (with an acceptably low probability of collision).
This PR replaces #1202. When embark is running on Linux and macOS, unix socket files are used for geth's and embark's IPC files. A problem can arise if a DApp is in a deeply nested directory structure such that character-length of the path to a socket file exceeds the maximum supported length. See #450. Also, if the DApp context is a Linux container running on a Windows Docker host, and if the DApp is mounted from the host's file system, there is a problem: unix socket files are incompatible with the Windows file system. Solve both problems at once by storing a DApp's `.ipc` files in a directory within `os.tmpdir()`. Introduce `ipcPath()` in `core/fs.js` and use a truncated SHA-512 hash of the DApp's path in the name of the temporary directory created for that purpose so that DApps won't collide (with an acceptably low probability of collision).
This PR replaces #1202. When embark is running on Linux and macOS, unix socket files are used for geth's and embark's IPC files. A problem can arise if a DApp is in a deeply nested directory structure such that character-length of the path to a socket file exceeds the maximum supported length. See #450. Also, if the DApp context is a Linux container running on a Windows Docker host, and if the DApp is mounted from the host's file system, there is a problem: unix socket files are incompatible with the Windows file system. Solve both problems at once by storing a DApp's `.ipc` files in a directory within `os.tmpdir()`. Introduce `ipcPath()` in `core/fs.js` and use a truncated SHA-512 hash of the DApp's path in the name of the temporary directory created for that purpose so that DApps won't collide (with an acceptably low probability of collision).
This PR replaces #1202. When embark is running on Linux and macOS, unix socket files are used for geth's and embark's IPC files. A problem can arise if a DApp is in a deeply nested directory structure such that character-length of the path to a socket file exceeds the maximum supported length. See #450. Also, if the DApp context is a Linux container running on a Windows Docker host, and if the DApp is mounted from the host's file system, there is a problem: unix socket files are incompatible with the Windows file system. Solve both problems at once by storing a DApp's `.ipc` files in a directory within `os.tmpdir()`. Introduce `ipcPath()` in `core/fs.js` and use a truncated SHA-512 hash of the DApp's path in the name of the temporary directory created for that purpose so that DApps won't collide (with an acceptably low probability of collision).
When embark is running on Linux and macOS, unix socket files are used for geth's and embark's IPC files. If the context is a Linux container running on a Windows Docker host, and if the DApp is mounted from the host's file system, there is a problem: unix socket files are incompatible with the Windows file system.
Detect the problematic scenario and use a path outside of the mounted directory for embark's and geth's IPC files.
To avoid a circular dependency problem, remove the
utils/utils.js
dependency fromcore/env.js
, don't haveutils/host.ts
depdend oncore/fs.js
, and implement theipcPath()
helper as a static method on the class exported fromcore/ipc.js
.