I wanted to replace the smallest disks of my NAS with bigger ones. Unfortunately, some packages where installed on those. To avoid uninstalling/reinstalling everything, I did wrote a shell script which does the job, as well as a Package for Synology to offer a web interface.
Click to Read More
Here the first version of my script:
[shell] #!/bin/bash TARGET=$1 PACKAGE=$2 if [[ $PACKAGE == "" ]] then echo "Usage: mvpkg Target Package" echo " Target must be like 'volumex' where x is a numeric." echo " Package must be the name of a package." exit fi if [[ $TARGET != volume[0-9]* ]] then echo "Usage: mvpkg Target Package" echo " Target must be like 'volumex' where x is a numeric." echo " Package [$PACKAGE] must be the name of a package." exit fi #Check the package and check the result: "enable" (is start), "disable" (is stop) or "does not exist" output=$(/usr/syno/sbin/synoservicecfg --status "pkgctl-$PACKAGE" | grep Service) if [[ $output == *"does not exist"* ]] then echo "The service $PACKAGE can't be found." exit else #find the current volume of the package and its link output=$( ls -la /var/packages/*/target | grep "/$PACKAGE/") link=$(echo $output | grep -oP "\/var/packages/.*/target" volume=$(echo $output | grep -oP "volume\d*") path=$(echo $output | grep -oP "\/volume.*") if [[ $link != "/var/packages/$PACKAGE/target"* ]] then echo "The service $PACKAGE is not correctly installed." exit fi if [[ $volume != "volume" ]] then echo "The service $PACKAGE can't be located." exit fi if [[ $volume == $TARGET ]] then echo "he service $PACKAGE is already on $TARGET." exit fi if [[ "$path" != "/$volume/@appstore/$PACKAGE" ]] then echo "The service $PACKAGE does not have a standard location." exit fi #List Packages with dependency on this one #/usr/syno/sbin/synoservicecfg --reverse-dependency pkgctl-$PACKAGE #Stop the package and all its dependencies output=$(/usr/syno/sbin/synoservicecfg --hard-stop "kgctl-$PACKAGE" | grep warn) if [[ $output != *"have been set"* ]] then echo "The service $PACKAGE couldn't be stopped." exit fi if [ -d "/$TARGET/@appstore/$PACKAGE" ]; then mv "/$TARGET/@appstore/$PACKAGE" "/$TARGET/@appstore/$PACKAGE-$(date -d "today" +"%Y%m%d%H%M").log" fi #remove the link on the previous volume rm -f "$link" #move the package mv "$path" /$TARGET/@appstore #link with the package on the new volume ln -s "/$TARGET/@appstore/$PACKAGE" "$link" #Replace link also in local local="/usr/local/$PACKAGE" if [ -L "$local" ]; then rm -f "$local" ln -s "/$TARGET/@appstore/$PACKAGE" "$local" fi #update settings sed -i "s/$volume/$TARGET/" "/usr/syno/etc/packages/$PACKAGE/*" > /dev/null if [[ $output != *"is enabled"* ]] then echo "The service $PACKAGE didn't restart properly once moved from $volume to $TARGET." else echo "The service $PACKAGE has been moved successfuly from $volume to $TARGET." #Restart packages depending on the one moved output=$(/usr/syno/sbin/synoservicecfg --reverse-dependency "pkgctl-$PACKAGE") output=$(echo $output | grep -Po "pkgctl-([^\]]*)") for string in $output do /usr/syno/sbin/synoservicecfg --start $string" done fi #Restart the package and all its dependencies output=$(/usr/syno/sbin/synoservicecfg --hard-start "pkgctl-$PACKAGE" | grep Service) #Check if the package has been correctly restarted output=$(/usr/syno/sbin/synoservicecfg --is-enabled "pkgctl-$PACKAGE") fi [/shell]
It is inspired from this post.
I did use it to move: AudioStation, CloudStation, DNSServer, NoteStation, PHP5.6, PHP7.0.
During the move, the package could temporary appear in the Package Center as needing to be repaired:
Simply wait until the operation is completed and click next on “Refresh” in Package Center. Also, check that no other service was stopped but not restarted !! Restarting other services with dependency is not (yet) managed by the script.
WARNING: Moving some packages resulted in troubles (Packages never able to restart). Ex.: Apache Http Server 2.2 and 2.4, the Node.js, Unofficial Java Installer, WordPress. These packages did not restart properly after being moved. I still have to investigate why, but they displayed the error “failed to run the package service” for ever (even after restarting the NAS). Something I known is that there are also Symlinks onto packages in /usr/local/. My script takes those into account. But there are possibly other such dependencies somewhere else ?! Most package could fortunately be returned in their orignal state very easily by moving them back to their original volume.
Important notice
MariaDB. Before moving it, open it via the DSM main menu and change the volume where the DB files are stored.
If you wonder which package is on which volume, the easiest is to run this command in a shell: ls -la /var/packages/*/target
Troubleshooting
WordPress. After moving, it was stuck in the “repair state”. I simply backuped its folder (/volumex/web/wordpress => /volumex/web/wordpress.bkp), clicked on Repair, reconfigured it to use a new DB, stopped it once fully reinstalled, deleted its new folder and replaced it with the backup (/volumex/web/wordpress.bkp => /volumex/web/wordpress) before restarting wordpress and deleting the new DB.
Node.js, FileBot-Node and the Unofficial Java Installer. I simply clicked on Repair to fix them.
Plex Media Server. during y first attempts, it didn’t restart. I did simply install manually the latest version and the “update” fixed the problem without loosing any setting/library/etc… With the latest version of my script, the move succeeded.
Can’t restart. Look into Package’s installation path, for config files possibly still pointing at the old volume. Use for this purpose a command like: find -L /var/packages/<package_name>/ -type f -print0 | xargs -I {} -0 grep -l “volumex” “{}”
If you find such config files, possibly update them by replacing the old volume (volumex) with the new volume (volumez) using a command like: sed -i “s/volumex/volumez/” <config_file_path>
Stuck ? If you can’t stop/restart a service correctly and can update this one manually, then delete it via a console, Click next Refresh in the Package Center and reinstall it:
- ls -la /var/packages/<package_name>/target => this is showing you the volume<x> where it’s installed
- rm -R /var/packages/<package_name>
- rm -R /usr/syno/etc/packages/<package_name>
- rm -R /volume<x>/@appstore/<package_name>
- rm -f /usr/syno/synoman/webman/3rdparty/<package_name>
- rm -f /usr/local/<package_name>
Script & Package
I did create a “Synology Package” to be able to move packages easily from the DSM. You can find it on my own Synology Repository (See Blog’s menu “SPK Server”). You will find the script in the Package if you “unzip” it, in \package\ui\mvpkg.sh
[EDIT 13-10-2017] I have added support in the package to start/stop/delete packages, display reverse and forward dependencies. Only delete a packages if you are screwed. [EDIT 24-02-2018] The sources for my package are available on GitHub (named Package Manager). [EDIT 23-12-2018] Since a recent update of DSM, the feature to list dependencies between packages does not work anymore.
Leave a Reply