Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • willsalmon/buildstream
  • CumHoleZH/buildstream
  • tchaik/buildstream
  • DCotyPortfolio/buildstream
  • jesusoctavioas/buildstream
  • patrickmmartin/buildstream
  • franred/buildstream
  • tintou/buildstream
  • alatiera/buildstream
  • martinblanchard/buildstream
  • neverdie22042524/buildstream
  • Mattlk13/buildstream
  • PServers/buildstream
  • phamnghia610909/buildstream
  • chiaratolentino/buildstream
  • eysz7-x-x/buildstream
  • kerrick1/buildstream
  • matthew-yates/buildstream
  • twofeathers/buildstream
  • mhadjimichael/buildstream
  • pointswaves/buildstream
  • Mr.JackWilson/buildstream
  • Tw3akG33k/buildstream
  • AlexFazakas/buildstream
  • eruidfkiy/buildstream
  • clamotion2/buildstream
  • nanonyme/buildstream
  • wickyjaaa/buildstream
  • nmanchev/buildstream
  • bojorquez.ja/buildstream
  • mostynb/buildstream
  • highpit74/buildstream
  • Demo112/buildstream
  • ba2014sheer/buildstream
  • tonimadrino/buildstream
  • usuario2o/buildstream
  • Angelika123456/buildstream
  • neo355/buildstream
  • corentin-ferlay/buildstream
  • coldtom/buildstream
  • wifitvbox81/buildstream
  • 358253885/buildstream
  • seanborg/buildstream
  • SotK/buildstream
  • DouglasWinship/buildstream
  • karansthr97/buildstream
  • louib/buildstream
  • bwh-ct/buildstream
  • robjh/buildstream
  • we88c0de/buildstream
  • zhengxian5555/buildstream
51 results
Show changes
Commits on Source (4)
......@@ -49,6 +49,7 @@ remote - stage files from remote urls
"""
import os
import stat
from buildstream import SourceError, utils
from ._downloadablefilesource import DownloadableFileSource
......@@ -75,6 +76,7 @@ class RemoteSource(DownloadableFileSource):
dest = os.path.join(directory, self.filename)
with self.timed_activity("Staging remote file to {}".format(dest)):
utils.safe_copy(self._get_mirror_file(), dest)
os.chmod(dest, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
def setup():
......
......@@ -49,10 +49,17 @@ zip - stage files from zip archives
# To extract the root of the archive directly, this can be set
# to an empty string.
base-dir: '*'
.. attention::
File permissions are not preserved. All extracted directories have
permissions 0755 and all extracted files have permissions 0644.
"""
import os
import zipfile
import stat
from buildstream import SourceError
from buildstream import utils
......@@ -74,6 +81,9 @@ class ZipSource(DownloadableFileSource):
return super().get_unique_key() + [self.base_dir]
def stage(self, directory):
exec_rights = (stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) & ~(stat.S_IWGRP | stat.S_IWOTH)
noexec_rights = exec_rights & ~(stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
try:
with zipfile.ZipFile(self._get_mirror_file()) as archive:
base_dir = None
......@@ -81,9 +91,27 @@ class ZipSource(DownloadableFileSource):
base_dir = self._find_base_dir(archive, self.base_dir)
if base_dir:
archive.extractall(path=directory, members=self._extract_members(archive, base_dir))
members = self._extract_members(archive, base_dir)
else:
archive.extractall(path=directory)
members = archive.namelist()
for member in members:
written = archive.extract(member, path=directory)
# zipfile.extract might create missing directories
rel = os.path.relpath(written, start=directory)
assert not os.path.isabs(rel)
rel = os.path.dirname(rel)
while rel:
os.chmod(os.path.join(directory, rel), exec_rights)
rel = os.path.dirname(rel)
if os.path.islink(written):
pass
elif os.path.isdir(written):
os.chmod(written, exec_rights)
else:
os.chmod(written, noexec_rights)
except (zipfile.BadZipFile, zipfile.LargeZipFile, OSError) as e:
raise SourceError("{}: Error staging source: {}".format(self, e)) from e
......
......@@ -1010,6 +1010,15 @@ def _call(*popenargs, terminate=False, **kwargs):
process = None
old_preexec_fn = kwargs.get('preexec_fn')
if 'preexec_fn' in kwargs:
del kwargs['preexec_fn']
def preexec_fn():
os.umask(stat.S_IWGRP | stat.S_IWOTH)
if old_preexec_fn is not None:
old_preexec_fn()
# Handle termination, suspend and resume
def kill_proc():
if process:
......@@ -1054,7 +1063,7 @@ def _call(*popenargs, terminate=False, **kwargs):
os.killpg(group_id, signal.SIGCONT)
with _signals.suspendable(suspend_proc, resume_proc), _signals.terminator(kill_proc):
process = subprocess.Popen(*popenargs, **kwargs)
process = subprocess.Popen(*popenargs, preexec_fn=preexec_fn, **kwargs)
output, _ = process.communicate()
exit_code = process.poll()
......
import os
import pytest
from buildstream import _yaml, utils
from tests.testutils import cli, create_repo, ALL_REPO_KINDS
DATA_DIR = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
"project"
)
def create_test_file(*path, mode=0o644, content='content\n'):
path = os.path.join(*path)
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w') as f:
f.write(content)
os.fchmod(f.fileno(), mode)
def create_test_directory(*path, mode=0o644):
create_test_file(*path, '.keep', content='')
path = os.path.join(*path)
os.chmod(path, mode)
@pytest.mark.integration
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.parametrize("kind", [(kind) for kind in ALL_REPO_KINDS] + ['local'])
def test_deterministic_source_umask(cli, tmpdir, datafiles, kind):
project = str(datafiles)
element_name = 'list'
element_path = os.path.join(project, 'elements', element_name)
repodir = os.path.join(str(tmpdir), 'repo')
sourcedir = os.path.join(project, 'source')
create_test_file(sourcedir, 'a.txt', mode=0o700)
create_test_file(sourcedir, 'b.txt', mode=0o755)
create_test_file(sourcedir, 'c.txt', mode=0o600)
create_test_file(sourcedir, 'd.txt', mode=0o400)
create_test_file(sourcedir, 'e.txt', mode=0o644)
create_test_file(sourcedir, 'f.txt', mode=0o4755)
create_test_file(sourcedir, 'g.txt', mode=0o2755)
create_test_file(sourcedir, 'h.txt', mode=0o1755)
create_test_directory(sourcedir, 'dir-a', mode=0o0700)
create_test_directory(sourcedir, 'dir-c', mode=0o0755)
create_test_directory(sourcedir, 'dir-d', mode=0o4755)
create_test_directory(sourcedir, 'dir-e', mode=0o2755)
create_test_directory(sourcedir, 'dir-f', mode=0o1755)
if kind == 'local':
source = {'kind': 'local',
'path': 'source'}
else:
repo = create_repo(kind, repodir)
ref = repo.create(sourcedir)
source = repo.source_config(ref=ref)
element = {
'kind': 'manual',
'depends': [
{
'filename': 'base.bst',
'type': 'build'
}
],
'sources': [
source
],
'config': {
'install-commands': [
'ls -l >"%{install-root}/ls-l"'
]
}
}
_yaml.dump(element, element_path)
def get_value_for_umask(umask):
checkoutdir = os.path.join(str(tmpdir), 'checkout-{}'.format(umask))
old_umask = os.umask(umask)
try:
result = cli.run(project=project, args=['build', element_name])
result.assert_success()
result = cli.run(project=project, args=['checkout', element_name, checkoutdir])
result.assert_success()
with open(os.path.join(checkoutdir, 'ls-l'), 'r') as f:
return f.read()
finally:
os.umask(old_umask)
cli.remove_artifact_from_cache(project, element_name)
assert get_value_for_umask(0o022) == get_value_for_umask(0o077)
@pytest.mark.integration
@pytest.mark.datafiles(DATA_DIR)
def test_deterministic_source_local(cli, tmpdir, datafiles):
"""Only user rights should be considered for local source.
"""
project = str(datafiles)
element_name = 'test'
element_path = os.path.join(project, 'elements', element_name)
sourcedir = os.path.join(project, 'source')
element = {
'kind': 'manual',
'depends': [
{
'filename': 'base.bst',
'type': 'build'
}
],
'sources': [
{
'kind': 'local',
'path': 'source'
}
],
'config': {
'install-commands': [
'ls -l >"%{install-root}/ls-l"'
]
}
}
_yaml.dump(element, element_path)
def get_value_for_mask(mask):
checkoutdir = os.path.join(str(tmpdir), 'checkout-{}'.format(mask))
create_test_file(sourcedir, 'a.txt', mode=0o644 & mask)
create_test_file(sourcedir, 'b.txt', mode=0o755 & mask)
create_test_file(sourcedir, 'c.txt', mode=0o4755 & mask)
create_test_file(sourcedir, 'd.txt', mode=0o2755 & mask)
create_test_file(sourcedir, 'e.txt', mode=0o1755 & mask)
create_test_directory(sourcedir, 'dir-a', mode=0o0755 & mask)
create_test_directory(sourcedir, 'dir-b', mode=0o4755 & mask)
create_test_directory(sourcedir, 'dir-c', mode=0o2755 & mask)
create_test_directory(sourcedir, 'dir-d', mode=0o1755 & mask)
try:
result = cli.run(project=project, args=['build', element_name])
result.assert_success()
result = cli.run(project=project, args=['checkout', element_name, checkoutdir])
result.assert_success()
with open(os.path.join(checkoutdir, 'ls-l'), 'r') as f:
return f.read()
finally:
cli.remove_artifact_from_cache(project, element_name)
assert get_value_for_mask(0o7777) == get_value_for_mask(0o0700)