How to Build Applications for Pantahub One

A few months back we released an experimental project called PantahubOne. At the time, it was born as a personal project from one of our team to help manage her children’s consumption of digital content as they increasingly spent more time looking at tablets, phones, and the like. The project has grown to include a front-end store experience where anyone can build an app, deploy it to PantaHub and then offer new apps to other customers or devices.

We recently updated PantahubOne — our demo one-click app store for Raspberry Pis — with the capability of building and deploying containerized applications. Applications deployed to the app store are built with Pantavisor (PVR) using Docker, and a new app manifest. In this post, we’ll show you how to configure the manifest file, build, and deploy an app to Pantacor Hub One.

How can you build your own manifest?

The app manifest is a JSON file inside the PVR application file system called: v0alpha.app.manifest.json.

Once this manifest is correctly configured, PantaHub One can create the user interface for the application. The manifest uses JSON Schema with the react-jsonschema-form. For more details about how you can build a UI for your application refer to the react-jsonschema-form documentation.

The following is the structure of the v0alpha.app.manifest.json.

{
"#spec": "app-manifest@1",
"_configfiles": [
{
"file": "/etc/wireguard/config.json",
"name": "wireguard.config",
"schema": {
"description": "",
"properties": {},
"required": [],
"title": "",
"type": ""
},
"type": "jsonschema",
"ui": {}
}
],
"_metaconfig": [
{
"meta-key-prefix": "your-application-prefix",
"name": "key-for-the-section", // key for the section not the name of the meta key-value
"schema": {
"description": "",
"properties": {},
"required": [],
"title": "",
"type": ""
},
"type": "jsonschema",
"ui": {}
}
],
"_status": [
{
"properties": [
{
"default": "default value in case the key is empty",
"key": "key to read from device-meta or user-meta",
"title": "Name of the variable for the UI",
"type": "device-meta|user-meta"
}
],
"title": "Section Title"
}
],
"icon": "vpn_key", // icons available in here https://material.io/resources/icons/?style=baseline
"logo": "URL or BASE64 encoded",
"title": "APP TITLE",
"version": "0.0.1"
}

App manifest field description (from bottom to top)

  • version: this is the version of your application, and should follow a semantic versioning schema
  • title: This is the name of the application, the one that will be shown in the UI.
  • icon: The icon to use in the menu for your application. We support all of the material design icons.
  • logo: This is the URL to the app’s logo 160px x 160px. Set a URL for your image or for a base64 src image.
  • _status: This is an array representing the sections of status views that can be described with:
    • title: title of the status section
    • properties: this is an array of objects that define what parts of the device metadata or user metadata can be read to show your application status.
      • default: default value in case the key is empty
    • key: the key to read from device-meta or user-meta
    • title: Name of the variable for the UI”
    • type: device-meta|user-meta
  • _metaconfig: This is an array of objects that configures how the meta configuration form works.
    • meta-key-prefix: your-application-prefix
    • name: key name of the form
    • type: type of meta configuration UI, right now the only available is “jsonscheme”
    • schema: JSON scheme to be used for react-jsonscheme-form. More information here.
    • ui: UI JSON scheme used to define UI configuration on the form builder. More information here.
  • _configfiles: This is an array of objects to configure how the configuration file is built.
    • file: full path pointing to the configuration file, this file is going to be a JSON file.
    • name: key name of the form
    • type: type of meta configuration UI, right now the only available is “jsonscheme”
    • schema: JSON scheme to be used for react-jsonscheme-form. More information here.
    • ui: UI JSON scheme used to define UI configuration on the form builder. More information here.
  • _readme: This is a plain paragraph on top of the overview section. Important this is not a full readme section, in an upcoming revision you will be able to write a full README.md file to be shown as readme. (optional)

The UI created inside of one.apps.pantahub.com has an overview and settings tab:

  • The overview has the result of rendering the _readme, _status, and _metaconfig configuration.
  • The Settings has the result of rendering the _configfiles configuration.

Create your own application

To create an application in the app store, start with a dummy device using the command line utililty pvr.

mkdir app_marketplace
cd app_marketplace
pvr init
touch README.md
pvr add
pvr commit
pvr device create app_marketplace

These commands will create a dummy device without the hardware and it works as a repository for our newly created applications.

Next, add a new PVR Docker application, for example:

pvr app add --from nextcloud nextcloud
pvr app install nextcloud

This creates a folder nextcloud inside app_marketplace with the following structure:

├── lxc.container.conf
├── root.squashfs
├── root.squashfs.docker-digest
├── run.json
└── src.json

Create your own application manifest file v0alpha.app.manifest.json in this directory.

After you have finished your application manifest, commit and post a new revision to the app-store device.

pvr add && pvr commit && pvr post

You should see new revision like this on your Pantacorhub device.

NOTE: This is the device used as the main source for one application and is a good example of how to create your own application market device.

My device

After this, you can get your Clone URL and add it to your app sources on one.apps.pantahub.com

Now using the power of configuration files, meta, and more you can build almost any type of application.

Inside the demo marketplace device, you can see the manifest of all our applications are in here, you can see the docker container for wireguard-vpn and learn how to handle and convert the config.json into something that could be used by your application.