You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ja...@apache.org on 2024/02/27 14:10:36 UTC

(solr) branch main updated: SOLR-14410: switch from SysV to systemd service (#428)

This is an automated email from the ASF dual-hosted git repository.

janhoy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new ccd5ede68bf SOLR-14410: switch from SysV to systemd service (#428)
ccd5ede68bf is described below

commit ccd5ede68bf0cd19be63cda4e35a320842336e07
Author: Marius Ghita <gh...@gmail.com>
AuthorDate: Tue Feb 27 16:10:29 2024 +0200

    SOLR-14410: switch from SysV to systemd service (#428)
    
    * Support Rocky Linux
    * Upgrade notes.
    * Print warning if init.d script exists
    * Review comment: restart on failure
    Also add RestartSec, StartLimitIntervalSec and StartLimitBurst
    
    Co-authored-by: Jan Høydahl <ja...@apache.org>
---
 solr/CHANGES.txt                                   |  2 +
 solr/bin/init.d/solr                               | 78 ----------------------
 solr/bin/install_solr_service.sh                   | 63 +++++++++--------
 solr/bin/systemd/solr.service                      | 38 +++++++++++
 solr/packaging/build.gradle                        |  2 +-
 .../pages/taking-solr-to-production.adoc           | 55 +++++++--------
 .../pages/major-changes-in-solr-10.adoc            |  4 ++
 7 files changed, 102 insertions(+), 140 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 80864bb77e7..80591bf2916 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -82,6 +82,8 @@ Other Changes
 
 * SOLR-16995: Add a ReplicaCount class to keep track of replicas per type (Vincent Primault)
 
+* SOLR-14410: Switch from SysV init script to systemd service definition (Marius Ghita via janhoy)
+
 ==================  9.6.0 ==================
 New Features
 ---------------------
diff --git a/solr/bin/init.d/solr b/solr/bin/init.d/solr
deleted file mode 100644
index e73e0d68300..00000000000
--- a/solr/bin/init.d/solr
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/sh
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-### BEGIN INIT INFO
-# Provides:          solr
-# Required-Start:    $remote_fs $syslog
-# Required-Stop:     $remote_fs $syslog
-# Default-Start:     2 3 4 5
-# Default-Stop:      0 1 6
-# Description:       Controls Apache Solr as a Service
-### END INIT INFO
-
-# Example of a very simple *nix init script that delegates commands to the bin/solr script
-# Typical usage is to do:
-#
-#   cp bin/init.d/solr /etc/init.d/solr
-#   chmod 755 /etc/init.d/solr
-#   chown root:root /etc/init.d/solr
-#   update-rc.d solr defaults
-#   update-rc.d solr enable
-
-# Where you extracted the Solr distribution bundle
-SOLR_INSTALL_DIR="/opt/solr"
-
-if [ ! -d "$SOLR_INSTALL_DIR" ]; then
-  echo "$SOLR_INSTALL_DIR not found! Please check the SOLR_INSTALL_DIR setting in your $0 script."
-  exit 1
-fi
-
-# Path to an include file that defines environment specific settings to override default
-# variables used by the bin/solr script. It's highly recommended to define this script so
-# that you can keep the Solr binary files separated from live files (pid, logs, index data, etc)
-# see bin/solr.in.sh for an example
-SOLR_ENV="/etc/default/solr.in.sh"
-
-if [ ! -f "$SOLR_ENV" ]; then
-  echo "$SOLR_ENV not found! Please check the SOLR_ENV setting in your $0 script."
-  exit 1
-fi
-
-# Specify the user to run Solr as; if not set, then Solr will run as root.
-# Running Solr as root is not recommended for production environments
-RUNAS="solr"
-
-# verify the specified run as user exists
-runas_uid="`id -u "$RUNAS"`"
-if [ $? -ne 0 ]; then
-  echo "User $RUNAS not found! Please create the $RUNAS user before running this script."
-  exit 1
-fi
-
-case "$1" in
-  start|stop|restart|status)
-    SOLR_CMD="$1"
-    ;;
-  *)
-    echo "Usage: $0 {start|stop|restart|status}"
-    exit
-esac
-
-if [ -n "$RUNAS" ]; then
-  su -c "SOLR_INCLUDE=\"$SOLR_ENV\" \"$SOLR_INSTALL_DIR/bin/solr\" $SOLR_CMD" - "$RUNAS"
-else
-  SOLR_INCLUDE="$SOLR_ENV" "$SOLR_INSTALL_DIR/bin/solr" "$SOLR_CMD"
-fi
diff --git a/solr/bin/install_solr_service.sh b/solr/bin/install_solr_service.sh
index d3135d489ff..8102b3d1539 100755
--- a/solr/bin/install_solr_service.sh
+++ b/solr/bin/install_solr_service.sh
@@ -29,7 +29,7 @@ print_usage() {
   echo ""
   echo "Usage: install_solr_service.sh <path_to_solr_distribution_archive> [OPTIONS]"
   echo ""
-  echo "  The first argument to the script must be a path to a Solr distribution archive, such as solr-5.0.0.tgz"
+  echo "  The first argument to the script must be a path to a Solr distribution archive, such as solr-10.0.0.tgz"
   echo "    (only .tgz is supported format for the archive)"
   echo ""
   echo "  Supported OPTIONS include:"
@@ -73,6 +73,8 @@ for command in "grep -E \"^NAME=\" /etc/os-release" \
       distro=RedHat
     elif [[ ${distro_string,,} == *"centos"* ]]; then
       distro=CentOS
+    elif [[ ${distro_string,,} == *"rocky"* ]]; then
+      distro=CentOS
     elif [[ ${distro_string,,} == *"ubuntu"* ]]; then
       distro=Ubuntu
     elif [[ ${distro_string,,} == *"suse"* ]]; then
@@ -100,6 +102,10 @@ if [ ! -f "$SOLR_ARCHIVE" ]; then
   exit 1
 fi
 
+if [ -f "/etc/init.d/${SOLR_SERVICE}" ]; then
+  echo "WARNING: Found pre-existing /etc/init.d/${SOLR_SERVICE}, please remove!"
+fi
+
 # strip off path info
 SOLR_INSTALL_FILE=${SOLR_ARCHIVE##*/}
 if [ ${SOLR_INSTALL_FILE: -4} == ".tgz" ]; then
@@ -185,8 +191,8 @@ fi
 # Test for availability of needed tools
 tar --version &>/dev/null       || print_error "Script requires the 'tar' command"
 if [[ $SOLR_START == "true" ]] ; then
-  service --version &>/dev/null || service --help &>/dev/null || print_error "Script requires the 'service' command"
-  java -version &>/dev/null     || print_error "Solr requires java, please install or set JAVA_HOME properly"
+  systemctl --version &>/dev/null || print_error "Script requires the 'systemctl' command"
+  java -version &>/dev/null       || print_error "Solr requires java, please install or set JAVA_HOME properly"
 fi
 lsof -h &>/dev/null             || echo "We recommend installing the 'lsof' command for more stable start/stop of Solr"
 
@@ -221,21 +227,21 @@ if [ -z "$SOLR_UPGRADE" ]; then
 fi
 
 if [ ! "$SOLR_UPGRADE" = "YES" ]; then
-  if [ -f "/etc/init.d/$SOLR_SERVICE" ]; then
-    print_usage "/etc/init.d/$SOLR_SERVICE already exists! Perhaps Solr is already setup as a service on this host? To upgrade Solr use the -f option."
+  if [ -f "/etc/systemd/system/$SOLR_SERVICE.service" ]; then
+    print_usage "/etc/systemd/system/$SOLR_SERVICE.service already exists! Perhaps Solr is already setup as a service on this host? To upgrade Solr use the -f option."
     exit 1
   fi
 
-  if [ -e "$SOLR_EXTRACT_DIR/$SOLR_SERVICE" ]; then
-    print_usage "$SOLR_EXTRACT_DIR/$SOLR_SERVICE already exists! Please move this directory / link or choose a different service name using the -s option."
+  if [ -e "$SOLR_EXTRACT_DIR/$SOLR_SERVICE.service" ]; then
+    print_usage "$SOLR_EXTRACT_DIR/$SOLR_SERVICE.service already exists! Please move this directory / link or choose a different service name using the -s option."
     exit 1
   fi
 fi
 
 # stop running instance
-if [ -f "/etc/init.d/$SOLR_SERVICE" ]; then
+if [ -f "/etc/systemd/system/$SOLR_SERVICE.service" ]; then
   echo -e "\nStopping Solr instance if exists ...\n"
-  service "$SOLR_SERVICE" stop
+  systemctl stop "$SOLR_SERVICE.service"
 fi
 
 # create user if not exists
@@ -284,17 +290,22 @@ else
   ln -s "$SOLR_INSTALL_DIR" "$SOLR_EXTRACT_DIR/$SOLR_SERVICE"
 fi
 
-# install init.d script
-echo -e "\nInstalling /etc/init.d/$SOLR_SERVICE script ...\n"
-cp "$SOLR_INSTALL_DIR/bin/init.d/solr" "/etc/init.d/$SOLR_SERVICE"
-chmod 0744 "/etc/init.d/$SOLR_SERVICE"
-chown root: "/etc/init.d/$SOLR_SERVICE"
-# do some basic variable substitution on the init.d script
-sed_expr1="s#SOLR_INSTALL_DIR=.*#SOLR_INSTALL_DIR=\"$SOLR_EXTRACT_DIR/$SOLR_SERVICE\"#"
-sed_expr2="s#SOLR_ENV=.*#SOLR_ENV=\"/etc/default/$SOLR_SERVICE.in.sh\"#"
-sed_expr3="s#RUNAS=.*#RUNAS=\"$SOLR_USER\"#"
-sed_expr4="s#Provides:.*#Provides: $SOLR_SERVICE#"
-sed -i -e "$sed_expr1" -e "$sed_expr2" -e "$sed_expr3" -e "$sed_expr4" "/etc/init.d/$SOLR_SERVICE"
+# install systemd service file
+echo -e "\nInstalling /etc/systemd/system/$SOLR_SERVICE.service ...\n"
+cp "$SOLR_INSTALL_DIR/bin/systemd/solr.service" "/etc/systemd/system/$SOLR_SERVICE.service"
+chmod 0644 "/etc/systemd/system/$SOLR_SERVICE.service"
+chown root "/etc/systemd/system/$SOLR_SERVICE.service"
+
+# do some basic variable substitution on the service file
+SAFE_SOLR_INSTALL_DIR="$SOLR_EXTRACT_DIR/$SOLR_SERVICE"
+SAFE_SOLR_SERVICE=$(systemd-escape --path "$SOLR_SERVICE")
+sed_expr1="s@{{SOLR_INSTALL_DIR}}@$SAFE_SOLR_INSTALL_DIR@g"
+sed_expr2="s/{{SOLR_SERVICE}}/$SAFE_SOLR_SERVICE/g"
+sed_expr3="s/{{SOLR_USER}}/$SOLR_USER/g"
+sed -i -e "$sed_expr1" -e "$sed_expr2" -e "$sed_expr3" "/etc/systemd/system/$SOLR_SERVICE.service"
+
+# we need to reload systemd after changing service files
+systemctl daemon-reload
 
 # install/move configuration
 if [ ! -d /etc/default ]; then
@@ -336,19 +347,13 @@ find "$SOLR_VAR_DIR" -type d -print0 | xargs -0 chmod 0750
 find "$SOLR_VAR_DIR" -type f -print0 | xargs -0 chmod 0640
 
 # configure autostart of service
-if [[ "$distro" == "RedHat" || "$distro" == "CentOS" || "$distro" == "SUSE" ]]; then
-  chkconfig "$SOLR_SERVICE" on
-else
-  update-rc.d "$SOLR_SERVICE" defaults
-fi
+systemctl enable "$SOLR_SERVICE.service"
 echo "Service $SOLR_SERVICE installed."
 echo "Customize Solr startup configuration in /etc/default/$SOLR_SERVICE.in.sh"
 
 # start service
 if [[ $SOLR_START == "true" ]] ; then
-  service "$SOLR_SERVICE" start
-  sleep 5
-  service "$SOLR_SERVICE" status
+  systemctl start "$SOLR_SERVICE.service"
 else
-  echo "Not starting Solr service (option -n given). Start manually with 'service $SOLR_SERVICE start'"
+  echo "Not starting Solr service (option -n given). Start manually with 'systemctl start $SOLR_SERVICE'"
 fi
diff --git a/solr/bin/systemd/solr.service b/solr/bin/systemd/solr.service
new file mode 100644
index 00000000000..0028e1ded25
--- /dev/null
+++ b/solr/bin/systemd/solr.service
@@ -0,0 +1,38 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This unit file generated by install_solr_service.sh script
+
+[Unit]
+Description=Apache Solr
+After=network.target
+StartLimitIntervalSec=300
+StartLimitBurst=5
+
+[Service]
+Type=forking
+User={{SOLR_USER}}
+Environment=SOLR_INCLUDE=/etc/default/{{SOLR_SERVICE}}.in.sh
+ExecStart={{SOLR_INSTALL_DIR}}/bin/solr start
+ExecStop={{SOLR_INSTALL_DIR}}/bin/solr stop
+Restart=on-failure
+RestartSec=3s
+TimeoutSec=180s
+PrivateTmp=true
+LimitNOFILE=65000
+LimitNPROC=65000
+
+[Install]
+WantedBy=multi-user.target
diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle
index 32e849c1330..cc48294880a 100644
--- a/solr/packaging/build.gradle
+++ b/solr/packaging/build.gradle
@@ -122,7 +122,7 @@ distributions {
       filesMatching([
           "**/*.sh",
           "**/bin/solr",
-          "**/bin/init.d/solr",
+          "**/bin/systemd/solr.service",
       ]) { copy ->
         copy.setMode(0755)
       }
diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/taking-solr-to-production.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/taking-solr-to-production.adoc
index 7cd071695b9..a5a20f32054 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/taking-solr-to-production.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/taking-solr-to-production.adoc
@@ -152,13 +152,9 @@ SOLR_LOGS_DIR=/var/solr/logs
 
 For more information about Log4J configuration, please see: xref:configuring-logging.adoc[].
 
-==== init.d Script
+==== systemd Service
 
-When running a service like Solr on Linux, it’s common to setup an init.d script so that system administrators can control Solr using the service tool, such as: `service solr start`.
-The installation script creates a very basic init.d script to help you get started.
-Take a moment to inspect the `/etc/init.d/solr` file, which is the default script name setup by the installation script.
-If you used the `-s` option on the install script to change the name of the service, then the filename will be different.
-Notice that the following variables are setup for your environment based on the parameters passed to the installation script:
+The installation script creates a very basic systemd service to help you get started. Take a moment to inspect the `/etc/systemd/system/solr.service` file, which is the default service file setup by the installation script. If you used the `-s` option on the install script to change the name of the service, then the filename will be different. Notice that the following variables are setup for your environment based on the parameters passed to the installation script:
 
 [source,bash]
 ----
@@ -167,44 +163,42 @@ SOLR_ENV=/etc/default/solr.in.sh
 RUNAS=solr
 ----
 
-The `SOLR_INSTALL_DIR` and `SOLR_ENV` variables should be self-explanatory.
-The `RUNAS` variable sets the owner of the Solr process, such as `solr`; if you don’t set this value, the script will run Solr as **root**, which is not recommended for production.
-You can use the `/etc/init.d/solr` script to start Solr by doing the following as root:
+The `SOLR_INSTALL_DIR` and `SOLR_ENV` variables should be self-explanatory. The `RUNAS` variable sets the owner of the Solr process, such as `solr`; if you don’t set this value, the script will run Solr as **root**, which is not recommended for production. You can start Solr by doing the following as root:
 
 [source,bash]
 ----
-service solr start
+systemctl start solr
 ----
 
-The `/etc/init.d/solr` script also supports the **stop**, **restart**, and *status* commands.
-Please keep in mind that the init script that ships with Solr is very basic and is intended to show you how to setup Solr as a service.
-However, it’s also common to use more advanced tools like *supervisord* or *upstart* to control Solr as a service on Linux.
-While showing how to integrate Solr with tools like supervisord is beyond the scope of this guide, the `init.d/solr` script should provide enough guidance to help you get started.
 Also, the installation script sets the Solr service to start automatically when the host machine initializes.
 
 === Progress Check
 
-In the next section, we cover some additional environment settings to help you fine-tune your production setup.
-However, before we move on, let's review what we've achieved thus far.
-Specifically, you should be able to control Solr using `/etc/init.d/solr`.
-Please verify the following commands work with your setup:
+In the next section, we cover some additional environment settings to help you fine-tune your production setup. However, before we move on, let's review what we've achieved thus far. Specifically, you should be able to control Solr using `systemctl`. Please verify the following commands work with your setup:
 
 [source,bash]
 ----
-sudo service solr restart
-sudo service solr status
+sudo systemctl restart solr
+sudo systemctl status solr
 ----
 
 The status command should give some basic information about the running Solr node that looks similar to:
 
 [source,text]
 ----
-Solr process PID running on port 8983
-{
-  "version":"5.0.0 - ubuntu - 2014-12-17 19:36:58",
-  "startTime":"2014-12-19T19:25:46.853Z",
-  "uptime":"0 days, 0 hours, 0 minutes, 8 seconds",
-  "memory":"85.4 MB (%17.4) of 490.7 MB"}
+● solr.service - Apache Solr
+   Loaded: loaded (/etc/systemd/system/solr.service; enabled; vendor preset: disabled)
+   Active: active (running) since Thu 2020-04-16 20:42:01 UTC; 53s ago
+ Main PID: 3708 (java)
+    Tasks: 41 (limit: 25056)
+   Memory: 517.1M
+   CGroup: /system.slice/solr.service
+           └─3708 java -server -Xms256M -Xmx512M -XX:+UseG1GC -XX:+PerfDisableSharedMem -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=250 -XX:+UseLargePages -XX:+AlwaysPreTouch -Xlog:gc*:file=/var/solr/logs/solr_gc.log:time,...
+Apr 16 20:41:47 localhost.localdomain systemd[1]: Starting Apache Solr...
+Apr 16 20:42:01 localhost.localdomain solr[3661]: [326B blob data]
+Apr 16 20:42:01 localhost.localdomain solr[3661]: Started Solr server on port 8983 (pid=3708). Happy searching!
+Apr 16 20:42:01 localhost.localdomain solr[3661]: [14B blob data]
+Apr 16 20:42:01 localhost.localdomain systemd[1]: Started Apache Solr.
 ----
 
 If the `status` command is not successful, look for error messages in `/var/solr/logs/solr.log`.
@@ -469,10 +463,7 @@ Below 32GB, Java is able to use compressed pointers, but above that point, large
 If your use case needs over 31GB of heap, then consider multiple nodes since they typically will perform better than one node with >32GB of heap.
 ====
 
-If your use case requires multiple instances, at a minimum you will need unique Solr home directories for each node you want to run; ideally, each home should be on a different physical disk so that multiple Solr nodes don’t have to compete with each other when accessing files on disk.
-Having different Solr home directories implies that you’ll need a different include file for each node.
-Moreover, if using the `/etc/init.d/solr` script to control Solr as a service, then you’ll need a separate script for each node.
-The easiest approach is to use the service installation script to add multiple services on the same host, such as:
+If your use case requires multiple instances, at a minimum you will need unique Solr home directories for each node you want to run; ideally, each home should be on a different physical disk so that multiple Solr nodes don’t have to compete with each other when accessing files on disk. Having different Solr home directories implies that you’ll need a different include file for each node. Moreover, if using `systemctl` to control Solr, then you’ll need a separate service for each node. Th [...]
 
 [source,bash,subs="attributes"]
 ----
@@ -484,6 +475,6 @@ After installing the solr2 service, verify it works correctly by doing:
 
 [source,bash]
 ----
-sudo service solr2 restart
-sudo service solr2 status
+sudo systemctl start solr2
+sudo systemctl status solr2
 ----
diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
index a48f1e72892..a712bbe54e8 100644
--- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
+++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
@@ -33,6 +33,10 @@ Before starting an upgrade to this version of Solr, please take the time to revi
 * `SolrClient` implementations that rely on "base URL" strings now only accept "root" URL paths (i.e. URLs that end in "/solr").
 Users who previously relied on collection-specific URLs to avoid including the collection name with each request can instead achieve this by specifying a "default collection" using the `withDefaultCollection` method available on most `SolrClient` Builders.
 
+=== Service installer
+
+The service installer now installs a `systemd` startup script instead of an `init.d` startup script. It is up to the user to uninstall any existing `init.d` script when upgrading.
+
 === Deprecation removals
 
 * The `jaegertracer-configurator` module, which was deprecated in 9.2, is removed. Users should migrate to the `opentelemetry` module.