Thursday, August 1, 2013

Always up to date...

Aloha,
Before I'll go to vacation for the next 2 weeks I thought it might be time to release another blogpost. It will be about updating the JDK on the Raspberry Pi remotely...
At home I have 5 Raspberry Pi's installed to test different things and now that the JDK8 developer preview for the Pi is in line with the weekly developer previews for the Desktop this means I have to update all of my Pi's every week...which is a bit time consuming.
Because I have already implemented a remote update feature for the applications on my Pi's it was just a small step to get this also up and running for the JDK8.

Prerequisites
First of all you need the code...please find it here
Your Raspberry Pi need an internet connection and you should be able to access it via SSH for the installation and setup.
You will need a DropBox account (you will get 2GB for free so why wait...get one here)
I use the Raspbian Wheezy hardfloat version and JDK8 but this example should work (with a few modifications) also on other hardware and operating systems as long as you get Java running on that device.

Preparation
To be able to use the remote update functionality I have setup my Pi's in the way that they automatically login with the user pi. In addition you have to make sure that a startup script will be called after login. To setup the Pi for auto login you need to execute the following steps...

1. Setup auto login on the Pi
SSH to your Pi and type in console
    "sudo apt-get install mingetty"

Now edit the inittab file with 
    "sudo nano /etc/inittab"

(Saving a file in nano will be done by pressing CTRL + O and exit nano with CTRL + X)

search for the line 
    "1:2345:respawn:/sbin/getty 38400 tty1" and

change it to 
    "1:2345:respawn:/sbin/mingetty --autologin <USER_NAME> --noclear tty1"

with this modification the user with the name <USER_NAME> will be logged in automatically after booting the Pi.


2. Add calling your script to the auto start procedure
SSH to your Pi and type in the console
    "sudo nano /home/pi/.bash_profile"

Add the following line to the file
    "sudo bash /home/pi/startupscript.sh"


3. Add a startup script that does the jdk installation
SSH to your Pi and type in the console
    "sudo nano /home/pi/startupscript.sh"

Now add the following code to the startup script file
    #!/bin/bash

    # Check if jdk8.gz file is present
    if [ -f /home/pi/jdk8.gz ]
    then
      # Remove installed jdk8
      sudo rm -r /opt/jdk1.8.0
  
      # Extract new jdk8 and remove jdk8.gz file after extraction
      sudo tar zxvf /home/pi/jdk8.gz -C /opt && rm /home/pi/jdk8.gz  
    fi

    # Start the Java program

    /opt/jdk1.8.0/bin/java -cp /home/pi/lib/smack.jar:/home/pi/lib/smackx.jar:/home/pi/PiUpdate.jar pi.Main

This script will first check if the jdk8.gz file is present in /home/pi and if this is the case it will remove the installed jdk from /opt/jdk1.8.0 and will extract the jdk8.gz to /opt/jdk1.8.0. After the extraction is done it will remove the jdk8.gz file and will start the Java application. If no jdk8.gz file is present it will simply start the Java application.

If you encounter problems when running the application it might be because of file permissions of the user Pi on the Raspberry Pi. It's not the preferred way but you could simply SSH to your Raspberry Pi with the user Pi and call "sudo chmod 777 -R /home/pi" which will give the user Pi all rights on all files and folders in /home/pi.


4. Modify the Main class
The Main class from the code needs some modifications...here is the part that you have to modify...

public class Main {
  private static final String JDK_FILE_ON_DROPBOX
    "PATH TO YOUR DROPBOX FOLDER/jdk8.gz";
  private static final String JDK_FILE_ON_PI
    "PATH TO jdk8.gz FILE ON PI";

  private String      senderName;
  private String      senderPassword;
  private String      server;
  private String      resource;
  private int         port;
  private XmppManager xmppManager;


  // ******************* Constructors ***************************************
  public Main() {
    senderName     = "YOUR JID";
    senderPassword = "YOUR XMPP PASSWORD";
    server         = "YOUR XMPP SERVER";  
    resource       = "YOUR RESOURCE";    
    port           = 5222;               
...

Please replace the magenta colored parts with your data (let's assume your xmpp account is mypi@jabber.ccc.de and the jdk8.gz file is in the public folder of your DropBox)

    "PATH TO YOUR DROPBOX FOLDER/jdk8.gz" 
with 
    "https://dl.dropbox.com/u/12345/jdk8.gz"

    "PATH TO jdk8.gz FILE ON PI"
with
    "/home/pi/jdk8.gz"

    "YOUR JID"
with
    "mypi"

    "YOUR XMPP PASSWORD"
with
    "secret"

    "YOUR XMPP SERVER"
with
    "jabber.ccc.de"

    "YOUR RESOURCE"
with
    "Home"


5. Test it...
To test it, reboot your Raspberry Pi (which should be connected to the Internet). On your desktop or mobile device open a chat client that "speaks" xmpp or jabber and login. Now start a chat with your Raspberry Pi by using the JID you defined in your code.
Taking a look at the code of the XmppManager class will show you that I've implemented three commands:
  • updatejdk
  • reboot
  • ipaddress
If you did everything right you should be able to ask the Raspberry Pi for it's ip address by typing "ipaddress" in the chat window and the Pi should answer it with sending you a message that contains it's ip address. 
If this works you have to copy the current JDK8 developer preview for the Pi and copy it to your DropBox in the folder that you defined in the code above. (You have to add the public link to the jdk8.gz file on your DropBox public folder once to the Main class above.)
Now rename the downloaded jdk file to jdk8.gz.
That's it...now you could send the Pi a chat message with "updatejdk" and it should answer with "Start downloading jdk...please wait". When the download is finished the Pi will send you a message "Download of jdk successful, please reboot".
Now you could send the Pi the message "reboot" and your Raspberry Pi will reboot itself, replace the installed JDK with the new one and start your application again. :)

That's it for today...now it's time for vacation...so no blogpost in August...read you soon...keep coding... :)

No comments:

Post a Comment