Skip to content

Commit 7e88474

Browse files
committed
Store sandbox state in Artifact proto
This is stored only when also storing the build tree. It is used to configure the sandbox for `bst shell --use-buildtree`. This is required for elements that create subsandboxes as part of `configure_sandbox()`.
1 parent 50c5273 commit 7e88474

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

src/buildstream/_artifact.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ def get_extract_key(self):
200200
# variables (Variables): The element's Variables
201201
# environment (dict): dict of the element's environment variables
202202
# sandboxconfig (SandboxConfig): The element's SandboxConfig
203+
# buildsandbox (Sandbox): The element's configured build sandbox
203204
#
204205
def cache(
205206
self,
@@ -213,6 +214,7 @@ def cache(
213214
variables,
214215
environment,
215216
sandboxconfig,
217+
buildsandbox,
216218
):
217219

218220
context = self._context
@@ -317,6 +319,19 @@ def cache(
317319
rootvdir._import_files_internal(buildrootvdir, properties=properties, collect_result=False)
318320
artifact.buildroot.CopyFrom(rootvdir._get_digest())
319321

322+
if buildsandbox is not None:
323+
sandbox_env = buildsandbox._get_configured_environment()
324+
if sandbox_env:
325+
for key, value in sorted(sandbox_env.items()):
326+
artifact.buildsandbox.environment.add(name=key, value=value)
327+
328+
artifact.buildsandbox.working_directory = buildsandbox._get_work_directory()
329+
330+
for subsandbox in buildsandbox._get_subsandboxes():
331+
vdir = subsandbox.get_virtual_directory()
332+
digest = artifact.buildsandbox.subsandbox_digests.add()
333+
digest.CopyFrom(vdir._get_digest())
334+
320335
os.makedirs(os.path.dirname(os.path.join(self._artifactdir, element.get_artifact_name())), exist_ok=True)
321336
keys = utils._deduplicate([self._cache_key, self._weak_cache_key])
322337
for key in keys:
@@ -681,6 +696,21 @@ def pull(self, *, pull_buildtrees):
681696

682697
return True
683698

699+
def configure_sandbox(self, sandbox):
700+
artifact = self._get_proto()
701+
702+
if artifact.buildsandbox and artifact.buildsandbox.environment:
703+
env = {}
704+
for env_var in artifact.buildsandbox.environment:
705+
env[env_var.name] = env_var.value
706+
else:
707+
env = self.load_environment()
708+
709+
sandbox.set_environment(env)
710+
711+
if artifact.buildsandbox and artifact.buildsandbox.working_directory:
712+
sandbox.set_work_directory(artifact.buildsandbox.working_directory)
713+
684714
# load_proto()
685715
#
686716
# Returns:

src/buildstream/_artifactcache.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,10 @@ def _push_artifact_blobs(self, artifact, artifact_digest, remote):
303303
except FileNotFoundError:
304304
pass
305305

306+
if artifact_proto.buildsandbox:
307+
for subsandbox_digest in artifact_proto.buildsandbox.subsandbox_digests:
308+
self.cas._send_directory(remote, subsandbox_digest)
309+
306310
digests = [artifact_digest, artifact_proto.low_diversity_meta, artifact_proto.high_diversity_meta]
307311

308312
if str(artifact_proto.public_data):
@@ -361,6 +365,9 @@ def _push_artifact_proto(self, element, artifact, artifact_digest, remote):
361365
referenced_directories.append(artifact_proto.sources)
362366
if artifact_proto.buildroot:
363367
referenced_directories.append(artifact_proto.buildroot)
368+
if artifact_proto.buildsandbox:
369+
for subsandbox_digest in artifact_proto.buildsandbox.subsandbox_digests:
370+
referenced_directories.append(subsandbox_digest)
364371

365372
referenced_blobs = [artifact_proto.low_diversity_meta, artifact_proto.high_diversity_meta] + [
366373
log_file.digest for log_file in artifact_proto.logs
@@ -419,6 +426,9 @@ def _pull_artifact_storage(self, element, key, artifact_digest, remote, pull_bui
419426
self.cas.fetch_directory(remote, artifact.buildtree)
420427
if str(artifact.buildroot):
421428
self.cas.fetch_directory(remote, artifact.buildroot)
429+
if artifact.buildsandbox:
430+
for subsandbox_digest in artifact.buildsandbox.subsandbox_digests:
431+
self.cas.fetch_directory(remote, subsandbox_digest)
422432

423433
digests = [artifact.low_diversity_meta, artifact.high_diversity_meta]
424434
if str(artifact.public_data):

src/buildstream/element.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,18 +1440,25 @@ def _prepare_sandbox(self, scope, shell=False, integrate=True, usebuildtree=Fals
14401440
# pylint: disable-next=contextmanager-generator-missing-cleanup
14411441
with self.__sandbox(config=self.__sandbox_config, allow_remote=False) as sandbox:
14421442

1443-
# Configure always comes first, and we need it.
1444-
self.__configure_sandbox(sandbox)
1445-
14461443
if usebuildtree:
1444+
# Configure the sandbox from artifact metadata
1445+
self.__artifact.configure_sandbox(sandbox)
1446+
14471447
# Use the cached buildroot directly
14481448
buildrootvdir = self.__artifact.get_buildroot()
14491449
sandbox_vroot = sandbox.get_virtual_directory()
14501450
sandbox_vroot._import_files_internal(buildrootvdir, collect_result=False)
14511451
elif shell and scope == _Scope.BUILD:
1452+
self.__configure_sandbox(sandbox)
14521453
# Stage what we need
14531454
self.__stage(sandbox)
14541455
else:
1456+
# Runtime shell or `bst artifact checkout`
1457+
1458+
# Don't call `configure_sandbox()` as that may attempt to construct subsandboxes
1459+
# with build dependencies and we're not setting up a build sandbox.
1460+
sandbox.set_environment(self.get_environment())
1461+
14551462
# Stage deps in the sandbox root
14561463
with self.timed_activity("Staging dependencies", silent_nested=True), self.__collect_overlaps(sandbox):
14571464
self._stage_dependency_artifacts(sandbox, scope)
@@ -1787,6 +1794,7 @@ def _cache_artifact(self, sandbox, collect):
17871794
variables=self.__variables,
17881795
environment=self.__environment,
17891796
sandboxconfig=self.__sandbox_config,
1797+
buildsandbox=sandbox if buildrootvdir else None,
17901798
)
17911799

17921800
if collect is not None and collectvdir is None:

0 commit comments

Comments
 (0)