How to develop a Frontview Add-on

July 10, 2008 by  
Filed under Resources

A Frontview Add-on is a software module that can be installed on the ReadyNAS to expand the services provided through Frontview. An add-on can contain a service daemon with a management piece that appears in Frontview. If you’ve ever taken a look at the Services → Installed Add-ons page in Frontview, you’ll see two such add-ons pre-installed — BitTorrent and ReadyNAS Photos.


As you can see, users can enable or disable an add-on by selecting or unselecting the checkbox, and can modify the add-on configuration from the Installed Add-ons page or by opening a new page.

Getting Started

We’ll start by creating, building, and testing a sample add-on, and then we’ll get a little deeper as we explain each component of the add-on and where you will need to put your changes.

A good level of competency in the following is recommended before writing a Frontview add-on:

  1. Linux shell environment and shell scripts
  2. Web 2.0 programming (HTML, Javascript, XML, AJAX)
  3. Perl or C for CGI back-end support

You’ll need to be running RAIDiator 4.1.3+.

Let’s proceed with the quick 4-step approach to creating your first add-on.

Step 1: Download the Frontview Add-on SDK

You’ll need to first download the Frontview Add-on SDK. The SDK contains the necessary templates for your add-on, including a create script to jump-start your add-on and a build script to package your add-on into a proper binary format that Frontview will recognize.

It is recommended that you create and build your add-on right on your ReadyNAS, but you can do so on any Linux platform as well. If you elect to do so on the ReadyNAS, you’ll need to set up SSH access as well as set up the working environment. Take a look here to do this.

Now click on the image below to download the Add-on SDK. It’s in a tar-gzip format, so you may need to right-click and save.


To extract the files, go to an empty directory and run the following command:

# tar xvzf addon_sdk.tgz

You’ll see the following file listing:

README
LICENSE
CHANGELOG
bin/build_addon
bin/create_addon
bin/xmlutil.nsp
bin/xmlutil.x86
template/language/de/ADDON.str
template/language/en-us/ADDON.str
template/language/fr/ADDON.str
template/language/ja/ADDON.str
template/language/ko/ADDON.str
template/language/zh-cn/ADDON.str
template/language/zh-tw/ADDON.str
template/ADDON.conf
template/ADDON.html
template/ADDON.js
template/ADDON.xml
template/ADDON_AVAILABLE.xml
template/ADDON_CURRENT.xml
template/ADDON_HANDLER.pl
template/ADDON_service
template/install.sh
template/remove.sh
template/running.sh
template/start.sh
template/stop.sh

Step 2: Create a template for your Add-on

You’ve got your add-on SDK environment in place. Now, let’s create a simple add-on using the SDK. The first add-on you will create does nothing but proves that it works, i.e. it can be installed, Frontview displays it, and you can remove it.

From your SDK base directory, run the following command:

# bin/create_addon

This command will ask you a series of questions about your add-on, and creates the necessary template files for you to allow you to build the add-on. If you make a mistake, just run it again. You will need to run this utility just once to create the necessary source files that you will later modify. Keep in mind that if you run it again with the same add-on name, existing source files will be overwritten.

Here’s the console output of create_addon:

Welcome to the Frontview Add-on Wizard

Enter a name for the add-on (please keep it short): Foo Bar

FOOBAR will be used as the tag for the add-on and
will be used as the base name for your add-on files.

Is this okay? (y/n) y

Enter a brief description for “Foo Bar” (no single quotes): This is the best add-on ever created for the ReadyNAS. Everyone will be so thrilled to see what this add-on does.

Description will read:
This is the best add-on ever created for the ReadyNAS. Everyone will be so thrilled to see what this add-on does.

Is this okay (y/n) y

Enter the version of the add-on [1.0]:

Version: 1.0

Is this okay (y/n) y

Enter the download URL of the add-on (i.e. http://www.UPDATEME.com/download/FOOBAR.bin) []: http://www.iamcool.com/download/FOOBAR.bin

Download URL: http://www.iamcool.com/download/FOOBAR.bin

Is this okay (y/n) y

Enter the URL for the XML file describing the currently available add-on (e.g. http://www.UPDATEME.com/download/FOOBAR_CURRENT.xml) []: http://www.iamcool.com/download/FOOBAR_CURRENT.xml

Current URL: http://www.iamcool.com/download/FOOBAR_CURRENT.xml

Is this okay (y/n) y

Enter the URL where more detailed information about the add-on can be found []: http://www.iamcool.com/info/FOOBAR.html

More Detail URL: http://www.iamcool.com/info/FOOBAR.html

Is this okay (y/n) y

Enter the icon URL of the add-on (must be https URL) []: https://www.iamcool.com/images/FOOBAR_ICON.jpg

Icon URL: https://www.iamcool.com/images/FOOBAR_ICON.jpg

Is this okay (y/n) y

Enter the author of the add-on []: Mr. Cool

Author URL: Mr. Cool

Is this okay (y/n) y

Enter the minimum version of RAIDiator firmware required (leave blank if none) []: 4.2.17

Minimum RAIDiator version required: 4.2.17

Is this okay? (y/n) y

Does the ReadyNAS need to be rebooted after the add-on installation? (y/n) [n]:

Reboot required: n

Is this okay? (y/n) y

Does the web server need to be restarted after the add-on installation? (y/n) [n]:

Restart web server after installation: n

Is this okay? (y/n) y

If you would like to make changes to your input, please make them in FOOBAR.xml. A base source code tree has been generated using the information that you provided. You’ll find the following files

FOOBAR/install.sh
FOOBAR/remove.sh
FOOBAR/start.sh
FOOBAR/stop.sh
FOOBAR/running.sh
FOOBAR/FOOBAR.html
FOOBAR/FOOBAR.js
FOOBAR/FOOBAR.xml
FOOBAR/FOOBAR_AVAILABLE.pl
FOOBAR/FOOBAR_CURRENT.pl
FOOBAR/FOOBAR_HANDLER.pl
FOOBAR/FOOBAR.conf
FOOBAR/language/en-us/FOOBAR.str
FOOBAR/language/de/FOOBAR.str
FOOBAR/language/fr/FOOBAR.str
FOOBAR/language/ja/FOOBAR.str
FOOBAR/language/ko/FOOBAR.str
FOOBAR/language/zh-cn/FOOBAR.str
FOOBAR/language/zh-tw/FOOBAR.str

After you make appropriate changes to the files above, you can build your add-on with build_addon. You need to be in the FOOBAR directory and run ../bin/build_addon.

During this process, a tag will be given to your add-on. Basically it’s just a capitalized version of the add-on name with no spaces. In our example above, the tag name for the add-on “Foo Bar” is “FOOBAR”.

Once complete, your add-on source files will be posted in the tag directory.

Step 3: Build your first Add-on

You are now ready to build your add-on source files into a binary. To do this, you’ll need to be in the add-on directory. Run the following commands (based on our “Foo Bar” add-on example above).  Note that you need to be in the add-on directory first.

# cd FOOBAR
# ../bin/build_addon
Successfully built "Foo Bar" add-on package as "FooBar_1.0.bin".

The build_addon command is used each time you want to re-create the add-on image with your changes. The resulting file will be an addon.bin file in your add-on directory. This is the file that Frontview recognizes as an add-on when you upload it from the System → Update → Local tab.

Step 4: Test your Add-on

Now let’s go ahead upload your new add-on from System → Update → Local.


After clicking on Perform System Update, wait until you get the confirmation that the add-on has been installed, and go to the Services → Installed Add-ons tab. You should see your add-on there.

Congratulations, you’ve just created your first Frontview add-on!

Understanding the maintenance scripts

Now that was easy, right? Now, let’s go through each source component of the FOOBAR add-on in detail so that you’ll have an idea on where you need to make modifications to create a real add-on. Let’s first go through the shell scripts.

install.sh

This script performs the necessary upkeep to install the add-on. The script adds two tag variables into /etc/default/services to keep track of whether the add-on is installed and whether it is enabled. For FOOBAR, the following variables are added:

FOOBAR_SUPPORT=1
FOOBAR=1

FOOBAR_SUPPORT tells Frontview that FOOBAR add-on is installed, and FOOBAR=1 tells Frontview that FOOBAR add-on is enabled.

Basically, you can leave most if not all of the install.sh content as-is. Make any changes necessary you may need for your add-on to install correctly (i.e. add a user account, create a database, etc.)

remove.sh

This script removes the add-on and cleans up after itself. You will need to set CONF_FILES to a list of configuration files used by the add-on so that they can be removed. You can also append program files that would need to be removed to PROG_FILES.

If you have modified any system configuration file or created a database, make sure to properly clean up in this script. It is a good practice not to leave behind any trace of the add-on.  The add-on entries added to /etc/default/services via install.sh are automatically removed.

start.sh

This script starts your add-on service. This can be similar to the startup scripts residing in /etc/init.d. Alternatively, you can daemonize the your process by using the start-stop-daemon command, e.g.

start-stop-daemon –start -b -m –pidfile /var/run/FOOBAR.pid –quiet –exec FOOBAR_service

FOOBAR_service is a sample shell script to mimic a real service.  All it does in the template is to sleep for a certain number of seconds.  You can replace the content or rename this service as you please.

stop.sh

Similar to the start.sh script, the stop.sh script stops your add-on service. If you had used start-stop-daemon to start the service, you can do the same command to stop it, e.g.

start-stop-daemon –stop –pidfile /var/run/FOOBAR.pid –signal QUIT –quiet

Make sure to use the same .pid file in your stop.sh script as you did in the start.sh.

running.sh

This script checks to see if the add-on service is running and exits with status 0 if it is, or non-zero if it’s stopped. This script tells Frontview whether a green or a gray status LED is displayed for the add-on.


Typically a check to see if the process is running is all you need to do here. You can set the ADDON_PROCESS variable in the script to your process name, or if you need to do something more, modify the script as required.

Understanding the source files

Now let’s take a look at the rest of the files.

FOOBAR.html

The add-on HTML file contains the UI element that is displayed within the add-on management frame. Notice that only the inner-box is controlled by the HTML file, and not the standard add-on framework controls (i.e. version, checkbox, Remove and Save buttons). The content of this HTML file will need to work closely with the add-on Javascript file (FOOBAR.js) and the Perl (or non-Perl) CGI handler (FOOBAR_HANDLER.pl).


If the HTML file is omitted, the gray bounding box and its contents within the add-on frame will not be displayed.

FOOBAR.js

The add-on Javascript file is automatically included by the Frontview add-on framework and the functions defined within the file is accessible by the add-on HTML file.

FOOBAR.xml

Remember running the create_addon command? create_addon automatically generated FOOBAR.xml based on the information you had entered.

<?xml version="1.0" encoding="UTF-8" ?>
<addon>
  <name>FOOBAR</name>
  <friendly_name>Foo Bar</friendly_name>
  <version>1.0</version>
  <get_url>FOOBAR_HANDLER.pl</get_url>
  <set_url>FOOBAR_HANDLER.pl</set_url>
  <preaction>FOOBAR_preaction</preaction>
  <onloadaction>FOOBAR_onloadaction</onloadaction>
</addon>

The tags recognized within the addon tag are as follows:

name - the tag name of the add-on
friendly_name – the add-on name as entered through create_addon
version - version of the add-on entered through create_addon
get_url – handler that returns the XML data for the HTML page
set_url – handler that performs the form processing for the HTML page
preaction - Javascript function (in FOOBAR.js) to call before HTML page has been loaded
onloadaction - Javascript function (in FOOBAR.js) to call after HTML page has been loaded

language/*/FOOBAR.str

Frontview uses string tags for all its strings, and likewise, so do Frontview add-ons. This is to allow for flexibility in supporting multiple languages. As you can see, when you ran create_addon, it generated the following string map files:

language/en-us/FOOBAR.str
language/de/FOOBAR.str
language/fr/FOOBAR.str
language/ja/FOOBAR.str
language/ko/FOOBAR.str
language/zh-cn/FOOBAR.str
language/zh-tw/FOOBAR.str

The format of the string map table files (e.g. FOOBAR.str) is as follows:

PREFIX_STRINGTAG1::::String1 Text
PREFIX_STRINGTAG2::::String2 Text

Frontview uses the convention of a string tag on the left in all caps, followed by 4 colons, followed by the corresponding text. Tag definitions are separated by new-lines. Tag names follow the Frontview convention of a prefix followed by a tag description.  Prefix is one of PROMPT, LABEL, SUCCESS, and ERROR.

PROMPT - Prompt text used on the left of input fields. Typically these tags will end with a colon.
LABEL - Label text are free-form text used for description, instructions, etc.
SUCCESS - Text used to inform of successful operation.
ERROR - Text used to warn of an error occurring during an operation.

Let’s take a look at the language/en-us/FOOBAR.str file.

LABEL_SERVICE_FOOBAR_INFO::::<b>Foo Bar.</b> This is the best add-on ever created for the ReadyNAS. Everyone will be so thrilled to see what this add-on does.
PROMPT_FOOBAR_RUNTIME_SECS::::Run-time (in secs):

You may notice that all the FOOBAR.str files other than the one in en-us and ja directories are empty.  This is to show you how you can easily support a localized version of your add-on.  By simply changing the browser language setting from English to a supported language, the add-on can appear that language.  Since we have a string definition file for Japanese, changing the browser language to Japanese results in:


You’ll see that the add-on description is still in English, but the prompt is in Japanese.  If you take a look at the language/ja/FOOBAR.str, you’ll see that only the prompt has been translated.

LABEL_SERVICE_FOOBAR_INFO::::<b>Foo Bar.</b> This is the best add-on ever created for the ReadyNAS. Everyone will be so thrilled to see what this add-on does.
PROMPT_FOOBAR_RUNTIME_SECS::::実行時間 (秒):

FOOBAR.conf

This file is used by Apache to allow the execution of the add-on handler. You should not change this file.

FOOBAR_HANDLER.pl

This is the Perl handler that processes the Save and Remove button actions from the add-on. The example handler is provided as guidance on how commands are processed and the resulting XML data returned to the add-on HTML page. How the XML data passing is handled is unfortunately beyond the scope of this article, but you can refer to this and other add-on Perl handlers to grasp how this is done.

Keep in mind that the add-on handler does not have to be written in Perl. You can just as well write this in C if you wish. You just need to specify the handler in the add-on XML file (see below). We recommend you use Perl as the front-end to a C binary if you wish to use C, as library calls to remove, enable, and disable the add-on are available only for Perl currently.

Let’s follow the source code.

First the following files are needed to include the necessary defines and common add-on funtions.

do "/frontview/lib/cgi-lib.pl";
do "/frontview/lib/addon.pl";

Read in the %in hash containing all input form variables passed from the HTML submit command.

# initialize the %in hash
%in = ();
ReadParse();

Get the request info. $operation is either get or set. $command contains one of 3 possible values — RemoveAddOn, ToggleService, or ModifyAddOnService. We’ll explain these commands shortly.

my $operation = $in{OPERATION};
my $command = $in{command};
my $enabled = $in{"CHECKBOX_FOOBAR_ENABLED"};

Read in the language string files for this add-on.  This gets the browser language setting and pulls in the right string map file.

get_default_language_strings("FOOBAR");

Initialize the XML payload with the header. We’ll append to this payload variable later.

my $xml_payload = "Content-type: text/xml; ...?>";

If the operation is a get, Show_FOOBAR_xml() returns the XML payload for the add-on container.  Basically this passes the add-on configuration so it can be displayed when the add-on page loads.

if( $operation eq "get" )
{
  $xml_payload .= Show_FOOBAR_xml();
}

If the operation is a set, each of the possible set commands are processed. The Remove_Service_xml and Toggle_Service_xml are pre-defined calls that will remove the add-on and toggle whether the add-on is enabled or not. The Modify_FOOBAR_xml call is defined in this file to process input form changes, and can be changed to fit your need.

elsif( $operation eq "set" )
{
  if( $command eq "RemoveAddOn" )
  {
    # Remove_Service_xml() removes this add-on
    $xml_payload .= Remove_Service_xml("FOOBAR");
  }

  elsif( $command eq "ToggleService" )
  {
    # Toggle_Service_xml() toggles the enabled state of the add-on
    $xml_payload .= Toggle_Service_xml("FOOBAR", $enabled);
  }
  elsif( $command eq "ModifyAddOnService" )
  {
    # Modify_FOOBAR_xml() processes the input form changes
    $xml_payload .= Modify_FOOBAR_xml();
  }
}

If you need to execute shell commands with root priviledge, you will need to use the spool_file() and empty_spool() functions.  An example of this is as follows:

$SPOOL .= "
df -h > /tmp/df.out
";

spool_file("${ORDER_SERVICE}_FOOBAR", $SPOOL);
empty_spool();

The above code will spool the shell commands in $SPOOL in a file /var/spool/frontview/60_FOOBAR (${ORDER_SERVICE} is 60).  When empty_spool() is called, the file will get executed as root.  Use the spool system with care as anything run by root can potentially result in data loss.

If you have any question with this SDK, please post on the ReadyNAS Developer Network forum.

1 Star2 Stars3 Stars4 Stars5 Stars (25 votes, average: 4.84 out of 5)
Loading ... Loading ...

Comments are closed.