sources
ARES System Manual: File Sources

This article is about file sources in storage. See also ax for a discussion about package sources. It is recommended you read the db entry before this one.

A file source is any data stream which is in a format that the storage daemon understands. When properly configured, sources allow the unit to seamlessly access text files stored in other databases, including other prims and remote webservers.

Only text files can be accessed from a file source; LSL programs and other assets must still be installed via in-world packages. For many types of post-market add-on however, remote sources can be a convenient alternative.


Source Table

The database subsection LSD:fs.source contains the list of filesystems that the storage daemon will attempt to mount at system startup. By default, these are:

  local: link=3 / phase rd
  ns-persona: http://my.nanite-systems.com/<;version>/persona/ / static ro
  setup: http://my.nanite-systems.com/<;version>/setup/ / static ro

where <version> is the current ARES version number, e.g. 0.4.4.

These source definitions are based on the Unix fstab format and provide everything ARES needs to know to find and interact with the source in question.

Use @db fs.source to see the current source definitions.

Each entry has the fields:

  <name>: <address> <path> <format> <options>

These are separated by spaces, and defined as follows:

  <name> is the the database key under LSD:fs.source where the record is stored; e.g. local: is really just the db command's output in response to the query fs.source. This is also called the mount or source name, and should be a short, one-word descriptor describing what makes the mount unique.
 
  <address> is how to find the file source. Its exact text depends on the filesystem in use.
 
  <path> is always / (reserved for future use).
 
  <format> is the type of filesystem being mounted. ARES currently supports two: phase and static (see below).
 
  <options> is a comma-separated list of flags describing how the filesystem should be used. Right now it only supports one option, the mount permissions. Valid permissions are ro (read only), rd (read and delete), and rw (read and write).


Mounts versus Sources

A mount is a source that is actively in use by the system. The fs command can be used to mount or unmount sources, but changes will only be carried over to the next system boot if they are saved in LSD:fs.source.


The Phase Filesystem

PHASE (Prim-to-prim Hardware-Agnostic Storage Engine) is a generic protocol for interacting with storage device drivers using chat channels. The underlying storage method is left up to the device author. For example, access to notecards stored on the unit is currently mediated using a phase driver built into the fs program, but the same protocol could also be used to implement storage in LinksetData, Experience Keys, or an HTTP backend. The phase protocol even supports writing to files, although this is, of course, not possible for notecards.

Source addresses when using phase are a comma-separated list of options, such as link=3 or device=chassis,channel=2. The options are:

  uuid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx sets an exact UUID for a linkset to target. This is not recommended unless you are connecting temporarily to a server.
  device=xxxx sets an exact UUID for a linkset to target, but does so by looking for an attached light bus device with the appropriate address, e.g. chassis or storage. (See hardware)
  link=x modifies the provided UUID by looking for a different link in the linkset. For example, device=storage,link=3 will look for the UUID of the third prim in the storage device's linkset.
  ch=x or channel=x changes the channel number from the default (1608011905). This is useful both for putting multiple filesystem drivers in the same prim.

If no UUID is set, ARES assumes its own linkset; this is why local's source address is just link=3.

It is possible to mount someone else's local storage by specifying the uuid and link fields, but note that doing this is protected by security rules (storage-ro, storage-rd, and storage-rw).

Finally, note that notecard storage cannot grant permissions above rd, as writing to notecards from within LSL is not (yet) possible.

Documentation on the phase protocol is included in the ARES SDK.


The Static Filesystem

Although the phase system can be used to implement any underlying storage medium, the storage daemon has built-in support for fetching files from a plain website. The static format differs from the syntax used by earlier versions of ARES, which has been retroactively named wf+ (Web Folders Plus).

To mount a static source successfully, the address must be an HTTP or HTTPS URL ending in /, and the source must be mounted as read-only (with the ro option). The page at the specified address should be in the following format:

<filename> <size>
<filename> <size>
<filename> <size>
<filename> <size>
...

That is, a plain text file (ideally text/plain) listing filenames and sizes on each line, with a space separating the record pairs. Filenames in ARES must never contain spaces.

For example:

aloof.p 947
analysis.p 987
backup.p 1043
barista.p 918
barkeep.p 949
bimbo.p 1191
boss.p 946
bratty.p 948

These files should be accessible by appending their names to the address, e.g. aloof.p in the above listing is available at http://my.nanite-systems.com/0.4.4/ns-persona/aloof.p

Below is a sample PHP source code file that implements the static filesystem on Apache. To use it, simply name it index.php and place it in your chosen directory.

<?php
header('Content-Type: text/plain');

function filter_filenames(string $file) {
    $unlistedFiles = [
        '.htaccess',
        'index.php',
        '..',
        '.'
   
]
;
    return array_search($file, $unlistedFiles) === FALSE;
}

function size_filenames(string $file) {
    return rawurlencode($file) . ' ' . filesize($file);
}

$items = scandir(getcwd());
$filteredItems = array_filter($items, 'filter_filenames');
$sizedItems = array_map('size_filenames', $filteredItems);
echo implode(chr(10), $sizedItems);