Search in sources :

Example 96 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class DarwinSandboxedStrategy method getRunUnderPath.

/**
   * If a --run_under= option is set and refers to a command via its path (as opposed to via its
   * label), we have to mount this. Note that this is best effort and works fine for shell scripts
   * and small binaries, but we can't track any further dependencies of this command.
   *
   * <p>If --run_under= refers to a label, it is automatically provided in the spawn's input files,
   * so mountInputs() will catch that case.
   */
private Path getRunUnderPath(Spawn spawn) {
    if (spawn.getResourceOwner() instanceof TestRunnerAction) {
        TestRunnerAction testRunnerAction = ((TestRunnerAction) spawn.getResourceOwner());
        RunUnder runUnder = testRunnerAction.getExecutionSettings().getRunUnder();
        if (runUnder != null && runUnder.getCommand() != null) {
            PathFragment sourceFragment = new PathFragment(runUnder.getCommand());
            Path mount;
            if (sourceFragment.isAbsolute()) {
                mount = blazeDirs.getFileSystem().getPath(sourceFragment);
            } else if (blazeDirs.getExecRoot().getRelative(sourceFragment).exists()) {
                mount = blazeDirs.getExecRoot().getRelative(sourceFragment);
            } else {
                List<Path> searchPath = SearchPath.parse(blazeDirs.getFileSystem(), clientEnv.get("PATH"));
                mount = SearchPath.which(searchPath, runUnder.getCommand());
            }
            // only need to hardlink when under workspace
            Path workspace = blazeDirs.getWorkspace();
            if (mount != null && mount.startsWith(workspace)) {
                return mount;
            }
        }
    }
    return null;
}
Also used : SearchPath(com.google.devtools.build.lib.vfs.SearchPath) Path(com.google.devtools.build.lib.vfs.Path) RunUnder(com.google.devtools.build.lib.analysis.config.RunUnder) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) TestRunnerAction(com.google.devtools.build.lib.rules.test.TestRunnerAction) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List)

Example 97 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class DarwinSandboxedStrategy method actuallyExec.

private void actuallyExec(Spawn spawn, ActionExecutionContext actionExecutionContext, AtomicReference<Class<? extends SpawnActionContext>> writeOutputFiles) throws ExecException, InterruptedException {
    Executor executor = actionExecutionContext.getExecutor();
    SandboxHelpers.reportSubcommand(executor, spawn);
    PrintWriter errWriter = sandboxDebug ? new PrintWriter(actionExecutionContext.getFileOutErr().getErrorStream()) : null;
    // Each invocation of "exec" gets its own sandbox.
    Path sandboxPath = SandboxHelpers.getSandboxRoot(blazeDirs, productName, uuid, execCounter);
    Path sandboxExecRoot = sandboxPath.getRelative("execroot").getRelative(execRoot.getBaseName());
    if (errWriter != null) {
        errWriter.printf("sandbox root is %s\n", sandboxPath.toString());
        errWriter.printf("working dir is %s\n", sandboxExecRoot.toString());
    }
    ImmutableMap<String, String> spawnEnvironment = StandaloneSpawnStrategy.locallyDeterminedEnv(execRoot, productName, spawn.getEnvironment());
    Set<Path> writableDirs = getWritableDirs(sandboxExecRoot, spawn.getEnvironment());
    Path runUnderPath = getRunUnderPath(spawn);
    HardlinkedExecRoot hardlinkedExecRoot = new HardlinkedExecRoot(execRoot, sandboxPath, sandboxExecRoot, errWriter);
    ImmutableSet<PathFragment> outputs = SandboxHelpers.getOutputFiles(spawn);
    try {
        hardlinkedExecRoot.createFileSystem(getMounts(spawn, actionExecutionContext), outputs, writableDirs);
    } catch (IOException e) {
        throw new UserExecException("Could not prepare sandbox directory", e);
    }
    // Flush our logs before executing the spawn, otherwise they might get overwritten.
    if (errWriter != null) {
        errWriter.flush();
    }
    DarwinSandboxRunner runner = new DarwinSandboxRunner(sandboxPath, sandboxExecRoot, getWritableDirs(sandboxExecRoot, spawnEnvironment), getInaccessiblePaths(), runUnderPath, verboseFailures);
    try {
        runSpawn(spawn, actionExecutionContext, spawnEnvironment, hardlinkedExecRoot, outputs, runner, writeOutputFiles);
    } finally {
        if (!sandboxDebug) {
            try {
                FileSystemUtils.deleteTree(sandboxPath);
            } catch (IOException e) {
                executor.getEventHandler().handle(Event.warn(String.format("Cannot delete sandbox directory after action execution: %s (%s)", sandboxPath.getPathString(), e)));
            }
        }
    }
}
Also used : SearchPath(com.google.devtools.build.lib.vfs.SearchPath) Path(com.google.devtools.build.lib.vfs.Path) Executor(com.google.devtools.build.lib.actions.Executor) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) UserExecException(com.google.devtools.build.lib.actions.UserExecException) IOException(java.io.IOException) PrintWriter(java.io.PrintWriter)

Example 98 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class DarwinSandboxedStrategy method getMounts.

@Override
public Map<PathFragment, Path> getMounts(Spawn spawn, ActionExecutionContext executionContext) throws ExecException {
    try {
        Map<PathFragment, Path> mounts = new HashMap<>();
        spawnHelpers.mountInputs(mounts, spawn, executionContext);
        Map<PathFragment, Path> unfinalized = new HashMap<>();
        spawnHelpers.mountRunfilesFromSuppliers(unfinalized, spawn);
        spawnHelpers.mountFilesFromFilesetManifests(unfinalized, spawn, executionContext);
        mounts.putAll(finalizeLinks(unfinalized));
        return mounts;
    } catch (IllegalArgumentException | IOException e) {
        throw new EnvironmentalExecException("Could not prepare mounts for sandbox execution", e);
    }
}
Also used : SearchPath(com.google.devtools.build.lib.vfs.SearchPath) Path(com.google.devtools.build.lib.vfs.Path) HashMap(java.util.HashMap) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) IOException(java.io.IOException) EnvironmentalExecException(com.google.devtools.build.lib.actions.EnvironmentalExecException)

Example 99 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class HardlinkedExecRoot method linkInputs.

/**
   * Make all specified inputs available in the sandbox.
   *
   * <p>We want the sandboxed process to have access only to these input files and not anything else
   * from the workspace. Furthermore, the process should not be able to modify these input files. We
   * achieve this by hardlinking all input files into a temporary "inputs" directory, then
   * symlinking them into their correct place inside the sandbox.
   *
   * <p>The hardlinks / symlinks combination (as opposed to simply directly hardlinking to the final
   * destination) is necessary, because we build a solib symlink tree for shared libraries where the
   * original file and the created symlink have two different file names (libblaze_util.so vs.
   * src_Stest_Scpp_Sblaze_Uutil_Utest.so) and our cc_wrapper.sh needs to be able to figure out both
   * names (by following solib symlinks back) to modify the paths to the shared libraries in
   * cc_binaries.
   */
private void linkInputs(Map<PathFragment, Path> inputs, Set<Path> createdDirs) throws IOException {
    // Create directory for input files.
    Path inputsDir = sandboxPath.getRelative("inputs");
    if (!inputsDir.exists()) {
        inputsDir.createDirectory();
    }
    for (ImmutableMap.Entry<PathFragment, Path> entry : inputs.entrySet()) {
        Path targetName = sandboxExecRoot.getRelative(entry.getKey());
        FileSystemUtils.createDirectoryAndParentsWithCache(createdDirs, targetName.getParentDirectory());
        // The target is supposed to be an empty file.
        if (entry.getValue() == null) {
            FileSystemUtils.createEmptyFile(targetName);
            continue;
        }
        // Hardlink, resolve symlink here instead in finalizeLinks.
        Path target = entry.getValue().resolveSymbolicLinks();
        Path hardlinkName = target.startsWith(execRoot) ? inputsDir.getRelative(target.relativeTo(execRoot)) : inputsDir.getRelative(entry.getKey());
        if (errWriter != null) {
            errWriter.printf("hardlink: %s -> %s\n", hardlinkName, target);
        }
        try {
            createHardLink(hardlinkName, target);
        } catch (IOException e) {
            // Creating a hardlink might fail when the input file and the sandbox directory are not on
            // the same filesystem / device. Then we use symlink instead.
            hardlinkName.createSymbolicLink(target);
        }
        // symlink
        if (errWriter != null) {
            errWriter.printf("symlink: %s -> %s\n", targetName, hardlinkName);
        }
        targetName.createSymbolicLink(hardlinkName);
    }
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) IOException(java.io.IOException) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 100 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class HardlinkedExecRoot method copyOutputs.

@Override
public void copyOutputs(Path execRoot, Collection<PathFragment> outputs) throws IOException {
    for (PathFragment output : outputs) {
        Path source = sandboxExecRoot.getRelative(output);
        Path target = execRoot.getRelative(output);
        if (source.isFile() || source.isSymbolicLink()) {
            Files.move(source.getPathFile(), target.getPathFile());
        } else if (source.isDirectory()) {
            try {
                source.renameTo(target);
            } catch (IOException e) {
                // Failed to move directory directly, thus move it recursively.
                target.createDirectory();
                FileSystemUtils.moveTreesBelow(source, target);
            }
        }
    }
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) IOException(java.io.IOException)

Aggregations

PathFragment (com.google.devtools.build.lib.vfs.PathFragment)512 Test (org.junit.Test)208 Artifact (com.google.devtools.build.lib.actions.Artifact)184 Path (com.google.devtools.build.lib.vfs.Path)111 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)65 SkyKey (com.google.devtools.build.skyframe.SkyKey)56 IOException (java.io.IOException)38 ArrayList (java.util.ArrayList)35 ImmutableList (com.google.common.collect.ImmutableList)32 Root (com.google.devtools.build.lib.actions.Root)32 HashMap (java.util.HashMap)27 Label (com.google.devtools.build.lib.cmdline.Label)26 LinkedHashMap (java.util.LinkedHashMap)26 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)23 ImmutableMap (com.google.common.collect.ImmutableMap)22 Map (java.util.Map)21 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)20 FilesetTraversalParams (com.google.devtools.build.lib.actions.FilesetTraversalParams)16 PackageIdentifier (com.google.devtools.build.lib.cmdline.PackageIdentifier)16 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)16