> For the complete documentation index, see [llms.txt](https://sandbox-docs.verifone.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sandbox-docs.verifone.com/adk-5.0-programmers-guide/readme/system_overview/pg_all_components/pg_installer.md).

# VOS3 Installer

#### Tableof Contents

* [VOS3 Installer and packaging](#pg_vos3_installer)
* [VOS3 Packaging](#vos3_installer_packaging)
  * [Packaging structure](#vos3_installer_packaging_overview)
  * [Manifest](#vos3_installer_packaging_manifest)
  * [User Package Types](#vos3_installer_user_package_types)
  * [Versions](#vos3_installer_versions)
  * [Versioned Data vs Data](#vos3_installer_versioned_data_vs_data)
  * [Libraries / Shared objects](#vos3_installer_shared_objects)
  * [Fonts](#vos3_installer_fonts)
  * [Installation Hooks](#vos3_installer_packaging_hooks)
  * [Sponsor changes](#vos3_installer_packaging_sponsor_change)
  * [Remove bundles](#vos3_installer_packaging_remove)
  * [Unified packaging files](#vos3_installer_packaging_upfiles)
    * [Unified VRK (UVRK)](#vos3_installer_packaging_uvrk)
    * [Unified Password (UPWD)](#vos3_installer_packaging_upwd)
  * [Mixed Dlfiles](#vos3_installer_packaging_mixed_dlfiles)
  * [CP applications](#vos3_installer_packaging_cp_apps)
  * [Tags](#vos3_installer_tags)
  * [Operation and usage](#vos3_installer_packaging_operations)
    * [Bundle directory](#vos3_installer_packaging_bundle_directory)
    * [Dlfile from bundle directory(ies)](#vos3_installer_packaging_operations_bundle_dir)
    * [Dlfile from dlfile directory (recursive)](#vos3_installer_packaging_operations_dlfile_dir)
    * [Merging Dlfiles](#vos3_installer_packaging_operations_merge)
    * [Validate Dlfile](#vos3_installer_packaging_operations_validate)
    * [Generate removal](#vos3_installer_packaging_operations_gen_removal)
    * [Recommendations and examples](#vos3_installer_packaging_operations_recommendations)
    * [Differentials](#vos3_installer_packaging_differentials)
* [VOS3 Package Signing](#vos3_installer_signing)
  * [Development signing](#vos3_installer_signing_dev)
  * [Production signing](#vos3_installer_signing_prod)
* [VOS3 Installer](#vos3_installer_installer)
  * [Principles](#vos3_installer_principle)
  * [Session](#vos3_installer_session)
  * [Conflicts](#vos3_installer_conflicts)
    * [Conflict rules](#vos3_installer_conflicts_rules)
    * [Verifying rules](#vos3_installer_conflicts_verifying_rules)
  * [Dependencies](#vos3_installer_dependencies)
  * [Targeting vs dependency](#vos3_installer_targeting_vs_dependency)
  * [Installation processing](#vos3_installer_installation_processing)
  * [Installer API](#vos3_installer_api)
    * [Installer API examples](#vos3_installer_api_examples)
      * [Install](#vos3_installer_api_examples_install)
      * [Verify](#vos3_installer_api_examples_verify)
      * [Bundle list](#vos3_installer_api_examples_bundle_list)
  * [Installer Issues and logs](#vos3_installer_logs)
  * [General recommendations](#vos3_installer_recommendations)
    * [Overwrites / customisation](#vos3_installer_recommendations_overwrites)
    * [Installation file location](#vos3_installer_recommendations_install_locations)

## VOS3 Installer and packaging <a href="#pg_vos3_installer" id="pg_vos3_installer"></a>

## VOS3 Packaging <a href="#vos3_installer_packaging" id="vos3_installer_packaging"></a>

### Packaging structure <a href="#vos3_installer_packaging_overview" id="vos3_installer_packaging_overview"></a>

On VOS3, the packaging structure has been improved over previous ones with the following objectives:

* avoid compressing already compressed sub-archives (speed)
* avoid recursive signing (ease of use)
* allow in-place installation (space)
* allow efficient differential creation without resigning (ease of use)
* enforce double signatures (long term security)
* manage dependencies and ownership (integrity)
* unify packaging: keys, password, cp apps (ease of use)

In addition to the VOS3 packaging, the VOS3 installer also accepts unified packaging for security assets like UVRK (keys) and UPWD (passwords).

Here is the structure and naming of VOS3 packaging:

* **Dlfile** : installable (tar archive)
  * **Meta** : dlfile meta information (tgz archive)
  * **Bundle csd** : bundle changeset data (tgz archive)
    * **bundle content** with each root directory corresponding to a **package**
  * **Bundle inf** : bundle information (tgz archive)
    * **bundle information** such as manifest, signatures, etc.
  * \[optionally: other Bundle csd / inf ]
  * \[optionally: unified packaging archives ]

This structure and meta information are automatically generated by the Packman tool. One only needs to provide manifest and content to be installed for Packman tool to produce this installable archive.

### Manifest <a href="#vos3_installer_packaging_manifest" id="vos3_installer_packaging_manifest"></a>

Each VOS3 bundle contains a manifest. Besides name and version of the bundle, the manifest provides options for assigning the bundle to a device linux user and structuring the bundle into packages.

Each package can then bear attributes for the [User Package Types](#vos3_installer_user_package_types) and as well as optional group membership and umask for file permissions.

Optionally, the bundle manifest also allows to:

* specify dependencies and ownership between bundles
* target specific device types or serial numbers
* remove or change sponsor (see packman command sponsor\_change\_create)
* remove bundles (see [Generate removal](#vos3_installer_packaging_operations_gen_removal))
* define [Installation Hooks](#vos3_installer_packaging_hooks)

The following table describes the structure of the VOS3 manifest JSON files applicable to application bundles.

{% hint style="info" %}
The manifest content will be extended with additional fields by the Packman packaging tool for installation purposes. Please do not alter the output produced by Packman in any way.
{% endhint %}

| Properties           | Type             | Mandatory | Description                                                                                                                                                                                                                                                                                                                                                                                                                             | Default     | Example                                                   |
| -------------------- | ---------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------- |
| BUNDLE INFORMATION   |                  |           |                                                                                                                                                                                                                                                                                                                                                                                                                                         |             |                                                           |
| `name`               | string           | Yes       | Name of the bundle                                                                                                                                                                                                                                                                                                                                                                                                                      | n/a         | "BundleA"                                                 |
| `version`            | string           | Yes       | Version of the bundle                                                                                                                                                                                                                                                                                                                                                                                                                   | n/a         | see [Versions](#vos3_installer_versions) Example: "1.0.0" |
| `version_extension`  | string           | No        | Version extension of the bundle                                                                                                                                                                                                                                                                                                                                                                                                         | ""          | "beta4"                                                   |
| `user`               | string           | Yes       | User name, one of: usrX (1-16)                                                                                                                                                                                                                                                                                                                                                                                                          |             | "usr1"                                                    |
| `tags`               | array of objects | No        | Free field information                                                                                                                                                                                                                                                                                                                                                                                                                  |             |                                                           |
| `name`               | string           | Yes       | Tag name which is up to the user's conventions                                                                                                                                                                                                                                                                                                                                                                                          |             |                                                           |
| `value`              | string           | Yes       | Tag value which is up to the user's conventions                                                                                                                                                                                                                                                                                                                                                                                         |             |                                                           |
| PACKAGES             |                  |           |                                                                                                                                                                                                                                                                                                                                                                                                                                         |             |                                                           |
| `packages`           | array of objects | Yes       | unlimited list of objects                                                                                                                                                                                                                                                                                                                                                                                                               |             |                                                           |
| `name`               | string           | Yes       | package name                                                                                                                                                                                                                                                                                                                                                                                                                            |             | "packageA"                                                |
| `type`               | string           | Yes       | One of available package types, see [User Package Types](#vos3_installer_user_package_types)                                                                                                                                                                                                                                                                                                                                            |             | "user\_ro"                                                |
| `group`              | string           | No        | <p>One of available owner groups:<br>- <strong>usrX</strong> (1-16) : private to user<br>- <strong>usrXsys</strong> (1-16) : User applications should use this when sharing files with system applications<br>- <strong>share</strong> : Use this when sharing files with all application and system users<br>- <strong>users</strong>: Application users should use this group when sharing files with all other application users</p> | usrX (1-16) | "usr1sys"                                                 |
| `umask`              | string           | No        | Umask to be applied during installation                                                                                                                                                                                                                                                                                                                                                                                                 | "027"       |                                                           |
| INSTALLATION HOOKS   |                  |           |                                                                                                                                                                                                                                                                                                                                                                                                                                         |             |                                                           |
| `hook`               | object           | No        | see [Installation Hooks](#vos3_installer_packaging_hooks)                                                                                                                                                                                                                                                                                                                                                                               |             |                                                           |
| `when`               | string           | Yes       | <p>When hook will be executed<br>- <strong>before\_dlfile</strong><br>- <strong>after\_dlfile</strong></p>                                                                                                                                                                                                                                                                                                                              |             |                                                           |
| `executable`         | string           | Yes       | Path of executable in the hook                                                                                                                                                                                                                                                                                                                                                                                                          |             | "patch\_config.sh"                                        |
| `keep_manifest`      | boolean          | No        | Keep manifest after hook run                                                                                                                                                                                                                                                                                                                                                                                                            | True        |                                                           |
| BUNDLE REMOVE        |                  |           |                                                                                                                                                                                                                                                                                                                                                                                                                                         |             |                                                           |
| `bundle_remove`      | object           | No        | see [Remove bundles](#vos3_installer_packaging_remove)                                                                                                                                                                                                                                                                                                                                                                                  |             |                                                           |
| `users`              | string           | No        | List of users whose bundles need to be removed. User (except root) can only remove himself                                                                                                                                                                                                                                                                                                                                              |             |                                                           |
| `bundles`            | array of objects | No        | list of bundles to remove by name and optionally version. User (except root) can only remove his bundles                                                                                                                                                                                                                                                                                                                                |             |                                                           |
| `name`               | string           | Yes       | Bundle name                                                                                                                                                                                                                                                                                                                                                                                                                             |             |                                                           |
| `version`            | string           | No        | Version of the bundle                                                                                                                                                                                                                                                                                                                                                                                                                   |             |                                                           |
| DEPENDENCIES         |                  |           |                                                                                                                                                                                                                                                                                                                                                                                                                                         |             |                                                           |
| `requires`           | array of objects | No        | once the current dlfile has finished installation, this bundle requires that all listed requirements are met                                                                                                                                                                                                                                                                                                                            |             |                                                           |
| `bundle`             | object           | No        | requirement on bundle presence                                                                                                                                                                                                                                                                                                                                                                                                          |             |                                                           |
| `name`               |                  | Yes       | name of bundle                                                                                                                                                                                                                                                                                                                                                                                                                          |             | "BundleB"                                                 |
| `version_ranges`     | array of objects | No        | list of version ranges, if absent all versions are assumed                                                                                                                                                                                                                                                                                                                                                                              |             |                                                           |
| `version_start`      | string           | No        | Lowest satisfying version (included) in [Versions](#vos3_installer_versions)                                                                                                                                                                                                                                                                                                                                                            | \<any>      | "1.0.0"                                                   |
| `version_end`        | string           | No        | Highest satisfying version (included) in [Versions](#vos3_installer_versions)                                                                                                                                                                                                                                                                                                                                                           | \<any>      | "2.0.0"                                                   |
| `sponsors`           | array of strings | No        | requirement on sponsor ID as an OR-list                                                                                                                                                                                                                                                                                                                                                                                                 |             | \[ "123456" ]                                             |
| `serial_numbers`     | array of strings | No        | requirement on serial number as an OR-list                                                                                                                                                                                                                                                                                                                                                                                              |             | \[ "123-456-789" ]                                        |
| TARGETING            |                  |           |                                                                                                                                                                                                                                                                                                                                                                                                                                         |             |                                                           |
| `target`             | object           | No        | Installs this bundle if it matches at least one of the "include" expressions and none of the "exclude" expressions. This object must not be empty                                                                                                                                                                                                                                                                                       |             |                                                           |
| `include`            | object           | No        | If absent, matching is assumed and exclude is evaluated. This object must not be empty                                                                                                                                                                                                                                                                                                                                                  |             |                                                           |
| `devices`            | array of strings | No        | List (union/OR) of regular expressions (pcre) matching device model names (model)                                                                                                                                                                                                                                                                                                                                                       | `[ "[]" ]`  |                                                           |
| `dt_names`           | array of strings | No        | List (union/OR) of regular expressions (pcre) matching device tree names (dt\_name)                                                                                                                                                                                                                                                                                                                                                     | `[ "[]" ]`  |                                                           |
| `serial_numbers`     | array of strings | No        | List (union/OR) of regular expressions (pcre) matching serial\_numbers                                                                                                                                                                                                                                                                                                                                                                  | `[ "[]" ]`  |                                                           |
| `hardware_platforms` | array of strings | No        | List (union/OR) of regular expressions (pcre) matching hardware\_platforms                                                                                                                                                                                                                                                                                                                                                              | `[ "[]" ]`  |                                                           |
| `exclude`            | object           |           | If absent, matching is assumed and include is evaluated. This object must not be empty                                                                                                                                                                                                                                                                                                                                                  |             |                                                           |
| `devices`            | array of strings | No        | List (union/OR) of regular expressions (pcre) matching device model names (model)                                                                                                                                                                                                                                                                                                                                                       | `[ "[]" ]`  |                                                           |
| `dt_names`           | array of strings | No        | List (union/OR) of regular expressions (pcre) matching device tree names (dt\_name)                                                                                                                                                                                                                                                                                                                                                     | `[ "[]" ]`  |                                                           |
| `serial_numbers`     | array of strings | No        | List (union/OR) of regular expressions (pcre) matching serial\_numbers                                                                                                                                                                                                                                                                                                                                                                  | `[ "[]" ]`  |                                                           |
| `hardware_platforms` | array of strings | No        | List (union/OR) of regular expressions (pcre) matching hardware\_platforms                                                                                                                                                                                                                                                                                                                                                              | `[ "[]" ]`  |                                                           |

{% hint style="info" %}
Packman tool validates every manifest and provides error information.
{% endhint %}

### User Package Types <a href="#vos3_installer_user_package_types" id="vos3_installer_user_package_types"></a>

Users need to package the applications according to VOS3 installation rules and choose one of the following package types:

| VOS3 Package Type                 | Installation Location               | Shortcut           | Owner Groups | Access | Main Purpose                                                                        |
| --------------------------------- | ----------------------------------- | ------------------ | ------------ | ------ | ----------------------------------------------------------------------------------- |
| **user\_ro**                      | /home/\<user>/                      | \~                 | usr\<X>      | RO     | application read-only executable, libraries, gui resources and other read-only data |
| **font\_ro**                      | /usr/share/fonts/                   |                    | share        | RO     | additional fonts                                                                    |
| **versioned\_data**               | /mnt/appdata/versioned/\<user>/     | \~/versioned\_data | usr\<X>      | RW     | private application configuration and assets                                        |
| **share\_users\_versioned\_data** | /mnt/appdata/versioned/share/       |                    | users        | RW     | shared data between usr\<X>                                                         |
| **share\_all\_versioned\_data**   | /mnt/appdata/versioned/globalshare/ |                    | share        | RW     | shared data between sys\_<> and usr\<X>                                             |
| **data**                          | /mnt/appdata/data/\<user>/          | \~/flash           | usr\<X>      | RW     | application non-critical data (large media, etc.)                                   |
| **user\_hook**                    | \<tmpfs>                            |                    |              | N/A    | user installation plugin to modify RW user data or versioned data                   |

Note that additional VOS3 system package types are provided for system usage only.

### Versions <a href="#vos3_installer_versions" id="vos3_installer_versions"></a>

Bundle versions follow a strict format that is used by Installer to validate and compare versions.

The format mandates dot separated valid numbers like "1.20.3".

It is recommended to follow the semantic of **MAJOR . MINOR . PATCH \[.PATCH\_REVX...]** where:

* MAJOR is incremented when incompatible API change are made,
* MINOR is incremented when new functionality is added, and
* PATCH is incremented when bugs are fixed.
* The optional additional "PATCH\_REVX" (and so forth) can be used to bring further version sub-fields.

Versions are ordered such as: 2.0.0 > 1.99.99 > 1.9.0 > 1.0.1 > 1.0.0.0 > 1.0.0

Optionally, a "version\_extension" (free string) can be added in the bundle manifest but this extension will not be taken into account during formal version comparisons. This field is useful for mentioning pre-releases, release candidates, alpha, etc.

### Versioned Data vs Data <a href="#vos3_installer_versioned_data_vs_data" id="vos3_installer_versioned_data_vs_data"></a>

As opposed to the "data" location (pointed by "\~/flash"), the "versioned data" (pointed by "\~/versioned\_data") content is backed up when installation takes place.

The safety of the versioned data comes at a storage cost where a backup copy of the previous state is always kept on each installation.

Therefore, it is recommended to use the "versioned data" for most of the application read/write resources.

The data location may be chosen instead when very large and non-critical resources need to be stored: e.g. large video files.

### Libraries / Shared objects <a href="#vos3_installer_shared_objects" id="vos3_installer_shared_objects"></a>

Dynamic libraries in Linux are also known as shared objects. These dynamic libraries are loaded dynamically by the Linux loader (ld). For this mechanism to work, linux uses the tool 'ldconfig' to create caches and symbolic links. The installer runs ldconfig on the system after each installation automatically. Therefore, application must follow the following guidelines:

* shared objects must be placed in **\~/lib** directory
* shared objects should be named **libname.so.X.Y.Z** where:
  * X.Y and Z are integer representing the version of this shared object (ie 1.0.0)
  * X is the major version and represent the compatibility level
  * The SONAME contained in this file must be present and match **"libname.so.X"**
* permissions should be set to 644

Consequently:

* "libname.so.X" should **not** be packaged: it will be generated by ldconfig
* "libname.so" should **not** be packaged: this is meant for compilation

{% hint style="info" %}
One can see the SONAME with : readelf -a libname.so.X.Y.Z | grep SONAME
{% endhint %}

### Fonts <a href="#vos3_installer_fonts" id="vos3_installer_fonts"></a>

VOS3 comes with preinstalled fonts. Additional fonts can be installed by users following those steps:

* Use *font\_ro* package type
* Put font files in root of package
* Set the group to *share*
* Use packman 1.11.0 or newer

{% hint style="info" %}
Packman avoids font conflicts with system and other applications by prepending the name of the bundle to the font file name.
{% endhint %}

### Installation Hooks <a href="#vos3_installer_packaging_hooks" id="vos3_installer_packaging_hooks"></a>

Installation hooks are similar to a plugin into the installation process. During installation, hooks are extracted, authenticated and executed in a temporary environment with same permissions as the user's home.

A hook is declared in the bundle manifest file using the "hook" field and its subfields described below.

The "when" attribute specifies time of execution:

* "before\_dlfile": before the DL file gets installed
* "after\_dlfile": after the DL file got installed

The "executable" attribute specifies which executable (elf or script) will be launched by the installer when hook is started. This executable path must exist within the bundle and be executable.

Linux ELF executables in hooks can link to standard libraries (libc, libstdc++, libm, ...), if additional libraries are needed those libraries need to be present in the hook and use "rpath" to allow linkage to occur.

Shell script executables in hooks can rely on busybox commands and executables that come with the hook.

This executable must return an exit code:

* 0: indicates that hook installation performed correctly
  * bundle (hook) is considered as installed
* 1: indicates that hook is not applicable
  * bundle (hook) is considered as not targeted (skipped)
  * installation continues
* 2: indicates an error
  * bundle (hook) is considered not installed
  * installation is aborted

Optionally, the "keep\_manifest" attribute can be used to inform the installer to keep manifest of hook or not. This determines if the hook will be listed when listing installed bundles.

Optionally, the "timeout" attribute can be used to shorten or lengthen the maximum time the hook is allowed to run. Exceeding this time, the installer will kill the hook process, consider it as an error and abort installation.

### Sponsor changes <a href="#vos3_installer_packaging_sponsor_change" id="vos3_installer_packaging_sponsor_change"></a>

{% hint style="info" %}
Each customer has a sponsor used to sign and when the very first user package is installed on a device, the sponsor is set in device. All subsequent packages on this device must be signed with same sponsor.
{% endhint %}

A Sponsor change package allows either to:

* remove/reset a device's current sponsor. This is also referred as "unlock".
* change current sponsor directly to another one: This method is the most secure as the device is never unlocked state.

Such sponsor change package uses specific manifest fields that are not described here as the Packman tool allows to create them automatically.

Here are the steps to follow to unlock device(s):

1. Use Packman's "sponsor\_change\_create" command, passing the "current\_sponsor" value and the "serial\_numbers": this will create a development signed sponsor unlock dlfile. Example:

   ```cpp
   packman.py sponsor_change_create -t vos3 -s dev --current_sponsor 123456 --serial_numbers "123-456-789" -o dl.unlock.tar
   ```
2. Use Online portal to production sign this dlfile: current sponsor signing for usr1 is required
3. Install resulting dlfile by any mean on devices matching the serial numbers

Here are the steps to follow to change sponsor on device(s):

1. Use Packman's "sponsor\_change\_create" command, passing the "current\_sponsor" and "new\_sponsor" values and the "serial\_numbers": this will create a development signed sponsor change dlfile. Example:

   ```cpp
   packman.py sponsor_change_create -t vos3 -s dev --current_sponsor 123456 --new_sponsor 654321 --serial_numbers "123-456-789" -o dl.change.tar
   ```
2. Separately:
   * Current sponsor: Use Online portal to production sign this dlfile: current sponsor signing for usr1 is required
   * New sponsor: Use Online portal to production sign this dlfile: new sponsor signing for usr1 is required
3. Use Packman's "sponsor\_change\_merge" command, passing both the current and new sponsor signed dlfiles. Example:

   ```cpp
   packman.py sponsor_change_merge -t vos3 -i dl.file_current_signed.tar dl.file_new_signed.tar -o dl.change_signed.tar
   ```
4. Install resulting (merged) dlfile by any mean on devices matching the serial numbers

Please refer to Packman tool's documentation and help for more details on "sponsor\_change\_create" and "sponsor\_change\_merge".

{% hint style="info" %}
Important: a sponsor change can only be applied once per device. Device keeps the last sponsor change signature timestamp and will only accept newer timestamps (ie newer signatures).
{% endhint %}

### Remove bundles <a href="#vos3_installer_packaging_remove" id="vos3_installer_packaging_remove"></a>

Using the "bundle\_remove" field in a manifest, one can make the VOS3 installer remove bundles and their content on a device.

This field hold two different ways to specify the bundles to be removed:

* by user
* by bundle name(s) + (optional) version

Such remove bundles are signed like any other bundle but are not allowed to have any package, therefore they do not install any content.

An application user is only able to remove its own (same user) bundles.

### Unified packaging files <a href="#vos3_installer_packaging_upfiles" id="vos3_installer_packaging_upfiles"></a>

VOS3 installer supports direct installation of unified packaging files as well as [Mixed Dlfiles](#vos3_installer_packaging_mixed_dlfiles).

Unified packaging files are meant to hold security assets that are reusable accross platforms and operating systems.

Currently two types of unified packaging exist: UVRK and UPWD

#### Unified VRK (UVRK) <a href="#vos3_installer_packaging_uvrk" id="vos3_installer_packaging_uvrk"></a>

This unified packaging holds one or more VRK keys for remote provisioning of keys.

Those files do not need to be signed and are generally made available through Verifone customer services.

Please refer to TODO INSERT\_LINK for complete explanation on UVRK.

#### Unified Password (UPWD) <a href="#vos3_installer_packaging_upwd" id="vos3_installer_packaging_upwd"></a>

This unified packaging holds one or more password files for remote provisioning of passwords.

Those files need to be signed by current sponsor: by packman for development and using Online Signing Portal for production.

Please refer to TODO INSERT\_LINK for complete explanation on UPWD.

### Mixed Dlfiles <a href="#vos3_installer_packaging_mixed_dlfiles" id="vos3_installer_packaging_mixed_dlfiles"></a>

Dlfiles can also contain unified packages (uvrk, upwd) alongside the bundles, these are called "Mixed" Dlfiles. Those mixed dlfile are valid for the VOS3 installer and can be generated using the "merge" command of packman.

{% hint style="info" %}
The Online Signing Portal is not able to sign upwd files that are embedded inside dlfiles. Therefore, make sure to sign upwd files before creating a "Mixed" dlfile.
{% endhint %}

### CP applications <a href="#vos3_installer_packaging_cp_apps" id="vos3_installer_packaging_cp_apps"></a>

In VOS3, CP (Commerce Platform) application are packaged as regular bundles. Please refer to CP Application documentation for more information, this section focuses only on VOS3 packaging of them.

In production mode, CP applications are system signed. Verifone will convert and sign development CP application packages to be used in production.

In Appdev mode, CP application can be signed and installed by usr1.

In all cases, for a CP application to run, two packages are needed:

* CP Application: prod or appdev
* CP Activation

To convert an CP Application package, use the "cpapp\_convert" command of the packman tool. This command allows to convert and select the mode (appdev or prod) using the "--cpapp\_type" option:

* Convert from zip to appdev:

  ```cpp
  packman.py cpapp_convert -t vos3 -s dev --cpapp_type appdev -z mycpapp-887643134.zip -o dl.mycpapp-887643134_appdev.tar
  ```
* Convert existing prod dlfile to appdev:

  ```cpp
  packman.py cpapp_convert -t vos3 -s dev --cpapp_type appdev -d dl.mycpapp-887643134_prod.tar -o dl.mycpapp-887643134_appdev.tar
  ```

To build a CP Activation package, use the "gen\_activation" command of the packman tool. This command creates automatically an activation package for a CP Application:

```cpp
packman.py gen_activation -t vos3 -s dev -d dl.mycpapp-887643134.tar dl.mycpapp-887643134_activate.tar
```

{% hint style="info" %}
For production devices, this activation package (usr1) must be signed on the Online Signing portal with the applicable sponsor.
{% endhint %}

### Tags <a href="#vos3_installer_tags" id="vos3_installer_tags"></a>

The manifest json file has a specific grammar that is checked and should only contain fields in accordance to this grammar. In order to allow addition of customer or application specific information to a bundle, the manifest provides an array of tag / value entries. The content and definition of those are completely left to the user's choice.

{% hint style="info" %}
Manifests are signed, therefore the content of tags is guaranteed to be verified in authenticity and integrity.
{% endhint %}

### Operation and usage <a href="#vos3_installer_packaging_operations" id="vos3_installer_packaging_operations"></a>

VOS3 package creation is done using the Packman tool.

This section will give and overview of the principal operations but please refer to the packman user guide for more commands and options.

Here is a sample showing how to create dlfile for single or multiple bundles and merging them: multi\_bundles\_sample.zip (please request sample bundle from the Support team).

#### Bundle directory <a href="#vos3_installer_packaging_bundle_directory" id="vos3_installer_packaging_bundle_directory"></a>

As packman tool will automatically create the final packaging: the main task left is to prepare the bundle content (files, executables, libraries,...) and a manifest.

This is done by preparing one directory per bundle which contains:

* **manifest.json** file at its root
  * manifest.json contains bundle name, version, packages with name and types
* **package directories** are at its root
  * package directory names must match the package names listed in manifest
  * those package directories contain the actual content of the bundle

#### Dlfile from bundle directory(ies) <a href="#vos3_installer_packaging_operations_bundle_dir" id="vos3_installer_packaging_operations_bundle_dir"></a>

To build a Dlfile from a bundle directory use:

```cpp
packman.py build -t vos3 -s dev -i <bundle_dir> -d <dlfile>
```

Where "bundle\_dir" is a [Bundle directory](#vos3_installer_packaging_bundle_directory).

The packaging process will show errors and warning explaining the issues.

Notes:

* the build command accepts several directories by using "-i \<bundle\_dir1> \<bundle\_dir2>" option.
* the build command accepts a parent directory containing many bundle directories, this can be enabled with the "-r" (recursive) option: "-r -i \<parent\_dir>".
* the build command will issue an error if destination already exists, to overwrite, use "-f" option.

#### Dlfile from dlfile directory (recursive) <a href="#vos3_installer_packaging_operations_dlfile_dir" id="vos3_installer_packaging_operations_dlfile_dir"></a>

To build a Dlfile from a dlfile directory use:

```cpp
packman.py build -t vos3 -s dev -r -i <dlfile_dir> -d <dlfile>
```

Where "dlfile\_dir" is a path to a directory which contains one or more [Bundle directory](#vos3_installer_packaging_bundle_directory)

#### Merging Dlfiles <a href="#vos3_installer_packaging_operations_merge" id="vos3_installer_packaging_operations_merge"></a>

To merge the content of several dlfiles into one use:

```cpp
packman.py merge -t vos3 -s dev -d <dlfile1> <dlfile2> -o <ouput_dlfile>
```

**Example:**

```cpp
packman.py merge -t vos3 -s dev -d dl.file1.tar dl.file2.tar -o dl.merged.tar
```

Notes:

* the merge command accepts any number of dlfiles in input on the "-d" option
* the merge command will issue an error if destination already exists, to overwrite, use "-f" option: example:

```cpp
packman.py merge -t vos3 -s dev -d <dlfile1> <dlfile2> -fo vos3dlfile.tar
```

#### Validate Dlfile <a href="#vos3_installer_packaging_operations_validate" id="vos3_installer_packaging_operations_validate"></a>

All packman packaging commands perform a validation on the output. This validation contains numerous checks such as json schema and content validation for manifests and changesets, entries, coherency between bundles, conflicts, etc. Packman also allows to just run validation on an existing archive.

To validate a Dlfile and all its content recursively use:

```cpp
packman.py validate -t vos3 -rd <dlfile>
```

This will show all warnings and errors of the dlfile or its children.

#### Generate removal <a href="#vos3_installer_packaging_operations_gen_removal" id="vos3_installer_packaging_operations_gen_removal"></a>

One can build remove bundle manually by editing a manifest and building the bundle. However Packman allows to create directly a removal dlfile from an existing dlfile.

This is done using the 'gen\_removal' command that takes as input a dlfile containing bundles and creates a dlfile containing the corresponding removal bundles. The type of remove bundles can be chosen with '--remove\_type' which takes one of the following values:

* bundle\_version (default): this creates remove bundles for the bundle and its version
* bundle : this creates remove bundles for the bundle without version specified
* user : this creates remove bundles for the user (removing all bundles for that user)

Example usage:

```cpp
packman.py gen_removal -t vos3 -s dev -d dl.file.tar -o dl.file_remove.tar
```

{% hint style="info" %}
Packman tool provides additional options like filtering by name and user. Please refer to packman documentation.
{% endhint %}

#### Recommendations and examples <a href="#vos3_installer_packaging_operations_recommendations" id="vos3_installer_packaging_operations_recommendations"></a>

**Bundle and Package name recommendations**

* must have a meaningful name
* must not have prefix (dl. , bdl. , pkg.)
* should not have postfix
* should not have version in the name

**Example 1: Bundle directory structure and manifest**

Here is an example of usr1 application manifest (Application bundle manifest):

```fragment
{
    "name": "bankapp",
    "version": "1.0.1",
    "user": "usr1",
    "packages": [
        {
            "name": "bankapp",
            "type": "user_ro"
        },
        {
            "name": "bankapp_res",
            "group": "share",
            "type": "user_ro"
        }
    ]
}
```

[Directory](/adk-5.0-programmers-guide/readme/annotated/class_directory.md) structure:

![](/files/uJf1HIb1vmcdF2nxUo5W)

Build command line:

```cpp
packman.py build -t vos3 -s dev -i bankapp -fd dl.bankapp_1.0.1.tar
```

**Example 2: manifest for configuration**

Here is an example of usr1 configuration manifest (Application bundle manifest):

```fragment
{
    "name": "bankAconfig",
    "version": "1.0.1",
    "user": "usr1",
    "packages": [{
            "name": "config",
            "type": "versioned_data"
        }
    ]
}
```

#### Differentials <a href="#vos3_installer_packaging_differentials" id="vos3_installer_packaging_differentials"></a>

The vos3 packaging allows to create differential dlfiles automatically and without the need to resign the resulting differential file. All of this is done using the "gen\_diff" command of packman and providing the source and destination dlfile.

```cpp
packman.py gen_diff -t vos3 --src dl.source.tar --dst dl.destination.tar -o dl.diff.tar
```

{% hint style="info" %}
Please refer to the packman user guide for more commands and options.
{% endhint %}

## VOS3 Package Signing <a href="#vos3_installer_signing" id="vos3_installer_signing"></a>

For user bundles, Packman tool automatically sets the signer to \['SPONSOR'] and with "-s dev" will sign this with a development sponsor (010245).

The vos3 signing method is actually composed of two signatures (each using a different signing algorithm) stored with Cryptographic Message Syntax (CMS). This approach improves cryptographic agility and also prepares for post-quantum cryptography (PQC).

### Development signing <a href="#vos3_installer_signing_dev" id="vos3_installer_signing_dev"></a>

The vos3 installer always verifies the signatures both in production and development modes. Therefore, even development bundles must be signed.

For development, the process is automatically done by Packman when specifying '-s dev'.

### Production signing <a href="#vos3_installer_signing_prod" id="vos3_installer_signing_prod"></a>

Production signing is performed using the Online Signing Portal. Dlfiles with user bundles use this portal: <https://sign.verifone.com/>

1. Upload the development signed dlfile(s) or Unified package(s) to the portal
2. Reviewers are alerted by mail that an approval is requested
3. As soon as 2 reviewers have approved, the signature is done
4. Requester receives notification by mail that request was approved
5. Signed dlfile(s) or Unified package(s) is available for download on portal

{% hint style="info" %}
The signing portal will only sign or resign bundles that are for the users the signer can sign. All other parts are preserved intact.
{% endhint %}

## VOS3 Installer <a href="#vos3_installer_installer" id="vos3_installer_installer"></a>

### Principles <a href="#vos3_installer_principle" id="vos3_installer_principle"></a>

An installation can be initiated:

* manually using the Software Control Panel (USB, netloader,...)
* remotely using VHQ
* any other application or service that uses the installer's API

The vos3 installer relies on an internal A/B installation mechanism. This mechanism ensures that any failure during installation allows to fall back to the previously (working) installed setup.

The vos3 installer also leverages this A/B mechanism to be resistant to power cuts and re-attempt installations several times before giving up and falling back.

The installer performs the following high-level actions securely:

* Addition of bundles: adds files to different places of the system according to package type
* Removal of bundles: removes installed files from system
* Launching of hooks: performs modification of writable files
* Manage sponsor: set, reset or change device sponsor

The vos3 installer natively supports installation of differential dlfiles.

### Session <a href="#vos3_installer_session" id="vos3_installer_session"></a>

The installer proceeds with installations using the notion of a **session**. An installation session is a modification to the system performed by the installer which is "transactional": either it is performed completely or not at all. A session is initiated by providing one or several input files (dlfiles and/or Unified packages):

1. the installation session is given an identifier
2. the input files are verified
3. the system is rebooted for input files to be installed
4. On success, new updated system is started. On failure, current system is restarted

### Conflicts <a href="#vos3_installer_conflicts" id="vos3_installer_conflicts"></a>

A conflict is an attempt to package or install two or more entries (dir, file, symlink) with the same path.

#### Conflict rules <a href="#vos3_installer_conflicts_rules" id="vos3_installer_conflicts_rules"></a>

Here are the conflict rules:

1. **Within one package** of any type, two or more entries of ANY type MUST NOT conflict with each other (this would be a TAR archive with duplicate entries)
2. **Within one bundle**, between two or more packages of same type:
   * two or more entries MUST NOT conflict with each other with only one exception:
     * conflicting entries are directories with same user/group and permissions
3. **Among all applicable bundles** (result of install session upon already installed bundles) for READ-ONLY package types (system\_ro, user\_ro, font\_ro, kernel\_ro) :
   * two or more entries MUST NOT conflict with each other with only one exception:
     * conflicting entries are directories with same user/group and permissions

{% hint style="info" %}
Rules above allow conflict for Read-write locations in different bundles, the order of installation (see below) will determine the outcome and overwrite any runtime modifications.
{% endhint %}

#### Verifying rules <a href="#vos3_installer_conflicts_verifying_rules" id="vos3_installer_conflicts_verifying_rules"></a>

**Installer** will detect & reject any attempt to break the above rules and fail the installation. In this case, it will provide information on first encountered conflict.

**Packman** tool will detect & reject any attempt to break the above rules in the scope the dlfiles provided to it.

{% hint style="info" %}
Hint: if several dlfiles may be involved in a conflict, an attempt to use the "merge" command of packman will reveal the conflicts if any
{% endhint %}

### Dependencies <a href="#vos3_installer_dependencies" id="vos3_installer_dependencies"></a>

The installer supports management of dependencies. Satisfaction of dependencies declared in manifests are verified at each dlfile end of verification.

Here is a example for multiple dlfiles provided for installation in one session:

* Already installed: bundle A
* Installation session (3 dlfiles), verification starts:
  * dlfile 1 : bundle B and C (depends on bundle A and B) → OK
  * dlfile 2 : bundle D (depends on B and E) → ERROR → E is not satisfied
  * dlfile 3 : bundle E (depends on A) → would have been ok but verification stopped at ERROR on dlfile 2

Dependency declaration is made in the bundle's [Manifest](#vos3_installer_packaging_manifest). Optionally, bundle version ranges for dependencies can be specified.

Other types of dependencies can also be declared to be required, such as sponsor id or serial number.

{% hint style="info" %}
This installation session is rejected, none of the dlfile is installed and fall back is performed.
{% endhint %}

### Targeting vs dependency <a href="#vos3_installer_targeting_vs_dependency" id="vos3_installer_targeting_vs_dependency"></a>

**Targeting**: *"manifest rules to check if a valid bundle should be filtered out from installation depending on device characteristics"*

**Dependency**: *"manifest rules to check if a valid bundle has all required resources to work properly on device, failing installation otherwise"*

Here is a comparative table between the two:

|            | Criterion type                                                                                         | Criteria                                                                              | Matching action     | Not matching             |
| ---------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | ------------------- | ------------------------ |
| Targeting  | Target reference value is always present and immutable                                                 | <p>- Serial Number<br>- Device Model<br>- Device tree name<br>- Hardware platform</p> | install bundle      | skip bundle installation |
| Dependency | Dependency reference value can change (or be removed) and come together with same installation session | <p>- Bundle name / version<br>- Sponsor ID<br>- Serial number</p>                     | accept installation | FAIL                     |

The installer evaluates the targeting before the dependencies.

### Installation processing <a href="#vos3_installer_installation_processing" id="vos3_installer_installation_processing"></a>

Here is high-level view of the operations performed by the installer for an installation session:

1. Verification of all dlfiles, for each dlfile in provided order: a. installer hook b. remove bundles (BO) c. "before\_dlfile" hooks (BO) d. normal bundles (BO) e. "after\_dlfile" hooks (BO) f. dependency check
2. Installation of all dlfiles into new image, for each dlfile in provided order: a. installer hook b. remove bundles (BO) c. "before\_dlfile" hooks (BO) d. normal bundles (BO) e. "after\_dlfile" hooks (BO) f. additional processing (ldconfig, mkfontdir)
3. Make new image active and reboot

Bundle ordering (BO): if several bundles are to be processed in the same step (marked BO above), the following order will be applied

1. root
   * bundle name alphabetic order
2. sys\_<>
   * bundle name alphabetic order
3. usrX
   * bundle name alphabetic order

### Installer API <a href="#vos3_installer_api" id="vos3_installer_api"></a>

This paragraph gives a brief and high-level overview of how to use the Installer API, please refer to the "installer/installer.hpp" header file for more details.

Here are the main classes of the Installer API:

* **Status** class: holds immediate success, failure and information on API calls
* **Session** class: main interaction class with the installer, used to prepare, initiate and retrieve result of session actions
* **SessionResult** class: holds the overall success, failure and information on a session processing
* **Version** class: helper class holding a version of a bundle
* **BundleInfo** class: container for bundle information

Here are the main functions of the Installer API:

* **list\_sessions()**: list all finished sessions
* **get\_bundle\_list()**: list installed bundles

At a given time, only one client is allowed to own an installation session. Here is a typical initiation of an installation:

1. construct a Session object: Session session;
2. add dlfiles to session: session.add("dl.file.tar")
3. successfully acquire the session with session.acquire()
4. start installation: session.install()

If the verification goes wrong, this call to install() returns an error in the Status. However if verification is ok, this call to install() does not return as device is rebooted. If the caller needs to retrieve the status of installation, it can save the identifier of the session with get\_id() and create (on reboot) a session with this identifier then call "get\_result()".

It is also possible to request the installer to only perform a verification by calling "session.verify()".

#### Installer API examples <a href="#vos3_installer_api_examples" id="vos3_installer_api_examples"></a>

**Install**

```cpp
#include <cstdio>
#include <iostream>
#include <filesystem>
#include <fstream>
#include <string>
#include <installer/installer.hpp>
using namespace std;
using namespace vfi;
namespace fs = std::filesystem;
#define SID_FILE "flash/sid"
int main()
{
   bool keep_files = true; // set to false to remove installation file during installation (default behaviour)
   installer::Status status;
   error_code ec;
   if ( fs::exists( SID_FILE, ec ) )
   {
   // post reboot installation result check
   ifstream is( SID_FILE );
   stringstream buffer;
   buffer << is.rdbuf();
   std::string sid_s = buffer.str();
   unsigned int sid = stoul( sid_s, nullptr, 0);
   cout << "sid:" << sid << endl;
   installer::Session session( sid );
   if ( session.get_state() == installer::Session::Complete )
   {
   // check installation result
   installer::Session::SessionResult res;
   if ( session.get_result( res ).is_ok() )
   {
   cout << "installaton of sid:" << sid << " is successful" << endl;
   }
   else
   {
   cout << "installation of sid:" << sid << " has failed" << endl;
   }
   fs::remove( SID_FILE, ec );
   }
   else
   {
   cout << "Session " << sid << " is not known" << endl;
   fs::remove( SID_FILE, ec );
   exit(1);
   }
   }
   else
   {
   // installation
   auto session = installer::Session();
   // It is strongly recommended to use flash/ to store installation files
   status = session.add( "flash/dl.example.tar" );
   if ( !status.is_ok() )
   {
   cout << "Bad argument: " << status.to_string() << endl;
   exit(1);
   }
   status = session.acquire();
   if ( status.is_ok() )
   {
   cout << "Session ID: " << session.get_id() << endl;
   // save session ID
   ofstream os( SID_FILE );
   os << session.get_id();
   os.close();
   // perform installation
   status = session.install( keep_files ); // last call before reboot
 if ( status.is_ok() )
   {
   // Should never get here
   }
   else
   {
   cout << "Install failed: " << status.to_string() << endl;
   exit(1);
   }
   }
   else
   {
   cout << "Failed to acquire session" << endl;
   exit(1);
   }
   }
   return 0;
}
```

**Verify**

```cpp
#include <cstdio>
#include <iostream>
#include <installer/installer.hpp>
using namespace std;
using namespace vfi;
int main()
{
   installer::Status status;
   // verification
   auto session = installer::Session();
   // It is strongly recommended to use flash/ to store installation files
   status = session.add( "flash/dl.example.tar" );
   if ( !status.is_ok() )
   {
   cout << "Bad argument: " << status.to_string() << endl;
   exit(1);
   }
   status = session.acquire();
   if ( status.is_ok() )
   {
   cout << "Session ID: " << session.get_id() << endl;
   // perform verification
   status = session.verify();
   if ( status.is_ok() )
   {
   cout << "Verification successful" << endl;
   }
   else
   {
   cout << "Verification failed: " << status.to_string() << endl;
   }
   // release session ( if installation is not intended )
   session.release();
   }
   else
   {
   cout << "Failed to acquire session" << endl;
   exit(1);
   }
   return 0;
}
```

**Bundle list**

```cpp
#include <cstdio>
#include <iostream>
#include <installer/installer.hpp>
using namespace std;
using namespace vfi;
int main()
{
   list<installer::BundleInfo> bundles;
   installer::Status status;
   bool get_from_active = true; // Set to false if want to get information for fallback image
   status = installer::get_bundle_list( bundles, get_from_active );
   if ( status == installer::Status::Ok )
   {
   for ( const auto &bundle : bundles )
   {
   cout << "Bundle: " << bundle.get_name() << endl;
   cout << "\tVersion: " << bundle.get_version().to_string() << endl;
   cout << "\tExtended version: " << bundle.get_extended_version() << endl;
   cout << "\tUser: " << bundle.get_user() << endl;
   cout << "\tDigest: " << bundle.get_digest() << endl;
   }
   }
   else
   {
   cout << "Failed to get bundle list" << endl;
   exit(1);
   }
   return 0;
}
```

### Installer Issues and logs <a href="#vos3_installer_logs" id="vos3_installer_logs"></a>

For each session, both for verification and for installation phase, the installer maintains its own log file that is available in the system dump log result. Main installer log is generally found in **"installer/installerd.log"**. When looking for installation error or history: Please have a look on this log which will contain most useful explanation. When reporting issues, please provide the full dumped log archive.

### General recommendations <a href="#vos3_installer_recommendations" id="vos3_installer_recommendations"></a>

#### Overwrites / customisation <a href="#vos3_installer_recommendations_overwrites" id="vos3_installer_recommendations_overwrites"></a>

Sometimes, applications provide default installation files and libraries and some of them are meant to be customized / overwritten by a customer or third-party. Due to the rule of [Conflicts](#vos3_installer_conflicts) this will lead to an error at installation.

Recommandation is to isolate the "customizable" parts in a bundle with a specific name: for example "AppNameCustom". Then customer or third-party can create a new version of this bundle with same name "AppNameCustom" but different content. This will work as a "plug-in": as the customized bundle has the same name, the previous version of the bundle will be removed and customized part will be added. Also, if additional information to the version is needed, one can use the "version\_extension": see [Versions](#vos3_installer_versions) .

#### Installation file location <a href="#vos3_installer_recommendations_install_locations" id="vos3_installer_recommendations_install_locations"></a>

For installation files storage it is recommended to use "data" (pointed by "\~/flash") location over "versioned data" (pointed by "\~/versioned\_data") as "versioned data" is copied during installation.

**Note:** globalshare (/mnt/appdata/versioned/globalshare/) and share (/mnt/appdata/versioned/share/) locations are "versioned data" locations.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://sandbox-docs.verifone.com/adk-5.0-programmers-guide/readme/system_overview/pg_all_components/pg_installer.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
