Table of Contents - Synology...Open Source Tool: tmux Open Source Tool: nmap Docker package Web...

Preview:

Citation preview

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

Recommended