Synology Move a Synology Package from a volume to another

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:

#!/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 "The 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 "pkgctl-$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

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:

Repair Package

Repair Package444

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.jsFileBot-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

Package Mover

Package Mover

[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.

Synology Synology: "failed to install '...'. This package is not published by Synology Inc,

I got the following message when trying to install third parties packages on my Synology: "failed to install '...'. This package is not published by Synology Inc,

The solution is simply to Trust Any Publisher.

Click to Read More

Go into the "Package Center" > Settings > General tab and select "Any Publisher" in the section "Trust Level"

Trust Any Publisher

Trust Any Publisher

Tips Prolong OnePlus One Battery life by limiting charge

My OnePlus One being only used to play music via AirPlay, it's always plugged into his craddle. I knew this was not good for the battery life and started to look for an App able to prevent my mobile to reload as long as its battery was not less than a certain percentage. I found a paper recommending to reload only once the battery was lower than 25, but also recommending to no reload higher than 85%. And I found an App able to control this on many rooted android phones: "Battery Charge Limit".

Click to Read More

According to this paper, it's not good for lithium batteries' life to do cycles between full charge (100%) and full discharged (0%). Ex.: Doing cycles between 85% and 25% provides a longer service life than doing cycles between 100% and 50%.

For sure, only a full charge (100%) will provide the specified energy of the battery, and therefore its maximum runtime. So, one has to find a compromise:

  • Cycles between 75–65% offer longest life
  • Electrical Vehicles do cycles between 85–25% to prolong battery life
  • Cycles between 100–25% give long runtime, makes best use of battery, but reduces battery life.

All being linear, the life-prolonging mid-range of 85-25% reduces the energy to 60 percent.

More details on the App "Battery Charge Limit" on this blog.

Tips Easy Root Toolkit for OnePlus One

My OnePlus One is already a quite old mobile, but I am still using it at home to play music. I recently reinstall Cyanogen Mod 13 and wanted to root it as this is required to use AirAudio. To avoid doing many manual operations, I looked for a fully automated toolkit and found "Bacon Root Toolkit".

Click to Read More

Highly recommended, it works like a charm!

A demo video exists on YouTube.

Bacon Root Toolkit v1.0.3