Package management

From NAS-Central Zyxel Wiki
Jump to: navigation, search

The package

A package is is a gzipped tar. composed of two parts, control.tar.tgz and data.tar.tgz.

control.tar.tgz

This file contains 5 files, control, preinst, postinst, prerm, postrm.

control

Control is a textfile, which describes the package. It contains several fields:

Field Description Contents Contents on an NSA-212 (Medion) if different Remarks
Package Package name E.g. MyPkg No space, no special characters.
Version Package version <PackageVersion>zypkg<SerialNo> <PackageVersion>pkg<SerialNo> Only SerialNo is used by the package manager, to detect if an update is available. Package version is the version string of the software itself. e.g. 1.0.1h
Descripton Description Free text Will be shown in the package management webpage
Depends Other packages which should be installed first Can be empty.
Size Compressed size in bytes e.g. 50000 Just approximately
Installed size The installed (uncompressed size) in bytes Just approximately
Architecture Target platform arm arm11
Zy-Model Target hardware e.g. NSA-220, NSA-320 STG-212 Is ignored by the package manager
IsBuiltin N AFAIK this tells if the package has an webinterface embedded in the Administration pages.
Filename The package file <PackageName>_<PackageVersion>_arm_<SerialNO>.zpkg <PackageName>_<PackageVersion>_arm11_<SerialNO>.pkg

Example:

Package: MyPkg
Version: 001zypkg001
Description: This is a testing package.
Depends:
Size: 23595056
Installed-Size: 67543040
Architecture: arm
Zy-Model: NSA-220
IsBuiltin: N
Filename: MyPkg_001_arm_001.zpkg

Undocumented fields, which are only used in combination with 'IsBuildin: Y'

Field Description
TreeLocation Defines where a packages is shown in the Administration page
ZyURL Defines which page to show?

preinst

Optional. A (bash) script which is executed before installation

postinst

Optional. A script which is executed after installation

prerm

Optional. A script which is executed before removal of package

postrm

Optional. A script which is executed after removal.

ReplaceRule

Firmware 5.x only. On firmware 5.x the package is no longer installed on the fixed /usr/local/zy-pkgs/, but on /i-data/<VOLUMENAME>/.PKG/<PKGNAME>/, where <VOLUMENAME> is unique, as it's derived from the GUID of the md container. To let the package adapt it's scripts/configuration files, this script is called after preinst, and before postinst. The script can extract the package directory from /etc/zyxel/pkg_conf/status:

PKGINSTPATH=`grep "${PKGNAME}" /etc/zyxel/pkg_conf/status |grep "Installed-Rule" |awk -F":" '{print $2}' |sed 's|/$||g'|sed 's| ||g'`

data.tar.gz

The contents of this file is extracted in /usr/local/zy-pkgs/, It is supposed to contain the actual package. There is only one mandatory file, etc/init.d/<PackageName>, which is the startscript of the package.
Other files can be put in etc/, lib/, bin/, ...
A webinterface can be put in gui/<PackageName>/

etc/init.d/<PackageName>

This is an executable bash script. It has to support 5 arguments:

Argument Description
getlink The script outputs the url of the webinterface. When that is a daemon running on a different port, it can be something like http://192.168.1.67:<port>/
If it is a webinterface in the firmware webserver, it's something like http://192.168.1.67/pkg/<PackageName>/, which points to gui/<PackageName>/
And yes, you have to extract the IP address of the box yourself.
status Outputs the current status. Possible values: Enabled and Disabled.
startup Is called when the system boots. The script should fire up it's daemons, when the package is enabled
shutdown Is called when the system shuts down.
enable The script should set a flag that the package is enabled, and fire up it's function
disable The script should remove the 'enabled' flag, and shutdown it's function.

A note on the 'enabled' flag. The recommended place for that is a file (/usr/local/zy-pkgs/)config/<PackageName>. This 'config' dir is in flashrom. (On a ZyXEL. On the Medion it's on disk). A factory reset will erase the flashrom, and so disable all packages. The size of the flashrom is limited, so do not store other configs/data here.

Build script

I have my packages in a directory <PackageName>, containing the subdirectories control and data, and use this script to build the package file:

#!/bin/sh

FILENAME=` cat $1/control/control | grep Filename | cut -d ' ' -f 2 `

echo Generating ==${FILENAME}==

cd $1
cd data
tar czf ../data.tar.gz *
cd ../control
tar czf ../control.tar.gz *
cd ..
tar czf ../${FILENAME} data.tar.gz control.tar.gz
rm data.tar.gz control.tar.gz
cd ..

mkdir -p i-data/md0/admin/zy-pkgs/
cp $1/control/control i-data/md0/admin/zy-pkgs/ZYPKGS
md5=` md5sum ${FILENAME} | cut -d ' ' -f 1 `
echo MD5SUM: ${md5} >>i-data/md0/admin/zy-pkgs/ZYPKGS
tar czf ZYPKG_INFO.tgz i-data

Updating packages

From the package' point of view an update is an uninstall followed by an install. So if your package cleans up all it's configuration files and stuff on uninstall (as it should), then everything is lost on an update. Fortunately there is a work around. The package manager logs what it's supposed to do in /usr/local/zy-pkgs/tmp/zypkg.log, so by parsing this file it is possible to let prerm and postrm behave different:

#!/bin/sh

PKGNAME="MyPkg"
PKG_ROOT="/usr/local/zy-pkgs"

IsUpgrading()
{
        if cat ${PKG_ROOT}/tmp/zypkg.log | grep "\[${PKGNAME}\]" | tail | grep "Upgrade Mode" >/dev/null
        then
                return 0
        fi
        return 1
}

IsUpgrading
if [ $? -eq 0 ] ; then
     echo "upgrading"
     # do something
else
     echo "uninstalling"
     # do something else
fi
exit 0

As the package manager will remove all files which were in data.tar.gz, you might want to move changed file (configuration files) in prerm. The postinst of the new package should put them back.

ZYPKG_INFO.tgz

Firmware 4.x, Medion firmware 1.x

On the Medion this file is called PKG_INFO.tgz. This file is downloaded by the package manager, and extracted in the root of the filesystem. It is supposed to contain a file i-data/md0/admin/zy-pkgs/ZYPKGS (on a Medion i-data/md0/admin/package/PKGS), and optionally the files /usr/local/zy-pkgs/etc/init.d/ZYPKG_DEPS and /usr/local/zy-pkgs/gui/ZYPKG_LANG_LIST.
The tgz file is extracted in the root of the filesystem, as said, without any protection. So if any of the subdirectories in the tarball has wrong credentials, it will be written to the filesystem. Further it is possible to push totally unrelated files to your filesystem.

/i-data/md0/admin/zy-pkgs/ZYPKGS

This file contains the description of all packages available on the package server, seperated by empty lines. The description is identical to the config.tar.gz/config file, with one extra field, MD5SUM:, followed by the md5sum of the package file.
BTW, it seems the config.tar.gz/config files are totally ignored by the package manager. To 'convert' a ZyXEL package to a Medion package it is sufficient to just edit the ZYPKGS file.

/usr/local/zy-pkgs/etc/init.d/ZYPKG_DEPS

This file basically contains a startup and shutdown sequence for the start scripts. Scripts which are not mentioned here will also be called. Actually all executables in /usr/local/zy-pkgs/etc/init.d/ will be called with the 'startup' argument on boot.

/usr/local/zy-pkgs/gui/ZYPKG_LANG_LIST

This file contains translations of the 'Description' field of all packages. One package per line:

var PackageName={'en':'English description','it':'Italian description','xx':'Whatever'}

I think this is javascript.
Don't bother about this file. If your package is not in it, the 'Description' field from ZYPKGS is used.

Firmware 5.x

The file is changed, mainly because the package root has changed.

/i-data/.system/zy-pkgs/ZYPKGS

Same function as /i-data/md0/admin/zy-pkgs/ZYPKGS

/i-data/.system/zy-pkgs/ZYPKG_DEPS

Same function as /usr/local/zy-pkgs/etc/init.d/ZYPKG_DEPS

/i-data/.system/zy-pkgs/SUPPKG

Seems to contain a shell script which is used to update certain packages.

/i-data/.system/zy-pkgs/pkggui/ZYPKG_LANG_LIST

Same function as /usr/local/zy-pkgs/gui/ZYPKG_LANG_LIST

The package manager

Firmware 4.x, Medion firmware 1.x

The package manager is a derivative of the ipkg package system. It keeps it's database on two places. A part in /i-data/md0/admin/zy-pkgs/, (/i-data/md0/admin/package on a Medion). This part can be reached in the admin share. The other part is in /usr/local/zy-pkgs/zypkg_conf/.

/usr/local/zy-pkgs/zypkg_conf/

The file 'status' contains info about all installed packages. The directory 'info/' contains the files from control.tar.gz, with the package names as prefix, e.g. PackageName.postrm
Further it contains files PackageName.insttime, containing the installtime of each package, and a file PackageName.list, which contains a list of installed files from the data.tar.gz file. These files will be removed if the package is deinstalled.

/i-data/md0/admin/zy-pkgs/

The main file here is ZYPKGS, which is overwritten each time you hit the 'Retreive packages' button in the webinterface. Further is contains all package files which you ever installed. If you deinstalled a package, and reinstall it, the manager will use the cached file here, rather than re-downloading it.

Firmware 5.x

The package manager is a derivative of the ipkg package system. It keeps it's database on three places. The list of available packages is in /i-data/.system/zy-pkgs/ZYPKGS. The list of installed packages is in /etc/zyxel/pkg_conf/status (on flashrom). Further for each package some data is stored in /i-data/<VOLUME>/.PKG/<PACKAGENAME>/zypkg_conf/info.

Buggy

Although the package manager has a database of all installed packages, including their control files, it will only show the packages listed in ZYPKGS in the webinterface.
On a Medion it's even worse (and possibly also on older ZyXEL firmwares), when a package is installed which is not listed in PKGS, the package manager doesn't show any package in the list.
A work-around for this is to use MetaRepository which dynamically generates a ZYPKGS file, and also adds the packages which are listed in the package managers database.

Single repository

The package manager can only handle one ZYPKGS file, which is extracted from one ZPKGS_INFO.tgz file, and so it can only handle a single repository. A work-around for this is to use MetaRepository which dynamically generates a ZYPKGS file, by combining files from several repositories

Hacks

By default the package manager downloads ftp://ftp2.zyxel.com/<NASTYPE/<FWTAG>/zypkg/ZYPKG_INFO.tgz, where <FWTAG>/ is empty for fw <4.40, 4.40/ for fw 4.40-4.6x, and 4.70/ for fw >= 4.70. On a Medion the manager downloads ftp://nas-download:sEhtalr@download.medion.de/package/PKG_INFO.tgz. Fortunately it is possible to change this.

/etc/package_src_url

This file contains the URL to the directory where the package manager downloads all it's stuff (ZYPKG_INFO.tgz and the package files), so on my NSA325 fw 4.70 this file contains the line ftp://ftp2.zyxel.com/NSA325/4.70/zypkg. (Indeed without trailing slash) This file can be changed easily:

echo <your-url> > /etc/package_src_url

When you retreive a new package list after this, this URL will be used. At least ftp:// and http:// are supported.

A problem is that this file is on a ram drive, so after a reboot it's reset to default. This can be worked around by putting a script in /usr/local/zy-pkgs/etc/init.d/, which is executed on each boot.

web_prefix

Unavailable on a Medion. This file can be put in the admin share, in zy-pkgs/ (So the full path is \\NAS\admin\zy-pkgs\web_prefix). The file should contain a single line containing the trunk of the url, including trailing slash, followed be a line ending. The package manager will add <NASTYPE>/<FWTAG>/zypkg/

On firmware 5 the zy-pkgs subdirectory is not available, by default. But you just can create it. Further the added path is <NASTYPE>/zypkg/<FWTAG>/

NO_UPDATE

When this file in put in /i-data/md0/admin/zy-pkgs/ (/i-data/md0/admin/package/ on a Medion), the package manager will not update. So you can manually edit ZYPKGS, and add the package files. If you retreive updates then, the ZYPKGS file will be read again.

MetaRepository

MetaRepository package can combine the contents of several repositories, including a directory on your disk. It downloads ZYPKG_INFO.tgz, and if that is not available, ZYPKGS. It can also convert ZYPKG_INFO.tgz files to PKG_INFO.tgz files, and ZYPKGS to PKGS, to install ZyXEL packages on a Medion.

Package errors

Sometimes a package installation fails, in that case a state 'Unknown' is showed in the webinterface. The webinterface shows this state when a file /usr/local/zy-pkgs/tmp/<PackageName>.err_msg exist. If you delete that file, and reload the webinterface, the error is gone. (But not the cause, of course).

Toolchain

Here you can download a native toolchain to compile binaries natively on your NAS. It's extracted from sdk3.3-genericfs-arm-mv5sft.tar.gz, which is shipped with the ZyXEL 4.70 GPL sources.
This toolchain needs to be chrooted, because it's directories are incompatible with the firmware ones. To do so, I added a script 'chroot.sh'. A simple program can be compiled and installed this way:

su
/path/to/toolchain/chroot.sh
cd /home/admin
wget <url-of-tarball>
tar xf <tarball>.tgz
cd <tarball>
./configure --prefix=/usr/local/zy-pkgs
make
make install
exit

Now you can collect your files from /path/to/toolchain/usr/local/zy-pkgs/.