mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-26 04:04:15 +00:00
fix to artifact diff. add missing file
This commit is contained in:
@@ -1489,6 +1489,39 @@ func UpdateFirehoseCursor(db DBTX, cursor int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// GetChildManifestPlatform returns the platform info for a manifest that is
|
||||
// referenced as a child of a manifest list. Returns nil if the digest is not
|
||||
// a child of any manifest list (i.e., it's a top-level single-arch manifest).
|
||||
// Used by the diff handler to match architectures when comparing a platform
|
||||
// child digest against a manifest list (or another child).
|
||||
func GetChildManifestPlatform(db DBTX, did, repository, digest string) (*PlatformInfo, error) {
|
||||
var p PlatformInfo
|
||||
var arch, os, variant, osVersion sql.NullString
|
||||
err := db.QueryRow(`
|
||||
SELECT
|
||||
COALESCE(mr.platform_os, ''),
|
||||
COALESCE(mr.platform_architecture, ''),
|
||||
COALESCE(mr.platform_variant, ''),
|
||||
COALESCE(mr.platform_os_version, '')
|
||||
FROM manifest_references mr
|
||||
JOIN manifests m ON mr.manifest_id = m.id
|
||||
WHERE m.did = ? AND m.repository = ? AND mr.digest = ?
|
||||
LIMIT 1
|
||||
`, did, repository, digest).Scan(&os, &arch, &variant, &osVersion)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
p.OS = os.String
|
||||
p.Architecture = arch.String
|
||||
p.Variant = variant.String
|
||||
p.OSVersion = osVersion.String
|
||||
p.Digest = digest
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
// IsManifestReferenced checks if a manifest digest is referenced as a child of
|
||||
// any manifest list for the given user. Used to protect manifest list children
|
||||
// from auto-removal (they are untagged but still needed by their parent list).
|
||||
|
||||
@@ -333,6 +333,26 @@ func (h *ManifestDiffHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
fromPlatformDigest := ""
|
||||
toPlatformDigest := ""
|
||||
|
||||
// platKey returns "os/arch[/variant]" for a platform.
|
||||
platKey := func(os, arch, variant string) string {
|
||||
k := os + "/" + arch
|
||||
if variant != "" {
|
||||
k += "/" + variant
|
||||
}
|
||||
return k
|
||||
}
|
||||
|
||||
// pickPlatformChild returns the child digest from a manifest list whose
|
||||
// platform matches the given key. Returns "" if no match.
|
||||
pickPlatformChild := func(m *db.ManifestWithMetadata, key string) string {
|
||||
for _, p := range m.Platforms {
|
||||
if platKey(p.OS, p.Architecture, p.Variant) == key {
|
||||
return p.Digest
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
if isMultiArch {
|
||||
// Build intersection of platforms
|
||||
for _, fp := range fromManifest.Platforms {
|
||||
@@ -348,33 +368,47 @@ func (h *ManifestDiffHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
selectedPlatform = r.URL.Query().Get("platform")
|
||||
if len(commonPlatforms) > 0 {
|
||||
if selectedPlatform == "" {
|
||||
selectedPlatform = commonPlatforms[0].OS + "/" + commonPlatforms[0].Architecture
|
||||
if commonPlatforms[0].Variant != "" {
|
||||
selectedPlatform += "/" + commonPlatforms[0].Variant
|
||||
}
|
||||
selectedPlatform = platKey(commonPlatforms[0].OS, commonPlatforms[0].Architecture, commonPlatforms[0].Variant)
|
||||
}
|
||||
// Find matching platform digests
|
||||
for _, fp := range fromManifest.Platforms {
|
||||
platKey := fp.OS + "/" + fp.Architecture
|
||||
if fp.Variant != "" {
|
||||
platKey += "/" + fp.Variant
|
||||
}
|
||||
if platKey == selectedPlatform {
|
||||
fromPlatformDigest = fp.Digest
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, tp := range toManifest.Platforms {
|
||||
platKey := tp.OS + "/" + tp.Architecture
|
||||
if tp.Variant != "" {
|
||||
platKey += "/" + tp.Variant
|
||||
}
|
||||
if platKey == selectedPlatform {
|
||||
toPlatformDigest = tp.Digest
|
||||
fromPlatformDigest = pickPlatformChild(fromManifest, selectedPlatform)
|
||||
toPlatformDigest = pickPlatformChild(toManifest, selectedPlatform)
|
||||
}
|
||||
} else if fromManifest.IsManifestList != toManifest.IsManifestList {
|
||||
// Mixed: one side is a manifest list, the other is a platform child.
|
||||
// Match them by looking up the single-arch side's platform via its
|
||||
// parent manifest_references row and picking the matching child from
|
||||
// the manifest list side.
|
||||
var listSide *db.ManifestWithMetadata
|
||||
var childDigest string
|
||||
if fromManifest.IsManifestList {
|
||||
listSide = fromManifest
|
||||
childDigest = toDigest
|
||||
} else {
|
||||
listSide = toManifest
|
||||
childDigest = fromDigest
|
||||
}
|
||||
|
||||
plat, _ := db.GetChildManifestPlatform(h.ReadOnlyDB, owner.DID, repo, childDigest)
|
||||
var listChildDigest string
|
||||
if plat != nil {
|
||||
listChildDigest = pickPlatformChild(listSide, platKey(plat.OS, plat.Architecture, plat.Variant))
|
||||
}
|
||||
// Fallback: if we couldn't determine the platform (or no match),
|
||||
// default to the first non-attestation child of the manifest list so
|
||||
// the diff at least shows real layers instead of an empty index.
|
||||
if listChildDigest == "" {
|
||||
for _, p := range listSide.Platforms {
|
||||
if p.Digest != "" {
|
||||
listChildDigest = p.Digest
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if fromManifest.IsManifestList {
|
||||
fromPlatformDigest = listChildDigest
|
||||
} else {
|
||||
toPlatformDigest = listChildDigest
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch layer/vuln data in parallel
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -293,11 +293,10 @@ function initTabController() {
|
||||
const content = document.getElementById('tag-content');
|
||||
const selector = document.getElementById('tag-selector');
|
||||
if (!content || !selector || !to) return;
|
||||
const fromDigest = content.dataset.digest;
|
||||
const currentTag = selector.value;
|
||||
if (!fromDigest || to === currentTag) return;
|
||||
if (!currentTag || to === currentTag) return;
|
||||
window.location.href = '/diff/' + content.dataset.owner + '/' + content.dataset.repo +
|
||||
'?from=' + encodeURIComponent(fromDigest) + '&to=' + encodeURIComponent(to);
|
||||
'?from=' + encodeURIComponent(currentTag) + '&to=' + encodeURIComponent(to);
|
||||
};
|
||||
|
||||
window.switchRepoTab = function(tabId) {
|
||||
|
||||
Reference in New Issue
Block a user