Valentin David pushed to branch bst-1.2 at BuildStream / buildstream
Commits:
-
1ad0a778
by Valentin David at 2019-02-13T09:42:43Z
-
e4b6b855
by Valentin David at 2019-02-13T11:41:24Z
2 changed files:
Changes:
| ... | ... | @@ -395,9 +395,7 @@ class CASCache(ArtifactCache): |
| 395 | 395 |
for chunk in iter(lambda: tmp.read(4096), b""):
|
| 396 | 396 |
h.update(chunk)
|
| 397 | 397 |
else:
|
| 398 |
- tmp = stack.enter_context(tempfile.NamedTemporaryFile(dir=self.tmpdir))
|
|
| 399 |
- # Set mode bits to 0644
|
|
| 400 |
- os.chmod(tmp.name, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
|
|
| 398 |
+ tmp = stack.enter_context(self._temporary_object())
|
|
| 401 | 399 |
|
| 402 | 400 |
if path:
|
| 403 | 401 |
with open(path, 'rb') as f:
|
| ... | ... | @@ -834,6 +832,19 @@ class CASCache(ArtifactCache): |
| 834 | 832 |
|
| 835 | 833 |
assert digest.size_bytes == os.fstat(stream.fileno()).st_size
|
| 836 | 834 |
|
| 835 |
+ # _temporary_object():
|
|
| 836 |
+ #
|
|
| 837 |
+ # Returns:
|
|
| 838 |
+ # (file): A file object to a named temporary file.
|
|
| 839 |
+ #
|
|
| 840 |
+ # Create a named temporary file with 0o0644 access rights.
|
|
| 841 |
+ @contextlib.contextmanager
|
|
| 842 |
+ def _temporary_object(self):
|
|
| 843 |
+ with tempfile.NamedTemporaryFile(dir=self.tmpdir) as f:
|
|
| 844 |
+ os.chmod(f.name,
|
|
| 845 |
+ stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
|
|
| 846 |
+ yield f
|
|
| 847 |
+ |
|
| 837 | 848 |
# _ensure_blob():
|
| 838 | 849 |
#
|
| 839 | 850 |
# Fetch and add blob if it's not already local.
|
| ... | ... | @@ -851,7 +862,7 @@ class CASCache(ArtifactCache): |
| 851 | 862 |
# already in local repository
|
| 852 | 863 |
return objpath
|
| 853 | 864 |
|
| 854 |
- with tempfile.NamedTemporaryFile(dir=self.tmpdir) as f:
|
|
| 865 |
+ with self._temporary_object() as f:
|
|
| 855 | 866 |
self._fetch_blob(remote, digest, f)
|
| 856 | 867 |
|
| 857 | 868 |
added_digest = self.add_object(path=f.name, link_directly=True)
|
| ... | ... | @@ -861,7 +872,7 @@ class CASCache(ArtifactCache): |
| 861 | 872 |
|
| 862 | 873 |
def _batch_download_complete(self, batch):
|
| 863 | 874 |
for digest, data in batch.send():
|
| 864 |
- with tempfile.NamedTemporaryFile(dir=self.tmpdir) as f:
|
|
| 875 |
+ with self._temporary_object() as f:
|
|
| 865 | 876 |
f.write(data)
|
| 866 | 877 |
f.flush()
|
| 867 | 878 |
|
| 1 | 1 |
import os
|
| 2 | 2 |
import shutil
|
| 3 |
+import stat
|
|
| 3 | 4 |
import pytest
|
| 4 | 5 |
from tests.testutils import cli, create_artifact_share, generate_junction
|
| 5 | 6 |
|
| ... | ... | @@ -358,3 +359,70 @@ def test_pull_missing_notifies_user(caplog, cli, tmpdir, datafiles): |
| 358 | 359 |
|
| 359 | 360 |
assert "INFO Remote ({}) does not have".format(share.repo) in result.stderr
|
| 360 | 361 |
assert "SKIPPED Pull" in result.stderr
|
| 362 |
+ |
|
| 363 |
+ |
|
| 364 |
+@pytest.mark.datafiles(DATA_DIR)
|
|
| 365 |
+def test_pull_access_rights(caplog, cli, tmpdir, datafiles):
|
|
| 366 |
+ project = str(datafiles)
|
|
| 367 |
+ checkout = os.path.join(str(tmpdir), 'checkout')
|
|
| 368 |
+ |
|
| 369 |
+ # Work-around datafiles not preserving mode
|
|
| 370 |
+ os.chmod(os.path.join(project, 'files/bin-files/usr/bin/hello'), 0o0755)
|
|
| 371 |
+ |
|
| 372 |
+ # We need a big file that does not go into a batch to test a different
|
|
| 373 |
+ # code path
|
|
| 374 |
+ os.makedirs(os.path.join(project, 'files/dev-files/usr/share'), exist_ok=True)
|
|
| 375 |
+ with open(os.path.join(project, 'files/dev-files/usr/share/big-file'), 'w') as f:
|
|
| 376 |
+ buf = ' ' * 4096
|
|
| 377 |
+ for _ in range(1024):
|
|
| 378 |
+ f.write(buf)
|
|
| 379 |
+ |
|
| 380 |
+ with create_artifact_share(os.path.join(str(tmpdir), 'artifactshare')) as share:
|
|
| 381 |
+ |
|
| 382 |
+ cli.configure({
|
|
| 383 |
+ 'artifacts': {'url': share.repo, 'push': True}
|
|
| 384 |
+ })
|
|
| 385 |
+ result = cli.run(project=project, args=['build', 'compose-all.bst'])
|
|
| 386 |
+ result.assert_success()
|
|
| 387 |
+ |
|
| 388 |
+ result = cli.run(project=project,
|
|
| 389 |
+ args=['checkout', '--hardlinks', '--no-integrate',
|
|
| 390 |
+ 'compose-all.bst', checkout])
|
|
| 391 |
+ result.assert_success()
|
|
| 392 |
+ |
|
| 393 |
+ st = os.lstat(os.path.join(checkout, 'usr/include/pony.h'))
|
|
| 394 |
+ assert stat.S_ISREG(st.st_mode)
|
|
| 395 |
+ assert stat.S_IMODE(st.st_mode) == 0o0644
|
|
| 396 |
+ |
|
| 397 |
+ st = os.lstat(os.path.join(checkout, 'usr/bin/hello'))
|
|
| 398 |
+ assert stat.S_ISREG(st.st_mode)
|
|
| 399 |
+ assert stat.S_IMODE(st.st_mode) == 0o0755
|
|
| 400 |
+ |
|
| 401 |
+ st = os.lstat(os.path.join(checkout, 'usr/share/big-file'))
|
|
| 402 |
+ assert stat.S_ISREG(st.st_mode)
|
|
| 403 |
+ assert stat.S_IMODE(st.st_mode) == 0o0644
|
|
| 404 |
+ |
|
| 405 |
+ shutil.rmtree(checkout)
|
|
| 406 |
+ |
|
| 407 |
+ artifacts = os.path.join(cli.directory, 'artifacts')
|
|
| 408 |
+ shutil.rmtree(artifacts)
|
|
| 409 |
+ |
|
| 410 |
+ result = cli.run(project=project, args=['pull', 'compose-all.bst'])
|
|
| 411 |
+ result.assert_success()
|
|
| 412 |
+ |
|
| 413 |
+ result = cli.run(project=project,
|
|
| 414 |
+ args=['checkout', '--hardlinks', '--no-integrate',
|
|
| 415 |
+ 'compose-all.bst', checkout])
|
|
| 416 |
+ result.assert_success()
|
|
| 417 |
+ |
|
| 418 |
+ st = os.lstat(os.path.join(checkout, 'usr/include/pony.h'))
|
|
| 419 |
+ assert stat.S_ISREG(st.st_mode)
|
|
| 420 |
+ assert stat.S_IMODE(st.st_mode) == 0o0644
|
|
| 421 |
+ |
|
| 422 |
+ st = os.lstat(os.path.join(checkout, 'usr/bin/hello'))
|
|
| 423 |
+ assert stat.S_ISREG(st.st_mode)
|
|
| 424 |
+ assert stat.S_IMODE(st.st_mode) == 0o0755
|
|
| 425 |
+ |
|
| 426 |
+ st = os.lstat(os.path.join(checkout, 'usr/share/big-file'))
|
|
| 427 |
+ assert stat.S_ISREG(st.st_mode)
|
|
| 428 |
+ assert stat.S_IMODE(st.st_mode) == 0o0644
|
