package catalogue import ( "strings" ) // ArtifactStoreScheme marks a reference to something in the mesh's artifact store, kept without // the store's address. const ArtifactStoreScheme = ArtifactStoreProvision + "://" // Recorded is a reference as the mesh records it: the artifact store's address, if the builder wrote // one, taken off. // // For a reference the builder announced — one it pushed to the store — which is the only kind // this is called on. An image the builder named `/@sha256:…` is kept as its path; an // archive it named `http:///v2//blobs/` likewise. A reference with no address // in it — an image id from a genesis build that had nowhere to publish, a package version — is // what it was. func Recorded(reference string) string { if strings.HasPrefix(reference, ArtifactStoreScheme) { return reference } if rest, isURL := strings.CutPrefix(reference, "http://"); isURL { if _, path, ok := strings.Cut(rest, "/v2/"); ok && strings.Contains(path, "/blobs/") { return ArtifactStoreScheme + path } return reference } host, path, ok := strings.Cut(reference, "/") if !ok || !isRegistryHost(host) || !strings.Contains(path, "@sha256:") { return reference } return ArtifactStoreScheme + path } // isRegistryHost is the runtime's own rule for reading the first component of a reference as a // registry rather than as a namespace: it has a dot or a port in it, or it is localhost. func isRegistryHost(component string) bool { return component == "localhost" || strings.ContainsAny(component, ".:") } // InArtifactStore reports whether a reference is a kept one, and what it names there. func InArtifactStore(reference string) (path string, kept bool) { return strings.CutPrefix(reference, ArtifactStoreScheme) } // Routed is a kept reference as a machine fetches it, through the artifact store at `address` // (host:port). A reference that is not a kept one is what it was. func Routed(reference, address string) string { path, kept := InArtifactStore(reference) if !kept { return reference } if strings.Contains(path, "/blobs/") { return "http://" + address + "/v2/" + path } return address + "/" + path }