From 4b7575da97d88ef4c7b2ec599b0c3fc457b4f561 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 7 May 2020 18:09:28 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- Gemfile.lock | 2 +- Guardfile | 51 ++++++++++--- app/services/base_container_service.rb | 12 +++ app/services/base_service.rb | 73 +++---------------- app/services/concerns/base_service_utility.rb | 72 ++++++++++++++++++ .../update-recursive-open-struct-gem.yml | 5 ++ doc/.vale/gitlab/spelling-exceptions.txt | 1 - doc/ci/docker/using_docker_images.md | 20 ++++- ...and-deploy-python-application-to-heroku.md | 11 ++- ...t-and-deploy-ruby-application-to-heroku.md | 18 ++++- doc/ci/yaml/README.md | 7 +- doc/install/requirements.md | 8 +- doc/raketasks/cleanup.md | 5 ++ doc/user/application_security/dast/index.md | 13 ++-- .../integrations/mattermost_slash_commands.md | 15 +++- lib/gitlab/import_export/project/base_task.rb | 16 ++++ .../import_export/project/export_task.rb | 13 +++- .../import_export/project/import_task.rb | 18 ----- locale/gitlab.pot | 18 ----- .../import_export/project/export_task_spec.rb | 39 +++++++++- .../import_export/project/import_task_spec.rb | 47 ++---------- spec/services/base_container_service_spec.rb | 23 ++++++ ...rake_task_object_storage_shared_context.rb | 17 +++++ ...ake_task_object_storage_shared_examples.rb | 22 ++++++ 24 files changed, 345 insertions(+), 181 deletions(-) create mode 100644 app/services/base_container_service.rb create mode 100644 app/services/concerns/base_service_utility.rb create mode 100644 changelogs/unreleased/update-recursive-open-struct-gem.yml create mode 100644 spec/services/base_container_service_spec.rb create mode 100644 spec/support/shared_contexts/lib/gitlab/import_export/project/rake_task_object_storage_shared_context.rb create mode 100644 spec/support/shared_examples/lib/gitlab/import_export/project/rake_task_object_storage_shared_examples.rb diff --git a/Gemfile.lock b/Gemfile.lock index 5c9611fdbd1..caec5566219 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -857,7 +857,7 @@ GEM re2 (1.2.0) recaptcha (4.13.1) json - recursive-open-struct (1.1.0) + recursive-open-struct (1.1.1) redis (4.1.3) redis-actionpack (5.2.0) actionpack (>= 5, < 7) diff --git a/Guardfile b/Guardfile index 21ee2a9d610..baaa52bd204 100644 --- a/Guardfile +++ b/Guardfile @@ -2,28 +2,51 @@ # More info at https://github.com/guard/guard#readme +require "guard/rspec/dsl" + cmd = ENV['GUARD_CMD'] || (ENV['SPRING'] ? 'spring rspec' : 'bundle exec rspec') -guard :rspec, cmd: cmd do - require "guard/rspec/dsl" - dsl = Guard::RSpec::Dsl.new(self) +directories %w(app ee lib spec) - directories %w(app ee lib spec) +rspec_context_for = proc do |context_path| + OpenStruct.new(to_s: "spec").tap do |rspec| + rspec.spec_dir = "#{context_path}spec" + rspec.spec = ->(m) { Guard::RSpec::Dsl.detect_spec_file_for(rspec, m) } + rspec.spec_helper = "#{rspec.spec_dir}/spec_helper.rb" + rspec.spec_files = %r{^#{rspec.spec_dir}/.+_spec\.rb$} + rspec.spec_support = %r{^#{rspec.spec_dir}/support/(.+)\.rb$} + end +end +rails_context_for = proc do |context_path, exts| + OpenStruct.new.tap do |rails| + rails.app_files = %r{^#{context_path}app/(.+)\.rb$} + + rails.views = %r{^#{context_path}app/(views/.+/[^/]*\.(?:#{exts}))$} + rails.view_dirs = %r{^#{context_path}app/views/(.+)/[^/]*\.(?:#{exts})$} + rails.layouts = %r{^#{context_path}app/layouts/(.+)/[^/]*\.(?:#{exts})$} + + rails.controllers = %r{^#{context_path}app/controllers/(.+)_controller\.rb$} + rails.routes = "#{context_path}config/routes.rb" + rails.app_controller = "#{context_path}app/controllers/application_controller.rb" + rails.spec_helper = "#{context_path}spec/rails_helper.rb" + end +end + +guard_setup = proc do |context_path| # RSpec files - rspec = dsl.rspec + rspec = rspec_context_for.call(context_path) watch(rspec.spec_helper) { rspec.spec_dir } watch(rspec.spec_support) { rspec.spec_dir } watch(rspec.spec_files) # Ruby files - ruby = dsl.ruby - dsl.watch_spec_files_for(ruby.lib_files) + watch(%r{^#{context_path}(lib/.+)\.rb$}) { |m| rspec.spec.call(m[1]) } # Rails files - rails = dsl.rails(view_extensions: %w(erb haml slim)) - dsl.watch_spec_files_for(rails.app_files) - dsl.watch_spec_files_for(rails.views) + rails = rails_context_for.call(context_path, %w(erb haml slim)) + watch(rails.app_files) { |m| rspec.spec.call(m[1]) } + watch(rails.views) { |m| rspec.spec.call(m[1]) } watch(rails.controllers) do |m| [ @@ -41,3 +64,11 @@ guard :rspec, cmd: cmd do watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") } watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") } end + +context_paths = ['', 'ee/'] + +context_paths.each do |context_path| + guard :rspec, cmd: cmd, spec_paths: ["#{context_path}spec/"] do + guard_setup.call(context_path) + end +end diff --git a/app/services/base_container_service.rb b/app/services/base_container_service.rb new file mode 100644 index 00000000000..56e4b8c908c --- /dev/null +++ b/app/services/base_container_service.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Base class, scoped by container (project or group) +class BaseContainerService + include BaseServiceUtility + + attr_reader :container, :current_user, :params + + def initialize(container:, current_user: nil, params: {}) + @container, @current_user, @params = container, current_user, params.dup + end +end diff --git a/app/services/base_service.rb b/app/services/base_service.rb index bc0b968f516..b4c4b6980a8 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -1,7 +1,16 @@ # frozen_string_literal: true +# This is the original root class for service related classes, +# and due to historical reason takes a project as scope. +# Later separate base classes for different scopes will be created, +# and existing service will use these one by one. +# After all are migrated, we can remove this class. +# +# TODO: New services should consider inheriting from +# BaseContainerService, or create new base class: +# https://gitlab.com/gitlab-org/gitlab/-/issues/216672 class BaseService - include Gitlab::Allowable + include BaseServiceUtility attr_accessor :project, :current_user, :params @@ -9,67 +18,5 @@ class BaseService @project, @current_user, @params = project, user, params.dup end - def notification_service - NotificationService.new - end - - def event_service - EventCreateService.new - end - - def todo_service - TodoService.new - end - - def log_info(message) - Gitlab::AppLogger.info message - end - - def log_error(message) - Gitlab::AppLogger.error message - end - - def system_hook_service - SystemHooksService.new - end - delegate :repository, to: :project - - # Add an error to the specified model for restricted visibility levels - def deny_visibility_level(model, denied_visibility_level = nil) - denied_visibility_level ||= model.visibility_level - - level_name = Gitlab::VisibilityLevel.level_name(denied_visibility_level).downcase - - model.errors.add(:visibility_level, "#{level_name} has been restricted by your GitLab administrator") - end - - def visibility_level - params[:visibility].is_a?(String) ? Gitlab::VisibilityLevel.level_value(params[:visibility]) : params[:visibility_level] - end - - private - - # Return a Hash with an `error` status - # - # message - Error message to include in the Hash - # http_status - Optional HTTP status code override (default: nil) - # pass_back - Additional attributes to be included in the resulting Hash - def error(message, http_status = nil, pass_back: {}) - result = { - message: message, - status: :error - }.reverse_merge(pass_back) - - result[:http_status] = http_status if http_status - result - end - - # Return a Hash with a `success` status - # - # pass_back - Additional attributes to be included in the resulting Hash - def success(pass_back = {}) - pass_back[:status] = :success - pass_back - end end diff --git a/app/services/concerns/base_service_utility.rb b/app/services/concerns/base_service_utility.rb new file mode 100644 index 00000000000..70b223a0289 --- /dev/null +++ b/app/services/concerns/base_service_utility.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module BaseServiceUtility + extend ActiveSupport::Concern + include Gitlab::Allowable + + ### Convenience service methods + + def notification_service + NotificationService.new + end + + def event_service + EventCreateService.new + end + + def todo_service + TodoService.new + end + + def system_hook_service + SystemHooksService.new + end + + # Logging + + def log_info(message) + Gitlab::AppLogger.info message + end + + def log_error(message) + Gitlab::AppLogger.error message + end + + # Add an error to the specified model for restricted visibility levels + def deny_visibility_level(model, denied_visibility_level = nil) + denied_visibility_level ||= model.visibility_level + + level_name = Gitlab::VisibilityLevel.level_name(denied_visibility_level).downcase + + model.errors.add(:visibility_level, "#{level_name} has been restricted by your GitLab administrator") + end + + def visibility_level + params[:visibility].is_a?(String) ? Gitlab::VisibilityLevel.level_value(params[:visibility]) : params[:visibility_level] + end + + private + + # Return a Hash with an `error` status + # + # message - Error message to include in the Hash + # http_status - Optional HTTP status code override (default: nil) + # pass_back - Additional attributes to be included in the resulting Hash + def error(message, http_status = nil, pass_back: {}) + result = { + message: message, + status: :error + }.reverse_merge(pass_back) + + result[:http_status] = http_status if http_status + result + end + + # Return a Hash with a `success` status + # + # pass_back - Additional attributes to be included in the resulting Hash + def success(pass_back = {}) + pass_back[:status] = :success + pass_back + end +end diff --git a/changelogs/unreleased/update-recursive-open-struct-gem.yml b/changelogs/unreleased/update-recursive-open-struct-gem.yml new file mode 100644 index 00000000000..0bab3114d85 --- /dev/null +++ b/changelogs/unreleased/update-recursive-open-struct-gem.yml @@ -0,0 +1,5 @@ +--- +title: Update recursive-open-struct to 1.1.1 to make it compatible with ruby 2.7 +merge_request: 31047 +author: +type: fixed diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt index 1cabfe303fa..c5e89f72043 100644 --- a/doc/.vale/gitlab/spelling-exceptions.txt +++ b/doc/.vale/gitlab/spelling-exceptions.txt @@ -311,7 +311,6 @@ Slack Slony SMTP Sobelow -Sourcegraph spidering Splunk SpotBugs diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md index 004edcde735..2759d6de085 100644 --- a/doc/ci/docker/using_docker_images.md +++ b/doc/ci/docker/using_docker_images.md @@ -26,7 +26,20 @@ test them on a dedicated CI server. To use GitLab Runner with Docker you need to [register a new Runner](https://docs.gitlab.com/runner/register/) to use the `docker` executor. -A one-line example can be seen below: +An example can be seen below. First we set up a temporary template to supply the services: + +```shell +cat > /tmp/test-config.template.toml << EOF +[[runners]] +[runners.docker] +[[runners.docker.services]] +name = "postgres:latest" +[[runners.docker.services]] +name = "mysql:latest" +EOF +``` + +Then we register the runner using the template that was just created: ```shell sudo gitlab-runner register \ @@ -34,9 +47,8 @@ sudo gitlab-runner register \ --registration-token "PROJECT_REGISTRATION_TOKEN" \ --description "docker-ruby:2.6" \ --executor "docker" \ - --docker-image ruby:2.6 \ - --docker-services postgres:latest \ - --docker-services mysql:latest + --template-config /tmp/test-config.template.toml \ + --docker-image ruby:2.6 ``` The registered runner will use the `ruby:2.6` Docker image and will run two diff --git a/doc/ci/examples/test-and-deploy-python-application-to-heroku.md b/doc/ci/examples/test-and-deploy-python-application-to-heroku.md index 6d05c37390a..2c626cb458a 100644 --- a/doc/ci/examples/test-and-deploy-python-application-to-heroku.md +++ b/doc/ci/examples/test-and-deploy-python-application-to-heroku.md @@ -76,14 +76,21 @@ To build this project you also need to have [GitLab Runner](https://docs.gitlab. You can use public runners available on `gitlab.com` or you can register your own: ```shell +cat > /tmp/test-config.template.toml << EOF +[[runners]] +[runners.docker] +[[runners.docker.services]] +name = "postgres:latest" +EOF + gitlab-runner register \ --non-interactive \ --url "https://gitlab.com/" \ --registration-token "PROJECT_REGISTRATION_TOKEN" \ --description "python-3.5" \ --executor "docker" \ - --docker-image python:3.5 \ - --docker-services postgres:latest + --template-config /tmp/test-config.template.toml \ + --docker-image python:3.5 ``` With the command above, you create a runner that uses the [`python:3.5`](https://hub.docker.com/_/python) image and uses a [PostgreSQL](https://hub.docker.com/_/postgres) database. diff --git a/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md b/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md index e480f4565ce..f772f7bbfcd 100644 --- a/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md +++ b/doc/ci/examples/test-and-deploy-ruby-application-to-heroku.md @@ -64,7 +64,19 @@ You can do this through the [Heroku Dashboard](https://dashboard.heroku.com/). First install [Docker Engine](https://docs.docker.com/installation/). To build this project you also need to have [GitLab Runner](https://docs.gitlab.com/runner/). -You can use public runners available on `gitlab.com` or register your own: +You can use public runners available on `gitlab.com` or register your own. Start by +creating a template configuration file in order to pass complex configuration: + +```shell +cat > /tmp/test-config.template.toml << EOF +[[runners]] +[runners.docker] +[[runners.docker.services]] +name = "mysql:latest" +EOF +``` + +Finally, register the runner, passing the newly-created template configuration file: ```shell gitlab-runner register \ @@ -73,8 +85,8 @@ gitlab-runner register \ --registration-token "PROJECT_REGISTRATION_TOKEN" \ --description "ruby:2.6" \ --executor "docker" \ - --docker-image ruby:2.6 \ - --docker-services latest + --template-config /tmp/test-config.template.toml \ + --docker-image ruby:2.6 ``` With the command above, you create a Runner that uses the [`ruby:2.6`](https://hub.docker.com/_/ruby) image and uses a [PostgreSQL](https://hub.docker.com/_/postgres) database. diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 1cf57fb9db2..8e36bc1c7e4 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -2240,7 +2240,12 @@ globally and all jobs will use that definition. Use the `paths` directive to choose which files or directories will be cached. Paths are relative to the project directory (`$CI_PROJECT_DIR`) and can't directly link outside it. Wildcards can be used that follow the [glob](https://en.wikipedia.org/wiki/Glob_(programming)) -patterns and [`filepath.Match`](https://golang.org/pkg/path/filepath/#Match). +patterns and: + +- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later, +[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match). +- In GitLab Runner 12.10 and earlier, +[`filepath.Match`](https://pkg.go.dev/path/filepath/#Match). Cache all files in `binaries` that end in `.apk` and the `.config` file: diff --git a/doc/install/requirements.md b/doc/install/requirements.md index e3981b6b92b..27a65fe8181 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -11,10 +11,10 @@ as the hardware requirements that are needed to install and use GitLab. ### Supported Linux distributions -- Ubuntu -- Debian -- CentOS -- openSUSE +- Ubuntu (16.04/18.04) +- Debian (8/9/10) +- CentOS (6/7/8) +- openSUSE (Leap 15.1/Enterprise Server 12.2) - Red Hat Enterprise Linux (please use the CentOS packages and instructions) - Scientific Linux (please use the CentOS packages and instructions) - Oracle Linux (please use the CentOS packages and instructions) diff --git a/doc/raketasks/cleanup.md b/doc/raketasks/cleanup.md index e40fa1a9ef1..7908af8da84 100644 --- a/doc/raketasks/cleanup.md +++ b/doc/raketasks/cleanup.md @@ -179,3 +179,8 @@ sudo gitlab-rake gitlab:cleanup:sessions:active_sessions_lookup_keys # installation from source bundle exec rake gitlab:cleanup:sessions:active_sessions_lookup_keys RAILS_ENV=production ``` + +## Container Registry garbage collection + +Container Registry can use considerable amounts of disk space. To clear up +unused layers, the registry includes a [garbage collect command](../administration/packages/container_registry.md#container-registry-garbage-collection). diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md index 290269faaf8..f4c0764ae0b 100644 --- a/doc/user/application_security/dast/index.md +++ b/doc/user/application_security/dast/index.md @@ -95,11 +95,11 @@ There are two ways to define the URL to be scanned by DAST: persist its domain in an `environment_url.txt` file, and DAST automatically parses that file to find its scan target. You can see an [example](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml) - of this in our Auto DevOps CI YML. + of this in our Auto DevOps CI YAML. If both values are set, the `DAST_WEBSITE` value takes precedence. -The included template creates a `dast` job in your CI/CD pipeline and scan +The included template creates a `dast` job in your CI/CD pipeline and scans your project's source code for possible vulnerabilities. The results are saved as a @@ -133,7 +133,7 @@ stages: ``` Be aware that if your pipeline is configured to deploy to the same webserver in -each run, running a pipeline while another is still running, could cause a race condition +each run, running a pipeline while another is still running could cause a race condition where one pipeline overwrites the code from another pipeline. The site to be scanned should be excluded from changes for the duration of a DAST scan. The only changes to the site should be from the DAST scanner. Be aware that any @@ -583,9 +583,10 @@ The DAST tool always emits a JSON report file called `gl-dast-report.json` and sample reports can be found in the [DAST repository](https://gitlab.com/gitlab-org/security-products/dast/-/tree/master/test/end-to-end/expect). -There are two formats of data in the JSON report that are used side by side: the -proprietary ZAP format which will be eventually deprecated, and a "common" format -which will be the default in the future. +There are two formats of data in the JSON report that are used side by side: + +- The proprietary ZAP format that will be eventually deprecated. +- A common format that will be the default in the future. ### Other formats diff --git a/doc/user/project/integrations/mattermost_slash_commands.md b/doc/user/project/integrations/mattermost_slash_commands.md index a23d8d7306d..6a202c9a130 100644 --- a/doc/user/project/integrations/mattermost_slash_commands.md +++ b/doc/user/project/integrations/mattermost_slash_commands.md @@ -17,21 +17,21 @@ If you have the Omnibus GitLab package installed, Mattermost is already bundled in it. All you have to do is configure it. Read more in the [Omnibus GitLab Mattermost documentation](https://docs.gitlab.com/omnibus/gitlab-mattermost/). -## Automated Configuration +## Automated configuration If Mattermost is installed on the same server as GitLab, the configuration process can be done for you by GitLab. Go to the Mattermost Slash Command service on your project and click the 'Add to Mattermost' button. -## Manual Configuration +## Manual configuration The configuration consists of two parts. First you need to enable the slash commands in Mattermost and then enable the service in GitLab. ### Step 1. Enable custom slash commands in Mattermost -This step is only required when using a source install, omnibus installs will be +This step is only required when using a source install, Omnibus installs will be preconfigured with the right settings. The first thing to do in Mattermost is to enable custom slash commands from @@ -145,6 +145,15 @@ trigger word followed by help. Example: `/gitlab help` The permissions to run the [available commands](#available-slash-commands) derive from the [permissions you have on the project](../../permissions.md#project-members-permissions). +## Troubleshooting + +If an event is not being triggered, confirm that the channel you're using is a public one, as +Mattermost webhooks do not have access to private channels. + +If a private channel is required, you can edit the webhook's channel in Mattermost and +select a private channel. It is not possible to use different channels for +different types of notifications - all events will be sent to the specified channel. + ## Further reading - [Mattermost slash commands documentation](https://docs.mattermost.com/developer/slash-commands.html) diff --git a/lib/gitlab/import_export/project/base_task.rb b/lib/gitlab/import_export/project/base_task.rb index 5c75eca2bed..f6afbfcc50d 100644 --- a/lib/gitlab/import_export/project/base_task.rb +++ b/lib/gitlab/import_export/project/base_task.rb @@ -26,6 +26,22 @@ module Gitlab } end + def disable_upload_object_storage + overwrite_uploads_setting('enabled', false) do + yield + end + end + + def overwrite_uploads_setting(key, value) + old_value = Settings.uploads.object_store[key] + Settings.uploads.object_store[key] = value + + yield + + ensure + Settings.uploads.object_store[key] = old_value + end + def success(message) logger.info(message) diff --git a/lib/gitlab/import_export/project/export_task.rb b/lib/gitlab/import_export/project/export_task.rb index 22efd0cb8a3..4919ace0742 100644 --- a/lib/gitlab/import_export/project/export_task.rb +++ b/lib/gitlab/import_export/project/export_task.rb @@ -19,7 +19,11 @@ module Gitlab .execute(Gitlab::ImportExport::AfterExportStrategies::MoveFileStrategy.new(archive_path: file_path), measurement_options) end + return error(project.import_export_shared.errors.join(', ')) if project.import_export_shared.errors.any? + success('Done!') + rescue Gitlab::ImportExport::Error => e + error(e.message) end private @@ -32,8 +36,13 @@ module Gitlab def with_export with_request_store do - ::Gitlab::GitalyClient.allow_n_plus_1_calls do - yield + # We are disabling ObjectStorage for `export` + # since when direct upload is enabled, remote storage will be used + # and Gitlab::ImportExport::AfterExportStrategies::MoveFileStrategy will fail to copy exported archive + disable_upload_object_storage do + ::Gitlab::GitalyClient.allow_n_plus_1_calls do + yield + end end end end diff --git a/lib/gitlab/import_export/project/import_task.rb b/lib/gitlab/import_export/project/import_task.rb index 101cc5f5ab0..20f7ac1eb18 100644 --- a/lib/gitlab/import_export/project/import_task.rb +++ b/lib/gitlab/import_export/project/import_task.rb @@ -67,24 +67,6 @@ module Gitlab Sidekiq::Worker.drain_all end - def disable_upload_object_storage - overwrite_uploads_setting('background_upload', false) do - overwrite_uploads_setting('direct_upload', false) do - yield - end - end - end - - def overwrite_uploads_setting(key, value) - old_value = Settings.uploads.object_store[key] - Settings.uploads.object_store[key] = value - - yield - - ensure - Settings.uploads.object_store[key] = old_value - end - def full_path "#{namespace.full_path}/#{project_path}" end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index abb751000b1..11bebabf468 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -9121,12 +9121,6 @@ msgstr "" msgid "FeatureFlags|Edit Feature Flag" msgstr "" -msgid "FeatureFlags|Edit Feature Flag User List" -msgstr "" - -msgid "FeatureFlags|Edit list" -msgstr "" - msgid "FeatureFlags|Enable features for specific users and specific environments by defining feature flag strategies. By default, features are available to all users in all environments." msgstr "" @@ -9139,9 +9133,6 @@ msgstr "" msgid "FeatureFlags|Feature Flag" msgstr "" -msgid "FeatureFlags|Feature Flag User List Details" -msgstr "" - msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}." msgstr "" @@ -9178,9 +9169,6 @@ msgstr "" msgid "FeatureFlags|Instance ID" msgstr "" -msgid "FeatureFlags|List details" -msgstr "" - msgid "FeatureFlags|Loading feature flags" msgstr "" @@ -9196,15 +9184,9 @@ msgstr "" msgid "FeatureFlags|New Feature Flag" msgstr "" -msgid "FeatureFlags|New Feature Flag User List" -msgstr "" - msgid "FeatureFlags|New feature flag" msgstr "" -msgid "FeatureFlags|New list" -msgstr "" - msgid "FeatureFlags|Percent rollout (logged in users)" msgstr "" diff --git a/spec/lib/gitlab/import_export/project/export_task_spec.rb b/spec/lib/gitlab/import_export/project/export_task_spec.rb index 7c091c43637..dc8eb54dc14 100644 --- a/spec/lib/gitlab/import_export/project/export_task_spec.rb +++ b/spec/lib/gitlab/import_export/project/export_task_spec.rb @@ -10,6 +10,7 @@ describe Gitlab::ImportExport::Project::ExportTask do let(:file_path) { 'spec/fixtures/gitlab/import_export/test_project_export.tar.gz' } let(:project) { create(:project, creator: user, namespace: user.namespace) } let(:project_name) { project.name } + let(:rake_task) { described_class.new(task_params) } let(:task_params) do { @@ -21,7 +22,7 @@ describe Gitlab::ImportExport::Project::ExportTask do } end - subject { described_class.new(task_params).export } + subject { rake_task.export } context 'when project is found' do let(:project) { create(:project, creator: user, namespace: user.namespace) } @@ -29,9 +30,13 @@ describe Gitlab::ImportExport::Project::ExportTask do around do |example| example.run ensure - File.delete(file_path) + File.delete(file_path) if File.exist?(file_path) end + include_context 'rake task object storage shared context' + + it_behaves_like 'rake task with disabled object_storage', ::Projects::ImportExport::ExportService, :success + it 'performs project export successfully' do expect { subject }.to output(/Done!/).to_stdout @@ -39,8 +44,6 @@ describe Gitlab::ImportExport::Project::ExportTask do expect(File).to exist(file_path) end - - it_behaves_like 'measurable' end context 'when project is not found' do @@ -66,4 +69,32 @@ describe Gitlab::ImportExport::Project::ExportTask do expect(subject).to eq(false) end end + + context 'when after export strategy fails' do + before do + allow_next_instance_of(Gitlab::ImportExport::AfterExportStrategies::MoveFileStrategy) do |after_export_strategy| + allow(after_export_strategy).to receive(:strategy_execute).and_raise(Gitlab::ImportExport::AfterExportStrategies::BaseAfterExportStrategy::StrategyError) + end + end + + it 'error is logged' do + expect(rake_task).to receive(:error).and_call_original + + expect(subject).to eq(false) + end + end + + context 'when saving services fail' do + before do + allow_next_instance_of(::Projects::ImportExport::ExportService) do |service| + allow(service).to receive(:execute).and_raise(Gitlab::ImportExport::Error) + end + end + + it 'error is logged' do + expect(rake_task).to receive(:error).and_call_original + + expect(subject).to eq(false) + end + end end diff --git a/spec/lib/gitlab/import_export/project/import_task_spec.rb b/spec/lib/gitlab/import_export/project/import_task_spec.rb index 4f4fcd3ad8a..d83cc173388 100644 --- a/spec/lib/gitlab/import_export/project/import_task_spec.rb +++ b/spec/lib/gitlab/import_export/project/import_task_spec.rb @@ -8,7 +8,7 @@ describe Gitlab::ImportExport::Project::ImportTask, :request_store do let!(:user) { create(:user, username: username) } let(:measurement_enabled) { false } let(:project) { Project.find_by_full_path("#{namespace_path}/#{project_name}") } - let(:import_task) { described_class.new(task_params) } + let(:rake_task) { described_class.new(task_params) } let(:task_params) do { username: username, @@ -19,29 +19,16 @@ describe Gitlab::ImportExport::Project::ImportTask, :request_store do } end - before do - allow(Settings.uploads.object_store).to receive(:[]=).and_call_original - end - - around do |example| - old_direct_upload_setting = Settings.uploads.object_store['direct_upload'] - old_background_upload_setting = Settings.uploads.object_store['background_upload'] - - Settings.uploads.object_store['direct_upload'] = true - Settings.uploads.object_store['background_upload'] = true - - example.run - - Settings.uploads.object_store['direct_upload'] = old_direct_upload_setting - Settings.uploads.object_store['background_upload'] = old_background_upload_setting - end - - subject { import_task.import } + subject { rake_task.import } context 'when project import is valid' do let(:project_name) { 'import_rake_test_project' } let(:file_path) { 'spec/fixtures/gitlab/import_export/lightweight_project_export.tar.gz' } + include_context 'rake task object storage shared context' + + it_behaves_like 'rake task with disabled object_storage', ::Projects::GitlabProjectsImportService, :execute_sidekiq_job + it 'performs project import successfully' do expect { subject }.to output(/Done!/).to_stdout expect { subject }.not_to raise_error @@ -53,28 +40,6 @@ describe Gitlab::ImportExport::Project::ImportTask, :request_store do expect(project.import_state.status).to eq('finished') end - it 'disables direct & background upload only during project creation' do - expect_next_instance_of(Projects::GitlabProjectsImportService) do |service| - expect(service).to receive(:execute).and_wrap_original do |m| - expect(Settings.uploads.object_store['background_upload']).to eq(false) - expect(Settings.uploads.object_store['direct_upload']).to eq(false) - - m.call - end - end - - expect(import_task).to receive(:execute_sidekiq_job).and_wrap_original do |m| - expect(Settings.uploads.object_store['background_upload']).to eq(true) - expect(Settings.uploads.object_store['direct_upload']).to eq(true) - expect(Settings.uploads.object_store).not_to receive(:[]=).with('backgroud_upload', false) - expect(Settings.uploads.object_store).not_to receive(:[]=).with('direct_upload', false) - - m.call - end - - subject - end - it_behaves_like 'measurable' end diff --git a/spec/services/base_container_service_spec.rb b/spec/services/base_container_service_spec.rb new file mode 100644 index 00000000000..47cfb387e25 --- /dev/null +++ b/spec/services/base_container_service_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe BaseContainerService do + let(:project) { Project.new } + let(:user) { User.new } + + describe '#initialize' do + it 'accepts container and current_user' do + subject = described_class.new(container: project, current_user: user) + + expect(subject.container).to eq(project) + expect(subject.current_user).to eq(user) + end + + it 'treats current_user as optional' do + subject = described_class.new(container: project) + + expect(subject.current_user).to be_nil + end + end +end diff --git a/spec/support/shared_contexts/lib/gitlab/import_export/project/rake_task_object_storage_shared_context.rb b/spec/support/shared_contexts/lib/gitlab/import_export/project/rake_task_object_storage_shared_context.rb new file mode 100644 index 00000000000..dc1a52e3629 --- /dev/null +++ b/spec/support/shared_contexts/lib/gitlab/import_export/project/rake_task_object_storage_shared_context.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +RSpec.shared_context 'rake task object storage shared context' do + before do + allow(Settings.uploads.object_store).to receive(:[]=).and_call_original + end + + around do |example| + old_object_store_setting = Settings.uploads.object_store['enabled'] + + Settings.uploads.object_store['enabled'] = true + + example.run + + Settings.uploads.object_store['enabled'] = old_object_store_setting + end +end diff --git a/spec/support/shared_examples/lib/gitlab/import_export/project/rake_task_object_storage_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/import_export/project/rake_task_object_storage_shared_examples.rb new file mode 100644 index 00000000000..d6dc89a2c15 --- /dev/null +++ b/spec/support/shared_examples/lib/gitlab/import_export/project/rake_task_object_storage_shared_examples.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'rake task with disabled object_storage' do |service_class, method| + it 'disables direct & background upload only for service call' do + expect_next_instance_of(service_class) do |service| + expect(service).to receive(:execute).and_wrap_original do |m| + expect(Settings.uploads.object_store['enabled']).to eq(false) + + m.call + end + end + + expect(rake_task).to receive(method).and_wrap_original do |m, *args| + expect(Settings.uploads.object_store['enabled']).to eq(true) + expect(Settings.uploads.object_store).not_to receive(:[]=).with('enabled', false) + + m.call(*args) + end + + subject + end +end