check.rake 22.5 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
    def check_init_script_exists
      print "Init script exists? ... "

126 127 128 129 130
      if omnibus_gitlab?
        puts 'skipped (omnibus-gitlab has no init script)'.magenta
        return
      end

Riyad Preukschas's avatar
Riyad Preukschas committed
131 132 133 134
      script_path = "/etc/init.d/gitlab"

      if File.exists?(script_path)
        puts "yes".green
Nihad Abbasov's avatar
Nihad Abbasov committed
135
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
136 137 138 139 140 141 142
        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
143
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
144 145 146 147 148 149
      end
    end

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

150 151 152 153 154
      if omnibus_gitlab?
        puts 'skipped (omnibus-gitlab has no init script)'.magenta
        return
      end

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

Riyad Preukschas's avatar
Riyad Preukschas committed
158 159
      unless File.exists?(script_path)
        puts "can't check because of previous errors".magenta
160 161 162
        return
      end

163
      recipe_content = File.read(recipe_path)
Riyad Preukschas's avatar
Riyad Preukschas committed
164 165 166 167 168 169 170 171 172 173 174 175
      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
176
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
177 178 179 180 181 182
      end
    end

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

183
      migration_status, _ = Gitlab::Popen.popen(%W(bundle exec rake db:migrate:status))
Riyad Preukschas's avatar
Riyad Preukschas committed
184 185 186

      unless migration_status =~ /down\s+\d{14}/
        puts "yes".green
187
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
188 189
        puts "no".red
        try_fixing_it(
190
          sudo_gitlab("bundle exec rake db:migrate RAILS_ENV=production")
Riyad Preukschas's avatar
Riyad Preukschas committed
191
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
192
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
193 194 195
      end
    end

196 197 198 199
    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
200 201 202 203
        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'")
        )
204 205 206 207 208
      else
        puts "no".green
      end
    end

Riyad Preukschas's avatar
Riyad Preukschas committed
209 210 211 212 213
    def check_satellites_exist
      print "Projects have satellites? ... "

      unless Project.count > 0
        puts "can't check, you have no projects".magenta
214 215
        return
      end
Riyad Preukschas's avatar
Riyad Preukschas committed
216 217 218
      puts ""

      Project.find_each(batch_size: 100) do |project|
219
        print "#{project.name_with_namespace.yellow} ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
220 221 222

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

280
    def check_redis_version
281 282
      print "Redis version >= 2.0.0? ... "

283
      if run_and_match(%W(redis-cli --version), /redis-cli 2.\d.\d/)
284
        puts "yes".green
285
      else
286 287
        puts "no".red
        try_fixing_it(
288
          "Update your redis server to a version >= 2.0.0"
289 290 291 292 293 294
        )
        for_more_information(
          "gitlab-public-wiki/wiki/Trouble-Shooting-Guide in section sidekiq"
        )
        fix_and_rerun
      end
295
    end
296 297
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
298 299


300 301 302
  namespace :env do
    desc "GITLAB | Check the configuration of the environment"
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
303 304 305 306 307 308 309 310 311 312 313 314 315
      warn_user_is_not_gitlab
      start_checking "Environment"

      check_gitlab_git_config

      finished_checking "Environment"
    end


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

    def check_gitlab_git_config
316
      print "Git configured for #{gitlab_user} user? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
317 318 319

      options = {
        "user.name"  => "GitLab",
320
        "user.email" => Gitlab.config.gitlab.email_from
Riyad Preukschas's avatar
Riyad Preukschas committed
321 322
      }
      correct_options = options.map do |name, value|
323
        run(%W(git config --global --get #{name})).try(:squish) == value
Riyad Preukschas's avatar
Riyad Preukschas committed
324 325 326 327 328 329 330
      end

      if correct_options.all?
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
331 332
          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
333 334 335 336
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
337
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
338 339
      end
    end
340 341
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
342 343


344
  namespace :gitlab_shell do
Ben Bodenmiller's avatar
Ben Bodenmiller committed
345
    desc "GITLAB | Check the configuration of GitLab Shell"
346
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
347
      warn_user_is_not_gitlab
Ben Bodenmiller's avatar
Ben Bodenmiller committed
348
      start_checking "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
349

350
      check_gitlab_shell
Riyad Preukschas's avatar
Riyad Preukschas committed
351
      check_repo_base_exists
352
      check_repo_base_is_not_symlink
Riyad Preukschas's avatar
Riyad Preukschas committed
353 354
      check_repo_base_user_and_group
      check_repo_base_permissions
355
      check_satellites_permissions
356 357
      check_update_hook_is_up_to_date
      check_repos_update_hooks_is_link
358
      check_gitlab_shell_self_test
Riyad Preukschas's avatar
Riyad Preukschas committed
359

Ben Bodenmiller's avatar
Ben Bodenmiller committed
360
      finished_checking "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
361 362 363 364 365 366 367
    end


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


368 369
    def check_update_hook_is_up_to_date
      print "update hook up-to-date? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
370

371
      hook_file = "update"
372
      gitlab_shell_hooks_path = Gitlab.config.gitlab_shell.hooks_path
373
      gitlab_shell_hook_file  = File.join(gitlab_shell_hooks_path, hook_file)
Riyad Preukschas's avatar
Riyad Preukschas committed
374

375 376 377 378 379 380 381 382 383 384 385 386
      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"
        )
387
      end
Riyad Preukschas's avatar
Riyad Preukschas committed
388 389 390 391 392
    end

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

393
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
Riyad Preukschas's avatar
Riyad Preukschas committed
394 395 396 397 398 399 400

      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
401
          "This should have been created when setting up GitLab Shell.",
Riyad Preukschas's avatar
Riyad Preukschas committed
402
          "Make sure it's set correctly in config/gitlab.yml",
Ben Bodenmiller's avatar
Ben Bodenmiller committed
403
          "Make sure GitLab Shell is installed correctly."
Riyad Preukschas's avatar
Riyad Preukschas committed
404 405
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
406
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
407
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
408
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
409 410 411
      end
    end

412 413 414
    def check_repo_base_is_not_symlink
      print "Repo base directory is a symlink? ... "

415
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
      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
432
    def check_repo_base_permissions
433
      print "Repo base access is drwxrws---? ... "
Riyad Preukschas's avatar
Riyad Preukschas committed
434

435
      repo_base_path = Gitlab.config.gitlab_shell.repos_path
Riyad Preukschas's avatar
Riyad Preukschas committed
436 437
      unless File.exists?(repo_base_path)
        puts "can't check because of previous errors".magenta
438 439 440
        return
      end

441
      if File.stat(repo_base_path).mode.to_s(8).ends_with?("2770")
Riyad Preukschas's avatar
Riyad Preukschas committed
442 443 444 445
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
446
          "sudo chmod -R ug+rwX,o-rwx #{repo_base_path}",
447
          "sudo chmod -R ug-s #{repo_base_path}",
448
          "find #{repo_base_path} -type d -print0 | sudo xargs -0 chmod g+s"
Riyad Preukschas's avatar
Riyad Preukschas committed
449 450
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
451
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
452
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
453
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
454 455 456
      end
    end

457 458 459 460 461 462 463 464 465 466 467 468 469 470
    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
471
          "sudo chmod u+rwx,g=rx,o-rwx #{satellites_path}",
472 473 474 475 476 477 478 479
        )
        for_more_information(
          see_installation_guide_section "GitLab"
        )
        fix_and_rerun
      end
    end

Riyad Preukschas's avatar
Riyad Preukschas committed
480
    def check_repo_base_user_and_group
481 482 483
      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
484

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

491 492 493
      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
494
        puts "yes".green
495
      else
Riyad Preukschas's avatar
Riyad Preukschas committed
496
        puts "no".red
497
        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
498
        try_fixing_it(
499
          "sudo chown -R #{gitlab_shell_ssh_user}:#{gitlab_shell_owner_group} #{repo_base_path}"
Riyad Preukschas's avatar
Riyad Preukschas committed
500 501
        )
        for_more_information(
Ben Bodenmiller's avatar
Ben Bodenmiller committed
502
          see_installation_guide_section "GitLab Shell"
Riyad Preukschas's avatar
Riyad Preukschas committed
503
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
504
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
505 506 507
      end
    end

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

511
      hook_file = "update"
512
      gitlab_shell_hooks_path = Gitlab.config.gitlab_shell.hooks_path
513 514
      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
515

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

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

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

Riyad Preukschas's avatar
Riyad Preukschas committed
530 531
        if project.empty_repo?
          puts "repository is empty".magenta
Riyad Preukschas's avatar
Riyad Preukschas committed
532
        else
Riyad Preukschas's avatar
Riyad Preukschas committed
533 534 535 536 537
          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(
538
              "sudo -u #{gitlab_shell_ssh_user} ln -sf #{gitlab_shell_hook_file} #{project_hook_file}"
Riyad Preukschas's avatar
Riyad Preukschas committed
539 540
            )
            for_more_information(
541
              "#{gitlab_shell_path}/support/rewrite-hooks.sh"
Riyad Preukschas's avatar
Riyad Preukschas committed
542 543 544 545 546 547
            )
            fix_and_rerun
            next
          end

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

564
    def check_gitlab_shell_self_test
565
      gitlab_shell_repo_base = gitlab_shell_path
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
      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
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
    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
607 608 609 610

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

611 612
    def gitlab_shell_path
      Gitlab.config.gitlab_shell.path
Riyad Preukschas's avatar
Riyad Preukschas committed
613 614
    end

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

619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
    def required_gitlab_shell_version
      File.read(File.join(Rails.root, "GITLAB_SHELL_VERSION")).strip
    end

    def gitlab_shell_major_version
      required_gitlab_shell_version.split(".")[0].to_i
    end

    def gitlab_shell_minor_version
      required_gitlab_shell_version.split(".")[1].to_i
    end

    def gitlab_shell_patch_version
      required_gitlab_shell_version.split(".")[2].to_i
    end

635 636
    def has_gitlab_shell3?
      gitlab_shell_version.try(:start_with?, "v3.")
Riyad Preukschas's avatar
Riyad Preukschas committed
637
    end
638
  end
639

Riyad Preukschas's avatar
Riyad Preukschas committed
640 641


Riyad Preukschas's avatar
Riyad Preukschas committed
642
  namespace :sidekiq do
643
    desc "GITLAB | Check the configuration of Sidekiq"
644
    task check: :environment  do
Riyad Preukschas's avatar
Riyad Preukschas committed
645
      warn_user_is_not_gitlab
Riyad Preukschas's avatar
Riyad Preukschas committed
646
      start_checking "Sidekiq"
Riyad Preukschas's avatar
Riyad Preukschas committed
647

Riyad Preukschas's avatar
Riyad Preukschas committed
648
      check_sidekiq_running
649
      only_one_sidekiq_running
Riyad Preukschas's avatar
Riyad Preukschas committed
650

Riyad Preukschas's avatar
Riyad Preukschas committed
651
      finished_checking "Sidekiq"
Riyad Preukschas's avatar
Riyad Preukschas committed
652 653 654 655 656 657
    end


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

Riyad Preukschas's avatar
Riyad Preukschas committed
658
    def check_sidekiq_running
Riyad Preukschas's avatar
Riyad Preukschas committed
659 660
      print "Running? ... "

661
      if sidekiq_process_count > 0
Riyad Preukschas's avatar
Riyad Preukschas committed
662 663 664 665
        puts "yes".green
      else
        puts "no".red
        try_fixing_it(
666
          sudo_gitlab("RAILS_ENV=production bin/background_jobs start")
Riyad Preukschas's avatar
Riyad Preukschas committed
667 668 669
        )
        for_more_information(
          see_installation_guide_section("Install Init Script"),
670
          "see log/sidekiq.log for possible errors"
Riyad Preukschas's avatar
Riyad Preukschas committed
671
        )
Riyad Preukschas's avatar
Riyad Preukschas committed
672
        fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
673 674
      end
    end
675 676

    def only_one_sidekiq_running
677 678
      process_count = sidekiq_process_count
      return if process_count.zero?
679 680

      print 'Number of Sidekiq processes ... '
681
      if process_count == 1
682 683
        puts '1'.green
      else
684
        puts "#{process_count}".red
685 686
        try_fixing_it(
          'sudo service gitlab stop',
687 688
          "sudo pkill -u #{gitlab_user} -f sidekiq",
          "sleep 10 && sudo pkill -9 -u #{gitlab_user} -f sidekiq",
689 690 691 692 693 694
          'sudo service gitlab start'
        )
        fix_and_rerun
      end
    end

695
    def sidekiq_process_count
696 697
      ps_ux, _ = Gitlab::Popen.popen(%W(ps ux))
      ps_ux.scan(/sidekiq \d+\.\d+\.\d+/).count
698
    end
Riyad Preukschas's avatar
Riyad Preukschas committed
699 700
  end

701
  namespace :ldap do
702
    task :check, [:limit] => :environment do |t, args|
703 704
      # Only show up to 100 results because LDAP directories can be very big.
      # This setting only affects the `rake gitlab:check` script.
705
      args.with_defaults(limit: 100)
706 707 708
      warn_user_is_not_gitlab
      start_checking "LDAP"

709
      if ldap_config.enabled
710
        print_users(args.limit)
711 712 713
      else
        puts 'LDAP is disabled in config/gitlab.yml'
      end
714 715 716 717

      finished_checking "LDAP"
    end

718
    def print_users(limit)
719
      puts "LDAP users with access to your GitLab server (only showing the first #{limit} results)"
720
      ldap.search(attributes: attributes, filter: filter, size: limit, return_result: false) do |entry|
721 722 723 724 725 726 727 728 729
        puts "DN: #{entry.dn}\t#{ldap_config.uid}: #{entry[ldap_config.uid]}"
      end
    end

    def attributes
      [ldap_config.uid]
    end

    def filter
730 731 732 733 734 735 736 737 738 739 740 741 742 743
      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
744 745 746 747 748 749 750 751 752 753
    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
754 755 756 757

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

Riyad Preukschas's avatar
Riyad Preukschas committed
758
  def fix_and_rerun
Riyad Preukschas's avatar
Riyad Preukschas committed
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
    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

785 786 787 788
  def sudo_gitlab(command)
    "sudo -u #{gitlab_user} -H #{command}"
  end

789 790 791 792
  def gitlab_user
    Gitlab.config.gitlab.user
  end

Riyad Preukschas's avatar
Riyad Preukschas committed
793 794 795 796 797 798 799 800 801 802 803 804 805
  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
806 807

  def check_gitlab_shell
808
    required_version = Gitlab::VersionInfo.new(gitlab_shell_major_version, gitlab_shell_minor_version, gitlab_shell_patch_version)
809
    current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
810

811
    print "GitLab Shell version >= #{required_version} ? ... "
Sato Hiroyuki's avatar
Sato Hiroyuki committed
812
    if current_version.valid? && required_version <= current_version
813
      puts "OK (#{current_version})".green
814
    else
815
      puts "FAIL. Please update gitlab-shell to #{required_version} from #{current_version}".red
816 817
    end
  end
818 819

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

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

Sato Hiroyuki's avatar
Sato Hiroyuki committed
826
    if current_version.valid? && required_version <= current_version
827
        puts "yes (#{current_version})".green
828 829 830
    else
      puts "no".red
      try_fixing_it(
Sato Hiroyuki's avatar
Sato Hiroyuki committed
831
        "Update your git to a version >= #{required_version} from #{current_version}"
832 833 834 835
      )
      fix_and_rerun
    end
  end
836 837 838 839

  def omnibus_gitlab?
    Dir.pwd == '/opt/gitlab/embedded/service/gitlab-rails'
  end
840
end