Commit d7ce1b1d authored by Phil Hughes's avatar Phil Hughes

Merge branch 'ce-to-ee-2018-11-28' into 'master'

CE upstream - 2018-11-28 10:21 UTC

Closes gitlab-ce#51506, gitlab-ce#41776, and gitlab-ce#50812

See merge request gitlab-org/gitlab-ee!8618
parents e7cfbaf9 b60ad423
/*
* Includes specific styles from the bootstrap4 foler in node_modules
* Includes specific styles from the bootstrap4 folder in node_modules
*/
@import "../../../node_modules/bootstrap/scss/functions";
......
......@@ -336,3 +336,12 @@ input[type=color].form-control {
.input-group-btn:last-child {
@extend .input-group-append;
}
/*
Bootstrap 4.1.2 introduced a new default vertical alignment which breaks our icons,
so we need to reset the vertical alignment to the default value. See:
- https://gitlab.com/gitlab-org/gitlab-ce/issues/51362
*/
svg {
vertical-align: baseline;
}
......@@ -32,16 +32,16 @@
margin: 0;
}
.flash-alert {
@extend .alert;
background-color: $red-500;
margin: 0;
.flash-text,
.flash-action {
display: inline-block;
}
.flash-alert {
@extend .alert;
background-color: $red-500;
margin: 0;
.flash-action {
margin-left: 5px;
text-decoration: none;
......
......@@ -8,6 +8,7 @@ class Projects::NetworkController < Projects::ApplicationController
before_action :require_non_empty_project
before_action :assign_ref_vars
before_action :authorize_download_code!
before_action :assign_options
before_action :assign_commit
def show
......@@ -29,10 +30,13 @@ class Projects::NetworkController < Projects::ApplicationController
render
end
def assign_options
@options = params.permit(:filter_ref, :extended_sha1)
end
def assign_commit
return if params[:extended_sha1].blank?
return if @options[:extended_sha1].blank?
@options[:extended_sha1] = params[:extended_sha1]
@commit = @repo.commit(@options[:extended_sha1])
end
......
- page_title "Find File", @ref
.file-finder-holder.tree-holder.clearfix.js-file-finder{ 'data-file-find-url': "#{escape_javascript(project_files_path(@project, @ref, @options.merge(format: :json)))}", 'data-find-tree-url': escape_javascript(project_tree_path(@project, @ref)), 'data-blob-url-template': escape_javascript(project_blob_path(@project, @id || @commit.id)) }
.file-finder-holder.tree-holder.clearfix.js-file-finder{ 'data-file-find-url': "#{escape_javascript(project_files_path(@project, @ref, format: :json))}", 'data-find-tree-url': escape_javascript(project_tree_path(@project, @ref)), 'data-blob-url-template': escape_javascript(project_blob_path(@project, @id || @commit.id)) }
.nav-block
.tree-ref-holder
= render 'shared/ref_switcher', destination: 'find_file', path: @path
......
......@@ -15,7 +15,7 @@
.changing-auth-method= icon('spinner spin lg')
.well-password-auth.collapse.js-well-password-auth
= f.label :password, _("Password"), class: "label-bold"
= f.password_field :password, value: mirror.password, class: 'form-control'
= f.password_field :password, value: mirror.password, class: 'form-control', autocomplete: 'new-password'
- unless is_push
.well-ssh-auth.collapse.js-well-ssh-auth
%p.js-ssh-public-key-present{ class: ('collapse' unless ssh_public_key_present) }
......
---
title: Fix flash notice styling for fluid layout
merge_request: 23382
author:
type: fixed
---
title: Disable password autocomplete in mirror form fill
merge_request: 23402
author:
type: fixed
---
title: Migration to write fullpath in all repository configs
merge_request: 22322
author:
type: other
# frozen_string_literal: true
class BackfillStoreProjectFullPathInRepo < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
BATCH_SIZE = 1_000
DELAY_INTERVAL = 5.minutes
UP_MIGRATION = 'BackfillProjectFullpathInRepoConfig::Up'
DOWN_MIGRATION = 'BackfillProjectFullpathInRepoConfig::Down'
disable_ddl_transaction!
class Project < ActiveRecord::Base
self.table_name = 'projects'
include EachBatch
end
def up
queue_background_migration_jobs_by_range_at_intervals(Project, UP_MIGRATION, DELAY_INTERVAL)
end
def down
queue_background_migration_jobs_by_range_at_intervals(Project, DOWN_MIGRATION, DELAY_INTERVAL)
end
end
......@@ -67,6 +67,9 @@ services you need to `.gitlab-ci.yml` or manually modify `config.toml`.
Any image found at [Docker Hub][hub] or your private Container Registry can be
used as a service.
Services inherit the same DNS servers, search domains, and additional hosts as
the CI container itself.
You can see some widely used services examples in the relevant documentation of
[CI services examples](../services/README.md).
......
# Getting started with interactive web terminals
# Getting started with interactive web terminals **[CORE ONLY]**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/50144) in GitLab 11.3.
......@@ -6,10 +6,9 @@ Interactive web terminals give the user access to a terminal in GitLab for
running one-off commands for their CI pipeline.
NOTE: **Note:**
This is not available for the shared Runners on GitLab.com.
To make use of this feature, you need to provide your
[own Runner](https://docs.gitlab.com/runner/install/) and properly
[configure it](#configuration).
GitLab.com does not support interactive web terminal at the moment. Please
follow [this issue](https://gitlab.com/gitlab-org/gitlab-ce/issues/52611) for
progress.
## Configuration
......
......@@ -110,11 +110,6 @@ module ExtractsPath
# resolved (e.g., when a user inserts an invalid path or ref).
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def assign_ref_vars
# assign allowed options
allowed_options = ["filter_ref"]
@options = params.select {|key, value| allowed_options.include?(key) && !value.blank? }
@options = HashWithIndifferentAccess.new(@options)
@id = get_id
@ref, @path = extract_ref(@id)
@repo = @project.repository
......
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
# This module is used to write the full path of all projects to
# the git repository config file.
# Storing the full project path in the git config allows admins to
# easily identify a project when it is using hashed storage.
module BackfillProjectFullpathInRepoConfig
OrphanedNamespaceError = Class.new(StandardError)
module Storage
# Class that returns the disk path for a project using hashed storage
class HashedProject
attr_accessor :project
ROOT_PATH_PREFIX = '@hashed'
def initialize(project)
@project = project
end
def disk_path
"#{ROOT_PATH_PREFIX}/#{disk_hash[0..1]}/#{disk_hash[2..3]}/#{disk_hash}"
end
def disk_hash
@disk_hash ||= Digest::SHA2.hexdigest(project.id.to_s) if project.id
end
end
# Class that returns the disk path for a project using legacy storage
class LegacyProject
attr_accessor :project
def initialize(project)
@project = project
end
def disk_path
project.full_path
end
end
end
# Concern used by Project and Namespace to determine the full
# route to the project
module Routable
extend ActiveSupport::Concern
def full_path
@full_path ||= build_full_path
end
def build_full_path
return path unless has_parent?
raise OrphanedNamespaceError if parent.nil?
parent.full_path + '/' + path
end
def has_parent?
read_attribute(association(:parent).reflection.foreign_key)
end
end
# Class used to interact with repository using Gitaly
class Repository
attr_reader :storage
def initialize(storage, relative_path)
@storage = storage
@relative_path = relative_path
end
def gitaly_repository
Gitaly::Repository.new(storage_name: @storage, relative_path: @relative_path)
end
end
# Namespace can be a user or group. It can be the root or a
# child of another namespace.
class Namespace < ActiveRecord::Base
self.table_name = 'namespaces'
self.inheritance_column = nil
include Routable
belongs_to :parent, class_name: 'Namespace', inverse_of: 'namespaces'
has_many :projects, inverse_of: :parent
has_many :namespaces, inverse_of: :parent
end
# Project is where the repository (etc.) is stored
class Project < ActiveRecord::Base
self.table_name = 'projects'
include Routable
include EachBatch
FULLPATH_CONFIG_KEY = 'gitlab.fullpath'
belongs_to :parent, class_name: 'Namespace', foreign_key: :namespace_id, inverse_of: 'projects'
delegate :disk_path, to: :storage
def add_fullpath_config
entries = { FULLPATH_CONFIG_KEY => full_path }
repository_service.set_config(entries)
end
def remove_fullpath_config
repository_service.delete_config([FULLPATH_CONFIG_KEY])
end
def cleanup_repository
repository_service.cleanup
end
def storage
@storage ||=
if hashed_storage?
Storage::HashedProject.new(self)
else
Storage::LegacyProject.new(self)
end
end
def hashed_storage?
self.storage_version && self.storage_version >= 1
end
def repository
@repository ||= Repository.new(repository_storage, disk_path + '.git')
end
def repository_service
@repository_service ||= Gitlab::GitalyClient::RepositoryService.new(repository)
end
end
# Base class for Up and Down migration classes
class BackfillFullpathMigration
RETRY_DELAY = 15.minutes
MAX_RETRIES = 2
# Base class for retrying one project
class BaseRetryOne
def perform(project_id, retry_count)
project = Project.find(project_id)
return unless project
migration_class.new.safe_perform_one(project, retry_count)
end
end
def perform(start_id, end_id)
Project.includes(:parent).where(id: start_id..end_id).each do |project|
safe_perform_one(project)
end
end
def safe_perform_one(project, retry_count = 0)
perform_one(project)
rescue GRPC::NotFound, GRPC::InvalidArgument, OrphanedNamespaceError
nil
rescue GRPC::BadStatus
schedule_retry(project, retry_count + 1) if retry_count < MAX_RETRIES
end
def schedule_retry(project, retry_count)
BackgroundMigrationWorker.perform_in(RETRY_DELAY, self.class::RetryOne.name, [project.id, retry_count])
end
end
# Class to add the fullpath to the git repo config
class Up < BackfillFullpathMigration
# Class used to retry
class RetryOne < BaseRetryOne
def migration_class
Up
end
end
def perform_one(project)
project.cleanup_repository
project.add_fullpath_config
end
end
# Class to rollback adding the fullpath to the git repo config
class Down < BackfillFullpathMigration
# Class used to retry
class RetryOne < BaseRetryOne
def migration_class
Down
end
end
def perform_one(project)
project.cleanup_repository
project.remove_fullpath_config
end
end
end
end
end
......@@ -31,7 +31,7 @@
"autosize": "^4.0.0",
"axios": "^0.17.1",
"babel-loader": "^8.0.4",
"bootstrap": "4.1.1",
"bootstrap": "4.1.3",
"brace-expansion": "^1.1.8",
"cache-loader": "^1.2.2",
"chart.js": "1.0.2",
......@@ -42,7 +42,7 @@
"core-js": "^2.4.1",
"cropper": "^2.3.0",
"css-loader": "^1.0.0",
"d3": "4.12.2",
"d3": "^4.13.0",
"d3-array": "^1.2.1",
"d3-axis": "^1.0.8",
"d3-brush": "^1.0.4",
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::BackgroundMigration::BackfillProjectFullpathInRepoConfig, :migration, schema: 20181010133639 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:group) { namespaces.create!(name: 'foo', path: 'foo') }
let(:subgroup) { namespaces.create!(name: 'bar', path: 'bar', parent_id: group.id) }
describe described_class::Storage::HashedProject do
let(:project) { double(id: 555) }
subject(:project_storage) { described_class.new(project) }
it 'has the correct disk_path' do
expect(project_storage.disk_path).to eq('@hashed/91/a7/91a73fd806ab2c005c13b4dc19130a884e909dea3f72d46e30266fe1a1f588d8')
end
end
describe described_class::Storage::LegacyProject do
let(:project) { double(full_path: 'this/is/the/full/path') }
subject(:project_storage) { described_class.new(project) }
it 'has the correct disk_path' do
expect(project_storage.disk_path).to eq('this/is/the/full/path')
end
end
describe described_class::Project do
let(:project_record) { projects.create!(namespace_id: subgroup.id, name: 'baz', path: 'baz') }
subject(:project) { described_class.find(project_record.id) }
describe '#full_path' do
it 'returns path containing all parent namespaces' do
expect(project.full_path).to eq('foo/bar/baz')
end
it 'raises OrphanedNamespaceError when any parent namespace does not exist' do
subgroup.update_attribute(:parent_id, namespaces.maximum(:id).succ)
expect { project.full_path }.to raise_error(Gitlab::BackgroundMigration::BackfillProjectFullpathInRepoConfig::OrphanedNamespaceError)
end
end
end
describe described_class::Up do
describe '#perform' do
subject(:migrate) { described_class.new.perform(projects.minimum(:id), projects.maximum(:id)) }
it 'asks the gitaly client to set config' do
projects.create!(namespace_id: subgroup.id, name: 'baz', path: 'baz')
projects.create!(namespace_id: subgroup.id, name: 'buzz', path: 'buzz', storage_version: 1)
expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service|
allow(repository_service).to receive(:cleanup)
expect(repository_service).to receive(:set_config).with('gitlab.fullpath' => 'foo/bar/baz')
end
expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service|
allow(repository_service).to receive(:cleanup)
expect(repository_service).to receive(:set_config).with('gitlab.fullpath' => 'foo/bar/buzz')
end
migrate
end
end
end
describe described_class::Down do
describe '#perform' do
subject(:migrate) { described_class.new.perform(projects.minimum(:id), projects.maximum(:id)) }
it 'asks the gitaly client to set config' do
projects.create!(namespace_id: subgroup.id, name: 'baz', path: 'baz')
expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service|
allow(repository_service).to receive(:cleanup)
expect(repository_service).to receive(:delete_config).with(['gitlab.fullpath'])
end
migrate
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20181010133639_backfill_store_project_full_path_in_repo.rb')
describe BackfillStoreProjectFullPathInRepo, :migration do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:group) { namespaces.create!(name: 'foo', path: 'foo') }
let(:subgroup) { namespaces.create!(name: 'bar', path: 'bar', parent_id: group.id) }
subject(:migration) { described_class.new }
around do |example|
Sidekiq::Testing.inline! do
example.run
end
end
describe '#up' do
shared_examples_for 'writes the full path to git config' do
it 'writes the git config' do
expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service|
allow(repository_service).to receive(:cleanup)
expect(repository_service).to receive(:set_config).with('gitlab.fullpath' => expected_path)
end
migration.up
end
it 'retries in case of failure' do
repository_service = spy(:repository_service)
allow(Gitlab::GitalyClient::RepositoryService).to receive(:new).and_return(repository_service)
allow(repository_service).to receive(:set_config).and_raise(GRPC::BadStatus, 'Retry me')
expect(repository_service).to receive(:set_config).exactly(3).times
migration.up
end
it 'cleans up repository before writing the config' do
expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service|
expect(repository_service).to receive(:cleanup).ordered
expect(repository_service).to receive(:set_config).ordered
end
migration.up
end
context 'legacy storage' do
it 'finds the repository at the correct location' do
Project.find(project.id).create_repository
expect { migration.up }.not_to raise_error
end
end
context 'hashed storage' do
it 'finds the repository at the correct location' do
project.update_attribute(:storage_version, 1)
Project.find(project.id).create_repository
expect { migration.up }.not_to raise_error
end
end
end
context 'project in group' do
let!(:project) { projects.create!(namespace_id: group.id, name: 'baz', path: 'baz') }
let(:expected_path) { 'foo/baz' }
it_behaves_like 'writes the full path to git config'
end
context 'project in subgroup' do
let!(:project) { projects.create!(namespace_id: subgroup.id, name: 'baz', path: 'baz') }
let(:expected_path) { 'foo/bar/baz' }
it_behaves_like 'writes the full path to git config'
end
end
describe '#down' do
context 'project in group' do
let!(:project) { projects.create!(namespace_id: group.id, name: 'baz', path: 'baz') }
it 'deletes the gitlab full config value' do
expect_any_instance_of(Gitlab::GitalyClient::RepositoryService)
.to receive(:delete_config).with(['gitlab.fullpath'])
migration.down
end
end
end
end
......@@ -18,33 +18,33 @@ describe MigrateIssuesToGhostUser, :migration do
let!(:ghost) { users.create(ghost: true, email: 'ghost@example.com') }
it 'does not create a new user' do
expect { schema_migrate_up! }.not_to change { User.count }
expect { migrate! }.not_to change { User.count }
end
it 'migrates issues where author = nil to the ghost user' do
schema_migrate_up!
migrate!
expect(issues.first.reload.author_id).to eq(ghost.id)
end
it 'does not change issues authored by an existing user' do
expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id}
expect { migrate! }.not_to change { issues.second.reload.author_id}
end
end
context 'when ghost user does not exist' do
it 'creates a new user' do
expect { schema_migrate_up! }.to change { User.count }.by(1)
expect { migrate! }.to change { User.count }.by(1)
end
it 'migrates issues where author = nil to the ghost user' do
schema_migrate_up!
migrate!
expect(issues.first.reload.author_id).to eq(User.ghost.id)
end
it 'does not change issues authored by an existing user' do
expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id}
expect { migrate! }.not_to change { issues.second.reload.author_id}
end
end
end
......
......@@ -1505,10 +1505,10 @@ bootstrap-vue@^2.0.0-rc.11:
popper.js "^1.12.9"
vue-functional-data-merge "^2.0.5"
bootstrap@4.1.1, bootstrap@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.1.1.tgz#3aec85000fa619085da8d2e4983dfd67cf2114cb"
integrity sha512-SpiDSOcbg4J/PjVSt4ny5eY6j74VbVSjROY4Fb/WIUXBV9cnb5luyR4KnPvNoXuGnBK1T+nJIWqRsvU3yP8Mcg==
bootstrap@4.1.3, bootstrap@^4.1.1:
version "4.1.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.1.3.tgz#0eb371af2c8448e8c210411d0cb824a6409a12be"
integrity sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w==
boxen@^1.2.1:
version "1.3.0"
......@@ -2415,12 +2415,7 @@ d3-force@1.1.0:
d3-quadtree "1"
d3-timer "1"
d3-format@1, d3-format@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.2.1.tgz#4e19ecdb081a341dafaf5f555ee956bcfdbf167f"
integrity sha512-U4zRVLDXW61bmqoo+OJ/V687e1T5nVd3TAKAJKgtpZ/P1JsMgyod0y9br+mlQOryTAACdiXI3wCjuERHFNp91w==
d3-format@1.2.2:
d3-format@1, d3-format@1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.2.2.tgz#1a39c479c8a57fe5051b2e67a3bee27061a74e7a"
integrity sha512-zH9CfF/3C8zUI47nsiKfD0+AGDEuM8LwBIP7pBVpyR4l/sKkZqITmMtxRp04rwBrlshIZ17XeFAaovN3++wzkw==
......@@ -2492,12 +2487,7 @@ d3-scale@1.0.7, d3-scale@^1.0.7:
d3-time "1"
d3-time-format "2"
d3-selection@1, d3-selection@1.2.0, d3-selection@^1.1.0, d3-selection@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.2.0.tgz#1b8ec1c7cedadfb691f2ba20a4a3cfbeb71bbc88"
integrity sha512-xW2Pfcdzh1gOaoI+LGpPsLR2VpBQxuFoxvrvguK8ZmrJbPIVvfNG6pU6GNfK41D6Qz15sj61sbW/AFYuukwaLQ==
d3-selection@1.3.0:
d3-selection@1, d3-selection@1.3.0, d3-selection@^1.1.0, d3-selection@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.3.0.tgz#d53772382d3dc4f7507bfb28bcd2d6aed2a0ad6d"
integrity sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==
......@@ -2554,42 +2544,6 @@ d3-zoom@1.7.1:
d3-selection "1"
d3-transition "1"
d3@4.12.2:
version "4.12.2"
resolved "https://registry.yarnpkg.com/d3/-/d3-4.12.2.tgz#12f775564c6a9de229f63db03446e2cb7bb56c8f"
integrity sha512-aKAlpgTmpuGeEpezB+GvPpX1x+gCMs/PHpuse6sCpkgw4Un3ZeqUobIc87eIy9adcl+wxPAnEyKyO5oulH3MOw==
dependencies:
d3-array "1.2.1"
d3-axis "1.0.8"
d3-brush "1.0.4"
d3-chord "1.0.4"
d3-collection "1.0.4"
d3-color "1.0.3"
d3-dispatch "1.0.3"
d3-drag "1.2.1"
d3-dsv "1.0.8"
d3-ease "1.0.3"
d3-force "1.1.0"
d3-format "1.2.1"
d3-geo "1.9.1"
d3-hierarchy "1.1.5"
d3-interpolate "1.1.6"
d3-path "1.0.5"
d3-polygon "1.0.3"
d3-quadtree "1.0.3"
d3-queue "3.0.7"
d3-random "1.1.0"
d3-request "1.0.6"
d3-scale "1.0.7"
d3-selection "1.2.0"
d3-shape "1.2.0"
d3-time "1.0.8"
d3-time-format "2.1.1"
d3-timer "1.0.7"
d3-transition "1.1.1"
d3-voronoi "1.1.2"
d3-zoom "1.7.1"
d3@^4.13.0:
version "4.13.0"
resolved "https://registry.yarnpkg.com/d3/-/d3-4.13.0.tgz#ab236ff8cf0cfc27a81e69bf2fb7518bc9b4f33d"
......
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