Main Page
From RDI
RDI: Runtime Dependencies Installer
Contents |
[edit] What is RDI ?
RDI is a library that gives an application the ability to install its dependencies at runtime.
It integrates many different kind of dependencies:
- Dynamic libraries (.dll or .so)
- RPM packages
- DEB packages
- Ruby Gems
It is very easy to adapt RDI to install another type of dependency (designed as plugins).
Once RDI is linked with an application, the application can describe its dependencies easily at runtime, and ask to install them. RDI first checks if the dependency needs to be installed before trying to do so.
When installing a dependency, the user can have the choice to install it within the application's space (i.e. local USB installations), in the system's space (/usr/lib, c:\windows...), or in the user's space (/home, Mes Documents...) if the user is not root/administrator of his system. A little GUI is provided for the user to choose what is his preferred method.
The application's environment is then altered, incorporating the new dependency, and can continue its process without having to restart most of the times.
RDI does not load the dependency itself (for example, no dlopen, no require...). It just prepares the application's context to ensure success when the application will try loading the dependency for real.
RDI has a very little memory footprint: it will not load its plugins unless required. Therefore, an application that asks for dependencies that are already installed will not load RDI plugins needed to install those dependencies (it may sound obvious, but still needs to be pointed out).
[edit] What is a dependency ?
[edit] Definition
A dependency is an object that can be installed in an application's context. For example, a dynamic library required for an application has to be installed in one of the directories where the application will look for libraries.
[edit] Interface
Dependencies can be reachable without installation, just by modifying the application context itself. For example, if a library is present in a new directory, it is possible to just add this directory to the list of directories storing libraries in the application's context to have the dependency loadable.
Dependencies can also be installed. For example, a library can be downloaded from the Internet to make it reachable by the application's context.
[edit] Structure
A dependency is structured into several components:
- A list of Testers components: their role is to tell how to test if the dependency is loadable.
- A list of Installers components: their role is to know how to install a dependency.
- Each Installer component is associated to a list of Context Modifiers components: their role is to adapt the application's context to make sure that what was installed will be loadable.
Testers, Installers and Context Modifiers are implemented in RDI as plugins, easy to extend to fit new types. Following are the current plugins shipped in RDI:
[edit] Testers
- Ruby requires.
- Dynamic libraries.
- Single files.
[edit] Installers
- Ruby Gems
- Downloadable zip files
[edit] Context Modifiers
- Dynamic libraries directories (LD_LIBRARY_PATH on Linux)
- Ruby load paths ($LOAD_PATH)
- Ruby Gems paths (GEM_PATH)
[edit] Example
Here is an example of installation of RubyGems description:
{
Testers: [
# Test if rubygems library exists
'RubyRequires: rubygems'
],
Installers: [
# Download RubyGems from the web, and install with some command line
( 'DownloadAndInstall: http://rubyforge.org/frs/download.php/60719/rubygems-1.3.5.zip | ruby -w setup.rb --destdir %INSTALLDIR%',
ContextModifiers: [
# Once installed, add the lib directory to the Ruby library path
'RubyLoadPath %INSTALLDIR%/lib/ruby/site_ruby/1.8',
# And the bin dir to the system PATH
'SystemPath %INSTALLDIR%/bin'
]
)
]
}
[edit] How RDI processes dependencies ?
An application can ask RDI to install a list of dependencies in 1 call to the RDI library.
RDI then processes 4 steps:
- Try to find if the dependencies are already loadable in the context. If this is the case, no extra steps are performed and RDI returns successfully.
- Try to locate dependencies by extending the context (search local directories for libraries...). If they have been found in this step, RDI returns successfully.
- Ask the user what to do with remaining dependencies: Install them ? Search for them in another directory ? Ignore them ?
- Install remaining dependencies that the user chose at previous step.
Here is the more detailed process:
[edit] How to install RDI ?
RDI is packaged for the following languages: Install RDI for Ruby
[edit] How to use RDI ?
RDI is a library. Here are the current languages API you can use:
[edit] What is the difference between RDI and other packagers ?
- Packagers are very often bound to their own packaging format (RPM, Gems...). Very often, users need to install several different types of packages/libraries/compiled sources for their application to run in a correct environment. RDI integrates already several different packaging formats, and has been designed to easily integrate new formats.
- Packagers don't operate at runtime. For example, installing a dynamic library will maybe need to alter the environment (PATH, LD_LIBRARY_PATH...). Packagers won't alter the environment of the process that called them. The user will have to change the environment himself, and restart his application afterwards. RDI will run the packager and then alter the environment.
- Packagers are not easily designed for local installations or users not having root/administrator privileges. It is sometimes difficult for a non-root user to install a package/library: he will have to tweak many obscure options and alter his environment in an even more obscure way. RDI is designed to install dependencies in many different flavours:
- In the system (need root access very often)
- In the local application directory (useful for USB installations)
- In the user's home directory (for non-root users)
- In a temporary directory (user has nearly no privilege at all, and the dependencies will work for his current session only)
- Packagers are not very open to plugins extensions. RDI is highly extensible, providing various ways to add dependency types not yet handled. Here are the different plugins that can be used in RDI:
- Context modifications plugins (i.e. 1 plugin to handle modification of GEM_PATH...)
- Installers plugins (i.e. 1 plugin to handle the installation of Ruby Gems...)
- Testers plugins (i.e. 1 plugin to test if Ruby files are accessible)
[edit] What are the current limitations of RDI ?
RDI is still in Alpha stage. That means that it is quite unstable, has still bugs, and misses some features. However, some projects already use it.
Current limitations (we are working actively on them) are:
- Handle only the following types of dependencies:
- Dynamic libraries
- Ruby Gems
- Interfaces are made for Ruby applications only.
[edit] Contact
RDI needs still many development efforts to be fully useable for a wide variety of developers. Any contribution is very welcome.
If you are interested in the development of RDI in any form, please contact me.
Thanks
Muriel
