replace shell call with a file based detection + user opt in/out (facebook#9956)

This commit is contained in:
Dennis Roppelt 2022-05-10 22:05:38 +02:00
parent e78451f3f6
commit da2d22df98
2 changed files with 45 additions and 11 deletions

View File

@ -1,21 +1,14 @@
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
package org.rocksdb.util;
import java.io.File;
import java.io.IOException;
public class Environment {
private static String OS = System.getProperty("os.name").toLowerCase();
private static String ARCH = System.getProperty("os.arch").toLowerCase();
private static boolean MUSL_LIBC;
static {
try {
final Process p = new ProcessBuilder("/usr/bin/env", "sh", "-c", "ldd /usr/bin/env | grep -q musl").start();
MUSL_LIBC = p.waitFor() == 0;
} catch (final IOException | InterruptedException e) {
MUSL_LIBC = false;
}
}
private static String MUSL_ENVIRONMENT = System.getenv("ROCKSDB_ENVIRONMENT_MUSL");
private static Boolean MUSL_LIBC;
public static boolean isAarch64() {
return ARCH.contains("aarch64");
@ -50,10 +43,28 @@ public class Environment {
OS.contains("nux");
}
/**
* lazy evaluation to prevent OS calls when "is this musl?" is not necessary
* no need to have a windows box report suspicious behaviour that the jvm attempts IO on unix paths
*/
public static boolean isMuslLibc() {
if(MUSL_LIBC == null) MUSL_LIBC = resolveIsMuslLibc();
return MUSL_LIBC;
}
static boolean resolveIsMuslLibc() {
// explicit user input in case any below calls cause issues in their environment
if("true".equalsIgnoreCase(MUSL_ENVIRONMENT)) return true;
if("false".equalsIgnoreCase(MUSL_ENVIRONMENT)) return false;
if(!isUnix()) return false; // not unix therefore not musl
File[] allFilesInLib = new File("/lib/").listFiles();
if(allFilesInLib == null) return false;
for(File f : allFilesInLib) {
if(f.getPath().startsWith("/lib/libc.musl")) return true;
}
return false;
}
public static boolean isSolaris() {
return OS.contains("sunos");
}

View File

@ -5,27 +5,34 @@
package org.rocksdb.util;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.lang.reflect.Field;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;
public class EnvironmentTest {
private final static String ARCH_FIELD_NAME = "ARCH";
private final static String OS_FIELD_NAME = "OS";
private final static String MUSL_ENVIRONMENT_FIELD_NAME = "MUSL_ENVIRONMENT";
private final static String MUSL_LIBC_FIELD_NAME = "MUSL_LIBC";
private static String INITIAL_OS;
private static String INITIAL_ARCH;
private static boolean INITIAL_MUSL_LIBC;
private static String INITIAL_MUSL_ENVIRONMENT;
private static Boolean INITIAL_MUSL_LIBC;
@BeforeClass
public static void saveState() {
INITIAL_ARCH = getEnvironmentClassField(ARCH_FIELD_NAME);
INITIAL_OS = getEnvironmentClassField(OS_FIELD_NAME);
INITIAL_MUSL_LIBC = getEnvironmentClassField(MUSL_LIBC_FIELD_NAME);
INITIAL_MUSL_ENVIRONMENT = getEnvironmentClassField(MUSL_ENVIRONMENT_FIELD_NAME);
}
@Test
@ -236,6 +243,21 @@ public class EnvironmentTest {
setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, false);
}
@Test
public void resolveIsMuslLibc() {
setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, null);
setEnvironmentClassFields("win", "anyarch");
assertThat(Environment.isUnix()).isFalse();
// with user input, will resolve to true if set as true. Even on OSs that appear absurd for musl. Users choice
assertThat(Environment.resolveIsMuslLibc()).isFalse();
setEnvironmentClassField(MUSL_ENVIRONMENT_FIELD_NAME, "true");
assertThat(Environment.resolveIsMuslLibc()).isTrue();
setEnvironmentClassField(MUSL_ENVIRONMENT_FIELD_NAME, "false");
assertThat(Environment.resolveIsMuslLibc()).isFalse();
}
private void setEnvironmentClassFields(String osName,
String osArch) {
setEnvironmentClassField(OS_FIELD_NAME, osName);
@ -246,6 +268,7 @@ public class EnvironmentTest {
public static void restoreState() {
setEnvironmentClassField(OS_FIELD_NAME, INITIAL_OS);
setEnvironmentClassField(ARCH_FIELD_NAME, INITIAL_ARCH);
setEnvironmentClassField(MUSL_ENVIRONMENT_FIELD_NAME, INITIAL_MUSL_ENVIRONMENT);
setEnvironmentClassField(MUSL_LIBC_FIELD_NAME, INITIAL_MUSL_LIBC);
}