Calling remote services in Inferno
There are a few ways to call remote services in the Inferno world.
Importing ("mounting") remote namespaces
Before we can go further, we must understand how to mount remote filesystems on our local machine (see
MountRemoteNamespace). This is a simple recipe for doing just this. (There may be other methods which are preferable for various reasons.)
On the remote machine
- Start up Inferno and run
svc/net to start network services.
- Let's say you want to export the namespace rooted at
/usr/john. Run listen -A tcp!*!54321 { export /usr/john & }. This will make the /usr/john/ namespace available on port 54321 (make sure this port is open to your "local" machine). If you want the connection to be authenticated, remove the -A option.
On the local machine
- Start up Inferno and run
svc/net to start network services.
- Let's say you want to mount the remote directory on
machine.somewhere.com at /n/remote. Run mount tcp!machine.somewhere.com!54321 /n/remote.
- Run
lc /n/remote. You should see the contents of the /usr/john namespace on the remote machine.
Calling native programs on remote computers
The
os command in a hosted installation of Inferno runs applications in the native operating system. For example, if Limbo is hosted on a Linux/Unix system, type
os uname. You should see the type of the host operating system (i.e. the output of running
uname in the host OS). We can call these native procedures from a different machine:
On the remote machine
This is the machine that will be running the native program. Let's say it's a machine running SunOS.
- Create a program on the remote machine. A good example is a simple shell script. Create a file called
dateloop.sh with the following contents:
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9 10; do
echo "Hello from `uname`, `date`"
sleep 1
done
- Set the file permissions to be an executable file (
chmod a+x dateloop.sh). Check that the file executes correctly (you should get 10 lines of output, one per second, with each line reading something like: Hello from SunOS, Tue Apr 20 09:34:07 BST 2004)
- Start up Inferno and run
svc/net to start network services
- Run
"bind -a '#C' /". This binds the host OS's command line program into the /cmd directory (do lc: you should see that the /cmd directory has appeared).
- Run
os /full/path/to/dateloop.sh. Check that you get the expected output as above.
On the local machine
Let's say that this is a machine running Linux.
- Start up Inferno and run
svc/net to start network services
- Run
"bind -a '#C' /".
- Run
os uname. Check that you get the expected output (e.g. "Linux").
- Now let's mount the whole of the remote namespace. Run
mount machine.somewhere.com /n/remote.
- This is equivalent to running
mount tcp!machine.somewhere.com!styx /n/remote, where styx is an alias to the port number under which the whole namespace is served (this is port 6666 by default: see /lib/ndb/inferno). This listener is run when you start up network services with svc/net.
- You may need to authenticated to make this connection. See MountRemoteNamespace for how to get authentication.
- Check that the mount has succeeded:
lc /n/remote. You should see the whole of the remote namespace.
- Bind the remote
/cmd directory on top of the existing directory: bind -b /n/remote/cmd /cmd. Note that this time the flag is -b, not -a. This is important (see the manual entry for bind).
- Run
os /full/path/to/dateloop.sh again. You should see the output of running dateloop.sh on the remote machine as above.
You can follow these steps for running any native process on a remote machine. Bear in mind that you have to give the full path to the executable on the remote machine unless it is in the
$PATH of the host OS.
Variation
The
os program assumes that the command interface of the OS in question is located at
/cmd. This presents a problem if we want to run programs on more than one host system. I have edited the
os program so that the location of the
/cmd directory can be specified. The new file is called
os_new.b. To use it, specify the location of the
/cmd directory with the
-o switch:
os_new -o /n/remote uname
In this case the
/cmd directory in question is in the directory
/n/remote. So, based on the above example, the output of this command should be "SunOS".
In this way output can be piped between different machines. In this example, we'll run
dateloop.sh on the remote machine and pipe its output through
cat on the local machine:
os_new -o /n/remote /full/path/to/dateloop.sh | os cat
Note: Piping the output through
cat doesn't really do very much except to illustrate the principle that the output from a program on one machine can be piped into the input of a program on another. There's probably a better example.
Using file2chan
file2chan is a useful and simple function for creating synthetic files (see the manual entry for file2chan and sh-file2chan). For example:
On the remote machine
- Run
svc/net to start network services
- Change to a directory in your homespace (e.g.
cd /usr/john)
- Type
load file2chan to load the file2chan module
- Run
file2chan oschan {} { os uname }. This creates a synthetic file called oschan (which you should see if you type ls). The empty first pair of braces means that reading this "file" will cause nothing to happen. The second pair of braces means that writing something (anything) to this file will cause the program os uname to be run.
- Try it - type
echo rubbish > oschan. You should see the name of the host OS.
On the local machine
- Run
svc/net to start network services
- Mount the namespace of the remote machine:
mount mymachine.somewhere.com /n/remote.
- Change to the directory containing the synthetic file on the remote machine:
cd /n/remote/usr/john. Type ls and you should see the "file" called oschan.
- Write something to the file:
echo rubbish > oschan.
- Nothing happens on the local machine! However, the output of
os uname appears on the remote machine.
So, in this way we can execute processes on a remote machine, but we haven't got the output back to our local machine. To do this, we'd probably have to write a Limbo program using the
file2chan function, and arrange it so that the output gets piped back down to the client (this is definitely possible, but I haven't found the right source code yet).
This link might be a good place to start, but I think the code in here is from an earlier version of Limbo.
--
JonBlower - 01 Apr 2004