From 5b6b44b754de663154b0eef90bcbe366f7446394 Mon Sep 17 00:00:00 2001 From: Serge Dubrouski Date: Tue, 24 Oct 2023 13:49:19 -0700 Subject: [PATCH] [antlir] One more fix for fs_util Summary: It looks like Antlir doesn't always materialize Python resources properly. Existing check for `path.name` passes but that still doesn't guarantee that the file exists. Switching to `os.path.exists` check instead. Test Plan: ``` buck2 test fbcode//antlir:test-fs-utils buck2 test fbcode//antlir:test-fs-utils-path-resource-zip buck2 test fbcode//antlir/bzl/genrule/facebook/chef_solo:test-centos9-fbcode-chef-solo-in-layer buck2 test fbcode//antlir/bzl/genrule/facebook/chef_solo:test-centos8-fbcode-chef-solo-in-layer ``` Reviewed By: justintrudell Differential Revision: D50604944 fbshipit-source-id: 64752cbf6a53b58605ca40b939498cfa2372d8a1 --- antlir/fs_utils.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/antlir/fs_utils.py b/antlir/fs_utils.py index 4683f62849..f15a9e0e0c 100644 --- a/antlir/fs_utils.py +++ b/antlir/fs_utils.py @@ -365,19 +365,22 @@ def resource(cls, package, name: str, *, exe: bool) -> Iterator["Path"]: open-source Python package formats: "zip", "fastzip", "pex", "xar". """ with importlib.resources.open_binary(package, name) as rsrc_in: - # This check is clowny, but `importlib` doesn't provide a clean - # way to ask if the resource already exists on disk. - if hasattr(rsrc_in, "name"): - # Future: once the bug with the XAR `access` implementation - # is fixed (https://fburl.com/42s41c0g), this can just check - # for boolean equality. - if not exe or (exe and os.access(rsrc_in.name, os.X_OK)): - yield Path(rsrc_in.name).abspath() - return - else: # pragma: no cover - # why does this happen? who knows but we can make a copy of - # the binary that _is_ executable - log.warning(f"{package}.{name} is not executable") + # Future: once the bug with the XAR `access` implementation + # is fixed (https://fburl.com/42s41c0g), this can just check + # for boolean equality. + if ( + hasattr(rsrc_in, "name") + and os.path.exists(rsrc_in.name) + and (not exe or (exe and os.access(rsrc_in.name, os.X_OK))) + ): + yield Path(rsrc_in.name).abspath() + return + + # why does this happen? who knows but we can make a copy of + # the binary that _is_ executable + log.warning( + f"{package}.{name} doesn't exist or is not executable" + ) # pragma: no cover # The resource has no path, so we have to materialize it. # # This code path is not reached by our coverage harness,