Starting and stopping a service remotely in RHEL/Fedora/CentOS - linux

I have created a service on TerminalB. I can start and stop the service by executing following commands at terminalB. Now I want to start and stop this service on TerminalB by executing a shell script present on another machine TerminalA using ssh or any other possible way.
service servicename stop
//do some file copy
service servicename start
I have executed below command in Terminal. (In remote.sh I just kept service servicename stop, but the service is not stopping).
ssh user#TerminalB "bash -s" < /home/remote.sh

Related

How to disable cron service delay on startup

I'm trying to add the execution of a shell script on server startup. I do it using cron, so I configured it with 'crontab -e' command. It looks so:
#reboot /home/user/run.sh
Then I enabled service with
sudo systemctl enable cron.service
But when I reboot my server, jobs are not started. I check service status with:
sudo systemctl status cron.service
screenshot with an example
And there is a message that it's 2h 55min left to start executing all jobs. So, as I understood service is running but with 3 hours delay. It's happening after every server startup.
Using sudo systemctl restart cron.service command helps to make service working, but the server skips #reboot jobs because "it's not system startup".

Execute shell script on server using Ansible

I have to run shell script on multiple server using Ansible. I am using following code.
-name: start script
hosts: list_of_host
become: yes
gather_facts: no
role:
- startscript
in startscript i have below code...
-name: start script
shell: /bin/bash /home/ansible/test_script.sh
chnaged_when: false
Test_script is forever running process on sever. so when i am executing this command it's not coming out from that server. I need that it should start script on server and come out and go to another server to start script.
If /home/ansible/test_script.sh is "forever running", you should convert that to a service and start it via systemctl.
Obviously ansible would wait for the shell: command to complete..
shell should not be used for "forever running" scripts.
You can also start the /home/ansible/test_script.sh by starting a screen and executing the script within it, so it continues to run after ansible exits,
or you can try and push that script to background execution by adding & at the end of your shell: command, as well as prefixing the command with nohup so it is not terminated when ansible's ssh connection disconnects

Make ExecStartPost command to run in background

I have a systemd service for my spring boot application connected to consul server, behind haproxy. consul provides consul-template to automatically update the service location in haproxy configuration file via consul-template command.
consul-template takes a template file and writes to the final haproxy configuration file and then reload the haproxy.
Now, consul-template process needs to run in background always along with my application, so that as the application comes up, it can detect new application startup and update its location in the configuration file.
Here is my systemd service file for this.
[Unit]
Description=myservice
Requires=network-online.target
After=network-online.target
[Service]
Type=forking
PIDFile=/home/dragon/myservice/run/myservice.pid
ExecStart=/home/dragon/myservice/bin/myservice-script start
ExecReload=/home/dragon/myservice/bin/myservice-script reload
ExecStop=/home/dragon/myservice/bin/myservice-script stop
ExecStartPost=consul-template -template '/etc/haproxy/haproxy.cfg.template:/etc/haproxy/haproxy.cfg:sudo systemctl reload haproxy'
User=dragon
[Install]
WantedBy=multi-user.target
Now, when I start systemctl start myservice, my application starts and the call to consul-template also works, but consul-template process doesn't go in background. I have to press Ctl+C and then systemctl comes back and I have both my application and consul-template process running.
Is there way to run the consul-template process in background specified in ExecStartPost?
I was trying to add & at the end of the ExecStartPost command, but then consul-template complains that it is an additional invalid argument and it fails.
I was also trying to make the command as /bin/sh -c "consul-template command here...", but then this also doesn't work. Even nohup in this command wasn't working.
Any help is really appreciated.
A workaround would be to have a bash file as your entrypoint, add all you need in there, then it will all magically work
I was trying to accomplish the same task. I wanted to fire off some HTTP requests to Tomcat once the service had started, so that I could warmup our servers ahead of the first user request.
I went through a lot of trial and error with using trying to use ExecStartPost to fire off an async process, but actually worked. By calling a shell script, I could trigger off background processes, but from my testing Systemd appears to kill the process thread when ExecStartPost finishes, so any child processes end up getting killed too. I tried various combinations of using &, setsid, nohup, etc, even some Perl to try and trigger off the an executable in it's own thread, but as soon as the shell script exite from ExecStartPost any processes running where killed. It's possible there's some solution that would work using ExecStartPost, but I couldn't find it.
However, what did work is creating a new service (like #divinedragon mentions) which piggy backs off the service I wanted to monitor (in this case Tomcat).
Since it took me a little research to get something working the way I wanted, I wanted to share my solution in case it helps someone.
The first step is to create a new service (e.g. /usr/lib/systemd/system/tomcat-service-listener.service):
[Unit]
Description=Tomcat start/stop event listener
# make sure to stop the service when Tomcat stops
BindsTo=tomcat.service
# waits for both Nginx & Tomcat to be started before this service is started
After=nginx.service tomcat.service
[Service]
Type=oneshot
ExecStart=/path/to/your/script.sh start
ExecStop=/path/to/your/script.sh stop
RemainAfterExit=yes
TimeoutStartSec=300
[Install]
# When the service is enabled, forces this service to start when Tomcat is started
WantedBy=tomcat.service
Some notes on what is happening here:
The BindsTo make sure the service gets stopped when Tomcat is stopped. This triggers the ExecStop command.
The After make sure that on server reboot, this service does not start until both Nginx & Tomcat have started.
The WantedBy will create the wants symlink for Tomcat (when the service is enabled), which will force Tomcat to start this service any time it's restarted.
The RemainAfterExit=yes is necessary for the ExecStop to work. If you only care about triggering something when you're service is started and don't care about when the service is stopped, you can set this to no and remove the ExecStop line.
Make the TimeoutStartSec long enough for whatever task you plan on running.
To get this service working, you then need to do the following:
# make the service executable
chmod 664 /usr/lib/systemd/system/tomcat-service-listener.service
# make Systemd aware of the new service
systemctl daemon-reload
# register the service so it's started/stopped with Tomcat
systemctl enable tomcat-service-listener.service
Now all you need script to trigger off the logic you want. In my case, I wanted to warmup some servers once Tomcat started so my /path/to/your/script.sh looks something like:
#!/bin/sh
SCRIPT_MODE="$1"
LOGFILE=/var/logs/myscript.log
log_message() {
local MESSAGE="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') $MESSAGE" >> "$LOGFILE"
return 0
}
warmup_server() {
local SERVER_ADDRESS="$1"
local SERVER_DESCRIPTION="$2"
log_message "Warming up $SERVER_DESCRIPTION..."
# we want to track the time it took to warm up the server
local START_TIME=$(date +%s)
# server restarts can take a while for all services to start, so we must retry long enough for all relevant services to start
HTTP_STATUS=$(curl --insecure --location --silent --show-error --fail --retry 60 --retry-delay 2 --retry-max-time 240 --output /dev/null --write-out "%{http_code}" '$SERVER_ADDRESS')
# we want to track the time it took to warm up the server
local TOTAL_STARTUP_TIME=$(($(date +%s)-$START_TIME))
log_message "$SERVER_DESCRIPTION started in $TOTAL_STARTUP_TIME seconds... (Status: $HTTP_STATUS)"
return 0
}
# monitor when Tomcat has stopped
if [ "$SCRIPT_MODE" == "stop" ]; then
log_message "Tomcat listener shutting down..."
exit 0
elif [ "$SCRIPT_MODE" == "start" ]; then
log_message "Tomcat listener started..."
fi
# servers to warm up
warmup_server 'https://127.0.0.1' 'Localhost #1'
warmup_server 'https://127.0.0.2' 'Localhost #2'
This seems to be working exactly as I want. The service starts up when the server is reboot and starting/stopping/restarting Tomcat fires off the expected events. Since it's independent of the Tomcat service, I can restart this warmup script if needed. It also doesn't delay the Tomcat startup time, since it is its own service, therefore running asynchronously like I wanted.

ExecStopPost is not getting executed if Service is not running in Systemctl

The issue is that my service is not running and i tried to execute the stop service command. So as the service is not running if i try to stop the service by using systemctl stop $servicename.service the ExecStop command will not get executed and thus my ExecStopPost is also not getting executed.But i want that ExecStopPost command to be executed even though my service is not running and i try to execute the stop service command.
If the service is not running the command given to ExecStopPost will not execute.

Cannot make a cronjob get the status of a service

I'm using Upstart to run a couple of services when the systems reboots. Those services should always be running. I have noticed that some of then crashed eventually, so I'm trying (without success) to create a watchdog script.
This script will check the status of the service. If the service is down, then it should start the service and send me an email about the issue. The email script is in php and is okay.
The problem with the watchdog bash script is that I'm just able to execute the script and read the status of the service if I launch the script manually.When using a cronjob for executing the script I get an "empty status" output.
I'll show you the script:
#!/bin/bash
# Check the service
status=$(status SERVICE | awk '{print $2}')
echo "Status of the SERVICE: $status"
When I execute it manually I get:
Status of the SERVICE: stop/waiting
And If execute it with a cronjob I get:
Status of the SERVICE:
As you see I'm not getting any output when executing the script with a cronjob. In short, the cronjob is running but without providing me with the status of the service.
Hope your X-vision can see the error that I'm not able.
BR,
albertof
The difference is usually environment variables. Likely PATH. Run
which status
To show what executable it's running, and then put that full path into the cron invocation.

Resources