-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: Enable tags to be pinned and overwritten tags to be tracked #83
Comments
You would get more or less this behavior if you use a more granular image version, such as Please see an answer I gave to a similar issue: #74 (comment):
|
It's the less that's the problem, something like this Isn't helpful to me because I don't want to update to 8.x, and by having it constantly showing as needing an update it trains me to ignore mongo, making it less likely that I'll notice when a 7.0 update is published. It doesn't need an ignore option so much as an "only track this tag" option, essentially "I've pinned this for a reason, just tell me if the pinned tag gets an update". |
Would your use case be covered sufficiently by only recommending updates to mongo in this case if, let's say, 7.1 was released? That is, staying within the same major (a bit more detail in the last sentence of the quote in the previous comment):
Cupdate relies on semantic versioning in tags to identify updates, meaning that if you were to ask Cupdate to ignore other tags, it wouldn't recognize a new push to the same tag as a new update. As a result, disabling checks for other tags would provide you with updates on vulnerabilities, graphs, etc., just not the image itself. Is that what you'd like to get out of Cupdate? |
Mongo is a bad example because they have a stupid versioning system where x.0 is their LTS release and x.1, x.2, are short-term support releases, so there you probably wouldn't want to jump to 7.1 anyway, but for most software that wouldn't be an issue. I haven't looked at your underlying logic but I had assumed you were tracking image manifest hashes (because otherwise any repo using a My primary point of comparison here is Diun. The additional contextual information that you're providing with Cupdate is useful but also most people (for better or worse) are using generic fixed tags (like |
Thanks for the clarification and sorry for the long answer. Cupdate doesn't currently take the digest into consideration. For example, There are a few ways I can see to solve this issue.
I intend to support option 1 as I think that aligns well with the current feature set and semantic versioning, as well as making hard-to-update services work better. I also intend on supporting option 3 as it's the standard way of freezing an image's version. I'm not convinced option 2 is necessary, it's probably better solved by option 3. Option 4 is similar to option 3 but contains a tag as well and could be used to check for changed digests (with some caveats). So now, I have a few questions again to take the opportunity to understand your (and probably others') use case:
A bit of background/context: I have had the intention of eventually supporting tracking image digests, mostly for vulnerability scanning (they could help with SBOMs) and to more correctly present the actual images in use. But digests come with a few issues that make them a bit cumbersome to implement and I haven't put in the required effort yet.
As most of Cupdate's code is made to be platform / runtime agnostic, the first issue has made digests a no-go. The other issue makes it quite cumbersome to use digests without assumptions. For example, in the case of remote hosts, not all hosts necessarily use the same architecture and would therefore not use the same manifests. I agree that probably a lot of people are using tags like |
So FWIW ,in terms of Docker at least, options 3 and 4 are identical on the backend. If you provide a manifest hash the tag is ignored, thus all of these:
Are the same underlying image, so it's really just a visual preference. As for my own use cases I use a big mix of images; some use semver, some don't, some I pin to major or minor versions, some I use with a generic tag (either because they don't semver or because I'm intentionally running a bleeding edge release). All of my containers (in terms of anything long-running) are managed via compose. I'm not using Renovate or similar tools (mostly because of the above, I'd spend more time crafting ways to handle non- and almost-semver tags than I currently spend updating things), nor am I using anything like Watchtower to blindly auto-update (because I like having a functional environment). I understand the complexities of working with multiple runtimes and dealing with multi-arch manifests and the difficulties that can bring in terms of tracking image updates across multiple hosts (or indeed hosts with qemu in use). I don't have any particular insight when it comes to k8s APIs as the bulk of my experience here is with docker registries and manifests. That said, antipattern or not you're likely to get a lot of confused users if you aren't tracking updates to non-semver tags at all and don't make that very clear in your docs, because running |
Thank you for your answer and for sharing your thoughts and experiences. I'm tracking the necessary Kubernetes changes in #90. After that, digests should be trackable on both platforms. It would lay the groundwork for getting overwritten tags to work. |
There's been a lot of related changed made recently and I think we're at a point where Cupdate will be able to handle digests properly in most cases. Feel free to try it out using the The work on supporting freezing tags that do follow semver, at least in part, has not been started. But I'm not convinced that a global option is the way forward, but I'll definitely be looking at implementing it as a way to experiment with the behavior and for you to try out. It might just not be what ends up being the documented solution for your use case. |
Checking out the PR image now, I am seeing some Unauthorised errors in the logs for manifest fetches:
For example, which manifests in the UI as
|
Thanks for taking a look. I've seen the issue with lscr.io locally as well. I don't think it's due to recent changes on our side. For me, it eventually started working after a few retries. I've read that that registry mirrors to several backends such as GHCR. I've only ever seen GHCR be in use,so Cupdate makes that assumption for auth. But recently some requests seem to have been sent to another backend registry, thus causing the unauthorized issue. Unfortunately I haven't seen any documentation from them on what registries are in use or how a client can identify what registry will be in use. I think we'll need to handle lscr a bit differently, hopefully with something we can reuse for other registries, like using the www-authenticate header. I've might have been too focused on non-semver tags and forgot to handle digests for new semver tags. I'll double check. Thanks again! |
lscr uses ghcr as a primary backend, in principle it should only ever change if there's a prolonged ghcr outage (or some policy/entitlement change that renders them unviable going forward), and realistically would end up using Docker Hub in that situation (the images themselves are also mirrored to quay and gitlab but quay's performance and reliability are pretty dire and gitlab only retains the last 10k tags). |
That was the case. I'm now grabbing the manifest and digest of the latest semver tags as well. Should be available if you pull the Thanks for the information! Edit: I've improved the support for lscr.io. I've pushed a fix to main and rebased #92 on top of that. The |
Looking much better with the most recent PR image, although there's a sorting issue where new There's also a very weird issue which isn't your problem per se, but is something to do with the docker library Traefik image and whatever is going on with their image pushes, because I have: So again possibly a sorting issue, but both of those v3.3's are SHA hashes that point to the same image, with the same attestation manifest but one is tagged and the other isn't. I can't actually update to |
Thanks! I noticed the sorting issue as well (#92 (comment)). It should be fixed now. Again, available on the As for the Traefik issue, I think this is an issue we can work around, but it requires knowledge of the target architecture. Essentially, the digest you have locally, Local{
"manifests": [
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "amd64",
"org.opencontainers.image.base.digest": "sha256:483f502c0e6aff6d80a807f25d3f88afa40439c29fdd2d21a0912e0f42db842a",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T19:27:21Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:81c7d4b7e69cc47f2d236c9ed9e9a4aa09794b57ddcc9650400a55177656e1b5",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "amd64",
"os": "linux"
},
"size": 1728
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "amd64",
"vnd.docker.reference.digest": "sha256:81c7d4b7e69cc47f2d236c9ed9e9a4aa09794b57ddcc9650400a55177656e1b5",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:a0f65e21fdc8c97b8db5f960452ae4e54a047560b72d3f1e8d188634855775cb",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm32v6",
"org.opencontainers.image.base.digest": "sha256:c79529000bdf8bc63d5a64a4a6f20fc86a2d5f7d8fc8c68863243a3e05c2a136",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T19:27:10Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:353d92f2258bfe055145fe6496a72ae60ba9df7238d1f152821c7636fb557df8",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v6"
},
"size": 1730
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm32v6",
"vnd.docker.reference.digest": "sha256:353d92f2258bfe055145fe6496a72ae60ba9df7238d1f152821c7636fb557df8",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:5e642e883f84ab165cd40b9200440eff266217d0e44c3ce72491824506222133",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 567
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm64v8",
"org.opencontainers.image.base.digest": "sha256:508c1b94e1d20635b3326ee2a28180102ffde2a13d5b72cdd1c4d4872ad2f83c",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-08T22:06:53Z",
"org.opencontainers.image.revision": "79eb99e8c991e149bfa5fd468bbbf2b0e1f2b16a",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#79eb99e8c991e149bfa5fd468bbbf2b0e1f2b16a:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.1"
},
"digest": "sha256:bd54fbba443e38a0ab67718c61d196762033a5c04a68b67aab0993e1cd92dac0",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "arm64",
"os": "linux",
"variant": "v8"
},
"size": 1730
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm64v8",
"vnd.docker.reference.digest": "sha256:bd54fbba443e38a0ab67718c61d196762033a5c04a68b67aab0993e1cd92dac0",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:e62748540f6ca3a561ca4244d21b5e509df10547838a7a7ed606d7b73ade8364",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "ppc64le",
"org.opencontainers.image.base.digest": "sha256:23dbce23b88f36f6d84223fefa3a7786f231fcd07d8350184cc4428ca38429ac",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T19:33:52Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:87ad07007290254488dd9abd4aea2affbc5b5b13871f5dec8c79db48b3966015",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "ppc64le",
"os": "linux"
},
"size": 1730
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "ppc64le",
"vnd.docker.reference.digest": "sha256:87ad07007290254488dd9abd4aea2affbc5b5b13871f5dec8c79db48b3966015",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:438104def6c17c8de2883ea5f6b50b0c8bdb66fb3a5ff29cd6b7d8a1a64e447a",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "riscv64",
"org.opencontainers.image.base.digest": "sha256:f9d2da150ceeb695656d64b6376cbcf3389ab6aba1270beb080711c72b3ad474",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-10T16:35:08Z",
"org.opencontainers.image.revision": "79eb99e8c991e149bfa5fd468bbbf2b0e1f2b16a",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#79eb99e8c991e149bfa5fd468bbbf2b0e1f2b16a:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.1"
},
"digest": "sha256:1713090e026d380b332566aa2c906969b5fc6eb5bfd4de4e54a5888deefe81e3",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "riscv64",
"os": "linux"
},
"size": 1730
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "riscv64",
"vnd.docker.reference.digest": "sha256:1713090e026d380b332566aa2c906969b5fc6eb5bfd4de4e54a5888deefe81e3",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:70f1d1d9bb3ddd05da289c26ef2e68fbea7499d5b27514497f03f2e31fcfd275",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "s390x",
"org.opencontainers.image.base.digest": "sha256:6bb03952a007ae0ef13a803b7678dda46d5ab1187713228b1252b90e6a60eebe",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T20:15:23Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:361d003ecc29d072a0d110a9a091f08f628d9399449cdd78276eb35b017a2fdd",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "s390x",
"os": "linux"
},
"size": 1728
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "s390x",
"vnd.docker.reference.digest": "sha256:361d003ecc29d072a0d110a9a091f08f628d9399449cdd78276eb35b017a2fdd",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:9eaafb48782b81936ebc42fd49a855b617f4f731d29b5e6b3fcebe66e4da36ec",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
}
],
"mediaType": "application/vnd.oci.image.index.v1+json",
"schemaVersion": 2
} If I fetch the manifest for v3.3, however, I get a fat manifest with the digest Remote{
"manifests": [
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "amd64",
"org.opencontainers.image.base.digest": "sha256:483f502c0e6aff6d80a807f25d3f88afa40439c29fdd2d21a0912e0f42db842a",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T19:27:21Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:81c7d4b7e69cc47f2d236c9ed9e9a4aa09794b57ddcc9650400a55177656e1b5",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "amd64",
"os": "linux"
},
"size": 1728
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "amd64",
"vnd.docker.reference.digest": "sha256:81c7d4b7e69cc47f2d236c9ed9e9a4aa09794b57ddcc9650400a55177656e1b5",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:a0f65e21fdc8c97b8db5f960452ae4e54a047560b72d3f1e8d188634855775cb",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm32v6",
"org.opencontainers.image.base.digest": "sha256:c79529000bdf8bc63d5a64a4a6f20fc86a2d5f7d8fc8c68863243a3e05c2a136",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T19:27:10Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:353d92f2258bfe055145fe6496a72ae60ba9df7238d1f152821c7636fb557df8",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v6"
},
"size": 1730
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm32v6",
"vnd.docker.reference.digest": "sha256:353d92f2258bfe055145fe6496a72ae60ba9df7238d1f152821c7636fb557df8",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:5e642e883f84ab165cd40b9200440eff266217d0e44c3ce72491824506222133",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 567
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm64v8",
"org.opencontainers.image.base.digest": "sha256:508c1b94e1d20635b3326ee2a28180102ffde2a13d5b72cdd1c4d4872ad2f83c",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-15T01:26:11Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:8630d704e299f03e2760d49758df08183789343bbda3ecc63e7db77804599156",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "arm64",
"os": "linux",
"variant": "v8"
},
"size": 1730
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm64v8",
"vnd.docker.reference.digest": "sha256:8630d704e299f03e2760d49758df08183789343bbda3ecc63e7db77804599156",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:5ccf3be6fd3d4519838d787874315b3d58633399b4c6aa6f810ef6d8a88461c1",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "ppc64le",
"org.opencontainers.image.base.digest": "sha256:23dbce23b88f36f6d84223fefa3a7786f231fcd07d8350184cc4428ca38429ac",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T19:33:52Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:87ad07007290254488dd9abd4aea2affbc5b5b13871f5dec8c79db48b3966015",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "ppc64le",
"os": "linux"
},
"size": 1730
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "ppc64le",
"vnd.docker.reference.digest": "sha256:87ad07007290254488dd9abd4aea2affbc5b5b13871f5dec8c79db48b3966015",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:438104def6c17c8de2883ea5f6b50b0c8bdb66fb3a5ff29cd6b7d8a1a64e447a",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "riscv64",
"org.opencontainers.image.base.digest": "sha256:f9d2da150ceeb695656d64b6376cbcf3389ab6aba1270beb080711c72b3ad474",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T20:26:10Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:b47b9bf6a9b762e38526ce82e5b0626510e299a52e87319d018a23549a20f0dd",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "riscv64",
"os": "linux"
},
"size": 1730
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "riscv64",
"vnd.docker.reference.digest": "sha256:b47b9bf6a9b762e38526ce82e5b0626510e299a52e87319d018a23549a20f0dd",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:66a0aea548886a01a60df52dbb7c291f206d318870b6d7db6dddb015cffc7980",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "s390x",
"org.opencontainers.image.base.digest": "sha256:6bb03952a007ae0ef13a803b7678dda46d5ab1187713228b1252b90e6a60eebe",
"org.opencontainers.image.base.name": "alpine:3.21",
"org.opencontainers.image.created": "2025-01-14T20:15:23Z",
"org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
"org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
"org.opencontainers.image.version": "v3.3.2"
},
"digest": "sha256:361d003ecc29d072a0d110a9a091f08f628d9399449cdd78276eb35b017a2fdd",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "s390x",
"os": "linux"
},
"size": 1728
},
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "s390x",
"vnd.docker.reference.digest": "sha256:361d003ecc29d072a0d110a9a091f08f628d9399449cdd78276eb35b017a2fdd",
"vnd.docker.reference.type": "attestation-manifest"
},
"digest": "sha256:9eaafb48782b81936ebc42fd49a855b617f4f731d29b5e6b3fcebe66e4da36ec",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
},
"size": 840
}
],
"mediaType": "application/vnd.oci.image.index.v1+json",
"schemaVersion": 2
} Diffing these we can see that the image index itself differ, but the images themselves only differ for some architectures. Assuming you're running amd64, the images are actually the same. Diff--- a/a
+++ b/a
@@ -72,13 +72,13 @@
"com.docker.official-images.bashbrew.arch": "arm64v8",
"org.opencontainers.image.base.digest": "sha256:508c1b94e1d20635b3326ee2a28180102ffde2a13d5b72cdd1c4d4872ad2f83c",
"org.opencontainers.image.base.name": "alpine:3.21",
- "org.opencontainers.image.created": "2025-01-08T22:06:53Z",
- "org.opencontainers.image.revision": "79eb99e8c991e149bfa5fd468bbbf2b0e1f2b16a",
- "org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#79eb99e8c991e149bfa5fd468bbbf2b0e1f2b16a:v3.3/alpine",
+ "org.opencontainers.image.created": "2025-01-15T01:26:11Z",
+ "org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
+ "org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
- "org.opencontainers.image.version": "v3.3.1"
+ "org.opencontainers.image.version": "v3.3.2"
},
- "digest": "sha256:bd54fbba443e38a0ab67718c61d196762033a5c04a68b67aab0993e1cd92dac0",
+ "digest": "sha256:8630d704e299f03e2760d49758df08183789343bbda3ecc63e7db77804599156",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "arm64",
@@ -90,10 +90,10 @@
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "arm64v8",
- "vnd.docker.reference.digest": "sha256:bd54fbba443e38a0ab67718c61d196762033a5c04a68b67aab0993e1cd92dac0",
+ "vnd.docker.reference.digest": "sha256:8630d704e299f03e2760d49758df08183789343bbda3ecc63e7db77804599156",
"vnd.docker.reference.type": "attestation-manifest"
},
- "digest": "sha256:e62748540f6ca3a561ca4244d21b5e509df10547838a7a7ed606d7b73ade8364",
+ "digest": "sha256:5ccf3be6fd3d4519838d787874315b3d58633399b4c6aa6f810ef6d8a88461c1",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
@@ -139,13 +139,13 @@
"com.docker.official-images.bashbrew.arch": "riscv64",
"org.opencontainers.image.base.digest": "sha256:f9d2da150ceeb695656d64b6376cbcf3389ab6aba1270beb080711c72b3ad474",
"org.opencontainers.image.base.name": "alpine:3.21",
- "org.opencontainers.image.created": "2025-01-10T16:35:08Z",
- "org.opencontainers.image.revision": "79eb99e8c991e149bfa5fd468bbbf2b0e1f2b16a",
- "org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#79eb99e8c991e149bfa5fd468bbbf2b0e1f2b16a:v3.3/alpine",
+ "org.opencontainers.image.created": "2025-01-14T20:26:10Z",
+ "org.opencontainers.image.revision": "4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b",
+ "org.opencontainers.image.source": "https://github.com/traefik/traefik-library-image.git#4fc0980f9d74f7c3be2ef4bf2513cb39b3d2226b:v3.3/alpine",
"org.opencontainers.image.url": "https://hub.docker.com/_/traefik",
- "org.opencontainers.image.version": "v3.3.1"
+ "org.opencontainers.image.version": "v3.3.2"
},
- "digest": "sha256:1713090e026d380b332566aa2c906969b5fc6eb5bfd4de4e54a5888deefe81e3",
+ "digest": "sha256:b47b9bf6a9b762e38526ce82e5b0626510e299a52e87319d018a23549a20f0dd",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "riscv64",
@@ -156,10 +156,10 @@
{
"annotations": {
"com.docker.official-images.bashbrew.arch": "riscv64",
- "vnd.docker.reference.digest": "sha256:1713090e026d380b332566aa2c906969b5fc6eb5bfd4de4e54a5888deefe81e3",
+ "vnd.docker.reference.digest": "sha256:b47b9bf6a9b762e38526ce82e5b0626510e299a52e87319d018a23549a20f0dd",
"vnd.docker.reference.type": "attestation-manifest"
},
- "digest": "sha256:70f1d1d9bb3ddd05da289c26ef2e68fbea7499d5b27514497f03f2e31fcfd275",
+ "digest": "sha256:66a0aea548886a01a60df52dbb7c291f206d318870b6d7db6dddb015cffc7980",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown", So there are a few issues here:
The first issue is a bit unfortunate as it requires us to solve the other issues. The second issue we'll just have to deal with. It seems common enough across runtimes (Docker Engine, Containerd) to point to the index rather than actual image manifest. The third issue would be solved by trying to apply the architecture of the engine to resolve the manifest like the runtimes would. So to recap: This is a result of not knowing the architecture in use and not resolving the manifest of an index based on the architecture. I'd hope to solve this as a second step, though. So I think we'll need to have to work with this limitation for now. |
@AlexGustafsson I wanted to say thank you for working on this enhancement and encourage you to continue with it. I adopted cupdate a little over a week ago and in combination with Diun, I was looking for a workflow where I would get notified of new docker images and then open cupdate to see what the changes were. Like many others, I will sometimes use Reading through this thread, I think I'm starting to understand the challenge, but would love continued effort in this area. What I was hoping cupdate would do was tell me -- regardless of the Please continue with this enhancement. Ideal would be to see what |
@jacobslusser Thanks! I think I've gotten most of the features working that would be required to solve this. With the change Cupdate will try to track the digest for all images, so it will almost always be available in the UI. For now, the digest is only shown on hover, unless the image is "pinned" - i.e. you specified an image like so: How would you like it to be shown? I don't really know of an obvious solution. There's not really any "version" to show and the tag is the exactly same in both cases. We could show the digest at all times, but it's quite technical and probably not user-friendly, assuming that people are using tags like "latest" due to perceived convenience in the first place. Here are a few screenshots of the current UI when nothing but a digest is specified. To be technically correct, the "sha256:" prefix is required. 10 hex digits are shown, with the rest being hidden as the fullt digest likely doesn't provide that much meaningful info. Any truncated text is always shown in full on hover. |
Changes merged to main, should be available on the Thanks a lot, @thespad for the discussions and testing. I'll keep this issue open until #95 is solved. But for now I'll mark #90 and #94 as solved. Please ping me here, in those issues or just open new bug tickets if you come across any issues or limitations. |
I can open a feature request, but not if the plan is to show the digest. TBH, for me - and I assume 99% of others -- the digest means next to zero for me. It would be better to leave it the way it is now than switch to showing digest. It's your project, so you should follow your heart, but if it were me, I would ideally like to see this simple change:
Example In this arrangement, it tells me everything I want to know:
|
Yeah, I agree the digest doesn't provide any helpful meaning. That's why we currently only show it when it's the only information we've got. I'm not sure Cupdate will be able to take this route. There are no standard, well-established means to identify what "version" is actually used within an image. The tag is basically it. We try to use standard OCI annotations, but a lot of the community has not caught up. So the best we can do (and what we currently do) is to try to show semantic upgrades to tags that have the same amount of detail. So in your case above, let's say you've defined "v1" as the tag for Docker to use, Cupdate will look for changes made to "v1" itself (such as changes that are likely equivalent to v1.0.1, but we can't really tell) as well as for a In the other case, If possible for your workflow, could you try to use more explicit tags (v1.11.1 in this case)? That would give you the behavior of looking up actual "versions" in almost all cases. I think you're suggestion makes a lot of sense from a user's standpoint, don't get me wrong, but I don't think it's currently technically feasible to do without assigning special meaning to So bottom line is, you'll probably get a much better experience if you use "versioned" tags with as much detail as possible, But your suggestion is good, so please feel free to open up a feature request so it can be tracked. I might have missed things or there may be better ways of solving it eventually. |
Part of the problem is that AFAIK none of the registries support fetching tags by digest, so you can't do something like:
Which means, like Alex said, you have to rely on the OCI labels or other metadata, which don't necessarily map to an actual tag somewhere to compare to. |
User stories
Feature description
For example I know that there's a newer postgres 17 tag, but I'm running postgres 15 and so I care about updates to that tag and can't/don't want to jump to 17.
This is especially common with databases but there are plenty of other situations where other tags may get pushed that you don't care about but still flag as "newer" versions.
Doesn't even need to be per image, just a global "only check for updates to the running tag" option would be sufficient
The text was updated successfully, but these errors were encountered: