使旧的init脚本在systemd中工作的最简单方法是什么?


48

我不想通过创建新的systemd脚本来做正确的事,我只是希望我的旧init脚本能够再次正常工作,因为我已经将系统升级到使用systemd的操作系统。

我已经简要研究了如何转换初始化脚本以及如何编写systemd脚本,但是我敢肯定,正确学习它并正确执行将花费我几个小时。

当前的情况是:

systemctl start solr
Failed to start solr.service: Unit solr.service failed to load: No such file or directory.

和:

sudo service solr start
Failed to start solr.service: Unit solr.service failed to load: No such file or directory.

现在,我只想恢复工作。使此功能再次起作用的阻力最小的途径是什么?

更新

我不想弄清楚这一切-我确实不是-但是我必须并且我已经发掘出我的第一个线索:

sudo systemctl enable solr
Synchronizing state for solr.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d solr defaults
insserv: warning: script 'K01solr' missing LSB tags and overrides
insserv: warning: script 'solr' missing LSB tags and overrides
Executing /usr/sbin/update-rc.d solr enable
update-rc.d: error: solr Default-Start contains no runlevels, aborting.

systemd不兼容页面显示:

LSB报头依赖性信息很重要。许多发行版上的SysV实现都没有使用LSB初始化脚本头中编码的依赖项信息,或者仅以非常有限的方式使用了它们。因此,它们通常不正确或不完整。但是,systemd会完全解释这些标头,并在运行时密切关注它们

我认为这意味着我的脚本要先解决,才能解决。

有问题的脚本:

#!/bin/sh

# Prerequisites:
# 1. Solr needs to be installed at /usr/local/solr/example
# 2. daemon needs to be installed
# 3. Script needs to be executed by root
# 4. $INSTALL_ROOT must be set

# This script will launch Solr in a mode that will automatically respawn if it
# crashes. Output will be sent to /var/log/solr/solr.log. A pid file will be
# created in the standard location.

start () {
    echo -n "Starting solr..."

    # Reset ulimit or else get issues with too many open files (https://issues.apache.org/jira/browse/SOLR-4)
    ulimit -n 10000

    # start daemon
    daemon --chdir='/usr/local/solr/example' --command "java -jar -server start.jar -DINSTALL_ROOT=$INSTALL_ROOT" --respawn --output=/var/log/solr/solr.log --name=solr --verbose

    RETVAL=$?
    if [ $RETVAL = 0 ]
    then
        echo "done."
    else
        echo "failed. See error code for more information."
    fi
    return $RETVAL
}

stop () {
    # stop daemon
    echo -n "Stopping solr..."

    daemon --stop --name=solr  --verbose
    RETVAL=$?

    if [ $RETVAL = 0 ]
    then
        echo "done."
    else
        echo "failed. See error code for more information."
    fi
    return $RETVAL
}


restart () {
    daemon --restart --name=solr  --verbose
}


status () {
    # report on the status of the daemon
    daemon --running --verbose --name=solr
    return $?
}


case "$1" in
    start)
        start
    ;;
    status)
        status
    ;;
    stop)
        stop
    ;;
    restart)
        stop
        sleep 15
        start
    ;;
    *)
        echo $"Usage: solr {start|status|stop|restart}"
        exit 3
    ;;
esac

exit $RETVAL

“我不想做正确的事”会给您带来很多负面反馈。希望你穿上危险品套装。无论如何,阻力最小的路径什么都不是;只需使用您的初始化脚本。
迈克尔·汉普顿

6
当然,有一天,我会做正确的事。但是我们生活在资源有限的世界中。我已经添加了有关什么不起作用的更多详细信息,因为显然这应该已经起作用了。
mlissner

您是否要在Ubuntu上执行此操作?上帝帮助你,为什么?
迈克尔·汉普顿

1
我是。那比其他地方差吗?
mlissner,2015年

1
在Ubuntu的所有其他失败中,与此有关的一个问题是Upstart是一场噩梦。这是很好的,他们终于摆脱它,但你的初始化脚本不与它真正兼容。它以前的工作方式很可能是通过(古老的)SysV兼容性实现的,虽然systemd可以解决此问题,但Ubuntu显然已经做了一些努力来打破它。我不建议您尝试进行这项工作,特别是因为与您已经花费的时间相比,编写systemd单元文件所花费的时间要少得多。
迈克尔·汉普顿

Answers:


34

认真地说,为这样的服务或大多数服务编写一个systemd单位文件是微不足道的。

这应该可以让您达到95%的效率。举例来说,/etc/systemd/system/solr.service

[Unit]
Description=Apache Solr
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
EnvironmentFile=/etc/courtlistener
WorkingDirectory=/usr/local/solr/example
ExecStart=/usr/bin/java -jar -server -Xmx${CL_SOLR_XMX} start.jar -DINSTALL_ROOT=${INSTALL_ROOT}
Restart=on-failure
LimitNOFILE=10000

[Install]
WantedBy=multi-user.target

请注意此处包含的内容,例如日志文件等;systemd将自动捕获并记录服务名称下的服务输出。


5
好吧,这几乎花了我整天的时间来调整和配置所有内容。systemd有一些奇怪之处,例如,除非您将其打开,否则此脚本将不会包含持久日志。最后,它仍然有效,谢谢您的推动。
mlissner

15

对我来说,只需要在标题中添加init info块就容易了,如此处所示

#!/bin/sh
### BEGIN INIT INFO
# Provides:          solr
# Required-Start:    
# Required-Stop:     
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: solr
# Description:       solr
### END INIT INFO

然后,执行sudo systemctl enable solr


1
您的代码中有一个错字,恰好与我的错字相同,并且一直阻止我的脚本正常工作(从而得到臭名昭著的"contains no runlevels, aborting"错误),直到我意识到它为止:第二行中缺少第三个#号(应该是### BEGIN INIT INFO)。我敢打赌,这也可以解释为什么您的选票也很少。
佩雷,2017年

1
糟糕,您是对的,可能它已在复制粘贴过程中删除!(现已修复)
eadmaster

7

将solr传统的init脚本与systemd一起使用的另一种解决方案:

systemctl daemon-reload  
systemctl enable solr  
systemctl start solr  

1
已经尝试过了,但是没有用,因为Ubuntu有问题。
迈克尔·汉普顿

4

使用提供的启动脚本来运行Solr更加方便。

systemd单位文件如下所示:

[Unit]
Description=Apache Solr for Nextcloud's nextant app fulltext indexing
After=syslog.target network.target remote-fs.target nss-lookup.target systemd-journald-dev-log.socket
Before=nginx.service

[Service]
Type=forking
User=solr
WorkingDirectory=/path/to/solr/server
ExecStart=/path/to/solr/bin/solr start
ExecStop=/path/to/solr/bin/solr stop
Restart=on-failure

[Install]
WantedBy=multi-user.target

请注意,您还可以通过添加EnvironmentFile[Service]部分来利用环境变量。该脚本bin/solr尊重环境变量,只看一看就可以了。


今天很好。在最初写问题时,Solr没有提供系统的单元。
迈克尔·汉普顿

1

在Debian上进行了测试:在脚本开头添加“ _SYSTEMCTL_SKIP_REDIRECT = OHYES”。

系统化的迷们可能不喜欢它,但是,嘿,我不喜欢系统化的,所以:)。


SYSTEMCTL_SKIP_REDIRECT=true

不适用于我:(
eadmaster

确保您_之前添加(下划线)SYSTEMCTL,如下所示:_SYSTEMCTL_SKIP_REDIRECT=1。如果您从命令行尝试该操作,则还需要导出该变量。
timurb

1

尝试在CentOS 7上使用LSB初始化脚本时遇到相同的错误。根本原因是该脚本是符号链接。一旦替换为原始副本,一切都可以正常工作。


我的脚本也可能是这种情况。
mlissner '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.