From 65a0624cd9236ea05cb51ee04e4ad4c2be05275f Mon Sep 17 00:00:00 2001 From: Thomas Hipp Date: Wed, 27 Jul 2016 16:09:38 +0200 Subject: [PATCH] CatalogJob: update the digests of tags Enable the CatalogJob to update the digest of existing tags. Resolves #828 Signed-off-by: Thomas Hipp --- app/models/repository.rb | 37 +++++++++++++++++++++++++++------- spec/models/repository_spec.rb | 10 +++++++-- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/app/models/repository.rb b/app/models/repository.rb index 0491214b5..543bcc470 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -193,11 +193,38 @@ def self.create_or_update!(repo) repository = Repository.find_or_create_by!(name: name, namespace: namespace) tags = repository.tags.pluck(:name) - to_be_created_tags = repo["tags"] - tags to_be_deleted_tags = tags - repo["tags"] client = Registry.get.client - to_be_created_tags.each do |tag| + + update_tags client, repository, repo["tags"] & tags + create_tags client, repository, portus, repo["tags"] - tags + + # Finally remove the tags that are left and return the repo. + repository.tags.where(name: to_be_deleted_tags).find_each { |t| t.delete_and_update!(portus) } + repository.reload + end + + # Update digest of already existing tags. + def self.update_tags(client, repository, tags) + tags.each do |tag| + # Try to fetch the manifest digest of the tag. + begin + _, digest, = client.manifest(repository.full_name, tag) + rescue StandardError => e + logger.tagged("catalog") do + logger.warn "Could not fetch manifest for '#{repository.full_name}' " \ + "with tag '#{tag}': " + e.message + end + next + end + repository.tags.find_by(name: tag).update!(digest: digest) + end + end + + # Create new tags. + def self.create_tags(client, repository, author, tags) + tags.each do |tag| # Try to fetch the manifest digest of the tag. begin id, digest, = client.manifest(repository.full_name, tag) @@ -206,12 +233,8 @@ def self.create_or_update!(repo) digest = "" end - Tag.create!(name: tag, repository: repository, author: portus, digest: digest, image_id: id) + Tag.create!(name: tag, repository: repository, author: author, digest: digest, image_id: id) logger.tagged("catalog") { logger.info "Created the tag '#{tag}'." } end - - # Finally remove the tags that are left and return the repo. - repository.tags.where(name: to_be_deleted_tags).find_each { |t| t.delete_and_update!(portus) } - repository.reload end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 936b92424..0ad5e3c3e 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -419,7 +419,7 @@ def get_url(repo, tag) let!(:namespace) { create(:namespace, team: team) } let!(:repo1) { create(:repository, name: "repo1", namespace: namespace) } let!(:repo2) { create(:repository, name: "repo2", namespace: namespace) } - let!(:tag1) { create(:tag, name: "tag1", repository: repo1) } + let!(:tag1) { create(:tag, name: "tag1", repository: repo1, digest: "foo") } let!(:tag2) { create(:tag, name: "tag2", repository: repo2) } let!(:tag3) { create(:tag, name: "tag3", repository: repo2) } @@ -432,7 +432,7 @@ def get_url(repo, tag) if args.first != "busybox" && !args.first.include?("/") raise "Should be included inside of a namespace" end - if args.last != "latest" && args.last != "0.1" + if args.last != "latest" && args.last != "0.1" && args.last != "tag1" raise "Using an unknown tag" end @@ -443,6 +443,12 @@ def get_url(repo, tag) end it "adds and deletes tags accordingly" do + # Update existing tag's digest + repo = { "name" => "#{namespace.name}/repo1", "tags" => ["tag1"] } + repo = Repository.create_or_update!(repo) + expect(repo.id).to eq repo1.id + expect(repo.tags.find_by(name: "tag1").digest).to match("digest") + # Removes the existing tag and adds two. repo = { "name" => "#{namespace.name}/repo1", "tags" => ["latest", "0.1"] } repo = Repository.create_or_update!(repo)