I have recently set up a LAMP Raspberry Pi and am using this at work to monitor some servers (see Raspberry PI as a LAMP server and PI as a Web Server Monitor)
I'm running it 'headless' (i.e. without a keyboard or mouse attached). This is fine until I wanted to reboot it yesterday, and realised that I would have to go through the hassle of opening a Putty session, connecting to the server, logging on, and issuing the reboot command. How convenient it would be if i could just click on a web link ...
After some investigation I discovered that I couldn't simply write a .php page with something like 'sudo reboot' in it. What I needed to do was ;
- Write a python script that would reboot the server
- Write a php page to execute the python script.
- I would also need to make some configuration changes to allow the reboot command to be run from a web application
Python Script
If I was booting from the command line I would enter sudo reboot. My python script therefore needs to allow me to run a system command. This is done by using the python subprocess command (there's a useful reference page at Subprocess and Shell Commands in Python ). With that knowledge, the resulting code is fairly easy to understand - see below. Note that the 'sudo' and 'reboot' commands are evaluated with their full paths.
command = "/usr/bin/sudo /sbin/reboot" import subprocess process = subprocess.Popen(command.split(), stdout=subprocess.PIPE) output = process.communicate()[0] print output
Time stamping
I decided that it would be nice to keep a record of the commands that were being issued as added a time stamp operation in the python code - this simply writes a line to a log file with the current date/time. I also found this useful when developing this mini app as I could have the script run (and see that it had run successfully!) without having to issue the 'reboot' command.
The timestamp code is as follows
# # Construct a timestamp variable # import time ts = time.time() import datetime st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') # # Open a file and allow content to be appended to it # f = open('/var/www/remotecontrol/logs/reboot.log', 'a') # write the timestamp and text to the file f.write(st) f.write(' : REBOOT command issued\n')
For the entire script, see attached example.
PHP Page
Once I had the script, I needed a page to allow me to run it. Executing the script from a web page is quite straight forward - e.g.
<?php exec("python /var/www/remotecontrol/python/reboot.py"); ?>
However I want to control the process so that the script only runs when a button is pressed. Therefore my page needs to :
- Display a page with a button on it
- When the user presses the button
- Execute the script
- Display a confirmation message
- Execute the script
I achieved this with the following code :
Output a button - when it is clicked execute javascript function reboot().
<input type="button" id="reboot" value="Reboot" onClick="reboot()"/>
The javascript function resubmits the page with an added parameter - i.e. status=reboot
<script> function reboot() { window.location="reboot.php?status=reboot"; } </script>
Php code in the page looks for the existence of the 'status' parameter and acts accordingly - note that it executes the script and puts out an indicationon the screen that the server is rebooting
<?php $status = $_GET["status"]; if ($status == "reboot"){ exec("python /var/www/remotecontrol/python/reboot.py"); print '<h2>Server is rebooting ...</h2>'; } ?>
The full code is attached below - note that the page offers two options reboot and shutdown. (The shutdown script is a clone of the reboot script - with the command changed to shutdown now.)
Configuration Changes
When I tried to run the function nothing happened - my page displayed the 'Server is rebooting' but the server didn't reboot. I looked in the logs and found sudo: no tty present and no askpass program specified. (NB the error.log file is located at /var/log/apache2). After some 'googling' I discovered that this was being issued because the current user doesn't have access to the command. although I always log on to the pi from the command line as the default user pi, this command is being issued by the web page via Apache - and with the default LAMP installation, Apache runs as user www.data, therefore, this user (i.e. Apache) needs to be given access to the sudo command to run the reboot command.
This is achieved as follows.
- From a putty session use command sudo visudo
- This will open up the sudo configuration file in the editor.
- Go to the end of the file and add the following line
www-data ALL=/sbin/reboot www-data ALL=NOPASSWD: /sbin/reboot
the effect of tis will be to enable user www-data to use the reboot command. if you want to issue other commands using sudo from Apache (e.g. shutdown, then add additional lines to the sudo configuration file.
When I had made the changes I rebooted the Pi to make sure the changes were applied.
That's it! - when I go to the url http://10.13.36.255/remotecontrol/reboot.php I see the following page; (I may add some styling to make it look better !)
When I click on the 'reboot button I see this, and the Pi reboots !
If this was anywhere other than in a very closed environment I would add some extra functionality to prevent the reboot page being actioned by unwanted users ! - but in this particular case I don't need to worry
Useful links