module Gitlab class TaskAbortedByUserError < StandardError; end end require 'rainbow/ext/string' # Prevent StateMachine warnings from outputting during a cron task StateMachines::Machine.ignore_method_conflicts = true if ENV['CRON'] namespace :gitlab do # Ask if the user wants to continue # # Returns "yes" the user chose to continue # Raises Gitlab::TaskAbortedByUserError if the user chose *not* to continue def ask_to_continue answer = prompt("Do you want to continue (yes/no)? ".color(:blue), %w{yes no}) raise Gitlab::TaskAbortedByUserError unless answer == "yes" end # Check which OS is running # # It will primarily use lsb_relase to determine the OS. # It has fallbacks to Debian, SuSE, OS X and systems running systemd. def os_name os_name = run_command(%W(lsb_release -irs)) os_name ||= if File.readable?('/etc/system-release') File.read('/etc/system-release') end os_name ||= if File.readable?('/etc/debian_version') debian_version = File.read('/etc/debian_version') "Debian #{debian_version}" end os_name ||= if File.readable?('/etc/SuSE-release') File.read('/etc/SuSE-release') end os_name ||= if os_x_version = run_command(%W(sw_vers -productVersion)) "Mac OS X #{os_x_version}" end os_name ||= if File.readable?('/etc/os-release') File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1] end os_name.try(:squish!) end # Prompt the user to input something # # message - the message to display before input # choices - array of strings of acceptable answers or nil for any answer # # Returns the user's answer def prompt(message, choices = nil) begin print(message) answer = STDIN.gets.chomp end while choices.present? && !choices.include?(answer) answer end # Runs the given command and matches the output against the given pattern # # Returns nil if nothing matched # Returns the MatchData if the pattern matched # # see also #run_command # see also String#match def run_and_match(command, regexp) run_command(command).try(:match, regexp) end # Runs the given command # # Returns nil if the command was not found # Returns the output of the command otherwise # # see also #run_and_match def run_command(command) output, _ = Gitlab::Popen.popen(command) output rescue Errno::ENOENT '' # if the command does not exist, return an empty string end def uid_for(user_name) run_command(%W(id -u #{user_name})).chomp.to_i end def gid_for(group_name) begin Etc.getgrnam(group_name).gid rescue ArgumentError # no group "group #{group_name} doesn't exist" end end def warn_user_is_not_gitlab unless @warned_user_not_gitlab gitlab_user = Gitlab.config.gitlab.user current_user = run_command(%W(whoami)).chomp unless current_user == gitlab_user puts " Warning ".color(:black).background(:yellow) puts " You are running as user #{current_user.color(:magenta)}, we hope you know what you are doing." puts " Things may work\/fail for the wrong reasons." puts " For correct results you should run this as user #{gitlab_user.color(:magenta)}." puts "" end @warned_user_not_gitlab = true end end # Tries to configure git itself # # Returns true if all subcommands were successfull (according to their exit code) # Returns false if any or all subcommands failed. def auto_fix_git_config(options) if !@warned_user_not_gitlab command_success = options.map do |name, value| system(*%W(#{Gitlab.config.git.bin_path} config --global #{name} #{value})) end command_success.all? else false end end def all_repos Gitlab.config.repositories.storages.each do |name, path| IO.popen(%W(find #{path} -mindepth 2 -maxdepth 2 -type d -name *.git)) do |find| find.each_line do |path| yield path.chomp end end end end def repository_storage_paths_args Gitlab.config.repositories.storages.values end end