container_repository.rb 1.7 KB
Newer Older
1
class ContainerRepository < ActiveRecord::Base
2
  belongs_to :project
3
  delegate :client, to: :registry
4
  validates :manifest, presence: true
5
  validates :name, presence: true
6 7
  before_destroy :delete_tags

8
  def registry
9 10 11 12 13 14 15 16 17 18 19 20
    @registry ||= begin
      token = Auth::ContainerRegistryAuthenticationService.full_access_token(path)

      url = Gitlab.config.registry.api_url
      host_port = Gitlab.config.registry.host_port

      ContainerRegistry::Registry.new(url, token: token, path: host_port)
    end
  end

  def path
    @path ||= "#{project.full_path}/#{name}"
21 22 23 24 25 26 27
  end

  def tag(tag)
    ContainerRegistry::Tag.new(self, tag)
  end

  def manifest
28
    @manifest ||= client.repository_tags(self.path)
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
  end

  def tags
    return @tags if defined?(@tags)
    return [] unless manifest && manifest['tags']

    @tags = manifest['tags'].map do |tag|
      ContainerRegistry::Tag.new(self, tag)
    end
  end

  def blob(config)
    ContainerRegistry::Blob.new(self, config)
  end

  def delete_tags
    return unless tags

47 48
    digests = tags.map {|tag| tag.digest }.to_set
    digests.all? do |digest|
49
      client.delete_repository_tag(self.path, digest)
50
    end
51 52
  end

53 54
  def self.project_from_path(repository_path)
    return unless repository_path.include?('/')
55 56 57 58 59

    ##
    # Projects are always located inside a namespace, so we can remove
    # the last node, and see if project with that path exists.
    #
60
    truncated_path = repository_path.slice(0...repository_path.rindex('/'))
61 62 63 64 65 66

    ##
    # We still make it possible to search projects by a full image path
    # in order to maintain backwards compatibility.
    #
    Project.find_by_full_path(truncated_path) ||
67
      Project.find_by_full_path(repository_path)
68 69
  end
end