Commit 4d9cc941 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'gitaly-socket-per-shard' into 'master'

One Gitaly connection per storage shard

See merge request !10150
parents 76a15db4 340a6f86
...@@ -3,20 +3,16 @@ class PostReceive ...@@ -3,20 +3,16 @@ class PostReceive
include DedicatedSidekiqQueue include DedicatedSidekiqQueue
def perform(repo_path, identifier, changes) def perform(repo_path, identifier, changes)
if repository_storage = Gitlab.config.repositories.storages.find { |p| repo_path.start_with?(p[1]['path'].to_s) } repo_relative_path = Gitlab::RepoPath.strip_storage_path(repo_path)
repo_path.gsub!(repository_storage[1]['path'].to_s, "")
else
log("Check gitlab.yml config for correct repositories.storages values. No repository storage path matches \"#{repo_path}\"")
end
changes = Base64.decode64(changes) unless changes.include?(' ') changes = Base64.decode64(changes) unless changes.include?(' ')
# Use Sidekiq.logger so arguments can be correlated with execution # Use Sidekiq.logger so arguments can be correlated with execution
# time and thread ID's. # time and thread ID's.
Sidekiq.logger.info "changes: #{changes.inspect}" if ENV['SIDEKIQ_LOG_ARGUMENTS'] Sidekiq.logger.info "changes: #{changes.inspect}" if ENV['SIDEKIQ_LOG_ARGUMENTS']
post_received = Gitlab::GitPostReceive.new(repo_path, identifier, changes) post_received = Gitlab::GitPostReceive.new(repo_relative_path, identifier, changes)
if post_received.project.nil? if post_received.project.nil?
log("Triggered hook for non-existing project with full path \"#{repo_path}\"") log("Triggered hook for non-existing project with full path \"#{repo_relative_path}\"")
return false return false
end end
...@@ -25,7 +21,7 @@ class PostReceive ...@@ -25,7 +21,7 @@ class PostReceive
elsif post_received.regular_project? elsif post_received.regular_project?
process_project_changes(post_received) process_project_changes(post_received)
else else
log("Triggered hook for unidentifiable repository type with full path \"#{repo_path}\"") log("Triggered hook for unidentifiable repository type with full path \"#{repo_relative_path}\"")
false false
end end
end end
......
...@@ -443,14 +443,10 @@ production: &base ...@@ -443,14 +443,10 @@ production: &base
# Gitaly settings # Gitaly settings
gitaly: gitaly:
# The socket_path setting is optional and obsolete. When this is set # This setting controls whether GitLab uses Gitaly (new component
# GitLab assumes it can reach a Gitaly services via a Unix socket at # introduced in 9.0). Eventually Gitaly use will become mandatory and
# this path. When this is commented out GitLab will not use Gitaly. # this option will disappear.
# enabled: false
# This setting is obsolete because we expect it to be moved under
# repositories/storages in GitLab 9.1.
#
# socket_path: tmp/sockets/private/gitaly.socket
# #
# 4. Advanced settings # 4. Advanced settings
...@@ -465,6 +461,7 @@ production: &base ...@@ -465,6 +461,7 @@ production: &base
storages: # You must have at least a `default` storage path. storages: # You must have at least a `default` storage path.
default: default:
path: /home/git/repositories/ path: /home/git/repositories/
gitaly_address: unix:/home/git/gitlab/tmp/sockets/private/gitaly.socket
## Backup settings ## Backup settings
backup: backup:
...@@ -577,6 +574,9 @@ test: ...@@ -577,6 +574,9 @@ test:
storages: storages:
default: default:
path: tmp/tests/repositories/ path: tmp/tests/repositories/
gitaly_address: unix:<%= Rails.root.join('tmp/sockets/private/gitaly.socket') %>
gitaly:
enabled: false
backup: backup:
path: tmp/tests/backups path: tmp/tests/backups
gitlab_shell: gitlab_shell:
......
...@@ -79,6 +79,10 @@ class Settings < Settingslogic ...@@ -79,6 +79,10 @@ class Settings < Settingslogic
value value
end end
def absolute(path)
File.expand_path(path, Rails.root)
end
private private
def base_url(config) def base_url(config)
...@@ -178,7 +182,7 @@ if github_settings ...@@ -178,7 +182,7 @@ if github_settings
end end
Settings['shared'] ||= Settingslogic.new({}) Settings['shared'] ||= Settingslogic.new({})
Settings.shared['path'] = File.expand_path(Settings.shared['path'] || "shared", Rails.root) Settings.shared['path'] = Settings.absolute(Settings.shared['path'] || "shared")
Settings['issues_tracker'] ||= {} Settings['issues_tracker'] ||= {}
...@@ -237,7 +241,7 @@ Settings['gitlab_ci'] ||= Settingslogic.new({}) ...@@ -237,7 +241,7 @@ Settings['gitlab_ci'] ||= Settingslogic.new({})
Settings.gitlab_ci['shared_runners_enabled'] = true if Settings.gitlab_ci['shared_runners_enabled'].nil? Settings.gitlab_ci['shared_runners_enabled'] = true if Settings.gitlab_ci['shared_runners_enabled'].nil?
Settings.gitlab_ci['all_broken_builds'] = true if Settings.gitlab_ci['all_broken_builds'].nil? Settings.gitlab_ci['all_broken_builds'] = true if Settings.gitlab_ci['all_broken_builds'].nil?
Settings.gitlab_ci['add_pusher'] = false if Settings.gitlab_ci['add_pusher'].nil? Settings.gitlab_ci['add_pusher'] = false if Settings.gitlab_ci['add_pusher'].nil?
Settings.gitlab_ci['builds_path'] = File.expand_path(Settings.gitlab_ci['builds_path'] || "builds/", Rails.root) Settings.gitlab_ci['builds_path'] = Settings.absolute(Settings.gitlab_ci['builds_path'] || "builds/")
Settings.gitlab_ci['url'] ||= Settings.send(:build_gitlab_ci_url) Settings.gitlab_ci['url'] ||= Settings.send(:build_gitlab_ci_url)
# #
...@@ -251,7 +255,7 @@ Settings.incoming_email['enabled'] = false if Settings.incoming_email['enabled'] ...@@ -251,7 +255,7 @@ Settings.incoming_email['enabled'] = false if Settings.incoming_email['enabled']
# #
Settings['artifacts'] ||= Settingslogic.new({}) Settings['artifacts'] ||= Settingslogic.new({})
Settings.artifacts['enabled'] = true if Settings.artifacts['enabled'].nil? Settings.artifacts['enabled'] = true if Settings.artifacts['enabled'].nil?
Settings.artifacts['path'] = File.expand_path(Settings.artifacts['path'] || File.join(Settings.shared['path'], "artifacts"), Rails.root) Settings.artifacts['path'] = Settings.absolute(Settings.artifacts['path'] || File.join(Settings.shared['path'], "artifacts"))
Settings.artifacts['max_size'] ||= 100 # in megabytes Settings.artifacts['max_size'] ||= 100 # in megabytes
# #
...@@ -265,14 +269,14 @@ Settings.registry['api_url'] ||= "http://localhost:5000/" ...@@ -265,14 +269,14 @@ Settings.registry['api_url'] ||= "http://localhost:5000/"
Settings.registry['key'] ||= nil Settings.registry['key'] ||= nil
Settings.registry['issuer'] ||= nil Settings.registry['issuer'] ||= nil
Settings.registry['host_port'] ||= [Settings.registry['host'], Settings.registry['port']].compact.join(':') Settings.registry['host_port'] ||= [Settings.registry['host'], Settings.registry['port']].compact.join(':')
Settings.registry['path'] = File.expand_path(Settings.registry['path'] || File.join(Settings.shared['path'], 'registry'), Rails.root) Settings.registry['path'] = Settings.absolute(Settings.registry['path'] || File.join(Settings.shared['path'], 'registry'))
# #
# Pages # Pages
# #
Settings['pages'] ||= Settingslogic.new({}) Settings['pages'] ||= Settingslogic.new({})
Settings.pages['enabled'] = false if Settings.pages['enabled'].nil? Settings.pages['enabled'] = false if Settings.pages['enabled'].nil?
Settings.pages['path'] = File.expand_path(Settings.pages['path'] || File.join(Settings.shared['path'], "pages"), Rails.root) Settings.pages['path'] = Settings.absolute(Settings.pages['path'] || File.join(Settings.shared['path'], "pages"))
Settings.pages['https'] = false if Settings.pages['https'].nil? Settings.pages['https'] = false if Settings.pages['https'].nil?
Settings.pages['host'] ||= "example.com" Settings.pages['host'] ||= "example.com"
Settings.pages['port'] ||= Settings.pages.https ? 443 : 80 Settings.pages['port'] ||= Settings.pages.https ? 443 : 80
...@@ -286,7 +290,7 @@ Settings.pages['external_https'] ||= false unless Settings.pages['external_http ...@@ -286,7 +290,7 @@ Settings.pages['external_https'] ||= false unless Settings.pages['external_http
# #
Settings['lfs'] ||= Settingslogic.new({}) Settings['lfs'] ||= Settingslogic.new({})
Settings.lfs['enabled'] = true if Settings.lfs['enabled'].nil? Settings.lfs['enabled'] = true if Settings.lfs['enabled'].nil?
Settings.lfs['storage_path'] = File.expand_path(Settings.lfs['storage_path'] || File.join(Settings.shared['path'], "lfs-objects"), Rails.root) Settings.lfs['storage_path'] = Settings.absolute(Settings.lfs['storage_path'] || File.join(Settings.shared['path'], "lfs-objects"))
# #
# Mattermost # Mattermost
...@@ -350,8 +354,8 @@ Settings.cron_jobs['remove_unreferenced_lfs_objects_worker']['job_class'] = 'Rem ...@@ -350,8 +354,8 @@ Settings.cron_jobs['remove_unreferenced_lfs_objects_worker']['job_class'] = 'Rem
# GitLab Shell # GitLab Shell
# #
Settings['gitlab_shell'] ||= Settingslogic.new({}) Settings['gitlab_shell'] ||= Settingslogic.new({})
Settings.gitlab_shell['path'] ||= Settings.gitlab['user_home'] + '/gitlab-shell/' Settings.gitlab_shell['path'] = Settings.absolute(Settings.gitlab_shell['path'] || Settings.gitlab['user_home'] + '/gitlab-shell/')
Settings.gitlab_shell['hooks_path'] ||= Settings.gitlab['user_home'] + '/gitlab-shell/hooks/' Settings.gitlab_shell['hooks_path'] = Settings.absolute(Settings.gitlab_shell['hooks_path'] || Settings.gitlab['user_home'] + '/gitlab-shell/hooks/')
Settings.gitlab_shell['secret_file'] ||= Rails.root.join('.gitlab_shell_secret') Settings.gitlab_shell['secret_file'] ||= Rails.root.join('.gitlab_shell_secret')
Settings.gitlab_shell['receive_pack'] = true if Settings.gitlab_shell['receive_pack'].nil? Settings.gitlab_shell['receive_pack'] = true if Settings.gitlab_shell['receive_pack'].nil?
Settings.gitlab_shell['upload_pack'] = true if Settings.gitlab_shell['upload_pack'].nil? Settings.gitlab_shell['upload_pack'] = true if Settings.gitlab_shell['upload_pack'].nil?
...@@ -374,6 +378,11 @@ unless Settings.repositories.storages['default'] ...@@ -374,6 +378,11 @@ unless Settings.repositories.storages['default']
Settings.repositories.storages['default']['path'] ||= Settings.gitlab['user_home'] + '/repositories/' Settings.repositories.storages['default']['path'] ||= Settings.gitlab['user_home'] + '/repositories/'
end end
Settings.repositories.storages.values.each do |storage|
# Expand relative paths
storage['path'] = Settings.absolute(storage['path'])
end
# #
# The repository_downloads_path is used to remove outdated repository # The repository_downloads_path is used to remove outdated repository
# archives, if someone has it configured incorrectly, and it points # archives, if someone has it configured incorrectly, and it points
...@@ -395,7 +404,7 @@ end ...@@ -395,7 +404,7 @@ end
Settings['backup'] ||= Settingslogic.new({}) Settings['backup'] ||= Settingslogic.new({})
Settings.backup['keep_time'] ||= 0 Settings.backup['keep_time'] ||= 0
Settings.backup['pg_schema'] = nil Settings.backup['pg_schema'] = nil
Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root) Settings.backup['path'] = Settings.absolute(Settings.backup['path'] || "tmp/backups/")
Settings.backup['archive_permissions'] ||= 0600 Settings.backup['archive_permissions'] ||= 0600
Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil }) Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil })
# Convert upload connection settings to use symbol keys, to make Fog happy # Convert upload connection settings to use symbol keys, to make Fog happy
...@@ -418,7 +427,7 @@ Settings.git['timeout'] ||= 10 ...@@ -418,7 +427,7 @@ Settings.git['timeout'] ||= 10
# least. This setting is fed to 'rm -rf' in # least. This setting is fed to 'rm -rf' in
# db/migrate/20151023144219_remove_satellites.rb # db/migrate/20151023144219_remove_satellites.rb
Settings['satellites'] ||= Settingslogic.new({}) Settings['satellites'] ||= Settingslogic.new({})
Settings.satellites['path'] = File.expand_path(Settings.satellites['path'] || "tmp/repo_satellites/", Rails.root) Settings.satellites['path'] = Settings.absolute(Settings.satellites['path'] || "tmp/repo_satellites/")
# #
# Extra customization # Extra customization
...@@ -440,7 +449,7 @@ Settings.rack_attack.git_basic_auth['bantime'] ||= 1.hour ...@@ -440,7 +449,7 @@ Settings.rack_attack.git_basic_auth['bantime'] ||= 1.hour
# Gitaly # Gitaly
# #
Settings['gitaly'] ||= Settingslogic.new({}) Settings['gitaly'] ||= Settingslogic.new({})
Settings.gitaly['socket_path'] ||= ENV['GITALY_SOCKET_PATH'] Settings.gitaly['enabled'] ||= false
# #
# Webpack settings # Webpack settings
......
# Make sure we initialize a Gitaly channel before Sidekiq starts multi-threaded execution. require 'uri'
Gitlab::GitalyClient.channel unless Rails.env.test?
# Make sure we initialize our Gitaly channels before Sidekiq starts multi-threaded execution.
if Gitlab.config.gitaly.enabled || Rails.env.test?
Gitlab.config.repositories.storages.each do |name, params|
address = params['gitaly_address']
unless address.present?
raise "storage #{name.inspect} is missing a gitaly_address"
end
unless URI(address).scheme == 'unix'
raise "Unsupported Gitaly address: #{address.inspect}"
end
Gitlab::GitalyClient.configure_channel(name, address)
end
end
...@@ -477,12 +477,12 @@ with setting up Gitaly until you upgrade to GitLab 9.1 or later. ...@@ -477,12 +477,12 @@ with setting up Gitaly until you upgrade to GitLab 9.1 or later.
# Enable Gitaly in the init script # Enable Gitaly in the init script
echo 'gitaly_enabled=true' | sudo tee -a /etc/default/gitlab echo 'gitaly_enabled=true' | sudo tee -a /etc/default/gitlab
Next, edit `/home/git/gitlab/config/gitlab.yml` and make sure `socket_path` in Next, edit `/home/git/gitlab/config/gitlab.yml` and make sure `enabled: true` in
the `gitaly:` section is uncommented. the `gitaly:` section is uncommented.
# <- gitlab.yml indentation starts here # <- gitlab.yml indentation starts here
gitaly: gitaly:
socket_path: tmp/sockets/private/gitaly.socket enabled: true
For more information about configuring Gitaly see For more information about configuring Gitaly see
[doc/administration/gitaly](../administration/gitaly). [doc/administration/gitaly](../administration/gitaly).
......
# From 9.0 to 9.1
** TODO: **
# TODO clean out 9.0-specific stuff
Make sure you view this update guide from the tag (version) of GitLab you would
like to install. In most cases this should be the highest numbered production
tag (without rc in it). You can select the tag in the version dropdown at the
top left corner of GitLab (below the menu bar).
If the highest number stable branch is unclear please check the
[GitLab Blog](https://about.gitlab.com/blog/archives.html) for installation
guide links by version.
### 1. Stop server
```bash
sudo service gitlab stop
```
### 2. Backup
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```
### 3. Update Ruby
NOTE: GitLab 9.0 and higher only support Ruby 2.3.x and dropped support for Ruby 2.1.x. Be
sure to upgrade your interpreter if necessary.
You can check which version you are running with `ruby -v`.
Download and compile Ruby:
```bash
mkdir /tmp/ruby && cd /tmp/ruby
curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.3.tar.gz
echo '1014ee699071aa2ddd501907d18cbe15399c997d ruby-2.3.3.tar.gz' | shasum -c - && tar xzf ruby-2.3.3.tar.gz
cd ruby-2.3.3
./configure --disable-install-rdoc
make
sudo make install
```
Install Bundler:
```bash
sudo gem install bundler --no-ri --no-rdoc
```
### 4. Update Node
GitLab now runs [webpack](http://webpack.js.org) to compile frontend assets and
it has a minimum requirement of node v4.3.0.
You can check which version you are running with `node -v`. If you are running
a version older than `v4.3.0` you will need to update to a newer version. You
can find instructions to install from community maintained packages or compile
from source at the nodejs.org website.
<https://nodejs.org/en/download/>
Since 8.17, GitLab requires the use of yarn `>= v0.17.0` to manage
JavaScript dependencies.
```bash
curl --location https://yarnpkg.com/install.sh | bash -
```
More information can be found on the [yarn website](https://yarnpkg.com/en/docs/install).
### 5. Get latest code
```bash
cd /home/git/gitlab
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
```
For GitLab Community Edition:
```bash
cd /home/git/gitlab
sudo -u git -H git checkout 9-1-stable
```
OR
For GitLab Enterprise Edition:
```bash
cd /home/git/gitlab
sudo -u git -H git checkout 9-1-stable-ee
```
### 6. Update gitlab-shell
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch --all --tags
sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_SHELL_VERSION)
```
### 7. Update gitlab-workhorse
Install and compile gitlab-workhorse. This requires
[Go 1.5](https://golang.org/dl) which should already be on your system from
GitLab 8.1. GitLab-Workhorse uses [GNU Make](https://www.gnu.org/software/make/).
If you are not using Linux you may have to run `gmake` instead of
`make` below.
```bash
cd /home/git/gitlab-workhorse
sudo -u git -H git fetch --all --tags
sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_WORKHORSE_VERSION)
sudo -u git -H make
```
### 8. Update configuration files
#### New configuration options for `gitlab.yml`
There might be configuration options available for [`gitlab.yml`][yaml]. View them with the command below and apply them manually to your current `gitlab.yml`:
```sh
cd /home/git/gitlab
git diff origin/9-0-stable:config/gitlab.yml.example origin/9-1-stable:config/gitlab.yml.example
```
#### Configuration changes for repository storages
This version introduces a new configuration structure for repository storages.
Update your current configuration as follows, replacing with your storages names and paths:
**For installations from source**
1. Update your `gitlab.yml`, from
```yaml
repositories:
storages: # You must have at least a 'default' storage path.
default: /home/git/repositories
nfs: /mnt/nfs/repositories
cephfs: /mnt/cephfs/repositories
```
to
```yaml
repositories:
storages: # You must have at least a 'default' storage path.
default:
path: /home/git/repositories
nfs:
path: /mnt/nfs/repositories
cephfs:
path: /mnt/cephfs/repositories
```
**For Omnibus installations**
1. Update your `/etc/gitlab/gitlab.rb`, from
```ruby
git_data_dirs({
"default" => "/var/opt/gitlab/git-data",
"nfs" => "/mnt/nfs/git-data",
"cephfs" => "/mnt/cephfs/git-data"
})
```
to
```ruby
git_data_dirs({
"default" => { "path" => "/var/opt/gitlab/git-data" },
"nfs" => { "path" => "/mnt/nfs/git-data" },
"cephfs" => { "path" => "/mnt/cephfs/git-data" }
})
```
#### Git configuration
Configure Git to generate packfile bitmaps (introduced in Git 2.0) on
the GitLab server during `git gc`.
```sh
cd /home/git/gitlab
sudo -u git -H git config --global repack.writeBitmaps true
```
#### Nginx configuration
Ensure you're still up-to-date with the latest NGINX configuration changes:
```sh
cd /home/git/gitlab
# For HTTPS configurations
git diff origin/9-0-stable:lib/support/nginx/gitlab-ssl origin/9-1-stable:lib/support/nginx/gitlab-ssl
# For HTTP configurations
git diff origin/9-0-stable:lib/support/nginx/gitlab origin/9-1-stable:lib/support/nginx/gitlab
```
If you are using Strict-Transport-Security in your installation to continue using it you must enable it in your Nginx
configuration as GitLab application no longer handles setting it.
If you are using Apache instead of NGINX please see the updated [Apache templates].
Also note that because Apache does not support upstreams behind Unix sockets you
will need to let gitlab-workhorse listen on a TCP port. You can do this
via [/etc/default/gitlab].
[Apache templates]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache
[/etc/default/gitlab]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-1-stable/lib/support/init.d/gitlab.default.example#L38
#### SMTP configuration
If you're installing from source and use SMTP to deliver mail, you will need to add the following line
to config/initializers/smtp_settings.rb:
```ruby
ActionMailer::Base.delivery_method = :smtp
```
See [smtp_settings.rb.sample] as an example.
[smtp_settings.rb.sample]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-0-stable/config/initializers/smtp_settings.rb.sample#L13
#### Init script
There might be new configuration options available for [`gitlab.default.example`][gl-example]. View them with the command below and apply them manually to your current `/etc/default/gitlab`:
```sh
cd /home/git/gitlab
git diff origin/9-0-stable:lib/support/init.d/gitlab.default.example origin/9-1-stable:lib/support/init.d/gitlab.default.example
```
Ensure you're still up-to-date with the latest init script changes:
```bash
cd /home/git/gitlab
sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
```
For Ubuntu 16.04.1 LTS:
```bash
sudo systemctl daemon-reload
```
### 9. Install libs, migrations, etc.
```bash
cd /home/git/gitlab
# MySQL installations (note: the line below states '--without postgres')
sudo -u git -H bundle install --without postgres development test --deployment
# PostgreSQL installations (note: the line below states '--without mysql')
sudo -u git -H bundle install --without mysql development test --deployment
# Optional: clean up old gems
sudo -u git -H bundle clean
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Update node dependencies and recompile assets
sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
# Clean up cache
sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
```
**MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md).
### 10. Optional: install Gitaly
Gitaly is still an optional component of GitLab. If you want to save time
during your 9.1 upgrade **you can skip this step**.
If you have not yet set up Gitaly then follow [Gitaly section of the installation
guide](../install/installation.md#install-gitaly).
If you installed Gitaly in GitLab 9.0 you need to make some changes in gitlab.yml.
Look for `socket_path:` the `gitaly:` section. Its value is usually
`/home/git/gitlab/tmp/sockets/private/gitaly.socket`. Note what socket
path your gitlab.yml is using. Now go to the `repositories:` section,
and for each entry under `storages:`, add a `gitaly_address:` based on
the socket path, but with `unix:` in front.
```yaml
repositories:
storages:
default:
path: /home/git/repositories
gitaly_address: unix:/home/git/gitlab/tmp/sockets/private/gitaly.socket
other_storage:
path: /home/git/other-repositories
gitaly_address: unix:/home/git/gitlab/tmp/sockets/private/gitaly.socket
```
Each entry under `storages:` should use the same `gitaly_address`.
### 11. Start application
```bash
sudo service gitlab start
sudo service nginx restart
```
### 12. Check application status
Check if GitLab and its environment are configured correctly:
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
```
To make sure you didn't miss anything run a more thorough check:
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
```
If all items are green, then congratulations, the upgrade is complete!
## Things went south? Revert to previous version (9.0)
### 1. Revert the code to the previous version
Follow the [upgrade guide from 8.17 to 9.0](8.17-to-9.0.md), except for the
database migration (the backup is already migrated to the previous version).
### 2. Restore from the backup
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
```
If you have more than one backup `*.tar` file(s) please add `BACKUP=timestamp_of_backup` to the command above.
[yaml]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-1-stable/config/gitlab.yml.example
[gl-example]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-1-stable/lib/support/init.d/gitlab.default.example
...@@ -139,7 +139,7 @@ module API ...@@ -139,7 +139,7 @@ module API
return unless Gitlab::GitalyClient.enabled? return unless Gitlab::GitalyClient.enabled?
begin begin
Gitlab::GitalyClient::Notifications.new.post_receive(params[:repo_path]) Gitlab::GitalyClient::Notifications.new(params[:repo_path]).post_receive
rescue GRPC::Unavailable => e rescue GRPC::Unavailable => e
render_api_error(e, 500) render_api_error(e, 500)
end end
......
...@@ -182,7 +182,9 @@ module Backup ...@@ -182,7 +182,9 @@ module Backup
dir_entries = Dir.entries(path) dir_entries = Dir.entries(path)
yield('custom_hooks') if dir_entries.include?('custom_hooks') if dir_entries.include?('custom_hooks') || dir_entries.include?('custom_hooks.tar')
yield('custom_hooks')
end
end end
def prepare def prepare
......
...@@ -4,28 +4,30 @@ module Gitlab ...@@ -4,28 +4,30 @@ module Gitlab
module GitalyClient module GitalyClient
SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze
def self.gitaly_address def self.configure_channel(storage, address)
if Gitlab.config.gitaly.socket_path @addresses ||= {}
"unix://#{Gitlab.config.gitaly.socket_path}" @addresses[storage] = address
end @channels ||= {}
@channels[storage] = new_channel(address)
end
def self.new_channel(address)
# NOTE: Gitaly currently runs on a Unix socket, so permissions are
# handled using the file system and no additional authentication is
# required (therefore the :this_channel_is_insecure flag)
GRPC::Core::Channel.new(address, {}, :this_channel_is_insecure)
end end
def self.channel def self.get_channel(storage)
return @channel if defined?(@channel) @channels[storage]
end
@channel = def self.get_address(storage)
if enabled? @addresses[storage]
# NOTE: Gitaly currently runs on a Unix socket, so permissions are
# handled using the file system and no additional authentication is
# required (therefore the :this_channel_is_insecure flag)
GRPC::Core::Channel.new(gitaly_address, {}, :this_channel_is_insecure)
else
nil
end
end end
def self.enabled? def self.enabled?
gitaly_address.present? Gitlab.config.gitaly.enabled
end end
def self.feature_enabled?(feature) def self.feature_enabled?(feature)
......
...@@ -7,8 +7,10 @@ module Gitlab ...@@ -7,8 +7,10 @@ module Gitlab
class << self class << self
def diff_from_parent(commit, options = {}) def diff_from_parent(commit, options = {})
stub = Gitaly::Diff::Stub.new(nil, nil, channel_override: GitalyClient.channel) project = commit.project
repo = Gitaly::Repository.new(path: commit.project.repository.path_to_repo) channel = GitalyClient.get_channel(project.repository_storage)
stub = Gitaly::Diff::Stub.new(nil, nil, channel_override: channel)
repo = Gitaly::Repository.new(path: project.repository.path_to_repo)
parent = commit.parents[0] parent = commit.parents[0]
parent_id = parent ? parent.id : EMPTY_TREE_ID parent_id = parent ? parent.id : EMPTY_TREE_ID
request = Gitaly::CommitDiffRequest.new( request = Gitaly::CommitDiffRequest.new(
......
...@@ -3,14 +3,19 @@ module Gitlab ...@@ -3,14 +3,19 @@ module Gitlab
class Notifications class Notifications
attr_accessor :stub attr_accessor :stub
def initialize def initialize(repo_path)
@stub = Gitaly::Notifications::Stub.new(nil, nil, channel_override: GitalyClient.channel) full_path = Gitlab::RepoPath.strip_storage_path(repo_path).
sub(/\.git\z/, '').sub(/\.wiki\z/, '')
@project = Project.find_by_full_path(full_path)
channel = GitalyClient.get_channel(@project.repository_storage)
@stub = Gitaly::Notifications::Stub.new(nil, nil, channel_override: channel)
end end
def post_receive(repo_path) def post_receive
repository = Gitaly::Repository.new(path: repo_path) repository = Gitaly::Repository.new(path: @project.repository.path_to_repo)
request = Gitaly::PostReceiveRequest.new(repository: repository) request = Gitaly::PostReceiveRequest.new(repository: repository)
stub.post_receive(request) @stub.post_receive(request)
end end
end end
end end
......
module Gitlab
module RepoPath
NotFoundError = Class.new(StandardError)
def self.strip_storage_path(repo_path)
result = nil
Gitlab.config.repositories.storages.values.each do |params|
storage_path = params['path']
if repo_path.start_with?(storage_path)
result = repo_path.sub(storage_path, '')
break
end
end
if result.nil?
raise NotFoundError.new("No known storage path matches #{repo_path.inspect}")
end
result.sub(/\A\/*/, '')
end
end
end
require 'base64' require 'base64'
require 'json' require 'json'
require 'securerandom' require 'securerandom'
require 'uri'
module Gitlab module Gitlab
class Workhorse class Workhorse
...@@ -21,10 +22,10 @@ module Gitlab ...@@ -21,10 +22,10 @@ module Gitlab
RepoPath: repository.path_to_repo, RepoPath: repository.path_to_repo,
} }
params.merge!( if Gitlab.config.gitaly.enabled
GitalySocketPath: Gitlab.config.gitaly.socket_path, address = Gitlab::GitalyClient.get_address(repository.project.repository_storage)
GitalyResourcePath: "/projects/#{repository.project.id}/git-http/info-refs", params[:GitalySocketPath] = URI(address).path
) if Gitlab.config.gitaly.socket_path.present? end
params params
end end
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::GitalyClient::Notifications do describe Gitlab::GitalyClient::Notifications do
let(:client) { Gitlab::GitalyClient::Notifications.new }
before do
allow(Gitlab.config.gitaly).to receive(:socket_path).and_return('path/to/gitaly.socket')
end
describe '#post_receive' do describe '#post_receive' do
let(:repo_path) { '/path/to/my_repo.git' }
it 'sends a post_receive message' do it 'sends a post_receive message' do
repo_path = create(:empty_project).repository.path_to_repo
expect_any_instance_of(Gitaly::Notifications::Stub). expect_any_instance_of(Gitaly::Notifications::Stub).
to receive(:post_receive).with(post_receive_request_with_repo_path(repo_path)) to receive(:post_receive).with(post_receive_request_with_repo_path(repo_path))
client.post_receive(repo_path) described_class.new(repo_path).post_receive
end end
end end
end end
require 'spec_helper'
describe ::Gitlab::RepoPath do
describe '.strip_storage_path' do
before do
allow(Gitlab.config.repositories).to receive(:storages).and_return({
'storage1' => { 'path' => '/foo' },
'storage2' => { 'path' => '/bar' },
})
end
it 'strips the storage path' do
expect(described_class.strip_storage_path('/bar/foo/qux/baz.git')).to eq('foo/qux/baz.git')
end
it 'raises NotFoundError if no storage matches the path' do
expect { described_class.strip_storage_path('/doesnotexist/foo.git') }.to raise_error(
described_class::NotFoundError
)
end
end
end
...@@ -184,18 +184,14 @@ describe Gitlab::Workhorse, lib: true do ...@@ -184,18 +184,14 @@ describe Gitlab::Workhorse, lib: true do
it { expect(subject).to eq({ GL_ID: "user-#{user.id}", RepoPath: repository.path_to_repo }) } it { expect(subject).to eq({ GL_ID: "user-#{user.id}", RepoPath: repository.path_to_repo }) }
context 'when Gitaly socket path is present' do context 'when Gitaly is enabled' do
let(:gitaly_socket_path) { '/tmp/gitaly.sock' }
before do before do
allow(Gitlab.config.gitaly).to receive(:socket_path).and_return(gitaly_socket_path) allow(Gitlab.config.gitaly).to receive(:enabled).and_return(true)
end end
it 'includes Gitaly params in the returned value' do it 'includes Gitaly params in the returned value' do
expect(subject).to include({ gitaly_socket_path = URI(Gitlab::GitalyClient.get_address('default')).path
GitalyResourcePath: "/projects/#{repository.project.id}/git-http/info-refs", expect(subject).to include({ GitalySocketPath: gitaly_socket_path })
GitalySocketPath: gitaly_socket_path,
})
end end
end end
end end
......
...@@ -424,12 +424,12 @@ describe API::Internal, api: true do ...@@ -424,12 +424,12 @@ describe API::Internal, api: true do
end end
before do before do
allow(Gitlab.config.gitaly).to receive(:socket_path).and_return('path/to/gitaly.socket') allow(Gitlab.config.gitaly).to receive(:enabled).and_return(true)
end end
it "calls the Gitaly client if it's enabled" do it "calls the Gitaly client if it's enabled" do
expect_any_instance_of(Gitlab::GitalyClient::Notifications). expect_any_instance_of(Gitlab::GitalyClient::Notifications).
to receive(:post_receive).with(project.repository.path) to receive(:post_receive)
post api("/internal/notify_post_receive"), valid_params post api("/internal/notify_post_receive"), valid_params
...@@ -438,7 +438,7 @@ describe API::Internal, api: true do ...@@ -438,7 +438,7 @@ describe API::Internal, api: true do
it "returns 500 if the gitaly call fails" do it "returns 500 if the gitaly call fails" do
expect_any_instance_of(Gitlab::GitalyClient::Notifications). expect_any_instance_of(Gitlab::GitalyClient::Notifications).
to receive(:post_receive).with(project.repository.path).and_raise(GRPC::Unavailable) to receive(:post_receive).and_raise(GRPC::Unavailable)
post api("/internal/notify_post_receive"), valid_params post api("/internal/notify_post_receive"), valid_params
......
...@@ -81,6 +81,10 @@ describe 'gitlab:app namespace rake task' do ...@@ -81,6 +81,10 @@ describe 'gitlab:app namespace rake task' do
end # backup_restore task end # backup_restore task
describe 'backup' do describe 'backup' do
before(:all) do
ENV['force'] = 'yes'
end
def tars_glob def tars_glob
Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar')) Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar'))
end end
...@@ -88,6 +92,9 @@ describe 'gitlab:app namespace rake task' do ...@@ -88,6 +92,9 @@ describe 'gitlab:app namespace rake task' do
def create_backup def create_backup
FileUtils.rm tars_glob FileUtils.rm tars_glob
# This reconnect makes our project fixture disappear, breaking the restore. Stub it out.
allow(ActiveRecord::Base.connection).to receive(:reconnect!)
# Redirect STDOUT and run the rake task # Redirect STDOUT and run the rake task
orig_stdout = $stdout orig_stdout = $stdout
$stdout = StringIO.new $stdout = StringIO.new
...@@ -119,9 +126,6 @@ describe 'gitlab:app namespace rake task' do ...@@ -119,9 +126,6 @@ describe 'gitlab:app namespace rake task' do
FileUtils.mkdir_p(path) FileUtils.mkdir_p(path)
FileUtils.touch(File.join(path, "dummy.txt")) FileUtils.touch(File.join(path, "dummy.txt"))
# We need to use the full path instead of the relative one
allow(Gitlab.config.gitlab_shell).to receive(:path).and_return(File.expand_path(Gitlab.config.gitlab_shell.path, Rails.root.to_s))
ENV["SKIP"] = "db" ENV["SKIP"] = "db"
create_backup create_backup
end end
...@@ -227,8 +231,8 @@ describe 'gitlab:app namespace rake task' do ...@@ -227,8 +231,8 @@ describe 'gitlab:app namespace rake task' do
FileUtils.mkdir('tmp/tests/default_storage') FileUtils.mkdir('tmp/tests/default_storage')
FileUtils.mkdir('tmp/tests/custom_storage') FileUtils.mkdir('tmp/tests/custom_storage')
storages = { storages = {
'default' => { 'path' => 'tmp/tests/default_storage' }, 'default' => { 'path' => Settings.absolute('tmp/tests/default_storage') },
'custom' => { 'path' => 'tmp/tests/custom_storage' } 'custom' => { 'path' => Settings.absolute('tmp/tests/custom_storage') }
} }
allow(Gitlab.config.repositories).to receive(:storages).and_return(storages) allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
......
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