Skip to content

Commit fb742e2

Browse files
committed
ccon: Add '--socket PATH' to support a create/start split
Along the lines of the create/start split we've been discussing for the OCI [1,2]. Pull some common functionality into a libccon, although I don't intend to make that a more than an internal helper. Post-error cleanup in ccon-cli is pretty slim, since the process is just about to die anyway. I'll probably go back through and add proper cleanup later. serve_socket gets too deeply nested for my taste, but it's not quite to the point where I'd pull out the request handling into a handle_start_request helper or some such. Mostly because I'd have to either setup a new buf/iov/msg in the helper's stack or pass that all through from serve_socket ;). A few notes on the tests: I don't have a stand-alone 'wait' on my system (it's built into most shells [3]), but I've added an explicit check for it because POSIX doesn't require it to be built in. The waiting in the create/start tests is a bit awkward, but here's the reasoning for the various steps: * Put the socket in a 'sock' subdirectory so we don't have to mess with inotifywait's --exclude (when what we really want is an --include). In most cases, the socket would be the first thing created in the test directory, but the process.host test will create a pivot-root.* before creating the socket. * Clear a 'wait' file before launching the inotifywait/start subshell and append to it from that subshell so grep has something to look at (even if it racily starts looking before the subshell processes the inotifywait line). * Block on a busy-wait grep until inotifywait sets up its watcher. This ensures we don't call ccon and create the socket before the watcher is looking. The zero-second sleep while we wait for inotifywait to setup its watcher is busy, but POSIX doesn't require 'sleep' to support non-integer times [4]. All of these issues could be abstracted out into an 'event' command [5], but they're fine for a proof-of-concept create/start split. [1]: https://groups.google.com/a/opencontainers.org/d/msg/dev/qWHoKs8Fsrk/k55FQrBzBgAJ Subject: Re: Splitting Start into create() and run() Date: Thu, 24 Mar 2016 15:04:14 -0700 Message-ID: <[email protected]> [2]: opencontainers/runtime-spec#384 Subject: Split create and start [3]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html#tag_17_06 [4]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sleep.html [5]: opencontainers/runtime-spec#508 Subject: runtime: Add an 'event' operation for subscribing to pushes
1 parent e4b616d commit fb742e2

File tree

12 files changed

+1126
-261
lines changed

12 files changed

+1126
-261
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
ccon
2+
ccon-cli
23
*.o

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ LDLIBS := $(shell pkg-config --libs-only-l jansson libcap-ng)
66
.PHONY: all clean fmt
77
.PRECIOUS: %.o
88

9-
all: ccon
9+
all: ccon ccon-cli
1010

1111
%.o: %.c
1212
$(CC) $(CFLAGS) -c -o "$@" "$<"
1313

14-
ccon: %: %.o
15-
$(CC) $(LDFLAGS) -o "$@" "$<" $(LDLIBS)
14+
ccon ccon-cli: %: %.o libccon.o
15+
$(CC) $(LDFLAGS) -o "$@" $^ $(LDLIBS)
1616

1717
clean:
18-
rm -f *.o ccon
18+
rm -f *.o ccon ccon-cli
1919

2020
fmt:
21-
indent --ignore-profile --linux-style *.c
21+
indent --ignore-profile --linux-style *.h *.c

README.md

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ than [LXC][lxc.container.conf.5]).
1111
## Table of contents
1212

1313
* [Lifecycle](#lifecycle)
14+
* [Socket communication](#socket-communication)
15+
* [Getting the container process's
16+
PID](#getting-the-container-processs-pid)
17+
* [Start request](#start-request)
1418
* [Configuration](#configuration)
1519
* [Version](#version)
1620
* [Namespaces](#namespaces)
@@ -58,8 +62,11 @@ synchronize the container setup. Here's an outline of the lifecycle:
5862
| | mounts filesystems |
5963
| | ← sends namespaces-complete |
6064
| runs pre-start hooks | blocks on exec-message |
61-
| sends exec-message → | |
62-
| | opens the local ptmx |
65+
| binds to socket path | |
66+
| sends connection socket → | |
67+
| blocks on exec-process message | listens for process JSON |
68+
| | ← sends exec-process message |
69+
| removes socket path | opens the local ptmx |
6370
| | ← sends pseudoterminal master |
6471
| waits on child death | executes user process |
6572
| splicing standard streams ||
@@ -83,6 +90,77 @@ use [`nsenter`][nsenter.1] or a wrapping ccon invocation to join those
8390
namespaces before the main ccon invocation creates the new mount
8491
namespace.
8592

93+
## Socket communication
94+
95+
With `--socket=PATH`, ccon will bind a [`SOCK_SEQPACKET` Unix
96+
socket][unix.7] to `PATH`. This path is created after namespace-setup
97+
completes, so users can use its presence as a trigger for further
98+
configuration (e.g. network setup) before [starting](#start-request)
99+
the [user-specified code](#process). The path is removed after a
100+
[start request](#start-request) is received or after the container
101+
process exits, whichever comes first.
102+
103+
The [`ccon-cli`](ccon-cli.c) program distributed with this repository
104+
is one client for the ccon socket.
105+
106+
### Getting the container process's PID
107+
108+
An [`SO_PEERCRED`][socket.7] request will return the container
109+
process's PID [in the receiving process's PID
110+
namespace][pid_namespaces.7]. The client can use this to look up the
111+
container process in their local [`/proc`][proc.5]. This request may
112+
be performed as many times as you like.
113+
114+
### Start request
115+
116+
The request is a single [`struct iovec`][recv.2] containing either a
117+
leading null byte or process JSON. Sending a single null-byte message
118+
will trigger the [**`process`**](#process) field present in the
119+
original configuration, while non-empty strings will completely
120+
override that field.
121+
122+
The response is a single [`struct iovec`][recv.2] containing either a
123+
single null-byte message (for success) or an error message encoded in
124+
[ASCII][ascii.7]. In this context, “success” means “successfully
125+
received the start request”, because the container process sends the
126+
response before actually executing the
127+
[user-specified code](#process).
128+
129+
If you set [**`host`**](#host) in your process JSON, `ccon-cli` will
130+
open the referenced path and pass the open file descriptor to the
131+
container over the Unix socket.
132+
133+
### Example
134+
135+
In one shell, launch ccon and have it listen on a socket at
136+
`/tmp/ccon-sock`:
137+
138+
```
139+
$ ccon --socket /tmp/ccon-sock
140+
```
141+
142+
In a second shell, get the container process's PID, but don't trigger
143+
the user-specified code:
144+
145+
```
146+
$ PID=$(ccon-cli --socket /tmp/ccon-sock --pid)
147+
$ echo "${PID}"
148+
2186
149+
```
150+
151+
You can then perform additional configuration using that PID:
152+
153+
```
154+
$ ip link set ccon-ex-veth1 netns "${PID}"
155+
```
156+
157+
And when you're finished setting up the environment, you can trigger
158+
the [user-specified code](#process):
159+
160+
```
161+
$ ccon-cli --socket /tmp/ccon-sock --config-string '{"args": ["busybox", "sh"]}'
162+
```
163+
86164
## Configuration
87165

88166
Ccon is similar to an [Open Container Specification][ocs] runtime in
@@ -822,6 +900,7 @@ be distributed under the GPLv3+.
822900
[setgid.2]: http://man7.org/linux/man-pages/man2/setgid.2.html
823901
[setuid.2]: http://man7.org/linux/man-pages/man2/setuid.2.html
824902
[syscall.2]: http://man7.org/linux/man-pages/man2/syscall.2.html
903+
[recv.2]: http://man7.org/linux/man-pages/man2/recv.2.html
825904
[environ.3p]: https://www.kernel.org/pub/linux/docs/man-pages/man-pages-posix/
826905
[exec.3]: http://man7.org/linux/man-pages/man3/exec.3.html
827906
[getcwd.3]: http://man7.org/linux/man-pages/man3/getcwd.3.html
@@ -830,11 +909,14 @@ be distributed under the GPLv3+.
830909
[pts.4]: http://man7.org/linux/man-pages/man4/pty.4.html
831910
[filesystems.5]: http://man7.org/linux/man-pages/man5/filesystems.5.html
832911
[lxc.container.conf.5]: https://linuxcontainers.org/lxc/manpages/man5/lxc.container.conf.5.html
912+
[proc.5]: https://linuxcontainers.org/lxc/manpages/man5/proc.5.html
913+
[ascii.7]: http://man7.org/linux/man-pages/man7/ascii.7.html
833914
[capabilities.7]: http://man7.org/linux/man-pages/man7/capabilities.7.html
834915
[namespaces.7]: http://man7.org/linux/man-pages/man7/namespaces.7.html
835916
[pid_namespaces.7]: http://man7.org/linux/man-pages/man7/pid_namespaces.7.html
836917
[pty.7]: http://man7.org/linux/man-pages/man7/pty.7.html
837918
[signal.7]: http://man7.org/linux/man-pages/man7/signal.7.html
919+
[socket.7]: http://man7.org/linux/man-pages/man7/socket.7.html
838920
[unix.7]: http://man7.org/linux/man-pages/man7/unix.7.html
839921
[user_namespaces.7]: http://man7.org/linux/man-pages/man7/user_namespaces.7.html
840922
[mount.8]: http://man7.org/linux/man-pages/man8/pty.8.html
@@ -843,4 +925,5 @@ be distributed under the GPLv3+.
843925
[cgroups]: https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
844926
[cgroups-unified]: https://www.kernel.org/doc/Documentation/cgroup-v2.txt
845927
[devpts]: https://www.kernel.org/doc/Documentation/filesystems/devpts.txt
928+
[rfc1345.s5]: https://tools.ietf.org/html/rfc1345#section-5
846929
[sd_listen_fds]: http://www.freedesktop.org/software/systemd/man/sd_listen_fds.html

0 commit comments

Comments
 (0)