Created
December 23, 2022 13:29
-
-
Save bartclone/3881b0ca23e8ae9fea8fb290eee11eeb to your computer and use it in GitHub Desktop.
Synology - move package(s) to other Volume
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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