Add php and composer alias on QNAP Startup - php

I came across a couple of issues with my QNAP NAS TS-251+ whilst developing a new project these are:
1) There is no php alias and when I add one via command line it is removed on NAS Restart.
2) A similar thing happens for Composer except on restart it removes Composer as well from the system.
How can I stop this from happening or get around it so that when my NAS restarts the php and composer alias are already set.

I managed to resolve this issue by adding a new script that runs when my NAS starts up. QNAP have provided some basic instructions on how to add a startup script on their wiki page under Running Your Own Application at Startup. However I added a couple more steps t
These steps are fairly basic:
Login to your NAS Server via SSH.
Run the following command mount $(/sbin/hal_app --get_boot_pd port_id=0)6 /tmp/config (Running ls /tmp/config will give you something similar to below)
Run vi /tmp/config/autorun.sh this will allow you to edit/create a file called autorun.sh **
For me I wanted to keep this file as simple as possible so I didn't have to change it much, so the script is just called from with this Shell Script. So add the following to autorun.sh.
autorun.sh code example:
#!/bin/sh
# autorun script for Turbo NAS
/share/CACHEDEV1_DATA/.qpkg/autorun/autorun_startup.sh start
exit 0
You will notice a path of /share/CACHEDEV1_DATA/.qpkg/autorun/ this is where my new script that I want to run is contained, you don't have to have yours here if you don't want to however I know the script will not be removed if placed here. autorun_startup.sh this is the name of the script I want to be running, and start is the command in the script I want to be running.
Run chmod +x /tmp/config/autorun.sh to make sure that autorun.sh is actually runnable.
Save the file and run umount /tmp/config (Important).
Navigate to the folder you have put in the autorun.sh (script in my case /share/CACHEDEV1_DATA/.qpkg/autorun/) and create any folders along the way that you need.
Create your new shell file using vi and call it whatever you want (Again in my case it is called autorun_startup.sh) and add your script to the file. The script I added is below but you can add whatever you want to you startup script.
autorun_startup.sh code example:
#!/bin/sh
RETVAL=0
QPKG_NAME="autorun"
APACHE_ROOT=`/sbin/getcfg SHARE_DEF defWeb -d Qweb -f
/etc/config/def_share.info`
QPKG_DIR=$(/sbin/getcfg $QPKG_NAME Install_Path -f /etc/config/qpkg.conf)
addPHPAlias() {
/bin/cat /etc/profile | /bin/grep "php" | /bin/grep "/usr/local/apache/bin/php" 1>>/dev/null 2>>/dev/null
[ $? -ne 0 ] && /bin/echo "alias php='/usr/local/apache/bin/php'" >> /etc/profile
}
addComposerAlias() {
/bin/cat /etc/profile | /bin/grep "composer" | /bin/grep "/usr/local/bin/composer" 1>>/dev/null 2>>/dev/null
[ $? -ne 0 ] && /bin/echo "alias composer='/usr/local/bin/composer'" >> /etc/profile
}
addPHPComposerAlias() {
/bin/cat /etc/profile | /bin/grep "php-composer" | /bin/grep "/usr/local/apache/bin/php /usr/local/bin/composer" 1>>/dev/null 2>>/dev/null
[ $? -ne 0 ] && /bin/echo "alias php-composer='php /usr/local/bin/composer'" >> /etc/profile
}
download_composer() {
curl -sS https://getcomposer.org/installer | /usr/local/apache/bin/php -- --install-dir=/usr/local/bin --filename=composer
}
case "$1" in
start)
/bin/echo "Enable PHP alias..."
/sbin/log_tool -t 0 -a "Enable PHP alias..."
addPHPAlias
/bin/echo "Downloading Composer..."
/sbin/log_tool -t 0 -a "Downloading Composer..."
download_composer
/bin/echo "Enable composer alias..."
/sbin/log_tool -t 0 -a "Enable composer alias..."
addComposerAlias
/bin/echo "Adding php composer alias..."
/sbin/log_tool -t 0 -a "Adding php composer alias..."
addPHPComposerAlias
/bin/echo "Use it: php-composer"
/sbin/log_tool -t 0 -a "Use it: php-composer"
;;
stop)
;;
restart)
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $RETVAL
Run chmod +x /share/CACHEDEV1_DATA/.qpkg/autorun/autorun_startup.sh to make sure your script is runnable.
Restart your NAS System to make sure the script has been run. After restart for my script I just did php -version via terminal to make sure that the php alias worked and it did.
(*) With steps 3 and 8 you can either do this via something like WinSCP or continue doing it via command line (SSH). For me I chose to do it via WinSCP but here is the command still for SSH
I am fairly new to server related stuff so if anyone has a better way cool.

Related

Launch php script at apache2 startup

I am trying to run a php script to restore a state after the server crashed, got restarted or smth.
Because the php script needs the database to run I first tried running it by creating a file in init.d, which did not work, it just started whenever it wantend.
So right now I think it is the easiest way to run the script on apache2 startup like discribed here.
So currently I have added php -q /var/www/scripts/testing.php & ;; to do_start() in /etc/init.d/apache2 like this:
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
if pidofproc -p $PIDFILE "$DAEMON" > /dev/null 2>&1 ; then
return 1
fi
if apache_conftest ; then
$APACHE2CTL start
php -q /var/www/scripts/testing.php &
;;
apache_wait_start $?
return $?
else
APACHE2_INIT_MESSAGE="The apache2$DIR_SUFFIX configtest failed."
return 2
fi
}
But because this didn't work at all, I have also added this php execution to the restart) part as mentioned in the link. This looks like this:
restart)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop stop
case "$?" in
0|1)
do_start
case "$?" in
0)
log_end_msg 0
;;
1|*)
log_end_msg 1 # Old process is still or failed to running
print_error_msg
exit 1
;;
esac
;;
*)
# Failed to stop
log_end_msg 1
print_error_msg
exit 1
;;
php -q /var/www/scripts/testing.php &
;;
esac
;;
But still the script is not run. The php script looks like this:
<?php
file_put_contents('/var/www/html/log', "301,$timestamp,Recreating all connections after restart,N/A\n",FILE_APPEND);
?>
Because i wanted it to be as simple as possible, but the log file is still empty. I am open to any idea solving my problem.
p.s.: I have already tried to do this by a service in /etc/systemd/system/ but since I am starting a connection that is supposed to be persistent, I have to use either screen, nohup or disown. I have tried those three, but no of this worked, they just didn't start the script. (was bash back then, I switched to php to be able to run it from the apache2 file)
You should not use apache to start your script, but follow your first idea of using an own init-script unless your php script depends on the existence of apache.
Just place a shell script callmyphp into /etc/init.d that calls the php interpreter and passes your php script as an argument like:
#!/bin/sh
/usr/bin/php -q /path/to/myphp.php
Don't forget to make your calling script executabel with chmod 755 /etc/init.d/callmyphp.
Then add your calling script via symbolic links to the desired run levels, i.e. by running update-rc.d callmyphp defaults
See also https://debian-administration.org/article/28/Making_scripts_run_at_boot_time_with_Debian

PHP shell_exec - bash kill httpd.exe then run httpd.exe again (need to restart Apache on Windows without service installed)

I have a php script that running on my local Windows machine and i need to restart Apache server from that script. I may stop Apache from that script but can't start it because it is being stopped and php execution after apache-stop is interrupted.
My php code is
shell_exec('bash -c "source ~/.bashrc && apache-stop && some-command && apache-start"');
//bash.exe is in PATH already
Bash functions ~/.bashrc
function apache-stop {
( tskill httpd )
if [[ $? -eq 0 ]]; then
echo "Apache stopped."
fi
}
function apache-start {
tasklist | grep -a "httpd.exe" > /dev/null
if [[ $? -eq 0 ]]; then
echo "Apache already running."
else
echo "Start Apache."
( /c/xampp/apache/bin/httpd.exe & )
fi
}
I use Apache on Windows 8.1 only as console application and run/kill it from bash console, hence i can't use Apache as a Windows Service. How to run apache-stop, some-command and apache-start from that php script, may be there is a way to run externally all this bash functions?

How can I check if a program is running in the background using a cron, and start it if needed?

I have the task to run a daemon in the background on a production server. However, I do want to be sure that this daemon always runs. The daemon is PHP process.
I tried to approach this by checking if the daemon is running, and if not: start it. So I have a command like:
if [ $(ps ax | grep -c "akeneo:batch:job-queue-consumer-daemon") -lt 3 ]; then php /home/sibo/www/bin/console akeneo:batch:job-queue-consumer-daemon & fi
I first do an if with ps and grep -c to check if there are processes running with a given name, and if not: I start the command ending with an &, forcing it to start.
The above command works, if I execute it from the command line the process gets started and I can see that is is running when I execute a simple ps ax-command.
However, as soon as I try to do this using the crontab it doesn't get started:
* * * * * if [ $(ps ax | grep -c "akeneo:batch:job-queue-consumer-daemon") -lt 3 ]; then php /home/sibo/www/bin/console akeneo:batch:job-queue-consumer-daemon & fi
I also set the MAILTO-header in the crontab, but I'm not getting any e-mails as well.
Can anyone tell me what's wrong with my approach? And how I can get it started?
An easy and old-style one is to create a bash file where you basically check if the process is running, otherwise you start it.
Here the content of the bash file:
#!/bin/bash
if [ $(ps -efa | grep -v grep | grep job-queue-consumer-daemon -c) -gt 0 ] ;
then
echo "Process running ...";
else
php /home/sibo/www/bin/console akeneo:batch:job-queue-consumer-daemon
fi;
Then in the crontab file you run the bash file.
There are special services for such tasks. For example http://supervisord.org/
Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems.
And you can manage it via f.e https://github.com/supervisorphp/supervisor
A command working on command line and not working in CRON, this happened to me and here is what solved my problem.
Run echo $PATH in your terminal, copy entire output.
Then type crontab -e and at top of file, write this
PATH=WHATEVER_YOU_COPIED_FROM_LAST_COMMAND_OUTPUT
PS: (more suggestions)
I think you need to install apt-get install postfix on Ubuntu to be able to send emails.
You should also see CRON logs by
grep CRON /var/log/syslog
i would recommend you to use supervisord, it handles these kinds of issues with automatic restart on failed services, additionaly, you can try to set the akeneo commands as a service.
Otherwise, if you would like to do it using cronjobs, you may have an issue with the php binary, you need to setup the absolute path :
e.g : /usr/bin/php
I would also recommend if you use cronjob:
Check the logs of the cronjob for additional issues
grep CRON /var/log/syslog
Clean it up using a standalone bash script (don't forget to chmod +x)

Open gnome-terminal from php script

I want to try to open gnome-terminal from php script:
shell_exec('bash /data/manager/application/.shell/system.sh');
This script use a function to check terminal:
SCRIPTCURRENT=`readlink -m $0`
SCRIPTCURRENTPATH=$(dirname "$SCRIPTCURRENT")
runintoterminal () {
if ! [ -t 1 ]; then
gnome-terminal -e "bash $1"
exit 0
fi
}
runintoterminal $SCRIPTCURRENT
I've tried:
shell_exec('gnome-terminal');
But it's doesn't work... (I know it's possible...) But how to ?
I use nginx and php-fpm. With my own socket. nginx and socket use my user and not www-data. (I'm on ubuntu 14.04LTS)
I've try 0777 rights...
My bash script can run from netbeans IDE ans terminal... but not from php...
The problem is most likely that gnome-terminal doesn't know where it should draw itself. Normally it shows up on the same display as the program that launched it (IDE, terminal), but web servers don't have displays so it doesn't know where to go. You can try DISPLAY=:0 gnome-terminal -e "bash $1" to show it on the current first local graphical login session, if it has permissions for that.
that other guy
shell_exec('DISPLAY=:0 bash /data/manager/application/.shell/system.sh');
Or on function:
SCRIPTCURRENT=`readlink -m $0`
SCRIPTCURRENTPATH=$(dirname "$SCRIPTCURRENT")
runintoterminal () {
if ! [ -t 1 ]; then
DISPLAY=:0 gnome-terminal -e "bash $1"
exit 0
fi
}
runintoterminal $SCRIPTCURRENT

Starting FOREVER or PM2 as WWW-DATA from a PHP script

I have a nodejs script named script.js.
var util = require('util');
var net = require("net");
process.on("uncaughtException", function(e) {
console.log(e);
});
var proxyPort = "40000";
var serviceHost = "1.2.3.4";
var servicePort = "50000";
net.createServer(function (proxySocket) {
var connected = false;
var buffers = new Array();
var serviceSocket = new net.Socket();
serviceSocket.connect(parseInt(servicePort), serviceHost);
serviceSocket.pipe(proxySocket).pipe(serviceSocket);
proxySocket.on("error", function (e) {
serviceSocket.end();
});
serviceSocket.on("error", function (e) {
console.log("Could not connect to service at host "
+ serviceHost + ', port ' + servicePort);
proxySocket.end();
});
proxySocket.on("close", function(had_error) {
serviceSocket.end();
});
serviceSocket.on("close", function(had_error) {
proxySocket.end();
});
}).listen(proxyPort);
I am runing it normally like nodejs script.js, but now i want to include forever or pm2 functionalities as well. When i am root everything works smootly:
chmod -R 777 /home/nodejs/forever/;
-- give rights
watch -n 0.1 'ps ax | grep forever | grep -v grep'
-- watch forwarders (where i see if a forever is opened)
/usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file
-- open with forever
forever list
-- it is there, i can see it
forever stopall
-- kill them all
The problem is when i want to run the script from a PHP script with the system or exec functions :
sudo -u www-data /usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file
-- open as www-data (or i can do this just by accessing `http://1.2.3.4/test.php`, it is the same thing)
forever list
-- see if it is there, and it is not (i see it in watch)
forever stopall
-- says no forever is opened
kill PID_ID
-- the only way is to kill it by pid ... and on another server all of this works very well, can create and kill forevers from a php script when accessing it from web ... not know why
-- everything is in /etc/sudoers including /usr/local/bin/forever
Why is that? How can i solve this?
I also made some trick, created a user 'forever2', i created a script.sh with this content :
sudo su forever2 user123; /usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file;
where user123 is not existent, is just a trick to exit the shell after execution. The script works, runs forever, i can close all forevers with the command forever stopall from root. When i try the same thing running the http://1.2.3.4/test.php or as www-data user i cannot close it from root or www-data, so not even this works.
I tried from Ubuntu 14.04.3 LTS, Ubuntu 14.04 LTS , Debian GNU/Linux 8 ... still the same thing.
Any ideeas?
Thanks.
If you are starting the process from within Apache or the web-server you are already as the www-data user, so doing a sudo su to the user context you already have is likely not necessary.
When you start this forever task you may also be required to shut the terminals/inputs and directly send to background. Something like this:
// Assemble command
$cmd = '/usr/bin/forever';
$cmd.= ' -d -v --pidfile /tmp/my.pid'; // add other options
$cmd.= ' start';
$cmd.= ' /etc/dynamic_ip/nodejs/proxy.js';
// "magic" to get details
$cmd.= ' 2>&1 1>/tmp/output.log'; // Route STDERR to STDOUT; STDOUT to file
$cmd.= ' &'; // Send whole task to background.
system($cmd);
Now, there won't be any output here but you should have something in /tmp/output.log which could show why forever failed, or the script crashed.
If you've been running the script sometimes as root, then trying the same command as www-data you may also be running into a permissions on one or more files/directories created from the execution as root which now conflict when running as www-data.
This is part of PHP security you say you're running it from a php script and your not your running it from Apache via a php script.
PHP web scripts should not have root access as such they run under the same permissions as Apache user www-data.
There are ways to prevent php running as root but run a task as root but it's a little hacky and I'm not going to share the code but I will explain so you can look into it. here is where to start
http://php.net/manual/en/function.proc-open.php
With a Proccess like this you can then execute a proc. Like your script.js via nodeJS using SUDO and then read stdOut and stdErr wait for password request then provide it by writing to stdIn for that process.
Don't forget in doing this the user www-data has to have a password and be in the sudoers list
Per the OPs Comment
Due to the way SUDO works the PATH does not appear to contain the path to the node executables npm, node so your best of building a .sh (bash script) and using sudo to run that.
You still need to monitor this process as it will still ask for a password
#!/bin/bash
sudo -u ec2-user -i
# change this to the path you want to run from
cd ~
/usr/local/bin/pm2 -v

Categories