Skip to content
Zvi edited this page May 31, 2015 · 4 revisions

What is a module

Module is a composable, optional part of the OSv guest. Multiple modules can be installed into one image.

Module may affect the following aspects of the guest image:

  • add files to the guest file system
  • declare run configurations which may be then chosen for execution during guest startup.

For example, a module may represent an application which was adapted to run on OSv.

Module resolution

Modules are identified by name. The mapping between module's name and its location is configured in osv.git/config.json in modules section. Each module has an entry with module name as key and location parameters as value.

The type property determines the how module should be located. The most common type is direct-dir which means the module is located in the local file system under directory specified in path property.

For example, the following configuration defines location of module named mgmt to be ${OSV_BASE}/mgmt/:

{
   "modules": {

        "mgmt": {
            "type": "direct-dir",
            "path": "${OSV_BASE}/mgmt/"
        }

   ...

}

Other types include git and svn. For these path is the URL to the repository containing the module.

You can include external mapping files by creating include entry with a list of files to include:

{
   "modules": {

   ...

       "include": [
           "${OSV_BASE}/apps/modules.json"
        ]
   }
}

Module structure

Module directory should contain certain files depending on the desired effect. All files are optional. If none of the files are present, including a module will have no effect on the image.

Automatic module building

If module contains Makefile it will be automatically built with make module command if it is required in the image.

The module may assume the following environment variables are set:

  • OSV_BASE - path to directory in which OSv is checked out.
  • OSV_BUILD_PATH - path to current build directory (eg. ${OSV_BASE}/build/release)

Uploading files using manifest file

Module may declare files which should be uploaded by creating a manifest file named usr.manifest. It has the following structure:

[manifest]
/usr/file1: ${MODULE_DIR}/file1
/usr/file2: ${MODULE_DIR}/file2

The path on the left from : is the path inside guest (destination) whereas the path on the right is the path on the host's local file system (source).

You can use wildcards to include whole directories:

/usr/tomcat/**: ${MODULE_DIR}/upstream/apache-tomcat-7.0.42/**

You can use & notation to save some space when both paths share a suffix. For example this:

/usr/lib/&/libboost_filesystem-mt.so.1.53.0: ${MODULE_DIR}/lib64/&

is equivalent to:

/usr/lib/libboost_filesystem-mt.so.1.53.0: ${MODULE_DIR}/lib64/libboost_filesystem-mt.so.1.53.0

The file allows to use simple variable substitution using ${variable} syntax. Currently defined variables:

  • OSV_BASE - same as described in "Automatic module building" section
  • MODULE_DIR - local file system path for current module. If the module is fetched from external repository this path will point to a temporary directory to which the module files have been fetched.

module.py

Module may contain a file named module.py in which you can use python DSL to:

  • declare dependencies on other modules
  • declare run configurations
  • access attributes of other modules
  • define file mappings (instead of or in addition to the manifest file)

Start by importing the API:

from osv.modules import api

If you want to declare a run configuration which executes an object file use api.run(cmdline). Example:

my_app = api.run('/usr/my_app.so --arg1 --arg2')

To declare a run configuration which starts Java application use api.run_java(jvm_args, classpath, args). Example:

my_app = api.run_java(
   classpath=['/java/lib1.jar', '/java/lib2.jar', '/java/classes'],
   args=["-Dkey=value", "com.myapp.Main", "arg1", "arg2"])

You can declare a compound run configuration by creating a list of run configurations. In this case, all apps will be started in parallel:

start_all = [api.run('/usr/app1.so'), api.run('/usr/app2')]

To declare dependency on another module, use api.require(name):

api.require('java')

This will make the module of given name will also be installed in the image.

Every global attributes defined in module.py are accessible to the modules which import them via the result of require() call. For example if module A has the following in its module.py:

from osv.modules import api

install_dir = '/usr/app'
app = api.run(install_dir + '/myapp.so')

Then module B may access the attributes of A form its module.py like this:

from osv.modules import api

_a = api.require('A')

run_all = [
   _a.app,
   api.run('/usr/monitor.so ' + 'path=' + _a.install_dir)
]

Image configurations

Image configuration is a file which determines which modules are installed in the image and which run configurations should be used to construct a default command line (executed when OSv boots). Creating image configuration is optional. See "Building an image" section for how to build an image form the command line directly.

Image configurations are looked up by name using the following path pattern osv.git/images/<name>.py. You can use the same python DSL as in module.py for importing modules and accessing their attributes.

Image configuration may declare run attribute which holds run configuration to be installed in the image. Example:

from osv.modules import api

run = [
  api.require('tomcat').default,
  api.require('mgmt').httpserver
]

The above will result in both 'tomcat' and 'mgmt' modules to be installed in the image. The run configuration assigned to default attribute of tomcat module will be started in parallel with the run configuration assigned to 'httpserver` attribute of mgmt module.

Building an image

Currently images may only be built as part of osv.git make process. To build an image using image configuration named myimage run:

scripts/build image=myimage

The build system will read image definition from images/myimage.py. If no image= parameter is specified the image named default is used.

If there is no image of the requested name the build system will assume it is a module name and will try to install that module. You can install many modules directly by separating them with , like this:

scripts/build image=tomcat,mgmt

By default this will also use default attribute of each module to append a run configuration to run list, if such attributes exist. What is on the run list is started in parallel.

You can also reference run configurations directly using .:

scripts/build image=tomcat,mgmt.shell,mgmt.httpserver
Clone this wiki locally