SDK on VirtualBox/Design

= Overview =

The virtualised SDK architecture supports multiple devices and emulators with a single Build Engine.

The main components are:
 * Build Engine
 * Qt Creator
 * Virtualbox Emulator(s)
 * Physical device(s)

Shared Folders
VirtualBox shared folders are used for sharing files between the host and the build engine and emulators for:
 * Configuration
 * SSH keys
 * Home directory
 * Targets
 * Other source directory trees

current
There are 3 shared folders at the moment.

mersdk:/etc/mersdk is mapped to the SailfishOS application areas mersdk folder and contains: configuration, targets and the ssh keys

home:/home/mersdk is mapped to the users 'home' directory

srcN:/home/srcN are each mapped to source directory areas on the host

planned
The upcoming SDK will have 4 shared folders on the Engine and 2 on the Emulator:


 * ./vmshare is shared as 'config' to MerSDK and emulators mounted under /etc/mersdk/share

./vmshare/ssh/private_keys/$index/$user   	private keys to ssh to emulators ./vmshare/devices.xml				device description/config


 * ./mersdk/targets is shared as 'targets' to MerSDK mounted under /host_targets/

./mersdk/targets/$name/		 	Targets ./mersdk/targets/targets.xml		Target description


 * ./mersdk/ssh is shared as 'ssh' to MerSDK mounted under /etc/sshd/authorized_keys

./mersdk/ssh/$user/authorized_keys	authorized_keys for sshd


 * ./emulator/$index/ssh is shared as 'ssh' to Emulator $index mounted under /etc/sshd/authorized_keys

./emulator/$index/ssh/$user/authorized_keys authorized_keys for sshd

Notice that there may be multiple emulators so each one has an 'internal persistent DeviceID' (ie not something changeable and user visible like a name) A simple index will be enough - we can use the same index for the internal LAN (see below)

Additional src dir mappings will look like this:


 * QtCreator asks for a shared src path

VBoxManage sharedfolder add MerSDK src --hostpath
 * Runs:

./share/qtcreator/MerProject/QtCreator.ini at MerSDK/SharedSrc
 * Also adds the path to:


 * Then run sdk-manage --srcdir --add 1
 * This adds and mounts a /home/src mountpoint (using systemd). Change --add to --remove to remove


 * The current version of scripts in sdk-utils/sdk-vm assumes these paths

Overview
The SDK network serves the following purposes:
 * Host -> Build Engine for ssh/web
 * Host -> Emulator for ssh/debugging
 * Host -> Device for ssh/debugging
 * Build Engine -> internet for updates and information
 * Build Engine -> Device with ssh to support deployment
 * Build Engine -> Emulator with ssh to support deployment, execution and debugging
 * Emulator -> internet for updates and information
 * Device -> Build Engine to authorise SDK activity

To do this the Emulator and Build Engine will have 2 network adaptors.

An adaptor running in NAT mode allows open outbound access and permits some incoming connections (ssh, www and gdb). This also handles Engine > Device connectivity.

A second adaptor is setup on the Build Engine and Emulators as a VirtualBox internal adaptor and supports open Build Engine <> Emulator(s) connectivity.

Note in the discussion the emulator 'index' is just a low value integer to support multiple emulator configurations.

QtCreator and the Build Engine need to collaborate to setup the Emulator internal networking.

To share information between QtCreator, the Build Engine and the Emulators there is a devices.xml file stored on the 'config' shared folder.

It looks like this:

 10.220.220   VER NEWVER  192.168.0.12 ssh/private_keys/d1 VER NEWVER  2              10.220.220         ssh/private_keys/2 08:00:5A:11:00:02 VER NEWVER

Build and Deployment
The primary goal of the SDK is to make it easy to build application packages.

The build process aims to follow the Qt-way and at the same time make the creation of packages as simple as possible.

It should be easy to do simple things and possible to do complex things.

The solution we use is to do every build as a proper package build but to avoid repeating steps or executing uneeded ones.

This ensures that any errors in the project such as using assets not handled by the install step are caught early - it also means that making a package is incremental and not a burden at the end of a project.

Packaging
The ultimate goal is to deliver a quality package to your end-user. This package is an rpm and will contain your binaries, QML and any assets such as sound and image files.

Building
When an application is built the normal qmake/make steps are run - but they happen as they would in a package build.

Deployment
We supports two deployment styles: package and fast

Package deployment
Normal deployment using rpm -i/-U will install to / - eg /usr/lib/ ie system locations

So when a build is finished and you want to deploy QtC will run a 'make install', package up the files and create an rpm which installs under / like any other package.

Fast deployment
However, during development you probably don't want to build a full rpm package and re-install it just to check a tiny change in a qml file.

So the SDK supports fast (incremental) deployment.

Clearly it is not ideal to simply install files all over a device potentially overwriting system files and certainly making it hard to clean up later - so the fast deployment installs within a development area.

Simply the build process runs 'make install' and then uses rsync to copy any changed files over to an area on the device/emulator known as the "deployment root" - /opt/sdk/

To enable this to work DEPLOYMENT_ROOT environment variable is set for code running in this manner.

The cleanest mechanism is for code to be aware of the mechanism:

QString(getenv("DEPLOYMENT_ROOT"))+QString("/usr/share/translations"));

engineeringEnglish->load("app_eng_en",     QString(getenv("DEPLOYMENT_ROOT"))+QString("/usr/share/translations"));

Alternative build-time solutions could also be devised.

Deployment mechanism
The Build engine handles the actual transfer of data since it has rsync and access to src/build results and there are no cross-platform issues. To do this it needs network and credential information about the device. QtC manages an XML file about the devices and shares this as the devices.xml described on this page.

This xml will also contain a list of emulators and info about them.

mb2 is now able to look at this and run rsync or copy and install the rpm

Packaging Metadata
The SDK allows the management of the metadata for a package.

Ths is done by allowing the user to
 * use simple SDK UI
 * extend the metadata for more complex packages
 * edit the yaml file
 * discard all assistance and use the raw spec file

This should include rpm package dependencies obtained from .pro and manually added dependencies.

One new requirement is that the Build engine and emulator need to talk to each other over tcp so we need to add a host-only network. This is needed for some future features too so that's acceptable.