Post on 10-Mar-2021
1.1
1.2
1.3
1.4
1.4.1
1.4.2
1.4.3
1.5
1.5.1
1.5.2
1.5.3
1.5.4
1.6
1.6.1
1.6.1.1
1.6.1.2
1.6.2
1.6.3
1.6.3.1
1.6.3.2
1.6.4
1.6.4.1
1.6.4.2
1.6.4.3
1.6.4.4
1.6.5
1.7
1.7.1
1.7.2
1.7.2.1
1.7.2.2
1.7.2.3
1.7.2.4
1.7.3
1.7.3.1
1.7.4
1.7.4.1
1.7.4.2
1.7.4.3
TableofContentsPackageDeveloperGuide
ReleaseNotes
BreakingChanges
GettingStarted
SystemRequirements
PrepareEnvrionment
YourFirstPackage
SynologyToolkit
BuildStage
PackStage
SignPackage(onlyforDSM6.X)
References
SynologyPackage
INFO
NecessaryFields
OptionalFields
package.tgz
scripts
ScriptEnvironmentVariables
ScriptMessages
conf
privilege
resource
PKG_DEPS
PKG_CONX
LICENSE
SynologyDSMIntegration
FHS
DesktopApplication
ApplicationConfig
ApplicationHelp
ApplicationI18N
ApplicationAuthentication
Privilege
PrivilegeConfig
Resource
ResourceConfig
ResourceTiming
ResourceUpdate
2
1.7.4.4
1.7.4.4.1
1.7.4.4.2
1.7.4.4.3
1.7.4.4.4
1.7.4.4.5
1.7.4.4.6
1.7.4.4.7
1.7.4.4.8
1.7.4.4.9
1.7.4.4.10
1.7.4.4.11
1.7.5
1.7.6
1.8
1.8.1
1.8.2
1.8.3
1.8.4
1.9
1.9.1
1.9.2
1.9.3
1.10
1.11
1.11.1
1.11.2
1.11.3
1.12
ResourceList
/usr/locallinker
Apache2.2Config
DataShare
Docker
IndexDB
MariaDB
PHPINI
PortConfig
SystemdUserUnit
SyslogConfig
WebService
Port
Monitor
PackageExamples
OpenSourceTool:tmux
OpenSourceTool:nmap
Dockerpackage
WebPackage:WordPress
PublishSynologyPackages
GetStartedwithPublishing
SubmittingthePackageforApproval
RespondingtoUserIssues
AppendixA:PlatformandArchValueMappingTable
AppendixB:CompileApplicationsManually
DownloadDSMToolChain
Compile
CompileOpenSourceProjects
AppendixC:PublicationReview&Verification
3
SynologyDSM7.0DeveloperGuideSynologyoffersthisdeveloperguidewithinstructionsonhowtodeveloppackagesonSynologyNASproducts.YoushouldhavebasicunderstandingofLinuxprogramming.Withthisguide,youcanfamiliarizeyourselfwiththefollowingprocedures:
CompileprogramstorunonaSynologyNAS.IntegratepackageswiththeSynologyDiskStationManager(DSM).IntegratepackageswiththeDSMhelp.IntegratepackageswiththeDSMdesktopapplication.IntegratepackageswiththeDSMfirewall.IntegratepackageswiththeDSMresourcemonitor.
THISDOCUMENTCONTAINSPROPRIETARYTECHNICALINFORMATIONWHICHISTHEPROPERTYOFSYNOLOGYINCORPORATEDANDSHALLNOTBEREPRODUCED,COPIED,ORUSEDASTHEBASISFORDESIGN,MANUFACTURING,ORSALEOFAPPARATUSWITHOUTWRITTENPERMISSIONOFSYNOLOGYINCORPORATED
CopyrightSynologyInc.®2021SynologyInc.Allrightsreserved.
Nopartofthispublicationmaybereproduced,storedinaretrievalsystem,ortransmitted,inanyformorbyanymeans,mechanical,electronic,photocopying,recording,orotherwise,withoutpriorwrittenpermissionofSynologyInc.,withthefollowingexceptions:AnypersonisherebyauthorizedtostoredocumentationonasinglecomputerforpersonaluseonlyandtoprintcopiesofdocumentationforpersonaluseprovidedthatthedocumentationcontainsSynology’scopyrightnotice.
TheSynologylogoisatrademarkofSynologyInc.
Nolicenses,expressorimplied,aregrantedwithrespecttoanyofthetechnologydescribedinthisdocument.Synologyretainsallintellectualpropertyrightsassociatedwiththetechnologydescribedinthisdocument.ThisdocumentisintendedtoassistapplicationdeveloperstodevelopapplicationsonlyforSynology-labeledcomputers.
Everyefforthasbeenmadetoensurethattheinformationinthisdocumentisaccurate.Synologyisnotresponsiblefortypographicalerrors.
SynologyInc.9F.,No.1,YuandongRd.,NewTaipeiCity22063,Taiwan
SynologyandtheSynologylogoaretrademarksofSynologyInc.,registeredintheUnitedStatesandothercountries.
MarvellisregisteredtrademarksofMarvellSemiconductor,Inc.oritssubsidiariesintheUnitedStatesandothercountries.
FreescaleisregisteredtrademarksofFreescale.IntelandAtomisregisteredtrademarksofIntel.
Semiconductor,Inc.oritssubsidiariesintheUnitedStatesandothercountries.
Otherproductsandcompanynamesmentionedhereinaretrademarksoftheirrespectiveholders.
EventhoughSynologyhasreviewedthisdocument,SYNOLOGYMAKESNOWARRANTYORREPRESENTATION,EITHEREXPRESSORIMPLIED,WITHRESPECTTOTHISDOCUMENT,ITSQUALITY,ACCURACY,MERCHANTABILITY,ORFITNESSFORAPARTICULARPURPOSE.ASARESULT,THISDOCUMENTISPROVIDED“ASIS,”ANDYOU,THEREADER,AREASSUMINGTHEENTIRERISKASTOITSQUALITYANDACCURACY.INNOEVENTWILLSYNOLOGYBELIABLEFORDIRECT,INDIRECT,SPECIAL,INCIDENTAL,ORCONSEQUENTIALDAMAGESRESULTINGFROMANYDEFECTORINACCURACYINTHISDOCUMENT,evenifadvisedofthepossibilityofsuchdamages.
THEWARRANTYANDREMEDIESSETFORTHABOVEAREEXCLUSIVEANDINLIEUOFALLOTHERS,ORALORWRITTEN,EXPRESSORIMPLIED.NoSynologydealer,agent,oremployeeisauthorizedtomakeanymodification,extension,oradditiontothiswarranty.
PackageDeveloperGuide
4
Somestatesdonotallowtheexclusionorlimitationofimpliedwarrantiesorliabilityforincidentalorconsequentialdamages,sotheabovelimitationorexclusionmaynotapplytoyou.Thiswarrantygivesyouspecificlegalrights,andyoumayalsohaveotherrightswhichvaryfromstatetostate.
PackageDeveloperGuide
5
SynologyPackageFramework7.0
BreakingChanges
FindmoredetailspleaserefertobreakingchangesBreakingChangesIn7.0.
1.PackageFramework
ForcelowerprivilegeforpackageForcesomeINFOfieldstobeneccessaryRemovepackagesigningRemoverun-assystemfromprivilegeChangedefaulthomepathfromtargettohomeChangePACKAGE_ICON.PNGfrom72x72to64x64ChangeFHSdirectoryowneraccordingtoprivilegesettingsChangepackageloglocationto/var/log/packages/[package_name].logand/var/log/synopkg.logConsiderprestartscriptonbootup
2.PackageCenter
RemovekeyringRemovetrustlevel
3.Commands
synopkgstartstartsthepackagewithitsdependeessynopkginstallchecksifthepackagecanbeinstalled
NewFeatures
1.SDKPlugin
Addpackage_installmoduleAddpackage_uninstallmoduleAddpackage_startmoduleAddpackage_stopmodule
2.PackageFramework
AddvardirectoryforFHSAddtmpdirectoryforFHSAddhomedirectoryforFHSAddprereplacescriptAddpostreplacescriptAddinstall_on_cold_storagetoINFO
Addexclude_modeltoINFO
AdddsmapppagetoINFOAdduse_deprecated_replace_mechanismtoINFOAddmultipledirectoriessupportfordsmuidirinINFO
ReleaseNotes
6
3.ResourceWorker
Addstrong-dependencetodata-shareworkerforpackagewhoneedsautostartafterencryptedsharemountedAddsystemd-user-unitworker
Enhancements
1.PackageFramework
RestartpackageafterrepairedaccordingtoitsoriginalstateCannotcontinuetoinstallpackageifspkchecksumisincorrect
2.PackageCenter
BeabletostartapackagewithitsdependeesBeabletostopapackagewithitsdependersBeabletouninstallapackagewithitsdependersBeabletorepairstart-failedpackageviarepairbuttonCommunitysourcesshouldhavesamename/source
ReleaseNotes
7
BreakingChangesin7.0InDSM7.0,there’resomebreakingchangesinpackageframeworkPackageCenterandcommands.Alsosee ReleaseNotes.
PackageFrameworkChanges
1.Forcelowerprivilegeforpackage
Allpackagesshouldprovideconf/privilegewithpackageinrun-asexplicitly.Anyprivilegedoperationshouldbeaccomplishedviaresourceworker.
2.ForcesomeINFOfieldstobeneccessary
Anypackageshouldhavepackage,version,os_min_ver,description,archandmaintainerfields.Futhermore,thevalueofos_min_vershouldbeatleast7.0-40000oryoucannotinstallthepackagecorrectly.
3.Removepackagesigningmechanism
Packagesarenolongerabletodosigninginpackingstage.
4.Removerun-assystemfromprivilege
Packageswillnotbeabletouserun-assysteminconf/privilege.Instead,allpackagesshouldrunaspackage.
5.Changedefaulthomepathfromtargettohome
Thehomedirectoryofpackageischangedfrom/var/packages/[package_name]/targetto/var/packages/[package_name]/homeanditsmodewillbe0700.
6.ChangePACKAGE_ICON.PNGfrom72x72to64x64
PackageshouldhavePACKAGE_ICON.PNGin64x64above7.0.
7.ChangeFHSdirectoryowneraccordingtoprivilegesettings
FHSdirectoriessuchastargetwillhavenewprivilegesettingsaccordingtoconf/privilege.
8.Changepackageloglocationto/var/log/packages/[package_name].logand/var/log/synopkg.log
Packageoperationlogisstillat/var/log/synopkg.logbutcontrolscriptlogwillbeat/var/log/packages/[package_name].log.Besides,whenyouaredevelopingapackage,youshouldalwayspayattentiontothecontentof/var/log/messagestocheckifthereareanywarningorerror.
9.Considerprestartscriptonbootup
Theprestartscriptwillrunonbootuptocheckifapackagecanbestarted.
PackageCenterChanges
1.Removekeyring&&Removetrustlevel
BreakingChanges
8
Userarenolongerbeabletoadd/removekeyringsonpackagecentersincewehavedeprecatedthecodesignmechanismofspk.Similarly,therewillbenotrustlevelsettingsforusertochoose.Anynon-synologypackagewillgetalertoninstallation.
CommandChanges
1.synopkgstartstartsapackagewithitsdependees
IfAdependsonB,runsynopkgstartAwillalsostartBwhenBisnotstarted.
2.synopkginstallchecksifpackagecanbeinstalled
ThesynopkginstallcommandwillhavesameconstraintsasUIinstallation.
BreakingChanges
9
GettingStartedGettingstartedtolearnhowtoeasilybuildpackagesjustthewayyoulike!
Whatcanpackagesdo?
accessDSMAPIaccessowneddatasharefolderintegratedesktopapplicationintegratehelpdocumentsintegratefirewallrulesintegrateresourcemonitordefinelifecyclebehaviourdefinerelationshipbetweenpackagesdefineidentityprivilege
Howtodeveloppackages?
Todeveloppackages,youfirstneedtoknowtheentireworkingflow:
1. PrepareaNAS
Youcanchooseoneatourofficialsiteandbuyitfromlocalsynologypartner.ItisrecommendedtotakeonefromthePlusSeries.
2. Prepareenvironmentsforlocaldevelopment
SinceourNASisnotalwaysinx86orx86_64architecture,weshouldpreparecorrespondingenvironmenttoourNAS(forcrosscompilingifyouaredevelopinginC/C++).WeprovidetonsoftoolsforcreatingdifferentdevelopmentenvironmentsofourNASinaneasyway.
3. Decidewhatyouwanttomake
IfyouwanttodevelopanapplicationinNode.js,youcanmakeyourpackagedependonourofficialNode.jspackage.IfyouwanttodevelopinPHP,youcanstillmakeyourpackagedependonPHPpackage.WehavealreadyprovidedNode.js,PHP,Perl,Python,JavapackagesforlangugageruntimeonDSM.
GettingStarted
10
YoucanmakegreatpackagesbyleveragingourPackageFrameworktohavestable,controllableandpowersavingproperties.Weprovidecompletetoolkitforcrosscompilingandpackingsoyoucanalsodevelopinaneasyway.
4. DecidewhethertopublishpackagesontoofficialSynologyPackageCenter
Begintodeveloppackages
Inlatertopics,wewilltakeacloserlookatdevelopment.Youcanfindarticlessuchas
SystemRequirementPrepareEnvironmentYourFirstPackage
GettingStarted
11
SystemRequirements
ToolkitRequirements
64bitgenericlinuxenvironmentwithrootpermission(e.g.,Ubuntu18.04LTS)bash(>=4.1.5)python(>=2.7.3)
PleaseDONOTinstalltoolkitonSynologyNAS asyourdevelopmentenvironment.NASisspecializedforstorage,andnotforgenericdevelopingpurpose.Instead,youcaninstallDockerpackageonNASthensetupagenericlinuxcontainertoinstallthetoolkit.
RuntimeRequirementsIfyourpackageisforDSM6thenyoushouldhaveaDSM6NAS.IfyourpackageisforDSM7thenyoushouldhaveaDSM7NAS.
PackageforDSM6isnotcompatiblewithDSM7
SystemRequirements
12
PrepareEnvironment
InstallToolkit
ToolkitInstallation:
Youneedtoclonethefront-endscriptsfromthislink.Wewilluse/toolkitastoolkitbaseinthisdocumentfromnowon.
apt-getinstallgit
mkdir-p/toolkit
cd/toolkit
gitclonehttps://github.com/SynologyOpenSource/pkgscripts-ng
Thenyouneedtoinstallafewtoolstomakethebuilttoolwork:
apt-getinstallcifs-utils\
python\
python-pip\
python3\
python3-pip
Atthismoment,youcanfindtoolkitfilesasthefollows:
/toolkit
├──pkgscripts-ng/
│├──include/
│├──EnvDeploy(deploymenttoolforchrootenvironment)
│└──PkgCreate.py(buildtoolforpackage)
└──build_env/(directorytostorechrootenvironments)
DeployChrootEnvironmentForDifferentNASTargetForfasterdevelopment,wehavepreparedseveralbuildenvironmentsofdifferentarchitectureswhichcontainsomepre-builtprojectswhoseexecutablebinariesorsharedlibrariesarebuiltinDSM,forexample,zlib,libxml2andsoon.
YoucanuseEnvDeploytodeploycorrespondingenvironmentofyourNAS.Forexample,ifthereisaNASinavotonarchitecture,itispossibletousefollowingcommandstodeployaenvironmentforavoton:
cd/toolkit/pkgscripts-ng/
gitcheckoutDSM7.0
./EnvDeploy-v7.0-pavoton#forDSM7.0
Itispossibletodownloadenvironmenttarballsmanually.Youhavetoputbase_env-7.0.txz,ds.{platform}-7.0.dev.txzandds.{platform}-7.0.env.txzintotoolkit/toolkit_tarballs.
/toolkit
├──pkgscripts-ng/
└──toolkit_tarballs/
├──base_env-7.0.txz
├──ds.avoton-7.0.dev.txz
└──ds.avoton-7.0.env.txz
cd/toolkit/pkgscripts-ng/
PrepareEnvrionment
13
./EnvDeploy-v7.0-pavoton-D#-Dimpliesnodownload
Asmentionedbefore,thedeployedenvironmentcontainssomepre-builtlibrariesandheaderswhichcanbefoundundercrossgccsysroot.Sysrootisthedefaultsearchpathofcompiler.Ifgcccannotfindheaderorlibraryfromthegivenpath,itwillthensearchsysroot/usr/{lib,include}.
/toolkit
├──pkgscripts-ng/
│├──include/
│├──EnvDeploy
│└──PkgCreate.py
└──build_env/
├──ds.avoton-7.0/
└──ds.avoton-6.2/
└──usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/
AvailablePlatforms
Youcanuseoneofthefollowingcommandstoshowavailableplatforms.If-visnotgiven,availableplatformsforallversionswillbelisted.
./EnvDeploy-v7.0--list
./EnvDeploy-v7.0--infoplatform
Youmayuseanytoolkitthatbelongtothesameplatformfamilytocreatespkforallplatformswithinthesameplatformfamily.e.g.youmayusethetoolkitforbraswelltocreatepackagerunsonallx86_64compatibleplatforms.Forplatformfamily,pleasecheckPlatformandArchValueMappingTable.
UpdateEnvironment
UseEnvDeployagaintoupdatetheenvironment.Forexample,youcanupdateavotonforDSM7.0asfollows.
./EnvDeploy-v7.0-pavoton
RemoveEnvironment
Toremoveaenvironment,youfirstneedtounmountthe/procfolderthenremovetheenvironmentfolder.Thefollowingcommandsillustratehowtoremoveanenvironmentwithversion7.0andplatformavoton.
umount/toolkit/build_env/ds.avoton-7.0/proc
rm-rf/toolkit/build_env/ds.avoton-7.0
PrepareEnvrionment
14
YourFirstPackageMakesureyouhavepreparedthedevelopmentenvironmentforyourNAS.
Downloadthetemplatepackage
Youcandownloadourtemplatepackagefromhttps://github.com/SynologyOpenSource/ExamplePackagesandplacetheExamplePackages/ExamplePackagedirectoryat/toolkit/source/ExamplePackage.
/toolkit/
├──build_env/
│└──ds.${platform}-${version}/
├──pkgscripts-ng/
│├──EnvDeploy
│└──PkgCreate.py
└──source/
└──ExamplePackage/
├──examplePkg.c
├──INFO.sh
├──Makefile
├──PACKAGE_ICON.PNG
├──PACKAGE_ICON_256.PNG
├──scripts/
│├──postinst
│├──postuninst
│├──postupgrade
│├──postreplace
│├──preinst
│├──preuninst
│├──preupgrade
│├──prereplace
│└──start-stop-status
└──SynoBuildConf/
├──depends
├──build
└──install
ConfigureBuildConfigs
Thestepstobuildpackageandpackpackageareconfiguredunder${project_path}/SynoBuildConf/.Youcanseethreefiles:
depends:configuredependenciesbetweenprojectsbuild:configurestepstobuildpackageinstall:configurestepstopackpackageinto.spkfile
ThisexamplewillechosomemessagesbyaprogramwritteninClanguage,soitisneccessarytocompileprograminbuildstage.WeapplyMakefileinthisexampletohelpusdoingcrosscompilation.
Wedonotconcernwhatyoudoinbuildconfigurationsothatitcanevendonothing.Thebuildsystemwilljustchrootintoenvironmentthencallthecorrespondingbuild,installscriptaccordingtothecommands.
ConfigureProperties
ThepackageinformationanditsbehaviorarecontrolledbyINFO.shwhichwillbetranslatedintoINFOfileininstall.
#!/bin/bash
#INFO.sh
source/pkgscripts/include/pkg_util.sh
YourFirstPackage
15
package="ExamplePackage"
version="1.0.0000"
os_min_ver="7.0-40000"
displayname="ExamplePackagePackage"
description="thisisanexamplepackage"
arch="$(pkg_get_unified_platform)"
maintainer="SynologyInc."
pkg_dump_info
ConfigureLifecycleBehaviourThepackagecontrolscriptscanbefoundat${project_path}/scripts/.YoucancontrolthebehaviourineachstagesuchascallingaexamplePkgprogramonpackagestart/stop.
#!/bin/sh
#scripts/start-stop-status
case$1in
start)
examplePkg"Start"
echo"HelloWorld">$SYNOPKG_TEMP_LOGFILE
exit0
;;
stop)
examplePkg"Stop"
echo"HelloWorld">$SYNOPKG_TEMP_LOGFILE
exit0
;;
status)
exit0
;;
esac
WriteaprogramandconfigureitscompilationandinstallationItiscommontobringcompiledprogramintoDSMviapackage.YoucanjustwriteyourprograminCandaddaMakefiletocompileyourprograms.
//examplePkg.c
#include<sys/sysinfo.h>
#include<syslog.h>
#include<stdio.h>
intmain(intargc,char**argv){
structsysinfoinfo;
intret;
ret=sysinfo(&info);
if(ret!=0){
syslog(LOG_SYSLOG,"Failedtogetinfo\n");
return-1;
}
syslog(LOG_SYSLOG,"[ExamplePkg]%ssamplepackage...",argv[1]);
syslog(LOG_SYSLOG,"[ExamplePkg]TotalRAM:%u\n",(unsignedint)info.totalram);
syslog(LOG_SYSLOG,"[ExamplePkg]FreeRAM:%u\n",(unsignedint)info.freeram);
return0;
}
#Makefile
include/env.mak
EXEC=examplePkg
OBJS=examplePkg.o
all:$(EXEC)
$(EXEC):$(OBJS)
$(CC)$(CFLAGS)$<-o$@$(LDFLAGS)
install:$(EXEC)
YourFirstPackage
16
mkdir-p$(DESTDIR)/usr/bin/
install$<$(DESTDIR)/usr/bin/
clean:
rm-rf*.o$(EXEC)
Anyadditionalfiles(e.g.,compiledprogram,mediaresources)shouldbepackedintopackage.tgzfileinside.spk.Weprovideseveralscriptcommandstodosuchoperations.Inthisexample,wewillpackcompiledexamplePkgexecutableviainstallbuildscript.
#SynoBuildConf/install(partial)
create_package_tgz(){
localfirewere_version=
localpackage_tgz_dir=/tmp/_package_tgz
localbinary_dir=$package_tgz_dir/usr/bin
rm-rf$package_tgz_dir&&mkdir-p$package_tgz_dir
mkdir-p$binary_dir
cp-avexamplePkg$binary_dir
makeinstallDESTDIR="$package_tgz_dir"
pkg_make_package$package_tgz_dir"${PKG_DIR}"
}
BuildAndPackThePackage
Afteryouhavefinishedpreparingthepackagesourcecode,youcanusethefollowingcommandstobuildandpackthepackageinto.spkat/toolkit/result_spk/${package}-${version}/*.spk.
cd/toolkit/pkgscripts-ng/
./PkgCreate.py-v7.0-pavoton-cExamplePackage
/toolkit/
├──pkgscripts-ng/
├──build_env/
│└──ds.${platform}-${version}
└──result_spk/
└──${package}-${version}/
└──*.spk
InstallAndTestThePackageGotoDSM>PackageCenter>ManualInstallthenselectyour.spkfiletodoinstallation.
Onceyouhaveinstalledandstartedthepackage,youcanseeitsmessageonUIandlogat/var/log/messages.
YourFirstPackage
17
ReadMore
SynologyToolkitSynologyPackageSynologyDSMIntegrationPackageExamples
YourFirstPackage
18
SynologyToolkitInthissection,wewillexplaintheworkflowofPackageToolkit.IfyouwanttobuildaSynologyPackagewithoutusingPackageToolkit,youmust:
PrepareacrosscompiletoolchainPrepareabuildenvironmentPreparemetadataCompilesourcecodePackthepackage
Creatingapackagemanuallycanbeverycomplexformostdevelopers,sowerecommendedusingthePackageToolkittomakethepackagecreationprocesseasier.
/toolkit/
├──build_env/
│└──ds.${platform}-${version}/
└──pkgscripts-ng/
├──EnvDeploy
└──PkgCreate.py
CreatePackageWorkflow:TherearetwostagesinthePkgCreate.pypackagecreationprocess:
BuildStage:compileyourprojectandalldependentprojectsinthecorrectorder.PackStage:packyourprojectintoan.spkfile
Tocreateyour.spkfilewithPkgCreate.pyproperly,youneedtoprovideadditionalconfigurationfilesandbuildscriptstodescribehowtobuildyourproject.Thesefilesareputinafoldernamed“SynoBuildConf”underyourproject.
SynoBuildConf/depends:definesthedependencyofyourproject.Forfurtherdetails,pleaserefertoBuildStageSynoBuildConf/build:specifiesPkgCreate.pyonhowtocompileyourproject.Forfurtherdetails,pleaserefertoBuildStageSynoBuildConf/install:specifiesPkgCreate.pyonhowtopackyourSPKfile.Forfurtherdetails,pleaserefertoPackStageSynoBuildConf/install-dev:similartoSynoBuildConf/install,butthiswillpackyour.spkfileinchrootenvironmentratherthangeneralDSMsystem.Forfurtherdetails,pleaserefertoCompileOpenSourceProject:nmap.
SynologyToolkit
19
SynologyToolkit
20
BuildStage:IntheBuildStage,PkgCreate.pywillcompiletheprojectanditsdependentprojects.Pleasenotethatinthisstage,PkgCreate.pydependsontwobuildscripts(SynoBuildConf/buildandSynoBuildConf/depends)togetthenecessaryinformation.
PkgCreate.py-v${version}-p${platform}${project}#buildprojectinspecificplatformversion
/toolkit/
├──build_env/
│└──ds.${platform}-${version}/
├──pkgscripts-ng/
│├──EnvDeploy
│└──PkgCreate.py
└──source/
└──${project}/
└──SynoBuildConf/
├──depends
├──build
└──install
BuildStageWorkflow:
1. BasedonyourSynoBuildConf/depend,PkgCreate.pywilllocatethetargetDSMversionfrom[default]section.2. PkgCreate.pywillresolvetheprojectsyoudependon.3. Yourprojectandthedependentprojectswhichareplacedunder/toolkit/sourcewillbehard-linkedto
/toolkit/build_env/ds.${platform}/source.4. TheirSynoBuildConf/buildwillbeexecutedinorderaccordingtotheirdependencybasedoneachSynoBuildConf/depend.5. Ifyourprojectisneededbyotherprojectforcrosscompiling,youmayaddSynoBuildConf/install-devscript.install-dev
scriptwillinstallcrosscompiledproductintoplatformchroot.
Note:SynoBuildConf/buildisexecutedunderchrootenvironment/toolkit/build_env/ds.${platform}.
BuildStage
21
SynoBuildConf/depends
PkgCreate.pywillresolveyourdependencyaccordingtothisconfigurationfile.Youneedtospecifyyourprojectdependencyandthebuildenvironmentofyourprojectinthisfile.Forexample:
[BuildDependent]
#eachlinehereisadependentproject
[ReferenceOnly]
#eachlinehereisaprojectforreferenceonlybutnoneedtobebuilt
[default]
all="7.0"#toolkitenvironmentversionofspecificplatform.(allplatformuse7.0toolkitenvironment)
TherearethreefieldsinSynoBuildConf/depends:
BuildDependent:Describesotherprojectswhicharedependentonthisproject.Forfurtherdetailsaboutthisfield,pleaserefertoCompileOpenSourceProject:nmap.ReferenceOnly:Describesotherprojectswhicharereferredbythisproject,withoutthebuildprocess.default:Describesthetoolkitenvironment.Thissectionisanecessaryfield.ItindicateseachplatformtobuildagainstsomeDSMversionandthekey"all"meansallplatformusethisversionbydefault.
YoucanuseProjDepends.pyscripttoseewhetherthedependencyorderofyourprojectsiscorrect.Option-x0willtraversealldependentprojectsof${project}.
cd/toolkit/pkgscripts-ng
./ProjDepends.py-x0${project}
Ifyourapplicationcontainsmorethanoneproject,putthemin/toolkit/sourceandeditSynoBuildConfaccordinglyforeachofthem.Foradvancedusage,youmayrefertoCompileOpenSourceProjectandReferences.
BuildStage
22
SynoBuildConf/build
SynoBuildConf/buildisashellscriptthattellsPkgCreate.pyhowtocompileyourproject.Thecurrentworkingdirectoryofthisshellscriptislocatedin/source/${project}underchrootenvironment.
Allpre-builtbinaries,headers,andlibrariesareundercrosscompilersysrootinchrootenvironment.Sincesysrootisthedefaultsearchpathofcrosscompiler,youdonotneedtoprovide-Ior-LtoCFLAGSorLDFLAGS.
Variables:
Youcanalsofindmostofthemin/toolkit/build_env/ds.${platform}-${version}/{env.mak,env32/64.mak}.TheycanbeusedinSynoBuildConf/build:
CC:pathofgcccrosscompiler.CXX:pathofg++crosscompiler.LD:pathofcrosscompilerlinker.CFLAGS :globalcflagsincludes.AR:pathofcrosscompilerar.NM:pathofcrosscompilernm.STRIP:pathofcrosscompilerstrip.RANLIB:pathofcrosscompilerranlib.OBJDUMP:pathofcrosscompilerobjdump.LDFLAGS :globalldflagsincludes.ConfigOpt:optionsforconfigure.ARCH:processorarchitecture.SYNO_PLATFORM:Synologyplatform.DSM_SHLIB_MAJOR:majornumberofDSM(integer).DSM_SHLIB_MINOR:minornumberofDSM(integer).DSM_SHLIB_NUM:buildnumberofDSM(integer).ToolChainSysRoot:crosscompilersysrootpath.SysRootPrefix:crosscompilersysrootconcatwithprefix/usr.SysRootInclude:crosscompilersysrootconcatwithinclude_dir/usr/include.SysRootLib:crosscompilersysrootconcatwithlib_dir/usr/lib.
#SynoBuildConf/build
case${MakeClean}in
[Yy][Ee][Ss])
makedistclean
;;
esac
make${MAKE_FLAGS}
TheaboveexamplecallsthemakecommandandcompilesyourprojectaccordingtoyourMakefilelocatedin/source/${project}.
Synologytoolkitenvironmenthasincludedselectedprebuildprojects.Youcanenterthechrootandusefollowingcommandstocheckifneededheaderorprojectisprovidedbytoolkit.
##innerchroot
dpkg-l#listalldpkgprojects.
dpkg-L{projectdev}#listprojectinstallfiles
dpkg-S{header/librarypattern}#searchheader/librarypattern.
Forexample,theprojectneedszlib.handlibz.sointhebuildstage.Usefollowingcommandtocheckifzlibanditscomponentareinstalledinchroot.
BuildStage
23
chroot/tookit/build_env/ds.avoton-7.0/
##innerchroot
>>dpkg-l|grepzlib
iizlib-1.x-avoton-dev7.0-7274allSynologybuild-timelibrary
>>dpkg-Lzlib-1.x-avoton-dev
/.
/usr
/usr/local
/usr/local/x86_64-pc-linux-gnu
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/libz.so
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/libz.a
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/pkgconfig
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/pkgconfig/zlib.pc
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/libz.so.1
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/libz.so.1.2.8
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/include
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/include/zconf.h
/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/include/zlib.h
>>dpkg-Szlib.so
zlib-1.x-avoton-dev:/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/libz.so
zlib-1.x-avoton-dev:/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/libz.so.1.2.8
zlib-1.x-avoton-dev:/usr/local/x86_64-pc-linux-gnu/x86_64-pc-linux-gnu/sys-root/usr/lib/libz.so.1
Someopensourceprojectsrequiretouseotherprojects'crosscompiledproductwhilebuildingtheirown.Forexample,pythonneedslibffiandzlibwhileconfigure,weneedtoprovidethosetwoprojectbeforebuildpython.Youcaninstallthecrosscompiledproductintothedestinationyouwantinbuildscript.PleaserefertoCompileOpenSourceProject:nmapformoreinformation.
Makefile
ThefollowingexampleshowsaMakefile.Mostofthecontentcontainstypicalmakefilerules.NotethatwhenwritingyourprojectMakefile,youcanutilizepre-definedvariablesin/env.mak.
##YoucanuseCCCFALGSLDLDFLAGSCXXCXXFLAGSARRANLIBREADELFSTRIPafterincludeenv.mak
include/env.mak
EXEC=examplePkg
OBJS=examplePkg.o
all:$(EXEC)
$(EXEC):$(OBJS)
$(CC)$(CFLAGS)$<-o$@$(LDFLAGS)
install:$(EXEC)
mkdir-p$(DESTDIR)/usr/bin/
install$<$(DESTDIR)/usr/bin/
clean:
rm-rf*.o$(EXEC)
Formoredetaileddescriptionsaboutmakefile,pleaserefertothearticlehere.
BuildStage
24
PackStage:InthePackStage,PkgCreate.pypacksallthenecessaryfilesaccordingtoyourmetadataandcreatesa.spkat/toolkit/result_spk.IfyouwantPkgCreate.pytoenterthePackStagewithouttheBuildStage,simplyrunPkgCreate.pywiththe-ioption.
cd/toolkit
pkgscripts-ng/PkgCreate.py-i${project}
/toolkit/
├──build_env/
│└──ds.${platform}-${version}/
├──pkgscripts-ng/
│├──EnvDeploy
│└──PkgCreate.py
└──source/
└──${project}/
└──SynoBuildConf/
├──depends
├──build
└──install
PackStageWorkFlow:
1. PkgCreate.pywillexecutethebuildscriptSynoBuildConf/install.i. CreateINFOfilebyusingINFO.sh.ii. Movenecessaryfilestoatemporaryfolder,/tmp/_install,forinstance,andcreatepackage.tgz.iii. Movenecessarymetadataandresourcestothetemporaryfolder,/tmp/_pkg,forinstance,andcreatethe.spkfile.
2. PkgCreate.pywillsignthenewlycreated.spkfilewithagpgkeywhichisplacedunder/root/(thepackagesigningmechanismisdeprecatedafterDSM7.0).
PackStage
25
SynoBuildConf/install
Thisfilemustbewritteninbashandindicatesonhowtopackyourproject.Thecurrentworkingdirectoryis/source/${project}underchrootenvironment.Ifthisisthetopprojectofyourpackage,thisfilewilldefinehowtocreatethe.spkfile,includingdirectorystructureandtheINFOfile.
#!/bin/bash
###UsePKG_DIRasworkingdirectory.
PKG_DIR=/tmp/_test_spk
rm-rf$PKG_DIR
mkdir-p$PKG_DIR
###getspkpackingfunctions
source/pkgscripts-ng/include/pkg_util.sh
create_inner_tarball(){
localinner_tarball_dir=/tmp/_inner_tarball
###cleardestinationdirectory
rm-rf$inner_tarball_dir&&mkdir-p$inner_tarball_dir
###installneededfileintoPKG_DIR
makeinstallDESTDIR="$inner_tarball_dir"
###createpackage.txz:$1=source_dir,$2=dest_dir
pkg_make_inner_tarball$inner_tarball_dir"${PKG_DIR}"
}
create_spk(){
localscripts_dir=$PKG_DIR/scripts
###CopyPackageCenterscriptstoPKG_DIR
mkdir-p$scripts_dir
cp-avscripts/*$scripts_dir
PackStage
26
###Copypackageicon
cp-avPACKAGE_ICON*.PNG$PKG_DIR
###GenerateINFOfile
./INFO.sh>INFO
cpINFO$PKG_DIR/INFO
###Createthefinalspk.
#pkg_make_spk<sourcepath><destpath><spkfilename>
#Pleaseputtheresultspkinto/image/packages
#spknamefunctions:pkg_get_spk_namepkg_get_spk_unified_namepkg_get_spk_family_name
mkdir-p/image/packages
pkg_make_spk${PKG_DIR}"/image/packages"$(pkg_get_spk_family_name)
}
create_inner_tarball
create_spk
Atthebeginning,thescriptcalledthePrepareDirsfunctionwhichwillpreparethenecessaryfolderfortheproject.
Aftercreatedthefolder,thescriptcalledSetupPackageFilestomovenecessaryresourcefilesto$INST_DIRand$PKG_DIR.Inthisstep,wecalledtheINFO.shfiletocreatetheINFOfile.AlthoughyoumayputthecodesthatgeneratetheINFOfileintheSynoBuildConf/installscript,wehighlyrecommendthatyoucreatetheINFOseperately.Generally,wenameitINFO.sh.YoucanseehowtowriteINFO.shinthefollowingsubsections.
Aftermovingtheresourcefiletotheproperlocation,wecalledtheMakePackagefunctiontocreatethepackage.Weincluded/sourcedascriptcalledpkg_util.shwhichislocatedat/pkgscripts-ng/include.Thepkg_make_packageandpkg_make_spkdefinedinpkg_util.shcanhelptocreatepackage.tgzand.spk.
pkg_make_inner_tarball$1$2:Createpackages.tgzof$2fromfilesin$1.pkg_make_spk$1$2:Createspkof$2fromfilesin$1.
INFO.shAsmentionedearlier,INFO.shisjustanoptionalscript.YoucancreatetheINFOfilebyhandormovethecodetoSynoBuildConf/install.However,westronglyrecommendthatyouutilizeINFO.shsothatyoucancreatetheINFOfileseparatelyfromSynoBuildConf/install.
#!/bin/bash
source/pkgscripts-ng/include/pkg_util.sh
package="ExamplePkg"
version="1.0.0000"
displayname="ExamplePackage"
maintainer="SynologyInc."
arch="$(pkg_get_unified_platform)"
description="thisisaExamplepackage"
["$(caller)"!="0NULL"]&&return0
pkg_dump_info
Theabovecodeisjustanexampletoshowsomeimportantvariablesforpkg_dump_info.IfyouwanttoknowmoredetailsabouttheINFOfileandeachfields,pleaserefertoINFO.
SimilartoSynoBuildConf/install,wemustfirstincludepkg_util.sh.Afterthat,wecansetuppropervariablesandcallthepkg_dump_infotocreatetheINFOfilecorrectly.Asyoumayhavenoticed,weusedanotherhelperfunctioncalledpkg_get_platformtosetthearchitecturevariable.Thisvariableindicatesthecurrentplatformwearebuilding.
pkg_get_spk_platform:Returnplatformfor“arch”inINFO.pkg_dump_info:DumpINFOaccordingtogivenvariables.
PackStage
27
RemembertomakeINFO.shbeexecutable(e.g.,chmod+xINFO.sh)
SpkPackingFunctions
Synologypackageframeworkprovidesseveralfunctionstoimproveefficiencyofpackingpackages.ThefunctionssuchasgeneratingarchitectureinformationintheINFOfile,separating.spknameandcreating.spkwillbeenabledafterimport/pkgscripts-ng/include/pkg_util.sh.
SpkPlatformFunctions
A.spkcanbeinstalledononeormoreplatforms.YoucandecidewhichplatformcanbeinstalldviaINFOfile.
functionname Values Description
(Nofunction) noarch Packageonlycontainscripts.spkcanberunonallsynologyModels.
pkg_get_platform_family x86_64i686armv7armv5ppc...
Unifyplatformswithsamekernelintoaplatformfamily.Thepackagecanrunonsamefamilyofsynologymodels.
pkg_get_spk_platform bromolowcedarviewqoriqarmadaxp...
Directlyoutputtheplatformwherethetoolkitenvironmentisused.Thepackagecanonlyrunonthespecificplatform.
Ifyourpackagedoesn'thaveanynativebinary,youcanusenoarchastheplatfromandwritethescriptsforyourpackage.Packagewitharch=noarchcanbeinstalledontoanysynologymodel.Ifyourpackagedoesn’thaveanykernelrelatedfunctions,thepackagecanrunonthesamearchitectureplatforms.Usefunctionpkg_get_platform_familytogetplatformfamily.Packagecanbeinstalledonthemodelsincludedinthesameplatformfamily.Forexample,packagewitharch=x86_64canbeinstallontobromolowcedarviewbroadwellmodels.Ifyourpackagecontainskernelrelatedfunctions,everyplatformswillneedaspecificspk.Pleaseusefunctionpkg_get_spk_platformtogettheplatform(s)whichiscompatiablewithyourenvironment.
SpkNamingFunctions
Afterspkgenerated,weneedtodistinguishspknamebyplatform.Wecanusespknamefunctions:
Functionname Correspondingplatformfunction Example Description
pkg_get_spk_name pkg_get_spk_platform
examplePkg-bromolow-1.0.0000.spk/examplePkg-cedarview-1.0.0000.spk...
Spknamedependsonwhichtoolkitenvironmentisusing.
pkg_get_spk_name noarch examplePkg-1.0.0000.spk
Ifthepackagehasplatform="noarch",thisfunctionwilloutputspknamewithoutplatforminfo.
pkg_get_spk_family_name pkg_get_platform_familyexamplePkg-x86_64-1.0.0000.spk
Spknamewillbeunifiedintoplatformfamily.Sameplatformfamilywillgeneatethesamespkname.i.ebromolowandx64willhavesamespkname.
YouneedtousepathofINFOasargument.Ifnopathspecified,thefunctionwillgetINFOfilefrom$PKG_DIR/INFOautomatically.
SpkCreationFunctions
Developercanusepkg_make_spktocreatespk.
pkg_make_spk$source_path$dest_path$spk_name
PackStage
28
source_pathisspksourcedirectory.Allspkfilesmustcopyintothisdirecotrybeforerunpkg_make_spk.dest_pathistargetspkpath.spk_nameisspknamewith/withoutplatforminfo.
Example:
pkg_make_spk/tmp/_test_spk"/image/packages"$(pkg_get_spk_family_name)
PackStage
29
SignPackage(onlyforDSM6.X)SigningmechanismisdeprecatedafterDSM7.0,youdon'tneedthisifyouaredevelopingpackageforDSM7.0
BetweenDSM5.1andDSM6.X,wehaveabuilt-incodesignmechanismtoensurethepackage'spublisherintegrity.ThetoolkithasaCodeSign.phpscripttosignthepackagewithGnuPGkeys.IfyoudonothaveaGPGkey,youwillneedtogenerateone.
SetupexistingGPGkey
IfyouhaveyourownGPGkey(withoutapassphrase)already,youwillneedtoputtheprivatekeyunder/root/.gnupgofeachplatform(e.g.,/toolkit/build_env/ds.${platform}-6.2/root/.gnupg/).
ThepackagesigningscriptsnowonlysupportkeysgeneratedbyGPG2.1.Ifyoudon'thaveyourownGPGkeyoryouareusingGPGkeysinGPG2.2format,youneedtoprepareGPGtoolandgenerateone.
SetupGPGtoolprovidedbydistIfyourdistprovidesGPG2.1,installgpgwithyourpackagemanagementtoolinyourdist.Forubuntudevelopers,youmayrunapt-getinstallgpggpg-agenttosetupGPGtool.
MakesureyouareusingGPG2.1.IfyourdistdoesnotprovidesGPG2.1,FollowtheinstructionsinthenextsectiontoprepareyourGPGtool.
SetupGPGtoolwithdocker
Assumeyou'redevelopingonavotonplatformwithDSMversion6.2,and/tmp/gpgkeyisthetemporaryfoldersavingtheGPGkeygenerated.
mkdir/tmp/gpgkey
dockerrun--rm-it-v/tmp/gpgkey:/root/.gnupg-eGPG_TTY=/dev/consolevladgh/gpg:0.2.3--gen-key
mv/tmp/gpgkey/path/to/build_env/ds.avoton-6.2/root/.gnupg
GenerateGPGkeywithgpg
gpg--gen-key
>Pleaseselectwhatkindofkeyyouwant:
(1)RSAandRSA(default)
>choosekeysizeandenteryourname,email
>enterapassphrase:justpressEnterwithouttypinganycharacter
WARNING:Pleasemakesurethatyoudonottypeanycharactersinthepassphrasefield,otherwisethebuildprocesswillFAIL.
Aftercompletingthestepsabove,thekeywillbegeneratedunder~/.gnupg.Youneedtomovethemintothechrootenvironment.
cp~/.gnupg/*/toolkit/build_env/ds.${platform}-6.2/root/.gnupg/
Youcanalsousethefollowingcommandstoverifywhetherthekeyhassuccessfullyimportedornot.
cd/toolkit/build_env/ds.${platform}-6.2/
chroot.
SignPackage(onlyforDSM6.X)
30
gpg-K
Theoutputmayproducethefollowingmessage:
/root/.gnupg/secring.gpg
------------------------
sec2048R/145E0AFD2015-12-21
uidSynologyInc.<synology_inc@synology.com>
ssb2048R/E0C20F112015-12-21
Signthepackage
IfyouwantPkgCreate.pytosignthepackageautomatically,youcanusethePkgCreate.pywithoutthe--no-signoption.Forexample,thefollowingcommandindicatesPkgCreate.pytobuildandinstallyourprojectwithoutasignature.
PkgCreate.py-i${project}
Inaddition,ifyouwanttosignthepackageonyourown,youcanusethefollowingcommandtosignyourpackagemanually.
chroot/toolkit/build_env/ds.${platform}-${version}
php/pkgscripts-ng/CodeSign.php[option]--sign=package-path
Options:
--keydir=keyringsdirectory(defaultis/root/.gnupg)
--keyfpr=key'sfingerprint(defaultis"".Underthiscircumstances,wewillusingthefirstkeyinthekeydirectorytosign
thepackage)
Examples:
php/pkgscripts-ng/CodeSign.php--sign=phpBB-3.0.12-0031.spk
php/pkgscripts-ng/CodeSign.php--keydir=/root/.gpg--keyfpr=C1BF63CD--sign=phpBB-3.0.12-0031.spk
SignPackage(onlyforDSM6.X)
31
ReferencesThissectionillustratesadvancedtypesofusageforthePackageToolkit.
PkgCreate.pyCommandOptionList
ThefollowingtablelistssomeofthePkgCreate.pycommands.
OptionName OptionPurpose
(default) Runbuildstageonlywhichincludelinkandcompilesourcecode.It'sthesameas-Uoption.
-p Specifytheplatformyouwanttopackyourproject.
-x Builddependentprojectlevel.EachprojectisbuiltaccordingtotheirownSynoBuildConf/build(e.g.,-x0,-x1)
-c Runbothbuildstageandpackstagewhichincludelinksourcecode,compilesourcecode,packpackageandsignthefinalspk.
-U Runbuildstageonlywhichincludeslinkandcompilesourcecode.
-l Runbuildstageonly,butwillonlylinkyoursourcecode.
-L Runbuildstageonly,butwillcompileyoursourcecodeonly.
-I Runpackstageonly,whichwillpackandsignyourspk.
--no-sign TellsPkgCreat.pynottosignyourspkfile.forexample,PkgCreat.py-I--no-sign${project}
-z Runallplatformsconcurrently.
-J Compileyourprojectwith-Jmakecommandoptions.
-S Disablesilentmake.
Thefollowingtableshowstherelationshipbetweencommandoptionsindifferentstages.Youcanchoosetheproperoptionsbasedonyourneeds.Option-cisenoughformostcases.
Stage Action (default) -l -L -U -I--no-sign -I -c
BuildStage LinkSourcecode Yes Yes No Yes No No Yes
BuildStage CompileSourcecode Yes No Yes Yes No No Yes
PackStage PackPackage No No No No Yes Yes Yes
PackStage SignPackage No No No No No Yes Yes
Platform-SpecificDependency
Platform-specificdependencymeansyoucanhaveseveraldependentprojectsfordifferentplatformsbyappending":${platform}"tothefollowingsections:BuildDependentandReferenceOnly.Thefollowingexampleshows816xandaramda370projectsthatareonlibbar-1.0.
#SynoBuildConf/depends
[BuildDependent]
libfoo-1.0
[BuildDependent:816x,armada370]
libfoo-1.0
References
32
libbar-1.0
[default]
all="7.0"
CollecttheSPKFileinYourOwnWayBydefault,PkgCreate.pywillmovetheSPKfileto/toolkit/result_spkaccordingto/toolkit/build_env/ds.${platform}-${version}/source/${project}/INFO.Youcanhaveyourowncollectoperationbyaddingahook,SynoBuildConf/collect.SynoBuildConf/collectcanbeanyexecutableshellscript(soremembertochmod+x)andPkgCreate.pywillpassthefollowingenvironmentvariablestoit:
SPK_SRC_DIR:SourcefolderoftargetSPKfile.SPK_DST_DIR:DefaultdestinationfoldertoputSPKfile.SPK_VERSION:Versionofpackage(accordingtoINFO).
ThecurrentworkingdirectoryofSynoBuildConf/collectis/source/${project}willbeunderchrootenvironment.
References
33
PackageIntroductionInthissection,youwilllearnthelayoutofsynologypackage(.spk)andthemeaningofeachfile.
spk
├──INFO
├──package.tgz
├──scripts
│├──postinst
│├──postuninst
│├──postupgrade
│├──preinst
│├──preuninst
│├──preupgrade
│└──start-stop-status
├──conf
│├──privilege
│└──resource
├──LICENSE
├──PACKAGE_ICON.PNG
└──PACKAGE_ICON_256.PNG
PackageStructureASynologypackagecontainsthefollowingfiles:
File/FolderName(casesensitive) Required Description File/Folder
TypeDSM
Requirement
INFO O Thisfiledescribesthepropertiesofapackage.
PropertiesFile 2.0-0731
package.tgz O
Thisisacompressedfilecontainingallthefilesthatshouldbeextractedintothesystem,suchasexecutablebinaries,libraries,orUIfiles.
TGZFile 2.0-0731
scripts O Thisfoldercontainsshellscriptswhichcontrolthelifecycleofapackage. Folder 2.0-0731
conf O Thisfoldercontainsadditionalconfigurations. Folder 4.2-3160
LICENSE XThefilecontentwillshowonUIintheinstallationprocedure.Itmustbelessthan1MB.
TextFile 3.2-1922
PACKAGE_ICON.PNG O
PNGformatimageshowninPackageCenterForDSM6.x,thedimensionshouldbe72x72.ForDSM7.0orabove,theimagedimensionshouldbe64x64.
PNGfile 3.2-1922
PACKAGE_ICON_256.PNG OPNGformatimageshowninPackageCenter.Itsdimensionshouldbe256x256.
PNGfile 5.0-4400
Tocreatesuchpackagelayout,pleaserefertothePackStagefordetailedsteps.
SynologyPackage
34
SynologyPackage
35
INFOThisfiledescribesthepropertiesofapackage
INFOFieldFormat:
Eachpropertyisdefinedaskey/valuepairseparatedbyanequalssign
key=value
INFOFieldList:
Youcandefinepropertiesaccordingtotherequirements:
NecessaryFieldsOptionalFields
thirdparty="yes"
maintainer="mycompany"
description="mydescription"
distributor="mycompany"
package="mypackagename"
silent_install="yes"
silent_uninstall="yes"
silent_upgrade="yes"
os_min_ver="7.0-40000"
version="0.0.1-0001"
arch="noarch"
HowtowriteanINFOFileInsteadofwritingtheINFOfilemanually,youcanusethehelperfunctionsinPackageToolkittogeneratesomefieldsprogrammatically.PleaserefertoINFO.shformoreinformation.
INFO
36
FieldName:package
Description:Packageidentity.Nomorethanoneversionofapackagecanexistatthesametimeintheenduser'sDSM;therefore,theidentificationisuniquetoidentifyyourpackage.Besides,PackageCenterwillcreatea/var/packages/[packageidentity]foldertoputpackagefiles.
Note:Thisvalueofthekeycannotcontainanyofthesespecialcharacters:,/,>,<,|or=.
Value:String
DefaultValue:(Empty)
Example:
package="DownloadStation"
DSMRequirement:2.0-0731
FieldName:versionDescription:Packageversion.Enduserscanidentifythepackageversion.
Note:
1. Eachversiondelimiterisonlyallowedtobe.-or_.2. Eachversionnumberwhichisdelimitedbydelimiterisonlyallowedtobenumber3. Versionvalueshouldbeintheformatof[featurenumber]-[buildnumber].Buildnumbershouldbeincreasedon
everyversionanditcanbeusedtodistinguishpackageversionsbetweendifferentDSMmajorversions.Value:String
DefaultValue:(Empty)
Example:
version="3.6-3263"
version="1.2.3-0001"
DSMRequirement:2.0-0731
FieldName:os_min_ver
Description:EarliestversionofDSMthatisrequiredtorunthepackage.Thevalueshouldbeatleast7.0-40000afterDSM7.0.Value:X.Y-ZDSMmajornumber,DSMminornumber,DSMbuildnumberDefaultValue:NoneExample:
os_min_ver="7.0-40000"
DSMRequirement:6.1-14715
FieldName:description
Description:PackageCentershowsashortdescriptionofthepackage.
Value:String
NecessaryFields
37
DefaultValue:(Empty)
Example:
description="DownloadStationisaweb-baseddownloadapplicationwhichallowsyoutodownloadfilesfromtheInternet
throughBT,FTP,HTTP,NZB,Thunder,FlashGet,QQDL,andeMule,andsubscribetoRSSfeedstokeepyouupdatedonthehot
testorlatestBT.ItofferstheautounzipservicetohelpyouextractcompressedfilestoyourSynologyNASwheneverfi
lesaredownloaded.WithDownloadStation,youcandownloadfilesfrommultiplefilehostingsites,andsearchfortorren
tfilesviasystemdefaultsearchenginesaswellasself-addedengineswiththeBTsearchfunction."
DSMRequirement:2.3-1118
DSMRequirement:4.2-3160
FieldName:arch
Description:ListtheCPUarchitectureswhichcanbeusedtoinstallthepackage.
Value:(archvaluesareseparatedwithaspace.PleasereferAppendixA:PlatformandArchValueMappingTabletomoreinformation)
DefaultValue:noarch
Note:
1. "noarch"meansthepackagecanbeinstalledandworkinanyplatform.Forexample,thepackageiswritteninPHPorshellscript.
2. Pleasenotpackallbinaryfileswithdifferentplatformstoonepackagespkfile.
Example:
arch="noarch"
or
arch="x86_64alpine"
DSMRequirement:2.0-0731
FieldName:maintainerDescription:PackageCentershowsthedeveloperofthepackage.
Value:String
DefaultValue:(Empty)
Example:
maintainer="SynologyInc."
DSMRequirement:2.0-0731
NecessaryFields
38
FieldName:displayname
Description:PackageCentershowsthenameofthepackage.Note:Ifdisplaynamekeyisempty,PackageCenterwilldisplaythevalueofpackagekey.
Value:StringDefaultValue:ThevalueofpackagekeyExample:NoneDSMRequirement:2.3-1118
FieldName:displayname_[DSMlanguage]
Description:PackageCentershowsthenameintheDSMlanguagesetbytheend-user.DSMsupportsthefollowinglanguages:enu(English)cht(TraditionalChinese)chs(SimplifiedChinese)krn(Korean)ger(German)fre(French)ita(Italian)spn(Spanish)jpn(Japanese)dan(Danish)nor(Norwegian)sve(Swedish)nld(Dutch)rus(Russian)plk(Polish)ptb(BrazilianPortuguese)ptg(EuropeanPortuguese)hun(Hungarian)trk(Turkish)csy(Czech)
Value:StringDefaultValue:packagenameExample:
displayname_enu="HelloWorld"
displayname_cht=""
DSMRequirement:2.3-1118
FieldName:description_[DSMlanguage]
Description:PackageCentershowsashortdescriptionintheDSMlanguagesetbytheend-user.DSMsupportsthefollowinglanguages:
enu(English)cht(TraditionalChinese)chs(SimplifiedChinese)krn(Korean)
OptionalFields
39
ger(German)fre(French)ita(Italian)spn(Spanish)jpn(Japanese)dan(Danish)nor(Norwegian)sve(Swedish)nld(Dutch)rus(Russian)plk(Polish)ptb(BrazilianPortuguese)ptg(EuropeanPortuguese)hun(Hungarian)trk(Turkish)csy(Czech)
Value:String
DefaultValue:descriptionExample:
description_enu="HelloWorld"
description_cht=""
DSMRequirement:2.3-1118
FieldName:maintainer_urlDescription:Ifapackagehasadeveloperwebpage,PackageCenterwillshowalinktolettheuseropenit.Value:StringDefaultValue:(Empty)Example:
maintainer_url="http://www.synology.com"
DSMRequirement:4.2-3160
FieldName:distributorDescription:PackageCentershowsthepublisherofthepackage.Value:StringDefaultValue:(Empty)Example:
distributor="SynologyInc."
DSMRequirement:4.2-3160
FieldName:distributor_url
Description:Ifapackageisinstalledandhasadistributerwebpage,PackageCenterwillshowalinktolettheuseropenit.Value:StringDefaultValue:(Empty)
OptionalFields
40
Example:
distributor_url="http://www.synology.com/enu/apps/3rd-party_application_integration.php"
DSMRequirement:4.2-3160
FieldName:support_url
Description:PackageCentershowsasupportlinktoallowuserstoseektechnicalsupportwhenneeded.
Value:String
DefaultValue:(Empty)
Example:
support_url="https://myds.synology.com/support/support_form.php".
FieldName:support_centerDescription:Ifsetto“yes,”PackageCenterdisplaysalinktomaketheenduserlaunchSynologySupportCenterApplicationwhenyourpackageisinstalled.
Note:Ifsetto“yes,”thereport_urllinkwon’tshowinPackageCenter.
Value:"yes"/"no"DefaultValue:"no"Example:NoneDSMRequirement:5.0-4458
FieldName:model
Description:Listofmodelsonwhichpackagescanbeinstalledinspesificmodels.ItisorganizedbySynologystring,architectureandmodelname.Value:(modelsareseparatedwithaspace,e.g.synology_88f6281_209,synology_cedarview_rs812rp+,synology_x86_411+II,synology_bromolow_3612xs,synology_cedarview_rs812rp+,…)DefaultValue:(Empty)Example:
model="synology_bromolow_3612xssynology_cedarview_rs812rp+".
DSMRequirement:4.0-2219
FieldName:exclude_arch
Description:ListtheCPUarchitectureswherethepackagecan'tbeusedtoinstallthepackage.Note:Becarefultousethisexclude_archfield.Ifthepackagehasdifferentexclude_archvalueinthedifferentversions,theendusercaninstallthepackageinthespecificversionwithoutsomearchvaluesofexclude_arch.
Value:(archvaluesareseparatedwithaspace.PleasereferAppendixA:PlatformandArchValueMappingTabletomoreinformation)DefaultValue:(Empty)Example:NoneDSMRequirement:6.0
OptionalFields
41
Example:
exclude_arch="bromolowcedarview".
FieldName:checksumDescription:ContainsMD5stringtoverifythepackage.tgz.Value:StringDefaultValue:(Empty)Example:NoneDSMRequirement:3.2-1922
FieldName:adminportDescription:ApackagelistenstoaspecificporttodisplayitsownUI.Ifthepackageisdefinedbyaport,alinkwillbeopenedwhenthepackageisstarted.
Note:adminprotocol,adminportandadminurlkeysarecombinedtoadminprotocol://ip:adminport/adminurllink
Value:0~65536DefaultValue:80Example:
adminport="9002"
DSMRequirement:2.0-0731
FieldName:adminurl
Description:Ifapackageisinstalledandhasawebpage,alinkwillbeopenedwhenthepackageisstarted.Note:adminprotocol,adminportandadminurlkeysarecombinedtoadminprotocol://ip:adminport/adminurllink
Value:StringDefaultValue:(Empty)Example:
adminurl="web"
DSMRequirement:2.3-1118
FieldName:adminprotocol
Description:ApackageusesaspecificprotocoltodisplayitsownUI.Ifapackageisinstalledandhasawebpage,aprotocolwillbeopenedwhenthepackageisstarted.
Note:adminprotocol,adminportandadminurlkeysarecombinedtoadminprotocol://ip:adminport/adminurllink
Value:http/https(Separatedwithaspace)DefaultValue:httpExample:
adminprotocol="http"
DSMRequirement:3.2-1922
OptionalFields
42
FieldName:dsmuidir
Description:DSMUIfoldernameinpackage.tgz.TheUIfolderofthepackagein/var/packges/[packgename]/target/[dsmuidir]willbeautomaticallylinkedtotheDSMUIfolderin/usr/syno/synoman/webman/3rdparty/[linkname]toshowyourpackage'sshortcutinDSM.
Note:
1. Ifonlyonepathisprovided,thepathwillbetherelativepathtodsmuidirinpackagetargetandthelinknamewillbepackagename.
2. Ifmultiplekey:valuepairsareprovided,thekeywillbethenameoflinkandthevaluewillbetherelativepathtodsmuidirinpackagetarget.
3. PleasereferIntegrateYourpackageintoDSMformoreinformation.Value:StringDefaultValue:(Empty)Example:
dsmuidir="ui"
dsmuidir="MyLinkName1:ui/app1MyLinkName2:ui/app2"
DSMRequirement:3.2-1922forsinglevalue7.0-40731formultiplevalues
FieldName:dsmappname
Description:ThevalueofeachindividualapplicationwillbeequaltotheuniquepropertynameinDSM’sconfigfilesoastobeintegratedintoSynologyDiskStation.
Note:PleasereferConfiginIntegrateYourpackageintoDSMchapterformoreinformation.
Value:(Separatedwithaspace)DefaultValue:(Empty)Example:
dsmappname="SYNO.SDS.PhotoStationSYNO.SDS.PersonalPhotoStation"
DSMRequirement:3.2-1922
FieldName:dsmapppageDescription:Theapplicationpagetoopenwhenclickonpackageopenbutton(shouldbeusedwithdsmappnamekey)Value:Pagename
Note:pagenamecorrespondstoPageListAppWindow'sfnvaluewhencallingSYNO.SDS.AppLaunch
DefaultValue:(Empty)Example:
dsmappname="SYNO.SDS.AdminCenter.Application"
dsmapppage="SYNO.SDS.AdminCenter.FileService.Main"
DSMRequirement:7.0-40332
FieldName:dsmapplaunchname
Description:Thevaluewillbeusedtolaunchdesktopapp,andithashigherprioritythandsmappname.Value:AppnameDefaultValue:sameasdsmappname
OptionalFields
43
Example:
dsmapplaunchname="SYNO.SDS.AdminCenter.Application"
DSMRequirement:7.0-40796
FieldName:checkport
Description:CheckifthereisanyconflictbetweentheadminportandtheportswhicharereservedorarelisteningonDSMexceptweb-serviceports(e.g.80,443)andDSMports(e.g.5000,5001).Value:"yes"/"no"DefaultValue:"yes"Example:NoneDSMRequirement:3.2-1922
FieldName:startable
Description:Whennoprograminthepackageprovidestheend-userwiththeoptionstoenableordisableitsfunction.Thiskeyissetto"no"andtheend-usercannotstartorstopthepackageinPackageCenter.
Note:Deprecatedafter6.1-14907,usectl_stopinstead.If“startable”issetto“no”,start-stop-statusscriptwhichrunsinbootuporshotdownisstillrequired.
Value:"yes"/"no"DefaultValue:"yes"Example:NoneDSMRequirement:3.2-1922
FieldName:ctl_stopDescription:Whennoprograminthepackageprovidestheend-userwiththeoptionstoenableordisableitsfunction.Thiskeyissetto"no"andtheend-usercannotstartorstopthepackageinPackageCenter.
Note:If“ctl_stop”issetto“no”,start-stop-statusscriptwhichrunsinbootuporshotdownisstillrequired.
Value:"yes"/"no"DefaultValue:"yes"Example:NoneDSMRequirement:6.1-14907
FieldName:ctl_uninstall
Description:Ifthiskeyissetto"no",theend-usercannotuninstallthepackageinPackageCenter.Value:"yes"/"no"DefaultValue:"yes"Example:NoneDSMRequirement:6.1-14907
FieldName:precheckstartstop
Description:Ifsetto"yes",letstart-stop-statuswithprestartorprestopargumentrunbeforestartorstopthepackage.Pleaserefertostart-stop-statusinscriptsformoreinformation.Value:"yes"/"no"
OptionalFields
44
DefaultValue:"yes"Example:NoneDSMRequirement:6.0
FieldName:helpurl
Description:Ifapackageisinstalledandhasa"help"webpage,PackageCenterwilldisplayahyperlinktotheuser.Value:StringDefaultValue:(Empty)Example:
helpurl="https://www.synology.com/en-global/knowledgebase"
DSMRequirement:3.2-1922
FieldName:beta
Description:Ifthispackageisconsideredthebetaversion,thebetainformationwillbeshowninPackageCenter.Value:"yes"/"no"DefaultValue:"no"Example:NoneDSMRequirement:6.0
FieldName:report_url
Description:Ifapackageisabetaversionandhasa"report"webpage,PackageCenterwilldisplayahyperlink.Ifthispackageisconsideredthebetaversion,thebetainformationwillbealsobeshowninPackageCenter.Value:StringDefaultValue:(Empty)Example:NoneDSMRequirement:3.2-1922
FieldName:install_reboot
Description:RebootDiskStationafterinstallingorupgradingthepackage.Value:"yes"/"no"DefaultValue:"no"Example:NoneDSMRequirement:3.2-1922
FieldName:install_dep_packages
Description:Beforeapackageisinstalledorupgraded,thesepackagesmustbeinstalledfirst.Inaddition,theorderofstartingorstoppingpackagesisalsodependentonit.Theformatconsistsofapackagename.Ifmorethanonedependentpackagesarerequired,thepackagenameofthepackage(s)willbeseparatedwithacolon,e.g.install_dep_packages="packageA".Ifaspecificversionrangeisrequired,packagenamewillbefollowedbyoneofthespecialcharacters=,<,>,>=,<=andpackageversionwhichiscomposedbynumberandperiods,e.g.install_dep_packages="packageA>2.2.2:packageB".
Note:>=and<=operatoronlysupportedinDSM4.2ornewer.Don’tuse<=and>=ifapackagecanbeinstalledinDSM4.1orolderbecauseitcannotbecomparedcorrectly.Instead,thepackageversionshouldbesetlowerorhigher.
OptionalFields
45
Value:PackagenamesNote:Eachpackagenameisseparatedwithacolon.
DefaultValue:(Empty)Example:
install_dep_packages="packageA"
or
install_dep_packages="packageA>2.2.2:packageB"
DSMRequirement:3.2-1922
FieldName:install_conflict_packagesDescription:Beforeyourpackageisinstalledorupgraded,theseconflictpackagescannotbeinstalled.Theformatconsistsofapackagename,e.g.install_conflict_packages="packageA".Ifmorethanoneconflictpackagesarerequiredwiththeformat,thenameofthepackage(s)willbeseparatedwithacolon,e.g.install_conflict_packages="packageA:packageB".Ifaspecificversionrangeisrequired,packagenamewillbefollowedbyoneofthespecialcharacters=,<,>,>=,<=andpackageversionwhichiscomposedbynumberandperiods,e.g.install_conflict_packages="packageA>2.2.2:packageB".
Note:>=and<=operatoronlysupportedinDSM4.2ornewer.Donotuse<=and>=ifapackagecanbeinstalledinDSM4.1becauseitcan’tbecomparedcorrectly.Instead,thepackageversionshouldbesetlowerorhigher.
Value:PackagenamesNote:Eachpackagenameisseparatedwithacolon.
DefaultValue:(Empty)Example:
install_conflict_packages="packageA:packageB"
or
install_conflict_packages="packageA>2.2.2:packageB"
DSMRequirement:4.1-2851
FieldName:install_break_packagesDescription:Afteryourpackageisinstalledorupgraded,theseto-be-brokenpackageswillbestoppedandremainbrokenduringtheexistenceofyourpackage.Theformatconsistsofapackagename,e.g.install_break_packages="packageA".Ifmorethanoneto-be-brokenpackagesarerequiredwiththeformat,thenameofthepackage(s)willbeseparatedwithacolon,e.g.install_break_packages="packageA:packageB".Ifaspecificversionrangeisrequired,packagenamewillbefollowedbyoneofthespecialcharacters=,<,>,>=,<=andpackageversionwhichiscomposedbynumberandperiods,e.g.install_break_packages="packageA>2.2.2:packageB".Value:Packagenames
Note:Eachpackagenameisseparatedwithacolon.
DefaultValue:(Empty)Example:
install_break_packages="packageA:packageB"
or
install_break_packages="packageA>2.2.2:packageB"
DSMRequirement:6.1-15117
FieldName:install_replace_packages
OptionalFields
46
Description:Afteryourpackageisinstalledorupgraded,theseto-be-replacedpackageswillberemoved.Theformatconsistsofapackagename,e.g.install_replace_packages="packageA".Ifmorethanoneto-be-replacedpackagesarerequiredwiththeformat,thenameofthepackage(s)willbeseparatedwithacolon,e.g.install_replace_packages="packageA:packageB".Ifaspecificversionrangeisrequired,packagenamewillbefollowedbyoneofthespecialcharacters=,<,>,>=,<=andpackageversionwhichiscomposedbynumberandperiods,e.g.install_replace_packages="packageA>2.2.2:packageB".Value:Packagenames
Note:Eachpackagenameisseparatedwithacolon.
DefaultValue:(Empty)Example:
install_replace_packages="packageA:packageB"
or
install_replace_packages="packageA>2.2.2:packageB"
DSMRequirement:6.1-15117
FieldName:install_dep_servicesDescription:Beforethepackageisinstalledorupgraded,theseservicesmustbestartedorenabledbytheend-user.Value:DSM4.2orolder:apache-web,mysql,php_disable_safe_exec_dirDSM4.3:apache-web,mysql,php_disable_safe_exec_dir,sshDSM5.0~DSM5.2:apache-web,php_disable_safe_exec_dir,ssh,pgsqlDSM6.0:ssh,pgsqlDSM7.0:ssh-shell,pgsql,network.target,network-online.target,nginx.service,avahi.service,atalk.service,crond.service,nfs-server.service
Note:Eachserviceisseparatedwithaspace.
DefaultValue:(Empty)Example:
install_dep_services="apache-webssh"
DSMRequirement:3.2-1922
FieldName:start_dep_services
Description:Beforethepackageisstarted,theseservicesmustbestartedorenabledbytheend-user.Ifstartableissetto“no”,thisvalueisignored.Value:DSM4.2orolder:apache-web,mysql,php_disable_safe_exec_dirDSM4.3:apache-web,mysql,php_disable_safe_exec_dir,sshDSM5.0~DSM5.2:apache-web,php_disable_safe_exec_dir,ssh,pgsqlDSM6.0:ssh,pgsqlDSM7.0:ssh-shell,pgsql,network.target,network-online.target,nginx.service,avahi.service,atalk.service,crond.service,nfs-server.service
Note:Eachserviceisseparatedwithaspace.
DefaultValue:(Empty)Example:
install_dep_services="apache-webssh"
DSMRequirement:3.2-1922
OptionalFields
47
FieldName:extractsize
Description:Thisvalueindicatestheminimalspacetoinstallapackage.Itwillbeusedtoprompttheuserifthereisenoughfreespacetoinstallit.
Note:
1. InDSM5.2ororder,thesizebasedonbyteunit.2. InDSM6.0ornewer,thesizebasedonkilobyteunit.
Value:SizeunitDefaultValue:ThebytesizeofSPKfileofpackageExample:
extractsize="253796"
DSMRequirement:4.0-2166
FieldName:support_conf_folder
Description:InDSM5.2ororder,ifyouwanttousesomespecialconfigurationfileswithina"conf"folder,thisvaluemustbesetto"yes".Moredetailsaregiveninthe"conf"section.Howerver,inDSM6.0ornewer,youdon'tneedtodefineitanymore.
Note:DeprecatedinDSM6.0
Value:"yes"/"no"DefaultValue:"no"Example:
support_conf_folder="yes"
DSMRequirement:4.2-3160~5.2
FieldName:install_typeDescription:Ifsetto“system”,yourpackagewillbeinstalledintherootfilesystem,/usr/local/packages/@appstore/,evenifthereisnovolume.
Note:Becarefulwhensettingthis,asitmayresultintheDiskStationcrashingifyourpackagerunsoutofthespaceintherootfilesystem.
Value:"system"DefaultValue:(Empty)Example:
install_type="system"
DSMRequirement:5.0-4458
FieldName:silent_install
Description:Ifsetto“yes”,yourpackageisallowedtobeinstalledwithoutthepackagewizardinthebackground.ThisallowsCMS(CentralManagementSystem)todistributepackageinstallationtootherNASconnected.Value:"yes"/"no"DefaultValue:"no"Example:
silent_install="yes"
OptionalFields
48
DSMRequirement:5.0-4458
FieldName:silent_upgrade
Description:Ifsetto“yes”,yourpackageisallowedtobeupgradedwithoutthepackagewizardinthebackground.Endusercannotmodifyanyinformationforupgrading.ThisallowsnotonlyyourpackagetobeupgradedautomaticallybutalsoforCMS(CentralManagementSystem)todistributepackageupgradestootherNASconnected.Value:"yes"/"no"DefaultValue:"no"Example:
silent_upgrade="yes"
DSMRequirement:5.0-4458
FieldName:silent_uninstall
Description:Ifsetto“yes”,yourpackageisallowedtobeuninstalledwithoutthepackagewizardinthebackground.ThisallowsCMS(CentralManagementSystem)todistributepackageuninstallationtootherNASconnected.Value:"yes"/"no"DefaultValue:"no"Example:
silent_uninstall="yes"
DSMRequirement:5.0-4458
FieldName:auto_upgrade_fromDescription:Itissettoaversionofyourpackage.Ifyourpackageissettosilent_upgrade="yes"andthevalueisset,PackageCenteronlyupgradesyourpackageautomaticallyfromtheinstalledpackagewiththeversionorthenewerversion.However,iftheenduserinstallaolderversionthanit,PackageCenterwon'tupgradeitautomaticallyandtheusermustupgradeitbythemself.Value:(apackageversion)DefaultValue:(Emptystring)Example:
auto_upgrade_from="2.0"
DSMRequirement:5.2-5565
FieldName:offline_installDescription:Ifsetto"yes",afterthepackageispublishedinsynologyserver,itwon'tbeshowninthepackagelistofPackageCenterfromSynologyserver.However,theusercaninstallthepackagemanually.Value:"yes"/"no"DefaultValue:"no"Example:
offline_install="yes"
DSMRequirement:DSM6.0
OptionalFields
49
FieldName:thirdparty
Description:Ifsetto“yes”,yourpackageisathird-partypackageandisn'tdevelopedbySynology.InPackageCenter,third-parypacakgeswillbeshowninanotherpart.
Note:It'snotusedinDSM5.0ornewer.
Value:"yes"/"no"DefaultValue:"no"Example:
thirdparty="yes"
DSMRequirement:4.0~4.3
FieldName:os_max_ver
Description:MaximumversionofDSMthatiscapabletorunthepackage.Value:X.Y-ZDSMmajornumber,DSMminornumber,DSMbuildnumberDefaultValue:NoneExample:
os_max_ver="6.1-14715"
DSMRequirement:6.1-14715
FieldName:support_move
Description:Ifsetto"yes",thepackagecanbemovedtoadifferentvolumeafterinstallation.Value:"yes"/"no"DefaultValue:"no"Example:
support_move="yes"
DSMRequirement:6.2-22306
FieldName:exclude_modelDescription:Listthemodelnameswherethepackagecan'tbeusedtoinstallthepackage.
Note:Becarefultousethisexclude_modelfield.Ifthepackagehasdifferentexclude_modelvalueinthedifferentversions,theendusercaninstallthepackageinthespecificversionwithoutsomemodelvaluesofexclude_model.
Value:modelvaluesareseparatedwithaspace.DefaultValue:(Empty)Example:
exclude_model="synology_cedarview_713+synology_kvmx64_virtualdsm"
DSMRequirement:7.0-40329
FieldName:use_deprecated_replace_mechanism
Description:ifsetto"yes",replaceewillbeuninstalledafterreplacerinstalled,andprereplace/postreplacescriptswillnotbe
OptionalFields
50
executed.Otherwise,replaceewillbeuninstalledbeforereplacerinstalled,andprereplace/postreplacewillbeexecuted.Value:"yes"/"no"DefaultValue:"no"Example:
install_replace_packages="packageA"
use_deprecated_replace_mechanism="yes"
DSMRequirement:7.0-40340
FieldName:install_on_cold_storage
Description:ifsetto"yes",thispackagecanbeinstalledoncoldstorage,whichhasverylargespacefordatastorage.Value:"yes"/"no"DefaultValue:"no"Example:
install_on_cold_storage="yes"
DSMRequirement:7.0-40726
OptionalFields
51
package.tgzThepackage.tgzisacompressedfile(tgz/xz)containingallthefilesyouwouldneedwhenbringingupyourapplicationssuchas:
executablefileslibraryfilesUIfilesconfigurationfiles
Youcanusepkg_make_packagefunctiontocreatethepackage.tgzinsteadofpackingitmanually.
Oncethepackageisinstalled,yourpackage.tgzwillbeextractedto/volume?/@appstore/[your_pkg_name]/or/usr/local/packages/@appstore/[your_pkg_name]/folder(dependingontheinstall_typeinINFO).Inthemeantime,therewillbeasoftlinkat/var/packages/[your_pkg_name]/targetpointingtotheassignedfolder.
Inadditiontothetargetdirectory,systemwillalsocreateotherdirectoriesforpackagetostoreitsdatafordifferentpurposes.DetailedinformationcanbefoundHERE.
package.tgz
52
scriptsThisfoldercontainsshellscriptscontrollingthelifecycleofapackage.
ScriptName Required Description
preinst O Itcanbeusedtocheckconditionsbeforeinstallationbutnottomakesideeffectsontothesystem.Packageinstallationwillbeabortedfornon-zeroreturnedvalue.
postinst O Itcanbeusedtoprepareenvironmentforpackageafterinstalled.Packagestatuswillbecomecorruptedfornon-zeroreturnedvalue.
preuninst O Itcanbeusedtocheckconditionsbeforeuninstallationbutnottomakesideeffectsontothesystem.Packageuninstallationwillbeabortedfornon-zeroreturnedvalue.
postuninst O Itcanbeusedtocleanupenvironmentforpackageafteruninstalled.
preupgrade O Itcanbeusedtocheckconditionsbeforeupgradebutnottomakesideeffectsontothesystem.Packageupgradewillbeabortedfornon-zeroreturnedvalue.
postupgrade O Itcanbeusedtoprepareenvironmentforpackageafterupgraded.Packagestatuswillbecomecorruptedfornon-zeroreturnedvalue.
prereplace X Itcanbeusedtododatamigrationwheninstall_replace_packagesisdefinedinINFOforpackagereplacement.Packagereplacementwillbeabortedfornon-zeroreturnedvalue.
postreplace X Itcanbeusedtododatamigrationwheninstall_replace_packagesisdefinedinINFOforpackagereplacement.Packagereplacementwillbeabortedfornon-zeroreturnedvalue.
start-stop-status O Itcanbeusedtocontrolpackagelifecycle.
Thesimplestimplemenationofscriptisjustdoingnothing:
#!/bin/sh
exit0
PleaserefertoScriptMessagesformechanismtoshowmessagestousers.
start-stop-status
#!/bin/sh
case"$1"in
start)
;;
stop)
;;
status)
;;
esac
exit0
Thisscriptisusedtostart,stopapackageanddetectrunningstatus.DSMwouldcallthisscriptwithdifferentparametersindifferentscenario:
start:Whenauserrunsthepackageorthesystemisturningon,thepackageshoulddoitsstartoperation.
stop:Whenauserstopsthepackageorthesystemisturningoff,thepackageshoulddoitsstopoperation.
scripts
53
status:Whenthepackagestatusisbeingchecked,thefollowingexitcodesshouldbereturnedaccordingtoitsstatus:
0:packageisrunning.
1:programofpackageisdeadand/var/runpidfileexists.
2:programofpackageisdeadand/var/locklockfileexists
3:packageisnotrunning
4:packagestatusisunknown
150:packageisbrokenandshouldbereinstalled.
prestart:IfprecheckstartstopinINFOissettoyes,thepackagecouldcheckifitisallowedtobestarted.
Note:ItwillalsorunbeforestartingapackageatbootingupafterDSM7.0.
prestop:IfprecheckstartstopinINFOissettoyes,thepackagecouldcheckifitisallowedtobestopped.
Note:Itwon'trunbeforestoppingapackageatshuttingdown.
ExecutionOrder
Installation
1. prereplace2. preinst3. postinst4. postreplace5. start-stop-statuswithprestartargumentifenduserchoosestostartitimmediately6. start-stop-statuswithstartargumentifenduserchoosestostartitimmediately
Upgrade
1. start-stop-statuswithprestopargumentifithasbeenstarted(old)2. start-stop-statuswithstopargumentifithasbeenstarted(old)3. preupgrade(new)4. preuninst(old)5. postuninst(old)6. prereplace(new)7. preinst(new)8. postinst(new)9. postreplace(new)10. postupgrade(new)11. start-stop-statuswithprestartargumentifitwasstartedbeforebeingupgraded(new)12. start-stop-statuswithstartargumentifitwasstartedbeforebeingupgraded(new)
Uninstallation
1. start-stop-statuswithprestopargumentifithasbeenstarted2. start-stop-statuswithstopargumentifithasbeenstarted3. preuninst4. postuninst
Start
1. start-stop-statuswithprestartargument2. start-stop-statuswithstartargument
scripts
54
Stop
1. start-stop-statuswithprestopargument2. start-stop-statuswithstopargument
scripts
55
ScriptEnvironmentVariablesSeveralvariablesareexportedbyPackageCenterandcanbeusedinthescripts.Descriptionsofthevariablesaregivenasbelow:
SYNOPKG_PKGNAME:PackageidentifywhichisdefinedinINFO.SYNOPKG_PKGVER:PackageversionwhichisdefinedinINFO.Thevaluewillbenewversionofpackagewhenitisupgrading.SYNOPKG_PKGDEST:Targetdirectorywherethepackageisstored.SYNOPKG_PKGDEST_VOL:Targetvolumewherethepackageisstored.SYNOPKG_PKGPORT:adminportportwhichisdefinedinINFO.Thisportwillbeoccupiedbythispackagewithitsmanagementinterface.SYNOPKG_PKGINST_TEMP_DIR:Thetemporarydirectorywherethepackageareextractedwheninstallingorupgradingit.SYNOPKG_TEMP_LOGFILE:Atemporaryfilepathforascripttologinformationorerrormessages.SYNOPKG_TEMP_UPGRADE_FOLDER:Thetemporarydirectorywhenthepackageisupgrading.Youcanmovethefilesfromthepreviousversionofthepackagetoitinpreupgradescriptandmovethembackinpostupgrade.SYNOPKG_DSM_LANGUAGE:Enduser'sDSMlanguage.SYNOPKG_DSM_VERSION_MAJOR:Enduser’smajornumberofDSMversionwhichisformattedas[DSMmajornumber].[DSMminornumber]-[DSMbuildnumber].SYNOPKG_DSM_VERSION_MINOR:Enduser’sminornumberofDSMversionwhichisformattedas[DSMmajornumber].[DSMminornumber]-[DSMbuildnumber].SYNOPKG_DSM_VERSION_BUILD:Enduser’sDSMbuildnumberofDSMversionwhichisformattedas[DSMmajornumber].[DSMminornumber]-[DSMbuildnumber].SYNOPKG_DSM_ARCH:Enduser’sDSMCPUarchitecture.PleasereferAppendixA:PlatformandArchValueMappingTabletomoreinformationSYNOPKG_PKG_STATUS :Packagestatuspresentedbythesevalues:INSTALL,UPGRADE,UNINSTALL,START,STOPorempty.1. INSTALLwillbesetasthestatusvalueinthepreinstandpostinstscriptswhilethepackageisinstalling.Iftheuserchooses
to“startafterinstallation”atthelaststepoftheinstallationwizard,thevaluewillbesettoINSTALLinthestart-stop-statusscriptwhenthepackageisstarted.
2. UPGRADEwillbesetasthestatusvalueinthepreupgrade,preuninst,postunist,preinst,postinstandpostupgradescriptssequentiallywhilethepackageisupgrading.Ifthepackagehasalreadystartedbeforeupgrade,thevaluewillbesettoUPGRADEinthestart-stop-statusscriptwhenthepackageisstartedorstopped.
3. UNINSTALLwillbesetasthestatusvalueinthepreuninstandpostunistscriptswhilethepackageisun-installing.Ifthepackagehasalreadystartedbeforeun-installation,thevaluewillbesettoUNINSTALLinthestart-stop-statusscriptwhenthepackageisstopped.
4. IftheuserstartsorstopsapackageinthePackageCenter,STARTorSTOPwillbesetasthestatusvalueinthestart-stop-statusscript.
5. WhentheNASisbootinguporshuttingdown,itsstatusvaluewillbeempty.SYNOPKG_OLD_PKGVER:OldpackageversionwhichisdefinedinINFOduringupgrading.SYNOPKG_TEMP_SPKFILE:ThelocationofpackagespkfileistemporarilystoredinDSwhenthepackageisinstalling/upgrading.SYNOPKG_USERNAME:Theusernamewhoinstalls,upgrades,uninstalls,startsorstopsthepackage.Ifthevalueisempty,theactionistriggeredbyDSM,notbytheenduser.SYNOPKG_PKG_PROGRESS_PATH:Atemporaryfilepathforascripttoshowingtheprogressininstallingandupgradingapackage.
Note:
1. Theprogressvalueisbetween0and1.2. Example:
flock-x"$SYNOPKG_PKG_PROGRESS_PATH"-cecho0.80>"$SYNOPKG_PKG_PROGRESS_PATH"
ScriptEnvironmentVariables
56
ScriptEnvironmentVariables
57
ShowMessagestoUsers
ShowMessageasScriptResult
Ifyouwanttosendapromptuserswithmessagesaftertheyinstalled,upgraded,uninstalled,started,orstoppedapackage,youcanusethe$SYNOPKG_TEMP_LOGFILEvariableinrelatedscripts.Forexample:
echo"HelloWorld!!">$SYNOPKG_TEMP_LOGFILE
Ifyouwanttopromptusersaccordingtotheirlanguage,youcanuse$SYNOPKG_DSM_LANGUAGEvariableforlanguageabbreviationasshownintheexamplebelow:
case$SYNOPKG_DSM_LANGUAGEin
chs)
echo"" >$SYNOPKG_TEMP_LOGFILE
;;
cht)
echo"" >$SYNOPKG_TEMP_LOGFILE
;;
csy)
echo"Český">$SYNOPKG_TEMP_LOGFILE
;;
dan)
echo"Dansk">$SYNOPKG_TEMP_LOGFILE
;;
enu)
echo"English">$SYNOPKG_TEMP_LOGFILE
;;
fre)
echo"Français">$SYNOPKG_TEMP_LOGFILE
;;
ger)
echo"Deutsch">$SYNOPKG_TEMP_LOGFILE
;;
hun)
echo"Magyar">$SYNOPKG_TEMP_LOGFILE
;;
ita)
echo"Italiano">$SYNOPKG_TEMP_LOGFILE
;;
jpn)
echo"" >$SYNOPKG_TEMP_LOGFILE
;;
krn)
echo"" >$SYNOPKG_TEMP_LOGFILE
;;
nld)
echo"Nederlands">$SYNOPKG_TEMP_LOGFILE
;;
nor)
echo"Norsk">$SYNOPKG_TEMP_LOGFILE
;;
plk)
echo"Polski">$SYNOPKG_TEMP_LOGFILE
;;
ptb)
echo"PortuguêsdoBrasil">$SYNOPKG_TEMP_LOGFILE
;;
ptg)
echo"PortuguêsEuropeu">$SYNOPKG_TEMP_LOGFILE
;;
rus)
echo"Русский">$SYNOPKG_TEMP_LOGFILE
;;
ScriptMessages
58
spn)
echo"Español">$SYNOPKG_TEMP_LOGFILE
;;
sve)
echo"Svenska">$SYNOPKG_TEMP_LOGFILE
;;
trk)
echo"Türkçe">$SYNOPKG_TEMP_LOGFILE
;;
*)
echo"English">$SYNOPKG_TEMP_LOGFILE
;;
esac
Pleasereferto"scripts"and"ScriptEnvironmentVariables"sectionsformoreinformation.
ShowMessageasDesktopNotification
Itispossibletouse/usr/syno/bin/synodsmnotifyexecutabletosenddesktopnotificationstousers.Thenotificationtitle/messagemustbeanI18Nstring.
/usr/syno/bin/synodsmnotify-c[app_id][user_or_group][i18n_string_for_title][i18n_string_for_msg]
/usr/syno/bin/synodsmnotify-ccom.company.App1adminMyPackage:app_tree:index_titleMyPackage:app_tree:node_1
/usr/syno/bin/synodsmnotify-ccom.company.App1@administratorsMyPackage:app_tree:index_titleMyPackage:app_tree:node_1
Notificationtitleandmessagehereshouldbeintheformatof[package_id]:[i18n_section]:[i18n_key]wherepackage_idisthepackagevalueinpackageINFOfile.I18NstringexamplecanbefoundinI18Npage.RemembertospecifydesktopnotificationstringstopreloadTextsfieldinapplicationconfig.
ScriptMessages
59
confTheconffoldercontainsthefollowingfiles:
File/FolderName Required Description File/Folder
TypeDSM
Requirement
PKG_DEPS X DefinedependencybetweenpackageswithrestrictionsofDSMversion. File 4.2-3160
PKG_CONX X DefineconflictsbetweenpackageswithrestrictionsofDSMversion. File 4.2-3160
privilege O Definefileprivilegeandexecutionprivilegetosecurethepackage. File 6.2-5891
resource X Definesystemresourcesthatcanbeusedinthelifecycleofpackage. File 6.2-5941
SinceDSM7.0,allpackagesareforcedtolowertheprivilegeexplicitly.Theprivilegemustbeprovidedforpackagetowork.
conf
60
PrivilegeDSM7.0,packagesareforcedtolowertheprivilegebyapplyingprivilegemechanismexplicitly.
Toreducesecurityrisks,packageshouldrunasanuserratherthanroot.Packagecanapplysuchmechanismbyprovidingaconfigurationfilenamedpivilege:
Withtheconfiguration,packagedeveloperiscapableto
Controldefaultuser/groupnameofprocessinscripts
Controlpermissionoffilesinpackage.tgz
Controlfilecapabilitiesinpackage.tgz
Controlifspecialsystemresourcesareaccessible
Toovercomethelimitationthatnormalusercannotbeusedtodoprivilegedoperations,weprovideawayforpackagetorequestsystemresources.PleaserefertoResourceformoreinformation.
SetupprivilegeconfigurationJustcreateafileatconf/privilegewithpreferedconfiguration.
{
"defaults":{
"run-as":"package"
}
}
privilege
61
ResourcePackagescanobtainsystemresourceseveninlowerprivilegeidentityiftheyapplythismechanism.
Stepstosetupresourceconfig
1. FindouttheresourcesyouwantfromResourceList
2. CheckifthecorrespondingTimingofselectedresourceissatisfied.
3. Createafileatconf/resourcewithpreferedconfiguration.
{
"data-share":{
"shares":[
{
"name":"MyShareFolderName",
"permission":{
"ro":["MyUserName"]
}
}
]
}
}
Theinstancehandlingtheresourcerequestiscalledworker.
resource
62
PKG_DEPS
ThePKG_DEPSissimilartoinstall_dep_packageskeyinINFOfile,butitadditionallydefinestherestrictionaccordingtospecificDSMversions.
priorityofPKG_DEPSishigherthaninstall_dep_packagesinINFO
Eachconfigurationfileisdefinedinstandard.inifileformatwithkey/valuepairsandsections.Asectiondescribesauniquenameofdependent/conflictingpackage.EachsectioncontainsinformationabouttherequirementsofpackageversionsandtherestrictionofDSMversions.
Key Description Value
pkg_min_ver Minimumversionofdependentpackage. Packageversion
pkg_max_ver Maximumversionofdependentpackage. Packageversion
dsm_min_ver MinimumrequiredDSMversion. X.Y-ZDSMmajornumber,DSMminornumber,DSMbuildnumber
dsm_max_ver MaximumrequiredDSMversion. X.Y-ZDSMmajornumber,DSMminornumber,DSMbuildnumber
;YourpackagedependsonPackageAinanyversion
[PackageA]
;YourpackagedependsonPackageBversion2ornewer
[PackageB]
pkg_min_ver=2
;YourpackagedependsonPackageCwithversion2orolder
[PackageC]
pkg_max_ver=2
;YourpackagedependsonPackageDwithversion2ornewerbutitwillbeignoredwhenDSMversionissmallerthan4.1-2668
[PackageD]
dsm_min_ver=4.1-2668
pkg_min_ver=2
;YourpackagedependsonPackageEwithversion2ornewerbutitwillbeignoredwhenDSMversionisbiggerthan4.1-2668
[PackageE]
dsm_max_ver=4.1-2668
pkg_min_ver=2
PKG_DEPS
63
PKG_CONX
ThePKG_CONXissimilartoinstall_conflict_packageskeyinINFOfile,butitadditionallydefinestherestrictionaccordingtospecificDSMversions.
priorityofPKG_CONXishigherthaninstall_conflict_packagesinINFO
Eachconfigurationfileisdefinedinstandard.inifileformatwithkey/valuepairsandsections.Asectiondescribesauniquenameofdependent/conflictingpackage.EachsectioncontainsinformationabouttherequirementsofpackageversionsandtherestrictionofDSMversions.
Key Description Value
pkg_min_ver Minimumversionofconflictingpackage. PackageVersion
pkg_max_ver Maximumversionofconflictingpackage. PackageVersion
dsm_min_ver MinimumrequriedDSMversion. X.Y-ZDSMmajornumber,DSMminornumber,DSMbuildnumber
dsm_max_ver MaximumrequriedDSMversion. X.Y-ZDSMmajornumber,DSMminornumber,DSMbuildnumber
;YourpackageconflictswithPackageAinanyversion
[PackageA]
;YourpackageconflictswithPackageBversion2ornewer
[PackageB]
pkg_min_ver=2
;YourpackageconflictswithPackageCversion2orolder
[PackageC]
pkg_max_ver=2
;YourpackageconflictswithPackageDversion2ornewer,butitwillbeignoredwhenDSMversionissmallerthan4.1-2668
[PackageD]
dsm_min_ver=4.1-2668
pkg_min_ver=2
;YourpackageconflictonPackageEwithversion2ornewerbutitwillbeignoredwhenDSMversionisbiggerthan4.1-2668
[PackageE]
dsm_max_ver=4.1-2668
pkg_min_ver=2
PKG_CONX
64
LicenseTheLICENSEfilecontainsthelicenses/userterms&conditions/enduseraggrementstoshowonthepackageinstallationwizard.ThepackagecenterwouldopenupadialogtoshowthecontentofLICENSEfileandprovideacheckboxforusertoagreethesetermsonthedialog.
HowtoplaceLICENSEfilePrepareafilecontainingyourterms&conditionsinplaintextformatthenputitto/ofyourpackage(thedirectorywheretheINFOis)
IftheLICENSEfileisproperlyputinsidespk,theinstallationwizardwouldshowyourlicensefilecontentlikethis:
LICENSE
65
SynologyDSMIntegration
SynologyDSMIntegration
66
PackageFilesystemHierarchyStandardAfterthepackageinstalled,therewillbesomedirectoriesforpackagetoputtheirdata.Therewillbedifferentdirectorieslinkedforpackageswhoinstalledonvolumepartition/systempartition.
/var/packages/[package_name]
├──etc->/volume[volume_number]/@appconf/[package_name](movetovolumesince7.0-41330,andoldpathstillworks)
├──var->/volume[volume_number]/@appdata/[package_name]
├──tmp->/volume[volume_number]/@apptemp/[package_name]
├──home->/volume[volume_number]/@apphome/[package_name]
└──target->/volume[volume_number]/@appstore/[package_name]
/var/packages/[package_name]
├──etc->/usr/syno/etc/packages/[package_name]
├──var->/usr/local/packages/@appdata/[package_name]
├──tmp->/usr/local/packages/@apptemp/[package_name]
├──home->/usr/local/packages/@apphome/[package_name]
└──target->/usr/local/packages/@appstore/[package_name]
Pleaserefertoinstall_typeinINFOformoreinformationaboutinstallationonvolume/systempartition.
Directory Purpose Mode CreationTiming RemoveTiming ScriptVariable
etc permanantconfigstorage 0755 installed/upgraded none none
var(since7.0-40314)
permanantdatastorage 0755 installed/upgraded none SYNOPKG_PKGVAR
tmp(since7.0-40356)
temporarydatastorage 0755 installed/upgraded
uninstalled/upgrading
SYNOPKG_PKGTMP
home(since7.0-40759)
privatestorage 0700 installed/upgraded none SYNOPKG_PKGHOME
target dataextractedfrompackage.tgz
0755 installed/upgraded
uninstalled/upgrading
SYNOPKG_PKGDEST
DirectoryOwnerRules
Whendefaultsrun-asispackage,FHSdirectoriesaresetto[packageuser]:[packagegroup]
Whendefaultsrun-asisroot,FHSdirectoriesaresettoroot:[packagegroup]
PleaserefertoPrivilegesectionformoreinformationaboutdefaultsrun-as.
FHS
67
DesktopApplicationYoucanprovideaAppConfigforyourpackagesothattheconfiguredapplicationwillshowonthemenuofdesktop.Itispossibletocustomizeicon,applicationprivilegeandtargeturl.
Todistinguishdifferentroleofusers,onepackagecanevenprovidemorethanoneapplicationsuchasadminapplicationforadministratorsandnormalapplicationfornormalusers.
Inaddition,anyapplicationcanbringitsownhelpdocumentsintodesktopbyprovidingaHelpConfig.
DesktopApplication
68
Stepstosetupdesktopapplication
1. Createadirectoryinsidepackage.tgz,thisdirectorywillbeusedtostoredesktopapplicationconfigs.Wenameitasuiforexamplehere.
2. AdddsmuidirkeytoyourINFOorINFO.shwhosevalueistherelativepathtothedirectoryyoujustcreatedonpreviousstep.
dsmuidir="ui"
dsmuidir="MyApp1:appui1MyApp2:appui2"
Ifyouhavemultipleapplications,thesecondformshouldbeapplied.Intheexampleabove,MyApp1representsanidentifierandappui1representsarelativepath.
Oncethepackageisinstalled,DSMwillcreatecorrespondingsoftlinkat/usr/syno/synoman/webman/3rdpaty/[identifier]/linkingtothepathwhereyourrelativepathis.Whentheidentifierisnotpresentedinthefirstform,DSMwillusepackagenameasidentifierbydefault.
3. CreateyourownAppConfigandHelpConfigunderthedirectoryspecifiedbydsmuidirifnecessary.
4. AdddsmappnamekeytoyourINFOorINFO.shwhosevalueistheuniqueapplicationnameinsideAppConfig.Thisapplicationwillbethetargetapplicationwhenopenbuttonofpackageisclickedinpackagecenter.
dsmappname="com.company.App1"
DesktopApplication
69
DesktopApplication
70
ApplicationConfigTointegratedesktopapplicationsintoDSM,youhavetoprovideaconfigfileinJSONformatunderthedirectoryspecifiedbydsmuidirinINFO.
{
".url":{
"com.company.App1":{
"type":"url",
"icon":"images/app_{0}.png",
"title":"TestApp1",
"desc":"Description",
"url":"http://www.yahoo.com",
"allUsers":true,
"preloadTexts":[
"app_tree:index_title",
"app_tree:node_1"
]
},
"com.company.App2":{
"type":"legacy",
"icon":"images/app2_{0}.png",
"title":"TestApp2",
"desc":"Description2",
"url":"http://www.synology.com",
"allUsers":true
}
}
}
Property Required Description
com.company.App1com.company.App2 O In“.url”,eachobjectshouldhaveauniquepropertyname.
type O
Whenyouclickthemenuitem,theaddressyouusetoconnecttotheDSMmanagementUIwillbeshownintherightframeofthemanagementUI.However,youcancustomizetheaddressasyouwish.The“type”valuecanbe"url"or"legacy"."url"meanswhenyouclicktheapplicationicon,theURLwillbeopenedinapop-upwindow,while"legacy"impliesthattheURLwillbeopenedinaniframewindowapplication.YoucanfollowthedescriptionsbelowtosetupyourcustomizedURL.
icon O
“icon”indicatestheiconfortheapplication.Itisatemplatestring.The“{0}”canbereplacedby“16”,“24”,“32”,“48”,“64”,“72”,“256”dependingontheresolutionoftheicon.Theiconmustbesavedunder/usr/syno/synoman/webman/3rdparty/xxx/wherexxxisthedirectorynameofyourpackage.Forexample,ifyoucreateadirectorynamed"images"andputtheiconimagefile“icon.png”init,thefullpathfortheiconwouldbe:/usr/syno/synoman/webman/3rdparty/xxx/images/icon_16.png/usr/syno/synoman/webman/3rdparty/xxx/images/icon_24.png/usr/syno/synoman/webman/3rdparty/xxx/images/icon_32.png/usr/syno/synoman/webman/3rdparty/xxx/images/icon_48.png/usr/syno/synoman/webman/3rdparty/xxx/images/icon_64.png/usr/syno/synoman/webman/3rdparty/xxx/images/icon_72.png/usr/syno/synoman/webman/3rdparty/xxx/images/icon_256.pngTheiconvalueshouldalsobesetas"images/icon_{0}.png"
title O “title”representstheapplicationnamethatwillbedisplayedinthemainmenu.
desc X “desc”displaysmoredetailsaboutthisapplicationuponmouse-over.
url OThefollowingisanexampleofvaluesettingforyourURLoftheapplication:“url”:http://www.synology.com/“url”:“3rdparty/xxx/index.html”
ApplicationConfig
71
allUsers X
Thiskeydetermineswhetherornotthemenuitemscanbeseenbyuserswhentheyloginwithanadminaccount.Ifyouwouldliketohaveallusersseethemenuitems,pleasesetthekeyvalueasbelow:"allUsers":trueThedefaultsettingisthatonlytheadmincanfindtheapplication.
preloadTexts XThespecifiedi18nsection:keystringswillbeloadedevenwhenapplicationuiisnotopened.Thisisnecessarywhencorrespondingstringsareusedtosenddesktopnotifications.
Textfieldssupporti18nvalue.
ApplicationConfig
72
ApplicationHelpTointegratehelpdocumentsintoDSMHelp,pleasefollowthesesteps:
1>Provideahelptoc.confdescribingyourhelpdocumentstructureandputitunderthedirectoryspecifiedbydsmuidirinINFO.
{
"app":"SYNO.App.TestAppInstance",
"title":"app_tree:index_title",
"content":"testapp_index.html",
"toc":[
{
"title":"app_tree:node_1",
"content":"testapp_node1.html",
"nodes":[
{
"title":"app_tree:node_1_child",
"content":"testapp_node1_child.html"
}
]
},{
"title":"app_tree:node_2",
"content":"testapp_node2.html"
}
]
}
Detailsofhelptoc.confarestatedbelow:
Property Description
app theapplicationinstance.
title thetextbeingdisplayed.
content thepathtoyourhelpdocument.
toc thechildnodesofroot.(useemptyarrayifyourapplicationdoesn'thaveone)
nodes thechildnodesoftocnode.
Textfieldssupporti18nvalue.
2>Createdirectoriesandfilesaccordingtoyourhelptoc.conf.
ui(specifiedbydsmuidirinINFO)
├──helptoc.conf
├──help
│├──enu
││└──testapp_index.html
│└──cht
│└──testapp_index.html
└──texts
├──enu
│└──strings
└──cht
└──strings
3>WriteeachhelpdocumentinthefollowingHTMLformatsothattheUIstylecanbeconsistentwithothers.
<!DOCTYPEhtml>
<htmlclass="img-no-display">
<head>
ApplicationHelp
73
<metacharset="UTF-8"/>
<metahttp-equiv="X-UA-Compatible"content="IE=edge,chrome=1">
<linkhref="../../../../help/help.css"rel="stylesheet"type="text/css">
<linkhref="../../../../help/scrollbar/flexcroll.css"rel="stylesheet"type="text/css">
<scripttype="text/javascript"src="../../../../help/scrollbar/flexcroll.js"></script>
<scripttype="text/javascript"src="../../../../help/scrollbar/initFlexcroll.js"></script>
</head>
<body>
Thisismyhelpdocumentcontent
</body>
</html>
ApplicationHelp
74
ApplicationInternationalizationThedesktopapplicationcanhavei18ntextreferencedbyconfig,help,etc.
ui(specifiedbydsmuidirinINFO)
└──texts
├──enu
│└──strings
└──cht
└──strings
Youhavetocreatedirectoriesaccordingtosupportedlanguagesthencreateafilenamedstringsinsideeachlanguagedirectory.
[dsmuidir]/texts/enu/strings
[app_tree]
index_title="Thisisatitle"
node_1="Thisisnode1"
[app_tab]
tab1="Thisistab1"
tab2="Thisistab2"
[dsmuidir]/texts/cht/strings
[app_tree]
index_title=""
node_1="1"
[app_tab]
tab1="1"
tab2="2"
Whenyouwanttousethesetexts,justreferencetheminsection:keyformat(onevaluecanonlybeonei18nstring)
"title":"app_tree:node_1"
I18NstringsareloadedonlywhenapplicationopenedondesktopafterDSM7.0.Ifthestringsareusedasdesktopnotifications,thosestringsshouldbespecifiedinpreloadTextsofapplicationconfig.
ApplicationI18N
75
ApplicationAuthenticationAfterintegratingyourapplicationintoSynologyDSM,youmaywanttoperformanauthenticationchecktoensureonlylogged-inuserscanaccessthepage.
Youcanrun/usr/syno/synoman/webman/modules/authenticate.cgitochecktheuserloginstatus.Howevertheauthenticate.cgimustberunwithsomeenvironmentvariables(HTTP_COOKIE,REMOTE_ADDR,SERVER_ADDR,etc.).Soexecutetheauthenticate.cgidirectlyfromthepackagecustomCGIisrecommendedsincetheenvironmentvariablesneededaresetautomatically.
SampleCodetest.cgi
Theauthenticate.cgiwilloutputtheusernameiftheuserhasloggedin.Therewillbenooutputiftheuserhasnotbeenauthenticated.
Hereisthesamplecodefor3rdpartyCGI(Note.compilethiswith-std=c99)
#define_GNU_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<strings.h>
/**
*Checkwhetheruserisloggedin.
*
*Ifuserhasloggedin,puttheusernameinto"user".
*
*@paramuserThebufferforgetusername
*@parambufsizeThebuffersizeofuser
*
*@return0:Usernotloggedinorerror
*1:Userloggedin.Theusernameiswrittentogiven"user"
*/
intIsUserLogin(char*user,intbufsize)
{
FILE*fp=NULL;
charbuf[1024];
intlogin=0;
bzero(user,bufsize);
fp=popen("/usr/syno/synoman/webman/modules/authenticate.cgi","r");
if(!fp){
return0;
}
bzero(buf,sizeof(buf));
fread(buf,1024,1,fp);
if(strlen(buf)>0){
snprintf(user,bufsize,"%s",buf);
login=1;
}
pclose(fp);
returnlogin;
}
intmain(intargc,char**argv)
{
charuser[256];
printf("Content-Type:text/html\r\n\r\n");
if(IsUserLogin(user,sizeof(user))==1){
printf("Userisauthenticated.Name:%s\n",user);
ApplicationAuthentication
76
}else{
printf("Userisnotauthenticated.\n");
}
return0;
}
Howtorunthetest.cgiDSMrequirescookietovalidatetheDSMloginsession.
Login
Accessthefollowingcgiwithyourcredentialinformation,youwillreceivethesessioninformationinyourcookie.
https://your-ip:5001/webapi/auth.cgi?api=SYNO.API.Auth&version=3&method=login&account=admin&passwd=your_admin_password&format=
cookie
Note.Ifyou'reusingtheinsecurehttpprotocol,pleasealtertheprotocolandchangetheportnumberto5000.
Accesstest.cgiwithcookie
Accesstest.cgiwithcookieinformation.
https://your-ip:5001/path/to/test.cgi
Ifyouarehavingtroubleaccessingyourtest.cgi,pleasetrytoaccessanyotherwebapiwithyourcookie.Thiswouldhelpyoutoclearifyifyourcookieinformationisvalidornot.
https://your-ip:5001/webapi/entry.cgi?api=SYNO.Core.System&version=3&method=info
Logout
Byaccessingthefollowingwebapi,youwillbeloggedout.
https://your-ip:5001/webapi/auth.cgi?api=SYNO.API.Auth&version=1&method=logout
ApplicationAuthentication
77
PrivilegeConfig
Tomakeyourpackagework,theremustexistconf/privilegeinsideyourpackage.Itcontrolssecurityrelatedbehavioursinentirepackagelifecycle.
{
"defaults":{
"run-as":"package"
},
"username":"myusername",
"groupname":"mygroupname",
"tool":[{
"relpath":"bin/mytool",
"user":"package",
"group":"package",
"permission":"0700"
}]
}
defaults(required)
Controlsdefaultsettingsforentireprivilegefile.Itcanonlybesetasvaluebelow.
run-as behaviouronfile behaviouronscript
package chown-hR"${package}:${package}" setresuidas[username]
run-as behaviouronfile behaviouronscript
root chown-hR"root:root" setresuidasroot
username/groupname(optional)(since6.0-5940)
Specifywhichnamewillbetheusernameandgroupname.Ifnotspecified,thepackagenamewillbethedefaultvalue.
ctrl-script(optional)
Controltheidentitytorunscripts.
"ctrl-script":[{
"action":"start",
"run-as":"package"
}]
Member Since Description
action6.0-5891
oneofpreinst,postinst,preuninst,postuninst,preupgrade,postupgrade,start,stop,status,prestart,prestop
run-as6.0-5891 seethedescriptionabove
executable(optional)
Specifytheidentitytochownoninstalledforspecificfile.
"executable":[{
"relpath":"bin/mybin",
"run-as":"package"
PrivilegeConfig
78
}]
Member Since Description
relpath 6.0-5891 relativepathunder/var/packages/[package_name]/target
run-as 6.0-5891 seethedescriptionabove
tool(optional)
Specifytheidentitytochownandchmodoninstalledforspecificfile.
Ifyouwant,youcanevensetfilecapabilities.
"tool":[{
"relpath":"bin/mytool",
"user":"package",
"group":"package",
"permission":"0700"
}]
Member Since Description
relpath 6.0-5891 String,thefile'srelativepathunder/var/packages/${package}/target/.
user 6.0-5891 String,file'sowneruser,mustbe"package".
group 6.0-5891 String,file'sownergroup,mustbe"package"
permission 6.0-5891 4digitnumbertosetfilepermission,forexample:4750
"tool":[{
"relpath":"bin/mytool",
"user":"package",
"group":"package",
"capabilities":"cap_chown,cap_net_raw",
"permission":"0700"
}]
Member Since Description
capabilities 7.0-40656 capabilitiesstringwithoutany+-=eipsymbol.thevaluecanbeviewedHERE
PackageUser/GroupVisibilityOnUI
PackageusersandgroupswillnotappearonmostUIsettings,buttherearesomeexceptions:
[x]Applicationprivilegepermissionviewer[x]FTPchrootuserselector[x]FileStation
[x]Changeowner[x]SharedLinksManager->Enablesecuresharing
[o]ControlPanel>SharedFolder>Edit>Permission>Systeminternaluser[o]ACLeditor
PrivilegeConfig
79
ResourceConfigItdefinesthesystemresourcethatisneccesaryforthispackagetowork.
{
"<resource-id>":{
<specification>
}
}
Forexample,youcanapply/usr/locallinker:
{
"usr-local-linker":{
"lib":["lib/foo"],
"bin":["bin/foo"],
"etc":["etc/foo"],
}
}
Fromthisexample,theusr-local-linkerrepresentstheresourceidanditsvaluerepresentsthefiletobelinked.
ResourceConfig
80
ResourceTimingEveryworkeracquiresresourcesatcertaintimingsandholdsitduringaninterval.Forexample,/usr/locallinkerholdstheresourceduringtheintervalFROM_ENABLE_TO_DISABLE,whichmeansitacquiresresourceatWHEN_ENABLEandreleasesitatWHEN_DISABLE.Thetimingsarelistedandexplainedbelow:
timing descrioption whenFailure
WHEN_PREINST beforepreinst abortinstallation,rollback,showalertmessageonUI
WHEN_POSTINST beforepostinst finishinstallation,showalertmessageonUI
WHEN_ENABLEbeforeWHEN_STARTUP,won'tprocessduringbootup abortstartup,rollback,showalertmessageonUI
WHEN_STARTUP beforestart abortstartup,rollback,showalertmessageonUI
ResourceTiming
81
WHEN_PREUNINST afterpreuninst finishuninstallation,showalertmessageonUI
WHEN_POSTUNINST beforepostuninst finishuninstallation,showalertmessageonUI
WHEN_DISABLEafterWHEN_HALT,won'tprocessduringshutdown ignore
WHEN_HALT afterstop ignore
NOTEToletthepackageitselfdecidewhetheruninstallationshouldcontinueornot,WHEN_PREUNINSTisprocessedafterthepreuninstscript.
ResourceTiming
82
ResourceUpdateSomeworkerssupportupdateoperationoutsideofworkertimings./usr/syno/sbin/synopkghelershouldbeusedtoaccomplishthisjob.Belowarethestepstoupdatetheresource:
1. Updatethefileat/var/packages/[package_name]/conf/resource2. Executethecommand/usr/syno/sbin/synopkghelperupdate[package_name][resource_id]totriggerupdatingprocedure.
Forexample,supposeapackageallowstheusertoedititslisteningportandneedstoupdatecorrepondingnetworksettings:
1. Usersubmitsnewporttotheapplication2. Theapplicationupdatesthefileat/var/packages/[package_name]/conf/resource3. Theapplicationexecutesthecommand/usr/syno/sbin/synopkghelperupdate${package}port-config,thentheport-config
workerwillreadtheconfigandreloadnetworksettings.
NOTENotallresourcesupportupdateoperation,pleaserefertotheUpdatablesectionofeachresource.
ResourceUpdate
83
AvailableWorkersAsmentionedinthesectionResource,aworkerisneededforresourcemanagement.
GivenaResourceConfigfile,theresourceworkerwillacquire/releasetheresourceatcertaintime.ThissectiondescribestheavailableresourceworkersontheDSM.
ResourceList
84
/usr/locallinker
Description
Package'sexecutablesandlibraryfilesshouldbeinstalledto/usr/local.Thisworkerlink/unlinkfilesto/usr/local/{bin,lib,etc}duringpackagestart/stop.
Acquire():Createsymboliclinksunder/usr/local/{bin,lib,etc}/thatpointstofilesin/var/packages/${package}/target/.Filesnotfoundunder/var/packages/${package}/target/willbeignored.Ifthetargetfilealreadyexistsin/usr/local/{bin,lib,etc},itwillbeunlink()first.Failureonanyfilelinkresultsinthisworkertoabortandtriggersrollback.
Release():Deletethelinksunder/usr/local/{bin,lib,etc}/.Ignorefilesthatarenotfound.Ignoreunlink()failure.
Provider
DSM
TimingFROM_ENABLE_TO_DISABLE
EnvironmentVariables
None
Updatable
No
Syntax
"usr-local-linker":{
"bin"["<relpath>",...],
"lib"["<relpath>",...],
"etc"["<relpath>",...]
}
Member Since Description
bin 6.0-5941 Stringarray,listoffilestobelinkedunder/usr/local/bin/.
lib 6.0-5941 Stringarray,listoffilestobelinkedunder/usr/local/lib/.
etc 6.0-5941 Stringarray,listoffilestobelinkedunder/usr/local/etc/.
relpath 6.0-5941 String,targetfile'srelativepathunder/var/packages/${package}/target/.
Example
"usr-local-linker":{
"bin":["usr/bin/a2p","usr/bin/perl"],
"lib":["lib/perl5"]
}
ResourceList
85
TheabovespecificationsgeneratesthefollowingsymboliclinksforthePerlpackage:
root@DS$ls-l/usr/local/{bin,lib,etc}
/usr/local/bin/:
total0
lrwxrwxrwx1rootroot30Aug1306:32a2p->/var/packages/Perl/target/usr/bin/a2p
lrwxrwxrwx1rootroot31Aug1306:32perl->/var/packages/Perl/target/usr/bin/perl
/usr/local/lib/:
total0
lrwxrwxrwx1rootroot28Aug1306:32perl5->/var/packages/Perl/target/lib/perl5
/usr/local/etc/:
total0
ResourceList
86
Apache2.2Config
Description
Packagescancarrysites-enabled/*.conffilesforApacheHTTPServer2.2.Thisworkerinstalls/uninstallstheseconfigfilesduringpackagestart/stop.
Acquire():Copytheconffilesto/usr/local/etc/httpd/sites-enabled/.ThenreloadApache2.2.Thefilesshouldhave.confextension,otherwiseitwillbeignoredFileswillbeprefixedby${package}.Existingfileswillbeunlink()first.Failureonanyfilecopyresultsinthisworkertoabortandtriggersrollback.
Release():DeletepreviouslycreatedlinksIgnorefilesthatarenotfound.Ignoreunlink()failure.
Provider
WebStation
TimingFROM_ENABLE_TO_DISABLE
EnvironmentVariables
None
Updatable
No
Syntax
"apache22":{
"sites-enabled":[{
"relpath":"<conf-relpath>",
},...]
}
Member Since Description
sites-enabled WebStation-1.0-0049 Objectarray,listofconffilestoinstall.
relpath WebStation-1.0-0049 Targetfile'srelativepathunder/var/packages/${package}/target/.
Example
{
"apache22":{
"sites-enabled":[{
"relpath":"synology_added/test_1.conf"
},{
"relpath":"synology_added/test_2.conf"
},{
"relpath":"synology_added/test_3.conf"
ResourceList
87
}]
}
}
ResourceList
88
DataShare
Description
Thisworkercreatessharedfolderandsetitspermissionduringpackagestartup.Thesharenamecanbehard-codedinthespecification.Thesharedfolderwillnotberemovedafterpackageuninstallation,sinceitmightdeletetheuser’spersonaldataaswell.
Acquire():Createsharedfolderandsetitspermission.Ifthesharedfolderalreadyexists,skipsharecreationandsetthepermission.
Release():Doesnothing.
Provider
DSM
TimingFROM_ENABLE_TO_POSTUNINST
EnvironmentVariables
None
Updatable
No
Syntax
"data-share":{
"shares":[{
"name":"<share-name>",
"permission":{
"ro":["<user-name>",...],
"rw":["<user-name>",...]
},
"once":"<once>"
},...]
}
Member Since Description
shares 6.0-5914 Objectarray,arrayofsharestocreate
name 6.0-5914 String,nameoftheshare
permission 6.0-5914 Jsonobject,permissionoftheshare.(optional)
ro 6.0-5914 Stringarrayuserstobeassignedwithread-onlypermission.
rw 6.0-5914 Stringarrayuserstobeassignedwithread/writepermission.
once 6.0-5914 Boolean,onlytrytocreateshareonpackage'sfirststart.(optional,default=false)
Example
Thefollowingspecificationcreatesasharemusic,andgivestheuserAudioStationread-onlypermission.Sinceoncedefaultstofalse,theaboveprocedureisraneverytimethepackagestarts.
ResourceList
89
"data-share":{
"shares":[{
"name":"music",
"permission":{
"ro":["AudioStation"]
}
}]
}
since7.0-41201,packagecenterwillcreateasymlinkunder/var/packages/[package_id]/shares/namedbysharefolderpointingtosharefolderpath.
ResourceList
90
Docker(sinceDSM7.0)
Description
Dockerworkerismadefordockerpackagetohelpthemeasilydeploytheircontainerswithoutcallingdockercommandbythemselves.Dockerworkerusedocker-composeframework,itwillgeneratedocker-compose.yamlaccordingtouser'sdockerworkerconfigurationandcreatecontainersduringinstallation.
Whenininstall/removepackagestage,workerwillcreate/removedocker-compose.yaml,volumeonhostdirectory,imagesandcontainers.
Wheninstart/stoppackagestage,workerwillstart/stopcontainersbycallingdocker-composestart/stop.
FROM_POSTINST_TO_PREUNINST
Acquire():Createdocker-compose.yamlandpreparehostvolumeforcontainertomount.Workerwillalsocreatecontainersinthisstage.Release():Removedocker-compose.yaml,hostvolume,containersandimages.Notethatworkerwillnotremovehostvolumeduringupgradedockerpackage.
FROM_STARTUP_TO_HALT
Acquire():Startcontainers.Release():Stopcontainers.
Provider
Docker
Timing
FROM_POSTINST_TO_PREUNINSTFROM_STARTUP_TO_HALT
EnvironmentVariables
None
Updatable
No
Syntax
"docker":{
"services":[{
servicesetting1
},{
servicesetting2
}...],
}
Key Since Type Required Nullable DefaultValue Description
services18.09.0-1018 Array true false N/A Listofdockerservicesinformationto
createdocker-compose.yaml
ResourceList
91
services
servicesspecifyserviceconfigurationssuchasservicename,imagenameandtag,containername,volume...etc.Dockerworkerwillcreatedocker-compose.yamlaccordingtogivenserviceconfigurations.
Key Since type Required Nullable DefaultValue Description
service 18.09.0-1018 string true false N/A Servicename.
image 18.09.0-1018 string true false N/A Imagename.
tag 18.09.0-1018 string true false N/A Imagetag.
build 18.09.0-1018 string true false N/A
RelativepathtoDockerfiledirectorythatpackagecarries.Moredetailwillbeelaboratedinbuildsection.
container_name 18.09.0-1018 string false true N/A Containername.
shares 18.09.0-1018
arrayofobjects
false true N/A
Containermountvolumespecificationsespeciallyforpersistantdataperpose.Moredetailwillbeelaboratedinvolumessection.
volumes 18.09.0-1018
arrayofobjects
false true N/A
Containermountvolumespecificationsespeciallyformountingconfigfileperpose.Moredetailwillbeelaboratedinvolumessection.
ports 18.09.0-1018
arrayofobjects
false true N/A Containerportsspecification.
environment 18.09.0-1018
arrayofobjects
false false N/A Containerenvironmentvariablesspecification.
depends 18.09.0-1018
arrayofobjects
false false N/A Specifydependentservice.
build
buildattributeisforbuildingimagewithgivenDockerfilepath.Thepathwillberelativepathbasedonpackagetargetpath(/var/packages/PKG_NAME/target/).
Syntax:
{
"build":"[Dockerfiledirectory]"
}
Transformtodocker-compose.yaml:
build:/var/packages/PKG_NAME/target/[Dockerfiledirectory]
Example:Letodoo_dockerdirectorycontainersDockerfileandisunder"/var/packages/Odoo/target/"
{
"build":"odoo_docker"
}
ResourceList
92
Transformtodocker-compose.yaml:
build:/var/packages/Odoo/target/odoo_docker
volumes
Volumescontainstwocategories-sharesandvolumeswhicharefordifferentpurposes.Althoughthosetwocategorieswillallbetransformintodocker-compose's"volumes"section,weseperatethemfordifferentusage.Thatis,sharesattributeisforpersistantdatavolumeswhilevolumesisforconfigurationfilesoranyotherconfigurationsrelativefiles.
shares:Thesharesattributeisforcontainerstopersistantdata.Useronlyneedtofillintheadirectorynameinsharesandtheworkerwillfirstcreatedirectoryunderdockersharedirectoryforuserand,then,genterateSOURCE:TARGETpairundervolumessectionindocker-compose.yaml.
Syntax:
{
"shares":[{
"host_dir":"[hostdirectory]",
"mount_point":"[mountpoint]"
},...{
...
}]
}
Transformtodocker-compose.yaml:
volumes:
-/volumeX/docker/PKG_NAME/[hostdirectory]:[mountpoint]
Example:
{
"shares":[{
"host_dir":"odoo_data",
"mount_point":"/var/lib/odoo"
}]
}
Transformtodocker-compose.yaml:
volumes:
-/volume1/docker/Odoo/odoo_data:/var/lib/odoo
volumes:Thevolumesattributeissimilartosharesattributebutisdesignforconfigurationfilesordirectorythatuserwouldliketomountintocontianer.Usercanspecifyrelativepathofhostconfigurationfileordirectorybasedonpackagetargetpath(/var/packages/PKG_NAME/target/)andtheworkerwillgenterateSOURCE:TARGETpairundervolumessectionindocker-compose.yaml.
Syntax:
{
"volumes":[{
"host_dir":"[hostconfigordirectory]",
"mount_point":"[mountpoint]"
},...{
...
}]
}
ResourceList
93
Transformtodocker-compose.yaml:
volumes:
-/var/packages/PKG_NAME/target/[hostconfigordirectory]:[mountpoint]
Example:
{
"volumes":[{
"host_dir":"odoo_docker/config",
"mount_point":"/etc/odoo"
}]
}
Transformtodocker-compose.yaml:
volumes:
-/var/packages/Odoo/target/odoo_docker:/etc/odoo
ports
portsattributeisforcreatingportsbindingforcontainer.
Restriction:Hostportneedstobeatbetween1025to65535.
Syntax:
{
"ports":[{
"host_port":"[portonhost]",
"container_port":"[portincontainer]",
"protocol":"[tcporudp]"
},...{
...
}]
}
Transformtodocker-compose.yaml:
ports:
-"[portonhost]:[portincontainer]/[tcporudp]"
Example:
{
"ports":[{
"host_port":"30076",
"container_port":"80",
"protocol":"tcp"
},{
"host_port":"30078",
"container_port":"443",
"protocol":"tcp"
}]
}
Transformtodocker-compose.yaml:
ports:
-"30076:80/tcp"
-"30078:443/tcp"
ResourceList
94
environment
environmentattributeisforcreatingenvironmentvariablesandvaluesforcontainers.
Syntax:
{
"environment":[{
"env_var":"[variablename]",
"env_value":"[value]"
},...{
...
}]
}
Transformtodocker-compose.yaml:
environment:
-"[variablename]:[value]"
Example:
{
"environment":[{
"env_var":"HOST",
"env_value":"odoo_db"
},{
"env_var":"USER",
"env_value":"odoo"
},{
"env_var":"PASSWORD",
"env_value":"odoo"
}]
}
Transformtodocker-compose.yaml:
environment:
-HOST=odoo_db
-USER=odoo
-PASSWORD=odoo
depends
dependsattributeisforspecifyingdependentservices,inthesamewayasdocker-comopose.
Syntax:
{
"depends":[{
"dep_service":"[servicename]"
},...{
...
}]
}
Transformtodocker-compose.yaml:
depends_on:
-[servicename]
Example:
{
ResourceList
95
"depends":[{
"dep_service":"odoo_db"
}]
}
Transformtodocker-compose.yaml:
depends_on:
-odoo_db
docker-composegenerationexample
conf/resource:
{
"docker":{
"services":[{
"service":"odoo",
"build":"odoo_docker",
"image":"odoo",
"container_name":"Odoo",
"tag":"12.0",
"environment":[{
"env_var":"HOST",
"env_value":"odoo_db"
},{
"env_var":"USER",
"env_value":"odoo"
},{
"env_var":"PASSWORD",
"env_value":"odoo"
}],
"shares":[{
"host_dir":"odoo_data",
"mount_point":"/var/lib/odoo"
}],
"ports":[{
"host_port":"{{wizard_http_port}}",
"container_port":"8069",
"protocol":"tcp"
}],
"depends":[{
"dep_service":"odoo_db"
}]
},{
"service":"odoo_db",
"image":"postgres",
"tag":"10",
"container_name":"Odoo_db",
"shares":[{
"host_dir":"db",
"mount_point":"/var/lib/postgresql/data/pgdata"
}],
"environment":[{
"env_var":"POSTGRES_DB",
"env_value":"postgres"
},{
"env_var":"POSTGRES_PASSWORD",
"env_value":"odoo"
},{
"env_var":"POSTGRES_USER",
"env_value":"odoo"
},{
"env_var":"PGDATA",
"env_value":"/var/lib/postgresql/data/pgdata"
}]
}]
}
ResourceList
96
}
Transformtodocker-compose.yaml:
version:'3'
services:
odoo:
build:/var/packages/Docker_Odoo_SynoCommunity/target/odoo_docker
image:odoo:12.0
container_name:Odoo
environment:
-HOST=odoo_db
-USER=odoo
-PASSWORD=odoo
volumes:
-/volume1/docker/Docker_Odoo_SynoCommunity//odoo_data:/var/lib/odoo
ports:
-"30076:8069/tcp"
depends_on:
-odoo_db
networks:
-Docker_Odoo_SynoCommunity
odoo_db:
image:postgres:10
container_name:Odoo_db
environment:
-POSTGRES_DB=postgres
-POSTGRES_PASSWORD=odoo
-POSTGRES_USER=odoo
-PGDATA=/var/lib/postgresql/data/pgdata
volumes:
-/volume1/docker/Docker_Odoo_SynoCommunity//db:/var/lib/postgresql/data/pgdata
networks:
-Docker_Odoo_SynoCommunity
networks:
Docker_Odoo_SynoCommunity:
driver:bridge
ResourceList
97
IndexDB
Description
Index/unindexpackagehelpandappindexduringpackagestart/stop.
Fordetaileddescriptiononpackageappindexandhelpindex,pleaserefertoIntegegrateHelpDocumentintoDSMHelp.
Acquire():Indexpackagehelpandappcontent.Release():Un-indexpackagehelpandappcontent.
Provider
DSM
Timing
FROM_ENABLE_TO_DISABLE
EnvironmentVariables
None
Updatable
No
Syntax
"indexdb":{
"app-index":{
"conf-relpath":"<confrelpath>",
"db-relpath":"<appdbrelpath>"
},
"help-index":{
"conf-relpath":"<confrelpath>",
"db-relpath":"<helpdbrelpath>"
}
}
Member Since Description
app-index 6.0-5924 Object,appindexinfo.
help-index 6.0-5924 Object,helpindexinfo.
conf-relpath 6.0-5924 String,configfile'srelativepathunder/var/packages/${package}/target/.
db-relpath 6.0-5924 String,dbfolder'srelativepathunder/var/packages/${package}/target/.
Example
"indexdb":{
"app-index":{
"conf-relpath":"app/index.conf",
"db-relpath":"indexdb/appindexdb"
},
"help-index":{
ResourceList
98
"conf-relpath":"app/helptoc.conf",
"db-relpath":"indexdb/helpindexdb"
}
}
ResourceList
99
MariaDB10
Description
Thisworkerregisteronthefollowingtimings:
PREINST/PREUNINSTItcheckstheresourcespecificationfromuser/wizardtoavoidfailureonanothertiming.
POSTINST/POSTUNINSTItperformsseveralstageswhenpackageintentstodoso:
POSTINST(install&upgrade)migrate-db:migratedbfrommariadb5tomariadb10,usuallyusedonupgradecreate-db:createdatabasegrant-user:createuserdrop-db-inst:dropolddatabase,usuallyusedondbmigration
POSTUNINST(uninstall)(donotrunduringupdate)drop-db-uninst:dropdatabasedrop-user-uninst:deleteuser,ifmultiplepackagessharesameuser,thisoptionshouldnotbeapplied
Ifworkerfailsonanystage,workerframeworkwouldrollbacktheperformedoperations.
Provider
MariaDB10package
TimingFROM_PREINST_TO_PREUNINST
FROM_POSTINST_TO_POSTUNINST
EnvironmentVariables
None
Updatable
No
Syntax
"mariadb10-db":{
"admin-account-m10":"<dbaccount>",
"admin-pw-m10":"<dbpassword>",
"admin-account-m5":"<m5dbaccount>",
"admin-pw-m5":"<m5dbpassword>",
"migrate-db":{
"flag":true|false,
"m5-db-name":"<dbname>",
"m10-db-name":"<dbname>",
"db-collision":"replace"|"error"
},
"create-db":{
"flag":true|false,
"db-name":"<dbname>",
"db-collision":"replace"|"skip"|"error"
},
"grant-user":{
"flag":true|false,
ResourceList
100
"db-name":"<dbname>",
"user-name":"<dbusername>",
"host":"<dbhost>",
"user-pw":"<dbpassword>"
},
"drop-db-inst":{
"flag":true|false,
"ver":"m5"|"m10",
"db-name":"<dbname>"
},
"drop-db-uninst":true|false,
"drop-user-uninst":true|false
}
Allfieldsarenotnecessary,butifyouenablesomestagesthenyouhavetofillupsomefields.(e.g.,enablecreate-dbstage,thenyouhavetoprovideadmin-account-m10andadmin-pw-m10)
Member(L1) Member(L2) Since Description
admin-account-
m10- 10.0.30-
0005 MariaDB10accountidwhichhasfullaccesspermission(root)
admin-pw-m10 - 10.0.30-0005
MariaDB10accountpasswordwhichhasfullaccesspermission(root)
admin-account-m5 - 10.0.30-0005 MariaDBaccountidwhichhasfullaccesspermission(root)
admin-pw-m5 - 10.0.30-0005 MariaDBaccountpasswordwhichhasfullaccesspermission(root)
migrate-db flag10.0.30-0005 whethertorunthestage
m5-db-name10.0.30-0005 migrationsourcedbnameofMariaDB
m10-db-name10.0.30-0005 migrationdestinationdbnameofMariaDB10
db-
collision
10.0.30-0005 DBCollisionStrategyonimportdonotprovide skip
create-db flag10.0.30-0005 whethertorunthestage
db-name10.0.30-0005 dbnametocreateonMariaDB10
db-
collision
10.0.30-0005 DBCollisionStrategyoncreatedb
grant-user flag10.0.30-0005 whethertorunthestage
db-name10.0.30-0005 targetdbnametograntforuser
user-name10.0.30-0005 createandgrantusername
host10.0.30-0005 userhost(default=localhost)
user-pw10.0.30-0005 userpassword
drop-db-inst flag10.0.30-0005 whethertorunthestage
ver10.0.30-0005 targetmariadbversion(m5/m10)
ResourceList
101
db-name10.0.30-0005 dbnametodrop
drop-db-uninst - 10.0.30-0005 whethertorunthestage
drop-user-uninst - 10.0.30-0005 whethertorunthestage
DBCollisionStrategy:whentherearesamedbnamesasprovidedfrommigrate-db&create-db,itcansolvetheconflictbyoneofthefollowingstrategies:
1. replacedropexistdbandreplaceitusingnewdb
2. errordonotdoanythingandjustreporterror,whichmightcauseinstallationfailure
3. skipdonotdoanythingandcontinuetoexecuteasusual
Example
"mariadb10-db":{
"admin-account-m10":"root",
"admin-pw-m10":"password!@#123432",
"admin-account-m5":"",
"admin-pw-m5":"",
"migrate-db":{
"flag":false,
"m5-db-name":"",
"m10-db-name":"",
"db-collision":""
},
"create-db":{
"flag":true,
"db-name":"myservice",
"db-collision":"error"
},
"grant-user":{
"flag":true,
"db-name":"myservice",
"user-name":"myservice_dbuser",
"host":"localhost",
"user-pw":"password!@#123432asd123123"
},
"drop-db-inst":{
"flag":false,
"ver":"",
"db-name":""
},
"drop-db-uninst":true,
"drop-user-uninst":false
}
ResourceList
102
PHPINI
Description
Packagescancarrycustomphp.iniandfpm.conffiles.Thisworkerinstalls/uninstallstheseconfigfilesduringpackagestart/stop.
Acquire():Copythephp.iniandfpm.conffilesto/usr/local/etc/php56/conf.d/and/usr/local/etc/php56/fpm.d/.Thenreloadphp56-fpm.
php.ini/fpm.conffilesshouldhave.ini/.confextension,otherwiseitwillbeignoredFileswillbeprefixedby${package}.Existingfileswillbeunlink()first.Failureonanyfilecopyresultsinthisworkertoabortandtriggersrollback.
Release():DeletepreviouslycreatedlinksIgnorefilesthatarenotfound.Ignoreunlink()failure.
Provider
PHP5.6
TimingFROM_ENABLE_TO_DISABLE
EnvironmentVariables
None
Updatable
No
Syntax
"php":{
"php-ini":[{
"relpath":"<ini-relpath>",
},...],
"fpm-conf":[{
"relpath":"<conf-relpath>",
},...]
}
Member Since Description
php-ini PHP5.6-5.6.17-0020 Objectarray,listofphp.inifilestoinstall.
fpm-conf PHP5.6-5.6.17-0020 Objectarray,listoffpm.conffilestoinstall.
relpath PHP5.6-5.6.17-0020 Targetfile'srelativepathunder/var/packages/${package}/target/.
Example
{
"php":{
"php-ini":[{
ResourceList
103
"relpath":"synology_added/etc/php/conf.d/test_1.ini"
},{
"relpath":"synology_added/etc/php/conf.d/test_2.ini"
},{
"relpath":"synology_added/etc/php/conf.d/test_3.ini"
}],
"fpm-conf":[{
"relpath":"synology_added/etc/php/fpm.d/test_1.conf"
},{
"relpath":"synology_added/etc/php/fpm.d/test_2.conf"
},{
"relpath":"synology_added/etc/php/fpm.d/test_3.conf"
}]
}
}
ResourceList
104
PortConfig
Description
Install/uninstallserviceportconfigfileduringpackageinstall/uninstall.
Fordetaileddescriptiononwhatisandhowtowriteaportconfigfile,pleaserefertoInstallPackageRelatedPortsInformationintoDSM.
Acquire():copythe.scfileto/usr/local/etc/service.d/Ifthedestinationfileexists,skipfilecopy.
Release():removethe.scfileandreloadthefirewallandportforward.Update():updatethe.scfileandreloadfirewallandportforward.
Timing
FROM_POSTINST_TO_POSTUNINST
EnvironmentVariables
None
Updatable
Yes,pleaserefertoConfigUpdateonhowtotriggerupdate.
Syntax
"port-config":{
"protocol-file":<protocol_file>
}
Member Since Description
protocol_file 6.0-5936 .scfile'srelativepathunder/var/package/{$package}/target/
Example
"port-config":{
"protocol-file":"port_conf/xxdns.sc"
}
ResourceList
105
SystemdUserUnit
Description
Thepackageframeworkwouldcopyfilesatconf/systemd/pkguser-[customname]tohome/.config/systemd/user/onacquiredandremovethemonreleased.
notethatuserunitcannotberelatedwithnormalsystemdunit.Ifyouneedyourpackagetoberelatedwithsystemservice,pleaserefertostart_dep_services
Thepackageshouldusesynosystemctlstartandsynosystemctlstoptocontroluserunitsinsidescripts.
Extra
Ifyouwanttohavesystemdunitinsidethesystem,youmayjustputyourunitsatconf/systemd/pkg-[customname]withouttheneedtousethissystemd-user-unitworker.
Thepackageframeworkwouldcopysystemdunitsto/usr/local/lib/systemd/systemonacquiredandremovethemonreleased.
Provider
DSM
Since
7.0-40761
Timing
FROM_POSTINST_TO_POSTUNINST
Syntax
"systemd-user-unit":{}
ResourceList
106
SyslogConfig
Description
Install/uninstallthesyslog-ngandlogrotateconfigfileduringpackagestart/stop.
Pleaserefertosyslog-ngonhowtowritethesyslog-ng'sconfigfile.
Acquire():Copypatterndb/logratoateto/usr/local/etc/syslog-ng/patterndb.d///usr/local/etc/logrotate.d/.Thenreloadsyslog-ng.Iffileexists,unlink()itfirst.Failureonanyfilecopyresultsinthisworkertoabortandtriggersrollback.
Release():Deletetheconfigfilesandreloadsyslog-ng.Ignoreunlink()failure.
Provider
DSM
Timing
FROM_ENABLE_TO_DISABLE
EnvironmentVariables
None
Updatable
No
Syntax
"syslog-config":{
"patterndb-relpath":"<relpath>",
"logrotate-relpath":"<relpath>"
}
Member Since Description
patterndb-
relpath
6.0-7145
String,syslog-ng'sconfigfile'srelativepathunder/var/packages/${package}/target/,ignorethisifthelogisnotgeneratedbysyslog-ng(optional)
logrotate-
relpath
6.0-5911
String,logrotate'sconfigfile'srelativepathunder/var/packages/${package}/target/,ignorethisiflogissavedtodatabase(optional)
Example
"syslog-config":{
"patterndb-relpath":"etc/syslog-ng.conf",
"logrotate-relpath":"etc/logrotate.conf"
}
ResourceList
107
ResourceList
108
WebService(sinceDSM7.0)
Description
Whenininstall/removepackagestage,workerwillupdate/removeserviceanddefaultportalsetting.
Wheninstart/stoppackagestage,workerwillstart/stopservicesetting.
FROM_PREINST_TO_PREUNINST
Acquire():syncinformationinuserspecified/var/package/${package}/target/*.jsonintousersetting,domigrateandsetupportalandservicewhichuserspecifyinresourcefileRelease():removeuser'ssetting
FROM_ENABLE_TO_DISABLE
Acquire():copy*.jsonand.mustacheunder/var/packages/${package}/target/into/usr/syno/etc/www/app.d/andenableservicesetting.Release():removefileswhichcopiedinto/usr/syno/etc/www/app.d/anddisableservicesetting
Provider
WebStation
Timing
FROM_PREINST_TO_PREUNINSTFROM_ENABLE_TO_DISABLE
Lowerprivilege
Accordingtopackagecenterprivilegepolicy,webpackagewillgetaconfinedprivilegeduringinstallationandruntime.Inordertosetupenvironmentforwebpackage,webserviceworkerprovideamechanismcalledpkg_dir_preparetoassistwebpackagecreatingwebsiterootdirectoryandsettingcorrespondingowner,group.Thedetailofpkg_dir_preparewillbeelaborateinpkg_dir_preparesection.
EnvironmentVariables
None
Updatable
No
Syntax
"webservice":{
"services":[{
servicesetting1
},{
servicesetting2
}...],
"portals":[{
defaultportalsetting1
},{
defaultportalsetting2
}],
"migrate":{
Migrationdata
},
ResourceList
109
"pkg_dir_prepare":[{
packagedirectorypreparesettings
}]
}
Key Since Type Required Nullable DefaultValue Description
services3.0.0-0214 Array true false N/A Listserviceswhicharewantedtobe
registered
portals3.0.0-0214 Array false true Empty
arrayListdefaultportalforservices(Unnecessary)
migrate3.0.0-0214 Object false true Empty
object Migrateinformation(Unnecessary)
pkg_dir_prepare3.0.0-0256 Array true false Empty
arraySettingspecificationofwebsiterootunderweb_package
Frameworkwillusedefaultvaluewhenfieldisnotrequiredanddoesn'texistorisnull.
services
Webserviceswhicharegoingtoregister,allowmultiplewebservicestoregister.FormoredetailpleaseseeWebService
portals
DefaultportalwhicharegoingtoregisterforaccessportalofservicesandwillcraeteUIShortcut.Devidedintoserverportalandaliasportal.
Important:Defaultserverportalisnotallowedregisteredasnamebaseportal,sinceyoumaynotbeabletolookupFQDN'scorrectIPfromclientside.
Example:
AliasPortal
{
"service":"wordpress",
"name":"wordpress",
"app":"SYNO.SDS.WordPress",
"type":"alias",
"alias":"wordpress"
}
ServerPortal
{
"service":"wordpress",
"name":"wordpress",
"app":"SYNO.SDS.WordPress",
"type":"server",
"http_port":[9000],
"https_port":[9001]
}
Key Since type Required Nullable DefaultValue Description
service 3.0.0-0214 string true false N/A
portalservicenamethatportallink,correspondingtoservicefieldinservicethatisabouttoregister
name 3.0.0-0214 string true false N/A portalname
display_name 3.0.0-0302 string false true sameas
name thetitleofwebUIportalshortcut
ResourceList
110
app 3.0.0-0214 string false true empty
string pacakge'sUIAppname
type 3.0.0-0214 string true false N/A portal'stype,couldbealiasorserver
alias 3.0.0-0214 string
true(iftypeisalias)
false N/A aliasname
http_port 3.0.0-0214
intarray false false
emptyarray(iftypeisserver)
Httpportsettingforserverportal,only1portallowed.Thereshouldbeatleasthttp_portorhttps_portorboth.
https_port 3.0.0-0214
intarray false false
emptyarray(iftypeisserver)
Httpsportsettingforserverportal,only1portallowed.Thereshouldbeatleasthttp_portorhttps_portorboth.
migrate
Migrateassistpackagemigrationfromolderversion(<DSM7.0)tonewerversion.Supportingtwokindsofmigratesetting-rootandvhost.
root
"root":[{
"old":"wordpress",
"new":"wordpress"
}]
Key Since type Required Nullable DefaultValue Description
root 3.0.0-0214 array false true empty
arrayMigratewebpackagefromwebsharefoldertoweb_packagessharefolder.
old 3.0.0-0214 string true false N/A nameofoldpackagewhichinwebsharefolder.
new 3.0.0-0214 string true false N/A nameofnewpackagewhichinweb_packages
sharefolder.
vhost
"vhost":[{
"root":"wordpress",
"service":"wordpress"
}]
Key Since type Required Nullable DefaultValue Description
vhost 3.0.0-0222 array false true empty
arrayMigratevirtualhost,whichpointingtooldpackage,toserviceportal.
root 3.0.0-0222 string true false N/A nameofoldpacakgewhichinwebsharefolder.
service 3.0.0-0222 string true false N/A newpackage'sservicename
pkg_dir_prepare
ResourceList
111
Webserviceworkerwillsetupwebsiterootdirectoryunderweb_packagesaccordingtotheinformationwebpackagespecifiedinworkerconfig.Theworkerwillremovethetargetdirectoryunderweb_packagebetweenpreuninstandpostuninst.Makesuretobackupyourwebsiterootinpreuninstscriptduringupgrade.
pkg_dir_prepareexample:
"pkg_dir_prepare":[{
"source":"/var/package/WordPress/target/src",
"target":"wordpress",
"mode":"0755",
"group":"http",
"user":"WordPress"
}]
Key Since type Required Nullable DefaultValue Description
source 3.0.0-0256 string false true N/A
Yourwebpackagesourcecodedirectory.Mostlyitwillbeunderpackagetargetpath(/var/package/$PKG_NAME/target/).Webserviceworkerwillmoveyoursourcedirectorytotargetdirectoryandsetownergroupaccordingtoyouruser:groupspecification.Notethatyoushouldspecifyafullpathinsourcefield.
target 3.0.0-0256 string true false N/A
Yourwebsiterootdirectory.targetdirectorywilbecreatedunderweb_packagesdirectory.Webserviceworkerwillmovesourcedirectorytotargetandsettedwithcorrespondingownergroupaccordingtoyouruser:groupspecification.Yousouldonlyspecifyarelativepathbasedonweb_packages.Notethatwhensourcefieldisnotspecified,webserviceworkerwillonlycreatetargetdirectoryandsetownergroupfortargetdirectory.
mode 3.0.0-0256 string true false N/A targetdirectoryaccessmodee.g."0755",
"0644"...etc.
group 3.0.0-0256 string true false N/A Nameoftargetdirectorygroupownership.
user 3.0.0-0256 string true false N/A Nameoftargetdirectoryuserownership.
WebService
PackagecouldregistertoWebStationviaWebStationwebapiorPackageWorker.
WebServicesupportfollowingtypesstaticservice
staticwebpageswebservicesnginx_phpservice
webservicethatuseingNginxasHTTPserverandPHPasscripts,e.g.phpMyAdminWillgeneratePHPProfileafterserviceregistered.YoucanmodifyitinWebStation->ScriptLanguageSettings->PHP.
apache_phpservicewebservicethatusingApacheasHTTPserveradnPHPasscripts,e.g.WordPressWillgengeratePHPProfileafterserviceregisterd.YoucanmodifyitinWebStation->ScriptLanguageSettings->PHP.
reverse_proxyservicewebservicedependingonreverseproxy,e.g.Docker-GitLab
commonfield
ResourceList
112
Key Since type Required Nullable DefaultValue
Description
service 3.0.0-0214 string true false N/A servicename
display_name 3.0.0-0214 string true false N/A servicedisplayname
display_name_i18n 3.0.0-0214 string false true null servicedisplayedindifferent
language(optional)
support_alias 3.0.0-0214 bool false false true Whethersupportaliasportal,
downgradeisnotallowed
support_server 3.0.0-0214 bool false false true Whethersuportserverportal,
downgradeisnotallowed
icon 3.0.0-0214 string false true null
iconpath,relativepathfrompackage'starget.Resolutionshouldreplacedin{0}.Fornow,weonlysupportpngformat.Willusedefaulticonifthisfieldisempty.
type 3.0.0-0214 string true false N/A servicetype
php 3.0.0-0214 object true false N/A
php-fpmsettingincludingprofile_name,backend,open_basedir,extensions,...etc.Thedetailwillbeshownasfollowingsection.
Detailofphpprofile
Key Since type Required Nullable DefaultValue Description
profile_name 3.0.0-0214 string true false N/A Nameofdefaultphpprofile,usermaynot
modifythisfield.
profile_desc 3.0.0-0214 string true false N/A Descriptionofphpprofile
backend 3.0.0-0214 int true false N/A
phpversion,3forPHP5.6,4forPHP7.0,5forPHP7.1,6forPHP7.2and7forPHP7.3,usermaynotmodifythisfield
open_basedir 3.0.0-0214 string false true empty
stringdefaultphpopen_basedirusermaymodifythisfield.
extensions 3.0.0-0214
stringarray false true empty
array
defaultswitchedonphpextension,usermaynotswitchofthesephpextension;however,theymayswitchonothers
php_settings 3.0.0-0214 object false true empty
objectkeyvaluepairs,definephpinisetting,usermaymodifythisfield.
user 3.0.0-0256 string true false N/A
Nameofuserwithprivilegewhilephp-fpmaccessingyourwebsite.Notethatthevalueofusershouldbethesameaspkg_dir_prepareuserinordertoaccessyourwebsitecorrectly.
group 3.0.0-0256 string true false N/A
Nameofgroupwithprivilegewhilephp-fpmaccessingyourwebsite.Notethatthevalueofgroupshouldbethesameaspkg_dir_preparegroupinordertoaccessyourwebsitecorrectly.
ResourceList
113
staticservice
Whentypeisstatic,systemwillserveyourpacakgewithnginx.
Key Since type Required Nullable DefaultValue Description
root 3.0.0-0214 string true false N/A
serviceworkingdirectory,willbetreatedasabsolutepathifstartwith/,otherwise,relativepathtoweb_pacakges
index 3.0.0-0214
stringarray false true ["index.html",
"index.html"]staticservice'sindexfile.noteusedefaultvalueifnullinthisfield
custom_rule 3.0.0-0214 object false true emptyobject Supportcustomizedroutingrule.For
moredetail,pleaseseeCustomrule
staticserviceworkersettingexample:
{
"service":"static",
"display_name":"staticservice",
"support_alias":true,
"support_server":true,
"type":"static",
"root":"static_dir",
"icon":"ui/Wordpress_{0}.png"
}
nginx_phpservice
Whentypeisnginx_php,systemwillserveyourpackagewithnginx.Thephpfilewillbeexecutedbyphp-fpm.Php-fpmdefaultbehaviorcanbedefinedinfield`php
Key Since type Required Nullable DefaultValue Description
root 3.0.0-0214 string true false N/A
serviceworkingdirectory,willbetreatedasabsolutepathifstartwith/,otherwise,relativepathtoweb_pacakges
index 3.0.0-0214
stringarray false true
["index.htm","index.html","index.php"]
nginxservice'sindexfile.noteusedefaultvalueifnullinthisfield.
custom_rule 3.0.0-0214 object false true emptyobject
Supportcustomizedroutingrule.Formoredetail,pleaseseeCustomrule
connect_timeout 3.0.0-0214 int false false 60 timeoutsettingforconnecting
php-fpm,inunitsofsecond
read_timeout 3.0.0-0214 int false false 60
timeoutsettingforgettingresponsefromphp-fpm,inunitsofsecond
send_timeout 3.0.0-0214 int false false 60 timeoutsettingforsendingrequest
tophp-fpm,inunitsofsecond
php 3.0.0-0214 object true false N/A definedefaultphpprofile
nginx_phpserviceworkersettingexample:
{
"service":"wordpress",
ResourceList
114
"display_name":"WordPress",
"support_alias":true,
"support_server":true,
"type":"nginx_php",
"root":"wordpress",
"icon":"ui/Wordpress_{0}.png",
"php":{
"profile_name":"WordPressProfile",
"profile_desc":"PHPProfileforWordPress",
"backend":6,
"open_basedir":"/var/services/web_packages/wordpress:/tmp:/var/services/tmp",
"extensions":[
"mysql",
"mysqli",
"pdo_mysql",
"curl",
"gd",
"iconv"
],
"php_settings":{
"mysql.default_socket":"/run/mysqld/mysqld10.sock",
"mysqli.default_socket":"mysqli.default_socket",
"pdo_mysql.default_socket":"/run/mysqld/mysqld10.sock",
"mysql.default_port":"3307",
"mysqli.default_port":"3307"
}
},
"connect_timeout":60,
"read_timeout":3600,
"send_timeout":60
}
apache_phpservice
Whentypeisapache_php,nginxwillpassrequesttoapacheserver.Thephpfilewillbeexecutedbyphp-fpm.Php-fpmdefaultbehaviorcanbedefinedinfieldphp.Comparetonginx_php,apache_phpwithadditionalfiledbackendtospecifyapacheversion
Key Since type Required Nullable DefaultValue Description
backend 3.0.0-0214 int true false N/A 1(Apache2.2)or2
(Apache2.4)
intercept_errors 3.0.0-0284 bool false false true true(on)orfalse(off)
apache_phpserviceworkersettingexample:
{
"service":"wordpress",
"display_name":"WordPress",
"support_alias":true,
"support_server":true,
"type":"apache_php",
"root":"wordpress",
"backend":2,
"icon":"ui/Wordpress_{0}.png",
"php":{
"profile_name":"WordPressProfile",
"profile_desc":"PHPProfileforWordPress",
"backend":6,
"open_basedir":"/var/services/web_packages/wordpress:/tmp:/var/services/tmp",
"extensions":[
"mysql",
"mysqli",
"pdo_mysql",
"curl",
"gd",
"iconv"
ResourceList
115
],
"php_settings":{
"mysql.default_socket":"/run/mysqld/mysqld10.sock",
"mysqli.default_socket":"mysqli.default_socket",
"pdo_mysql.default_socket":"/run/mysqld/mysqld10.sock",
"mysql.default_port":"3307",
"mysqli.default_port":"3307"
}
},
"intercept_errors":false,
"connect_timeout":60,
"read_timeout":3600,
"send_timeout":60
}
reverse_proxyservice
Whentypeisreverse_proxy,nginxwillproxyrequesttotargetservices
Key Since type Required Nullable DefaultValue Description
proxy_target 3.0.0-0214 string true false N/A
Proxytarget,supporthttp,https,andunix.Thisvaluewillbefilledinnginxproxy_passURL.Formoredetailpleaseseeproxy_pass
proxy_headers 3.0.0-0214 array false true empty
arraydefineproxyrelayheadervaluepairlist
proxy_intercept_errors 3.0.0-0284 bool false false false
specifywhetherlettingnginxreturnerrorpageforyourpackagesifthere'sanerroroccur.Defaultissettingtofalse
proxy_http_version 3.0.0-0214 int false false 1 proxyhttpversion,support1.0
(0),1.1(1)
custom_rule 3.0.0-0214 object false true empty
object
definespecificroutingrule,shouldbecompatiblewithsupport_aliasandsupport_serversetting.Formoredetailpleaseseecustomrule
connect_timeout 3.0.0-0214 int false false 60 timeoutsettingforconnecting
proxytarget,inunitsofsecond
read_timeout 3.0.0-0214 int false false 60
timeoutsettingforgettingresponsefromproxytarget,inunitsofsecond
send_timeout 3.0.0-0214 int false false 60
timeoutsettingforsendingrequesttophp-fpm,inunitsofsecond
Youcoulddefineproxyheadertomodifyproxybehavior,e.g.modifyhostorturnonwebsocket.Ifneedsupportofwebsocket,youshouldspecifyUpgradeandConnectionheaderasshownbelow:
Key Since type Required Nullable DefaultValue Description
name 3.0.0-0214 string true false N/A headername
value 3.0.0-0214 string true false N/A headervalue
reverse_proxyserviceworkersettingexample:
{
"service":"gitlab",
ResourceList
116
"display_name":"GitLab",
"support_alias":true,
"support_server":true,
"type":"reverse_proxy",
"icon":"ui/gitlab_{0}.png",
"proxy_target":"http://gitlab:30000",
"proxy_headers":[{
"name":"host",
"value":"gitlab"
},{
"name":"Upgrade",
"value":"$http_upgrade"
},{
"name":"Connection",
"value":"$connection_upgrade"
}]
"connect_timeout":60,
"read_timeout":3600,
"send_timeout":60
}
CustomRule
Youcouldmodifyconfigviacustom_rulefieldinjsonkeyvalueformat.Jsonkeyistargetname,jsonvalueistargetconfig'smustachefilepathYoucanreferencenginx_service_template.mustache,apache22_service_template.mustacheandapache24_service_template.mustacheunder/var/packages/WebStation/target/miscforroutingrulethatyoucanmodify.Field{{\@jsonkey\@}}inmustachetemplatewillbereplacedbyfilesspecifiedincustom_ruleYoushouldconsiderthecompatibilitybetweenserverandalias,andcoulduse{{#alias}}toseperatethesetwodifferentroutingrules.
Customruleexample:
"custom_rule":{
"global_rule":"/var/packages/WordPress/target/misc/nginx_global.mustache",
"fastcgi_rule":"/var/packages/WordPress/target/misc/nginx_fastcgi.mustache",
"proxy_rule":"/var/packages/WordPress/target/misc/nginx_proxy.mustache",
"apache_rule":"/var/packages/WordPress/target/misc/apache.mustache"
}
Customruletype
key affecttarget affectservicetype effect
global_rule Nginx all modifyservice'srequestbehavior
fastcgi_rule Nginx nginx_php modifybehaviorofrequestpassedtophp-fpm
proxy_rule Nginx reverse_proxy modifybehaviorofrequestpassedtoproxytarget
apache_rule Apache2.2orApache2.4(dependsonapachebackend) apache_php modifyapachebehavior
ResourceList
117
PortIfyourpackageserviceusesspecificportsforcommunication(e.g.SurveillanceStationusesports19997/udpforsourceportand19998/udpfordestinationport),youshouldprepareaserviceconfigurationfileforthispackagetodescribewhichportswillbeused.Afterthat,oncetheusercreatesfirewallrulesorportforwardingrulesfromthebuilt-inapplication,yourpackageservicewillalsobelistedforselection.
ServiceConfigureFileName
Thefilenameshouldfollowthenamingconvention[package_name].sc(ex:SurveillanceStation.sc).[package_name]shouldbethepackagenamethatisspecifiedbythekey"package"intheINFOfile,andscmeansServiceConfigurefile.
ConfigureFormatTemplate
Pleaseseethefollowingexample:
[service_name]
title="Englishtitle"
desc="Englishdescription"
port_forward="yes"or"no"
src.ports="ports/protocols"
dst.ports="ports/protocols"
[service_name2]
…
Section/KeyDescriptions
Pleaseseethefollowingstatementsforthestringsandkeys:
Section/Key Description Value DefaultValue
DSMRequirement
service_name
Required
Usuallyapackageonlyhasoneuniqueservicename.Ifyourpackageneedsmorethanoneportdescription,youcandefineservice_name2,service_name3,…
Note:service_namecannotbeemptyandcanonlyincludecharacters“a~z”,“A~Z”,“0~9”,“-”,“\”,“.”
Uniqueservicename N/A 4.0-2206
title
Required
EnglishtitlewhichwillbeshownonfieldProtocolatfirewallbuild-inselectionmenu.
Englishtitle N/A 4.0-2206
desc
Required
EnglishdescriptionwhichwillbeshownonfieldApplicationsatfirewallbuild-inselectionmenu.
Englishdescription N/A 4.0-2206
port_forward
Optional
Ifsetto“yes,”yourpackageservicerelatedportswillbelistedwhenuserssetportforwardingrulefrombuild-inapplications.Otherwisetheywillnot
“yes”or“no” “no” 4.0-2206
Port
118
belisted.
src.ports
Optional
Ifyourpackageservicehasspecifiedsourceports,youcansettheminthiskey.Thevalueshouldcontainatleasttheportnumbers,andadefaultprotocolthatistcp+udp.
Ex:6000,7000:8000/tcp,udpmeanssourceportsare6000,7000to8000,allportsaretcp+udp.
ports/protocolsports:1~65535(separatedby‘,’anduse‘:’torepresentportrange)protocols:tcp,udp(separatedby‘,’)
ports:N/A
protocols:tcp,udp
4.0-2206
dst.ports
Required
Eachserviceshouldhavedestinationports.Thevalueshouldcontainatleasttheportnumbers,andadefaultprotocolthatistcp+udp.
Ex:6000,7000:8000/tcp,udpmeansdestinationportsare6000,7000to8000,allportsaretcp+udp.
ports/protocolsports:1~65535(separatedby‘,’anduse‘:’torepresentportrange)protocols:tcp,udp(separatedby‘,’)
ports:N/A
protocols:tcp,udp
4.0-2206
Pleaseseethefollowingexample(SurveillanceStation.sc):
[ss_findhostd_port]
title="SearchSurveillanceStation"
desc="SurveillanceStation"
port_forward="yes"
src.ports="19997/udp"
dst.ports="19998/udp"
Aftertheserviceconfigurationfileisready,addthefollowingcontenttotheresourcespecificationfile.PleaserefertoPortConfigformoredetail.
"port-config":{
"protocol-file":"port_conf/xxdns.sc"
}
CheckportconflictBeforetryingtochangeaportnumber,youwouldneedtocheckiftheportnumberwasalreadyinuse.
HowtocheckiftheportnumberwasinuseAssumethepackagenamedDhcpServerandtheport-configDhcpServer.sccontains:
[dhcp_udp]
title="DHCPServer"
title_key="DHCPServer"
desc="DHCPServer"
desc_key="DHCPServer"
port_forward="no"
dst.ports="67,68/udp"
Pleaserunthefollowinginstructionstocheckiftheportisinusewhileyouaretryingtochangetheportnumberfrom67to667
servicetool--conf-port-conflict-check--tcp667
Theoutputwouldlooklikethis:
Port
119
root@dev:~#servicetool--conf-port-conflict-check--tcp667
IsConflict:falsePort:667Protocol:tcpServiceName:(null)
root@dev:~#
Thereturncodedoesnotindicateportoccupation,youneedtoparsethestandardoutputtoextracttheIsConflictvalue.
IftheIsConflictvalueisfalse,youcanusethatportnumbersafely.
Port
120
MonitorTheDSMmanagesresourcebyslicesorprocesses.Itrequirestheinformation"whoownsthisprocess".Forpackages,theyshouldtellDSMwhichdaemonbelongstothem.
AllyouhavetodoistofilltheSlicefieldinyoursystemdunitwith[package_name].slice.HereisanexamplefieldfromunitsforMyPackage:
...
[Service]
Slice=MyPackage.slice
...
Ifthefieldisproperlyset,youshouldbeabletoseeyourpackageshownontheresourcemonitor.
Monitor
121
PackageExamples
PackageExamples
122
CompileOpenSourceProjectThischapterwillshowyouhowtobuildanopensourceprojectforyourDSMsystemusingPackageToolkit.Ifyouwishtocompiletheopensourceprojectmanually,pleaserefertoAppendixB:CompileOpenSourceProjectManually.
YouhavetocreateSynoBuildConf/build,SynoBuildConf/install,andSynoBuildConf/dependsbeforeusingPackageToolkit.
Unlikethepreviousexample,compilinganapplicationonmostopensourceprojectsmayrequireexecutingthefollowingthreesteps:
1. configure2. make3. makeinstall
Theconfigurescriptconsistsofmanylineswhichareusedtochecksomedetailsaboutthemachinewherethesoftwareisgoingtobeinstalled.Thisscriptwillalsocheckalotofdependenciesonyoursystem.Whenyouruntheconfigurescript,youwillseealotofoutputonthescreen,eachbeingsomesortofquestionwitharespectiveyes/noasareply.Ifanyofthemajorrequirementsaremissingonyoursystem,theconfigurescriptwillexitandyouwillnotbeabletoproceedwiththeinstallationuntilyoumeettherequiredconditions.Inmostcases,compileapplicationsonsomeparticulartargetmachineswillrequireyoutomodifytheconfigurescriptmanuallytoprovidethecorrectvalues.
Whenrunningtheconfigurescripttoconfiguresoftwarepackagesforcross-compiling,youwillneedtospecifytheCC,LD,RANLIB,CFLAGS,LDFLAGS,host,target,andbuild.
Inthischapter,wewilluseplatformavotonasourexample.
Preparation:
Firstdownloadthetmuxsourcecodefromtheofficialgithubsiteoryoucandownloadexampletmuxpackageprojectfromthislink.
Note:Thearchivefileyou'vedownloadedfromtheabovelinksisdifferentfromtheofficialtmuxsourcecode.Wehaveaddedthenecessarybuildscripts.
ProjectLayout:
tmux/
├──tmuxrelatedsourcecode
├──SynoBuildConf/
|├──build
|├──depends
|└──install
└──synology
├──conf/
├──scripts/
└──INFO.sh
SynoBuildConf/depends:Thefollowingisthedependsfileforthisexample.Thereisnothingspecialaboutthedependsfile.
[default]
all="7.0"
SynoBuildConf/build:
OpenSourceTool:tmux
123
Thebuildscriptisslightlydifferentfromthepreviousone.Hereyouwillhavetopassthefollowingenvironmentvariablestoconfigure:
CCARCFLAGSLDFLAGS
Inaddition,sincetmuxisdependentonncurses,youwillneedtousepkg-configtoresolvethenecessaryheaderfilesandlibrariesfortmux.
ThefollowingisanexampleofSynoBuildConf/build:
#!/bin/sh
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
case${MakeClean}in
[Yy][Ee][Ss])
makedistclean
;;
esac
NCURSES_INCS="$(pkg-configncurses--cflags)"
NCURSES_LIBS="$(pkg-configncurses--libs)"
CFLAGS="${CFLAGS}${NCURSES_INCS}"
LDFLAGS="${LDFLAGS}${NCURSES_LIBS}"
autoreconf-if
envCC="${CC}"AR="${AR}"CFLAGS="${CFLAGS}"LDFLAGS="${LDFLAGS}"\
./configure${ConfigOpt}
make${MAKE_FLAGS}
SynoBuildConf/install
Insteadofcopyingthebinarytothedestinationfolder,mostbigprojectswillusemakeinstalltoinstallthebinariesandlibraries.YoucanpasstheDESTDIRenvironmentvariabletospecifywhereyouwanttoinstallthebinariesandlibraries.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
PKG_NAME="tmux"
INST_DIR="/tmp/_${PKG_NAME}"
PKG_DIR="/tmp/_${PKG_NAME}_pkg"
PKG_DEST="/image/packages"
PrepareDirs(){
fordirin$INST_DIR$PKG_DIR;do
rm-rf"$dir"
done
fordirin$INST_DIR$PKG_DIR$PKG_DEST;do
mkdir-p"$dir"
done
}
InstallTmux(){
DESTDIR="${INST_DIR}"makeinstall
}
GenerateINFO(){
synology/INFO.sh>INFO
cpINFO"${PKG_DIR}"
}
InstallSynologyConfig(){
OpenSourceTool:tmux
124
cp-rsynology/scripts/"${PKG_DIR}"
cp-rsynology/conf/"${PKG_DIR}"
cpsynology/PACKAGE_ICON{,_256}.PNG"${PKG_DIR}"
}
MakePackage(){
source/pkgscripts/include/pkg_util.sh
pkg_make_package$INST_DIR$PKG_DIR
pkg_make_spk$PKG_DIR$PKG_DEST
}
main(){
PrepareDirs
InstallTmux
GenerateINFO
InstallSynologyConfig
MakePackage
}
main"$@"
INFO.shAsmentionedbefore,wewilluseINFO.shtogeneratetheINFOfile.
#!/bin/sh
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
./pkgscripts/include/pkg_util.sh
package="tmux"
version="1.9.1-1001"
os_min_ver="7.0-40850"
displayname="tmux"
arch="$(pkg_get_platform)"
maintainer="SynologyInc."
description="TmuxpackageforSynologyDSM."
support_url="https://github.com/tmux/tmux"
thirdparty="yes"
startable="no"
silent_install="yes"
silent_upgrade="yes"
silent_uninstall="yes"
["$(caller)"!="0NULL"]&&return0
pkg_dump_info
Note:RemembertosettheexecutablebitofINFO.shfile.
BuildandCreatePackage:
Runthefollowingcommandstocompilethesourcecodeandbuildthepackage.
/toolkit/pkgscripts-ng/PkgCreate.py-pavoton-ctmux
Afterthebuildprocess,youcanchecktheresultin/toolkit/result_spk.
VerifytheResult
Ifthebuildingprocesswassuccessful,youwillseethatthe.spkfilehasbeenplacedunderresult_spkfolder.Totestthespkfile,YoucanusemanualinstallfromPackageCenterthenconnecttoDSMviasshtotrytmuxcommand.
Ifyoufailedtoinstallthepackage,itispossibletofindouttheerrorlogsat/var/log/messages.
OpenSourceTool:tmux
125
References
ToolkitPackageFormatPrivilegeResource
OpenSourceTool:tmux
126
CompileOpenSourceProject:nmapThischapterwillshowyouhowtobuildanopensourceprojectforyourDSMsystemusingPackageToolkit.Theopensourceprojectthatwearegoingtobuildinthisexampleisnmap,anetworkscanningprogram.Wewilluseavotonasourbuildenvironmentplatform.
Ifyouwishtocompileanopensourceprojectmanually,pleaserefertoAppendixB:CompileOpenSourceProjectManually.
YouhavetocreatetheSynoBuildConf/build,SynoBuildConf/install,andSynoBuildConf/dependsbeforeusingPackageToolkit.
Unlikethepreviousexample,compilinganapplicationonmostopensourceprojectsmayrequireexecutingthefollowingthreesteps:
1. configure2. make3. makeinstall
Theconfigurescriptconsistsofmanylineswhichareusedtochecksomedetailsaboutthemachinewherethesoftwareisgoingtobeinstalled.Thisscriptwillalsocheckalotofdependenciesonyoursystem.Whenyouruntheconfigurescript,youwillseealotofoutputonthescreen,eachbeingsomesortofquestionwitharespectiveyes/noasareply.Ifanyofthemajorrequirementsaremissingonyoursystem,theconfigurescriptwillexitandyouwillnotbeabletoproceedwiththeinstallationuntilyoumeettherequiredconditions.Inmostcases,compileapplicationsonsomeparticulartargetmachineswillrequireyoutomodifytheconfigurescriptmanuallytoprovidethecorrectvalues.
Whenrunningtheconfigurescripttoconfiguresoftwarepackagesforcross-compiling,youwillneedtospecifytheCC,LD,RANLIB,CFLAGS,LDFLAGS,host,target,andbuild.
Preparation:
Youcandownloadtheprojectsbyfollowingcommands:
gitclonehttps://github.com/SynologyOpenSource/ExamplePackages.git
cp-aExamplePackages/libpcap/toolkit/source
cp-aExamplePackages/nmap/toolkit/source
Ournmap&libpcapsourcecodecomefromhere:
wgethttps://nmap.org/dist/nmap-7.91.tar.bz2
wgethttp://www.tcpdump.org/release/libpcap-1.9.1.tar.gz
ProjectLayout:
Afteryoudownloadthesourcecode,yourtoolkitlayoutshouldlooklikethefollowingfigure.
/toolkit/
├──build_env/
│└──ds.${platform}-${version}/
│└──/usr/syno/
│├──bin
│├──include
│└──lib
├──pkgscripts-ng/
└──source/
├──nmap/
│├──nmaprelatedsourcecode
│├──SynoBuildConf/
│|├──build
│|├──depends
OpenSourceTool:nmap
127
│|└──install
|└──synology
│├──PACKAGE_ICON.PNG
│├──PACKAGE_ICON_256.PNG
│├──INFO.sh
│├──conf/
│|├──privilege
│|└──resource
│└──scripts/
└──libpcap/
├──libpcaprelatedsourcecode
├──Makefile
└──SynoBuildConf/
├──build
├──depends
├──install-dev
└──install
Thefile,install-dev,isaspecialfilewhichwewillbecoveredinthefollowingsection.
SynoBuildConf/depends:
TheSynoBuildConf/dependsfornmapisslightlydifferentfromthepreviousexample.Sincenmapdependsonlibpcap,wehavetoaddthevaluetotheBuildDependentfield,sothatthePkgCreate.pycanresolvethedependencyandcompiletheprojectinthecorrectorder.
Thedependsfilefornmapisasfollows.
[BuildDependent]
libpcap
[default]
all="7.0"
However,theSynoBuildConf/dependsforlibpcapisthesameastheHelloWorldExample.
[BuildDependent]
[default]
all="7.0"
SynoBuildConf/build:TheSynoBuildConf/buildscriptisalsodifferentfromthepreviousone.
Hereyouwillhavetopassseveralenvironmentvariablestoconfigure,sothatnmapcanbecompiledproperly
CCCXXLDARSTRIPRANLIBNMCFLAGSCXXFLAGSLDFLAGS
Sincenmapwillbecompiledwithmanyfeaturesbydefault,wewillneedtodisablesomeofthemtomakeitclean.Thefollowinglistcontainsthefeaturesthatwillbedisabled:
OpenSourceTool:nmap
128
ndiffzenmapnpingncatnmap-updateliblua
Note:Ifyouareinterestedinsomeoftheabovefeaturesandyouwanttoenablethem,justchangethe--without-${feature}into--with-${feature}.
ThefollowingistheSynoBuildConf/buildfornmap
#!/bin/sh
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
PKG_NAME=nmap
INST_DIR=/tmp/_${PKG_NAME}
case${MakeClean}in
[Yy][Ee][Ss])
makedistclean
;;
esac
LDFLAGS+=$(shellpkg-config--libslibnllibnl-genl)
envCC="${CC}"CXX="${CXX}"LD="${LD}"AR=${AR}STRIP=${STRIP}RANLIB=${RANLIB}NM=${NM}\
CFLAGS="${CFLAGS}"CXXFLAGS="$CXXFLAGS$CFLAGS"\
LDFLAGS="${LDFLAGS}-ldbus-1"\
./configure${ConfigOpt}\
--prefix=${INST_DIR}\
--without-ndiff\
--without-zenmap\
--without-nping\
--without-ncat\
--without-nmap-update\
--without-liblua\
--with-libpcap=/usr/local
make${MAKE_FLAGS}
Inthisexample,--with-libpcapisassignedwithvalue/usr/local.Weneedtoinstalllibpcap'scrosscompiledproductinto"/usr/local"sothatnmap'sconfigurecanretrievelibpcapcorrectly.
ThefollowingistheSynoBuildConf/buildforlibpcap.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
case${MakeClean}in
[Yy][Ee][Ss])
makedistclean
;;
esac
case${CleanOnly}in
[Yy][Ee][Ss])
return
;;
esac
#prefixwith/usr/local,allfileswillbeinstalledinto/usr/local
envCC="${CC}"CXX="${CXX}"LD="${LD}"AR=${AR}STRIP=${STRIP}RANLIB=${RANLIB}NM=${NM}\
CFLAGS="${CFLAGS}-Os"CXXFLAGS="${CXXFLAGS}"LDFLAGS="${LDFLAGS}"\
./configure${ConfigOpt}\
--with-pcap=linux--prefix=/usr/local
OpenSourceTool:nmap
129
make${MAKE_FLAGS}
makeinstall
Theabovescriptwillinstalllibpcaprelatedfilesinto/usr/local/inchrootenvironment.Afterinstallinglibpcap,nmapcanfindlibpcap'scrosscompiledproductsin/usr/local.
Synologytoolkitprovideslibpcapinchroot.
>dpkg-l|greplibpcap
iilibpcap-avoton-dev7.0-7274allSynologybuild-timelibrary
nmapcanusechroot'slibpcapbyusing${SysRootPrefix}variable.
--with-libpcap=${SysRootPrefix}
SynoBuildConf/installInsteadofcopyingthebinarytothedestinationfolder,mostbigprojectswillusemakeinstalltoinstallthebinariesandlibraries.Sincewehaveusedthe--prefixflagwhenconfiguringthenmapproject,wecanjustexecutemakeinstallanditwillinstallthenmaprelatedfilestothefolderspecifiedby--prefix.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
PKG_NAME="nmap"
INST_DIR="/tmp/_${PKG_NAME}"
PKG_DIR="/tmp/_${PKG_NAME}_pkg"
PKG_DEST="/image/packages"
PrepareDirs(){
fordirin$INST_DIR$PKG_DIR;do
rm-rf"$dir"
done
fordirin$INST_DIR$PKG_DIR$PKG_DEST;do
mkdir-p"$dir"
done
}
SetupPackageFiles(){
makeinstall
synology/INFO.sh>INFO
cpINFO"${PKG_DIR}"
cp-rsynology/conf/"${PKG_DIR}"
cp-rsynology/scripts/"${PKG_DIR}"
cpsynology/PACKAGE_ICON{,_256}.PNG"${PKG_DIR}"
}
MakePackage(){
source/pkgscripts-ng/include/pkg_util.sh
pkg_make_package$INST_DIR$PKG_DIR
pkg_make_spk$PKG_DIR$PKG_DEST
}
main(){
PrepareDirs
SetupPackageFiles
MakePackage
}
main"$@"
OpenSourceTool:nmap
130
conf/resource
{
"usr-local-linker":{
"bin":["bin/nmap"]
}
}
conf/privilege
{
"defaults":{
"run-as":"package"
}
}
INFO.shAsmentionedbefore,wewilluseINFO.shtogeneratetheINFOfile.
#!/bin/sh
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
./pkgscripts-ng/include/pkg_util.sh
package="nmap"
version="7.91-1001"
os_min_ver="7.0-40850"
displayname="nmap"
arch="$(pkg_get_platform)"
maintainer="SynologyInc."
description="ThispackagewillinstallnmapinyourDSMsystem."
["$(caller)"!="0NULL"]&&return0
pkg_dump_info
Note:RemembertosettheexecutablebitofINFO.shfile.
BuildandCreatePackage:
Lastly,runthefollowingcommandstocompilethesourcecodeandbuildthepackage.
/toolkit/pkgscripts-ng/PkgCreate.py-pavoton-x0-cnmap
Afterthebuildprocess,youcanchecktheresultin/toolkit/result_spk.
VerifytheResult
Ifthepackingprocesswassuccessful,youwillseeanspkfileplacedintheresult_spkfolder.Totestthespkfile,YoucanusemanualinstallfromPackageCenterthenconnecttoDSMviasshtotrynmap-v-Alocalhostcommand.
Ifyoufailedtoinstallthepackage,itispossibletofindouttheerrorlogsat/var/log/messages.
References
OpenSourceTool:nmap
131
ToolkitPackageFormatPrivilegeResource
OpenSourceTool:nmap
132
CompileDockerPackage-GitlabThischapterwillshowhowtocompileadockerpackagebyusingawellknownversioncontrolopensource-Gitlab.
TocreateaGitlabdockercontainer,youonlyneedtodependsonDockerpackageandfillindockerworkerconfigurationandtheworkerwilldotheresetforyou.
Asmentionedbefore,youhavetocreateSynoBuildConf/build,SynoBuildConf/installandSynoBuildConf/dependsforpackingspk.However,sincedockerpackagewillpullimagesorbuildimageontheDSM,Wedon'tneedtobuildanycodewhilepackingthespk.
ProjectLayout:
docker-gitlab
├──conf
│├──privilege
│└──resource
├──INFO.sh
├──scripts
│├──postinst
│├──postuninst
│├──postupgrade
│├──preinst
│├──preuninst
│├──preupgrade
│├──script_customized
│└──start-stop-status
├──SynoBuildConf
│├──build
│├──depends
│└──install
└──ui
├──config.png
├──Gitlab_120.png
├──Gitlab_16.png
├──Gitlab_24.png
├──Gitlab_256.png
├──Gitlab_32.png
├──Gitlab_48.png
├──Gitlab_64.png
└──Gitlab_72.png
INFO.sh:
WewilluseINFO.shtogeneratetheINFOfile.ThefollowingistheINFO.shfileforthisexample.Formoredetailsofeachkey'spurpose,pleaseseeINFO.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
package="wordpress_sample"
."/pkgscripts-ng/include/pkg_util.sh"
version="12.9.0-1"
os_min_ver="7.0-40337"
install_dep_packages="Docker>=18.09.0-1017"
maintainer="Gitlab"
thirdparty="yes"
arch="avoton"
reloadui="yes"
adminurl="wordpress"
dsmuidir="ui"
Dockerpackage
133
displayname="Gitlab"
package_icon="`/pkgscripts-ng/include/base64.php${ICON_PATH}`"
["$(caller)"!="0NULL"]&&return0
pkg_dump_info
SynoBuildConf/depends:Thefollowingisthedependsfileforthisexample.
[default]
all="7.0"
SynoBuildConf/build:Thefollowingisthebuildfileforthisexample.SinceWordPressisdependsonPHP,thereisnothingtodoinbuild.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
case${MakeClean}in
[Yy][Ee][Ss])
makeclean
;;
esac
case${CleanOnly}in
[Yy][Ee][Ss])
return
;;
esac
make${MAKE_FLAGS}
SynoBuildConf/install:
Thefollowingistheinstallfileforthisexample.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
#setincludeprojectstoinstallintothispackage
INST_DIR="/tmp/_Gitlab"#tempfolderfordsmfiles
PKG_DIR="/tmp/_Gitlab_pkg"#tempfolderforpackagefiles
PKG_DEST="/image/packages"
#prepareinstallandpackagedir
fordirin$INST_DIR$PKG_DIR;do
rm-rf"$dir"
done
fordirin$INST_DIR$PKG_DIR$PKG_DEST;do
mkdir-p"$dir"#usedefaultmask
done
[-d$INST_DIR/ui]||install-d$INST_DIR/ui
cp-aui/*$INST_DIR/ui
[-d$PKG_DIR]||install-d$PKG_DIR
[-d$PKG_DIR/scripts]||install-d$PKG_DIR/scripts
cp-aconf$PKG_DIR
cp-ascripts/*$PKG_DIR/scripts
chmod755$PKG_DIR/scripts/*
Dockerpackage
134
./INFO.sh>INFO
install-c-m644INFO$PKG_DIR
."/pkgscripts-ng/include/pkg_util.sh"
pkg_make_package$INST_DIR$PKG_DIR
pkg_make_spk$PKG_DIR$PKG_DEST
UIconfig:UIconfigisplacedinuifolder.
{
".url":{
"SYNO.SDS.GitLab":{
"allUsers":true,
"desc":"Docker-GitLab",
"icon":"images/Docker_GitLab_SynoCommunity-{0}.png",
"port":"@PORT@",
"protocol":"http",
"texts":"texts",
"title":"GitLab",
"type":"url",
"url":"/"
}
}
}
Scripts:ThefollowingarespkscriptsforinstallingdockerGitlabspkintoDSM.
preinst:Thereisnothingtodoforpreinstinthisexample.Youcancustomizeyourownpreinstscripttofityourcircumstances.
#!/bin/sh
exit0
postinst:Inpostinststage,wesetupportinui/configafteruserspecifyininstallwizard.
#!/bin/sh
PKG_NAME="Gitlab"
PORT_CONFIG_FILE="/var/packages/$PKG_NAME/etc/port_config"
port=""
if[!-z"$wizard_http_port"];then
#newinstall
port="$wizard_http_port"
elif[-f"$PORT_CONFIG_FILE"];then
#upgrade
port=$(get_key_value"$PORT_CONFIG_FILE"port)
fi
echo"port=$port">$PORT_CONFIG_FILE
if[-f"$SYNOPKG_PKGDEST/app/config"];then
sed-i"s/@PORT@/$port/g""$SYNOPKG_PKGDEST/ui/config"
fi
exit0
Dockerpackage
135
preuninst:Thereisnothingtodoinpreuninstinthisexample.Youcancustomizeyourownpreuninstscripttofityourcircumstances.
#!/bin/sh
exit0
postuninst:Inpostuninststage,weremovegitlabportconfigurationfile.
#!/bin/sh
PKG_NAME="Gitlab"
PORT_CONFIG_FILE="/var/packages/$PKG_NAME/etc/port_config"
if["$SYNOPKG_PKG_STATUS"="UNINSTALL"];then
rm-f"$PORT_CONFIG_FILE"
fi
exit0
preupgrade:Thereisnothingtodoinpreupgradeinthisexample.Youcancustomizeyourownpreupgradescriptforupgradepurpose.
#!/bin/sh
exit0
postupgrade:Thereisnotingtodoinpostupgradeinthisexample.Youcancustomizeyourownpostupgadescriptforupgradepurpose.
#!/bin/sh
exit0
start-stop-status:Forstart-stop-statusinthisexample.Youcouldcalldocker_inspecttoseeifyourcontainerisrunning.
#!/bin/bash
GITLAB_NAME="GitLab"
DOCKER_INSPECT="/usr/local/bin/docker_inspect"
case"$1"in
start)
;;
stop)
;;
status)
"$DOCKER_INSPECT""$GITLAB_NAME"|grep-q"\"Status\":\"running\","||exit1
;;
log)
echo""
;;
*)
echo"Usage:$0{start|stop|status}">&2
exit1
;;
esac
exit0
Privilege:Thefollowingistheprivilegefileunderconfdirectory.Theprivilegefileisconfigurationforspecifyingtheinstallationandruntimeprivilege.Thedetailofprivilegewillbeelaboratedunderprivilgesection.
Dockerpackage
136
{
"defaults":{
"run-as":"package"
},
"username":"Gitlab"
}
`
Worker:Thefollowingistheresourcefileunderconfdirectory.Theresourcefileareconfigurationsforcallingworkers.Inthisexample,sincedockerpackageonlyneeddockerworkertopreparecontainerforthem,wewritedockerworkerconfigurationforsettingupGitlabcontainer.Formoredetails,pleaseseedockerworker.
{
"docker":{
"services":[{
"service":"gitlab",
"image":"gitlab/gitlab-ce",
"container_name":"GitLab",
"tag":"12.9.0-ce.0",
"restart":"always",
"shares":[{
"host_dir":"gitlab/data",
"mount_point":"/var/opt/gitlab"
},{
"host_dir":"gitlab/logs",
"mount_point":"/var/log/gitlab"
},{
"host_dir":"gitlab/config",
"mount_point":"/etc/gitlab"
}],
"ports":[{
"host_port":"{{wizard_http_port}}",
"container_port":"80",
"protocol":"tcp"
},{
"host_port":"{{wizard_https_port}}",
"container_port":"443",
"protocol":"tcp"
},{
"host_port":"{{wizard_ssh_port}}",
"container_port":"22",
"protocol":"tcp"
}]
}]
}
}
BuildandCreatePackageRunthefollowingcommandtobuildyoursourcecodeintopackage.
/toolkit/pkgscripts-ng/PkgCreate.py-pavoton-cdocker-gitlab
Afterthebuildprocess,youcanchecktheresultin/toolkit/result_spk.
VerifytheResult
Dockerpackage
137
Ifthebuildingprocesswassuccessful,youwillseethatthe.spkfilehasbeenplacedunderresult_spkfolder.Totestthespkfile,youcanusemanualinstallinPackageCentertoinstallyourpackage.
Dockerpackage
138
CompileWebPackage-WordPressThischapterwillusewellknownopensourceproject-WordPressasanexampletoshowyouhowtobuildaphpbasedwebpackageintegratingwithDSMPackages--WebStation,MariaDBandApacheserver.
WordPressisthelargestself-hostedbloggingOpenSourceProjectthathavebeenusedbymillionsofwebsites.AllitneedisaPHPwebserverandadatabase,thenyoucanbuildyourownbloggingwebsite.Inthisexample,wewilluseWebStationandApacheaswebservertohostWordPress,anduseMariaDBasdatabase.Oncethewebsitewassettedup,youcouldmodifywebserverconfigurationsforWordPressviaWebStationUI.
Asmentionedbefore,youhavetocreateSynoBuildConf/build,SynoBuildConf/install,SynoBuildConf/dependsandWordPresssourceprojectbeforecreatingspk.However,sinceWordPressdependsonPHP,wedon'thavetocompileanysourcecode.
Preparation:FirstyouneedtodownloadWordPressfromofficialwebsiteandunarchiveitintoyourspksourceproject.Inthisexample,weputitundersrcasshowninProjectLayout.
Secondly,beforeinstallingyourWordPressspk,youneedtodownloadthedependantpackagessuchasWebStation,MariaDB,PHP7.2andApache2.2inDSMfromPackageCenter.NotedthatweusePHP7.2andApache2.2inthisexample,youcanchoosewhateveryouwantinconsideringyourcircumstances.
Third,accordingtoinstructionsfromWordPressofficialwebsite,youhavetosetupDBinformationforWordPress.Formoredetails,pleaseseeWordPress-howotinstallwordpress.
ProjectLayout:
/toolkit/source/wordpress_sample
├──PACKAGE_ICON.PNG
├──PACKAGE_ICON_256.PNG
├──conf
│├──privilege
│└──resource
├──INFO.sh
├──Makefile
├──scripts
│├──postinst
│├──postuninst
│├──postupgrade
│├──preinst
│├──preuninst
│├──preupgrade
│├──script_customized
│└──start-stop-status
├──src
│└──wordpress
│└──wp-admin
├──SynoBuildConf
│├──build
│├──depends
│└──install
└──ui
├──Wordpress_120.png
├──Wordpress_16.png
├──Wordpress_24.png
├──Wordpress_256.png
├──Wordpress_32.png
├──Wordpress_48.png
├──Wordpress_64.png
└──Wordpress_72.png
WebPackage:WordPress
139
INFO.sh(thisfileshouldhaveexecutablepermission:chmod+xINFO.sh):
Asmetionedbefore,wewilluseINFO.shtogeneratetheINFOfile.ThefollowingistheINFO.shfileforthisexample.Formoredetailsofeachkey'spurpose,pleaseseeINFO.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
package="wordpress_sample"
."/pkgscripts-ng/include/pkg_util.sh"
version="5.5.1-1001"
os_min_ver="7.0-40337"
startstop_restart_services="nginx.service"
instuninst_restart_services="nginx.service"
install_dep_packages="WebStation>=3.0.0-0226:MariaDB10:PHP7.3>=7.3.16-0150:Apache2.2>=2.2.34-0104"
install_provide_packages="WEBSTATION_SERVICE"
maintainer="WordPress"
thirdparty="yes"
silent_upgrade="yes"
arch="noarch"
reloadui="yes"
adminprotocol="http"
adminport="80"
adminurl="wordpress"
dsmuidir="ui"
["$(caller)"!="0NULL"]&&return0
pkg_dump_info
SynoBuildConf/depends:
Thefollowingisthedependsfileforthisexample.
[default]
all="7.0"
SynoBuildConf/build:
Thefollowingisthebuildfileforthisexample.SinceWordPressisdependsonPHP,thereisnothingtodoinbuild.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
case${MakeClean}in
[Yy][Ee][Ss])
makeclean
;;
esac
case${CleanOnly}in
[Yy][Ee][Ss])
return
;;
esac
make${MAKE_FLAGS}
WebPackage:WordPress
140
SynoBuildConf/install:
Thefollowingistheinstallfileforthisexample.Inthisexample,weinstallourpackagewiththehelpofMakefile.
#!/bin/bash
#Copyright(c)2000-2021SynologyInc.Allrightsreserved.
#setincludeprojectstoinstallintothispackage
INST_DIR="/tmp/_WordPress"#tempfolderfordsmfiles
PKG_DIR="/tmp/_WordPress_pkg"#tempfolderforpackagefiles
PKG_DEST="/image/packages"
#prepareinstallandpackagedir
fordirin$INST_DIR$PKG_DIR;do
rm-rf"$dir"
done
fordirin$INST_DIR$PKG_DIR$PKG_DEST;do
mkdir-p"$dir"#usedefaultmask
done
makeINSTALLDIR=$INST_DIRinstall
makePACKAGEDIR=$PKG_DIRpackage
."/pkgscripts-ng/include/pkg_util.sh"
pkg_make_package$INST_DIR$PKG_DIR
pkg_make_spk$PKG_DIR$PKG_DEST
Makefile:
ThefollowingistheMakefilefileforthisexample.Watchouttheindentmustbetabinsteadofspace.
WORDPRESSDIR=src
WORDPRESS_INSTALL_DIR=$(INSTALLDIR)/$(WORDPRESSDIR)
allclean:
.PHONY:
install:
[-d$(INSTALLDIR)]||install-d$(INSTALLDIR)
[-d$(WORDPRESS_INSTALL_DIR)]||install-d$(WORDPRESS_INSTALL_DIR)
cp-a$(WORDPRESSDIR)/*$(WORDPRESS_INSTALL_DIR)
[-d$(INSTALLDIR)/ui]||install-d$(INSTALLDIR)/ui
cp-aui/*$(INSTALLDIR)/ui
#changeownertonobodyuser/grouponDS
chown-Rhttp:http$(WORDPRESS_INSTALL_DIR)
INFO:INFO.sh
envUISTRING_PATH=$(STRING_DIR)./INFO.sh>INFO
package:INFO
[-d$(PACKAGEDIR)]||install-d$(PACKAGEDIR)
[-d$(PACKAGEDIR)/scripts]||install-d$(PACKAGEDIR)/scripts
cp-ascripts/*$(PACKAGEDIR)/scripts
chmod755$(PACKAGEDIR)/scripts/*
cp-aPACKAGE_ICON.PNG$(PACKAGEDIR)
cp-aPACKAGE_ICON_256.PNG$(PACKAGEDIR)
cp-aconf$(PACKAGEDIR)
install-c-m644INFO$(PACKAGEDIR)
clean:
WebPackage:WordPress
141
Scripts(thesefilesshouldhaveexecutablepermission):
ThefollowingarespkscriptsforinstallingWordPressspkintoDSM.
preinst:Thereisnothingtodoforpreinstinthisexample.Youcancustomizeyourownpreinstscripttofityourcircumstances.
#!/bin/sh
exit0
postinst:Inpostinststage,wemovethesourceprojectinto"/var/services/web_packages"sinceit'sWebStation'sworkingdirectory.
#!/bin/sh
WEBSITE_ROOT="/var/services/web_packages/wordpress"
chown-RWordPress:http"$WEBSITE_ROOT/*"
exit0
preuninst:Thereisnothingtodoinpreuninstinthisexample.Youcancustomizeyourownpreuninstscripttofityourcircumstances.
#!/bin/sh
exit0
postuninst:Inpostuninststage,weremovesourceprojectfrom"/var/services/web_packages".
#!/bin/sh
exit0
preupgrade:Thereisnothingtodoinpreupgradeinthisexample.Youcancustomizeyourownpreupgradescriptforupgradepurpose.
#!/bin/sh
exit0
postupgrade:Thereisnotingtodoinpostupgradeinthisexample.Youcancustomizeyourownpostupgadescriptforupgradepurpose.
#!/bin/sh
exit0
start-stop-status:Thereisnothingtodoinstart-stop-statusinthisexample.Youcancustomizeyourownstart-stop-statusscriptbyfollowingthetemplate.
#!/bin/sh
case"$1"in
start)
exit0
;;
WebPackage:WordPress
142
stop)
exit0
;;
status)
exit0
;;
*)
exit1
;;
esac
Privilege:Thefollowingistheprivilegefileunderconfdirectory.Theprivilegefileisconfigurationforspecifyingtheinstallationandruntimeprivilege.Thedetailofprivilegewillbeelaboratedunderprivilgesection.
{
"defaults":{
"run-as":"package"
},
"username":"WordPress",
"join-groupname":"http"
}
`
Worker:Thefollowingistheresourcefileunderconfdirectory.Theresourcefileareconfigurationsforcallingworkers.Inthisexample,sincewewouldliketointegrateWordPresswithWebStation,wewillcallWebStation'sworkertorunspecificsetupduringinstallation.Formoredetails,pleaseseewebservice.
{
"webservice":{
"services":[{
"service":"wordpress",
"display_name":"WordPress",
"support_alias":true,
"support_server":true,
"type":"apache_php",
"root":"wordpress",
"backend":1,
"icon":"ui/Wordpress_{0}.png",
"php":{
"profile_name":"WordPressProfile",
"profile_desc":"PHPProfileforWordPress",
"backend":7,
"open_basedir":"/var/services/web_packages/wordpress:/tmp:/var/services/tmp",
"extensions":[
"mysql",
"mysqli",
"pdo_mysql",
"curl",
"gd",
"iconv"
],
"php_settings":{
"mysql.default_socket":"/run/mysqld/mysqld10.sock",
"mysqli.default_socket":"mysqli.default_socket",
"pdo_mysql.default_socket":"/run/mysqld/mysqld10.sock",
"display_errors":"1",
"error_reporting":"E_ALL",
"log_errors":"true"
WebPackage:WordPress
143
},
"user":"WordPress",
"group":"http"
},
"connect_timeout":60,
"read_timeout":3600,
"send_timeout":60
}],
"portals":[{
"service":"wordpress",
"type":"alias",
"name":"wordpress",
"alias":"wordpress",
"app":"SYNO.SDS.WordPress"
}],
"pkg_dir_prepare":[{
"source":"/var/packages/WordPress/target/src/wordpress",
"target":"wordpress",
"mode":"0755",
"user":"WordPress",
"group":"http"
}]
}
}
BuildandCreatePackageRunthefollowingcommandtobuildyoursourcecodeintopackage.
/toolkit/pkgscripts-ng/PkgCreate.py-pavoton-cwordpress_sample
Afterthebuildprocess,youcanchecktheresultin/toolkit/result_spk.
VerifytheResult
Ifthebuildingprocesswassuccessful,youwillseethatthe.spkfilehasbeenplacedunderresult_spkfolder.Totestthespkfile,youcanusemanualinstallinPackageCentertoinstallyourpackage.
WordPressInstallationNote
userneedtocreatedatabasemanuallyfirst(byusingphpmyadminorsomethingelse)databaseaddressshouldbesettolocalhost:/run/mysqld/mysqld10.sockifyouareusingdbrootuserifyouseeerrorpagesfromnginx,youmightneedtodisablenginxerrorinterceptmanually:
1. findoutthenginxconfofwordpress
root@nas:/etc/nginx/conf.d#grep-R'wordpress'.
./.service.6522c657-36cf-4165-84ab-f9e271a712eb.60d1dcff-5b7f-4908-8890-fcfc19b333c8.conf:location^~/wordpress/{
./.service.6522c657-36cf-4165-84ab-f9e271a712eb.60d1dcff-5b7f-4908-8890-fcfc19b333c8.conf:location^~/wordpress
/{
./www.webservice_portal_6522c657-36cf-4165-84ab-f9e271a712eb.conf:location=/wordpress{
./www.webservice_portal_6522c657-36cf-4165-84ab-f9e271a712eb.conf:location~^/wordpress/{
root@nas:/etc/nginx/conf.d#cat.service.6522c657-36cf-4165-84ab-f9e271a712eb.60d1dcff-5b7f-4908-8890-fcfc19b333c8.c
onf
location^~/wordpress/{
includeconf.d/.webstation.error_page.default.conf*;
location^~/wordpress/{
proxy_connect_timeout60s;
proxy_read_timeout3600s;
WebPackage:WordPress
144
proxy_send_timeout60s;
proxy_passhttp://localhost:914;
proxy_set_headerX-Forwarded-By$server_addr;
proxy_set_headerX-Real-IP$remote_addr;
proxy_set_headerX-Forwarded-Proto$scheme;
proxy_set_headerX-Forwarded-Port$server_port;
proxy_set_headerHost$http_host;
proxy_set_headerUpgrade$http_upgrade;
proxy_http_version1.1;
proxy_intercept_errorson;
}
}
2. modifyproxy_intercept_errorsfromontooffinwordpressnginxconf
3. runsystemctlreloadnginxthenyoucanseeoriginalerrorpagefromwordpressnow
WebPackage:WordPress
145
PublishSynologyPackages
PublishSynologyPackages
146
GetStartedwithPublishingTopublishinSynologyPackageCenterrequiresafewsimplesteps.Hereishowtodoit:
1. ApplyonSynologywebsite(https://www.synology.com/en-global/support/developer#apply).
2. ReadandaccepttheDeveloperDistributionAgreementandPackageDeveloperGuideline.NotethatpackagesthatyoupublishonPackageCentermustcomplywiththeTermsofServiceinPackageCenter.
Pleasenotethatthepackagequalitydirectlyinfluencesthelong-termsuccessofyourpackageintermsofinstallation,onlinereviews,engagement,anduserretention.
GetStartedwithPublishing
147
SubmittingthePackageforApprovalBeforeyoupublishyourpackageinPackageCenteranddistributeittousers,youneedtogetthepackage(theSPKfile)ready,makesureyouhavetestitinternally,andprepareyourpromotionmaterialsifneeded.Pleaseseethebelowbeforesubmittingyourpackagetous.
ConfirmPackageBehaviour
Itshouldmeetourpackagereviewitems.PleaserefertoPackagereview.
FreeorPaidPackage
InPackageCenter,youcanpublishfreeorpaidpackages.FreepackagescanbedownloadedbyanyuserinPackageCenter.PaidappscanbedownloadedonlybyuserswhohavearegisteredSynologyAccount.
Decidingwhetheryourpackagewillbefreeorpaidisimportantbecausefreepackagesmustremainfree.
Onceyourpackageispublishedasafreeone,youcannotchangeittoapaidpackage.Ifyoupublishyourpackageasapaidone,youcanchangeittofreeatanytime(butcannotbechangedbacktopaid).
PrepareScreenshotsWhenyoupublishinPackageCenter,youmustsupplyavarietyofhigh-qualityscreen-shotstoshowcaseyourpackageorbrand.Afteryoupublish,theywillappearonyourpackagedetailspage,orelsewhere.Thesescreen-shotsareakeypartofasuccessfulpackagedetailspagethatwillattractandengageusers.Therefore,youmayalsoconsiderhiringaprofessionaltoproducethemforyou.
SubmitYourPackageWhenyouarereadytopublish,gotoSynologywebsite(https://www.synology.com/en-global/support/developer#apply)toapplyyourpackage.
Makesurethat:
Yourpackageistherightversion.Youprovideadownloadlinkforyourpackage.Youprovideapackagedescriptionwithwhatitdoes.Youprovideachangelogwithwhatwasupdatedinthisversion.Thelinktoyourwebsiteandthesupportemailaddressiscorrect.YouhaveacknowledgedthatyourpackagemeetstheDeveloperDistributionAgreementandalsotheTermsofServicefromPackageCenter.
Wewillhaveacompletedandrigorousinternalprocesstomakesurethequalityofthepublishedpackage.Therearefourmajorprocessesinshort:
1. Receiveyourpackageandreleasenote2. Checkthescriptsofthepackage3. VerifythefunctionsofthepackageondifferentmajorversionsofDSManddifferentmodels.(Checklist)4. ReleasethepackageinPackageCenter.Intheverificationstage,wewillaskyoutoprovideabriefoperationmanualandtest
scenariofortesting.Ifthereareanyissues,wewillfeedbacktoyourteamsandprovidetherelatedinformation.Inordertoexpeditetheverification,WestronglyrecommendyourQCshouldverifythepackagebeforesubmittingit.
SubmittingthePackageforApproval
148
SubmittingthePackageforApproval
149
RespondingtoUserIssuesAfteryoupublishapackage,itiscrucialforyoutooffersupporttoyourcustomers.Promptandcourteoussupportcanprovideabetterexperienceforusers,whichcanresultinmoredownloadsandmorepositiveonlinereviewsforyourpackages.Usersaremorelikelytobemoreengagedwithyourpackageandrecommenditifyouareresponsivetotheirneedsandfeedback.
Therearemanywaysthatyoucankeepintouchwithusersandofferthemsupport.Themostcommonwayistoprovideasupportemailaddressinyourpackagedetailspage.Youcanalsoprovidesupportinotherways,suchasaforumoramailinglist.TheSynologytechnicalsupportteamprovidesusersupportfordownloading,installingandpaymentsissues,butissuesthatfalloutsideofthesetopicswillfallunderyourdomain.Examplesofissuesyoucansupportinclude:featurerequests,questionsaboutusingtheappandquestionsaboutcompatibilitysettings.
Afterpublishing,pleaseplanto:
Providealinktoyoursupportresourcesandsetupanyothersupportoutletssuchasaforum.Provideanappropriatesupportemailaddressonyourpackagedetailpageandrespondtouserswhentheyemailyou.Acknowledgeandfixissueswithyourpackage.Ithelpstobetransparentandlistknownissuesonyourpackagedetailspageregularly.Publishupdatesfrequently,withoutsacrificingqualityorannoyinguserswithtoo-frequentupdates.Witheachupdate,makesureyouprovideasummaryofwhatisnew.Userswillreaditandappreciatethatyouareseriousaboutimprovingthequalityofyourpackage.
RespondingtoUserIssues
150
AppendixA:PlatformandArchValueMappingTableThearchitectureoftheNASisdevelopeduponvariousplatformsonwhichyourpackageisdesignedandneedstobeaddressedintheINFOfileinthepackage.
Inthebelowtable,youwillfindthestringvaluecorrespondingtotheplatforminquestion.Forexample,iftheplatformofyourNASisMarvellARMADA370,armada370,thevaluethatshouldtobeprovidedasapairofthearchkeyisarmada370.
PleasechecktheplatformsoftheNAStobesupportedandrefertothetablebelowfortheircorrespondingstringvalues:
ArchFamily Memberplatforms
noarch (allplatforms)
x86_64 apollolake,avoton,braswell,broadwell,broadwellnk,broadwellntb,broadwellntbap,bromolow,cedarview,coffeelake,denverton,geminilake,grantley,kvmx64,purley,skylaked,v1000
i686 evansport
armv7 alpine,alpine4k
armv5 628x
armv8 rtd1296,armada37xx
Supportedplatformvaluelist:
alpinealpine4kapollolakearmada370armada375armada37xxarmada38xarmadaxpavotonbraswellbroadwellbroadwellnkbroadwellntbbroadwellntbapbromolowcedarviewcoffeelakecomcerto2kdenvertonevansportgeminilakegrantleykvmx64monacopurleyrtd1296rtd1619skylakedv1000
AppendixA:PlatformandArchValueMappingTable
151
Youcancheckthe"PackageArch"fieldintheCPUlisttofindoutwhicharchdoesyourNASbelongto.
AppendixA:PlatformandArchValueMappingTable
152
CompileApplicationsTheSynologyNASemploysembeddedSoCorx86-basedCPUs,implementingseveralplatforms--suchasARMandx86--onavarietyofSynologyNASmodels.Inordertorun3rd-partyapplicationsontheSynologyNAS,itisnecessarytocompileapplicationsintoanexecutableformatforthecorrespondingplatform.
ThisinformationwillhelpyoudeterminewhichDSMtoolchain(pleaserefertothe“DownloadDSMToolChain”section)todownloadforeachmodel.
PleaserefertoWhatkindofCPUdoesmyNAShaveforacompletemodellist.
TocompileanapplicationfortheSynologyNAS,acompilerthatrunsonLinuxPCisrequiredinordertogenerateanexecutablefilefortheSynologyNAS.Thiscompilingprocedureiscalledcross-compiling,andthesetofcompilingtools(compiler,linker,etc)usedtocompiletheapplicationiscalledatoolchain.
AppendixB:CompileApplicationsManually
153
DownloadDSMToolChainTodownloadtheDSMtoolchain,pleasegotoSynologyArchive.
Youwouldneedtoknowwhatyourtargetplatformistodownloadthecorrespondingtoolchain.Hereistheplatformlist
Ifyouarenotsureaboutwhichtoolchainyouneed,pleaseexecutethefollowingcommandonyourSynologyNAS.
DiskStation>uname-a
LinuxDiskStation4.4.59+#24922SMPPREEMPTMonAug1912:13:37CST2019x86_64GNU/Linuxsynology_apollolake_718+
DiskStation>
Theoutput"synology_apollolake_718+"tellsyouwhichtoolchainisappropriate.Forexample,apollolakemeansyouneedthetoolchainfor"Intelx86Linux4.4.59(Apollolake)"ontheSynologyArchive.
AfteryoudownloadtheDSMtoolchain,extractittowhereyouwantitonyourcomputer.Forthefollowinginstructionswewillextractto/usr/local/asanexample.Youcanextractthetoolchainbyusingthefollowingcommand:
#tarxJfapollolake-gcc493_glibc220_linaro_x86_64-GPL.txz-C/usr/local/
Pleasemakesurethetoolchainislocatedinthedirectory/usr/localonyourcomputertoensureproperintegration.
DownloadDSMToolChain
154
CompileYoucanstartcompilinganapplicationcalledexamplePkg.c”,forexample,thatlookslikethis:
#include<sys/sysinfo.h>
intmain()
{
structsysinfoinfo;
intret;
ret=sysinfo(&info);
if(ret!=0){
printf("Failedtogetsysteminformation.\n");
return-1;
}
printf("TotalRAM:%u\n",info.totalram);
printf("FreeRAM:%u\n",info.freeram);
return0;
}
Tocompiletheapplication,runthefollowingcommand:
/usr/local/arm-marvell-linux-gnueabi/bin/arm-marvell-linux-gnueabigccexamplePkg.c–osysinfo
YoucanalsowriteaMakefileforit:
EXEC=sysinfo
OBJS=sysinfo.o
CC=/usr/local/arm-marvell-linux-gnueabi/bin/arm-marvell-linuxgnueabi-gcc
LD=/usr/local/arm-marvell-linux-gnueabi/bin/arm-marvell-linuxgnueabi-ld
CFLAGS+=-I/usr/local/arm-marvell-linux-gnueabi/arm-marvell-linuxgnueabi/libc/include
LDFLAGS+=-L/usr/local/arm-marvell-linux-gnueabi/arm-marvell-linuxgnueabi/libc/lib
all:$(EXEC)
$(EXEC):$(OBJS)
$(CC)$(CFLAGS)$(OBJS)-o$@$(LDFLAGS)
clean:
rm-rf*.o$(PROG)*.core
Compile
155
CompileOpenSourceProjectsTocompileanapplicationonmostopensourceprojects,youwillbeaskedtoexecutethefollowingthreesteps:
1. configure2. make3. makeinstall
Theconfigurescriptbasicallyconsistsofmanylineswhichareusedtocheckdetailsaboutthemachineonwherethesoftwareisgoingtobeinstalled.Thescriptwillcheckforalotofdependenciesonyoursystem.Whenyouruntheconfigurescript,youwillseealotofoutputonthescreen,eachbeingsomesortofquestionwitharespectiveyes/noreply.Ifthereareanymajorrequirementsmissingonyoursystem,theconfigurescriptwillexitandyouwillnotbeabletoproceedwiththeinstallationuntilyoumeetalltherequirements.Inmostcases,compileapplicationsonsomeparticulartargetmachineswillrequireyoutomodifytheconfigurescriptmanuallytoprovidethecorrectvalues.
Whenrunningtheconfigurescripttoconfiguresoftwarepackagesforcross-compiling,youwillneedtospecifytheCC,LD,RANLIB,CFLAGS,LDFLAGS,host,target,andbuild,etc.Allthesevaluescanbefoundin/env32.makor/env64.makinyourchrootenvironment.Someexamplesaregivenbelow.
ForIntelX86-compatibleplatforminDSM7.0:
envCC=/usr/local/x86_64-pc-linux-gnu/bin/x86_64-pc-linux-gnu-wrap-gcc\
LD=/usr/local/x86_64-pc-linux-gnu/bin/x86_64-pc-linux-gnu-ld\
RANLIB=/usr/local/x86_64-pc-linux-gnu/bin/x86_64-pc-linux-gnu-ranlib\
CFLAGS="-DSYNOPLAT_F_X86_64-O2-include/usr/syno/include/platformconfig.h-DSYNO_ENVIRONMENT-DBUILD_ARCH=64-D_LARGEFIL
E64_SOURCE-D_FILE_OFFSET_BITS=64-g-DSDK_VER_MIN_REQUIRED=600"\
./configure\
--host=i686-pc-linux-gnu\
--target=i686-pc-linux-gnu\
--build=i686-pc-linux\
--prefix=/usr/local
CompileOpenSourceProjects
156
PackageReviewWeareexcitedthatyouarecreatingpackagesfortheSynologyDSMandwanttohelpyouunderstandourguidelinessoyoucanbeconfidentyourpackagewillgetthroughthereviewprocessquickly.
ReviewItem ReviewGuideline
INFO:requiredfield EnsurerequiredfieldsinINFOexists
INFO:deprecatedfield EnsuredeprecatedfieldsinINFOdoesnotexist(fromDSM7.0)
Lowerpriviledge Thepackageshouldberunwithnon-privilegeduser(fromDSM7.0)
Packageinstallation Thepackageshouldbeinstalledsuccessfully
Packagestart Thepackageshouldbestartedsuccessfully
Packagestop Thepackageshouldbestoppedsuccessfully
Packageupgrade Thepackageshouldbeupgradedsuccessfully
Packageuninstall Thepackageshouldbeuninstalledsuccessfully
Offlineinstallation Thepackageshouldbeabletobeinstalledoffline
Networkactivityduringinstallation Thereshouldnotbeanyabnormalconnectionduringinstallation
Securityadvisorscan Thepackageshouldnotcauseanysecurityadvisorissue
Antivirusessentialscan Thepackageshouldpassthevirusscanning
Cleanup/fileleftover Filesbelongtopackageshouldberemovedafteruninstallation
Cleanup/processleftover Processbelongtopackageshouldbestoppedafteruninstallation
Port-config Registerportnumbersusedbyservicesofpackage
Portconflict Registeredportshouldnotconflictwithotherservices
Errorlog Thereshouldnotbeanyerrorlogleftonsystem
Apparmorlog Thereshouldnotbeanydenylogfromapparmor
Coredumpfile Thereshouldnotbeanycoredumpfileleftonsystem
Ad-hoctest Checkanyotherabnormalbehavior
AppendixC:PublicationReview&Verification
157