UnMENU documentation

From Unraid | Docs
Jump to: navigation, search
This page is under construction... Please be patient, or, help where you can by adding text.

unMENU User Documentation

Built-in web-pages


A new and improved unRAID web-interface now exists. It does not replace the existing web-management console, but supplements it. It is accessible on an entirely different port on your server (typically port 8080) It is named "unmenu.awk"

The original purpose of unmenu.awk was to explore ways to improve the unmenu web-interface with a rapid development tool helping to spark ideas rather than just having a discussion in a thread. Many people, like myself, can visualize easier when presented with a starting point. Because it is written in a language easy to understand, and you do not need to be an expert to contribute, many have helped in its development... as such, there will be continued discussion...

As unmenu.awk evolved, it became clear it was more than a prototyping tool. It was a fully functional addition to the unRAID server.

The home page of the unmenu.awk web interface for unRAID servers looks like the illustration below. The set of "links" in the top left portion of the screen is automatically defined based on the plug-in files found when the unmenu.awk interface is started. Most of the functions in the list are plug-ins. A small handful are built into the unmenu.awk program. (Main, Array-Management, Disk-Management, About, and Help) Also built in is a simple "syslog" viewer. (but not used, as an external plug-in has the same "url" and overrides the built-in function.)

You must stop the unmenu.awk program and restart it for it to see a new plug-in and add it to its menu. You do not need to stop and re-start it when making changes to a plug-in when initially developing it, as they are interpreted when the page is invoked.

After installing it, and starting it, to invoke you would type this URL in your browser. //tower:8080

The new and improved interface has many of the same features as the stock management page, and a lot of new features.

  • The set of links presented at the very top is dynamically defined by the installed plug-ins and will automatically appear on all pages in the improved interface except those that supply the HTTP header and the entire content of the page (configurable per plug-in). At this time, the file-browser plug-in is the only plug-in that supplies its own HTTP header and top of page menu.
  • Next at the top of the new improved interface is the array status. It will show if the array is on-line, stopped, calculating parity, etc. As long as the array is in a STARTED status, the main page auto-refreshes every 60 seconds. (configurable locally if you prefer a different refresh rate) The status will appear in RED if anything unusual is occurring.
  • The next section the front page shows both the disks in the protected array, and then any that are connected, but not part of the protected array.

The protected disks area of the screen shows the physical disk, where it is mounted, and its status, model number, read/write statistics and space used on the disk.

  • Next you can see the space used and free on the USB flash drive.
  • An improvement over the stock main page is the color coding of disk temperature reading when they reach various warning thresholds.
    • As delivered, the disk temperature will show highlighted in YELLOW when over 40°C, in ORANGE when over 45°C, and in RED when over 50°C. The specific thresholds are configurable locally on your server.
  • On those disks with file systems that are mounted, you can see the total size, space used, percentage used, and the amount of free space.
  • There is also a line on the page showing the total disk space, total used, total percentage used, and free space. By default, it uses the "marketing" divisor of 1000 when displaying disk sizes. You can locally configure unmenu.awk to divide by 1024 if you like the computer science definition of Megabytes, Gigabytes, and Terrabytes.
  • For those disks that are not in the protected array you can see the individual disk partitions, their file-system types, and if mounted, their free space. (The disk-management page on the improved interface will let you mount, un-mount, share, and un-share unprotected disks, even if they are from your PC and do not have a reiserfs file-system.) The unprotected disks will not be part of the "user-shares" merge of disks, but you will be able to browse them, read, and (if you enable it in your local configuration file) write to them. This feature in the improved interface is there to allow you to easily migrate and access your old data.
  • The lower portion of the main page is also configurable. As delivered, it shows the last 6 lines of the "syslog" and color codes some of the lines that are interesting in some way. If a disk were to start having errors, odds are you might see some message here before the array takes it offline.
  • Any single web-page may be shown at the bottom most section of the "main" page. A sample is included in the supplied configuration file to show a list of open files instead of the syslog tail (only usable if you add the lsof package)

Array Management

Disk Management

System Log Viewer


The "About" page looks like this. If you have not defined an ADD_ON_VERSION in each of the plug-in modules, it assigns version 0.1. http://i36.tinypic.com/2d9uv0g.jpg


web-pages defined by plug-ins

System Log Viewer

Useful Links

Disk Usage

Dupe Files

System Info

File Browser

The file-browser plug-in allows you to traverse your "user" and "disk" shares, and even to click on and open small and moderate sized files. (I do not allow you to open files over 10 Meg in size, but you can change that to a larger size if you have a lot of RAM and do not care if it takes a long time to get your file. (awk is nowhere near as efficient at this as a dedicated server)

The file size limitation is because the file needs to be completely read into memory and then copied from one process to another as it sends it onward to the browser. In other words, it probably needs near 30 Meg of memory for itself when serving such a large file. You would not want to run out of RAM by serving an ISO image. (Can't fit 10 Gig of data into 512 Meg of RAM, even if you wanted to.) If you attempt to click on a file larger than allowed, the file-browser just gives you a warning: Sorry: too big to open via unmenu awk based web-server.

The file-browser plug-in does allow you to click on text files, pictures, mp3 files (under 10 Meg in size). If it knows the file type, it will send it to the browser. If it does not, it will upload it to the browser for your "PC" to deal with. I am very happy to have gotten this to work... it is really tough dealing with binary files in awk. At this time, it is the only plug-in to supply its own HTTP header, as the content type must be set based on the type of file clicked when browsing. In the same way, it is the only plug-in that constructs its own top menu.

The file-browser has no ability to change the files on the server, nor any to delete the files.

It has NO security other than being restricted to a set of starting folders. By default, these are /mnt/user and /mnt/disk1,2,3.... You can edit the unmenu configuration to change this easily. You can limit it to specific folders and completely exclude others, or you can add a "top" level folder of "/" and browse anywhere.

The file-browser plug-in does not look at how you have partitioned user-shares by login id. It can browse anywhere. The exact same way you can browse when logged in using "telnet" and "ls"

It looks a bit like this when browsing: http://i35.tinypic.com/29dbbth.jpg

Network Status

User Scripts

We've got a great "User scripts" plug-in that is based on a suggestion from bubbaQ. It allows you to group all the quick little admin scripts on buttons on a single page and get rid of some of the clutter in the main menu. The button names are grabbed from the script file. The scripts themselves are in a configurable directory, but by default it is the same directory as the the other unmenu awk and cgi scripts.

Give the "User-Scripts" plug-in a try. It might work well, for example, for the "commands" you created to start and stop vmware. Now, you can create buttons.

The scripts themselves are matched and made into buttons if they have a name matching "[0-9]*unmenu_user_script*" and are executable.

They are executed when the button is pressed, so you now can have "Start VmWare" and "Stop VmWare" buttons.

Here are two sample 'User Scripts'

root@Tower:/boot# cat 10-unmenu_user_script_hello

#define USER_SCRIPT_LABEL Hello World
#define USER_SCRIPT_DESCR Print a famous greeting.
echo "Hello World"

root@Tower:/boot# cat 20-unmenu_user_script_goodbye

#define USER_SCRIPT_LABEL Goodbye World
#define USER_SCRIPT_DESCR Print a variation of a famous greeting
#define USER_SCRIPT_DESCR written by one of the authors of "C" language.
echo "Goodbye World"

Note: you can have multiple USER_SCRIPT_DESCR lines. The lines are concatenated. They can contain HTML, but do not need to have any.

It looks like this when you select the "User Scripts" menu choice... presenting whatever "buttons" you have defined along with their affiliated descriptions. http://i33.tinypic.com/xkzt6t.jpg

This is the first "cgi" shell script that has buttons and processes the querrystring parameter passed from the browser as $3.

A user defined button for the "User-Scripts" plug-in can be as simple as this 4 line example used to run disk speed tests on all the disks on your server:

#define USER_SCRIPT_LABEL Disk Speed Test
#define USER_SCRIPT_DESCR Run disk transfer speed tests (using hdparm -tT)
echo "<pre>"
hdparm -tT /dev/[hs]d?

Thanks to bubbaQ for the suggestion for this great plug-in

Package Manager

You can use the "Package-Manager" plug-in to download and install "package extensions" A sample set of package configuration files is included. The package configuration file will automatically be MOVED to the /boot/packages folder when the package-manager plug-in is invoked.

Once a package is downloaded through the plug-in, it may be installed manually by simply pressing a single button on the web-interface. After installation (and you test it works) you are presented a button to configure an "auto-re-install-on-reboot" for that package. If you press that button, your "go" script will have a line appended to it automatically ... or, if you already have the /boot/custom/etc/rc.d structure in place, a file will be put there instead of a line added to the go script. Only one line is ever appended to the "go" script. It will auto-install all of the packages designated by you.

If you only want to manually install, don't enable the "auto-install-on-reboot" feature on a package. If you do enable it for a given package, the web-interface will then present a button to disable the auto-install-on-reboot for that package. Pressing it will remove that package from being auto-installed in the future by removing the "packagename.auto_install" file. (no harm done)

The auto-install feature creates a "packagename.auto_install" script in the /boot/packages folder. Those scripts contain the commands needed for auto-installation and are run in turn on re-boot. In the same way, the "manual-install" button creates a "packagename.manual_install" script. It can be invoked to reinstall a package, or viewed to see what occurs when a package is installed. If the /boot/packages folder does not exist, it will be created. Most everything can be locally configured in unmenu_local.conf by copying it from the equivalent lines from unmenu.conf.

downloadable packages are defined in *-unmenu*package*.conf files. Although given file can contain multiple package definitions, we've already learned it is best to put only one package definition in a file.

A sample package configuration file (included in the distributed zip file) looks like this:

PACKAGE_NAME List Open Files
PACKAGE_DESCR The lsof command is used to list open files on a file system. This is important to know if you are
PACKAGE_DESCR attempting to shut down your server.  If a file-system has open files, it may not be un-mounted.  If it
PACKAGE_DESCR cannot be un-mounted, the unRAID array cannot be shut down cleanly.
PACKAGE_URL http://slackware.mirrors.pair.com/slackware-current/slackware/ap/lsof-4.78-i486-1.tgz
PACKAGE_FILE lsof-4.78-i486-1.tgz
PACKAGE_MD5 e5f72c903462cf170a3fdaa9e01af1ff
PACKAGE_INSTALLATION installpkg lsof-4.78-i486-1.tgz
PACKAGE_VERSION_TEST lsof -v 2>&1 | grep revision | awk '{print $2}'

A far more complicated package configuration file is shown here. It has multiple files to download and several user configurable input fields.

#UNMENU_RELEASE $Revision: 146 $ $Date: 2010-08-17 23:44:04 -0400 (Tue, 17 Aug 2010) $
PACKAGE_DESCR Video Streaming
Air Video can stream videos in almost any format to your iPhone and iPod touch. PACKAGE_DESCR You don't need to copy your videos to the device just to watch them. Live Conversion. If the PACKAGE_DESCR videos in your collection are not in format supported by iPhone, Air Video will convert them on fly*. You PACKAGE_DESCR don't need to wait until the entire video is converted. You can start watching it almost immediately! PACKAGE_DESCR * Live Conversion requires iPhone or iPod touch with firmware 3.0 and a sufficiently powerful computer PACKAGE_DESCR (Intel Core 2 duo or equivalent processor is recommended). PACKAGE_DESCR
If you have less than 1Gig of RAM you'll probably need to stop all other add-ons before you can install PACKAGE_DESCR this one as the installation involves compiling "ffmpeg" and that takes a lot of RAM. On my older server with only 512Meg of RAM I also needed to PACKAGE_DESCR "Stop" the unRAID array. This frees up the memory used by the user-shares. This also prevents the need for PACKAGE_DESCR a full parity check in case you do run out of memory and the need to reboot the server to restore normal operation.
PACKAGE_DESCR You'll need to install the 'gcc' compile package before this one, and if on an older release of unRAID, the pbzip2 package too. # the airvideo server .jar file PACKAGE_URL http://inmethod.com/air-video/download/linux/alpha3/AirVideoServerLinux.jar PACKAGE_FILE AirVideoServerLinux.jar PACKAGE_MD5 e04e16d8ce3a24dc5d35d0a3c3cc295a # the faac file PACKAGE_EXTRA_URL http://slackpack.ludost.net/packages/12.1/faac-1.26-i486-1gds.tgz PACKAGE_EXTRA_FILE faac-1.26-i486-1gds.tgz PACKAGE_EXTRA_MD5 b2076c450fffca386a213144b6fcdb0c # the faad2 file PACKAGE_EXTRA_URL http://slackpack.ludost.net/packages/12.1/faad2-2.6.1-i486-2gds.tgz PACKAGE_EXTRA_FILE faad2-2.6.1-i486-2gds.tgz PACKAGE_EXTRA_MD5 303562055b4c8d67cb24cf751acdf04b # the git-core file PACKAGE_EXTRA_URL http://lp.slackwaresupport.com/Slackware-10.1/Console/git-core/git-core-0.99.6-i486-1mik.tgz PACKAGE_EXTRA_FILE git-core-0.99.6-i486-1mik.tgz PACKAGE_EXTRA_MD5 f88e1beee14cbd3b5c475a1dff8935b2 # the lame file PACKAGE_EXTRA_URL http://slackpack.ludost.net/packages/12.1/lame-3.98.2-i486-1gds.tgz PACKAGE_EXTRA_FILE lame-3.98.2-i486-1gds.tgz PACKAGE_EXTRA_MD5 55deced6c5ecd9836b3bebf49f8579e4 # the mpeg file PACKAGE_EXTRA_URL http://lp.slackwaresupport.com/Slackware-11.0/X11/mpeg4ip/mpeg4ip- PACKAGE_EXTRA_FILE mpeg4ip- PACKAGE_EXTRA_MD5 2b50c235deb0236e59e5d7200acf0cea # the xvidcore file PACKAGE_EXTRA_URL http://repository.slacky.eu/slackware-12.1/multimedia/xvidcore/1.2.1/xvidcore-1.2.1-i486-1sl.tgz PACKAGE_EXTRA_FILE xvidcore-1.2.1-i486-1sl.tgz PACKAGE_EXTRA_MD5 3ea278d2ced5dd0afabd54a62bf0e043 # the yasm file PACKAGE_EXTRA_URL http://repository.slacky.eu/slackware-12.1/development/yasm/0.7.2/yasm-0.7.2-i486-1sl.tgz PACKAGE_EXTRA_FILE yasm-0.7.2-i486-1sl.tgz PACKAGE_EXTRA_MD5 df5df2bf568bb05990c1f0daa7e804eb # the jam file PACKAGE_EXTRA_URL http://repository.slacky.eu/slackware-12.1/development/jam/2.5/jam-2.5-i486-2gal.tgz PACKAGE_EXTRA_FILE jam-2.5-i486-2gal.tgz PACKAGE_EXTRA_MD5 096ad8c4f82e40f35bb7e000749d7175 # the x264 file PACKAGE_EXTRA_URL http://connie.slackware.com/~alien/slackbuilds/x264/pkg/13.0/x264-20100425-i486-1alien.tgz PACKAGE_EXTRA_FILE x264-20100425-i486-1alien.tgz PACKAGE_EXTRA_MD5 9868016da0904cbccbdd76cc86146d4c # the libX11 file PACKAGE_EXTRA_URL http://slackware.oregonstate.edu/slackware-12.2/slackware/x/libX11-1.1.5-i486-1.tgz PACKAGE_EXTRA_FILE libX11-1.1.5-i486-1.tgz PACKAGE_EXTRA_MD5 ffddc89e6711aa6a91ac0c4855af7789 # the libXcb file PACKAGE_EXTRA_URL http://linuxpackages.cs.utah.edu//Slackware-11.0/X11/libxcb/libxcb-1.0-i486-1ced.tgz PACKAGE_EXTRA_FILE libxcb-1.0-i486-1ced.tgz PACKAGE_EXTRA_MD5 1a7be0f71dc1cd0939e986a580b56d76 # the libXau file PACKAGE_EXTRA_URL http://slackware.oregonstate.edu/slackware-12.2/slackware/x/libXau-1.0.4-i486-1.tgz PACKAGE_EXTRA_FILE libXau-1.0.4-i486-1.tgz PACKAGE_EXTRA_MD5 8f978d7e6dd297e7f26dc0e123eaced4 # the ffmpeg for airvideo PACKAGE_EXTRA_URL http://www.inmethod.com/air-video/download/ffmpeg-for-2.2.5.tar.bz2 PACKAGE_EXTRA_FILE ffmpeg-for-2.2.5.tar.bz2 PACKAGE_EXTRA_MD5 1623d51b433555e08d0c2fcf1dee1b55 # the Java run-time environment PACKAGE_EXTRA_URL http://slackware.cs.utah.edu/pub/slackware/slackware-12.2/slackware/l/jre-6u11-i586-1.tgz PACKAGE_EXTRA_FILE jre-6u11-i586-1.tgz PACKAGE_EXTRA_MD5 ec548608da146865a8a86dbdc209c587 PACKAGE_INSTALLED /var/log/airvideo PACKAGE_DEPENDENCIES This package relies on quite a few different packages. Most are installed along with this one but PACKAGE_DEPENDENCIES there are a few that need to be installed prior to this package. The "gcc" compiler package that is PACKAGE_DEPENDENCIES included with unmenu must be installed first in order to compile ffmpeg. PACKAGE_VARIABLE password||vPassword=12345||Enter the password used to connect to the Airvideo Server PACKAGE_VARIABLE folders||vFolders=Anime:/mnt/user/Anime,Movies:/mnt/user/Movies||Enter the list of folders you would like to be visible. Note the format of the line and make sure to replicate it exactly for your sources PACKAGE_VARIABLE Temp Directory||vTMPDIR=/boot/packages/compile_temp_dir||This directory location will be used by the compiler for temporary files. If you have over 1Gig of RAM you can probably use /var/tmp. If you have less memory, use /boot/packages/compile_temp_dir PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/faac-1.26-i486-1gds.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/faad2-2.6.1-i486-2gds.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/lame-3.98.2-i486-1gds.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/x264-20100425-i486-1alien.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/xvidcore-1.2.1-i486-1sl.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/git-core-0.99.6-i486-1mik.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/jam-2.5-i486-2gal.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/mpeg4ip- PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/yasm-0.7.2-i486-1sl.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/libX11-1.1.5-i486-1.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/libxcb-1.0-i486-1ced.tgz PACKAGE_INSTALLATION installpkg "${PACKAGE_DIRECTORY}"/libXau-1.0.4-i486-1.tgz # compile ffmpeg first. that way we have as much RAM as possible for it to succeed. PACKAGE_INSTALLATION if [ ! -x "${PACKAGE_DIRECTORY}/ffmpeg/ffmpeg" ]; then PACKAGE_INSTALLATION test ! -f /usr/bin/cc && echo "The 'gcc' C compiler has not been installed. ffmpeg compile not possible" PACKAGE_INSTALLATION test ! -f /usr/bin/cc && exit PACKAGE_INSTALLATION MEM="$(free -m | grep Mem: | awk '{print $2}')" PACKAGE_INSTALLATION ulimit -v 250000 PACKAGE_INSTALLATION if [ "${MEM}" -lt 768 ]; then PACKAGE_INSTALLATION echo "Warning: You may not have enough memory ( $MEM ) to compile ffmpeg, but we'll try and see how far we can get." PACKAGE_INSTALLATION fi PACKAGE_INSTALLATION sync PACKAGE_INSTALLATION echo 3 > /proc/sys/vm/drop_caches PACKAGE_INSTALLATION CACHE_PRESSURE=`sysctl vm.vfs_cache_pressure| awk '{print $3}'` PACKAGE_INSTALLATION sysctl -w vm.vfs_cache_pressure=200 PACKAGE_INSTALLATION if [ ! -d "${PACKAGE_DIRECTORY}/ffmpeg" ]; then PACKAGE_INSTALLATION if [ ! -f /usr/bin/bzip2 ]; then PACKAGE_INSTALLATION if [ ! -f /usr/bin/pbzip2 ]; then PACKAGE_INSTALLATION echo "An bzip2 program was not detected. Please install either the pbzip2 package or bzip2." PACKAGE_INSTALLATION exit PACKAGE_INSTALLATION fi PACKAGE_INSTALLATION fi PACKAGE_INSTALLATION cd "${PACKAGE_DIRECTORY}"; PACKAGE_INSTALLATION if [ -f /usr/bin/bzip2 ]; then PACKAGE_INSTALLATION tar --no-same-owner -xf ffmpeg-for-2.2.5.tar.bz2; PACKAGE_INSTALLATION else PACKAGE_INSTALLATION tar --use-compress-prog=pbzip2 --no-same-owner -xf ffmpeg-for-2.2.5.tar.bz2; PACKAGE_INSTALLATION fi PACKAGE_INSTALLATION fi PACKAGE_INSTALLATION # in an attempt to keep from using all RAM in a serrver with minimal resources, use a temporary directory PACKAGE_INSTALLATION # not located in memory for intermediate compile files. PACKAGE_INSTALLATION mkdir -p "${vTMPDIR-/var/tmp}" PACKAGE_INSTALLATION TMPDIR="${vTMPDIR-/var/tmp}"; export TMPDIR PACKAGE_INSTALLATION echo TMPDIR set to $TMPDIR PACKAGE_INSTALLATION cd "${PACKAGE_DIRECTORY}/ffmpeg"; PACKAGE_INSTALLATION ./configure.orig.fixed --enable-gpl --enable-nonfree --enable-postproc --enable-pthreads \ PACKAGE_INSTALLATION --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libx264 \ PACKAGE_INSTALLATION --enable-libxvid --enable-x11grab --disable-shared --enable-static \ PACKAGE_INSTALLATION --disable-decoder=aac; PACKAGE_INSTALLATION make PACKAGE_INSTALLATION test ! -f "${PACKAGE_DIRECTORY}/ffmpeg/ffmpeg" && echo "ffmpeg compile failed. install aborted" PACKAGE_INSTALLATION test ! -f "${PACKAGE_DIRECTORY}/ffmpeg/ffmpeg" && exit PACKAGE_INSTALLATION cd "${PACKAGE_DIRECTORY}"; PACKAGE_INSTALLATION sysctl -w vm.vfs_cache_pressure=$CACHE_PRESSURE PACKAGE_INSTALLATION fi # If Java Run-Time is not already installed, install it. PACKAGE_INSTALLATION test ! -f /usr/lib/java/bin/java && installpkg "${PACKAGE_DIRECTORY}"/jre-6u11-i586-1.tgz #install /etc/rc.d/unraid.d/rc.unraid_airvideo to allow clean start and stop of service PACKAGE_INSTALLATION [ ! -d /etc/rc.d/unraid.d ] && mkdir /etc/rc.d/unraid.d PACKAGE_INSTALLATION echo 'case $1 in' >/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo 'start)' >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo "cd ${PACKAGE_DIRECTORY}" >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo "echo \"air-video-server.sh test.properties &\" | at now + 1 minute" >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo ";;" >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo 'stop)' >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo "av_pid=\$(ps -ef | grep AirVideo | grep -v grep | awk '{print\$2}');" >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo "test \"\$av_pid\" != \"\" && kill -0 \$av_pid && kill \$av_pid" >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo ";;" >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION echo "esac" >>/etc/rc.d/unraid.d/rc.unraid_airvideo PACKAGE_INSTALLATION chmod +x /etc/rc.d/unraid.d/rc.unraid_airvideo #create the button to start airvideo PACKAGE_INSTALLATION echo "#UNMENU_RELEASE \$Revision: 75 \$ \$Date: 2010-04-25 22:20:22 -0400 (Sun, 25 Apr 2010) \$" > "${SCRIPT_DIRECTORY}/41- unmenu_user_script_start_airvideo" PACKAGE_INSTALLATION echo "#define USER_SCRIPT_LABEL Start AirVideo" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_start_airvideo" PACKAGE_INSTALLATION echo "#define USER_SCRIPT_DESCR This will start the AirVideo service so you can stream and live convert files" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_start_airvideo" PACKAGE_INSTALLATION echo "#define USER_SCRIPT_TEST test -e /boot/packages/AirVideoServerLinux.jar && echo \"Start AirVideo\"" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_start_airvideo" PACKAGE_INSTALLATION echo "echo \"< pre >\"" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_start_airvideo" PACKAGE_INSTALLATION echo "set -xv" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_start_airvideo" PACKAGE_INSTALLATION echo "cd ${PACKAGE_DIRECTORY}" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_start_airvideo" PACKAGE_INSTALLATION echo "echo \"air-video-server.sh test.properties &\" | at now + 1 minute" >> "${SCRIPT_DIRECTORY}/41unmenu_user_script_start_airvideo" PACKAGE_INSTALLATION echo >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_stop_airvideo" #create the button to stop airvideo PACKAGE_INSTALLATION echo "#UNMENU_RELEASE \$Revision: 75 \$ \$Date: 2010-04-25 22:20:22 -0400 (Sun, 25 Apr 2010) \$" > "${SCRIPT_DIRECTORY}/41unmenu_user_script_stop_airvideo" PACKAGE_INSTALLATION echo "#define USER_SCRIPT_LABEL Stop AirVideo" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_stop_airvideo" PACKAGE_INSTALLATION echo "#define USER_SCRIPT_DESCR This will stop the AirVideo service from running so that the array can be stopped cleanly" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_stop_airvideo" PACKAGE_INSTALLATION echo "#define USER_SCRIPT_TEST test -x /boot/packages/AirVideoServerLinux.jar && echo \"Stop AirVideo\"" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_stop_airvideo" PACKAGE_INSTALLATION echo "echo \"< pre >\"" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_stop_airvideo" PACKAGE_INSTALLATION echo "set -xv" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_stop_airvideo" PACKAGE_INSTALLATION echo "av_pid=\$(ps -ef | grep AirVideo | grep -v grep | awk '{print\$2}');" >> "${SCRIPT_DIRECTORY}/41 unmenu_user_script_stop_airvideo" PACKAGE_INSTALLATION echo "test \"\$av_pid\" != \"\" && kill -0 \$av_pid && kill \$av_pid" >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_stop_airvideo" PACKAGE_INSTALLATION echo >> "${SCRIPT_DIRECTORY}/41-unmenu_user_script_stop_airvideo" #create test.properties file PACKAGE_INSTALLATION rm -f "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION touch "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION echo "path.ffmpeg = "${PACKAGE_DIRECTORY}"/ffmpeg/ffmpeg" >> "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION echo "path.mp4creator = /usr/bin/mp4creator" >> "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION echo "path.faac = /usr/bin/faac" >> "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION echo "password = passwordPlaceHolder" >> "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION echo "subtitles.encoding = windows-1250" >> "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION echo "subtitles.font = Verdana" >> "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION echo "folders = folderPlaceHolder" >> "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION sed -i s@passwordPlaceHolder@"${vPassword}"@ "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION sed -i s@folderPlaceHolder@"${vFolders}"@ "${PACKAGE_DIRECTORY}"/test.properties PACKAGE_INSTALLATION rm -rf "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION touch "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "#!/bin/bash" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "PROPFILE='/etc/conf.d/air-video-server'" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "LOCALPROP=\`echo ~/.air-video-server/air-video-server.properties\`" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "if [ -a \"\$1\" ]; then" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo " PROPFILE=\"\$1\"" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "else" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo " [ -a \"\$LOCALPROP\" ] && PROPFILE=\"\$LOCALPROP\"" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "fi" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "exec /usr/lib/jre1.6.0_11/bin/java -jar "${PACKAGE_DIRECTORY}"/AirVideoServerLinux.jar \"\$PROPFILE\"" >> "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION chmod +x "${PACKAGE_DIRECTORY}"/air-video-server.sh PACKAGE_INSTALLATION echo "Version: 2.2.5" > /var/log/airvideo PACKAGE_INSTALLATION cd "${PACKAGE_DIRECTORY}" PACKAGE_INSTALLATION echo "bash air-video-server.sh test.properties" | at now + 1 minute PACKAGE_VERSION_TEST grep "Version:" /var/log/airvideo | awk '{print $2}' PACKAGE_VERSION_STRING 2.2.5 PACKAGE_MEMORY_USAGE Heavy

The package manager plug-in page in the unmenu.awk interface looks like this: http://i37.tinypic.com/15335w1.jpg

unRAID Main

unRAID Main is a really neat plug-in that provides the ability to view and use the stock unRAID management pages in an unmenu plug-in.

All the normal functions in the standard unRAID management screens are available (It is just in an inline frame), but with the additional unmenu.awk links at the top. (One known issue: The "Refresh" button on the supplied management page when viewed as an unMENU page does not refresh the screen when using Firefox as your browser. Use the Browser's refresh button instead. This is not a bug in unMENU, but a side-effect of how Firefox deals in an inline-frame with the specific code Lime-technology used for the refresh button.)

It looks like this: http://i37.tinypic.com/23w1t9t.jpg

unMENU Technical Documentation


Many of the features and functions in the unmenu.awk program are configurable. This is done using two files: unmenu.conf and unmenu_local.conf

These two files hold the configuration values... unmenu.conf will be distributed and will have new values added over time and subsequent releases. Although you can edit it to change a value you are much better off making a copy of the file named unmenu_local.conf. Then edit unmenu_local.conf to change the variable and it will be used instead of the one in unmenu.conf.

The unmenu.conf file currently has definitions for:

   * the "port" used by the web-server
   * the "name" used to reference the web-server
   * color coded warning indications for disk temperatures
   * The refresh-interval for the main page.  (It Automatically refreshes every 60 seconds when the array is STARTED)
   * mount options for disks not in the protected array.  (defined as read-only, but you could mount a drive as read-write if desired)
   * links for display on the "links" plug-in.
   * A definition of what to put in the bottom portion of the main screen (currently, a color-coded syslog viewer showing the last 6 lines)
   * A method to restrict the file-browser plug-in to specific folders

unmenu plug-ins

The unmenu.awk interface automatically includes menu links for plug-in files. These plug-in files can be written in either "awk" or as a "shell script"

A plug-in is a file named ZZ-unmenu-whatever_you_like.awk or ZZ-unmenu-whatever_you_like.cgi where ZZ is a one, two, or three digit number.

The number indicates where in sequence it will be added to the top menu. (the menu choices are in lexical order, as shown by an "ls" command on the folder holding the plug-in files. With that in mind, files starting with 1, 10, and 100 will be in the menu before 2, 3, 4... because of the leading "1") If you wish a specific order, use leading zeros. 001, 002, 003 ... etc.

  • The first few entries in the top menu in the improved interface are always "Main", "Array Mgmt", "Disk Mgmt", "Syslog"
  • These are followed by the plug-in links,
  • These are followed by two links that are always "About", and "Help"

The valid "defines" you can put at the top of a plug-in are:

ADD_ON_MENU The label to be shown on the top menu. If no label is given, the URL can still be accessed, but will not have an entry in the set of top of screen links.

#define ADD_ON_MENU = xxxxxxxx

ADD_ON_URL The "URL" affiliated with a "plug-in" If the URL is the same as a built-in, it will display instead of the built-in when the top menu link is clicked. Currently, the "system_log" URL is defined in a plug-in that color codes specific lines. It overrides the built-in syslog viewer that does not do color coding.

#define ADD_ON_URL = xxxxxxxxx

ADD_ON_STATUS If set to "NO", no top of screen status box is shown


ADD_ON_TYPE If set to anything other than "awk" the script is invoked as an execuitable command.

#define ADD_ON_TYPE = awk

ADD_ON_HTML_TAGS expect YES or NO...

  • YES = include <HTML><HEAD><TITLE></TITLE></HEAD><BODY> ... </BODY></HTML>
  • NO = let plug in supply, default if ADD_ON_HTML_TAGS not specified = YES


  • YES = include top of page heading with menu links,
  • NO = do not show heading, default if ADD_ON_PAGE_HEADING not specified = YES

ADD_ON_VERSION A string describing the "version" of the plug-in to be shown on the "About" page, if not defined, version 0.1 will be assigned in the "About" page.

#define ADD_ON_VERSION = 1.0

ADD_ON_HTTP_HEADER This define is used when the plug-in will supply the entire HTTP header... It is used when the document type returned will not be the normal html/text. Specifically, the File-Browser plug-in sets this to NO, as it has to be able to serve various object types. When set to NO, the plug-in must supply the entire content fed to the browser, including any and all HTTP header lines. If this is not speficied, the default is YES, and HTTP headers will be supplied by unmenu.awk.


ADD_ON_HEAD This define may be repeated multiple times.. Each line is added to the <HEAD> section of the HTML output to the browser.

#define ADD_ON_HEAD = <STYLE type="text/css">
#define ADD_ON_HEAD =   td.t {
#define ADD_ON_HEAD =   border-top: 1px solid black;
#define ADD_ON_HEAD =  }
#define ADD_ON_HEAD = </STYLE>

awk plug-ins

the simplest "awk" plug-in would have the following 6 lines as contents:

#define ADD_ON_MENU=Hello World
#define ADD_ON_URL=hello_1
#define ADD_ON_TYPE=awk
print "Hello World"

cgi plug-ins

the simplest "shell" plug-in would have the following 3 lines as contents:

#define ADD_ON_MENU=Hello World
#define ADD_ON_URL=hello_2
echo "Hello World"

To illustrate how easy this can be... I added these three lines to a file named 40-unmenu-uptime.cgi and put that file in the same folder as unmenu.awk.

#define ADD_ON_MENU=Uptime
#define ADD_ON_URL=uptime

I stopped and re-started my unmenu.awk process, and here is the result. A new "Uptime" menu choice, and a new piece of information available via the web interface. http://i36.tinypic.com/vqqxck.jpg

If multi-line output was present, I would have had to either add HTML formatting, or simply echo "<pre>" before the entire output. <pre>, in HTML, indicates the following output is preformatted and should be shown as is.

Here is an example of a multi-line Process List plug-in (all 4 lines of it) I named it 41-unmenu-process_list.cgi :

#ADD_ON_MENU=Process List
echo "<pre>"
ps -ef

It looks like this now when invoked: http://i37.tinypic.com/2q8xago.jpg

In the process list (near the bottom, process 2580) you can see that when the shell invokes the "cgi" plug-in, $1 is the current array state, $2 is always "GET", $3 is the URL. This ($3) will have the querystring parameters from form fields as well. You would need to parse them from $3 as needed. I'm currently using $4 to pass a concatenated set of URL/Menu Label pairs, so it would be easy to add a full top menu to any plug-in, even those that do the full HTTP headers themselves. (that was not yet being passed as a parameter when I did this screen-shot) The "File-Browser" plug-in uses this to create its top menu to look consistent with all the other screens.

Any command that can be output to the screen and that is not interactive (wanting input from the user) can be made into a plug-in with ease, either as an "awk" script, or as a shell script.

Hope this gives you a few ideas. Most of the add-on packages we are putting on our servers have a command line interface, many have the ability to invoke a command to get status. Now it is easy to web-enable those same commands. Try this one... you get both uptime AND a process list... Not too shabby for 4 lines of plug-in. You could name it 25-unmenu-top.cgi

#ADD_ON_MENU=Top Processes
echo "<pre>"
top -b -n1

or this one for SAMBA status... name it as 25-unmenu-smb_status.cgi

echo <pre>"

unmenu syslog color coding

The Syslog page in unmenu is built into unmenu.awk. It is a simple display, without any ability to color code lines needing attention or of interest. There is also a syslog plug-in, originally written by Joe L, but modified by RobJ to color code lines in the display of the log. Since it has the same "url" as the built-in, it overrides the normal built-in page and is used instead.

The "syslog" plug-in uses a pair of configuration files to define the "interesting" lines to be color coded. Those files are syslog_match.conf (supplied) and syslog_user_match.conf (For additional patterns of lines matching locally installed software output sent to the syslog.)

Both files use the same format:

# Once a rule is matched, we do not look further.  These few lines should be matched out of "color" sequence
# that way, we do not match patterns further in this list.

match_case||" ACPI Error "||orange
match_case||" read_file: error 2 opening /boot/config/super.dat"||green
match_case||" ntpd.*Listening on interface"||black

any_case  ||"error"||red
match_case||"Emask "||red
match_case||"arity incorrect"||red

Each line in the syslog_match.conf files has three fields:

  • the first field indicates if the pattern should match exactly the case of the syslog lines (match_case) or if it should be considered a match regardless of case (any_case)
  • the second field contains the text of the syslog line to be matched.
  • the third field indicates the color of the line to be highlighted if matched.

unmenu package manager package.conf

The unmenu "Package Manager" plug-in uses a series of package definition files. Unless locally configured differently, these files must be located in the same folder where unmenu is invoked or in the /boot/packages folder on your USB Flash drive. Package manager configuration files are always moved to the /boot/packages folder when the Package Manager is invoked.

To be recognized by the Package Manager, the configuration files must match a specific pattern: *-unmenu-*package*.conf

Each package definition file contains a series of lines, each line prefaced with a KEY-WORD that describes the content of that line. The KEY-WORD must be separated from the remainder of the line by a space, tab, or "=". In most of the package files I defined, I simply use a single space.

The KEY-WORDS in package.conf files define (at a minimum) the package name, description, how to install it, and the URL where it is located.

Valid KEY-WORDS are:

this KEY-WORD must be first in a group defining a package
a description of the package and its purpose and any special notes
this key-word may be repeated multiple times to allow a longer description to be supplied
URL to download the package from
name of the file to save when downloading
MD5 checksum of downloaded package file
additional URL to download
this set of 3 "PACKAGE_EXTRA" lines may be repeated for each additional file needed
name of the additional file to save
this set of 3 "PACKAGE_EXTRA" lines may be repeated for each additional file needed
MD5 checksum of additional package file
this set of 3 "PACKAGE_EXTRA" lines may be repeated for each additional file needed
name of a file (including its path) that is associated with this package and always exists after package installation
if the file named by this KEY-WORD exists, the package is considered "installed"
informational only, one dependency per line, shown to the user on the package manager web-page
this key word may be repeated multiple times to describe multiple dependencies
however the example below shows multiple dependencies on same line ???
the script line or lines that actually install the package; may also handle setup and configuration and local customization
this key word may be repeated multiple times to define a script of commands
a command or pipeline of commands that will return a version string for an installed package file; the returned string is then compared with PACKAGE_VERSION_STRING
a string to compare with the output of PACKAGE_VERSION_TEST
informational only, shown to the user on the package manager web-page
a user-editable field used to configure a package
it consists of a "Label" or prompt (possibly displaying the possible responses), a variable and initial value (eg. Minutes=5), and a description of the field to be shown to the user
all three components must be on one line, separated by a pair of || symbols (see the examples below)
this key word may be repeated multiple times to describe multiple variables
this can have one of three values. "64bit", "32bit", or "any"
if the PACKAGE_OS parameter line does not exist in the .conf file, the package is considered to be 32 bit only package.
only packages designated as 64bit or "any" are shown to users of unRAID 6.X (the 64 bit unRAID). Packages designated as 64bit are not shown to those on 32bit unRAID.

There is a special line you can add to an existing package.conf file if you make changes to it and do not wish it to be overwritten by the "Check-for-updates/Install Updates" process in unMENU. You can add a line like this:


The "#" must be at the left margin of a line, but the added line can be anywhere in the file.

The PACKAGE_INSTALLATION lines are used to automatically create one or two files in the /boot/packages directory.

  • packagename.manual_install
This file is created if you elect to manually install the package by pressing the "Install" button on the web-interface. It contains the script of commands as listed in the PACKAGE_INSTALLATION KEY-WORDS. This package.manual_install file is then used to perform the initial installation.
  • packagename.auto_install
This file is created if you elect to enable an auto-install upon reboot of the package by pressing the "Auto-Install" button on the web-interface. It contains the same script of commands as listed in the PACKAGE_INSTALLATION KEY-WORDS, but the file name is recognized by a script added to either the "config/go" file, or to the /boot/custom/etc/rc.d folder, if it exists. This package.auto_install file is then used to perform the installation whenever the unRAID server is rebooted.

A sample package configuration file is shown here:

PACKAGE_NAME lsof (list open files)
PACKAGE_DESCR The <b>lsof</b> command is used to list open files on a file system. This is important to know if you are
PACKAGE_DESCR attempting to shut down your server.  If a file-system has open files, it may not be un-mounted.  If it
PACKAGE_DESCR cannot be un-mounted, the unRAID array cannot be shut down cleanly.
PACKAGE_URL http://slackware.cs.utah.edu/pub/slackware/slackware-current/slackware/ap/lsof-4.78-i486-1.tgz
PACKAGE_FILE lsof-4.78-i486-1.tgz
PACKAGE_MD5 e5f72c903462cf170a3fdaa9e01af1ff
PACKAGE_INSTALLATION installpkg lsof-4.78-i486-1.tgz
PACKAGE_VERSION_TEST lsof -v 2>&1 | grep revision | awk '{print $2}'

A much more complicated package configuration file, with 6 user configurable PACKAGE_VARIABLE fields, for the APC UPS control package. The PACKAGE_INSTALLATION section installs the package, edits some of the package configuration files, starts the "apcupsd" daemon process running, creates a short "doshutdown" script, and then edits rc.6 to use apccontrol instead of poweroff :

PACKAGE_NAME apcupsd - A daemon for controlling APC UPS devices
PACKAGE_DESCR Apcupsd version 3.14.8 can be used for power management and controlling most
PACKAGE_DESCR of APC's UPS models on Unix and Windows machines. 
Apcupsd works with most of APC's PACKAGE_DESCR Smart-UPS models as well as most simple signaling models such as Back-UPS and BackUPS-Office. PACKAGE_DESCR PACKAGE_DESCR

Note: If you elect to not power down the UPS, the server may not detect when power is eventually restored, and will not start until you press its power button. PACKAGE_DESCR For this reason, most users will want to set Power Down UPS after shutdown? = YES PACKAGE_URL http://rlworkman.net/pkgs/13.0/i486/apcupsd-3.14.8-i486-1_rlw.tgz PACKAGE_FILE apcupsd-3.14.8-i486-1_rlw.tgz PACKAGE_INSTALLED /sbin/apcaccess PACKAGE_DEPENDENCIES /usr/bin/mail, /sbin/powerdown PACKAGE_MD5 90467e2be810639805e657f69bb5cb7a PACKAGE_VARIABLE Use Serial Port?(YES/NO)||vDEVICE=NO||If set to NO, a connection via USB cable is used. If YES, a connection via SERIAL cable will be used. PACKAGE_VARIABLE Cable Type:(smart/usb/dumb)||vCABLETYPE=smart||Use "smart" for APC UPS, "usb" for some other brands, "dumb" for others with appropriate cable to serial port. PACKAGE_VARIABLE Battery Level||vBATTERYLEVEL=10||Shutdown will occur when percentage charge remaining is less than this level. PACKAGE_VARIABLE Minutes Remaining||vMINUTES=5||Shutdown will occur when remaining runtime reaches this value. PACKAGE_VARIABLE Total Seconds Outage||vTIMEOUT=300||If outage (in seconds) exceeds this value, a shutdown will occur. PACKAGE_VARIABLE Power Down UPS after shutdown?(YES/NO)||vUPS_KILL=NO||If YES the UPS will power itself off after the server is powered down. This allows it to save its batteries. If NO, the UPS will not power down. You only want this if the UPS is powering other equipment that must stay powered. PACKAGE_INSTALLATION test -f /etc/apcupsd/apcupsd.conf && rm /etc/apcupsd/apcupsd.conf PACKAGE_INSTALLATION [ ! -d /var/lock/subsys/ ] && mkdir -p /var/lock/subsys PACKAGE_INSTALLATION [ -f /etc/rc.d/rc.apcupsd ] && /etc/rc.d/rc.apcupsd stop PACKAGE_INSTALLATION killall apcupsd PACKAGE_INSTALLATION installpkg apcupsd-3.14.8-i486-1_rlw.tgz PACKAGE_INSTALLATION [ "${vDEVICE-NO}" != "YES" ] && sed -i -e "s/^DEVICE \/dev\/ttyS0/#DEVICE \/dev\/ttyS0/" /etc/apcupsd/apcupsd.conf PACKAGE_INSTALLATION [ "${vDEVICE-NO}" = "YES" ] && sed -i -e "s/^UPSTYPE usb/UPSTYPE apcsmart/" /etc/apcupsd/apcupsd.conf PACKAGE_INSTALLATION [ "${vCABLETYPE-smart}" != "smart" ] && sed -i -e "s/^UPSCABLE smart/UPSCABLE ${vCABLETYPE-smart}/" /etc/apcupsd/apcupsd.conf PACKAGE_INSTALLATION sed -i -e "s/^MINUTES 3/MINUTES ${vMINUTES-5}/" /etc/apcupsd/apcupsd.conf PACKAGE_INSTALLATION sed -i -e "s/^BATTERYLEVEL 5/BATTERYLEVEL ${vBATTERYLEVEL-10}/" /etc/apcupsd/apcupsd.conf PACKAGE_INSTALLATION sed -i -e "s/^TIMEOUT 0/TIMEOUT ${vTIMEOUT-300}/" /etc/apcupsd/apcupsd.conf PACKAGE_INSTALLATION sed -i -e "s/WALL=wall/WALL=\"mail -s 'unRAID_Server_UPS_Alert' root\"/" /etc/apcupsd/apccontrol PACKAGE_INSTALLATION /etc/rc.d/rc.apcupsd start PACKAGE_INSTALLATION #Now, put into place the shutdown script replacement PACKAGE_INSTALLATION echo "/sbin/powerdown" >/etc/apcupsd/doshutdown PACKAGE_INSTALLATION echo "exit 99" >>/etc/apcupsd/doshutdown PACKAGE_INSTALLATION chmod 755 /etc/apcupsd/doshutdown PACKAGE_INSTALLATION [ "${vUPS_KILL-YES}" != "NO" ] && sed -i -e "s/\/sbin\/poweroff/\/etc\/apcupsd\/apccontrol killpower; \/sbin\/poweroff/" /etc/rc.d/rc.6 PACKAGE_VERSION_TEST strings /sbin/apcupsd | grep VERSION | grep -v "^VERSION$" | awk '{ print $3 }' PACKAGE_VERSION_STRING 3.14.8 PACKAGE_MEMORY_USAGE Light (10K to 500K) PACKAGE_OS 32bit

The file it creates in the /boot/packages folder when the auto-install option is enabled is named: apcupsd-3.14.8-i486-1_rlw.tgz.auto_install
Its contents are:

test -f /etc/apcupsd/apcupsd.conf && rm /etc/apcupsd/apcupsd.conf
[ ! -d /var/lock/subsys/ ] && mkdir -p /var/lock/subsys
[ -f /etc/rc.d/rc.apcupsd ] && /etc/rc.d/rc.apcupsd stop
killall apcupsd
installpkg apcupsd-3.14.8-i486-1_rlw.tgz
[ "${vDEVICE-NO}" != "YES" ] && sed -i -e "s/^DEVICE \/dev\/ttyS0/#DEVICE \/dev\/ttyS0/" /etc/apcupsd/apcupsd.conf
[ "${vDEVICE-NO}" = "YES" ] && sed -i -e "s/^UPSTYPE usb/UPSTYPE apcsmart/" /etc/apcupsd/apcupsd.conf
[ "${vCABLETYPE-smart}" != "smart" ] && sed -i -e "s/^UPSCABLE smart/UPSCABLE ${vCABLETYPE-smart}/" /etc/apcupsd/apcupsd.conf
sed -i -e "s/^MINUTES 3/MINUTES ${vMINUTES-5}/" /etc/apcupsd/apcupsd.conf
sed -i -e "s/^BATTERYLEVEL 5/BATTERYLEVEL ${vBATTERYLEVEL-10}/" /etc/apcupsd/apcupsd.conf
sed -i -e "s/^TIMEOUT 0/TIMEOUT ${vTIMEOUT-300}/" /etc/apcupsd/apcupsd.conf
sed -i -e "s/WALL=wall/WALL=\"mail -s 'unRAID_Server_UPS_Alert' root\"/" /etc/apcupsd/apccontrol
/etc/rc.d/rc.apcupsd start
#Now, put into place the shutdown script replacement
echo "/sbin/powerdown" >/etc/apcupsd/doshutdown
echo "exit 99" >>/etc/apcupsd/doshutdown
chmod 755 /etc/apcupsd/doshutdown
[ "${vUPS_KILL-YES}" != "NO" ] && sed -i -e "s/\/sbin\/poweroff/\/etc\/apcupsd\/apccontrol killpower; \/sbin\/poweroff/" /etc/rc.d/rc.6