c5912ecd73
* master: (1327 commits) Merge branch 'render-json-leak' into 'security' Merge branch 'ssrf' into 'security' Merge branch 'ssrf' into 'security' Merge branch 'fix-links-target-blank' into 'security' Merge branch '28058-hide-emails-in-atom-feeds' into 'security' Fix karma test Reset filters after click Handle Route#name being nil after an update Only add frontend code coverage instrumentation when generating coverage report fix recompile assets step in 9.0 upgrade guide to use yarn Undo explicit conversion to Integer Make level_value accept string integers Make feature spec more robust Removed d3.js from the main application.js bundle Extend compound status for manual actions specs Update css to be nice and tidy. Fix pipeline status for transition between stages add an index to the ghost column Return 404 in project issues API endpoint when project cannot be found Improve rename projects migration ... Conflicts: doc/ci/docker/using_docker_build.md spec/lib/gitlab/import_export/all_models.yml
101 lines
2.8 KiB
Ruby
101 lines
2.8 KiB
Ruby
require 'faraday'
|
|
require 'faraday_middleware'
|
|
|
|
module ContainerRegistry
|
|
class Client
|
|
attr_accessor :uri
|
|
|
|
MANIFEST_VERSION = 'application/vnd.docker.distribution.manifest.v2+json'.freeze
|
|
|
|
# Taken from: FaradayMiddleware::FollowRedirects
|
|
REDIRECT_CODES = Set.new [301, 302, 303, 307]
|
|
|
|
def initialize(base_uri, options = {})
|
|
@base_uri = base_uri
|
|
@options = options
|
|
end
|
|
|
|
def update_token(token)
|
|
@options[:token] = token
|
|
end
|
|
|
|
def repository_tags(name)
|
|
response_body faraday.get("/v2/#{name}/tags/list")
|
|
end
|
|
|
|
def repository_manifest(name, reference)
|
|
response_body faraday.get("/v2/#{name}/manifests/#{reference}")
|
|
end
|
|
|
|
def repository_tag_digest(name, reference)
|
|
response = faraday.head("/v2/#{name}/manifests/#{reference}")
|
|
response.headers['docker-content-digest'] if response.success?
|
|
end
|
|
|
|
def delete_repository_tag(name, reference)
|
|
faraday.delete("/v2/#{name}/manifests/#{reference}").success?
|
|
end
|
|
|
|
def blob(name, digest, type = nil)
|
|
type ||= 'application/octet-stream'
|
|
response_body faraday_blob.get("/v2/#{name}/blobs/#{digest}", nil, 'Accept' => type), allow_redirect: true
|
|
end
|
|
|
|
def delete_blob(name, digest)
|
|
faraday.delete("/v2/#{name}/blobs/#{digest}").success?
|
|
end
|
|
|
|
private
|
|
|
|
def initialize_connection(conn, options)
|
|
conn.request :json
|
|
|
|
if options[:user] && options[:password]
|
|
conn.request(:basic_auth, options[:user].to_s, options[:password].to_s)
|
|
elsif options[:token]
|
|
conn.request(:authorization, :bearer, options[:token].to_s)
|
|
end
|
|
|
|
conn.adapter :net_http
|
|
end
|
|
|
|
def accept_manifest(conn)
|
|
conn.headers['Accept'] = MANIFEST_VERSION
|
|
|
|
conn.response :json, content_type: 'application/json'
|
|
conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v1+prettyjws'
|
|
conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v1+json'
|
|
conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v2+json'
|
|
end
|
|
|
|
def response_body(response, allow_redirect: false)
|
|
if allow_redirect && REDIRECT_CODES.include?(response.status)
|
|
response = redirect_response(response.headers['location'])
|
|
end
|
|
|
|
response.body if response && response.success?
|
|
end
|
|
|
|
def redirect_response(location)
|
|
return unless location
|
|
|
|
# We explicitly remove authorization token
|
|
faraday_blob.get(location) do |req|
|
|
req['Authorization'] = ''
|
|
end
|
|
end
|
|
|
|
def faraday
|
|
@faraday ||= Faraday.new(@base_uri) do |conn|
|
|
initialize_connection(conn, @options)
|
|
accept_manifest(conn)
|
|
end
|
|
end
|
|
|
|
def faraday_blob
|
|
@faraday_blob ||= Faraday.new(@base_uri) do |conn|
|
|
initialize_connection(conn, @options)
|
|
end
|
|
end
|
|
end
|
|
end
|