MODS Package Manager - vletroye/SynoPackages GitHub Wiki

Description

This Package for Synology contains one 'WebApp' which can list all Packages installed on your Synology. Selecting a Package via the UI, you can move it to another volume or erase it without taking dependencies into account, if any. These are two features not natively supported by Synology. Indeed, a package may only be uninstalled if there is not other package depending on it. And moving packages from a volume to another is a risky operation because there is not warranty that all dependencies are moved correctly.

The package can also 'start' and 'stop' packages. This is useful as moving a Package will stop all reverse dependencies. Once a package moved, you could have to restart the dependencies manually, one by one (This is implemented but does not work with packages taking time to restart).

Finally, the package should display forward and reverse dependencies, which is useful before moving of erasing a package to know where are the possible impacts.

  • reverse-dependencies on a package X are packages depending on X.
  • forward-dependencies on a package X are packages on which A depends. But since the latest version of the DSM (6.1.x), dependencies are not listed anymore ?!

NB: The 'Reset' button can be used to reset the current selection in the UI. It does not trigger any action on Synology.

Use this package at your own risk !

Sources

Find the source code here

Notice

  • In the past, this 'WebApp' based on php had a dependency on the Package Init_3rdparty. Init_3rdparty is used to initialize properly the system Web Server (the WebStation) to run a php application. Concretely, it allows this Web Server to access files and execute programs not under a valid path (/var/services/tmp, /etc.defaults, /usr/bin/php, /usr/syno/synoman, /etc, /var/run, /volume1/@tmp/php, /var/services/web, /var/services/photo, /var/services/blog, /var/services/homes). But now I am apply the trick of Rob Van Aarle's trick to run my php application on nginx without dependency anymore on the WebStation.

  • Since the most recent versions of DSM, commands like 'synoservice' and 'synoservicectl' may only be run by the "root" user... Also, packages are installed with the "root" user and may therefore not be deleted or moved by the "http" user running nginx. To solve those issues, the Package is adding one entry in the /etc/sudoers file to authorize the "http" user to execute "synoservicectl", etc...

  • Erasing a Package can take time. If you still see it the Package Manager after clicking on 'Erase', possibly click on 'refresh'...

  • Although analyzing the dependencies used to work fine, I notice recently that the outcomes were not correct anymore. Ex.: I get a completely wrong answer like 'no service depend on service [pkgctl-WebStation]' when executing: user@Synology:~# /usr/syno/sbin/synoservice --reverse-dependency 'pkgctl-WebStation' (See the screenshot when one tries to stop this service)

Stopping WebStation

Making of

There is no special scripts used to start-stop/install/upgrade/remove this package except:

  • to authorize the "http" user to run the mandatory scripts & commands: http ALL=NOPASSWD: /usr/syno/sbin/synoservicecfg, /volume1/@appstore/MODS_PackageManager/ui/rmpkg.sh, /volume1/@appstore/MODS_PackageManager/ui/mvpkg.sh
  • to "deploy" the nginx config required to run this app without dependency on the WebStation

This is a 'Single App' Package, meaning that it may not contain several items. The resources are therefore directly under the 'dsmuidir' folder, next to the 'config' file and the 'images' folder.

The app is very simple and use server side a lot of Shell Scripts to collect info about the installed Packages and to move them. Calls are made by the html client UI using Ajax.

Ex.: Here under

  • $PACKAGE is the name of a package, as known by Synology (I.e.: not the display name, but the actual Package name - the value set in the field 'package' of SPK's INFO file).

  • $TARGET is the name of a volume as known by Synology and displayed on the DSM > Storage Manager.)

  • to start a package, the php page execute: /usr/syno/sbin/synoservicecfg --hard-start 'pkgctl-$PACKAGE' 2>&1

  • to stop a package, the php page execute: /usr/syno/sbin/synoservicecfg --hard-stop 'pkgctl-$PACKAGE' 2>&1

  • to get reverse dependencies, the php page execute: /usr/syno/sbin/synoservicecfg --reverse-dependency 'pkgctl-$PACKAGE' 2>&1

  • to get forward dependencies, the php page execute: /usr/syno/sbin/synoservicecfg --forward-dependency 'pkgctl-$PACKAGE' 2>&1

  • to move a package, the php page calls a more complex script: mvpkg.sh '$TARGET' '$PACKAGE' 2>&1

  • to erase a package, the php page calls a more complex script: rmpkg.sh '$PACKAGE' 2>&1

  • to retrieve the installation volume, the installation path, and the name of all available packages, the php page simply executes and parse the output of: ls -la /var/packages/*/target

  • to retrieve the list of all available volumes, as targets to move packages, the php page executes: df -la --output=target | grep volume

  • to get the status of the all packages, the php page executes and parse the output of: /usr/syno/sbin/synoservicecfg --status

mvpkg.sh

This shell script is taking two parameters as input: TARGET=$1 and PACKAGE=$2

  • It checks first that the package exist using: /usr/syno/sbin/synoservicecfg --status "pkgctl-$PACKAGE" | grep Service
  • It fetches next the current volume ($volume) and path ($path) of that package using: ls -la /var/packages/*/target | grep "/$PACKAGE/"
  • It checks next that the package is correctly installed by validation that its folder contains a link ($link) named /var/packages/$PACKAGE/target
  • It also checks that the package is well deployed in the appstore by comparing $path with "/$volume/@appstore/$PACKAGE"
  • It stops the package and all its dependencies: /usr/syno/sbin/synoservicecfg --hard-stop "pkgctl-$PACKAGE"
  • If the package already exists on the target volume, this one is backuped using: mv "/$TARGET/@appstore/$PACKAGE" "/$TARGET/@appstore/$PACKAGE-$(date -d "today" +"%Y%m%d%H%M").log"
  • And the link /var/packages/$PACKAGE/target is deleted: rm -f "$link"
  • Finally, the package is moved onto the target volume: mv "$path" /$TARGET/@appstore
  • And the link is recreated: ln -s "/$TARGET/@appstore/$PACKAGE" "$link"

Some 'known stuff to be updated' is next handled:

  • Update the links in the folder /usr/local: rm -f "$local"; ln -s "/$TARGET/@appstore/$PACKAGE" "$local"
  • update the volume in any config file under /usr/syno/etc: sed -i "s/$volume/$TARGET/" "/usr/syno/etc/packages/$PACKAGE/*" &>/dev/null

The script also:

  • restart the package and its reverse dependencies
  • and checks that the package has correctly restarted

rmpkg.sh

This shell script is taking one parameter as input: PACKAGE=$1

  • It checks first that the package exist using: /usr/syno/sbin/synoservicecfg --status "pkgctl-$PACKAGE" | grep Service
  • It stops the package and all its dependencies: /usr/syno/sbin/synoservicecfg --hard-stop "pkgctl-$PACKAGE"
  • It fetches next the current volume ($volume) and path ($path) of that package using: ls -la /var/packages/*/target | grep "/$PACKAGE/"
  • It deletes first any possible links: /usr/syno/synoman/webman/3rdparty/$PACKAGE and /usr/local/$PACKAGE
  • It deletes next the folders /$volume/@appstore/$PACKAGE and /var/packages/$PACKAGE

Illustration

MODS Package Manager

This Package has been generated with 'Mods Packager'. It illustrates how an application based on php and shell scripts can be run on Synology, in a DSM iframe.