Packaging guideline - ReadyNAS/sdk GitHub Wiki
- Read
NasApplicationsSpec.md
and follow the guidelines. - If your application uses
systemd
to control service start/stop, your unit name must befvapp-[AppName].service
. If not, include an emptyServiceName
tag. For example,<ServiceName/>
. (See sample 2) - Your
postinst
must containsystemctl restart apache2.service
. (Older documentation that said to usereload-or-restart
was wrong.) - You can optionally
enable
and/orstart
your application frompostinst
. Otherwise, installation of your application will NOT be enabled or started. For example, you can addsystemctl start fvapp-sample1.service
andsystemctl enable fvapp-sample1.service
inpostinst
. - Your
prerm
must stop and disable the service if you use systemd service.
From script languages such as bash, php, perl, etc, you can use command line utility /usr/bin/rn_nml
to send minimum set of NML in simple form.
For example, if you want to get the Serial Number of the device, you can use rn_nml -g systeminfo | xmllint --xpath /SystemInfo/Model/text\(\) -
. Please note, xmllint
is in the libxml2-utils
package. So if you want to use the xmllint
command, your app must use the libxml2-utils
package.
# mymodel=$(rn_nml -g systeminfo | xmllint --xpath '/SystemInfo/Model/text()' -)
# echo $mymodel
ReadyNAS 314
This command returns all system info, including serial number and model.
# rn_nml -g systeminfo
<?xml version="1.0" encoding="UTF-8"?>
<SystemInfo>
<Model>ReadyNAS 314</Model>
<Serial>3C312A0J0010A</Serial>
<Firmware_Name>ReadyNASOS</Firmware_Name>
<Firmware_Version>6.0.1-T1089</Firmware_Version>
<Memory>1024</Memory>
<CPU_Number>4</CPU_Number>
<CPU_Frequency>2127.915039</CPU_Frequency>
<MAC_Address>84:1B:5E:26:D7:10,84:1B:5E:26:D7:11</MAC_Address>
<Language>en_us</Language>
<Raid_Level>zfs</Raid_Level>
<HDD_Vendor/>
<HDD_Model/>
<HDD_Serial/>
<HDD_Firmware/>
<Registered>0</Registered>
<Raid/>
<Anti-Virus-Def-Version>not enabled</Anti-Virus-Def-Version>
<Anti-Virus-Last-Updated>2013020018</Anti-Virus-Last-Updated>
</SystemInfo>
This command returns all shares in simple form. For detailed listing, use rn_nml -g shares-detail
instead.
# rn_nml -g shares
<?xml version="1.0" encoding="UTF-8"?>
<Share_Collection>
<Share id="data/Backup" resource-id="data/Backup" resource-type="SimpleShare" share-name="Backup"/>
<Share id="data/Documents" resource-id="data/Documents" resource-type="SimpleShare" share-name="Documents"/>
<Share id="data/Music" resource-id="data/Music" resource-type="SimpleShare" share-name="Music"/>
<Share id="data/Pictures" resource-id="data/Pictures" resource-type="SimpleShare" share-name="Pictures"/>
<Share id="data/Videos" resource-id="data/Videos" resource-type="SimpleShare" share-name="Videos"/>
<Share id="data/εδΊ¬" resource-id="data/εδΊ¬" resource-type="SimpleShare" share-name="εδΊ¬"/>
</Share_Collection>
NOTE: This output format is subject to change without notice.
This command returns all shares in detailed form. For simple parsing purpose, it is recommended to use rn_nml -g shares
instead.
# rn_nml -g shares-detail
<?xml version="1.0" encoding="UTF-8"?>
<Share_Collection>
<Share id="data/Backup" resource-id="data/Backup" resource-type="Share">
<Folder_Owner>
<Access>ReadWrite</Access>
<System_User id="99" resource-id="99" resource-type="System_User">
<User_Id>99</User_Id>
<User_Name>guest</User_Name>
</System_User>
</Folder_Owner>
<Folder_Group>
<Access>ReadWrite</Access>
<System_Group id="99" resource-id="99" resource-type="System_Group">
<Group_Id>99</Group_Id>
<Group_Name><![CDATA[guest]]></Group_Name>
</System_Group>
</Folder_Group>
<Folder_Everyone>
<Access>ReadWrite</Access>
</Folder_Everyone>
<Access_Acl_List>
<acl tag="user-obj" perm="7"/>
<acl account="98" tag="user" perm="7"/>
<acl account="99" tag="user" perm="7"/>
<acl tag="group-obj" perm="7"/>
<acl account="98" tag="group" perm="7"/>
<acl account="99" tag="group" perm="7"/>
<acl tag="mask" perm="7"/>
<acl tag="other" perm="7"/>
</Access_Acl_List>
<Default_Acl_List>
<acl tag="user-obj" perm="7"/>
<acl account="98" tag="user" perm="7"/>
<acl account="99" tag="user" perm="7"/>
<acl tag="group-obj" perm="7"/>
<acl account="98" tag="group" perm="7"/>
<acl account="99" tag="group" perm="7"/>
<acl tag="mask" perm="7"/>
<acl tag="other" perm="7"/>
</Default_Acl_List>
<Protocol_List>
<cifs id="0" resource-id="0" protocol-id="1" resource-type="cifs">
<Group_List/>
<Host_List/>
<User_List/>
<DFS_List/>
<Property_List>
<Not_Available>0</Not_Available>
<Share_Display_Option>0</Share_Display_Option>
<Enable_Oplocks>0</Enable_Oplocks>
<Enable_Recycle_Bin>0</Enable_Recycle_Bin>
<Recycle_Size_Limit>0</Recycle_Size_Limit>
<Recycle_Age_Limit>25000</Recycle_Age_Limit>
<Default_Access>ReadWrite</Default_Access>
<Allow_Guest_Access>1</Allow_Guest_Access>
<New_File_Folder_Perm_Autoset>1</New_File_Folder_Perm_Autoset>
<Acl_Change_Restriction_Toggle>0</Acl_Change_Restriction_Toggle>
<Folder_Create_Group_Rights>ReadWrite</Folder_Create_Group_Rights>
<Folder_Create_EveryOne_Rights>ReadWrite</Folder_Create_EveryOne_Rights>
<File_Create_Group_Rights>ReadWrite</File_Create_Group_Rights>
<File_Create_EveryOne_Rights>ReadWrite</File_Create_EveryOne_Rights>
<Enable_DFS>0</Enable_DFS>
</Property_List>
</cifs>
..... deleted by editor .....
This command returns all internal volumes. For detailed information (such as volume size), use rn_nml -g volumes-detail
instead.
# rn_nml -g volumes
<?xml version="1.0" encoding="UTF-8"?>
<Volume_Collection>
<Volume resource-id="MyVolume" resource-type="Volume"/>
<Volume resource-id="data" resource-type="Volume"/>
</Volume_Collection>
NOTE: This output format is subject to change without notice.
This command returns all internal volumes with detailed information. For simple listing, use rn_nml -g volumes
instead.
# rn_nml -g volumes-detail
<?xml version="1.0" encoding="UTF-8"?>
<Volume_Collection>
<Volume resource-id="data" resource-type="Volume" ejectable="false">
<Property_List>
<Volume_Name>data</Volume_Name>
<Volume_Mode>1</Volume_Mode>
<AltRoot/>
<DeDup/>
<AutoExpand>on</AutoExpand>
<AutoReplace>on</AutoReplace>
<CacheFile/>
<Delegation>on</Delegation>
<ListSnapshots>on</ListSnapshots>
<Version>0</Version>
<Allocated>70190504</Allocated>
<Capacity>70190504</Capacity>
<Free>70182876</Free>
<Available>70182876</Available>
<GUID>e738b302-236b-48b6-a3f7-af38c00007bd</GUID>
<Health>UNPROTECTED</Health>
<Checksum>on</Checksum>
</Property_List>
<vdev_list>
<RAID LEVEL="1" ID="0">
<Disk resource-id="sda"/>
</RAID>
</vdev_list>
</Volume>
</Volume_Collection>
Send <add>
with resource-type="Share_Collection"
. This command adds one share whose name is sharename
under the volume named volname
. Allows CIFS and AFP access. Access using the other protocols will be disabled. As a special case, if volname
is *
, then a share is created on the volume selected by readynasd
.
rn_nml -a share:/volname/sharename:opts
rn_nml -a share:/volname/sharename
Same as above, except this command can specify which protocol is enabled by comma separated form. Valid protocols are cifs
, afp
, nfs
and ftp
. You can use *
as volname
.
# rn_nml -a share:/data/MyShare ... create share with cifs and afp enabled
# rn_nml -a share:/data/MyShare:cifs ... create share with only cifs enabled
# rn_nml -a share:/data/MyShare:ftp,nfs ... create share with ftp and nfs enabled
# rn_nml -a 'share:/*/MyShare' ... create share with cifs and afp enabled on default volume
rn_nml -s share:/volname/sharename:opts
rn_nml -s share:/volname/sharename
Similar to 'rn_nml -a', but this command sets options for an existing share.
# rn_nml -s share:/data/MyShare ... set share with cifs and afp enabled
# rn_nml -s share:/data/MyShare:cifs ... set share with only cifs enabled
# rn_nml -s share:/data/MyShare:ftp,nfs ... set share with ftp and nfs enabled
# rn_nml -s share:/data/MyShare: ... set share with all protocol disabled
Protocol specific options can be included. Currently default access and host-based ACL can be set.
# rn_nml -s share:/data/MyShare:protocol{protocolopts}
The protocolopts
is form paramname=(paramvalue)
.
paramname | paramvalue |
---|---|
default | default access, one of Disabled , ReadOnly or ReadWrite . |
hostacl | triplet of hostspec , access , root_privilege . |
If do not want to change for the particular protocols, use {} . Below is example to set NFS for ReadOnly for default, and specify host specific access control. Other protocols remain unchanged. |
# ./rn_nml -s 'share:/data/Videos:cifs{},afp{},nfs{default=(ReadOnly),hostacl=(10.20.0.25,ReadWrite,0),hostacl=(10.20.0.20,ReadWrite,1)},ftp{}'
This command marks a share that is used by appname
. If share is UsedBy
appname
and the /apps/{appname}/etc/samba.include
file exists, then smb.conf
includes the share within the [sharename]
section. If samba.include
does not exist, the following files are searched in the order listed below and the first file found is included instead. {Arch}
is either x86_64
or arm
. {ShareName}
is the sharename.
/apps/{appname}/etc/samba.include
/apps/{appname}/etc/samba.include.{Arch}
/apps/{appname}/etc/samba.include.{ShareName}.{Arch}
Example follows.
# rn_nml -a shareUsedBy:/data/MyShare=myapp
This command deletes the specified share.
root@nas-26-D7-10:~# rn_nml -g shares
<?xml version="1.0" encoding="UTF-8"?>
<Share_Collection>
<Share id="data/Backup" resource-id="data/Backup" resource-type="SimpleShare" share-name="Backup"/>
<Share id="data/Documents" resource-id="data/Documents" resource-type="SimpleShare" share-name="Documents"/>
<Share id="data/Music" resource-id="data/Music" resource-type="SimpleShare" share-name="Music"/>
<Share id="data/Pictures" resource-id="data/Pictures" resource-type="SimpleShare" share-name="Pictures"/>
<Share id="data/Videos" resource-id="data/Videos" resource-type="SimpleShare" share-name="Videos"/>
<Share id="data/ι«ε
η" resource-id="data/ι«ε
η" resource-type="SimpleShare" share-name="ι«ε
η"/>
</Share_Collection>
root@nas-26-D7-10:~# rn_nml -d share:/data/ι«ε
η
root@nas-26-D7-10:~# rn_nml -g shares
<?xml version="1.0" encoding="UTF-8"?>
<Share_Collection>
<Share id="data/Backup" resource-id="data/Backup" resource-type="SimpleShare" share-name="Backup"/>
<Share id="data/Documents" resource-id="data/Documents" resource-type="SimpleShare" share-name="Documents"/>
<Share id="data/Music" resource-id="data/Music" resource-type="SimpleShare" share-name="Music"/>
<Share id="data/Pictures" resource-id="data/Pictures" resource-type="SimpleShare" share-name="Pictures"/>
<Share id="data/Videos" resource-id="data/Videos" resource-type="SimpleShare" share-name="Videos"/>
</Share_Collection>
rn_nml -d shareUsedBy:/volname/sharename=appname
This command unmarks a share that is used by appname
.
# rn_nml -a shareUsedBy:/data/MyShare=myapp
rn_nml -a user:username:primarygroup:b64pass
rn_nml -a user:username:primarygroup:b64pass:uid
This command adds a new user. b64pass
is base64 encoded plain password. Two examples are shown below. The first example creates user account r2d2
whose primary group is jedi
, password is StarWars
, and uid is 1962
. The second example does not specify uid.
# rn_nml -a user:r2d2:jedi:$(echo -n StarWars | base64):1962
# rn_nml -a user:r2d2:jedi:$(echo -n StarWars | base64)
This command lists all users in NML.
# rn_nml -g users
rn_nml -s user:uid:b64pass:primarygroup
This command changes user password and primary group.
# rn_nml -s user:1963:$(echo -n DarthVader | base64)
# rn_nml -s user:1963:$(echo -n DarthVader | base64):droid
This command deletes the user identified by uid
.
# rn_nml -d user:1962
rn_nml -a group:groupname:gid
This command adds a new group. Two examples are shown below. The first example creates the group account jedi
whose gid is 2013
. The second example does not specify gid.
# rn_nml -a group:jedi:2013
# rn_nml -a group:jedi
This command lists all groups in NML.
# rn_nml -g groups
This command deletes the group identified by gid
.
# rn_nml -d group:2013
This command installs a Debian package. path-to-deb-pkg
is absolute path to the local Debian package file, whose extension is .deb
.
Same as above, but ignores verifying signature.
This command sends <set>
with resource-type="LocalApp"
, resource-id="Application"
, and state="running"
. This command will eventually call systemctl start fvapp-[AppName].service
and systemctl enable fvapp-AppName].service
.
This command sends <set>
with resource-type="LocalApp"
, resource-id="Application"
, and state="stopped"
. This command will eventually call systemctl stop fvapp-[AppName].service
and systemctl disable fvapp-AppName].service
.
This command shuts down and powers off the system.
This command shuts down and reboots the system.
event_push app readynasd '<add-s resource-type="LocalApp" resource-id="LocalApp"><LocalApp appname="sample1" success="0" reboot="0"/></add-s>' 0 0
This command sends an event to readynasd
for app installation complete. Default value of success
and reboot
is 0
. 0
is false
. When success=0
, then reboot
flag is ignored. If success=1
and reboot=1
, then the appropriate message will display in a pop-up window.
event_push app readynasd '<delete-s resource-type="LocalApp" resource-id="LocalApp"><LocalApp appname="sample1" success="0" reboot="0"/></delete-s>' 0 0
This command sends an event to readynasd for app un-installation complete. Default value of success
and reboot
is 0
. 0
is false
. When success=0
, then reboot
flag is ignored. If success=1
and reboot=1
, then the appropriate message will display in a pop-up window.
ReadyNAS OS 6.7.0 has added a newer feature to allow app developers to use existing third-party debian repositories within their app. This will help the developer provide the newer apps based on updates that may not exist in the Debian Jessie's repo and/or would require a more manual intervention.
The new configuration allowed for the ReadyNAS App developers is located within the debian control
file. At the end of the control
file you are able to add the following user defined fields:
XB-Repo:
XB-Repo-Key-Url:
XB-Repo-Keyserver:
XB-Repo-Key-ID:
-
XB-Repo
contains the string that you would have in your /etc/apt/source.d/x.list -
XB-Repo-Key-Url
contains a link to the gpg key file information. -
XB-Repo-Keyserver
is optional and it can contain the repoβs referenced key server. -
XB-Repo-Key-ID
contains the key id that would work with the key server.
The ReadyNAS will look at these fields, apply the configuration settings, update the apt list, then run the updated apt ReadyNAS app installation.
The following is an example o how a control file would look:
Source: nodejs-app
Section: contrib
Priority: extra
Maintainer: Dev ReadyNAS <[email protected]>
Build-Depends: debhelper (>= 8.0.0)
Standards-Version: 3.9.8
Homepage: https://nodejs.org/
Package: nodejs-app
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, readynasos (>= 6.7.0~T158), nodejs (>= 6.9.0)
Conflicts: nodejs (>=7.0.0)
Description: NodeJS App for ReadyNAS
XB-Repo: deb https://deb.nodesource.com/node_6.x jessie main
XB-Repo-Key-Url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key
Note: To help ensure ReadyNAS root volumes are kept at a manageable capacity. We would urge developers to keep the app dependencies under 100MB. Depending on what the installed applications.