diff --git a/gems/gitlab-backup-cli/lib/gitlab/backup/cli/source_context.rb b/gems/gitlab-backup-cli/lib/gitlab/backup/cli/source_context.rb index a73aec577b0d6220e75f635a754d9acee77d3d5e..a3d60e21108add2538de4fb76cae1bf3b1767cc0 100644 --- a/gems/gitlab-backup-cli/lib/gitlab/backup/cli/source_context.rb +++ b/gems/gitlab-backup-cli/lib/gitlab/backup/cli/source_context.rb @@ -13,8 +13,9 @@ def gitlab_version end def backup_basedir - # TODO: decouple from Rails codebase, load from gitlab.yml file - Rails.root.join('tmp/backups') + path = gitlab_config[env]['backup']['path'] + + absolute_path(path) end # CI Builds basepath @@ -78,6 +79,17 @@ def env private + # Return a fullpath for a given path + # + # When the path is already a full one return itself as a Pathname + # otherwise uses gitlab_basepath as its base + # @param [String|Pathname] path + # @return [Pathname] + def absolute_path(path) + # Joins with gitlab_basepath when relative, otherwise return full path + Pathname(File.expand_path(path, gitlab_basepath)) + end + def gitlab_basepath return Pathname.new(GITLAB_PATH) if GITLAB_PATH diff --git a/gems/gitlab-backup-cli/spec/fixtures/gitlab-relativepaths.yml b/gems/gitlab-backup-cli/spec/fixtures/gitlab-relativepaths.yml new file mode 100644 index 0000000000000000000000000000000000000000..e681f25f2957b369e76042b069de556a1d7174e8 --- /dev/null +++ b/gems/gitlab-backup-cli/spec/fixtures/gitlab-relativepaths.yml @@ -0,0 +1,222 @@ +# # # # # # # # # # # # # # # # # # +# GitLab application config file # +# # # # # # # # # # # # # # # # # # + +test: + object_store: + enabled: false + gravatar: + enabled: true + external_diffs: + enabled: false + # Diffs may be `always` external (the default), or they can be made external + # after they have become `outdated` (i.e., the MR is closed or a new version + # has been pushed). + # when: always + # The location where external diffs are stored (default: shared/external-diffs). + storage_path: tmp/tests/external-diffs + object_store: + enabled: false + remote_directory: external-diffs # The bucket name + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + lfs: + enabled: false + # The location where LFS objects are stored (default: shared/lfs-objects). + # storage_path: shared/lfs-objects + object_store: + enabled: false + remote_directory: lfs-objects # The bucket name + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + artifacts: + path: tmp/tests/artifacts + enabled: true + # The location where build artifacts are stored (default: shared/artifacts). + # path: shared/artifacts + object_store: + enabled: false + remote_directory: artifacts # The bucket name + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + uploads: + storage_path: tmp/tests/public + object_store: + enabled: false + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + + terraform_state: + enabled: true + storage_path: tmp/tests/terraform_state + object_store: + enabled: false + remote_directory: terraform + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + + ci_secure_files: + enabled: true + storage_path: tmp/tests/ci_secure_files + object_store: + enabled: false + remote_directory: ci-secure-files + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + + gitlab: + host: localhost + port: 80 + + content_security_policy: + enabled: true + report_only: false + directives: + base_uri: + child_src: + connect_src: + default_src: "'self'" + font_src: + form_action: + frame_ancestors: "'self'" + frame_src: "'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com" + img_src: "* data: blob:" + manifest_src: + media_src: + object_src: "'none'" + script_src: "'self' 'unsafe-eval' http://localhost:* https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://www.gstatic.com/recaptcha/ https://apis.google.com" + style_src: "'self' 'unsafe-inline'" + worker_src: "'self' blob:" + report_uri: + + # When you run tests we clone and set up gitlab-shell + # In order to set it up correctly you need to specify + # your system username you use to run GitLab + # user: YOUR_USERNAME + pages: + path: tmp/tests/pages + object_store: + enabled: false + remote_directory: pages # The bucket name + connection: + provider: AWS + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + local_store: + enabled: true + path: tmp/tests/pages + repositories: + storages: + default: + path: tmp/tests/repositories/ + gitaly_address: unix:tmp/tests/gitaly/praefect.socket + + gitaly: + client_path: tmp/tests/gitaly/_build/bin + token: secret + workhorse: + secret_file: tmp/gitlab_workhorse_test_secret + backup: + path: /tmp/gitlab/full/backups + gitaly_backup_path: tmp/tests/gitaly/_build/bin/gitaly-backup + gitlab_shell: + path: tmp/tests/gitlab-shell/ + authorized_keys_file: tmp/tests/authorized_keys + issues_tracker: + redmine: + title: "Redmine" + project_url: "http://redmine/projects/:issues_tracker_id" + issues_url: "http://redmine/:project_id/:issues_tracker_id/:id" + new_issue_url: "http://redmine/projects/:issues_tracker_id/issues/new" + jira: + title: "Jira" + url: https://sample_company.atlassian.net + project_key: PROJECT + + omniauth: + # enabled: true + allow_single_sign_on: true + external_providers: [] + + providers: + - { name: 'alicloud', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET' } + - { name: 'github', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + url: "https://github.com/", + verify_ssl: false, + args: { scope: 'user:email' } } + - { name: 'bitbucket', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET' } + - { name: 'gitlab', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + args: { scope: 'api' } } + - { name: 'google_oauth2', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + args: { access_type: 'offline', approval_prompt: '' } } + - { name: 'jwt', + app_secret: 'YOUR_APP_SECRET', + args: { + algorithm: 'HS256', + uid_claim: 'email', + required_claims: ["name", "email"], + info_map: { name: "name", email: "email" }, + auth_url: 'https://example.com/', + valid_within: null, + } + } + - { name: 'auth0', + args: { + client_id: 'YOUR_AUTH0_CLIENT_ID', + client_secret: 'YOUR_AUTH0_CLIENT_SECRET', + domain: 'YOUR_AUTH0_DOMAIN', + scope: 'openid profile email' } } + - { name: 'salesforce', + app_id: 'YOUR_CLIENT_ID', + app_secret: 'YOUR_CLIENT_SECRET' + } + - { name: 'atlassian_oauth2', + app_id: 'YOUR_CLIENT_ID', + app_secret: 'YOUR_CLIENT_SECRET', + args: { scope: 'offline_access read:jira-user read:jira-work', prompt: 'consent' } + } + ldap: + enabled: false + servers: + main: + label: ldap + host: 127.0.0.1 + port: 3890 + uid: 'uid' + encryption: 'plain' # "start_tls" or "simple_tls" or "plain" + base: 'dc=example,dc=com' + user_filter: '' + group_base: 'ou=groups,dc=example,dc=com' + admin_group: '' + prometheus: + enabled: true + server_address: 'localhost:9090' diff --git a/gems/gitlab-backup-cli/spec/fixtures/gitlab.yml b/gems/gitlab-backup-cli/spec/fixtures/gitlab.yml new file mode 100644 index 0000000000000000000000000000000000000000..77454e2a0498d5dd20e17e985202b8f80a89c160 --- /dev/null +++ b/gems/gitlab-backup-cli/spec/fixtures/gitlab.yml @@ -0,0 +1,222 @@ +# # # # # # # # # # # # # # # # # # +# GitLab application config file # +# # # # # # # # # # # # # # # # # # + +test: + object_store: + enabled: false + gravatar: + enabled: true + external_diffs: + enabled: false + # Diffs may be `always` external (the default), or they can be made external + # after they have become `outdated` (i.e., the MR is closed or a new version + # has been pushed). + # when: always + # The location where external diffs are stored (default: shared/external-diffs). + storage_path: tmp/tests/external-diffs + object_store: + enabled: false + remote_directory: external-diffs # The bucket name + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + lfs: + enabled: false + # The location where LFS objects are stored (default: shared/lfs-objects). + # storage_path: shared/lfs-objects + object_store: + enabled: false + remote_directory: lfs-objects # The bucket name + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + artifacts: + path: tmp/tests/artifacts + enabled: true + # The location where build artifacts are stored (default: shared/artifacts). + # path: shared/artifacts + object_store: + enabled: false + remote_directory: artifacts # The bucket name + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + uploads: + storage_path: tmp/tests/public + object_store: + enabled: false + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + + terraform_state: + enabled: true + storage_path: tmp/tests/terraform_state + object_store: + enabled: false + remote_directory: terraform + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + + ci_secure_files: + enabled: true + storage_path: tmp/tests/ci_secure_files + object_store: + enabled: false + remote_directory: ci-secure-files + connection: + provider: AWS # Only AWS supported at the moment + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + + gitlab: + host: localhost + port: 80 + + content_security_policy: + enabled: true + report_only: false + directives: + base_uri: + child_src: + connect_src: + default_src: "'self'" + font_src: + form_action: + frame_ancestors: "'self'" + frame_src: "'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com" + img_src: "* data: blob:" + manifest_src: + media_src: + object_src: "'none'" + script_src: "'self' 'unsafe-eval' http://localhost:* https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://www.gstatic.com/recaptcha/ https://apis.google.com" + style_src: "'self' 'unsafe-inline'" + worker_src: "'self' blob:" + report_uri: + + # When you run tests we clone and set up gitlab-shell + # In order to set it up correctly you need to specify + # your system username you use to run GitLab + # user: YOUR_USERNAME + pages: + path: tmp/tests/pages + object_store: + enabled: false + remote_directory: pages # The bucket name + connection: + provider: AWS + aws_access_key_id: AWS_ACCESS_KEY_ID + aws_secret_access_key: AWS_SECRET_ACCESS_KEY + region: us-east-1 + local_store: + enabled: true + path: tmp/tests/pages + repositories: + storages: + default: + path: tmp/tests/repositories/ + gitaly_address: unix:tmp/tests/gitaly/praefect.socket + + gitaly: + client_path: tmp/tests/gitaly/_build/bin + token: secret + workhorse: + secret_file: tmp/gitlab_workhorse_test_secret + backup: + path: tmp/tests/backups + gitaly_backup_path: tmp/tests/gitaly/_build/bin/gitaly-backup + gitlab_shell: + path: tmp/tests/gitlab-shell/ + authorized_keys_file: tmp/tests/authorized_keys + issues_tracker: + redmine: + title: "Redmine" + project_url: "http://redmine/projects/:issues_tracker_id" + issues_url: "http://redmine/:project_id/:issues_tracker_id/:id" + new_issue_url: "http://redmine/projects/:issues_tracker_id/issues/new" + jira: + title: "Jira" + url: https://sample_company.atlassian.net + project_key: PROJECT + + omniauth: + # enabled: true + allow_single_sign_on: true + external_providers: [] + + providers: + - { name: 'alicloud', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET' } + - { name: 'github', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + url: "https://github.com/", + verify_ssl: false, + args: { scope: 'user:email' } } + - { name: 'bitbucket', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET' } + - { name: 'gitlab', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + args: { scope: 'api' } } + - { name: 'google_oauth2', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + args: { access_type: 'offline', approval_prompt: '' } } + - { name: 'jwt', + app_secret: 'YOUR_APP_SECRET', + args: { + algorithm: 'HS256', + uid_claim: 'email', + required_claims: ["name", "email"], + info_map: { name: "name", email: "email" }, + auth_url: 'https://example.com/', + valid_within: null, + } + } + - { name: 'auth0', + args: { + client_id: 'YOUR_AUTH0_CLIENT_ID', + client_secret: 'YOUR_AUTH0_CLIENT_SECRET', + domain: 'YOUR_AUTH0_DOMAIN', + scope: 'openid profile email' } } + - { name: 'salesforce', + app_id: 'YOUR_CLIENT_ID', + app_secret: 'YOUR_CLIENT_SECRET' + } + - { name: 'atlassian_oauth2', + app_id: 'YOUR_CLIENT_ID', + app_secret: 'YOUR_CLIENT_SECRET', + args: { scope: 'offline_access read:jira-user read:jira-work', prompt: 'consent' } + } + ldap: + enabled: false + servers: + main: + label: ldap + host: 127.0.0.1 + port: 3890 + uid: 'uid' + encryption: 'plain' # "start_tls" or "simple_tls" or "plain" + base: 'dc=example,dc=com' + user_filter: '' + group_base: 'ou=groups,dc=example,dc=com' + admin_group: '' + prometheus: + enabled: true + server_address: 'localhost:9090' diff --git a/gems/gitlab-backup-cli/spec/gitlab/backup/cli/source_context_spec.rb b/gems/gitlab-backup-cli/spec/gitlab/backup/cli/source_context_spec.rb index 9b6ad7c3b784a4a48a6b290e38ec9f2d81f1444a..49ccbd91a9676af5a9495f822fabf0cfc2f57ed6 100644 --- a/gems/gitlab-backup-cli/spec/gitlab/backup/cli/source_context_spec.rb +++ b/gems/gitlab-backup-cli/spec/gitlab/backup/cli/source_context_spec.rb @@ -9,6 +9,7 @@ before do allow(context).to receive(:gitlab_basepath).and_return(fake_gitlab_basepath) + FileUtils.mkdir fake_gitlab_basepath.join('config') end after do @@ -23,4 +24,27 @@ expect(context.gitlab_version).to eq('17.0.3-ee') end end + + describe '#backup_basedir' do + context 'with a relative path configured in gitlab.yml' do + it 'returns a full path based on gitlab basepath' do + use_gitlab_config_fixture('gitlab.yml') + + expect(context.backup_basedir).to eq(fake_gitlab_basepath.join('tmp/tests/backups')) + end + end + + context 'with full path configure in gitlab.yml' do + it 'returns a full path as configured in gitlab.yml' do + use_gitlab_config_fixture('gitlab-relativepaths.yml') + + expect(context.backup_basedir).to eq(Pathname('/tmp/gitlab/full/backups')) + end + end + end + + def use_gitlab_config_fixture(fixture) + gitlab_yml_fixture = fixtures_path.join(fixture) + FileUtils.copy(gitlab_yml_fixture, fake_gitlab_basepath.join('config/gitlab.yml')) + end end diff --git a/gems/gitlab-backup-cli/spec/spec_helper.rb b/gems/gitlab-backup-cli/spec/spec_helper.rb index 02246b5a4dd6dec711dab9431ce3eb9491bae498..82c2604b9c3dcc38ead19a7f826f51b0050da37c 100644 --- a/gems/gitlab-backup-cli/spec/spec_helper.rb +++ b/gems/gitlab-backup-cli/spec/spec_helper.rb @@ -7,6 +7,8 @@ require 'factory_bot' require 'gitlab/rspec/next_instance_of' +ENV["RAILS_ENV"] ||= "test" + # Load spec support code Dir['spec/support/**/*.rb'].each { |f| load f }