diff --git a/changelogs/unreleased/alternative-env-override.yml b/changelogs/unreleased/alternative-env-override.yml new file mode 100644 index 0000000000000000000000000000000000000000..ebc9148f8ebe8c6b27b0b0537028f24b9b9ab545_Y2hhbmdlbG9ncy91bnJlbGVhc2VkL2FsdGVybmF0aXZlLWVudi1vdmVycmlkZS55bWw= --- /dev/null +++ b/changelogs/unreleased/alternative-env-override.yml @@ -0,0 +1,5 @@ +--- +title: Allow gitlab build remote overrides from the environment +merge_request: 5067 +author: +type: added diff --git a/doc/build/team_member_docs.md b/doc/build/team_member_docs.md index b17d00cfb841cb5388e1dc6e4a0d6c67b4ff7b39_ZG9jL2J1aWxkL3RlYW1fbWVtYmVyX2RvY3MubWQ=..ebc9148f8ebe8c6b27b0b0537028f24b9b9ab545_ZG9jL2J1aWxkL3RlYW1fbWVtYmVyX2RvY3MubWQ= 100644 --- a/doc/build/team_member_docs.md +++ b/doc/build/team_member_docs.md @@ -50,6 +50,24 @@ while other environment variables, if not specified, will be populated from their corresponding files and passed on to the triggered pipeline. +## I want to use a specific mirror or fork of various GitLab components in my build + +The repository sources for most software that Omnibus Builds can be found in +the `.custom_sources.yml` file in the `omnibus-gitlab` repository. The main +GitLab components can be overridden via environment variables. Check the table +below for details: + +| Environment Variable | Description | +| --------------------------------------------- | ----------- | +| ALTERNATIVE_PRIVATE_TOKEN | An access token used if needing to pull from private repositories. | +| GITLAB_ALTERNATIVE_REPO | Git repository location for the GitLab Rails application. | +| GITLAB_SHELL_ALTERNATIVE_REPO | Git repository location for [GitLab Shell](https://gitlab.com/gitlab-org/gitlab-shell). | +| GITLAB_WORKHORSE_ALTERNATIVE_REPO | Git repository location for [GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse). | +| GITLAB_PAGES_ALTERNATIVE_REPO | Git repository location for [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages). | +| GITALY_SERVER_ALTERNATIVE_REPO | Git repository location for [Gitaly](https://gitlab.com/gitlab-org/gitaly). | +| GITLAB_ELASTICSEARCH_INDEXER_ALTERNATIVE_REPO | Git repository location for [GitLab Elasticsearch Indexer](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer). | +| GITLAB_KAS_ALTERNATIVE_REPO | Git repository location for [GitLab Kubernetes Agent Server](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent). | + ## Building packages for other OSs If you specifically want a package for an OS other than Ubuntu 16.04, or want to diff --git a/lib/gitlab/version.rb b/lib/gitlab/version.rb index b17d00cfb841cb5388e1dc6e4a0d6c67b4ff7b39_bGliL2dpdGxhYi92ZXJzaW9uLnJi..ebc9148f8ebe8c6b27b0b0537028f24b9b9ab545_bGliL2dpdGxhYi92ZXJzaW9uLnJi 100644 --- a/lib/gitlab/version.rb +++ b/lib/gitlab/version.rb @@ -120,10 +120,35 @@ end end - def remote + def read_remote_from_env + remote = case @software + when "gitlab-rails", "gitlab-rails-ee" + Gitlab::Util.get_env("GITLAB_ALTERNATIVE_REPO") + when "gitlab-shell" + Gitlab::Util.get_env("GITLAB_SHELL_ALTERNATIVE_REPO") + when "gitlab-workhorse" + Gitlab::Util.get_env("GITLAB_WORKHORSE_ALTERNATIVE_REPO") + when "gitlab-pages" + Gitlab::Util.get_env("GITLAB_PAGES_ALTERNATIVE_REPO") + when "gitaly" + Gitlab::Util.get_env("GITALY_SERVER_ALTERNATIVE_REPO") + when "gitlab-elasticsearch-indexer" + Gitlab::Util.get_env("GITLAB_ELASTICSEARCH_INDEXER_ALTERNATIVE_REPO") + when "gitlab-kas" + Gitlab::Util.get_env("GITLAB_KAS_ALTERNATIVE_REPO") + end + + if remote && Gitlab::Util.get_env("ALTERNATIVE_PRIVATE_TOKEN") + attach_remote_credential(remote, Gitlab::Util.get_env("ALTERNATIVE_PRIVATE_TOKEN")) + else + remote + end + end + + def read_remote_from_file filepath = File.expand_path(".custom_sources.yml", @project_root) sources = YAML.load_file(filepath)[@software] return "" unless sources if ::Gitlab::Version.security_channel? @@ -124,12 +149,12 @@ filepath = File.expand_path(".custom_sources.yml", @project_root) sources = YAML.load_file(filepath)[@software] return "" unless sources if ::Gitlab::Version.security_channel? - attach_remote_credential(sources[::Gitlab::Version.sources_channel]) || sources[::Gitlab::Version.fallback_sources_channel] + attach_remote_credential(sources[::Gitlab::Version.sources_channel], Gitlab::Util.get_env("CI_JOB_TOKEN")) || sources[::Gitlab::Version.fallback_sources_channel] else sources[::Gitlab::Version.sources_channel] end end @@ -131,7 +156,11 @@ else sources[::Gitlab::Version.sources_channel] end end + def remote + read_remote_from_env || read_remote_from_file || "" + end + private @@ -136,7 +165,7 @@ private - def attach_remote_credential(url) + def attach_remote_credential(url, token) return unless url uri = URI.parse(url) uri.user = "gitlab-ci-token" @@ -139,8 +168,8 @@ return unless url uri = URI.parse(url) uri.user = "gitlab-ci-token" - uri.password = Gitlab::Util.get_env("CI_JOB_TOKEN") + uri.password = token uri.to_s rescue URI::InvalidURIError # Git may use scp address which is not valid URI. Ignore it diff --git a/spec/gitlab/build/info_spec.rb b/spec/gitlab/build/info_spec.rb index b17d00cfb841cb5388e1dc6e4a0d6c67b4ff7b39_c3BlYy9naXRsYWIvYnVpbGQvaW5mb19zcGVjLnJi..ebc9148f8ebe8c6b27b0b0537028f24b9b9ab545_c3BlYy9naXRsYWIvYnVpbGQvaW5mb19zcGVjLnJi 100644 --- a/spec/gitlab/build/info_spec.rb +++ b/spec/gitlab/build/info_spec.rb @@ -195,7 +195,7 @@ describe 'with security sources channel selected' do before do allow(::Gitlab::Version).to receive(:sources_channel).and_return('security') - allow(ENV).to receive(:[]).with('CI_JOB_TOKEN').and_return('CJT') + stub_env_var('CI_JOB_TOKEN', 'CJT') end it 'returns security mirror for GitLab CE with attached credential' do diff --git a/spec/gitlab/version_spec.rb b/spec/gitlab/version_spec.rb index b17d00cfb841cb5388e1dc6e4a0d6c67b4ff7b39_c3BlYy9naXRsYWIvdmVyc2lvbl9zcGVjLnJi..ebc9148f8ebe8c6b27b0b0537028f24b9b9ab545_c3BlYy9naXRsYWIvdmVyc2lvbl9zcGVjLnJi 100644 --- a/spec/gitlab/version_spec.rb +++ b/spec/gitlab/version_spec.rb @@ -2,8 +2,12 @@ require 'gitlab/version' RSpec.describe Gitlab::Version do + before do + allow(ENV).to receive(:[]).and_call_original + end + describe '.sources_channel' do subject { described_class } context 'with ALTERNATIVE_SOURCES=true' do it 'returns "alternative"' do @@ -5,10 +9,9 @@ describe '.sources_channel' do subject { described_class } context 'with ALTERNATIVE_SOURCES=true' do it 'returns "alternative"' do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with('ALTERNATIVE_SOURCES').and_return('true') + stub_env_var('ALTERNATIVE_SOURCES', 'true') expect(subject.sources_channel).to eq('alternative') end @@ -16,10 +19,9 @@ context 'with SECURITY_SOURCES=true' do it 'returns "security"' do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with('SECURITY_SOURCES').and_return('true') + stub_env_var('SECURITY_SOURCES', 'true') expect(subject.sources_channel).to eq('security') end it 'ignores ALTERNATIVE_SOURCES=true and still return "security"' do @@ -21,11 +23,10 @@ expect(subject.sources_channel).to eq('security') end it 'ignores ALTERNATIVE_SOURCES=true and still return "security"' do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with('ALTERNATIVE_SOURCES').and_return('true') - allow(ENV).to receive(:[]).with('SECURITY_SOURCES').and_return('true') + stub_env_var('ALTERNATIVE_SOURCES', 'true') + stub_env_var('SECURITY_SOURCES', 'true') expect(subject.sources_channel).to eq('security') end @@ -33,9 +34,8 @@ context 'with neither ALTERNATIVE_SOURCES or SECURITY_SOURCES set true' do it 'returns "remote"' do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with('ALTERNATIVE_SOURCES').and_return('false') - allow(ENV).to receive(:[]).with('SECURITY_SOURCES').and_return('false') + stub_env_var('ALTERNATIVE_SOURCES', 'false') + stub_env_var('SECURITY_SOURCES', 'false') expect(subject.sources_channel).to eq('remote') end @@ -47,8 +47,7 @@ context 'with ALTERNATIVE_SOURCES=true' do it 'returns "alternative"' do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with('ALTERNATIVE_SOURCES').and_return('true') + stub_env_var('ALTERNATIVE_SOURCES', 'true') expect(subject.fallback_sources_channel).to eq('alternative') end @@ -56,8 +55,7 @@ context 'with ALTERNATIVE_SOURCES not set true' do it 'returns "remote"' do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with('ALTERNATIVE_SOURCES').and_return('false') + stub_env_var('ALTERNATIVE_SOURCES', 'false') expect(subject.fallback_sources_channel).to eq('remote') end @@ -121,5 +119,22 @@ end end + context 'with alternative env override' do + let(:software) { 'gitlab-rails-ee' } + + it 'returns "alternative" link from the environment whenever present' do + stub_env_var('GITLAB_ALTERNATIVE_REPO', 'https://gitlab.example.com/gitlab.git') + + expect(subject.remote).to eq('https://gitlab.example.com/gitlab.git') + end + + it 'attaches credentials to alternative env links when present' do + stub_env_var('GITLAB_ALTERNATIVE_REPO', 'https://gitlab.example.com/gitlab.git') + stub_env_var('ALTERNATIVE_PRIVATE_TOKEN', 'APT') + + expect(subject.remote).to eq('https://gitlab-ci-token:APT@gitlab.example.com/gitlab.git') + end + end + context 'with security source channel selected' do before do @@ -124,7 +139,6 @@ context 'with security source channel selected' do before do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with("CI_JOB_TOKEN").and_return("CJT") + stub_env_var('CI_JOB_TOKEN', 'CJT') mock_sources_channel('security') end @@ -281,8 +295,7 @@ let(:software) { 'gitlab-rails' } it 'identifies correct version from env variable' do - allow(ENV).to receive(:[]).and_call_original - allow(ENV).to receive(:[]).with("GITLAB_VERSION").and_return("5.6.7") + stub_env_var('GITLAB_VERSION', '5.6.7') allow(File).to receive(:read).and_return("1.2.3") expect(subject.print).to eq("v5.6.7") end