Skip to content

Instantly share code, notes, and snippets.

@bartclone
Created December 23, 2022 13:29
Show Gist options
  • Save bartclone/3881b0ca23e8ae9fea8fb290eee11eeb to your computer and use it in GitHub Desktop.
Save bartclone/3881b0ca23e8ae9fea8fb290eee11eeb to your computer and use it in GitHub Desktop.
Synology - move package(s) to other Volume
#!/bin/ash
#
# Author: Bart Koppers
# License: GPL v3 - https://www.gnu.org/licenses/gpl-3.0.html
#
# Purpose:
# - easy & safe relocation of Synology packages to a different volume
# Relies on:
# - synoservice, the SynoService Tool Help (Version 25426),
# see CLI Administrator Guide for Synology NAS
# [https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_Administration_CLI_Guide.pdf]
# - naming of Packages, these should follow the pkgctl-<Packagename> convention
#
# Synology-behaviour on (custom) packages
# - /var/packages/<packagename>
# - /var/packages/<packagename>/enabled if Package is active/running
#
# TODO :
# - ? multiple package-names, at once ( so >1, not necessarily all/ALL)
# - :) functions...
# - some check on free space
# - ? exceptions/extras "per package", for example
# - *SynologyDrive : edit /var/packages/SynologyDrive/etc/db-path.conf --> db-vol=/volumeX
# - *Docker: has a link in \@appstore/Docker/docker -> /volumeX/@docker
# Parameters
NEW_VOLUME=${1:-volume1}
WHICH_PKG=${2:-ALL}
REALLY_RUN=${3:-DRYRUN}
# NOW=${NOW:-$(date +"%Y-%m-%d")}
if [ $# -lt 1 -o $# -gt 3 ] ; then
cat <<EOF
$(basename $0) moves Synology-package(s) to another volume:
- stopping package-service if enabled
- move package, relink
- restart package-service
$0 needs EXACTLY 3 parameters - no more, no less
Usage : $0 <volume-to-move-to> <packagename>|ALL nothing|YES
Defaults: - Volume1
- All packages
- Dry Run: do nothing (no stop/no move/no relinking)
so, you're safe unless YES is specified as 3rd parameter
Example : $0 volume1 HyperBackupVault YES
- if running: stops package HyperBackupVault
- moves package HyperBackupVault to /volume1/@appstore
- if HyperBackupVault was running: restarts the service
CAVEATS: Doesn't take dependencies into account, like other apps/packages or volumes
- if a package (like Docker) does some management on its own,
this script DOES NOT change any of those dependencies
- if a package requires other packages to be running, or needs Volumes to exist,
well, this script is quite INGNORANT of those! :)
*************************************************************************
WARNING: RUNNING THIS SCRIPT DOES NOT IMPLY OR GUARANTEE THAT
THE RESULT IS OK! FAULTS CAN HAPPEN.
*************************************************************************
- Using Synology Packages implies YOUR fitness to use it
- If you are unsure, get errors AND/OR want to be (more) certain,
then SKIP this script
- You can always just remove and re-install packages MANUALLY and ONE-BY-ONE
from the Synology webGUI, it's however manual and can be slower ..
EOF
echo "Bye." && exit
else
echo "Options: volume-$NEW_VOLUME package=$WHICH_PKG and $REALLY_RUN"
fi
# check if root/sudo
if [ "$UID" -ne 0 ] ; then echo "Please run as root, or use sudo" ; exit ; fi
# If not exist, create directory @appstore on new volume
[ "$REALLY_RUN" = "YES" ] && mkdir -p /$NEW_VOLUME/\@appstore
# Get all packages currently installed
# Best solution: get a list of packages installed using
# synoservicecfg --list|grep pkgctl | cut -d'-' -f2
# (alternative: PACKAGES=ls /var/packages/ ; for packagedir in $PACKAGES, etc)
if [ "$WHICH_PKG" = "ALL" ] ; then
PACKAGES=$(synoservice --list|grep -i pkgctl|cut -d'-' -f2-)
else
PACKAGES=$(synoservice --list|grep pkgctl|grep -i $WHICH_PKG|cut -d'-' -f2-)
fi
echo "Packages: $PACKAGES"
for packagename in $PACKAGES
do
echo "Checking packagename: $packagename"
packagedir=""
linktarget=""
packagedir="/var/packages/$packagename"
echo " in dir: $packagedir"
# where is the package *currently* installed, or: what is the target of the link?
# linktarget= ([ -L $packagedir/target ] && $(realpath $packagedir/target)) || "Not a linked target"
linktarget=$(realpath $packagedir/target)
echo "Target = $linktarget"
echo "Processing: $packagename"
newlocation=/$NEW_VOLUME/\@appstore/$packagename
newlink=/var/packages/$packagename/target
if [ -d "$newlocation" ]; then
echo "!NOTICE! DIrectory $newlocation already contains a package $packagename"
continue
fi
# get status - if enabled/running, there's a file /var/packages/<packagename>/enabled
service_enabled=0
if [ -f $packagedir/enabled ] ; then
service_enabled=1
echo "Stopping package $packagename:"
runscript="synoservicectl --stop pkgctl-$packagename"
[ "$REALLY_RUN" = "YES" ] && result=$($runscript) || result="**DRYRUN**: $runscript"
echo "Result stopping $packagename : $result"
else
echo "Package $packagename *not* enabled, not stopped"
fi
# move package to new volume
echo " Moving package from $linktarget to /$NEW_VOLUME/\@appstore/$packagename"
[ "$REALLY_RUN" = "YES" ] && mv $linktarget /$NEW_VOLUME/\@appstore/$packagename
# re-link
echo " Re-linking $newlocation to $newlink - Cmd: ln -sf $newlocation $newlink"
[ "$REALLY_RUN" = "YES" ] && ln -sf $newlocation $newlink
# re-enable packageservice
if [ $service_enabled=1 ] ; then
runscript="synoservicectl --start pkgctl-$packagename"
result="placeholder - not yet run: $runscript"
[ "$REALLY_RUN" = "YES" ] && result=$($runscript) || result="**DRYRUN**: $runscript"
echo "Result enabling $packagename : $result"
else
echo "No need to re-enable $package"
fi
done
#################################################
## ToDo / Extend script ##
#################################################
# Multiple arrays?
# https://stackoverflow.com/questions/1063347/passing-arrays-as-parameters-in-bash/4017175#4017175
# https://brianchildress.co/named-parameters-in-bash/
# Array should be the last argument and only one array can be passed
#!/bin/bash
# function copyFiles() {
# local msg="$1" # Save first argument in a variable
# shift # Shift all arguments to the left (original $1 gets lost)
# local arr=("$@") # Rebuild the array with rest of arguments
# for i in "${arr[@]}";
# do
# echo "$msg $i"
# done
# }
#
# array=("one" "two" "three")
# copyFiles "Copying" "${array[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment