Plugin system documentation


RobJ

Recommended Posts

Is there documentation for the unRAID plugin system?

 

Unfortunately, the docs on plugin development aren't organized, or in one place.  It is scattered around, and no one person is maintaining it.  Here's what I found:

- How does the plugin system work? Documentation Added  (old, and some parts are obsolete, but provides a basic foundation)

- Plugin Authors: Changes for 6.1 release - discusses compatibility changes

- Important unRAID 6.1 Plugin System Changes - discusses compatibility changes too

- New!  Version 6.3.0-rc9 Release Notes - important plugin changes for 6.3

- Community Applications plugin - the app store for all plugins; read the note at the bottom of first post

- Plugin Templates for CA / Appstore - guidelines for full Community Applications compatibility

- Application Template Categorizer plugin - for plugin or Docker template authors - use it!

- Programming board  (there is a little more info scattered throughout this board for devs)

- Per this post, "study existing code and plugins.  Also look at scripts in /usr/local/sbin.  For example 'emhttp_event' has info on events".

- Most new plugin authors start by taking apart a few selected plugins, and copying the basic structures.

- Note to prospective plugin developers: always ask yourself first, is this something better suited as a Docker container?  Because of better program isolation and fewer dependency issues, developers are strongly encouraged to choose Docker container development over creating another plugin.

 

Support topics for all plugins are found in the Plugin Support board.

Link to comment
  • 1 year later...
  • 1 year later...

Plugins dependent upon other plugins.  (Mainly notes for myself so I know what CA is doing)

 

Plugins at boot time are installed in order of the ASCII sort (not natural) of the filename including the .plg extension

 

CA when doing multiple previous app installations installs them in order of an ASCII sort excluding the .plg extension.  This handles the special circumstance where UD+ looks for UD to be queued for install at boot prior to installing but it actually winds up installing first at boot time.

 

If you make a plugin that is dependent upon another plugin being installed and it errors out if the other plugin is not installed, you must ensure that you can handle both very slightly differing sort orders.

Link to comment
  • 2 months later...

Is there any documentation about the latest plugin syntax? I'm trying to find a way to cache non-packages for offline installation of the plugin. 

 

 

The linked guide mentions being able to use 

<FILE Name="/usr/local/emhttp/plugins/&name;/ntfs-3g.png">
<LOCAL>/boot/config/plugins/&name;/ntfs-3g.png</LOCAL>
</FILE>

to be able to store a copy of the defined file on the USB. However, it can't integrate with a FILE tag that also has a URL. I want to do the opposite, to mirror the behavior of installing packages. That is, download the remote file to the USB (under /boot/config/plugins) and then copy the file into the working directory under /usr/local/emhttp/plugins. Then on a reboot/reinstall of the plugin it can utilize the already-downloaded version instead of making a network request.

 

However, this copy operation does not seem to function in reverse. The following snippet successfully downloads the file from Github onto the USB but does not copy the file from the USB into the emhttp working directory

 

<FILE Name="/boot/config/plugins/icon.png">
<URL>www.blahblahgithub.com/icon.png</URL>
<MD5>&iconfilemd5;</MD5>
</FILE>

<FILE Name="/boot/config/plugins/icon.png">
<LOCAL>/usr/local/emhttp/plugins/snmp/icon.png</LOCAL>
</FILE>

 

Without using a custom-written inline bash file, is there any built in syntax to accomplish this? Is there any documentation on what tags are available to us and how they work? I assume the plugin manager isn't open source but if anyone knows of a repo I can peruse to glean more info, I can do that as well. 

Link to comment

From looking at your .plg, why not simplify the entire thing?  Have the .txz have everything that is stored within /usr/local/emhttp/plugins/snmp  You don't need to worry about permissions, copying etc and your build process gets simplified

  • Like 1
Link to comment
On 4/2/2020 at 5:52 AM, Squid said:

From looking at your .plg, why not simplify the entire thing?  Have the .txz have everything that is stored within /usr/local/emhttp/plugins/snmp  You don't need to worry about permissions, copying etc and your build process gets simplified

I'll have to look into that. Thanks for the advice! The .txz file would then be cached on the USB and unzipped into  /usr/local/emhttp/plugins? Do you have any recommended repos that install in this fashion? 

 

I would still be interested in an answer to my original question if anyone can provide: What documentation is out there for the allowed XML tags in a .plg file that would tell us input and output, allowed tags, etc. 

Link to comment

You can have a look at the Dynamix plugins. Dynamix System Temp maybe a good example for your case.

 

About the use of <FILE> and <LOCAL>

 

<FILE>     = indicates the final destination of the file location and name

<LOCAL> = indicates where a local copy (previously downloaded) version of the file is placed.

 

In your example, it would be

<FILE Name="/boot/config/plugins/snmp/icon.png">
<URL>https://raw.githubusercontent.com/path/to/file/icon.png</URL>
</FILE>

<FILE Name="/usr/local/emhttp/plugins/snmp/icon.png">
<LOCAL>/boot/config/plugins/snmp/icon.png</LOCAL>
</FILE>

Always make a dedicated folder for your plugin, i.e. "snmp" and store files in there.

 

The use of <LOCAL> has the advantage that once a file is downloaded and locally stored on flash, it doesn't need to be redownloaded, it will be copied locally during installation of the plugin.

 

The disadvantage of this method is that a updated version of the file doesn't get automatically installed.

Your plugin script needs to remove the local copy first, then redownload the file, if a new version is required. This is all additional coding you have to provide yourself.

 

Edited by bonienl
Link to comment
1 hour ago, kubed_zero said:

I would still be interested in an answer to my original question if anyone can provide: What documentation is out there for the allowed XML tags in a .plg file that would tell us input and output, allowed tags, etc. 

Unfortunately that documentation doesn't exist.

It is one of those "open" actions.

Link to comment
2 hours ago, kubed_zero said:

I would still be interested in an answer to my original question if anyone can provide: What documentation is out there for the allowed XML tags in a .plg file that would tell us input and output, allowed tags, etc. 

I think the closest you will get is by running

plugin --help

from the CLI

Link to comment
7 hours ago, kubed_zero said:

Do you have any recommended repos that install in this fashion? 

All of mine.  All of @bonienl   Build files (copy_to_git.sh and pkg_build) are on my GitHub https://github.com/Squidly271/community.applications which can be used as a basis for yours are also there.

 

7 hours ago, kubed_zero said:

What documentation is out there

You probably already found this which is the closest to "documentation"  https://forums.unraid.net/topic/33322-how-does-the-plugin-system-work-documentation-added-wip/

 

Beyond that, what every one around here did when starting is look at @bonienl's plugins as a basis

6 hours ago, bonienl said:

Unfortunately that documentation doesn't exist.

 

But it's coming soon(tm)   😁

On 9/1/2014 at 4:52 PM, limetech said:

 

I'm working on some documentation and guidelines for Plugin Developers which will show up in a wiki on limetech github.

 

Link to comment
  • 1 year later...
  • 4 months later...

Since this has already happened to 2 different plugins from different authors, it should be noted that spaces, special characters etc are NOT allowed in the name attribute

<PLUGIN  name="&name;"

Spaces etc worked by accident on versions of the OS < 6.10, but when on 6.10 this will prevent the GUI from displaying the current update status of the plugin

 

Additionally, the filename of the .plg, the folder it's stored in within /usr/local/emhttp/plugins) and the name attribute should all be the same for best results on the system

  • Like 1
Link to comment
  • 1 month later...

Where can I find information on writing the actual heart of a plugin? I get the pgl syntax but can't find any kind of documentation or comments on writing an actual plugin. I want to write a web UI front end for Unraid for rclone to let you create schedules for syncing. Something that lets the user specify when to run, source, which rclone configured bucket, etc... I know the rclone side of everything but can't figure out how to get a plugin with a web interface in Unraid.

Link to comment
12 hours ago, IMTheNachoMan said:

Where can I find information on writing the actual heart of a plugin? I get the pgl syntax but can't find any kind of documentation or comments on writing an actual plugin. I want to write a web UI front end for Unraid for rclone to let you create schedules for syncing. Something that lets the user specify when to run, source, which rclone configured bucket, etc... I know the rclone side of everything but can't figure out how to get a plugin with a web interface in Unraid.

Unfortunately based on my own personal search i dont believe that there is any single source of the information you seek. What little there is is scattered around old forum posts with little mention of how out of date it may be. Your best bet is to pick a popular plugin made by one of the big names on the forums, like squid, dlandon, or bonienl, head over to the github repo and try to understand how they work. From there you can graduate to finding the plugins webui files on your server and modifying the live files to try and change things around a bit. If you break something a reboot is all that is needed to unpack the plugin fresh from its archive files and preferably you would choose a not overly risky plugin to mess with. Its a round about way of getting what you need, but so far as i have found there really isnt another option.

Link to comment

At a high level, there's no real challenge in creating a plugin.  After the header information on the .page, it's all standard javascript / html / css from that point, and the .plg itself handles the install, background scripts started right away etc

 

But, like @primeval_god says, you reverse engineer something already existing (I'd suggest the dynamix series of plugins to look at first - Mine do things slightly differently).

 

Any specific questions just ask and someone will hopefully come back with the answer

Link to comment
57 minutes ago, primeval_god said:

Unfortunately based on my own personal search i dont believe that there is any single source of the information you seek. What little there is is scattered around old forum posts with little mention of how out of date it may be. Your best bet is to pick a popular plugin made by one of the big names on the forums, like squid, dlandon, or bonienl, head over to the github repo and try to understand how they work. From there you can graduate to finding the plugins webui files on your server and modifying the live files to try and change things around a bit. If you break something a reboot is all that is needed to unpack the plugin fresh from its archive files and preferably you would choose a not overly risky plugin to mess with. Its a round about way of getting what you need, but so far as i have found there really isnt another option.

 

Got it. Thank you! I started doing that but thought (read: hoped) there was an easier way.

 

34 minutes ago, Squid said:

At a high level, there's no real challenge in creating a plugin.  After the header information on the .page, it's all standard javascript / html / css from that point, and the .plg itself handles the install, background scripts started right away etc

 

But, like @primeval_god says, you reverse engineer something already existing (I'd suggest the dynamix series of plugins to look at first - Mine do things slightly differently).

 

Any specific questions just ask and someone will hopefully come back with the answer

 

There seems to be a lot of proprietary stuff. For example, it looks like this part is used to add a new row to the page? But what exactly is the format of that first line?

_(Hourly schedule)_:
: <span class="time">&nbsp;&nbsp;_(Any)_</span>
  <span class="time"><input type="number" name="hourlyMM" value="<?=$cfg['hourlyMM']?>" min="0" max="59" maxlength="2" class="cast" required></span>
  <span class="date">&nbsp;_(Any)_</span>
  <span class="auto"><?=$tasks1 ? implode(", ", $tasks1) : '<_(none)_>'?></span>

 

Link to comment

The basic format (if you're utilizing Dynamix to reverse engineer) is Markdown.  That first line simply is "Hourly schedule:", but the underscores cause it to also be translated if the translations exist.  There's a translation guide kicking around here somewhere.

 

Now, @bonienl will yell at me if I say this, but nothing says you have to actually follow that formatting.  CA can't use it all, and is simply javascript, most of my other plugins handle the formatting and saving the config information via standard posts. 

 

It really all depends upon what you're trying to accomplish and how you want it to look.

Link to comment
45 minutes ago, Squid said:

It really all depends upon what you're trying to accomplish and how you want it to look.

 

To start with I just want to make a web UI for rclone to configure sync jobs. A place to specify source share, destination rclone cloud service, when to run, cache size, etc.... I have a script that does it and sends a nice HTML formatted email with status of sync. I will keep playing around with this. I'll figure it out one day. 
 

(I have fingers crossed that for future version of Unraid they implement a cleaner plugin system. The web UI aspect could be handled by a simple XML type config. Maybe one day. Fingers crossed.)

Link to comment
10 minutes ago, IMTheNachoMan said:

I'll figure it out

Credit to @bonienl the system isn't perfect, but it also works pretty good once you figure it out.  But, as you noticed it's not a "plugin" system per se.  Rather its the same  programming and method of operation as the rest of the UI (if you choose to implement it that way).

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.