blob: 3653598bf8c9c63410e484304848c08dad4d6887 [file] [log] [blame]
#!/bin/bash
#
# module.sh - gerrit
#
# Copyright 2019 Luigi Santivetti <luigi.santivetti@gmail.com>
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
declare -r module="gerrit"
source $common_sh
module_enable $module
declare -r etc_d="$mod_rootfs_d/etc"
declare -r logs_d="$mod_rootfs_d/var/log/gerrit"
declare -r hooks_d="$mod_rootfs_d/hooks"
declare -r hooks_mir="gerrit-hooks.git"
declare -r keystore="$host_name.keystore"
declare -r keystore_pkcs12="$host_name.pkcs12.keystore"
declare -r keystore_f="$etc_d/$keystore_pkcs12"
declare -r config_f="$etc_d/gerrit.config"
declare -r secure_f="$etc_d/secure.config"
declare -r entrypoint="entrypoint.sh"
declare -r entrypoint_f="$mod_docker_d/$entrypoint"
declare -r dockerfile="Dockerfile"
declare -r dockerfile_f="$mod_docker_d/$dockerfile"
declare -r gerrit_cli_f="$mod_docker_d/gerrit-cli.sh"
declare -r war_version="3.0.0"
declare -r war_mirror="https://gerrit-releases.storage.googleapis.com"
declare -r revision="1"
declare -r rsa_id="${host_name}-con-gerrit.id_rsa"
declare -r rsa_id_f="$mod_rootfs_d/etc/$rsa_id"
# Gerrit is always configured with a loopback on localhost. If the web server
# is configured to only utilise SSL encryption for all the public incoming
# and outgoing traffic, unencrypted requests and responses over simple http
# made to and from Gerrit (i.e. headers) are never exposed to the outside
# world. 'gerrit_has_https' allows to also encrypt looped back traffic that,
# as it stands, should be considered redundant.
declare -r gerrit_has_https=1
if [ "$gerrit_has_https" -eq 1 ]; then
declare -r jar_sslib_mir1="https://gerrit-ci.gerritforge.com/job"
declare -r jar_sslib_mir2="plugin-secure-config-bazel-stable-3.0/lastSuccessfulBuild"
declare -r jar_sslib_mir3="artifact/bazel-bin/plugins/secure-config"
declare -r jar_sslib="secure-config"
declare -r jar_sslib_f="${mod_rootfs_d}/lib/${jar_sslib}.jar"
fi
# Staged resources
declare -r war_f="$mod_staging_d/gerrit-$war_version.war"
declare -ar mod_more_dirs=( $etc_d $logs_d $hooks_d )
declare -ar mod_more_files=( $config_f $secure_f $entrypoint_f $dockerfile_f $gerrit_cli_f )
declare -ar mod_more_trefs=( config_t secure_t entrypoint_bang_t dockerfile_t gerrit_cli_bang_t )
function tod_watch
{
__watch_module_common || return $s_err
}
function tod_doins
{
__fetch_module_common || return $s_err
__gerrit_do_sitepath || return $s_err
# Update $config_f after init is done
__doins_module_common || return $s_err
__gerrit_do_lock || return $s_err
}
function tod_fetch
{
__fetch_module_common || return $s_err
}
function tod_upins
{
__gerrit_do_unlock || return $s_err
__upins_module_common || return $s_err
__gerrit_do_lock || return $s_err
}
function tod_clmod
{
__clmod_module_common || return $s_err
}
function tod_clins
{
__clins_module_common || return $s_err
}
function tod_doall
{
tod_doins || return $s_err
tod_upmod || return $s_err
}
function tod_upall
{
tod_upins || return $s_err
tod_upmod || return $s_err
}
function tod_upmod
{
__fetch_module_common || return $s_err
__gerrit_do_keystore || return $s_err
__gerrit_do_hooks || return $s_err
__gerrit_do_ssh_rsa_id || return $s_err
}
function __gerrit_do_lock
{
set_mode "0644" "root" $config_f
set_mode "0644" "root" $secure_f
}
function __gerrit_do_unlock
{
set_mode "0666" "1000" $config_f
set_mode "0666" "1000" $secure_f
}
function __gerrit_do_sitepath
{
[ -f "$war_f" ] || {
lets -l -e "missing $(basename $war_f), is it in the MANIFEST?"
return $s_err
}
# Make a bare skeleton of the essential rootfs tree
java -jar "$war_f" init --batch --skip-plugins --delete-caches --no-auto-start \
--site-path "$mod_rootfs_d" 2>&1 | lets -l -x "java"
[ ${PIPESTATUS[0]} -eq 0 ] || {
lets -l -e "failed to init gerrit SITE_PATH"
return $s_err
}
sleep 1
# Remove runtime files and directories
rm -f $mod_rootfs_d/etc/{ssh,secure}*
rm -Rf $mod_rootfs_d/{static,index,logs,data,index,cache,git,db,tmp}/*
# Make sure gerrit.config is present before any real init is ever attempted
[ -f "$config_f" ]
}
function __gerrit_do_sslib
{
# In order to use encrypted password, sslib needs to be available in /lib
cp $mod_staging_d/$jar_sslib.jar $jar_sslib_f
chmod 0664 $jar_sslib_f
local gerrit_war
if [ -f "$mod_rootfs_d/bin/gerrit.war" ]; then
gerrit_war="$mod_rootfs_d/bin/gerrit.war"
elif [ -f "$mod_staging_d/gerrit-$war_version.war" ]; then
gerrit_war="$mod_staging_d/gerrit-$war_version.war"
else
lets -l -e "gerrit.war not found"
return $s_err
fi
if [ -z "$PASSWD_F" ] || [ ! -f "$PASSWD_F" ]; then
lets -l -e "keystore needs PASSWD_F"
return $s_err
fi
source $PASSWD_F
[ -n "${_PASSWD_GERRIT_KEYSTORE_KEY_PASS_}" ] || {
lets -l -e "_PASSWD_GERRIT_KEYSTORE_KEY_PASS_ not defined"
return $s_err
}
__gerrit_do_unlock || return $s_err
java -jar $gerrit_war passwd -d "$mod_rootfs_d" \
httpd.sslKeyPassword "${_PASSWD_GERRIT_KEYSTORE_KEY_PASS_}" | lets -l -x "sslib"
java -jar $gerrit_war passwd -d "$mod_rootfs_d" \
auth.registerEmailPrivateKey "${_PASSWD_GERRIT_EMAIL_PRIV_KEY_}" | lets -l -x "sslib"
[ ${PIPESTATUS[0]} -eq 0 ] || return $s_err
__gerrit_do_lock
}
function __gerrit_do_keystore
{
if [ "$gerrit_has_https" -ne 1 ]; then
lets -l -i "secure config not enabled"
return $s_ok
fi
if [ ! -f "$mod_staging_d/$keystore" ] || \
[ ! -f "$mod_staging_d/$keystore_pkcs12" ]; then
[ -n "$PASSWD_F" ] && [ -f "$PASSWD_F" ] || {
lets -l -e "keystore needs PASSWD_F"
return $s_err
}
rm -f $mod_staging_d/$keystore
rm -f $mod_staging_d/$keystore_pkcs12
source $PASSWD_F
# This isn't run as part of templates creation, make sure variables are
# defined
[ -n "${_PASSWD_GERRIT_KEYSTORE_STORE_PASS_}" ] && \
[ -n "${_PASSWD_GERRIT_KEYSTORE_KEY_PASS_}" ] || {
lets -l -e "keystore needs passwords"
return $s_err
}
keytool -keystore $mod_staging_d/$keystore -v \
-alias $module -genkey -keyalg RSA \
-dname "cn=$host_name, ou=$host_name, o=$host_name, c=$host_name" \
-storepass ${_PASSWD_GERRIT_KEYSTORE_STORE_PASS_} \
-keypass ${_PASSWD_GERRIT_KEYSTORE_KEY_PASS_} 2>&1 | \
lets -l -x "keytool"
[ ${PIPESTATUS[0]} -eq 0 ] || {
lets -l -e "failed to create keystore: $mod_staging_d/$keystore"
return $s_err
}
lets -l -i "converting to keystore to PKCS12 format ..."
# Warning: Different store and key passwords not supported for PKCS12 KeyStores.
# So just use the same for both
keytool -importkeystore -deststoretype pkcs12 -noprompt -v \
-deststorepass ${_PASSWD_GERRIT_KEYSTORE_KEY_PASS_} \
-destkeypass ${_PASSWD_GERRIT_KEYSTORE_KEY_PASS_} \
-destkeystore $mod_staging_d/$keystore_pkcs12 \
-srcstorepass ${_PASSWD_GERRIT_KEYSTORE_STORE_PASS_} \
-srckeypass ${_PASSWD_GERRIT_KEYSTORE_KEY_PASS_} \
-srckeystore $mod_staging_d/$keystore -alias $module 2>&1 | \
lets -l -x "keytool"
[ "${PIPESTATUS[0]}" -eq 0 ] || {
lets -l -e "failed to convert PKCS12 keystore: $mod_staging_d/$keystore"
return $s_err
}
# Last bit, if we got this far, then we want to store the key password
# and gerrit requires it at start up. Do this using gerrit sslib
__gerrit_do_sslib || return $s_err
fi
sudo cp $mod_staging_d/$keystore_pkcs12 $keystore_f || return $s_err
sudo chmod 0600 $keystore_f && sudo chown root:root $keystore_f
}
function __gerrit_do_hooks
{
if [ ! -d "$mod_staging_d/$hooks_mir" ]; then
lets -l -w "$hooks_mir not found, not installing hooks"
return $s_ok
fi
sudo cp -ar --preserve=all $mod_staging_d/$hooks_mir/* $hooks_d/ || {
lets -l -e "failed to install hooks"
return $s_err
}
}
function __gerrit_do_ssh_rsa_id
{
if [ -f "$mod_staging_d/$rsa_id" ] && [ -f "$mod_staging_d/$rsa_id.pub" ]; then
lets -l -w "$rsa_id already exists"
else
sudo rm -f ${mod_staging_d}/${rsa_id}
sudo rm -f ${mod_staging_d}/${rsa_id}.pub
ssh-keygen -b 2048 -t rsa -f $mod_staging_d/$rsa_id -C "con@drkc" -N "" 2>&1 | \
lets -l -x "keygen"
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
lets -l -e "failed to create new rsa_id"
return $s_err
fi
fi
diff ${rsa_id_f}.pub $mod_staging_d/${rsa_id}.pub 2>&1 | lets -l -x "diff"
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
sudo cp -a --preserve=all ${mod_staging_d}/${rsa_id} ${rsa_id_f} || {
lets -l -e "failed to copy new rsa_id"
return $s_err
}
sudo cp -a --preserve=all ${mod_staging_d}/${rsa_id}.pub ${rsa_id_f}.pub || {
lets -l -e "failed to copy new rsa_id.pub"
sudo rm -f ${rsa_id_f}
return $s_err
}
else
lets -l -i "no need to copy new rsa_id.pub"
fi
}