opf/openproject

View on GitHub
packaging/addons/repositories/bin/postinstall

Summary

Maintainability
Test Coverage
#!/bin/bash

set -e

. ${INSTALLER_DIR}/wizard

CLI="${APP_NAME}"
VHOST_INCLUDES_DIR="/etc/${APP_NAME}/addons/apache2/includes/vhost"
SERVER_INCLUDES_DIR="/etc/${APP_NAME}/addons/apache2/includes/server"
OSFAMILY="$(wiz_fact osfamily)"
SERVER_USER=$(${CLI} config:get SERVER_USER || echo "")
SERVER_GROUP=$(${CLI} config:get SERVER_GROUP || echo "")
SERVER_PATH_PREFIX=$(${CLI} config:get SERVER_PATH_PREFIX || echo "")
INTERNAL_PORT=$(${CLI} config:get PORT || echo "6000")
INTERNAL_URL="http://127.0.0.1:${INTERNAL_PORT}${SERVER_PATH_PREFIX}"

##
# Create and set proper permissions to the given SVN repositories root
create_svn_repositories() {
    local svn_repositories="$(wiz_get "repositories/svn-path")"
    if [ ! -d "$svn_repositories" ] ; then
        mkdir -p "$svn_repositories"
    fi

    # Ensure permissions are set to what we need
    chown ${SERVER_USER}.${SERVER_GROUP} "$svn_repositories"
    chmod 2770 "$svn_repositories"

    ${CLI} config:set SVN_REPOSITORIES="$svn_repositories"

    if [ "$OSFAMILY" = "redhat" ] ; then
        chcon -R -h -t httpd_sys_content_t "$svn_repositories" || true
        chcon -R -h -t httpd_sys_rw_content_t "$svn_repositories" || true
    fi
}

##
# Create and set proper permissions to the given GIT repositories root
create_git_repositories() {
    local git_repositories="$(wiz_get "repositories/git-path")"
    local git_http_backend="$(wiz_get "repositories/git-http-backend")"

    if [ ! -d "$git_repositories" ] ; then
        mkdir -p "$git_repositories"
    fi

    # Ensure permissions are set to what we need
    chown ${APP_USER}.${SERVER_GROUP} "$git_repositories"
    chmod 2770 "$git_repositories"

    ${CLI} config:set GIT_REPOSITORIES="$git_repositories"

    if [ "$OSFAMILY" = "redhat" ] ; then
        chcon -R -h -t httpd_sys_content_t "$git_repositories" || true
        chcon -R -h -t httpd_sys_rw_content_t "$git_repositories" || true

        # selinux requires the file, NOT the path, so remove the trailing
        # slash we require elsewhere
        git_http_backend_file=${git_http_backend%/}
        chcon -t httpd_git_script_exec_t "$git_http_backend_file" || true
        chcon -R -t httpd_git_rw_content_t "$git_repositories" || true
    fi
}

##
# Determine whether the given vendor (svn/git)
# has been selected for installation in the wizard.
vendor_selected() {
    local VENDOR="$1"
    VENDOR_CHOICE=$(wiz_get "repositories/$VENDOR-install")

    [ "$VENDOR_CHOICE" = "install" ]
}


configure_api_key() {
    local sys_api_key="$(wiz_get "repositories/api-key")"
    ${CLI} config:set SYS_API_KEY="${sys_api_key}"
}

reload_apache2() {
    case "$OSFAMILY" in
        "debian"|"suse")
            service apache2 restart || true
            ;;
        "redhat")
            service httpd restart || true
            ;;
    esac
}

##
# Enable an included vhost configuration
enable_apache2_vhost_include() {
    local output="$1"
    chmod 0640 "$output"

    if [ "$OSFAMILY" = "redhat" ] ; then
        # deal with SELinux
        chcon -t httpd_config_t "$dst" || true
    fi
}

##
# Replace the configuration templates in 'svn_dav.conf'
# and output the configured file as an Apache vhost configuration.
setup_svn_configuration() {
    local apikey="$1"
    local src="conf/vhost/svn_dav.conf"
    local dst="$VHOST_INCLUDES_DIR/svn_dav.conf"
    local svn_repositories="$(wiz_get "repositories/svn-path")"

    tmpfile=$(mktemp)
    cp -f "$src" "$tmpfile"
    sed -i "s|_SVN_REPOSITORIES_|${svn_repositories}|g" ${tmpfile}
    sed -i "s|_APP_URI_|${INTERNAL_URL}|g" ${tmpfile}
    sed -i "s|_APP_API_KEY_|${sys_api_key}|g" ${tmpfile}
    sed -i "s|_SERVER_PATH_PREFIX_|${SERVER_PATH_PREFIX}|g" ${tmpfile}
    mv -f "$tmpfile" "$dst"

    enable_apache2_vhost_include "$dst"
}

##
# Configures the Apache repoman wrapper to create and delete SVN repositories
# through a simple API
# in order to bypass permission problems created when pushing to mod_svn / Apache
setup_subversion_wrapper() {
    local access_token="$1"
    local src="conf/vhost/repoman_svn_wrapper.conf"
    local dst="$VHOST_INCLUDES_DIR/repoman_svn_wrapper.conf"
    local svn_repositories="$(wiz_get "repositories/svn-path")"

    tmpfile=$(mktemp)
    cp -f "$src" "$tmpfile"
    sed -i "s|_REPOMAN_ACCESS_TOKEN_|${access_token}|g" ${tmpfile}
    sed -i "s|_SVN_REPOSITORIES_|${svn_repositories}|g" ${tmpfile}
    sed -i "s|_SERVER_PATH_PREFIX_|${SERVER_PATH_PREFIX}|g" ${tmpfile}
    mv -f "$tmpfile" "$dst"

    ${CLI} config:set SVN_REPOMAN_TOKEN="$access_token"
    ${CLI} config:set SVN_REPOMAN_URL="http://127.0.0.1${SERVER_PATH_PREFIX}repoman_svn"

    enable_apache2_vhost_include "$dst"
}


##
# Create a vhost for the repository wrapper to be accessed by localhost
setup_subversion_vhost() {
    local src="conf/server/20_repoman_svn_vhost.conf"
    local dst="$SERVER_INCLUDES_DIR/20_repoman_svn_vhost.conf"
    local repoman_location="$VHOST_INCLUDES_DIR/repoman_svn_wrapper.conf"

    tmpfile=$(mktemp)
    cp -f "$src" "$tmpfile"
    sed -i "s|_REPOMAN_SVN_CONF_LOCATION_|${repoman_location}|g" ${tmpfile}
    mv -f "$tmpfile" "$dst"

    enable_apache2_vhost_include "$dst"
}


##
# Replace the configuration templates in 'git_smart_http.conf'
# and output the configured file as an Apache vhost configuration.
setup_git_configuration() {
    local apikey="$1"
    local src="conf/vhost/git_smart_http.conf"
    local dst="$VHOST_INCLUDES_DIR/git_smart_http.conf"
    local git_repositories="$(wiz_get "repositories/git-path")"
    local git_http_backend="$(wiz_get "repositories/git-http-backend")"

    # Force trailing slash if missing to treat as CGI script
    trailing=${git_http_backend:length-1:1}
    [[ $trailing != "/" ]] && git_http_backend="${git_http_backend}/"; :

    tmpfile=$(mktemp)
    cp -f "$src" "$tmpfile"
    sed -i "s|_GIT_REPOSITORIES_|${git_repositories}|g" ${tmpfile}
    sed -i "s|_GIT_HTTP_BACKEND_|${git_http_backend}|g" ${tmpfile}
    sed -i "s|_APP_URI_|${INTERNAL_URL}|g" ${tmpfile}
    sed -i "s|_APP_API_KEY_|${sys_api_key}|g" ${tmpfile}
    sed -i "s|_SERVER_PATH_PREFIX_|${SERVER_PATH_PREFIX}|g" ${tmpfile}
    mv -f "$tmpfile" "$dst"

    enable_apache2_vhost_include "$dst"
}

##
# Let openproject be a member of the apache group
# for easier group-based sharing of repository directories
add_openproject_to_apache_group() {
    if usermod --help 2>&1 | grep -- "-A group" &>/dev/null ; then
        # sles11
        usermod -A "${SERVER_GROUP}" "${APP_USER}"
    else
        usermod -a -G "${SERVER_GROUP}" "${APP_USER}"
    fi
}

##
# Configure the correct perl include path for loading
# the OpenProjectAuthentication perl module.
# Configure and write SVN and Git configuration files as Apache vhosts.
configure_apache2_server() {
    local sys_api_key="$(wiz_get "repositories/api-key")"
    local repositories_perl_conf="$SERVER_INCLUDES_DIR/00_repositories_perl.conf"

    # Delete old configuration, if it exists
    local old_repositories_perl_conf="$SERVER_INCLUDES_DIR/repositories_perl.conf"
    if [ -e ${old_repositories_perl_conf} ] ; then
        rm -f ${old_repositories_perl_conf}
    fi

    case "$OSFAMILY" in
        "debian")
            mkdir -p /usr/lib/perl5/Apache/
            cp -f "${APP_HOME}/extra/Apache/OpenProjectAuthentication.pm" /usr/lib/perl5/Apache/
            cp -f "${APP_HOME}/extra/Apache/OpenProjectRepoman.pm" /usr/lib/perl5/Apache/
            cat - <<SERVER_CONF > "$repositories_perl_conf"
PerlSwitches -I/usr/lib/perl5
PerlLoadModule Apache::OpenProjectAuthentication
PerlLoadModule Apache::OpenProjectRepoman
SERVER_CONF
            ;;
        "redhat")
            local perl_dir="/usr/lib64/perl5/Apache/"
            mkdir -p $perl_dir
            cp -f "${APP_HOME}/extra/Apache/OpenProjectAuthentication.pm" "$perl_dir"
            cp -f "${APP_HOME}/extra/Apache/OpenProjectRepoman.pm" "$perl_dir"
            cat - <<SERVER_CONF > "$repositories_perl_conf"
PerlSwitches -I/usr/lib64/perl5/vendor_perl
PerlLoadModule Apache::OpenProjectAuthentication
PerlLoadModule Apache::OpenProjectRepoman
SERVER_CONF
            ;;
        "suse")
            local perl_version="$(perl -e 'print substr $^V, 1;')"
            local perl_dir="/usr/lib/perl5/vendor_perl/${perl_version}/Apache"
            mkdir -p "$perl_dir"
            cp -f "${APP_HOME}/extra/Apache/OpenProjectAuthentication.pm" "$perl_dir"
            cp -f "${APP_HOME}/extra/Apache/OpenProjectRepoman.pm" "$perl_dir"
            echo "PerlLoadModule Apache::OpenProjectAuthentication" > "$repositories_perl_conf"
            echo "PerlLoadModule Apache::OpenProjectRepoman" >> "$repositories_perl_conf"
            ;;
    esac

    # Install SVN and Git when requested
    if vendor_selected "svn"; then
        echo "Setting up SVN integration for Apache"

        # Install Apache wrapper
        local apache_wrapper_token="$(wiz_get "repositories/apache-wrapper-token")"
        setup_subversion_wrapper "$apache_wrapper_token"
        setup_subversion_vhost

        setup_svn_configuration "$sys_api_key"
        create_svn_repositories
    fi

    if vendor_selected "git"; then
        echo "Setting up Git integration for Apache"
        setup_git_configuration "$sys_api_key"
        create_git_repositories
    fi

    reload_apache2
}

install_apache_configuration() {
    ${CLI} config:set SVN_REPOSITORIES=""
    ${CLI} config:set GIT_REPOSITORIES=""

    if vendor_selected "svn" || vendor_selected "git"; then
        configure_apache2_server
        add_openproject_to_apache_group
    else
        echo "No repositories have been configured. Skipping configuration."
    fi
}

case "$(wiz_get "server/autoinstall")" in
    "skip")
        # vhost and config removal is already taken care of by the server wizard
        ;;
    "install")
        configure_api_key
        case "$(wiz_get "server/variant")" in
            "apache2")
                install_apache_configuration
                ;;
            *)
                echo "Unsupported server variant."
                ;;
        esac
        ;;
esac