Merge branch 'master' into discussions

Conflicts:
	app/assets/stylesheets/main.scss
	app/models/project.rb
	app/views/notes/_common_form.html.haml
	app/views/notes/_per_line_form.html.haml
	lib/gitlab/markdown.rb
	spec/models/note_spec.rb
This commit is contained in:
Riyad Preukschas 2012-12-23 01:03:57 +01:00
commit db2c15369c
276 changed files with 4466 additions and 2603 deletions

View file

@ -2,7 +2,7 @@ Dir["#{Rails.root}/lib/api/*.rb"].each {|file| require file}
module Gitlab
class API < Grape::API
version 'v2', using: :path
version 'v3', using: :path
rescue_from ActiveRecord::RecordNotFound do
rack_response({'message' => '404 Not found'}.to_json, 404)

View file

@ -1,12 +1,12 @@
module Gitlab
module Entities
class User < Grape::Entity
expose :id, :email, :name, :bio, :skype, :linkedin, :twitter,
expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter,
:dark_scheme, :theme_id, :blocked, :created_at
end
class UserBasic < Grape::Entity
expose :id, :email, :name, :blocked, :created_at
expose :id, :username, :email, :name, :blocked, :created_at
end
class UserLogin < UserBasic
@ -18,7 +18,7 @@ module Gitlab
end
class Project < Grape::Entity
expose :id, :code, :name, :description, :path, :default_branch
expose :id, :name, :description, :default_branch
expose :owner, using: Entities::UserBasic
expose :private_flag, as: :private
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at

View file

@ -5,13 +5,18 @@ module Gitlab
end
def user_project
if @project ||= current_user.projects.find_by_id(params[:id]) ||
current_user.projects.find_by_path(params[:id])
else
not_found!
end
@project ||= find_project
@project || not_found!
end
@project
def find_project
project = Project.find_by_id(params[:id]) || Project.find_with_namespace(params[:id])
if project && can?(current_user, :read_project, project)
project
else
nil
end
end
def paginate(object)
@ -32,6 +37,10 @@ module Gitlab
end
end
def can?(object, action, subject)
abilities.allowed?(object, action, subject)
end
def attributes_for_keys(keys)
attrs = {}
keys.each do |key|

View file

@ -17,7 +17,7 @@ module Gitlab
# Get a list of project issues
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/issues
get ":id/issues" do
@ -27,7 +27,7 @@ module Gitlab
# Get a single project issue
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# issue_id (required) - The ID of a project issue
# Example Request:
# GET /projects/:id/issues/:issue_id
@ -39,7 +39,7 @@ module Gitlab
# Create a new project issue
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# title (required) - The title of an issue
# description (optional) - The description of an issue
# assignee_id (optional) - The ID of a user to assign issue
@ -62,7 +62,7 @@ module Gitlab
# Update an existing issue
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# issue_id (required) - The ID of a project issue
# title (optional) - The title of an issue
# description (optional) - The description of an issue
@ -88,7 +88,7 @@ module Gitlab
# Delete a project issue (deprecated)
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# issue_id (required) - The ID of a project issue
# Example Request:
# DELETE /projects/:id/issues/:issue_id

View file

@ -8,7 +8,7 @@ module Gitlab
# List merge requests
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
#
# Example:
# GET /projects/:id/merge_requests
@ -22,7 +22,7 @@ module Gitlab
# Show MR
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# merge_request_id (required) - The ID of MR
#
# Example:
@ -40,7 +40,7 @@ module Gitlab
#
# Parameters:
#
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# source_branch (required) - The source branch
# target_branch (required) - The target branch
# assignee_id - Assignee user ID
@ -67,7 +67,7 @@ module Gitlab
# Update MR
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# source_branch - The source branch
# target_branch - The target branch
@ -95,7 +95,7 @@ module Gitlab
# Post comment to merge request
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# note (required) - Text of comment
# Examples:

View file

@ -7,7 +7,7 @@ module Gitlab
# Get a list of project milestones
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/milestones
get ":id/milestones" do
@ -19,7 +19,7 @@ module Gitlab
# Get a single project milestone
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# milestone_id (required) - The ID of a project milestone
# Example Request:
# GET /projects/:id/milestones/:milestone_id
@ -33,7 +33,7 @@ module Gitlab
# Create a new project milestone
#
# Parameters:
# id (required) - The ID or code name of the project
# id (required) - The ID of the project
# title (required) - The title of the milestone
# description (optional) - The description of the milestone
# due_date (optional) - The due date of the milestone
@ -54,7 +54,7 @@ module Gitlab
# Update an existing project milestone
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# milestone_id (required) - The ID of a project milestone
# title (optional) - The title of a milestone
# description (optional) - The description of a milestone

View file

@ -9,7 +9,7 @@ module Gitlab
# Get a list of project wall notes
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/notes
get ":id/notes" do
@ -20,7 +20,7 @@ module Gitlab
# Get a single project wall note
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# note_id (required) - The ID of a note
# Example Request:
# GET /projects/:id/notes/:note_id
@ -32,7 +32,7 @@ module Gitlab
# Create a new project wall note
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# body (required) - The content of a note
# Example Request:
# POST /projects/:id/notes
@ -54,7 +54,7 @@ module Gitlab
# Get a list of project +noteable+ notes
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# noteable_id (required) - The ID of an issue or snippet
# Example Request:
# GET /projects/:id/issues/:noteable_id/notes
@ -67,7 +67,7 @@ module Gitlab
# Get a single +noteable+ note
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# noteable_id (required) - The ID of an issue or snippet
# note_id (required) - The ID of a note
# Example Request:
@ -82,7 +82,7 @@ module Gitlab
# Create a new +noteable+ note
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# noteable_id (required) - The ID of an issue or snippet
# body (required) - The content of a note
# Example Request:

View file

@ -16,7 +16,7 @@ module Gitlab
# Get a single project
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id
get ":id" do
@ -27,8 +27,6 @@ module Gitlab
#
# Parameters:
# name (required) - name for new project
# code (optional) - code for new project, uses project name if not set
# path (optional) - path for new project, uses project name if not set
# description (optional) - short project description
# default_branch (optional) - 'master' by default
# issues_enabled (optional) - enabled by default
@ -56,18 +54,23 @@ module Gitlab
# Get a project team members
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# query - Query string
# Example Request:
# GET /projects/:id/members
get ":id/members" do
@members = paginate user_project.users
if params[:query].present?
@members = paginate user_project.users.where("username LIKE ?", "%#{params[:query]}%")
else
@members = paginate user_project.users
end
present @members, with: Entities::ProjectMember, project: user_project
end
# Get a project team members
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# user_id (required) - The ID of a user
# Example Request:
# GET /projects/:id/members/:user_id
@ -79,7 +82,7 @@ module Gitlab
# Add a new project team member
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# user_id (required) - The ID of a user
# access_level (required) - Project access level
# Example Request:
@ -102,7 +105,7 @@ module Gitlab
# Update project team member
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# user_id (required) - The ID of a team member
# access_level (required) - Project access level
# Example Request:
@ -122,7 +125,7 @@ module Gitlab
# Remove a team member from project
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# user_id (required) - The ID of a team member
# Example Request:
# DELETE /projects/:id/members/:user_id
@ -135,7 +138,7 @@ module Gitlab
# Get project hooks
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/hooks
get ":id/hooks" do
@ -147,7 +150,7 @@ module Gitlab
# Get a project hook
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# hook_id (required) - The ID of a project hook
# Example Request:
# GET /projects/:id/hooks/:hook_id
@ -160,7 +163,7 @@ module Gitlab
# Add hook to project
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# url (required) - The hook URL
# Example Request:
# POST /projects/:id/hooks
@ -177,7 +180,7 @@ module Gitlab
# Update an existing project hook
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# hook_id (required) - The ID of a project hook
# url (required) - The hook URL
# Example Request:
@ -198,7 +201,7 @@ module Gitlab
# Delete project hook
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# hook_id (required) - The ID of hook to delete
# Example Request:
# DELETE /projects/:id/hooks
@ -211,7 +214,7 @@ module Gitlab
# Get a project repository branches
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/repository/branches
get ":id/repository/branches" do
@ -221,7 +224,7 @@ module Gitlab
# Get a single branch
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# branch (required) - The name of the branch
# Example Request:
# GET /projects/:id/repository/branches/:branch
@ -233,7 +236,7 @@ module Gitlab
# Get a project repository tags
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/repository/tags
get ":id/repository/tags" do
@ -243,7 +246,7 @@ module Gitlab
# Get a project repository commits
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# ref_name (optional) - The name of a repository branch or tag
# Example Request:
# GET /projects/:id/repository/commits
@ -261,7 +264,7 @@ module Gitlab
# Get a project snippets
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/snippets
get ":id/snippets" do
@ -271,7 +274,7 @@ module Gitlab
# Get a project snippet
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# snippet_id (required) - The ID of a project snippet
# Example Request:
# GET /projects/:id/snippets/:snippet_id
@ -283,7 +286,7 @@ module Gitlab
# Create a new project snippet
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# title (required) - The title of a snippet
# file_name (required) - The name of a snippet file
# lifetime (optional) - The expiration date of a snippet
@ -309,7 +312,7 @@ module Gitlab
# Update an existing project snippet
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# snippet_id (required) - The ID of a project snippet
# title (optional) - The title of a snippet
# file_name (optional) - The name of a snippet file
@ -335,7 +338,7 @@ module Gitlab
# Delete a project snippet
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# snippet_id (required) - The ID of a project snippet
# Example Request:
# DELETE /projects/:id/snippets/:snippet_id
@ -349,7 +352,7 @@ module Gitlab
# Get a raw project snippet
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# snippet_id (required) - The ID of a project snippet
# Example Request:
# GET /projects/:id/snippets/:snippet_id/raw
@ -362,7 +365,7 @@ module Gitlab
# Get a raw file contents
#
# Parameters:
# id (required) - The ID or code name of a project
# id (required) - The ID of a project
# sha (required) - The commit or branch name
# filepath (required) - The path to the file to display
# Example Request:

View file

@ -101,8 +101,6 @@ module Gitlab
key = current_user.keys.find params[:id]
key.delete
end
end
end
end

View file

@ -38,7 +38,7 @@ module Gitlab
email: email,
password: password,
password_confirmation: password,
projects_limit: Gitlab.config.default_projects_limit,
projects_limit: Gitlab.config.gitlab.default_projects_limit,
}, as: :admin)
if Gitlab.config.omniauth['block_auto_created_users'] && !ldap
@user.blocked = true

View file

@ -38,7 +38,7 @@ module Gitlab
end
def url_to_repo path
Gitlab.config.ssh_path + "#{path}.git"
Gitlab.config.gitolite.ssh_path_prefix + "#{path}.git"
end
def enable_automerge

View file

@ -16,7 +16,7 @@ module Gitlab
def ga_repo
@ga_repo ||= ::Gitolite::GitoliteAdmin.new(
File.join(config_tmp_dir,'gitolite'),
conf: Gitlab.config.gitolite_config_file
conf: Gitlab.config.gitolite.config_file
)
end
@ -167,7 +167,7 @@ module Gitlab
# Enable access to all repos for gitolite admin.
# We use it for accept merge request feature
def admin_all_repo
owner_name = Gitlab.config.gitolite_admin_key
owner_name = Gitlab.config.gitolite.admin_key
# @ALL repos premission for gitolite owner
repo_name = "@all"
@ -189,7 +189,7 @@ module Gitlab
def pull tmp_dir
Dir.mkdir tmp_dir
`git clone #{Gitlab.config.gitolite_admin_uri} #{tmp_dir}/gitolite`
`git clone #{Gitlab.config.gitolite.admin_uri} #{tmp_dir}/gitolite`
unless File.exists?(File.join(tmp_dir, 'gitolite', 'conf', 'gitolite.conf'))
raise PullError, "unable to clone gitolite-admin repo"

View file

@ -38,12 +38,12 @@ module Grack
end
def validate_get_request
true
can?(user, :download_code, project)
end
def validate_post_request
if @request.path_info.end_with?('git-upload-pack')
can?(user, :push_code, project)
can?(user, :download_code, project)
elsif @request.path_info.end_with?('git-receive-pack')
action = if project.protected_branch?(current_ref)
:push_code_to_protected_branches

View file

@ -28,7 +28,7 @@ module Gitlab
h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil?
h[:id] = sha
h[:date] = date
h[:message] = escape_once(message)
h[:message] = message
h[:login] = author.email
h
end

View file

@ -17,16 +17,15 @@ module Gitlab
@commits = collect_commits
@days = index_commits
end
def days_json
@days_json = @days.compact.map { |d| [d.day, d.strftime("%b")] }.to_json
def to_json(*args)
{
days: @days.compact.map { |d| [d.day, d.strftime("%b")] },
commits: @commits.map(&:to_graph_hash)
}.to_json(*args)
end
def commits_json
@commits_json = @commits.map(&:to_graph_hash).to_json
end
protected
protected
# Get commits from repository
#

View file

@ -14,6 +14,11 @@ module Gitlab
logs = `tail -n 2000 #{path}`.split("\n")
end
def self.read_latest_for filename
path = Rails.root.join("log", filename)
logs = `tail -n 2000 #{path}`.split("\n")
end
def self.build
new(Rails.root.join("log", file_name))
end

View file

@ -81,28 +81,32 @@ module Gitlab
end
REFERENCE_PATTERN = %r{
(\W)? # Prefix (1)
( # Reference (2)
@([\w\._]+) # User name (3)
|[#!$](\d+) # Issue/MR/Snippet ID (4)
|([\h]{6,40}) # Commit ID (5)
(?<prefix>\W)? # Prefix
( # Reference
@(?<user>[a-zA-Z][a-zA-Z0-9_\-\.]*) # User name
|\#(?<issue>\d+) # Issue ID
|!(?<merge_request>\d+) # MR ID
|\$(?<snippet>\d+) # Snippet ID
|(?<commit>[\h]{6,40}) # Commit ID
)
(\W)? # Suffix (6)
(?<suffix>\W)? # Suffix
}x.freeze
TYPES = [:user, :issue, :merge_request, :snippet, :commit].freeze
def parse_references(text)
# parse reference links
text.gsub!(REFERENCE_PATTERN) do |match|
prefix = $1 || ''
reference = $2
identifier = $3 || $4 || $5
suffix = $6 || ''
prefix = $~[:prefix]
suffix = $~[:suffix]
type = TYPES.select{|t| !$~[t].nil?}.first
identifier = $~[type]
# Avoid HTML entities
if prefix.ends_with?('&') || suffix.starts_with?(';')
if prefix && suffix && prefix[0] == '&' && suffix[-1] == ';'
match
elsif ref_link = reference_link(reference, identifier)
prefix + ref_link + suffix
elsif ref_link = reference_link(type, identifier)
"#{prefix}#{ref_link}#{suffix}"
else
match
end
@ -115,7 +119,7 @@ module Gitlab
# parse emoji
text.gsub!(EMOJI_PATTERN) do |match|
if valid_emoji?($2)
image_tag("emoji/#{$2}.png", class: 'emoji', title: $1, alt: $1)
image_tag("emoji/#{$2}.png", class: 'emoji', title: $1, alt: $1, size: "20x20")
else
match
end
@ -137,19 +141,12 @@ module Gitlab
# identifier - Object identifier (Issue ID, SHA hash, etc.)
#
# Returns string rendered by the processing method
def reference_link(reference, identifier)
case reference
when /^@/ then reference_user(identifier)
when /^#/ then reference_issue(identifier)
when /^!/ then reference_merge_request(identifier)
when /^\$/ then reference_snippet(identifier)
when /^\h/ then reference_commit(identifier)
end
def reference_link(type, identifier)
send("reference_#{type}", identifier)
end
def reference_user(identifier)
if user = @project.users.where(name: identifier).first
member = @project.users_projects.where(user_id: user).first
if member = @project.users_projects.joins(:user).where(users: { username: identifier }).first
link_to("@#{identifier}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
end
end

View file

@ -15,10 +15,10 @@ module Gitlab
def execute
# Create new dir if missing
new_dir_path = File.join(Gitlab.config.git_base_path, new_dir)
new_dir_path = File.join(Gitlab.config.gitolite.repos_path, new_dir)
system("mkdir -m 770 #{new_dir_path}") unless File.exists?(new_dir_path)
old_path = File.join(Gitlab.config.git_base_path, old_dir, "#{project.path}.git")
old_path = File.join(Gitlab.config.gitolite.repos_path, old_dir, "#{project.path}.git")
new_path = File.join(new_dir_path, "#{project.path}.git")
if File.exists? new_path

View file

@ -6,7 +6,6 @@
while read oldrev newrev ref
do
# For every branch or tag that was pushed, create a Resque job in redis.
pwd=`pwd`
reponame=`basename "$pwd" | sed s/\.git$//`
env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$reponame\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1
repo_path=`pwd`
env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$repo_path\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1
done

View file

@ -11,14 +11,20 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
def block_code(code, language)
options = { options: {encoding: 'utf-8'} }
options.merge!(lexer: language.downcase) if Pygments::Lexer.find(language)
h.content_tag :div, class: h.user_color_scheme_class do
if Pygments::Lexer.find(language)
Pygments.highlight(code, options.merge(lexer: language.downcase))
else
Pygments.highlight(code, options)
end.html_safe
end
# New lines are placed to fix an rendering issue
# with code wrapped inside <h1> tag for next case:
#
# # Title kinda h1
#
# ruby code here
#
<<-HTML
<div class="#{h.user_color_scheme_class}">#{Pygments.highlight(code, options)}</div>
HTML
end
def postprocess(full_document)

View file

@ -1,20 +0,0 @@
desc "Add all users to all projects (admin users are added as masters)"
task :add_users_to_project_teams => :environment do |t, args|
user_ids = User.where(:admin => false).pluck(:id)
admin_ids = User.where(:admin => true).pluck(:id)
Project.find_each do |project|
puts "Importing #{user_ids.size} users into #{project.code}"
UsersProject.bulk_import(project, user_ids, UsersProject::DEVELOPER)
puts "Importing #{admin_ids.size} admins into #{project.code}"
UsersProject.bulk_import(project, admin_ids, UsersProject::MASTER)
end
end
desc "Add user to as a developer to all projects"
task :add_user_to_project_teams, [:email] => :environment do |t, args|
user = User.find_by_email args.email
project_ids = Project.pluck(:id)
UsersProject.user_bulk_import(user, project_ids, UsersProject::DEVELOPER)
end

View file

@ -1,14 +1,14 @@
require 'active_record/fixtures'
namespace :gitlab do
namespace :app do
namespace :backup do
# Create backup of GitLab system
desc "GITLAB | Create a backup of the GitLab system"
task :backup_create => :environment do
Rake::Task["gitlab:app:db_dump"].invoke
Rake::Task["gitlab:app:repo_dump"].invoke
task :create => :environment do
Rake::Task["gitlab:backup:db:create"].invoke
Rake::Task["gitlab:backup:repo:create"].invoke
Dir.chdir(Gitlab.config.backup_path)
Dir.chdir(Gitlab.config.backup.path)
# saving additional informations
s = {}
@ -17,7 +17,7 @@ namespace :gitlab do
s[:gitlab_version] = %x{git rev-parse HEAD}.gsub(/\n/,"")
s[:tar_version] = %x{tar --version | head -1}.gsub(/\n/,"")
File.open("#{Gitlab.config.backup_path}/backup_information.yml", "w+") do |file|
File.open("#{Gitlab.config.backup.path}/backup_information.yml", "w+") do |file|
file << s.to_yaml.gsub(/^---\n/,'')
end
@ -39,10 +39,10 @@ namespace :gitlab do
# delete backups
print "Deleting old backups... "
if Gitlab.config.backup_keep_time > 0
if Gitlab.config.backup.keep_time > 0
file_list = Dir.glob("*_gitlab_backup.tar").map { |f| f.split(/_/).first.to_i }
file_list.sort.each do |timestamp|
if Time.at(timestamp) < (Time.now - Gitlab.config.backup_keep_time)
if Time.at(timestamp) < (Time.now - Gitlab.config.backup.keep_time)
%x{rm #{timestamp}_gitlab_backup.tar}
end
end
@ -54,15 +54,15 @@ namespace :gitlab do
# Restore backup of GitLab system
desc "GITLAB | Restore a previously created backup"
task :backup_restore => :environment do
Dir.chdir(Gitlab.config.backup_path)
task :restore => :environment do
Dir.chdir(Gitlab.config.backup.path)
# check for existing backups in the backup dir
file_list = Dir.glob("*_gitlab_backup.tar").each.map { |f| f.split(/_/).first.to_i }
puts "no backups found" if file_list.count == 0
if file_list.count > 1 && ENV["BACKUP"].nil?
puts "Found more than one backup, please specify which one you want to restore:"
puts "rake gitlab:app:backup_restore BACKUP=timestamp_of_backup"
puts "rake gitlab:backup:restore BACKUP=timestamp_of_backup"
exit 1;
end
@ -93,8 +93,8 @@ namespace :gitlab do
exit 1
end
Rake::Task["gitlab:app:db_restore"].invoke
Rake::Task["gitlab:app:repo_restore"].invoke
Rake::Task["gitlab:backup:db:restore"].invoke
Rake::Task["gitlab:backup:repo:restore"].invoke
# cleanup: remove tmp files
print "Deleting tmp directories..."
@ -110,82 +110,86 @@ namespace :gitlab do
################################# REPOSITORIES #################################
task :repo_dump => :environment do
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
puts "Dumping repositories:"
project = Project.all.map { |n| [n.path, n.path_to_repo] }
project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
project.each do |project|
print "- Dumping repository #{project.first}... "
if Kernel.system("cd #{project.second} > /dev/null 2>&1 && git bundle create #{backup_path_repo}/#{project.first}.bundle --all > /dev/null 2>&1")
puts "[DONE]".green
else
puts "[FAILED]".red
namespace :repo do
task :create => :environment do
backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
puts "Dumping repositories:"
project = Project.all.map { |n| [n.path, n.path_to_repo] }
project << ["gitolite-admin.git", File.join(Gitlab.config.git_base_path, "gitolite-admin.git")]
project.each do |project|
print "- Dumping repository #{project.first}... "
if Kernel.system("cd #{project.second} > /dev/null 2>&1 && git bundle create #{backup_path_repo}/#{project.first}.bundle --all > /dev/null 2>&1")
puts "[DONE]".green
else
puts "[FAILED]".red
end
end
end
end
task :repo_restore => :environment do
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
puts "Restoring repositories:"
project = Project.all.map { |n| [n.path, n.path_to_repo] }
project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
project.each do |project|
print "- Restoring repository #{project.first}... "
FileUtils.rm_rf(project.second) if File.dirname(project.second) # delete old stuff
if Kernel.system("cd #{File.dirname(project.second)} > /dev/null 2>&1 && git clone --bare #{backup_path_repo}/#{project.first}.bundle #{project.first}.git > /dev/null 2>&1")
permission_commands = [
"sudo chmod -R g+rwX #{Gitlab.config.git_base_path}",
"sudo chown -R #{Gitlab.config.ssh_user}:#{Gitlab.config.ssh_user} #{Gitlab.config.git_base_path}"
]
permission_commands.each { |command| Kernel.system(command) }
puts "[DONE]".green
else
puts "[FAILED]".red
task :restore => :environment do
backup_path_repo = File.join(Gitlab.config.backup.path, "repositories")
puts "Restoring repositories:"
project = Project.all.map { |n| [n.path, n.path_to_repo] }
project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
project.each do |project|
print "- Restoring repository #{project.first}... "
FileUtils.rm_rf(project.second) if File.dirname(project.second) # delete old stuff
if Kernel.system("cd #{File.dirname(project.second)} > /dev/null 2>&1 && git clone --bare #{backup_path_repo}/#{project.first}.bundle #{project.first}.git > /dev/null 2>&1")
permission_commands = [
"sudo chmod -R g+rwX #{Gitlab.config.git_base_path}",
"sudo chown -R #{Gitlab.config.ssh_user}:#{Gitlab.config.ssh_user} #{Gitlab.config.git_base_path}"
]
permission_commands.each { |command| Kernel.system(command) }
puts "[DONE]".green
else
puts "[FAILED]".red
end
end
end
end
###################################### DB ######################################
task :db_dump => :environment do
backup_path_db = File.join(Gitlab.config.backup_path, "db")
FileUtils.mkdir_p(backup_path_db) unless Dir.exists?(backup_path_db)
namespace :db do
task :create => :environment do
backup_path_db = File.join(Gitlab.config.backup.path, "db")
FileUtils.mkdir_p(backup_path_db) unless Dir.exists?(backup_path_db)
puts "Dumping database tables:"
ActiveRecord::Base.connection.tables.each do |tbl|
print "- Dumping table #{tbl}... "
count = 1
File.open(File.join(backup_path_db, tbl + ".yml"), "w+") do |file|
ActiveRecord::Base.connection.select_all("SELECT * FROM `#{tbl}`").each do |line|
line.delete_if{|k,v| v.blank?}
output = {tbl + '_' + count.to_s => line}
file << output.to_yaml.gsub(/^---\n/,'') + "\n"
count += 1
puts "Dumping database tables:"
ActiveRecord::Base.connection.tables.each do |tbl|
print "- Dumping table #{tbl}... "
count = 1
File.open(File.join(backup_path_db, tbl + ".yml"), "w+") do |file|
ActiveRecord::Base.connection.select_all("SELECT * FROM `#{tbl}`").each do |line|
line.delete_if{|k,v| v.blank?}
output = {tbl + '_' + count.to_s => line}
file << output.to_yaml.gsub(/^---\n/,'') + "\n"
count += 1
end
puts "[DONE]".green
end
end
end
task :restore=> :environment do
backup_path_db = File.join(Gitlab.config.backup.path, "db")
puts "Restoring database tables:"
Rake::Task["db:reset"].invoke
Dir.glob(File.join(backup_path_db, "*.yml") ).each do |dir|
fixture_file = File.basename(dir, ".*" )
print "- Loading fixture #{fixture_file}..."
if File.size(dir) > 0
ActiveRecord::Fixtures.create_fixtures(backup_path_db, fixture_file)
puts "[DONE]".green
else
puts "[SKIPPING]".yellow
end
puts "[DONE]".green
end
end
end
task :db_restore=> :environment do
backup_path_db = File.join(Gitlab.config.backup_path, "db")
puts "Restoring database tables:"
Rake::Task["db:reset"].invoke
Dir.glob(File.join(backup_path_db, "*.yml") ).each do |dir|
fixture_file = File.basename(dir, ".*" )
print "- Loading fixture #{fixture_file}..."
if File.size(dir) > 0
ActiveRecord::Fixtures.create_fixtures(backup_path_db, fixture_file)
puts "[DONE]".green
else
puts "[SKIPPING]".yellow
end
end
end
end # namespace end: app
end # namespace end: backup
end # namespace end: gitlab

View file

@ -0,0 +1,24 @@
namespace :gitlab do
namespace :import do
desc "GITLAB | Add all users to all projects (admin users are added as masters)"
task :all_users_to_all_projects => :environment do |t, args|
user_ids = User.where(:admin => false).pluck(:id)
admin_ids = User.where(:admin => true).pluck(:id)
Project.find_each do |project|
puts "Importing #{user_ids.size} users into #{project.code}"
UsersProject.bulk_import(project, user_ids, UsersProject::DEVELOPER)
puts "Importing #{admin_ids.size} admins into #{project.code}"
UsersProject.bulk_import(project, admin_ids, UsersProject::MASTER)
end
end
desc "GITLAB | Add a specific user to all projects (as a developer)"
task :user_to_projects, [:email] => :environment do |t, args|
user = User.find_by_email args.email
project_ids = Project.pluck(:id)
UsersProject.user_bulk_import(user, project_ids, UsersProject::DEVELOPER)
end
end
end

968
lib/tasks/gitlab/check.rake Normal file
View file

@ -0,0 +1,968 @@
namespace :gitlab do
desc "GITLAB | Check the configuration of GitLab and its environment"
task check: %w{gitlab:env:check
gitlab:gitolite:check
gitlab:resque:check
gitlab:app:check}
namespace :app do
desc "GITLAB | Check the configuration of the GitLab Rails app"
task check: :environment do
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
check_satellites_exist
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"
)
check_failed
end
end
def check_database_is_not_sqlite
print "Database is not SQLite ... "
database_config_file = Rails.root.join("config", "database.yml")
unless File.read(database_config_file) =~ /sqlite/
puts "yes".green
else
puts "no".red
for_more_information(
"https://github.com/gitlabhq/gitlabhq/wiki/Migrate-from-SQLite-to-MySQL",
see_database_guide
)
check_failed
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"
)
check_failed
end
end
def check_gitlab_config_not_outdated
print "GitLab config outdated? ... "
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
unless Gitlab.config.pre_40_config
puts "no".green
else
puts "yes".red
try_fixing_it(
"Backup your config/gitlab.yml",
"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"
)
check_failed
end
end
def check_init_script_exists
print "Init script exists? ... "
script_path = "/etc/init.d/gitlab"
if File.exists?(script_path)
puts "yes".green
else
puts "no".red
try_fixing_it(
"Install the init script"
)
for_more_information(
see_installation_guide_section "Install Init Script"
)
check_failed
end
end
def check_init_script_up_to_date
print "Init script up-to-date? ... "
script_path = "/etc/init.d/gitlab"
unless File.exists?(script_path)
puts "can't check because of previous errors".magenta
return
end
recipe_content = `curl https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab 2>/dev/null`
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"
)
check_failed
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
else
puts "no".red
try_fixing_it(
"sudo -u gitlab -H bundle exec rake db:migrate"
)
check_failed
end
end
def check_satellites_exist
print "Projects have satellites? ... "
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.satellite.exists?
puts "yes".green
else
puts "no".red
try_fixing_it(
"sudo -u gitlab -H bundle exec rake gitlab:satellites:create",
"If necessary, remove the tmp/repo_satellites directory ...",
"... and rerun the above command"
)
for_more_information(
"doc/raketasks/maintenance.md "
)
check_failed
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}",
"sudo chmod -R rwX #{log_path}"
)
for_more_information(
see_installation_guide_section "GitLab"
)
check_failed
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}",
"sudo chmod -R rwX #{tmp_path}"
)
for_more_information(
see_installation_guide_section "GitLab"
)
check_failed
end
end
end
namespace :env do
desc "GITLAB | Check the configuration of the environment"
task check: :environment do
warn_user_is_not_gitlab
start_checking "Environment"
check_gitlab_in_git_group
check_issue_1056_shell_profile_error
check_gitlab_git_config
check_python2_exists
check_python2_version
finished_checking "Environment"
end
# Checks
########################
def check_gitlab_git_config
print "Git configured for gitlab user? ... "
options = {
"user.name" => "GitLab",
"user.email" => Gitlab.config.gitlab.email_from
}
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(
"sudo -u gitlab -H git config --global user.name \"#{options["user.name"]}\"",
"sudo -u gitlab -H git config --global user.email \"#{options["user.email"]}\""
)
for_more_information(
see_installation_guide_section "GitLab"
)
check_failed
end
end
def check_gitlab_in_git_group
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
print "gitlab user is in #{gitolite_ssh_user} group? ... "
if run_and_match("id -rnG", /\Wgit\W/)
puts "yes".green
else
puts "no".red
try_fixing_it(
"sudo usermod -a -G #{gitolite_ssh_user} gitlab"
)
for_more_information(
see_installation_guide_section "System Users"
)
check_failed
end
end
# see https://github.com/gitlabhq/gitlabhq/issues/1059
def check_issue_1056_shell_profile_error
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
print "Has no \"-e\" in ~#{gitolite_ssh_user}/.profile ... "
profile_file = File.expand_path("~#{Gitlab.config.gitolite.ssh_user}/.profile")
unless File.read(profile_file) =~ /^-e PATH/
puts "yes".green
else
puts "no".red
try_fixing_it(
"Open #{profile_file}",
"Find the line starting with \"-e PATH\"",
"Remove \"-e \" so the line starts with PATH"
)
for_more_information(
see_installation_guide_section("Gitolite"),
"https://github.com/gitlabhq/gitlabhq/issues/1059"
)
check_failed
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"
)
check_failed
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"
)
check_failed
end
end
end
namespace :gitolite do
desc "GITLAB | Check the configuration of Gitolite"
task check: :environment do
warn_user_is_not_gitlab
start_checking "Gitolite"
check_gitolite_is_up_to_date
check_gitoliterc_repo_umask
check_gitoliterc_git_config_keys
check_dot_gitolite_exists
check_dot_gitolite_user_and_group
check_dot_gitolite_permissions
check_repo_base_exists
check_repo_base_user_and_group
check_repo_base_permissions
check_can_clone_gitolite_admin
check_can_commit_to_gitolite_admin
check_post_receive_hook_exists
check_post_receive_hook_is_up_to_date
check_repos_post_receive_hooks_is_link
check_repos_git_config
finished_checking "Gitolite"
end
# Checks
########################
def check_can_clone_gitolite_admin
print "Can clone gitolite-admin? ... "
test_path = "/tmp/gitlab_gitolite_admin_test"
FileUtils.rm_rf(test_path)
`git clone -q #{Gitlab.config.gitolite.admin_uri} #{test_path}`
raise unless $?.success?
puts "yes".green
rescue
puts "no".red
try_fixing_it(
"Make sure the \"admin_uri\" is set correctly in config/gitlab.yml",
"Try cloning it yourself with:",
" git clone -q #{Gitlab.config.gitolite.admin_uri} /tmp/gitolite-admin",
"Make sure Gitolite is installed correctly."
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
# assumes #check_can_clone_gitolite_admin has been run before
def check_can_commit_to_gitolite_admin
print "Can commit to gitolite-admin? ... "
test_path = "/tmp/gitlab_gitolite_admin_test"
unless File.exists?(test_path)
puts "can't check because of previous errors".magenta
return
end
Dir.chdir(test_path) do
`touch foo && git add foo && git commit -qm foo`
raise unless $?.success?
end
puts "yes".green
rescue
puts "no".red
try_fixing_it(
"Try committing to it yourself with:",
" git clone -q #{Gitlab.config.gitolite.admin_uri} /tmp/gitolite-admin",
" touch foo",
" git add foo",
" git commit -m \"foo\"",
"Make sure Gitolite is installed correctly."
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
ensure
FileUtils.rm_rf("/tmp/gitolite_gitlab_test")
end
def check_dot_gitolite_exists
print "Config directory exists? ... "
gitolite_config_path = File.expand_path("~#{Gitlab.config.gitolite.ssh_user}/.gitolite")
if File.directory?(gitolite_config_path)
puts "yes".green
else
puts "no".red
puts "#{gitolite_config_path} is missing".red
try_fixing_it(
"This should have been created when setting up Gitolite.",
"Make sure Gitolite is installed correctly."
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
end
def check_dot_gitolite_permissions
print "Config directory access is drwxr-x---? ... "
gitolite_config_path = File.expand_path("~#{Gitlab.config.gitolite.ssh_user}/.gitolite")
unless File.exists?(gitolite_config_path)
puts "can't check because of previous errors".magenta
return
end
if `stat --printf %a #{gitolite_config_path}` == "750"
puts "yes".green
else
puts "no".red
puts "#{gitolite_config_path} is not writable".red
try_fixing_it(
"sudo chmod 750 #{gitolite_config_path}"
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
end
def check_dot_gitolite_user_and_group
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
print "Config directory owned by #{gitolite_ssh_user}:#{gitolite_ssh_user} ... "
gitolite_config_path = File.expand_path("~#{gitolite_ssh_user}/.gitolite")
unless File.exists?(gitolite_config_path)
puts "can't check because of previous errors".magenta
return
end
if `stat --printf %U #{gitolite_config_path}` == gitolite_ssh_user && # user
`stat --printf %G #{gitolite_config_path}` == gitolite_ssh_user #group
puts "yes".green
else
puts "no".red
puts "#{gitolite_config_path} is not owned by #{gitolite_ssh_user}".red
try_fixing_it(
"sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{gitolite_config_path}"
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
end
def check_gitolite_is_up_to_date
print "Using recommended version ... "
if gitolite_version.try(:start_with?, "v3.04")
puts "yes".green
else
puts "no".red
try_fixing_it(
"We strongly recommend using the version pointed out in the installation guide."
)
for_more_information(
see_installation_guide_section "Gitolite"
)
# this is not a "hard" failure
end
end
def check_gitoliterc_git_config_keys
gitoliterc_path = File.join(gitolite_home, ".gitolite.rc")
print "Allow all Git config keys in .gitolite.rc ... "
option_name = if has_gitolite3?
# see https://github.com/sitaramc/gitolite/blob/v3.04/src/lib/Gitolite/Rc.pm#L329
"GIT_CONFIG_KEYS"
else
# assume older version
# see https://github.com/sitaramc/gitolite/blob/v2.3/conf/example.gitolite.rc#L49
"$GL_GITCONFIG_KEYS"
end
option_value = ".*"
if open(gitoliterc_path).grep(/#{option_name}\s*=[>]?\s*["']#{option_value}["']/).any?
puts "yes".green
else
puts "no".red
try_fixing_it(
"Open #{gitoliterc_path}",
"Find the \"#{option_name}\" option",
"Change its value to \".*\""
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
end
def check_gitoliterc_repo_umask
gitoliterc_path = File.join(gitolite_home, ".gitolite.rc")
print "Repo umask is 0007 in .gitolite.rc? ... "
option_name = if has_gitolite3?
# see https://github.com/sitaramc/gitolite/blob/v3.04/src/lib/Gitolite/Rc.pm#L328
"UMASK"
else
# assume older version
# see https://github.com/sitaramc/gitolite/blob/v2.3/conf/example.gitolite.rc#L32
"$REPO_UMASK"
end
option_value = "0007"
if open(gitoliterc_path).grep(/#{option_name}\s*=[>]?\s*#{option_value}/).any?
puts "yes".green
else
puts "no".red
try_fixing_it(
"Open #{gitoliterc_path}",
"Find the \"#{option_name}\" option",
"Change its value to \"0007\""
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
end
def check_post_receive_hook_exists
print "post-receive hook exists? ... "
hook_file = "post-receive"
gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
gitlab_hook_file = Rails.root.join.join("lib", "hooks", hook_file)
if File.exists?(gitolite_hook_file)
puts "yes".green
else
puts "no".red
try_fixing_it(
"sudo -u #{gitolite_ssh_user} cp #{gitlab_hook_file} #{gitolite_hook_file}"
)
for_more_information(
see_installation_guide_section "Setup GitLab Hooks"
)
check_failed
end
end
def check_post_receive_hook_is_up_to_date
print "post-receive hook up-to-date? ... "
hook_file = "post-receive"
gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
gitolite_hook_content = File.read(gitolite_hook_file)
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
unless File.exists?(gitolite_hook_file)
puts "can't check because of previous errors".magenta
return
end
gitlab_hook_file = Rails.root.join.join("lib", "hooks", hook_file)
gitlab_hook_content = File.read(gitlab_hook_file)
if gitolite_hook_content == gitlab_hook_content
puts "yes".green
else
puts "no".red
try_fixing_it(
"sudo -u #{gitolite_ssh_user} cp #{gitlab_hook_file} #{gitolite_hook_file}"
)
for_more_information(
see_installation_guide_section "Setup GitLab Hooks"
)
check_failed
end
end
def check_repo_base_exists
print "Repo base directory exists? ... "
repo_base_path = Gitlab.config.gitolite.repos_path
if File.exists?(repo_base_path)
puts "yes".green
else
puts "no".red
puts "#{repo_base_path} is missing".red
try_fixing_it(
"This should have been created when setting up Gitolite.",
"Make sure it's set correctly in config/gitlab.yml",
"Make sure Gitolite is installed correctly."
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
end
def check_repo_base_permissions
print "Repo base access is drwsrws---? ... "
repo_base_path = Gitlab.config.gitolite.repos_path
unless File.exists?(repo_base_path)
puts "can't check because of previous errors".magenta
return
end
if `stat --printf %a #{repo_base_path}` == "6770"
puts "yes".green
else
puts "no".red
puts "#{repo_base_path} is not writable".red
try_fixing_it(
"sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}"
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
end
def check_repo_base_user_and_group
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
print "Repo base owned by #{gitolite_ssh_user}:#{gitolite_ssh_user}? ... "
repo_base_path = Gitlab.config.gitolite.repos_path
unless File.exists?(repo_base_path)
puts "can't check because of previous errors".magenta
return
end
if `stat --printf %U #{repo_base_path}` == gitolite_ssh_user && # user
`stat --printf %G #{repo_base_path}` == gitolite_ssh_user #group
puts "yes".green
else
puts "no".red
puts "#{repo_base_path} is not owned by #{gitolite_ssh_user}".red
try_fixing_it(
"sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{repo_base_path}"
)
for_more_information(
see_installation_guide_section "Gitolite"
)
check_failed
end
end
def check_repos_git_config
print "Git config in repos: ... "
unless Project.count > 0
puts "can't check, you have no projects".magenta
return
end
puts ""
options = {
"core.sharedRepository" => "0660",
}
Project.find_each(batch_size: 100) do |project|
print "#{project.name_with_namespace.yellow} ... "
correct_options = options.map do |name, value|
run("git --git-dir=\"#{project.path_to_repo}\" config --get #{name}").try(:chomp) == value
end
if correct_options.all?
puts "ok".green
else
puts "wrong or missing".red
try_fixing_it(
"sudo -u gitlab -H bundle exec rake gitlab:gitolite:update_repos"
)
for_more_information(
"doc/raketasks/maintenance.md"
)
check_failed
end
end
end
def check_repos_post_receive_hooks_is_link
print "post-receive hooks in repos are links: ... "
hook_file = "post-receive"
gitolite_hooks_path = File.join(Gitlab.config.gitolite.hooks_path, "common")
gitolite_hook_file = File.join(gitolite_hooks_path, hook_file)
gitolite_ssh_user = Gitlab.config.gitolite.ssh_user
unless File.exists?(gitolite_hook_file)
puts "can't check because of previous errors".magenta
return
end
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} ... "
project_hook_file = File.join(project.path_to_repo, "hooks", hook_file)
unless File.exists?(project_hook_file)
puts "missing".red
try_fixing_it(
"sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}"
)
for_more_information(
"lib/support/rewrite-hooks.sh"
)
check_failed
next
end
if run_and_match("stat --format %N #{project_hook_file}", /#{hook_file}.+->.+#{gitolite_hook_file}/)
puts "ok".green
else
puts "not a link to Gitolite's hook".red
try_fixing_it(
"sudo -u #{gitolite_ssh_user} ln -sf #{gitolite_hook_file} #{project_hook_file}"
)
for_more_information(
"lib/support/rewrite-hooks.sh"
)
check_failed
end
end
end
# Helper methods
########################
def gitolite_home
File.expand_path("~#{Gitlab.config.gitolite.ssh_user}")
end
def gitolite_version
gitolite_version_file = "#{gitolite_home}/gitolite/src/VERSION"
if File.readable?(gitolite_version_file)
File.read(gitolite_version_file)
end
end
def has_gitolite3?
gitolite_version.try(:start_with?, "v3.")
end
end
namespace :resque do
desc "GITLAB | Check the configuration of Resque"
task check: :environment do
warn_user_is_not_gitlab
start_checking "Resque"
check_resque_running
finished_checking "Resque"
end
# Checks
########################
def check_resque_running
print "Running? ... "
if run_and_match("ps aux | grep -i resque", /resque-[\d\.]+:.+$/)
puts "yes".green
else
puts "no".red
try_fixing_it(
"sudo service gitlab restart",
"or",
"sudo /etc/init.d/gitlab restart"
)
for_more_information(
see_installation_guide_section("Install Init Script"),
"see log/resque.log for possible errors"
)
check_failed
end
end
end
# Helper methods
##########################
def check_failed
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
# 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)
unless `#{command} 2>/dev/null`.blank?
`#{command}`
end
end
# Runs the given command and matches the output agains the given pattern
#
# Returns nil if nothing matched
# Retunrs the MatchData if the pattern matched
#
# see also #run
# see also String#match
def run_and_match(command, pattern)
run(command).try(:match, pattern)
end
def see_database_guide
"doc/install/databases.md"
end
def see_installation_guide_section(section)
"doc/install/installation.md in section \"#{section}\""
end
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
def warn_user_is_not_gitlab
unless @warned_user_not_gitlab
current_user = run("whoami").chomp
unless current_user == "gitlab"
puts "#{Colored.color(:black)+Colored.color(:on_yellow)} Warning #{Colored.extra(:clear)}"
puts " You are running as user #{current_user.magenta}, we hope you know what you are doing."
puts " Some tests may pass\/fail for the wrong reason."
puts " For meaningful results you should run this as user #{"gitlab".magenta}."
puts ""
end
@warned_user_not_gitlab = true
end
end
end

View file

@ -1,17 +1,20 @@
namespace :gitlab do
namespace :app do
desc "GITLAB | Enable auto merge"
task :enable_automerge => :environment do
Gitlab::Gitolite.new.enable_automerge
desc "GITLAB | Enable auto merge"
task :enable_automerge => :environment do
Gitlab::Gitolite.new.enable_automerge
Project.find_each do |project|
if project.repo_exists? && !project.satellite.exists?
puts "Creating satellite for #{project.name}...".green
project.satellite.create
end
Project.find_each do |project|
if project.repo_exists? && !project.satellite.exists?
puts "Creating satellite for #{project.name}...".green
project.satellite.create
end
puts "Done!".green
end
puts "Done!".green
end
namespace :satellites do
desc "GITLAB | Create satellite repos"
task create: 'gitlab:enable_automerge'
end
end

View file

@ -1,6 +1,6 @@
namespace :gitlab do
desc "GITLAB | Enable usernames and namespaces for user projects"
task activate_namespaces: :environment do
task enable_namespaces: :environment do
print "\nUsernames for users:".yellow
User.find_each(batch_size: 500) do |user|
@ -27,7 +27,7 @@ namespace :gitlab do
end
print "\n\nMove projects from groups under groups dirs:".yellow
git_path = Gitlab.config.git_base_path
git_path = Gitlab.config.gitolite.repos_path
Project.where('namespace_id IS NOT NULL').find_each(batch_size: 500) do |project|
next unless project.group

View file

@ -12,7 +12,7 @@ namespace :gitlab do
desc "GITLAB | Import bare repositories from git_host -> base_path into GitLab project instance"
task :repos => :environment do
git_base_path = Gitlab.config.git_base_path
git_base_path = Gitlab.config.gitolite.repos_path
repos_to_import = Dir.glob(git_base_path + '/*')
repos_to_import.each do |repo_path|

110
lib/tasks/gitlab/info.rake Normal file
View file

@ -0,0 +1,110 @@
namespace :gitlab do
namespace :env do
desc "GITLAB | Show information about GitLab and its environment"
task info: :environment do
# check which OS is running
os_name = run("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.squish!
# check if there is an RVM environment
rvm_version = run_and_match("rvm --version", /[\d\.]+/).try(:to_s)
# check Ruby version
ruby_version = run_and_match("ruby --version", /[\d\.p]+/).try(:to_s)
# check Gem version
gem_version = run("gem --version")
# check Bundler version
bunder_version = run_and_match("bundle --version", /[\d\.]+/).try(:to_s)
# check Bundler version
rake_version = run_and_match("rake --version", /[\d\.]+/).try(:to_s)
puts ""
puts "System information".yellow
puts "System:\t\t#{os_name || "unknown".red}"
puts "Current User:\t#{`whoami`}"
puts "Using RVM:\t#{rvm_version.present? ? "yes".green : "no"}"
puts "RVM Version:\t#{rvm_version}" if rvm_version.present?
puts "Ruby Version:\t#{ruby_version || "unknown".red}"
puts "Gem Version:\t#{gem_version || "unknown".red}"
puts "Bundler Version:#{bunder_version || "unknown".red}"
puts "Rake Version:\t#{rake_version || "unknown".red}"
# check database adapter
database_adapter = ActiveRecord::Base.connection.adapter_name.downcase
project = Project.new(path: "some-project")
project.path = "some-project"
# construct clone URLs
http_clone_url = project.http_url_to_repo
ssh_clone_url = project.ssh_url_to_repo
omniauth_providers = Gitlab.config.omniauth.providers
omniauth_providers.map! { |provider| provider['name'] }
puts ""
puts "GitLab information".yellow
puts "Version:\t#{Gitlab::Version}"
puts "Revision:\t#{Gitlab::Revision}"
puts "Directory:\t#{Rails.root}"
puts "DB Adapter:\t#{database_adapter}"
puts "URL:\t\t#{Gitlab.config.gitlab.url}"
puts "HTTP Clone URL:\t#{http_clone_url}"
puts "SSH Clone URL:\t#{ssh_clone_url}"
puts "Using LDAP:\t#{Gitlab.config.ldap.enabled ? "yes".green : "no"}"
puts "Using Omniauth:\t#{Gitlab.config.omniauth.enabled ? "yes".green : "no"}"
puts "Omniauth Providers: #{omniauth_providers.map(&:magenta).join(', ')}" if Gitlab.config.omniauth.enabled
# check Gitolite version
gitolite_version_file = "#{Gitlab.config.gitolite.repos_path}/../gitolite/src/VERSION"
if File.exists?(gitolite_version_file) && File.readable?(gitolite_version_file)
gitolite_version = File.read(gitolite_version_file)
end
puts ""
puts "Gitolite information".yellow
puts "Version:\t#{gitolite_version || "unknown".red}"
puts "Admin URI:\t#{Gitlab.config.gitolite.admin_uri}"
puts "Admin Key:\t#{Gitlab.config.gitolite.admin_key}"
puts "Repositories:\t#{Gitlab.config.gitolite.repos_path}"
puts "Hooks:\t\t#{Gitlab.config.gitolite.hooks_path}"
puts "Git:\t\t#{Gitlab.config.git.bin_path}"
end
# Helper methods
# Runs the given command and matches the output agains the given pattern
#
# Returns nil if nothing matched
# Retunrs the MatchData if the pattern matched
#
# see also #run
# see also String#match
def run_and_match(command, regexp)
run(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)
unless `#{command} 2>/dev/null`.blank?
`#{command}`
end
end
end
end

View file

@ -4,7 +4,7 @@ namespace :gitlab do
task :setup => [
'db:setup',
'db:seed_fu',
'gitlab:app:enable_automerge'
'gitlab:enable_automerge'
]
end
end

View file

@ -1,113 +0,0 @@
namespace :gitlab do
namespace :app do
desc "GITLAB | Check GitLab installation status"
task :status => :environment do
puts "\nStarting diagnostics".yellow
git_base_path = Gitlab.config.git_base_path
print "config/database.yml............"
if File.exists?(Rails.root.join "config", "database.yml")
puts "exists".green
else
puts "missing".red
return
end
print "config/gitlab.yml............"
if File.exists?(Rails.root.join "config", "gitlab.yml")
puts "exists".green
else
puts "missing".red
return
end
print "#{git_base_path}............"
if File.exists?(git_base_path)
puts "exists".green
else
puts "missing".red
return
end
print "#{git_base_path} is writable?............"
if File.stat(git_base_path).writable?
puts "YES".green
else
puts "NO".red
return
end
FileUtils.rm_rf("/tmp/gitolite_gitlab_test")
begin
`git clone -q #{Gitlab.config.gitolite_admin_uri} /tmp/gitolite_gitlab_test`
raise unless $?.success?
print "Can clone gitolite-admin?............"
puts "YES".green
rescue
print "Can clone gitolite-admin?............"
puts "NO".red
return
end
begin
Dir.chdir("/tmp/gitolite_gitlab_test") do
`touch blah && git add blah && git commit -qm blah -- blah`
raise unless $?.success?
end
print "Can git commit?............"
puts "YES".green
rescue
print "Can git commit?............"
puts "NO".red
return
ensure
FileUtils.rm_rf("/tmp/gitolite_gitlab_test")
end
print "UMASK for .gitolite.rc is 0007? ............"
if open(File.absolute_path("#{git_base_path}/../.gitolite.rc")).grep(/UMASK([ \t]*)=([ \t>]*)0007/).any?
puts "YES".green
else
puts "NO".red
return
end
gitolite_hooks_path = File.join(Gitlab.config.git_hooks_path, "common")
gitlab_hook_files = ['post-receive']
gitlab_hook_files.each do |file_name|
dest = File.join(gitolite_hooks_path, file_name)
print "#{dest} exists? ............"
if File.exists?(dest)
puts "YES".green
else
puts "NO".red
return
end
end
if Project.count > 0
puts "\nValidating projects repositories:".yellow
Project.find_each(:batch_size => 100) do |project|
print "* #{project.name}....."
hook_file = File.join(project.path_to_repo, 'hooks', 'post-receive')
unless File.exists?(hook_file)
puts "post-receive file missing".red
next
end
original_content = File.read(Rails.root.join('lib', 'hooks', 'post-receive'))
new_content = File.read(hook_file)
if original_content == new_content
puts "post-receive file ok".green
else
puts "post-receive file content does not match".red
end
end
end
puts "\nFinished".blue
end
end
end

View file

@ -1,12 +1,8 @@
require 'resque/tasks'
# Fix Exception
# ActiveRecord::StatementInvalid
# Error
# PGError: ERROR: prepared statement "a3" already exists
task "resque:setup" => :environment do
Resque.after_fork do |job|
ActiveRecord::Base.establish_connection
Resque.after_fork do
Resque.redis.client.reconnect
end
end

View file

@ -1,5 +1,5 @@
task :travis do
["spinach", "rspec spec"].each do |cmd|
["rake spinach", "rake spec"].each do |cmd|
puts "Starting to run #{cmd}..."
system("export DISPLAY=:99.0 && bundle exec #{cmd}")
raise "#{cmd} failed!" unless $?.exitstatus == 0