structure.md 3.9 KB

Application structure

.
├── htdocs
│   └── luci-static
│       └── resources
│           └── view
│               └── example
│                   ├── form.js
│                   ├── htmlview.js
│                   └── rpc.js
├── Makefile
├── po
│   ├── templates
│   │   └── example.pot
├── README.md
└── root
    ├── etc
    │   ├── luci.example.yaml
    │   └── uci-defaults
    │       └── 80_example
    └── usr
        ├── libexec
        │   └── rpcd
        │       └── luci.example
        └── share
            ├── luci
            │   └── menu.d
            │       └── luci-app-example.json
            └── rpcd
                └── acl.d
                    └── luci-app-example.json

Your starting point for this layout is the applications directory in the LuCI git repository.

A folder must be created with a name like luci-app-appname.

For the rest of this documentation, appname is example.

Root files

At least one file must exist in applications/luci-app-example - a Makefile. This defines what license is to be applied to the code, and what packages are required for the package to be installed. In this example app, YAML is processed by the Lua code, so lyaml is marked as a dependency.

A README.md file is also recommended. It should provide context on what the app does, and perhaps instructions on how to test things like RPC calls.

Javascript code

All JS code is placed under htdocs/luci-static/resources/view/appname/, where appname is the name without luci-app- prepended (in this case, htdocs/luci-static-resources/view/example).

Menu mapping

The JSON file that maps view/example/* to menu items is defined in root/usr/share/luci/menu.d. The file is named the same as the containing folder for the app, with a .json extension - luci-app-example.json.

ACL mapping

The JSON file that defines what APIs may be called is defined in root/usr/share/rpcd/acl.d/. The file is named the same as the containing folder for the app, with a .json extension - luci-app-example.json.

If ACL rights are not granted correctly, the web UI will show an error indicating "Access denied". Fix the ACL file, deploy it to the device/virtual machine, and restart rpcd.

Note that there may be legacy UCI (luci-compat) grants ACL in place, permitting read and write for all applications to all UCI resources. This should not be taken as a reason to skip granting the correct ACLs in your application. To ensure your ACLs are correct, you can move acl.d/luci-compat out of the way and restart rpcd. Put the file back when you've finished testing, as other LuCI applications may depend on it.

Additional files

LuCI apps do not have to have any additional files such as Lua scripts or UCI default setup. However, here's how you deal with those if needed.

Installing additional files

Any additional files needed by this application should be placed in root/ using the directory tree that applies. This example application needs a RPCd script to be installed, so it places a file in root/usr/libexec/rpcd/ and calls it luci.example. Scripts must have their execution bit set, and committed to the git repository with the bit set.

This example application also installs a file in /etc/ by putting it in root/etc/luci.example.yaml.

The OpenWrt packaging system will install these files automatically.

UCI defaults

UCI defaults are documented in the OpenWrt wiki. They create default files in the running system's /etc/config/ directory.

Place any defaults in the file root/etc/uci-defaults/appname, possibly with a number prepended to control sequencing - this example package uses 80_example as the filename.