diff --git a/Gemfile.lock b/Gemfile.lock index 408e0a08c11..4c56e998018 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -372,7 +372,7 @@ GEM faraday_middleware multi_json fast_blank (1.0.0) - fast_gettext (1.6.0) + fast_gettext (2.1.0) ffaker (2.10.0) ffi (1.15.3) ffi-compiler (1.0.1) diff --git a/db/migrate/20210830140524_add_state_to_member.rb b/db/migrate/20210830140524_add_state_to_member.rb new file mode 100644 index 00000000000..6009376badb --- /dev/null +++ b/db/migrate/20210830140524_add_state_to_member.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddStateToMember < ActiveRecord::Migration[6.1] + include Gitlab::Database::MigrationHelpers + + def up + unless column_exists?(:members, :state) + with_lock_retries do + add_column :members, :state, :integer, limit: 2, default: 0 + end + end + end + + def down + if column_exists?(:members, :state) + with_lock_retries do + remove_column :members, :state + end + end + end +end diff --git a/db/schema_migrations/20210830140524 b/db/schema_migrations/20210830140524 new file mode 100644 index 00000000000..ed07d932278 --- /dev/null +++ b/db/schema_migrations/20210830140524 @@ -0,0 +1 @@ +54f7c66eed745b62d0b53a407a96721f90392ab7f800db9c8a2607f22974ef3c \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 6467d3d19df..dbc7af116af 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -14873,7 +14873,8 @@ CREATE TABLE members ( requested_at timestamp without time zone, expires_at date, ldap boolean DEFAULT false NOT NULL, - override boolean DEFAULT false NOT NULL + override boolean DEFAULT false NOT NULL, + state smallint DEFAULT 0 ); CREATE SEQUENCE members_id_seq diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml index 56877970ce3..21d9470cfb1 100644 --- a/lib/gitlab/import_export/project/import_export.yml +++ b/lib/gitlab/import_export/project/import_export.yml @@ -333,6 +333,9 @@ excluded_attributes: project_members: - :source_id - :invite_email_success + - :state + group_members: + - :state metrics: - :merge_request_id - :pipeline_id diff --git a/lib/gitlab/sidekiq_cluster/cli.rb b/lib/gitlab/sidekiq_cluster/cli.rb index 05319ba17a2..3dee257229d 100644 --- a/lib/gitlab/sidekiq_cluster/cli.rb +++ b/lib/gitlab/sidekiq_cluster/cli.rb @@ -57,6 +57,11 @@ module Gitlab worker_queues = SidekiqConfig::CliMethods.worker_queues(@rails_path) queue_groups = argv.map do |queues_or_query_string| + if queues_or_query_string =~ /[\r\n]/ + raise CommandError, + 'The queue arguments cannot contain newlines' + end + next worker_queues if queues_or_query_string == SidekiqConfig::WorkerMatcher::WILDCARD_MATCH # When using the queue query syntax, we treat each queue group diff --git a/spec/bin/sidekiq_cluster_spec.rb b/spec/bin/sidekiq_cluster_spec.rb index 1bba048a27c..eb014c511e3 100644 --- a/spec/bin/sidekiq_cluster_spec.rb +++ b/spec/bin/sidekiq_cluster_spec.rb @@ -1,11 +1,14 @@ # frozen_string_literal: true -require 'spec_helper' +require 'fast_spec_helper' require 'shellwords' +require 'rspec-parameterized' -RSpec.describe 'bin/sidekiq-cluster' do +RSpec.describe 'bin/sidekiq-cluster', :aggregate_failures do using RSpec::Parameterized::TableSyntax + let(:root) { File.expand_path('../..', __dir__) } + context 'when selecting some queues and excluding others' do where(:args, :included, :excluded) do %w[--negate cronjob] | '-qdefault,1' | '-qcronjob,1' @@ -13,10 +16,10 @@ RSpec.describe 'bin/sidekiq-cluster' do end with_them do - it 'runs successfully', :aggregate_failures do + it 'runs successfully' do cmd = %w[bin/sidekiq-cluster --dryrun] + args - output, status = Gitlab::Popen.popen(cmd, Rails.root.to_s) + output, status = Gitlab::Popen.popen(cmd, root) expect(status).to be(0) expect(output).to include('bundle exec sidekiq') @@ -31,10 +34,10 @@ RSpec.describe 'bin/sidekiq-cluster' do %w[*], %w[--queue-selector *] ].each do |args| - it "runs successfully with `#{args}`", :aggregate_failures do + it "runs successfully with `#{args}`" do cmd = %w[bin/sidekiq-cluster --dryrun] + args - output, status = Gitlab::Popen.popen(cmd, Rails.root.to_s) + output, status = Gitlab::Popen.popen(cmd, root) expect(status).to be(0) expect(output).to include('bundle exec sidekiq') @@ -43,4 +46,20 @@ RSpec.describe 'bin/sidekiq-cluster' do end end end + + context 'when arguments contain newlines' do + it 'raises an error' do + [ + ["default\n"], + ["defaul\nt"] + ].each do |args| + cmd = %w[bin/sidekiq-cluster --dryrun] + args + + output, status = Gitlab::Popen.popen(cmd, root) + + expect(status).to be(1) + expect(output).to include('cannot contain newlines') + end + end + end end diff --git a/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb b/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb index 3dd5ac8ee6c..e818b03cf75 100644 --- a/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb +++ b/spec/lib/gitlab/sidekiq_cluster/cli_spec.rb @@ -48,6 +48,18 @@ RSpec.describe Gitlab::SidekiqCluster::CLI do cli.run(%w(*)) end + it 'raises an error when the arguments contain newlines' do + invalid_arguments = [ + ["foo\n"], + ["foo\r"], + %W[foo b\nar] + ] + + invalid_arguments.each do |arguments| + expect { cli.run(arguments) }.to raise_error(described_class::CommandError) + end + end + context 'with --negate flag' do it 'starts Sidekiq workers for all queues in all_queues.yml except the ones in argv' do expect(Gitlab::SidekiqConfig::CliMethods).to receive(:worker_queues).and_return(['baz']) diff --git a/.cross-join-allowlist.yml b/spec/support/database/cross-join-allowlist.yml similarity index 100% rename from .cross-join-allowlist.yml rename to spec/support/database/cross-join-allowlist.yml diff --git a/spec/support/database/prevent_cross_joins.rb b/spec/support/database/prevent_cross_joins.rb index fb92b622636..52c7bb49c50 100644 --- a/spec/support/database/prevent_cross_joins.rb +++ b/spec/support/database/prevent_cross_joins.rb @@ -81,7 +81,7 @@ end Gitlab::Database.singleton_class.prepend( Database::PreventCrossJoins::GitlabDatabaseMixin) -ALLOW_LIST = Set.new(YAML.load_file(Rails.root.join('.cross-join-allowlist.yml'))).freeze +ALLOW_LIST = Set.new(YAML.load_file(File.join(__dir__, 'cross-join-allowlist.yml'))).freeze RSpec.configure do |config| config.include(::Database::PreventCrossJoins::SpecHelpers)