check.rake 20.3 KB
Newer Older
1
namespace :gitlab do
2 3
  desc "GITLAB | Check the configuration of GitLab and its environment"
  task check: %w{gitlab:env:check
4
                 gitlab:gitlab_shell:check
Riyad Preukschas's avatar
Riyad Preukschas committed
5
                 gitlab:sidekiq:check
Riyad Preukschas's avatar
Riyad Preukschas committed
6 7 8
                 gitlab:app:check}


9

10
  namespace :app do
11 12
    desc "GITLAB | Check the configuration of the GitLab Rails app"
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
13 14 15 16 17 18 19 20 21 22 23 24
      warn_user_is_not_gitlab
      start_checking "GitLab"

      check_database_config_exists
      check_database_is_not_sqlite
      check_migrations_are_up
      check_gitlab_config_exists
      check_gitlab_config_not_outdated
      check_log_writable
      check_tmp_writable
      check_init_script_exists
      check_init_script_up_to_date
Hiroyuki Sato's avatar
Hiroyuki Sato committed
25
      check_projects_have_namespace
Riyad Preukschas's avatar
Riyad Preukschas committed
26
      check_satellites_exist
27
      check_redis_version
28
      check_git_version
Riyad Preukschas's avatar
Riyad Preukschas committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

      finished_checking "GitLab"
    end


    # Checks
    ########################

    def check_database_config_exists
      print "Database config exists? ... "

      database_config_file = Rails.root.join("config", "database.yml")

      if File.exists?(database_config_file)
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
          "Copy config/database.yml.<your db> to config/database.yml",
          "Check that the information in config/database.yml is correct"
        )
        for_more_information(
          see_database_guide,
          "http://guides.rubyonrails.org/getting_started.html#configuring-a-database"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
54
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
55 56 57 58
      end
    end

    def check_database_is_not_sqlite
59
      print "Database is SQLite ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
60 61 62

      database_config_file = Rails.root.join("config", "database.yml")

63
      unless File.read(database_config_file) =~ /adapter:\s+sqlite/
64
        puts "no".green
Riyad Preukschas's avatar
Riyad Preukschas committed
65
      else
66
        puts "yes".red
Riyad Preukschas's avatar
Riyad Preukschas committed
67 68 69 70
        for_more_information(
          "https://github.com/gitlabhq/gitlabhq/wiki/Migrate-from-SQLite-to-MySQL",
          see_database_guide
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
71
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
      end
    end

    def check_gitlab_config_exists
      print "GitLab config exists? ... "

      gitlab_config_file = Rails.root.join("config", "gitlab.yml")

      if File.exists?(gitlab_config_file)
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
          "Copy config/gitlab.yml.example to config/gitlab.yml",
          "Update config/gitlab.yml to match your setup"
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
91
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
92 93 94 95
      end
    end

    def check_gitlab_config_not_outdated
Riyad Preukschas's avatar
Riyad Preukschas committed
96
      print "GitLab config outdated? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
97 98 99 100 101 102 103

      gitlab_config_file = Rails.root.join("config", "gitlab.yml")
      unless File.exists?(gitlab_config_file)
        puts "can't check because of previous errors".magenta
      end

      # omniauth or ldap could have been deleted from the file
104
      unless Gitlab.config['git_host']
Riyad Preukschas's avatar
Riyad Preukschas committed
105
        puts "no".green
Riyad Preukschas's avatar
Riyad Preukschas committed
106
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
107
        puts "yes".red
Riyad Preukschas's avatar
Riyad Preukschas committed
108
        try_fixing_it(
Riyad Preukschas's avatar
Riyad Preukschas committed
109
          "Backup your config/gitlab.yml",
Riyad Preukschas's avatar
Riyad Preukschas committed
110 111 112 113 114 115
          "Copy config/gitlab.yml.example to config/gitlab.yml",
          "Update config/gitlab.yml to match your setup"
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
116
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
117 118
      end
    end
119

Riyad Preukschas's avatar
Riyad Preukschas committed
120 121 122 123 124 125 126
    def check_init_script_exists
      print "Init script exists? ... "

      script_path = "/etc/init.d/gitlab"

      if File.exists?(script_path)
        puts "yes".green
Nihad Abbasov's avatar
Nihad Abbasov committed
127
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
128 129 130 131 132 133 134
        puts "no".red
        try_fixing_it(
          "Install the init script"
        )
        for_more_information(
          see_installation_guide_section "Install Init Script"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
135
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
136 137 138 139 140 141
      end
    end

    def check_init_script_up_to_date
      print "Init script up-to-date? ... "

142
      recipe_path = Rails.root.join("lib/support/init.d/", "gitlab")
Riyad Preukschas's avatar
Riyad Preukschas committed
143
      script_path = "/etc/init.d/gitlab"
144

Riyad Preukschas's avatar
Riyad Preukschas committed
145 146
      unless File.exists?(script_path)
        puts "can't check because of previous errors".magenta
147 148 149
        return
      end

150
      recipe_content = File.read(recipe_path)
Riyad Preukschas's avatar
Riyad Preukschas committed
151 152 153 154 155 156 157 158 159 160 161 162
      script_content = File.read(script_path)

      if recipe_content == script_content
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
          "Redownload the init script"
        )
        for_more_information(
          see_installation_guide_section "Install Init Script"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
163
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
164 165 166 167 168 169 170 171 172 173
      end
    end

    def check_migrations_are_up
      print "All migrations up? ... "

      migration_status =  `bundle exec rake db:migrate:status`

      unless migration_status =~ /down\s+\d{14}/
        puts "yes".green
174
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
175 176
        puts "no".red
        try_fixing_it(
177
          sudo_gitlab("bundle exec rake db:migrate RAILS_ENV=production")
Riyad Preukschas's avatar
Riyad Preukschas committed
178
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
179
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
180 181 182 183 184 185 186 187
      end
    end

    def check_satellites_exist
      print "Projects have satellites? ... "

      unless Project.count > 0
        puts "can't check, you have no projects".magenta
188 189
        return
      end
Riyad Preukschas's avatar
Riyad Preukschas committed
190 191 192
      puts ""

      Project.find_each(batch_size: 100) do |project|
193
        print "#{project.name_with_namespace.yellow} ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
194 195 196

        if project.satellite.exists?
          puts "yes".green
197 198
        elsif project.empty_repo?
          puts "can't create, repository is empty".magenta
Riyad Preukschas's avatar
Riyad Preukschas committed
199 200 201
        else
          puts "no".red
          try_fixing_it(
202
            sudo_gitlab("bundle exec rake gitlab:satellites:create RAILS_ENV=production"),
203 204
            "If necessary, remove the tmp/repo_satellites directory ...",
            "... and rerun the above command"
Riyad Preukschas's avatar
Riyad Preukschas committed
205 206 207 208
          )
          for_more_information(
            "doc/raketasks/maintenance.md "
          )
Riyad Preukschas's avatar
Riyad Preukschas committed
209
          fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
        end
      end
    end

    def check_log_writable
      print "Log directory writable? ... "

      log_path = Rails.root.join("log")

      if File.writable?(log_path)
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
          "sudo chown -R gitlab #{log_path}",
bassrock's avatar
bassrock committed
225
          "sudo chmod -R u+rwX #{log_path}"
Riyad Preukschas's avatar
Riyad Preukschas committed
226 227 228 229
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
230
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
231 232 233 234 235 236 237 238 239 240 241 242 243 244
      end
    end

    def check_tmp_writable
      print "Tmp directory writable? ... "

      tmp_path = Rails.root.join("tmp")

      if File.writable?(tmp_path)
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
          "sudo chown -R gitlab #{tmp_path}",
bassrock's avatar
bassrock committed
245
          "sudo chmod -R u+rwX #{tmp_path}"
Riyad Preukschas's avatar
Riyad Preukschas committed
246 247 248 249
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
250
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
251
      end
252
    end
253

254
    def check_redis_version
255 256
      print "Redis version >= 2.0.0? ... "

257 258
      if run_and_match("redis-cli --version", /redis-cli 2.\d.\d/)
        puts "yes".green
259
      else
260 261
        puts "no".red
        try_fixing_it(
262
          "Update your redis server to a version >= 2.0.0"
263 264 265 266 267 268
        )
        for_more_information(
          "gitlab-public-wiki/wiki/Trouble-Shooting-Guide in section sidekiq"
        )
        fix_and_rerun
      end
269
    end
270 271
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
272 273


274 275 276
  namespace :env do
    desc "GITLAB | Check the configuration of the environment"
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
      warn_user_is_not_gitlab
      start_checking "Environment"

      check_gitlab_git_config
      check_python2_exists
      check_python2_version

      finished_checking "Environment"
    end


    # Checks
    ########################

    def check_gitlab_git_config
292
      print "Git configured for #{gitlab_user} user? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
293 294 295

      options = {
        "user.name"  => "GitLab",
296
        "user.email" => Gitlab.config.gitlab.email_from
Riyad Preukschas's avatar
Riyad Preukschas committed
297 298 299 300 301 302 303 304 305 306
      }
      correct_options = options.map do |name, value|
        run("git config --global --get #{name}").try(:squish) == value
      end

      if correct_options.all?
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
307 308
          sudo_gitlab("git config --global user.name  \"#{options["user.name"]}\""),
          sudo_gitlab("git config --global user.email \"#{options["user.email"]}\"")
Riyad Preukschas's avatar
Riyad Preukschas committed
309 310 311 312
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
313
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
      end
    end

    def check_python2_exists
      print "Has python2? ... "

      # Python prints its version to STDERR
      # so we can't just use run("python2 --version")
      if run_and_match("which python2", /python2$/)
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
          "Make sure you have Python 2.5+ installed",
          "Link it to python2"
        )
        for_more_information(
          see_installation_guide_section "Packages / Dependencies"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
333
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
      end
    end

    def check_python2_version
      print "python2 is supported version? ... "

      # Python prints its version to STDERR
      # so we can't just use run("python2 --version")

      unless run_and_match("which python2", /python2$/)
        puts "can't check because of previous errors".magenta
        return
      end

      if `python2 --version 2>&1` =~ /2\.[567]\.\d/
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
          "Make sure you have Python 2.5+ installed",
          "Link it to python2"
        )
        for_more_information(
          see_installation_guide_section "Packages / Dependencies"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
359
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
360
      end
361 362 363
    end
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
364 365


366
  namespace :gitlab_shell do
Ben Bodenmiller's avatar
Ben Bodenmiller committed
367
    desc "GITLAB | Check the configuration of GitLab Shell"
368
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
369
      warn_user_is_not_gitlab
Ben Bodenmiller's avatar
Ben Bodenmiller committed
370
      start_checking "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
371

372
      check_gitlab_shell
Riyad Preukschas's avatar
Riyad Preukschas committed
373
      check_repo_base_exists
374
      check_repo_base_is_not_symlink
Riyad Preukschas's avatar
Riyad Preukschas committed
375 376
      check_repo_base_user_and_group
      check_repo_base_permissions
377 378
      check_update_hook_is_up_to_date
      check_repos_update_hooks_is_link
379
      check_gitlab_shell_self_test
Riyad Preukschas's avatar
Riyad Preukschas committed
380

Ben Bodenmiller's avatar
Ben Bodenmiller committed
381
      finished_checking "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
382 383 384 385 386 387 388
    end


    # Checks
    ########################


389 390
    def check_update_hook_is_up_to_date
      print "update hook up-to-date? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
391

392
      hook_file = "update"
393
      gitlab_shell_hooks_path = Gitlab.config.gitlab_shell.hooks_path
394
      gitlab_shell_hook_file  = File.join(gitlab_shell_hooks_path, hook_file)
Riyad Preukschas's avatar
Riyad Preukschas committed
395

396 397 398 399 400 401 402 403 404 405 406 407
      if File.exists?(gitlab_shell_hook_file)
        puts "yes".green
      else
        puts "no".red
        puts "Could not find #{gitlab_shell_hook_file}"
        try_fixing_it(
          'Check the hooks_path in config/gitlab.yml',
          'Check your gitlab-shell installation'
        )
        for_more_information(
          see_installation_guide_section "GitLab Shell"
        )
408
      end
Riyad Preukschas's avatar
Riyad Preukschas committed
409 410 411 412 413
    end

    def check_repo_base_exists
      print "Repo base directory exists? ... "

414
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
Riyad Preukschas's avatar
Riyad Preukschas committed
415 416 417 418 419 420 421

      if File.exists?(repo_base_path)
        puts "yes".green
      else
        puts "no".red
        puts "#{repo_base_path} is missing".red
        try_fixing_it(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
422
          "This should have been created when setting up GitLab Shell.",
Riyad Preukschas's avatar
Riyad Preukschas committed
423
          "Make sure it's set correctly in config/gitlab.yml",
Ben Bodenmiller's avatar
Ben Bodenmiller committed
424
          "Make sure GitLab Shell is installed correctly."
Riyad Preukschas's avatar
Riyad Preukschas committed
425 426
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
427
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
428
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
429
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
430 431 432
      end
    end

433 434 435
    def check_repo_base_is_not_symlink
      print "Repo base directory is a symlink? ... "

436
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
      unless File.exists?(repo_base_path)
        puts "can't check because of previous errors".magenta
        return
      end

      unless File.symlink?(repo_base_path)
        puts "no".green
      else
        puts "yes".red
        try_fixing_it(
          "Make sure it's set to the real directory in config/gitlab.yml"
        )
        fix_and_rerun
      end
    end

Riyad Preukschas's avatar
Riyad Preukschas committed
453
    def check_repo_base_permissions
454
      print "Repo base access is drwxrws---? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
455

456
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
Riyad Preukschas's avatar
Riyad Preukschas committed
457 458
      unless File.exists?(repo_base_path)
        puts "can't check because of previous errors".magenta
459 460 461
        return
      end

462
      if File.stat(repo_base_path).mode.to_s(8).ends_with?("2770")
Riyad Preukschas's avatar
Riyad Preukschas committed
463 464 465 466
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
467
          "sudo chmod -R ug+rwX,o-rwx #{repo_base_path}",
468
          "sudo chmod -R ug-s #{repo_base_path}",
469
          "find #{repo_base_path} -type d -print0 | sudo xargs -0 chmod g+s"
Riyad Preukschas's avatar
Riyad Preukschas committed
470 471
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
472
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
473
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
474
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
475 476 477 478
      end
    end

    def check_repo_base_user_and_group
479 480 481
      gitlab_shell_ssh_user = Gitlab.config.gitlab_shell.ssh_user
      gitlab_shell_owner_group = Gitlab.config.gitlab_shell.owner_group
      print "Repo base owned by #{gitlab_shell_ssh_user}:#{gitlab_shell_owner_group}? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
482

483
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
Riyad Preukschas's avatar
Riyad Preukschas committed
484 485
      unless File.exists?(repo_base_path)
        puts "can't check because of previous errors".magenta
486 487 488
        return
      end

489 490 491
      uid = uid_for(gitlab_shell_ssh_user)
      gid = gid_for(gitlab_shell_owner_group)
      if File.stat(repo_base_path).uid == uid && File.stat(repo_base_path).gid == gid
Riyad Preukschas's avatar
Riyad Preukschas committed
492
        puts "yes".green
493
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
494
        puts "no".red
495
        puts "  User id for #{gitlab_shell_ssh_user}: #{uid}. Groupd id for #{gitlab_shell_owner_group}: #{gid}".blue
Riyad Preukschas's avatar
Riyad Preukschas committed
496
        try_fixing_it(
497
          "sudo chown -R #{gitlab_shell_ssh_user}:#{gitlab_shell_owner_group} #{repo_base_path}"
Riyad Preukschas's avatar
Riyad Preukschas committed
498 499
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
500
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
501
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
502
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
503 504 505
      end
    end

506 507
    def check_repos_update_hooks_is_link
      print "update hooks in repos are links: ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
508

509
      hook_file = "update"
510
      gitlab_shell_hooks_path = Gitlab.config.gitlab_shell.hooks_path
511 512
      gitlab_shell_hook_file  = File.join(gitlab_shell_hooks_path, hook_file)
      gitlab_shell_ssh_user = Gitlab.config.gitlab_shell.ssh_user
Riyad Preukschas's avatar
Riyad Preukschas committed
513

514
      unless File.exists?(gitlab_shell_hook_file)
Riyad Preukschas's avatar
Riyad Preukschas committed
515 516 517
        puts "can't check because of previous errors".magenta
        return
      end
518

Riyad Preukschas's avatar
Riyad Preukschas committed
519 520 521 522 523
      unless Project.count > 0
        puts "can't check, you have no projects".magenta
        return
      end
      puts ""
524

Riyad Preukschas's avatar
Riyad Preukschas committed
525
      Project.find_each(batch_size: 100) do |project|
526
        print "#{project.name_with_namespace.yellow} ... "
527

Riyad Preukschas's avatar
Riyad Preukschas committed
528 529
        if project.empty_repo?
          puts "repository is empty".magenta
Riyad Preukschas's avatar
Riyad Preukschas committed
530
        else
Riyad Preukschas's avatar
Riyad Preukschas committed
531 532 533 534 535
          project_hook_file = File.join(project.repository.path_to_repo, "hooks", hook_file)

          unless File.exists?(project_hook_file)
            puts "missing".red
            try_fixing_it(
536
              "sudo -u #{gitlab_shell_ssh_user} ln -sf #{gitlab_shell_hook_file} #{project_hook_file}"
Riyad Preukschas's avatar
Riyad Preukschas committed
537 538
            )
            for_more_information(
Martin Bastien's avatar
Martin Bastien committed
539
              "#{gitlab_shell_user_home}/gitlab-shell/support/rewrite-hooks.sh"
Riyad Preukschas's avatar
Riyad Preukschas committed
540 541 542 543 544 545
            )
            fix_and_rerun
            next
          end

          if File.lstat(project_hook_file).symlink? &&
546
              File.realpath(project_hook_file) == File.realpath(gitlab_shell_hook_file)
Riyad Preukschas's avatar
Riyad Preukschas committed
547 548
            puts "ok".green
          else
Ben Bodenmiller's avatar
Ben Bodenmiller committed
549
            puts "not a link to GitLab Shell's hook".red
Riyad Preukschas's avatar
Riyad Preukschas committed
550
            try_fixing_it(
551
              "sudo -u #{gitlab_shell_ssh_user} ln -sf #{gitlab_shell_hook_file} #{project_hook_file}"
Riyad Preukschas's avatar
Riyad Preukschas committed
552 553 554 555 556 557
            )
            for_more_information(
              "lib/support/rewrite-hooks.sh"
            )
            fix_and_rerun
          end
558 559
        end
      end
560
    end
Riyad Preukschas's avatar
Riyad Preukschas committed
561

562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
    def check_gitlab_shell_self_test
      gitlab_shell_repo_base = File.expand_path('gitlab-shell', gitlab_shell_user_home)
      check_cmd = File.expand_path('bin/check', gitlab_shell_repo_base)
      puts "Running #{check_cmd}"
      if system(check_cmd, chdir: gitlab_shell_repo_base)
        puts 'gitlab-shell self-check successful'.green
      else
        puts 'gitlab-shell self-check failed'.red
        try_fixing_it(
          'Make sure GitLab is running;',
          'Check the gitlab-shell configuration file:',
          sudo_gitlab("editor #{File.expand_path('config.yml', gitlab_shell_repo_base)}")
        )
        fix_and_rerun
      end
    end

Hiroyuki Sato's avatar
Hiroyuki Sato committed
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
    def check_projects_have_namespace
      print "projects have namespace: ... "

      unless Project.count > 0
        puts "can't check, you have no projects".magenta
        return
      end
      puts ""

      Project.find_each(batch_size: 100) do |project|
        print "#{project.name_with_namespace.yellow} ... "

        if project.namespace
          puts "yes".green
        else
          puts "no".red
          try_fixing_it(
            "Migrate global projects"
          )
          for_more_information(
            "doc/update/5.4-to-6.0.md in section \"#global-projects\""
          )
          fix_and_rerun
        end
      end
    end
Riyad Preukschas's avatar
Riyad Preukschas committed
605 606 607 608

    # Helper methods
    ########################

609 610
    def gitlab_shell_user_home
      File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}")
Riyad Preukschas's avatar
Riyad Preukschas committed
611 612
    end

613
    def gitlab_shell_version
614
      Gitlab::Shell.new.version
Riyad Preukschas's avatar
Riyad Preukschas committed
615 616
    end

617 618
    def has_gitlab_shell3?
      gitlab_shell_version.try(:start_with?, "v3.")
Riyad Preukschas's avatar
Riyad Preukschas committed
619
    end
620
  end
621

Riyad Preukschas's avatar
Riyad Preukschas committed
622 623


Riyad Preukschas's avatar
Riyad Preukschas committed
624
  namespace :sidekiq do
625
    desc "GITLAB | Check the configuration of Sidekiq"
626
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
627
      warn_user_is_not_gitlab
Riyad Preukschas's avatar
Riyad Preukschas committed
628
      start_checking "Sidekiq"
Riyad Preukschas's avatar
Riyad Preukschas committed
629

Riyad Preukschas's avatar
Riyad Preukschas committed
630
      check_sidekiq_running
631
      only_one_sidekiq_running
Riyad Preukschas's avatar
Riyad Preukschas committed
632

Riyad Preukschas's avatar
Riyad Preukschas committed
633
      finished_checking "Sidekiq"
Riyad Preukschas's avatar
Riyad Preukschas committed
634 635 636 637 638 639
    end


    # Checks
    ########################

Riyad Preukschas's avatar
Riyad Preukschas committed
640
    def check_sidekiq_running
Riyad Preukschas's avatar
Riyad Preukschas committed
641 642
      print "Running? ... "

643
      if sidekiq_process_count > 0
Riyad Preukschas's avatar
Riyad Preukschas committed
644 645 646 647
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
648
          sudo_gitlab("RAILS_ENV=production script/background_jobs start")
Riyad Preukschas's avatar
Riyad Preukschas committed
649 650 651
        )
        for_more_information(
          see_installation_guide_section("Install Init Script"),
652
          "see log/sidekiq.log for possible errors"
Riyad Preukschas's avatar
Riyad Preukschas committed
653
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
654
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
655 656
      end
    end
657 658

    def only_one_sidekiq_running
659 660
      process_count = sidekiq_process_count
      return if process_count.zero?
661 662

      print 'Number of Sidekiq processes ... '
663
      if process_count == 1
664 665
        puts '1'.green
      else
666
        puts "#{process_count}".red
667 668
        try_fixing_it(
          'sudo service gitlab stop',
669 670
          "sudo pkill -u #{gitlab_user} -f sidekiq",
          "sleep 10 && sudo pkill -9 -u #{gitlab_user} -f sidekiq",
671 672 673 674 675 676
          'sudo service gitlab start'
        )
        fix_and_rerun
      end
    end

677 678
    def sidekiq_process_count
      `ps ux`.scan(/sidekiq \d+\.\d+\.\d+/).count
679
    end
Riyad Preukschas's avatar
Riyad Preukschas committed
680 681 682 683 684 685
  end


  # Helper methods
  ##########################

Riyad Preukschas's avatar
Riyad Preukschas committed
686
  def fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
    puts "  Please #{"fix the error above"} and rerun the checks.".red
  end

  def for_more_information(*sources)
    sources = sources.shift if sources.first.is_a?(Array)

    puts "  For more information see:".blue
    sources.each do |source|
      puts "  #{source}"
    end
  end

  def finished_checking(component)
    puts ""
    puts "Checking #{component.yellow} ... #{"Finished".green}"
    puts ""
  end

  def see_database_guide
    "doc/install/databases.md"
  end

  def see_installation_guide_section(section)
    "doc/install/installation.md in section \"#{section}\""
  end

713 714 715 716
  def sudo_gitlab(command)
    "sudo -u #{gitlab_user} -H #{command}"
  end

717 718 719 720
  def gitlab_user
    Gitlab.config.gitlab.user
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
721 722 723 724 725 726 727 728 729 730 731 732 733
  def start_checking(component)
    puts "Checking #{component.yellow} ..."
    puts ""
  end

  def try_fixing_it(*steps)
    steps = steps.shift if steps.first.is_a?(Array)

    puts "  Try fixing it:".blue
    steps.each do |step|
      puts "  #{step}"
    end
  end
734 735

  def check_gitlab_shell
736
    required_version = Gitlab::VersionInfo.new(1, 7, 9)
737
    current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
738

739
    print "GitLab Shell version >= #{required_version} ? ... "
Sato Hiroyuki's avatar
Sato Hiroyuki committed
740
    if current_version.valid? && required_version <= current_version
741
      puts "OK (#{current_version})".green
742
    else
743
      puts "FAIL. Please update gitlab-shell to #{required_version} from #{current_version}".red
744 745
    end
  end
746 747

  def check_git_version
748
    required_version = Gitlab::VersionInfo.new(1, 7, 10)
749
    current_version = Gitlab::VersionInfo.parse(run("#{Gitlab.config.git.bin_path} --version"))
Sato Hiroyuki's avatar
Sato Hiroyuki committed
750

751
    puts "Your git bin path is \"#{Gitlab.config.git.bin_path}\""
Sato Hiroyuki's avatar
Sato Hiroyuki committed
752 753
    print "Git version >= #{required_version} ? ... "

Sato Hiroyuki's avatar
Sato Hiroyuki committed
754
    if current_version.valid? && required_version <= current_version
755
        puts "yes (#{current_version})".green
756 757 758
    else
      puts "no".red
      try_fixing_it(
Sato Hiroyuki's avatar
Sato Hiroyuki committed
759
        "Update your git to a version >= #{required_version} from #{current_version}"
760 761 762 763
      )
      fix_and_rerun
    end
  end
764
end