Skip to content

Commit

Permalink
Fix Pex isolation losing perm bits.
Browse files Browse the repository at this point in the history
Now that PEXes only run in unzipped mode and venv mode, they always
will be isolating from loose sources and the resources copy mechanism
is no longer needed.
  • Loading branch information
jsirois committed Mar 10, 2022
1 parent a602c1a commit 990fbcd
Showing 1 changed file with 22 additions and 31 deletions.
53 changes: 22 additions & 31 deletions pex/third_party/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
import importlib
import os
import re
import shutil
import sys
import zipfile
from collections import OrderedDict, namedtuple
from contextlib import closing


# NB: All pex imports are performed lazily to play well with the un-imports performed by both the
Expand Down Expand Up @@ -346,8 +344,13 @@ def isolated():
global _ISOLATED
if _ISOLATED is None:
from pex import vendor
from pex.common import atomic_directory, is_pyc_temporary_file
from pex.third_party.pkg_resources import resource_isdir, resource_listdir, resource_stream
from pex.common import (
atomic_directory,
filter_pyc_dirs,
filter_pyc_files,
is_pyc_temporary_file,
safe_copy,
)
from pex.util import CacheHelper
from pex.variables import ENV

Expand All @@ -360,32 +363,6 @@ def isolated():
for vendor_spec in vendor.iter_vendor_specs()
)

# TODO(John Sirois): Unify with `pex.util.DistributionHelper.access_zipped_assets`.
def recursive_copy(srcdir, dstdir):
os.mkdir(dstdir)
for entry_name in resource_listdir(module, srcdir):
if not entry_name:
# The `resource_listdir` function returns a '' entry name for the directory
# entry itself if it is either present on the filesystem or present as an
# explicit zip entry. Since we only care about files and subdirectories at this
# point, skip these entries.
continue
# NB: Resource path components are always separated by /, on all systems.
src_entry = "{}/{}".format(srcdir, entry_name) if srcdir else entry_name
dst_entry = os.path.join(dstdir, entry_name)
if resource_isdir(module, src_entry):
if os.path.basename(src_entry) == "__pycache__":
continue
recursive_copy(src_entry, dst_entry)
elif (
not entry_name.endswith(".pyc")
and not is_pyc_temporary_file(entry_name)
and src_entry not in vendor_lockfiles
):
with open(dst_entry, "wb") as fp:
with closing(resource_stream(module, src_entry)) as resource:
shutil.copyfileobj(resource, fp)

pex_path = os.path.join(vendor.VendorSpec.ROOT, "pex")
with _tracer().timed("Hashing pex"):
assert os.path.isdir(pex_path), (
Expand All @@ -400,7 +377,21 @@ def recursive_copy(srcdir, dstdir):
with atomic_directory(isolated_dir, exclusive=True) as chroot:
if not chroot.is_finalized():
with _tracer().timed("Extracting pex to {}".format(isolated_dir)):
recursive_copy("", os.path.join(chroot.work_dir, "pex"))
pex_path = os.path.join(vendor.VendorSpec.ROOT, "pex")
for root, dirs, files in os.walk(pex_path):
relroot = os.path.relpath(root, pex_path)
for d in filter_pyc_dirs(dirs):
os.makedirs(os.path.join(chroot.work_dir, "pex", relroot, d))
for f in filter_pyc_files(files):
rel_f = os.path.join(relroot, f)
if (
not is_pyc_temporary_file(rel_f)
and rel_f not in vendor_lockfiles
):
safe_copy(
os.path.join(root, f),
os.path.join(chroot.work_dir, "pex", rel_f),
)

_ISOLATED = IsolationResult(pex_hash=dir_hash, chroot_path=isolated_dir)
return _ISOLATED
Expand Down

0 comments on commit 990fbcd

Please sign in to comment.