diff --git a/.github/workflows/rpm-build.yml b/.github/workflows/rpm-build.yml index 6e34c4d9b8..87c7f2cbc0 100644 --- a/.github/workflows/rpm-build.yml +++ b/.github/workflows/rpm-build.yml @@ -91,13 +91,13 @@ jobs: cleaned_branch=${branch//[^a-zA-Z0-9_-]/} # Add the github run ID to the branch name - cleaned_branch=cleaned_branch-${{ github.run_id }} + cleaned_branch=$cleaned_branch-${{ github.run_id }} # Save the branch name to the environment echo "branch=$cleaned_branch" >> $GITHUB_OUTPUT # Set the testing and snapshot repository url to the job output - echo "rpm_repo_testing_url=$RPM_REPO_TESTING_URL/$branch" >> $GITHUB_OUTPUT + echo "rpm_repo_testing_url=$RPM_REPO_TESTING_URL/$cleaned_branch" >> $GITHUB_OUTPUT echo "rpm_repo_snapshots_url=$RPM_REPO_SNAPSHOTS_URL/openrouteservice-jws" >> $GITHUB_OUTPUT echo "rpm_repo_releases_url=$RPM_REPO_RELEASES_URL/openrouteservice-jws" >> $GITHUB_OUTPUT @@ -132,7 +132,7 @@ jobs: echo "CONTAINER_NAME=$CONTAINER_NAME" >> "$GITHUB_ENV" echo "PUSH_TO_DOCKER_HUB=$PUSH_TO_DOCKER_HUB" >> "$GITHUB_ENV" - - name: Build the RPM package + - name: Build the RPM packages id: rpmbuild run: | # Define the RPM build directory @@ -147,15 +147,21 @@ jobs: cp -f ${{ github.workspace }}/ors-api/target/ors.war $RPM_BUILD_DIR/BUILD/ cp -f ${{ github.workspace }}/.rpm-packaging/example-config.json $RPM_BUILD_DIR/BUILD/ rpmbuild -bb ${{ github.workspace }}/.rpm-packaging/ors-war.spec + rpmbuild -bb ${{ github.workspace }}/.rpm-packaging/ors-selinux.spec # Save the RPM package name and path as an step output - export rpm_name=openrouteservice-${{ env.ORS_VERSION }}-jws5-el8-noarch.rpm - export rpm_path=${{ github.workspace }}/$rpm_name - echo "RPM_NAME=$rpm_name" >> "$GITHUB_ENV" - echo "RPM_PATH=$rpm_path" >> "$GITHUB_ENV" + export rpm_ors_name=openrouteservice-${{ env.ORS_VERSION }}-jws5-el8-noarch.rpm + export rpm_ors_path=${{ github.workspace }}/$rpm_ors_name + echo "RPM_ORS_NAME=$rpm_ors_name" >> "$GITHUB_ENV" + echo "RPM_ORS_PATH=$rpm_ors_path" >> "$GITHUB_ENV" + export rpm_selinux_name=openrouteservice-${{ env.ORS_VERSION }}-jws5-selinux-el8-noarch.rpm + export rpm_selinux_path=${{ github.workspace }}/$rpm_selinux_name + echo "RPM_SELINUX_NAME=$rpm_selinux_name" >> "$GITHUB_ENV" + echo "RPM_SELINUX_PATH=$rpm_selinux_path" >> "$GITHUB_ENV" # Copy the RPM package to the workspace - cp -f $RPM_BUILD_DIR/RPMS/noarch/*.rpm $rpm_path + cp -f $RPM_BUILD_DIR/RPMS/noarch/openrouteservice-jws5-${{ env.ORS_VERSION }}-1.noarch.rpm $rpm_ors_path + cp -f $RPM_BUILD_DIR/RPMS/noarch/openrouteservice-jws5-selinux-${{ env.ORS_VERSION }}-1.noarch.rpm $rpm_selinux_path - name: Import the GPG key uses: MichaelsJP/ghaction-import-gpg@v1.0 @@ -184,15 +190,22 @@ jobs: - name: Sign the RPM package run: | - rpm --addsign ${{ env.RPM_PATH }} + rpm --addsign ${{ env.RPM_ORS_PATH }} + rpm --addsign ${{ env.RPM_SELINUX_PATH }} # Print signature details - rpm --query -pi ${{ env.RPM_PATH }} + rpm --query -pi ${{ env.RPM_ORS_PATH }} + rpm --query -pi ${{ env.RPM_SELINUX_PATH }} # Verify the signature and fail if it is not valid - rpm --checksig ${{ env.RPM_PATH }} + rpm --checksig ${{ env.RPM_ORS_PATH }} if [ $? -ne 0 ]; then echo "RPM signature is not valid" exit 1 fi + rpm --checksig ${{ env.RPM_SELINUX_PATH }} + if [ $? -ne 0 ]; then + echo "RPM_SELINUX signature is not valid" + exit 1 + fi - name: Prepare the RPM testing repository run: | @@ -204,7 +217,8 @@ jobs: - name: Upload the testing RPM run: | # Upload the RPM package to the testing repository - .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_testing_url }}/noarch/${{ env.RPM_NAME }}' + .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_ORS_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_testing_url }}/noarch/${{ env.RPM_ORS_NAME }}' + .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_SELINUX_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_testing_url }}/noarch/${{ env.RPM_SELINUX_NAME }}' - name: Login to Docker registry uses: docker/login-action@v2 @@ -300,9 +314,10 @@ jobs: # Restart the systemd service podman exec -u root ${{ env.CONTAINER_NAME }} sh -c 'systemctl restart jws5-tomcat.service' - + echo "Waiting for the podman container to build graphs and return 200" .github/utils/url_check.sh '127.0.0.1:8080/ors/v2/health' 200 ${{ env.HEALTH_WAIT_TIME }} + - name: Print the container logs for debugging if: runner.debug == '1' shell: bash @@ -337,8 +352,8 @@ jobs: uses: actions/upload-release-asset@v1 with: upload_url: ${{ github.event.release.upload_url }} - asset_path: ${{ env.RPM_PATH }} - asset_name: ${{ env.RPM_NAME }} + asset_path: ${{ env.RPM_ORS_PATH }} + asset_name: ${{ env.RPM_ORS_NAME }} asset_content_type: application/x-rpm - name: Upload the RPM package to the nexus releases rpm registry @@ -347,7 +362,8 @@ jobs: # Check that the RPM Nexus releases repository exists and fail completely if not. .github/utils/check_nexus_repo_exists.sh '${{ secrets.NEXUS_URL }}' '${{ env.RPM_REPO_NAME }}' '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' 'true' # Upload the RPM package to the nexus releases rpm registry - .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_releases_url }}/noarch/${{ env.RPM_NAME }}' + .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_ORS_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_releases_url }}/noarch/${{ env.RPM_ORS_NAME }}' + .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_SELINUX_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_releases_url }}/noarch/${{ env.RPM_SELINUX_NAME }}' # Do a curl request to the releases repository and wait for the repomd.xml to be initialized to ensure a correct repository .github/utils/url_check.sh '${{ steps.job_environment_variables.outputs.rpm_repo_releases_url }}/repodata/repomd.xml' 200 ${{ env.RPM_REPO_INIT_WAIT_TIME }} @@ -358,7 +374,8 @@ jobs: # Check that the RPM Nexus snapshots repository exists and fail completely if not. .github/utils/check_nexus_repo_exists.sh '${{ secrets.NEXUS_URL }}' '${{ env.RPM_REPO_NAME }}' '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' 'true' # Upload the RPM package to the nexus snapshots rpm registry - .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_snapshots_url }}/noarch/${{ env.RPM_NAME }}' + .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_ORS_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_snapshots_url }}/noarch/${{ env.RPM_ORS_NAME }}' + .github/utils/upload_rpm_package.sh '${{ secrets.NEXUS_USERNAME }}' '${{ secrets.NEXUS_PASSWORD }}' '${{ env.RPM_SELINUX_PATH }}' '${{ steps.job_environment_variables.outputs.rpm_repo_snapshots_url }}/noarch/${{ env.RPM_SELINUX_NAME }}' # Do a curl request to the releases repository and wait for the repomd.xml to be initialized to ensure a correct repository .github/utils/url_check.sh '${{ steps.job_environment_variables.outputs.rpm_repo_snapshots_url }}/repodata/repomd.xml' 200 ${{ env.RPM_REPO_INIT_WAIT_TIME }} diff --git a/.rpm-packaging/.rpm_selinux_testing.sh b/.rpm-packaging/.rpm_selinux_testing.sh new file mode 100755 index 0000000000..2fe32afab8 --- /dev/null +++ b/.rpm-packaging/.rpm_selinux_testing.sh @@ -0,0 +1,199 @@ +#!/bin/bash +# Get container name from first argument or use default +container_name=${1:-"ors-selinux-test"} +# Get ORS version from second argument or use default +ORS_VERSION=${2:-"7.2"} +# Recreate the container env +recreate_container=${3:-"false"} +# Org to connect to register to redhat +redhat_org=${4:-""} +# Activation key to connect to register to redhat +redhat_activation_key=${5:-""} + +check_container_running() { + lxc exec "$container_name" ls 2>/dev/null # Redirect error output to /dev/null + return $? +} + +wait_for_container_ready() { + local max_attempts=30 # Set the maximum number of attempts + local attempts=0 + while [ $attempts -lt $max_attempts ]; do + if check_container_running; then + echo "Successfully connected to the console of $container_name." + break + else + echo "Waiting for $container_name to be ready (Attempt $((attempts + 1)) of $max_attempts)..." + sleep 5 # Adjust the sleep interval as needed + fi + + attempts=$((attempts + 1)) + done + + if [ $attempts -eq $max_attempts ]; then + echo "Max attempts reached. $container_name is not ready." + exit 1 + fi +} + +# Write the above function with .spec as an input +build_rpm_with_spec() { + local specfile=$1 + local ors_version=$2 + export ORS_VERSION=$ors_version + # Get absolute path of the specfile with basepath + specfile=$(readlink -f "$specfile") + if [ ! -f "$specfile" ]; then + echo "File $specfile does not exist." + exit 1 + fi + echo "Building RPM with specfile $specfile" + mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} + cp -f ../ors-api/target/ors.war ~/rpmbuild/BUILD/ors.war + cp -f example-config.json ~/rpmbuild/BUILD/example-config.json + rpmbuild -bb "$specfile" +} + +# Write function that takes a filepath as an input and pushes this file to the container +push_file_to_container() { + local filepath=$1 + local container_path=$2 + echo "Pushing file $filepath to container $container_name at $container_path" + # Check if the file exists + if [ ! -f "$filepath" ]; then + echo "File $filepath does not exist." + exit 1 + fi + + lxc file push "$filepath" "$container_name/$container_path" +} + +# Write function that activates SELinux in the container +activate_selinux_in_container() { + echo "Activating SELinux. Dont' reboot the container after this." + lxc exec "$container_name" -- bash -c "dnf -y install selinux-policy-targeted" + lxc exec "$container_name" -- bash -c "echo SELINUX=permissive > /etc/selinux/config" + lxc exec "$container_name" -- bash -c "setenforce 0" + lxc exec "$container_name" -- bash -c "sestatus" +} + +# Fail if org and activation key are not set +if [ -z "$redhat_org" ] || [ -z "$redhat_activation_key" ]; then + echo "Redhat org and activation key must be set" + exit 1 +fi + +####################################################### +# Script to setup a container for testing the ORS RPM # +####################################################### + +echo "Creating container for testing" +recreate=false +# Test different variances of recreate_container and depending on output assign true or false to recreate +if [ "$recreate_container" = "true" ]; then + echo "Recreating container set to true" + recreate=true +elif [ "$recreate_container" = "false" ] && check_container_running; then + recreate=false +else + echo "Container is not running or doeesn't exist. Recreating container" + recreate=true +fi + +echo "Recreate container: $recreate" +if $recreate; then + echo "Deleting container" + lxc delete "$container_name" -f +fi +# Check if the image already exists, and if so, use it +if $recreate && lxc image list | grep -wq "$container_name"; then + echo "Reusing image" + lxc launch "$container_name" "$container_name" --vm -c security.secureboot=false -c limits.cpu=4 -c limits.memory=5GiB +elif $recreate && ! lxc image list | grep -wq "$container_name"; then + echo "Building new image" + lxc launch images:rockylinux/8/amd64 $container_name --vm -c security.secureboot=false -c limits.cpu=4 -c limits.memory=5GiB + if [ $? -ne 0 ]; then + echo "Error creating the VM" + exit 1 + fi + + wait_for_container_ready + + echo "Prepare the container for convert2rhel" + lxc exec "$container_name" -- bash -c "curl -o /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release https://www.redhat.com/security/data/fd431d51.txt && curl -o /etc/yum.repos.d/convert2rhel.repo https://ftp.redhat.com/redhat/convert2rhel/8/convert2rhel.repo && dnf -y update && dnf -y install convert2rhel && echo org = $redhat_org >> /etc/convert2rhel.ini && echo activation_key = $redhat_activation_key >> /etc/convert2rhel.ini" + + echo "Rebooting the container" + lxc restart "$container_name" + wait_for_container_ready + + echo "Converting the container to RHEL" + lxc exec "$container_name" -- bash -c "convert2rhel -y" + + echo "Rebooting the container" + lxc restart "$container_name" + wait_for_container_ready + + echo "Subscribe" + lxc exec "$container_name" -- bash -c "subscription-manager register --force --org $redhat_org --activationkey $redhat_activation_key" + + echo "Installing additional packages" + lxc exec "$container_name" -- bash -c "dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm" + lxc exec "$container_name" -- bash -c "dnf -y update && dnf -y install htop vim less audit setroubleshoot-server policycoreutils policycoreutils-python-utils setools setools-console setroubleshoot openssh-server openssh-clients" + lxc exec "$container_name" -- bash -c "dnf group install -y jws5" + + lxc exec "$container_name" -- bash -c "sudo systemctl enable --now sshd" + lxc exec "$container_name" -- bash -c "echo \"root:root\" | chpasswd" + lxc exec "$container_name" -- bash -c "dnf clean all" + + # Set the ORS_HOME env variable + lxc exec "$container_name" -- bash -c "echo \"export ORS_HOME=/opt/openrouteservice\" >> /etc/profile" + + echo "Publishing image $container_name for reuse" + lxc stop "$container_name" + lxc publish --reuse "$container_name" --alias "$container_name" + lxc start "$container_name" +else + echo "Not recreating container" +fi + +# To activate SELinux in the container, run the following +wait_for_container_ready +activate_selinux_in_container + +echo "Building RPM" +# Call build_rpm_with_spec and save result in variable rpm_path +mvn clean package -T14 -DskipTests -f ../pom.xml +build_rpm_with_spec ors-war.spec "$ORS_VERSION" +build_rpm_with_spec ors-selinux.spec "$ORS_VERSION" + +echo "Pushing RPM to container" +push_file_to_container "$(readlink -f ~/rpmbuild/RPMS/noarch/openrouteservice-jws5-$ORS_VERSION-1.noarch.rpm)" /tmp/ors.rpm +push_file_to_container "$(readlink -f ~/rpmbuild/RPMS/noarch/openrouteservice-jws5-selinux-$ORS_VERSION-1.noarch.rpm)" /tmp/ors-selinux.rpm + +echo "Install the ors RPM" +# Create /opt/openrouteservice +lxc exec "$container_name" -- bash -c "mkdir -p /opt/openrouteservice" + +# Install the ors rpm with exporting ORS_HOME as an env +lxc exec "$container_name" -- bash -c "export ORS_HOME=/opt/openrouteservice; dnf install -y /tmp/ors.rpm /tmp/ors-selinux.rpm" + +# Print the local ip address of the lxc container and assign it to the variable ip_address +ip_address=$(lxc exec "$container_name" -- ip addr show enp5s0 | grep -w inet | awk '{print $2}' | awk -F'/' '{print $1}') +echo "###################### STATUS ######################" +echo "# Credentials: 'root:root'" +echo "# Ways to connect to the instance:" +# Show the ssh connect command use password authentication and auto accept the host key +echo "# ssh -o \"StrictHostKeyChecking=no\" -o \"PasswordAuthentication=yes\" root@$ip_address" +# Show the pure lxc connect command +echo "# lxc exec $container_name -- bash" +echo "####################################################" + +lxc file push ../ors-api/src/test/files/heidelberg.osm.gz "$container_name/opt/openrouteservice/files/osm-file.osm.gz" +lxc exec "$container_name" -- bash -c "chown openrouteservice:openrouteservice /opt/openrouteservice/files/osm-file.osm.gz" + +lxc exec "$container_name" -- bash -c "cp -f /opt/openrouteservice/config/example-config.json /opt/openrouteservice/config/ors-config.json" +lxc exec "$container_name" -- bash -c "chown openrouteservice:openrouteservice /opt/openrouteservice/config/ors-config.json" +lxc exec "$container_name" -- bash -c "systemctl start jws5-tomcat.service" + + +#lxc exec "$container_name" -- bash -c "curl -X POST 'http://10.5.184.222:8080/v2/directions/driving-car' -H 'Content-Type: application/json; charset=utf-8' -d '{\"coordinates\":[[8.680916, 49.410973], [8.687782, 49.424597]]}'" diff --git a/.rpm-packaging/dockerfile-ubi8-java17-jws57 b/.rpm-packaging/dockerfile-ubi8-java17-jws57 index 04b9bb5844..cd7ca6fa4e 100644 --- a/.rpm-packaging/dockerfile-ubi8-java17-jws57 +++ b/.rpm-packaging/dockerfile-ubi8-java17-jws57 @@ -15,7 +15,7 @@ RUN sed -i 's/\(def in_container():\)/\1\n return False/g' /usr/lib64/python* # Attach to the rhel8 repositories of the access key and unregister if it fails subscription-manager attach || subscription-manager unregister && \ # Update the system and unregister if it fails - yum update -y && yum groupinstall jws5 -y || subscription-manager unregister && \ + yum update -y && yum groupinstall jws5 -y && yum install policycoreutils-python-utils -y && yum install jws5-tomcat-selinux -y || subscription-manager unregister && \ # give user root the passwort "root" echo "root:root" | chpasswd && \ # Unregister from redhat in any case in the end to avoid too many registered systems diff --git a/.rpm-packaging/ors-selinux.spec b/.rpm-packaging/ors-selinux.spec new file mode 100644 index 0000000000..3b26dfd5fc --- /dev/null +++ b/.rpm-packaging/ors-selinux.spec @@ -0,0 +1,104 @@ +%define java_version 17 +%define ors_version %{getenv:ORS_VERSION} +%define tomcat_user tomcat +%define ors_group openrouteservice +%define ors_user openrouteservice +%define jws_config_folder /etc/opt/rh/scls/jws5/tomcat/conf.d +%define jws_webapps_folder /var/opt/rh/scls/jws5/lib/tomcat/webapps +%define rpm_state_dir %{_localstatedir}/lib/rpm-state/openrouteservice_selinux +%define ors_temporary_files_location %{rpm_state_dir}/install +Name: openrouteservice-jws5-selinux +Version: %{ors_version} +Release: 1 +Summary: Apply SELinux rules for openrouteservice-jws5 +License: GPL 3 +BuildArch: noarch +Requires: openrouteservice-jws5 = %{ors_version} +Requires: jws5-tomcat-selinux +Vendor: HeiGIT gGmbH + +# For a detailed step explanation see: https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_syntax + +%description +This rpm package applies SELinux rules to the openrouteservice home folder + +%install + +%files + +%pre +############################################################################################################### +# This is the pre-installation scriptlet for the openrouteservice-jws5 rpm package. +# It checks for the existence of the JWS_HOME environment variable and checks if the webapps folder exists. +# It also checks if the JWS_CONF_FOLDER and JWS_WEBAPPS_FOLDER environment variables are set and if not, sets them to the default values. +# All variables are saved in the %{rpm_state_dir}/openrouteservice-jws5-temp-home-state file for later stages. +############################################################################################################### + +# Check for the JWS home ENV variable to be set and echo 'set' +if [ -n "${ORS_HOME}" ]; then + echo "ORS_HOME variable found. Attempting ORS installation at ${ORS_HOME}." + mkdir -p ${ORS_HOME} %{ors_temporary_files_location} + echo "ORS_HOME=${ORS_HOME}" > %{rpm_state_dir}/openrouteservice-jws5-temp-home-state +else + echo "ORS_HOME is not set. Exiting installation." + # Exit the rpm installation with an error + exit 1 +fi + +# Check if the environment variables are set for JWS_CONF_FOLDER and JWS_WEBAPPS_FOLDER if not, set the default values for them +if [ -z "${JWS_CONF_FOLDER}" ]; then + echo "JWS_CONF_FOLDER is not explicitly set. Setting default value to %{jws_config_folder}." + jws_config_folder=%{jws_config_folder} +else + jws_config_folder=${JWS_CONF_FOLDER} +fi + +# Do the same for the JWS_WEBAPPS_FOLDER +if [ -z "${JWS_WEBAPPS_FOLDER}" ]; then + echo "JWS_WEBAPPS_FOLDER is not explicitly set. Setting default value to %{jws_webapps_folder}." + jws_webapps_folder=%{jws_webapps_folder} +else + jws_webapps_folder=${JWS_WEBAPPS_FOLDER} +fi + +# Check if webapps folder exists +if [ -d ${jws_webapps_folder} ]; then + echo "JWS webapps dir found at ${jws_webapps_folder}" +else + echo "No webapps folder found. Exiting installation." + # Exit the rpm installation with an error + exit 1 +fi + +if [ -d ${jws_config_folder} ]; then + echo "JWS conf.d dir found at ${jws_config_folder}" +else + echo "No conf.d folder found. Exiting installation." + # Exit the rpm installation with an error + exit 1 +fi + +# Set the remaining variables +jws_config_location=${jws_config_folder}/openrouteservice.conf + +# Save all variables in the ORS_HOME in a file called openrouteservice-jws5-permanent-state +echo "jws_webapps_folder=${jws_webapps_folder}" > ${ORS_HOME}/.openrouteservice-jws5-permanent-state +echo "jws_config_location=${jws_config_location}" >> ${ORS_HOME}/.openrouteservice-jws5-permanent-state + +%preun + +%post + +# Source the openrouteservice-jws5-permanent-state file from %{rpm_state_dir} +. %{rpm_state_dir}/openrouteservice-jws5-temp-home-state +# Source the openrouteservice-jws5-permanent-state file from ${ORS_HOME} to get the permanent variables +. ${ORS_HOME}/.openrouteservice-jws5-permanent-state + +# copy permissions of jws tomcat folder to openrouteservice home folder +semanage fcontext -a -t jws5_tomcat_var_lib_t ${ORS_HOME} +restorecon -vvRF /opt/openrouteservice + +%postun + +semanage fcontext -a -t unlabeled_t ${ORS_HOME} +restorecon -vvRF /opt/openrouteservice diff --git a/.rpm-packaging/rhel8_post_install_check.sh b/.rpm-packaging/rhel8_post_install_check.sh index d0c14212bc..08667f790b 100755 --- a/.rpm-packaging/rhel8_post_install_check.sh +++ b/.rpm-packaging/rhel8_post_install_check.sh @@ -83,7 +83,13 @@ find_owned_content '${ORS_HOME}/*' "" "root" 0 || SUCCESSFUL=false find_owned_content '${ORS_HOME}/*' "root" "" 0 || SUCCESSFUL=false find_owned_content '${ORS_HOME}/*' "tomcat" "" 0 || SUCCESSFUL=false find_owned_content '${ORS_HOME}/*' "" "tomcat" 0 || SUCCESSFUL=false - +# Check selinux labels +check_selinux_label '${ORS_HOME}/.elevation-cache' "" "" "" "" 0 || SUCCESSFUL=false # change to "*" "*" "jws5_var_lib_t" "*" when container has selinux enabled +check_selinux_label '${ORS_HOME}/.graphs' "" "" "" "" 0 || SUCCESSFUL=false # change to "*" "*" "jws5_var_lib_t" "*" when container has selinux enabled +check_selinux_label '${ORS_HOME}/.openrouteservice-jws5-permanent-state' "" "" "" "" 0 || SUCCESSFUL=false # change to "*" "*" "jws5_var_lib_t" "*" when container has selinux enabled +check_selinux_label '${ORS_HOME}/config' "" "" "" "" 0 || SUCCESSFUL=false # change to "*" "*" "jws5_var_lib_t" "*" when container has selinux enabled +check_selinux_label '${ORS_HOME}/files' "" "" "" "" 0 || SUCCESSFUL=false # change to "*" "*" "jws5_var_lib_t" "*" when container has selinux enabled +check_selinux_label '${ORS_HOME}/logs' "" "" "" "" 0 || SUCCESSFUL=false # change to "*" "*" "jws5_var_lib_t" "*" when container has selinux enabled # Fail if any of the checks failed if [[ "$SUCCESSFUL" == false ]]; then diff --git a/.rpm-packaging/scripts/helper_functions.sh b/.rpm-packaging/scripts/helper_functions.sh index f39c07600e..0f5bf09b79 100755 --- a/.rpm-packaging/scripts/helper_functions.sh +++ b/.rpm-packaging/scripts/helper_functions.sh @@ -47,7 +47,7 @@ check_java_version() { log_success "Java version is $java_version as expected" } -# Function to check for a line in a file +# Function to check for a line in a directory # Usage: check_line_in_file check_line_in_file() { local line="$1" @@ -59,17 +59,17 @@ check_line_in_file() { result=$(${CONTAINER_ENGINE} exec -u root "$CONTAINER_NAME" bash -c "grep '$line' $path_to_file") exit_code=$? if [[ "$should_exist" = true && $exit_code -ne 0 ]]; then - log_error "Line '$line' should exist in file $path_to_file but does not." + log_error "Line '$line' should exist in directory $path_to_file but does not." return 1 elif [[ "$should_exist" = false && $exit_code -eq 0 ]]; then - log_error "Line '$line' should not exist in file $path_to_file but does." + log_error "Line '$line' should not exist in directory $path_to_file but does." return 1 fi # If should exist is true, the logging should be different if [[ "$should_exist" = true ]]; then - log_success "Line '$line' exists in file $path_to_file as expected." + log_success "Line '$line' exists in directory $path_to_file as expected." else - log_success "Line '$line' does not exist in file $path_to_file as expected." + log_success "Line '$line' does not exist in directory $path_to_file as expected." fi } @@ -98,7 +98,7 @@ check_folder_exists() { fi } -# Function to check if a file exists +# Function to check if a directory exists # Usage: check_file_exists check_file_exists() { local path_to_file="$1" @@ -129,7 +129,7 @@ check_file_is_symlink() { local path_to_file="$1" local should_exist="$2" - # Check if file exists. Else the symlink will fail if it doesn't exist + # Check if directory exists. Else the symlink will fail if it doesn't exist local _ local exit_code _=$(${CONTAINER_ENGINE} exec -u root "$CONTAINER_NAME" bash -c "test -f $path_to_file") @@ -139,11 +139,11 @@ check_file_is_symlink() { return 1 fi - # Check if file is a symlink + # Check if directory is a symlink local result result=$(${CONTAINER_ENGINE} exec -u root "$CONTAINER_NAME" bash -c "find $path_to_file -type l -xtype f | wc -l") if [[ "$should_exist" = true && $result -ne 1 ]]; then - log_error "A file exists at $path_to_file but it is no symlink." + log_error "A directory exists at $path_to_file but it is no symlink." return 1 elif [[ "$should_exist" = false && $result -ne 0 ]]; then log_error "The Symlink at $path_to_file shouldn't exist but does." @@ -219,6 +219,39 @@ check_user_in_group() { log_success "User $user_name is in group $group_name as expected." } +# Function to check the selinux label +check_selinux_label() { + local fileOrDir="$1" + local seUser="$2" + local seRole="$3" + local seType="$4" + local seLevel="$5" + + local any="[a-z0-9_]+" + [ "$seUser" == "*" ] && seUser=$any + [ "$seRole" == "*" ] && seRole=$any + [ "$seType" == "*" ] && seType=$any + [ "$seLevel" == "*" ] && seLevel=$any + local label="${seUser}:${seRole}:${seType}:${seLevel}" + [[ "$label" =~ :::.* ]] && label="\?" + + local result=$(${CONTAINER_ENGINE} exec -u root "${CONTAINER_NAME}" bash -c "ls -AZ $fileOrDir") + + local allGood=1 + IFS=$'\n' + for line in $result; do + if ! [[ "$line" =~ ^${label}" ".* ]]; then + echo "$line has not the expected label $label" + allGood=0 + fi + done + + (($allGood)) && echo "All files in $fileOrDir have the expected selinux label $label" && return 0 + + echo "Not all files in $fileOrDir have the expected selinux label $label" + return 1 +} + # Function to check if owned content count matches expected count # Usage: find_owned_content [] [] find_owned_content() { diff --git a/docs/installation/Installation-and-Usage.md b/docs/installation/Installation-and-Usage.md index ec91cb6324..9668fd2640 100644 --- a/docs/installation/Installation-and-Usage.md +++ b/docs/installation/Installation-and-Usage.md @@ -46,7 +46,7 @@ dnf install -y java-17-openjdk-headless For the installation, the variable `ORS_HOME` showing the persistence directory of the OpenRouteService needs to be set, e.g. ```bash -echo "ORS_HOME=/opt/openrouteservice" >> /etc/environment +echo "export ORS_HOME=/opt/openrouteservice" >> /etc/environment ``` **Only if** JBoss Web Service was installed _in a different way_ than described above, some paths need to be specified additionally: @@ -173,6 +173,52 @@ cp /opt/openrouteservice/config/config-example.json /opt/openrouteservice/config curl http://127.0.0.1:8080/ors/v2/status ``` +--- + +## Custom settings for JWS 5.x + +In order to set custom settings for JAVA_OPTS, CATALINA_OPTS, e.g. you can use following commands: + +```bash +sudo mkdir -p /etc/opt/rh/scls/jws5/tomcat/conf.d +``` + +```bash +sudoedit /etc/opt/rh/scls/jws5/tomcat/conf.d/openrouteservice.conf +``` + +```bash +export CATALINA_OPTS="$CATALINA_OPTS -Xms4g -Xmx4g" +export ORS_HOME=/data/openrouteservice +``` + +After setting the values it is required to restart JWS 5.x + +## Starting OpenRouteService + +```bash +sudo systemctl enable --now jws5-tomcat.service +``` + +## Usage + +Openrouteservice offers a set of endpoints for different spatial purposes. They are served with the help +of [Tomcat in a java servlet container](https://github.com/GIScience/openrouteservice/blob/master/ors-api/WebContent/WEB-INF/web.xml). +By default you will be able to query the services with these addresses: + +- `http://127.0.0.1:8080/ors/v2/directions` +- `http://127.0.0.1:8080/ors/v2/isochrones` +- `http://127.0.0.1:8080/ors/v2/matrix` + +## Logging and debugging + +JWS 5.x uses RHEL's journald functionality. + +```bash +sudo journalctl -f -u jws5-tomcat +``` + + --- ## Other Resources diff --git a/ors-api/pom.xml b/ors-api/pom.xml index 18678bea7d..0797828356 100644 --- a/ors-api/pom.xml +++ b/ors-api/pom.xml @@ -30,7 +30,7 @@ ../pom.xml openrouteservice org.heigit.ors - 7.2.0-SNAPSHOT-5 + 7.2.0-SNAPSHOT-6 4.0.0 diff --git a/ors-engine/pom.xml b/ors-engine/pom.xml index ed6f9919a0..72e74d50c1 100644 --- a/ors-engine/pom.xml +++ b/ors-engine/pom.xml @@ -30,7 +30,7 @@ ../pom.xml openrouteservice org.heigit.ors - 7.2.0-SNAPSHOT-5 + 7.2.0-SNAPSHOT-6 4.0.0 diff --git a/ors-engine/src/main/java/org/heigit/ors/config/AppConfig.java b/ors-engine/src/main/java/org/heigit/ors/config/AppConfig.java index 81571c91aa..95368cf677 100644 --- a/ors-engine/src/main/java/org/heigit/ors/config/AppConfig.java +++ b/ors-engine/src/main/java/org/heigit/ors/config/AppConfig.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class AppConfig { @@ -82,6 +83,12 @@ public AppConfig() { } LOGGER.info("Loading configuration from " + configFile); config = ConfigFactory.parseFile(configFile); + + try { + config.getConfig("ors"); + } catch (ConfigException e) { + throw new IOException("Configuration file could not be read."); + } config = overrideFromEnvVariables(config); } catch (IOException ioe) { @@ -148,8 +155,19 @@ private Config overrideFromEnvVariables(Config baseConfig) { // Print info about the baseConfig baseConfig = ConfigFactory.parseString("ors.services.routing.profiles.default_params.graphs_root_path=".concat(FilenameUtils.concat(orsHome, ".graphs"))).withFallback(baseConfig); baseConfig = ConfigFactory.parseString("ors.services.routing.profiles.default_params.elevation_cache_path=".concat(FilenameUtils.concat(orsHome, ".elevation_cache"))).withFallback(baseConfig); - // Find a better solution to this. For now, we hard code the path to the osm file and its file name - baseConfig = ConfigFactory.parseString("ors.services.routing.sources=[".concat(FilenameUtils.concat(orsHome, "files/osm-file.osm.gz")).concat("]")).withFallback(baseConfig); + + // Find a better solution to this. For now, we prepend ORS_HOME to any given file paths + List sources = baseConfig.getStringList("ors.services.routing.sources"); + if (sources.isEmpty()) { + baseConfig = ConfigFactory.parseString("ors.services.routing.sources=[".concat(FilenameUtils.concat(orsHome, "files/osm-file.osm.gz")).concat("]")).withFallback(baseConfig); + } else { + List adjustedSources = new ArrayList<>(); + for (String src : sources) { + adjustedSources.add(FilenameUtils.concat(orsHome, src)); + } + baseConfig = ConfigFactory.parseString("ors.services.routing.sources=[".concat(adjustedSources.stream().map(s -> "\"" + s + "\"").collect(Collectors.joining(", "))).concat("]")).withFallback(baseConfig); + } + // Adjust the logging path baseConfig = ConfigFactory.parseString("ors.logging.location=".concat(FilenameUtils.concat(orsHome, "logs"))).withFallback(baseConfig); } diff --git a/pom.xml b/pom.xml index 18fa07364e..a5ac707a7b 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ 4.0.0 org.heigit.ors openrouteservice - 7.2.0-SNAPSHOT-5 + 7.2.0-SNAPSHOT-6 pom openrouteservice https://openrouteservice.org