Skip to content

Commit 4b68532

Browse files
larsrc-googlecopybara-github
authored andcommitted
Make WorkerExecRoot not be a subclass of SandboxedSpawn.
It was only reusing a static method, yet inheriting a bunch of other things. This change should be a no-op. Prework for sandboxing multiplex workers. RELNOTES: None. PiperOrigin-RevId: 356456267
1 parent b075c2c commit 4b68532

File tree

5 files changed

+62
-73
lines changed

5 files changed

+62
-73
lines changed

src/main/java/com/google/devtools/build/lib/sandbox/AbstractContainerizingSandboxedSpawn.java

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,17 @@
1616

1717
import com.google.common.base.Preconditions;
1818
import com.google.common.collect.Iterables;
19-
import com.google.common.flogger.GoogleLogger;
2019
import com.google.devtools.build.lib.exec.TreeDeleter;
2120
import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxInputs;
2221
import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxOutputs;
2322
import com.google.devtools.build.lib.vfs.FileSystemUtils;
24-
import com.google.devtools.build.lib.vfs.FileSystemUtils.MoveResult;
2523
import com.google.devtools.build.lib.vfs.Path;
2624
import com.google.devtools.build.lib.vfs.PathFragment;
2725
import java.io.IOException;
2826
import java.util.LinkedHashSet;
2927
import java.util.List;
3028
import java.util.Map;
3129
import java.util.Set;
32-
import java.util.concurrent.atomic.AtomicBoolean;
3330
import javax.annotation.Nullable;
3431

3532
/**
@@ -38,10 +35,6 @@
3835
*/
3936
public abstract class AbstractContainerizingSandboxedSpawn implements SandboxedSpawn {
4037

41-
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
42-
43-
private static final AtomicBoolean warnedAboutMovesBeingCopies = new AtomicBoolean(false);
44-
4538
private final Path sandboxPath;
4639
private final Path sandboxExecRoot;
4740
private final List<String> arguments;
@@ -170,50 +163,9 @@ protected void createInputs(SandboxInputs inputs) throws IOException {
170163

171164
protected abstract void copyFile(Path source, Path target) throws IOException;
172165

173-
/**
174-
* Moves all given outputs from a root to another.
175-
*
176-
* <p>This is a support function to help with the implementation of {@link #copyOutputs(Path)}.
177-
*
178-
* @param outputs outputs to move as relative paths to a root
179-
* @param sourceRoot source directory from which to resolve outputs
180-
* @param targetRoot target directory to which to move the resolved outputs from the source
181-
* @throws IOException if any of the moves fails
182-
*/
183-
static void moveOutputs(SandboxOutputs outputs, Path sourceRoot, Path targetRoot)
184-
throws IOException {
185-
for (PathFragment output : Iterables.concat(outputs.files(), outputs.dirs())) {
186-
Path source = sourceRoot.getRelative(output);
187-
Path target = targetRoot.getRelative(output);
188-
if (source.isFile() || source.isSymbolicLink()) {
189-
// Ensure the target directory exists in the target. The directories for the action outputs
190-
// have already been created, but the spawn outputs may be different from the overall action
191-
// outputs. This is the case for test actions.
192-
target.getParentDirectory().createDirectoryAndParents();
193-
if (FileSystemUtils.moveFile(source, target).equals(MoveResult.FILE_COPIED)) {
194-
if (warnedAboutMovesBeingCopies.compareAndSet(false, true)) {
195-
logger.atWarning().log(
196-
"Moving files out of the sandbox (e.g. from %s to %s"
197-
+ ") had to be done with a file copy, which is detrimental to performance; are "
198-
+ " the two trees in different file systems?",
199-
source, target);
200-
}
201-
}
202-
} else if (source.isDirectory()) {
203-
try {
204-
source.renameTo(target);
205-
} catch (IOException e) {
206-
// Failed to move directory directly, thus move it recursively.
207-
target.createDirectory();
208-
FileSystemUtils.moveTreesBelow(source, target);
209-
}
210-
}
211-
}
212-
}
213-
214166
@Override
215167
public void copyOutputs(Path execRoot) throws IOException {
216-
moveOutputs(outputs, sandboxExecRoot, execRoot);
168+
SandboxHelpers.moveOutputs(outputs, sandboxExecRoot, execRoot);
217169
}
218170

219171
@Override

src/main/java/com/google/devtools/build/lib/sandbox/SandboxHelpers.java

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@
1616

1717
import com.google.auto.value.AutoValue;
1818
import com.google.common.collect.ImmutableSet;
19+
import com.google.common.collect.Iterables;
20+
import com.google.common.flogger.GoogleLogger;
1921
import com.google.devtools.build.lib.actions.ActionInput;
2022
import com.google.devtools.build.lib.actions.Artifact;
2123
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
2224
import com.google.devtools.build.lib.actions.Spawn;
2325
import com.google.devtools.build.lib.actions.cache.VirtualActionInput;
2426
import com.google.devtools.build.lib.actions.cache.VirtualActionInput.EmptyActionInput;
2527
import com.google.devtools.build.lib.analysis.test.TestConfiguration;
28+
import com.google.devtools.build.lib.vfs.FileSystemUtils;
29+
import com.google.devtools.build.lib.vfs.FileSystemUtils.MoveResult;
2630
import com.google.devtools.build.lib.vfs.Path;
2731
import com.google.devtools.build.lib.vfs.PathFragment;
2832
import com.google.devtools.common.options.OptionsParsingResult;
@@ -34,6 +38,7 @@
3438
import java.util.Map;
3539
import java.util.Set;
3640
import java.util.TreeMap;
41+
import java.util.concurrent.atomic.AtomicBoolean;
3742
import java.util.concurrent.atomic.AtomicInteger;
3843

3944
/**
@@ -42,7 +47,9 @@
4247
* <p>All sandboxed strategies within a build should share the same instance of this object.
4348
*/
4449
public final class SandboxHelpers {
50+
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
4551

52+
private static final AtomicBoolean warnedAboutMovesBeingCopies = new AtomicBoolean(false);
4653
/**
4754
* If true, materialize virtual inputs only inside the sandbox, not the output tree. This flag
4855
* exists purely to support rolling this out as the defaut in a controlled manner.
@@ -101,6 +108,48 @@ public static void atomicallyWriteVirtualInput(
101108
}
102109
}
103110

111+
/**
112+
* Moves all given outputs from a root to another.
113+
*
114+
* <p>This is a support function to help with the implementation of {@link
115+
* SandboxfsSandboxedSpawn#copyOutputs(Path)}.
116+
*
117+
* @param outputs outputs to move as relative paths to a root
118+
* @param sourceRoot source directory from which to resolve outputs
119+
* @param targetRoot target directory to which to move the resolved outputs from the source
120+
* @throws IOException if any of the moves fails
121+
*/
122+
public static void moveOutputs(SandboxOutputs outputs, Path sourceRoot, Path targetRoot)
123+
throws IOException {
124+
for (PathFragment output : Iterables.concat(outputs.files(), outputs.dirs())) {
125+
Path source = sourceRoot.getRelative(output);
126+
Path target = targetRoot.getRelative(output);
127+
if (source.isFile() || source.isSymbolicLink()) {
128+
// Ensure the target directory exists in the target. The directories for the action outputs
129+
// have already been created, but the spawn outputs may be different from the overall action
130+
// outputs. This is the case for test actions.
131+
target.getParentDirectory().createDirectoryAndParents();
132+
if (FileSystemUtils.moveFile(source, target).equals(MoveResult.FILE_COPIED)) {
133+
if (warnedAboutMovesBeingCopies.compareAndSet(false, true)) {
134+
logger.atWarning().log(
135+
"Moving files out of the sandbox (e.g. from %s to %s"
136+
+ ") had to be done with a file copy, which is detrimental to performance; are "
137+
+ "the two trees in different file systems?",
138+
source, target);
139+
}
140+
}
141+
} else if (source.isDirectory()) {
142+
try {
143+
source.renameTo(target);
144+
} catch (IOException e) {
145+
// Failed to move directory directly, thus move it recursively.
146+
target.createDirectory();
147+
FileSystemUtils.moveTreesBelow(source, target);
148+
}
149+
}
150+
}
151+
}
152+
104153
/** Wrapper class for the inputs of a sandbox. */
105154
public static final class SandboxInputs {
106155

@@ -178,7 +227,7 @@ private static void materializeVirtualInput(
178227
*/
179228
public void materializeVirtualInputs(Path sandboxExecRoot) throws IOException {
180229
for (VirtualActionInput input : virtualInputs) {
181-
materializeVirtualInput(input, sandboxExecRoot, /*needsDelete=*/ false);
230+
materializeVirtualInput(input, sandboxExecRoot, /*isExecRootSandboxed=*/ false);
182231
}
183232
}
184233
}
@@ -257,7 +306,7 @@ public SandboxInputs processInputFiles(
257306
} else {
258307
if (actionInput instanceof VirtualActionInput) {
259308
SandboxInputs.materializeVirtualInput(
260-
(VirtualActionInput) actionInput, execRoot, /*needsDelete=*/ true);
309+
(VirtualActionInput) actionInput, execRoot, /* isExecRootSandboxed=*/ true);
261310
}
262311

263312
if (actionInput.isSymlink()) {

src/main/java/com/google/devtools/build/lib/sandbox/SandboxfsSandboxedSpawn.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public void copyOutputs(Path targetExecRoot) throws IOException {
201201
// TODO(jmmv): If we knew the targetExecRoot when setting up the spawn, we may be able to
202202
// configure sandboxfs so that the output files are written directly to their target locations.
203203
// This would avoid having to move them after-the-fact.
204-
AbstractContainerizingSandboxedSpawn.moveOutputs(outputs, sandboxScratchDir, targetExecRoot);
204+
SandboxHelpers.moveOutputs(outputs, sandboxScratchDir, targetExecRoot);
205205
}
206206

207207
@Override

src/main/java/com/google/devtools/build/lib/worker/WorkerExecRoot.java

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,10 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.lib.worker;
1515

16-
import com.google.common.collect.ImmutableList;
17-
import com.google.common.collect.ImmutableMap;
18-
import com.google.common.collect.ImmutableSet;
1916
import com.google.common.collect.Iterables;
17+
import com.google.devtools.build.lib.sandbox.SandboxHelpers;
2018
import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxInputs;
2119
import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxOutputs;
22-
import com.google.devtools.build.lib.sandbox.SymlinkedSandboxedSpawn;
23-
import com.google.devtools.build.lib.sandbox.SynchronousTreeDeleter;
2420
import com.google.devtools.build.lib.vfs.FileStatus;
2521
import com.google.devtools.build.lib.vfs.FileSystemUtils;
2622
import com.google.devtools.build.lib.vfs.Path;
@@ -32,31 +28,20 @@
3228
import java.util.Set;
3329

3430
/** Creates and manages the contents of a working directory of a persistent worker. */
35-
final class WorkerExecRoot extends SymlinkedSandboxedSpawn {
31+
final class WorkerExecRoot {
3632
private final Path workDir;
3733
private final SandboxInputs inputs;
3834
private final SandboxOutputs outputs;
3935
private final Set<PathFragment> workerFiles;
4036

4137
public WorkerExecRoot(
4238
Path workDir, SandboxInputs inputs, SandboxOutputs outputs, Set<PathFragment> workerFiles) {
43-
super(
44-
workDir,
45-
workDir,
46-
ImmutableList.of(),
47-
ImmutableMap.of(),
48-
inputs,
49-
outputs,
50-
ImmutableSet.of(),
51-
new SynchronousTreeDeleter(),
52-
/*statisticsPath=*/ null);
5339
this.workDir = workDir;
5440
this.inputs = inputs;
5541
this.outputs = outputs;
5642
this.workerFiles = workerFiles;
5743
}
5844

59-
@Override
6045
public void createFileSystem() throws IOException {
6146
workDir.createDirectoryAndParents();
6247

@@ -173,4 +158,8 @@ private void createInputs(Iterable<PathFragment> inputsToCreate) throws IOExcept
173158
}
174159
}
175160
}
161+
162+
public void copyOutputs(Path execRoot) throws IOException {
163+
SandboxHelpers.moveOutputs(outputs, workDir, execRoot);
164+
}
176165
}

src/test/java/com/google/devtools/build/lib/sandbox/AbstractContainerizingSandboxedSpawnTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ public void testMoveOutputs() throws Exception {
7878
Path outputsDir = testRoot.getRelative("outputs");
7979
outputsDir.createDirectory();
8080
outputsDir.getRelative("very").createDirectory();
81-
AbstractContainerizingSandboxedSpawn.moveOutputs(
82-
SandboxOutputs.create(outputs, outputDirs), execRoot, outputsDir);
81+
SandboxHelpers.moveOutputs(SandboxOutputs.create(outputs, outputDirs), execRoot, outputsDir);
8382

8483
assertThat(outputsDir.getRelative("very/output.txt").isFile(Symlinks.NOFOLLOW)).isTrue();
8584
assertThat(outputsDir.getRelative("very/output.link").isSymbolicLink()).isTrue();
@@ -130,7 +129,7 @@ public void renameTo(Path source, Path target) throws IOException {
130129
testRoot.createDirectoryAndParents();
131130

132131
FileCopyWarningTracker tracker = new FileCopyWarningTracker();
133-
Logger logger = Logger.getLogger(AbstractContainerizingSandboxedSpawn.class.getName());
132+
Logger logger = Logger.getLogger(SandboxHelpers.class.getName());
134133
logger.setUseParentHandlers(false);
135134
logger.addHandler(tracker);
136135

@@ -153,7 +152,7 @@ public void renameTo(Path source, Path target) throws IOException {
153152
outputsDir.createDirectory();
154153
outputsDir.getRelative("very").createDirectory();
155154
outputsDir.getRelative("much").createDirectory();
156-
AbstractContainerizingSandboxedSpawn.moveOutputs(
155+
SandboxHelpers.moveOutputs(
157156
SandboxOutputs.create(outputs, ImmutableSet.of()), execRoot, outputsDir);
158157

159158
assertThat(outputsDir.getRelative("very/output1.txt").isFile(Symlinks.NOFOLLOW)).isTrue();

0 commit comments

Comments
 (0)