-
Notifications
You must be signed in to change notification settings - Fork 988
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
Android builds fail on Darwin due to watchman issues #13783
Comments
If I try to drop starting Watchman entirely, and remove it from the Android build, I get this:
Which makes sense, since that's kinda what Watchman fixes for a lot of people: |
Normally, we provide a wrapped Watchman instance which already has a socket path specified: status-mobile/nix/mobile/android/watchman.nix Lines 13 to 15 in b565cbf
But if I try to provide unwrapped Watchman directly to the Android build, it fails with:
Which is something I have not seen before. |
Interestingly enough, this was originally introduced to So I assume this was done to fix the |
It appears the snprintf(
plist_path,
sizeof(plist_path),
"%s/Library/LaunchAgents/com.github.facebook.watchman.plist",
pw->pw_dir); And inside of #if defined(__APPLE__)
return spawn_via_launchd();
#elif defined(_WIN32)
return spawn_win32(daemon_argv);
#else
return run_service_as_daemon();
#endif So it appears the default way Watchman wants to spawn under Darwin is using Launchd, but that can't work in Nix sandbox. |
The docs aren't very helpful in understanding how the path is actually determined:
https://facebook.github.io/watchman/docs/cmd/get-sockname.html |
The const std::string& get_unix_sock_name() {
return flags.unix_sock_name;
}
const std::string& get_named_pipe_sock_path() {
return flags.named_pipe_path;
} The {"unix-listener-path",
'u',
#ifdef _WIN32
"Specify alternate unix domain socket path (specifying this will disable"
" named pipes unless `--named-pipe-path` is specified)",
#else
"Specify alternate unix domain socket path",
#endif
REQ_STRING,
&flags.unix_sock_name,
"PATH",
IS_DAEMON}, Which default value is generated by compute_file_name(flags.unix_sock_name, user, "sock", "sockname"); Which is defined here: |
According to the socket docs:
https://facebook.github.io/watchman/docs/socket-interface.html We might be able to use the |
No, that doesn't seem to work:
|
This flag might be of interest: {"no-site-spawner",
'S',
"Don't use the site or system spawner",
OPT_NONE,
&flags.no_site_spawner,
NULL,
IS_DAEMON}, Which does this: if (flags.no_site_spawner) {
// The astute reader will notice this we're calling run_service_as_daemon()
// here and not the various other platform spawning functions in the block
// further below in this function. This is deliberate: we want
// to do the most simple background running possible when the
// no_site_spawner flag is used. In the future we plan to
// migrate the platform spawning functions to use the site_spawn
// functionality.
return run_service_as_daemon();
} Which could possibly a way to have it spawn a daemon without using Launchd. But it appears this flag was introduced in:
Which was only introduced in release v2020.05.11.00. |
I tried building most recent
Which appears to be due to them having some kind of weird custom Facebook-specific dependency fetching code:
https://github.com/facebook/watchman/tree/v2022.08.08.00/build/fbcode_builder Because we can never reinvent the wheel enough times... |
So, what are my options:
I'm learning towards either option 2 or 3. |
I tried editing the
|
If I run |
One idea I had to fix And we are stuck on Gradle 5 until we are able to upgrade to React-Native v68: And that is blocked on some
And also this might not be the right way to go about it, since the watching might be done by React Native and not Gradle. |
While looking into this issue: I found this suggestion from 2019:
But when I look at the same file in our watch: watch == null ? !ci.isCI : watch Which uses the exports.isCI = !!(
env.CI || // Travis CI, CircleCI, Cirrus CI, Gitlab CI, Appveyor, CodeShip, dsari
env.CONTINUOUS_INTEGRATION || // Travis CI, Cirrus CI
env.BUILD_NUMBER || // Jenkins, TeamCity
env.RUN_ID || // TaskCluster, dsari
exports.name ||
false
) So setting |
This passing of Watchman socket was implemented in order to avoid this: ``` Error: EMFILE: too many open files, watch at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:204:21) Emitted 'error' event on NodeWatcher instance at: at NodeWatcher.checkedEmitError (/private/tmp/nix-build-status-mobile-build-nightly-android.drv-0/node_modules/sane/src/node_watcher.js:143:12) at FSWatcher.emit (node:events:527:28) at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:210:12) { errno: -24, syscall: 'watch', code: 'EMFILE', filename: null } ``` Which is caused by `jest-haste-map` used by `metro` starting to watch the filesystem for file changes, which is pointless when doing a one-off build using Nix. By entirely dropping use of Watchman we also fix the following issue: ``` [cli] unable to talk to your watchman on /tmp/tmp-status-mobile-ABC/jenkins-state/sock! (Permission denied) ``` Which happens on multi-user Nix installations becuase the user that the Nix build is executed as is not the same as the user that starts Watchman and creates the socket file. Issue: #13783 Signed-off-by: Jakub Sokołowski <jakub@status.im>
But this wouldn't fix the issue for local builds on Darwin right? |
This passing of Watchman socket was implemented in order to avoid this: ``` Error: EMFILE: too many open files, watch at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:204:21) Emitted 'error' event on NodeWatcher instance at: at NodeWatcher.checkedEmitError (/private/tmp/nix-build-status-mobile-build-nightly-android.drv-0/node_modules/sane/src/node_watcher.js:143:12) at FSWatcher.emit (node:events:527:28) at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:210:12) { errno: -24, syscall: 'watch', code: 'EMFILE', filename: null } ``` Which is caused by `jest-haste-map` used by `metro` starting to watch the filesystem for file changes, which is pointless when doing a one-off build using Nix. But by setting `CI=true` we can make `metro` not start this waching of files in the first place, removing the need for use of Watchman entirely. By entirely dropping use of Watchman we also fix the following issue: ``` [cli] unable to talk to your watchman on /tmp/tmp-status-mobile-ABC/jenkins-state/sock! (Permission denied) ``` Which happens on multi-user Nix installations becuase the user that the Nix build is executed as is not the same as the user that starts Watchman and creates the socket file. Issue: #13783 Signed-off-by: Jakub Sokołowski <jakub@status.im>
This passing of Watchman socket was implemented in order to avoid this: ``` Error: EMFILE: too many open files, watch at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:204:21) Emitted 'error' event on NodeWatcher instance at: at NodeWatcher.checkedEmitError (/private/tmp/nix-build-status-mobile-build-nightly-android.drv-0/node_modules/sane/src/node_watcher.js:143:12) at FSWatcher.emit (node:events:527:28) at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:210:12) { errno: -24, syscall: 'watch', code: 'EMFILE', filename: null } ``` Which is caused by `jest-haste-map` used by `metro` starting to watch the filesystem for file changes, which is pointless when doing a one-off build using Nix. But by setting `CI=true` we can make `metro` not start this waching of files in the first place, removing the need for use of Watchman entirely. By entirely dropping use of Watchman we also fix the following issue: ``` [cli] unable to talk to your watchman on /tmp/tmp-status-mobile-ABC/jenkins-state/sock! (Permission denied) ``` Which happens on multi-user Nix installations becuase the user that the Nix build is executed as is not the same as the user that starts Watchman and creates the socket file. Issue: #13783 Signed-off-by: Jakub Sokołowski <jakub@status.im>
This passing of Watchman socket was implemented in order to avoid this: ``` Error: EMFILE: too many open files, watch at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:204:21) Emitted 'error' event on NodeWatcher instance at: at NodeWatcher.checkedEmitError (/private/tmp/nix-build-status-mobile-build-nightly-android.drv-0/node_modules/sane/src/node_watcher.js:143:12) at FSWatcher.emit (node:events:527:28) at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:210:12) { errno: -24, syscall: 'watch', code: 'EMFILE', filename: null } ``` Which is caused by `jest-haste-map` used by `metro` starting to watch the filesystem for file changes, which is pointless when doing a one-off build using Nix. But by setting `CI=true` we can make `metro` not start this waching of files in the first place, removing the need for use of Watchman entirely. By entirely dropping use of Watchman we also fix the following issue: ``` [cli] unable to talk to your watchman on /tmp/tmp-status-mobile-ABC/jenkins-state/sock! (Permission denied) ``` Which happens on multi-user Nix installations becuase the user that the Nix build is executed as is not the same as the user that starts Watchman and creates the socket file. Issue: #13783 Signed-off-by: Jakub Sokołowski <jakub@status.im>
Fixed in: #13784 |
Currently if someone tries to build Android on a Darwin OS using a multi-user Nix installation they will get this from Gradle:
Which is caused by limited permissions of the
watchman
socket:Created by the
scripts/build-android.sh
script:status-mobile/scripts/build-android.sh
Lines 54 to 58 in b565cbf
Since builds are run as
nixbld*
users we either have to fix permissions, or change how we start Watchman in the first place.The text was updated successfully, but these errors were encountered: