Commit 1c5876eb7b2deb069d919bd19b51c9f6218e0f41

Authored by Dmitriy Zaporozhets
1 parent b4f16faa

Do gitolite calls async. Remove satellite with project remove

Procfile
1 1 web: bundle exec unicorn_rails -p $PORT
2   -worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default
  2 +worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitolite
... ...
app/contexts/projects/create_context.rb
... ... @@ -32,16 +32,10 @@ module Projects
32 32 @project.namespace_id = current_user.namespace_id
33 33 end
34 34  
35   - Project.transaction do
36   - @project.creator = current_user
37   - @project.save!
  35 + @project.creator = current_user
38 36  
39   - # Add user as project master
40   - @project.users_projects.create!(project_access: UsersProject::MASTER, user: current_user)
41   -
42   - # when project saved no team member exist so
43   - # project repository should be updated after first user add
44   - @project.update_repository
  37 + if @project.save
  38 + @project.users_projects.create(project_access: UsersProject::MASTER, user: current_user)
45 39 end
46 40  
47 41 @project
... ...
app/models/project.rb
... ... @@ -299,6 +299,9 @@ class Project < ActiveRecord::Base
299 299 def trigger_post_receive(oldrev, newrev, ref, user)
300 300 data = post_receive_data(oldrev, newrev, ref, user)
301 301  
  302 + # Create satellite
  303 + self.satellite.create unless self.satellite.exists?
  304 +
302 305 # Create push event
303 306 self.observe_push(data)
304 307  
... ... @@ -313,9 +316,6 @@ class Project < ActiveRecord::Base
313 316 self.execute_services(data.dup)
314 317 end
315 318  
316   - # Create satellite
317   - self.satellite.create unless self.satellite.exists?
318   -
319 319 # Discover the default branch, but only if it hasn't already been set to
320 320 # something else
321 321 if repository && default_branch.nil?
... ... @@ -460,11 +460,17 @@ class Project < ActiveRecord::Base
460 460 end
461 461  
462 462 def update_repository
463   - gitolite.update_repository(self)
  463 + GitoliteWorker.perform_async(
  464 + :update_repository,
  465 + self.id
  466 + )
464 467 end
465 468  
466 469 def destroy_repository
467   - gitolite.remove_repository(self)
  470 + GitoliteWorker.perform_async(
  471 + :remove_repository,
  472 + self.path_with_namespace
  473 + )
468 474 end
469 475  
470 476 def repo_exists?
... ...
app/models/users_project.rb
... ... @@ -129,7 +129,7 @@ class UsersProject < ActiveRecord::Base
129 129 end
130 130  
131 131 def update_repository
132   - gitolite.update_repository(project)
  132 + project.update_repository
133 133 end
134 134  
135 135 def project_access_human
... ...
app/observers/project_observer.rb
... ... @@ -10,6 +10,7 @@ class ProjectObserver < ActiveRecord::Observer
10 10 def after_destroy(project)
11 11 log_info("Project \"#{project.name}\" was removed")
12 12  
  13 + project.satellite.destroy
13 14 project.destroy_repository
14 15 end
15 16  
... ...
app/workers/gitolite_worker.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +class GitoliteWorker
  2 + include Sidekiq::Worker
  3 + include Gitolited
  4 +
  5 + sidekiq_options queue: :gitolite
  6 +
  7 + def perform(action, arg)
  8 + gitolite.send(action, arg)
  9 + end
  10 +end
... ...
app/workers/post_receive.rb
... ... @@ -13,13 +13,14 @@ class PostReceive
13 13  
14 14 # Ignore push from non-gitlab users
15 15 user = if identifier.eql? Gitlab.config.gitolite.admin_key
16   - email = project.repository.commit(newrev).author.email rescue nil
17   - User.find_by_email(email) if email
18   - elsif /^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier)
19   - User.find_by_email(identifier)
20   - else
21   - Key.find_by_identifier(identifier).try(:user)
22   - end
  16 + email = project.repository.commit(newrev).author.email rescue nil
  17 + User.find_by_email(email) if email
  18 + elsif /^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier)
  19 + User.find_by_email(identifier)
  20 + else
  21 + Key.find_by_identifier(identifier).try(:user)
  22 + end
  23 +
23 24 return false unless user
24 25  
25 26 project.trigger_post_receive(oldrev, newrev, ref, user)
... ...
lib/gitlab/backend/gitolite.rb
... ... @@ -22,7 +22,8 @@ module Gitlab
22 22 end
23 23 end
24 24  
25   - def update_repository project
  25 + def update_repository project_id
  26 + project = Project.find(project_id)
26 27 config.update_project!(project)
27 28 end
28 29  
... ... @@ -33,8 +34,15 @@ module Gitlab
33 34 end
34 35 end
35 36  
36   - def remove_repository project
37   - config.destroy_project!(project)
  37 + # Remove repository from gitolite
  38 + #
  39 + # name - project path with namespace
  40 + #
  41 + # Ex.
  42 + # remove_repository("gitlab/gitlab-ci")
  43 + #
  44 + def remove_repository(name)
  45 + config.destroy_project!(name)
38 46 end
39 47  
40 48 def url_to_repo path
... ...
lib/gitlab/backend/gitolite_config.rb
... ... @@ -4,6 +4,8 @@ require 'fileutils'
4 4  
5 5 module Gitlab
6 6 class GitoliteConfig
  7 + include Gitlab::Popen
  8 +
7 9 class PullError < StandardError; end
8 10 class PushError < StandardError; end
9 11 class BrokenGitolite < StandardError; end
... ... @@ -87,12 +89,14 @@ module Gitlab
87 89 Gitlab::GitLogger.error(message)
88 90 end
89 91  
90   - def destroy_project(project)
91   - # do rm-rf only if repository exists
92   - if project.repository
93   - FileUtils.rm_rf(project.repository.path_to_repo)
94   - end
95   - conf.rm_repo(project.path_with_namespace)
  92 + def path_to_repo(name)
  93 + File.join(Gitlab.config.gitolite.repos_path, "#{name}.git")
  94 + end
  95 +
  96 + def destroy_project(name)
  97 + full_path = path_to_repo(name)
  98 + FileUtils.rm_rf(full_path) if File.exists?(full_path)
  99 + conf.rm_repo(name)
96 100 end
97 101  
98 102 def clean_repo repo_name
... ... @@ -210,14 +214,14 @@ module Gitlab
210 214 end
211 215  
212 216 def push
213   - output, status = popen('git add -A')
  217 + output, status = popen('git add -A', tmp_conf_path)
214 218 raise "Git add failed." unless status.zero?
215 219  
216 220 # git commit returns 0 on success, and 1 if there is nothing to commit
217   - output, status = popen('git commit -m "GitLab"')
  221 + output, status = popen('git commit -m "GitLab"', tmp_conf_path)
218 222 raise "Git add failed." unless [0,1].include?(status)
219 223  
220   - output, status = popen('git push')
  224 + output, status = popen('git push', tmp_conf_path)
221 225  
222 226 if output =~ /remote\: FATAL/
223 227 raise BrokenGitolite, output
... ... @@ -230,20 +234,8 @@ module Gitlab
230 234 end
231 235 end
232 236  
233   - def popen(cmd, path = nil)
234   - path ||= File.join(config_tmp_dir,'gitolite')
235   - vars = { "PWD" => path }
236   - options = { :chdir => path }
237   -
238   - @cmd_output = ""
239   - @cmd_status = 0
240   - Open3.popen3(vars, cmd, options) do |stdin, stdout, stderr, wait_thr|
241   - @cmd_status = wait_thr.value.exitstatus
242   - @cmd_output << stdout.read
243   - @cmd_output << stderr.read
244   - end
245   -
246   - return @cmd_output, @cmd_status
  237 + def tmp_conf_path
  238 + File.join(config_tmp_dir,'gitolite')
247 239 end
248 240 end
249 241 end
... ...
lib/gitlab/popen.rb 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +module Gitlab
  2 + module Popen
  3 + def popen(cmd, path)
  4 + vars = { "PWD" => path }
  5 + options = { :chdir => path }
  6 +
  7 + @cmd_output = ""
  8 + @cmd_status = 0
  9 + Open3.popen3(vars, cmd, options) do |stdin, stdout, stderr, wait_thr|
  10 + @cmd_status = wait_thr.value.exitstatus
  11 + @cmd_output << stdout.read
  12 + @cmd_output << stderr.read
  13 + end
  14 +
  15 + return @cmd_output, @cmd_status
  16 + end
  17 + end
  18 +end
... ...
lib/gitlab/satellite/satellite.rb
... ... @@ -3,6 +3,8 @@ module Gitlab
3 3  
4 4 module Satellite
5 5 class Satellite
  6 + include Gitlab::Popen
  7 +
6 8 PARKING_BRANCH = "__parking_branch"
7 9  
8 10 attr_accessor :project
... ... @@ -24,8 +26,10 @@ module Gitlab
24 26 end
25 27  
26 28 def create
27   - create_cmd = "git clone #{project.url_to_repo} #{path}"
28   - if system(create_cmd)
  29 + output, status = popen("git clone #{project.url_to_repo} #{path}",
  30 + Gitlab.config.satellites.path)
  31 +
  32 + if status.zero?
29 33 true
30 34 else
31 35 Gitlab::GitLogger.error("Failed to create satellite for #{project.name_with_namespace}")
... ... @@ -66,6 +70,10 @@ module Gitlab
66 70 @repo ||= Grit::Repo.new(path)
67 71 end
68 72  
  73 + def destroy
  74 + FileUtils.rm_rf(path)
  75 + end
  76 +
69 77 private
70 78  
71 79 # Clear the working directory
... ...
lib/tasks/sidekiq.rake
... ... @@ -6,7 +6,7 @@ namespace :sidekiq do
6 6  
7 7 desc "GITLAB | Start sidekiq"
8 8 task :start do
9   - run "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default -e #{Rails.env} -P #{pidfile} >> #{Rails.root.join("log", "sidekiq.log")} 2>&1 &"
  9 + run "nohup bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitolite,common,default -e #{Rails.env} -P #{pidfile} >> #{Rails.root.join("log", "sidekiq.log")} 2>&1 &"
10 10 end
11 11  
12 12 def pidfile
... ...