mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-22 02:21:34 +00:00
Merge pull request #3085 from djs55/update-logging
Support pluggable logging systems
This commit is contained in:
commit
29c3ef0aa0
@ -33,7 +33,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.9.91
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
services:
|
||||
|
94
docs/logging.md
Normal file
94
docs/logging.md
Normal file
@ -0,0 +1,94 @@
|
||||
# Logging
|
||||
|
||||
By default LinuxKit will write onboot and service logs directly to files in
|
||||
`/var/log` and `/var/log/onboot`.
|
||||
|
||||
It is tricky to write the logs to a disk or a network service as no disks
|
||||
or networks are available until the `onboot` containers run. We work around
|
||||
this by splitting the logging into 2 pieces:
|
||||
|
||||
1. `memlogd`: an in-memory circular buffer which receives logs (including
|
||||
all the early `onboot` logs)
|
||||
2. a log writing `service` that starts later and can download and process
|
||||
the logs from `memlogd`
|
||||
|
||||
To use this new logging system, you should add the `memlogd` container to
|
||||
the `init` block in the LinuxKit yml. On boot `memlogd` will be started
|
||||
from `init.d` and it will listen on a Unix domain socket:
|
||||
|
||||
```
|
||||
/var/run/linuxkit-external-logging.sock
|
||||
```
|
||||
|
||||
The `init`/`service` process will look for this socket and redirect the
|
||||
`stdout` and `stderr` of both `onboot` and `services` to `memlogd`.
|
||||
|
||||
## memlogd: an in-memory circular buffer
|
||||
|
||||
The `memlogd` daemon reads the logs from the `onboot` and `services` containers
|
||||
and stores them together with a timestamp and the name of the originating
|
||||
container in a circular buffer in memory.
|
||||
|
||||
The contents of the circular buffer can be read over the Unix domain socket
|
||||
```
|
||||
/var/run/memlogq.sock
|
||||
```
|
||||
|
||||
The circular buffer has a fixed size (overridden by the command-line argument
|
||||
`-max-lines`) and when it fills up, the oldest messages will be overwritten.
|
||||
|
||||
To store the logs somewhere more permanent, for example a disk or a remote
|
||||
network service, a service should be added to the yaml which connects to
|
||||
`memlogd` and streams the logs. The example program `logread` in the `memlogd`
|
||||
package demonstrates how to do this.
|
||||
|
||||
### Message format
|
||||
|
||||
The format used to read logs is similar to [kmsg](https://www.kernel.org/doc/Documentation/ABI/testing/dev-kmsg):
|
||||
```
|
||||
<timestamp>,<log>;<body>
|
||||
```
|
||||
where `<timestamp>` is an RFC3339-formatted timestamp, `<log>` is the name of
|
||||
the log (e.g. `docker-ce.out`) and `<body>` is the output. The `<log>` must
|
||||
not contain the character `;`.
|
||||
|
||||
### Usage examples
|
||||
```
|
||||
/ # logread -f
|
||||
2018-07-05T13:22:32Z,memlogd;memlogd started
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: waiting for carrier
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.err;eth0: could not detect a useable init
|
||||
system
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: carrier acquired
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;DUID 00:01:00:01:22:d0:d8:18:02:50:00:00:00:02
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: IAID 00:00:00:02
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: adding address fe80::d33a:3936:
|
||||
2ee4:5c8c
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: soliciting an IPv6 router
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: soliciting a DHCP lease
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: offered 192.168.65.4 from 192.1
|
||||
68.65.1 `vpnkit'
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: leased 192.168.65.4 for 7200 se
|
||||
conds
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: adding route to 192.168.65.0/24
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;eth0: adding default route via 192.16
|
||||
8.65.1
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;exiting due to oneshot
|
||||
2018-07-05T13:22:32Z,onboot.001-dhcpcd.out;dhcpcd exited
|
||||
^C
|
||||
```
|
||||
|
||||
Current issues and limitations:
|
||||
|
||||
- No docker logger plugin support yet - it could be nice to add support to
|
||||
memlogd, so the docker container logs would also be gathered in one place
|
||||
- No syslog compatibility at the moment and `/dev/log` doesn’t exist. This
|
||||
socket could be created to keep syslog compatibility, e.g. by using
|
||||
https://github.com/mcuadros/go-syslog. Processes that require syslog should
|
||||
then be able to log directly to memlogd.
|
||||
- Kernel messages not read on startup yet (but can be captured with
|
||||
`logwrite dmesg`)
|
||||
- Currently no direct external hooks exposed - but options available that
|
||||
could be added. Should also be possible to pipe output to e.g. `oklog`
|
||||
from `logread` (https://github.com/oklog/oklog)
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -4,7 +4,7 @@ kernel:
|
||||
cmdline: "console=ttyS0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/vpnkit-expose-port:v0.4 # install vpnkit-expose-port and vpnkit-iptables-wrapper on host
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
30
examples/logging.yml
Normal file
30
examples/logging.yml
Normal file
@ -0,0 +1,30 @@
|
||||
# Simple example of using an external logging service
|
||||
kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:f2bc1bda1ab18146967fa1a149800aaf14bee81b
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
- linuxkit/memlogd:883f0d46e7d3ae2d787e8acb496da115a4707cbc
|
||||
onboot:
|
||||
- name: sysctl
|
||||
image: linuxkit/sysctl:v0.4
|
||||
- name: dhcpcd
|
||||
image: linuxkit/dhcpcd:v0.4
|
||||
command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
|
||||
services:
|
||||
# Inside the getty type `/proc/1/root/usr/bin/logread -F` to follow the log
|
||||
- name: getty
|
||||
image: linuxkit/getty:44730fd0a7c59dbacf5b48b54ba33f551bcf7ef0
|
||||
env:
|
||||
- INSECURE=true
|
||||
# A service which generates log messages for testing
|
||||
- name: write-to-the-logs
|
||||
image: alpine
|
||||
command: ["/bin/sh", "-c", "while /bin/true; do echo hello $(date); sleep 1; done" ]
|
||||
trust:
|
||||
org:
|
||||
- linuxkit
|
||||
- library
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
onboot:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
services:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -3,7 +3,7 @@ kernel:
|
||||
cmdline: console=ttyS1
|
||||
ucode: intel-ucode.cpio
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -4,7 +4,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
onboot:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53-rt
|
||||
cmdline: "console=tty0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0 root=/dev/vda"
|
||||
init:
|
||||
- linuxkit/init:a14b7ef6115e6d56fe5bf7c40517b9e190dd4dfb
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.9.38
|
||||
cmdline: "console=tty0 console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
onboot:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
onboot:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=tty0 console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@ -199,17 +198,11 @@ func start(ctx context.Context, service, sock, basePath, dumpSpec string) (strin
|
||||
return "", 0, "failed to create container", err
|
||||
}
|
||||
|
||||
logger := GetLog(varLogDir)
|
||||
|
||||
io := func(id string) (cio.IO, error) {
|
||||
stdoutFile := filepath.Join("/var/log", service+".out.log")
|
||||
stderrFile := filepath.Join("/var/log", service+".err.log")
|
||||
// We just need this to exist. If we cannot write to the directory,
|
||||
// we'll discard output instead.
|
||||
if err := ioutil.WriteFile(stdoutFile, []byte{}, 0600); err != nil {
|
||||
stdoutFile = "/dev/null"
|
||||
}
|
||||
if err := ioutil.WriteFile(stderrFile, []byte{}, 0600); err != nil {
|
||||
stderrFile = "/dev/null"
|
||||
}
|
||||
stdoutFile := logger.Path(service + ".out")
|
||||
stderrFile := logger.Path(service + ".err")
|
||||
return &logio{
|
||||
cio.Config{
|
||||
Stdin: "/dev/null",
|
||||
@ -219,7 +212,6 @@ func start(ctx context.Context, service, sock, basePath, dumpSpec string) (strin
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
task, err := ctr.NewTask(ctx, io)
|
||||
if err != nil {
|
||||
// Don't bother to destroy the container here.
|
||||
|
193
pkg/init/cmd/service/logging.go
Normal file
193
pkg/init/cmd/service/logging.go
Normal file
@ -0,0 +1,193 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
errLoggingNotEnabled = errors.New("logging system not enabled")
|
||||
logWriteSocket = "/var/run/linuxkit-external-logging.sock"
|
||||
logReadSocket = "/var/run/memlogdq.sock"
|
||||
)
|
||||
|
||||
const (
|
||||
logDumpCommand byte = iota
|
||||
)
|
||||
|
||||
// Log provides access to a log by path or io.WriteCloser
|
||||
type Log interface {
|
||||
Path(string) string // Path of the log file (may be a FIFO)
|
||||
Open(string) (io.WriteCloser, error) // Opens a log stream
|
||||
Dump(string) // Copies logs to the console
|
||||
}
|
||||
|
||||
// GetLog returns the log destination we should use.
|
||||
func GetLog(logDir string) Log {
|
||||
// is an external logging system enabled?
|
||||
if _, err := os.Stat(logWriteSocket); !os.IsNotExist(err) {
|
||||
return &remoteLog{
|
||||
fifoDir: "/var/run",
|
||||
}
|
||||
}
|
||||
return &fileLog{
|
||||
dir: logDir,
|
||||
}
|
||||
}
|
||||
|
||||
type fileLog struct {
|
||||
dir string
|
||||
}
|
||||
|
||||
func (f *fileLog) localPath(n string) string {
|
||||
return filepath.Join(f.dir, n+".log")
|
||||
}
|
||||
|
||||
// Path returns the name of a log file path for the named service.
|
||||
func (f *fileLog) Path(n string) string {
|
||||
path := f.localPath(n)
|
||||
// We just need this to exist, otherwise containerd will say:
|
||||
//
|
||||
// ERRO[0000] failed to create task error="failed to start io pipe
|
||||
// copy: containerd-shim: opening /var/log/... failed: open
|
||||
// /var/log/...: no such file or directory: unknown"
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
// If we cannot write to the directory, we'll discard output instead.
|
||||
return "/dev/null"
|
||||
}
|
||||
_ = file.Close()
|
||||
return path
|
||||
}
|
||||
|
||||
// Open a log file for the named service.
|
||||
func (f *fileLog) Open(n string) (io.WriteCloser, error) {
|
||||
return os.OpenFile(f.localPath(n), os.O_WRONLY|os.O_CREATE, 0644)
|
||||
}
|
||||
|
||||
// Dump copies logs to the console.
|
||||
func (f *fileLog) Dump(n string) {
|
||||
path := f.localPath(n)
|
||||
if err := dumpFile(os.Stdout, path); err != nil {
|
||||
fmt.Printf("Error writing %s to console: %v", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
type remoteLog struct {
|
||||
fifoDir string
|
||||
}
|
||||
|
||||
// Path returns the name of a FIFO connected to the logging daemon.
|
||||
func (r *remoteLog) Path(n string) string {
|
||||
path := filepath.Join(r.fifoDir, n+".log")
|
||||
if err := syscall.Mkfifo(path, 0600); err != nil {
|
||||
return "/dev/null"
|
||||
}
|
||||
go func() {
|
||||
// In a goroutine because Open of the FIFO will block until
|
||||
// containerd opens it when the task is started.
|
||||
fd, err := syscall.Open(path, syscall.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
// Should never happen: we just created the fifo
|
||||
log.Printf("failed to open fifo %s: %s", path, err)
|
||||
}
|
||||
defer syscall.Close(fd)
|
||||
if err := sendToLogger(n, fd); err != nil {
|
||||
// Should never happen: logging is enabled
|
||||
log.Printf("failed to send fifo %s to logger: %s", path, err)
|
||||
}
|
||||
}()
|
||||
return path
|
||||
}
|
||||
|
||||
// Open a log file for the named service.
|
||||
func (r *remoteLog) Open(n string) (io.WriteCloser, error) {
|
||||
fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
|
||||
if err != nil {
|
||||
log.Fatal("Unable to create socketpair: ", err)
|
||||
}
|
||||
logFile := os.NewFile(uintptr(fds[0]), "")
|
||||
|
||||
if err := sendToLogger(n, fds[1]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return logFile, nil
|
||||
}
|
||||
|
||||
// Dump copies logs to the console.
|
||||
func (r *remoteLog) Dump(n string) {
|
||||
addr := net.UnixAddr{
|
||||
Name: logReadSocket,
|
||||
Net: "unix",
|
||||
}
|
||||
conn, err := net.DialUnix("unix", nil, &addr)
|
||||
if err != nil {
|
||||
log.Printf("Failed to connect to logger: %s", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
nWritten, err := conn.Write([]byte{logDumpCommand})
|
||||
if err != nil || nWritten < 1 {
|
||||
log.Printf("Failed to request logs from logger: %s", err)
|
||||
return
|
||||
}
|
||||
reader := bufio.NewReader(conn)
|
||||
for {
|
||||
line, err := reader.ReadString('\n')
|
||||
if err == io.EOF {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Failed to read log message: %s", err)
|
||||
return
|
||||
}
|
||||
// a line is of the form
|
||||
// <timestamp>,<log>;<body>
|
||||
prefixBody := strings.SplitN(line, ";", 2)
|
||||
csv := strings.Split(prefixBody[0], ",")
|
||||
if len(csv) < 2 {
|
||||
log.Printf("Failed to parse log message: %s", line)
|
||||
continue
|
||||
}
|
||||
if csv[1] == n {
|
||||
fmt.Print(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendToLogger(name string, fd int) error {
|
||||
var ctlSocket int
|
||||
var err error
|
||||
if ctlSocket, err = syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ctlConn net.Conn
|
||||
if ctlConn, err = net.FileConn(os.NewFile(uintptr(ctlSocket), "")); err != nil {
|
||||
return err
|
||||
}
|
||||
defer ctlConn.Close()
|
||||
|
||||
ctlUnixConn, ok := ctlConn.(*net.UnixConn)
|
||||
if !ok {
|
||||
// should never happen
|
||||
log.Fatal("Internal error, invalid cast.")
|
||||
}
|
||||
|
||||
raddr := net.UnixAddr{Name: logWriteSocket, Net: "unixgram"}
|
||||
oobs := syscall.UnixRights(fd)
|
||||
_, _, err = ctlUnixConn.WriteMsgUnix([]byte(name), oobs, &raddr)
|
||||
if err != nil {
|
||||
return errLoggingNotEnabled
|
||||
}
|
||||
return nil
|
||||
}
|
@ -62,6 +62,8 @@ func runcInit(rootPath, serviceType string) int {
|
||||
log.Fatalf("Cannot create log directory %s: %v", logDir, err)
|
||||
}
|
||||
|
||||
logger := GetLog(logDir)
|
||||
|
||||
for _, file := range files {
|
||||
name := file.Name()
|
||||
path := filepath.Join(rootPath, name)
|
||||
@ -76,23 +78,19 @@ func runcInit(rootPath, serviceType string) int {
|
||||
pidfile := filepath.Join(tmpdir, name)
|
||||
cmd := exec.Command(runcBinary, "create", "--bundle", path, "--pid-file", pidfile, name)
|
||||
|
||||
// stream stdout and stderr to respective files
|
||||
// ideally we want to use io.MultiWriter here, sending one stream to stdout/stderr, another to the files
|
||||
// however, this hangs if we do, due to a runc bug, see https://github.com/opencontainers/runc/issues/1721#issuecomment-366315563
|
||||
// once that is fixed, this can be cleaned up
|
||||
stdoutFile := filepath.Join(logDir, serviceType+"."+name+".out.log")
|
||||
stdout, err := os.OpenFile(stdoutFile, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
stdoutLog := serviceType + "." + name + ".out"
|
||||
stdout, err := logger.Open(stdoutLog)
|
||||
if err != nil {
|
||||
log.Printf("Error opening stdout log file: %v", err)
|
||||
log.Printf("Error opening stdout log connection: %v", err)
|
||||
status = 1
|
||||
continue
|
||||
}
|
||||
defer stdout.Close()
|
||||
|
||||
stderrFile := filepath.Join(logDir, serviceType+"."+name+".err.log")
|
||||
stderr, err := os.OpenFile(stderrFile, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
stderrLog := serviceType + "." + name + ".err"
|
||||
stderr, err := logger.Open(stderrLog)
|
||||
if err != nil {
|
||||
log.Printf("Error opening stderr log file: %v", err)
|
||||
log.Printf("Error opening stderr log connection: %v", err)
|
||||
status = 1
|
||||
continue
|
||||
}
|
||||
@ -152,13 +150,11 @@ func runcInit(rootPath, serviceType string) int {
|
||||
cleanup(path)
|
||||
_ = os.Remove(pidfile)
|
||||
|
||||
// dump the log file outputs to os.Stdout/os.Stderr
|
||||
if err = dumpFile(os.Stdout, stdoutFile); err != nil {
|
||||
log.Printf("Error writing stdout of onboot service %s to console: %v", name, err)
|
||||
}
|
||||
if err = dumpFile(os.Stderr, stderrFile); err != nil {
|
||||
log.Printf("Error writing stderr of onboot service %s to console: %v", name, err)
|
||||
}
|
||||
// ideally we want to use io.MultiWriter here, sending one stream to stdout/stderr, another to the log
|
||||
// however, this hangs if we do, due to a runc bug, see https://github.com/opencontainers/runc/issues/1721#issuecomment-366315563
|
||||
// once that is fixed, this can be cleaned up
|
||||
logger.Dump(stdoutLog)
|
||||
logger.Dump(stderrLog)
|
||||
}
|
||||
|
||||
_ = os.RemoveAll(tmpdir)
|
||||
|
19
pkg/memlogd/Dockerfile
Normal file
19
pkg/memlogd/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
||||
FROM linuxkit/alpine:1b05307ae8152e3d38f79e297b0632697a30c65c AS build
|
||||
|
||||
RUN apk add --no-cache go musl-dev
|
||||
ENV GOPATH=/go PATH=$PATH:/go/bin
|
||||
|
||||
COPY cmd/ /go/src/
|
||||
RUN go-compile.sh /go/src/memlogd
|
||||
RUN go-compile.sh /go/src/logread
|
||||
RUN go-compile.sh /go/src/logwrite
|
||||
|
||||
FROM scratch
|
||||
ENTRYPOINT []
|
||||
CMD []
|
||||
WORKDIR /
|
||||
COPY --from=build /go/bin/memlogd usr/bin/memlogd
|
||||
COPY --from=build /go/bin/logread usr/bin/logread
|
||||
COPY --from=build /go/bin/logwrite usr/bin/logwrite
|
||||
# We'll start from init.d
|
||||
COPY etc/ /etc/
|
3
pkg/memlogd/build.yml
Normal file
3
pkg/memlogd/build.yml
Normal file
@ -0,0 +1,3 @@
|
||||
image: memlogd
|
||||
binds:
|
||||
- /var/run:/var/run
|
@ -20,12 +20,15 @@ func main() {
|
||||
var follow bool
|
||||
var dumpFollow bool
|
||||
|
||||
flag.StringVar(&socketPath, "socket", "/tmp/memlogdq.sock", "memlogd log query socket")
|
||||
flag.StringVar(&socketPath, "socket", "/var/run/memlogdq.sock", "memlogd log query socket")
|
||||
flag.BoolVar(&dumpFollow, "F", false, "dump log, then follow")
|
||||
flag.BoolVar(&follow, "f", false, "follow log buffer")
|
||||
flag.Parse()
|
||||
|
||||
addr := net.UnixAddr{socketPath, "unix"}
|
||||
addr := net.UnixAddr{
|
||||
Name: socketPath,
|
||||
Net: "unix",
|
||||
}
|
||||
conn, err := net.DialUnix("unix", nil, &addr)
|
||||
if err != nil {
|
||||
panic(err)
|
@ -37,7 +37,7 @@ func main() {
|
||||
var serverSocket string
|
||||
var name string
|
||||
|
||||
flag.StringVar(&serverSocket, "socket", "/tmp/memlogd.sock", "socket to pass fd's to memlogd")
|
||||
flag.StringVar(&serverSocket, "socket", "/var/run/linuxkit-external-logging.sock", "socket to pass fd's to memlogd")
|
||||
flag.StringVar(&name, "n", "", "name of sender, defaults to first argument if left blank")
|
||||
flag.Parse()
|
||||
args := flag.Args()
|
@ -11,7 +11,8 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
@ -36,14 +37,13 @@ const (
|
||||
)
|
||||
|
||||
type queryMessage struct {
|
||||
conn *net.UnixConn
|
||||
conn net.Conn
|
||||
mode logMode
|
||||
}
|
||||
|
||||
type connListener struct {
|
||||
conn *net.UnixConn
|
||||
cond *sync.Cond // condition and mutex used to notify listeners of more data
|
||||
buffer bytes.Buffer
|
||||
conn net.Conn
|
||||
output chan *logEntry
|
||||
err error
|
||||
exitOnEOF bool // exit instead of blocking if no more data in read buffer
|
||||
}
|
||||
@ -56,57 +56,20 @@ func doLog(logCh chan logEntry, msg string) {
|
||||
func logQueryHandler(l *connListener) {
|
||||
defer l.conn.Close()
|
||||
|
||||
data := make([]byte, 0xffff)
|
||||
|
||||
l.cond.L.Lock()
|
||||
for {
|
||||
var n, remaining int
|
||||
var rerr, werr error
|
||||
|
||||
for rerr == nil && werr == nil {
|
||||
if n, rerr = l.buffer.Read(data); n == 0 { // process data before checking error
|
||||
break // exit read loop to wait for more data
|
||||
for msg := range l.output {
|
||||
_, err := io.Copy(l.conn, strings.NewReader(msg.String()+"\n"))
|
||||
if err != nil {
|
||||
l.err = err
|
||||
return
|
||||
}
|
||||
l.cond.L.Unlock()
|
||||
|
||||
remaining = n
|
||||
w := data
|
||||
for remaining > 0 && werr == nil {
|
||||
w = data[:remaining]
|
||||
n, werr = l.conn.Write(w)
|
||||
w = w[n:]
|
||||
remaining = remaining - n
|
||||
}
|
||||
|
||||
l.cond.L.Lock()
|
||||
}
|
||||
|
||||
// check errors
|
||||
if werr != nil {
|
||||
l.err = werr
|
||||
l.cond.L.Unlock()
|
||||
break
|
||||
}
|
||||
|
||||
if rerr != nil && rerr != io.EOF { // EOF is ok, just wait for more data
|
||||
l.err = rerr
|
||||
l.cond.L.Unlock()
|
||||
break
|
||||
}
|
||||
if l.exitOnEOF && rerr == io.EOF { // ... unless we should exit on EOF
|
||||
l.err = nil
|
||||
l.cond.L.Unlock()
|
||||
break
|
||||
}
|
||||
l.cond.Wait() // unlock and wait for more data
|
||||
}
|
||||
}
|
||||
|
||||
func (msg *logEntry) String() string {
|
||||
return fmt.Sprintf("%s %s %s", msg.time.Format(time.RFC3339), msg.source, msg.msg)
|
||||
return fmt.Sprintf("%s,%s;%s", msg.time.Format(time.RFC3339), msg.source, msg.msg)
|
||||
}
|
||||
|
||||
func ringBufferHandler(ringSize int, logCh chan logEntry, queryMsgChan chan queryMessage) {
|
||||
func ringBufferHandler(ringSize, chanSize int, logCh chan logEntry, queryMsgChan chan queryMessage) {
|
||||
// Anything that interacts with the ring buffer goes through this handler
|
||||
ring := ring.New(ringSize)
|
||||
listeners := list.New()
|
||||
@ -128,10 +91,11 @@ func ringBufferHandler(ringSize int, logCh chan logEntry, queryMsgChan chan quer
|
||||
remove = append(remove, e)
|
||||
continue
|
||||
}
|
||||
l.cond.L.Lock()
|
||||
l.buffer.WriteString(fmt.Sprintf("%s\n", msg.String()))
|
||||
l.cond.L.Unlock()
|
||||
l.cond.Signal()
|
||||
select {
|
||||
case l.output <- &msg:
|
||||
default:
|
||||
// channel is full so drop message
|
||||
}
|
||||
}
|
||||
if len(remove) > 0 { // remove listeners that returned errors
|
||||
for _, e := range remove {
|
||||
@ -142,20 +106,31 @@ func ringBufferHandler(ringSize int, logCh chan logEntry, queryMsgChan chan quer
|
||||
}
|
||||
|
||||
case msg := <-queryMsgChan:
|
||||
l := connListener{conn: msg.conn, cond: sync.NewCond(&sync.Mutex{}), err: nil, exitOnEOF: (msg.mode == logDump)}
|
||||
listeners.PushBack(&l)
|
||||
l := connListener{
|
||||
conn: msg.conn,
|
||||
output: make(chan *logEntry, chanSize),
|
||||
err: nil,
|
||||
exitOnEOF: (msg.mode == logDump),
|
||||
}
|
||||
go logQueryHandler(&l)
|
||||
if msg.mode == logDumpFollow || msg.mode == logFollow {
|
||||
// register for future logs
|
||||
listeners.PushBack(&l)
|
||||
}
|
||||
if msg.mode == logDumpFollow || msg.mode == logDump {
|
||||
l.cond.L.Lock()
|
||||
// fill with current data in buffer
|
||||
ring.Do(func(f interface{}) {
|
||||
if msg, ok := f.(logEntry); ok {
|
||||
s := fmt.Sprintf("%s\n", msg.String())
|
||||
l.buffer.WriteString(s)
|
||||
select {
|
||||
case l.output <- &msg:
|
||||
default:
|
||||
// channel is full so drop message
|
||||
}
|
||||
}
|
||||
})
|
||||
l.cond.L.Unlock()
|
||||
l.cond.Signal() // signal handler that more data is available
|
||||
}
|
||||
if msg.mode == logDump {
|
||||
close(l.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -245,6 +220,23 @@ func readLogFromFd(maxLineLen int, fd int, source string, logCh chan logEntry) {
|
||||
}
|
||||
}
|
||||
|
||||
func loggingRequestHandler(lineMaxLength int, logCh chan logEntry, fdMsgChan chan fdMessage) {
|
||||
for true {
|
||||
select {
|
||||
case msg := <-fdMsgChan: // incoming fd
|
||||
if strings.Contains(msg.name, ";") {
|
||||
// The log message spec bans ";" in the log names
|
||||
doLog(logCh, fmt.Sprintf("ERROR: cannot register log with name '%s' as it contains ;", msg.name))
|
||||
if err := syscall.Close(msg.fd); err != nil {
|
||||
doLog(logCh, fmt.Sprintf("ERROR: failed to close fd: %s", err))
|
||||
}
|
||||
continue
|
||||
}
|
||||
go readLogFromFd(lineMaxLength, msg.fd, msg.name, logCh)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
@ -254,19 +246,23 @@ func main() {
|
||||
var passedLogFD int
|
||||
var linesInBuffer int
|
||||
var lineMaxLength int
|
||||
var daemonize bool
|
||||
|
||||
flag.StringVar(&socketQueryPath, "socket-query", "/tmp/memlogdq.sock", "unix domain socket for responding to log queries. Overridden by -fd-query")
|
||||
flag.StringVar(&socketLogPath, "socket-log", "/tmp/memlogd.sock", "unix domain socket to listen for new fds to add to log. Overridden by -fd-log")
|
||||
flag.StringVar(&socketQueryPath, "socket-query", "/var/run/memlogdq.sock", "unix domain socket for responding to log queries. Overridden by -fd-query")
|
||||
flag.StringVar(&socketLogPath, "socket-log", "/var/run/linuxkit-external-logging.sock", "unix domain socket to listen for new fds to add to log. Overridden by -fd-log")
|
||||
flag.IntVar(&passedLogFD, "fd-log", -1, "an existing SOCK_DGRAM socket for receiving fd's. Overrides -socket-log.")
|
||||
flag.IntVar(&passedQueryFD, "fd-query", -1, "an existing SOCK_STREAM for receiving log read requets. Overrides -socket-query.")
|
||||
flag.IntVar(&linesInBuffer, "max-lines", 5000, "Number of log lines to keep in memory")
|
||||
flag.IntVar(&lineMaxLength, "max-line-len", 1024, "Maximum line length recorded. Additional bytes are dropped.")
|
||||
|
||||
flag.BoolVar(&daemonize, "daemonize", false, "Bind sockets and then daemonize.")
|
||||
flag.Parse()
|
||||
|
||||
var connLogFd *net.UnixConn
|
||||
if passedLogFD == -1 { // no fd on command line, use socket path
|
||||
addr := net.UnixAddr{socketLogPath, "unixgram"}
|
||||
addr := net.UnixAddr{
|
||||
Name: socketLogPath,
|
||||
Net: "unixgram",
|
||||
}
|
||||
if connLogFd, err = net.ListenUnixgram("unixgram", &addr); err != nil {
|
||||
log.Fatal("Unable to open socket: ", err)
|
||||
}
|
||||
@ -282,7 +278,10 @@ func main() {
|
||||
|
||||
var connQuery *net.UnixListener
|
||||
if passedQueryFD == -1 { // no fd on command line, use socket path
|
||||
addr := net.UnixAddr{socketQueryPath, "unix"}
|
||||
addr := net.UnixAddr{
|
||||
Name: socketQueryPath,
|
||||
Net: "unix",
|
||||
}
|
||||
if connQuery, err = net.ListenUnix("unix", &addr); err != nil {
|
||||
log.Fatal("Unable to open socket: ", err)
|
||||
}
|
||||
@ -296,20 +295,40 @@ func main() {
|
||||
}
|
||||
defer connQuery.Close()
|
||||
|
||||
if daemonize {
|
||||
child := exec.Command(os.Args[0],
|
||||
"-fd-log", "3", // connLogFd in ExtraFiles below
|
||||
"-fd-query", "4", // connQuery in ExtraFiles below
|
||||
"-max-lines", fmt.Sprintf("%d", linesInBuffer),
|
||||
"-max-line-len", fmt.Sprintf("%d", lineMaxLength),
|
||||
)
|
||||
connLogFile, err := connLogFd.File()
|
||||
if err != nil {
|
||||
log.Fatalf("The -fd-log cannot be represented as a *File: %s", err)
|
||||
}
|
||||
connQueryFile, err := connQuery.File()
|
||||
if err != nil {
|
||||
log.Fatalf("The -fd-query cannot be represented as a *File: %s", err)
|
||||
}
|
||||
child.ExtraFiles = append(child.ExtraFiles, connLogFile, connQueryFile)
|
||||
if err := child.Start(); err != nil {
|
||||
log.Fatalf("Failed to re-exec: %s", err)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
logCh := make(chan logEntry)
|
||||
fdMsgChan := make(chan fdMessage)
|
||||
queryMsgChan := make(chan queryMessage)
|
||||
|
||||
// receive fds from the logging Unix domain socket and send on fdMsgChan
|
||||
go receiveFdHandler(connLogFd, logCh, fdMsgChan)
|
||||
// receive fds from the querying Unix domain socket and send on queryMsgChan
|
||||
go receiveQueryHandler(connQuery, logCh, queryMsgChan)
|
||||
go ringBufferHandler(linesInBuffer, logCh, queryMsgChan)
|
||||
// process both log messages and queries
|
||||
go ringBufferHandler(linesInBuffer, linesInBuffer, logCh, queryMsgChan)
|
||||
|
||||
doLog(logCh, "memlogd started")
|
||||
|
||||
for true {
|
||||
select {
|
||||
case msg := <-fdMsgChan: // incoming fd
|
||||
go readLogFromFd(lineMaxLength, msg.fd, msg.name, logCh)
|
||||
}
|
||||
}
|
||||
loggingRequestHandler(lineMaxLength, logCh, fdMsgChan)
|
||||
}
|
198
pkg/memlogd/cmd/memlogd/main_test.go
Normal file
198
pkg/memlogd/cmd/memlogd/main_test.go
Normal file
@ -0,0 +1,198 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNonblock(t *testing.T) {
|
||||
// Test that writes to the logger don't block because it is full
|
||||
linesInBuffer := 10
|
||||
|
||||
logCh := make(chan logEntry)
|
||||
queryMsgChan := make(chan queryMessage)
|
||||
|
||||
go ringBufferHandler(linesInBuffer, linesInBuffer, logCh, queryMsgChan)
|
||||
|
||||
// Overflow the log to make sure it doesn't block
|
||||
for i := 0; i < 2*linesInBuffer; i++ {
|
||||
select {
|
||||
case logCh <- logEntry{time: time.Now(), source: "memlogd", msg: "hello TestNonblock"}:
|
||||
continue
|
||||
case <-time.After(time.Second):
|
||||
t.Errorf("write to the logger blocked for over 1s after %d (size was set to %d)", i, linesInBuffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFinite(t *testing.T) {
|
||||
// Test that the logger doesn't store more than its configured maximum size
|
||||
linesInBuffer := 10
|
||||
|
||||
logCh := make(chan logEntry)
|
||||
queryMsgChan := make(chan queryMessage)
|
||||
|
||||
go ringBufferHandler(linesInBuffer, linesInBuffer, logCh, queryMsgChan)
|
||||
|
||||
// Overflow the log by 2x
|
||||
for i := 0; i < 2*linesInBuffer; i++ {
|
||||
logCh <- logEntry{time: time.Now(), source: "memlogd", msg: "hello TestFinite"}
|
||||
}
|
||||
a, b := loopback()
|
||||
defer a.Close()
|
||||
defer b.Close()
|
||||
queryM := queryMessage{
|
||||
conn: a,
|
||||
mode: logDump,
|
||||
}
|
||||
queryMsgChan <- queryM
|
||||
r := bufio.NewReader(b)
|
||||
count := 0
|
||||
for {
|
||||
_, err := r.ReadString('\n')
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("Unexpected error reading from socket: %s", err)
|
||||
}
|
||||
count++
|
||||
}
|
||||
if linesInBuffer != count {
|
||||
t.Errorf("Read %d lines but expected %d", count, linesInBuffer)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFinite2(t *testing.T) {
|
||||
// Test that the query connection doesn't store more than the configured
|
||||
// maximum size.
|
||||
linesInBuffer := 10
|
||||
// the output buffer size will be 1/2 of the ring
|
||||
outputBufferSize := linesInBuffer / 2
|
||||
logCh := make(chan logEntry)
|
||||
queryMsgChan := make(chan queryMessage)
|
||||
|
||||
go ringBufferHandler(linesInBuffer, outputBufferSize, logCh, queryMsgChan)
|
||||
|
||||
// fill the ring
|
||||
for i := 0; i < linesInBuffer; i++ {
|
||||
logCh <- logEntry{time: time.Now(), source: "memlogd", msg: "hello TestFinite2"}
|
||||
}
|
||||
|
||||
a, b := loopback()
|
||||
defer a.Close()
|
||||
defer b.Close()
|
||||
queryM := queryMessage{
|
||||
conn: a,
|
||||
mode: logDump,
|
||||
}
|
||||
queryMsgChan <- queryM
|
||||
// since the ring won't fit in the output buffer some should be dropped
|
||||
|
||||
r := bufio.NewReader(b)
|
||||
count := 0
|
||||
for {
|
||||
_, err := r.ReadString('\n')
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("Unexpected error reading from socket: %s", err)
|
||||
}
|
||||
count++
|
||||
}
|
||||
if count != outputBufferSize {
|
||||
t.Errorf("Read %d lines but expected %d", count, outputBufferSize)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoodName(t *testing.T) {
|
||||
// Test that the source names can't contain ";"
|
||||
linesInBuffer := 10
|
||||
logCh := make(chan logEntry)
|
||||
fdMsgChan := make(chan fdMessage)
|
||||
queryMsgChan := make(chan queryMessage)
|
||||
|
||||
go ringBufferHandler(linesInBuffer, linesInBuffer, logCh, queryMsgChan)
|
||||
go loggingRequestHandler(80, logCh, fdMsgChan)
|
||||
|
||||
fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
|
||||
if err != nil {
|
||||
log.Fatal("Unable to create socketpair: ", err)
|
||||
}
|
||||
a := fdToConn(fds[0])
|
||||
b := fdToConn(fds[1])
|
||||
defer a.Close()
|
||||
defer b.Close()
|
||||
// defer close fds
|
||||
|
||||
fdMsgChan <- fdMessage{
|
||||
name: "semi-colons are banned;",
|
||||
fd: fds[0],
|
||||
}
|
||||
// although the fd should be rejected my memlogd the Write should be buffered
|
||||
// by the kernel and not block.
|
||||
if _, err := b.Write([]byte("hello\n")); err != nil {
|
||||
log.Fatalf("Failed to write log message: %s", err)
|
||||
}
|
||||
c, d := loopback()
|
||||
defer c.Close()
|
||||
defer d.Close()
|
||||
// this log should not be in the ring because the connection was rejected.
|
||||
queryM := queryMessage{
|
||||
conn: c,
|
||||
mode: logDumpFollow,
|
||||
}
|
||||
queryMsgChan <- queryM
|
||||
// The error log is generated asynchronously. It should be fast. On error time out
|
||||
// after 5s.
|
||||
d.SetDeadline(time.Now().Add(5 * time.Second))
|
||||
r := bufio.NewReader(d)
|
||||
for {
|
||||
line, err := r.ReadString('\n')
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("Unexpected error reading from socket: %s", err)
|
||||
}
|
||||
if strings.Contains(line, "ERROR: cannot register log") {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatal("Failed to read error message when registering a log with a ;")
|
||||
}
|
||||
|
||||
// caller must close fd themselves: closing the net.Conn will not close fd.
|
||||
func fdToConn(fd int) net.Conn {
|
||||
f := os.NewFile(uintptr(fd), "")
|
||||
c, err := net.FileConn(f)
|
||||
if err != nil {
|
||||
log.Fatal("Unable to create net.Conn from file descriptor: ", err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func loopback() (net.Conn, net.Conn) {
|
||||
fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
|
||||
if err != nil {
|
||||
log.Fatal("Unable to create socketpair: ", err)
|
||||
}
|
||||
a := fdToConn(fds[0])
|
||||
b := fdToConn(fds[1])
|
||||
// net.Conns are independent of the fds, so we must close the fds now.
|
||||
if err := syscall.Close(fds[0]); err != nil {
|
||||
log.Fatal("Unable to close socketpair fd: ", err)
|
||||
}
|
||||
if err := syscall.Close(fds[1]); err != nil {
|
||||
log.Fatal("Unable to close socketpair fd: ", err)
|
||||
}
|
||||
return a, b
|
||||
}
|
@ -16,8 +16,8 @@ func main() {
|
||||
var memlogdBundle string
|
||||
var pidFile string
|
||||
var detach bool
|
||||
flag.StringVar(&socketLogPath, "socket-log", "/tmp/memlogd.sock", "path to fd logging socket. Created and passed to logging container. Existing socket will be removed.")
|
||||
flag.StringVar(&socketQueryPath, "socket-query", "/tmp/memlogdq.sock", "path to query socket. Created and passed to logging container. Existing socket will be removed.")
|
||||
flag.StringVar(&socketLogPath, "socket-log", "/var/run/linuxkit-external-logging.sock", "path to fd logging socket. Created and passed to logging container. Existing socket will be removed.")
|
||||
flag.StringVar(&socketQueryPath, "socket-query", "/var/run/memlogdq.sock", "path to query socket. Created and passed to logging container. Existing socket will be removed.")
|
||||
flag.StringVar(&memlogdBundle, "bundle", "/containers/init/memlogd", "runc bundle with memlogd")
|
||||
flag.StringVar(&pidFile, "pid-file", "/run/memlogd.pid", "path to pid file")
|
||||
flag.BoolVar(&detach, "detach", true, "detach from subprocess")
|
3
pkg/memlogd/etc/init.d/002-logging
Executable file
3
pkg/memlogd/etc/init.d/002-logging
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
/usr/bin/memlogd -daemonize
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel-clear-containers:4.9.x
|
||||
cmdline: "root=/dev/pmem0p1 rootflags=dax,data=ordered,errors=remount-ro rw rootfstype=ext4 tsc=reliable no_timer_check rcupdate.rcu_expedited=1 i8042.direct=1 i8042.dumbkbd=1 i8042.nopnp=1 i8042.noaux=1 noreplace-smp reboot=k panic=1 console=hvc0 console=hvc1 initcall_debug iommu=off quiet cryptomgr.notests page_poison=on"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
onboot:
|
||||
- name: sysctl
|
||||
image: mobylinux/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel-ima:4.11.1-186dd3605ee7b23214850142f8f02b4679dbd148
|
||||
cmdline: "console=ttyS0 console=tty0 page_poison=1 ima_appraise=enforce_ns"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: mobylinux/kernel-landlock:4.9.x
|
||||
cmdline: "console=ttyS0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- mobylinux/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9
|
||||
- mobylinux/containerd:18eaf72f3f4f9a9f29ca1951f66df701f873060b
|
||||
- mobylinux/ca-certificates:eabc5a6e59f05aa91529d80e9a595b85b046f935
|
||||
|
@ -1,54 +0,0 @@
|
||||
### Logging tools
|
||||
|
||||
Experimental logging tools for linuxkit.
|
||||
|
||||
This project currently provides three tools for system logs; `logwrite`, `logread` and `memlogd` (+ `startmemlogd` to run `memlogd` with `runc`).
|
||||
|
||||
`memlogd` is the daemon that keeps logs in a circular buffer in memory. It is started automatically by `init`/`startmemlogd` in a runc container. It is passed two sockets - one that allows clients to dump/follow the logs and one that can be used to send open file descriptors to `memlogd`. When `memlogd` receives a file descriptor it will read from the file descriptor and timestamp and append the content to the in-memory log until the file is closed.
|
||||
|
||||
`logwrite` executes a command and will send stderr and stdout to `memlogd`. It does this by opening a socketpair for stdout and stderr and then sends the file descriptors to memlogd, before executing a specified command. Output is also sent to normal stderr/stdin. For example, `logwrite ls` will show the output both in the console and record it in the logs.
|
||||
|
||||
`logread` connects to memlogd and dumps the ring buffer. Parameters `-f` and `-F` can be used to follow the logs and disable the initial log dump (it behaves similar to busybox’ `logread`)
|
||||
|
||||
Init is modified to run all `onboot` and `service` containers wrapped in`logwrite` and to run `/usr/bin/startmemlogd`.
|
||||
|
||||
New sockets:
|
||||
`/tmp/memlogd.sock` — sock_dgram which accepts an fd and a null-terminated source description
|
||||
`/tmp/memlogdq.sock` — sock_stream to ask to dump/follow logs
|
||||
|
||||
Usage examples:
|
||||
```
|
||||
/ # logread -f
|
||||
2017-04-15T15:37:37Z memlogd memlogd started
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: waiting for carrier
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: carrier acquired
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout DUID 00:01:00:01:20:84:fa:c1:02:50:00:00:00:24
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: IAID 00:00:00:24
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: adding address fe80::84e3:ca52:2590:fe80
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: soliciting an IPv6 router
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: soliciting a DHCP lease
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: offered 192.168.65.37 from 192.168.65.1 `vpnkit'
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: leased 192.168.65.37 for 7199 seconds
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: adding route to 192.168.65.0/24
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout eth0: adding default route via 192.168.65.1
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout exiting due to oneshot
|
||||
2017-04-15T15:37:37Z 002-dhcpcd.stdout dhcpcd exited
|
||||
2017-04-15T15:37:37Z rngd.stderr Unable to open file: /dev/tpm0
|
||||
^C
|
||||
/ # logwrite echo testing123
|
||||
testing123
|
||||
/ # logread | tail -n1
|
||||
2017-04-15T15:37:45Z echo.stdout testing123
|
||||
/ # echo -en "GET / HTTP/1.0\n\n" | nc localhost 80 > /dev/null
|
||||
/ # logread | grep nginx
|
||||
2017-04-15T15:42:40Z nginx.stdout 127.0.0.1 - - [15/Apr/2017:15:42:40 +0000] "GET / HTTP/1.0" 200 612 "-" "-" "-"
|
||||
```
|
||||
|
||||
Current issues and limitations:
|
||||
|
||||
- The moby tool only supports onboot and service containers. `memlogd` runs as a special container that is managed by init, as it needs fd’s created in advance. To work around this a memlogd container is exported during build. The init-section in the yml is used to extract it to `/containers/init/memlogd` with a pre-created `config.json`.
|
||||
- No docker logger plugin support yet - it could be nice to add support to memlogd, so the docker container logs would also be gathered in one place
|
||||
- No syslog compatibility at the moment and `/dev/log` doesn’t exist. This socket could be created to keep syslog compatibility, e.g. by using https://github.com/mcuadros/go-syslog. Processes that require syslog should then be able to log directly to memlogd.
|
||||
- Kernel messages not read on startup yet (but can be captured with `logwrite dmesg`)
|
||||
- Currently no direct external hooks exposed - but options available that could be added. Should also be possible to pipe output to e.g. `oklog` from `logread` (https://github.com/oklog/oklog)
|
||||
|
@ -1,33 +0,0 @@
|
||||
kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=tty0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
- linuxkit/memlogd:9b5834189f598f43c507f6938077113906f51012
|
||||
onboot:
|
||||
- name: sysctl
|
||||
image: linuxkit/sysctl:v0.4
|
||||
- name: dhcpcd
|
||||
image: linuxkit/dhcpcd:1fe0db6b1eb7bcb1e4823e61e08afe6d48af7d16
|
||||
command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
|
||||
services:
|
||||
- name: rngd
|
||||
image: linuxkit/rngd:v0.4
|
||||
- name: nginx
|
||||
image: nginx:1.13.8-alpine
|
||||
capabilities:
|
||||
- CAP_NET_BIND_SERVICE
|
||||
- CAP_CHOWN
|
||||
- CAP_SETUID
|
||||
- CAP_SETGID
|
||||
- CAP_DAC_OVERRIDE
|
||||
files:
|
||||
- path: etc/docker/daemon.json
|
||||
contents: '{"debug": true}'
|
||||
trust:
|
||||
org:
|
||||
- linuxkit
|
||||
- library
|
2
projects/logging/pkg/init/.gitignore
vendored
2
projects/logging/pkg/init/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
sbin/
|
||||
usr/
|
@ -1,6 +0,0 @@
|
||||
# Use sha256 here to get a fixed version
|
||||
FROM alpine:edge@sha256:99588bc8883c955c157d18fc3eaa4a3c1400c223e6c7cabca5f600a3e9f8d5cd
|
||||
ENTRYPOINT []
|
||||
CMD []
|
||||
WORKDIR /
|
||||
COPY . ./
|
@ -1,14 +0,0 @@
|
||||
.PHONY: tag push
|
||||
default: push
|
||||
|
||||
IMAGE=init
|
||||
DEPS=Dockerfile init $(wildcard etc/*) $(wildcard etc/init.d/*)
|
||||
|
||||
HASH?=$(shell git ls-tree HEAD -- ../$(notdir $(CURDIR)) | awk '{print $$3}')
|
||||
|
||||
tag: $(DEPS)
|
||||
docker build --no-cache --network=none -t linuxkit/$(IMAGE):$(HASH) .
|
||||
|
||||
push: tag
|
||||
docker pull linuxkit/$(IMAGE):$(HASH) || \
|
||||
docker push linuxkit/$(IMAGE):$(HASH)
|
@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# bring up containerd
|
||||
ulimit -n 1048576
|
||||
ulimit -p unlimited
|
||||
|
||||
printf "\nStarting containerd\n"
|
||||
mkdir -p /var/log
|
||||
exec /usr/bin/containerd
|
@ -1,36 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# start memlogd container
|
||||
|
||||
/usr/bin/startmemlogd
|
||||
|
||||
# start onboot containers, run to completion
|
||||
|
||||
if [ -d /containers/onboot ]
|
||||
then
|
||||
for f in $(find /containers/onboot -mindepth 1 -maxdepth 1 | sort)
|
||||
do
|
||||
base="$(basename $f)"
|
||||
/bin/mount --bind "$f/rootfs" "$f/rootfs"
|
||||
mount -o remount,rw "$f/rootfs"
|
||||
/usr/bin/logwrite -n "$(basename $f)" /usr/bin/runc run --bundle "$f" "$(basename $f)"
|
||||
printf " - $base\n"
|
||||
done
|
||||
fi
|
||||
|
||||
# start service containers
|
||||
|
||||
if [ -d /containers/services ]
|
||||
then
|
||||
for f in $(find /containers/services -mindepth 1 -maxdepth 1 | sort)
|
||||
do
|
||||
base="$(basename $f)"
|
||||
/bin/mount --bind "$f/rootfs" "$f/rootfs"
|
||||
mount -o remount,rw "$f/rootfs"
|
||||
log="/var/log/$base.log"
|
||||
/usr/bin/logwrite -n "$(basename $f)" ctr run --runtime-config "$f/config.json" --rootfs "$f/rootfs" --id "$(basename $f)" </dev/null 2>$log >$log &
|
||||
printf " - $base\n"
|
||||
done
|
||||
fi
|
||||
|
||||
wait
|
@ -1,112 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# mount filesystems
|
||||
mount -n -t proc proc /proc -o nodev,nosuid,noexec,relatime
|
||||
|
||||
mount -n -t tmpfs tmpfs /run -o nodev,nosuid,noexec,relatime,size=10%,mode=755
|
||||
mount -n -t tmpfs tmpfs /tmp -o nodev,nosuid,noexec,relatime,size=10%,mode=1777
|
||||
|
||||
# mount devfs
|
||||
mount -n -t devtmpfs dev /dev -o nosuid,noexec,relatime,size=10m,nr_inodes=248418,mode=755
|
||||
# devices
|
||||
[ -c /dev/console ] || mknod -m 600 /dev/console c 5 1
|
||||
[ -c /dev/tty1 ] || mknod -m 620 /dev/tty1 c 4 1
|
||||
[ -c /dev/tty ] || mknod -m 666 /dev/tty c 5 0
|
||||
|
||||
[ -c /dev/null ] || mknod -m 666 /dev/null c 1 3
|
||||
[ -c /dev/kmsg ] || mknod -m 660 /dev/kmsg c 1 11
|
||||
|
||||
# extra symbolic links not provided by default
|
||||
[ -e /dev/fd ] || ln -snf /proc/self/fd /dev/fd
|
||||
[ -e /dev/stdin ] || ln -snf /proc/self/fd/0 /dev/stdin
|
||||
[ -e /dev/stdout ] || ln -snf /proc/self/fd/1 /dev/stdout
|
||||
[ -e /dev/stderr ] || ln -snf /proc/self/fd/2 /dev/stderr
|
||||
[ -e /proc/kcore ] && ln -snf /proc/kcore /dev/core
|
||||
|
||||
# devfs filesystems
|
||||
mkdir -p -m 1777 /dev/mqueue
|
||||
mkdir -p -m 1777 /dev/shm
|
||||
mkdir -p -m 0755 /dev/pts
|
||||
mount -n -t mqueue -o noexec,nosuid,nodev mqueue /dev/mqueue
|
||||
mount -n -t tmpfs -o noexec,nosuid,nodev,mode=1777 shm /dev/shm
|
||||
mount -n -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts
|
||||
|
||||
# mount sysfs
|
||||
sysfs_opts=nodev,noexec,nosuid
|
||||
mount -n -t sysfs -o ${sysfs_opts} sysfs /sys
|
||||
[ -d /sys/kernel/security ] && mount -n -t securityfs -o ${sysfs_opts} securityfs /sys/kernel/security
|
||||
[ -d /sys/kernel/debug ] && mount -n -t debugfs -o ${sysfs_opts} debugfs /sys/kernel/debug
|
||||
[ -d /sys/kernel/config ] && mount -n -t configfs -o ${sysfs_opts} configfs /sys/kernel/config
|
||||
[ -d /sys/fs/fuse/connections ] && mount -n -t fusectl -o ${sysfs_opts} fusectl /sys/fs/fuse/connections
|
||||
[ -d /sys/fs/selinux ] && mount -n -t selinuxfs -o nosuid,noexec selinuxfs /sys/fs/selinux
|
||||
[ -d /sys/fs/pstore ] && mount -n -t pstore pstore -o ${sysfs_opts} /sys/fs/pstore
|
||||
[ -d /sys/firmware/efi/efivars ] && mount -n -t efivarfs -o ro,${sysfs_opts} efivarfs /sys/firmware/efi/efivars
|
||||
|
||||
# misc /proc mounted fs
|
||||
[ -d /proc/sys/fs/binfmt_misc ] && mount -t binfmt_misc -o nodev,noexec,nosuid binfmt_misc /proc/sys/fs/binfmt_misc
|
||||
|
||||
# mount cgroups
|
||||
mount -n -t tmpfs -o nodev,noexec,nosuid,mode=755,size=10m cgroup_root /sys/fs/cgroup
|
||||
|
||||
while read name hier groups enabled rest
|
||||
do
|
||||
case "${enabled}" in
|
||||
1) mkdir -p /sys/fs/cgroup/${name}
|
||||
mount -n -t cgroup -o ${sysfs_opts},${name} ${name} /sys/fs/cgroup/${name}
|
||||
;;
|
||||
esac
|
||||
done < /proc/cgroups
|
||||
|
||||
# use hierarchy for memory
|
||||
echo 1 > /sys/fs/cgroup/memory/memory.use_hierarchy
|
||||
|
||||
# for compatibility
|
||||
mkdir -p /sys/fs/cgroup/systemd
|
||||
mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
|
||||
|
||||
# start mdev for hotplug
|
||||
echo "/sbin/mdev" > /proc/sys/kernel/hotplug
|
||||
|
||||
# mdev -s will not create /dev/usb[1-9] devices with recent kernels
|
||||
# so we trigger hotplug events for usb for now
|
||||
for i in $(find /sys/devices -name 'usb[0-9]*'); do
|
||||
[ -e $i/uevent ] && echo add > $i/uevent
|
||||
done
|
||||
|
||||
mdev -s
|
||||
|
||||
# set hostname
|
||||
if [ -s /etc/hostname ]
|
||||
then
|
||||
hostname -F /etc/hostname
|
||||
fi
|
||||
|
||||
if [ $(hostname) = "(none)" -a -f /sys/class/net/eth0/address ]
|
||||
then
|
||||
mac=$(cat /sys/class/net/eth0/address)
|
||||
hostname linuxkit-$(echo $mac | sed 's/://g')
|
||||
fi
|
||||
|
||||
# set system clock from hwclock
|
||||
hwclock --hctosys --utc
|
||||
|
||||
# bring up loopback interface
|
||||
ip addr add 127.0.0.1/8 dev lo brd + scope host
|
||||
ip route add 127.0.0.0/8 dev lo scope host
|
||||
ip link set lo up
|
||||
|
||||
# for containerising dhcpcd and other containers that need writable etc
|
||||
mkdir /tmp/etc
|
||||
mv /etc/resolv.conf /tmp/etc/resolv.conf
|
||||
ln -snf /tmp/etc/resolv.conf /etc/resolv.conf
|
||||
|
||||
# remount rootfs as readonly
|
||||
mount -o remount,ro /
|
||||
|
||||
# make /var writeable and shared
|
||||
mount -o bind /var /var
|
||||
mount -o remount,rw,nodev,nosuid,noexec,relatime /var /var
|
||||
mount --make-rshared /var
|
||||
|
||||
# make / rshared
|
||||
mount --make-rshared /
|
@ -1,15 +0,0 @@
|
||||
# /etc/inittab
|
||||
|
||||
::sysinit:/etc/init.d/rcS
|
||||
::once:/etc/init.d/containerd
|
||||
::once:/etc/init.d/containers
|
||||
|
||||
# Stuff to do for the 3-finger salute
|
||||
::ctrlaltdel:/sbin/reboot
|
||||
|
||||
# Stuff to do before rebooting
|
||||
::shutdown:/usr/sbin/killall5 -15
|
||||
::shutdown:/bin/sleep 5
|
||||
::shutdown:/usr/sbin/killall5 -9
|
||||
::shutdown:/bin/echo "Unmounting filesystems"
|
||||
::shutdown:/bin/umount -a -r
|
@ -1,12 +0,0 @@
|
||||
|
||||
Welcome to LinuxKit
|
||||
|
||||
## .
|
||||
## ## ## ==
|
||||
## ## ## ## ## ===
|
||||
/"""""""""""""""""\___/ ===
|
||||
{ / ===-
|
||||
\______ O __/
|
||||
\ \ __/
|
||||
\____\_______/
|
||||
|
@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
setup_console() {
|
||||
tty=${1%,*}
|
||||
speed=${1#*,}
|
||||
inittab="$2"
|
||||
securetty="$3"
|
||||
line=
|
||||
term="linux"
|
||||
[ "$speed" = "$1" ] && speed=115200
|
||||
|
||||
case "$tty" in
|
||||
ttyS*|ttyAMA*|ttyUSB*|ttyMFD*)
|
||||
line="-L"
|
||||
term="vt100"
|
||||
;;
|
||||
tty?)
|
||||
line=""
|
||||
speed="38400"
|
||||
term=""
|
||||
;;
|
||||
esac
|
||||
# skip consoles already in inittab
|
||||
grep -q "^$tty:" "$inittab" && return
|
||||
|
||||
echo "$tty::once:cat /etc/issue" >> "$inittab"
|
||||
echo "$tty::respawn:/sbin/getty -n -l /bin/sh $line $speed $tty $term" >> "$inittab"
|
||||
if ! grep -q -w "$tty" "$securetty"; then
|
||||
echo "$tty" >> "$securetty"
|
||||
fi
|
||||
}
|
||||
|
||||
/bin/mount -t tmpfs tmpfs /mnt
|
||||
|
||||
/bin/cp -a / /mnt 2>/dev/null
|
||||
|
||||
/bin/mount -t proc -o noexec,nosuid,nodev proc /proc
|
||||
for opt in $(cat /proc/cmdline); do
|
||||
case "$opt" in
|
||||
console=*)
|
||||
setup_console ${opt#console=} /mnt/etc/inittab /mnt/etc/securetty;;
|
||||
esac
|
||||
done
|
||||
|
||||
exec /bin/busybox switch_root /mnt /sbin/init
|
5
projects/logging/pkg/memlogd/.gitignore
vendored
5
projects/logging/pkg/memlogd/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
usr
|
||||
hash
|
||||
containers
|
||||
.*
|
||||
sbin
|
@ -1,3 +0,0 @@
|
||||
FROM scratch
|
||||
COPY . ./
|
||||
WORKDIR /
|
@ -1,3 +0,0 @@
|
||||
FROM scratch
|
||||
COPY . ./
|
||||
CMD ["/usr/bin/memlogd","-fd","3"]
|
@ -1,66 +0,0 @@
|
||||
GO_COMPILE=mobylinux/go-compile:3afebc59c5cde31024493c3f91e6102d584a30b9@sha256:e0786141ea7df8ba5735b63f2a24b4ade9eae5a02b0e04c4fca33b425ec69b0a
|
||||
|
||||
SHA_IMAGE=alpine:3.5@sha256:dfbd4a3a8ebca874ebd2474f044a0b33600d4523d03b0df76e5c5986cb02d7e8
|
||||
|
||||
MEMLOGD_BINARY=usr/bin/memlogd
|
||||
LOGWRITE_BINARY=usr/bin/logwrite
|
||||
STARTMEMLOGD_BINARY=usr/bin/startmemlogd
|
||||
LOGREAD_BINARY=sbin/logread
|
||||
|
||||
IMAGE=memlogd
|
||||
|
||||
.PHONY: tag push clean container
|
||||
default: tag
|
||||
|
||||
DEPS=$(MEMLOGD_BINARY) $(LOGWRITE_BINARY) $(STARTMEMLOGD_BINARY) $(LOGREAD_BINARY)
|
||||
|
||||
$(MEMLOGD_BINARY): cmd/memlogd/main.go
|
||||
mkdir -p $(dir $@)
|
||||
tar -Ccmd/memlogd -cf - main.go | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf -
|
||||
|
||||
$(LOGWRITE_BINARY): cmd/logwrite/main.go
|
||||
mkdir -p $(dir $@)
|
||||
tar -Ccmd/logwrite -cf - main.go | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf -
|
||||
|
||||
$(STARTMEMLOGD_BINARY): cmd/startmemlogd/main.go
|
||||
mkdir -p $(dir $@)
|
||||
tar -Ccmd/startmemlogd -cf - main.go | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf -
|
||||
|
||||
$(LOGREAD_BINARY): cmd/logread/main.go
|
||||
mkdir -p $(dir $@)
|
||||
tar -Ccmd/logread -cf - main.go | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf -
|
||||
|
||||
containers: $(MEMLOGD_BINARY) Dockerfile.memlogd config.json
|
||||
mkdir -p containers/init/memlogd/rootfs
|
||||
tar -cf - $^ | docker build -f Dockerfile.memlogd -t $(IMAGE):build1 --no-cache -
|
||||
docker create --name $(IMAGE)-build1 $(IMAGE):build1
|
||||
docker export $(IMAGE)-build1 | tar -Ccontainers/init/memlogd/rootfs -xv -
|
||||
docker rm $(IMAGE)-build1
|
||||
docker rmi $(IMAGE):build1
|
||||
mv containers/init/memlogd/rootfs/Dockerfile.memlogd containers/init/memlogd/rootfs/Dockerfile
|
||||
mv containers/init/memlogd/rootfs/config.json containers/init/memlogd
|
||||
|
||||
container: Dockerfile $(LOGWRITE_BINARY) $(STARTMEMLOGD_BINARY) $(LOGREAD_BINARY) containers
|
||||
tar cf - $^ | docker build --no-cache -t $(IMAGE):build -
|
||||
|
||||
hash: Dockerfile Dockerfile.memlogd $(DEPS)
|
||||
find $^ -type f | xargs cat | docker run --rm -i $(SHA_IMAGE) sha1sum - | sed 's/ .*//' > hash
|
||||
|
||||
push: hash container
|
||||
docker pull linuxkit/$(IMAGE):$(shell cat hash) || \
|
||||
(docker tag $(IMAGE):build linuxkit/$(IMAGE):$(shell cat hash) && \
|
||||
docker push linuxkit/$(IMAGE):$(shell cat hash))
|
||||
docker rmi $(IMAGE):build
|
||||
rm -f hash
|
||||
|
||||
tag: hash container
|
||||
docker pull linuxkit/$(IMAGE):$(shell cat hash) || \
|
||||
docker tag $(IMAGE):build linuxkit/$(IMAGE):$(shell cat hash)
|
||||
docker rmi $(IMAGE):build
|
||||
rm -f hash
|
||||
|
||||
clean:
|
||||
rm -rf hash usr containers sbin
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
@ -1,115 +0,0 @@
|
||||
{
|
||||
"ociVersion": "1.0.0-rc5-dev",
|
||||
"platform": {
|
||||
"os": "linux",
|
||||
"arch": "amd64"
|
||||
},
|
||||
"process": {
|
||||
"consoleSize": {
|
||||
"height": 0,
|
||||
"width": 0
|
||||
},
|
||||
"user": {
|
||||
"uid": 0,
|
||||
"gid": 0
|
||||
},
|
||||
"args": [
|
||||
"/usr/bin/memlogd",
|
||||
"-fd-log",
|
||||
"3",
|
||||
"-fd-query",
|
||||
"4"
|
||||
],
|
||||
"env": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
],
|
||||
"cwd": "/",
|
||||
"capabilities": {}
|
||||
},
|
||||
"root": {
|
||||
"path": "rootfs",
|
||||
"readonly": true
|
||||
},
|
||||
"mounts": [
|
||||
{
|
||||
"destination": "/proc",
|
||||
"type": "proc",
|
||||
"source": "proc",
|
||||
"options": [
|
||||
"nosuid",
|
||||
"nodev",
|
||||
"noexec",
|
||||
"relatime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"destination": "/dev",
|
||||
"type": "tmpfs",
|
||||
"source": "tmpfs",
|
||||
"options": [
|
||||
"nosuid",
|
||||
"strictatime",
|
||||
"mode=755",
|
||||
"size=65536k",
|
||||
"ro"
|
||||
]
|
||||
},
|
||||
{
|
||||
"destination": "/sys",
|
||||
"type": "sysfs",
|
||||
"source": "sysfs",
|
||||
"options": [
|
||||
"nosuid",
|
||||
"noexec",
|
||||
"nodev",
|
||||
"ro"
|
||||
]
|
||||
},
|
||||
{
|
||||
"destination": "/dev/pts",
|
||||
"type": "devpts",
|
||||
"source": "devpts",
|
||||
"options": [
|
||||
"nosuid",
|
||||
"noexec",
|
||||
"newinstance",
|
||||
"ptmxmode=0666",
|
||||
"mode=0620"
|
||||
]
|
||||
},
|
||||
{
|
||||
"destination": "/sys/fs/cgroup",
|
||||
"type": "cgroup",
|
||||
"source": "cgroup",
|
||||
"options": [
|
||||
"nosuid",
|
||||
"noexec",
|
||||
"nodev",
|
||||
"relatime",
|
||||
"ro"
|
||||
]
|
||||
}
|
||||
],
|
||||
"linux": {
|
||||
"resources": {
|
||||
"disableOOMKiller": false
|
||||
},
|
||||
"namespaces": [
|
||||
{
|
||||
"type": "network"
|
||||
},
|
||||
{
|
||||
"type": "pid"
|
||||
},
|
||||
{
|
||||
"type": "ipc"
|
||||
},
|
||||
{
|
||||
"type": "uts"
|
||||
},
|
||||
{
|
||||
"type": "mount"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: "linuxkitprojects/kernel-memorizer:4.10_dbg-17e2eee03ab59f8df8a9c10ace003a84aec2f540"
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
onboot:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.9.34
|
||||
cmdline: "console=ttyS0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
onboot:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: okernel:latest
|
||||
cmdline: "console=tty0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkitprojects/kernel-shiftfs:4.11.4-881a041fc14bd95814cf140b5e98d97dd65160b5
|
||||
cmdline: "console=ttyS0 console=tty0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: dhcpcd
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: poweroff
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
services:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.4.139
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: check-kernel-config
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.9.111
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: check-kernel-config
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: check-kernel-config
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.17.4
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: check-kernel-config
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.4.139
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: check
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.9.111
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: check
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: check
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.17.4
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: check
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
trust:
|
||||
org:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 page_poison=1"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: test
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: binfmt
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
onboot:
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
- linuxkit/containerd:27a4c84cc8fab2d5ea04342546ecd20453ec99b3
|
||||
- linuxkit/ca-certificates:v0.4
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: dhcpcd
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: format
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: extend
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: modprobe
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: modprobe
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: format
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: extend
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: format
|
||||
|
@ -2,7 +2,7 @@ kernel:
|
||||
image: linuxkit/kernel:4.14.53
|
||||
cmdline: "console=ttyS0 console=ttyAMA0"
|
||||
init:
|
||||
- linuxkit/init:0e4af96fecc8f752c80d41c0b7d06570cc1dc6b2
|
||||
- linuxkit/init:6cc1442112980c889230b6449df09d5b48de6854
|
||||
- linuxkit/runc:v0.4
|
||||
onboot:
|
||||
- name: format
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user