Re: [yocto-patches] [yocto-autobuilder-helper][PATCH v2 01/10] scripts/utils: fix stale extraction dir when tarball is updated

Paul Barker <[email protected]>
Newsgroups org.yoctoproject.lists.yocto-patches
Message-ID <[email protected]>
On Mon, 2026-06-01 at 16:18 -0700, Tim Orling via lists.yoctoproject.org
wrote:
> From: Tim Orling <[email protected]>
> 
> Previously the entire download/cache-validation block in
> setup_tools_tarball() was guarded by `if not os.path.exists(btdir)`.
> Once the extraction directory existed from a prior build, every
> subsequent call was a no-op: the cached tarball was never re-validated,
> so a freshly-published SDK (e.g. vcontainer-tarball-latest) was silently
> ignored and the stale btdir kept being used.
> 
> Fix by moving the lock/download block outside the btdir existence guard
> so cache validation always runs. Track tarball_updated to know when the
> cached download was actually replaced, then remove the stale btdir when
> True so the fresh tarball is re-extracted.
> 
> Also add an mtime-based staleness check for local-path (cp) sources so
> that a newer source file automatically invalidates the cached copy.
> 
> AI-Generated: Claude Cowork Sonnet 4.6
> Signed-off-by: Tim Orling <[email protected]>
> ---
>  scripts/utils.py | 64 +++++++++++++++++++++++++++++++-----------------
>  1 file changed, 41 insertions(+), 23 deletions(-)
> 
> diff --git a/scripts/utils.py b/scripts/utils.py
> index 88842f0..87acad6 100644
> --- a/scripts/utils.py
> +++ b/scripts/utils.py
> @@ -481,31 +481,49 @@ def setup_tools_tarball(ourconfig, btdir, bttarball, name="buildtools"):
>          if ";" in bttarball:
>              bttarball, sha256 = bttarball.split(";")
>          btdir = os.path.abspath(btdir)
> +        btdlpath = getconfig("BASE_SHAREDDIR", ourconfig) + "/cluster-downloads-cache/" + os.path.basename(bttarball)
> +        btlock = btdlpath + ".lock"
> +        if not os.path.exists(os.path.dirname(btdlpath)):
> +            os.makedirs(os.path.dirname(btdlpath), exist_ok=True)
> +        # Always run the cache-validation / download step so that a freshly
> +        # published tarball is detected even when btdir already exists from a
> +        # previous build.  tarball_updated is set to True whenever the cached
> +        # download is replaced, which triggers removal of the stale btdir.
> +        tarball_updated = False
> +        while True:
> +            try:
> +                with open(btlock, 'a+') as lf:
> +                    fileno = lf.fileno()
> +                    fcntl.flock(fileno, fcntl.LOCK_EX)
> +                    if sha256 and os.path.exists(btdlpath):
> +                        dl_sha256 = sha256_file(btdlpath)
> +                        if dl_sha256 != sha256:
> +                            os.unlink(btdlpath)
> +                    elif bttarball.startswith("/") and os.path.exists(btdlpath):
> +                        # For local-path sources (e.g. vcontainer-tarball-latest)
> +                        # invalidate the cached copy when the source is newer so
> +                        # that a freshly-published tarball is always picked up.
> +                        if os.path.getmtime(bttarball) > os.path.getmtime(btdlpath):
> +                            os.unlink(btdlpath)
> +                        os.unlink(btdlpath)
> +                    if not os.path.exists(btdlpath):
> +                        if bttarball.startswith("/"):
> +                            subprocess.check_call(["cp", bttarball, btdlpath])
> +                        else:
> +                            subprocess.check_call(["wget", "-O", btdlpath, bttarball])
> +                        os.chmod(btdlpath, 0o775)
> +                        tarball_updated = True
> +                break
> +            except OSError:
> +                # We raced with someone else, try again
> +                pass

Hi Tim,

This loop allows us to handle random OSError conditions caused by a
race, but it turns a deterministic OSError into an infinite loop. The
logic already exists, you're just moving it around, but now I have seen
it I cannot unsee it!

Should we add a timeout while we are here?

> +        # If the underlying tarball changed, remove any stale extraction
> +        # directory so it is re-extracted below.
> +        if tarball_updated and os.path.exists(btdir):
> +            print("Removing stale %s extraction at %s" % (name, btdir))
> +            subprocess.check_call(["rm", "-rf", btdir])
>          if not os.path.exists(btdir):
> -            btdlpath = getconfig("BASE_SHAREDDIR", ourconfig) + "/cluster-downloads-cache/" + os.path.basename(bttarball)
>              print("Extracting %s %s" % (name, bttarball))
> -            btlock = btdlpath + ".lock"
> -            if not os.path.exists(os.path.dirname(btdlpath)):
> -                os.makedirs(os.path.dirname(btdlpath), exist_ok=True)
> -            while True:
> -                try:
> -                    with open(btlock, 'a+') as lf:
> -                        fileno = lf.fileno()
> -                        fcntl.flock(fileno, fcntl.LOCK_EX)
> -                        if sha256 and os.path.exists(btdlpath):
> -                            dl_sha256 = sha256_file(btdlpath)
> -                            if dl_sha256 != sha256:
> -                                os.unlink(btdlpath)
> -                        if not os.path.exists(btdlpath):
> -                            if bttarball.startswith("/"):
> -                                subprocess.check_call(["cp", bttarball, btdlpath])
> -                            else:
> -                                subprocess.check_call(["wget", "-O", btdlpath, bttarball])
> -                            os.chmod(btdlpath, 0o775)
> -                    break
> -                except OSError:
> -                    # We raced with someone else, try again
> -                    pass
>              subprocess.check_call(["bash", btdlpath, "-d", btdir, "-y"])
>          enable_tools_tarball(btdir, name)

Best regards,

-- 
Paul Barker
signature.asc (application/pgp-signature, 252 B)
-----BEGIN PGP SIGNATURE-----

iIcEABYKAC8WIQSzjPXf5Y1BDWhU2iCrY1Tsnbr0bgUCah6u1hEccGF1bEBwYmFy
a2VyLmRldgAKCRCrY1Tsnbr0binIAP0ZdbdwF+Nnx077+l1ZU573bumo92EL+zqo
w4A3devlhwEA3dbBO3JfBnbEW+GaFkRv79J3n3HeT62HfAXx6jU9zgc=
=xBBX
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.