Commit 34fade4e authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 4148328b be10da6a
# frozen_string_literal: true
module Ci
class ApplicationRecord < ::ApplicationRecord
self.abstract_class = true
def self.table_name_prefix
'ci_'
end
def self.model_name
@model_name ||= ActiveModel::Name.new(self, nil, self.name.demodulize)
end
end
end
......@@ -3,10 +3,9 @@
module Ci
# The purpose of this class is to store Build related data that can be disposed.
# Data that should be persisted forever, should be stored with Ci::Build model.
class BuildMetadata < ApplicationRecord
class BuildMetadata < Ci::ApplicationRecord
BuildTimeout = Struct.new(:value, :source)
extend Gitlab::Ci::Model
include Presentable
include ChronicDurationAttribute
include Gitlab::Utils::StrongMemoize
......
# frozen_string_literal: true
module Ci
class BuildNeed < ApplicationRecord
extend Gitlab::Ci::Model
class BuildNeed < Ci::ApplicationRecord
include BulkInsertSafe
include IgnorableColumns
......
# frozen_string_literal: true
class Ci::BuildPendingState < ApplicationRecord
extend Gitlab::Ci::Model
class Ci::BuildPendingState < Ci::ApplicationRecord
belongs_to :build, class_name: 'Ci::Build', foreign_key: :build_id
enum state: Ci::Stage.statuses
......
# frozen_string_literal: true
module Ci
class BuildReportResult < ApplicationRecord
extend Gitlab::Ci::Model
class BuildReportResult < Ci::ApplicationRecord
self.primary_key = :build_id
belongs_to :build, class_name: "Ci::Build", inverse_of: :report_results
......
......@@ -3,8 +3,7 @@
module Ci
# The purpose of this class is to store Build related runner session.
# Data will be removed after transitioning from running to any state.
class BuildRunnerSession < ApplicationRecord
extend Gitlab::Ci::Model
class BuildRunnerSession < Ci::ApplicationRecord
include IgnorableColumns
ignore_columns :build_id_convert_to_bigint, remove_with: '14.1', remove_after: '2021-07-22'
......
# frozen_string_literal: true
module Ci
class BuildTraceChunk < ApplicationRecord
extend ::Gitlab::Ci::Model
class BuildTraceChunk < Ci::ApplicationRecord
include ::Comparable
include ::FastDestroyAll
include ::Checksummable
......
......@@ -7,7 +7,7 @@ module Ci
# This class is part of a migration to move all CI classes to a new separate database.
# Initially we are only going to be moving the `Ci::InstanceVariable` model and it will be duplicated in the main and CI tables
# Do not extend this class in any other models.
class BaseModel < ::ApplicationRecord
class CiDatabaseRecord < Ci::ApplicationRecord
self.abstract_class = true
if Gitlab::Database.has_config?(:ci)
......
# frozen_string_literal: true
module Ci
class DailyBuildGroupReportResult < ApplicationRecord
extend Gitlab::Ci::Model
class DailyBuildGroupReportResult < Ci::ApplicationRecord
PARAM_TYPES = %w[coverage].freeze
belongs_to :last_pipeline, class_name: 'Ci::Pipeline', foreign_key: :last_pipeline_id
......
# frozen_string_literal: true
module Ci
class DeletedObject < ApplicationRecord
extend Gitlab::Ci::Model
class DeletedObject < Ci::ApplicationRecord
mount_uploader :file, DeletedObjectUploader
scope :ready_for_destruction, ->(limit) do
......
# frozen_string_literal: true
module Ci
class FreezePeriod < ApplicationRecord
class FreezePeriod < Ci::ApplicationRecord
include StripAttribute
self.table_name = 'ci_freeze_periods'
include Ci::NamespacedModelName
default_scope { order(created_at: :asc) } # rubocop:disable Cop/DefaultScope
......
# frozen_string_literal: true
module Ci
class GroupVariable < ApplicationRecord
extend Gitlab::Ci::Model
class GroupVariable < Ci::ApplicationRecord
include Ci::HasVariable
include Presentable
include Ci::Maskable
......
# frozen_string_literal: true
module Ci
class InstanceVariable < ::Ci::BaseModel
extend Gitlab::Ci::Model
class InstanceVariable < Ci::CiDatabaseRecord
extend Gitlab::ProcessMemoryCache::Helper
include Ci::NewHasVariable
include Ci::Maskable
......
# frozen_string_literal: true
module Ci
class JobArtifact < ApplicationRecord
class JobArtifact < Ci::ApplicationRecord
include AfterCommitQueue
include ObjectStorage::BackgroundMove
include UpdateProjectStatistics
......@@ -10,7 +10,6 @@ module Ci
include Artifactable
include FileStoreMounter
include EachBatch
extend Gitlab::Ci::Model
TEST_REPORT_FILE_TYPES = %w[junit].freeze
COVERAGE_REPORT_FILE_TYPES = %w[cobertura].freeze
......
# frozen_string_literal: true
module Ci
class JobVariable < ApplicationRecord
extend Gitlab::Ci::Model
class JobVariable < Ci::ApplicationRecord
include Ci::NewHasVariable
include BulkInsertSafe
......
# frozen_string_literal: true
module Ci
class PendingBuild < ApplicationRecord
extend Gitlab::Ci::Model
class PendingBuild < Ci::ApplicationRecord
belongs_to :project
belongs_to :build, class_name: 'Ci::Build'
......
# frozen_string_literal: true
module Ci
class Pipeline < ApplicationRecord
extend Gitlab::Ci::Model
class Pipeline < Ci::ApplicationRecord
include Ci::HasStatus
include Importable
include AfterCommitQueue
......
......@@ -3,8 +3,7 @@
# This class is being used to persist additional artifacts after a pipeline completes, which is a great place to cache a computed result in object storage
module Ci
class PipelineArtifact < ApplicationRecord
extend Gitlab::Ci::Model
class PipelineArtifact < Ci::ApplicationRecord
include UpdateProjectStatistics
include Artifactable
include FileStoreMounter
......
# frozen_string_literal: true
module Ci
class PipelineChatData < ApplicationRecord
class PipelineChatData < Ci::ApplicationRecord
include Ci::NamespacedModelName
self.table_name = 'ci_pipeline_chat_data'
belongs_to :chat_name
......
# frozen_string_literal: true
module Ci
class PipelineConfig < ApplicationRecord
extend Gitlab::Ci::Model
class PipelineConfig < Ci::ApplicationRecord
self.table_name = 'ci_pipelines_config'
self.primary_key = :pipeline_id
......
# frozen_string_literal: true
module Ci
class PipelineMessage < ApplicationRecord
extend Gitlab::Ci::Model
class PipelineMessage < Ci::ApplicationRecord
MAX_CONTENT_LENGTH = 10_000
belongs_to :pipeline
......
# frozen_string_literal: true
module Ci
class PipelineSchedule < ApplicationRecord
extend Gitlab::Ci::Model
class PipelineSchedule < Ci::ApplicationRecord
extend ::Gitlab::Utils::Override
include Importable
include StripAttribute
......
# frozen_string_literal: true
module Ci
class PipelineScheduleVariable < ApplicationRecord
extend Gitlab::Ci::Model
class PipelineScheduleVariable < Ci::ApplicationRecord
include Ci::HasVariable
belongs_to :pipeline_schedule
......
# frozen_string_literal: true
module Ci
class PipelineVariable < ApplicationRecord
extend Gitlab::Ci::Model
class PipelineVariable < Ci::ApplicationRecord
include Ci::HasVariable
belongs_to :pipeline
......
# frozen_string_literal: true
module Ci
class Ref < ApplicationRecord
extend Gitlab::Ci::Model
class Ref < Ci::ApplicationRecord
include AfterCommitQueue
include Gitlab::OptimisticLocking
......
# frozen_string_literal: true
module Ci
class Resource < ApplicationRecord
extend Gitlab::Ci::Model
class Resource < Ci::ApplicationRecord
belongs_to :resource_group, class_name: 'Ci::ResourceGroup', inverse_of: :resources
belongs_to :processable, class_name: 'Ci::Processable', foreign_key: 'build_id', inverse_of: :resource
......
# frozen_string_literal: true
module Ci
class ResourceGroup < ApplicationRecord
extend Gitlab::Ci::Model
class ResourceGroup < Ci::ApplicationRecord
belongs_to :project, inverse_of: :resource_groups
has_many :resources, class_name: 'Ci::Resource', inverse_of: :resource_group
......
# frozen_string_literal: true
module Ci
class Runner < ApplicationRecord
extend Gitlab::Ci::Model
class Runner < Ci::ApplicationRecord
include Gitlab::SQL::Pattern
include RedisCacheable
include ChronicDurationAttribute
......
# frozen_string_literal: true
module Ci
class RunnerNamespace < ApplicationRecord
extend Gitlab::Ci::Model
class RunnerNamespace < Ci::ApplicationRecord
include Limitable
self.limit_name = 'ci_registered_group_runners'
......
# frozen_string_literal: true
module Ci
class RunnerProject < ApplicationRecord
extend Gitlab::Ci::Model
class RunnerProject < Ci::ApplicationRecord
include Limitable
self.limit_name = 'ci_registered_project_runners'
......
# frozen_string_literal: true
module Ci
class RunningBuild < ApplicationRecord
extend Gitlab::Ci::Model
class RunningBuild < Ci::ApplicationRecord
belongs_to :project
belongs_to :build, class_name: 'Ci::Build'
belongs_to :runner, class_name: 'Ci::Runner'
......
......@@ -2,7 +2,9 @@
module Ci
module Sources
class Pipeline < ApplicationRecord
class Pipeline < Ci::ApplicationRecord
include Ci::NamespacedModelName
self.table_name = "ci_sources_pipelines"
belongs_to :project, class_name: "Project"
......
# frozen_string_literal: true
module Ci
class Stage < ApplicationRecord
extend Gitlab::Ci::Model
class Stage < Ci::ApplicationRecord
include Importable
include Ci::HasStatus
include Gitlab::OptimisticLocking
......
# frozen_string_literal: true
module Ci
class Trigger < ApplicationRecord
extend Gitlab::Ci::Model
class Trigger < Ci::ApplicationRecord
include Presentable
belongs_to :project
......
# frozen_string_literal: true
module Ci
class TriggerRequest < ApplicationRecord
extend Gitlab::Ci::Model
class TriggerRequest < Ci::ApplicationRecord
belongs_to :trigger
belongs_to :pipeline, foreign_key: :commit_id
has_many :builds
......
# frozen_string_literal: true
module Ci
class UnitTest < ApplicationRecord
extend Gitlab::Ci::Model
class UnitTest < Ci::ApplicationRecord
MAX_NAME_SIZE = 255
MAX_SUITE_NAME_SIZE = 255
......
# frozen_string_literal: true
module Ci
class UnitTestFailure < ApplicationRecord
extend Gitlab::Ci::Model
class UnitTestFailure < Ci::ApplicationRecord
REPORT_WINDOW = 14.days
validates :unit_test, :build, :failed_at, presence: true
......
# frozen_string_literal: true
module Ci
class Variable < ApplicationRecord
extend Gitlab::Ci::Model
class Variable < Ci::ApplicationRecord
include Ci::HasVariable
include Presentable
include Ci::Maskable
......
# frozen_string_literal: true
class CiPlatformMetric < ApplicationRecord
class CiPlatformMetric < Ci::ApplicationRecord
include BulkInsertSafe
self.table_name = 'ci_platform_metrics'
PLATFORM_TARGET_MAX_LENGTH = 255
validates :recorded_at, presence: true
......
# frozen_string_literal: true
class CommitStatus < ApplicationRecord
class CommitStatus < Ci::ApplicationRecord
include Ci::HasStatus
include Importable
include AfterCommitQueue
......
# frozen_string_literal: true
module Gitlab
module Ci
module Model
def table_name_prefix
"ci_"
end
module Ci
module NamespacedModelName
extend ActiveSupport::Concern
class_methods do
def model_name
@model_name ||= ActiveModel::Name.new(self, nil, self.name.demodulize)
@model_name ||= ActiveModel::Name.new(self, Ci)
end
end
end
......
......@@ -6,13 +6,13 @@
.form-check
= f.check_box :enforce_terms, class: 'form-check-input'
= f.label :enforce_terms, class: 'form-check-label' do
= _("Require all users to accept Terms of Service and Privacy Policy when they access GitLab.")
= _("All users must accept the Terms of Service and Privacy Policy to access GitLab")
.form-text.text-muted
= _("When enabled, users cannot use GitLab until the terms have been accepted.")
.form-group
= f.label :terms do
= _("Terms of Service Agreement and Privacy Policy")
= f.text_area :terms, class: 'form-control gl-form-input', rows: 8
.form-text.text-muted
= _("Markdown enabled")
= _("Markdown supported.")
= link_to _('What is Markdown?'), help_page_path('user/markdown.md'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _("Save changes"), class: "gl-button btn btn-confirm"
......@@ -64,7 +64,8 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Include a Terms of Service agreement and Privacy Policy that all users must accept.')
= _('Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance.')
= link_to _('Learn more.'), help_page_path('user/admin_area/settings/terms.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
= render 'terms'
......
......@@ -92,7 +92,7 @@ test: &test
### Migrations
Any migrations that affect `Ci::BaseModel` models
Any migrations that affect `Ci::CiDatabaseRecord` models
and their tables must be placed in two directories for now:
- `db/migrate`
......
......@@ -488,47 +488,6 @@ like a standard migration invocation.
The migration might fail if there is a very long running transaction (40+ minutes)
accessing the `users` table.
## Multi-Threading
Sometimes a migration might need to use multiple Ruby threads to speed up a
migration. For this to work your migration needs to include the module
`Gitlab::Database::MultiThreadedMigration`:
```ruby
class MyMigration < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
include Gitlab::Database::MultiThreadedMigration
end
```
You can then use the method `with_multiple_threads` to perform work in separate
threads. For example:
```ruby
class MyMigration < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
include Gitlab::Database::MultiThreadedMigration
def up
with_multiple_threads(4) do
disable_statement_timeout
# ...
end
end
end
```
Here the call to `disable_statement_timeout` uses the connection local to
the `with_multiple_threads` block, instead of re-using the global connection
pool. This ensures each thread has its own connection object, and doesn't time
out when trying to obtain one.
PostgreSQL has a maximum amount of connections that it allows. This
limit can vary from installation to installation. As a result, it's recommended
you do not use more than 32 threads in a single migration. Usually, 4-8 threads
should be more than enough.
## Removing indexes
If the table is not empty when removing an index, make sure to use the method
......
......@@ -5,59 +5,35 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
# Enforce accepting Terms of Service **(FREE SELF)**
# Terms of Service and Privacy Policy **(FREE SELF)**
An administrator can enforce acceptance of a terms of service and privacy policy. When this option is enabled, new and existing users must accept the terms.
An administrator can enforce acceptance of a terms of service and privacy policy.
When this option is enabled, new and existing users must accept the terms.
If configured, the Terms of Service page can be viewed via `https://your-instance.com/-/users/terms` at anytime.
When enabled, you can view the Terms of Service at the `-/users/terms` page on the instance,
for example `https://gitlab.example.com/-/users/terms`.
## Configuration
## Enforce a Terms of Service and Privacy Policy
To enforce acceptance of a Terms of Service and Privacy Policy:
1. Log in to the GitLab instance as an admin user.
1. On the top bar, select **Menu >** **{admin}** **Admin**.
1. In the left sidebar, select **Settings > General**.
1. Expand the **Terms of Service and Privacy Policy** section.
1. Check the **Require all users to accept Terms of Service and Privacy Policy when they access
GitLab.** checkbox.
1. Input the text of the **Terms of Service and Privacy Policy**. Markdown formatting can be used in this input box.
1. Check the **All users must accept the Terms of Service and Privacy Policy to access GitLab** checkbox.
1. Input the text of the **Terms of Service and Privacy Policy**. You can use [Markdown](../../markdown.md)
in this text box.
1. Click **Save changes**.
1. When you are presented with the **Terms of Service** statement, click **Accept terms**.
![Enable enforcing Terms of Service](img/enforce_terms.png)
For each update to the terms, a new version is stored. When a user accepts or declines the terms,
GitLab records which version they accepted or declined.
## New users
When this feature is enabled, a checkbox is added to the sign-up form.
When enabled, it adds a mandatory checkbox to the sign up page for new users:
![Sign up form](img/sign_up_terms.png)
This checkbox is required during sign up.
Users can review the terms entered in the admin panel before
accepting. The page is opened in a new window so they can
continue their registration afterwards.
## Accepting terms
When this feature is enabled, the users that have not accepted the
terms of service are presented with a screen where they can either
accept or decline the terms.
![Respond to terms](img/respond_to_terms.png)
If the user accepts the terms, they are directed to where they
were going. After a sign-in or sign-up this is most likely the
dashboard.
If the user was already logged in when the feature was turned on,
they are asked to accept the terms on their next interaction.
If a user declines the terms, they are signed out.
Existing users must accept the terms on their next GitLab interaction.
If a logged-in user declines the terms, they are signed out.
<!-- ## Troubleshooting
......
......@@ -7,7 +7,9 @@
# purchase via CustomersDot/Zuora
module Ci
module Minutes
class AdditionalPack < ApplicationRecord
class AdditionalPack < Ci::ApplicationRecord
include Ci::NamespacedModelName
self.table_name = 'ci_minutes_additional_packs'
belongs_to :namespace
......
......@@ -4,8 +4,8 @@ module Ci
module Minutes
# Track usage of Shared Runners minutes at root namespace level.
# This class ensures that we keep 1 record per namespace per month.
class NamespaceMonthlyUsage < ApplicationRecord
self.table_name = "ci_namespace_monthly_usages"
class NamespaceMonthlyUsage < Ci::ApplicationRecord
include Ci::NamespacedModelName
belongs_to :namespace
......
......@@ -4,8 +4,8 @@ module Ci
module Minutes
# Track usage of Shared Runners minutes at root project level.
# This class ensures that we keep 1 record per project per month.
class ProjectMonthlyUsage < ApplicationRecord
self.table_name = "ci_project_monthly_usages"
class ProjectMonthlyUsage < Ci::ApplicationRecord
include Ci::NamespacedModelName
belongs_to :project
......
......@@ -2,7 +2,9 @@
module Ci
module Sources
class Project < ApplicationRecord
class Project < Ci::ApplicationRecord
include Ci::NamespacedModelName
self.table_name = "ci_sources_projects"
belongs_to :pipeline, class_name: "Ci::Pipeline", optional: false
......
......@@ -2,7 +2,8 @@
module Ci
module Subscriptions
class Project < ApplicationRecord
class Project < Ci::ApplicationRecord
include Ci::NamespacedModelName
include ::Limitable
self.table_name = 'ci_subscriptions_projects'
......
# frozen_string_literal: true
module Gitlab
module Database
module MultiThreadedMigration
MULTI_THREAD_AR_CONNECTION = :thread_local_ar_connection
# This overwrites the default connection method so that every thread can
# use a thread-local connection, while still supporting all of Rails'
# migration methods.
def connection
Thread.current[MULTI_THREAD_AR_CONNECTION] ||
ActiveRecord::Base.connection
end
# Starts a thread-pool for N threads, along with N threads each using a
# single connection. The provided block is yielded from inside each
# thread.
#
# Example:
#
# with_multiple_threads(4) do
# execute('SELECT ...')
# end
#
# thread_count - The number of threads to start.
#
# join - When set to true this method will join the threads, blocking the
# caller until all threads have finished running.
#
# Returns an Array containing the started threads.
def with_multiple_threads(thread_count, join: true)
pool = Gitlab::Database.main.create_connection_pool(thread_count)
threads = Array.new(thread_count) do
Thread.new do
pool.with_connection do |connection|
Thread.current[MULTI_THREAD_AR_CONNECTION] = connection
yield
ensure
Thread.current[MULTI_THREAD_AR_CONNECTION] = nil
end
end
end
threads.each(&:join) if join
threads
end
end
end
end
......@@ -1900,6 +1900,9 @@ msgstr ""
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
msgstr ""
msgid "Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance."
msgstr ""
msgid "Add a bullet list"
msgstr ""
......@@ -3279,6 +3282,9 @@ msgstr ""
msgid "All threads resolved"
msgstr ""
msgid "All users must accept the Terms of Service and Privacy Policy to access GitLab"
msgstr ""
msgid "All users must have a name."
msgstr ""
......@@ -17457,9 +17463,6 @@ msgstr ""
msgid "Incident|There was an issue loading incident data. Please try again."
msgstr ""
msgid "Include a Terms of Service agreement and Privacy Policy that all users must accept."
msgstr ""
msgid "Include author name in notification email body"
msgstr ""
......@@ -20181,6 +20184,9 @@ msgstr ""
msgid "Markdown is supported"
msgstr ""
msgid "Markdown supported."
msgstr ""
msgid "MarkdownEditor|Add a link (%{modifierKey}K)"
msgstr ""
......@@ -28053,9 +28059,6 @@ msgstr ""
msgid "Require all users in this group to setup two-factor authentication"
msgstr ""
msgid "Require all users to accept Terms of Service and Privacy Policy when they access GitLab."
msgstr ""
msgid "Require all users to set up two-factor authentication"
msgstr ""
......@@ -37154,6 +37157,9 @@ msgstr ""
msgid "What is Auto DevOps?"
msgstr ""
msgid "What is Markdown?"
msgstr ""
msgid "What is repository mirroring?"
msgstr ""
......@@ -37184,9 +37190,6 @@ msgstr ""
msgid "When disabled, an external authentication provider must be used."
msgstr ""
msgid "When enabled, users cannot use GitLab until the terms have been accepted."
msgstr ""
msgid "When leaving the URL blank, classification labels can still be specified without disabling cross project features or performing external authorization checks."
msgstr ""
......
......@@ -190,7 +190,7 @@ RSpec.describe 'Admin updates settings' do
accept_terms(admin)
page.within('.as-terms') do
check 'Require all users to accept Terms of Service and Privacy Policy when they access GitLab.'
check 'All users must accept the Terms of Service and Privacy Policy to access GitLab'
fill_in 'Terms of Service Agreement', with: 'Be nice!'
click_button 'Save changes'
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Database::MultiThreadedMigration do
let(:migration) do
Class.new { include Gitlab::Database::MultiThreadedMigration }.new
end
describe '#connection' do
after do
Thread.current[described_class::MULTI_THREAD_AR_CONNECTION] = nil
end
it 'returns the thread-local connection if present' do
Thread.current[described_class::MULTI_THREAD_AR_CONNECTION] = 10
expect(migration.connection).to eq(10)
end
it 'returns the global connection if no thread-local connection was set' do
expect(migration.connection).to eq(ActiveRecord::Base.connection)
end
end
describe '#with_multiple_threads' do
it 'starts multiple threads and yields the supplied block in every thread' do
output = Queue.new
migration.with_multiple_threads(2) do
output << migration.connection.execute('SELECT 1')
end
expect(output.size).to eq(2)
end
it 'joins the threads when the join parameter is set' do
expect_any_instance_of(Thread).to receive(:join).and_call_original
migration.with_multiple_threads(1) { }
end
end
end
......@@ -13,7 +13,7 @@ RSpec.describe Gitlab::Database::SchemaMigrations::Context do
end
context 'multiple databases' do
let(:connection) { Ci::BaseModel.connection }
let(:connection) { Ci::CiDatabaseRecord.connection }
it 'returns a directory path that is database specific' do
skip_if_multiple_databases_not_setup
......
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