This page documents the prototype BundleGenerator (BundleGen) demo that allows an OCI image to be downloaded from a registry and converted to an OCI bundle*, applying rules based on a platform and app configuration.

The source code for BundleGen can be found on Consult Red's GitLab here: https://redgitlab.redembedded.com:8443/rdk-sig-dac/bundlegen

A README.md file is included in the repo with instructions on how to set up a dev environment and use bundlegen on both Fedora and Ubuntu

Video

Hello World (Xi6 & Ubuntu 16)

This shows the Docker "Hello World" image (https://hub.docker.com/_/hello-world) being pulled from the Docker registry and run on both an Ubuntu 16 VM and then an Xi6 STB. The Hello World image is a multi-architecture image, allowing bundlegen to select the correct architecture (amd64 or armv7) based on the platform configuration.

BundleGen_HelloWorld.mov

Wayland EGL Test (Xi6)

This shows LGI's Wayland-EGL-Test app (https://github.com/stagingrdkm/lgpub/tree/master/dac/apps) running on an Xi6 STB. It also shows how BundleGen refuses to create a bundle for the Vagrant VM since the VM does not have graphics output so the app cannot run on the VM.

BundleGen_Wayland.mov

Input/Output Formats

STB/Operator Config

As shown in the videos, one of the inputs to bundlegen is a JSON file defining the configuration of the platform that will run the device.

This configuration file requires comments/feedback to ensure it covers all use cases. The idea is this config could be mostly automatically generated by a tool either run on the STB or by Bitbake, with only minor sections needing to be filled in by hand. An operator would maintain a platform configuration per-device, with the ability to create a generic "operator.json" file that would allow options to be set for all operator devices (which could be overridden by individual platforms as required).

Below is the metadata for the Comcast Xi6 STB used in the demo video. Note the RDK section is currently unused by bundlegen

{
   "platformName":"xi6",
   "os":"linux",
   "arch":{
      "arch":"arm",
      "variant":"v7"
   },
   "rdk":{
      "version":"2020Q4",
      "supportedFeatures":[
         "Controller",
         "DeviceInfo",
         "Monitor",
         "OCDM",
         "TraceControl",
         "WifiManager",
         "com.comcast.CoPilot",
         "com.comcast.DeviceProvisioning",
         "com.comcast.FrameRate",
         "com.comcast.HdcpProfile",
         "com.comcast.HdmiInput",
         "com.comcast.StateObserver",
         "com.comcast.StorageManager",
         "org.rdk.ActivityMonitor",
         "org.rdk.DeviceDiagnostics",
         "org.rdk.DisplaySettings",
         "org.rdk.FrontPanel",
         "org.rdk.HomeNetworking",
         "org.rdk.LoggingPreferences",
         "org.rdk.Network",
         "org.rdk.OCIContainer",
         "org.rdk.Proxies",
         "org.rdk.SleepTimer",
         "org.rdk.TTSResource",
         "org.rdk.TTSSettings",
         "org.rdk.Timer",
         "org.rdk.UserPreferences",
         "org.rdk.Warehouse"
      ]
   },
   "hardware":{
      "graphics":true,
      "maxRam":"4096M"
   },
   "storage":{
      "persistent":{
         "storageDir":"/tmp/data",
         "maxSize":"100M"
      }
   },
   "gpu":{
      "westeros":{
         "hostSocket":"/tmp/westeros-dac"
      },
      "extraMounts":[
         {
            "source":"/tmp/nxserver_ipc",
            "destination":"/tmp/nxserver_ipc",
            "type":"bind",
            "options":[
               "bind",
               "ro"
            ]
         }
      ],
      "envvar":[
         "LD_PRELOAD=/usr/lib/libwayland-client.so.0:/usr/lib/libwayland-egl.so.0"
      ],
      "devs":[
         {
            "type":"c",
            "path":"/dev/nexus",
            "major":33,
            "minor":0,
            "access":"rw"
         }
      ],
      "gfxLibs":[
         {
            "src":"/usr/lib/libEGL.so",
            "dst":"/usr/lib/libEGL.so"
         },
         {
            "src":"/usr/lib/libEGL.so",
            "dst":"/usr/lib/libEGL.so.1"
         },
         {
            "src":"/usr/lib/libGLESv2.so",
            "dst":"/usr/lib/libGLESv2.so"
         },
         {
            "src":"/usr/lib/libGLESv2.so",
            "dst":"/usr/lib/libGLESv2.so.2"
         },
         {
            "src":"/usr/lib/libwayland-egl.so.0",
            "dst":"/usr/lib/libwayland-egl.so"
         },
         {
            "src":"/usr/lib/libwayland-egl.so.0",
            "dst":"/usr/lib/libwayland-egl.so.0"
         },
         {
            "src":"/usr/lib/libwayland-egl.so.0",
            "dst":"/usr/lib/libwayland-egl.so.1"
         },
         {
            "src":"/usr/lib/libnxclient.so",
            "dst":"/usr/lib/libnxclient.so"
         },
         {
            "src":"/usr/lib/libnexus.so",
            "dst":"/usr/lib/libnexus.so"
         },
         {
            "src":"/usr/lib/libnxpl.so",
            "dst":"/usr/lib/libnxpl.so"
         },
         {
            "src":"/usr/lib/libwesteros_simpleshell_client.so.0",
            "dst":"/usr/lib/libwesteros_simpleshell_client.so.0"
         },
         {
            "src":"/usr/lib/libwayland-server.so.0",
            "dst":"/usr/lib/libwayland-server.so.0"
         }
      ]
   },
   "mounts":[

   ],
   "network":{
      "options":[
         "nat",
         "open",
         "private"
      ]
   },
   "envvar":[
      "XDG_RUNTIME_DIR=/tmp"
   ],
   "resourceLimits":[
      {
         "type":"RLIMIT_NPROC",
         "hard":300,
         "soft":300
      },
      {
         "type":"RLIMIT_RTPRIO",
         "hard":6,
         "soft":6
      }
   ],
   "disableUserNamespacing":false,
   "usersAndGroups":{
      "uidMap":[
         {
            "containerID":0,
            "hostID":996,
            "size":1
         }
      ],
      "gidMap":[
         {
            "containerID":0,
            "hostID":992,
            "size":1
         }
      ]
   },
   "logging":{
      "mode":"file",
      "logDir":"/var/log"
   },
   "dobby":{
      "pluginDir":"/usr/lib/plugins/dobby",
      "pluginDependencies":[
         "/lib/libc.so.6",
         "/lib/libdl.so.2",
         "/lib/libcap.so.2",
         "/lib/libgcc_s.so.1",
         "/lib/libm.so.6",
         "/lib/libpthread.so.0",
         "/lib/libresolv.so.2",
         "/lib/librt.so.1",
         "/lib/libsystemd.so.0",
         "/usr/lib/liblzma.so.5",
         "/usr/lib/libnl-3.so.200",
         "/usr/lib/libnl-route-3.so.200",
         "/usr/lib/libstdc++.so.6",
         "/usr/lib/libyajl.so.2",
         "/lib/ld-linux-armhf.so.3"
      ]
   }
}


App Metadata (Future SDK Integration)

One other input is app metadata. This currently is a standalone JSON file, with similar fields to those defined in the MAS, but with a bit more technical information (including bind mounts, storage configuration and network configuration). The goal would be for this to be generated by the SDK tooling, and embedded inside the OCI Image either by extending the image config or including it as a separate layer that can be read by BundleGen.

This metadata would sit alongside the MAS metadata, as this info is more low-level and not required to be known by an app-store service.

Below are two example app metadata files - one for the console-based hello-world app and the other for the flutter app (not shown in demo videos)

hello-world
{
   "id":"com.docker.helloworld",
   "type":"application/vnd.rdk-app.dac.native",
   "graphics":false,
   "network":{
      "type":"none"
   },
   "storage":{
      "persistent":[

      ],
      "temp":[

      ]
   },
   "resources":{
      "ram":"5M"
   },
   "features":[

   ],
   "mounts":[

   ]
}


wayland-egl-test
{
   "id":"com.rdk.flutter",
   "type":"application/vnd.rdk-app.dac.native",
   "graphics":true,
   "network":{
      "type":"nat",
      "dnsmasq":"true"
   },
   "storage":{
      "persistent":[
         {
            "size":"60M",
            "path":"/home/private"
         }
      ],
      "temp":[
         {
            "size":"100M",
            "path":"/home/temp"
         },
         {
            "size":"10M",
            "path":"/var/volatile"
         }
      ]
   },
   "resources":{
      "ram":"256M"
   },
   "features":[

   ],
   "mounts":[

   ]
}


Future Improvements Required

Full library matching

The current demo does not currently match all the libraries in the bundle with those on the STB, although this functionality is planned. This will reduce the final size of the bundle significantly.

Security Analysis

The generated bundle is based off a combination of the bundles in use by Sky in production and the latest base config from OCI. This should be reviewed to add any necessary restrictions such as cgroup restrictions, resource limits and mounts.

  • No labels