check.rake 21.7 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
6
                 gitlab:ldap:check
Riyad Preukschas's avatar
Riyad Preukschas committed
7 8 9
                 gitlab:app:check}


10

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

      check_database_config_exists
      check_database_is_not_sqlite
      check_migrations_are_up
20
      check_orphaned_users_groups
Riyad Preukschas's avatar
Riyad Preukschas committed
21 22 23 24 25 26
      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
27
      check_projects_have_namespace
Riyad Preukschas's avatar
Riyad Preukschas committed
28
      check_satellites_exist
29
      check_redis_version
30
      check_git_version
Riyad Preukschas's avatar
Riyad Preukschas committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

      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
56
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
57 58 59 60
      end
    end

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

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

65
      unless File.read(database_config_file) =~ /adapter:\s+sqlite/
66
        puts "no".green
Riyad Preukschas's avatar
Riyad Preukschas committed
67
      else
68
        puts "yes".red
69
        puts "Please fix this by removing the SQLite entry from the database.yml".blue
Riyad Preukschas's avatar
Riyad Preukschas committed
70 71 72 73
        for_more_information(
          "https://github.com/gitlabhq/gitlabhq/wiki/Migrate-from-SQLite-to-MySQL",
          see_database_guide
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
74
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
      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
94
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
95 96 97 98
      end
    end

    def check_gitlab_config_not_outdated
Riyad Preukschas's avatar
Riyad Preukschas committed
99
      print "GitLab config outdated? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
100 101 102 103 104 105 106

      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
107
      unless Gitlab.config['git_host']
Riyad Preukschas's avatar
Riyad Preukschas committed
108
        puts "no".green
Riyad Preukschas's avatar
Riyad Preukschas committed
109
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
110
        puts "yes".red
Riyad Preukschas's avatar
Riyad Preukschas committed
111
        try_fixing_it(
Riyad Preukschas's avatar
Riyad Preukschas committed
112
          "Backup your config/gitlab.yml",
Riyad Preukschas's avatar
Riyad Preukschas committed
113 114 115 116 117 118
          "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
119
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
120 121
      end
    end
122

Riyad Preukschas's avatar
Riyad Preukschas committed
123 124 125 126 127 128 129
    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
130
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
131 132 133 134 135 136 137
        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
138
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
139 140 141 142 143 144
      end
    end

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

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

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

153
      recipe_content = File.read(recipe_path)
Riyad Preukschas's avatar
Riyad Preukschas committed
154 155 156 157 158 159 160 161 162 163 164 165
      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
166
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
167 168 169 170 171 172
      end
    end

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

173
      migration_status, _ = Gitlab::Popen.popen(%W(bundle exec rake db:migrate:status))
Riyad Preukschas's avatar
Riyad Preukschas committed
174 175 176

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

186 187 188 189
    def check_orphaned_users_groups
      print "Database contains orphaned UsersGroups? ... "
      if UsersGroup.where("user_id not in (select id from users)").count > 0
        puts "yes".red
190 191 192 193
        try_fixing_it(
          "You can delete the orphaned records using something along the lines of:",
          sudo_gitlab("bundle exec rails runner -e production 'UsersGroup.where(\"user_id NOT IN (SELECT id FROM users)\").delete_all'")
        )
194 195 196 197 198
      else
        puts "no".green
      end
    end

Riyad Preukschas's avatar
Riyad Preukschas committed
199 200 201 202 203
    def check_satellites_exist
      print "Projects have satellites? ... "

      unless Project.count > 0
        puts "can't check, you have no projects".magenta
204 205
        return
      end
Riyad Preukschas's avatar
Riyad Preukschas committed
206 207 208
      puts ""

      Project.find_each(batch_size: 100) do |project|
209
        print "#{project.name_with_namespace.yellow} ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
210 211 212

        if project.satellite.exists?
          puts "yes".green
213 214
        elsif project.empty_repo?
          puts "can't create, repository is empty".magenta
Riyad Preukschas's avatar
Riyad Preukschas committed
215 216 217
        else
          puts "no".red
          try_fixing_it(
218
            sudo_gitlab("bundle exec rake gitlab:satellites:create RAILS_ENV=production"),
219 220
            "If necessary, remove the tmp/repo_satellites directory ...",
            "... and rerun the above command"
Riyad Preukschas's avatar
Riyad Preukschas committed
221 222 223 224
          )
          for_more_information(
            "doc/raketasks/maintenance.md "
          )
Riyad Preukschas's avatar
Riyad Preukschas committed
225
          fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
        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
241
          "sudo chmod -R u+rwX #{log_path}"
Riyad Preukschas's avatar
Riyad Preukschas committed
242 243 244 245
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
246
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
247 248 249 250 251 252 253 254 255 256 257 258 259 260
      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
261
          "sudo chmod -R u+rwX #{tmp_path}"
Riyad Preukschas's avatar
Riyad Preukschas committed
262 263 264 265
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
266
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
267
      end
268
    end
269

270
    def check_redis_version
271 272
      print "Redis version >= 2.0.0? ... "

273
      if run_and_match(%W(redis-cli --version), /redis-cli 2.\d.\d/)
274
        puts "yes".green
275
      else
276 277
        puts "no".red
        try_fixing_it(
278
          "Update your redis server to a version >= 2.0.0"
279 280 281 282 283 284
        )
        for_more_information(
          "gitlab-public-wiki/wiki/Trouble-Shooting-Guide in section sidekiq"
        )
        fix_and_rerun
      end
285
    end
286 287
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
288 289


290 291 292
  namespace :env do
    desc "GITLAB | Check the configuration of the environment"
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
293 294 295 296 297 298 299 300 301 302 303 304 305
      warn_user_is_not_gitlab
      start_checking "Environment"

      check_gitlab_git_config

      finished_checking "Environment"
    end


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

    def check_gitlab_git_config
306
      print "Git configured for #{gitlab_user} user? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
307 308 309

      options = {
        "user.name"  => "GitLab",
310
        "user.email" => Gitlab.config.gitlab.email_from
Riyad Preukschas's avatar
Riyad Preukschas committed
311 312
      }
      correct_options = options.map do |name, value|
313
        run(%W(git config --global --get #{name})).try(:squish) == value
Riyad Preukschas's avatar
Riyad Preukschas committed
314 315 316 317 318 319 320
      end

      if correct_options.all?
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
321 322
          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
323 324 325 326
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
327
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
328 329
      end
    end
330 331
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
332 333


334
  namespace :gitlab_shell do
Ben Bodenmiller's avatar
Ben Bodenmiller committed
335
    desc "GITLAB | Check the configuration of GitLab Shell"
336
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
337
      warn_user_is_not_gitlab
Ben Bodenmiller's avatar
Ben Bodenmiller committed
338
      start_checking "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
339

340
      check_gitlab_shell
Riyad Preukschas's avatar
Riyad Preukschas committed
341
      check_repo_base_exists
342
      check_repo_base_is_not_symlink
Riyad Preukschas's avatar
Riyad Preukschas committed
343 344
      check_repo_base_user_and_group
      check_repo_base_permissions
345
      check_satellites_permissions
346 347
      check_update_hook_is_up_to_date
      check_repos_update_hooks_is_link
348
      check_gitlab_shell_self_test
Riyad Preukschas's avatar
Riyad Preukschas committed
349

Ben Bodenmiller's avatar
Ben Bodenmiller committed
350
      finished_checking "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
351 352 353 354 355 356 357
    end


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


358 359
    def check_update_hook_is_up_to_date
      print "update hook up-to-date? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
360

361
      hook_file = "update"
362
      gitlab_shell_hooks_path = Gitlab.config.gitlab_shell.hooks_path
363
      gitlab_shell_hook_file  = File.join(gitlab_shell_hooks_path, hook_file)
Riyad Preukschas's avatar
Riyad Preukschas committed
364

365 366 367 368 369 370 371 372 373 374 375 376
      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"
        )
377
      end
Riyad Preukschas's avatar
Riyad Preukschas committed
378 379 380 381 382
    end

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

383
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
Riyad Preukschas's avatar
Riyad Preukschas committed
384 385 386 387 388 389 390

      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
391
          "This should have been created when setting up GitLab Shell.",
Riyad Preukschas's avatar
Riyad Preukschas committed
392
          "Make sure it's set correctly in config/gitlab.yml",
Ben Bodenmiller's avatar
Ben Bodenmiller committed
393
          "Make sure GitLab Shell is installed correctly."
Riyad Preukschas's avatar
Riyad Preukschas committed
394 395
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
396
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
397
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
398
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
399 400 401
      end
    end

402 403 404
    def check_repo_base_is_not_symlink
      print "Repo base directory is a symlink? ... "

405
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
      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
422
    def check_repo_base_permissions
423
      print "Repo base access is drwxrws---? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
424

425
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
Riyad Preukschas's avatar
Riyad Preukschas committed
426 427
      unless File.exists?(repo_base_path)
        puts "can't check because of previous errors".magenta
428 429 430
        return
      end

431
      if File.stat(repo_base_path).mode.to_s(8).ends_with?("2770")
Riyad Preukschas's avatar
Riyad Preukschas committed
432 433 434 435
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
436
          "sudo chmod -R ug+rwX,o-rwx #{repo_base_path}",
437
          "sudo chmod -R ug-s #{repo_base_path}",
438
          "find #{repo_base_path} -type d -print0 | sudo xargs -0 chmod g+s"
Riyad Preukschas's avatar
Riyad Preukschas committed
439 440
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
441
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
442
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
443
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
444 445 446
      end
    end

447 448 449 450 451 452 453 454 455 456 457 458 459 460
    def check_satellites_permissions
      print "Satellites access is drwxr-x---? ... "

      satellites_path = Gitlab.config.satellites.path
      unless File.exists?(satellites_path)
        puts "can't check because of previous errors".magenta
        return
      end

      if File.stat(satellites_path).mode.to_s(8).ends_with?("0750")
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
Michael  Krane's avatar
Michael Krane committed
461
          "sudo chmod u+rwx,g=rx,o-rwx #{satellites_path}",
462 463 464 465 466 467 468 469
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
        fix_and_rerun
      end
    end

Riyad Preukschas's avatar
Riyad Preukschas committed
470
    def check_repo_base_user_and_group
471 472 473
      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
474

475
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
Riyad Preukschas's avatar
Riyad Preukschas committed
476 477
      unless File.exists?(repo_base_path)
        puts "can't check because of previous errors".magenta
478 479 480
        return
      end

481 482 483
      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
484
        puts "yes".green
485
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
486
        puts "no".red
487
        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
488
        try_fixing_it(
489
          "sudo chown -R #{gitlab_shell_ssh_user}:#{gitlab_shell_owner_group} #{repo_base_path}"
Riyad Preukschas's avatar
Riyad Preukschas committed
490 491
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
492
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
493
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
494
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
495 496 497
      end
    end

498 499
    def check_repos_update_hooks_is_link
      print "update hooks in repos are links: ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
500

501
      hook_file = "update"
502
      gitlab_shell_hooks_path = Gitlab.config.gitlab_shell.hooks_path
503 504
      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
505

506
      unless File.exists?(gitlab_shell_hook_file)
Riyad Preukschas's avatar
Riyad Preukschas committed
507 508 509
        puts "can't check because of previous errors".magenta
        return
      end
510

Riyad Preukschas's avatar
Riyad Preukschas committed
511 512 513 514 515
      unless Project.count > 0
        puts "can't check, you have no projects".magenta
        return
      end
      puts ""
516

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

Riyad Preukschas's avatar
Riyad Preukschas committed
520 521
        if project.empty_repo?
          puts "repository is empty".magenta
Riyad Preukschas's avatar
Riyad Preukschas committed
522
        else
Riyad Preukschas's avatar
Riyad Preukschas committed
523 524 525 526 527
          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(
528
              "sudo -u #{gitlab_shell_ssh_user} ln -sf #{gitlab_shell_hook_file} #{project_hook_file}"
Riyad Preukschas's avatar
Riyad Preukschas committed
529 530
            )
            for_more_information(
531
              "#{gitlab_shell_path}/support/rewrite-hooks.sh"
Riyad Preukschas's avatar
Riyad Preukschas committed
532 533 534 535 536 537
            )
            fix_and_rerun
            next
          end

          if File.lstat(project_hook_file).symlink? &&
538
              File.realpath(project_hook_file) == File.realpath(gitlab_shell_hook_file)
Riyad Preukschas's avatar
Riyad Preukschas committed
539 540
            puts "ok".green
          else
Ben Bodenmiller's avatar
Ben Bodenmiller committed
541
            puts "not a link to GitLab Shell's hook".red
Riyad Preukschas's avatar
Riyad Preukschas committed
542
            try_fixing_it(
543
              "sudo -u #{gitlab_shell_ssh_user} ln -sf #{gitlab_shell_hook_file} #{project_hook_file}"
Riyad Preukschas's avatar
Riyad Preukschas committed
544 545 546 547 548 549
            )
            for_more_information(
              "lib/support/rewrite-hooks.sh"
            )
            fix_and_rerun
          end
550 551
        end
      end
552
    end
Riyad Preukschas's avatar
Riyad Preukschas committed
553

554
    def check_gitlab_shell_self_test
555
      gitlab_shell_repo_base = gitlab_shell_path
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
      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
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
    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
597 598 599 600

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

601 602
    def gitlab_shell_path
      Gitlab.config.gitlab_shell.path
Riyad Preukschas's avatar
Riyad Preukschas committed
603 604
    end

605
    def gitlab_shell_version
606
      Gitlab::Shell.new.version
Riyad Preukschas's avatar
Riyad Preukschas committed
607 608
    end

609 610
    def has_gitlab_shell3?
      gitlab_shell_version.try(:start_with?, "v3.")
Riyad Preukschas's avatar
Riyad Preukschas committed
611
    end
612
  end
613

Riyad Preukschas's avatar
Riyad Preukschas committed
614 615


Riyad Preukschas's avatar
Riyad Preukschas committed
616
  namespace :sidekiq do
617
    desc "GITLAB | Check the configuration of Sidekiq"
618
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
619
      warn_user_is_not_gitlab
Riyad Preukschas's avatar
Riyad Preukschas committed
620
      start_checking "Sidekiq"
Riyad Preukschas's avatar
Riyad Preukschas committed
621

Riyad Preukschas's avatar
Riyad Preukschas committed
622
      check_sidekiq_running
623
      only_one_sidekiq_running
Riyad Preukschas's avatar
Riyad Preukschas committed
624

Riyad Preukschas's avatar
Riyad Preukschas committed
625
      finished_checking "Sidekiq"
Riyad Preukschas's avatar
Riyad Preukschas committed
626 627 628 629 630 631
    end


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

Riyad Preukschas's avatar
Riyad Preukschas committed
632
    def check_sidekiq_running
Riyad Preukschas's avatar
Riyad Preukschas committed
633 634
      print "Running? ... "

635
      if sidekiq_process_count > 0
Riyad Preukschas's avatar
Riyad Preukschas committed
636 637 638 639
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
640
          sudo_gitlab("RAILS_ENV=production bin/background_jobs start")
Riyad Preukschas's avatar
Riyad Preukschas committed
641 642 643
        )
        for_more_information(
          see_installation_guide_section("Install Init Script"),
644
          "see log/sidekiq.log for possible errors"
Riyad Preukschas's avatar
Riyad Preukschas committed
645
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
646
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
647 648
      end
    end
649 650

    def only_one_sidekiq_running
651 652
      process_count = sidekiq_process_count
      return if process_count.zero?
653 654

      print 'Number of Sidekiq processes ... '
655
      if process_count == 1
656 657
        puts '1'.green
      else
658
        puts "#{process_count}".red
659 660
        try_fixing_it(
          'sudo service gitlab stop',
661 662
          "sudo pkill -u #{gitlab_user} -f sidekiq",
          "sleep 10 && sudo pkill -9 -u #{gitlab_user} -f sidekiq",
663 664 665 666 667 668
          'sudo service gitlab start'
        )
        fix_and_rerun
      end
    end

669
    def sidekiq_process_count
670 671
      ps_ux, _ = Gitlab::Popen.popen(%W(ps ux))
      ps_ux.scan(/sidekiq \d+\.\d+\.\d+/).count
672
    end
Riyad Preukschas's avatar
Riyad Preukschas committed
673 674
  end

675
  namespace :ldap do
676
    task :check, [:limit] => :environment do |t, args|
677 678
      # Only show up to 100 results because LDAP directories can be very big.
      # This setting only affects the `rake gitlab:check` script.
679
      args.with_defaults(limit: 100)
680 681 682
      warn_user_is_not_gitlab
      start_checking "LDAP"

683
      if ldap_config.enabled
684
        print_users(args.limit)
685 686 687
      else
        puts 'LDAP is disabled in config/gitlab.yml'
      end
688 689 690 691

      finished_checking "LDAP"
    end

692
    def print_users(limit)
693
      puts "LDAP users with access to your GitLab server (only showing the first #{limit} results)"
694
      ldap.search(attributes: attributes, filter: filter, size: limit, return_result: false) do |entry|
695 696 697 698 699 700 701 702 703
        puts "DN: #{entry.dn}\t#{ldap_config.uid}: #{entry[ldap_config.uid]}"
      end
    end

    def attributes
      [ldap_config.uid]
    end

    def filter
704 705 706 707 708 709 710 711 712 713 714 715 716 717
      uid_filter = Net::LDAP::Filter.present?(ldap_config.uid)
      if user_filter
        Net::LDAP::Filter.join(uid_filter, user_filter)
      else
        uid_filter
      end
    end

    def user_filter
      if ldap_config['user_filter'] && ldap_config.user_filter.present?
        Net::LDAP::Filter.construct(ldap_config.user_filter)
      else
        nil
      end
718 719 720 721 722 723 724 725 726 727
    end

    def ldap
      @ldap ||= OmniAuth::LDAP::Adaptor.new(ldap_config).connection
    end

    def ldap_config
      @ldap_config ||= Gitlab.config.ldap
    end
  end
Riyad Preukschas's avatar
Riyad Preukschas committed
728 729 730 731

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

Riyad Preukschas's avatar
Riyad Preukschas committed
732
  def fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
    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

759 760 761 762
  def sudo_gitlab(command)
    "sudo -u #{gitlab_user} -H #{command}"
  end

763 764 765 766
  def gitlab_user
    Gitlab.config.gitlab.user
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
767 768 769 770 771 772 773 774 775 776 777 778 779
  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
780 781

  def check_gitlab_shell
782
    required_version = Gitlab::VersionInfo.new(1, 9, 4)
783
    current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
784

785
    print "GitLab Shell version >= #{required_version} ? ... "
Sato Hiroyuki's avatar
Sato Hiroyuki committed
786
    if current_version.valid? && required_version <= current_version
787
      puts "OK (#{current_version})".green
788
    else
789
      puts "FAIL. Please update gitlab-shell to #{required_version} from #{current_version}".red
790 791
    end
  end
792 793

  def check_git_version
794
    required_version = Gitlab::VersionInfo.new(1, 7, 10)
795
    current_version = Gitlab::VersionInfo.parse(run(%W(#{Gitlab.config.git.bin_path} --version)))
Sato Hiroyuki's avatar
Sato Hiroyuki committed
796

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

Sato Hiroyuki's avatar
Sato Hiroyuki committed
800
    if current_version.valid? && required_version <= current_version
801
        puts "yes (#{current_version})".green
802 803 804
    else
      puts "no".red
      try_fixing_it(
Sato Hiroyuki's avatar
Sato Hiroyuki committed
805
        "Update your git to a version >= #{required_version} from #{current_version}"
806 807 808 809
      )
      fix_and_rerun
    end
  end
810
end