Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/api/merge_requests.rb2
-rw-r--r--lib/backup/database.rb7
-rw-r--r--lib/backup/manager.rb2
-rw-r--r--lib/backup/repository.rb5
-rw-r--r--lib/backup/uploads.rb6
-rw-r--r--lib/gitlab/backend/grack_auth.rb11
-rw-r--r--lib/gitlab/backend/shell_env.rb11
-rw-r--r--lib/gitlab/bitbucket_import/client.rb21
-rw-r--r--lib/redcarpet/render/gitlab_html.rb8
-rw-r--r--lib/rouge/formatters/html_gitlab.rb168
-rw-r--r--lib/support/nginx/gitlab25
-rw-r--r--lib/support/nginx/gitlab-ssl25
-rw-r--r--lib/tasks/gitlab/check.rake8
-rw-r--r--lib/tasks/gitlab/import.rake4
-rw-r--r--lib/tasks/gitlab/update_commit_count.rake20
15 files changed, 298 insertions, 25 deletions
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index aa43e1dffd9..ce21c699e8f 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -229,7 +229,7 @@ module API
authorize! :read_merge_request, merge_request
- present paginate(merge_request.notes), with: Entities::MRNote
+ present paginate(merge_request.notes.fresh), with: Entities::MRNote
end
# Post comment to merge request
diff --git a/lib/backup/database.rb b/lib/backup/database.rb
index c5a5396cbbf..bbb230a10f0 100644
--- a/lib/backup/database.rb
+++ b/lib/backup/database.rb
@@ -7,7 +7,11 @@ module Backup
def initialize
@config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
@db_dir = File.join(Gitlab.config.backup.path, 'db')
- FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir)
+ FileUtils.rm_rf(@db_dir)
+ # Ensure the parent dir of @db_dir exists
+ FileUtils.mkdir_p(Gitlab.config.backup.path)
+ # Fail if somebody raced to create @db_dir before us
+ FileUtils.mkdir(@db_dir, mode: 0700)
end
def dump
@@ -25,7 +29,6 @@ module Backup
abort 'Backup failed' unless success
$progress.print 'Compressing database ... '
- FileUtils.rm_f db_file_name_gz
success = system('gzip', db_file_name)
report_success(success)
abort 'Backup failed: compress error' unless success
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index 6fa2079d1a8..9ae4b346436 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -16,8 +16,6 @@ module Backup
file << s.to_yaml.gsub(/^---\n/,'')
end
- FileUtils.chmod(0700, folders_to_backup)
-
# create archive
$progress.print "Creating backup archive: #{tar_file} ... "
orig_umask = File.umask(0077)
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
index dfb2da9f84e..4d70f7883dd 100644
--- a/lib/backup/repository.rb
+++ b/lib/backup/repository.rb
@@ -130,7 +130,10 @@ module Backup
def prepare
FileUtils.rm_rf(backup_repos_path)
- FileUtils.mkdir_p(backup_repos_path)
+ # Ensure the parent dir of backup_repos_path exists
+ FileUtils.mkdir_p(Gitlab.config.backup.path)
+ # Fail if somebody raced to create backup_repos_path before us
+ FileUtils.mkdir(backup_repos_path, mode: 0700)
end
def silent
diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb
index bf43610acf6..1f9626644e6 100644
--- a/lib/backup/uploads.rb
+++ b/lib/backup/uploads.rb
@@ -10,7 +10,11 @@ module Backup
# Copy uploads from public/uploads to backup/uploads
def dump
- FileUtils.mkdir_p(backup_uploads_dir)
+ FileUtils.rm_rf(backup_uploads_dir)
+ # Ensure the parent dir of backup_uploads_dir exists
+ FileUtils.mkdir_p(Gitlab.config.backup.path)
+ # Fail if somebody raced to create backup_uploads_dir before us
+ FileUtils.mkdir(backup_uploads_dir, mode: 0700)
FileUtils.cp_r(app_uploads_dir, backup_dir)
end
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb
index 03cef30c97d..12292f614e9 100644
--- a/lib/gitlab/backend/grack_auth.rb
+++ b/lib/gitlab/backend/grack_auth.rb
@@ -26,7 +26,12 @@ module Grack
auth!
if project && authorized_request?
- @app.call(env)
+ if ENV['GITLAB_GRACK_AUTH_ONLY'] == '1'
+ # Tell gitlab-git-http-server the request is OK, and what the GL_ID is
+ render_grack_auth_ok
+ else
+ @app.call(env)
+ end
elsif @user.nil? && !@gitlab_ci
unauthorized
else
@@ -174,6 +179,10 @@ module Grack
end
end
+ def render_grack_auth_ok
+ [200, { "Content-Type" => "application/json" }, [JSON.dump({ 'GL_ID' => Gitlab::ShellEnv.gl_id(@user) })]]
+ end
+
def render_not_found
[404, { "Content-Type" => "text/plain" }, ["Not Found"]]
end
diff --git a/lib/gitlab/backend/shell_env.rb b/lib/gitlab/backend/shell_env.rb
index 17ec029eed4..9f5adee594a 100644
--- a/lib/gitlab/backend/shell_env.rb
+++ b/lib/gitlab/backend/shell_env.rb
@@ -7,7 +7,7 @@ module Gitlab
def set_env(user)
# Set GL_ID env variable
if user
- ENV['GL_ID'] = "user-#{user.id}"
+ ENV['GL_ID'] = gl_id(user)
end
end
@@ -15,5 +15,14 @@ module Gitlab
# Reset GL_ID env variable
ENV['GL_ID'] = nil
end
+
+ def gl_id(user)
+ if user.present?
+ "user-#{user.id}"
+ else
+ # This empty string is used in the render_grack_auth_ok method
+ ""
+ end
+ end
end
end
diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb
index 5b1952b9675..778b76f6890 100644
--- a/lib/gitlab/bitbucket_import/client.rb
+++ b/lib/gitlab/bitbucket_import/client.rb
@@ -1,6 +1,8 @@
module Gitlab
module BitbucketImport
class Client
+ class Unauthorized < StandardError; end
+
attr_reader :consumer, :api
def initialize(access_token = nil, access_token_secret = nil)
@@ -46,23 +48,23 @@ module Gitlab
end
def user
- JSON.parse(api.get("/api/1.0/user").body)
+ JSON.parse(get("/api/1.0/user").body)
end
def issues(project_identifier)
- JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/issues").body)
+ JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues").body)
end
def issue_comments(project_identifier, issue_id)
- JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body)
+ JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body)
end
def project(project_identifier)
- JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}").body)
+ JSON.parse(get("/api/1.0/repositories/#{project_identifier}").body)
end
def find_deploy_key(project_identifier, key)
- JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key|
+ JSON.parse(get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key|
deploy_key["key"].chomp == key.chomp
end
end
@@ -82,11 +84,18 @@ module Gitlab
end
def projects
- JSON.parse(api.get("/api/1.0/user/repositories").body).select { |repo| repo["scm"] == "git" }
+ JSON.parse(get("/api/1.0/user/repositories").body).select { |repo| repo["scm"] == "git" }
end
private
+ def get(url)
+ response = api.get(url)
+ raise Unauthorized if (400..499).include?(response.code.to_i)
+
+ response
+ end
+
def config
Gitlab.config.omniauth.providers.find { |provider| provider.name == "bitbucket"}
end
diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb
index 2f7aff03c2a..04440e4f68d 100644
--- a/lib/redcarpet/render/gitlab_html.rb
+++ b/lib/redcarpet/render/gitlab_html.rb
@@ -22,10 +22,10 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
ERB::Util.html_escape_once(text)
end
- # Stolen from Rugments::Plugins::Redcarpet as this module is not required
- # from Rugments's gem root.
+ # Stolen from Rouge::Plugins::Redcarpet as this module is not required
+ # from Rouge's gem root.
def block_code(code, language)
- lexer = Rugments::Lexer.find_fancy(language, code) || Rugments::Lexers::PlainText
+ lexer = Rouge::Lexer.find_fancy(language, code) || Rouge::Lexers::PlainText
# XXX HACK: Redcarpet strips hard tabs out of code blocks,
# so we assume you're not using leading spaces that aren't tabs,
@@ -34,7 +34,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
code.gsub!(/^ /, "\t")
end
- formatter = Rugments::Formatters::HTML.new(
+ formatter = Rouge::Formatters::HTMLGitlab.new(
cssclass: "code highlight #{@color_scheme} #{lexer.tag}"
)
formatter.format(lexer.lex(code))
diff --git a/lib/rouge/formatters/html_gitlab.rb b/lib/rouge/formatters/html_gitlab.rb
new file mode 100644
index 00000000000..485af6832d7
--- /dev/null
+++ b/lib/rouge/formatters/html_gitlab.rb
@@ -0,0 +1,168 @@
+require 'cgi'
+
+module Rouge
+ module Formatters
+ class HTMLGitlab < Rouge::Formatter
+ tag 'html_gitlab'
+
+ # Creates a new <tt>Rouge::Formatter::HTMLGitlab</tt> instance.
+ #
+ # [+nowrap+] If set to True, don't wrap the output at all, not
+ # even inside a <tt><pre></tt> tag (default: false).
+ # [+cssclass+] CSS class for the wrapping <tt><div></tt> tag
+ # (default: 'highlight').
+ # [+linenos+] If set to 'table', output line numbers as a table
+ # with two cells, one containing the line numbers,
+ # the other the whole code. This is copy paste friendly,
+ # but may cause alignment problems with some browsers
+ # or fonts. If set to 'inline', the line numbers will
+ # be integrated in the <tt><pre></tt> tag that contains
+ # the code (default: nil).
+ # [+linenostart+] The line number for the first line (default: 1).
+ # [+lineanchors+] If set to true the formatter will wrap each output
+ # line in an anchor tag with a name of L-linenumber.
+ # This allows easy linking to certain lines
+ # (default: false).
+ # [+lineanchorsid+] If lineanchors is true the name of the anchors can
+ # be changed with lineanchorsid to e.g. foo-linenumber
+ # (default: 'L').
+ # [+anchorlinenos+] If set to true, will wrap line numbers in <tt><a></tt>
+ # tags. Used in combination with linenos and lineanchors
+ # (default: false).
+ # [+inline_theme+] Inline CSS styles for the <pre> tag (default: false).
+ def initialize(
+ nowrap: false,
+ cssclass: 'highlight',
+ linenos: nil,
+ linenostart: 1,
+ lineanchors: false,
+ lineanchorsid: 'L',
+ anchorlinenos: false,
+ inline_theme: nil
+ )
+ @nowrap = nowrap
+ @cssclass = cssclass
+ @linenos = linenos
+ @linenostart = linenostart
+ @lineanchors = lineanchors
+ @lineanchorsid = lineanchorsid
+ @anchorlinenos = anchorlinenos
+ @inline_theme = Theme.find(@inline_theme).new if @inline_theme.is_a?(String)
+ end
+
+ def render(tokens)
+ case @linenos
+ when 'table'
+ render_tableized(tokens)
+ when 'inline'
+ render_untableized(tokens)
+ else
+ render_untableized(tokens)
+ end
+ end
+
+ alias_method :format, :render
+
+ private
+
+ def render_untableized(tokens)
+ data = process_tokens(tokens)
+
+ html = ''
+ html << "<pre class=\"#{@cssclass}\"><code>" unless @nowrap
+ html << wrap_lines(data[:code])
+ html << "</code></pre>\n" unless @nowrap
+ html
+ end
+
+ def render_tableized(tokens)
+ data = process_tokens(tokens)
+
+ html = ''
+ html << "<div class=\"#{@cssclass}\">" unless @nowrap
+ html << '<table><tbody>'
+ html << "<td class=\"linenos\"><pre>"
+ html << wrap_linenos(data[:numbers])
+ html << '</pre></td>'
+ html << "<td class=\"lines\"><pre><code>"
+ html << wrap_lines(data[:code])
+ html << '</code></pre></td>'
+ html << '</tbody></table>'
+ html << '</div>' unless @nowrap
+ html
+ end
+
+ def process_tokens(tokens)
+ num_lines = 0
+ last_val = ''
+ rendered = ''
+
+ tokens.each do |tok, val|
+ last_val = val
+ num_lines += val.scan(/\n/).size
+ rendered << span(tok, val)
+ end
+
+ numbers = (@linenostart..num_lines + @linenostart - 1).to_a
+
+ { numbers: numbers, code: rendered }
+ end
+
+ def wrap_linenos(numbers)
+ if @anchorlinenos
+ numbers.map! do |number|
+ "<a href=\"##{@lineanchorsid}#{number}\">#{number}</a>"
+ end
+ end
+ numbers.join("\n")
+ end
+
+ def wrap_lines(rendered)
+ if @lineanchors
+ lines = rendered.split("\n")
+ lines = lines.each_with_index.map do |line, index|
+ number = index + @linenostart
+
+ if @linenos == 'inline'
+ "<a name=\"L#{number}\"></a>" \
+ "<span class=\"linenos\">#{number}</span>" \
+ "<span id=\"#{@lineanchorsid}#{number}\" class=\"line\">#{line}" \
+ '</span>'
+ else
+ "<span id=\"#{@lineanchorsid}#{number}\" class=\"line\">#{line}" \
+ '</span>'
+ end
+ end
+ lines.join("\n")
+ else
+ if @linenos == 'inline'
+ lines = rendered.split("\n")
+ lines = lines.each_with_index.map do |line, index|
+ number = index + @linenostart
+ "<span class=\"linenos\">#{number}</span>#{line}"
+ end
+ lines.join("\n")
+ else
+ rendered
+ end
+ end
+ end
+
+ def span(tok, val)
+ # http://stackoverflow.com/a/1600584/2587286
+ val = CGI.escapeHTML(val)
+
+ if tok.shortname.empty?
+ val
+ else
+ if @inline_theme
+ rules = @inline_theme.style_for(tok).rendered_rules
+ "<span style=\"#{rules.to_a.join(';')}\">#{val}</span>"
+ else
+ "<span class=\"#{tok.shortname}\">#{val}</span>"
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab
index edb987875df..efa0898900f 100644
--- a/lib/support/nginx/gitlab
+++ b/lib/support/nginx/gitlab
@@ -38,6 +38,11 @@ upstream gitlab {
server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0;
}
+## Experimental: gitlab-git-http-server
+# upstream gitlab-git-http-server {
+# server localhost:8181;
+# }
+
## Normal HTTP host
server {
## Either remove "default_server" from the listen line below,
@@ -109,6 +114,26 @@ server {
proxy_pass http://gitlab;
}
+ ## Experimental: send Git HTTP traffic to gitlab-git-http-server instead of Unicorn
+ # location ~ [-\/\w\.]+\.git\/ {
+ # ## If you use HTTPS make sure you disable gzip compression
+ # ## to be safe against BREACH attack.
+ # # gzip off;
+
+ # ## https://github.com/gitlabhq/gitlabhq/issues/694
+ # ## Some requests take more than 30 seconds.
+ # proxy_read_timeout 300;
+ # proxy_connect_timeout 300;
+ # proxy_redirect off;
+
+ # proxy_set_header Host $http_host;
+ # proxy_set_header X-Real-IP $remote_addr;
+ # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ # proxy_set_header X-Forwarded-Proto $scheme;
+
+ # proxy_pass http://gitlab-git-http-server;
+ # }
+
## Enable gzip compression as per rails guide:
## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression
## WARNING: If you are using relative urls remove the block below
diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl
index 766559b49f6..314525518f1 100644
--- a/lib/support/nginx/gitlab-ssl
+++ b/lib/support/nginx/gitlab-ssl
@@ -42,6 +42,11 @@ upstream gitlab {
server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0;
}
+## Experimental: gitlab-git-http-server
+# upstream gitlab-git-http-server {
+# server localhost:8181;
+# }
+
## Redirects all HTTP traffic to the HTTPS host
server {
## Either remove "default_server" from the listen line below,
@@ -156,6 +161,26 @@ server {
proxy_pass http://gitlab;
}
+ ## Experimental: send Git HTTP traffic to gitlab-git-http-server instead of Unicorn
+ # location ~ [-\/\w\.]+\.git\/ {
+ # ## If you use HTTPS make sure you disable gzip compression
+ # ## to be safe against BREACH attack.
+ # gzip off;
+
+ # ## https://github.com/gitlabhq/gitlabhq/issues/694
+ # ## Some requests take more than 30 seconds.
+ # proxy_read_timeout 300;
+ # proxy_connect_timeout 300;
+ # proxy_redirect off;
+
+ # proxy_set_header Host $http_host;
+ # proxy_set_header X-Real-IP $remote_addr;
+ # proxy_set_header X-Forwarded-Ssl on;
+ # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ # proxy_set_header X-Forwarded-Proto $scheme;
+ # proxy_pass http://gitlab-git-http-server;
+ # }
+
## Enable gzip compression as per rails guide:
## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression
## WARNING: If you are using relative urls remove the block below
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index aed84226a2f..badb47c6779 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -485,7 +485,8 @@ namespace :gitlab do
if project.empty_repo?
puts "repository is empty".magenta
- elsif File.realpath(project_hook_directory) == File.realpath(gitlab_shell_hooks_path)
+ elsif File.directory?(project_hook_directory) && File.directory?(gitlab_shell_hooks_path) &&
+ (File.realpath(project_hook_directory) == File.realpath(gitlab_shell_hooks_path))
puts 'ok'.green
else
puts "wrong or missing hooks".red
@@ -754,7 +755,7 @@ namespace :gitlab do
print "Ruby version >= #{required_version} ? ... "
if current_version.valid? && required_version <= current_version
- puts "yes (#{current_version})".green
+ puts "yes (#{current_version})".green
else
puts "no".red
try_fixing_it(
@@ -772,7 +773,7 @@ namespace :gitlab do
print "Git version >= #{required_version} ? ... "
if current_version.valid? && required_version <= current_version
- puts "yes (#{current_version})".green
+ puts "yes (#{current_version})".green
else
puts "no".red
try_fixing_it(
@@ -806,4 +807,3 @@ namespace :gitlab do
end
end
end
-
diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake
index 5f83e5e8e7f..c1ee271ae2b 100644
--- a/lib/tasks/gitlab/import.rake
+++ b/lib/tasks/gitlab/import.rake
@@ -62,11 +62,11 @@ namespace :gitlab do
project = Projects::CreateService.new(user, project_params).execute
- if project.valid?
+ if project.persisted?
puts " * Created #{project.name} (#{repo_path})".green
else
puts " * Failed trying to create #{project.name} (#{repo_path})".red
- puts " Validation Errors: #{project.errors.messages}".red
+ puts " Errors: #{project.errors.messages}".red
end
end
end
diff --git a/lib/tasks/gitlab/update_commit_count.rake b/lib/tasks/gitlab/update_commit_count.rake
new file mode 100644
index 00000000000..9b636f12d9f
--- /dev/null
+++ b/lib/tasks/gitlab/update_commit_count.rake
@@ -0,0 +1,20 @@
+namespace :gitlab do
+ desc "GitLab | Update commit count for projects"
+ task update_commit_count: :environment do
+ projects = Project.where(commit_count: 0)
+ puts "#{projects.size} projects need to be updated. This might take a while."
+ ask_to_continue unless ENV['force'] == 'yes'
+
+ projects.find_each(batch_size: 100) do |project|
+ print "#{project.name_with_namespace.yellow} ... "
+
+ unless project.repo_exists?
+ puts "skipping, because the repo is empty".magenta
+ next
+ end
+
+ project.update_commit_count
+ puts project.commit_count.to_s.green
+ end
+ end
+end