Commit 7aefec62 authored by GitLab Bot's avatar GitLab Bot Committed by root

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-06-20

# Conflicts:
#	lib/gitlab/search/parsed_query.rb

[ci skip]
parents db5550e1 bd88a276
...@@ -434,7 +434,7 @@ group :ed25519 do ...@@ -434,7 +434,7 @@ group :ed25519 do
end end
# Gitaly GRPC client # Gitaly GRPC client
gem 'gitaly-proto', '~> 0.101.0', require: 'gitaly' gem 'gitaly-proto', '~> 0.102.0', require: 'gitaly'
gem 'grpc', '~> 1.11.0' gem 'grpc', '~> 1.11.0'
# Locked until https://github.com/google/protobuf/issues/4210 is closed # Locked until https://github.com/google/protobuf/issues/4210 is closed
......
...@@ -307,7 +307,7 @@ GEM ...@@ -307,7 +307,7 @@ GEM
gettext_i18n_rails (>= 0.7.1) gettext_i18n_rails (>= 0.7.1)
po_to_json (>= 1.0.0) po_to_json (>= 1.0.0)
rails (>= 3.2.0) rails (>= 3.2.0)
gitaly-proto (0.101.0) gitaly-proto (0.102.0)
google-protobuf (~> 3.1) google-protobuf (~> 3.1)
grpc (~> 1.10) grpc (~> 1.10)
github-linguist (5.3.3) github-linguist (5.3.3)
...@@ -1073,7 +1073,7 @@ DEPENDENCIES ...@@ -1073,7 +1073,7 @@ DEPENDENCIES
gettext (~> 3.2.2) gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3) gettext_i18n_rails_js (~> 1.3)
gitaly-proto (~> 0.101.0) gitaly-proto (~> 0.102.0)
github-linguist (~> 5.3.3) github-linguist (~> 5.3.3)
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-gollum-lib (~> 4.2) gitlab-gollum-lib (~> 4.2)
......
...@@ -310,7 +310,7 @@ GEM ...@@ -310,7 +310,7 @@ GEM
gettext_i18n_rails (>= 0.7.1) gettext_i18n_rails (>= 0.7.1)
po_to_json (>= 1.0.0) po_to_json (>= 1.0.0)
rails (>= 3.2.0) rails (>= 3.2.0)
gitaly-proto (0.101.0) gitaly-proto (0.102.0)
google-protobuf (~> 3.1) google-protobuf (~> 3.1)
grpc (~> 1.10) grpc (~> 1.10)
github-linguist (5.3.3) github-linguist (5.3.3)
...@@ -1083,7 +1083,7 @@ DEPENDENCIES ...@@ -1083,7 +1083,7 @@ DEPENDENCIES
gettext (~> 3.2.2) gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3) gettext_i18n_rails_js (~> 1.3)
gitaly-proto (~> 0.101.0) gitaly-proto (~> 0.102.0)
github-linguist (~> 5.3.3) github-linguist (~> 5.3.3)
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-gollum-lib (~> 4.2) gitlab-gollum-lib (~> 4.2)
......
...@@ -366,7 +366,7 @@ export default class CreateMergeRequestDropdown { ...@@ -366,7 +366,7 @@ export default class CreateMergeRequestDropdown {
removeMessage(target) { removeMessage(target) {
const { input, message } = this.getTargetData(target); const { input, message } = this.getTargetData(target);
const inputClasses = ['gl-field-error-outline', 'gl-field-success-outline']; const inputClasses = ['gl-field-error-outline', 'gl-field-success-outline'];
const messageClasses = ['gl-field-hint', 'gl-field-error-message', 'gl-field-success-message']; const messageClasses = ['text-muted', 'text-danger', 'text-success'];
inputClasses.forEach(cssClass => input.classList.remove(cssClass)); inputClasses.forEach(cssClass => input.classList.remove(cssClass));
messageClasses.forEach(cssClass => message.classList.remove(cssClass)); messageClasses.forEach(cssClass => message.classList.remove(cssClass));
...@@ -393,7 +393,7 @@ export default class CreateMergeRequestDropdown { ...@@ -393,7 +393,7 @@ export default class CreateMergeRequestDropdown {
this.removeMessage(target); this.removeMessage(target);
input.classList.add('gl-field-success-outline'); input.classList.add('gl-field-success-outline');
message.classList.add('gl-field-success-message'); message.classList.add('text-success');
message.textContent = sprintf(__('%{text} is available'), { text }); message.textContent = sprintf(__('%{text} is available'), { text });
message.style.display = 'inline-block'; message.style.display = 'inline-block';
} }
...@@ -403,7 +403,7 @@ export default class CreateMergeRequestDropdown { ...@@ -403,7 +403,7 @@ export default class CreateMergeRequestDropdown {
const text = target === 'branch' ? __('branch name') : __('source'); const text = target === 'branch' ? __('branch name') : __('source');
this.removeMessage(target); this.removeMessage(target);
message.classList.add('gl-field-hint'); message.classList.add('text-muted');
message.textContent = sprintf(__('Checking %{text} availability…'), { text }); message.textContent = sprintf(__('Checking %{text} availability…'), { text });
message.style.display = 'inline-block'; message.style.display = 'inline-block';
} }
...@@ -415,7 +415,7 @@ export default class CreateMergeRequestDropdown { ...@@ -415,7 +415,7 @@ export default class CreateMergeRequestDropdown {
this.removeMessage(target); this.removeMessage(target);
input.classList.add('gl-field-error-outline'); input.classList.add('gl-field-error-outline');
message.classList.add('gl-field-error-message'); message.classList.add('text-danger');
message.textContent = text; message.textContent = text;
message.style.display = 'inline-block'; message.style.display = 'inline-block';
} }
......
...@@ -201,6 +201,10 @@ label { ...@@ -201,6 +201,10 @@ label {
} }
.gl-show-field-errors { .gl-show-field-errors {
.form-control {
height: 34px;
}
.gl-field-success-outline { .gl-field-success-outline {
border: 1px solid $green-600; border: 1px solid $green-600;
......
...@@ -9,7 +9,7 @@ class Admin::HooksController < Admin::ApplicationController ...@@ -9,7 +9,7 @@ class Admin::HooksController < Admin::ApplicationController
end end
def create def create
@hook = SystemHook.new(hook_params) @hook = SystemHook.new(hook_params.to_h)
if @hook.save if @hook.save
redirect_to admin_hooks_path, notice: 'Hook was successfully created.' redirect_to admin_hooks_path, notice: 'Hook was successfully created.'
......
...@@ -55,7 +55,7 @@ class DashboardController < Dashboard::ApplicationController ...@@ -55,7 +55,7 @@ class DashboardController < Dashboard::ApplicationController
return unless @no_filters_set return unless @no_filters_set
respond_to do |format| respond_to do |format|
format.html format.html { render }
format.atom { head :bad_request } format.atom { head :bad_request }
end end
end end
......
...@@ -249,13 +249,13 @@ class ProjectsController < Projects::ApplicationController ...@@ -249,13 +249,13 @@ class ProjectsController < Projects::ApplicationController
if find_branches if find_branches
branches = BranchesFinder.new(@repository, params).execute.take(100).map(&:name) branches = BranchesFinder.new(@repository, params).execute.take(100).map(&:name)
options[s_('RefSwitcher|Branches')] = branches options['Branches'] = branches
end end
if find_tags && @repository.tag_count.nonzero? if find_tags && @repository.tag_count.nonzero?
tags = TagsFinder.new(@repository, params).execute.take(100).map(&:name) tags = TagsFinder.new(@repository, params).execute.take(100).map(&:name)
options[s_('RefSwitcher|Tags')] = tags options['Tags'] = tags
end end
# If reference is commit id - we should add it to branch/tag selectbox # If reference is commit id - we should add it to branch/tag selectbox
......
...@@ -458,6 +458,7 @@ module ProjectsHelper ...@@ -458,6 +458,7 @@ module ProjectsHelper
@ref || @repository.try(:root_ref) @ref || @repository.try(:root_ref)
end end
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1235
def sanitize_repo_path(project, message) def sanitize_repo_path(project, message)
return '' unless message.present? return '' unless message.present?
......
...@@ -3,7 +3,7 @@ module Clusters ...@@ -3,7 +3,7 @@ module Clusters
class Prometheus < ActiveRecord::Base class Prometheus < ActiveRecord::Base
include PrometheusAdapter include PrometheusAdapter
VERSION = "2.0.0".freeze VERSION = '6.7.3'.freeze
self.table_name = 'clusters_applications_prometheus' self.table_name = 'clusters_applications_prometheus'
...@@ -37,6 +37,7 @@ module Clusters ...@@ -37,6 +37,7 @@ module Clusters
Gitlab::Kubernetes::Helm::InstallCommand.new( Gitlab::Kubernetes::Helm::InstallCommand.new(
name, name,
chart: chart, chart: chart,
version: version,
values: values values: values
) )
end end
......
...@@ -48,7 +48,7 @@ module RedisCacheable ...@@ -48,7 +48,7 @@ module RedisCacheable
def cast_value_from_cache(attribute, value) def cast_value_from_cache(attribute, value)
if Gitlab.rails5? if Gitlab.rails5?
self.class.type_for_attribute(attribute).cast(value) self.class.type_for_attribute(attribute.to_s).cast(value)
else else
self.class.column_for_attribute(attribute).type_cast_from_database(value) self.class.column_for_attribute(attribute).type_cast_from_database(value)
end end
......
...@@ -161,7 +161,10 @@ class Repository ...@@ -161,7 +161,10 @@ class Repository
# Returns a list of commits that are not present in any reference # Returns a list of commits that are not present in any reference
def new_commits(newrev) def new_commits(newrev)
refs = ::Gitlab::Git::RevList.new(raw, newrev: newrev).new_refs # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1233
refs = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
::Gitlab::Git::RevList.new(raw, newrev: newrev).new_refs
end
refs.map { |sha| commit(sha.strip) } refs.map { |sha| commit(sha.strip) }
end end
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
%label{ for: 'new-branch-name' } %label{ for: 'new-branch-name' }
= _('Branch name') = _('Branch name')
%input#new-branch-name.js-branch-name.form-control{ type: 'text', placeholder: "#{@issue.to_branch_name}", value: "#{@issue.to_branch_name}" } %input#new-branch-name.js-branch-name.form-control{ type: 'text', placeholder: "#{@issue.to_branch_name}", value: "#{@issue.to_branch_name}" }
%span.js-branch-message.form-text.text-muted %span.js-branch-message.form-text
.form-group .form-group
%label{ for: 'source-name' } %label{ for: 'source-name' }
......
---
title: Fix branches are not shown in Merge Request dropdown when preferred language
is not English
merge_request: 20016
author: Hiroyuki Sato
type: fixed
---
title: Specify chart version when installing applications on Clusters
merge_request: 20010
author:
type: fixed
---
title: Add filename filtering to code search
merge_request: 19509
author:
type: added
---
title: 'Rails5 fix expected: 1 time with arguments: (97, anything, {"squash"=>false})
received: 0 times'
merge_request: 20004
author: Jasper Maes
type: fixed
---
title: 'Rails5 fix expected: 0 times with any arguments received: 1 time with arguments:
DashboardController'
merge_request: 20018
author: Jasper Maes
type: fixed
---
title: Rails5 fix Admin::HooksController
merge_request: 20017
author: Jasper Maes
type: fixed
---
title: Rails5 fix Projects::PagesController spec
merge_request: 20007
author: Jasper Maes
type: fixed
---
title: Updated the icon for expand buttons to ellipsis
merge_request: 18793
author: Constance Okoghenun
type: changed
\ No newline at end of file
---
title: migrate backup rake task to gitaly
merge_request:
author:
type: added
...@@ -450,6 +450,7 @@ repositories_storages = Settings.repositories.storages.values ...@@ -450,6 +450,7 @@ repositories_storages = Settings.repositories.storages.values
repository_downloads_path = Settings.gitlab['repository_downloads_path'].to_s.gsub(%r{/$}, '') repository_downloads_path = Settings.gitlab['repository_downloads_path'].to_s.gsub(%r{/$}, '')
repository_downloads_full_path = File.expand_path(repository_downloads_path, Settings.gitlab['user_home']) repository_downloads_full_path = File.expand_path(repository_downloads_path, Settings.gitlab['user_home'])
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1237
Gitlab::GitalyClient::StorageSettings.allow_disk_access do Gitlab::GitalyClient::StorageSettings.allow_disk_access do
if repository_downloads_path.blank? || repositories_storages.any? { |rs| [repository_downloads_path, repository_downloads_full_path].include?(rs.legacy_disk_path.gsub(%r{/$}, '')) } if repository_downloads_path.blank? || repositories_storages.any? { |rs| [repository_downloads_path, repository_downloads_full_path].include?(rs.legacy_disk_path.gsub(%r{/$}, '')) }
Settings.gitlab['repository_downloads_path'] = File.join(Settings.shared['path'], 'cache/archive') Settings.gitlab['repository_downloads_path'] = File.join(Settings.shared['path'], 'cache/archive')
......
...@@ -37,6 +37,7 @@ def validate_storages_config ...@@ -37,6 +37,7 @@ def validate_storages_config
end end
end end
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1237
def validate_storages_paths def validate_storages_paths
Gitlab::GitalyClient::StorageSettings.allow_disk_access do Gitlab::GitalyClient::StorageSettings.allow_disk_access do
Gitlab.config.repositories.storages.each do |name, repository_storage| Gitlab.config.repositories.storages.each do |name, repository_storage|
......
...@@ -122,11 +122,11 @@ POST /projects/:id/pages/domains ...@@ -122,11 +122,11 @@ POST /projects/:id/pages/domains
| `key` | file/string | no | The certificate key in PEM format. | | `key` | file/string | no | The certificate key in PEM format. |
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="domain=ssl.domain.example" --form="certificate=@/path/to/cert.pem" --form="key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "domain=ssl.domain.example" --form "certificate=@/path/to/cert.pem" --form "key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains
``` ```
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="domain=ssl.domain.example" --form="certificate=$CERT_PEM" --form="key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "domain=ssl.domain.example" --form "certificate=$CERT_PEM" --form "key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains
``` ```
```json ```json
...@@ -158,11 +158,11 @@ PUT /projects/:id/pages/domains/:domain ...@@ -158,11 +158,11 @@ PUT /projects/:id/pages/domains/:domain
| `key` | file/string | no | The certificate key in PEM format. | | `key` | file/string | no | The certificate key in PEM format. |
```bash ```bash
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="certificate=@/path/to/cert.pem" --form="key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "certificate=@/path/to/cert.pem" --form "key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
``` ```
```bash ```bash
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="certificate=$CERT_PEM" --form="key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "certificate=$CERT_PEM" --form "key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
``` ```
```json ```json
......
...@@ -252,6 +252,53 @@ Keep in mind that the relation passed to ...@@ -252,6 +252,53 @@ Keep in mind that the relation passed to
`change_column_type_using_background_migration` _must_ include `EachBatch`, `change_column_type_using_background_migration` _must_ include `EachBatch`,
otherwise it will raise a `TypeError`. otherwise it will raise a `TypeError`.
This migration then needs to be followed in a separate release (_not_ a patch
release) by a cleanup migration, which should steal from the queue and handle
any remaining rows. For example:
```ruby
class MigrateRemainingIssuesClosedAt < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
class Issue < ActiveRecord::Base
self.table_name = 'issues'
include EachBatch
end
def up
Gitlab::BackgroundMigration.steal('CopyColumn')
Gitlab::BackgroundMigration.steal('CleanupConcurrentTypeChange')
migrate_remaining_rows if migrate_column_type?
end
def down
# Previous migrations already revert the changes made here.
end
def migrate_remaining_rows
Issue.where('closed_at_for_type_change IS NULL AND closed_at IS NOT NULL').each_batch do |batch|
batch.update_all('closed_at_for_type_change = closed_at')
end
cleanup_concurrent_column_type_change(:issues, :closed_at)
end
def migrate_column_type?
# Some environments may have already executed the previous version of this
# migration, thus we don't need to migrate those environments again.
column_for('issues', 'closed_at').type == :datetime # rubocop:disable Migration/Datetime
end
end
```
For more information, see [the documentation on cleaning up background
migrations](background_migrations.md#cleaning-up).
## Adding Indexes ## Adding Indexes
Adding indexes is an expensive process that blocks INSERT and UPDATE queries for Adding indexes is an expensive process that blocks INSERT and UPDATE queries for
......
...@@ -155,11 +155,11 @@ page](https://golang.org/dl). ...@@ -155,11 +155,11 @@ page](https://golang.org/dl).
# Remove former Go installation folder # Remove former Go installation folder
sudo rm -rf /usr/local/go sudo rm -rf /usr/local/go
curl --remote-name --progress https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz curl --remote-name --progress https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
echo '1862f4c3d3907e59b04a757cfda0ea7aa9ef39274af99a784f5be843c80c6772 go1.8.3.linux-amd64.tar.gz' | shasum -a256 -c - && \ echo 'fa1b0e45d3b647c252f51f5e1204aba049cde4af177ef9f2181f43004f901035 go1.10.3.linux-amd64.tar.gz' | shasum -a256 -c - && \
sudo tar -C /usr/local -xzf go1.8.3.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/ sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/
rm go1.8.3.linux-amd64.tar.gz rm go1.10.3.linux-amd64.tar.gz
## 4. Node ## 4. Node
......
...@@ -81,8 +81,8 @@ More information can be found on the [yarn website](https://yarnpkg.com/en/docs/ ...@@ -81,8 +81,8 @@ More information can be found on the [yarn website](https://yarnpkg.com/en/docs/
### 5. Update Go ### 5. Update Go
NOTE: GitLab 9.2 and higher only supports Go 1.8.3 and dropped support for Go NOTE: GitLab 11.0 and higher only supports Go 1.9.x and newer, and dropped support for Go
1.5.x through 1.7.x. Be sure to upgrade your installation if necessary. 1.5.x through 1.8.x. Be sure to upgrade your installation if necessary.
You can check which version you are running with `go version`. You can check which version you are running with `go version`.
...@@ -92,11 +92,11 @@ Download and install Go: ...@@ -92,11 +92,11 @@ Download and install Go:
# Remove former Go installation folder # Remove former Go installation folder
sudo rm -rf /usr/local/go sudo rm -rf /usr/local/go
curl --remote-name --progress https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz curl --remote-name --progress https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
echo '1862f4c3d3907e59b04a757cfda0ea7aa9ef39274af99a784f5be843c80c6772 go1.8.3.linux-amd64.tar.gz' | shasum -a256 -c - && \ echo 'fa1b0e45d3b647c252f51f5e1204aba049cde4af177ef9f2181f43004f901035 go1.10.3.linux-amd64.tar.gz' | shasum -a256 -c - && \
sudo tar -C /usr/local -xzf go1.8.3.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz
sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/ sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/
rm go1.8.3.linux-amd64.tar.gz rm go1.10.3.linux-amd64.tar.gz
``` ```
### 6. Get latest code ### 6. Get latest code
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
## On Microsoft Teams ## On Microsoft Teams
To enable Microsoft Teams integration you must create an incoming webhook integration on Microsoft Teams by following the steps described in this [document](https://msdn.microsoft.com/en-us/microsoft-teams/connectors). To enable Microsoft Teams integration you must create an incoming webhook integration on Microsoft Teams by following the steps described in this [document](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/connectors#setting-up-a-custom-incoming-webhook).
## On GitLab ## On GitLab
......
...@@ -4,7 +4,6 @@ require_relative 'helper' ...@@ -4,7 +4,6 @@ require_relative 'helper'
module Backup module Backup
class Repository class Repository
include Backup::Helper include Backup::Helper
# rubocop:disable Metrics/AbcSize
attr_reader :progress attr_reader :progress
...@@ -18,69 +17,66 @@ module Backup ...@@ -18,69 +17,66 @@ module Backup
Project.find_each(batch_size: 1000) do |project| Project.find_each(batch_size: 1000) do |project|
progress.print " * #{display_repo_path(project)} ... " progress.print " * #{display_repo_path(project)} ... "
path_to_project_repo = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
path_to_repo(project)
end
path_to_project_bundle = path_to_bundle(project)
# Create namespace dir or hashed path if missing
if project.hashed_storage?(:repository) if project.hashed_storage?(:repository)
FileUtils.mkdir_p(File.dirname(File.join(backup_repos_path, project.disk_path))) FileUtils.mkdir_p(File.dirname(File.join(backup_repos_path, project.disk_path)))
else else
FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.full_path)) if project.namespace FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.full_path)) if project.namespace
end end
if empty_repo?(project) if !empty_repo?(project)
progress.puts "[SKIPPED]".color(:cyan) backup_project(project)
progress.puts "[DONE]".color(:green)
else else
in_path(path_to_project_repo) do |dir| progress.puts "[SKIPPED]".color(:cyan)
FileUtils.mkdir_p(path_to_tars(project))
cmd = %W(tar -cf #{path_to_tars(project, dir)} -C #{path_to_project_repo} #{dir})
output, status = Gitlab::Popen.popen(cmd)
unless status.zero?
progress_warn(project, cmd.join(' '), output)
end
end end
cmd = %W(#{Gitlab.config.git.bin_path} --git-dir=#{path_to_project_repo} bundle create #{path_to_project_bundle} --all) wiki = ProjectWiki.new(project)
output, status = Gitlab::Popen.popen(cmd)
if status.zero? if !empty_repo?(wiki)
progress.puts "[DONE]".color(:green) backup_project(wiki)
progress.puts "[DONE] Wiki".color(:green)
else else
progress_warn(project, cmd.join(' '), output) progress.puts "[SKIPPED] Wiki".color(:cyan)
end end
end end
wiki = ProjectWiki.new(project)
path_to_wiki_repo = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
path_to_repo(wiki)
end end
path_to_wiki_bundle = path_to_bundle(wiki)
if File.exist?(path_to_wiki_repo) def prepare_directories
progress.print " * #{display_repo_path(wiki)} ... " Gitlab.config.repositories.storages.each do |name, repository_storage|
delete_all_repositories(name, repository_storage)
end
end
if empty_repo?(wiki) def backup_project(project)
progress.puts " [SKIPPED]".color(:cyan) gitaly_migrate(:repository_backup) do |is_enabled|
else if is_enabled
cmd = %W(#{Gitlab.config.git.bin_path} --git-dir=#{path_to_wiki_repo} bundle create #{path_to_wiki_bundle} --all) backup_project_gitaly(project)
output, status = Gitlab::Popen.popen(cmd)
if status.zero?
progress.puts " [DONE]".color(:green)
else else
progress_warn(wiki, cmd.join(' '), output) backup_project_local(project)
end
end end
end end
backup_custom_hooks(project)
rescue => e
progress_warn(project, e, 'Failed to backup repo')
end end
def backup_project_gitaly(project)
path_to_project_bundle = path_to_bundle(project)
Gitlab::GitalyClient::RepositoryService.new(project.repository)
.create_bundle(path_to_project_bundle)
end end
def prepare_directories def backup_project_local(project)
Gitlab.config.repositories.storages.each do |name, repository_storage| path_to_project_repo = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
delete_all_repositories(name, repository_storage) path_to_repo(project)
end end
path_to_project_bundle = path_to_bundle(project)
cmd = %W(#{Gitlab.config.git.bin_path} --git-dir=#{path_to_project_repo} bundle create #{path_to_project_bundle} --all)
output, status = Gitlab::Popen.popen(cmd)
progress_warn(project, cmd.join(' '), output) unless status.zero?
end end
def delete_all_repositories(name, repository_storage) def delete_all_repositories(name, repository_storage)
...@@ -97,8 +93,6 @@ module Backup ...@@ -97,8 +93,6 @@ module Backup
path = repository_storage.legacy_disk_path path = repository_storage.legacy_disk_path
return unless File.exist?(path) return unless File.exist?(path)
# Move all files in the existing repos directory except . and .. to
# repositories.old.<timestamp> directory
bk_repos_path = File.join(Gitlab.config.backup.path, "tmp", "#{name}-repositories.old." + Time.now.to_i.to_s) bk_repos_path = File.join(Gitlab.config.backup.path, "tmp", "#{name}-repositories.old." + Time.now.to_i.to_s)
FileUtils.mkdir_p(bk_repos_path, mode: 0700) FileUtils.mkdir_p(bk_repos_path, mode: 0700)
files = Dir.glob(File.join(path, "*"), File::FNM_DOTMATCH) - [File.join(path, "."), File.join(path, "..")] files = Dir.glob(File.join(path, "*"), File::FNM_DOTMATCH) - [File.join(path, "."), File.join(path, "..")]
...@@ -129,13 +123,47 @@ module Backup ...@@ -129,13 +123,47 @@ module Backup
.restore_custom_hooks(custom_hooks_path) .restore_custom_hooks(custom_hooks_path)
end end
def local_backup_custom_hooks(project)
in_path(path_to_tars(project)) do |dir|
path_to_project_repo = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
path_to_repo(project)
end
break unless File.exist?(File.join(path_to_project_repo, dir))
FileUtils.mkdir_p(path_to_tars(project))
cmd = %W(tar -cf #{path_to_tars(project, dir)} -c #{path_to_project_repo} #{dir})
output, status = Gitlab::Popen.popen(cmd)
unless status.zero?
progress_warn(project, cmd.join(' '), output)
end
end
end
def gitaly_backup_custom_hooks(project)
FileUtils.mkdir_p(path_to_tars(project))
custom_hooks_path = path_to_tars(project, 'custom_hooks')
Gitlab::GitalyClient::RepositoryService.new(project.repository)
.backup_custom_hooks(custom_hooks_path)
end
def backup_custom_hooks(project)
gitaly_migrate(:backup_custom_hooks) do |is_enabled|
if is_enabled
gitaly_backup_custom_hooks(project)
else
local_backup_custom_hooks(project)
end
end
end
def restore_custom_hooks(project) def restore_custom_hooks(project)
in_path(path_to_tars(project)) do |dir| in_path(path_to_tars(project)) do |dir|
gitaly_migrate(:restore_custom_hooks) do |is_enabled| gitaly_migrate(:restore_custom_hooks) do |is_enabled|
if is_enabled if is_enabled
local_restore_custom_hooks(project, dir)
else
gitaly_restore_custom_hooks(project, dir) gitaly_restore_custom_hooks(project, dir)
else
local_restore_custom_hooks(project, dir)
end end
end end
end end
...@@ -186,7 +214,6 @@ module Backup ...@@ -186,7 +214,6 @@ module Backup
end end
end end
end end
# rubocop:enable Metrics/AbcSize
protected protected
...@@ -224,9 +251,7 @@ module Backup ...@@ -224,9 +251,7 @@ module Backup
def prepare def prepare
FileUtils.rm_rf(backup_repos_path) FileUtils.rm_rf(backup_repos_path)
# Ensure the parent dir of backup_repos_path exists
FileUtils.mkdir_p(Gitlab.config.backup.path) FileUtils.mkdir_p(Gitlab.config.backup.path)
# Fail if somebody raced to create backup_repos_path before us
FileUtils.mkdir(backup_repos_path, mode: 0700) FileUtils.mkdir(backup_repos_path, mode: 0700)
end end
...@@ -242,7 +267,6 @@ module Backup ...@@ -242,7 +267,6 @@ module Backup
end end
def empty_repo?(project_or_wiki) def empty_repo?(project_or_wiki)
# Protect against stale caches
project_or_wiki.repository.expire_emptiness_caches project_or_wiki.repository.expire_emptiness_caches
project_or_wiki.repository.empty? project_or_wiki.repository.empty?
end end
......
...@@ -7,67 +7,11 @@ module Gitlab ...@@ -7,67 +7,11 @@ module Gitlab
end end
def new_pointers(object_limit: nil, not_in: nil) def new_pointers(object_limit: nil, not_in: nil)
@repository.gitaly_migrate(:blob_get_new_lfs_pointers) do |is_enabled|
if is_enabled
@repository.gitaly_blob_client.get_new_lfs_pointers(@newrev, object_limit, not_in) @repository.gitaly_blob_client.get_new_lfs_pointers(@newrev, object_limit, not_in)
else
git_new_pointers(object_limit, not_in)
end
end
end end
def all_pointers def all_pointers
@repository.gitaly_migrate(:blob_get_all_lfs_pointers) do |is_enabled|
if is_enabled
@repository.gitaly_blob_client.get_all_lfs_pointers(@newrev) @repository.gitaly_blob_client.get_all_lfs_pointers(@newrev)
else
git_all_pointers
end
end
end
private
def git_new_pointers(object_limit, not_in)
@new_pointers ||= begin
rev_list.new_objects(rev_list_params(not_in: not_in)) do |object_ids|
object_ids = object_ids.take(object_limit) if object_limit
Gitlab::Git::Blob.batch_lfs_pointers(@repository, object_ids)
end
end
end
def git_all_pointers
params = {}
if rev_list_supports_new_options?
params[:options] = ["--filter=blob:limit=#{Gitlab::Git::Blob::LFS_POINTER_MAX_SIZE}"]
end
rev_list.all_objects(rev_list_params(params)) do |object_ids|
Gitlab::Git::Blob.batch_lfs_pointers(@repository, object_ids)
end
end
def rev_list
Gitlab::Git::RevList.new(@repository, newrev: @newrev)
end
# We're passing the `--in-commit-order` arg to ensure we don't wait
# for git to traverse all commits before returning pointers.
# This is required in order to improve the performance of LFS integrity check
def rev_list_params(params = {})
params[:options] ||= []
params[:options] << "--in-commit-order" if rev_list_supports_new_options?
params[:require_path] = true
params
end
def rev_list_supports_new_options?
return @option_supported if defined?(@option_supported)
@option_supported = Gitlab::Git.version >= Gitlab::VersionInfo.parse('2.16.0')
end end
end end
end end
......
...@@ -4,7 +4,7 @@ module Gitlab ...@@ -4,7 +4,7 @@ module Gitlab
extend Gitlab::Git::Popen extend Gitlab::Git::Popen
def self.git_version def self.git_version
Gitlab::VersionInfo.parse(popen(%W(#{Gitlab.config.git.bin_path} --version), nil).first) Gitlab::VersionInfo.parse(Gitaly::Server.all.first.git_binary_version)
end end
end end
end end
......
...@@ -196,20 +196,21 @@ module Gitlab ...@@ -196,20 +196,21 @@ module Gitlab
end end
def create_bundle(save_path) def create_bundle(save_path)
request = Gitaly::CreateBundleRequest.new(repository: @gitaly_repo) gitaly_fetch_stream_to_file(
response = GitalyClient.call( save_path,
@storage,
:repository_service,
:create_bundle, :create_bundle,
request, Gitaly::CreateBundleRequest,
timeout: GitalyClient.default_timeout GitalyClient.default_timeout
) )
File.open(save_path, 'wb') do |f|
response.each do |message|
f.write(message.data)
end
end end
def backup_custom_hooks(save_path)
gitaly_fetch_stream_to_file(
save_path,
:backup_custom_hooks,
Gitaly::BackupCustomHooksRequest,
GitalyClient.default_timeout
)
end end
def create_from_bundle(bundle_path) def create_from_bundle(bundle_path)
...@@ -309,6 +310,25 @@ module Gitlab ...@@ -309,6 +310,25 @@ module Gitlab
private private
def gitaly_fetch_stream_to_file(save_path, rpc_name, request_class, timeout)
request = request_class.new(repository: @gitaly_repo)
response = GitalyClient.call(
@storage,
:repository_service,
rpc_name,
request,
timeout: timeout
)
File.open(save_path, 'wb') do |f|
response.each do |message|
f.write(message.data)
end
end
# If the file is empty means that we recieved an empty stream, we delete the file
FileUtils.rm(save_path) if File.zero?(save_path)
end
def gitaly_repo_stream_request(file_path, rpc_name, request_class, timeout) def gitaly_repo_stream_request(file_path, rpc_name, request_class, timeout)
request = request_class.new(repository: @gitaly_repo) request = request_class.new(repository: @gitaly_repo)
enum = Enumerator.new do |y| enum = Enumerator.new do |y|
......
module Gitlab module Gitlab
module HealthChecks module HealthChecks
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1218
class FsShardsCheck class FsShardsCheck
extend BaseAbstractCheck extend BaseAbstractCheck
RANDOM_STRING = SecureRandom.hex(1000).freeze RANDOM_STRING = SecureRandom.hex(1000).freeze
......
...@@ -2,11 +2,12 @@ module Gitlab ...@@ -2,11 +2,12 @@ module Gitlab
module Kubernetes module Kubernetes
module Helm module Helm
class InstallCommand < BaseCommand class InstallCommand < BaseCommand
attr_reader :name, :chart, :repository, :values attr_reader :name, :chart, :version, :repository, :values
def initialize(name, chart:, values:, repository: nil) def initialize(name, chart:, values:, version: nil, repository: nil)
@name = name @name = name
@chart = chart @chart = chart
@version = version
@values = values @values = values
@repository = repository @repository = repository
end end
...@@ -39,9 +40,13 @@ module Gitlab ...@@ -39,9 +40,13 @@ module Gitlab
def script_command def script_command
<<~HEREDOC <<~HEREDOC
helm install #{chart} --name #{name} --namespace #{Gitlab::Kubernetes::Helm::NAMESPACE} -f /data/helm/#{name}/config/values.yaml >/dev/null helm install #{chart} --name #{name}#{optional_version_flag} --namespace #{Gitlab::Kubernetes::Helm::NAMESPACE} -f /data/helm/#{name}/config/values.yaml >/dev/null
HEREDOC HEREDOC
end end
def optional_version_flag
" --version #{version}" if version
end
end end
end end
end end
......
module Gitlab module Gitlab
module Search module Search
class ParsedQuery class ParsedQuery
<<<<<<< HEAD
prepend EE::Gitlab::Search::ParsedQuery prepend EE::Gitlab::Search::ParsedQuery
=======
>>>>>>> upstream/master
attr_reader :term, :filters attr_reader :term, :filters
def initialize(term, filters) def initialize(term, filters)
......
...@@ -24,6 +24,7 @@ module Gitlab ...@@ -24,6 +24,7 @@ module Gitlab
address = val['gitaly_address'] address = val['gitaly_address']
end end
# https://gitlab.com/gitlab-org/gitaly/issues/1238
Gitlab::GitalyClient::StorageSettings.allow_disk_access do Gitlab::GitalyClient::StorageSettings.allow_disk_access do
storages << { name: key, path: val.legacy_disk_path } storages << { name: key, path: val.legacy_disk_path }
end end
......
...@@ -337,7 +337,12 @@ describe Projects::MergeRequestsController do ...@@ -337,7 +337,12 @@ describe Projects::MergeRequestsController do
context 'when the sha parameter matches the source SHA' do context 'when the sha parameter matches the source SHA' do
def merge_with_sha(params = {}) def merge_with_sha(params = {})
post :merge, base_params.merge(sha: merge_request.diff_head_sha).merge(params) post_params = base_params.merge(sha: merge_request.diff_head_sha).merge(params)
if Gitlab.rails5?
post :merge, params: post_params, as: :json
else
post :merge, post_params
end
end end
it 'returns :success' do it 'returns :success' do
......
...@@ -71,7 +71,7 @@ describe Projects::PagesController do ...@@ -71,7 +71,7 @@ describe Projects::PagesController do
{ {
namespace_id: project.namespace, namespace_id: project.namespace,
project_id: project, project_id: project,
project: { pages_https_only: false } project: { pages_https_only: 'false' }
} }
end end
...@@ -96,7 +96,7 @@ describe Projects::PagesController do ...@@ -96,7 +96,7 @@ describe Projects::PagesController do
it 'calls the update service' do it 'calls the update service' do
expect(Projects::UpdateService) expect(Projects::UpdateService)
.to receive(:new) .to receive(:new)
.with(project, user, request_params[:project]) .with(project, user, ActionController::Parameters.new(request_params[:project]).permit!)
.and_return(update_service) .and_return(update_service)
patch :update, request_params patch :update, request_params
......
...@@ -620,6 +620,22 @@ describe ProjectsController do ...@@ -620,6 +620,22 @@ describe ProjectsController do
expect(parsed_body["Tags"]).to include("v1.0.0") expect(parsed_body["Tags"]).to include("v1.0.0")
expect(parsed_body["Commits"]).to include("123456") expect(parsed_body["Commits"]).to include("123456")
end end
context "when preferred language is Japanese" do
before do
user.update!(preferred_language: 'ja')
sign_in(user)
end
it "gets a list of branches, tags and commits" do
get :refs, namespace_id: public_project.namespace, id: public_project, ref: "123456"
parsed_body = JSON.parse(response.body)
expect(parsed_body["Branches"]).to include("master")
expect(parsed_body["Tags"]).to include("v1.0.0")
expect(parsed_body["Commits"]).to include("123456")
end
end
end end
describe 'GET edit' do describe 'GET edit' do
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Git::LfsChanges do describe Gitlab::Git::LfsChanges do
let(:project) { create(:project, :repository) } set(:project) { create(:project, :repository) }
let(:newrev) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' } let(:newrev) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
let(:blob_object_id) { '0c304a93cb8430108629bbbcaa27db3343299bc0' } let(:blob_object_id) { '0c304a93cb8430108629bbbcaa27db3343299bc0' }
subject { described_class.new(project.repository, newrev) } subject { described_class.new(project.repository, newrev) }
describe '#new_pointers' do describe '#new_pointers' do
shared_examples 'new pointers' do
it 'filters new objects to find lfs pointers' do it 'filters new objects to find lfs pointers' do
expect(subject.new_pointers(not_in: []).first.id).to eq(blob_object_id) expect(subject.new_pointers(not_in: []).first.id).to eq(blob_object_id)
end end
...@@ -17,34 +16,4 @@ describe Gitlab::Git::LfsChanges do ...@@ -17,34 +16,4 @@ describe Gitlab::Git::LfsChanges do
expect(subject.new_pointers(object_limit: 1)).to eq([]) expect(subject.new_pointers(object_limit: 1)).to eq([])
end end
end end
context 'with gitaly enabled' do
it_behaves_like 'new pointers'
end
context 'with gitaly disabled', :skip_gitaly_mock do
it_behaves_like 'new pointers'
it 'uses rev-list to find new objects' do
rev_list = double
allow(Gitlab::Git::RevList).to receive(:new).and_return(rev_list)
expect(rev_list).to receive(:new_objects).and_return([])
subject.new_pointers
end
end
end
describe '#all_pointers', :skip_gitaly_mock do
it 'uses rev-list to find all objects' do
rev_list = double
allow(Gitlab::Git::RevList).to receive(:new).and_return(rev_list)
allow(rev_list).to receive(:all_objects).and_yield([blob_object_id])
expect(Gitlab::Git::Blob).to receive(:batch_lfs_pointers).with(project.repository, [blob_object_id])
subject.all_pointers
end
end
end end
...@@ -7,13 +7,7 @@ describe Gitlab::Kubernetes::Helm::Api do ...@@ -7,13 +7,7 @@ describe Gitlab::Kubernetes::Helm::Api do
let(:namespace) { Gitlab::Kubernetes::Namespace.new(gitlab_namespace, client) } let(:namespace) { Gitlab::Kubernetes::Namespace.new(gitlab_namespace, client) }
let(:application) { create(:clusters_applications_prometheus) } let(:application) { create(:clusters_applications_prometheus) }
let(:command) do let(:command) { application.install_command }
Gitlab::Kubernetes::Helm::InstallCommand.new(
application.name,
chart: application.chart,
values: application.values
)
end
subject { helm } subject { helm }
......
...@@ -3,17 +3,13 @@ require 'rails_helper' ...@@ -3,17 +3,13 @@ require 'rails_helper'
describe Gitlab::Kubernetes::Helm::InstallCommand do describe Gitlab::Kubernetes::Helm::InstallCommand do
let(:application) { create(:clusters_applications_prometheus) } let(:application) { create(:clusters_applications_prometheus) }
let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE } let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
let(:install_command) { application.install_command }
let(:install_command) do
described_class.new(
application.name,
chart: application.chart,
values: application.values
)
end
subject { install_command } subject { install_command }
context 'for ingress' do
let(:application) { create(:clusters_applications_ingress) }
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
...@@ -22,18 +18,38 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -22,18 +18,38 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
EOS EOS
end end
end end
end
context 'for prometheus' do
let(:application) { create(:clusters_applications_prometheus) }
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
helm init --client-only >/dev/null
helm install #{application.chart} --name #{application.name} --version #{application.version} --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
EOS
end
end
end
context 'with an application with a repository' do context 'for runner' do
let(:ci_runner) { create(:ci_runner) } let(:ci_runner) { create(:ci_runner) }
let(:application) { create(:clusters_applications_runner, runner: ci_runner) } let(:application) { create(:clusters_applications_runner, runner: ci_runner) }
let(:install_command) do
described_class.new( it_behaves_like 'helm commands' do
application.name, let(:commands) do
chart: application.chart, <<~EOS
values: application.values, helm init --client-only >/dev/null
repository: application.repository helm repo add #{application.name} #{application.repository}
) helm install #{application.chart} --name #{application.name} --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml >/dev/null
EOS
end end
end
end
context 'for jupyter' do
let(:application) { create(:clusters_applications_jupyter) }
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
......
...@@ -73,6 +73,7 @@ describe Clusters::Applications::Ingress do ...@@ -73,6 +73,7 @@ describe Clusters::Applications::Ingress do
it 'should be initialized with ingress arguments' do it 'should be initialized with ingress arguments' do
expect(subject.name).to eq('ingress') expect(subject.name).to eq('ingress')
expect(subject.chart).to eq('stable/nginx-ingress') expect(subject.chart).to eq('stable/nginx-ingress')
expect(subject.version).to be_nil
expect(subject.values).to eq(ingress.values) expect(subject.values).to eq(ingress.values)
end end
end end
......
...@@ -36,6 +36,7 @@ describe Clusters::Applications::Jupyter do ...@@ -36,6 +36,7 @@ describe Clusters::Applications::Jupyter do
it 'should be initialized with 4 arguments' do it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('jupyter') expect(subject.name).to eq('jupyter')
expect(subject.chart).to eq('jupyter/jupyterhub') expect(subject.chart).to eq('jupyter/jupyterhub')
expect(subject.version).to be_nil
expect(subject.repository).to eq('https://jupyterhub.github.io/helm-chart/') expect(subject.repository).to eq('https://jupyterhub.github.io/helm-chart/')
expect(subject.values).to eq(jupyter.values) expect(subject.values).to eq(jupyter.values)
end end
......
...@@ -109,6 +109,7 @@ describe Clusters::Applications::Prometheus do ...@@ -109,6 +109,7 @@ describe Clusters::Applications::Prometheus do
it 'should be initialized with 3 arguments' do it 'should be initialized with 3 arguments' do
expect(subject.name).to eq('prometheus') expect(subject.name).to eq('prometheus')
expect(subject.chart).to eq('stable/prometheus') expect(subject.chart).to eq('stable/prometheus')
expect(subject.version).to eq('6.7.3')
expect(subject.values).to eq(prometheus.values) expect(subject.values).to eq(prometheus.values)
end end
end end
......
...@@ -31,6 +31,7 @@ describe Clusters::Applications::Runner do ...@@ -31,6 +31,7 @@ describe Clusters::Applications::Runner do
it 'should be initialized with 4 arguments' do it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('runner') expect(subject.name).to eq('runner')
expect(subject.chart).to eq('runner/gitlab-runner') expect(subject.chart).to eq('runner/gitlab-runner')
expect(subject.version).to be_nil
expect(subject.repository).to eq('https://charts.gitlab.io') expect(subject.repository).to eq('https://charts.gitlab.io')
expect(subject.values).to eq(gitlab_runner.values) expect(subject.values).to eq(gitlab_runner.values)
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