Currently I am having an issue with trying to run a process/script in the background[The master starts it on the minion]
The script is something like this:
#!/bin/bash
nohup ping 8.8.8.8 >/dev/null&
And I call it from the master with:
Process-Name:
service.running:
- name: Script-Name
- enable: True
For some reason it gets stuck on the master,I've read a little bit on this issue[it has happenned before apparently] and tried their solutions on it but apparently nothing involving the service state seems to work.
Is there anyway to work around this?
In short, you should configure your script as system daemon first (SysV init.d script, or systemd unit, or ... depends on OS).
Details
The service.running function requires properly configured system service ~ daemon.
For example, on RHEL-based Linux, if you don't see your script name in the output of one of these commands, you should configure it as proper service first (which is a separate topic):
# systemd
systemctl list-units | grep your_service_name
# SysV init.d
chkconfig --list | grep your_service_name
And because you want to start it in background, cmd.run function is not the right tool either:
It will only report successful start of the script without waiting for its completion results.
It will also start new instance of your script every time.
However, if all you simply want is to "fire and forget", use cmd.run.
Related
I am trying to run a series of commands to configure a vlan on a Dell EMC OS10 server using Paramiko. However I am running into a rather frustrating problem.
I want to run the following
# configure terminal
(config)# interface vlan 3
(conf-if-vl-3)# description VLAN-TEST
(conf-if-vl-3)# end
However, I can't seem to figure out how to achieve this with paramiko.SSHClient().
When I try to use sshclient.exec_command("show vlan") it works great, it runs this command and exits. However, I don't know how to run more than one command with a single exec_command.
If I run sshclient.exec_command("configure") to access the configuration shell, the command completes and I believe the channel is closed, since my next command sshclient.exec_command("interface vlan ...") is not successful since the switch is no longer in configure mode.
If there is a way to establish a persistent channel with exec_command that would be ideal.
Instead I have resorted to a function as follows
chan = sshClient.invoke_shell()
chan.send("configure\n")
chan.send("interface vlan 3\n")
chan.send("description VLAN_TEST\n")
chan.send("end\n")
Oddly, this works when I run it from a Python terminal one command at a time.
However, when I call this function from my Python main, it fails. Perhaps the channel is closed too soon when it goes out of scope from the function call?
Please advise if there is a more reasonable way to do this
Regarding sending commands to the configure mode started with SSHClient.exec_commmand, see:
Execute (sub)commands in secondary shell/command on SSH server in Python Paramiko
Though it's quite common that "devices" do not support the "exec" channel at all:
Executing command using Paramiko exec_command on device is not working
Regarding your problem with invoke_shell, it's quite possible that the server needs some time to get ready for the next command.
Quick-and-dirty solution is to "sleep" shortly between the individual send calls.
Better solution to is to wait for command prompt before sending the next command.
Below is the BHd.service file; this is the first time I've done this, and everything is finally working perfectly except that when I stop the service, it always without fail stops httpd (and likely other services listed here). I sincerely have looked everywhere for the answer. I don't think it should be doing this.
Log story short, I need smb, nfs, httpd and mariadb to be running before this unit start. I do not want them to be stopped after the unit is stopped or reloaded; for now, firewalld must be off. I honestly can't tell what line is affecting the systemctl stop command, everything I read indicates that Requires and After only affect systemctl start.
[Unit]
Description=BH
Documentation=somewhere.com
Wants=smb.service nfs.service
After=httpd.service mariadb.service
Requires=httpd.service mariadb.service
Conflicts=firewalld.service
[Service]
Type=forking
PIDFile=/var/run/BHd.pid
ExecStart=/usr/bin/python /var/www/html/pythonscripts/BHd.py start
ExecStop=/usr/bin/python /var/www/html/pythonscripts/BHd.py stop
[Install]
Alias=BHd
WantedBy=smb.service nfs.service
RequiredBy=httpd.service mariadb.service
EDIT: More info
[root#BHDEMO ~]# systemctl -l | grep BH
BHd.service loaded failed failed Description
[root#BHDEMO ~]#
Short Answer: systemctl disable BHd
Long Answer:
Well, I feel stupid... I'm sure some of you will think "this guy is writing a 40k line service but didn't know that!"... yes, that's how us computer engineers roll, lol.
The Solution:
After editing this file over and over in an attempt to get it working, I never tried systemctl disable BHd... that did it... I had a few lines in the Install section early, WantedBy and RequiredBy as seen above. I realized about 5 hours ago that this was not correct and deleted it. Unfortunately, just doing another enable is not sufficient, as those lines created directories that needed to be uninstalled with disable, then reinstalled with enabled without the added files and folders. Almost sounds like a linux bug that should be fixed, imagine how many like me over the years wasted so much time.
I just encountered and circumvented a problem in Matlab, but I'm still wondering why this happens, and I also want to leave the information here for future reference.
In Matlab's Parallel Computing Toolbox, the command matlabpool local starts a local pool of Matlab workers which are then used transparently to speed up commands like parfor by distributing processing onto the different CPU cores. I tried to do so on a Linux machine which I connected to through ssh from my home Linux computer. I used ssh without X forwarding because the script I wanted to run only computes and saves the result, but does not produce graphical output.
The problem: matlabpool hung forever, without any indication of the cause. I restarted the remote machine, restarted Matlab, checked for license problems, without result.
The problem was resolved however when I closed ssh and logged back in, this time including the -X option for X11 forwarding – even though then I started Matlab with the -nodesktop option.
Does anyone have an idea why matlabpool on Linux appears to depend on access to X11?
Even though matlabpool starts and communicates with background headless workers, you can still create figures and plots and print/export them as images inside the parfor parallel loop. The following is a valid use case:
matlabpool(..)
parfor i=1:4
plot(..)
print(...)
close(..)
end
To me this suggests that background workers will still depend on graphics capabilities to generate the invisible plots in memory (maybe it's using virtual framebuffers and such). Of course this is just speculation on my part :)
EDIT:
Just to be sure here, can you try the following sequence of commands:
[client]$ ssh -v -x user#server # X11 forwarding disabled
[server]$ unset DISPLAY # clear $DISPLAY variable
[server]$ nohup matlab -nodesktop -nodisplay -noFigureWindows -nosplash \
-r "myscript; quit;" 2>&1 < /dev/null &
Where the script contains a simple parallel test like:
myscript.m
parpool('local',2)
smpd
fprintf('hello from lab#%d', labindex);
end
delete(gcp('nocreate'))
If MATLAB still hangs, try adding the -debug start option:
matlab -debug starts MATLAB and displays debugging information that can be useful, especially for X based problems.
I'm hoping someone out there is used to monit and can help me.
Im running a home data server, with Ubuntu 13.10.
I have CGminer setup to start when the PC boots, from a bash script of my own creation. It contains a few tweaks and setting that need running before it gets going.
But if for some reason my interweb goes down...cgminer will close after a small amount of time. Now, if im asleep, and it closes. That valuable mining time, and a waste of the electric. So I'm looking into monit as a way of fixing that.
Im hoping to be able to have monit (or something similar, doesnt have to be monit) Start CGMiner from my script, check every so often that CGminer is still running, and if not, restart it from my script.
I just cant get my head around the config file for monit...Help would be awesome
Yes, you can achieve that with monit. You only need that your start script writes pid into pidfile:
check process xyz with pidfile /var/run/xyz.pid
start = "/bin/xyz start"
stop = "/bin/xyz stop"
I am running a rewrite map with an external rewrite program (prg) in apache2 that may produce an error and die.
When the rewrite map is not running any more the system obviously doesn't function properly.
So I wanted to start a simple wrapper shell script that itself executes map program (which is written in php) and restarts it if it dies:
#!/bin/bash
until /usr/bin/php /somepath/mymap.php; do
echo "map died but i will restart it right away!"
done
If I try that in the shell by hand, it works fine, however it does not work when started by the webserver.
...and then communicates with the rewriting engine via its stdin and
stdout file-handles. For each map-function lookup it will receive the
key to lookup as a newline-terminated string on stdin. It then has to
give back the looked-up value as a newline-terminated string on stdout
or the four-character string ``NULL'' if it fails...
The reason seems pretty clear to me. The first script takes stdin but doesn't redirect it to the sub script.
I guess I somehow need to define a descriptor using exec and redirect stdin/stdout of the scripts properly. But how do I do that?
It's a common problem that some script works executed "by hand" and do not work when executed indirectly (via cron or from apache).
Usually the root cause is one of:
your script needs some extra environment varaible (PATH, LD_LIBRARY_PATH, etc.)
your script requires terminal
First thing to do is to grab some debug info, so add to your script:
env > /tmp/$0.env # get environment
and get stderr:
... /usr/bin/php /somepath/mymap.php 2>/tmp/$0.stderr ...
This may lead you to the solution.
If your script requires terminal and you cannot fix it you can run your script via gnu screen.
Good luck.
Michał Šrajer has given one very common cause of trouble (environment). You should certainly be sure that the environment is sufficiently well set up, because Apache sets its own environment rigorously and does not pass on any inherited junk values; it only passes what it is configured to pass (SetEnv and PassEnv directives, IIRC).
Another problem is that you think your mapping process will fail; that's worrying. Further, it is symptomatic of yet another problem, which I think is the main one.
The first time the map process is run, it will read the request from the web server, but if the mapping fails, you rerun it - but the web server is still waiting for the output from the original request, and the map process is waiting for the input, so there's an impasse.
Note that a child process automatically inherits the standard input and standard output of its parent unless you do something to change it.
If you think things might fail, you'll need to capture the standard input so that when you rerun the program, you can resupply the input (though why it would work on the second time when it failed on the first is a separate mystery).
Maybe:
if tee /tmp/xx.$$ | /usr/bin/php /somepath/mymap.php
then : OK
else
until /usr/bin/php /somepath/mymap.php < /tmp/xx.$$
do echo "map died but I will restart it right away!"
done
fi
rm -f /tmp/xx.$$
Unresolved issues include:
You should add traps to ensure that the temporary file is removed;
You should probably not use /tmp as the directory;
The messages probably do not get sent to the web server and from thence to the client browser until the overall script terminates, so the echoed messages simply mess up the start of the response;
There is no limit on the number of failures;
There is no logging of the failures;
There is no attempt to fix the problem that caused the failure;
And there are probably others I've not thought of yet.
until is not a valid keyword, you probably have it aliased and aliases do not work on scripts. my mistake, it seems it is.
regardless, this is what you want to do:
while true; do
/usr/bin/php /somepath/mymap.php
done
if this also fails then yes, either your program expects a terminal or you have something missing in your env.