diff --git a/files/gitlab/database.yml b/files/gitlab/database.yml new file mode 100644 index 0000000000..0a8e2f21e9 --- /dev/null +++ b/files/gitlab/database.yml @@ -0,0 +1,10 @@ +production: + adapter: mysql2 + encoding: utf8 + reconnect: false + database: gitlabhq_production + pool: 5 + username: gitlab + password: "$database_password" + # host: localhost + # # socket: /tmp/mysql.sock diff --git a/files/gitlab/gitlab-worker.service b/files/gitlab/gitlab-worker.service new file mode 100644 index 0000000000..40c7c89308 --- /dev/null +++ b/files/gitlab/gitlab-worker.service @@ -0,0 +1,13 @@ +[Unit] +Description=Gitlab Resque Worker +Requires=redis.service +After=redis.service +Wants=postfix.service mysqld.service + +[Service] +Type=forking +User=gitlab +WorkingDirectory=/home/gitlab/gitlab +ExecStart=/bin/sh -c "RAILS_ENV=production bundle exec rake sidekiq:start" +ExecStopPost=/bin/sh -c "RAILS_ENV=production bundle exec rake sidekiq:stop" +PIDFile=/home/gitlab/gitlab/tmp/pids/sidekiq.pid diff --git a/files/gitlab/gitlab.service b/files/gitlab/gitlab.service new file mode 100644 index 0000000000..d22a834f0f --- /dev/null +++ b/files/gitlab/gitlab.service @@ -0,0 +1,15 @@ +[Unit] +Description=Gitlab Unicorn +Requires=redis.service mysqld.service +After=redis.service mysqld.service +Wants=postfix.service mysqld.service gitlab-worker.service + +[Service] +Type=simple +User=gitlab +WorkingDirectory=/home/gitlab/gitlab +ExecStart=/bin/sh -c "bundle exec unicorn_rails -c /home/gitlab/gitlab/config/unicorn.rb -E production" +PIDFile=/home/gitlab/gitlab/tmp/pids/unicorn.pid + +[Install] +WantedBy=multi-user.target diff --git a/files/gitlab/iptables b/files/gitlab/iptables new file mode 100644 index 0000000000..878b981078 --- /dev/null +++ b/files/gitlab/iptables @@ -0,0 +1,14 @@ +*filter +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT +-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT + +-A INPUT -j REJECT --reject-with icmp-host-prohibited +-A FORWARD -j REJECT --reject-with icmp-host-prohibited +COMMIT + diff --git a/files/gitlab/unicorn.rb b/files/gitlab/unicorn.rb new file mode 100644 index 0000000000..0c916ceff2 --- /dev/null +++ b/files/gitlab/unicorn.rb @@ -0,0 +1,68 @@ +# uncomment and customize to run in non-root path +# note that config/gitlab.yml web path should also be changed +# ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" + +app_dir = "/home/gitlab/gitlab/" +worker_processes 2 +working_directory app_dir + +# Load app into the master before forking workers for super-fast +# worker spawn times +preload_app true + +# nuke workers after 30 seconds (60 is the default) +timeout 30 + +# listen on a Unix domain socket and/or a TCP port, + +listen 3000 # listen to port 8080 on all TCP interfaces +#listen "127.0.0.1:8080" # listen to port 8080 on the loopback interface +listen "#{app_dir}/tmp/sockets/gitlab.socket" + +pid "#{app_dir}/tmp/pids/unicorn.pid" +stderr_path "#{app_dir}/log/unicorn.stderr.log" +stdout_path "#{app_dir}/log/unicorn.stdout.log" + +# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow +if GC.respond_to?(:copy_on_write_friendly=) + GC.copy_on_write_friendly = true +end + + +before_fork do |server, worker| + # the following is highly recomended for Rails + "preload_app true" + # as there's no need for the master process to hold a connection + defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! + + ## + # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and + # immediately start loading up a new version of itself (loaded with a new + # version of our app). When this new Unicorn is completely loaded + # it will begin spawning workers. The first worker spawned will check to + # see if an .oldbin pidfile exists. If so, this means we've just booted up + # a new Unicorn and need to tell the old one that it can now die. To do so + # we send it a QUIT. + # + # Using this method we get 0 downtime deploys. + + old_pid = "#{server.config[:pid]}.oldbin" + + if File.exists?(old_pid) && server.pid != old_pid + begin + sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU + Process.kill(sig, File.read(old_pid).to_i) + rescue Errno::ENOENT, Errno::ESRCH + # someone else did our job for us + end + end +end + +after_fork do |server, worker| + # Unicorn master loads the app then forks off workers - because of the way + # Unix forking works, we need to make sure we aren't using any of the parent's + # sockets, e.g. db connection + + defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection + # Redis and Memcached would go here but their connections are established + # on demand, so the master never opens a socket +end diff --git a/files/gitlab/vhost.conf b/files/gitlab/vhost.conf new file mode 100644 index 0000000000..ff3b2b08a7 --- /dev/null +++ b/files/gitlab/vhost.conf @@ -0,0 +1,15 @@ + + ServerName gitlab-dev.cloud.fedoraproject.org + + # Uncomment if you want redirect from HTTP to HTTPS + #RewriteEngine on + #RewriteCond %{SERVER_PORT} ^80$ + #RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] + + ProxyPass / http://127.0.0.1:3000/ + ProxyPassReverse / http://127.0.0.1:3000/ + ProxyPreserveHost On + + #CustomLog logs/httpd/gitlab-access.log combined + #ErrorLog logs/httpd/gitlab-error.log + diff --git a/inventory/host_vars/gitlab-dev.cloud.fedoraproject.org b/inventory/host_vars/gitlab-dev.cloud.fedoraproject.org new file mode 100644 index 0000000000..c3b3551e2a --- /dev/null +++ b/inventory/host_vars/gitlab-dev.cloud.fedoraproject.org @@ -0,0 +1,10 @@ +--- +instance_type: m1.small +image: ami-00000016 +keypair: admin +security_group: webserver +zone: fedoracloud +hostbase: gitlab-dev- +public_ip: 209.132.184.158 +root_auth_users: skvidal codeblock +description: GitLab development/testing instance diff --git a/inventory/inventory b/inventory/inventory index ca87fc37b7..e2ff0269b8 100644 --- a/inventory/inventory +++ b/inventory/inventory @@ -329,6 +329,7 @@ virthost-comm01.qa.fedoraproject.org 209.132.184.142 # lists-dev.cloud.fedoraproject.org on openstack 209.132.184.145 +gitlab-dev.cloud.fedoraproject.org [jenkins-slaves] 209.132.184.165 diff --git a/playbooks/hosts/gitlab-dev.cloud.fedoraproject.org.yml b/playbooks/hosts/gitlab-dev.cloud.fedoraproject.org.yml new file mode 100644 index 0000000000..59b0a8ec32 --- /dev/null +++ b/playbooks/hosts/gitlab-dev.cloud.fedoraproject.org.yml @@ -0,0 +1,219 @@ +- name: check/create instance + hosts: gitlab-dev.cloud.fedoraproject.org + user: root + gather_facts: False + + vars_files: + - /srv/web/infra/ansible/vars/global.yml + - ${private}/vars.yml + + tasks: + - include: $tasks/persistent_cloud.yml + +- name: provision instance + hosts: gitlab-dev.cloud.fedoraproject.org + user: root + gather_facts: True + + vars_files: + - /srv/web/infra/ansible/vars/global.yml + - ${private}/vars.yml + - ${vars}/${ansible_distribution}.yml + - ${private}/gitlab/vars.yml + + tasks: + - include: $tasks/cloud_setup_basic.yml + + handlers: + - include: $handlers/restart_services.yml + +- hosts: gitlab-dev.cloud.fedoraproject.org + user: root + tasks: + - name: Install necessary packages + yum: state=present name=$item + with_items: + - httpd + - ruby + - rubygems + - ruby-devel + - git + - python-pygments + - perl-Data-Dumper + - postfix + - redis + - libicu-devel + - libxslt-devel + - libxml2-devel + - mysql-server + - mysql-devel + - MySQL-python + - gcc + - gcc-c++ + - glibc-devel + + - name: Start services and make them start on boot + shell: systemctl enable $item.service && systemctl start $item.service + with_items: + - mysqld + - redis + - httpd + + - name: Create user 'git' + user: state=present name=git system=yes shell=/bin/sh comment="Git Version Control" + + - name: Create user 'gitlab' + user: state=present name=gitlab groups=git comment="GitLab" generate_ssh_key=yes + notify: + - Add local ssh key to known_hosts + + handlers: + - name: Add local ssh key to known_hosts + shell: ssh-keyscan localhost >> /home/gitlab/.ssh/known_hosts + +- hosts: gitlab-dev.cloud.fedoraproject.org + user: root + sudo: yes + sudo_user: git + tasks: + - name: Clone the gitlab fork of gitolite + git: repo=https://github.com/gitlabhq/gitolite.git dest=/home/git/gitolite version=gl-v320 + + - name: ensure /home/git/bin exists + file: state=directory path=/home/git/bin + # It’s not ideal to solve this using handlers, but we don’t want that append script to trigger twice – and it’s not possible to check if it has run without doing anything crazy. + notify: + - Setup gitolite PATH + - Setup gitolite symlink + + handlers: + - name: Setup gitolite PATH + command: sh -c 'printf "%b\n%b\n" "PATH=\$PATH:/home/git/bin" "export PATH" >> /home/git/.profile' + + - name: Setup gitolite symlink + command: sh -c 'gitolite/install -ln /home/git/bin' chdir=/home/git + +- hosts: gitlab-dev.cloud.fedoraproject.org + user: root + tasks: + - name: Copy the 'gitlab' user SSH key to the 'git' user home directory + command: cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub creates=/home/git/gitlab.pub + + - name: Set permissions on the copied SSH key + file: path=/home/git/gitlab.pub mode=0444 + +- hosts: gitlab-dev.cloud.fedoraproject.org + user: root + sudo: yes + sudo_user: git + tasks: + - name: Run gitolite setup (creates gitolite-admin repo) + command: sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub" creates=/home/git/repositories/gitolite-admin.git + +- hosts: gitlab-dev.cloud.fedoraproject.org + user: root + tasks: + - name: Ensure Gitolite config dir is owned by git:git and has mode 750 + file: state=directory path=/home/git/.gitolite mode=750 owner=git group=git recurse=yes + + - name: Fix directory permissions for repositories (1) + command: chmod -R ug+rwX,o-rwx /home/git/repositories/ + + - name: Fix directory permissions for repositories (2) + file: state=directory path=/home/git/repositories owner=git group=git recurse=yes + + - name: Fix directory permissions for repositories (3) + shell: find /home/git/repositories -type d -print0 | sudo xargs -0 chmod g+s + + - name: Fix directory permissions for /home/git + shell: chmod 750 /home/git + + - name: Create a MySQL db + mysql_db: state=present name=gitlabhq_production collation=utf8_unicode_ci encoding=utf8 + + - name: Add a MySQL 'gitlab' user + mysql_user: state=present name=gitlab host=localhost password=$database_password + + - name: Grant permissions to the new MySQL 'gitlab' user + mysql_user: state=present name=gitlab priv=gitlabhq_production.*:SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER + + - name: Install some extra necessary gems + command: gem install $item + with_items: + - charlock_holmes + - bundler + +- hosts: gitlab-dev.cloud.fedoraproject.org + user: root + sudo: yes + sudo_user: gitlab + tasks: + - name: Clone GitLab 4.2 stable + git: repo=https://github.com/gitlabhq/gitlabhq.git dest=/home/gitlab/gitlab version=4-2-stable + + # TODO: Make this a template in case we want to tweak. + - name: Copy example config file into place + command: cp /home/gitlab/gitlab/config/gitlab.yml.example /home/gitlab/gitlab/config/gitlab.yml creates=/home/gitlab/gitlab/config/gitlab.yml + + - name: Create Unicorn config + template: src=$files/gitlab/unicorn.rb dest=/home/gitlab/gitlab/config/unicorn.rb + + - name: Create database config + template: src=$files/gitlab/database.yml dest=/home/gitlab/gitlab/config/database.yml + + - name: Run bundler + command: /usr/local/bin/bundle install --deployment --without development test postgres chdir=/home/gitlab/gitlab + + - name: Set git username + command: chdir=/home/gitlab git config --global user.name "GitLab" + + - name: Set git email + command: chdir=/home/gitlab git config --global user.email "gitlab@localhost" # Should use same user.email as in config/gitlab.yml – is it really needed? + + - name: run rake gitlab:setup + shell: chdir=/home/gitlab/gitlab yes yes | /usr/local/bin/bundle exec rake gitlab:setup RAILS_ENV=production + +- hosts: gitlab-dev.cloud.fedoraproject.org + user: root + tasks: + - name: Copy post-receive hook + command: cp /home/gitlab/gitlab/lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive creates=/home/git/.gitolite/hooks/common/post-receive + + - name: Set permissions on post-receive hook + file: state=file path=/home/git/.gitolite/hooks/common/post-receive owner=git group=git + + - name: Put gitlab and gitlab-worker systemd files in place + template: src=$files/gitlab/$item.service dest=/lib/systemd/system/$item.service + with_items: + - gitlab + - gitlab-worker + + - name: Symlink systemd files into /etc + command: creates=/etc/systemd/system/$item.service ln -s /usr/lib/systemd/system/$item.service /etc/systemd/system/ + with_items: + - gitlab + - gitlab-worker + + - name: Tell systemd to find the new files + command: systemctl --system daemon-reload + + - name: Start gitlab at boot + command: systemctl enable gitlab + + - name: Start gitlab now + command: systemctl start gitlab.service + + - name: Configure Apache + template: src=$files/gitlab/vhost.conf dest=/etc/httpd/conf.d/gitlab.conf + + - name: Allow Apache to proxy to Unicorn (SELinux) + command: setsebool -P httpd_can_network_connect 1 + + - name: Restart Apache + command: service httpd restart + + - name: Fix iptables + template: src=$files/gitlab/iptables dest=/etc/sysconfig/iptables + + - name: Restart iptables + command: service iptables restart