This RFC describes an installation concept that aims to be more natural to the end-user than current package-based installers. The idea behind this concept is to get rid of the whole installation process. The complete application, including its dependencies and data files, is a single self-contained executable (one app, one file). There is absolutely no installation process. Just run and you're done. Delete and it's uninstalled. Replace and you've upgraded.
The RFC is incomplete in that it doesn't describes all edge-cases. Also, it does not touch on how one obtains application packages or resolves dependencies. Repositories will handle this task, but their specification and usage should be part of a separate RFC.
The concept is based on bundles and packages which will be described from the end-user's point of view. Later we will get into a few implementation details.
From the user's point of view, the bundle is the application. The application is executed when you double-click the bundle. Bundles must be self-contained. There are no installation scripts and no dependencies. Bundles must be location-independent, so the user can move them around wherever he wants. In other words, bundles are not installed; they run directly. On the first run, the user might have to agree to the application's license, though.
By default, the Deskbar queries all bundles on trusted volumes. The Deskbar provides a search interface for running applications and allows for maintaining a list of favorite applications which you can organize in a folder-like hierarchy. Additionally, a list of the most frequently used applications is shown (if possible, pure file viewers like ShowImage are not shown in that list). This is necessary because the number of found bundles might be much bigger than the number of applications the user actually works with.
Since all bundles are queried automatically (on trusted volumes) a first-time run isn't necessary to open a file with that application. Of course, the application marked as preferred in your Deskbar will take precedence.
Bundles can be uninstalled by simply deleting the bundle file. When a bundle is deleted its data files and settings are automatically removed from the system when certain cleanup criteria apply (e.g., after 30 days or depending on available disk storage; also see the note below). This provides the possibility to undo the deletion without losing any settings and it is required for supporting upgrades. Removable media require special handling because otherwise unmounting would result in the system thinking the bundle got deleted (which might not be desired). The settings could, for example, be preserved for a much longer period or migrated to the volume the application resides on (this must be an explicit process, so no secret data gets exposed mistakenly).
Doing an upgrade (or downgrade) is as simple as replacing/overwriting the existing bundle file with a new version. Still, you can have multiple versions of the same application on your computer without any conflicts. In case of incompatibilities each application version gets a separate set of settings.
Bundles may contain multiple applications like it might be the case for an office suite. There is either a default application that should be executed on double-click or the bundle behaves like a folder, showing all available applications when opened. The Deskbar menu will always expand a multi-app bundle as if it were a folder. The default application is highlighted in bold.
Packages are an advanced form of the BeOS .pkg files. They are primarily intended for system upgrades, application add-ons, and system components/extensions. The installation is a simple one-click process, similar to the Haiku R1 package installer. Unlike bundles, packages are allowed to have dependencies, even on bundles. Bundles and packages go hand in hand, but bundles are preferred and should be used whenever possible.
Only if advanced installation features are required and bundles cannot solve your problem in a clean way packages may be used.
Internally, bundles are compressed, read-only file system images. The compression method should be good enough, so people don't .zip the bundles (which destroys the no-install process).
Installs, uninstalls, and upgrades are atomic: they either succeed or fail. If the system crashes in the middle of an operation the system can revert changes and go back into a clean state. If dependencies are missing the system will search for them in the known repositories. When dependencies are not needed, anymore, they are cleaned up automatically.
Meta-Information in bundles and packages:
- internal version (different between incompatible versions)
- type: normal or system (appear in separate Deskbar sections)
- target architecture
- dependencies (only for packages)
Each application within a bundle gets its own entry:
- keywords (e.g.: imaging, photo, image)
- path (path of the binary application within the bundle)
- ID (used to construct app's MIME type)
- supported file types
- capabilities: actions on file types (e.g.: Compress, Print, Reply, ...)
- exported supplementaries (samples, docs, ...)
The ID follows this scheme:
where TYPE is either of "app", "pkg", "add-on". You must follow the MIME-types RFC and not use slashes when creating your ID. The application's MIME type is generated by prepending "application/x-" to the ID. For example, BeMail would have the ID "app.HaikuInc.BeMail" and the MIME type "application/x-app.HaikuInc.BeMail".
Every bundle has an internal set of default settings. Only modifications to these default settings should be stored outside of the bundle. All bundle data is stored in two folders (one global, one per user) named by the application's ID. Their contents are categorized by the app's "internal version". All folders should be created on-demand: <ID>/v<internal-version>/
Applications should be aware of duplicate add-ons in the global and per-user folders.
On upgrades between compatible versions your settings and add-ons are preserved. But if the internal version has changed the versions will behave like two totally separate applications. In that case it is the new app's responsibility to migrate settings from older versions. Add-ons cannot be migrated because they are only allowed to depend on one specific internal version number.
Attributes and queries
It's important that attributes are preserved over the Internet, so attributes are not stored as BFS-style meta-data, but integrated into the bundle (e.g., as a flattened BMessage). A dedicated index_server must be responsible for indexing bundle and package contents.
You can inspect a bundle's contents by right-clicking it. Tracker will add an item that allows for navigating bundles as if they were folders. The mount-point is located in a temporary folder. The complete path to the binary (including the mount-point) is passed to the application in argv (i.e.: it is actually executed from that location). Mounted bundles are not shown in Tracker's volume list.
All exported supplementaries are added to Tracker/Deskbar's context-menu.
Tracker's info dialog
The dialog will be extended with a bundle's:
- name and version
- short and long description
- access to all supplementaries
All actions for managing bundles and packages are accessible from the command-line (possibly with advanced options). The application used to run a bundle is RunBundle. It automatically mounts the bundle, executes the application contained within, and unmounts the bundle when the application quits. The bundle is automatically installed if that is not the case, yet.
Possible future directions
With union-mounts (ala UnionFS) we can add limited dependency support to bundles without risking DLL-hell.
It should be possible to encrypt (e.g., for commercial apps) and sign (e.g., for system upgrades) bundles and packages.
The Fildirute concept could allow for mounting bundles in-place, so you can "cd" into a bundle from the command-line.