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 packages.
The packaging tool is in the
bin directory of the VisionAppster installation. If it is in your
PATH, this command will give you basic usage instructions:
If you installed the Flatpak version 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 sub-command.
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.
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
.toolplugin 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 file,
component.json. The file doesn't exist yet, but any
update 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 component. The
--scan flag instructs
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
.tool 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 this:
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 package (
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 will contain
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
analysisapp/ 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 plugin component:
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 the message.
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.