Go Back   HowtoForge Forums | HowtoForge - Linux Howtos and Tutorials > ISPConfig 3 > Developers' Forum

Do you like HowtoForge? Please consider supporting us by becoming a subscriber.
Reply
 
Thread Tools Display Modes
  #1  
Old 20th September 2010, 15:35
zabersoft zabersoft is offline
Member
 
Join Date: Aug 2010
Posts: 33
Thanks: 1
Thanked 2 Times in 1 Post
Default Here is how to run server.sh from PHP

Disclaimer: This approach is NOT recommended by the ISPConfig developers - as reiterated by Till in many a post. You should only do this in very specific scenarios. I believe that this approach still has its merits however, so I've decided to share my findings in solving this problem with you all.

Server.sh is the shell script that runs server.php which updates all the ISPConfig configuration and does all the useful stuff which happens after you create a client, website, ftp user etc. etc.

Usually server.sh is run by a cron job, as root, every minute

When to use this approach:
We decided to manually invoke server.sh after having used the remoting functions in ISPConfig as we had 2 issues we wanted to solve:

1) Our system setup was time-critical - That is, we wanted ISPConfig to create directories, FTP/DB users immediatly after having called the remoting functions

2) We wanted to avoid creating an extension, if possible, as we wanted to be able to rapidly deploy our system on new servers - and having to mess about with ISPConfig internals and customizing ISPConfig would slow down our deployment process.

Potential pitfalls:
As Till has mentioned then the primary issue with our approach is:
Quote:
ISPConfig is a multiserver controlpanel, so the controlpanel does not nescessarily run on the same server then the apache webserver. Almost all larger installs use the multiserver features and in these enviroments you can not simply call server.sh from apache.
The recommended approach is to create an extension which gets invoked after the "regular" server.sh cron job finishes. You can read up on this here:

http://www.howtoforge.com/forums/showthread.php?t=47951

The solution:
If you have all the potential pitfalls in mind, and still want to run server.sh manually from apache, then here is how to do it. Basically the solution rests in the fact that you can take advantage of the setuid and setgid bits to run a c executable as root. This has been the major stumbling block in running server.sh from apache - as if it isn't run as root, nothing will work (no directories will be created etc. etc. - as the script doesn't run with the appropriate privileges). So what we do is create a c executable which then in turn invokes server.sh

First, the PHP code which runs our custom c executable (which we will create a bit later):

PHP Code:
//This function enables us to execute something on the server in the background - grabbed from php.net somewhere
function execInBackground($cmd) { 
    if (
substr(php_uname(), 07) == "Windows"){ 
        
pclose(popen("start /B "$cmd"r"));  
    } 
    else { 
        
exec($cmd " > /dev/null &");   
    } 


//Call our "elevated rights" executable and tell it to run server.sh
execInBackground("/path/to/your/executable/elevaterights updateispcon");

//Let's wait for it to finish before moving on to other things - like copying files or whatever you wanna do
while (!is_dir($document_root)) {
  
//foo

I tried to simplify things a bit here - There is actually no need to execute the elevaterights executable in the background - you can easily just do a regular exec without piping output to dev null

Anyhoo - now the critical part: The c executable where all the magic happens

Code:
/*
compile using: gcc elevaterights.c -o elevaterights 
then: chown root:root elevaterights 
next: chmod 6755 elevaterights - this enables the system to run this executable as root (the 4 sets the setuid bit, 2 sets the setgid bit - 4+2 = 6(755)) 
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <strings.h>

int main( int argc, char *argv[] )
{
   setuid( 0 );
   setgid( 0 );
   
//Run the ISPConfig updater script
 if (strcmp(argv[1],"updateispcon") == 0) {
     puts("Executing ISPConfig Update script ...");
     system( "/usr/local/ispconfig/server/server.sh" );
	 system( "cp /path/to/your/executable/lockfile /path/to/your/executable/.sitekick_lock" );
 } else  if (strcmp(argv[1],"restarthttpd") == 0) {
  //lock file is created in PHP
  FILE *fp = fopen("/path/to/your/executable/.sitekick_lock","r");
	if( fp ) {
	// exists
	fclose(fp);
     puts("Restarting Apache ...");
     system( "/etc/init.d/apache2 restart" );
	 puts("Deleting restart lock file ...");
	 system( "rm /path/to/your/executable/.sitekick_lock" );
   } else {
    puts("No lock file found - doing nothing ...");
   }
    return 0;
}

} //end main
To explain a bit ... The reason you see all that mumbo jumbo regarding a lockfile and not just a straightforward execution of server.sh is that when we were going through this process we ran into a problem with server.sh restarting apache. Usually when ISPConfig adds new vhosts it restarts apache so they are up and running immediatly. For some reason, when we were invoking server.sh from apache this caused the process to hang. I suspect that this is a recursiveness thing - as I could not track down any actual error conditions. That is - calling server.sh from apache which then tries to restart apache hangs, as it is trying to kill itself. So to speak. That's my guess in anyway.

So, we solved this by creating a new cronjob which is run every minute and invoked like so:

/path/to/your/executable/elevaterights restarthttpd

The reference you see to "lockfile" in the above code is just a dummy file which gets copied to .sitekick_lock - which the cron job then looks for to determine whether apache needs a restart.

In addition to this, we had to tweak a bit in the ISPConfig code to stop it from restarting apache when it has done its job. We just added a single line (return 0; ) to the function restartHttpd in server/mods-available/web_module.inc.php (around line 130)

I would be very interested to see if somebody who had another setup were to try the above code - and just removed all the lockfile / manual restart whatnot and see if the same thing happens for them. Because - well as this approach works then the whole apache restart issue makes it slightly messy - and some of the benefit of this approach - which is not altering any ISPConfig files gets slightly lost as we need to do that tweak to web_module.inc.php

Anyhoo - That's my story - Hope this helps someone, and maybe this can spark a discussion on how silly I am in doing all this and that there is a much better approach available (Here's hoping - haha)

Last edited by zabersoft; 20th September 2010 at 15:38.
Reply With Quote
The Following 2 Users Say Thank You to zabersoft For This Useful Post:
falko (21st September 2010), till (20th September 2010)
Sponsored Links
  #2  
Old 20th September 2010, 15:59
till till is offline
Super Moderator
 
Join Date: Apr 2005
Location: Lüneburg, Germany
Posts: 35,509
Thanks: 815
Thanked 5,269 Times in 4,130 Posts
Default

If I understand your explanation correctly, you have to restart apache with a one minute cronjob. So your changes get applied after about one minute. Thats the same time that the normal ispconfig system takes to apply the changes, so I dont see the real benefit in the time to get changes applied.

If you want to get changes applied faster, then the approach that was used in ispconfig 2 might be a good choice.

1) Comment out the server.sh root cronjob.
2) create a bash script, e.g. /usr/local/bin/ispconfig_server.sh with the following content:

Code:
#!/bin/bash

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin

. /etc/profile

error ()
{
  echo "ERROR: $1"
  exit 1
}

ID="id -u"
MYUID=`$ID 2>/dev/null`

if [ ! -z "$MYUID" ];
then
  if [ $MYUID != 0 ];
  then
    error "You need root privileges to run this script! / Vous devez avoir les privileges root pour executer ce script!";
  fi
fi

while (true) do
  if [ -f /usr/local/ispconfig/interface/web/temp/.run ]; then
    touch /usr/local/ispconfig/server/temp/.run2
    rm -f /usr/local/ispconfig/interface/web/temp/.run
    /usr/bin/php -q /usr/local/ispconfig/server/server.php
    rm -f /usr/local/ispconfig/server/temp/.run2
  fi
  sleep 10
done

exit 0
Start this shell script in the background, it will run forever until you kill it or you reboot the server. It has a very low resource usage. The script checks every 10 seconds if a file /usr/local/ispconfig/interface/web/temp/.run exists and if that file exists it will start the ispconfig update process. You can even reduce the time to less then 10 seconds if nescessary.

So if you want to start an update from the ispconfig interface then, you just execute this php command:

touch('/usr/local/ispconfig/interface/web/temp/.run');

This variant is only usable on single server systems, thats why we dont use it in ispconfig 3.
__________________
Till Brehm
--
Get ISPConfig support and the ISPConfig 3 manual from ispconfig.org.

Last edited by till; 20th September 2010 at 16:05.
Reply With Quote
  #3  
Old 20th September 2010, 16:14
zabersoft zabersoft is offline
Member
 
Join Date: Aug 2010
Posts: 33
Thanks: 1
Thanked 2 Times in 1 Post
Default Excellent

Hi Till,

Thank you for that nice reply and an excellent new approach - I will certainly give it a go as this would probably be a lot cleaner than what I am doing now.

However, one question - The .run file which tells the bash script (ispconfig_server.sh) to invoke server.php - this gets created by ISPConfig whenever an update to its config has been made? You didn't remove this in ISPConfig 3 even though this approach has been deprecated?

Just making sure

Thanks again!

PS: The reason for all this was that it was critical that directories etc. got created ASAP so we could set up our system files immediatly and update databases etc. - That is, a complete setup of the systems. Accessibility to the site was of a secondary concern - so it was OK that apache got restarted a minute later - as at that point everything was ready to go. With the other approach, the user risked having to wait up to 2 minutes+ for everything to finish (And we don't like to keep people waiting, looking at a spinner ) - Now everything is all set up in 30 seconds or less, typically.

With your new/old approach then +10 seconds is AOK by us, and should solve our problems

Last edited by zabersoft; 20th September 2010 at 16:34.
Reply With Quote
  #4  
Old 20th September 2010, 17:16
till till is offline
Super Moderator
 
Join Date: Apr 2005
Location: Lüneburg, Germany
Posts: 35,509
Thanks: 815
Thanked 5,269 Times in 4,130 Posts
Default

Quote:
However, one question - The .run file which tells the bash script (ispconfig_server.sh) to invoke server.php - this gets created by ISPConfig whenever an update to its config has been made? You didn't remove this in ISPConfig 3 even though this approach has been deprecated?
No, the file does not get created by ispconfig. You can either invoke it the same way that you do it for your approach or you add the line at the end of the remoting index.php file.
__________________
Till Brehm
--
Get ISPConfig support and the ISPConfig 3 manual from ispconfig.org.
Reply With Quote
  #5  
Old 21st September 2010, 16:02
zabersoft zabersoft is offline
Member
 
Join Date: Aug 2010
Posts: 33
Thanks: 1
Thanked 2 Times in 1 Post
Default

I have now spent the day implementing Till's approach and it works like a beaut.

What I've done is create a cron job which runs a small PHP file which checks whether the bash script Till posted is running, and if not starts it. This is to ensure that it always is active (even after a reboot) - I guess you could add it to /etc/init.d but I didn't want to bother with that.

This is my PHP cron job:

PHP Code:
//Path to sitekick internal system files
$sitekick_sys "/var/www/xxxxx/sitekick/"

     
//Check if ISPConfig updater process is running - if not, start it
      
exec("ps aux | grep '/var/www/xxxxx/sitekick/[i]spconfig_updater.sh' | wc -l"$check);
      if(
intval($check[0]) > 0) { 
          echo(
'ISPConfig updater is already running');
      } else {
        echo(
'Updater not running - starting in background');
        
$command "nohup /var/www/xxxxx/sitekick/ispconfig_updater.sh > /dev/null &";
        
exec($command);
        echo 
$command;
      } 
As you can see I placed the bash script in another location than the one Till mentioned, as I want to keep our own stuff outside of ISPConfig dirs. Also, I had to change ownership of the script to root for everything to work properly.

I did not disable the "regular" server.sh cron job, as I saw no reason to. I still want things to work as usual in ISPConfig if we set up a client/vhost manually in the ISPConfig back-end.

All Till's bash script really does is just wait for .run to be touched/created and then do the update. I modded it slightly so that it only waits 5 seconds between each check. I can't see that this tweak should have any detrimental effect.

I still use my elevated rights executable as posted in the original post - but now its job has changed to:
1) touch .run (you need to be root to do this, so it's a problem from apache)
2) Run all my post ISPConfig update actions as root - I changed this to all be located in a custom PHP file which is run by my elevated rights executable - for easier maintenance

Anyway - Here's a happy man signing off as everything is working as it should
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with services!! banzaiwebstudio.com Installation/Configuration 7 19th May 2010 21:13
Error when install ISPConfig 2 with components built from source X-admin Installation/Configuration 5 30th April 2010 13:22
ffmpeg Video support for ubuntu 7.10 [suphp-ispconfig] amaurib Installation/Configuration 13 16th February 2010 17:26
Unable to install ISPConfig bdonecker Installation/Configuration 21 26th May 2009 08:20
Apache2 Freezes celtic Server Operation 31 28th May 2007 17:18


All times are GMT +2. The time now is 07:02.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.