2 desc "GITLAB | Check the configuration of GitLab and its environment"
3 task check: %w{gitlab:env:check
11 desc "GITLAB | Check the configuration of the GitLab Rails app"
12 task check: :environment do
13 warn_user_is_not_gitlab
14 start_checking "GitLab"
16 check_database_config_exists
17 check_database_is_not_sqlite
18 check_migrations_are_up
19 check_gitlab_config_exists
20 check_gitlab_config_not_outdated
23 check_init_script_exists
24 check_init_script_up_to_date
25 check_satellites_exist
27 finished_checking "GitLab"
32 ########################
34 def check_database_config_exists
35 print "Database config exists? ... "
37 database_config_file = Rails.root.join("config", "database.yml")
39 if File.exists?(database_config_file)
44 "Copy config/database.yml.<your db> to config/database.yml",
45 "Check that the information in config/database.yml is correct"
49 "http://guides.rubyonrails.org/getting_started.html#configuring-a-database"
55 def check_database_is_not_sqlite
56 print "Database is SQLite ... "
58 database_config_file = Rails.root.join("config", "database.yml")
60 unless File.read(database_config_file) =~ /adapter:\s+sqlite/
65 "https://github.com/gitlabhq/gitlabhq/wiki/Migrate-from-SQLite-to-MySQL",
72 def check_gitlab_config_exists
73 print "GitLab config exists? ... "
75 gitlab_config_file = Rails.root.join("config", "gitlab.yml")
77 if File.exists?(gitlab_config_file)
82 "Copy config/gitlab.yml.example to config/gitlab.yml",
83 "Update config/gitlab.yml to match your setup"
86 see_installation_guide_section "GitLab"
92 def check_gitlab_config_not_outdated
93 print "GitLab config outdated? ... "
95 gitlab_config_file = Rails.root.join("config", "gitlab.yml")
96 unless File.exists?(gitlab_config_file)
97 puts "can't check because of previous errors".magenta
100 # omniauth or ldap could have been deleted from the file
101 unless Gitlab.config['git_host']
106 "Backup your config/gitlab.yml",
107 "Copy config/gitlab.yml.example to config/gitlab.yml",
108 "Update config/gitlab.yml to match your setup"
110 for_more_information(
111 see_installation_guide_section "GitLab"
117 def check_init_script_exists
118 print "Init script exists? ... "
120 script_path = "/etc/init.d/gitlab"
122 if File.exists?(script_path)
127 "Install the init script"
129 for_more_information(
130 see_installation_guide_section "Install Init Script"
136 def check_init_script_up_to_date
137 print "Init script up-to-date? ... "
139 script_path = "/etc/init.d/gitlab"
140 unless File.exists?(script_path)
141 puts "can't check because of previous errors".magenta
145 recipe_content = `curl https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab 2>/dev/null`
146 script_content = File.read(script_path)
148 if recipe_content == script_content
153 "Redownload the init script"
155 for_more_information(
156 see_installation_guide_section "Install Init Script"
162 def check_migrations_are_up
163 print "All migrations up? ... "
165 migration_status = `bundle exec rake db:migrate:status`
167 unless migration_status =~ /down\s+\d{14}/
172 "sudo -u gitlab -H bundle exec rake db:migrate"
178 def check_satellites_exist
179 print "Projects have satellites? ... "
181 unless Project.count > 0
182 puts "can't check, you have no projects".magenta
187 Project.find_each(batch_size: 100) do |project|
188 print "#{project.name_with_namespace.yellow} ... "
190 if project.satellite.exists?
192 elsif project.empty_repo?
193 puts "can't create, repository is empty".magenta
197 "sudo -u gitlab -H bundle exec rake gitlab:satellites:create",
198 "If necessary, remove the tmp/repo_satellites directory ...",
199 "... and rerun the above command"
201 for_more_information(
202 "doc/raketasks/maintenance.md "
209 def check_log_writable
210 print "Log directory writable? ... "
212 log_path = Rails.root.join("log")
214 if File.writable?(log_path)
219 "sudo chown -R gitlab #{log_path}",
220 "sudo chmod -R rwX #{log_path}"
222 for_more_information(
223 see_installation_guide_section "GitLab"
229 def check_tmp_writable
230 print "Tmp directory writable? ... "
232 tmp_path = Rails.root.join("tmp")
234 if File.writable?(tmp_path)
239 "sudo chown -R gitlab #{tmp_path}",
240 "sudo chmod -R rwX #{tmp_path}"
242 for_more_information(
243 see_installation_guide_section "GitLab"
253 desc "GITLAB | Check the configuration of the environment"
254 task check: :environment do
255 warn_user_is_not_gitlab
256 start_checking "Environment"
258 check_gitlab_in_git_group
259 check_issue_1059_shell_profile_error
260 check_gitlab_git_config
262 check_python2_version
264 finished_checking "Environment"
269 ########################
271 def check_gitlab_git_config
272 print "Git configured for gitlab user? ... "
275 "user.name" => "GitLab",
276 "user.email" => Gitlab.config.gitlab.email_from
278 correct_options = options.map do |name, value|
279 run("git config --global --get #{name}").try(:squish) == value
282 if correct_options.all?
287 "sudo -u gitlab -H git config --global user.name \"#{options["user.name"]}\"",
288 "sudo -u gitlab -H git config --global user.email \"#{options["user.email"]}\""
290 for_more_information(
291 see_installation_guide_section "GitLab"
297 def check_gitlab_in_git_group
298 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
299 print "gitlab user is in #{gitolite_ssh_user} group? ... "
301 if run_and_match("id -rnG", /\Wgit\W/)
306 "sudo usermod -a -G #{gitolite_ssh_user} gitlab"
308 for_more_information(
309 see_installation_guide_section "System Users"
315 # see https://github.com/gitlabhq/gitlabhq/issues/1059
316 def check_issue_1059_shell_profile_error
317 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
318 print "Has no \"-e\" in ~#{gitolite_ssh_user}/.profile ... "
320 profile_file = File.join(gitolite_home, ".profile")
322 unless File.read(profile_file) =~ /^-e PATH/
327 "Open #{profile_file}",
328 "Find the line starting with \"-e PATH\"",
329 "Remove \"-e \" so the line starts with PATH"
331 for_more_information(
332 see_installation_guide_section("Gitolite"),
333 "https://github.com/gitlabhq/gitlabhq/issues/1059"
339 def check_python2_exists
340 print "Has python2? ... "
342 # Python prints its version to STDERR
343 # so we can't just use run("python2 --version")
344 if run_and_match("which python2", /python2$/)
349 "Make sure you have Python 2.5+ installed",
352 for_more_information(
353 see_installation_guide_section "Packages / Dependencies"
359 def check_python2_version
360 print "python2 is supported version? ... "
362 # Python prints its version to STDERR
363 # so we can't just use run("python2 --version")
365 unless run_and_match("which python2", /python2$/)
366 puts "can't check because of previous errors".magenta
370 if `python2 --version 2>&1` =~ /2\.[567]\.\d/
375 "Make sure you have Python 2.5+ installed",
378 for_more_information(
379 see_installation_guide_section "Packages / Dependencies"
388 namespace :gitolite do
389 desc "GITLAB | Check the configuration of Gitolite"
390 task check: :environment do
391 warn_user_is_not_gitlab
392 start_checking "Gitolite"
394 check_gitolite_is_up_to_date
395 check_gitoliterc_repo_umask
396 check_gitoliterc_git_config_keys
397 check_dot_gitolite_exists
398 check_dot_gitolite_user_and_group
399 check_dot_gitolite_permissions
400 check_repo_base_exists
401 check_repo_base_is_not_symlink
402 check_repo_base_user_and_group
403 check_repo_base_permissions
404 check_can_clone_gitolite_admin
405 check_can_commit_to_gitolite_admin
406 check_post_receive_hook_exists
407 check_post_receive_hook_is_up_to_date
408 check_repos_post_receive_hooks_is_link
409 check_repos_git_config
411 finished_checking "Gitolite"
416 ########################
418 def check_can_clone_gitolite_admin
419 print "Can clone gitolite-admin? ... "
421 test_path = "/tmp/gitlab_gitolite_admin_test"
422 FileUtils.rm_rf(test_path)
423 `git clone -q #{Gitlab.config.gitolite.admin_uri} #{test_path}`
424 raise unless $?.success?
430 "Make sure the \"admin_uri\" is set correctly in config/gitlab.yml",
431 "Try cloning it yourself with:",
432 " git clone -q #{Gitlab.config.gitolite.admin_uri} /tmp/gitolite-admin",
433 "Make sure Gitolite is installed correctly."
435 for_more_information(
436 see_installation_guide_section "Gitolite"
441 # assumes #check_can_clone_gitolite_admin has been run before
442 def check_can_commit_to_gitolite_admin
443 print "Can commit to gitolite-admin? ... "
445 test_path = "/tmp/gitlab_gitolite_admin_test"
446 unless File.exists?(test_path)
447 puts "can't check because of previous errors".magenta
451 Dir.chdir(test_path) do
452 `touch foo && git add foo && git commit -qm foo`
453 raise unless $?.success?
460 "Try committing to it yourself with:",
461 " git clone -q #{Gitlab.config.gitolite.admin_uri} /tmp/gitolite-admin",
464 " git commit -m \"foo\"",
465 "Make sure Gitolite is installed correctly."
467 for_more_information(
468 see_installation_guide_section "Gitolite"
472 FileUtils.rm_rf("/tmp/gitolite_gitlab_test")
475 def check_dot_gitolite_exists
476 print "Config directory exists? ... "
478 gitolite_config_path = File.join(gitolite_home, ".gitolite")
480 if File.directory?(gitolite_config_path)
484 puts "#{gitolite_config_path} is missing".red
486 "This should have been created when setting up Gitolite.",
487 "Make sure Gitolite is installed correctly."
489 for_more_information(
490 see_installation_guide_section "Gitolite"
496 def check_dot_gitolite_permissions
497 print "Config directory access is drwxr-x---? ... "
499 gitolite_config_path = File.join(gitolite_home, ".gitolite")
500 unless File.exists?(gitolite_config_path)
501 puts "can't check because of previous errors".magenta
505 if `stat --printf %a #{gitolite_config_path}` == "750"
510 "sudo chmod 750 #{gitolite_config_path}"
512 for_more_information(
513 see_installation_guide_section "Gitolite"
519 def check_dot_gitolite_user_and_group
520 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
521 print "Config directory owned by #{gitolite_ssh_user}:#{gitolite_ssh_user} ... "
523 gitolite_config_path = File.join(gitolite_home, ".gitolite")
524 unless File.exists?(gitolite_config_path)
525 puts "can't check because of previous errors".magenta
529 if `stat --printf %U #{gitolite_config_path}` == gitolite_ssh_user && # user
530 `stat --printf %G #{gitolite_config_path}` == gitolite_ssh_user #group
534 puts "#{gitolite_config_path} is not owned by #{gitolite_ssh_user}".red
536 "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{gitolite_config_path}"
538 for_more_information(
539 see_installation_guide_section "Gitolite"
545 def check_gitolite_is_up_to_date
546 print "Using recommended version ... "
547 if gitolite_version.try(:start_with?, "v3.2")
552 "We strongly recommend using the version pointed out in the installation guide."
554 for_more_information(
555 see_installation_guide_section "Gitolite"
557 # this is not a "hard" failure
561 def check_gitoliterc_git_config_keys
562 gitoliterc_path = File.join(gitolite_home, ".gitolite.rc")
564 print "Allow all Git config keys in .gitolite.rc ... "
565 option_name = if has_gitolite3?
566 # see https://github.com/sitaramc/gitolite/blob/v3.04/src/lib/Gitolite/Rc.pm#L329
569 # assume older version
570 # see https://github.com/sitaramc/gitolite/blob/v2.3/conf/example.gitolite.rc#L49
574 if open(gitoliterc_path).grep(/#{option_name}\s*=[>]?\s*["']#{option_value}["']/).any?
579 "Open #{gitoliterc_path}",
580 "Find the \"#{option_name}\" option",
581 "Change its value to \".*\""
583 for_more_information(
584 see_installation_guide_section "Gitolite"
590 def check_gitoliterc_repo_umask
591 gitoliterc_path = File.join(gitolite_home, ".gitolite.rc")
593 print "Repo umask is 0007 in .gitolite.rc? ... "
594 option_name = if has_gitolite3?
595 # see https://github.com/sitaramc/gitolite/blob/v3.04/src/lib/Gitolite/Rc.pm#L328
598 # assume older version
599 # see https://github.com/sitaramc/gitolite/blob/v2.3/conf/example.gitolite.rc#L32
602 option_value = "0007"
603 if open(gitoliterc_path).grep(/#{option_name}\s*=[>]?\s*#{option_value}/).any?
608 "Open #{gitoliterc_path}",
609 "Find the \"#{option_name}\" option",
610 "Change its value to \"0007\""
612 for_more_information(
613 see_installation_guide_section "Gitolite"
619 def check_post_receive_hook_exists
620 print "post-receive hook exists? ... "
622 hook_file = "post-receive"
623 gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
624 gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
625 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
627 gitlab_hook_file = Rails.root.join.join("lib", "hooks", hook_file)
629 if File.exists?(gitolite_hook_file)
634 "sudo -u #{gitolite_ssh_user} cp #{gitlab_hook_file} #{gitolite_hook_file}"
636 for_more_information(
637 see_installation_guide_section "Setup GitLab Hooks"
643 def check_post_receive_hook_is_up_to_date
644 print "post-receive hook up-to-date? ... "
646 hook_file = "post-receive"
647 gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
648 gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
649 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
651 unless File.exists?(gitolite_hook_file)
652 puts "can't check because of previous errors".magenta
656 gitolite_hook_content = File.read(gitolite_hook_file)
657 gitlab_hook_file = Rails.root.join.join("lib", "hooks", hook_file)
658 gitlab_hook_content = File.read(gitlab_hook_file)
660 if gitolite_hook_content == gitlab_hook_content
665 "sudo -u #{gitolite_ssh_user} cp #{gitlab_hook_file} #{gitolite_hook_file}"
667 for_more_information(
668 see_installation_guide_section "Setup GitLab Hooks"
674 def check_repo_base_exists
675 print "Repo base directory exists? ... "
677 repo_base_path = Gitlab.config.gitolite.repos_path
679 if File.exists?(repo_base_path)
683 puts "#{repo_base_path} is missing".red
685 "This should have been created when setting up Gitolite.",
686 "Make sure it's set correctly in config/gitlab.yml",
687 "Make sure Gitolite is installed correctly."
689 for_more_information(
690 see_installation_guide_section "Gitolite"
696 def check_repo_base_is_not_symlink
697 print "Repo base directory is a symlink? ... "
699 repo_base_path = Gitlab.config.gitolite.repos_path
700 unless File.exists?(repo_base_path)
701 puts "can't check because of previous errors".magenta
705 unless File.symlink?(repo_base_path)
710 "Make sure it's set to the real directory in config/gitlab.yml"
716 def check_repo_base_permissions
717 print "Repo base access is drwsrws---? ... "
719 repo_base_path = Gitlab.config.gitolite.repos_path
720 unless File.exists?(repo_base_path)
721 puts "can't check because of previous errors".magenta
725 if `stat --printf %a #{repo_base_path}` == "6770"
729 puts "#{repo_base_path} is not writable".red
731 "sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}"
733 for_more_information(
734 see_installation_guide_section "Gitolite"
740 def check_repo_base_user_and_group
741 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
742 print "Repo base owned by #{gitolite_ssh_user}:#{gitolite_ssh_user}? ... "
744 repo_base_path = Gitlab.config.gitolite.repos_path
745 unless File.exists?(repo_base_path)
746 puts "can't check because of previous errors".magenta
750 if `stat --printf %U #{repo_base_path}` == gitolite_ssh_user && # user
751 `stat --printf %G #{repo_base_path}` == gitolite_ssh_user #group
755 puts "#{repo_base_path} is not owned by #{gitolite_ssh_user}".red
757 "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{repo_base_path}"
759 for_more_information(
760 see_installation_guide_section "Gitolite"
766 def check_repos_git_config
767 print "Git config in repos: ... "
769 unless Project.count > 0
770 puts "can't check, you have no projects".magenta
776 "core.sharedRepository" => "0660",
779 Project.find_each(batch_size: 100) do |project|
780 print "#{project.name_with_namespace.yellow} ... "
782 correct_options = options.map do |name, value|
783 run("git --git-dir=\"#{project.repository.path_to_repo}\" config --get #{name}").try(:chomp) == value
786 if correct_options.all?
789 puts "wrong or missing".red
791 "sudo -u gitlab -H bundle exec rake gitlab:gitolite:update_repos"
793 for_more_information(
794 "doc/raketasks/maintenance.md"
801 def check_repos_post_receive_hooks_is_link
802 print "post-receive hooks in repos are links: ... "
804 hook_file = "post-receive"
805 gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
806 gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
807 gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
809 unless File.exists?(gitolite_hook_file)
810 puts "can't check because of previous errors".magenta
814 unless Project.count > 0
815 puts "can't check, you have no projects".magenta
820 Project.find_each(batch_size: 100) do |project|
821 print "#{project.name_with_namespace.yellow} ... "
822 project_hook_file = File.join(project.repository.path_to_repo, "hooks", hook_file)
824 unless File.exists?(project_hook_file)
827 "sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}"
829 for_more_information(
830 "lib/support/rewrite-hooks.sh"
836 if run_and_match("stat --format %N #{project_hook_file}", /#{hook_file}.+->.+#{gitolite_hook_file}/)
839 puts "not a link to Gitolite's hook".red
841 "sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}"
843 for_more_information(
844 "lib/support/rewrite-hooks.sh"
853 ########################
856 File.expand_path("~#{Gitlab.config.gitolite.ssh_user}")
860 gitolite_version_file = "#{gitolite_home}/gitolite/src/VERSION"
861 if File.readable?(gitolite_version_file)
862 File.read(gitolite_version_file)
867 gitolite_version.try(:start_with?, "v3.")
874 desc "GITLAB | Check the configuration of Sidekiq"
875 task check: :environment do
876 warn_user_is_not_gitlab
877 start_checking "Resque"
881 finished_checking "Resque"
886 ########################
888 def check_resque_running
889 print "Running? ... "
891 if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d\.\d\.\d.+$/)
896 "sudo service gitlab restart",
898 "sudo /etc/init.d/gitlab restart"
900 for_more_information(
901 see_installation_guide_section("Install Init Script"),
902 "see log/sidekiq.log for possible errors"
911 ##########################
914 puts " Please #{"fix the error above"} and rerun the checks.".red
917 def for_more_information(*sources)
918 sources = sources.shift if sources.first.is_a?(Array)
920 puts " For more information see:".blue
921 sources.each do |source|
926 def finished_checking(component)
928 puts "Checking #{component.yellow} ... #{"Finished".green}"
932 def see_database_guide
933 "doc/install/databases.md"
936 def see_installation_guide_section(section)
937 "doc/install/installation.md in section \"#{section}\""
940 def start_checking(component)
941 puts "Checking #{component.yellow} ..."
945 def try_fixing_it(*steps)
946 steps = steps.shift if steps.first.is_a?(Array)
948 puts " Try fixing it:".blue