diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
commit | 43a25d93ebdabea52f99b05e15b06250cd8f07d7 (patch) | |
tree | dceebdc68925362117480a5d672bcff122fb625b /lib/gitlab/pages | |
parent | 20c84b99005abd1c82101dfeff264ac50d2df211 (diff) |
Add latest changes from gitlab-org/gitlab@16-0-stable-eev16.0.0-rc42
Diffstat (limited to 'lib/gitlab/pages')
-rw-r--r-- | lib/gitlab/pages/deployment_update.rb | 11 | ||||
-rw-r--r-- | lib/gitlab/pages/random_domain.rb | 51 | ||||
-rw-r--r-- | lib/gitlab/pages/virtual_host_finder.rb | 71 |
3 files changed, 131 insertions, 2 deletions
diff --git a/lib/gitlab/pages/deployment_update.rb b/lib/gitlab/pages/deployment_update.rb index 2f5c6938e2a..6845f5d88ec 100644 --- a/lib/gitlab/pages/deployment_update.rb +++ b/lib/gitlab/pages/deployment_update.rb @@ -46,9 +46,13 @@ module Gitlab end end + def root_dir + build.options[:publish] || PUBLIC_DIR + end + # Calculate page size after extract def total_size - @total_size ||= build.artifacts_metadata_entry(PUBLIC_DIR + '/', recursive: true).total_size + @total_size ||= build.artifacts_metadata_entry("#{root_dir}/", recursive: true).total_size end def max_size_from_settings @@ -74,7 +78,10 @@ module Gitlab def validate_public_folder if total_size <= 0 - errors.add(:base, 'Error: The `public/` folder is missing, or not declared in `.gitlab-ci.yml`.') + errors.add( + :base, + 'Error: You need to either include a `public/` folder in your artifacts, or specify ' \ + 'which one to use for Pages using `publish` in `.gitlab-ci.yml`') end end diff --git a/lib/gitlab/pages/random_domain.rb b/lib/gitlab/pages/random_domain.rb new file mode 100644 index 00000000000..8aa7611c910 --- /dev/null +++ b/lib/gitlab/pages/random_domain.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Gitlab + module Pages + class RandomDomain + PROJECT_PATH_LIMIT = 48 + SUBDOMAIN_LABEL_LIMIT = 63 + + def self.generate(project_path:, namespace_path:) + new(project_path: project_path, namespace_path: namespace_path).generate + end + + def initialize(project_path:, namespace_path:) + @project_path = project_path + @namespace_path = namespace_path + end + + # Subdomains have a limit of 63 bytes (https://www.freesoft.org/CIE/RFC/1035/9.htm) + # For this reason we're limiting each part of the unique subdomain + # + # The domain is made up of 3 parts, like: projectpath-namespacepath-randomstring + # - project path: between 1 and 48 chars + # - namespace path: when the project path has less than 48 chars, + # the namespace full path will be used to fill the value up to 48 chars + # - random hexadecimal: to ensure a random value, the domain is then filled + # with a random hexadecimal value to complete 63 chars + def generate + domain = project_path.byteslice(0, PROJECT_PATH_LIMIT) + + # if the project_path has less than PROJECT_PATH_LIMIT chars, + # fill the domain with the parent full_path up to 48 chars like: + # projectpath-namespacepath + if domain.length < PROJECT_PATH_LIMIT + namespace_size = PROJECT_PATH_LIMIT - domain.length - 1 + domain.concat('-', namespace_path.byteslice(0, namespace_size)) + end + + # Complete the domain with random hexadecimal values util it is 63 chars long + # PS.: SecureRandom.hex return an string twice the size passed as argument. + domain.concat('-', SecureRandom.hex(SUBDOMAIN_LABEL_LIMIT - domain.length - 1)) + + # Slugify ensures the format and size (63 chars) of the given string + Gitlab::Utils.slugify(domain) + end + + private + + attr_reader :project_path, :namespace_path + end + end +end diff --git a/lib/gitlab/pages/virtual_host_finder.rb b/lib/gitlab/pages/virtual_host_finder.rb new file mode 100644 index 00000000000..5fec60188f8 --- /dev/null +++ b/lib/gitlab/pages/virtual_host_finder.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +module Gitlab + module Pages + class VirtualHostFinder + def initialize(host) + @host = host&.downcase + end + + def execute + return if host.blank? + + gitlab_host = ::Settings.pages.host.downcase.prepend(".") + + if host.ends_with?(gitlab_host) + name = host.delete_suffix(gitlab_host) + + by_namespace_domain(name) || + by_unique_domain(name) + else + by_custom_domain(host) + end + end + + private + + attr_reader :host + + def by_unique_domain(name) + project = Project.by_pages_enabled_unique_domain(name) + + return unless Feature.enabled?(:pages_unique_domain, project) + return unless project&.pages_deployed? + + ::Pages::VirtualDomain.new(projects: [project]) + end + + def by_namespace_domain(name) + namespace = Namespace.top_most.by_path(name) + + return if namespace.blank? + + cache = if Feature.enabled?(:cache_pages_domain_api, namespace) + ::Gitlab::Pages::CacheControl.for_namespace(namespace.id) + end + + ::Pages::VirtualDomain.new( + trim_prefix: namespace.full_path, + projects: namespace.all_projects_with_pages, + cache: cache + ) + end + + def by_custom_domain(host) + domain = PagesDomain.find_by_domain_case_insensitive(host) + + return unless domain&.pages_deployed? + + cache = if Feature.enabled?(:cache_pages_domain_api, domain.project.root_namespace) + ::Gitlab::Pages::CacheControl.for_domain(domain.id) + end + + ::Pages::VirtualDomain.new( + projects: [domain.project], + domain: domain, + cache: cache + ) + end + end + end +end |