# Copyright 1999-2014 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ EAPI="5" # Maintainer notes: # - This ebuild uses Bundler to download and install all gems in deployment mode # (i.e. into isolated directory inside application). That's not Gentoo way how # it should be done, but GitLab has too many dependencies that it will be too # difficult to maintain them via ebuilds. # USE_RUBY="ruby21" PYTHON_COMPAT=( python2_7 ) inherit eutils python-r1 ruby-ng user DESCRIPTION="GitLab CI is a continuous integration server that is tightly integrated with GitLab" HOMEPAGE="https://gitlab.com/gitlab-org/gitlab-ci" SRC_URI="https://github.com/gitlabhq/gitlab-ci/archive/v${PV}.tar.gz -> ${P}.tar.gz" RESTRICT="mirror" LICENSE="MIT" SLOT="0" KEYWORDS="~amd64 ~x86" IUSE="mysql +postgres" ## Gems dependencies: # charlock_holmes dev-libs/icu # grape, capybara dev-libs/libxml2, dev-libs/libxslt # pg dev-db/postgresql # mysql virtual/mysql # GEMS_DEPEND=" dev-libs/icu dev-libs/libxml2 dev-libs/libxslt postgres? ( >=dev-db/postgresql-9.1:* ) mysql? ( virtual/mysql )" DEPEND="${GEMS_DEPEND} dev-vcs/git" RDEPEND="${DEPEND} dev-db/redis virtual/mta" ruby_add_bdepend " virtual/rubygems >=dev-ruby/bundler-1.0" # no patches needed so far ... #RUBY_PATCHES=( #) MY_NAME="gitlab-ci" MY_USER="gitlab_ci" DEST_DIR="/opt/${MY_NAME}" CONF_DIR="/etc/${MY_NAME}" LOGS_DIR="/var/log/${MY_NAME}" TEMP_DIR="/var/tmp/${MY_NAME}" RUN_DIR="/run/${MY_NAME}" # When updating ebuild to newer version, check list of the queues in # https://gitlab.com/gitlab-org/gitlab-ci/blob/v${PV}/script/background_jobs SIDEKIQ_QUEUES="runner,common,default" pkg_setup() { enewgroup gitlab_ci enewuser gitlab_ci -1 /bin/bash ${DEST_DIR} "gitlab_ci,cron,redis" } all_ruby_prepare() { # fix paths sed -i -E \ -e "s|redis://redis.example.com:6379|unix:/run/redis/redis.sock|" \ config/resque.yml.example || die "failed to filter resque.yml.example" sed -i -E \ -e "s|/home/gitlab_ci/gitlab-ci/tmp/(pids\|sockets)|${RUN_DIR}|" \ -e "s|/home/gitlab_ci/gitlab-ci/log|${LOGS_DIR}|" \ -e "s|/home/gitlab_ci/gitlab-ci|${DEST_DIR}|" \ config/unicorn.rb.example || die "failed to filter unicorn.rb.example" sed -i \ -e "s|/home/gitlab_ci/gitlab-ci/tmp/sockets|${RUN_DIR}|" \ -e "s|/home/gitlab_ci/gitlab-ci/public|${DEST_DIR}/public|" \ lib/support/nginx/gitlab_ci || die "failed to filter nginx/gitlab_ci" # modify default database settings for PostgreSQL sed -i -E \ -e 's|(username:).*|\1 gitlab|' \ -e 's|(password:).*|\1 gitlab|' \ -e 's|(socket:).*|/run/postgresql/.s.PGSQL.5432|' \ config/database.yml.postgresql \ || die "failed to filter database.yml.postgresql" # modify default database settings for MySQL sed -i -E \ -e "s|/tmp/mysql.sock|/run/mysqld/mysqld.sock|" \ config/database.yml.mysql || die "failed to filter database.yml.mysql" # rename config files mv config/application.yml.example config/application.yml mv config/unicorn.rb.example config/unicorn.rb local dbconf=config/database.yml if use postgres && ! use mysql; then mv ${dbconf}.postgresql ${dbconf} rm ${dbconf}.mysql elif use mysql && ! use postgres; then mv ${dbconf}.mysql ${dbconf} rm ${dbconf}.postgresql fi # remove useless files rm -r lib/support/init.d } all_ruby_install() { local dest=${DEST_DIR} local conf=${CONF_DIR} local logs=${LOGS_DIR} local temp=${TEMP_DIR} local runs=${RUN_DIR} # prepare directories diropts -m750 dodir ${logs} ${temp} diropts -m755 dodir ${conf} ${dest}/public/uploads dosym ${temp} ${dest}/tmp dosym ${logs} ${dest}/log # install configs insinto ${conf} doins -r config/* dosym ${conf} ${dest}/config echo 'export RAILS_ENV=production' > "${D}/${dest}/.profile" # remove needless dirs rm -Rf config tmp log # install the rest files # using cp 'cause doins is slow cp -Rl * "${D}/${dest}"/ # install logrotate config dodir /etc/logrotate.d cat > "${D}/etc/logrotate.d/${MY_NAME}" <<-EOF ${logs}/*.log { missingok delaycompress compress copytruncate } EOF ## Install gems via bundler ## cd "${D}/${dest}" local without="development test aws" local flag; for flag in mysql postgres; do without+="$(use $flag || echo ' '$flag)" done local bundle_args="--deployment ${without:+--without ${without}}" einfo "Running bundle install ${bundle_args} ..." ${RUBY} /usr/bin/bundle install ${bundle_args} || die "bundler failed" # clean gems cache rm -Rf vendor/bundle/ruby/*/cache # fix permissions fowners -R ${MY_USER}:${MY_USER} ${dest} ${temp} ${logs} fowners ${MY_USER}:${MY_USER} ${conf}/database.yml fperms 640 ${conf}/database.yml ## RC script ## local rcscript=gitlab-ci-unicorn.init cp "${FILESDIR}/${rcscript}" "${T}" || die sed -i \ -e "s|@USER@|${MY_USER}|" \ -e "s|@GITLAB_CI_BASE@|${dest}|" \ -e "s|@LOGS_DIR@|${logs}|" \ -e "s|@RUN_DIR@|${runs}|" \ -e "s|@QUEUES@|${SIDEKIQ_QUEUES}|" \ "${T}/${rcscript}" \ || die "failed to filter ${rcscript}" newinitd "${T}/${rcscript}" "${MY_NAME}" } pkg_postinst() { elog elog "1. Configure your GitLab CI's settings in ${CONF_DIR}/application.yml." elog elog "2. Configure your database settings in ${CONF_DIR}/database.yml" elog " for \"production\" environment." elog elog "3. Adjust the webserver settings in ${CONF_DIR}/unicorn.rb" elog elog "4. Then you should create a database for your GitLab CI instance, if you" elog "haven't done so already." elog if use postgres; then elog "If you have local PostgreSQL running, just copy&run:" elog " su postgres" elog " psql -c \"CREATE ROLE gitlab_ci PASSWORD 'gitlab_ci' \\" elog " NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;\"" elog " createdb -E UTF-8 -O gitlab_ci gitlab_ci_production" elog " Note: You should change your password to something more random..." elog fi elog "4. Finally execute the following command to initlize environment:" elog " emerge --config \"=${CATEGORY}/${PF}\"" elog " Note: Do not forget to start Redis server first!" elog elog "If this is an update from previous version, it's HIGHLY recommended" elog "to backup your database before running the config phase!" } pkg_config() { einfo "Checking configuration files" if [ ! -r "${CONF_DIR}/database.yml" ]; then eerror "Copy ${CONF_DIR}/database.yml.* to" eerror "${CONF_DIR}/database.yml and edit this file in order to configure your" eerror "database settings for \"production\" environment."; die fi local email_from="$(ryaml ${CONF_DIR}/application.yml production gitlab_ci email_from)" local gitlab_ci_home="$(egethome ${MY_USER})" # configure Git global settings if [ ! -e "${gitlab_ci_home}/.gitconfig" ]; then einfo "Setting git user" su -l ${MY_USER} -c " git config --global user.email '${email_from}'; git config --global user.name 'GitLab CI'" \ || die "failed to setup git name and email" fi if [ ! -d "${DEST_DIR}/.git" ]; then # create dummy git repo as workaround for # https://github.com/bundler/bundler/issues/2039 einfo "Initializing dummy git repository to avoid false errors from bundler" su -l ${MY_USER} -c " cd ${DEST_DIR} git init git add README.md git commit -m 'Dummy repository'" >/dev/null fi ## Initialize app ## local RAILS_ENV="production" local RUBY=${RUBY:-/usr/bin/ruby} local BUNDLE="${RUBY} /usr/bin/bundle" local dbname="$(ryaml ${CONF_DIR}/database.yml production database)" if [ -f "${DEST_DIR}/.secret" ]; then local update=true einfo "Migrating database ..." exec_rake db:migrate else local update=false einfo "Initializing database ..." exec_rake setup einfo "Setting up cron schedules ..." exec_rake whenever -w fi if [ "${update}" = 'true' ]; then ewarn ewarn "This configuration script runs only common migration tasks." ewarn "Please read guides on" ewarn " https://gitlab.com/gitlab-org/gitlab-ci/tree/v${PV}/doc/update" ewarn "for any additional migration tasks specific to your previous GitLab CI" ewarn "version." fi } ryaml() { ruby -ryaml -e 'puts ARGV[1..-1].inject(YAML.load(File.read(ARGV[0]))) {|acc, key| acc[key] }' "$@" } exec_rake() { local command="${BUNDLE} exec rake $@ RAILS_ENV=${RAILS_ENV}" echo " ${command}" su -l ${MY_USER} -c " export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8 cd ${DEST_DIR} ${command}" \ || die "failed to run rake $@" }