nix: stop passing watchman socket to Nix builds

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: https://github.com/status-im/status-mobile/issues/13783

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2022-08-09 20:49:59 +02:00
parent b565cbf85e
commit 5903cf73fb
No known key found for this signature in database
GPG Key ID: 09AA5403E54D9931
4 changed files with 17 additions and 53 deletions

View File

@ -5,14 +5,7 @@ let
# Import a jsbundle compiled out of clojure codebase
jsbundle = callPackage ./jsbundle { };
# Import a patched version of watchman (important for sandboxed builds on macOS)
watchmanFactory = callPackage ./watchman.nix { };
# TARGETS
release = callPackage ./release.nix {
inherit jsbundle status-go watchmanFactory;
};
release = callPackage ./release.nix { inherit jsbundle status-go; };
in {
# TARGETS
inherit release jsbundle;

View File

@ -1,4 +1,4 @@
{ stdenv, pkgs, deps, lib, watchmanFactory
{ stdenv, pkgs, deps, lib
, androidPkgs, patchMavenSources, jsbundle, status-go }:
{
@ -6,13 +6,8 @@
buildEnv ? "prod",
# Path to the file containing secret environment variables
secretsFile ? "",
# Path to the socket file exposed by an external watchman instance
# (workaround needed for building Android on macOS)
watchmanSockPath ? "",
}:
assert (lib.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
let
inherit (lib) toLower optionalString stringLength getConfig makeLibraryPath elem;
@ -26,8 +21,8 @@ let
# Used to detect end-to-end builds
androidAbiInclude = getConfig "android.abi-include" "armeabi-v7a;arm64-v8a;x86";
envFileName =
if androidAbiInclude == "x86" then ".env.e2e"
envFileName =
if androidAbiInclude == "x86" then ".env.e2e"
else if (elem buildType ["release" "nightly"]) then ".env.${buildType}"
else if (elem buildType ["pr" "manual"]) then ".env.jenkins"
else ".env";
@ -36,7 +31,6 @@ let
gradleBuildType = if buildType == "pr" then "Pr" else "Release";
apksPath = "./android/app/build/outputs/apk/${toLower gradleBuildType}";
patchedWatchman = watchmanFactory watchmanSockPath;
baseName = "${buildType}-android";
in stdenv.mkDerivation rec {
@ -54,15 +48,17 @@ in stdenv.mkDerivation rec {
"package.json" "yarn.lock" "metro.config.js" ".babelrc"
"resources/.*" "translations/.*" "src/js/worklet_factory.js"
"modules/react-native-status/android.*" "android/.*"
envFileName "VERSION" ".watchmanconfig"
"status-go-version.json" "react-native.config.js"
envFileName "VERSION" "status-go-version.json" "react-native.config.js"
];
};
};
buildInputs = with pkgs; [ nodejs openjdk ];
nativeBuildInputs = with pkgs; [ bash gradle unzip ]
++ lib.optionals stdenv.isDarwin [ file gnumake patchedWatchman ];
++ lib.optionals stdenv.isDarwin [ file gnumake ];
# Disable metro watching for file changes. (#13783)
CI = true;
# Used by Clojure at compile time to include JS modules
BUILD_ENV = buildEnv;
@ -92,8 +88,8 @@ in stdenv.mkDerivation rec {
# Ensure we have the right .env file
cp -bf ./${envFileName} ./.env
# Export all vars from .env file
export $(cut -d= -f1 .env)
# Export all vars from .env file
export $(cut -d= -f1 .env)
# Copy index.js and app/ input files
cp -ra --no-preserve=ownership ${builtJsBundle}/* ./
@ -121,7 +117,7 @@ in stdenv.mkDerivation rec {
buildPhase = let
adhocEnvVars = optionalString stdenv.isLinux
"LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${makeLibraryPath [ pkgs.zlib ]}";
in
in
assert ANDROID_ABI_SPLIT != null && ANDROID_ABI_SPLIT != "";
assert stringLength ANDROID_ABI_INCLUDE > 0;
''

View File

@ -1,18 +0,0 @@
{ stdenv, runCommand, makeWrapper,
watchman }:
let
patchedWatchmanFactory = watchmanSockPath:
assert (builtins.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
if stdenv.isDarwin then
assert (builtins.stringLength watchmanSockPath) > 0;
# Create a wrapper to watchman that includes the --sockname flag
runCommand "patched-watchman" { nativeBuildInputs = [ makeWrapper ]; } ''
mkdir -p $out/bin
makeWrapper ${watchman}/bin/watchman \
$out/bin/watchman \
--add-flags "--sockname=${watchmanSockPath}"
'' else watchman;
in patchedWatchmanFactory

View File

@ -47,24 +47,17 @@ if [[ -n "${OPENSEA_API_KEY}" ]]; then append_env_export 'OPENSEA_API_KEY'; fi
if [[ -s "${SECRETS_FILE_PATH}" ]]; then
nixOpts+=("--argstr" "secretsFile" "${SECRETS_FILE_PATH}")
fi
nixOpts+=("--option" "extra-sandbox-paths" "${KEYSTORE_PATH} ${SECRETS_FILE_PATH}")
# Used by Clojure at compile time to include JS modules
nixOpts+=("--argstr" "buildEnv" "$(must_get_env BUILD_ENV)")
# On Darwin we hit a sandbox serialization limit of 65535.
# https://github.com/NixOS/nix/issues/4119
if [[ "$(uname -s)" =~ Darwin ]]; then
# Start a watchman instance if not started already and store its socket path.
# In order to get access to the right versions of watchman and jq,
# we start an ad-hoc nix-shell that imports the packages from nix/nixpkgs-bootstrap.
WATCHMAN_SOCKFILE=$(watchman get-sockname --no-pretty | jq -r .sockname)
nixOpts+=(
"--argstr" "watchmanSockPath" "${WATCHMAN_SOCKFILE}"
"--option" "extra-sandbox-paths" "${KEYSTORE_PATH} ${SECRETS_FILE_PATH} ${WATCHMAN_SOCKFILE}"
)
nixOpts+=("--option" "build-use-sandbox" "false")
else
nixOpts+=(
"--option" "build-use-sandbox" "true"
"--option" "extra-sandbox-paths" "${KEYSTORE_PATH} ${SECRETS_FILE_PATH}"
)
nixOpts+=("--option" "build-use-sandbox" "true")
fi
nixOpts+=("--arg" "config" "{${config}}")