Skip to content

If the latest registry in upstreams don't agree with each other, mirror all of them #8

@johnnychen94

Description

@johnnychen94

It makes less sense to code the complex logic here as the storage server doesn't care much about which is the latest one; simply pulling down all registry tarballs and whatever packages they contain would be good enough.

function query_latest_hash(registry::RegistryMeta, upstreams::AbstractVector{<:AbstractString})
# collect current registry hashes from servers
uuid = registry.uuid
hash_info = Dict{String, Vector{String}}() # Dict(hashA => [serverA, serverB], ...)
servers = String[] # [serverA, serverB]
for server in upstreams
hash = query_latest_hash(registry, server)
isnothing(hash) && continue
push!(get!(hash_info, hash, String[]), server)
push!(servers, server)
end
# for each hash check what other servers know about it
if isempty(hash_info)
# if none of the upstreams contains the registry we want to mirror
@warn "failed to find available registry" registry=registry.name upstreams=upstreams
return nothing
end
# a hash might be known to many upstreams
for (hash, hash_servers) in hash_info
for server in servers
server in hash_servers && continue
url_exists("$server/registry/$uuid/$hash") || continue
push!(hash_servers, server)
end
end
# Ideally, there is an upstream server that knows all hashes, and we set hash in that server
# as the latest hash.
# In practice, we set the first non-malicious hash known to fewest servers as the latest hash.
hashes = sort!(collect(keys(hash_info)))
sort!(hashes, by = hash -> length(hash_info[hash]))
hashes[findfirst(x->verify_registry_hash(registry.source_url, x), hashes)]
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions