Fix 500 errors with legacy appearance logos

Prior to GitLab 9.0, attachments were not tracked the `uploads` table,
so it was possible that the appearance logos were just stored in the
database as a string and mounted via CarrierWave.

https://gitlab.com/gitlab-org/gitlab-ce/issues/29240 implemented in
GitLab 10.3 was supposed to cover populating the `uploads` table for all
attachments, including all the logos from appearances. However, it's
possible that didn't work for logos or the `uploads` entry was orphaned.

GitLab instances that had a customized logo with no associated `uploads`
entry would see Error 500s. The only way to fix this is to delete the
`logo` column from the `appearances` table and re-upload the attachment.

This change makes things more robust by falling back to the original
behavior if the upload is not available.

This is a CE backport of
https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/9277.

Closes https://gitlab.com/gitlab-org/gitlab-ee/issues/9357
This commit is contained in:
Stan Hu 2019-01-23 10:28:26 -08:00
parent 768475bd78
commit 19f9d99870
3 changed files with 17 additions and 1 deletions

View file

@ -44,7 +44,11 @@ class Appearance < ActiveRecord::Base
private private
def logo_system_path(logo, mount_type) def logo_system_path(logo, mount_type)
return unless logo&.upload # Legacy attachments may not have have an associated Upload record,
# so fallback to the AttachmentUploader#url if this is the
# case. AttachmentUploader#path doesn't work because for a local
# file, this is an absolute path to the file.
return logo&.url unless logo&.upload
# If we're using a CDN, we need to use the full URL # If we're using a CDN, we need to use the full URL
asset_host = ActionController::Base.asset_host asset_host = ActionController::Base.asset_host

View file

@ -0,0 +1,5 @@
---
title: Fix 500 errors with legacy appearance logos
merge_request: 24615
author:
type: fixed

View file

@ -36,6 +36,13 @@ describe Appearance do
expect(subject.send("#{logo_type}_path")).to be_nil expect(subject.send("#{logo_type}_path")).to be_nil
end end
it 'returns the path when the upload has been orphaned' do
appearance.send(logo_type).upload.destroy
appearance.reload
expect(appearance.send("#{logo_type}_path")).to eq(expected_path)
end
it 'returns a local path using the system route' do it 'returns a local path using the system route' do
expect(appearance.send("#{logo_type}_path")).to eq(expected_path) expect(appearance.send("#{logo_type}_path")).to eq(expected_path)
end end