Commit e38d4acd authored by Marin Jankovski's avatar Marin Jankovski

Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq

parents 394364e4 7ff1c0e3
...@@ -2,16 +2,16 @@ v 7.6.0 ...@@ -2,16 +2,16 @@ v 7.6.0
- Fork repository to groups - Fork repository to groups
- New rugged version - New rugged version
- Add CRON=1 backup setting for quiet backups - Add CRON=1 backup setting for quiet backups
- Fix failing wiki restore
- -
- Add optional Sidekiq MemoryKiller middleware (enabled via SIDEKIQ_MAX_RSS env variable)
- -
- -
- Create project with repository in synchrony
- Added ability to create empty repo or import existing one if project does not have repository
- -
- -
- - Reactivate highlight.js language autodetection
-
-
-
-
- -
- -
......
...@@ -82,6 +82,24 @@ Please keep the change in a single MR **as small as possible**. If you want to c ...@@ -82,6 +82,24 @@ Please keep the change in a single MR **as small as possible**. If you want to c
For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). If you would like quick feedback on your merge request feel free to mention one of the Merge Marshalls of [the core-team](https://about.gitlab.com/core-team/). Please ensure that your merge request meets the contribution acceptance criteria. For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). If you would like quick feedback on your merge request feel free to mention one of the Merge Marshalls of [the core-team](https://about.gitlab.com/core-team/). Please ensure that your merge request meets the contribution acceptance criteria.
## Definition of done
If you contribute to GitLab please know that changes involve more than just code.
We have the following [definition of done](http://guide.agilealliance.org/guide/definition-of-done.html).
Please ensure you support the feature you contribute through all of these steps.
1. Description explaning the relevancy (see following item)
1. Working and clean code that is commented where needed
1. Unit and integration tests that pass on the CI server
1. Documented in the /doc directory
1. Changelog entry added
1. Reviewed and any concerns are addressed
1. Merged by the project lead
1. Added to the release blog article
1. Added to [the website](https://gitlab.com/gitlab-com/www-gitlab-com/) if relevant
1. Community questions answered
1. Answers to questions radiated (in docs/wiki/etc.)
## Merge request description format ## Merge request description format
1. What does this MR do? 1. What does this MR do?
......
...@@ -59,6 +59,10 @@ ...@@ -59,6 +59,10 @@
pre { pre {
white-space: pre; white-space: pre;
word-wrap: normal; word-wrap: normal;
code {
font-family: $monospace_font;
}
} }
} }
} }
class Projects::ImportsController < Projects::ApplicationController
# Authorize
before_filter :authorize_admin_project!
before_filter :require_no_repo
before_filter :redirect_if_progress, except: :show
def new
end
def create
@project.import_url = params[:project][:import_url]
if @project.save
@project.reload
if @project.import_failed?
@project.import_retry
else
@project.import_start
end
end
redirect_to project_import_path(@project)
end
def show
unless @project.import_in_progress?
if @project.import_finished?
redirect_to(@project) and return
else
redirect_to new_project_import_path(@project) and return
end
end
end
private
def require_no_repo
if @project.repository_exists?
redirect_to(@project) and return
end
end
def redirect_if_progress
if @project.import_in_progress?
redirect_to project_import_path(@project) and return
end
end
end
class Projects::RepositoriesController < Projects::ApplicationController class Projects::RepositoriesController < Projects::ApplicationController
# Authorize # Authorize
before_filter :authorize_download_code! before_filter :authorize_download_code!
before_filter :require_non_empty_project before_filter :require_non_empty_project, except: :create
before_filter :authorize_admin_project!, only: :create
def create
@project.create_repository
redirect_to @project
end
def archive def archive
unless can?(current_user, :download_code, @project) unless can?(current_user, :download_code, @project)
......
...@@ -4,7 +4,7 @@ class ProjectsController < ApplicationController ...@@ -4,7 +4,7 @@ class ProjectsController < ApplicationController
before_filter :repository, except: [:new, :create] before_filter :repository, except: [:new, :create]
# Authorize # Authorize
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive, :retry_import] before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive]
layout 'navless', only: [:new, :create, :fork] layout 'navless', only: [:new, :create, :fork]
before_filter :set_title, only: [:new, :create] before_filter :set_title, only: [:new, :create]
...@@ -19,10 +19,11 @@ class ProjectsController < ApplicationController ...@@ -19,10 +19,11 @@ class ProjectsController < ApplicationController
def create def create
@project = ::Projects::CreateService.new(current_user, project_params).execute @project = ::Projects::CreateService.new(current_user, project_params).execute
flash[:notice] = 'Project was successfully created.' if @project.saved?
respond_to do |format| if @project.saved?
format.js redirect_to project_path(@project), notice: 'Project was successfully created.'
else
render 'new'
end end
end end
...@@ -47,7 +48,7 @@ class ProjectsController < ApplicationController ...@@ -47,7 +48,7 @@ class ProjectsController < ApplicationController
def show def show
if @project.import_in_progress? if @project.import_in_progress?
redirect_to import_project_path(@project) redirect_to project_import_path(@project)
return return
end end
...@@ -60,37 +61,20 @@ class ProjectsController < ApplicationController ...@@ -60,37 +61,20 @@ class ProjectsController < ApplicationController
respond_to do |format| respond_to do |format|
format.html do format.html do
if @project.empty_repo? if @project.repository_exists?
render "projects/empty", layout: user_layout if @project.empty_repo?
render "projects/empty", layout: user_layout
else
@last_push = current_user.recent_push(@project.id) if current_user
render :show, layout: user_layout
end
else else
@last_push = current_user.recent_push(@project.id) if current_user render "projects/no_repo", layout: user_layout
render :show, layout: user_layout
end end
end end
format.json { pager_json("events/_events", @events.count) }
end
end
def import format.json { pager_json("events/_events", @events.count) }
if @project.import_finished?
redirect_to @project
return
end
end
def retry_import
unless @project.import_failed?
redirect_to import_project_path(@project)
end
@project.import_url = project_params[:import_url]
if @project.save
@project.reload
@project.import_retry
end end
redirect_to import_project_path(@project)
end end
def destroy def destroy
......
module BlobHelper module BlobHelper
def highlightjs_class(blob_name) def highlightjs_class(blob_name)
if blob_name.include?('.') if no_highlight_files.include?(blob_name.downcase)
ext = blob_name.split('.').last 'no-highlight'
return 'language-' + ext
else else
if no_highlight_files.include?(blob_name.downcase) blob_name.downcase
'no-highlight'
else
blob_name.downcase
end
end end
end end
......
module Emails module Emails
module Profile module Profile
def new_user_email(user_id, password, token = nil) def new_user_email(user_id, token = nil)
@user = User.find(user_id) @user = User.find(user_id)
@password = password
@target_url = user_url(@user) @target_url = user_url(@user)
@token = token @token = token
mail(to: @user.email, subject: subject("Account was created for you")) mail(to: @user.email, subject: subject("Account was created for you"))
......
...@@ -136,7 +136,7 @@ class Project < ActiveRecord::Base ...@@ -136,7 +136,7 @@ class Project < ActiveRecord::Base
state_machine :import_status, initial: :none do state_machine :import_status, initial: :none do
event :import_start do event :import_start do
transition :none => :started transition [:none, :finished] => :started
end end
event :import_finish do event :import_finish do
...@@ -586,4 +586,25 @@ class Project < ActiveRecord::Base ...@@ -586,4 +586,25 @@ class Project < ActiveRecord::Base
def origin_merge_requests def origin_merge_requests
merge_requests.where(source_project_id: self.id) merge_requests.where(source_project_id: self.id)
end end
def create_repository
if gitlab_shell.add_repository(path_with_namespace)
true
else
errors.add(:base, "Failed to create repository")
false
end
end
def repository_exists?
!!repository.exists?
end
def create_wiki
ProjectWiki.new(self, self.owner).wiki
true
rescue ProjectWiki::CouldNotCreateWikiError => ex
errors.add(:base, "Failed create wiki")
false
end
end end
...@@ -107,7 +107,7 @@ class NotificationService ...@@ -107,7 +107,7 @@ class NotificationService
# Notify new user with email after creation # Notify new user with email after creation
def new_user(user, token = nil) def new_user(user, token = nil)
# Don't email omniauth created users # Don't email omniauth created users
mailer.new_user_email(user.id, user.password, token) unless user.extern_uid? mailer.new_user_email(user.id, token) unless user.extern_uid?
end end
# Notify users on new note in system # Notify users on new note in system
......
...@@ -37,35 +37,22 @@ module Projects ...@@ -37,35 +37,22 @@ module Projects
@project.creator = current_user @project.creator = current_user
if @project.save Project.transaction do
log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"") @project.save
system_hook_service.execute_hooks_for(@project, :create)
unless @project.group unless @project.import?
@project.team << [current_user, :master] unless @project.create_repository
end raise 'Failed to create repository'
end
@project.update_column(:last_activity_at, @project.created_at)
if @project.import?
@project.import_start
else
GitlabShellWorker.perform_async(
:add_repository,
@project.path_with_namespace
)
end end
end
if @project.persisted?
if @project.wiki_enabled? if @project.wiki_enabled?
begin @project.create_wiki
# force the creation of a wiki,
ProjectWiki.new(@project, @project.owner).wiki
rescue ProjectWiki::CouldNotCreateWikiError => ex
# Prevent project observer crash
# if failed to create wiki
nil
end
end end
after_create_actions
end end
@project @project
...@@ -84,5 +71,20 @@ module Projects ...@@ -84,5 +71,20 @@ module Projects
namespace = Namespace.find_by(id: namespace_id) namespace = Namespace.find_by(id: namespace_id)
current_user.can?(:create_projects, namespace) current_user.can?(:create_projects, namespace)
end end
def after_create_actions
log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")
system_hook_service.execute_hooks_for(@project, :create)
unless @project.group
@project.team << [current_user, :master]
end
@project.update_column(:last_activity_at, @project.created_at)
if @project.import?
@project.import_start
end
end
end end
end end
- if @project.saved?
- if @project.import?
:plain
location.href = "#{import_project_path(@project)}";
- else
:plain
location.href = "#{project_path(@project)}";
- else
:plain
$(".project-edit-errors").html("#{escape_javascript(render('errors'))}");
$('.project-submit').enable();
$('.save-project-loader').hide();
$('.project-edit-container').show();
- if @project.import_in_progress?
.save-project-loader
.center
%h2
%i.fa.fa-spinner.fa-spin
Import in progress.
%p.monospace git clone --bare #{hidden_pass_url(@project.import_url)}
%p Please wait while we import the repository for you. Refresh at will.
:javascript
new ProjectImport();
- elsif @project.import_failed?
.save-project-loader
.center
%h2
Import failed. Retry?
%hr
- if can?(current_user, :admin_project, @project)
= form_for @project, url: retry_import_project_path(@project), method: :put, html: { class: 'form-horizontal' } do |f|
.form-group.import-url-data
= f.label :import_url, class: 'control-label' do
%span Import existing git repo
.col-sm-10
= f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
.bs-callout.bs-callout-info
This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
%br
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}
.form-actions
= f.submit 'Retry import', class: "btn btn-create", tabindex: 4
%h3.page-title
- if @project.import_failed?
Import failed. Retry?
- else
Import repository
%hr
= form_for @project, url: project_import_path(@project), method: :post, html: { class: 'form-horizontal' } do |f|
.form-group.import-url-data
= f.label :import_url, class: 'control-label' do
%span Import existing git repo
.col-sm-10
= f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
.bs-callout.bs-callout-info
This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
%br
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}
.form-actions
= f.submit 'Start import', class: "btn btn-create", tabindex: 4
.save-project-loader
.center
%h2
%i.fa.fa-spinner.fa-spin
Import in progress.
%p.monospace git clone --bare #{hidden_pass_url(@project.import_url)}
%p Please wait while we import the repository for you. Refresh at will.
:javascript
new ProjectImport();
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
= render 'projects/errors' = render 'projects/errors'
.project-edit-content .project-edit-content
= form_for @project, remote: true, html: { class: 'new_project form-horizontal' } do |f| = form_for @project, html: { class: 'new_project form-horizontal' } do |f|
.form-group.project-name-holder .form-group.project-name-holder
= f.label :name, class: 'control-label' do = f.label :name, class: 'control-label' do
%strong Project name %strong Project name
......
%h2
%i.fa.fa-warning
No repository
%p.slead
The repository for this project does not exist.
%br
This means you can not push code until you create an empty repository or import existing one.
%hr
.no-repo-actions
= link_to project_repository_path(@project), method: :post, class: 'btn btn-primary' do
Create empty bare repository
%strong.prepend-left-10.append-right-10 or
= link_to new_project_import_path(@project), class: 'btn' do
Import repository
- if can? current_user, :remove_project, @project
.prepend-top-20
= link_to 'Remove project', @project, data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right"
...@@ -15,6 +15,7 @@ Sidekiq.configure_server do |config| ...@@ -15,6 +15,7 @@ Sidekiq.configure_server do |config|
config.server_middleware do |chain| config.server_middleware do |chain|
chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger
chain.add Gitlab::SidekiqMiddleware::MemoryKiller if ENV['SIDEKIQ_MAX_RSS']
end end
end end
......
...@@ -186,8 +186,6 @@ Gitlab::Application.routes.draw do ...@@ -186,8 +186,6 @@ Gitlab::Application.routes.draw do
post :upload_image post :upload_image
post :toggle_star post :toggle_star
get :autocomplete_sources get :autocomplete_sources
get :import
put :retry_import
end end
scope module: :projects do scope module: :projects do
...@@ -232,8 +230,9 @@ Gitlab::Application.routes.draw do ...@@ -232,8 +230,9 @@ Gitlab::Application.routes.draw do
end end
resource :fork, only: [:new, :create] resource :fork, only: [:new, :create]
resource :import, only: [:new, :create, :show]
resource :repository, only: [:show] do resource :repository, only: [:show, :create] do
member do member do
get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex } get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex }
end end
......
...@@ -20,7 +20,6 @@ Please report suspected security vulnerabilities in private to <support@gitlab.c ...@@ -20,7 +20,6 @@ Please report suspected security vulnerabilities in private to <support@gitlab.c
1. Create feature branches for the blog post on GitLab.com and link them from the code branch 1. Create feature branches for the blog post on GitLab.com and link them from the code branch
1. Merge and publish the blog posts 1. Merge and publish the blog posts
1. Send tweets about the release from `@gitlabhq` 1. Send tweets about the release from `@gitlabhq`
1. Send out an email to the 'GitLab Newsletter' mailing list on MailChimp (or the 'Subscribers' list if the security fix is for EE only)
1. Send out an email to [the community google mailing list](https://groups.google.com/forum/#!forum/gitlabhq) 1. Send out an email to [the community google mailing list](https://groups.google.com/forum/#!forum/gitlabhq)
1. Post a signed copy of our complete announcement to [oss-security](http://www.openwall.com/lists/oss-security/) and request a CVE number 1. Post a signed copy of our complete announcement to [oss-security](http://www.openwall.com/lists/oss-security/) and request a CVE number
1. Add the security researcher to the [Security Researcher Acknowledgments list](http://about.gitlab.com/vulnerability-acknowledgements/) 1. Add the security researcher to the [Security Researcher Acknowledgments list](http://about.gitlab.com/vulnerability-acknowledgements/)
......
...@@ -10,6 +10,8 @@ If you have local changes to your GitLab repository the script will stash them a ...@@ -10,6 +10,8 @@ If you have local changes to your GitLab repository the script will stash them a
**GitLab Upgrader is available only for GitLab version 6.4.2 or higher.** **GitLab Upgrader is available only for GitLab version 6.4.2 or higher.**
**This script does NOT update gitlab-shell, it needs manual update. See step 5 below.**
## 0. Backup ## 0. Backup
cd /home/git/gitlab cd /home/git/gitlab
......
# Data: docker run --name gitlab_data genezys/gitlab:7.5.1 /bin/true
# Run: docker run --detach --name gitlab --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data genezys/gitlab:7.5.1
FROM ubuntu:14.04
MAINTAINER Vincent Robert <vincent.robert@genezys.net>
# Install required packages
RUN apt-get update -q \
&& DEBIAN_FRONTEND=noninteractive apt-get install -qy \
openssh-server \
wget \
&& apt-get clean
# Download & Install GitLab
RUN TMP_FILE=$(mktemp); \
wget -q -O $TMP_FILE https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.5.1-omnibus.5.2.0.ci-1_amd64.deb \
&& dpkg -i $TMP_FILE \
&& rm -f $TMP_FILE
# Manage SSHD through runit
RUN mkdir -p /opt/gitlab/sv/sshd/supervise \
&& mkfifo /opt/gitlab/sv/sshd/supervise/ok \
&& printf "#!/bin/sh\nexec 2>&1\numask 077\nexec /usr/sbin/sshd -D" > /opt/gitlab/sv/sshd/run \
&& chmod a+x /opt/gitlab/sv/sshd/run \
&& ln -s /opt/gitlab/sv/sshd /opt/gitlab/service \
&& mkdir -p /var/run/sshd
# Expose web & ssh
EXPOSE 80 22
# Volume & configuration
VOLUME ["/var/opt/gitlab", "/var/log/gitlab", "/etc/gitlab"]
ADD gitlab.rb /etc/gitlab/
# Default is to run runit & reconfigure
CMD gitlab-ctl reconfigure > /var/log/gitlab/reconfigure.log & /opt/gitlab/embedded/bin/runsvdir-start
What is GitLab?
===============
GitLab offers git repository management, code reviews, issue tracking, activity feeds, wikis. It has LDAP/AD integration, handles 25,000 users on a single server but can also run on a highly available active/active cluster. A subscription gives you access to our support team and to GitLab Enterprise Edition that contains extra features aimed at larger organizations.
<https://about.gitlab.com>
![GitLab Logo](https://gitlab.com/uploads/appearance/logo/1/brand_logo-c37eb221b456bb4b472cc1084480991f.png)
How to use this image.
======================
I recommend creating a data volume container first, this will simplify migrations and backups:
docker run --name gitlab_data genezys/gitlab:7.5.1 /bin/true
This empty container will exist to persist as volumes the 3 directories used by GitLab, so remember not to delete it:
- `/var/opt/gitlab` for application data
- `/var/log/gitlab` for logs
- `/etc/gitlab` for configuration
Then run GitLab:
docker run --detach --name gitlab --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data genezys/gitlab:7.5.1
You can then go to `http://localhost:8080/` (or most likely `http://192.168.59.103:8080/` if you use boot2docker). Next time, you can just use `docker start gitlab` and `docker stop gitlab`.
How to configure GitLab.
========================
This container uses the official Omnibus GitLab distribution, so all configuration is done in the unique configuration file `/etc/gitlab/gitlab.rb`.
To access GitLab configuration, you can start a new container using the shared data volume container:
docker run -ti --rm --volumes-from gitlab_data ubuntu vi /etc/gitlab/gitlab.rb
**Note** that GitLab will reconfigure itself **at each container start.** You will need to restart the container to reconfigure your GitLab.
You can find all available options in [GitLab documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#configuration).
# External URL should be your Docker instance.
# By default, this example is the "standard" boot2docker IP.
# Always use port 80 here to force the internal nginx to bind port 80,
# even if you intend to use another port in Docker.
external_url "http://192.168.59.103/"
# Some configuration of GitLab
# You can find more at https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#configuration
gitlab_rails['gitlab_email_from'] = 'gitlab@example.com'
gitlab_rails['gitlab_support_email'] = 'support@example.com'
gitlab_rails['time_zone'] = 'Europe/Paris'
# SMTP settings
# You must use an external server, the Docker container does not install an SMTP server
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.example.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "user"
gitlab_rails['smtp_password'] = "password"
gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['smtp_authentication'] = "plain"
gitlab_rails['smtp_enable_starttls_auto'] = true
# Enable LDAP authentication
# gitlab_rails['ldap_enabled'] = true
# gitlab_rails['ldap_host'] = 'ldap.example.com'
# gitlab_rails['ldap_port'] = 389
# gitlab_rails['ldap_method'] = 'plain' # 'ssl' or 'plain'
# gitlab_rails['ldap_allow_username_or_email_login'] = false
# gitlab_rails['ldap_uid'] = 'uid'
# gitlab_rails['ldap_base'] = 'ou=users,dc=example,dc=com'
...@@ -131,7 +131,7 @@ module SharedProject ...@@ -131,7 +131,7 @@ module SharedProject
end end
step 'public empty project "Empty Public Project"' do step 'public empty project "Empty Public Project"' do
create :empty_project, :public, name: "Empty Public Project" create :project_empty_repo, :public, name: "Empty Public Project"
end end
step 'project "Community" has comments' do step 'project "Community" has comments' do
......
...@@ -33,15 +33,20 @@ module API ...@@ -33,15 +33,20 @@ module API
end end
project = Project.find_with_namespace(project_path) project = Project.find_with_namespace(project_path)
return false unless project
unless project
return Gitlab::GitAccessStatus.new(false, 'No such project')
end
actor = if params[:key_id] actor = if params[:key_id]
Key.find(params[:key_id]) Key.find_by(id: params[:key_id])
elsif params[:user_id] elsif params[:user_id]
User.find(params[:user_id]) User.find_by(id: params[:user_id])
end end
return false unless actor unless actor
return Gitlab::GitAccessStatus.new(false, 'No such user or key')
end
access.check( access.check(
actor, actor,
......
...@@ -59,7 +59,7 @@ module Backup ...@@ -59,7 +59,7 @@ module Backup
FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(repos_path)
Project.find_each(batch_size: 1000) do |project| Project.find_each(batch_size: 1000) do |project|
$progress.print "#{project.path_with_namespace} ... " $progress.print " * #{project.path_with_namespace} ... "
project.namespace.ensure_dir_exist if project.namespace project.namespace.ensure_dir_exist if project.namespace
...@@ -81,7 +81,13 @@ module Backup ...@@ -81,7 +81,13 @@ module Backup
if File.exists?(path_to_bundle(wiki)) if File.exists?(path_to_bundle(wiki))
$progress.print " * #{wiki.path_with_namespace} ... " $progress.print " * #{wiki.path_with_namespace} ... "
# If a wiki bundle exists, first remove the empty repo
# that was initialized with ProjectWiki.new() and then
# try to restore with 'git clone --bare'.
FileUtils.rm_rf(path_to_repo(wiki))
cmd = %W(git clone --bare #{path_to_bundle(wiki)} #{path_to_repo(wiki)}) cmd = %W(git clone --bare #{path_to_bundle(wiki)} #{path_to_repo(wiki)})
if system(*cmd, silent) if system(*cmd, silent)
$progress.puts " [DONE]".green $progress.puts " [DONE]".green
else else
......
...@@ -8,15 +8,7 @@ module Gitlab ...@@ -8,15 +8,7 @@ module Gitlab
def check(actor, cmd, project, changes = nil) def check(actor, cmd, project, changes = nil)
case cmd case cmd
when *DOWNLOAD_COMMANDS when *DOWNLOAD_COMMANDS
if actor.is_a? User download_access_check(actor, project)
download_access_check(actor, project)
elsif actor.is_a? DeployKey
actor.projects.include?(project)
elsif actor.is_a? Key
download_access_check(actor.user, project)
else
raise 'Wrong actor'
end
when *PUSH_COMMANDS when *PUSH_COMMANDS
if actor.is_a? User if actor.is_a? User
push_access_check(actor, project, changes) push_access_check(actor, project, changes)
...@@ -32,7 +24,23 @@ module Gitlab ...@@ -32,7 +24,23 @@ module Gitlab
end end
end end
def download_access_check(user, project) def download_access_check(actor, project)
if actor.is_a?(User)
user_download_access_check(actor, project)
elsif actor.is_a?(DeployKey)
if actor.projects.include?(project)
build_status_object(true)
else
build_status_object(false, "Deploy key not allowed to access this project")
end
elsif actor.is_a? Key
user_download_access_check(actor.user, project)
else
raise 'Wrong actor'
end
end
def user_download_access_check(user, project)
if user && user_allowed?(user) && user.can?(:download_code, project) if user && user_allowed?(user) && user.can?(:download_code, project)
build_status_object(true) build_status_object(true)
else else
......
module Gitlab
module SidekiqMiddleware
class MemoryKiller
# Wait 30 seconds for running jobs to finish during graceful shutdown
GRACEFUL_SHUTDOWN_WAIT = 30
def call(worker, job, queue)
yield
current_rss = get_rss
return unless max_rss > 0 && current_rss > max_rss
Sidekiq.logger.warn "current RSS #{current_rss} exceeds maximum RSS "\
"#{max_rss}"
Sidekiq.logger.warn "sending SIGUSR1 to PID #{Process.pid}"
# SIGUSR1 tells Sidekiq to stop accepting new jobs
Process.kill('SIGUSR1', Process.pid)
Sidekiq.logger.warn "spawning thread that will send SIGTERM to PID "\
"#{Process.pid} in #{graceful_shutdown_wait} seconds"
# Send the final shutdown signal to Sidekiq from a separate thread so
# that the current job can finish
Thread.new do
sleep(graceful_shutdown_wait)
Process.kill('SIGTERM', Process.pid)
end
end
private
def get_rss
output, status = Gitlab::Popen.popen(%W(ps -o rss= -p #{Process.pid}))
return 0 unless status.zero?
output.to_i
end
def max_rss
@max_rss ||= ENV['SIDEKIQ_MAX_RSS'].to_s.to_i
end
def graceful_shutdown_wait
@graceful_shutdown_wait ||= (
ENV['SIDEKIQ_GRACEFUL_SHUTDOWN_WAIT'] || GRACEFUL_SHUTDOWN_WAIT
).to_i
end
end
end
end
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
# #
FactoryGirl.define do FactoryGirl.define do
# Project without repository
#
# Project does not have bare repository.
# Use this factory if you dont need repository in tests
factory :empty_project, class: 'Project' do factory :empty_project, class: 'Project' do
sequence(:name) { |n| "project#{n}" } sequence(:name) { |n| "project#{n}" }
path { name.downcase.gsub(/\s/, '_') } path { name.downcase.gsub(/\s/, '_') }
...@@ -47,6 +51,20 @@ FactoryGirl.define do ...@@ -47,6 +51,20 @@ FactoryGirl.define do
end end
end end
# Project with empty repository
#
# This is a case when you just created a project
# but not pushed any code there yet
factory :project_empty_repo, parent: :empty_project do
after :create do |project|
project.create_repository
end
end
# Project with test repository
#
# Test repository source can be found at
# https://gitlab.com/gitlab-org/gitlab-test
factory :project, parent: :empty_project do factory :project, parent: :empty_project do
path { 'gitlabhq' } path { 'gitlabhq' }
......
...@@ -46,6 +46,25 @@ describe Gitlab::GitAccess do ...@@ -46,6 +46,25 @@ describe Gitlab::GitAccess do
it { subject.allowed?.should be_false } it { subject.allowed?.should be_false }
end end
end end
describe 'deploy key permissions' do
let(:key) { create(:deploy_key) }
context 'pull code' do
context 'allowed' do
before { key.projects << project }
subject { access.download_access_check(key, project) }
it { subject.allowed?.should be_true }
end
context 'denied' do
subject { access.download_access_check(key, project) }
it { subject.allowed?.should be_false }
end
end
end
end end
describe 'push_access_check' do describe 'push_access_check' do
......
...@@ -46,7 +46,7 @@ describe Notify do ...@@ -46,7 +46,7 @@ describe Notify do
token = 'kETLwRaayvigPq_x3SNM' token = 'kETLwRaayvigPq_x3SNM'
subject { Notify.new_user_email(new_user.id, new_user.password, token) } subject { Notify.new_user_email(new_user.id, token) }
it_behaves_like 'an email sent from GitLab' it_behaves_like 'an email sent from GitLab'
...@@ -83,7 +83,7 @@ describe Notify do ...@@ -83,7 +83,7 @@ describe Notify do
let(:example_site_path) { root_path } let(:example_site_path) { root_path }
let(:new_user) { create(:user, email: 'newguy@example.com', password: "securePassword") } let(:new_user) { create(:user, email: 'newguy@example.com', password: "securePassword") }
subject { Notify.new_user_email(new_user.id, new_user.password) } subject { Notify.new_user_email(new_user.id) }
it_behaves_like 'an email sent from GitLab' it_behaves_like 'an email sent from GitLab'
......
...@@ -26,7 +26,7 @@ describe API::API, api: true do ...@@ -26,7 +26,7 @@ describe API::API, api: true do
end end
end end
describe "GET /internal/allowed" do describe "POST /internal/allowed" do
context "access granted" do context "access granted" do
before do before do
project.team << [user, :developer] project.team << [user, :developer]
...@@ -140,7 +140,7 @@ describe API::API, api: true do ...@@ -140,7 +140,7 @@ describe API::API, api: true do
archive(key, project) archive(key, project)
response.status.should == 200 response.status.should == 200
response.body.should == 'true' JSON.parse(response.body)["status"].should be_true
end end
end end
...@@ -149,10 +149,28 @@ describe API::API, api: true do ...@@ -149,10 +149,28 @@ describe API::API, api: true do
archive(key, project) archive(key, project)
response.status.should == 200 response.status.should == 200
response.body.should == 'false' JSON.parse(response.body)["status"].should be_false
end end
end end
end end
context 'project does not exist' do
it do
pull(key, OpenStruct.new(path_with_namespace: 'gitlab/notexists'))
response.status.should == 200
JSON.parse(response.body)["status"].should be_false
end
end
context 'user does not exist' do
it do
pull(OpenStruct.new(id: 0), project)
response.status.should == 200
JSON.parse(response.body)["status"].should be_false
end
end
end end
def pull(key, project) def pull(key, project)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment