DragonFly On-Line Manual Pages
CLOUDABI-RUN(1) DragonFly General Commands Manual CLOUDABI-RUN(1)
NAME
cloudabi-run - execute CloudABI processes
SYNOPSIS
cloudabi-run path
DESCRIPTION
CloudABI is a purely capability-based runtime environment, meaning that
access to system resources is solely based on the set of file descriptor
that the process possesses. For example, CloudABI processes can only
access a file if it possesses a file descriptor for that file or one of
its parent directories. This makes it critical that a CloudABI process
is provided the right set of file descriptors on startup.
The problem with providing a set of file descriptors on startup is that
the file descriptors either need to be placed at fixed indices or that a
separate configuration file describes the purpose of each file
descriptor. The latter is hard to accomplish, due to the fact that
CloudABI programs cannot open configuration files from arbitrary
locations on the filesystem.
To simplify program configuration and at the same time make it easier to
safely set up the initial set of file descriptors, CloudABI processes can
be launched using the cloudabi-run utility. cloudabi-run executes a
CloudABI program stored at a path and provides it a copy of YAML data
read from standard input. The YAML data is provided in an already parsed
form and can be accessed by using the alternative entry point
program_main():
#include <program.h>
void program_main(const argdata_t *ad);
The YAML data can be traversed by using the <argdata.h> functions
argdata_get_binary(), argdata_get_bool(), argdata_get_float(),
argdata_get_int(), argdata_get_str(), argdata_get_str_c(),
argdata_get_timestamp(), argdata_iterate_map(), and
argdata_iterate_seq(). The names of these functions correspond to the
respective YAML types.
By default, cloudabi-run executes the process with an empty set of file
descriptors. File descriptors can be granted to the process by attaching
them to the YAML data as objects using specialized YAML tags. The
CloudABI process can obtain the file descriptor numbers of these objects
by calling argdata_get_fd().
YAML TAGS
The following YAML tags can be used to provide resources to CloudABI
processes:
tag:nuxi.nl,2015:cloudabi/fd: int
Exposes a file descriptor by decimal file descriptor number, or the
special values "stdout" and "stderr".
tag:nuxi.nl,2015:cloudabi/file: map
Opens a file for reading. File objects have the following
attributes:
path: str
The path of the file.
tag:nuxi.nl,2015:cloudabi/socket: map
Creates a socket and binds it to a specified address. Socket
objects have the following attributes:
bind: str
The address to which the socket should be bound. If the
address starts with a /, this creates a UNIX domain socket
and binds it to the path provided. Otherwise, it resolves
the address using getaddrinfo(3).
type: str
Socket type. Valid types are "dgram" for datagram sockets,
"seqpacket" for sequenced-packet sockets , and "stream" for
stream sockets. The default value is "stream".
EXAMPLES
The following example shows a program that writes a fixed message to all
of the file descriptors stored in a sequence. With the configuration
provided, it writes the message to standard output three times in a row.
$ cat hello.c
#include <argdata.h>
#include <program.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
static bool print_message(const argdata_t *ad, void *unused) {
int fd;
if (argdata_get_fd(ad, &fd) == 0)
dprintf(fd, "Hello, world\n");
return true;
}
void program_main(const argdata_t *ad) {
argdata_iterate_seq(ad, print_message, NULL);
exit(0);
}
$ cat hello.yaml
%TAG ! tag:nuxi.nl,2015:cloudabi/
---
- !fd stdout
- !fd stdout
- !fd stdout
$ x86_64-unknown-cloudabi-cc -o hello hello.c
$ cloudabi-run hello < hello.yaml
Hello, world
Hello, world
Hello, world
Below is a simple web server that writes simple responses to incoming
requests. With the configuration provided, it listens on TCP port 12345.
$ cat webserver.c
#include <sys/socket.h>
#include <argdata.h>
#include <program.h>
#include <stdlib.h>
#include <unistd.h>
void program_main(const argdata_t *ad) {
int sockfd;
if (argdata_get_fd(ad, &sockfd) == 0) {
int connfd;
while ((connfd = accept(sockfd, NULL, NULL)) >= 0) {
const char buf[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n\r\n"
"Hello, world\n";
write(connfd, buf, sizeof(buf) - 1);
close(connfd);
}
}
exit(1);
}
$ cat webserver.yaml
%TAG ! tag:nuxi.nl,2015:cloudabi/
---
!socket
bind: 0.0.0.0:12345
$ x86_64-unknown-cloudabi-cc -o webserver webserver.c
$ cloudabi-run webserver < webserver.yaml
IMPLEMENTATION NOTES
cloudabi-run invokes a helper utility called cloudabi-reexec before
executing the executable stored at path. cloudabi-reexec is a CloudABI
executable that merely acts as a proxy to guarantee that the process
already runs in capabilities mode before executing the requested binary,
making it safe to run cloudabi-run on third-party executables.
As CloudABI's program_exec() function scans the argument data to obtain a
list of file descriptors that need to be retained in the new process,
cloudabi-run guarantees that any file descriptors that are not specified
in the YAML data are closed. File descriptors are renumbered to be
contiguous, starting at file descriptor zero.
AUTHORS
CloudABI has been developed by Nuxi, the Netherlands: https://nuxi.nl/.
DragonFly 6.5-DEVELOPMENT August 7, 2015 DragonFly 6.5-DEVELOPMENT