The Mount Table

Wherein you use the basic tools of service discovery.

Prerequisites:
All tutorials require Vanadium installation, and must run in a bash shell.
Further, please download this script then source it:

source ~/Downloads/scenario-b-setup.sh

This command wipes tutorial files and defines shell environment variables. If you start a new terminal, and just want to re-establish the environment, see instructions here.

Introduction

This tutorial focusses on using a mount table with the fortune server and client programs you made in the basics tutorial, and just re-made with the prerequisites script above.

Credentials

To keep security simple initially, all processes here will use the same credentials. Further, credentials will be specified using this environment variable:

export V23_CREDENTIALS=$V_TUT/cred/basics

Vanadium programs consult this environment variable when the credentials aren't specified by using the --v23.credentials flag, or by using a security agent.

Start a table

When you ran the fortune server in the basics tutorial, you told it to write its network endpoint to a file, then you told the client to read that file so it would know where to find the server.

Let's do that again, but this time instead of using a file to hold the endpoint, we'll use a server.

The server is called a mount table, and its executable has the name mounttabled:

PORT_MT=23000  # Pick an unused port.
kill_tut_process TUT_PID_MT
$V_BIN/mounttabled --v23.tcp.address :$PORT_MT &
TUT_PID_MT=$!

A mount table happens to be a Vanadium service. This means the vrpc program can report its VDL interface:

$V_BIN/vrpc signature -s /localhost:$PORT_MT

It also means that the mount table has a principal - it must run with credentials. Since the --v23.credentials flag wasn't specified at startup, the Vanadium runtime consulted the environment variable V23_CREDENTIALS (set above) to get the credentials.

Had credentials been left unspecified, randomly generated credentials would have been used, and the problems reviewed at the end of the basics tutorial would happen below when processes start talking to each other. Mount table security will be discussed in later tutorial.

The -s option stands for 'shallow resolve'. It forces vprc to apply to mount table itself and not what might be mounted at its root.

The namespace client

The table is up, but empty.

Start the existing fortune server binary, so we have a service to put in the table:

kill_tut_process TUT_PID_S1
$V_TUT/bin/server --endpoint-file-name $V_TUT/s1.txt &
TUT_PID_S1=$!

Mounting

namespace is a command line client dedicated to manipulating mount tables. The following mounts the server at the name fortuneAlpha.

$V_BIN/namespace \
    --v23.namespace.root /localhost:$PORT_MT \
    mount fortuneAlpha `cat $V_TUT/s1.txt` 100m

The flag --v23.namespace.root specifies which mount table to use. The flag is available in all Vanadium programs.

In Vanadium, services live in hierachical trees called the namespaces. The root node of a tree is a mount table, hence the flag name. Other nodes are either services (leaves) or other mount tables.

Globbing

To glob is to use a character pattern to select strings from a set.

The command namespace glob * reports the names of all known names:

$V_BIN/namespace \
    --v23.namespace.root /localhost:$PORT_MT \
    glob -l '*'

There's just one name: fortuneAlpha. Use of the flag -l triggers additional output; you see the name's endpoint, and you see it will expire (will be dropped from the table) in about one hundred minutes. That's what the 100m meant in the mount command above.

Resolution

When a name is known, and you just want to resolve it to an endpoint, use namespace resolve {name}:

$V_BIN/namespace \
    --v23.namespace.root /localhost:$PORT_MT \
    resolve fortuneAlpha

The output should match the endpoint recorded in $V_TUT/s1.txt:

cat $V_TUT/s1.txt

Name usage

Recapping, here's how you connected the fortune client to the fortune server using a full service endpoint name in the basics tutorial:

$V_TUT/bin/client --server `cat $V_TUT/s1.txt`

Now you can use the name fortuneAlpha instead:

$V_TUT/bin/client \
    --v23.namespace.root /localhost:$PORT_MT \
    --server fortuneAlpha

The client program didn't need to be recompiled to allow this new usage because Vanadium code in the client interprets the value of the --server flag.

In the first command, --server's value was something like /@3@tcp@127.0.0.1:.... The leading / caused it to be interpreted directly as an endpoint rather than as a service name to be used as a lookup key. That means communication attempts begin immediately, and if the string doesn't refer to a live service, you won't know it until the attempts timeout.

In the second command, --server's value was just fortuneAlpha. Strings that don't start with / are treated as service names needing a lookup. If a lookup fails, the client will know it immediately, and may retry depending on various configurations.

The namespace variable

This tutorial uses only one mount table, and it's repetitive to constantly specify the --v23.namespace.root flag with the same value.

Ommiting the flag will trigger use the following shell variable:

export V23_NAMESPACE=/localhost:$PORT_MT

Now a fortune retrieval is as simple as:

$V_TUT/bin/client --server fortuneAlpha

Flags vs. variables

In Vanadium, flag values, when specified, always trump the values of corresponding shell variables. So --v23.namespace.root trumps $V23_NAMESPACE, and --v23.credentials trumps $V23_CREDENTIALS.

Shell variable values, in turn, trump default behavior.

The default behavior for unspecified namespace is to use a public mount table maintained by the v23 team. Circa April 2015 the service runs at ns.dev.v.io:8101. The port serves Vanadium protocol, not HTTP.

The default behavior for unspecified credentials is to generate random credentials.

Many names, one endpoint

A single service instance can have multiple names. Mount the same service again, with the name fortuneBeta, and a brief time to live:

$V_BIN/namespace mount fortuneBeta `cat $V_TUT/s1.txt` 5m

Do the glob again:

$V_BIN/namespace glob -l '*'

You'll see two names, with the same endpoint, but with different expiration times. Later you'll find the names can have different access control lists as well.

Confirm that the second name works:

$V_TUT/bin/client --server fortuneBeta

Many endpoints, one name

Start a second instance of the fortune server:

kill_tut_process TUT_PID_S2
$V_TUT/bin/server --endpoint-file-name $V_TUT/s2.txt &
TUT_PID_S2=$!

Mount it on the (original) name fortuneAlpha:

$V_BIN/namespace mount fortuneAlpha `cat $V_TUT/s2.txt` 100m

List the names again:

$V_BIN/namespace glob -l '*'

Now the name fortuneAlpha reports two endpoints, with distinct expiration times.

This is a means to implement redundancy, load sharing, etc. The mount table will resolve specific requests to one endpoint, but multiple endpoints let it assign a server using simple rotation, or by using load, response times, etc.

Confirm that fortuneAlpha still works (with two endpoints):

$V_TUT/bin/client --server fortuneAlpha

Now kill the original server:

kill_tut_process TUT_PID_S1

And retry the request:

$V_TUT/bin/client --server fortuneAlpha

You should still get a fortune, but this time it can only come from the second server instance.

The mount table will still report the dangling endpoint until it expires, as it might come back to life.

Unmounting

Unmounting works as you might expect:

$V_BIN/namespace unmount fortuneAlpha `cat $V_TUT/s1.txt`
$V_BIN/namespace unmount fortuneBeta `cat $V_TUT/s1.txt`

That leaves only server 2 in the table (with the name fortuneAlpha):

$V_BIN/namespace glob -l '*'

The reported endpoint should match the stored endpoint of server 2:

cat $V_TUT/s2.txt

Unmount it as well:

$V_BIN/namespace unmount fortuneAlpha `cat $V_TUT/s2.txt`

Optionally observe failure

Optionally, confirm that client use of the unmounted name fortuneAlpha fails. Feel free to interrupt before the retry attempts exhaust themselves.

$V_TUT/bin/client --server fortuneAlpha

Cleanup

kill_tut_process TUT_PID_S2
kill_tut_process TUT_PID_MT
unset V23_CREDENTIALS
unset V23_NAMESPACE

Summary