Message ID | 20250626140731.2732545-2-clara.kowalsky@siemens.com |
---|---|
State | Superseded, archived |
Headers | show |
Series | [v2,1/2] container_fetcher: Fix missing checksum warning | expand |
On 26.06.25 16:07, Clara Kowalsky wrote: > If a tag and digest are specified for a container image in the SRC_URI, > the tag is ignored until now and the container image with the matching > digest is fetched. > With this change, the container image is fetched based on the specified > tag and it is checked whether the digest matches. If not, an error is > thrown. > > Signed-off-by: Clara Kowalsky <clara.kowalsky@siemens.com> > --- > meta/lib/container_fetcher.py | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/meta/lib/container_fetcher.py b/meta/lib/container_fetcher.py > index 16467abb..08766742 100644 > --- a/meta/lib/container_fetcher.py > +++ b/meta/lib/container_fetcher.py > @@ -11,6 +11,7 @@ from bb.fetch2 import FetchMethod > from bb.fetch2 import logger > from bb.fetch2 import MissingChecksumEvent > from bb.fetch2 import NoChecksumError > +from bb.fetch2 import ChecksumError > from bb.fetch2 import runfetchcmd > > class Container(FetchMethod): > @@ -47,6 +48,22 @@ class Container(FetchMethod): > def download(self, ud, d): > tarball = ud.localfile[:-len('.zst')] > with tempfile.TemporaryDirectory(dir=d.getVar('DL_DIR')) as tmpdir: > + # If both tag and digest are provided, verify they match > + if ud.digest and not "tag" in ud.parm: Hmm, I'm confused by my own suggestion right now: Did you test that again? Don't we rather need if ud.digest and "tag" in ud.parm: ? > + inspect_output = runfetchcmd(f"skopeo inspect docker://{ud.container_name}:{ud.tag}", d, True) > + actual_digest = json.loads(inspect_output)["Digest"] > + if actual_digest != ud.digest: > + messages = [] > + messages.append(f"Checksum mismatch for {ud.container_name}:{ud.tag}") > + messages.append("If this change is expected (e.g. you have upgraded " \ > + "to a new version without updating the checksums) " \ > + "then you can use these lines within the recipe:") > + messages.append(f'SRC_URI = "docker://{ud.container_name};digest={actual_digest};tag={ud.tag}"') > + messages.append("Otherwise you should retry the download and/or " \ > + "check with upstream to determine if the container image has " \ > + "become corrupted or otherwise unexpectedly modified.") > + raise ChecksumError("\n".join(messages), ud.url, actual_digest) > + > # Take a two steps for downloading into a docker archive because > # not all source may have the required Docker schema 2 manifest. > runfetchcmd("skopeo copy --preserve-digests " + \ Jan
On 26.06.25 18:00, Jan Kiszka wrote: > On 26.06.25 16:07, Clara Kowalsky wrote: >> If a tag and digest are specified for a container image in the SRC_URI, >> the tag is ignored until now and the container image with the matching >> digest is fetched. >> With this change, the container image is fetched based on the specified >> tag and it is checked whether the digest matches. If not, an error is >> thrown. >> >> Signed-off-by: Clara Kowalsky <clara.kowalsky@siemens.com> >> --- >> meta/lib/container_fetcher.py | 17 +++++++++++++++++ >> 1 file changed, 17 insertions(+) >> >> diff --git a/meta/lib/container_fetcher.py b/meta/lib/container_fetcher.py >> index 16467abb..08766742 100644 >> --- a/meta/lib/container_fetcher.py >> +++ b/meta/lib/container_fetcher.py >> @@ -11,6 +11,7 @@ from bb.fetch2 import FetchMethod >> from bb.fetch2 import logger >> from bb.fetch2 import MissingChecksumEvent >> from bb.fetch2 import NoChecksumError >> +from bb.fetch2 import ChecksumError >> from bb.fetch2 import runfetchcmd >> >> class Container(FetchMethod): >> @@ -47,6 +48,22 @@ class Container(FetchMethod): >> def download(self, ud, d): >> tarball = ud.localfile[:-len('.zst')] >> with tempfile.TemporaryDirectory(dir=d.getVar('DL_DIR')) as tmpdir: >> + # If both tag and digest are provided, verify they match >> + if ud.digest and not "tag" in ud.parm: > > Hmm, I'm confused by my own suggestion right now: Did you test that > again? Don't we rather need > > if ud.digest and "tag" in ud.parm: > > ? Forgot to fully test this.. Yes, the v2 is not working. With "if ud.digest and not "tag" in ud.parm:", we only enter this case if no tag is specified in the SRC_URI, which is not what we want. The digest is then compared to the digest of "latest"... Tested with "if ud.digest and "tag" in ud.parm:": This is correct, it means we have a tag and a digest explicitly specified in the SRC_URI and then we want to do the "skopeo inspect" to check for a mismatch. Sending v3 with this change + Reviewed-By. BR, Clara > >> + inspect_output = runfetchcmd(f"skopeo inspect docker://{ud.container_name}:{ud.tag}", d, True) >> + actual_digest = json.loads(inspect_output)["Digest"] >> + if actual_digest != ud.digest: >> + messages = [] >> + messages.append(f"Checksum mismatch for {ud.container_name}:{ud.tag}") >> + messages.append("If this change is expected (e.g. you have upgraded " \ >> + "to a new version without updating the checksums) " \ >> + "then you can use these lines within the recipe:") >> + messages.append(f'SRC_URI = "docker://{ud.container_name};digest={actual_digest};tag={ud.tag}"') >> + messages.append("Otherwise you should retry the download and/or " \ >> + "check with upstream to determine if the container image has " \ >> + "become corrupted or otherwise unexpectedly modified.") >> + raise ChecksumError("\n".join(messages), ud.url, actual_digest) >> + >> # Take a two steps for downloading into a docker archive because >> # not all source may have the required Docker schema 2 manifest. >> runfetchcmd("skopeo copy --preserve-digests " + \ > > Jan >
diff --git a/meta/lib/container_fetcher.py b/meta/lib/container_fetcher.py index 16467abb..08766742 100644 --- a/meta/lib/container_fetcher.py +++ b/meta/lib/container_fetcher.py @@ -11,6 +11,7 @@ from bb.fetch2 import FetchMethod from bb.fetch2 import logger from bb.fetch2 import MissingChecksumEvent from bb.fetch2 import NoChecksumError +from bb.fetch2 import ChecksumError from bb.fetch2 import runfetchcmd class Container(FetchMethod): @@ -47,6 +48,22 @@ class Container(FetchMethod): def download(self, ud, d): tarball = ud.localfile[:-len('.zst')] with tempfile.TemporaryDirectory(dir=d.getVar('DL_DIR')) as tmpdir: + # If both tag and digest are provided, verify they match + if ud.digest and not "tag" in ud.parm: + inspect_output = runfetchcmd(f"skopeo inspect docker://{ud.container_name}:{ud.tag}", d, True) + actual_digest = json.loads(inspect_output)["Digest"] + if actual_digest != ud.digest: + messages = [] + messages.append(f"Checksum mismatch for {ud.container_name}:{ud.tag}") + messages.append("If this change is expected (e.g. you have upgraded " \ + "to a new version without updating the checksums) " \ + "then you can use these lines within the recipe:") + messages.append(f'SRC_URI = "docker://{ud.container_name};digest={actual_digest};tag={ud.tag}"') + messages.append("Otherwise you should retry the download and/or " \ + "check with upstream to determine if the container image has " \ + "become corrupted or otherwise unexpectedly modified.") + raise ChecksumError("\n".join(messages), ud.url, actual_digest) + # Take a two steps for downloading into a docker archive because # not all source may have the required Docker schema 2 manifest. runfetchcmd("skopeo copy --preserve-digests " + \
If a tag and digest are specified for a container image in the SRC_URI, the tag is ignored until now and the container image with the matching digest is fetched. With this change, the container image is fetched based on the specified tag and it is checked whether the digest matches. If not, an error is thrown. Signed-off-by: Clara Kowalsky <clara.kowalsky@siemens.com> --- meta/lib/container_fetcher.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)