Non-interactive AWS install by running a single script.

Merge branch 'master' into non-interactive-aws-install

Conflicts:
	doc/installation.md

Fix merge mess in installation.md
This commit is contained in:
Sytse Sijbrandij 2012-09-02 18:31:16 +02:00
parent eae41ad1df
commit b80dd3d242
215 changed files with 3829 additions and 3348 deletions

View file

@ -16,5 +16,6 @@ module Gitlab
mount Users
mount Projects
mount Issues
mount Milestones
end
end

View file

@ -95,7 +95,7 @@ module Gitlab
end
end
# Delete a project issue
# Delete a project issue (deprecated)
#
# Parameters:
# id (required) - The ID or code name of a project
@ -103,8 +103,7 @@ module Gitlab
# Example Request:
# DELETE /projects/:id/issues/:issue_id
delete ":id/issues/:issue_id" do
@issue = user_project.issues.find(params[:issue_id])
@issue.destroy
error!({'message' => 'method not allowed'}, 405)
end
end
end

80
lib/api/milestones.rb Normal file
View file

@ -0,0 +1,80 @@
module Gitlab
# Milestones API
class Milestones < Grape::API
before { authenticate! }
resource :projects do
# Get a list of project milestones
#
# Parameters:
# id (required) - The ID or code name of a project
# Example Request:
# GET /projects/:id/milestones
get ":id/milestones" do
present user_project.milestones, with: Entities::Milestone
end
# Get a single project milestone
#
# Parameters:
# id (required) - The ID or code name of a project
# milestone_id (required) - The ID of a project milestone
# Example Request:
# GET /projects/:id/milestones/:milestone_id
get ":id/milestones/:milestone_id" do
@milestone = user_project.milestones.find(params[:milestone_id])
present @milestone, with: Entities::Milestone
end
# Create a new project milestone
#
# Parameters:
# id (required) - The ID or code name 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
# Example Request:
# POST /projects/:id/milestones
post ":id/milestones" do
@milestone = user_project.milestones.new(
title: params[:title],
description: params[:description],
due_date: params[:due_date]
)
if @milestone.save
present @milestone, with: Entities::Milestone
else
error!({'message' => '404 Not found'}, 404)
end
end
# Update an existing project milestone
#
# Parameters:
# id (required) - The ID or code name 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
# due_date (optional) - The due date of a milestone
# closed (optional) - The status of the milestone
# Example Request:
# PUT /projects/:id/milestones/:milestone_id
put ":id/milestones/:milestone_id" do
@milestone = user_project.milestones.find(params[:milestone_id])
parameters = {
title: (params[:title] || @milestone.title),
description: (params[:description] || @milestone.description),
due_date: (params[:due_date] || @milestone.due_date),
closed: (params[:closed] || @milestone.closed)
}
if @milestone.update_attributes(parameters)
present @milestone, with: Entities::Milestone
else
error!({'message' => '404 Not found'}, 404)
end
end
end
end
end

View file

@ -2,54 +2,57 @@ require 'gitolite'
require 'timeout'
require 'fileutils'
# TODO: refactor & cleanup
module Gitlab
class Gitolite
class AccessDenied < StandardError; end
class InvalidKey < StandardError; end
def self.update_project(path, project)
self.new.configure { |git| git.update_project(path, project) }
def set_key key_id, key_content, projects
configure do |c|
c.update_keys(key_id, key_content)
c.update_projects(projects)
end
end
def self.destroy_project(project)
self.new.configure { |git| git.destroy_project(project) }
def remove_key key_id, projects
configure do |c|
c.delete_key(key_id)
c.update_projects(projects)
end
end
def pull
def update_repository project
configure do |c|
c.update_project(project.path, project)
end
end
alias_method :create_repository, :update_repository
def remove_repository project
configure do |c|
c.destroy_project(project)
end
end
def url_to_repo path
Gitlab.config.ssh_path + "#{path}.git"
end
def initialize
# create tmp dir
@local_dir = File.join(Rails.root, 'tmp',"gitlabhq-gitolite-#{Time.now.to_i}")
Dir.mkdir @local_dir
`git clone #{GitHost.admin_uri} #{@local_dir}/gitolite`
end
def push
Dir.chdir(File.join(@local_dir, "gitolite"))
`git add -A`
`git commit -am "Gitlab"`
`git push`
Dir.chdir(Rails.root)
FileUtils.rm_rf(@local_dir)
end
def configure
Timeout::timeout(30) do
File.open(File.join(Rails.root, 'tmp', "gitlabhq-gitolite.lock"), "w+") do |f|
begin
f.flock(File::LOCK_EX)
pull
yield(self)
push
ensure
f.flock(File::LOCK_UN)
end
end
def enable_automerge
configure do |git|
git.admin_all_repo
end
rescue Exception => ex
Gitlab::Logger.error(ex.message)
raise Gitolite::AccessDenied.new("gitolite timeout")
end
protected
def destroy_project(project)
FileUtils.rm_rf(project.path_to_repo)
@ -106,13 +109,13 @@ module Gitlab
name_writers = project.repository_writers
name_masters = project.repository_masters
pr_br = project.protected_branches.map(&:name).join(" ")
pr_br = project.protected_branches.map(&:name).join("$ ")
repo.clean_permissions
# Deny access to protected branches for writers
unless name_writers.blank? || pr_br.blank?
repo.add_permission("-", pr_br, name_writers)
repo.add_permission("-", pr_br.strip + "$ ", name_writers)
end
# Add read permissions
@ -153,5 +156,47 @@ module Gitlab
conf.add_repo(repo, true)
ga_repo.save
end
private
def pull
# create tmp dir
@local_dir = File.join(Rails.root, 'tmp',"gitlabhq-gitolite-#{Time.now.to_i}")
Dir.mkdir @local_dir
`git clone #{Gitlab.config.gitolite_admin_uri} #{@local_dir}/gitolite`
end
def push
Dir.chdir(File.join(@local_dir, "gitolite"))
`git add -A`
`git commit -am "Gitlab"`
`git push`
Dir.chdir(Rails.root)
FileUtils.rm_rf(@local_dir)
end
def configure
Timeout::timeout(30) do
File.open(File.join(Rails.root, 'tmp', "gitlabhq-gitolite.lock"), "w+") do |f|
begin
f.flock(File::LOCK_EX)
pull
yield(self)
push
ensure
f.flock(File::LOCK_UN)
end
end
end
rescue Exception => ex
if ex.message =~ /is not a valid SSH key string/
raise Gitolite::InvalidKey.new("ssh key is not valid")
else
Gitlab::Logger.error(ex.message)
raise Gitolite::AccessDenied.new("gitolite timeout")
end
end
end
end

View file

@ -0,0 +1,54 @@
module Grack
class Auth < Rack::Auth::Basic
def valid?
# Authentication with username and password
email, password = @auth.credentials
user = User.find_by_email(email)
return false unless user.try(:valid_password?, password)
# Set GL_USER env variable
ENV['GL_USER'] = email
# Pass Gitolite update hook
ENV['GL_BYPASS_UPDATE_HOOK'] = "true"
# Need this patch because the rails mount
@env['PATH_INFO'] = @env['REQUEST_PATH']
# Find project by PATH_INFO from env
if m = /^\/([\w-]+).git/.match(@env['PATH_INFO']).to_a
return false unless project = Project.find_by_path(m.last)
end
# Git upload and receive
if @env['REQUEST_METHOD'] == 'GET'
true
elsif @env['REQUEST_METHOD'] == 'POST'
if @env['REQUEST_URI'].end_with?('git-upload-pack')
return project.dev_access_for?(user)
elsif @env['REQUEST_URI'].end_with?('git-receive-pack')
if project.protected_branches.map(&:name).include?(current_ref)
project.master_access_for?(user)
else
project.dev_access_for?(user)
end
else
false
end
else
false
end
end# valid?
def current_ref
if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/
input = Zlib::GzipReader.new(@request.body).read
else
input = @request.body.read
end
# Need to reset seek point
@request.body.rewind
/refs\/heads\/([\w-]+)/.match(input).to_a.first
end
end# Auth
end# Grack

View file

@ -1,17 +0,0 @@
require File.join(Rails.root, "lib", "gitlab", "gitolite")
module Gitlab
class GitHost
def self.system
Gitlab::Gitolite
end
def self.admin_uri
Gitlab.config.git_host.admin_uri
end
def self.url_to_repo(path)
Gitlab.config.ssh_path + "#{path}.git"
end
end
end

View file

@ -1,5 +1,14 @@
module Gitlab
# Custom parsing for Gitlab-flavored Markdown
# Custom parser for Gitlab-flavored Markdown
#
# It replaces references in the text with links to the appropriate items in Gitlab.
#
# Supported reference formats are:
# * @foo for team members
# * #123 for issues
# * !123 for merge requests
# * $123 for snippets
# * 123456 for commits
#
# Examples
#
@ -67,25 +76,25 @@ module Gitlab
def reference_user(identifier)
if user = @project.users.where(name: identifier).first
member = @project.users_projects.where(user_id: user).first
link_to("@#{user.name}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
link_to("@#{identifier}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
end
end
def reference_issue(identifier)
if issue = @project.issues.where(id: identifier).first
link_to("##{issue.id}", project_issue_path(@project, issue), html_options.merge(title: "Issue: #{issue.title}", class: "gfm gfm-issue #{html_options[:class]}"))
link_to("##{identifier}", project_issue_path(@project, issue), html_options.merge(title: "Issue: #{issue.title}", class: "gfm gfm-issue #{html_options[:class]}"))
end
end
def reference_merge_request(identifier)
if merge_request = @project.merge_requests.where(id: identifier).first
link_to("!#{merge_request.id}", project_merge_request_path(@project, merge_request), html_options.merge(title: "Merge Request: #{merge_request.title}", class: "gfm gfm-merge_request #{html_options[:class]}"))
link_to("!#{identifier}", project_merge_request_path(@project, merge_request), html_options.merge(title: "Merge Request: #{merge_request.title}", class: "gfm gfm-merge_request #{html_options[:class]}"))
end
end
def reference_snippet(identifier)
if snippet = @project.snippets.where(id: identifier).first
link_to("$#{snippet.id}", project_snippet_path(@project, snippet), html_options.merge(title: "Snippet: #{snippet.title}", class: "gfm gfm-snippet #{html_options[:class]}"))
link_to("$#{identifier}", project_snippet_path(@project, snippet), html_options.merge(title: "Snippet: #{snippet.title}", class: "gfm gfm-snippet #{html_options[:class]}"))
end
end

54
lib/support/init-gitlab Normal file
View file

@ -0,0 +1,54 @@
#! /bin/bash
### BEGIN INIT INFO
# Provides: gitlab
# Required-Start: $local_fs $remote_fs $network $syslog redis-server
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: GitLab git repository management
# Description: GitLab git repository management
### END INIT INFO
DAEMON_OPTS="-c /home/gitlab/gitlab/config/unicorn.rb -E production -D"
NAME=unicorn
DESC="Gitlab service"
PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid
RESQUE_PID=/home/gitlab/gitlab/tmp/pids/resque_worker.pid
case "$1" in
start)
CD_TO_APP_DIR="cd /home/gitlab/gitlab"
START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS"
START_RESQUE_PROCESS="./resque.sh"
echo -n "Starting $DESC: "
if [ `whoami` = root ]; then
sudo -u gitlab sh -l -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS"
else
$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS
fi
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
kill -QUIT `cat $PID`
kill -QUIT `cat $RESQUE_PID`
echo "$NAME."
;;
restart)
echo -n "Restarting $DESC: "
kill -USR2 `cat $PID`
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
kill -HUP `cat $PID`
echo "$NAME."
;;
*)
echo "Usage: $NAME {start|stop|restart|reload}" >&2
exit 1
;;
esac
exit 0

33
lib/support/nginx-gitlab Normal file
View file

@ -0,0 +1,33 @@
upstream gitlab {
server unix:/home/gitlab/gitlab/tmp/sockets/gitlab.socket;
}
server {
listen YOUR_SERVER_IP:80; # e.g., listen 192.168.1.1:80;
server_name YOUR_SERVER_FQDN; # e.g., server_name source.example.com;
root /home/gitlab/gitlab/public;
# individual nginx logs for this gitlab vhost
access_log /var/log/nginx/gitlab_access.log;
error_log /var/log/nginx/gitlab_error.log;
location / {
# serve static files from defined root folder;.
# @gitlab is a named location for the upstream fallback, see below
try_files $uri $uri/index.html $uri.html @gitlab;
}
# if a file, which is not found in the root folder is requested,
# then the proxy pass the request to the upsteam (gitlab unicorn)
location @gitlab {
proxy_redirect off;
# you need to change this to "https", if you set "ssl" directive to "on"
proxy_set_header X-FORWARDED_PROTO http;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://gitlab;
}
}

View file

@ -0,0 +1,26 @@
desc "Add all users to all projects, system administratos are added as masters"
task :add_users_to_project_teams => :environment do |t, args|
users = User.find_all_by_admin(false, :select => 'id').map(&:id)
admins = User.find_all_by_admin(true, :select => 'id').map(&:id)
users.each do |user|
puts "#{user}"
end
Project.all.each do |project|
puts "Importing #{users.length} users into #{project.path}"
UsersProject.bulk_import(project, users, UsersProject::DEVELOPER)
puts "Importing #{admins.length} admins into #{project.path}"
UsersProject.bulk_import(project, admins, 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_email = args.email
user = User.find_by_email(user_email)
project_ids = Project.all.map(&:id)
UsersProject.user_bulk_import(user,project_ids,UsersProject::DEVELOPER)
end

View file

@ -144,8 +144,7 @@ namespace :gitlab do
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}",
"sudo chown gitlab:gitlab /home/git/repositories/**/hooks/post-receive"
"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

View file

@ -2,9 +2,7 @@ namespace :gitlab do
namespace :app do
desc "GITLAB | Enable auto merge"
task :enable_automerge => :environment do
Gitlab::GitHost.system.new.configure do |git|
git.admin_all_repo
end
Gitlab::Gitolite.new.enable_automerge
Project.find_each do |project|
if project.repo_exists? && !project.satellite.exists?

View file

@ -16,7 +16,7 @@ namespace :gitlab do
task :update_keys => :environment do
puts "Starting Key"
Key.find_each(:batch_size => 100) do |key|
key.update_repository
Gitlab::Gitolite.new.set_key(key.identifier, key.key, key.projects)
print '.'
end
puts "Done with keys"

View file

@ -1,7 +1,11 @@
namespace :gitlab do
namespace :app do
desc "GITLAB | Setup production application"
task :setup => ['db:setup', 'db:seed_fu', 'gitlab:app:enable_automerge']
task :setup => [
'db:setup',
'db:seed_fu',
'gitlab:app:enable_automerge'
]
end
end

View file

@ -56,6 +56,20 @@ namespace :gitlab do
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 "Validating projects repositories:".yellow
Project.find_each(:batch_size => 100) do |project|
@ -67,13 +81,7 @@ namespace :gitlab do
next
end
unless File.owned?(hook_file)
puts "post-receive file is not owner by gitlab".red
next
end
puts "post-reveice file ok".green
puts "post-receive file ok".green
end
end

View file

@ -1,19 +0,0 @@
namespace :gitlab do
namespace :gitolite do
desc "GITLAB | Rewrite hooks for repos"
task :update_hooks => :environment do
puts "Starting Projects"
Project.find_each(:batch_size => 100) do |project|
begin
if project.commit
project.write_hooks
print ".".green
end
rescue Exception => e
print e.message.red
end
end
puts "\nDone with projects"
end
end
end

View file

@ -0,0 +1,23 @@
namespace :gitlab do
namespace :gitolite do
desc "GITLAB | Write GITLAB hook for gitolite"
task :write_hooks => :environment do
gitolite_hooks_path = File.join(Gitlab.config.git_hooks_path, "common")
gitlab_hooks_path = Rails.root.join("lib", "hooks")
gitlab_hook_files = ['post-receive']
gitlab_hook_files.each do |file_name|
source = File.join(gitlab_hooks_path, file_name)
dest = File.join(gitolite_hooks_path, file_name)
puts "sudo -u root cp #{source} #{dest}".yellow
`sudo -u root cp #{source} #{dest}`
puts "sudo -u root chown git:git #{dest}".yellow
`sudo -u root chown git:git #{dest}`
end
end
end
end