Search in sources :

Example 11 with DirectoryNode

use of build.bazel.remote.execution.v2.DirectoryNode in project bazel-buildfarm by bazelbuild.

the class AbstractServerInstance method validateActionInputDirectory.

@VisibleForTesting
public static void validateActionInputDirectory(String directoryPath, Directory directory, Stack<Digest> pathDigests, Set<Digest> visited, Map<Digest, Directory> directoriesIndex, Consumer<String> onInputFile, Consumer<String> onInputDirectory, Consumer<Digest> onInputDigest, PreconditionFailure.Builder preconditionFailure) {
    Set<String> entryNames = new HashSet<>();
    String lastFileName = "";
    for (FileNode fileNode : directory.getFilesList()) {
        String fileName = fileNode.getName();
        if (entryNames.contains(fileName)) {
            preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject("/" + directoryPath + ": " + fileName).setDescription(DUPLICATE_DIRENT);
        } else if (lastFileName.compareTo(fileName) > 0) {
            preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject("/" + directoryPath + ": " + lastFileName + " > " + fileName).setDescription(DIRECTORY_NOT_SORTED);
        }
        // FIXME serverside validity check? regex?
        Preconditions.checkState(isValidFilename(), INVALID_FILE_NAME);
        lastFileName = fileName;
        entryNames.add(fileName);
        onInputDigest.accept(fileNode.getDigest());
        String filePath = directoryPath.isEmpty() ? fileName : (directoryPath + "/" + fileName);
        onInputFile.accept(filePath);
    }
    String lastSymlinkName = "";
    for (SymlinkNode symlinkNode : directory.getSymlinksList()) {
        String symlinkName = symlinkNode.getName();
        if (entryNames.contains(symlinkName)) {
            preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject("/" + directoryPath + ": " + symlinkName).setDescription(DUPLICATE_DIRENT);
        } else if (lastSymlinkName.compareTo(symlinkName) > 0) {
            preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject("/" + directoryPath + ": " + lastSymlinkName + " > " + symlinkName).setDescription(DIRECTORY_NOT_SORTED);
        }
        /* FIXME serverside validity check? regex?
      Preconditions.checkState(
          isValidFilename(symlinkName),
          INVALID_FILE_NAME);
      Preconditions.checkState(
          isValidFilename(symlinkNode.getTarget()),
          INVALID_FILE_NAME);
      // FIXME verify that any relative pathing for the target is within the input root
      */
        lastSymlinkName = symlinkName;
        entryNames.add(symlinkName);
    }
    String lastDirectoryName = "";
    for (DirectoryNode directoryNode : directory.getDirectoriesList()) {
        String directoryName = directoryNode.getName();
        if (entryNames.contains(directoryName)) {
            preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject("/" + directoryPath + ": " + directoryName).setDescription(DUPLICATE_DIRENT);
        } else if (lastDirectoryName.compareTo(directoryName) > 0) {
            preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject("/" + directoryPath + ": " + lastDirectoryName + " > " + directoryName).setDescription(DIRECTORY_NOT_SORTED);
        }
        /* FIXME serverside validity check? regex?
      Preconditions.checkState(
          isValidFilename(directoryName),
          INVALID_FILE_NAME);
      */
        lastDirectoryName = directoryName;
        entryNames.add(directoryName);
        Digest directoryDigest = directoryNode.getDigest();
        if (pathDigests.contains(directoryDigest)) {
            preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject(DIRECTORY_CYCLE_DETECTED).setDescription("/" + directoryPath + ": " + directoryName);
        } else {
            String subDirectoryPath = directoryPath.isEmpty() ? directoryName : (directoryPath + "/" + directoryName);
            onInputDirectory.accept(subDirectoryPath);
            if (!visited.contains(directoryDigest)) {
                validateActionInputDirectoryDigest(subDirectoryPath, directoryDigest, pathDigests, visited, directoriesIndex, onInputFile, onInputDirectory, onInputDigest, preconditionFailure);
            } else {
                enumerateActionInputDirectory(subDirectoryPath, directoriesIndex.get(directoryDigest), directoriesIndex, onInputFile, onInputDirectory);
            }
        }
    }
}
Also used : Digest(build.bazel.remote.execution.v2.Digest) SymlinkNode(build.bazel.remote.execution.v2.SymlinkNode) DirectoryNode(build.bazel.remote.execution.v2.DirectoryNode) ByteString(com.google.protobuf.ByteString) FileNode(build.bazel.remote.execution.v2.FileNode) HashSet(java.util.HashSet) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 12 with DirectoryNode

use of build.bazel.remote.execution.v2.DirectoryNode in project bazel-buildfarm by bazelbuild.

the class AbstractServerInstance method enumerateActionInputDirectory.

private static void enumerateActionInputDirectory(String directoryPath, Directory directory, Map<Digest, Directory> directoriesIndex, Consumer<String> onInputFile, Consumer<String> onInputDirectory) {
    for (FileNode fileNode : directory.getFilesList()) {
        String fileName = fileNode.getName();
        String filePath = directoryPath.isEmpty() ? fileName : (directoryPath + "/" + fileName);
        onInputFile.accept(filePath);
    }
    for (DirectoryNode directoryNode : directory.getDirectoriesList()) {
        String directoryName = directoryNode.getName();
        Digest directoryDigest = directoryNode.getDigest();
        String subDirectoryPath = directoryPath.isEmpty() ? directoryName : (directoryPath + "/" + directoryName);
        onInputDirectory.accept(subDirectoryPath);
        enumerateActionInputDirectory(subDirectoryPath, directoriesIndex.get(directoryDigest), directoriesIndex, onInputFile, onInputDirectory);
    }
}
Also used : Digest(build.bazel.remote.execution.v2.Digest) DirectoryNode(build.bazel.remote.execution.v2.DirectoryNode) ByteString(com.google.protobuf.ByteString) FileNode(build.bazel.remote.execution.v2.FileNode)

Example 13 with DirectoryNode

use of build.bazel.remote.execution.v2.DirectoryNode in project bazel-buildfarm by bazelbuild.

the class AbstractServerInstance method validateCommand.

@VisibleForTesting
void validateCommand(Command command, Digest inputRootDigest, Set<String> inputFiles, Set<String> inputDirectories, Map<Digest, Directory> directoriesIndex, PreconditionFailure.Builder preconditionFailure) {
    validatePlatform(command.getPlatform(), preconditionFailure);
    // FIXME should input/output collisions (through directories) be another
    // invalid action?
    filesUniqueAndSortedPrecondition(command.getOutputFilesList(), preconditionFailure);
    filesUniqueAndSortedPrecondition(command.getOutputDirectoriesList(), preconditionFailure);
    validateOutputs(inputFiles, inputDirectories, Sets.newHashSet(command.getOutputFilesList()), Sets.newHashSet(command.getOutputDirectoriesList()), preconditionFailure);
    environmentVariablesUniqueAndSortedPrecondition(command.getEnvironmentVariablesList(), preconditionFailure);
    if (command.getArgumentsList().isEmpty()) {
        preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject(INVALID_COMMAND).setDescription("argument list is empty");
    }
    String workingDirectory = command.getWorkingDirectory();
    if (!workingDirectory.isEmpty()) {
        if (workingDirectory.startsWith("/")) {
            preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject(INVALID_COMMAND).setDescription("working directory is absolute");
        } else {
            Directory directory = directoriesIndex.get(inputRootDigest);
            for (String segment : workingDirectory.split("/")) {
                Directory nextDirectory = directory;
                // linear for now
                for (DirectoryNode dirNode : directory.getDirectoriesList()) {
                    if (dirNode.getName().equals(segment)) {
                        nextDirectory = directoriesIndex.get(dirNode.getDigest());
                        break;
                    }
                }
                if (nextDirectory == directory) {
                    preconditionFailure.addViolationsBuilder().setType(VIOLATION_TYPE_INVALID).setSubject(INVALID_COMMAND).setDescription("working directory is not an input directory");
                    break;
                }
                directory = nextDirectory;
            }
        }
    }
}
Also used : DirectoryNode(build.bazel.remote.execution.v2.DirectoryNode) ByteString(com.google.protobuf.ByteString) OutputDirectory(build.bazel.remote.execution.v2.OutputDirectory) Directory(build.bazel.remote.execution.v2.Directory) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 14 with DirectoryNode

use of build.bazel.remote.execution.v2.DirectoryNode in project bazel-buildfarm by bazelbuild.

the class CFCExecFileSystem method treeContainsPath.

private static boolean treeContainsPath(String directoryPath, Map<Digest, Directory> directoriesIndex, Digest rootDigest) {
    Directory directory = directoriesIndex.get(rootDigest);
    for (String name : directoryPath.split("/")) {
        List<DirectoryNode> subdirs = directory.getDirectoriesList();
        int index = Collections.binarySearch(Lists.transform(subdirs, DirectoryNode::getName), name);
        if (index < 0) {
            return false;
        }
        directory = directoriesIndex.get(subdirs.get(index).getDigest());
    }
    return true;
}
Also used : DirectoryNode(build.bazel.remote.execution.v2.DirectoryNode) Directory(build.bazel.remote.execution.v2.Directory) OutputDirectory(build.buildfarm.worker.OutputDirectory)

Example 15 with DirectoryNode

use of build.bazel.remote.execution.v2.DirectoryNode in project bazel-buildfarm by bazelbuild.

the class CFCExecFileSystem method fetchInputs.

private Iterable<ListenableFuture<Void>> fetchInputs(Path path, Digest directoryDigest, Map<Digest, Directory> directoriesIndex, OutputDirectory outputDirectory, ImmutableList.Builder<String> inputFiles, ImmutableList.Builder<Digest> inputDirectories) throws IOException {
    Directory directory = directoriesIndex.get(directoryDigest);
    if (directory == null) {
        // not quite IO...
        throw new IOException("Directory " + DigestUtil.toString(directoryDigest) + " is not in directories index");
    }
    Iterable<ListenableFuture<Void>> downloads = directory.getFilesList().stream().map(fileNode -> put(path, fileNode, inputFiles)).collect(ImmutableList.toImmutableList());
    downloads = concat(downloads, directory.getSymlinksList().stream().map(symlinkNode -> putSymlink(path, symlinkNode)).collect(ImmutableList.toImmutableList()));
    for (DirectoryNode directoryNode : directory.getDirectoriesList()) {
        Digest digest = directoryNode.getDigest();
        String name = directoryNode.getName();
        OutputDirectory childOutputDirectory = outputDirectory != null ? outputDirectory.getChild(name) : null;
        Path dirPath = path.resolve(name);
        if (childOutputDirectory != null || !linkInputDirectories) {
            Files.createDirectories(dirPath);
            downloads = concat(downloads, fetchInputs(dirPath, digest, directoriesIndex, childOutputDirectory, inputFiles, inputDirectories));
        } else {
            downloads = concat(downloads, ImmutableList.of(transform(linkDirectory(dirPath, digest, directoriesIndex), (result) -> {
                // we saw null entries in the built immutable list without synchronization
                synchronized (inputDirectories) {
                    inputDirectories.add(digest);
                }
                return null;
            }, fetchService)));
        }
        if (Thread.currentThread().isInterrupted()) {
            break;
        }
    }
    return downloads;
}
Also used : Directory(build.bazel.remote.execution.v2.Directory) MoreExecutors.listeningDecorator(com.google.common.util.concurrent.MoreExecutors.listeningDecorator) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Command(build.bazel.remote.execution.v2.Command) DirectoryNode(build.bazel.remote.execution.v2.DirectoryNode) Futures.transformAsync(com.google.common.util.concurrent.Futures.transformAsync) Executors.newWorkStealingPool(java.util.concurrent.Executors.newWorkStealingPool) MINUTES(java.util.concurrent.TimeUnit.MINUTES) Utils.getInterruptiblyOrIOException(build.buildfarm.common.io.Utils.getInterruptiblyOrIOException) ContentAddressableStorage(build.buildfarm.cas.ContentAddressableStorage) DigestUtil(build.buildfarm.common.DigestUtil) Level(java.util.logging.Level) Action(build.bazel.remote.execution.v2.Action) UserPrincipal(java.nio.file.attribute.UserPrincipal) Directories(build.buildfarm.common.io.Directories) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) Digest(build.bazel.remote.execution.v2.Digest) Iterables.concat(com.google.common.collect.Iterables.concat) Map(java.util.Map) FileNode(build.bazel.remote.execution.v2.FileNode) Path(java.nio.file.Path) ExecutorService(java.util.concurrent.ExecutorService) Nullable(javax.annotation.Nullable) Utils.readdir(build.buildfarm.common.io.Utils.readdir) Futures.immediateFuture(com.google.common.util.concurrent.Futures.immediateFuture) MoreExecutors.shutdownAndAwaitTermination(com.google.common.util.concurrent.MoreExecutors.shutdownAndAwaitTermination) Dirent(build.buildfarm.common.io.Dirent) CASFileCache(build.buildfarm.cas.cfc.CASFileCache) Futures.allAsList(com.google.common.util.concurrent.Futures.allAsList) Files(java.nio.file.Files) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOException(java.io.IOException) Logger(java.util.logging.Logger) Preconditions.checkState(com.google.common.base.Preconditions.checkState) ExecutionException(java.util.concurrent.ExecutionException) Consumer(java.util.function.Consumer) List(java.util.List) Futures.immediateFailedFuture(com.google.common.util.concurrent.Futures.immediateFailedFuture) Iterables.filter(com.google.common.collect.Iterables.filter) SymlinkNode(build.bazel.remote.execution.v2.SymlinkNode) OutputDirectory(build.buildfarm.worker.OutputDirectory) Futures.transform(com.google.common.util.concurrent.Futures.transform) Collections(java.util.Collections) InputStream(java.io.InputStream) Path(java.nio.file.Path) Digest(build.bazel.remote.execution.v2.Digest) OutputDirectory(build.buildfarm.worker.OutputDirectory) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) DirectoryNode(build.bazel.remote.execution.v2.DirectoryNode) Utils.getInterruptiblyOrIOException(build.buildfarm.common.io.Utils.getInterruptiblyOrIOException) IOException(java.io.IOException) Directory(build.bazel.remote.execution.v2.Directory) OutputDirectory(build.buildfarm.worker.OutputDirectory)

Aggregations

DirectoryNode (build.bazel.remote.execution.v2.DirectoryNode)17 Directory (build.bazel.remote.execution.v2.Directory)15 Digest (build.bazel.remote.execution.v2.Digest)9 FileNode (build.bazel.remote.execution.v2.FileNode)9 ByteString (com.google.protobuf.ByteString)8 OutputDirectory (build.bazel.remote.execution.v2.OutputDirectory)6 IOException (java.io.IOException)5 Path (java.nio.file.Path)4 OutputDirectory (build.buildfarm.worker.OutputDirectory)3 SymlinkNode (build.bazel.remote.execution.v2.SymlinkNode)2 Utils.getInterruptiblyOrIOException (build.buildfarm.common.io.Utils.getInterruptiblyOrIOException)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Action (build.bazel.remote.execution.v2.Action)1 Command (build.bazel.remote.execution.v2.Command)1 ContentAddressableStorage (build.buildfarm.cas.ContentAddressableStorage)1 CASFileCache (build.buildfarm.cas.cfc.CASFileCache)1 DigestUtil (build.buildfarm.common.DigestUtil)1 DirectoryEntry (build.buildfarm.common.TreeIterator.DirectoryEntry)1 Directories (build.buildfarm.common.io.Directories)1 Dirent (build.buildfarm.common.io.Dirent)1