Commit 93278597 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-11-05

# Conflicts:
#	app/assets/javascripts/notes/stores/getters.js
#	app/models/application_setting.rb
#	app/models/commit_status.rb
#	db/schema.rb

[ci skip]
parents bf184d1f ec37e707
import Vue from 'vue'; import Vue from 'vue';
import { GlLoadingIcon, GlTooltipDirective } from '@gitlab-org/gitlab-ui'; import { GlLoadingIcon } from '@gitlab-org/gitlab-ui';
Vue.component('gl-loading-icon', GlLoadingIcon); Vue.component('gl-loading-icon', GlLoadingIcon);
Vue.directive('gl-tooltip', GlTooltipDirective);
...@@ -3,6 +3,7 @@ import { mapActions } from 'vuex'; ...@@ -3,6 +3,7 @@ import { mapActions } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { pluralize, truncate } from '~/lib/utils/text_utility'; import { pluralize, truncate } from '~/lib/utils/text_utility';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue'; import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import { COUNT_OF_AVATARS_IN_GUTTER, LENGTH_OF_AVATAR_TOOLTIP } from '../constants'; import { COUNT_OF_AVATARS_IN_GUTTER, LENGTH_OF_AVATAR_TOOLTIP } from '../constants';
export default { export default {
...@@ -10,6 +11,9 @@ export default { ...@@ -10,6 +11,9 @@ export default {
Icon, Icon,
UserAvatarImage, UserAvatarImage,
}, },
directives: {
GlTooltip: GlTooltipDirective,
},
props: { props: {
discussions: { discussions: {
type: Array, type: Array,
......
...@@ -192,9 +192,12 @@ export const firstUnresolvedDiscussionId = (state, getters) => diffOrder => { ...@@ -192,9 +192,12 @@ export const firstUnresolvedDiscussionId = (state, getters) => diffOrder => {
return getters.unresolvedDiscussionsIdsByDate[0]; return getters.unresolvedDiscussionsIdsByDate[0];
}; };
<<<<<<< HEAD
export const getDiscussion = state => discussionId => export const getDiscussion = state => discussionId =>
state.discussions.find(discussion => discussion.id === discussionId); state.discussions.find(discussion => discussion.id === discussionId);
=======
>>>>>>> upstream/master
export const commentsDisabled = state => state.commentsDisabled; export const commentsDisabled = state => state.commentsDisabled;
// prevent babel-plugin-rewire from generating an invalid default during karma tests // prevent babel-plugin-rewire from generating an invalid default during karma tests
......
...@@ -5,7 +5,7 @@ import Icon from '~/vue_shared/components/icon.vue'; ...@@ -5,7 +5,7 @@ import Icon from '~/vue_shared/components/icon.vue';
import GfmAutoComplete from '~/gfm_auto_complete'; import GfmAutoComplete from '~/gfm_auto_complete';
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
import Api from '~/api'; import Api from '~/api';
import { GlModal } from '@gitlab-org/gitlab-ui'; import { GlModal, GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import eventHub from './event_hub'; import eventHub from './event_hub';
import EmojiMenuInModal from './emoji_menu_in_modal'; import EmojiMenuInModal from './emoji_menu_in_modal';
...@@ -16,6 +16,9 @@ export default { ...@@ -16,6 +16,9 @@ export default {
Icon, Icon,
GlModal, GlModal,
}, },
directives: {
GlTooltip: GlTooltipDirective,
},
props: { props: {
currentEmoji: { currentEmoji: {
type: String, type: String,
......
<script> <script>
import { calculateRemainingMilliseconds, formatTime } from '~/lib/utils/datetime_utility'; import { calculateRemainingMilliseconds, formatTime } from '~/lib/utils/datetime_utility';
import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
/** /**
* Counts down to a given end date. * Counts down to a given end date.
*/ */
export default { export default {
directives: {
GlTooltip: GlTooltipDirective,
},
props: { props: {
endDateString: { endDateString: {
type: String, type: String,
......
...@@ -348,6 +348,7 @@ ...@@ -348,6 +348,7 @@
@include media-breakpoint-down(xs) { @include media-breakpoint-down(xs) {
width: 100%; width: 100%;
margin: $btn-side-margin 0;
} }
} }
} }
......
...@@ -147,3 +147,9 @@ table { ...@@ -147,3 +147,9 @@ table {
} }
} }
} }
.top-area + .content-list {
th {
border-top: 0;
}
}
...@@ -39,10 +39,6 @@ ...@@ -39,10 +39,6 @@
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
svg {
vertical-align: middle;
}
} }
.next-run-cell { .next-run-cell {
...@@ -52,6 +48,10 @@ ...@@ -52,6 +48,10 @@
a { a {
color: $text-color; color: $text-color;
} }
svg {
vertical-align: middle;
}
} }
.pipeline-schedules-user-callout { .pipeline-schedules-user-callout {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
class PersonalAccessTokensFinder class PersonalAccessTokensFinder
attr_accessor :params attr_accessor :params
delegate :build, :find, :find_by, :find_by_token, to: :execute delegate :build, :find, :find_by_id, :find_by_token, to: :execute
def initialize(params = {}) def initialize(params = {})
@params = params @params = params
......
...@@ -6,7 +6,10 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -6,7 +6,10 @@ class ApplicationSetting < ActiveRecord::Base
include TokenAuthenticatable include TokenAuthenticatable
include IgnorableColumn include IgnorableColumn
include ChronicDurationAttribute include ChronicDurationAttribute
<<<<<<< HEAD
prepend EE::ApplicationSetting prepend EE::ApplicationSetting
=======
>>>>>>> upstream/master
add_authentication_token_field :runners_registration_token add_authentication_token_field :runners_registration_token
add_authentication_token_field :health_check_access_token add_authentication_token_field :health_check_access_token
......
...@@ -17,7 +17,7 @@ module Ci ...@@ -17,7 +17,7 @@ module Ci
metadata: nil, metadata: nil,
trace: nil, trace: nil,
junit: 'junit.xml', junit: 'junit.xml',
codequality: 'codequality.json', codequality: 'gl-code-quality-report.json',
sast: 'gl-sast-report.json', sast: 'gl-sast-report.json',
dependency_scanning: 'gl-dependency-scanning-report.json', dependency_scanning: 'gl-dependency-scanning-report.json',
container_scanning: 'gl-container-scanning-report.json', container_scanning: 'gl-container-scanning-report.json',
......
...@@ -55,7 +55,11 @@ class CommitStatus < ActiveRecord::Base ...@@ -55,7 +55,11 @@ class CommitStatus < ActiveRecord::Base
stale_schedule: 7, stale_schedule: 7,
job_execution_timeout: 8, job_execution_timeout: 8,
archived_failure: 9 archived_failure: 9
<<<<<<< HEAD
}.merge(EE_FAILURE_REASONS) }.merge(EE_FAILURE_REASONS)
=======
}
>>>>>>> upstream/master
## ##
# We still create some CommitStatuses outside of CreatePipelineService. # We still create some CommitStatuses outside of CreatePipelineService.
......
...@@ -4,6 +4,7 @@ class DeployToken < ActiveRecord::Base ...@@ -4,6 +4,7 @@ class DeployToken < ActiveRecord::Base
include Expirable include Expirable
include TokenAuthenticatable include TokenAuthenticatable
include PolicyActor include PolicyActor
include Gitlab::Utils::StrongMemoize
add_authentication_token_field :token add_authentication_token_field :token
AVAILABLE_SCOPES = %i(read_repository read_registry).freeze AVAILABLE_SCOPES = %i(read_repository read_registry).freeze
...@@ -49,7 +50,9 @@ class DeployToken < ActiveRecord::Base ...@@ -49,7 +50,9 @@ class DeployToken < ActiveRecord::Base
# to a single project, later we're going to extend # to a single project, later we're going to extend
# that to be for multiple projects and namespaces. # that to be for multiple projects and namespaces.
def project def project
projects.first strong_memoize(:project) do
projects.first
end
end end
def expires_at def expires_at
......
# frozen_string_literal: true
class PoolRepository < ActiveRecord::Base
POOL_PREFIX = '@pools'
belongs_to :shard
validates :shard, presence: true
# For now, only pool repositories are tracked in the database. However, we may
# want to add other repository types in the future
self.table_name = 'repositories'
has_many :pool_member_projects, class_name: 'Project', foreign_key: :pool_repository_id
def shard_name
shard&.name
end
def shard_name=(name)
self.shard = Shard.by_name(name)
end
end
...@@ -4,6 +4,15 @@ module Postgresql ...@@ -4,6 +4,15 @@ module Postgresql
class ReplicationSlot < ActiveRecord::Base class ReplicationSlot < ActiveRecord::Base
self.table_name = 'pg_replication_slots' self.table_name = 'pg_replication_slots'
# Returns true if there are any replication slots in use.
# PostgreSQL-compatible databases such as Aurora don't support
# replication slots, so this will return false as well.
def self.in_use?
transaction { exists? }
rescue ActiveRecord::StatementInvalid
false
end
# Returns true if the lag observed across all replication slots exceeds a # Returns true if the lag observed across all replication slots exceeds a
# given threshold. # given threshold.
# #
...@@ -11,6 +20,8 @@ module Postgresql ...@@ -11,6 +20,8 @@ module Postgresql
# statistics it takes between 1 and 5 seconds to replicate around # statistics it takes between 1 and 5 seconds to replicate around
# 100 MB of data. # 100 MB of data.
def self.lag_too_great?(max = 100.megabytes) def self.lag_too_great?(max = 100.megabytes)
return false unless in_use?
lag_function = "#{Gitlab::Database.pg_wal_lsn_diff}" \ lag_function = "#{Gitlab::Database.pg_wal_lsn_diff}" \
"(#{Gitlab::Database.pg_current_wal_insert_lsn}(), restart_lsn)::bigint" "(#{Gitlab::Database.pg_current_wal_insert_lsn}(), restart_lsn)::bigint"
......
...@@ -98,8 +98,7 @@ class Project < ActiveRecord::Base ...@@ -98,8 +98,7 @@ class Project < ActiveRecord::Base
unless: :ci_cd_settings, unless: :ci_cd_settings,
if: proc { ProjectCiCdSetting.available? } if: proc { ProjectCiCdSetting.available? }
after_create :set_last_activity_at after_create :set_timestamps_for_create
after_create :set_last_repository_updated_at
after_update :update_forks_visibility_level after_update :update_forks_visibility_level
before_destroy :remove_private_deploy_keys before_destroy :remove_private_deploy_keys
...@@ -127,6 +126,7 @@ class Project < ActiveRecord::Base ...@@ -127,6 +126,7 @@ class Project < ActiveRecord::Base
alias_attribute :title, :name alias_attribute :title, :name
# Relations # Relations
belongs_to :pool_repository
belongs_to :creator, class_name: 'User' belongs_to :creator, class_name: 'User'
belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'namespace_id' belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'namespace_id'
belongs_to :namespace belongs_to :namespace
...@@ -2101,13 +2101,8 @@ class Project < ActiveRecord::Base ...@@ -2101,13 +2101,8 @@ class Project < ActiveRecord::Base
gitlab_shell.exists?(repository_storage, "#{disk_path}.git") gitlab_shell.exists?(repository_storage, "#{disk_path}.git")
end end
# set last_activity_at to the same as created_at def set_timestamps_for_create
def set_last_activity_at update_columns(last_activity_at: self.created_at, last_repository_updated_at: self.created_at)
update_column(:last_activity_at, self.created_at)
end
def set_last_repository_updated_at
update_column(:last_repository_updated_at, self.created_at)
end end
def cross_namespace_reference?(from) def cross_namespace_reference?(from)
......
# frozen_string_literal: true
class Shard < ActiveRecord::Base
# Store shard names from the configuration file in the database. This is not a
# list of active shards - we just want to assign an immutable, unique ID to
# every shard name for easy indexing / referencing.
def self.populate!
return unless table_exists?
# The GitLab config does not change for the lifecycle of the process
in_config = Gitlab.config.repositories.storages.keys.map(&:to_s)
transaction do
in_db = all.pluck(:name)
missing = in_config - in_db
missing.map { |name| by_name(name) }
end
end
def self.by_name(name)
find_or_create_by(name: name)
rescue ActiveRecord::RecordNotUnique
retry
end
end
...@@ -460,12 +460,6 @@ class User < ActiveRecord::Base ...@@ -460,12 +460,6 @@ class User < ActiveRecord::Base
by_username(username).take! by_username(username).take!
end end
def find_by_personal_access_token(token_string)
return unless token_string
PersonalAccessTokensFinder.new(state: 'active').find_by_token(token_string)&.user # rubocop: disable CodeReuse/Finder
end
# Returns a user for the given SSH key. # Returns a user for the given SSH key.
def find_by_ssh_key_id(key_id) def find_by_ssh_key_id(key_id)
Key.find_by(id: key_id)&.user Key.find_by(id: key_id)&.user
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
- subscribed = params[:subscribed] - subscribed = params[:subscribed]
- labels_or_filters = @labels.exists? || search.present? || subscribed.present? - labels_or_filters = @labels.exists? || search.present? || subscribed.present?
- if can_admin_label - if @labels.present? && can_admin_label
- content_for(:header_content) do - content_for(:header_content) do
.nav-controls .nav-controls
= link_to _('New label'), new_group_label_path(@group), class: "btn btn-success" = link_to _('New label'), new_group_label_path(@group), class: "btn btn-success"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
- subscribed = params[:subscribed] - subscribed = params[:subscribed]
- labels_or_filters = @labels.exists? || @prioritized_labels.exists? || search.present? || subscribed.present? - labels_or_filters = @labels.exists? || @prioritized_labels.exists? || search.present? || subscribed.present?
- if can_admin_label - if @labels.present? && can_admin_label
- content_for(:header_content) do - content_for(:header_content) do
.nav-controls .nav-controls
= link_to _('New label'), new_project_label_path(@project), class: "btn btn-success qa-label-create-new" = link_to _('New label'), new_project_label_path(@project), class: "btn btn-success qa-label-create-new"
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
.text-content .text-content
%h4= _("Labels can be applied to issues and merge requests to categorize them.") %h4= _("Labels can be applied to issues and merge requests to categorize them.")
%p= _("You can also star a label to make it a priority label.") %p= _("You can also star a label to make it a priority label.")
- if can?(current_user, :admin_label, @project) .text-center
= link_to _('New label'), new_project_label_path(@project), class: 'btn btn-success', title: _('New label'), id: 'new_label_link' - if can?(current_user, :admin_label, @project)
= link_to _('Generate a default set of labels'), generate_project_labels_path(@project), method: :post, class: 'btn btn-success btn-inverted', title: _('Generate a default set of labels'), id: 'generate_labels_link' = link_to _('New label'), new_project_label_path(@project), class: 'btn btn-success', title: _('New label'), id: 'new_label_link'
= link_to _('Generate a default set of labels'), generate_project_labels_path(@project), method: :post, class: 'btn btn-success btn-inverted', title: _('Generate a default set of labels'), id: 'generate_labels_link'
- if can?(current_user, :admin_label, @group)
= link_to _('New label'), new_group_label_path(@group), class: 'btn btn-success', title: _('New label'), id: 'new_label_link'
---
title: Start tracking shards and pool repositories in the database
merge_request: 22482
author:
type: other
---
title: Fixing styling issues on the scheduled pipelines page
merge_request:
author:
type: fixed
---
title: Remove PersonalAccessTokensFinder#find_by method
merge_request: 22617
author:
type: fixed
---
title: Allow Rails concurrency when running in Puma
merge_request: 22751
author:
type: performance
---
title: Remove gitlab-ui's tooltip from global
merge_request:
author:
type: performance
---
title: Update project and group labels empty state
merge_request: 22745
author: George Tsiolis
type: changed
---
title: Disable replication lag check for Aurora PostgreSQL databases
merge_request: 22786
author:
type: fixed
...@@ -45,4 +45,6 @@ Rails.application.configure do ...@@ -45,4 +45,6 @@ Rails.application.configure do
# Do not log asset requests # Do not log asset requests
config.assets.quiet = true config.assets.quiet = true
config.allow_concurrency = defined?(::Puma)
end end
...@@ -83,5 +83,5 @@ Rails.application.configure do ...@@ -83,5 +83,5 @@ Rails.application.configure do
config.eager_load = true config.eager_load = true
config.allow_concurrency = false config.allow_concurrency = defined?(::Puma)
end end
return unless Shard.connected?
return if Gitlab::Database.read_only?
Shard.populate!
# frozen_string_literal: true
class AddIndexToProjectDeployTokensDeployTokenId < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
# MySQL already has index inserted
add_concurrent_index :project_deploy_tokens, :deploy_token_id if Gitlab::Database.postgresql?
end
def down
remove_concurrent_index(:project_deploy_tokens, :deploy_token_id) if Gitlab::Database.postgresql?
end
end
# frozen_string_literal: true
class AddShardsTable < ActiveRecord::Migration
DOWNTIME = false
def change
create_table :shards do |t|
t.string :name, null: false, index: { unique: true }
end
end
end
# frozen_string_literal: true
class AddRepositoriesTable < ActiveRecord::Migration
DOWNTIME = false
def change
create_table :repositories, id: :bigserial do |t|
t.references :shard, null: false, index: true, foreign_key: { on_delete: :restrict }
t.string :disk_path, null: false, index: { unique: true }
end
add_column :projects, :pool_repository_id, :bigint
add_index :projects, :pool_repository_id, where: 'pool_repository_id IS NOT NULL'
end
end
# frozen_string_literal: true
class AddProjectsPoolRepositoryIdForeignKey < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_foreign_key(
:projects,
:repositories,
column: :pool_repository_id,
on_delete: :nullify
)
end
def down
remove_foreign_key(:projects, column: :pool_repository_id)
end
end
...@@ -212,6 +212,7 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -212,6 +212,7 @@ ActiveRecord::Schema.define(version: 20181101144347) do
t.integer "receive_max_input_size" t.integer "receive_max_input_size"
t.integer "diff_max_patch_bytes", default: 102400, null: false t.integer "diff_max_patch_bytes", default: 102400, null: false
t.integer "archive_builds_in_seconds" t.integer "archive_builds_in_seconds"
<<<<<<< HEAD
end end
create_table "approvals", force: :cascade do |t| create_table "approvals", force: :cascade do |t|
...@@ -240,6 +241,8 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -240,6 +241,8 @@ ActiveRecord::Schema.define(version: 20181101144347) do
t.integer "user_id", null: false t.integer "user_id", null: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
=======
>>>>>>> upstream/master
end end
add_index "approvers", ["target_id", "target_type"], name: "index_approvers_on_target_id_and_target_type", using: :btree add_index "approvers", ["target_id", "target_type"], name: "index_approvers_on_target_id_and_target_type", using: :btree
...@@ -2156,6 +2159,7 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -2156,6 +2159,7 @@ ActiveRecord::Schema.define(version: 20181101144347) do
t.datetime_with_timezone "created_at", null: false t.datetime_with_timezone "created_at", null: false
end end
add_index "project_deploy_tokens", ["deploy_token_id"], name: "index_project_deploy_tokens_on_deploy_token_id", using: :btree
add_index "project_deploy_tokens", ["project_id", "deploy_token_id"], name: "index_project_deploy_tokens_on_project_id_and_deploy_token_id", unique: true, using: :btree add_index "project_deploy_tokens", ["project_id", "deploy_token_id"], name: "index_project_deploy_tokens_on_project_id_and_deploy_token_id", unique: true, using: :btree
create_table "project_features", force: :cascade do |t| create_table "project_features", force: :cascade do |t|
...@@ -2314,9 +2318,14 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -2314,9 +2318,14 @@ ActiveRecord::Schema.define(version: 20181101144347) do
t.string "external_authorization_classification_label" t.string "external_authorization_classification_label"
t.boolean "mirror_overwrites_diverged_branches" t.boolean "mirror_overwrites_diverged_branches"
t.boolean "pages_https_only", default: true t.boolean "pages_https_only", default: true
<<<<<<< HEAD
t.string "external_webhook_token" t.string "external_webhook_token"
t.boolean "packages_enabled" t.boolean "packages_enabled"
t.boolean "merge_requests_author_approval" t.boolean "merge_requests_author_approval"
=======
t.boolean "remote_mirror_available_overridden"
t.integer "pool_repository_id", limit: 8
>>>>>>> upstream/master
end end
add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree
...@@ -2336,6 +2345,7 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -2336,6 +2345,7 @@ ActiveRecord::Schema.define(version: 20181101144347) do
add_index "projects", ["path"], name: "index_projects_on_path", using: :btree add_index "projects", ["path"], name: "index_projects_on_path", using: :btree
add_index "projects", ["path"], name: "index_projects_on_path_trigram", using: :gin, opclasses: {"path"=>"gin_trgm_ops"} add_index "projects", ["path"], name: "index_projects_on_path_trigram", using: :gin, opclasses: {"path"=>"gin_trgm_ops"}
add_index "projects", ["pending_delete"], name: "index_projects_on_pending_delete", using: :btree add_index "projects", ["pending_delete"], name: "index_projects_on_pending_delete", using: :btree
add_index "projects", ["pool_repository_id"], name: "index_projects_on_pool_repository_id", where: "(pool_repository_id IS NOT NULL)", using: :btree
add_index "projects", ["repository_storage", "created_at"], name: "idx_project_repository_check_partial", where: "(last_repository_check_at IS NULL)", using: :btree add_index "projects", ["repository_storage", "created_at"], name: "idx_project_repository_check_partial", where: "(last_repository_check_at IS NULL)", using: :btree
add_index "projects", ["repository_storage"], name: "index_projects_on_repository_storage", using: :btree add_index "projects", ["repository_storage"], name: "index_projects_on_repository_storage", using: :btree
add_index "projects", ["runners_token"], name: "index_projects_on_runners_token", using: :btree add_index "projects", ["runners_token"], name: "index_projects_on_runners_token", using: :btree
...@@ -2558,6 +2568,14 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -2558,6 +2568,14 @@ ActiveRecord::Schema.define(version: 20181101144347) do
add_index "remote_mirrors", ["last_successful_update_at"], name: "index_remote_mirrors_on_last_successful_update_at", using: :btree add_index "remote_mirrors", ["last_successful_update_at"], name: "index_remote_mirrors_on_last_successful_update_at", using: :btree
add_index "remote_mirrors", ["project_id"], name: "index_remote_mirrors_on_project_id", using: :btree add_index "remote_mirrors", ["project_id"], name: "index_remote_mirrors_on_project_id", using: :btree
create_table "repositories", id: :bigserial, force: :cascade do |t|
t.integer "shard_id", null: false
t.string "disk_path", null: false
end
add_index "repositories", ["disk_path"], name: "index_repositories_on_disk_path", unique: true, using: :btree
add_index "repositories", ["shard_id"], name: "index_repositories_on_shard_id", using: :btree
create_table "repository_languages", id: false, force: :cascade do |t| create_table "repository_languages", id: false, force: :cascade do |t|
t.integer "project_id", null: false t.integer "project_id", null: false
t.integer "programming_language_id", null: false t.integer "programming_language_id", null: false
...@@ -2649,6 +2667,12 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -2649,6 +2667,12 @@ ActiveRecord::Schema.define(version: 20181101144347) do
add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree
add_index "services", ["template"], name: "index_services_on_template", using: :btree add_index "services", ["template"], name: "index_services_on_template", using: :btree
create_table "shards", force: :cascade do |t|
t.string "name", null: false
end
add_index "shards", ["name"], name: "index_shards_on_name", unique: true, using: :btree
create_table "site_statistics", force: :cascade do |t| create_table "site_statistics", force: :cascade do |t|
t.integer "repositories_count", default: 0, null: false t.integer "repositories_count", default: 0, null: false
end end
...@@ -3363,11 +3387,15 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -3363,11 +3387,15 @@ ActiveRecord::Schema.define(version: 20181101144347) do
add_foreign_key "project_mirror_data", "projects", name: "fk_d1aad367d7", on_delete: :cascade add_foreign_key "project_mirror_data", "projects", name: "fk_d1aad367d7", on_delete: :cascade
add_foreign_key "project_repository_states", "projects", on_delete: :cascade add_foreign_key "project_repository_states", "projects", on_delete: :cascade
add_foreign_key "project_statistics", "projects", on_delete: :cascade add_foreign_key "project_statistics", "projects", on_delete: :cascade
<<<<<<< HEAD
add_foreign_key "prometheus_alert_events", "projects", on_delete: :cascade add_foreign_key "prometheus_alert_events", "projects", on_delete: :cascade
add_foreign_key "prometheus_alert_events", "prometheus_alerts", on_delete: :cascade add_foreign_key "prometheus_alert_events", "prometheus_alerts", on_delete: :cascade
add_foreign_key "prometheus_alerts", "environments", on_delete: :cascade add_foreign_key "prometheus_alerts", "environments", on_delete: :cascade
add_foreign_key "prometheus_alerts", "projects", on_delete: :cascade add_foreign_key "prometheus_alerts", "projects", on_delete: :cascade
add_foreign_key "prometheus_alerts", "prometheus_metrics", on_delete: :cascade add_foreign_key "prometheus_alerts", "prometheus_metrics", on_delete: :cascade
=======
add_foreign_key "projects", "repositories", column: "pool_repository_id", name: "fk_6e5c14658a", on_delete: :nullify
>>>>>>> upstream/master
add_foreign_key "prometheus_metrics", "projects", on_delete: :cascade add_foreign_key "prometheus_metrics", "projects", on_delete: :cascade
add_foreign_key "protected_branch_merge_access_levels", "namespaces", column: "group_id", name: "fk_98f3d044fe", on_delete: :cascade add_foreign_key "protected_branch_merge_access_levels", "namespaces", column: "group_id", name: "fk_98f3d044fe", on_delete: :cascade
add_foreign_key "protected_branch_merge_access_levels", "protected_branches", name: "fk_8a3072ccb3", on_delete: :cascade add_foreign_key "protected_branch_merge_access_levels", "protected_branches", name: "fk_8a3072ccb3", on_delete: :cascade
...@@ -3390,7 +3418,12 @@ ActiveRecord::Schema.define(version: 20181101144347) do ...@@ -3390,7 +3418,12 @@ ActiveRecord::Schema.define(version: 20181101144347) do
add_foreign_key "push_event_payloads", "events", name: "fk_36c74129da", on_delete: :cascade add_foreign_key "push_event_payloads", "events", name: "fk_36c74129da", on_delete: :cascade
add_foreign_key "push_rules", "projects", name: "fk_83b29894de", on_delete: :cascade add_foreign_key "push_rules", "projects", name: "fk_83b29894de", on_delete: :cascade
add_foreign_key "releases", "projects", name: "fk_47fe2a0596", on_delete: :cascade add_foreign_key "releases", "projects", name: "fk_47fe2a0596", on_delete: :cascade
<<<<<<< HEAD
add_foreign_key "remote_mirrors", "projects", name: "fk_43a9aa4ca8", on_delete: :cascade add_foreign_key "remote_mirrors", "projects", name: "fk_43a9aa4ca8", on_delete: :cascade
=======
add_foreign_key "remote_mirrors", "projects", on_delete: :cascade
add_foreign_key "repositories", "shards", on_delete: :restrict
>>>>>>> upstream/master
add_foreign_key "repository_languages", "projects", on_delete: :cascade add_foreign_key "repository_languages", "projects", on_delete: :cascade
add_foreign_key "resource_label_events", "epics", on_delete: :cascade add_foreign_key "resource_label_events", "epics", on_delete: :cascade
add_foreign_key "resource_label_events", "issues", on_delete: :cascade add_foreign_key "resource_label_events", "issues", on_delete: :cascade
......
...@@ -518,11 +518,9 @@ module API ...@@ -518,11 +518,9 @@ module API
PersonalAccessTokensFinder.new({ user: user, impersonation: true }.merge(options)) PersonalAccessTokensFinder.new({ user: user, impersonation: true }.merge(options))
end end
# rubocop: disable CodeReuse/ActiveRecord
def find_impersonation_token def find_impersonation_token
finder.find_by(id: declared_params[:impersonation_token_id]) || not_found!('Impersonation Token') finder.find_by_id(declared_params[:impersonation_token_id]) || not_found!('Impersonation Token')
end end
# rubocop: enable CodeReuse/ActiveRecord
end end
before { authenticated_as_admin! } before { authenticated_as_admin! }
......
...@@ -95,6 +95,7 @@ excluded_attributes: ...@@ -95,6 +95,7 @@ excluded_attributes:
- :path - :path
- :namespace_id - :namespace_id
- :creator_id - :creator_id
- :pool_repository_id
- :import_url - :import_url
- :import_status - :import_status
- :avatar - :avatar
......
...@@ -92,7 +92,7 @@ describe PersonalAccessTokensFinder do ...@@ -92,7 +92,7 @@ describe PersonalAccessTokensFinder do
end end
describe 'with id' do describe 'with id' do
subject { finder(params).find_by(id: active_personal_access_token.id) } subject { finder(params).find_by_id(active_personal_access_token.id) }
it { is_expected.to eq(active_personal_access_token) } it { is_expected.to eq(active_personal_access_token) }
...@@ -106,7 +106,7 @@ describe PersonalAccessTokensFinder do ...@@ -106,7 +106,7 @@ describe PersonalAccessTokensFinder do
end end
describe 'with token' do describe 'with token' do
subject { finder(params).find_by(token: active_personal_access_token.token) } subject { finder(params).find_by_token(active_personal_access_token.token) }
it { is_expected.to eq(active_personal_access_token) } it { is_expected.to eq(active_personal_access_token) }
...@@ -207,7 +207,7 @@ describe PersonalAccessTokensFinder do ...@@ -207,7 +207,7 @@ describe PersonalAccessTokensFinder do
end end
describe 'with id' do describe 'with id' do
subject { finder(params).find_by(id: active_personal_access_token.id) } subject { finder(params).find_by_id(active_personal_access_token.id) }
it { is_expected.to eq(active_personal_access_token) } it { is_expected.to eq(active_personal_access_token) }
...@@ -221,7 +221,7 @@ describe PersonalAccessTokensFinder do ...@@ -221,7 +221,7 @@ describe PersonalAccessTokensFinder do
end end
describe 'with token' do describe 'with token' do
subject { finder(params).find_by(token: active_personal_access_token.token) } subject { finder(params).find_by_token(active_personal_access_token.token) }
it { is_expected.to eq(active_personal_access_token) } it { is_expected.to eq(active_personal_access_token) }
......
...@@ -33,7 +33,7 @@ describe Gitlab::Ci::Config::Entry::Reports do ...@@ -33,7 +33,7 @@ describe Gitlab::Ci::Config::Entry::Reports do
where(:keyword, :file) do where(:keyword, :file) do
:junit | 'junit.xml' :junit | 'junit.xml'
:codequality | 'codequality.json' :codequality | 'gl-code-quality-report.json'
:sast | 'gl-sast-report.json' :sast | 'gl-sast-report.json'
:dependency_scanning | 'gl-dependency-scanning-report.json' :dependency_scanning | 'gl-dependency-scanning-report.json'
:container_scanning | 'gl-container-scanning-report.json' :container_scanning | 'gl-container-scanning-report.json'
......
...@@ -298,6 +298,7 @@ project: ...@@ -298,6 +298,7 @@ project:
- ci_cd_settings - ci_cd_settings
- import_export_upload - import_export_upload
- repository_languages - repository_languages
- pool_repository
award_emoji: award_emoji:
- awardable - awardable
- user - user
......
...@@ -3,7 +3,27 @@ ...@@ -3,7 +3,27 @@
require 'spec_helper' require 'spec_helper'
describe Postgresql::ReplicationSlot, :postgresql do describe Postgresql::ReplicationSlot, :postgresql do
describe '.in_use?' do
it 'returns true when replication slots are present' do
expect(described_class).to receive(:exists?).and_return(true)
expect(described_class.in_use?).to be_truthy
end
it 'returns false when replication slots are not present' do
expect(described_class.in_use?).to be_falsey
end
it 'returns false if the existence check is invalid' do
expect(described_class).to receive(:exists?).and_raise(ActiveRecord::StatementInvalid.new('PG::FeatureNotSupported'))
expect(described_class.in_use?).to be_falsey
end
end
describe '.lag_too_great?' do describe '.lag_too_great?' do
before do
expect(described_class).to receive(:in_use?).and_return(true)
end
it 'returns true when replication lag is too great' do it 'returns true when replication lag is too great' do
expect(described_class) expect(described_class)
.to receive(:pluck) .to receive(:pluck)
......
...@@ -8,6 +8,7 @@ describe Project do ...@@ -8,6 +8,7 @@ describe Project do
it { is_expected.to belong_to(:group) } it { is_expected.to belong_to(:group) }
it { is_expected.to belong_to(:namespace) } it { is_expected.to belong_to(:namespace) }
it { is_expected.to belong_to(:creator).class_name('User') } it { is_expected.to belong_to(:creator).class_name('User') }
it { is_expected.to belong_to(:pool_repository) }
it { is_expected.to have_many(:users) } it { is_expected.to have_many(:users) }
it { is_expected.to have_many(:services) } it { is_expected.to have_many(:services) }
it { is_expected.to have_many(:events) } it { is_expected.to have_many(:events) }
......
# frozen_string_literals: true
require 'spec_helper'
describe Shard do
describe '.populate!' do
it 'creates shards based on the config file' do
expect(described_class.all).to be_empty
stub_storage_settings(foo: {}, bar: {}, baz: {})
described_class.populate!
expect(described_class.all.map(&:name)).to match_array(%w[default foo bar baz])
end
end
describe '.by_name' do
let(:default_shard) { described_class.find_by(name: 'default') }
before do
described_class.populate!
end
it 'returns an existing shard' do
expect(described_class.by_name('default')).to eq(default_shard)
end
it 'creates a new shard' do
result = described_class.by_name('foo')
expect(result).not_to eq(default_shard)
expect(result.name).to eq('foo')
end
it 'retries if creation races' do
expect(described_class)
.to receive(:find_or_create_by)
.with(name: 'default')
.and_raise(ActiveRecord::RecordNotUnique, 'fail')
.once
expect(described_class)
.to receive(:find_or_create_by)
.with(name: 'default')
.and_call_original
expect(described_class.by_name('default')).to eq(default_shard)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment