Commit 15b602ab authored by Valery Sizov's avatar Valery Sizov

Merge branch 'es_application_settings' into 'master'

ES settings in the ApplicationSetting



See merge request !359
parents 648424a4 756f9624
...@@ -7,6 +7,7 @@ v 8.9.0 (unreleased) ...@@ -7,6 +7,7 @@ v 8.9.0 (unreleased)
- Instrument instance methods of Gitlab::InsecureKeyFingerprint class - Instrument instance methods of Gitlab::InsecureKeyFingerprint class
- Add API endpoint for Merge Request Approvals !449 - Add API endpoint for Merge Request Approvals !449
- Distribute RepositoryUpdateMirror jobs in time and add exclusive lease on them by project_id - Distribute RepositoryUpdateMirror jobs in time and add exclusive lease on them by project_id
- [Elastic] Move ES settings to application settings
v 8.8.5 v 8.8.5
- Make sure OAuth routes that we generate for Geo matches with the ones in Rails routes !444 - Make sure OAuth routes that we generate for Geo matches with the ones in Rails routes !444
......
...@@ -42,6 +42,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -42,6 +42,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
def application_setting_params def application_setting_params
restricted_levels = params[:application_setting][:restricted_visibility_levels] restricted_levels = params[:application_setting][:restricted_visibility_levels]
if restricted_levels.nil? if restricted_levels.nil?
params[:application_setting][:restricted_visibility_levels] = [] params[:application_setting][:restricted_visibility_levels] = []
else else
...@@ -51,6 +52,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -51,6 +52,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
end end
import_sources = params[:application_setting][:import_sources] import_sources = params[:application_setting][:import_sources]
if import_sources.nil? if import_sources.nil?
params[:application_setting][:import_sources] = [] params[:application_setting][:import_sources] = []
else else
...@@ -111,6 +113,10 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -111,6 +113,10 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_packet_size, :metrics_packet_size,
:send_user_confirmation_email, :send_user_confirmation_email,
:container_registry_token_expire_delay, :container_registry_token_expire_delay,
:elasticsearch_indexing,
:elasticsearch_search,
:elasticsearch_host,
:elasticsearch_port,
restricted_visibility_levels: [], restricted_visibility_levels: [],
import_sources: [], import_sources: [],
disabled_oauth_sign_in_sources: [] disabled_oauth_sign_in_sources: []
......
...@@ -55,6 +55,14 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -55,6 +55,14 @@ class ApplicationSetting < ActiveRecord::Base
presence: true, presence: true,
numericality: { only_integer: true, greater_than: 0 } numericality: { only_integer: true, greater_than: 0 }
validates :elasticsearch_host,
presence: { message: "can't be blank when indexing is enabled" },
if: :elasticsearch_indexing?
validates :elasticsearch_port,
presence: { message: "can't be blank when indexing is enabled" },
if: :elasticsearch_indexing?
validates_each :restricted_visibility_levels do |record, attr, value| validates_each :restricted_visibility_levels do |record, attr, value|
unless value.nil? unless value.nil?
value.each do |level| value.each do |level|
...@@ -134,9 +142,15 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -134,9 +142,15 @@ class ApplicationSetting < ActiveRecord::Base
disabled_oauth_sign_in_sources: [], disabled_oauth_sign_in_sources: [],
send_user_confirmation_email: false, send_user_confirmation_email: false,
container_registry_token_expire_delay: 5, container_registry_token_expire_delay: 5,
elasticsearch_host: ENV['ELASTIC_HOST'] || 'localhost',
elasticsearch_port: ENV['ELASTIC_PORT'] || '9200'
) )
end end
def elasticsearch_host
read_attribute(:elasticsearch_host).split(',').map(&:strip)
end
def home_page_url_column_exist def home_page_url_column_exist
ActiveRecord::Base.connection.column_exists?(:application_settings, :home_page_url) ActiveRecord::Base.connection.column_exists?(:application_settings, :home_page_url)
end end
......
module Elastic module Elastic
module ApplicationSearch module ApplicationSearch
extend ActiveSupport::Concern extend ActiveSupport::Concern
extend Gitlab::CurrentSettings
included do included do
include Elasticsearch::Model include Elasticsearch::Model
self.__elasticsearch__.client = Elasticsearch::Client.new(
host: Gitlab.config.elasticsearch.host,
port: Gitlab.config.elasticsearch.port
)
index_name [Rails.application.class.parent_name.downcase, self.name.downcase, Rails.env].join('-') index_name [Rails.application.class.parent_name.downcase, self.name.downcase, Rails.env].join('-')
settings \ settings \
...@@ -31,13 +27,13 @@ module Elastic ...@@ -31,13 +27,13 @@ module Elastic
} }
after_commit on: :create do after_commit on: :create do
if Gitlab.config.elasticsearch.enabled && self.searchable? if current_application_settings.elasticsearch_indexing? && self.searchable?
ElasticIndexerWorker.perform_async(:index, self.class.to_s, self.id) ElasticIndexerWorker.perform_async(:index, self.class.to_s, self.id)
end end
end end
after_commit on: :update do after_commit on: :update do
if Gitlab.config.elasticsearch.enabled && self.searchable? if current_application_settings.elasticsearch_indexing? && self.searchable?
ElasticIndexerWorker.perform_async( ElasticIndexerWorker.perform_async(
:update, :update,
self.class.to_s, self.class.to_s,
...@@ -48,12 +44,12 @@ module Elastic ...@@ -48,12 +44,12 @@ module Elastic
end end
after_commit on: :destroy do after_commit on: :destroy do
if Gitlab.config.elasticsearch.enabled && self.searchable? if current_application_settings.elasticsearch_indexing? && self.searchable?
ElasticIndexerWorker.perform_async(:delete, self.class.to_s, self.id) ElasticIndexerWorker.perform_async(:delete, self.class.to_s, self.id)
end end
end end
# Should be overridden in the models where not eveything should be indexed # Should be overridden in the models where some records should be skipped
def searchable? def searchable?
true true
end end
......
...@@ -5,11 +5,6 @@ module Elastic ...@@ -5,11 +5,6 @@ module Elastic
included do included do
include Elasticsearch::Git::Repository include Elasticsearch::Git::Repository
self.__elasticsearch__.client = Elasticsearch::Client.new(
host: Gitlab.config.elasticsearch.host,
port: Gitlab.config.elasticsearch.port
)
def repository_id def repository_id
project.id project.id
end end
......
...@@ -5,11 +5,6 @@ module Elastic ...@@ -5,11 +5,6 @@ module Elastic
included do included do
include Elasticsearch::Git::Repository include Elasticsearch::Git::Repository
self.__elasticsearch__.client = Elasticsearch::Client.new(
host: Gitlab.config.elasticsearch.host,
port: Gitlab.config.elasticsearch.port
)
def repository_id def repository_id
"wiki_#{project.id}" "wiki_#{project.id}"
end end
......
...@@ -229,7 +229,7 @@ class Project < ActiveRecord::Base ...@@ -229,7 +229,7 @@ class Project < ActiveRecord::Base
project.save project.save
end end
if Gitlab.config.elasticsearch.enabled if current_application_settings.elasticsearch_indexing?
project.repository.index_blobs project.repository.index_blobs
project.repository.index_commits project.repository.index_commits
end end
......
class ProjectWiki class ProjectWiki
include Gitlab::ShellAdapter include Gitlab::ShellAdapter
include Elastic::WikiRepositoriesSearch include Elastic::WikiRepositoriesSearch
include Gitlab::CurrentSettings
MARKUPS = { MARKUPS = {
'Markdown' => :markdown, 'Markdown' => :markdown,
...@@ -193,6 +194,6 @@ class ProjectWiki ...@@ -193,6 +194,6 @@ class ProjectWiki
end end
def update_elastic_index def update_elastic_index
index_blobs if Gitlab.config.elasticsearch.enabled index_blobs if current_application_settings.elasticsearch_indexing?
end end
end end
...@@ -74,7 +74,7 @@ class GitPushService < BaseService ...@@ -74,7 +74,7 @@ class GitPushService < BaseService
CreateCommitBuildsService.new.execute(@project, current_user, build_push_data, mirror_update: mirror_update) CreateCommitBuildsService.new.execute(@project, current_user, build_push_data, mirror_update: mirror_update)
ProjectCacheWorker.perform_async(@project.id) ProjectCacheWorker.perform_async(@project.id)
index_commits_blobs if Gitlab.config.elasticsearch.enabled index_commits_blobs if current_application_settings.elasticsearch_indexing?
end end
def index_commits_blobs def index_commits_blobs
......
module Search module Search
class GlobalService class GlobalService
include Gitlab::CurrentSettings
attr_accessor :current_user, :params attr_accessor :current_user, :params
def initialize(user, params) def initialize(user, params)
...@@ -11,7 +13,7 @@ module Search ...@@ -11,7 +13,7 @@ module Search
projects = ProjectsFinder.new.execute(current_user) projects = ProjectsFinder.new.execute(current_user)
projects = projects.in_namespace(group.id) if group projects = projects.in_namespace(group.id) if group
if Gitlab.config.elasticsearch.enabled if current_application_settings.elasticsearch_search?
Gitlab::Elastic::SearchResults.new(current_user, projects.pluck(:id), params[:search]) Gitlab::Elastic::SearchResults.new(current_user, projects.pluck(:id), params[:search])
else else
Gitlab::SearchResults.new(current_user, projects, params[:search]) Gitlab::SearchResults.new(current_user, projects, params[:search])
......
module Search module Search
class ProjectService class ProjectService
include Gitlab::CurrentSettings
attr_accessor :project, :current_user, :params attr_accessor :project, :current_user, :params
def initialize(project, user, params) def initialize(project, user, params)
...@@ -7,7 +9,7 @@ module Search ...@@ -7,7 +9,7 @@ module Search
end end
def execute def execute
if Gitlab.config.elasticsearch.enabled if current_application_settings.elasticsearch_search?
Gitlab::Elastic::ProjectSearchResults.new(current_user, Gitlab::Elastic::ProjectSearchResults.new(current_user,
project.id, project.id,
params[:search], params[:search],
......
module Search module Search
class SnippetService class SnippetService
include Gitlab::CurrentSettings
attr_accessor :current_user, :params attr_accessor :current_user, :params
def initialize(user, params) def initialize(user, params)
...@@ -7,7 +8,7 @@ module Search ...@@ -7,7 +8,7 @@ module Search
end end
def execute def execute
if Gitlab.config.elasticsearch.enabled if current_application_settings.elasticsearch_search?
Gitlab::Elastic::SnippetSearchResults.new(current_user, Gitlab::Elastic::SnippetSearchResults.new(current_user,
params[:search]) params[:search])
else else
......
...@@ -340,6 +340,34 @@ ...@@ -340,6 +340,34 @@
.help-block .help-block
If you got a lot of false alarms from repository checks you can choose to clear all repository check information from the database. If you got a lot of false alarms from repository checks you can choose to clear all repository check information from the database.
%fieldset
%legend Elasticsearch
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :elasticsearch_indexing do
= f.check_box :elasticsearch_indexing
Elasticsearch indexing
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :elasticsearch_search do
= f.check_box :elasticsearch_search
Search with Elasticsearch enabled
.form-group
= f.label :elasticsearch_host, 'Host', class: 'control-label col-sm-2'
.col-sm-10
= f.text_field :elasticsearch_host, value: @application_setting.elasticsearch_host.join(', '), class: 'form-control', placeholder: 'localhost'
.help-block
The TCP/IP host to use for connecting to Elasticsearch. Use a comma-separated list to support clustering (e.g., "host1, host2").
.form-group
= f.label :elasticsearch_port, 'Port', class: 'control-label col-sm-2'
.col-sm-10
= f.text_field :elasticsearch_port, class: 'form-control', placeholder: ApplicationSetting.current.elasticsearch_port
.form-actions .form-actions
= f.submit 'Save', class: 'btn btn-save' = f.submit 'Save', class: 'btn btn-save'
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
%p %p
Elasticsearch Elasticsearch
%span.light.pull-right %span.light.pull-right
= boolean_to_icon Gitlab.config.elasticsearch.enabled = boolean_to_icon current_application_settings.elasticsearch_search?
%p %p
Geo Geo
%span.light.pull-right %span.light.pull-right
......
class ElasticIndexerWorker class ElasticIndexerWorker
include Sidekiq::Worker include Sidekiq::Worker
include Elasticsearch::Model::Client::ClassMethods
sidekiq_options queue: :elasticsearch sidekiq_options queue: :elasticsearch
ISSUE_TRACKED_FIELDS = %w(assignee_id author_id confidential) ISSUE_TRACKED_FIELDS = %w(assignee_id author_id confidential)
Client = Elasticsearch::Client.new(host: Gitlab.config.elasticsearch.host,
port: Gitlab.config.elasticsearch.port)
def perform(operation, class_name, record_id, options = {}) def perform(operation, class_name, record_id, options = {})
klass = class_name.constantize klass = class_name.constantize
case operation.to_s case operation.to_s
when /index|update/ when /index|update/
record = klass.find(record_id) record = klass.find(record_id)
record.__elasticsearch__.client = Client record.__elasticsearch__.client = client
record.__elasticsearch__.__send__ "#{operation}_document" record.__elasticsearch__.__send__ "#{operation}_document"
update_issue_notes(record, options["changed_fields"]) if klass == Issue update_issue_notes(record, options["changed_fields"]) if klass == Issue
when /delete/ when /delete/
Client.delete index: klass.index_name, type: klass.document_type, id: record_id client.delete index: klass.index_name, type: klass.document_type, id: record_id
clear_project_indexes(record_id) if klass == Project clear_project_indexes(record_id) if klass == Project
end end
...@@ -35,7 +33,7 @@ class ElasticIndexerWorker ...@@ -35,7 +33,7 @@ class ElasticIndexerWorker
def clear_project_indexes(record_id) def clear_project_indexes(record_id)
# Remove repository index # Remove repository index
Client.delete_by_query({ client.delete_by_query({
index: Repository.__elasticsearch__.index_name, index: Repository.__elasticsearch__.index_name,
body: { body: {
query: { query: {
......
class PostReceive class PostReceive
include Sidekiq::Worker include Sidekiq::Worker
extend Gitlab::CurrentSettings
sidekiq_options queue: :post_receive sidekiq_options queue: :post_receive
...@@ -50,7 +51,7 @@ class PostReceive ...@@ -50,7 +51,7 @@ class PostReceive
end end
def update_wiki_es_indexes(post_received) def update_wiki_es_indexes(post_received)
return unless Gitlab.config.elasticsearch.enabled return unless current_application_settings.elasticsearch_indexing?
post_received.project.wiki.index_blobs post_received.project.wiki.index_blobs
end end
......
...@@ -150,14 +150,6 @@ production: &base ...@@ -150,14 +150,6 @@ production: &base
# The location where LFS objects are stored (default: shared/lfs-objects). # The location where LFS objects are stored (default: shared/lfs-objects).
# storage_path: shared/lfs-objects # storage_path: shared/lfs-objects
## Elasticsearch (EE only)
# Enable it if you are going to use elasticsearch instead of
# regular database search
elasticsearch:
enabled: false
# host: localhost
# port: 9200
## GitLab Pages ## GitLab Pages
pages: pages:
enabled: false enabled: false
......
# Be sure to restart your server when you modify this file.
require 'gitlab/current_settings'
module Elasticsearch
module Model
module Client
module ClassMethods
include Gitlab::CurrentSettings
def client(client = nil)
if @client.nil? || es_configuration_changed?
@es_host = current_application_settings.elasticsearch_host
@es_port = current_application_settings.elasticsearch_port
@client = Elasticsearch::Client.new(
host: current_application_settings.elasticsearch_host,
port: current_application_settings.elasticsearch_port
)
end
@client
end
def es_configuration_changed?
@es_host != current_application_settings.elasticsearch_host ||
@es_port != current_application_settings.elasticsearch_port
end
end
end
end
end
class AddEsToApplicationSettings < ActiveRecord::Migration
def up
add_column :application_settings, :elasticsearch_indexing, :boolean, default: false, null: false
add_column :application_settings, :elasticsearch_search, :boolean, default: false, null: false
add_column :application_settings, :elasticsearch_host, :string, default: 'localhost'
add_column :application_settings, :elasticsearch_port, :string, default: '9200'
es_enabled = Settings.elasticsearch['enabled']
es_host = Settings.elasticsearch['host']
es_host = es_host.join(',') if es_host.is_a?(Array)
es_port = Settings.elasticsearch['port']
execute <<-SQL.strip_heredoc
UPDATE application_settings
SET
elasticsearch_indexing = #{es_enabled},
elasticsearch_search = #{es_enabled},
elasticsearch_host = '#{es_host}',
elasticsearch_port = '#{es_port}'
SQL
end
def down
remove_column :application_settings, :elasticsearch_indexing
remove_column :application_settings, :elasticsearch_search
remove_column :application_settings, :elasticsearch_host
remove_column :application_settings, :elasticsearch_port
end
end
...@@ -88,6 +88,10 @@ ActiveRecord::Schema.define(version: 20160615142710) do ...@@ -88,6 +88,10 @@ ActiveRecord::Schema.define(version: 20160615142710) do
t.boolean "send_user_confirmation_email", default: false t.boolean "send_user_confirmation_email", default: false
t.integer "container_registry_token_expire_delay", default: 5 t.integer "container_registry_token_expire_delay", default: 5
t.text "after_sign_up_text" t.text "after_sign_up_text"
t.boolean "elasticsearch_indexing", default: false, null: false
t.boolean "elasticsearch_search", default: false, null: false
t.string "elasticsearch_host", default: "localhost"
t.string "elasticsearch_port", default: "9200"
end end
create_table "approvals", force: :cascade do |t| create_table "approvals", force: :cascade do |t|
......
...@@ -22,7 +22,7 @@ searching in: ...@@ -22,7 +22,7 @@ searching in:
- snippets - snippets
- wiki repositories - wiki repositories
Once the data is added to the database, search indexes will be updated Once the data is added to the database or repository, search indexes will be updated
automatically. Elasticsearch can be installed on the same machine that GitLab automatically. Elasticsearch can be installed on the same machine that GitLab
is installed or on a separate server. is installed or on a separate server.
...@@ -45,63 +45,34 @@ use the packages that are available for your OS. ...@@ -45,63 +45,34 @@ use the packages that are available for your OS.
## Enable Elasticsearch ## Enable Elasticsearch
In order to enable Elasticsearch you need to have access to the server that In order to enable Elasticsearch you need to have access to the server that GitLab is hosted on, and an administrator account on your GitLab instance. Go to **Admin > Settings** and find the "Elasticsearch" section.
GitLab is hosted on.
The following three parameters are needed to enable Elasticsearch: The following Elasticsearch settings are available:
| Parameter | Description | | Parameter | Description |
| --------- | ----------- | | --------- | ----------- |
| `enabled` | Enables/disables the Elasticsearch integration. Can be either `true` or `false` | | `Elasticsearch indexing` | Enables/disables Elasticsearch indexing. You may want to enable indexing but disable search in order to give the index time to be fully completed, for example. |
| `host` | The host where Elasticsearch is installed on. Can be either an IP or a domain name which correctly resolves to an IP. It can be changed in the [Elasticsearch configuration settings][elastic-settings]. The default value is `localhost` | | `Search with Elasticsearch enabled` | Enables/disables using Elasticsearch in search. |
| `port` | The TCP port that Elasticsearch listens to. It can be changed in the [Elasticsearch configuration settings][elastic-settings]. The default value is `9200` | | `Host` | The TCP/IP host to use for connecting to Elasticsearch. Use a comma-separated list to support clustering (e.g., "host1, host2"). |
| `Port` | The TCP port that Elasticsearch listens to. The default value is 9200 |
### Enable Elasticsearch in Omnibus installations
If you have used one of the [Omnibus packages][pkg] to install GitLab, all ## Add GitLab's data to the Elasticsearch index
you have to do is edit `/etc/gitlab/gitlab.rb` and add the following lines:
```ruby
gitlab_rails['elasticsearch_enabled'] = true
gitlab_rails['elasticsearch_host'] = "localhost"
gitlab_rails['elasticsearch_port'] = 9200
```
Replace the values as you see fit according to the
[settings table above](#enable-elasticsearch).
Save the file and reconfigure GitLab for the changes to take effect:
`sudo gitlab-ctl reconfigure`.
As a last step, move on to
[add GitLab's data to the Elasticsearch index](#add-gitlabs-data-to-the-elasticsearch-index).
### Enable Elasticsearch in source installations
If you have installed GitLab from source, edit `/home/git/gitlab/config/gitlab.yml`:
```yaml Configure Elasticsearch's host and port in **Admin > Settings**. Then create empty indexes using one of the following commands:
elasticsearch:
enabled: true
host: localhost
port: 9200
```
Replace the values as you see fit according to the
[settings table above](#enable-elasticsearch).
Save the file and restart GitLab for the changes to take effect: ```
`sudo service gitlab restart`. # Omnibus installations
sudo gitlab-rake gitlab:elastic:create_empty_indexes
As a last step, move on to # Installations from source
[add GitLab's data to the Elasticsearch index](#add-gitlabs-data-to-the-elasticsearch-index). bundle exec rake gitlab:elastic:create_empty_indexes
```
## Add GitLab's data to the Elasticsearch index
After [enabling Elasticsearch](#enable-elasticsearch), you must run the
following rake tasks to add GitLab's data to the Elasticsearch index.
It might take a while depending on how big your Git repositories are (see Then enable Elasticsearch indexing and run indexing tasks. It might take a while depending on how big your Git repositories are (see
[Indexing large repositories](#indexing-large-repositories)). [Indexing large repositories](#indexing-large-repositories)).
--- ---
...@@ -167,7 +138,8 @@ sudo gitlab-rake gitlab:elastic:index_database ...@@ -167,7 +138,8 @@ sudo gitlab-rake gitlab:elastic:index_database
# Installations from source # Installations from source
bundle exec rake gitlab:elastic:index_database RAILS_ENV=production bundle exec rake gitlab:elastic:index_database RAILS_ENV=production
``` ```
To index all available entities:
Or everything at once (database records, repositories, wikis):
``` ```
# Omnibus installations # Omnibus installations
...@@ -179,10 +151,7 @@ bundle exec rake gitlab:elastic:index RAILS_ENV=production ...@@ -179,10 +151,7 @@ bundle exec rake gitlab:elastic:index RAILS_ENV=production
## Disable Elasticsearch ## Disable Elasticsearch
Disabling the Elasticsearch integration is as easy as setting `enabled` to Disabling the Elasticsearch integration is as easy as unchecking `Search with Elasticsearch enabled` and `Elasticsearch indexing` in **Admin > Settings**.
`false` in your GitLab settings. See [Enable Elasticsearch](#enable-elasticsearch)
to find where those settings are and don't forget to reconfigure/restart GitLab
for the changes to take effect.
## Special recommendations ## Special recommendations
...@@ -241,8 +210,7 @@ time drop. ...@@ -241,8 +210,7 @@ time drop.
To minimize downtime of the search feature we recommend the following: To minimize downtime of the search feature we recommend the following:
1. Configure Elasticsearch in `gitlab.yml`, or `gitlab.rb` for Omnibus 1. Configure Elasticsearch in **Admin > Settings**, but do not enable it, just set a host and port.
installations, but do not enable it, just set a host and port.
1. Create empty indexes: 1. Create empty indexes:
...@@ -257,7 +225,7 @@ To minimize downtime of the search feature we recommend the following: ...@@ -257,7 +225,7 @@ To minimize downtime of the search feature we recommend the following:
1. Index all repositories using the `gitlab:elastic:index_repositories` Rake 1. Index all repositories using the `gitlab:elastic:index_repositories` Rake
task (see above). You'll probably want to do this in parallel. task (see above). You'll probably want to do this in parallel.
1. Enable Elasticsearch and restart GitLab. Note that once enabled the index will be updated when new data is pushed to the GitLab server. 1. Enable Elasticsearch indexing.
1. Run indexers for database (with the `UPDATE_INDEX=1` parameter), wikis, and 1. Run indexers for database (with the `UPDATE_INDEX=1` parameter), wikis, and
repositories. By running the repository indexer twice you will be sure that repositories. By running the repository indexer twice you will be sure that
......
require Rails.root.join('spec', 'support', 'stub_configuration')
class Spinach::Features::GlobalSearch < Spinach::FeatureSteps class Spinach::Features::GlobalSearch < Spinach::FeatureSteps
include SharedAuthentication include SharedAuthentication
include SharedPaths include SharedPaths
include SharedProject include SharedProject
include SharedElastic include SharedElastic
include StubConfiguration
before do before do
[::Project, Issue, MergeRequest, Milestone].each do |model| [::Project, Issue, MergeRequest, Milestone].each do |model|
...@@ -15,7 +18,7 @@ class Spinach::Features::GlobalSearch < Spinach::FeatureSteps ...@@ -15,7 +18,7 @@ class Spinach::Features::GlobalSearch < Spinach::FeatureSteps
model.__elasticsearch__.delete_index! model.__elasticsearch__.delete_index!
end end
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
step 'project has all data available for the search' do step 'project has all data available for the search' do
......
...@@ -3,6 +3,7 @@ class Spinach::Features::ProjectSearch < Spinach::FeatureSteps ...@@ -3,6 +3,7 @@ class Spinach::Features::ProjectSearch < Spinach::FeatureSteps
include SharedPaths include SharedPaths
include SharedProject include SharedProject
include SharedElastic include SharedElastic
include StubConfiguration
before do before do
[::Project, Repository, Note, MergeRequest, Milestone, ::ProjectWiki, Issue].each do |model| [::Project, Repository, Note, MergeRequest, Milestone, ::ProjectWiki, Issue].each do |model|
...@@ -15,7 +16,7 @@ class Spinach::Features::ProjectSearch < Spinach::FeatureSteps ...@@ -15,7 +16,7 @@ class Spinach::Features::ProjectSearch < Spinach::FeatureSteps
model.__elasticsearch__.delete_index! model.__elasticsearch__.delete_index!
end end
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
step 'project has all data available for the search' do step 'project has all data available for the search' do
......
...@@ -3,6 +3,7 @@ class Spinach::Features::SnippetsSearch < Spinach::FeatureSteps ...@@ -3,6 +3,7 @@ class Spinach::Features::SnippetsSearch < Spinach::FeatureSteps
include SharedPaths include SharedPaths
include SharedProject include SharedProject
include SharedElastic include SharedElastic
include StubConfiguration
before do before do
Snippet.__elasticsearch__.create_index! Snippet.__elasticsearch__.create_index!
...@@ -11,7 +12,7 @@ class Spinach::Features::SnippetsSearch < Spinach::FeatureSteps ...@@ -11,7 +12,7 @@ class Spinach::Features::SnippetsSearch < Spinach::FeatureSteps
after do after do
Snippet.__elasticsearch__.delete_index! Snippet.__elasticsearch__.delete_index!
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
step 'there is a snippet "index" with "php rocks" string' do step 'there is a snippet "index" with "php rocks" string' do
......
...@@ -25,7 +25,7 @@ module SharedElastic ...@@ -25,7 +25,7 @@ module SharedElastic
end end
step 'Elasticsearch is enabled' do step 'Elasticsearch is enabled' do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
end end
def select_filter(name) def select_filter(name)
......
...@@ -44,6 +44,10 @@ module Gitlab ...@@ -44,6 +44,10 @@ module Gitlab
akismet_enabled: false, akismet_enabled: false,
repository_checks_enabled: true, repository_checks_enabled: true,
container_registry_token_expire_delay: 5, container_registry_token_expire_delay: 5,
elasticsearch_search: false,
elasticsearch_indexing: false,
elasticsearch_host: ENV['ELASTIC_HOST'] || 'localhost',
elasticsearch_port: ENV['ELASTIC_PORT'] || '9200'
) )
end end
......
module Gitlab module Gitlab
module Elastic module Elastic
class Indexer class Indexer
include Gitlab::CurrentSettings
Error = Class.new(StandardError) Error = Class.new(StandardError)
def initialize def initialize
connection_info = { connection_info = {
host: Gitlab.config.elasticsearch.host, host: current_application_settings.elasticsearch_host,
port: Gitlab.config.elasticsearch.port port: current_application_settings.elasticsearch_port
}.to_json }.to_json
# We accept any form of settings, including string and array # We accept any form of settings, including string and array
......
...@@ -30,7 +30,7 @@ namespace :gitlab do ...@@ -30,7 +30,7 @@ namespace :gitlab do
check_ruby_version check_ruby_version
check_git_version check_git_version
check_active_users check_active_users
check_elasticsearch if Gitlab.config.elasticsearch.enabled check_elasticsearch if ApplicationSetting.current.elasticsearch_indexing?
finished_checking "GitLab" finished_checking "GitLab"
end end
...@@ -972,8 +972,8 @@ namespace :gitlab do ...@@ -972,8 +972,8 @@ namespace :gitlab do
end end
def check_elasticsearch def check_elasticsearch
client = Elasticsearch::Client.new(host: Gitlab.config.elasticsearch.host, client = Elasticsearch::Client.new(host: ApplicationSetting.current.elasticsearch_host,
port: Gitlab.config.elasticsearch.port) port: ApplicationSetting.current.elasticsearch_port)
print "Elasticsearch version >= 2.0? ... " print "Elasticsearch version >= 2.0? ... "
......
...@@ -2,13 +2,14 @@ require 'spec_helper' ...@@ -2,13 +2,14 @@ require 'spec_helper'
describe "Indexer" do describe "Indexer" do
it "runs commands" do it "runs commands" do
stub_application_setting(es_host: ['elastic-host1', 'elastic-host2'])
expect(Gitlab::Popen).to receive(:popen).with( expect(Gitlab::Popen).to receive(:popen).with(
[File.join(Rails.root, 'bin/elastic_repo_indexer'), '1', 'full_repo_path'], [File.join(Rails.root, 'bin/elastic_repo_indexer'), '1', 'full_repo_path'],
nil, nil,
hash_including( hash_including(
'ELASTIC_CONNECTION_INFO' => { 'ELASTIC_CONNECTION_INFO' => {
host: Gitlab.config.elasticsearch.host, host: ApplicationSetting.current.elasticsearch_host,
port: Gitlab.config.elasticsearch.port port: ApplicationSetting.current.elasticsearch_port
}.to_json, }.to_json,
'RAILS_ENV' => Rails.env, 'RAILS_ENV' => Rails.env,
'FROM_SHA' => '000000', 'FROM_SHA' => '000000',
......
...@@ -6,13 +6,13 @@ describe Gitlab::Elastic::ProjectSearchResults, lib: true do ...@@ -6,13 +6,13 @@ describe Gitlab::Elastic::ProjectSearchResults, lib: true do
let(:query) { 'hello world' } let(:query) { 'hello world' }
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
Project.__elasticsearch__.create_index! Project.__elasticsearch__.create_index!
Issue.__elasticsearch__.create_index! Issue.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
Project.__elasticsearch__.delete_index! Project.__elasticsearch__.delete_index!
Issue.__elasticsearch__.delete_index! Issue.__elasticsearch__.delete_index!
end end
......
require 'spec_helper' require 'spec_helper'
describe "Issue", elastic: true do describe Issue, elastic: true do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
Issue.__elasticsearch__.create_index! described_class.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) described_class.__elasticsearch__.delete_index!
Issue.__elasticsearch__.delete_index! stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "searches issues" do it "searches issues" do
...@@ -21,11 +21,11 @@ describe "Issue", elastic: true do ...@@ -21,11 +21,11 @@ describe "Issue", elastic: true do
# The issue I have no access to # The issue I have no access to
create :issue, title: 'bla-bla term' create :issue, title: 'bla-bla term'
Issue.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
options = { project_ids: [project.id] } options = { project_ids: [project.id] }
expect(Issue.elastic_search('term', options: options).total_count).to eq(2) expect(described_class.elastic_search('term', options: options).total_count).to eq(2)
end end
it "returns json with all needed elements" do it "returns json with all needed elements" do
......
require 'spec_helper' require 'spec_helper'
describe "MergeRequest", elastic: true do describe MergeRequest, elastic: true do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
MergeRequest.__elasticsearch__.create_index! described_class.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) described_class.__elasticsearch__.delete_index!
MergeRequest.__elasticsearch__.delete_index! stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "searches merge requests" do it "searches merge requests" do
...@@ -21,11 +21,11 @@ describe "MergeRequest", elastic: true do ...@@ -21,11 +21,11 @@ describe "MergeRequest", elastic: true do
# The merge request you have no access to # The merge request you have no access to
create :merge_request, title: 'also with term' create :merge_request, title: 'also with term'
MergeRequest.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
options = { project_ids: [project.id] } options = { project_ids: [project.id] }
expect(MergeRequest.elastic_search('term', options: options).total_count).to eq(2) expect(described_class.elastic_search('term', options: options).total_count).to eq(2)
end end
it "returns json with all needed elements" do it "returns json with all needed elements" do
......
require 'spec_helper' require 'spec_helper'
describe "Milestone", elastic: true do describe Milestone, elastic: true do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
Milestone.__elasticsearch__.create_index! described_class.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) described_class.__elasticsearch__.delete_index!
Milestone.__elasticsearch__.delete_index! stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "searches milestones" do it "searches milestones" do
...@@ -21,11 +21,11 @@ describe "Milestone", elastic: true do ...@@ -21,11 +21,11 @@ describe "Milestone", elastic: true do
# The milestone you have no access to # The milestone you have no access to
create :milestone, title: 'bla-bla term' create :milestone, title: 'bla-bla term'
Milestone.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
options = { project_ids: [project.id] } options = { project_ids: [project.id] }
expect(Milestone.elastic_search('term', options: options).total_count).to eq(2) expect(described_class.elastic_search('term', options: options).total_count).to eq(2)
end end
it "returns json with all needed elements" do it "returns json with all needed elements" do
......
require 'spec_helper' require 'spec_helper'
describe "Note", elastic: true do describe Note, elastic: true do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
Note.__elasticsearch__.create_index! described_class.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) described_class.__elasticsearch__.delete_index!
Note.__elasticsearch__.delete_index! stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "searches notes" do it "searches notes" do
...@@ -20,11 +20,11 @@ describe "Note", elastic: true do ...@@ -20,11 +20,11 @@ describe "Note", elastic: true do
# The note in the project you have no access to # The note in the project you have no access to
create :note, note: 'bla-bla term' create :note, note: 'bla-bla term'
Note.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
options = { project_ids: [issue.project.id] } options = { project_ids: [issue.project.id] }
expect(Note.elastic_search('term', options: options).total_count).to eq(1) expect(described_class.elastic_search('term', options: options).total_count).to eq(1)
end end
it "returns json with all needed elements" do it "returns json with all needed elements" do
......
require 'spec_helper' require 'spec_helper'
describe "Projects", elastic: true do describe Project, elastic: true do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
Project.__elasticsearch__.create_index! described_class.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) described_class.__elasticsearch__.delete_index!
Project.__elasticsearch__.delete_index! stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "searches projects" do it "searches projects" do
...@@ -18,11 +18,11 @@ describe "Projects", elastic: true do ...@@ -18,11 +18,11 @@ describe "Projects", elastic: true do
create :empty_project, path: 'someone_elses_project' create :empty_project, path: 'someone_elses_project'
project_ids = [project.id, project1.id, project2.id] project_ids = [project.id, project1.id, project2.id]
Project.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
expect(Project.elastic_search('test', options: { pids: project_ids }).total_count).to eq(1) expect(described_class.elastic_search('test', options: { pids: project_ids }).total_count).to eq(1)
expect(Project.elastic_search('test1', options: { pids: project_ids }).total_count).to eq(1) expect(described_class.elastic_search('test1', options: { pids: project_ids }).total_count).to eq(1)
expect(Project.elastic_search('someone_elses_project', options: { pids: project_ids }).total_count).to eq(0) expect(described_class.elastic_search('someone_elses_project', options: { pids: project_ids }).total_count).to eq(0)
end end
it "returns json with all needed elements" do it "returns json with all needed elements" do
......
require 'spec_helper' require 'spec_helper'
describe "Repository", elastic: true do describe Repository, elastic: true do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
Repository.__elasticsearch__.create_index! described_class.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) described_class.__elasticsearch__.delete_index!
Repository.__elasticsearch__.delete_index! stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "searches blobs and commits" do it "searches blobs and commits" do
...@@ -17,7 +17,7 @@ describe "Repository", elastic: true do ...@@ -17,7 +17,7 @@ describe "Repository", elastic: true do
project.repository.index_blobs project.repository.index_blobs
project.repository.index_commits project.repository.index_commits
Repository.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
expect(project.repository.search('def popen')[:blobs][:total_count]).to eq(1) expect(project.repository.search('def popen')[:blobs][:total_count]).to eq(1)
expect(project.repository.search('initial')[:commits][:total_count]).to eq(1) expect(project.repository.search('initial')[:commits][:total_count]).to eq(1)
......
require 'spec_helper' require 'spec_helper'
describe "Snippet", elastic: true do describe Snippet, elastic: true do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
Snippet.__elasticsearch__.create_index! described_class.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) described_class.__elasticsearch__.delete_index!
Snippet.__elasticsearch__.delete_index! stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "searches snippets by code" do it "searches snippets by code" do
...@@ -20,11 +20,11 @@ describe "Snippet", elastic: true do ...@@ -20,11 +20,11 @@ describe "Snippet", elastic: true do
snippet3 = create :personal_snippet, :public, content: 'genius code' snippet3 = create :personal_snippet, :public, content: 'genius code'
Snippet.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
options = { author_id: user.id } options = { author_id: user.id }
result = Snippet.elastic_search_code('genius code', options: options) result = described_class.elastic_search_code('genius code', options: options)
expect(result.total_count).to eq(2) expect(result.total_count).to eq(2)
expect(result.records.map(&:id)).to include(snippet.id, snippet3.id) expect(result.records.map(&:id)).to include(snippet.id, snippet3.id)
...@@ -38,12 +38,12 @@ describe "Snippet", elastic: true do ...@@ -38,12 +38,12 @@ describe "Snippet", elastic: true do
create :snippet, :public, file_name: 'index.php' create :snippet, :public, file_name: 'index.php'
create :snippet create :snippet
Snippet.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
options = { author_id: user.id } options = { author_id: user.id }
expect(Snippet.elastic_search('home', options: options).total_count).to eq(1) expect(described_class.elastic_search('home', options: options).total_count).to eq(1)
expect(Snippet.elastic_search('index.php', options: options).total_count).to eq(1) expect(described_class.elastic_search('index.php', options: options).total_count).to eq(1)
end end
it "returns json with all needed elements" do it "returns json with all needed elements" do
......
require 'spec_helper' require 'spec_helper'
describe "ProjectWiki", elastic: true do describe ProjectWiki, elastic: true do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
ProjectWiki.__elasticsearch__.create_index! described_class.__elasticsearch__.create_index!
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) described_class.__elasticsearch__.delete_index!
ProjectWiki.__elasticsearch__.delete_index! stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "searches wiki page" do it "searches wiki page" do
...@@ -18,7 +18,7 @@ describe "ProjectWiki", elastic: true do ...@@ -18,7 +18,7 @@ describe "ProjectWiki", elastic: true do
project.wiki.index_blobs project.wiki.index_blobs
ProjectWiki.__elasticsearch__.refresh_index! described_class.__elasticsearch__.refresh_index!
expect(project.wiki.search('bla', type: :blob)[:blobs][:total_count]).to eq(1) expect(project.wiki.search('bla', type: :blob)[:blobs][:total_count]).to eq(1)
end end
......
...@@ -800,11 +800,13 @@ describe Repository, models: true do ...@@ -800,11 +800,13 @@ describe Repository, models: true do
describe "Elastic search", elastic: true do describe "Elastic search", elastic: true do
before do before do
stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
Repository.__elasticsearch__.create_index! Repository.__elasticsearch__.create_index!
end end
after do after do
Repository.__elasticsearch__.delete_index! Repository.__elasticsearch__.delete_index!
stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
describe :find_commits_by_message_with_elastic do describe :find_commits_by_message_with_elastic do
......
...@@ -139,11 +139,11 @@ describe GitPushService, services: true do ...@@ -139,11 +139,11 @@ describe GitPushService, services: true do
describe "ES indexing" do describe "ES indexing" do
before do before do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
end end
after do after do
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) stub_application_setting(elasticsearch_search: false, elasticsearch_indexing: false)
end end
it "triggers indexer" do it "triggers indexer" do
......
...@@ -75,7 +75,7 @@ describe PostReceive do ...@@ -75,7 +75,7 @@ describe PostReceive do
it "triggers wiki index update" do it "triggers wiki index update" do
expect(Project).to receive(:find_with_namespace).with("#{project.path_with_namespace}.wiki").and_return(nil) expect(Project).to receive(:find_with_namespace).with("#{project.path_with_namespace}.wiki").and_return(nil)
expect(Project).to receive(:find_with_namespace).with(project.path_with_namespace).and_return(project) expect(Project).to receive(:find_with_namespace).with(project.path_with_namespace).and_return(project)
allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) stub_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
expect_any_instance_of(ProjectWiki).to receive(:index_blobs) expect_any_instance_of(ProjectWiki).to receive(:index_blobs)
repo_path = "#{pwd(project)}.wiki" repo_path = "#{pwd(project)}.wiki"
......
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