Building component packages🔗
Component packages can be built either on the command line or
graphically in the Builder. This
document describes how to use the
va-pkg command-line tool to build
On Windows, the packaging tool is in the
bin directory of the
VisionAppster installation. In a user-scope Linux installation, it is
$HOME/.local/bin. If this directory is in
PATH, this command will give you basic usage instructions:
If you installed the Flatpak version to the system scope on Linux, type this first:
alias va-pkg="flatpak run --command=va-pkg com.visionappster.Builder"
--help after a sub-command name will show you help on that
Generally, the process of creating a component package has three phases:
Create a directory structure with all the files that will go into the package.
Create a manifest file,
component.json, at the root.
Zip the directory.
Native tool plugins🔗
If your intent is to publicly sell the plugin through VisionAppster Store, things become a bit more challenging. To prevent fragmentation of the platform, we require that all publicly distributed native extensions have been compiled for all the supported target platforms. Privately sold extensions don’t have this requirement. Furthermore, code that runs on VisionAppster Cloud as an API only needs to support Linux x86_64.
To build compliant native plugins, use our cross-compilation tools. They can also be used for example if you work on Windows and want your code to run in the cloud.
As a result of the build process, you’ll get one or more
files, one for each supported architecture. These files are just shared
libraries with a special extension.
The convention is to place native tool plugins into directories that specify the target architecture. So, at the minimum, the directory structure that goes into a tool plugin package is like this:
mycomponent/ mycomponent/linux-x86_64/ mycomponent/linux-x86_64/mycooltools.toolplugin
mycomponent/ is the root directory that will hold the manifest
component.json. The file doesn’t exist yet, but any
command will automatically create it. Since we followed the naming
conventions, creating a manifest file is straightforward. Give this
command in the parent directory of
va-pkg update \ --component-id com.example.tools.cool \ --version 1.0.0 \ --scan mycomponent
com.example.tools.cool is the ID of your
va-pkg to scan the whole directory hierarchy and add all
found files to the manifest file. Now you have what makes up a working
package at a minimum:
mycomponent/ mycomponent/component.json mycomponent/linux-x86_64/ mycomponent/linux-x86_64/mycooltools.toolplugin
To build the package:
va-pkg build mycomponent
This will create
com.example.tools.cool-1.0.0.vapkg in the current
directory. You can inspect the contents of the package with
unzip -l com.example.tools.cool-1.0.0.vapkg
The output should list these files:
Tool files contain processing graphs created in the Builder. They contain no native code and are thus executable on all supported platforms, provided that the native extensions used by the graph have been installed.
The processing graph and its parameters may be valuable information you
want to protect. While the
.tool file format isn’t designed to be
human-readable, it isn’t too hard to figure out its contents. Obviously,
the Builder can easily open them for introspection.
To protect your IPR,
va-pkg makes it possible to encrypt
files. An encrypted processing graph can be loaded and executed by the
VisionAppster Engine only if it comes from an installed component that
has a valid digital signature, and the full component ID of that
component matches the ID assigned to the
.tool file. If an encrypted
tool file is loaded in the Builder, it will appear just like a native
tool that cannot be opened.
Since encrypted files require a valid signature, they can only be used if the package has been validated and signed by VisionAppster Store. You must register the component ID using your seller account and use the full component ID to encrypt files.
Let’s assume you have created a processing graph, made it a
compound and saved it as a
.tool file. To
include this file in a component package you just need to copy the file
to the package directory. The contents of the directory will look like
mycomponent/ mycomponent/component.json mycomponent/MyComplexTool.tool mycomponent/linux-x86_64/ mycomponent/linux-x86_64/mycooltools.toolplugin
To encrypt the file, give this command in the root directory of the
va-pkg tool encrypt \ --full-component-id com.example.tools.cool/1 \ MyComplexTool.tool
This will encrypt
MyComplexTool.tool in a way that makes it
unloadable from any component other than one with a full component ID of
com.example.tools.cool/1 and a valid signature. The encrypted tool
will be saved to
Alternatively, you can create a new package and make the package
containing the native tool plugin a dependency (with
va-pkg update --depends). Here, we’ll incorporate everything into a
single component. Add the encrypted file to the manifest:
va-pkg update files +MyComplexTool.toolc .
va-pkg update --scan . can be used.
Now, if you build the component package again with
va-pkg build, it
MyComplexTool.toolc. When installed, this tool will
appear among other tools in the Builder as “My Complex Tool”.
When you save a project in the Builder, the Builder creates an app that
runs a processing graph. The app is stored in the
directory under the project directory. Since the app is built in the
Builder, the natural way to create a component package out of it is to
use the Builder.
It is usually a good idea to build required tools into a separate component and add the full component IDs of required tool plugins as dependencies to the app component. You can do this in the Builder’s graphical interface.
Alternatively, you can create a self-contained app component by copying
the app’s files from
analysisapp/ to the root directory of your tool
mycomponent/ mycomponent/component.json mycomponent/main.qml mycomponent/appconfig.json mycomponent/engine.tool mycomponent/MyComplexTool.tool mycomponent/linux-x86_64/ mycomponent/linux-x86_64/mycooltools.toolplugin
The component ID of such a package would need to be changed. This
requires a change in the native C code that implements the tool plugin.
If you want to encrypt the
.tool files, the new ID must be given
there as well:
va-pkg tool encrypt \ --full-component-id com.example.apps.cool/1 engine.tool va-pkg tool encrypt \ --full-component-id com.example.apps.cool/1 MyComplexTool.tool
The manifest must also be updated:
va-pkg update --component-id com.example.apps.cool --scan .
Finally, the package can be built:
cd .. va-pkg build mycomponent
This will create
com.example.apps.cool-1.0.0.vapkg that contains not
only the app but also a native tool plugin and a tool file.
If you want to distribute your component through VisionAppster Store or run an app in VisionAppster Cloud, you must register the component ID using your seller account. During the registration process, your component will be assigned a UUID and a name. When you build a component for the Store, these need to be stored in the manifest:
va-pkg update \ --uuid 9ab4862d-bfd8-4d8e-a044-505b54d7f55f \ --name "My cool component" mycomponent va-pkg build mycomponent
If the package contains encrypted tool files or copy-protected native tool plugins, you’ll be unable to use them unless the package has a valid signature. Packages will be signed by the cloud service once they have gone through validation. But this may take time and you usually want to test the package yourself before uploading it to validation. Therefore, VisionAppster Cloud provides an API for signing packages. The URL of the API is
The package to be signed is uploaded using HTTP POST:
curl --data-binary "@com.example.apps.cool-1.0.0.vapkg" \ --header "Content-Type: application/vnd.va-pkg" \ --header "Authorization: Bearer API-TOKEN" \ --header "Buyer-ID: BUYER-ID-1,BUYER-ID-2..." \ -X POST \ https://could.visionappster.com/api/1/signatures/sign \ > com.example.apps.cool-1.0.0-signed.vapkg
Content-Type header tells the server how to handle the body of
Authorization header must contain an API token that can be
generated for a seller account in the cloud service. The server inspects
the token and verifies that it is valid and belongs to a seller account
that owns the uploaded package.
Buyer-ID header contains a comma-separated list of UUIDs. Each
identifies a buyer account to which a temporary license is generated.
The license allows 24 hours of usage for the single uploaded component.
The server performs basic integrity checks to ensure that the format of
the package is OK, generates a signature file for
component.json.crt) and sends the signed package back in the
response body. On error, you’ll get an appropriate HTTP error code.
The signing API lets you to give a short-term license to any buyer account. If you have installed any packages from the Store using the buyer account, the new license should available automatically. It is also possible to retrieve the licenses manually. The URL of the license API is
To retrieve the license file, give the following command:
curl --header "Authorization: Bearer API-TOKEN" \ https://could.visionappster.com/api/1/users/BUYER-ID/licenses.vapkg \ > licenses.vapkg
BUYER-ID is the UUID of your buyer account, which was also
used in the signing API call.
API-TOKEN is an authorization key you
can set in your buyer account.
The server returns your licenses as a component package that can be installed just like any package.